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)
64 #if defined(CONFIG_USER_ONLY)
67 #define IS_USER(s) (s->user)
70 /* These instructions trap after executing, so defer them until after the
71 conditional executions state has been updated. */
75 static TCGv_ptr cpu_env;
76 /* We reuse the same 64-bit temporaries for efficiency. */
77 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
78 static TCGv_i32 cpu_R[16];
80 /* FIXME: These should be removed. */
81 static TCGv cpu_F0s, cpu_F1s;
82 static TCGv_i64 cpu_F0d, cpu_F1d;
84 #include "gen-icount.h"
86 static const char *regnames[] =
87 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
88 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
90 /* initialize TCG globals. */
91 void arm_translate_init(void)
95 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
97 for (i = 0; i < 16; i++) {
98 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
99 offsetof(CPUState, regs[i]),
107 static int num_temps;
109 /* Allocate a temporary variable. */
110 static TCGv_i32 new_tmp(void)
113 return tcg_temp_new_i32();
116 /* Release a temporary variable. */
117 static void dead_tmp(TCGv tmp)
123 static inline TCGv load_cpu_offset(int offset)
125 TCGv tmp = new_tmp();
126 tcg_gen_ld_i32(tmp, cpu_env, offset);
130 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
132 static inline void store_cpu_offset(TCGv var, int offset)
134 tcg_gen_st_i32(var, cpu_env, offset);
138 #define store_cpu_field(var, name) \
139 store_cpu_offset(var, offsetof(CPUState, name))
141 /* Set a variable to the value of a CPU register. */
142 static void load_reg_var(DisasContext *s, TCGv var, int reg)
146 /* normaly, since we updated PC, we need only to add one insn */
148 addr = (long)s->pc + 2;
150 addr = (long)s->pc + 4;
151 tcg_gen_movi_i32(var, addr);
153 tcg_gen_mov_i32(var, cpu_R[reg]);
157 /* Create a new temporary and set it to the value of a CPU register. */
158 static inline TCGv load_reg(DisasContext *s, int reg)
160 TCGv tmp = new_tmp();
161 load_reg_var(s, tmp, reg);
165 /* Set a CPU register. The source must be a temporary and will be
167 static void store_reg(DisasContext *s, int reg, TCGv var)
170 tcg_gen_andi_i32(var, var, ~1);
171 s->is_jmp = DISAS_JUMP;
173 tcg_gen_mov_i32(cpu_R[reg], var);
177 /* Value extensions. */
178 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
179 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
180 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
181 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
183 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
184 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
187 static inline void gen_set_cpsr(TCGv var, uint32_t mask)
189 TCGv tmp_mask = tcg_const_i32(mask);
190 gen_helper_cpsr_write(var, tmp_mask);
191 tcg_temp_free_i32(tmp_mask);
193 /* Set NZCV flags from the high 4 bits of var. */
194 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
196 static void gen_exception(int excp)
198 TCGv tmp = new_tmp();
199 tcg_gen_movi_i32(tmp, excp);
200 gen_helper_exception(tmp);
204 static void gen_smul_dual(TCGv a, TCGv b)
206 TCGv tmp1 = new_tmp();
207 TCGv tmp2 = new_tmp();
208 tcg_gen_ext16s_i32(tmp1, a);
209 tcg_gen_ext16s_i32(tmp2, b);
210 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
212 tcg_gen_sari_i32(a, a, 16);
213 tcg_gen_sari_i32(b, b, 16);
214 tcg_gen_mul_i32(b, b, a);
215 tcg_gen_mov_i32(a, tmp1);
219 /* Byteswap each halfword. */
220 static void gen_rev16(TCGv var)
222 TCGv tmp = new_tmp();
223 tcg_gen_shri_i32(tmp, var, 8);
224 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
225 tcg_gen_shli_i32(var, var, 8);
226 tcg_gen_andi_i32(var, var, 0xff00ff00);
227 tcg_gen_or_i32(var, var, tmp);
231 /* Byteswap low halfword and sign extend. */
232 static void gen_revsh(TCGv var)
234 TCGv tmp = new_tmp();
235 tcg_gen_shri_i32(tmp, var, 8);
236 tcg_gen_andi_i32(tmp, tmp, 0x00ff);
237 tcg_gen_shli_i32(var, var, 8);
238 tcg_gen_ext8s_i32(var, var);
239 tcg_gen_or_i32(var, var, tmp);
243 /* Unsigned bitfield extract. */
244 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
247 tcg_gen_shri_i32(var, var, shift);
248 tcg_gen_andi_i32(var, var, mask);
251 /* Signed bitfield extract. */
252 static void gen_sbfx(TCGv var, int shift, int width)
257 tcg_gen_sari_i32(var, var, shift);
258 if (shift + width < 32) {
259 signbit = 1u << (width - 1);
260 tcg_gen_andi_i32(var, var, (1u << width) - 1);
261 tcg_gen_xori_i32(var, var, signbit);
262 tcg_gen_subi_i32(var, var, signbit);
266 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
267 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
269 tcg_gen_andi_i32(val, val, mask);
270 tcg_gen_shli_i32(val, val, shift);
271 tcg_gen_andi_i32(base, base, ~(mask << shift));
272 tcg_gen_or_i32(dest, base, val);
275 /* Round the top 32 bits of a 64-bit value. */
276 static void gen_roundqd(TCGv a, TCGv b)
278 tcg_gen_shri_i32(a, a, 31);
279 tcg_gen_add_i32(a, a, b);
282 /* FIXME: Most targets have native widening multiplication.
283 It would be good to use that instead of a full wide multiply. */
284 /* 32x32->64 multiply. Marks inputs as dead. */
285 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
287 TCGv_i64 tmp1 = tcg_temp_new_i64();
288 TCGv_i64 tmp2 = tcg_temp_new_i64();
290 tcg_gen_extu_i32_i64(tmp1, a);
292 tcg_gen_extu_i32_i64(tmp2, b);
294 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
295 tcg_temp_free_i64(tmp2);
299 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
301 TCGv_i64 tmp1 = tcg_temp_new_i64();
302 TCGv_i64 tmp2 = tcg_temp_new_i64();
304 tcg_gen_ext_i32_i64(tmp1, a);
306 tcg_gen_ext_i32_i64(tmp2, b);
308 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
309 tcg_temp_free_i64(tmp2);
313 /* Signed 32x32->64 multiply. */
314 static void gen_imull(TCGv a, TCGv b)
316 TCGv_i64 tmp1 = tcg_temp_new_i64();
317 TCGv_i64 tmp2 = tcg_temp_new_i64();
319 tcg_gen_ext_i32_i64(tmp1, a);
320 tcg_gen_ext_i32_i64(tmp2, b);
321 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
322 tcg_temp_free_i64(tmp2);
323 tcg_gen_trunc_i64_i32(a, tmp1);
324 tcg_gen_shri_i64(tmp1, tmp1, 32);
325 tcg_gen_trunc_i64_i32(b, tmp1);
326 tcg_temp_free_i64(tmp1);
329 /* Swap low and high halfwords. */
330 static void gen_swap_half(TCGv var)
332 TCGv tmp = new_tmp();
333 tcg_gen_shri_i32(tmp, var, 16);
334 tcg_gen_shli_i32(var, var, 16);
335 tcg_gen_or_i32(var, var, tmp);
339 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
340 tmp = (t0 ^ t1) & 0x8000;
343 t0 = (t0 + t1) ^ tmp;
346 static void gen_add16(TCGv t0, TCGv t1)
348 TCGv tmp = new_tmp();
349 tcg_gen_xor_i32(tmp, t0, t1);
350 tcg_gen_andi_i32(tmp, tmp, 0x8000);
351 tcg_gen_andi_i32(t0, t0, ~0x8000);
352 tcg_gen_andi_i32(t1, t1, ~0x8000);
353 tcg_gen_add_i32(t0, t0, t1);
354 tcg_gen_xor_i32(t0, t0, tmp);
359 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
361 /* Set CF to the top bit of var. */
362 static void gen_set_CF_bit31(TCGv var)
364 TCGv tmp = new_tmp();
365 tcg_gen_shri_i32(tmp, var, 31);
370 /* Set N and Z flags from var. */
371 static inline void gen_logic_CC(TCGv var)
373 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
374 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
378 static void gen_adc(TCGv t0, TCGv t1)
381 tcg_gen_add_i32(t0, t0, t1);
382 tmp = load_cpu_field(CF);
383 tcg_gen_add_i32(t0, t0, tmp);
387 /* dest = T0 + T1 + CF. */
388 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
391 tcg_gen_add_i32(dest, t0, t1);
392 tmp = load_cpu_field(CF);
393 tcg_gen_add_i32(dest, dest, tmp);
397 /* dest = T0 - T1 + CF - 1. */
398 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
401 tcg_gen_sub_i32(dest, t0, t1);
402 tmp = load_cpu_field(CF);
403 tcg_gen_add_i32(dest, dest, tmp);
404 tcg_gen_subi_i32(dest, dest, 1);
408 /* T0 &= ~T1. Clobbers T1. */
409 /* FIXME: Implement bic natively. */
410 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
412 TCGv tmp = new_tmp();
413 tcg_gen_not_i32(tmp, t1);
414 tcg_gen_and_i32(dest, t0, tmp);
418 /* FIXME: Implement this natively. */
419 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
421 /* FIXME: Implement this natively. */
422 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
430 tcg_gen_shri_i32(tmp, t1, i);
431 tcg_gen_shli_i32(t1, t1, 32 - i);
432 tcg_gen_or_i32(t0, t1, tmp);
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_rori_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: gen_helper_ror(var, var, shift); break;
521 #define PAS_OP(pfx) \
523 case 0: gen_pas_helper(glue(pfx,add16)); break; \
524 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
525 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
526 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
527 case 4: gen_pas_helper(glue(pfx,add8)); break; \
528 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
530 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
535 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
537 tmp = tcg_temp_new_ptr();
538 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
540 tcg_temp_free_ptr(tmp);
543 tmp = tcg_temp_new_ptr();
544 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
546 tcg_temp_free_ptr(tmp);
548 #undef gen_pas_helper
549 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
562 #undef gen_pas_helper
567 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
568 #define PAS_OP(pfx) \
570 case 0: gen_pas_helper(glue(pfx,add8)); break; \
571 case 1: gen_pas_helper(glue(pfx,add16)); break; \
572 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
573 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
574 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
575 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
577 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
582 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
584 tmp = tcg_temp_new_ptr();
585 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
587 tcg_temp_free_ptr(tmp);
590 tmp = tcg_temp_new_ptr();
591 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
593 tcg_temp_free_ptr(tmp);
595 #undef gen_pas_helper
596 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
609 #undef gen_pas_helper
614 static void gen_test_cc(int cc, int label)
622 tmp = load_cpu_field(ZF);
623 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
626 tmp = load_cpu_field(ZF);
627 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
630 tmp = load_cpu_field(CF);
631 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
634 tmp = load_cpu_field(CF);
635 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
638 tmp = load_cpu_field(NF);
639 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
642 tmp = load_cpu_field(NF);
643 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
646 tmp = load_cpu_field(VF);
647 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
650 tmp = load_cpu_field(VF);
651 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
653 case 8: /* hi: C && !Z */
654 inv = gen_new_label();
655 tmp = load_cpu_field(CF);
656 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
658 tmp = load_cpu_field(ZF);
659 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
662 case 9: /* ls: !C || Z */
663 tmp = load_cpu_field(CF);
664 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
666 tmp = load_cpu_field(ZF);
667 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
669 case 10: /* ge: N == V -> N ^ V == 0 */
670 tmp = load_cpu_field(VF);
671 tmp2 = load_cpu_field(NF);
672 tcg_gen_xor_i32(tmp, tmp, tmp2);
674 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
676 case 11: /* lt: N != V -> N ^ V != 0 */
677 tmp = load_cpu_field(VF);
678 tmp2 = load_cpu_field(NF);
679 tcg_gen_xor_i32(tmp, tmp, tmp2);
681 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
683 case 12: /* gt: !Z && N == V */
684 inv = gen_new_label();
685 tmp = load_cpu_field(ZF);
686 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
688 tmp = load_cpu_field(VF);
689 tmp2 = load_cpu_field(NF);
690 tcg_gen_xor_i32(tmp, tmp, tmp2);
692 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
695 case 13: /* le: Z || N != V */
696 tmp = load_cpu_field(ZF);
697 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
699 tmp = load_cpu_field(VF);
700 tmp2 = load_cpu_field(NF);
701 tcg_gen_xor_i32(tmp, tmp, tmp2);
703 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
706 fprintf(stderr, "Bad condition code 0x%x\n", cc);
712 static const uint8_t table_logic_cc[16] = {
731 /* Set PC and Thumb state from an immediate address. */
732 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
736 s->is_jmp = DISAS_UPDATE;
737 if (s->thumb != (addr & 1)) {
739 tcg_gen_movi_i32(tmp, addr & 1);
740 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
743 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
746 /* Set PC and Thumb state from var. var is marked as dead. */
747 static inline void gen_bx(DisasContext *s, TCGv var)
749 s->is_jmp = DISAS_UPDATE;
750 tcg_gen_andi_i32(cpu_R[15], var, ~1);
751 tcg_gen_andi_i32(var, var, 1);
752 store_cpu_field(var, thumb);
755 /* Variant of store_reg which uses branch&exchange logic when storing
756 to r15 in ARM architecture v7 and above. The source must be a temporary
757 and will be marked as dead. */
758 static inline void store_reg_bx(CPUState *env, DisasContext *s,
761 if (reg == 15 && ENABLE_ARCH_7) {
764 store_reg(s, reg, var);
768 static inline TCGv gen_ld8s(TCGv addr, int index)
770 TCGv tmp = new_tmp();
771 tcg_gen_qemu_ld8s(tmp, addr, index);
774 static inline TCGv gen_ld8u(TCGv addr, int index)
776 TCGv tmp = new_tmp();
777 tcg_gen_qemu_ld8u(tmp, addr, index);
780 static inline TCGv gen_ld16s(TCGv addr, int index)
782 TCGv tmp = new_tmp();
783 tcg_gen_qemu_ld16s(tmp, addr, index);
786 static inline TCGv gen_ld16u(TCGv addr, int index)
788 TCGv tmp = new_tmp();
789 tcg_gen_qemu_ld16u(tmp, addr, index);
792 static inline TCGv gen_ld32(TCGv addr, int index)
794 TCGv tmp = new_tmp();
795 tcg_gen_qemu_ld32u(tmp, addr, index);
798 static inline TCGv_i64 gen_ld64(TCGv addr, int index)
800 TCGv_i64 tmp = tcg_temp_new_i64();
801 tcg_gen_qemu_ld64(tmp, addr, index);
804 static inline void gen_st8(TCGv val, TCGv addr, int index)
806 tcg_gen_qemu_st8(val, addr, index);
809 static inline void gen_st16(TCGv val, TCGv addr, int index)
811 tcg_gen_qemu_st16(val, addr, index);
814 static inline void gen_st32(TCGv val, TCGv addr, int index)
816 tcg_gen_qemu_st32(val, addr, index);
819 static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
821 tcg_gen_qemu_st64(val, addr, index);
822 tcg_temp_free_i64(val);
825 static inline void gen_set_pc_im(uint32_t val)
827 tcg_gen_movi_i32(cpu_R[15], val);
830 /* Force a TB lookup after an instruction that changes the CPU state. */
831 static inline void gen_lookup_tb(DisasContext *s)
833 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
834 s->is_jmp = DISAS_UPDATE;
837 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
840 int val, rm, shift, shiftop;
843 if (!(insn & (1 << 25))) {
846 if (!(insn & (1 << 23)))
849 tcg_gen_addi_i32(var, var, val);
853 shift = (insn >> 7) & 0x1f;
854 shiftop = (insn >> 5) & 3;
855 offset = load_reg(s, rm);
856 gen_arm_shift_im(offset, shiftop, shift, 0);
857 if (!(insn & (1 << 23)))
858 tcg_gen_sub_i32(var, var, offset);
860 tcg_gen_add_i32(var, var, offset);
865 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
871 if (insn & (1 << 22)) {
873 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
874 if (!(insn & (1 << 23)))
878 tcg_gen_addi_i32(var, var, val);
882 tcg_gen_addi_i32(var, var, extra);
884 offset = load_reg(s, rm);
885 if (!(insn & (1 << 23)))
886 tcg_gen_sub_i32(var, var, offset);
888 tcg_gen_add_i32(var, var, offset);
893 #define VFP_OP2(name) \
894 static inline void gen_vfp_##name(int dp) \
897 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
899 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
909 static inline void gen_vfp_abs(int dp)
912 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
914 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
917 static inline void gen_vfp_neg(int dp)
920 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
922 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
925 static inline void gen_vfp_sqrt(int dp)
928 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
930 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
933 static inline void gen_vfp_cmp(int dp)
936 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
938 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
941 static inline void gen_vfp_cmpe(int dp)
944 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
946 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
949 static inline void gen_vfp_F1_ld0(int dp)
952 tcg_gen_movi_i64(cpu_F1d, 0);
954 tcg_gen_movi_i32(cpu_F1s, 0);
957 static inline void gen_vfp_uito(int dp)
960 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
962 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
965 static inline void gen_vfp_sito(int dp)
968 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
970 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
973 static inline void gen_vfp_toui(int dp)
976 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
978 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
981 static inline void gen_vfp_touiz(int dp)
984 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
986 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
989 static inline void gen_vfp_tosi(int dp)
992 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
994 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
997 static inline void gen_vfp_tosiz(int dp)
1000 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1002 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1005 #define VFP_GEN_FIX(name) \
1006 static inline void gen_vfp_##name(int dp, int shift) \
1008 TCGv tmp_shift = tcg_const_i32(shift); \
1010 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
1012 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
1013 tcg_temp_free_i32(tmp_shift); \
1025 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1028 tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1030 tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1033 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1036 tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1038 tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1042 vfp_reg_offset (int dp, int reg)
1045 return offsetof(CPUARMState, vfp.regs[reg]);
1047 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1048 + offsetof(CPU_DoubleU, l.upper);
1050 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1051 + offsetof(CPU_DoubleU, l.lower);
1055 /* Return the offset of a 32-bit piece of a NEON register.
1056 zero is the least significant end of the register. */
1058 neon_reg_offset (int reg, int n)
1062 return vfp_reg_offset(0, sreg);
1065 static TCGv neon_load_reg(int reg, int pass)
1067 TCGv tmp = new_tmp();
1068 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1072 static void neon_store_reg(int reg, int pass, TCGv var)
1074 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1078 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1080 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1083 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1085 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1088 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1089 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1090 #define tcg_gen_st_f32 tcg_gen_st_i32
1091 #define tcg_gen_st_f64 tcg_gen_st_i64
1093 static inline void gen_mov_F0_vreg(int dp, int reg)
1096 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1098 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1101 static inline void gen_mov_F1_vreg(int dp, int reg)
1104 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1106 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1109 static inline void gen_mov_vreg_F0(int dp, int reg)
1112 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1114 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1117 #define ARM_CP_RW_BIT (1 << 20)
1119 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1121 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1124 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1126 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1129 static inline TCGv iwmmxt_load_creg(int reg)
1131 TCGv var = new_tmp();
1132 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1136 static inline void iwmmxt_store_creg(int reg, TCGv var)
1138 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1141 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1143 iwmmxt_store_reg(cpu_M0, rn);
1146 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1148 iwmmxt_load_reg(cpu_M0, rn);
1151 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1153 iwmmxt_load_reg(cpu_V1, rn);
1154 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1157 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1159 iwmmxt_load_reg(cpu_V1, rn);
1160 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1163 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1165 iwmmxt_load_reg(cpu_V1, rn);
1166 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1169 #define IWMMXT_OP(name) \
1170 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1172 iwmmxt_load_reg(cpu_V1, rn); \
1173 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1176 #define IWMMXT_OP_ENV(name) \
1177 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1179 iwmmxt_load_reg(cpu_V1, rn); \
1180 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1183 #define IWMMXT_OP_ENV_SIZE(name) \
1184 IWMMXT_OP_ENV(name##b) \
1185 IWMMXT_OP_ENV(name##w) \
1186 IWMMXT_OP_ENV(name##l)
1188 #define IWMMXT_OP_ENV1(name) \
1189 static inline void gen_op_iwmmxt_##name##_M0(void) \
1191 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1205 IWMMXT_OP_ENV_SIZE(unpackl)
1206 IWMMXT_OP_ENV_SIZE(unpackh)
1208 IWMMXT_OP_ENV1(unpacklub)
1209 IWMMXT_OP_ENV1(unpackluw)
1210 IWMMXT_OP_ENV1(unpacklul)
1211 IWMMXT_OP_ENV1(unpackhub)
1212 IWMMXT_OP_ENV1(unpackhuw)
1213 IWMMXT_OP_ENV1(unpackhul)
1214 IWMMXT_OP_ENV1(unpacklsb)
1215 IWMMXT_OP_ENV1(unpacklsw)
1216 IWMMXT_OP_ENV1(unpacklsl)
1217 IWMMXT_OP_ENV1(unpackhsb)
1218 IWMMXT_OP_ENV1(unpackhsw)
1219 IWMMXT_OP_ENV1(unpackhsl)
1221 IWMMXT_OP_ENV_SIZE(cmpeq)
1222 IWMMXT_OP_ENV_SIZE(cmpgtu)
1223 IWMMXT_OP_ENV_SIZE(cmpgts)
1225 IWMMXT_OP_ENV_SIZE(mins)
1226 IWMMXT_OP_ENV_SIZE(minu)
1227 IWMMXT_OP_ENV_SIZE(maxs)
1228 IWMMXT_OP_ENV_SIZE(maxu)
1230 IWMMXT_OP_ENV_SIZE(subn)
1231 IWMMXT_OP_ENV_SIZE(addn)
1232 IWMMXT_OP_ENV_SIZE(subu)
1233 IWMMXT_OP_ENV_SIZE(addu)
1234 IWMMXT_OP_ENV_SIZE(subs)
1235 IWMMXT_OP_ENV_SIZE(adds)
1237 IWMMXT_OP_ENV(avgb0)
1238 IWMMXT_OP_ENV(avgb1)
1239 IWMMXT_OP_ENV(avgw0)
1240 IWMMXT_OP_ENV(avgw1)
1244 IWMMXT_OP_ENV(packuw)
1245 IWMMXT_OP_ENV(packul)
1246 IWMMXT_OP_ENV(packuq)
1247 IWMMXT_OP_ENV(packsw)
1248 IWMMXT_OP_ENV(packsl)
1249 IWMMXT_OP_ENV(packsq)
1251 static void gen_op_iwmmxt_set_mup(void)
1254 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1255 tcg_gen_ori_i32(tmp, tmp, 2);
1256 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1259 static void gen_op_iwmmxt_set_cup(void)
1262 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1263 tcg_gen_ori_i32(tmp, tmp, 1);
1264 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1267 static void gen_op_iwmmxt_setpsr_nz(void)
1269 TCGv tmp = new_tmp();
1270 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1271 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1274 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1276 iwmmxt_load_reg(cpu_V1, rn);
1277 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1278 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1281 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1287 rd = (insn >> 16) & 0xf;
1288 tmp = load_reg(s, rd);
1290 offset = (insn & 0xff) << ((insn >> 7) & 2);
1291 if (insn & (1 << 24)) {
1293 if (insn & (1 << 23))
1294 tcg_gen_addi_i32(tmp, tmp, offset);
1296 tcg_gen_addi_i32(tmp, tmp, -offset);
1297 tcg_gen_mov_i32(dest, tmp);
1298 if (insn & (1 << 21))
1299 store_reg(s, rd, tmp);
1302 } else if (insn & (1 << 21)) {
1304 tcg_gen_mov_i32(dest, tmp);
1305 if (insn & (1 << 23))
1306 tcg_gen_addi_i32(tmp, tmp, offset);
1308 tcg_gen_addi_i32(tmp, tmp, -offset);
1309 store_reg(s, rd, tmp);
1310 } else if (!(insn & (1 << 23)))
1315 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1317 int rd = (insn >> 0) & 0xf;
1320 if (insn & (1 << 8)) {
1321 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1324 tmp = iwmmxt_load_creg(rd);
1328 iwmmxt_load_reg(cpu_V0, rd);
1329 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1331 tcg_gen_andi_i32(tmp, tmp, mask);
1332 tcg_gen_mov_i32(dest, tmp);
1337 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1338 (ie. an undefined instruction). */
1339 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1342 int rdhi, rdlo, rd0, rd1, i;
1344 TCGv tmp, tmp2, tmp3;
1346 if ((insn & 0x0e000e00) == 0x0c000000) {
1347 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1349 rdlo = (insn >> 12) & 0xf;
1350 rdhi = (insn >> 16) & 0xf;
1351 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1352 iwmmxt_load_reg(cpu_V0, wrd);
1353 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1354 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1355 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1356 } else { /* TMCRR */
1357 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1358 iwmmxt_store_reg(cpu_V0, wrd);
1359 gen_op_iwmmxt_set_mup();
1364 wrd = (insn >> 12) & 0xf;
1366 if (gen_iwmmxt_address(s, insn, addr)) {
1370 if (insn & ARM_CP_RW_BIT) {
1371 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1373 tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1374 iwmmxt_store_creg(wrd, tmp);
1377 if (insn & (1 << 8)) {
1378 if (insn & (1 << 22)) { /* WLDRD */
1379 tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1381 } else { /* WLDRW wRd */
1382 tmp = gen_ld32(addr, IS_USER(s));
1385 if (insn & (1 << 22)) { /* WLDRH */
1386 tmp = gen_ld16u(addr, IS_USER(s));
1387 } else { /* WLDRB */
1388 tmp = gen_ld8u(addr, IS_USER(s));
1392 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1395 gen_op_iwmmxt_movq_wRn_M0(wrd);
1398 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1399 tmp = iwmmxt_load_creg(wrd);
1400 gen_st32(tmp, addr, IS_USER(s));
1402 gen_op_iwmmxt_movq_M0_wRn(wrd);
1404 if (insn & (1 << 8)) {
1405 if (insn & (1 << 22)) { /* WSTRD */
1407 tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1408 } else { /* WSTRW wRd */
1409 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1410 gen_st32(tmp, addr, IS_USER(s));
1413 if (insn & (1 << 22)) { /* WSTRH */
1414 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1415 gen_st16(tmp, addr, IS_USER(s));
1416 } else { /* WSTRB */
1417 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1418 gen_st8(tmp, addr, IS_USER(s));
1426 if ((insn & 0x0f000000) != 0x0e000000)
1429 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1430 case 0x000: /* WOR */
1431 wrd = (insn >> 12) & 0xf;
1432 rd0 = (insn >> 0) & 0xf;
1433 rd1 = (insn >> 16) & 0xf;
1434 gen_op_iwmmxt_movq_M0_wRn(rd0);
1435 gen_op_iwmmxt_orq_M0_wRn(rd1);
1436 gen_op_iwmmxt_setpsr_nz();
1437 gen_op_iwmmxt_movq_wRn_M0(wrd);
1438 gen_op_iwmmxt_set_mup();
1439 gen_op_iwmmxt_set_cup();
1441 case 0x011: /* TMCR */
1444 rd = (insn >> 12) & 0xf;
1445 wrd = (insn >> 16) & 0xf;
1447 case ARM_IWMMXT_wCID:
1448 case ARM_IWMMXT_wCASF:
1450 case ARM_IWMMXT_wCon:
1451 gen_op_iwmmxt_set_cup();
1453 case ARM_IWMMXT_wCSSF:
1454 tmp = iwmmxt_load_creg(wrd);
1455 tmp2 = load_reg(s, rd);
1456 tcg_gen_bic_i32(tmp, tmp, tmp2);
1458 iwmmxt_store_creg(wrd, tmp);
1460 case ARM_IWMMXT_wCGR0:
1461 case ARM_IWMMXT_wCGR1:
1462 case ARM_IWMMXT_wCGR2:
1463 case ARM_IWMMXT_wCGR3:
1464 gen_op_iwmmxt_set_cup();
1465 tmp = load_reg(s, rd);
1466 iwmmxt_store_creg(wrd, tmp);
1472 case 0x100: /* WXOR */
1473 wrd = (insn >> 12) & 0xf;
1474 rd0 = (insn >> 0) & 0xf;
1475 rd1 = (insn >> 16) & 0xf;
1476 gen_op_iwmmxt_movq_M0_wRn(rd0);
1477 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1478 gen_op_iwmmxt_setpsr_nz();
1479 gen_op_iwmmxt_movq_wRn_M0(wrd);
1480 gen_op_iwmmxt_set_mup();
1481 gen_op_iwmmxt_set_cup();
1483 case 0x111: /* TMRC */
1486 rd = (insn >> 12) & 0xf;
1487 wrd = (insn >> 16) & 0xf;
1488 tmp = iwmmxt_load_creg(wrd);
1489 store_reg(s, rd, tmp);
1491 case 0x300: /* WANDN */
1492 wrd = (insn >> 12) & 0xf;
1493 rd0 = (insn >> 0) & 0xf;
1494 rd1 = (insn >> 16) & 0xf;
1495 gen_op_iwmmxt_movq_M0_wRn(rd0);
1496 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1497 gen_op_iwmmxt_andq_M0_wRn(rd1);
1498 gen_op_iwmmxt_setpsr_nz();
1499 gen_op_iwmmxt_movq_wRn_M0(wrd);
1500 gen_op_iwmmxt_set_mup();
1501 gen_op_iwmmxt_set_cup();
1503 case 0x200: /* WAND */
1504 wrd = (insn >> 12) & 0xf;
1505 rd0 = (insn >> 0) & 0xf;
1506 rd1 = (insn >> 16) & 0xf;
1507 gen_op_iwmmxt_movq_M0_wRn(rd0);
1508 gen_op_iwmmxt_andq_M0_wRn(rd1);
1509 gen_op_iwmmxt_setpsr_nz();
1510 gen_op_iwmmxt_movq_wRn_M0(wrd);
1511 gen_op_iwmmxt_set_mup();
1512 gen_op_iwmmxt_set_cup();
1514 case 0x810: case 0xa10: /* WMADD */
1515 wrd = (insn >> 12) & 0xf;
1516 rd0 = (insn >> 0) & 0xf;
1517 rd1 = (insn >> 16) & 0xf;
1518 gen_op_iwmmxt_movq_M0_wRn(rd0);
1519 if (insn & (1 << 21))
1520 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1522 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1523 gen_op_iwmmxt_movq_wRn_M0(wrd);
1524 gen_op_iwmmxt_set_mup();
1526 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1527 wrd = (insn >> 12) & 0xf;
1528 rd0 = (insn >> 16) & 0xf;
1529 rd1 = (insn >> 0) & 0xf;
1530 gen_op_iwmmxt_movq_M0_wRn(rd0);
1531 switch ((insn >> 22) & 3) {
1533 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1536 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1539 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1544 gen_op_iwmmxt_movq_wRn_M0(wrd);
1545 gen_op_iwmmxt_set_mup();
1546 gen_op_iwmmxt_set_cup();
1548 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1549 wrd = (insn >> 12) & 0xf;
1550 rd0 = (insn >> 16) & 0xf;
1551 rd1 = (insn >> 0) & 0xf;
1552 gen_op_iwmmxt_movq_M0_wRn(rd0);
1553 switch ((insn >> 22) & 3) {
1555 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1558 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1561 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1566 gen_op_iwmmxt_movq_wRn_M0(wrd);
1567 gen_op_iwmmxt_set_mup();
1568 gen_op_iwmmxt_set_cup();
1570 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1571 wrd = (insn >> 12) & 0xf;
1572 rd0 = (insn >> 16) & 0xf;
1573 rd1 = (insn >> 0) & 0xf;
1574 gen_op_iwmmxt_movq_M0_wRn(rd0);
1575 if (insn & (1 << 22))
1576 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1578 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1579 if (!(insn & (1 << 20)))
1580 gen_op_iwmmxt_addl_M0_wRn(wrd);
1581 gen_op_iwmmxt_movq_wRn_M0(wrd);
1582 gen_op_iwmmxt_set_mup();
1584 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1585 wrd = (insn >> 12) & 0xf;
1586 rd0 = (insn >> 16) & 0xf;
1587 rd1 = (insn >> 0) & 0xf;
1588 gen_op_iwmmxt_movq_M0_wRn(rd0);
1589 if (insn & (1 << 21)) {
1590 if (insn & (1 << 20))
1591 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1593 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1595 if (insn & (1 << 20))
1596 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1598 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1600 gen_op_iwmmxt_movq_wRn_M0(wrd);
1601 gen_op_iwmmxt_set_mup();
1603 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1604 wrd = (insn >> 12) & 0xf;
1605 rd0 = (insn >> 16) & 0xf;
1606 rd1 = (insn >> 0) & 0xf;
1607 gen_op_iwmmxt_movq_M0_wRn(rd0);
1608 if (insn & (1 << 21))
1609 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1611 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1612 if (!(insn & (1 << 20))) {
1613 iwmmxt_load_reg(cpu_V1, wrd);
1614 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1616 gen_op_iwmmxt_movq_wRn_M0(wrd);
1617 gen_op_iwmmxt_set_mup();
1619 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1620 wrd = (insn >> 12) & 0xf;
1621 rd0 = (insn >> 16) & 0xf;
1622 rd1 = (insn >> 0) & 0xf;
1623 gen_op_iwmmxt_movq_M0_wRn(rd0);
1624 switch ((insn >> 22) & 3) {
1626 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1629 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1632 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1637 gen_op_iwmmxt_movq_wRn_M0(wrd);
1638 gen_op_iwmmxt_set_mup();
1639 gen_op_iwmmxt_set_cup();
1641 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1642 wrd = (insn >> 12) & 0xf;
1643 rd0 = (insn >> 16) & 0xf;
1644 rd1 = (insn >> 0) & 0xf;
1645 gen_op_iwmmxt_movq_M0_wRn(rd0);
1646 if (insn & (1 << 22)) {
1647 if (insn & (1 << 20))
1648 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1650 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1652 if (insn & (1 << 20))
1653 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1655 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1657 gen_op_iwmmxt_movq_wRn_M0(wrd);
1658 gen_op_iwmmxt_set_mup();
1659 gen_op_iwmmxt_set_cup();
1661 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1662 wrd = (insn >> 12) & 0xf;
1663 rd0 = (insn >> 16) & 0xf;
1664 rd1 = (insn >> 0) & 0xf;
1665 gen_op_iwmmxt_movq_M0_wRn(rd0);
1666 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1667 tcg_gen_andi_i32(tmp, tmp, 7);
1668 iwmmxt_load_reg(cpu_V1, rd1);
1669 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1671 gen_op_iwmmxt_movq_wRn_M0(wrd);
1672 gen_op_iwmmxt_set_mup();
1674 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1675 if (((insn >> 6) & 3) == 3)
1677 rd = (insn >> 12) & 0xf;
1678 wrd = (insn >> 16) & 0xf;
1679 tmp = load_reg(s, rd);
1680 gen_op_iwmmxt_movq_M0_wRn(wrd);
1681 switch ((insn >> 6) & 3) {
1683 tmp2 = tcg_const_i32(0xff);
1684 tmp3 = tcg_const_i32((insn & 7) << 3);
1687 tmp2 = tcg_const_i32(0xffff);
1688 tmp3 = tcg_const_i32((insn & 3) << 4);
1691 tmp2 = tcg_const_i32(0xffffffff);
1692 tmp3 = tcg_const_i32((insn & 1) << 5);
1698 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1699 tcg_temp_free(tmp3);
1700 tcg_temp_free(tmp2);
1702 gen_op_iwmmxt_movq_wRn_M0(wrd);
1703 gen_op_iwmmxt_set_mup();
1705 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1706 rd = (insn >> 12) & 0xf;
1707 wrd = (insn >> 16) & 0xf;
1708 if (rd == 15 || ((insn >> 22) & 3) == 3)
1710 gen_op_iwmmxt_movq_M0_wRn(wrd);
1712 switch ((insn >> 22) & 3) {
1714 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1715 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1717 tcg_gen_ext8s_i32(tmp, tmp);
1719 tcg_gen_andi_i32(tmp, tmp, 0xff);
1723 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1724 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1726 tcg_gen_ext16s_i32(tmp, tmp);
1728 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1732 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1733 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1736 store_reg(s, rd, tmp);
1738 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1739 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1741 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1742 switch ((insn >> 22) & 3) {
1744 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1747 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1750 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1753 tcg_gen_shli_i32(tmp, tmp, 28);
1757 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1758 if (((insn >> 6) & 3) == 3)
1760 rd = (insn >> 12) & 0xf;
1761 wrd = (insn >> 16) & 0xf;
1762 tmp = load_reg(s, rd);
1763 switch ((insn >> 6) & 3) {
1765 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1768 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1771 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1775 gen_op_iwmmxt_movq_wRn_M0(wrd);
1776 gen_op_iwmmxt_set_mup();
1778 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1779 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1781 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1783 tcg_gen_mov_i32(tmp2, tmp);
1784 switch ((insn >> 22) & 3) {
1786 for (i = 0; i < 7; i ++) {
1787 tcg_gen_shli_i32(tmp2, tmp2, 4);
1788 tcg_gen_and_i32(tmp, tmp, tmp2);
1792 for (i = 0; i < 3; i ++) {
1793 tcg_gen_shli_i32(tmp2, tmp2, 8);
1794 tcg_gen_and_i32(tmp, tmp, tmp2);
1798 tcg_gen_shli_i32(tmp2, tmp2, 16);
1799 tcg_gen_and_i32(tmp, tmp, tmp2);
1806 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1807 wrd = (insn >> 12) & 0xf;
1808 rd0 = (insn >> 16) & 0xf;
1809 gen_op_iwmmxt_movq_M0_wRn(rd0);
1810 switch ((insn >> 22) & 3) {
1812 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1815 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1818 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1823 gen_op_iwmmxt_movq_wRn_M0(wrd);
1824 gen_op_iwmmxt_set_mup();
1826 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1827 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1829 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1831 tcg_gen_mov_i32(tmp2, tmp);
1832 switch ((insn >> 22) & 3) {
1834 for (i = 0; i < 7; i ++) {
1835 tcg_gen_shli_i32(tmp2, tmp2, 4);
1836 tcg_gen_or_i32(tmp, tmp, tmp2);
1840 for (i = 0; i < 3; i ++) {
1841 tcg_gen_shli_i32(tmp2, tmp2, 8);
1842 tcg_gen_or_i32(tmp, tmp, tmp2);
1846 tcg_gen_shli_i32(tmp2, tmp2, 16);
1847 tcg_gen_or_i32(tmp, tmp, tmp2);
1854 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1855 rd = (insn >> 12) & 0xf;
1856 rd0 = (insn >> 16) & 0xf;
1857 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1859 gen_op_iwmmxt_movq_M0_wRn(rd0);
1861 switch ((insn >> 22) & 3) {
1863 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1866 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1869 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1872 store_reg(s, rd, tmp);
1874 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1875 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1876 wrd = (insn >> 12) & 0xf;
1877 rd0 = (insn >> 16) & 0xf;
1878 rd1 = (insn >> 0) & 0xf;
1879 gen_op_iwmmxt_movq_M0_wRn(rd0);
1880 switch ((insn >> 22) & 3) {
1882 if (insn & (1 << 21))
1883 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1885 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1888 if (insn & (1 << 21))
1889 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1891 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1894 if (insn & (1 << 21))
1895 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1897 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1902 gen_op_iwmmxt_movq_wRn_M0(wrd);
1903 gen_op_iwmmxt_set_mup();
1904 gen_op_iwmmxt_set_cup();
1906 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1907 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1908 wrd = (insn >> 12) & 0xf;
1909 rd0 = (insn >> 16) & 0xf;
1910 gen_op_iwmmxt_movq_M0_wRn(rd0);
1911 switch ((insn >> 22) & 3) {
1913 if (insn & (1 << 21))
1914 gen_op_iwmmxt_unpacklsb_M0();
1916 gen_op_iwmmxt_unpacklub_M0();
1919 if (insn & (1 << 21))
1920 gen_op_iwmmxt_unpacklsw_M0();
1922 gen_op_iwmmxt_unpackluw_M0();
1925 if (insn & (1 << 21))
1926 gen_op_iwmmxt_unpacklsl_M0();
1928 gen_op_iwmmxt_unpacklul_M0();
1933 gen_op_iwmmxt_movq_wRn_M0(wrd);
1934 gen_op_iwmmxt_set_mup();
1935 gen_op_iwmmxt_set_cup();
1937 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1938 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1939 wrd = (insn >> 12) & 0xf;
1940 rd0 = (insn >> 16) & 0xf;
1941 gen_op_iwmmxt_movq_M0_wRn(rd0);
1942 switch ((insn >> 22) & 3) {
1944 if (insn & (1 << 21))
1945 gen_op_iwmmxt_unpackhsb_M0();
1947 gen_op_iwmmxt_unpackhub_M0();
1950 if (insn & (1 << 21))
1951 gen_op_iwmmxt_unpackhsw_M0();
1953 gen_op_iwmmxt_unpackhuw_M0();
1956 if (insn & (1 << 21))
1957 gen_op_iwmmxt_unpackhsl_M0();
1959 gen_op_iwmmxt_unpackhul_M0();
1964 gen_op_iwmmxt_movq_wRn_M0(wrd);
1965 gen_op_iwmmxt_set_mup();
1966 gen_op_iwmmxt_set_cup();
1968 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1969 case 0x214: case 0x614: case 0xa14: case 0xe14:
1970 if (((insn >> 22) & 3) == 0)
1972 wrd = (insn >> 12) & 0xf;
1973 rd0 = (insn >> 16) & 0xf;
1974 gen_op_iwmmxt_movq_M0_wRn(rd0);
1976 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
1980 switch ((insn >> 22) & 3) {
1982 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
1985 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
1988 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
1992 gen_op_iwmmxt_movq_wRn_M0(wrd);
1993 gen_op_iwmmxt_set_mup();
1994 gen_op_iwmmxt_set_cup();
1996 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
1997 case 0x014: case 0x414: case 0x814: case 0xc14:
1998 if (((insn >> 22) & 3) == 0)
2000 wrd = (insn >> 12) & 0xf;
2001 rd0 = (insn >> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2004 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2008 switch ((insn >> 22) & 3) {
2010 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2013 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2016 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2020 gen_op_iwmmxt_movq_wRn_M0(wrd);
2021 gen_op_iwmmxt_set_mup();
2022 gen_op_iwmmxt_set_cup();
2024 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2025 case 0x114: case 0x514: case 0x914: case 0xd14:
2026 if (((insn >> 22) & 3) == 0)
2028 wrd = (insn >> 12) & 0xf;
2029 rd0 = (insn >> 16) & 0xf;
2030 gen_op_iwmmxt_movq_M0_wRn(rd0);
2032 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2036 switch ((insn >> 22) & 3) {
2038 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2041 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2044 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2048 gen_op_iwmmxt_movq_wRn_M0(wrd);
2049 gen_op_iwmmxt_set_mup();
2050 gen_op_iwmmxt_set_cup();
2052 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2053 case 0x314: case 0x714: case 0xb14: case 0xf14:
2054 if (((insn >> 22) & 3) == 0)
2056 wrd = (insn >> 12) & 0xf;
2057 rd0 = (insn >> 16) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0);
2060 switch ((insn >> 22) & 3) {
2062 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2066 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2069 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2073 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2076 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2080 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2084 gen_op_iwmmxt_movq_wRn_M0(wrd);
2085 gen_op_iwmmxt_set_mup();
2086 gen_op_iwmmxt_set_cup();
2088 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2089 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2090 wrd = (insn >> 12) & 0xf;
2091 rd0 = (insn >> 16) & 0xf;
2092 rd1 = (insn >> 0) & 0xf;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0);
2094 switch ((insn >> 22) & 3) {
2096 if (insn & (1 << 21))
2097 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2099 gen_op_iwmmxt_minub_M0_wRn(rd1);
2102 if (insn & (1 << 21))
2103 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2105 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2108 if (insn & (1 << 21))
2109 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2111 gen_op_iwmmxt_minul_M0_wRn(rd1);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd);
2117 gen_op_iwmmxt_set_mup();
2119 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2120 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2121 wrd = (insn >> 12) & 0xf;
2122 rd0 = (insn >> 16) & 0xf;
2123 rd1 = (insn >> 0) & 0xf;
2124 gen_op_iwmmxt_movq_M0_wRn(rd0);
2125 switch ((insn >> 22) & 3) {
2127 if (insn & (1 << 21))
2128 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2130 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2133 if (insn & (1 << 21))
2134 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2136 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2139 if (insn & (1 << 21))
2140 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2142 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd);
2148 gen_op_iwmmxt_set_mup();
2150 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2151 case 0x402: case 0x502: case 0x602: case 0x702:
2152 wrd = (insn >> 12) & 0xf;
2153 rd0 = (insn >> 16) & 0xf;
2154 rd1 = (insn >> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0);
2156 tmp = tcg_const_i32((insn >> 20) & 3);
2157 iwmmxt_load_reg(cpu_V1, rd1);
2158 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2160 gen_op_iwmmxt_movq_wRn_M0(wrd);
2161 gen_op_iwmmxt_set_mup();
2163 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2164 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2165 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2166 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2167 wrd = (insn >> 12) & 0xf;
2168 rd0 = (insn >> 16) & 0xf;
2169 rd1 = (insn >> 0) & 0xf;
2170 gen_op_iwmmxt_movq_M0_wRn(rd0);
2171 switch ((insn >> 20) & 0xf) {
2173 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2176 gen_op_iwmmxt_subub_M0_wRn(rd1);
2179 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2182 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2185 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2188 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2191 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2194 gen_op_iwmmxt_subul_M0_wRn(rd1);
2197 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2202 gen_op_iwmmxt_movq_wRn_M0(wrd);
2203 gen_op_iwmmxt_set_mup();
2204 gen_op_iwmmxt_set_cup();
2206 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2207 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2208 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2209 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2210 wrd = (insn >> 12) & 0xf;
2211 rd0 = (insn >> 16) & 0xf;
2212 gen_op_iwmmxt_movq_M0_wRn(rd0);
2213 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2214 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2216 gen_op_iwmmxt_movq_wRn_M0(wrd);
2217 gen_op_iwmmxt_set_mup();
2218 gen_op_iwmmxt_set_cup();
2220 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2221 case 0x418: case 0x518: case 0x618: case 0x718:
2222 case 0x818: case 0x918: case 0xa18: case 0xb18:
2223 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2224 wrd = (insn >> 12) & 0xf;
2225 rd0 = (insn >> 16) & 0xf;
2226 rd1 = (insn >> 0) & 0xf;
2227 gen_op_iwmmxt_movq_M0_wRn(rd0);
2228 switch ((insn >> 20) & 0xf) {
2230 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2233 gen_op_iwmmxt_addub_M0_wRn(rd1);
2236 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2239 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2242 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2245 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2248 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2251 gen_op_iwmmxt_addul_M0_wRn(rd1);
2254 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2259 gen_op_iwmmxt_movq_wRn_M0(wrd);
2260 gen_op_iwmmxt_set_mup();
2261 gen_op_iwmmxt_set_cup();
2263 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2264 case 0x408: case 0x508: case 0x608: case 0x708:
2265 case 0x808: case 0x908: case 0xa08: case 0xb08:
2266 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2267 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2269 wrd = (insn >> 12) & 0xf;
2270 rd0 = (insn >> 16) & 0xf;
2271 rd1 = (insn >> 0) & 0xf;
2272 gen_op_iwmmxt_movq_M0_wRn(rd0);
2273 switch ((insn >> 22) & 3) {
2275 if (insn & (1 << 21))
2276 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2278 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2281 if (insn & (1 << 21))
2282 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2284 gen_op_iwmmxt_packul_M0_wRn(rd1);
2287 if (insn & (1 << 21))
2288 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2290 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2293 gen_op_iwmmxt_movq_wRn_M0(wrd);
2294 gen_op_iwmmxt_set_mup();
2295 gen_op_iwmmxt_set_cup();
2297 case 0x201: case 0x203: case 0x205: case 0x207:
2298 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2299 case 0x211: case 0x213: case 0x215: case 0x217:
2300 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2301 wrd = (insn >> 5) & 0xf;
2302 rd0 = (insn >> 12) & 0xf;
2303 rd1 = (insn >> 0) & 0xf;
2304 if (rd0 == 0xf || rd1 == 0xf)
2306 gen_op_iwmmxt_movq_M0_wRn(wrd);
2307 tmp = load_reg(s, rd0);
2308 tmp2 = load_reg(s, rd1);
2309 switch ((insn >> 16) & 0xf) {
2310 case 0x0: /* TMIA */
2311 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2313 case 0x8: /* TMIAPH */
2314 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2316 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2317 if (insn & (1 << 16))
2318 tcg_gen_shri_i32(tmp, tmp, 16);
2319 if (insn & (1 << 17))
2320 tcg_gen_shri_i32(tmp2, tmp2, 16);
2321 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2340 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2341 (ie. an undefined instruction). */
2342 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2344 int acc, rd0, rd1, rdhi, rdlo;
2347 if ((insn & 0x0ff00f10) == 0x0e200010) {
2348 /* Multiply with Internal Accumulate Format */
2349 rd0 = (insn >> 12) & 0xf;
2351 acc = (insn >> 5) & 7;
2356 tmp = load_reg(s, rd0);
2357 tmp2 = load_reg(s, rd1);
2358 switch ((insn >> 16) & 0xf) {
2360 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2362 case 0x8: /* MIAPH */
2363 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2365 case 0xc: /* MIABB */
2366 case 0xd: /* MIABT */
2367 case 0xe: /* MIATB */
2368 case 0xf: /* MIATT */
2369 if (insn & (1 << 16))
2370 tcg_gen_shri_i32(tmp, tmp, 16);
2371 if (insn & (1 << 17))
2372 tcg_gen_shri_i32(tmp2, tmp2, 16);
2373 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2381 gen_op_iwmmxt_movq_wRn_M0(acc);
2385 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2386 /* Internal Accumulator Access Format */
2387 rdhi = (insn >> 16) & 0xf;
2388 rdlo = (insn >> 12) & 0xf;
2394 if (insn & ARM_CP_RW_BIT) { /* MRA */
2395 iwmmxt_load_reg(cpu_V0, acc);
2396 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2397 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2398 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2399 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2401 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2402 iwmmxt_store_reg(cpu_V0, acc);
2410 /* Disassemble system coprocessor instruction. Return nonzero if
2411 instruction is not defined. */
2412 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2415 uint32_t rd = (insn >> 12) & 0xf;
2416 uint32_t cp = (insn >> 8) & 0xf;
2421 if (insn & ARM_CP_RW_BIT) {
2422 if (!env->cp[cp].cp_read)
2424 gen_set_pc_im(s->pc);
2426 tmp2 = tcg_const_i32(insn);
2427 gen_helper_get_cp(tmp, cpu_env, tmp2);
2428 tcg_temp_free(tmp2);
2429 store_reg(s, rd, tmp);
2431 if (!env->cp[cp].cp_write)
2433 gen_set_pc_im(s->pc);
2434 tmp = load_reg(s, rd);
2435 tmp2 = tcg_const_i32(insn);
2436 gen_helper_set_cp(cpu_env, tmp2, tmp);
2437 tcg_temp_free(tmp2);
2443 static int cp15_user_ok(uint32_t insn)
2445 int cpn = (insn >> 16) & 0xf;
2446 int cpm = insn & 0xf;
2447 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2449 if (cpn == 13 && cpm == 0) {
2451 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2455 /* ISB, DSB, DMB. */
2456 if ((cpm == 5 && op == 4)
2457 || (cpm == 10 && (op == 4 || op == 5)))
2463 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2464 instruction is not defined. */
2465 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2470 /* M profile cores use memory mapped registers instead of cp15. */
2471 if (arm_feature(env, ARM_FEATURE_M))
2474 if ((insn & (1 << 25)) == 0) {
2475 if (insn & (1 << 20)) {
2479 /* mcrr. Used for block cache operations, so implement as no-op. */
2482 if ((insn & (1 << 4)) == 0) {
2486 if (IS_USER(s) && !cp15_user_ok(insn)) {
2489 if ((insn & 0x0fff0fff) == 0x0e070f90
2490 || (insn & 0x0fff0fff) == 0x0e070f58) {
2491 /* Wait for interrupt. */
2492 gen_set_pc_im(s->pc);
2493 s->is_jmp = DISAS_WFI;
2496 rd = (insn >> 12) & 0xf;
2497 tmp2 = tcg_const_i32(insn);
2498 if (insn & ARM_CP_RW_BIT) {
2500 gen_helper_get_cp15(tmp, cpu_env, tmp2);
2501 /* If the destination register is r15 then sets condition codes. */
2503 store_reg(s, rd, tmp);
2507 tmp = load_reg(s, rd);
2508 gen_helper_set_cp15(cpu_env, tmp2, tmp);
2510 /* Normally we would always end the TB here, but Linux
2511 * arch/arm/mach-pxa/sleep.S expects two instructions following
2512 * an MMU enable to execute from cache. Imitate this behaviour. */
2513 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2514 (insn & 0x0fff0fff) != 0x0e010f10)
2517 tcg_temp_free_i32(tmp2);
2521 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2522 #define VFP_SREG(insn, bigbit, smallbit) \
2523 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2524 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2525 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2526 reg = (((insn) >> (bigbit)) & 0x0f) \
2527 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2529 if (insn & (1 << (smallbit))) \
2531 reg = ((insn) >> (bigbit)) & 0x0f; \
2534 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2535 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2536 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2537 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2538 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2539 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2541 /* Move between integer and VFP cores. */
2542 static TCGv gen_vfp_mrs(void)
2544 TCGv tmp = new_tmp();
2545 tcg_gen_mov_i32(tmp, cpu_F0s);
2549 static void gen_vfp_msr(TCGv tmp)
2551 tcg_gen_mov_i32(cpu_F0s, tmp);
2556 vfp_enabled(CPUState * env)
2558 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2561 static void gen_neon_dup_u8(TCGv var, int shift)
2563 TCGv tmp = new_tmp();
2565 tcg_gen_shri_i32(var, var, shift);
2566 tcg_gen_ext8u_i32(var, var);
2567 tcg_gen_shli_i32(tmp, var, 8);
2568 tcg_gen_or_i32(var, var, tmp);
2569 tcg_gen_shli_i32(tmp, var, 16);
2570 tcg_gen_or_i32(var, var, tmp);
2574 static void gen_neon_dup_low16(TCGv var)
2576 TCGv tmp = new_tmp();
2577 tcg_gen_ext16u_i32(var, var);
2578 tcg_gen_shli_i32(tmp, var, 16);
2579 tcg_gen_or_i32(var, var, tmp);
2583 static void gen_neon_dup_high16(TCGv var)
2585 TCGv tmp = new_tmp();
2586 tcg_gen_andi_i32(var, var, 0xffff0000);
2587 tcg_gen_shri_i32(tmp, var, 16);
2588 tcg_gen_or_i32(var, var, tmp);
2592 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2593 (ie. an undefined instruction). */
2594 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2596 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2602 if (!arm_feature(env, ARM_FEATURE_VFP))
2605 if (!vfp_enabled(env)) {
2606 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2607 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2609 rn = (insn >> 16) & 0xf;
2610 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2611 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2614 dp = ((insn & 0xf00) == 0xb00);
2615 switch ((insn >> 24) & 0xf) {
2617 if (insn & (1 << 4)) {
2618 /* single register transfer */
2619 rd = (insn >> 12) & 0xf;
2624 VFP_DREG_N(rn, insn);
2627 if (insn & 0x00c00060
2628 && !arm_feature(env, ARM_FEATURE_NEON))
2631 pass = (insn >> 21) & 1;
2632 if (insn & (1 << 22)) {
2634 offset = ((insn >> 5) & 3) * 8;
2635 } else if (insn & (1 << 5)) {
2637 offset = (insn & (1 << 6)) ? 16 : 0;
2642 if (insn & ARM_CP_RW_BIT) {
2644 tmp = neon_load_reg(rn, pass);
2648 tcg_gen_shri_i32(tmp, tmp, offset);
2649 if (insn & (1 << 23))
2655 if (insn & (1 << 23)) {
2657 tcg_gen_shri_i32(tmp, tmp, 16);
2663 tcg_gen_sari_i32(tmp, tmp, 16);
2672 store_reg(s, rd, tmp);
2675 tmp = load_reg(s, rd);
2676 if (insn & (1 << 23)) {
2679 gen_neon_dup_u8(tmp, 0);
2680 } else if (size == 1) {
2681 gen_neon_dup_low16(tmp);
2683 for (n = 0; n <= pass * 2; n++) {
2685 tcg_gen_mov_i32(tmp2, tmp);
2686 neon_store_reg(rn, n, tmp2);
2688 neon_store_reg(rn, n, tmp);
2693 tmp2 = neon_load_reg(rn, pass);
2694 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2698 tmp2 = neon_load_reg(rn, pass);
2699 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2705 neon_store_reg(rn, pass, tmp);
2709 if ((insn & 0x6f) != 0x00)
2711 rn = VFP_SREG_N(insn);
2712 if (insn & ARM_CP_RW_BIT) {
2714 if (insn & (1 << 21)) {
2715 /* system register */
2720 /* VFP2 allows access to FSID from userspace.
2721 VFP3 restricts all id registers to privileged
2724 && arm_feature(env, ARM_FEATURE_VFP3))
2726 tmp = load_cpu_field(vfp.xregs[rn]);
2731 tmp = load_cpu_field(vfp.xregs[rn]);
2733 case ARM_VFP_FPINST:
2734 case ARM_VFP_FPINST2:
2735 /* Not present in VFP3. */
2737 || arm_feature(env, ARM_FEATURE_VFP3))
2739 tmp = load_cpu_field(vfp.xregs[rn]);
2743 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2744 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2747 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2753 || !arm_feature(env, ARM_FEATURE_VFP3))
2755 tmp = load_cpu_field(vfp.xregs[rn]);
2761 gen_mov_F0_vreg(0, rn);
2762 tmp = gen_vfp_mrs();
2765 /* Set the 4 flag bits in the CPSR. */
2769 store_reg(s, rd, tmp);
2773 tmp = load_reg(s, rd);
2774 if (insn & (1 << 21)) {
2776 /* system register */
2781 /* Writes are ignored. */
2784 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2791 /* TODO: VFP subarchitecture support.
2792 * For now, keep the EN bit only */
2793 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2794 store_cpu_field(tmp, vfp.xregs[rn]);
2797 case ARM_VFP_FPINST:
2798 case ARM_VFP_FPINST2:
2799 store_cpu_field(tmp, vfp.xregs[rn]);
2806 gen_mov_vreg_F0(0, rn);
2811 /* data processing */
2812 /* The opcode is in bits 23, 21, 20 and 6. */
2813 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2817 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2819 /* rn is register number */
2820 VFP_DREG_N(rn, insn);
2823 if (op == 15 && (rn == 15 || rn > 17)) {
2824 /* Integer or single precision destination. */
2825 rd = VFP_SREG_D(insn);
2827 VFP_DREG_D(rd, insn);
2830 if (op == 15 && (rn == 16 || rn == 17)) {
2831 /* Integer source. */
2832 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2834 VFP_DREG_M(rm, insn);
2837 rn = VFP_SREG_N(insn);
2838 if (op == 15 && rn == 15) {
2839 /* Double precision destination. */
2840 VFP_DREG_D(rd, insn);
2842 rd = VFP_SREG_D(insn);
2844 rm = VFP_SREG_M(insn);
2847 veclen = env->vfp.vec_len;
2848 if (op == 15 && rn > 3)
2851 /* Shut up compiler warnings. */
2862 /* Figure out what type of vector operation this is. */
2863 if ((rd & bank_mask) == 0) {
2868 delta_d = (env->vfp.vec_stride >> 1) + 1;
2870 delta_d = env->vfp.vec_stride + 1;
2872 if ((rm & bank_mask) == 0) {
2873 /* mixed scalar/vector */
2882 /* Load the initial operands. */
2887 /* Integer source */
2888 gen_mov_F0_vreg(0, rm);
2893 gen_mov_F0_vreg(dp, rd);
2894 gen_mov_F1_vreg(dp, rm);
2898 /* Compare with zero */
2899 gen_mov_F0_vreg(dp, rd);
2910 /* Source and destination the same. */
2911 gen_mov_F0_vreg(dp, rd);
2914 /* One source operand. */
2915 gen_mov_F0_vreg(dp, rm);
2919 /* Two source operands. */
2920 gen_mov_F0_vreg(dp, rn);
2921 gen_mov_F1_vreg(dp, rm);
2925 /* Perform the calculation. */
2927 case 0: /* mac: fd + (fn * fm) */
2929 gen_mov_F1_vreg(dp, rd);
2932 case 1: /* nmac: fd - (fn * fm) */
2935 gen_mov_F1_vreg(dp, rd);
2938 case 2: /* msc: -fd + (fn * fm) */
2940 gen_mov_F1_vreg(dp, rd);
2943 case 3: /* nmsc: -fd - (fn * fm) */
2946 gen_mov_F1_vreg(dp, rd);
2949 case 4: /* mul: fn * fm */
2952 case 5: /* nmul: -(fn * fm) */
2956 case 6: /* add: fn + fm */
2959 case 7: /* sub: fn - fm */
2962 case 8: /* div: fn / fm */
2965 case 14: /* fconst */
2966 if (!arm_feature(env, ARM_FEATURE_VFP3))
2969 n = (insn << 12) & 0x80000000;
2970 i = ((insn >> 12) & 0x70) | (insn & 0xf);
2977 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2984 tcg_gen_movi_i32(cpu_F0s, n);
2987 case 15: /* extension space */
3010 case 11: /* cmpez */
3014 case 15: /* single<->double conversion */
3016 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3018 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3020 case 16: /* fuito */
3023 case 17: /* fsito */
3026 case 20: /* fshto */
3027 if (!arm_feature(env, ARM_FEATURE_VFP3))
3029 gen_vfp_shto(dp, 16 - rm);
3031 case 21: /* fslto */
3032 if (!arm_feature(env, ARM_FEATURE_VFP3))
3034 gen_vfp_slto(dp, 32 - rm);
3036 case 22: /* fuhto */
3037 if (!arm_feature(env, ARM_FEATURE_VFP3))
3039 gen_vfp_uhto(dp, 16 - rm);
3041 case 23: /* fulto */
3042 if (!arm_feature(env, ARM_FEATURE_VFP3))
3044 gen_vfp_ulto(dp, 32 - rm);
3046 case 24: /* ftoui */
3049 case 25: /* ftouiz */
3052 case 26: /* ftosi */
3055 case 27: /* ftosiz */
3058 case 28: /* ftosh */
3059 if (!arm_feature(env, ARM_FEATURE_VFP3))
3061 gen_vfp_tosh(dp, 16 - rm);
3063 case 29: /* ftosl */
3064 if (!arm_feature(env, ARM_FEATURE_VFP3))
3066 gen_vfp_tosl(dp, 32 - rm);
3068 case 30: /* ftouh */
3069 if (!arm_feature(env, ARM_FEATURE_VFP3))
3071 gen_vfp_touh(dp, 16 - rm);
3073 case 31: /* ftoul */
3074 if (!arm_feature(env, ARM_FEATURE_VFP3))
3076 gen_vfp_toul(dp, 32 - rm);
3078 default: /* undefined */
3079 printf ("rn:%d\n", rn);
3083 default: /* undefined */
3084 printf ("op:%d\n", op);
3088 /* Write back the result. */
3089 if (op == 15 && (rn >= 8 && rn <= 11))
3090 ; /* Comparison, do nothing. */
3091 else if (op == 15 && rn > 17)
3092 /* Integer result. */
3093 gen_mov_vreg_F0(0, rd);
3094 else if (op == 15 && rn == 15)
3096 gen_mov_vreg_F0(!dp, rd);
3098 gen_mov_vreg_F0(dp, rd);
3100 /* break out of the loop if we have finished */
3104 if (op == 15 && delta_m == 0) {
3105 /* single source one-many */
3107 rd = ((rd + delta_d) & (bank_mask - 1))
3109 gen_mov_vreg_F0(dp, rd);
3113 /* Setup the next operands. */
3115 rd = ((rd + delta_d) & (bank_mask - 1))
3119 /* One source operand. */
3120 rm = ((rm + delta_m) & (bank_mask - 1))
3122 gen_mov_F0_vreg(dp, rm);
3124 /* Two source operands. */
3125 rn = ((rn + delta_d) & (bank_mask - 1))
3127 gen_mov_F0_vreg(dp, rn);
3129 rm = ((rm + delta_m) & (bank_mask - 1))
3131 gen_mov_F1_vreg(dp, rm);
3139 if (dp && (insn & 0x03e00000) == 0x00400000) {
3140 /* two-register transfer */
3141 rn = (insn >> 16) & 0xf;
3142 rd = (insn >> 12) & 0xf;
3144 VFP_DREG_M(rm, insn);
3146 rm = VFP_SREG_M(insn);
3149 if (insn & ARM_CP_RW_BIT) {
3152 gen_mov_F0_vreg(0, rm * 2);
3153 tmp = gen_vfp_mrs();
3154 store_reg(s, rd, tmp);
3155 gen_mov_F0_vreg(0, rm * 2 + 1);
3156 tmp = gen_vfp_mrs();
3157 store_reg(s, rn, tmp);
3159 gen_mov_F0_vreg(0, rm);
3160 tmp = gen_vfp_mrs();
3161 store_reg(s, rn, tmp);
3162 gen_mov_F0_vreg(0, rm + 1);
3163 tmp = gen_vfp_mrs();
3164 store_reg(s, rd, tmp);
3169 tmp = load_reg(s, rd);
3171 gen_mov_vreg_F0(0, rm * 2);
3172 tmp = load_reg(s, rn);
3174 gen_mov_vreg_F0(0, rm * 2 + 1);
3176 tmp = load_reg(s, rn);
3178 gen_mov_vreg_F0(0, rm);
3179 tmp = load_reg(s, rd);
3181 gen_mov_vreg_F0(0, rm + 1);
3186 rn = (insn >> 16) & 0xf;
3188 VFP_DREG_D(rd, insn);
3190 rd = VFP_SREG_D(insn);
3191 if (s->thumb && rn == 15) {
3193 tcg_gen_movi_i32(addr, s->pc & ~2);
3195 addr = load_reg(s, rn);
3197 if ((insn & 0x01200000) == 0x01000000) {
3198 /* Single load/store */
3199 offset = (insn & 0xff) << 2;
3200 if ((insn & (1 << 23)) == 0)
3202 tcg_gen_addi_i32(addr, addr, offset);
3203 if (insn & (1 << 20)) {
3204 gen_vfp_ld(s, dp, addr);
3205 gen_mov_vreg_F0(dp, rd);
3207 gen_mov_F0_vreg(dp, rd);
3208 gen_vfp_st(s, dp, addr);
3212 /* load/store multiple */
3214 n = (insn >> 1) & 0x7f;
3218 if (insn & (1 << 24)) /* pre-decrement */
3219 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3225 for (i = 0; i < n; i++) {
3226 if (insn & ARM_CP_RW_BIT) {
3228 gen_vfp_ld(s, dp, addr);
3229 gen_mov_vreg_F0(dp, rd + i);
3232 gen_mov_F0_vreg(dp, rd + i);
3233 gen_vfp_st(s, dp, addr);
3235 tcg_gen_addi_i32(addr, addr, offset);
3237 if (insn & (1 << 21)) {
3239 if (insn & (1 << 24))
3240 offset = -offset * n;
3241 else if (dp && (insn & 1))
3247 tcg_gen_addi_i32(addr, addr, offset);
3248 store_reg(s, rn, addr);
3256 /* Should never happen. */
3262 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3264 TranslationBlock *tb;
3267 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3269 gen_set_pc_im(dest);
3270 tcg_gen_exit_tb((long)tb + n);
3272 gen_set_pc_im(dest);
3277 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3279 if (unlikely(s->singlestep_enabled)) {
3280 /* An indirect jump so that we still trigger the debug exception. */
3285 gen_goto_tb(s, 0, dest);
3286 s->is_jmp = DISAS_TB_JUMP;
3290 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3293 tcg_gen_sari_i32(t0, t0, 16);
3297 tcg_gen_sari_i32(t1, t1, 16);
3300 tcg_gen_mul_i32(t0, t0, t1);
3303 /* Return the mask of PSR bits set by a MSR instruction. */
3304 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3308 if (flags & (1 << 0))
3310 if (flags & (1 << 1))
3312 if (flags & (1 << 2))
3314 if (flags & (1 << 3))
3317 /* Mask out undefined bits. */
3318 mask &= ~CPSR_RESERVED;
3319 if (!arm_feature(env, ARM_FEATURE_V6))
3320 mask &= ~(CPSR_E | CPSR_GE);
3321 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3323 /* Mask out execution state bits. */
3326 /* Mask out privileged bits. */
3332 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3333 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3337 /* ??? This is also undefined in system mode. */
3341 tmp = load_cpu_field(spsr);
3342 tcg_gen_andi_i32(tmp, tmp, ~mask);
3343 tcg_gen_andi_i32(t0, t0, mask);
3344 tcg_gen_or_i32(tmp, tmp, t0);
3345 store_cpu_field(tmp, spsr);
3347 gen_set_cpsr(t0, mask);
3354 /* Returns nonzero if access to the PSR is not permitted. */
3355 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3359 tcg_gen_movi_i32(tmp, val);
3360 return gen_set_psr(s, mask, spsr, tmp);
3363 /* Generate an old-style exception return. Marks pc as dead. */
3364 static void gen_exception_return(DisasContext *s, TCGv pc)
3367 store_reg(s, 15, pc);
3368 tmp = load_cpu_field(spsr);
3369 gen_set_cpsr(tmp, 0xffffffff);
3371 s->is_jmp = DISAS_UPDATE;
3374 /* Generate a v6 exception return. Marks both values as dead. */
3375 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3377 gen_set_cpsr(cpsr, 0xffffffff);
3379 store_reg(s, 15, pc);
3380 s->is_jmp = DISAS_UPDATE;
3384 gen_set_condexec (DisasContext *s)
3386 if (s->condexec_mask) {
3387 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3388 TCGv tmp = new_tmp();
3389 tcg_gen_movi_i32(tmp, val);
3390 store_cpu_field(tmp, condexec_bits);
3394 static void gen_nop_hint(DisasContext *s, int val)
3398 gen_set_pc_im(s->pc);
3399 s->is_jmp = DISAS_WFI;
3403 /* TODO: Implement SEV and WFE. May help SMP performance. */
3409 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3411 static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3414 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3415 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3416 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3422 static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3425 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3426 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3427 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3432 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3433 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3434 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3435 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3436 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3438 /* FIXME: This is wrong. They set the wrong overflow bit. */
3439 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3440 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3441 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3442 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3444 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3445 switch ((size << 1) | u) { \
3447 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3450 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3453 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3456 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3459 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3462 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3464 default: return 1; \
3467 #define GEN_NEON_INTEGER_OP(name) do { \
3468 switch ((size << 1) | u) { \
3470 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3473 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3476 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3479 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3482 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3485 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3487 default: return 1; \
3490 static TCGv neon_load_scratch(int scratch)
3492 TCGv tmp = new_tmp();
3493 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3497 static void neon_store_scratch(int scratch, TCGv var)
3499 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3503 static inline TCGv neon_get_scalar(int size, int reg)
3507 tmp = neon_load_reg(reg >> 1, reg & 1);
3509 tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3511 gen_neon_dup_low16(tmp);
3513 gen_neon_dup_high16(tmp);
3519 static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3527 tcg_gen_andi_i32(rd, t0, 0xff);
3528 tcg_gen_shri_i32(tmp, t0, 8);
3529 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3530 tcg_gen_or_i32(rd, rd, tmp);
3531 tcg_gen_shli_i32(tmp, t1, 16);
3532 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3533 tcg_gen_or_i32(rd, rd, tmp);
3534 tcg_gen_shli_i32(tmp, t1, 8);
3535 tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3536 tcg_gen_or_i32(rd, rd, tmp);
3538 tcg_gen_shri_i32(rm, t0, 8);
3539 tcg_gen_andi_i32(rm, rm, 0xff);
3540 tcg_gen_shri_i32(tmp, t0, 16);
3541 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3542 tcg_gen_or_i32(rm, rm, tmp);
3543 tcg_gen_shli_i32(tmp, t1, 8);
3544 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3545 tcg_gen_or_i32(rm, rm, tmp);
3546 tcg_gen_andi_i32(tmp, t1, 0xff000000);
3547 tcg_gen_or_i32(t1, rm, tmp);
3548 tcg_gen_mov_i32(t0, rd);
3555 static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3563 tcg_gen_andi_i32(rd, t0, 0xff);
3564 tcg_gen_shli_i32(tmp, t1, 8);
3565 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3566 tcg_gen_or_i32(rd, rd, tmp);
3567 tcg_gen_shli_i32(tmp, t0, 16);
3568 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3569 tcg_gen_or_i32(rd, rd, tmp);
3570 tcg_gen_shli_i32(tmp, t1, 24);
3571 tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3572 tcg_gen_or_i32(rd, rd, tmp);
3574 tcg_gen_andi_i32(rm, t1, 0xff000000);
3575 tcg_gen_shri_i32(tmp, t0, 8);
3576 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3577 tcg_gen_or_i32(rm, rm, tmp);
3578 tcg_gen_shri_i32(tmp, t1, 8);
3579 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3580 tcg_gen_or_i32(rm, rm, tmp);
3581 tcg_gen_shri_i32(tmp, t0, 16);
3582 tcg_gen_andi_i32(tmp, tmp, 0xff);
3583 tcg_gen_or_i32(t1, rm, tmp);
3584 tcg_gen_mov_i32(t0, rd);
3591 static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3598 tcg_gen_andi_i32(tmp, t0, 0xffff);
3599 tcg_gen_shli_i32(tmp2, t1, 16);
3600 tcg_gen_or_i32(tmp, tmp, tmp2);
3601 tcg_gen_andi_i32(t1, t1, 0xffff0000);
3602 tcg_gen_shri_i32(tmp2, t0, 16);
3603 tcg_gen_or_i32(t1, t1, tmp2);
3604 tcg_gen_mov_i32(t0, tmp);
3610 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3615 for (n = 0; n < q + 1; n += 2) {
3616 t0 = neon_load_reg(reg, n);
3617 t1 = neon_load_reg(reg, n + 1);
3619 case 0: gen_neon_unzip_u8(t0, t1); break;
3620 case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same. */
3621 case 2: /* no-op */; break;
3624 neon_store_scratch(tmp + n, t0);
3625 neon_store_scratch(tmp + n + 1, t1);
3629 static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3636 tcg_gen_shli_i32(rd, t0, 8);
3637 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3638 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3639 tcg_gen_or_i32(rd, rd, tmp);
3641 tcg_gen_shri_i32(t1, t1, 8);
3642 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3643 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3644 tcg_gen_or_i32(t1, t1, tmp);
3645 tcg_gen_mov_i32(t0, rd);
3651 static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3658 tcg_gen_shli_i32(rd, t0, 16);
3659 tcg_gen_andi_i32(tmp, t1, 0xffff);
3660 tcg_gen_or_i32(rd, rd, tmp);
3661 tcg_gen_shri_i32(t1, t1, 16);
3662 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3663 tcg_gen_or_i32(t1, t1, tmp);
3664 tcg_gen_mov_i32(t0, rd);
3675 } neon_ls_element_type[11] = {
3689 /* Translate a NEON load/store element instruction. Return nonzero if the
3690 instruction is invalid. */
3691 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3710 if (!vfp_enabled(env))
3712 VFP_DREG_D(rd, insn);
3713 rn = (insn >> 16) & 0xf;
3715 load = (insn & (1 << 21)) != 0;
3717 if ((insn & (1 << 23)) == 0) {
3718 /* Load store all elements. */
3719 op = (insn >> 8) & 0xf;
3720 size = (insn >> 6) & 3;
3723 nregs = neon_ls_element_type[op].nregs;
3724 interleave = neon_ls_element_type[op].interleave;
3725 spacing = neon_ls_element_type[op].spacing;
3726 if (size == 3 && (interleave | spacing) != 1)
3728 load_reg_var(s, addr, rn);
3729 stride = (1 << size) * interleave;
3730 for (reg = 0; reg < nregs; reg++) {
3731 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3732 load_reg_var(s, addr, rn);
3733 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3734 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3735 load_reg_var(s, addr, rn);
3736 tcg_gen_addi_i32(addr, addr, 1 << size);
3740 tmp64 = gen_ld64(addr, IS_USER(s));
3741 neon_store_reg64(tmp64, rd);
3742 tcg_temp_free_i64(tmp64);
3744 tmp64 = tcg_temp_new_i64();
3745 neon_load_reg64(tmp64, rd);
3746 gen_st64(tmp64, addr, IS_USER(s));
3748 tcg_gen_addi_i32(addr, addr, stride);
3750 for (pass = 0; pass < 2; pass++) {
3753 tmp = gen_ld32(addr, IS_USER(s));
3754 neon_store_reg(rd, pass, tmp);
3756 tmp = neon_load_reg(rd, pass);
3757 gen_st32(tmp, addr, IS_USER(s));
3759 tcg_gen_addi_i32(addr, addr, stride);
3760 } else if (size == 1) {
3762 tmp = gen_ld16u(addr, IS_USER(s));
3763 tcg_gen_addi_i32(addr, addr, stride);
3764 tmp2 = gen_ld16u(addr, IS_USER(s));
3765 tcg_gen_addi_i32(addr, addr, stride);
3766 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3768 neon_store_reg(rd, pass, tmp);
3770 tmp = neon_load_reg(rd, pass);
3772 tcg_gen_shri_i32(tmp2, tmp, 16);
3773 gen_st16(tmp, addr, IS_USER(s));
3774 tcg_gen_addi_i32(addr, addr, stride);
3775 gen_st16(tmp2, addr, IS_USER(s));
3776 tcg_gen_addi_i32(addr, addr, stride);
3778 } else /* size == 0 */ {
3781 for (n = 0; n < 4; n++) {
3782 tmp = gen_ld8u(addr, IS_USER(s));
3783 tcg_gen_addi_i32(addr, addr, stride);
3787 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3791 neon_store_reg(rd, pass, tmp2);
3793 tmp2 = neon_load_reg(rd, pass);
3794 for (n = 0; n < 4; n++) {
3797 tcg_gen_mov_i32(tmp, tmp2);
3799 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3801 gen_st8(tmp, addr, IS_USER(s));
3802 tcg_gen_addi_i32(addr, addr, stride);
3813 size = (insn >> 10) & 3;
3815 /* Load single element to all lanes. */
3818 size = (insn >> 6) & 3;
3819 nregs = ((insn >> 8) & 3) + 1;
3820 stride = (insn & (1 << 5)) ? 2 : 1;
3821 load_reg_var(s, addr, rn);
3822 for (reg = 0; reg < nregs; reg++) {
3825 tmp = gen_ld8u(addr, IS_USER(s));
3826 gen_neon_dup_u8(tmp, 0);
3829 tmp = gen_ld16u(addr, IS_USER(s));
3830 gen_neon_dup_low16(tmp);
3833 tmp = gen_ld32(addr, IS_USER(s));
3837 default: /* Avoid compiler warnings. */
3840 tcg_gen_addi_i32(addr, addr, 1 << size);
3842 tcg_gen_mov_i32(tmp2, tmp);
3843 neon_store_reg(rd, 0, tmp2);
3844 neon_store_reg(rd, 1, tmp);
3847 stride = (1 << size) * nregs;
3849 /* Single element. */
3850 pass = (insn >> 7) & 1;
3853 shift = ((insn >> 5) & 3) * 8;
3857 shift = ((insn >> 6) & 1) * 16;
3858 stride = (insn & (1 << 5)) ? 2 : 1;
3862 stride = (insn & (1 << 6)) ? 2 : 1;
3867 nregs = ((insn >> 8) & 3) + 1;
3868 load_reg_var(s, addr, rn);
3869 for (reg = 0; reg < nregs; reg++) {
3873 tmp = gen_ld8u(addr, IS_USER(s));
3876 tmp = gen_ld16u(addr, IS_USER(s));
3879 tmp = gen_ld32(addr, IS_USER(s));
3881 default: /* Avoid compiler warnings. */
3885 tmp2 = neon_load_reg(rd, pass);
3886 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3889 neon_store_reg(rd, pass, tmp);
3890 } else { /* Store */
3891 tmp = neon_load_reg(rd, pass);
3893 tcg_gen_shri_i32(tmp, tmp, shift);
3896 gen_st8(tmp, addr, IS_USER(s));
3899 gen_st16(tmp, addr, IS_USER(s));
3902 gen_st32(tmp, addr, IS_USER(s));
3907 tcg_gen_addi_i32(addr, addr, 1 << size);
3909 stride = nregs * (1 << size);
3916 base = load_reg(s, rn);
3918 tcg_gen_addi_i32(base, base, stride);
3921 index = load_reg(s, rm);
3922 tcg_gen_add_i32(base, base, index);
3925 store_reg(s, rn, base);
3930 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3931 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3933 tcg_gen_and_i32(t, t, c);
3934 tcg_gen_bic_i32(f, f, c);
3935 tcg_gen_or_i32(dest, t, f);
3938 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3941 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3942 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3943 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3948 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3951 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3952 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3953 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3958 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3961 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3962 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3963 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3968 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3974 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3975 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3980 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3981 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3988 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3989 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3994 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3995 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4002 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4006 case 0: gen_helper_neon_widen_u8(dest, src); break;
4007 case 1: gen_helper_neon_widen_u16(dest, src); break;
4008 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4013 case 0: gen_helper_neon_widen_s8(dest, src); break;
4014 case 1: gen_helper_neon_widen_s16(dest, src); break;
4015 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4022 static inline void gen_neon_addl(int size)
4025 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4026 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4027 case 2: tcg_gen_add_i64(CPU_V001); break;
4032 static inline void gen_neon_subl(int size)
4035 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4036 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4037 case 2: tcg_gen_sub_i64(CPU_V001); break;
4042 static inline void gen_neon_negl(TCGv_i64 var, int size)
4045 case 0: gen_helper_neon_negl_u16(var, var); break;
4046 case 1: gen_helper_neon_negl_u32(var, var); break;
4047 case 2: gen_helper_neon_negl_u64(var, var); break;
4052 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4055 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4056 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4061 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4065 switch ((size << 1) | u) {
4066 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4067 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4068 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4069 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4071 tmp = gen_muls_i64_i32(a, b);
4072 tcg_gen_mov_i64(dest, tmp);
4075 tmp = gen_mulu_i64_i32(a, b);
4076 tcg_gen_mov_i64(dest, tmp);
4082 /* Translate a NEON data processing instruction. Return nonzero if the
4083 instruction is invalid.
4084 We process data in a mixture of 32-bit and 64-bit chunks.
4085 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4087 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4100 TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4103 if (!vfp_enabled(env))
4105 q = (insn & (1 << 6)) != 0;
4106 u = (insn >> 24) & 1;
4107 VFP_DREG_D(rd, insn);
4108 VFP_DREG_N(rn, insn);
4109 VFP_DREG_M(rm, insn);
4110 size = (insn >> 20) & 3;
4111 if ((insn & (1 << 23)) == 0) {
4112 /* Three register same length. */
4113 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4114 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4115 || op == 10 || op == 11 || op == 16)) {
4116 /* 64-bit element instructions. */
4117 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4118 neon_load_reg64(cpu_V0, rn + pass);
4119 neon_load_reg64(cpu_V1, rm + pass);
4123 gen_helper_neon_add_saturate_u64(CPU_V001);
4125 gen_helper_neon_add_saturate_s64(CPU_V001);
4130 gen_helper_neon_sub_saturate_u64(CPU_V001);
4132 gen_helper_neon_sub_saturate_s64(CPU_V001);
4137 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4139 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4144 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4147 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4151 case 10: /* VRSHL */
4153 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4155 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4158 case 11: /* VQRSHL */
4160 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4163 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4169 tcg_gen_sub_i64(CPU_V001);
4171 tcg_gen_add_i64(CPU_V001);
4177 neon_store_reg64(cpu_V0, rd + pass);
4184 case 10: /* VRSHL */
4185 case 11: /* VQRSHL */
4188 /* Shift instruction operands are reversed. */
4195 case 20: /* VPMAX */
4196 case 21: /* VPMIN */
4197 case 23: /* VPADD */
4200 case 26: /* VPADD (float) */
4201 pairwise = (u && size < 2);
4203 case 30: /* VPMIN/VPMAX (float) */
4211 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4220 tmp = neon_load_reg(rn, n);
4221 tmp2 = neon_load_reg(rn, n + 1);
4223 tmp = neon_load_reg(rm, n);
4224 tmp2 = neon_load_reg(rm, n + 1);
4228 tmp = neon_load_reg(rn, pass);
4229 tmp2 = neon_load_reg(rm, pass);
4233 GEN_NEON_INTEGER_OP(hadd);
4236 GEN_NEON_INTEGER_OP_ENV(qadd);
4238 case 2: /* VRHADD */
4239 GEN_NEON_INTEGER_OP(rhadd);
4241 case 3: /* Logic ops. */
4242 switch ((u << 2) | size) {
4244 tcg_gen_and_i32(tmp, tmp, tmp2);
4247 tcg_gen_bic_i32(tmp, tmp, tmp2);
4250 tcg_gen_or_i32(tmp, tmp, tmp2);
4253 tcg_gen_not_i32(tmp2, tmp2);
4254 tcg_gen_or_i32(tmp, tmp, tmp2);
4257 tcg_gen_xor_i32(tmp, tmp, tmp2);
4260 tmp3 = neon_load_reg(rd, pass);
4261 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4265 tmp3 = neon_load_reg(rd, pass);
4266 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4270 tmp3 = neon_load_reg(rd, pass);
4271 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4277 GEN_NEON_INTEGER_OP(hsub);
4280 GEN_NEON_INTEGER_OP_ENV(qsub);
4283 GEN_NEON_INTEGER_OP(cgt);
4286 GEN_NEON_INTEGER_OP(cge);
4289 GEN_NEON_INTEGER_OP(shl);
4292 GEN_NEON_INTEGER_OP_ENV(qshl);
4294 case 10: /* VRSHL */
4295 GEN_NEON_INTEGER_OP(rshl);
4297 case 11: /* VQRSHL */
4298 GEN_NEON_INTEGER_OP_ENV(qrshl);
4301 GEN_NEON_INTEGER_OP(max);
4304 GEN_NEON_INTEGER_OP(min);
4307 GEN_NEON_INTEGER_OP(abd);
4310 GEN_NEON_INTEGER_OP(abd);
4312 tmp2 = neon_load_reg(rd, pass);
4313 gen_neon_add(size, tmp, tmp2);
4316 if (!u) { /* VADD */
4317 if (gen_neon_add(size, tmp, tmp2))
4321 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4322 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4323 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4329 if (!u) { /* VTST */
4331 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4332 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4333 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4338 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4339 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4340 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4345 case 18: /* Multiply. */
4347 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4348 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4349 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4353 tmp2 = neon_load_reg(rd, pass);
4355 gen_neon_rsb(size, tmp, tmp2);
4357 gen_neon_add(size, tmp, tmp2);
4361 if (u) { /* polynomial */
4362 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4363 } else { /* Integer */
4365 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4366 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4367 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4372 case 20: /* VPMAX */
4373 GEN_NEON_INTEGER_OP(pmax);
4375 case 21: /* VPMIN */
4376 GEN_NEON_INTEGER_OP(pmin);
4378 case 22: /* Hultiply high. */
4379 if (!u) { /* VQDMULH */
4381 case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4382 case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4385 } else { /* VQRDHMUL */
4387 case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4388 case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4393 case 23: /* VPADD */
4397 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4398 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4399 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4403 case 26: /* Floating point arithnetic. */
4404 switch ((u << 2) | size) {
4406 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4409 gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4412 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4415 gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4421 case 27: /* Float multiply. */
4422 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4425 tmp2 = neon_load_reg(rd, pass);
4427 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4429 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4433 case 28: /* Float compare. */
4435 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4438 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4440 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4443 case 29: /* Float compare absolute. */
4447 gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4449 gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4451 case 30: /* Float min/max. */
4453 gen_helper_neon_max_f32(tmp, tmp, tmp2);
4455 gen_helper_neon_min_f32(tmp, tmp, tmp2);
4459 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4461 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4468 /* Save the result. For elementwise operations we can put it
4469 straight into the destination register. For pairwise operations
4470 we have to be careful to avoid clobbering the source operands. */
4471 if (pairwise && rd == rm) {
4472 neon_store_scratch(pass, tmp);
4474 neon_store_reg(rd, pass, tmp);
4478 if (pairwise && rd == rm) {
4479 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4480 tmp = neon_load_scratch(pass);
4481 neon_store_reg(rd, pass, tmp);
4484 /* End of 3 register same size operations. */
4485 } else if (insn & (1 << 4)) {
4486 if ((insn & 0x00380080) != 0) {
4487 /* Two registers and shift. */
4488 op = (insn >> 8) & 0xf;
4489 if (insn & (1 << 7)) {
4494 while ((insn & (1 << (size + 19))) == 0)
4497 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4498 /* To avoid excessive dumplication of ops we implement shift
4499 by immediate using the variable shift operations. */
4501 /* Shift by immediate:
4502 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4503 /* Right shifts are encoded as N - shift, where N is the
4504 element size in bits. */
4506 shift = shift - (1 << (size + 3));
4514 imm = (uint8_t) shift;
4519 imm = (uint16_t) shift;
4530 for (pass = 0; pass < count; pass++) {
4532 neon_load_reg64(cpu_V0, rm + pass);
4533 tcg_gen_movi_i64(cpu_V1, imm);
4538 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4540 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4545 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4547 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4552 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4554 case 5: /* VSHL, VSLI */
4555 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4559 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4561 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4563 case 7: /* VQSHLU */
4564 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4567 if (op == 1 || op == 3) {
4569 neon_load_reg64(cpu_V0, rd + pass);
4570 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4571 } else if (op == 4 || (op == 5 && u)) {
4573 cpu_abort(env, "VS[LR]I.64 not implemented");
4575 neon_store_reg64(cpu_V0, rd + pass);
4576 } else { /* size < 3 */
4577 /* Operands in T0 and T1. */
4578 tmp = neon_load_reg(rm, pass);
4580 tcg_gen_movi_i32(tmp2, imm);
4584 GEN_NEON_INTEGER_OP(shl);
4588 GEN_NEON_INTEGER_OP(rshl);
4593 GEN_NEON_INTEGER_OP(shl);
4595 case 5: /* VSHL, VSLI */
4597 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4598 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4599 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4604 GEN_NEON_INTEGER_OP_ENV(qshl);
4606 case 7: /* VQSHLU */
4608 case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4609 case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4610 case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4617 if (op == 1 || op == 3) {
4619 tmp2 = neon_load_reg(rd, pass);
4620 gen_neon_add(size, tmp2, tmp);
4622 } else if (op == 4 || (op == 5 && u)) {
4627 mask = 0xff >> -shift;
4629 mask = (uint8_t)(0xff << shift);
4635 mask = 0xffff >> -shift;
4637 mask = (uint16_t)(0xffff << shift);
4641 if (shift < -31 || shift > 31) {
4645 mask = 0xffffffffu >> -shift;
4647 mask = 0xffffffffu << shift;
4653 tmp2 = neon_load_reg(rd, pass);
4654 tcg_gen_andi_i32(tmp, tmp, mask);
4655 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4656 tcg_gen_or_i32(tmp, tmp, tmp2);
4659 neon_store_reg(rd, pass, tmp);
4662 } else if (op < 10) {
4663 /* Shift by immediate and narrow:
4664 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4665 shift = shift - (1 << (size + 3));
4669 imm = (uint16_t)shift;
4671 tmp2 = tcg_const_i32(imm);
4672 TCGV_UNUSED_I64(tmp64);
4675 imm = (uint32_t)shift;
4676 tmp2 = tcg_const_i32(imm);
4677 TCGV_UNUSED_I64(tmp64);
4680 tmp64 = tcg_const_i64(shift);
4687 for (pass = 0; pass < 2; pass++) {
4689 neon_load_reg64(cpu_V0, rm + pass);
4692 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4694 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4697 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4699 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4702 tmp = neon_load_reg(rm + pass, 0);
4703 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4704 tmp3 = neon_load_reg(rm + pass, 1);
4705 gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4706 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4711 if (op == 8 && !u) {
4712 gen_neon_narrow(size - 1, tmp, cpu_V0);
4715 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4717 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4719 neon_store_reg(rd, pass, tmp);
4722 tcg_temp_free_i64(tmp64);
4726 } else if (op == 10) {
4730 tmp = neon_load_reg(rm, 0);
4731 tmp2 = neon_load_reg(rm, 1);
4732 for (pass = 0; pass < 2; pass++) {
4736 gen_neon_widen(cpu_V0, tmp, size, u);
4739 /* The shift is less than the width of the source
4740 type, so we can just shift the whole register. */
4741 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4742 if (size < 2 || !u) {
4745 imm = (0xffu >> (8 - shift));
4748 imm = 0xffff >> (16 - shift);
4750 imm64 = imm | (((uint64_t)imm) << 32);
4751 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4754 neon_store_reg64(cpu_V0, rd + pass);
4756 } else if (op == 15 || op == 16) {
4757 /* VCVT fixed-point. */
4758 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4759 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4762 gen_vfp_ulto(0, shift);
4764 gen_vfp_slto(0, shift);
4767 gen_vfp_toul(0, shift);
4769 gen_vfp_tosl(0, shift);
4771 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4776 } else { /* (insn & 0x00380080) == 0 */
4779 op = (insn >> 8) & 0xf;
4780 /* One register and immediate. */
4781 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4782 invert = (insn & (1 << 5)) != 0;
4800 imm = (imm << 8) | (imm << 24);
4803 imm = (imm < 8) | 0xff;
4806 imm = (imm << 16) | 0xffff;
4809 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4814 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4815 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4821 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4822 if (op & 1 && op < 12) {
4823 tmp = neon_load_reg(rd, pass);
4825 /* The immediate value has already been inverted, so
4827 tcg_gen_andi_i32(tmp, tmp, imm);
4829 tcg_gen_ori_i32(tmp, tmp, imm);
4834 if (op == 14 && invert) {
4837 for (n = 0; n < 4; n++) {
4838 if (imm & (1 << (n + (pass & 1) * 4)))
4839 val |= 0xff << (n * 8);
4841 tcg_gen_movi_i32(tmp, val);
4843 tcg_gen_movi_i32(tmp, imm);
4846 neon_store_reg(rd, pass, tmp);
4849 } else { /* (insn & 0x00800010 == 0x00800000) */
4851 op = (insn >> 8) & 0xf;
4852 if ((insn & (1 << 6)) == 0) {
4853 /* Three registers of different lengths. */
4857 /* prewiden, src1_wide, src2_wide */
4858 static const int neon_3reg_wide[16][3] = {
4859 {1, 0, 0}, /* VADDL */
4860 {1, 1, 0}, /* VADDW */
4861 {1, 0, 0}, /* VSUBL */
4862 {1, 1, 0}, /* VSUBW */
4863 {0, 1, 1}, /* VADDHN */
4864 {0, 0, 0}, /* VABAL */
4865 {0, 1, 1}, /* VSUBHN */
4866 {0, 0, 0}, /* VABDL */
4867 {0, 0, 0}, /* VMLAL */
4868 {0, 0, 0}, /* VQDMLAL */
4869 {0, 0, 0}, /* VMLSL */
4870 {0, 0, 0}, /* VQDMLSL */
4871 {0, 0, 0}, /* Integer VMULL */
4872 {0, 0, 0}, /* VQDMULL */
4873 {0, 0, 0} /* Polynomial VMULL */
4876 prewiden = neon_3reg_wide[op][0];
4877 src1_wide = neon_3reg_wide[op][1];
4878 src2_wide = neon_3reg_wide[op][2];
4880 if (size == 0 && (op == 9 || op == 11 || op == 13))
4883 /* Avoid overlapping operands. Wide source operands are
4884 always aligned so will never overlap with wide
4885 destinations in problematic ways. */
4886 if (rd == rm && !src2_wide) {
4887 tmp = neon_load_reg(rm, 1);
4888 neon_store_scratch(2, tmp);
4889 } else if (rd == rn && !src1_wide) {
4890 tmp = neon_load_reg(rn, 1);
4891 neon_store_scratch(2, tmp);
4894 for (pass = 0; pass < 2; pass++) {
4896 neon_load_reg64(cpu_V0, rn + pass);
4899 if (pass == 1 && rd == rn) {
4900 tmp = neon_load_scratch(2);
4902 tmp = neon_load_reg(rn, pass);
4905 gen_neon_widen(cpu_V0, tmp, size, u);
4909 neon_load_reg64(cpu_V1, rm + pass);
4912 if (pass == 1 && rd == rm) {
4913 tmp2 = neon_load_scratch(2);
4915 tmp2 = neon_load_reg(rm, pass);
4918 gen_neon_widen(cpu_V1, tmp2, size, u);
4922 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4923 gen_neon_addl(size);
4925 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4926 gen_neon_subl(size);
4928 case 5: case 7: /* VABAL, VABDL */
4929 switch ((size << 1) | u) {
4931 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4934 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4937 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4940 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4943 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4946 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4953 case 8: case 9: case 10: case 11: case 12: case 13:
4954 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4955 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4959 case 14: /* Polynomial VMULL */
4960 cpu_abort(env, "Polynomial VMULL not implemented");
4962 default: /* 15 is RESERVED. */
4965 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4967 if (op == 10 || op == 11) {
4968 gen_neon_negl(cpu_V0, size);
4972 neon_load_reg64(cpu_V1, rd + pass);
4976 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4977 gen_neon_addl(size);
4979 case 9: case 11: /* VQDMLAL, VQDMLSL */
4980 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4981 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4984 case 13: /* VQDMULL */
4985 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4990 neon_store_reg64(cpu_V0, rd + pass);
4991 } else if (op == 4 || op == 6) {
4992 /* Narrowing operation. */
4997 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5000 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5003 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5004 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5011 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5014 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5017 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5018 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5019 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5027 neon_store_reg(rd, 0, tmp3);
5028 neon_store_reg(rd, 1, tmp);
5031 /* Write back the result. */
5032 neon_store_reg64(cpu_V0, rd + pass);
5036 /* Two registers and a scalar. */
5038 case 0: /* Integer VMLA scalar */
5039 case 1: /* Float VMLA scalar */
5040 case 4: /* Integer VMLS scalar */
5041 case 5: /* Floating point VMLS scalar */
5042 case 8: /* Integer VMUL scalar */
5043 case 9: /* Floating point VMUL scalar */
5044 case 12: /* VQDMULH scalar */
5045 case 13: /* VQRDMULH scalar */
5046 tmp = neon_get_scalar(size, rm);
5047 neon_store_scratch(0, tmp);
5048 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5049 tmp = neon_load_scratch(0);
5050 tmp2 = neon_load_reg(rn, pass);
5053 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5055 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5057 } else if (op == 13) {
5059 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5061 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5063 } else if (op & 1) {
5064 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5067 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5068 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5069 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5076 tmp2 = neon_load_reg(rd, pass);
5079 gen_neon_add(size, tmp, tmp2);
5082 gen_helper_neon_add_f32(tmp, tmp, tmp2);
5085 gen_neon_rsb(size, tmp, tmp2);
5088 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5095 neon_store_reg(rd, pass, tmp);
5098 case 2: /* VMLAL sclar */
5099 case 3: /* VQDMLAL scalar */
5100 case 6: /* VMLSL scalar */
5101 case 7: /* VQDMLSL scalar */
5102 case 10: /* VMULL scalar */
5103 case 11: /* VQDMULL scalar */
5104 if (size == 0 && (op == 3 || op == 7 || op == 11))
5107 tmp2 = neon_get_scalar(size, rm);
5108 tmp3 = neon_load_reg(rn, 1);
5110 for (pass = 0; pass < 2; pass++) {
5112 tmp = neon_load_reg(rn, 0);
5116 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5118 if (op == 6 || op == 7) {
5119 gen_neon_negl(cpu_V0, size);
5122 neon_load_reg64(cpu_V1, rd + pass);
5126 gen_neon_addl(size);
5129 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5130 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5136 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5141 neon_store_reg64(cpu_V0, rd + pass);
5147 default: /* 14 and 15 are RESERVED */
5151 } else { /* size == 3 */
5154 imm = (insn >> 8) & 0xf;
5161 neon_load_reg64(cpu_V0, rn);
5163 neon_load_reg64(cpu_V1, rn + 1);
5165 } else if (imm == 8) {
5166 neon_load_reg64(cpu_V0, rn + 1);
5168 neon_load_reg64(cpu_V1, rm);
5171 tmp64 = tcg_temp_new_i64();
5173 neon_load_reg64(cpu_V0, rn);
5174 neon_load_reg64(tmp64, rn + 1);
5176 neon_load_reg64(cpu_V0, rn + 1);
5177 neon_load_reg64(tmp64, rm);
5179 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5180 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5181 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5183 neon_load_reg64(cpu_V1, rm);
5185 neon_load_reg64(cpu_V1, rm + 1);
5188 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5189 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5190 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5191 tcg_temp_free_i64(tmp64);
5194 neon_load_reg64(cpu_V0, rn);
5195 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5196 neon_load_reg64(cpu_V1, rm);
5197 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5198 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5200 neon_store_reg64(cpu_V0, rd);
5202 neon_store_reg64(cpu_V1, rd + 1);
5204 } else if ((insn & (1 << 11)) == 0) {
5205 /* Two register misc. */
5206 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5207 size = (insn >> 18) & 3;
5209 case 0: /* VREV64 */
5212 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5213 tmp = neon_load_reg(rm, pass * 2);
5214 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5216 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5217 case 1: gen_swap_half(tmp); break;
5218 case 2: /* no-op */ break;
5221 neon_store_reg(rd, pass * 2 + 1, tmp);
5223 neon_store_reg(rd, pass * 2, tmp2);
5226 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5227 case 1: gen_swap_half(tmp2); break;
5230 neon_store_reg(rd, pass * 2, tmp2);
5234 case 4: case 5: /* VPADDL */
5235 case 12: case 13: /* VPADAL */
5238 for (pass = 0; pass < q + 1; pass++) {
5239 tmp = neon_load_reg(rm, pass * 2);
5240 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5241 tmp = neon_load_reg(rm, pass * 2 + 1);
5242 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5244 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5245 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5246 case 2: tcg_gen_add_i64(CPU_V001); break;
5251 neon_load_reg64(cpu_V1, rd + pass);
5252 gen_neon_addl(size);
5254 neon_store_reg64(cpu_V0, rd + pass);
5259 for (n = 0; n < (q ? 4 : 2); n += 2) {
5260 tmp = neon_load_reg(rm, n);
5261 tmp2 = neon_load_reg(rd, n + 1);
5262 neon_store_reg(rm, n, tmp2);
5263 neon_store_reg(rd, n + 1, tmp);
5271 Rd A3 A2 A1 A0 B2 B0 A2 A0
5272 Rm B3 B2 B1 B0 B3 B1 A3 A1
5276 gen_neon_unzip(rd, q, 0, size);
5277 gen_neon_unzip(rm, q, 4, size);
5279 static int unzip_order_q[8] =
5280 {0, 2, 4, 6, 1, 3, 5, 7};
5281 for (n = 0; n < 8; n++) {
5282 int reg = (n < 4) ? rd : rm;
5283 tmp = neon_load_scratch(unzip_order_q[n]);
5284 neon_store_reg(reg, n % 4, tmp);
5287 static int unzip_order[4] =
5289 for (n = 0; n < 4; n++) {
5290 int reg = (n < 2) ? rd : rm;
5291 tmp = neon_load_scratch(unzip_order[n]);
5292 neon_store_reg(reg, n % 2, tmp);
5298 Rd A3 A2 A1 A0 B1 A1 B0 A0
5299 Rm B3 B2 B1 B0 B3 A3 B2 A2
5303 count = (q ? 4 : 2);
5304 for (n = 0; n < count; n++) {
5305 tmp = neon_load_reg(rd, n);
5306 tmp2 = neon_load_reg(rd, n);
5308 case 0: gen_neon_zip_u8(tmp, tmp2); break;
5309 case 1: gen_neon_zip_u16(tmp, tmp2); break;
5310 case 2: /* no-op */; break;
5313 neon_store_scratch(n * 2, tmp);
5314 neon_store_scratch(n * 2 + 1, tmp2);
5316 for (n = 0; n < count * 2; n++) {
5317 int reg = (n < count) ? rd : rm;
5318 tmp = neon_load_scratch(n);
5319 neon_store_reg(reg, n % count, tmp);
5322 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5326 for (pass = 0; pass < 2; pass++) {
5327 neon_load_reg64(cpu_V0, rm + pass);
5329 if (op == 36 && q == 0) {
5330 gen_neon_narrow(size, tmp, cpu_V0);
5332 gen_neon_narrow_satu(size, tmp, cpu_V0);
5334 gen_neon_narrow_sats(size, tmp, cpu_V0);
5339 neon_store_reg(rd, 0, tmp2);
5340 neon_store_reg(rd, 1, tmp);
5344 case 38: /* VSHLL */
5347 tmp = neon_load_reg(rm, 0);
5348 tmp2 = neon_load_reg(rm, 1);
5349 for (pass = 0; pass < 2; pass++) {
5352 gen_neon_widen(cpu_V0, tmp, size, 1);
5353 neon_store_reg64(cpu_V0, rd + pass);
5358 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5359 if (op == 30 || op == 31 || op >= 58) {
5360 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5361 neon_reg_offset(rm, pass));
5364 tmp = neon_load_reg(rm, pass);
5367 case 1: /* VREV32 */
5369 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5370 case 1: gen_swap_half(tmp); break;
5374 case 2: /* VREV16 */
5381 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5382 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5383 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5389 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5390 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5391 case 2: gen_helper_clz(tmp, tmp); break;
5398 gen_helper_neon_cnt_u8(tmp, tmp);
5403 tcg_gen_not_i32(tmp, tmp);
5405 case 14: /* VQABS */
5407 case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5408 case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5409 case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5413 case 15: /* VQNEG */
5415 case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5416 case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5417 case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5421 case 16: case 19: /* VCGT #0, VCLE #0 */
5422 tmp2 = tcg_const_i32(0);
5424 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5425 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5426 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5429 tcg_temp_free(tmp2);
5431 tcg_gen_not_i32(tmp, tmp);
5433 case 17: case 20: /* VCGE #0, VCLT #0 */
5434 tmp2 = tcg_const_i32(0);
5436 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5437 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5438 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5441 tcg_temp_free(tmp2);
5443 tcg_gen_not_i32(tmp, tmp);
5445 case 18: /* VCEQ #0 */
5446 tmp2 = tcg_const_i32(0);
5448 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5449 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5450 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5453 tcg_temp_free(tmp2);
5457 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5458 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5459 case 2: tcg_gen_abs_i32(tmp, tmp); break;
5466 tmp2 = tcg_const_i32(0);
5467 gen_neon_rsb(size, tmp, tmp2);
5468 tcg_temp_free(tmp2);
5470 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5471 tmp2 = tcg_const_i32(0);
5472 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5473 tcg_temp_free(tmp2);
5475 tcg_gen_not_i32(tmp, tmp);
5477 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5478 tmp2 = tcg_const_i32(0);
5479 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5480 tcg_temp_free(tmp2);
5482 tcg_gen_not_i32(tmp, tmp);
5484 case 26: /* Float VCEQ #0 */
5485 tmp2 = tcg_const_i32(0);
5486 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5487 tcg_temp_free(tmp2);
5489 case 30: /* Float VABS */
5492 case 31: /* Float VNEG */
5496 tmp2 = neon_load_reg(rd, pass);
5497 neon_store_reg(rm, pass, tmp2);
5500 tmp2 = neon_load_reg(rd, pass);
5502 case 0: gen_neon_trn_u8(tmp, tmp2); break;
5503 case 1: gen_neon_trn_u16(tmp, tmp2); break;
5507 neon_store_reg(rm, pass, tmp2);
5509 case 56: /* Integer VRECPE */
5510 gen_helper_recpe_u32(tmp, tmp, cpu_env);
5512 case 57: /* Integer VRSQRTE */
5513 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5515 case 58: /* Float VRECPE */
5516 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5518 case 59: /* Float VRSQRTE */
5519 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5521 case 60: /* VCVT.F32.S32 */
5524 case 61: /* VCVT.F32.U32 */
5527 case 62: /* VCVT.S32.F32 */
5530 case 63: /* VCVT.U32.F32 */
5534 /* Reserved: 21, 29, 39-56 */
5537 if (op == 30 || op == 31 || op >= 58) {
5538 tcg_gen_st_f32(cpu_F0s, cpu_env,
5539 neon_reg_offset(rd, pass));
5541 neon_store_reg(rd, pass, tmp);
5546 } else if ((insn & (1 << 10)) == 0) {
5548 n = ((insn >> 5) & 0x18) + 8;
5549 if (insn & (1 << 6)) {
5550 tmp = neon_load_reg(rd, 0);
5553 tcg_gen_movi_i32(tmp, 0);
5555 tmp2 = neon_load_reg(rm, 0);
5556 tmp4 = tcg_const_i32(rn);
5557 tmp5 = tcg_const_i32(n);
5558 gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5560 if (insn & (1 << 6)) {
5561 tmp = neon_load_reg(rd, 1);
5564 tcg_gen_movi_i32(tmp, 0);
5566 tmp3 = neon_load_reg(rm, 1);
5567 gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5568 tcg_temp_free_i32(tmp5);
5569 tcg_temp_free_i32(tmp4);
5570 neon_store_reg(rd, 0, tmp2);
5571 neon_store_reg(rd, 1, tmp3);
5573 } else if ((insn & 0x380) == 0) {
5575 if (insn & (1 << 19)) {
5576 tmp = neon_load_reg(rm, 1);
5578 tmp = neon_load_reg(rm, 0);
5580 if (insn & (1 << 16)) {
5581 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5582 } else if (insn & (1 << 17)) {
5583 if ((insn >> 18) & 1)
5584 gen_neon_dup_high16(tmp);
5586 gen_neon_dup_low16(tmp);
5588 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5590 tcg_gen_mov_i32(tmp2, tmp);
5591 neon_store_reg(rd, pass, tmp2);
5602 static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5604 int crn = (insn >> 16) & 0xf;
5605 int crm = insn & 0xf;
5606 int op1 = (insn >> 21) & 7;
5607 int op2 = (insn >> 5) & 7;
5608 int rt = (insn >> 12) & 0xf;
5611 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5612 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5616 tmp = load_cpu_field(teecr);
5617 store_reg(s, rt, tmp);
5620 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5622 if (IS_USER(s) && (env->teecr & 1))
5624 tmp = load_cpu_field(teehbr);
5625 store_reg(s, rt, tmp);
5629 fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5630 op1, crn, crm, op2);
5634 static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5636 int crn = (insn >> 16) & 0xf;
5637 int crm = insn & 0xf;
5638 int op1 = (insn >> 21) & 7;
5639 int op2 = (insn >> 5) & 7;
5640 int rt = (insn >> 12) & 0xf;
5643 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5644 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5648 tmp = load_reg(s, rt);
5649 gen_helper_set_teecr(cpu_env, tmp);
5653 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5655 if (IS_USER(s) && (env->teecr & 1))
5657 tmp = load_reg(s, rt);
5658 store_cpu_field(tmp, teehbr);
5662 fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5663 op1, crn, crm, op2);
5667 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5671 cpnum = (insn >> 8) & 0xf;
5672 if (arm_feature(env, ARM_FEATURE_XSCALE)
5673 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5679 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5680 return disas_iwmmxt_insn(env, s, insn);
5681 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5682 return disas_dsp_insn(env, s, insn);
5687 return disas_vfp_insn (env, s, insn);
5689 /* Coprocessors 7-15 are architecturally reserved by ARM.
5690 Unfortunately Intel decided to ignore this. */
5691 if (arm_feature(env, ARM_FEATURE_XSCALE))
5693 if (insn & (1 << 20))
5694 return disas_cp14_read(env, s, insn);
5696 return disas_cp14_write(env, s, insn);
5698 return disas_cp15_insn (env, s, insn);
5701 /* Unknown coprocessor. See if the board has hooked it. */
5702 return disas_cp_insn (env, s, insn);
5707 /* Store a 64-bit value to a register pair. Clobbers val. */
5708 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5712 tcg_gen_trunc_i64_i32(tmp, val);
5713 store_reg(s, rlow, tmp);
5715 tcg_gen_shri_i64(val, val, 32);
5716 tcg_gen_trunc_i64_i32(tmp, val);
5717 store_reg(s, rhigh, tmp);
5720 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5721 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5726 /* Load value and extend to 64 bits. */
5727 tmp = tcg_temp_new_i64();
5728 tmp2 = load_reg(s, rlow);
5729 tcg_gen_extu_i32_i64(tmp, tmp2);
5731 tcg_gen_add_i64(val, val, tmp);
5732 tcg_temp_free_i64(tmp);
5735 /* load and add a 64-bit value from a register pair. */
5736 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5742 /* Load 64-bit value rd:rn. */
5743 tmpl = load_reg(s, rlow);
5744 tmph = load_reg(s, rhigh);
5745 tmp = tcg_temp_new_i64();
5746 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5749 tcg_gen_add_i64(val, val, tmp);
5750 tcg_temp_free_i64(tmp);
5753 /* Set N and Z flags from a 64-bit value. */
5754 static void gen_logicq_cc(TCGv_i64 val)
5756 TCGv tmp = new_tmp();
5757 gen_helper_logicq_cc(tmp, val);
5762 static void disas_arm_insn(CPUState * env, DisasContext *s)
5764 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5771 insn = ldl_code(s->pc);
5774 /* M variants do not implement ARM mode. */
5779 /* Unconditional instructions. */
5780 if (((insn >> 25) & 7) == 1) {
5781 /* NEON Data processing. */
5782 if (!arm_feature(env, ARM_FEATURE_NEON))
5785 if (disas_neon_data_insn(env, s, insn))
5789 if ((insn & 0x0f100000) == 0x04000000) {
5790 /* NEON load/store. */
5791 if (!arm_feature(env, ARM_FEATURE_NEON))
5794 if (disas_neon_ls_insn(env, s, insn))
5798 if ((insn & 0x0d70f000) == 0x0550f000)
5800 else if ((insn & 0x0ffffdff) == 0x01010000) {
5803 if (insn & (1 << 9)) {
5804 /* BE8 mode not implemented. */
5808 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5809 switch ((insn >> 4) & 0xf) {
5812 gen_helper_clrex(cpu_env);
5818 /* We don't emulate caches so these are a no-op. */
5823 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5829 op1 = (insn & 0x1f);
5830 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5831 addr = load_reg(s, 13);
5834 tmp = tcg_const_i32(op1);
5835 gen_helper_get_r13_banked(addr, cpu_env, tmp);
5836 tcg_temp_free_i32(tmp);
5838 i = (insn >> 23) & 3;
5840 case 0: offset = -4; break; /* DA */
5841 case 1: offset = 0; break; /* IA */
5842 case 2: offset = -8; break; /* DB */
5843 case 3: offset = 4; break; /* IB */
5847 tcg_gen_addi_i32(addr, addr, offset);
5848 tmp = load_reg(s, 14);
5849 gen_st32(tmp, addr, 0);
5850 tmp = load_cpu_field(spsr);
5851 tcg_gen_addi_i32(addr, addr, 4);
5852 gen_st32(tmp, addr, 0);
5853 if (insn & (1 << 21)) {
5854 /* Base writeback. */
5856 case 0: offset = -8; break;
5857 case 1: offset = 4; break;
5858 case 2: offset = -4; break;
5859 case 3: offset = 0; break;
5863 tcg_gen_addi_i32(addr, addr, offset);
5864 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5865 store_reg(s, 13, addr);
5867 tmp = tcg_const_i32(op1);
5868 gen_helper_set_r13_banked(cpu_env, tmp, addr);
5869 tcg_temp_free_i32(tmp);
5875 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5881 rn = (insn >> 16) & 0xf;
5882 addr = load_reg(s, rn);
5883 i = (insn >> 23) & 3;
5885 case 0: offset = -4; break; /* DA */
5886 case 1: offset = 0; break; /* IA */
5887 case 2: offset = -8; break; /* DB */
5888 case 3: offset = 4; break; /* IB */
5892 tcg_gen_addi_i32(addr, addr, offset);
5893 /* Load PC into tmp and CPSR into tmp2. */
5894 tmp = gen_ld32(addr, 0);
5895 tcg_gen_addi_i32(addr, addr, 4);
5896 tmp2 = gen_ld32(addr, 0);
5897 if (insn & (1 << 21)) {
5898 /* Base writeback. */
5900 case 0: offset = -8; break;
5901 case 1: offset = 4; break;
5902 case 2: offset = -4; break;
5903 case 3: offset = 0; break;
5907 tcg_gen_addi_i32(addr, addr, offset);
5908 store_reg(s, rn, addr);
5912 gen_rfe(s, tmp, tmp2);
5914 } else if ((insn & 0x0e000000) == 0x0a000000) {
5915 /* branch link and change to thumb (blx <offset>) */
5918 val = (uint32_t)s->pc;
5920 tcg_gen_movi_i32(tmp, val);
5921 store_reg(s, 14, tmp);
5922 /* Sign-extend the 24-bit offset */
5923 offset = (((int32_t)insn) << 8) >> 8;
5924 /* offset * 4 + bit24 * 2 + (thumb bit) */
5925 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5926 /* pipeline offset */
5930 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5931 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5932 /* iWMMXt register transfer. */
5933 if (env->cp15.c15_cpar & (1 << 1))
5934 if (!disas_iwmmxt_insn(env, s, insn))
5937 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5938 /* Coprocessor double register transfer. */
5939 } else if ((insn & 0x0f000010) == 0x0e000010) {
5940 /* Additional coprocessor register transfer. */
5941 } else if ((insn & 0x0ff10020) == 0x01000000) {
5944 /* cps (privileged) */
5948 if (insn & (1 << 19)) {
5949 if (insn & (1 << 8))
5951 if (insn & (1 << 7))
5953 if (insn & (1 << 6))
5955 if (insn & (1 << 18))
5958 if (insn & (1 << 17)) {
5960 val |= (insn & 0x1f);
5963 gen_set_psr_im(s, mask, 0, val);
5970 /* if not always execute, we generate a conditional jump to
5972 s->condlabel = gen_new_label();
5973 gen_test_cc(cond ^ 1, s->condlabel);
5976 if ((insn & 0x0f900000) == 0x03000000) {
5977 if ((insn & (1 << 21)) == 0) {
5979 rd = (insn >> 12) & 0xf;
5980 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5981 if ((insn & (1 << 22)) == 0) {
5984 tcg_gen_movi_i32(tmp, val);
5987 tmp = load_reg(s, rd);
5988 tcg_gen_ext16u_i32(tmp, tmp);
5989 tcg_gen_ori_i32(tmp, tmp, val << 16);
5991 store_reg(s, rd, tmp);
5993 if (((insn >> 12) & 0xf) != 0xf)
5995 if (((insn >> 16) & 0xf) == 0) {
5996 gen_nop_hint(s, insn & 0xff);
5998 /* CPSR = immediate */
6000 shift = ((insn >> 8) & 0xf) * 2;
6002 val = (val >> shift) | (val << (32 - shift));
6003 i = ((insn & (1 << 22)) != 0);
6004 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6008 } else if ((insn & 0x0f900000) == 0x01000000
6009 && (insn & 0x00000090) != 0x00000090) {
6010 /* miscellaneous instructions */
6011 op1 = (insn >> 21) & 3;
6012 sh = (insn >> 4) & 0xf;
6015 case 0x0: /* move program status register */
6018 tmp = load_reg(s, rm);
6019 i = ((op1 & 2) != 0);
6020 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6024 rd = (insn >> 12) & 0xf;
6028 tmp = load_cpu_field(spsr);
6031 gen_helper_cpsr_read(tmp);
6033 store_reg(s, rd, tmp);
6038 /* branch/exchange thumb (bx). */
6039 tmp = load_reg(s, rm);
6041 } else if (op1 == 3) {
6043 rd = (insn >> 12) & 0xf;
6044 tmp = load_reg(s, rm);
6045 gen_helper_clz(tmp, tmp);
6046 store_reg(s, rd, tmp);
6054 /* Trivial implementation equivalent to bx. */
6055 tmp = load_reg(s, rm);
6065 /* branch link/exchange thumb (blx) */
6066 tmp = load_reg(s, rm);
6068 tcg_gen_movi_i32(tmp2, s->pc);
6069 store_reg(s, 14, tmp2);
6072 case 0x5: /* saturating add/subtract */
6073 rd = (insn >> 12) & 0xf;
6074 rn = (insn >> 16) & 0xf;
6075 tmp = load_reg(s, rm);
6076 tmp2 = load_reg(s, rn);
6078 gen_helper_double_saturate(tmp2, tmp2);
6080 gen_helper_sub_saturate(tmp, tmp, tmp2);
6082 gen_helper_add_saturate(tmp, tmp, tmp2);
6084 store_reg(s, rd, tmp);
6087 gen_set_condexec(s);
6088 gen_set_pc_im(s->pc - 4);
6089 gen_exception(EXCP_BKPT);
6090 s->is_jmp = DISAS_JUMP;
6092 case 0x8: /* signed multiply */
6096 rs = (insn >> 8) & 0xf;
6097 rn = (insn >> 12) & 0xf;
6098 rd = (insn >> 16) & 0xf;
6100 /* (32 * 16) >> 16 */
6101 tmp = load_reg(s, rm);
6102 tmp2 = load_reg(s, rs);
6104 tcg_gen_sari_i32(tmp2, tmp2, 16);
6107 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6108 tcg_gen_shri_i64(tmp64, tmp64, 16);
6110 tcg_gen_trunc_i64_i32(tmp, tmp64);
6111 tcg_temp_free_i64(tmp64);
6112 if ((sh & 2) == 0) {
6113 tmp2 = load_reg(s, rn);
6114 gen_helper_add_setq(tmp, tmp, tmp2);
6117 store_reg(s, rd, tmp);
6120 tmp = load_reg(s, rm);
6121 tmp2 = load_reg(s, rs);
6122 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6125 tmp64 = tcg_temp_new_i64();
6126 tcg_gen_ext_i32_i64(tmp64, tmp);
6128 gen_addq(s, tmp64, rn, rd);
6129 gen_storeq_reg(s, rn, rd, tmp64);
6130 tcg_temp_free_i64(tmp64);
6133 tmp2 = load_reg(s, rn);
6134 gen_helper_add_setq(tmp, tmp, tmp2);
6137 store_reg(s, rd, tmp);
6144 } else if (((insn & 0x0e000000) == 0 &&
6145 (insn & 0x00000090) != 0x90) ||
6146 ((insn & 0x0e000000) == (1 << 25))) {
6147 int set_cc, logic_cc, shiftop;
6149 op1 = (insn >> 21) & 0xf;
6150 set_cc = (insn >> 20) & 1;
6151 logic_cc = table_logic_cc[op1] & set_cc;
6153 /* data processing instruction */
6154 if (insn & (1 << 25)) {
6155 /* immediate operand */
6157 shift = ((insn >> 8) & 0xf) * 2;
6159 val = (val >> shift) | (val << (32 - shift));
6162 tcg_gen_movi_i32(tmp2, val);
6163 if (logic_cc && shift) {
6164 gen_set_CF_bit31(tmp2);
6169 tmp2 = load_reg(s, rm);
6170 shiftop = (insn >> 5) & 3;
6171 if (!(insn & (1 << 4))) {
6172 shift = (insn >> 7) & 0x1f;
6173 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6175 rs = (insn >> 8) & 0xf;
6176 tmp = load_reg(s, rs);
6177 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6180 if (op1 != 0x0f && op1 != 0x0d) {
6181 rn = (insn >> 16) & 0xf;
6182 tmp = load_reg(s, rn);
6186 rd = (insn >> 12) & 0xf;
6189 tcg_gen_and_i32(tmp, tmp, tmp2);
6193 store_reg_bx(env, s, rd, tmp);
6196 tcg_gen_xor_i32(tmp, tmp, tmp2);
6200 store_reg_bx(env, s, rd, tmp);
6203 if (set_cc && rd == 15) {
6204 /* SUBS r15, ... is used for exception return. */
6208 gen_helper_sub_cc(tmp, tmp, tmp2);
6209 gen_exception_return(s, tmp);
6212 gen_helper_sub_cc(tmp, tmp, tmp2);
6214 tcg_gen_sub_i32(tmp, tmp, tmp2);
6216 store_reg_bx(env, s, rd, tmp);
6221 gen_helper_sub_cc(tmp, tmp2, tmp);
6223 tcg_gen_sub_i32(tmp, tmp2, tmp);
6225 store_reg_bx(env, s, rd, tmp);
6229 gen_helper_add_cc(tmp, tmp, tmp2);
6231 tcg_gen_add_i32(tmp, tmp, tmp2);
6233 store_reg_bx(env, s, rd, tmp);
6237 gen_helper_adc_cc(tmp, tmp, tmp2);
6239 gen_add_carry(tmp, tmp, tmp2);
6241 store_reg_bx(env, s, rd, tmp);
6245 gen_helper_sbc_cc(tmp, tmp, tmp2);
6247 gen_sub_carry(tmp, tmp, tmp2);
6249 store_reg_bx(env, s, rd, tmp);
6253 gen_helper_sbc_cc(tmp, tmp2, tmp);
6255 gen_sub_carry(tmp, tmp2, tmp);
6257 store_reg_bx(env, s, rd, tmp);
6261 tcg_gen_and_i32(tmp, tmp, tmp2);
6268 tcg_gen_xor_i32(tmp, tmp, tmp2);
6275 gen_helper_sub_cc(tmp, tmp, tmp2);
6281 gen_helper_add_cc(tmp, tmp, tmp2);
6286 tcg_gen_or_i32(tmp, tmp, tmp2);
6290 store_reg_bx(env, s, rd, tmp);
6293 if (logic_cc && rd == 15) {
6294 /* MOVS r15, ... is used for exception return. */
6298 gen_exception_return(s, tmp2);
6303 store_reg_bx(env, s, rd, tmp2);
6307 tcg_gen_bic_i32(tmp, tmp, tmp2);
6311 store_reg_bx(env, s, rd, tmp);
6315 tcg_gen_not_i32(tmp2, tmp2);
6319 store_reg_bx(env, s, rd, tmp2);
6322 if (op1 != 0x0f && op1 != 0x0d) {
6326 /* other instructions */
6327 op1 = (insn >> 24) & 0xf;
6331 /* multiplies, extra load/stores */
6332 sh = (insn >> 5) & 3;
6335 rd = (insn >> 16) & 0xf;
6336 rn = (insn >> 12) & 0xf;
6337 rs = (insn >> 8) & 0xf;
6339 op1 = (insn >> 20) & 0xf;
6341 case 0: case 1: case 2: case 3: case 6:
6343 tmp = load_reg(s, rs);
6344 tmp2 = load_reg(s, rm);
6345 tcg_gen_mul_i32(tmp, tmp, tmp2);
6347 if (insn & (1 << 22)) {
6348 /* Subtract (mls) */
6350 tmp2 = load_reg(s, rn);
6351 tcg_gen_sub_i32(tmp, tmp2, tmp);
6353 } else if (insn & (1 << 21)) {
6355 tmp2 = load_reg(s, rn);
6356 tcg_gen_add_i32(tmp, tmp, tmp2);
6359 if (insn & (1 << 20))
6361 store_reg(s, rd, tmp);
6365 tmp = load_reg(s, rs);
6366 tmp2 = load_reg(s, rm);
6367 if (insn & (1 << 22))
6368 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6370 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6371 if (insn & (1 << 21)) /* mult accumulate */
6372 gen_addq(s, tmp64, rn, rd);
6373 if (!(insn & (1 << 23))) { /* double accumulate */
6375 gen_addq_lo(s, tmp64, rn);
6376 gen_addq_lo(s, tmp64, rd);
6378 if (insn & (1 << 20))
6379 gen_logicq_cc(tmp64);
6380 gen_storeq_reg(s, rn, rd, tmp64);
6381 tcg_temp_free_i64(tmp64);
6385 rn = (insn >> 16) & 0xf;
6386 rd = (insn >> 12) & 0xf;
6387 if (insn & (1 << 23)) {
6388 /* load/store exclusive */
6389 op1 = (insn >> 21) & 0x3;
6394 addr = tcg_temp_local_new_i32();
6395 load_reg_var(s, addr, rn);
6396 if (insn & (1 << 20)) {
6397 gen_helper_mark_exclusive(cpu_env, addr);
6400 tmp = gen_ld32(addr, IS_USER(s));
6402 case 1: /* ldrexd */
6403 tmp = gen_ld32(addr, IS_USER(s));
6404 store_reg(s, rd, tmp);
6405 tcg_gen_addi_i32(addr, addr, 4);
6406 tmp = gen_ld32(addr, IS_USER(s));
6409 case 2: /* ldrexb */
6410 tmp = gen_ld8u(addr, IS_USER(s));
6412 case 3: /* ldrexh */
6413 tmp = gen_ld16u(addr, IS_USER(s));
6418 store_reg(s, rd, tmp);
6420 int label = gen_new_label();
6422 tmp2 = tcg_temp_local_new_i32();
6423 gen_helper_test_exclusive(tmp2, cpu_env, addr);
6424 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
6425 tmp = load_reg(s,rm);
6428 gen_st32(tmp, addr, IS_USER(s));
6430 case 1: /* strexd */
6431 gen_st32(tmp, addr, IS_USER(s));
6432 tcg_gen_addi_i32(addr, addr, 4);
6433 tmp = load_reg(s, rm + 1);
6434 gen_st32(tmp, addr, IS_USER(s));
6436 case 2: /* strexb */
6437 gen_st8(tmp, addr, IS_USER(s));
6439 case 3: /* strexh */
6440 gen_st16(tmp, addr, IS_USER(s));
6445 gen_set_label(label);
6446 tcg_gen_mov_i32(cpu_R[rd], tmp2);
6447 tcg_temp_free(tmp2);
6449 tcg_temp_free(addr);
6451 /* SWP instruction */
6454 /* ??? This is not really atomic. However we know
6455 we never have multiple CPUs running in parallel,
6456 so it is good enough. */
6457 addr = load_reg(s, rn);
6458 tmp = load_reg(s, rm);
6459 if (insn & (1 << 22)) {
6460 tmp2 = gen_ld8u(addr, IS_USER(s));
6461 gen_st8(tmp, addr, IS_USER(s));
6463 tmp2 = gen_ld32(addr, IS_USER(s));
6464 gen_st32(tmp, addr, IS_USER(s));
6467 store_reg(s, rd, tmp2);
6473 /* Misc load/store */
6474 rn = (insn >> 16) & 0xf;
6475 rd = (insn >> 12) & 0xf;
6476 addr = load_reg(s, rn);
6477 if (insn & (1 << 24))
6478 gen_add_datah_offset(s, insn, 0, addr);
6480 if (insn & (1 << 20)) {
6484 tmp = gen_ld16u(addr, IS_USER(s));
6487 tmp = gen_ld8s(addr, IS_USER(s));
6491 tmp = gen_ld16s(addr, IS_USER(s));
6495 } else if (sh & 2) {
6499 tmp = load_reg(s, rd);
6500 gen_st32(tmp, addr, IS_USER(s));
6501 tcg_gen_addi_i32(addr, addr, 4);
6502 tmp = load_reg(s, rd + 1);
6503 gen_st32(tmp, addr, IS_USER(s));
6507 tmp = gen_ld32(addr, IS_USER(s));
6508 store_reg(s, rd, tmp);
6509 tcg_gen_addi_i32(addr, addr, 4);
6510 tmp = gen_ld32(addr, IS_USER(s));
6514 address_offset = -4;
6517 tmp = load_reg(s, rd);
6518 gen_st16(tmp, addr, IS_USER(s));
6521 /* Perform base writeback before the loaded value to
6522 ensure correct behavior with overlapping index registers.
6523 ldrd with base writeback is is undefined if the
6524 destination and index registers overlap. */
6525 if (!(insn & (1 << 24))) {
6526 gen_add_datah_offset(s, insn, address_offset, addr);
6527 store_reg(s, rn, addr);
6528 } else if (insn & (1 << 21)) {
6530 tcg_gen_addi_i32(addr, addr, address_offset);
6531 store_reg(s, rn, addr);
6536 /* Complete the load. */
6537 store_reg(s, rd, tmp);
6546 if (insn & (1 << 4)) {
6548 /* Armv6 Media instructions. */
6550 rn = (insn >> 16) & 0xf;
6551 rd = (insn >> 12) & 0xf;
6552 rs = (insn >> 8) & 0xf;
6553 switch ((insn >> 23) & 3) {
6554 case 0: /* Parallel add/subtract. */
6555 op1 = (insn >> 20) & 7;
6556 tmp = load_reg(s, rn);
6557 tmp2 = load_reg(s, rm);
6558 sh = (insn >> 5) & 7;
6559 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6561 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6563 store_reg(s, rd, tmp);
6566 if ((insn & 0x00700020) == 0) {
6567 /* Halfword pack. */
6568 tmp = load_reg(s, rn);
6569 tmp2 = load_reg(s, rm);
6570 shift = (insn >> 7) & 0x1f;
6571 if (insn & (1 << 6)) {
6575 tcg_gen_sari_i32(tmp2, tmp2, shift);
6576 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6577 tcg_gen_ext16u_i32(tmp2, tmp2);
6581 tcg_gen_shli_i32(tmp2, tmp2, shift);
6582 tcg_gen_ext16u_i32(tmp, tmp);
6583 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6585 tcg_gen_or_i32(tmp, tmp, tmp2);
6587 store_reg(s, rd, tmp);
6588 } else if ((insn & 0x00200020) == 0x00200000) {
6590 tmp = load_reg(s, rm);
6591 shift = (insn >> 7) & 0x1f;
6592 if (insn & (1 << 6)) {
6595 tcg_gen_sari_i32(tmp, tmp, shift);
6597 tcg_gen_shli_i32(tmp, tmp, shift);
6599 sh = (insn >> 16) & 0x1f;
6601 tmp2 = tcg_const_i32(sh);
6602 if (insn & (1 << 22))
6603 gen_helper_usat(tmp, tmp, tmp2);
6605 gen_helper_ssat(tmp, tmp, tmp2);
6606 tcg_temp_free_i32(tmp2);
6608 store_reg(s, rd, tmp);
6609 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6611 tmp = load_reg(s, rm);
6612 sh = (insn >> 16) & 0x1f;
6614 tmp2 = tcg_const_i32(sh);
6615 if (insn & (1 << 22))
6616 gen_helper_usat16(tmp, tmp, tmp2);
6618 gen_helper_ssat16(tmp, tmp, tmp2);
6619 tcg_temp_free_i32(tmp2);
6621 store_reg(s, rd, tmp);
6622 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6624 tmp = load_reg(s, rn);
6625 tmp2 = load_reg(s, rm);
6627 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6628 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6631 store_reg(s, rd, tmp);
6632 } else if ((insn & 0x000003e0) == 0x00000060) {
6633 tmp = load_reg(s, rm);
6634 shift = (insn >> 10) & 3;
6635 /* ??? In many cases it's not neccessary to do a
6636 rotate, a shift is sufficient. */
6638 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6639 op1 = (insn >> 20) & 7;
6641 case 0: gen_sxtb16(tmp); break;
6642 case 2: gen_sxtb(tmp); break;
6643 case 3: gen_sxth(tmp); break;
6644 case 4: gen_uxtb16(tmp); break;
6645 case 6: gen_uxtb(tmp); break;
6646 case 7: gen_uxth(tmp); break;
6647 default: goto illegal_op;
6650 tmp2 = load_reg(s, rn);
6651 if ((op1 & 3) == 0) {
6652 gen_add16(tmp, tmp2);
6654 tcg_gen_add_i32(tmp, tmp, tmp2);
6658 store_reg(s, rd, tmp);
6659 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6661 tmp = load_reg(s, rm);
6662 if (insn & (1 << 22)) {
6663 if (insn & (1 << 7)) {
6667 gen_helper_rbit(tmp, tmp);
6670 if (insn & (1 << 7))
6673 tcg_gen_bswap32_i32(tmp, tmp);
6675 store_reg(s, rd, tmp);
6680 case 2: /* Multiplies (Type 3). */
6681 tmp = load_reg(s, rm);
6682 tmp2 = load_reg(s, rs);
6683 if (insn & (1 << 20)) {
6684 /* Signed multiply most significant [accumulate]. */
6685 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6686 if (insn & (1 << 5))
6687 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6688 tcg_gen_shri_i64(tmp64, tmp64, 32);
6690 tcg_gen_trunc_i64_i32(tmp, tmp64);
6691 tcg_temp_free_i64(tmp64);
6693 tmp2 = load_reg(s, rd);
6694 if (insn & (1 << 6)) {
6695 tcg_gen_sub_i32(tmp, tmp, tmp2);
6697 tcg_gen_add_i32(tmp, tmp, tmp2);
6701 store_reg(s, rn, tmp);
6703 if (insn & (1 << 5))
6704 gen_swap_half(tmp2);
6705 gen_smul_dual(tmp, tmp2);
6706 /* This addition cannot overflow. */
6707 if (insn & (1 << 6)) {
6708 tcg_gen_sub_i32(tmp, tmp, tmp2);
6710 tcg_gen_add_i32(tmp, tmp, tmp2);
6713 if (insn & (1 << 22)) {
6714 /* smlald, smlsld */
6715 tmp64 = tcg_temp_new_i64();
6716 tcg_gen_ext_i32_i64(tmp64, tmp);
6718 gen_addq(s, tmp64, rd, rn);
6719 gen_storeq_reg(s, rd, rn, tmp64);
6720 tcg_temp_free_i64(tmp64);
6722 /* smuad, smusd, smlad, smlsd */
6725 tmp2 = load_reg(s, rd);
6726 gen_helper_add_setq(tmp, tmp, tmp2);
6729 store_reg(s, rn, tmp);
6734 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6736 case 0: /* Unsigned sum of absolute differences. */
6738 tmp = load_reg(s, rm);
6739 tmp2 = load_reg(s, rs);
6740 gen_helper_usad8(tmp, tmp, tmp2);
6743 tmp2 = load_reg(s, rd);
6744 tcg_gen_add_i32(tmp, tmp, tmp2);
6747 store_reg(s, rn, tmp);
6749 case 0x20: case 0x24: case 0x28: case 0x2c:
6750 /* Bitfield insert/clear. */
6752 shift = (insn >> 7) & 0x1f;
6753 i = (insn >> 16) & 0x1f;
6757 tcg_gen_movi_i32(tmp, 0);
6759 tmp = load_reg(s, rm);
6762 tmp2 = load_reg(s, rd);
6763 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6766 store_reg(s, rd, tmp);
6768 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6769 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6771 tmp = load_reg(s, rm);
6772 shift = (insn >> 7) & 0x1f;
6773 i = ((insn >> 16) & 0x1f) + 1;
6778 gen_ubfx(tmp, shift, (1u << i) - 1);
6780 gen_sbfx(tmp, shift, i);
6783 store_reg(s, rd, tmp);
6793 /* Check for undefined extension instructions
6794 * per the ARM Bible IE:
6795 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6797 sh = (0xf << 20) | (0xf << 4);
6798 if (op1 == 0x7 && ((insn & sh) == sh))
6802 /* load/store byte/word */
6803 rn = (insn >> 16) & 0xf;
6804 rd = (insn >> 12) & 0xf;
6805 tmp2 = load_reg(s, rn);
6806 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6807 if (insn & (1 << 24))
6808 gen_add_data_offset(s, insn, tmp2);
6809 if (insn & (1 << 20)) {
6811 if (insn & (1 << 22)) {
6812 tmp = gen_ld8u(tmp2, i);
6814 tmp = gen_ld32(tmp2, i);
6818 tmp = load_reg(s, rd);
6819 if (insn & (1 << 22))
6820 gen_st8(tmp, tmp2, i);
6822 gen_st32(tmp, tmp2, i);
6824 if (!(insn & (1 << 24))) {
6825 gen_add_data_offset(s, insn, tmp2);
6826 store_reg(s, rn, tmp2);
6827 } else if (insn & (1 << 21)) {
6828 store_reg(s, rn, tmp2);
6832 if (insn & (1 << 20)) {
6833 /* Complete the load. */
6837 store_reg(s, rd, tmp);
6843 int j, n, user, loaded_base;
6845 /* load/store multiple words */
6846 /* XXX: store correct base if write back */
6848 if (insn & (1 << 22)) {
6850 goto illegal_op; /* only usable in supervisor mode */
6852 if ((insn & (1 << 15)) == 0)
6855 rn = (insn >> 16) & 0xf;
6856 addr = load_reg(s, rn);
6858 /* compute total size */
6860 TCGV_UNUSED(loaded_var);
6863 if (insn & (1 << i))
6866 /* XXX: test invalid n == 0 case ? */
6867 if (insn & (1 << 23)) {
6868 if (insn & (1 << 24)) {
6870 tcg_gen_addi_i32(addr, addr, 4);
6872 /* post increment */
6875 if (insn & (1 << 24)) {
6877 tcg_gen_addi_i32(addr, addr, -(n * 4));
6879 /* post decrement */
6881 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6886 if (insn & (1 << i)) {
6887 if (insn & (1 << 20)) {
6889 tmp = gen_ld32(addr, IS_USER(s));
6893 tmp2 = tcg_const_i32(i);
6894 gen_helper_set_user_reg(tmp2, tmp);
6895 tcg_temp_free_i32(tmp2);
6897 } else if (i == rn) {
6901 store_reg(s, i, tmp);
6906 /* special case: r15 = PC + 8 */
6907 val = (long)s->pc + 4;
6909 tcg_gen_movi_i32(tmp, val);
6912 tmp2 = tcg_const_i32(i);
6913 gen_helper_get_user_reg(tmp, tmp2);
6914 tcg_temp_free_i32(tmp2);
6916 tmp = load_reg(s, i);
6918 gen_st32(tmp, addr, IS_USER(s));
6921 /* no need to add after the last transfer */
6923 tcg_gen_addi_i32(addr, addr, 4);
6926 if (insn & (1 << 21)) {
6928 if (insn & (1 << 23)) {
6929 if (insn & (1 << 24)) {
6932 /* post increment */
6933 tcg_gen_addi_i32(addr, addr, 4);
6936 if (insn & (1 << 24)) {
6939 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6941 /* post decrement */
6942 tcg_gen_addi_i32(addr, addr, -(n * 4));
6945 store_reg(s, rn, addr);
6950 store_reg(s, rn, loaded_var);
6952 if ((insn & (1 << 22)) && !user) {
6953 /* Restore CPSR from SPSR. */
6954 tmp = load_cpu_field(spsr);
6955 gen_set_cpsr(tmp, 0xffffffff);
6957 s->is_jmp = DISAS_UPDATE;
6966 /* branch (and link) */
6967 val = (int32_t)s->pc;
6968 if (insn & (1 << 24)) {
6970 tcg_gen_movi_i32(tmp, val);
6971 store_reg(s, 14, tmp);
6973 offset = (((int32_t)insn << 8) >> 8);
6974 val += (offset << 2) + 4;
6982 if (disas_coproc_insn(env, s, insn))
6987 gen_set_pc_im(s->pc);
6988 s->is_jmp = DISAS_SWI;
6992 gen_set_condexec(s);
6993 gen_set_pc_im(s->pc - 4);
6994 gen_exception(EXCP_UDEF);
6995 s->is_jmp = DISAS_JUMP;
7001 /* Return true if this is a Thumb-2 logical op. */
7003 thumb2_logic_op(int op)
7008 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7009 then set condition code flags based on the result of the operation.
7010 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7011 to the high bit of T1.
7012 Returns zero if the opcode is valid. */
7015 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7022 tcg_gen_and_i32(t0, t0, t1);
7026 tcg_gen_bic_i32(t0, t0, t1);
7030 tcg_gen_or_i32(t0, t0, t1);
7034 tcg_gen_not_i32(t1, t1);
7035 tcg_gen_or_i32(t0, t0, t1);
7039 tcg_gen_xor_i32(t0, t0, t1);
7044 gen_helper_add_cc(t0, t0, t1);
7046 tcg_gen_add_i32(t0, t0, t1);
7050 gen_helper_adc_cc(t0, t0, t1);
7056 gen_helper_sbc_cc(t0, t0, t1);
7058 gen_sub_carry(t0, t0, t1);
7062 gen_helper_sub_cc(t0, t0, t1);
7064 tcg_gen_sub_i32(t0, t0, t1);
7068 gen_helper_sub_cc(t0, t1, t0);
7070 tcg_gen_sub_i32(t0, t1, t0);
7072 default: /* 5, 6, 7, 9, 12, 15. */
7078 gen_set_CF_bit31(t1);
7083 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7085 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7087 uint32_t insn, imm, shift, offset;
7088 uint32_t rd, rn, rm, rs;
7099 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7100 || arm_feature (env, ARM_FEATURE_M))) {
7101 /* Thumb-1 cores may need to treat bl and blx as a pair of
7102 16-bit instructions to get correct prefetch abort behavior. */
7104 if ((insn & (1 << 12)) == 0) {
7105 /* Second half of blx. */
7106 offset = ((insn & 0x7ff) << 1);
7107 tmp = load_reg(s, 14);
7108 tcg_gen_addi_i32(tmp, tmp, offset);
7109 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7112 tcg_gen_movi_i32(tmp2, s->pc | 1);
7113 store_reg(s, 14, tmp2);
7117 if (insn & (1 << 11)) {
7118 /* Second half of bl. */
7119 offset = ((insn & 0x7ff) << 1) | 1;
7120 tmp = load_reg(s, 14);
7121 tcg_gen_addi_i32(tmp, tmp, offset);
7124 tcg_gen_movi_i32(tmp2, s->pc | 1);
7125 store_reg(s, 14, tmp2);
7129 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7130 /* Instruction spans a page boundary. Implement it as two
7131 16-bit instructions in case the second half causes an
7133 offset = ((int32_t)insn << 21) >> 9;
7134 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7137 /* Fall through to 32-bit decode. */
7140 insn = lduw_code(s->pc);
7142 insn |= (uint32_t)insn_hw1 << 16;
7144 if ((insn & 0xf800e800) != 0xf000e800) {
7148 rn = (insn >> 16) & 0xf;
7149 rs = (insn >> 12) & 0xf;
7150 rd = (insn >> 8) & 0xf;
7152 switch ((insn >> 25) & 0xf) {
7153 case 0: case 1: case 2: case 3:
7154 /* 16-bit instructions. Should never happen. */
7157 if (insn & (1 << 22)) {
7158 /* Other load/store, table branch. */
7159 if (insn & 0x01200000) {
7160 /* Load/store doubleword. */
7163 tcg_gen_movi_i32(addr, s->pc & ~3);
7165 addr = load_reg(s, rn);
7167 offset = (insn & 0xff) * 4;
7168 if ((insn & (1 << 23)) == 0)
7170 if (insn & (1 << 24)) {
7171 tcg_gen_addi_i32(addr, addr, offset);
7174 if (insn & (1 << 20)) {
7176 tmp = gen_ld32(addr, IS_USER(s));
7177 store_reg(s, rs, tmp);
7178 tcg_gen_addi_i32(addr, addr, 4);
7179 tmp = gen_ld32(addr, IS_USER(s));
7180 store_reg(s, rd, tmp);
7183 tmp = load_reg(s, rs);
7184 gen_st32(tmp, addr, IS_USER(s));
7185 tcg_gen_addi_i32(addr, addr, 4);
7186 tmp = load_reg(s, rd);
7187 gen_st32(tmp, addr, IS_USER(s));
7189 if (insn & (1 << 21)) {
7190 /* Base writeback. */
7193 tcg_gen_addi_i32(addr, addr, offset - 4);
7194 store_reg(s, rn, addr);
7198 } else if ((insn & (1 << 23)) == 0) {
7199 /* Load/store exclusive word. */
7200 addr = tcg_temp_local_new();
7201 load_reg_var(s, addr, rn);
7202 if (insn & (1 << 20)) {
7203 gen_helper_mark_exclusive(cpu_env, addr);
7204 tmp = gen_ld32(addr, IS_USER(s));
7205 store_reg(s, rd, tmp);
7207 int label = gen_new_label();
7208 tmp2 = tcg_temp_local_new();
7209 gen_helper_test_exclusive(tmp2, cpu_env, addr);
7210 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7211 tmp = load_reg(s, rs);
7212 gen_st32(tmp, addr, IS_USER(s));
7213 gen_set_label(label);
7214 tcg_gen_mov_i32(cpu_R[rd], tmp2);
7215 tcg_temp_free(tmp2);
7217 tcg_temp_free(addr);
7218 } else if ((insn & (1 << 6)) == 0) {
7222 tcg_gen_movi_i32(addr, s->pc);
7224 addr = load_reg(s, rn);
7226 tmp = load_reg(s, rm);
7227 tcg_gen_add_i32(addr, addr, tmp);
7228 if (insn & (1 << 4)) {
7230 tcg_gen_add_i32(addr, addr, tmp);
7232 tmp = gen_ld16u(addr, IS_USER(s));
7235 tmp = gen_ld8u(addr, IS_USER(s));
7238 tcg_gen_shli_i32(tmp, tmp, 1);
7239 tcg_gen_addi_i32(tmp, tmp, s->pc);
7240 store_reg(s, 15, tmp);
7242 /* Load/store exclusive byte/halfword/doubleword. */
7243 /* ??? These are not really atomic. However we know
7244 we never have multiple CPUs running in parallel,
7245 so it is good enough. */
7246 op = (insn >> 4) & 0x3;
7247 addr = tcg_temp_local_new();
7248 load_reg_var(s, addr, rn);
7249 if (insn & (1 << 20)) {
7250 gen_helper_mark_exclusive(cpu_env, addr);
7253 tmp = gen_ld8u(addr, IS_USER(s));
7256 tmp = gen_ld16u(addr, IS_USER(s));
7259 tmp = gen_ld32(addr, IS_USER(s));
7260 tcg_gen_addi_i32(addr, addr, 4);
7261 tmp2 = gen_ld32(addr, IS_USER(s));
7262 store_reg(s, rd, tmp2);
7267 store_reg(s, rs, tmp);
7269 int label = gen_new_label();
7270 tmp2 = tcg_temp_local_new();
7271 gen_helper_test_exclusive(tmp2, cpu_env, addr);
7272 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7273 tmp = load_reg(s, rs);
7276 gen_st8(tmp, addr, IS_USER(s));
7279 gen_st16(tmp, addr, IS_USER(s));
7282 gen_st32(tmp, addr, IS_USER(s));
7283 tcg_gen_addi_i32(addr, addr, 4);
7284 tmp = load_reg(s, rd);
7285 gen_st32(tmp, addr, IS_USER(s));
7290 gen_set_label(label);
7291 tcg_gen_mov_i32(cpu_R[rm], tmp2);
7292 tcg_temp_free(tmp2);
7294 tcg_temp_free(addr);
7297 /* Load/store multiple, RFE, SRS. */
7298 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7299 /* Not available in user mode. */
7302 if (insn & (1 << 20)) {
7304 addr = load_reg(s, rn);
7305 if ((insn & (1 << 24)) == 0)
7306 tcg_gen_addi_i32(addr, addr, -8);
7307 /* Load PC into tmp and CPSR into tmp2. */
7308 tmp = gen_ld32(addr, 0);
7309 tcg_gen_addi_i32(addr, addr, 4);
7310 tmp2 = gen_ld32(addr, 0);
7311 if (insn & (1 << 21)) {
7312 /* Base writeback. */
7313 if (insn & (1 << 24)) {
7314 tcg_gen_addi_i32(addr, addr, 4);
7316 tcg_gen_addi_i32(addr, addr, -4);
7318 store_reg(s, rn, addr);
7322 gen_rfe(s, tmp, tmp2);
7326 if (op == (env->uncached_cpsr & CPSR_M)) {
7327 addr = load_reg(s, 13);
7330 tmp = tcg_const_i32(op);
7331 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7332 tcg_temp_free_i32(tmp);
7334 if ((insn & (1 << 24)) == 0) {
7335 tcg_gen_addi_i32(addr, addr, -8);
7337 tmp = load_reg(s, 14);
7338 gen_st32(tmp, addr, 0);
7339 tcg_gen_addi_i32(addr, addr, 4);
7341 gen_helper_cpsr_read(tmp);
7342 gen_st32(tmp, addr, 0);
7343 if (insn & (1 << 21)) {
7344 if ((insn & (1 << 24)) == 0) {
7345 tcg_gen_addi_i32(addr, addr, -4);
7347 tcg_gen_addi_i32(addr, addr, 4);
7349 if (op == (env->uncached_cpsr & CPSR_M)) {
7350 store_reg(s, 13, addr);
7352 tmp = tcg_const_i32(op);
7353 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7354 tcg_temp_free_i32(tmp);
7362 /* Load/store multiple. */
7363 addr = load_reg(s, rn);
7365 for (i = 0; i < 16; i++) {
7366 if (insn & (1 << i))
7369 if (insn & (1 << 24)) {
7370 tcg_gen_addi_i32(addr, addr, -offset);
7373 for (i = 0; i < 16; i++) {
7374 if ((insn & (1 << i)) == 0)
7376 if (insn & (1 << 20)) {
7378 tmp = gen_ld32(addr, IS_USER(s));
7382 store_reg(s, i, tmp);
7386 tmp = load_reg(s, i);
7387 gen_st32(tmp, addr, IS_USER(s));
7389 tcg_gen_addi_i32(addr, addr, 4);
7391 if (insn & (1 << 21)) {
7392 /* Base register writeback. */
7393 if (insn & (1 << 24)) {
7394 tcg_gen_addi_i32(addr, addr, -offset);
7396 /* Fault if writeback register is in register list. */
7397 if (insn & (1 << rn))
7399 store_reg(s, rn, addr);
7406 case 5: /* Data processing register constant shift. */
7409 tcg_gen_movi_i32(tmp, 0);
7411 tmp = load_reg(s, rn);
7413 tmp2 = load_reg(s, rm);
7414 op = (insn >> 21) & 0xf;
7415 shiftop = (insn >> 4) & 3;
7416 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7417 conds = (insn & (1 << 20)) != 0;
7418 logic_cc = (conds && thumb2_logic_op(op));
7419 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7420 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7424 store_reg(s, rd, tmp);
7429 case 13: /* Misc data processing. */
7430 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7431 if (op < 4 && (insn & 0xf000) != 0xf000)
7434 case 0: /* Register controlled shift. */
7435 tmp = load_reg(s, rn);
7436 tmp2 = load_reg(s, rm);
7437 if ((insn & 0x70) != 0)
7439 op = (insn >> 21) & 3;
7440 logic_cc = (insn & (1 << 20)) != 0;
7441 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7444 store_reg_bx(env, s, rd, tmp);
7446 case 1: /* Sign/zero extend. */
7447 tmp = load_reg(s, rm);
7448 shift = (insn >> 4) & 3;
7449 /* ??? In many cases it's not neccessary to do a
7450 rotate, a shift is sufficient. */
7452 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7453 op = (insn >> 20) & 7;
7455 case 0: gen_sxth(tmp); break;
7456 case 1: gen_uxth(tmp); break;
7457 case 2: gen_sxtb16(tmp); break;
7458 case 3: gen_uxtb16(tmp); break;
7459 case 4: gen_sxtb(tmp); break;
7460 case 5: gen_uxtb(tmp); break;
7461 default: goto illegal_op;
7464 tmp2 = load_reg(s, rn);
7465 if ((op >> 1) == 1) {
7466 gen_add16(tmp, tmp2);
7468 tcg_gen_add_i32(tmp, tmp, tmp2);
7472 store_reg(s, rd, tmp);
7474 case 2: /* SIMD add/subtract. */
7475 op = (insn >> 20) & 7;
7476 shift = (insn >> 4) & 7;
7477 if ((op & 3) == 3 || (shift & 3) == 3)
7479 tmp = load_reg(s, rn);
7480 tmp2 = load_reg(s, rm);
7481 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7483 store_reg(s, rd, tmp);
7485 case 3: /* Other data processing. */
7486 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7488 /* Saturating add/subtract. */
7489 tmp = load_reg(s, rn);
7490 tmp2 = load_reg(s, rm);
7492 gen_helper_double_saturate(tmp, tmp);
7494 gen_helper_sub_saturate(tmp, tmp2, tmp);
7496 gen_helper_add_saturate(tmp, tmp, tmp2);
7499 tmp = load_reg(s, rn);
7501 case 0x0a: /* rbit */
7502 gen_helper_rbit(tmp, tmp);
7504 case 0x08: /* rev */
7505 tcg_gen_bswap32_i32(tmp, tmp);
7507 case 0x09: /* rev16 */
7510 case 0x0b: /* revsh */
7513 case 0x10: /* sel */
7514 tmp2 = load_reg(s, rm);
7516 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7517 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7521 case 0x18: /* clz */
7522 gen_helper_clz(tmp, tmp);
7528 store_reg(s, rd, tmp);
7530 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7531 op = (insn >> 4) & 0xf;
7532 tmp = load_reg(s, rn);
7533 tmp2 = load_reg(s, rm);
7534 switch ((insn >> 20) & 7) {
7535 case 0: /* 32 x 32 -> 32 */
7536 tcg_gen_mul_i32(tmp, tmp, tmp2);
7539 tmp2 = load_reg(s, rs);
7541 tcg_gen_sub_i32(tmp, tmp2, tmp);
7543 tcg_gen_add_i32(tmp, tmp, tmp2);
7547 case 1: /* 16 x 16 -> 32 */
7548 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7551 tmp2 = load_reg(s, rs);
7552 gen_helper_add_setq(tmp, tmp, tmp2);
7556 case 2: /* Dual multiply add. */
7557 case 4: /* Dual multiply subtract. */
7559 gen_swap_half(tmp2);
7560 gen_smul_dual(tmp, tmp2);
7561 /* This addition cannot overflow. */
7562 if (insn & (1 << 22)) {
7563 tcg_gen_sub_i32(tmp, tmp, tmp2);
7565 tcg_gen_add_i32(tmp, tmp, tmp2);
7570 tmp2 = load_reg(s, rs);
7571 gen_helper_add_setq(tmp, tmp, tmp2);
7575 case 3: /* 32 * 16 -> 32msb */
7577 tcg_gen_sari_i32(tmp2, tmp2, 16);
7580 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7581 tcg_gen_shri_i64(tmp64, tmp64, 16);
7583 tcg_gen_trunc_i64_i32(tmp, tmp64);
7584 tcg_temp_free_i64(tmp64);
7587 tmp2 = load_reg(s, rs);
7588 gen_helper_add_setq(tmp, tmp, tmp2);
7592 case 5: case 6: /* 32 * 32 -> 32msb */
7593 gen_imull(tmp, tmp2);
7594 if (insn & (1 << 5)) {
7595 gen_roundqd(tmp, tmp2);
7602 tmp2 = load_reg(s, rs);
7603 if (insn & (1 << 21)) {
7604 tcg_gen_add_i32(tmp, tmp, tmp2);
7606 tcg_gen_sub_i32(tmp, tmp2, tmp);
7611 case 7: /* Unsigned sum of absolute differences. */
7612 gen_helper_usad8(tmp, tmp, tmp2);
7615 tmp2 = load_reg(s, rs);
7616 tcg_gen_add_i32(tmp, tmp, tmp2);
7621 store_reg(s, rd, tmp);
7623 case 6: case 7: /* 64-bit multiply, Divide. */
7624 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7625 tmp = load_reg(s, rn);
7626 tmp2 = load_reg(s, rm);
7627 if ((op & 0x50) == 0x10) {
7629 if (!arm_feature(env, ARM_FEATURE_DIV))
7632 gen_helper_udiv(tmp, tmp, tmp2);
7634 gen_helper_sdiv(tmp, tmp, tmp2);
7636 store_reg(s, rd, tmp);
7637 } else if ((op & 0xe) == 0xc) {
7638 /* Dual multiply accumulate long. */
7640 gen_swap_half(tmp2);
7641 gen_smul_dual(tmp, tmp2);
7643 tcg_gen_sub_i32(tmp, tmp, tmp2);
7645 tcg_gen_add_i32(tmp, tmp, tmp2);
7649 tmp64 = tcg_temp_new_i64();
7650 tcg_gen_ext_i32_i64(tmp64, tmp);
7652 gen_addq(s, tmp64, rs, rd);
7653 gen_storeq_reg(s, rs, rd, tmp64);
7654 tcg_temp_free_i64(tmp64);
7657 /* Unsigned 64-bit multiply */
7658 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7662 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7664 tmp64 = tcg_temp_new_i64();
7665 tcg_gen_ext_i32_i64(tmp64, tmp);
7668 /* Signed 64-bit multiply */
7669 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7674 gen_addq_lo(s, tmp64, rs);
7675 gen_addq_lo(s, tmp64, rd);
7676 } else if (op & 0x40) {
7677 /* 64-bit accumulate. */
7678 gen_addq(s, tmp64, rs, rd);
7680 gen_storeq_reg(s, rs, rd, tmp64);
7681 tcg_temp_free_i64(tmp64);
7686 case 6: case 7: case 14: case 15:
7688 if (((insn >> 24) & 3) == 3) {
7689 /* Translate into the equivalent ARM encoding. */
7690 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7691 if (disas_neon_data_insn(env, s, insn))
7694 if (insn & (1 << 28))
7696 if (disas_coproc_insn (env, s, insn))
7700 case 8: case 9: case 10: case 11:
7701 if (insn & (1 << 15)) {
7702 /* Branches, misc control. */
7703 if (insn & 0x5000) {
7704 /* Unconditional branch. */
7705 /* signextend(hw1[10:0]) -> offset[:12]. */
7706 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7707 /* hw1[10:0] -> offset[11:1]. */
7708 offset |= (insn & 0x7ff) << 1;
7709 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7710 offset[24:22] already have the same value because of the
7711 sign extension above. */
7712 offset ^= ((~insn) & (1 << 13)) << 10;
7713 offset ^= ((~insn) & (1 << 11)) << 11;
7715 if (insn & (1 << 14)) {
7716 /* Branch and link. */
7717 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7721 if (insn & (1 << 12)) {
7726 offset &= ~(uint32_t)2;
7727 gen_bx_im(s, offset);
7729 } else if (((insn >> 23) & 7) == 7) {
7731 if (insn & (1 << 13))
7734 if (insn & (1 << 26)) {
7735 /* Secure monitor call (v6Z) */
7736 goto illegal_op; /* not implemented. */
7738 op = (insn >> 20) & 7;
7740 case 0: /* msr cpsr. */
7742 tmp = load_reg(s, rn);
7743 addr = tcg_const_i32(insn & 0xff);
7744 gen_helper_v7m_msr(cpu_env, addr, tmp);
7745 tcg_temp_free_i32(addr);
7751 case 1: /* msr spsr. */
7754 tmp = load_reg(s, rn);
7756 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7760 case 2: /* cps, nop-hint. */
7761 if (((insn >> 8) & 7) == 0) {
7762 gen_nop_hint(s, insn & 0xff);
7764 /* Implemented as NOP in user mode. */
7769 if (insn & (1 << 10)) {
7770 if (insn & (1 << 7))
7772 if (insn & (1 << 6))
7774 if (insn & (1 << 5))
7776 if (insn & (1 << 9))
7777 imm = CPSR_A | CPSR_I | CPSR_F;
7779 if (insn & (1 << 8)) {
7781 imm |= (insn & 0x1f);
7784 gen_set_psr_im(s, offset, 0, imm);
7787 case 3: /* Special control operations. */
7788 op = (insn >> 4) & 0xf;
7791 gen_helper_clrex(cpu_env);
7796 /* These execute as NOPs. */
7804 /* Trivial implementation equivalent to bx. */
7805 tmp = load_reg(s, rn);
7808 case 5: /* Exception return. */
7809 /* Unpredictable in user mode. */
7811 case 6: /* mrs cpsr. */
7814 addr = tcg_const_i32(insn & 0xff);
7815 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7816 tcg_temp_free_i32(addr);
7818 gen_helper_cpsr_read(tmp);
7820 store_reg(s, rd, tmp);
7822 case 7: /* mrs spsr. */
7823 /* Not accessible in user mode. */
7824 if (IS_USER(s) || IS_M(env))
7826 tmp = load_cpu_field(spsr);
7827 store_reg(s, rd, tmp);
7832 /* Conditional branch. */
7833 op = (insn >> 22) & 0xf;
7834 /* Generate a conditional jump to next instruction. */
7835 s->condlabel = gen_new_label();
7836 gen_test_cc(op ^ 1, s->condlabel);
7839 /* offset[11:1] = insn[10:0] */
7840 offset = (insn & 0x7ff) << 1;
7841 /* offset[17:12] = insn[21:16]. */
7842 offset |= (insn & 0x003f0000) >> 4;
7843 /* offset[31:20] = insn[26]. */
7844 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7845 /* offset[18] = insn[13]. */
7846 offset |= (insn & (1 << 13)) << 5;
7847 /* offset[19] = insn[11]. */
7848 offset |= (insn & (1 << 11)) << 8;
7850 /* jump to the offset */
7851 gen_jmp(s, s->pc + offset);
7854 /* Data processing immediate. */
7855 if (insn & (1 << 25)) {
7856 if (insn & (1 << 24)) {
7857 if (insn & (1 << 20))
7859 /* Bitfield/Saturate. */
7860 op = (insn >> 21) & 7;
7862 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7865 tcg_gen_movi_i32(tmp, 0);
7867 tmp = load_reg(s, rn);
7870 case 2: /* Signed bitfield extract. */
7872 if (shift + imm > 32)
7875 gen_sbfx(tmp, shift, imm);
7877 case 6: /* Unsigned bitfield extract. */
7879 if (shift + imm > 32)
7882 gen_ubfx(tmp, shift, (1u << imm) - 1);
7884 case 3: /* Bitfield insert/clear. */
7887 imm = imm + 1 - shift;
7889 tmp2 = load_reg(s, rd);
7890 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7896 default: /* Saturate. */
7899 tcg_gen_sari_i32(tmp, tmp, shift);
7901 tcg_gen_shli_i32(tmp, tmp, shift);
7903 tmp2 = tcg_const_i32(imm);
7906 if ((op & 1) && shift == 0)
7907 gen_helper_usat16(tmp, tmp, tmp2);
7909 gen_helper_usat(tmp, tmp, tmp2);
7912 if ((op & 1) && shift == 0)
7913 gen_helper_ssat16(tmp, tmp, tmp2);
7915 gen_helper_ssat(tmp, tmp, tmp2);
7917 tcg_temp_free_i32(tmp2);
7920 store_reg(s, rd, tmp);
7922 imm = ((insn & 0x04000000) >> 15)
7923 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7924 if (insn & (1 << 22)) {
7925 /* 16-bit immediate. */
7926 imm |= (insn >> 4) & 0xf000;
7927 if (insn & (1 << 23)) {
7929 tmp = load_reg(s, rd);
7930 tcg_gen_ext16u_i32(tmp, tmp);
7931 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7935 tcg_gen_movi_i32(tmp, imm);
7938 /* Add/sub 12-bit immediate. */
7940 offset = s->pc & ~(uint32_t)3;
7941 if (insn & (1 << 23))
7946 tcg_gen_movi_i32(tmp, offset);
7948 tmp = load_reg(s, rn);
7949 if (insn & (1 << 23))
7950 tcg_gen_subi_i32(tmp, tmp, imm);
7952 tcg_gen_addi_i32(tmp, tmp, imm);
7955 store_reg(s, rd, tmp);
7958 int shifter_out = 0;
7959 /* modified 12-bit immediate. */
7960 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7961 imm = (insn & 0xff);
7964 /* Nothing to do. */
7966 case 1: /* 00XY00XY */
7969 case 2: /* XY00XY00 */
7973 case 3: /* XYXYXYXY */
7977 default: /* Rotated constant. */
7978 shift = (shift << 1) | (imm >> 7);
7980 imm = imm << (32 - shift);
7985 tcg_gen_movi_i32(tmp2, imm);
7986 rn = (insn >> 16) & 0xf;
7989 tcg_gen_movi_i32(tmp, 0);
7991 tmp = load_reg(s, rn);
7993 op = (insn >> 21) & 0xf;
7994 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7995 shifter_out, tmp, tmp2))
7998 rd = (insn >> 8) & 0xf;
8000 store_reg(s, rd, tmp);
8007 case 12: /* Load/store single data item. */
8012 if ((insn & 0x01100000) == 0x01000000) {
8013 if (disas_neon_ls_insn(env, s, insn))
8021 /* s->pc has already been incremented by 4. */
8022 imm = s->pc & 0xfffffffc;
8023 if (insn & (1 << 23))
8024 imm += insn & 0xfff;
8026 imm -= insn & 0xfff;
8027 tcg_gen_movi_i32(addr, imm);
8029 addr = load_reg(s, rn);
8030 if (insn & (1 << 23)) {
8031 /* Positive offset. */
8033 tcg_gen_addi_i32(addr, addr, imm);
8035 op = (insn >> 8) & 7;
8038 case 0: case 8: /* Shifted Register. */
8039 shift = (insn >> 4) & 0xf;
8042 tmp = load_reg(s, rm);
8044 tcg_gen_shli_i32(tmp, tmp, shift);
8045 tcg_gen_add_i32(addr, addr, tmp);
8048 case 4: /* Negative offset. */
8049 tcg_gen_addi_i32(addr, addr, -imm);
8051 case 6: /* User privilege. */
8052 tcg_gen_addi_i32(addr, addr, imm);
8055 case 1: /* Post-decrement. */
8058 case 3: /* Post-increment. */
8062 case 5: /* Pre-decrement. */
8065 case 7: /* Pre-increment. */
8066 tcg_gen_addi_i32(addr, addr, imm);
8074 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8075 if (insn & (1 << 20)) {
8077 if (rs == 15 && op != 2) {
8080 /* Memory hint. Implemented as NOP. */
8083 case 0: tmp = gen_ld8u(addr, user); break;
8084 case 4: tmp = gen_ld8s(addr, user); break;
8085 case 1: tmp = gen_ld16u(addr, user); break;
8086 case 5: tmp = gen_ld16s(addr, user); break;
8087 case 2: tmp = gen_ld32(addr, user); break;
8088 default: goto illegal_op;
8093 store_reg(s, rs, tmp);
8100 tmp = load_reg(s, rs);
8102 case 0: gen_st8(tmp, addr, user); break;
8103 case 1: gen_st16(tmp, addr, user); break;
8104 case 2: gen_st32(tmp, addr, user); break;
8105 default: goto illegal_op;
8109 tcg_gen_addi_i32(addr, addr, imm);
8111 store_reg(s, rn, addr);
8125 static void disas_thumb_insn(CPUState *env, DisasContext *s)
8127 uint32_t val, insn, op, rm, rn, rd, shift, cond;
8134 if (s->condexec_mask) {
8135 cond = s->condexec_cond;
8136 s->condlabel = gen_new_label();
8137 gen_test_cc(cond ^ 1, s->condlabel);
8141 insn = lduw_code(s->pc);
8144 switch (insn >> 12) {
8148 op = (insn >> 11) & 3;
8151 rn = (insn >> 3) & 7;
8152 tmp = load_reg(s, rn);
8153 if (insn & (1 << 10)) {
8156 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8159 rm = (insn >> 6) & 7;
8160 tmp2 = load_reg(s, rm);
8162 if (insn & (1 << 9)) {
8163 if (s->condexec_mask)
8164 tcg_gen_sub_i32(tmp, tmp, tmp2);
8166 gen_helper_sub_cc(tmp, tmp, tmp2);
8168 if (s->condexec_mask)
8169 tcg_gen_add_i32(tmp, tmp, tmp2);
8171 gen_helper_add_cc(tmp, tmp, tmp2);
8174 store_reg(s, rd, tmp);
8176 /* shift immediate */
8177 rm = (insn >> 3) & 7;
8178 shift = (insn >> 6) & 0x1f;
8179 tmp = load_reg(s, rm);
8180 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8181 if (!s->condexec_mask)
8183 store_reg(s, rd, tmp);
8187 /* arithmetic large immediate */
8188 op = (insn >> 11) & 3;
8189 rd = (insn >> 8) & 0x7;
8190 if (op == 0) { /* mov */
8192 tcg_gen_movi_i32(tmp, insn & 0xff);
8193 if (!s->condexec_mask)
8195 store_reg(s, rd, tmp);
8197 tmp = load_reg(s, rd);
8199 tcg_gen_movi_i32(tmp2, insn & 0xff);
8202 gen_helper_sub_cc(tmp, tmp, tmp2);
8207 if (s->condexec_mask)
8208 tcg_gen_add_i32(tmp, tmp, tmp2);
8210 gen_helper_add_cc(tmp, tmp, tmp2);
8212 store_reg(s, rd, tmp);
8215 if (s->condexec_mask)
8216 tcg_gen_sub_i32(tmp, tmp, tmp2);
8218 gen_helper_sub_cc(tmp, tmp, tmp2);
8220 store_reg(s, rd, tmp);
8226 if (insn & (1 << 11)) {
8227 rd = (insn >> 8) & 7;
8228 /* load pc-relative. Bit 1 of PC is ignored. */
8229 val = s->pc + 2 + ((insn & 0xff) * 4);
8230 val &= ~(uint32_t)2;
8232 tcg_gen_movi_i32(addr, val);
8233 tmp = gen_ld32(addr, IS_USER(s));
8235 store_reg(s, rd, tmp);
8238 if (insn & (1 << 10)) {
8239 /* data processing extended or blx */
8240 rd = (insn & 7) | ((insn >> 4) & 8);
8241 rm = (insn >> 3) & 0xf;
8242 op = (insn >> 8) & 3;
8245 tmp = load_reg(s, rd);
8246 tmp2 = load_reg(s, rm);
8247 tcg_gen_add_i32(tmp, tmp, tmp2);
8249 store_reg(s, rd, tmp);
8252 tmp = load_reg(s, rd);
8253 tmp2 = load_reg(s, rm);
8254 gen_helper_sub_cc(tmp, tmp, tmp2);
8258 case 2: /* mov/cpy */
8259 tmp = load_reg(s, rm);
8260 store_reg(s, rd, tmp);
8262 case 3:/* branch [and link] exchange thumb register */
8263 tmp = load_reg(s, rm);
8264 if (insn & (1 << 7)) {
8265 val = (uint32_t)s->pc | 1;
8267 tcg_gen_movi_i32(tmp2, val);
8268 store_reg(s, 14, tmp2);
8276 /* data processing register */
8278 rm = (insn >> 3) & 7;
8279 op = (insn >> 6) & 0xf;
8280 if (op == 2 || op == 3 || op == 4 || op == 7) {
8281 /* the shift/rotate ops want the operands backwards */
8290 if (op == 9) { /* neg */
8292 tcg_gen_movi_i32(tmp, 0);
8293 } else if (op != 0xf) { /* mvn doesn't read its first operand */
8294 tmp = load_reg(s, rd);
8299 tmp2 = load_reg(s, rm);
8302 tcg_gen_and_i32(tmp, tmp, tmp2);
8303 if (!s->condexec_mask)
8307 tcg_gen_xor_i32(tmp, tmp, tmp2);
8308 if (!s->condexec_mask)
8312 if (s->condexec_mask) {
8313 gen_helper_shl(tmp2, tmp2, tmp);
8315 gen_helper_shl_cc(tmp2, tmp2, tmp);
8320 if (s->condexec_mask) {
8321 gen_helper_shr(tmp2, tmp2, tmp);
8323 gen_helper_shr_cc(tmp2, tmp2, tmp);
8328 if (s->condexec_mask) {
8329 gen_helper_sar(tmp2, tmp2, tmp);
8331 gen_helper_sar_cc(tmp2, tmp2, tmp);
8336 if (s->condexec_mask)
8339 gen_helper_adc_cc(tmp, tmp, tmp2);
8342 if (s->condexec_mask)
8343 gen_sub_carry(tmp, tmp, tmp2);
8345 gen_helper_sbc_cc(tmp, tmp, tmp2);
8348 if (s->condexec_mask) {
8349 gen_helper_ror(tmp2, tmp2, tmp);
8351 gen_helper_ror_cc(tmp2, tmp2, tmp);
8356 tcg_gen_and_i32(tmp, tmp, tmp2);
8361 if (s->condexec_mask)
8362 tcg_gen_neg_i32(tmp, tmp2);
8364 gen_helper_sub_cc(tmp, tmp, tmp2);
8367 gen_helper_sub_cc(tmp, tmp, tmp2);
8371 gen_helper_add_cc(tmp, tmp, tmp2);
8375 tcg_gen_or_i32(tmp, tmp, tmp2);
8376 if (!s->condexec_mask)
8380 tcg_gen_mul_i32(tmp, tmp, tmp2);
8381 if (!s->condexec_mask)
8385 tcg_gen_bic_i32(tmp, tmp, tmp2);
8386 if (!s->condexec_mask)
8390 tcg_gen_not_i32(tmp2, tmp2);
8391 if (!s->condexec_mask)
8399 store_reg(s, rm, tmp2);
8403 store_reg(s, rd, tmp);
8413 /* load/store register offset. */
8415 rn = (insn >> 3) & 7;
8416 rm = (insn >> 6) & 7;
8417 op = (insn >> 9) & 7;
8418 addr = load_reg(s, rn);
8419 tmp = load_reg(s, rm);
8420 tcg_gen_add_i32(addr, addr, tmp);
8423 if (op < 3) /* store */
8424 tmp = load_reg(s, rd);
8428 gen_st32(tmp, addr, IS_USER(s));
8431 gen_st16(tmp, addr, IS_USER(s));
8434 gen_st8(tmp, addr, IS_USER(s));
8437 tmp = gen_ld8s(addr, IS_USER(s));
8440 tmp = gen_ld32(addr, IS_USER(s));
8443 tmp = gen_ld16u(addr, IS_USER(s));
8446 tmp = gen_ld8u(addr, IS_USER(s));
8449 tmp = gen_ld16s(addr, IS_USER(s));
8452 if (op >= 3) /* load */
8453 store_reg(s, rd, tmp);
8458 /* load/store word immediate offset */
8460 rn = (insn >> 3) & 7;
8461 addr = load_reg(s, rn);
8462 val = (insn >> 4) & 0x7c;
8463 tcg_gen_addi_i32(addr, addr, val);
8465 if (insn & (1 << 11)) {
8467 tmp = gen_ld32(addr, IS_USER(s));
8468 store_reg(s, rd, tmp);
8471 tmp = load_reg(s, rd);
8472 gen_st32(tmp, addr, IS_USER(s));
8478 /* load/store byte immediate offset */
8480 rn = (insn >> 3) & 7;
8481 addr = load_reg(s, rn);
8482 val = (insn >> 6) & 0x1f;
8483 tcg_gen_addi_i32(addr, addr, val);
8485 if (insn & (1 << 11)) {
8487 tmp = gen_ld8u(addr, IS_USER(s));
8488 store_reg(s, rd, tmp);
8491 tmp = load_reg(s, rd);
8492 gen_st8(tmp, addr, IS_USER(s));
8498 /* load/store halfword immediate offset */
8500 rn = (insn >> 3) & 7;
8501 addr = load_reg(s, rn);
8502 val = (insn >> 5) & 0x3e;
8503 tcg_gen_addi_i32(addr, addr, val);
8505 if (insn & (1 << 11)) {
8507 tmp = gen_ld16u(addr, IS_USER(s));
8508 store_reg(s, rd, tmp);
8511 tmp = load_reg(s, rd);
8512 gen_st16(tmp, addr, IS_USER(s));
8518 /* load/store from stack */
8519 rd = (insn >> 8) & 7;
8520 addr = load_reg(s, 13);
8521 val = (insn & 0xff) * 4;
8522 tcg_gen_addi_i32(addr, addr, val);
8524 if (insn & (1 << 11)) {
8526 tmp = gen_ld32(addr, IS_USER(s));
8527 store_reg(s, rd, tmp);
8530 tmp = load_reg(s, rd);
8531 gen_st32(tmp, addr, IS_USER(s));
8537 /* add to high reg */
8538 rd = (insn >> 8) & 7;
8539 if (insn & (1 << 11)) {
8541 tmp = load_reg(s, 13);
8543 /* PC. bit 1 is ignored. */
8545 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8547 val = (insn & 0xff) * 4;
8548 tcg_gen_addi_i32(tmp, tmp, val);
8549 store_reg(s, rd, tmp);
8554 op = (insn >> 8) & 0xf;
8557 /* adjust stack pointer */
8558 tmp = load_reg(s, 13);
8559 val = (insn & 0x7f) * 4;
8560 if (insn & (1 << 7))
8561 val = -(int32_t)val;
8562 tcg_gen_addi_i32(tmp, tmp, val);
8563 store_reg(s, 13, tmp);
8566 case 2: /* sign/zero extend. */
8569 rm = (insn >> 3) & 7;
8570 tmp = load_reg(s, rm);
8571 switch ((insn >> 6) & 3) {
8572 case 0: gen_sxth(tmp); break;
8573 case 1: gen_sxtb(tmp); break;
8574 case 2: gen_uxth(tmp); break;
8575 case 3: gen_uxtb(tmp); break;
8577 store_reg(s, rd, tmp);
8579 case 4: case 5: case 0xc: case 0xd:
8581 addr = load_reg(s, 13);
8582 if (insn & (1 << 8))
8586 for (i = 0; i < 8; i++) {
8587 if (insn & (1 << i))
8590 if ((insn & (1 << 11)) == 0) {
8591 tcg_gen_addi_i32(addr, addr, -offset);
8593 for (i = 0; i < 8; i++) {
8594 if (insn & (1 << i)) {
8595 if (insn & (1 << 11)) {
8597 tmp = gen_ld32(addr, IS_USER(s));
8598 store_reg(s, i, tmp);
8601 tmp = load_reg(s, i);
8602 gen_st32(tmp, addr, IS_USER(s));
8604 /* advance to the next address. */
8605 tcg_gen_addi_i32(addr, addr, 4);
8609 if (insn & (1 << 8)) {
8610 if (insn & (1 << 11)) {
8612 tmp = gen_ld32(addr, IS_USER(s));
8613 /* don't set the pc until the rest of the instruction
8617 tmp = load_reg(s, 14);
8618 gen_st32(tmp, addr, IS_USER(s));
8620 tcg_gen_addi_i32(addr, addr, 4);
8622 if ((insn & (1 << 11)) == 0) {
8623 tcg_gen_addi_i32(addr, addr, -offset);
8625 /* write back the new stack pointer */
8626 store_reg(s, 13, addr);
8627 /* set the new PC value */
8628 if ((insn & 0x0900) == 0x0900)
8632 case 1: case 3: case 9: case 11: /* czb */
8634 tmp = load_reg(s, rm);
8635 s->condlabel = gen_new_label();
8637 if (insn & (1 << 11))
8638 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8640 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8642 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8643 val = (uint32_t)s->pc + 2;
8648 case 15: /* IT, nop-hint. */
8649 if ((insn & 0xf) == 0) {
8650 gen_nop_hint(s, (insn >> 4) & 0xf);
8654 s->condexec_cond = (insn >> 4) & 0xe;
8655 s->condexec_mask = insn & 0x1f;
8656 /* No actual code generated for this insn, just setup state. */
8659 case 0xe: /* bkpt */
8660 gen_set_condexec(s);
8661 gen_set_pc_im(s->pc - 2);
8662 gen_exception(EXCP_BKPT);
8663 s->is_jmp = DISAS_JUMP;
8668 rn = (insn >> 3) & 0x7;
8670 tmp = load_reg(s, rn);
8671 switch ((insn >> 6) & 3) {
8672 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8673 case 1: gen_rev16(tmp); break;
8674 case 3: gen_revsh(tmp); break;
8675 default: goto illegal_op;
8677 store_reg(s, rd, tmp);
8685 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8688 addr = tcg_const_i32(16);
8689 gen_helper_v7m_msr(cpu_env, addr, tmp);
8690 tcg_temp_free_i32(addr);
8694 addr = tcg_const_i32(17);
8695 gen_helper_v7m_msr(cpu_env, addr, tmp);
8696 tcg_temp_free_i32(addr);
8698 tcg_temp_free_i32(tmp);
8701 if (insn & (1 << 4))
8702 shift = CPSR_A | CPSR_I | CPSR_F;
8705 gen_set_psr_im(s, shift, 0, ((insn & 7) << 6) & shift);
8715 /* load/store multiple */
8716 rn = (insn >> 8) & 0x7;
8717 addr = load_reg(s, rn);
8718 for (i = 0; i < 8; i++) {
8719 if (insn & (1 << i)) {
8720 if (insn & (1 << 11)) {
8722 tmp = gen_ld32(addr, IS_USER(s));
8723 store_reg(s, i, tmp);
8726 tmp = load_reg(s, i);
8727 gen_st32(tmp, addr, IS_USER(s));
8729 /* advance to the next address */
8730 tcg_gen_addi_i32(addr, addr, 4);
8733 /* Base register writeback. */
8734 if ((insn & (1 << rn)) == 0) {
8735 store_reg(s, rn, addr);
8742 /* conditional branch or swi */
8743 cond = (insn >> 8) & 0xf;
8749 gen_set_condexec(s);
8750 gen_set_pc_im(s->pc);
8751 s->is_jmp = DISAS_SWI;
8754 /* generate a conditional jump to next instruction */
8755 s->condlabel = gen_new_label();
8756 gen_test_cc(cond ^ 1, s->condlabel);
8759 /* jump to the offset */
8760 val = (uint32_t)s->pc + 2;
8761 offset = ((int32_t)insn << 24) >> 24;
8767 if (insn & (1 << 11)) {
8768 if (disas_thumb2_insn(env, s, insn))
8772 /* unconditional branch */
8773 val = (uint32_t)s->pc;
8774 offset = ((int32_t)insn << 21) >> 21;
8775 val += (offset << 1) + 2;
8780 if (disas_thumb2_insn(env, s, insn))
8786 gen_set_condexec(s);
8787 gen_set_pc_im(s->pc - 4);
8788 gen_exception(EXCP_UDEF);
8789 s->is_jmp = DISAS_JUMP;
8793 gen_set_condexec(s);
8794 gen_set_pc_im(s->pc - 2);
8795 gen_exception(EXCP_UDEF);
8796 s->is_jmp = DISAS_JUMP;
8799 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8800 basic block 'tb'. If search_pc is TRUE, also generate PC
8801 information for each intermediate instruction. */
8802 static inline void gen_intermediate_code_internal(CPUState *env,
8803 TranslationBlock *tb,
8806 DisasContext dc1, *dc = &dc1;
8808 uint16_t *gen_opc_end;
8810 target_ulong pc_start;
8811 uint32_t next_page_start;
8815 /* generate intermediate code */
8822 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8824 dc->is_jmp = DISAS_NEXT;
8826 dc->singlestep_enabled = env->singlestep_enabled;
8828 dc->thumb = env->thumb;
8829 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8830 dc->condexec_cond = env->condexec_bits >> 4;
8831 #if !defined(CONFIG_USER_ONLY)
8833 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8835 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8838 cpu_F0s = tcg_temp_new_i32();
8839 cpu_F1s = tcg_temp_new_i32();
8840 cpu_F0d = tcg_temp_new_i64();
8841 cpu_F1d = tcg_temp_new_i64();
8844 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8845 cpu_M0 = tcg_temp_new_i64();
8846 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8849 max_insns = tb->cflags & CF_COUNT_MASK;
8851 max_insns = CF_COUNT_MASK;
8854 /* Reset the conditional execution bits immediately. This avoids
8855 complications trying to do it at the end of the block. */
8856 if (env->condexec_bits)
8858 TCGv tmp = new_tmp();
8859 tcg_gen_movi_i32(tmp, 0);
8860 store_cpu_field(tmp, condexec_bits);
8863 #ifdef CONFIG_USER_ONLY
8864 /* Intercept jump to the magic kernel page. */
8865 if (dc->pc >= 0xffff0000) {
8866 /* We always get here via a jump, so know we are not in a
8867 conditional execution block. */
8868 gen_exception(EXCP_KERNEL_TRAP);
8869 dc->is_jmp = DISAS_UPDATE;
8873 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8874 /* We always get here via a jump, so know we are not in a
8875 conditional execution block. */
8876 gen_exception(EXCP_EXCEPTION_EXIT);
8877 dc->is_jmp = DISAS_UPDATE;
8882 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8883 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8884 if (bp->pc == dc->pc) {
8885 gen_set_condexec(dc);
8886 gen_set_pc_im(dc->pc);
8887 gen_exception(EXCP_DEBUG);
8888 dc->is_jmp = DISAS_JUMP;
8889 /* Advance PC so that clearing the breakpoint will
8890 invalidate this TB. */
8892 goto done_generating;
8898 j = gen_opc_ptr - gen_opc_buf;
8902 gen_opc_instr_start[lj++] = 0;
8904 gen_opc_pc[lj] = dc->pc;
8905 gen_opc_instr_start[lj] = 1;
8906 gen_opc_icount[lj] = num_insns;
8909 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8913 disas_thumb_insn(env, dc);
8914 if (dc->condexec_mask) {
8915 dc->condexec_cond = (dc->condexec_cond & 0xe)
8916 | ((dc->condexec_mask >> 4) & 1);
8917 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8918 if (dc->condexec_mask == 0) {
8919 dc->condexec_cond = 0;
8923 disas_arm_insn(env, dc);
8926 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8930 if (dc->condjmp && !dc->is_jmp) {
8931 gen_set_label(dc->condlabel);
8934 /* Translation stops when a conditional branch is encountered.
8935 * Otherwise the subsequent code could get translated several times.
8936 * Also stop translation when a page boundary is reached. This
8937 * ensures prefetch aborts occur at the right place. */
8939 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8940 !env->singlestep_enabled &&
8942 dc->pc < next_page_start &&
8943 num_insns < max_insns);
8945 if (tb->cflags & CF_LAST_IO) {
8947 /* FIXME: This can theoretically happen with self-modifying
8949 cpu_abort(env, "IO on conditional branch instruction");
8954 /* At this stage dc->condjmp will only be set when the skipped
8955 instruction was a conditional branch or trap, and the PC has
8956 already been written. */
8957 if (unlikely(env->singlestep_enabled)) {
8958 /* Make sure the pc is updated, and raise a debug exception. */
8960 gen_set_condexec(dc);
8961 if (dc->is_jmp == DISAS_SWI) {
8962 gen_exception(EXCP_SWI);
8964 gen_exception(EXCP_DEBUG);
8966 gen_set_label(dc->condlabel);
8968 if (dc->condjmp || !dc->is_jmp) {
8969 gen_set_pc_im(dc->pc);
8972 gen_set_condexec(dc);
8973 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8974 gen_exception(EXCP_SWI);
8976 /* FIXME: Single stepping a WFI insn will not halt
8978 gen_exception(EXCP_DEBUG);
8981 /* While branches must always occur at the end of an IT block,
8982 there are a few other things that can cause us to terminate
8983 the TB in the middel of an IT block:
8984 - Exception generating instructions (bkpt, swi, undefined).
8986 - Hardware watchpoints.
8987 Hardware breakpoints have already been handled and skip this code.
8989 gen_set_condexec(dc);
8990 switch(dc->is_jmp) {
8992 gen_goto_tb(dc, 1, dc->pc);
8997 /* indicate that the hash table must be used to find the next TB */
9001 /* nothing more to generate */
9007 gen_exception(EXCP_SWI);
9011 gen_set_label(dc->condlabel);
9012 gen_set_condexec(dc);
9013 gen_goto_tb(dc, 1, dc->pc);
9019 gen_icount_end(tb, num_insns);
9020 *gen_opc_ptr = INDEX_op_end;
9023 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9024 qemu_log("----------------\n");
9025 qemu_log("IN: %s\n", lookup_symbol(pc_start));
9026 log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9031 j = gen_opc_ptr - gen_opc_buf;
9034 gen_opc_instr_start[lj++] = 0;
9036 tb->size = dc->pc - pc_start;
9037 tb->icount = num_insns;
9041 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9043 gen_intermediate_code_internal(env, tb, 0);
9046 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9048 gen_intermediate_code_internal(env, tb, 1);
9051 static const char *cpu_mode_names[16] = {
9052 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9053 "???", "???", "???", "und", "???", "???", "???", "sys"
9056 void cpu_dump_state(CPUState *env, FILE *f,
9057 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9067 /* ??? This assumes float64 and double have the same layout.
9068 Oh well, it's only debug dumps. */
9077 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9079 cpu_fprintf(f, "\n");
9081 cpu_fprintf(f, " ");
9083 psr = cpsr_read(env);
9084 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9086 psr & (1 << 31) ? 'N' : '-',
9087 psr & (1 << 30) ? 'Z' : '-',
9088 psr & (1 << 29) ? 'C' : '-',
9089 psr & (1 << 28) ? 'V' : '-',
9090 psr & CPSR_T ? 'T' : 'A',
9091 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9094 for (i = 0; i < 16; i++) {
9095 d.d = env->vfp.regs[i];
9099 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9100 i * 2, (int)s0.i, s0.s,
9101 i * 2 + 1, (int)s1.i, s1.s,
9102 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9105 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9109 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9110 unsigned long searched_pc, int pc_pos, void *puc)
9112 env->regs[15] = gen_opc_pc[pc_pos];