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 /* FIXME: Implement this natively. */
409 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
411 static void shifter_out_im(TCGv var
, int shift
)
413 TCGv tmp
= new_tmp();
415 tcg_gen_andi_i32(tmp
, var
, 1);
417 tcg_gen_shri_i32(tmp
, var
, shift
);
419 tcg_gen_andi_i32(tmp
, tmp
, 1);
425 /* Shift by immediate. Includes special handling for shift == 0. */
426 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
432 shifter_out_im(var
, 32 - shift
);
433 tcg_gen_shli_i32(var
, var
, shift
);
439 tcg_gen_shri_i32(var
, var
, 31);
442 tcg_gen_movi_i32(var
, 0);
445 shifter_out_im(var
, shift
- 1);
446 tcg_gen_shri_i32(var
, var
, shift
);
453 shifter_out_im(var
, shift
- 1);
456 tcg_gen_sari_i32(var
, var
, shift
);
458 case 3: /* ROR/RRX */
461 shifter_out_im(var
, shift
- 1);
462 tcg_gen_rotri_i32(var
, var
, shift
); break;
464 TCGv tmp
= load_cpu_field(CF
);
466 shifter_out_im(var
, 0);
467 tcg_gen_shri_i32(var
, var
, 1);
468 tcg_gen_shli_i32(tmp
, tmp
, 31);
469 tcg_gen_or_i32(var
, var
, tmp
);
475 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
476 TCGv shift
, int flags
)
480 case 0: gen_helper_shl_cc(var
, var
, shift
); break;
481 case 1: gen_helper_shr_cc(var
, var
, shift
); break;
482 case 2: gen_helper_sar_cc(var
, var
, shift
); break;
483 case 3: gen_helper_ror_cc(var
, var
, shift
); break;
487 case 0: gen_helper_shl(var
, var
, shift
); break;
488 case 1: gen_helper_shr(var
, var
, shift
); break;
489 case 2: gen_helper_sar(var
, var
, shift
); break;
490 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
491 tcg_gen_rotr_i32(var
, var
, shift
); break;
497 #define PAS_OP(pfx) \
499 case 0: gen_pas_helper(glue(pfx,add16)); break; \
500 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
501 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
502 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
503 case 4: gen_pas_helper(glue(pfx,add8)); break; \
504 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
506 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
511 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
513 tmp
= tcg_temp_new_ptr();
514 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
516 tcg_temp_free_ptr(tmp
);
519 tmp
= tcg_temp_new_ptr();
520 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
522 tcg_temp_free_ptr(tmp
);
524 #undef gen_pas_helper
525 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
538 #undef gen_pas_helper
543 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
544 #define PAS_OP(pfx) \
546 case 0: gen_pas_helper(glue(pfx,add8)); break; \
547 case 1: gen_pas_helper(glue(pfx,add16)); break; \
548 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
549 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
550 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
551 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
553 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
558 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
560 tmp
= tcg_temp_new_ptr();
561 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
563 tcg_temp_free_ptr(tmp
);
566 tmp
= tcg_temp_new_ptr();
567 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
569 tcg_temp_free_ptr(tmp
);
571 #undef gen_pas_helper
572 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
585 #undef gen_pas_helper
590 static void gen_test_cc(int cc
, int label
)
598 tmp
= load_cpu_field(ZF
);
599 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
602 tmp
= load_cpu_field(ZF
);
603 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
606 tmp
= load_cpu_field(CF
);
607 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
610 tmp
= load_cpu_field(CF
);
611 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
614 tmp
= load_cpu_field(NF
);
615 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
618 tmp
= load_cpu_field(NF
);
619 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
622 tmp
= load_cpu_field(VF
);
623 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
626 tmp
= load_cpu_field(VF
);
627 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
629 case 8: /* hi: C && !Z */
630 inv
= gen_new_label();
631 tmp
= load_cpu_field(CF
);
632 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
634 tmp
= load_cpu_field(ZF
);
635 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
638 case 9: /* ls: !C || Z */
639 tmp
= load_cpu_field(CF
);
640 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
642 tmp
= load_cpu_field(ZF
);
643 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
645 case 10: /* ge: N == V -> N ^ V == 0 */
646 tmp
= load_cpu_field(VF
);
647 tmp2
= load_cpu_field(NF
);
648 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
650 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
652 case 11: /* lt: N != V -> N ^ V != 0 */
653 tmp
= load_cpu_field(VF
);
654 tmp2
= load_cpu_field(NF
);
655 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
657 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
659 case 12: /* gt: !Z && N == V */
660 inv
= gen_new_label();
661 tmp
= load_cpu_field(ZF
);
662 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
664 tmp
= load_cpu_field(VF
);
665 tmp2
= load_cpu_field(NF
);
666 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
668 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
671 case 13: /* le: Z || N != V */
672 tmp
= load_cpu_field(ZF
);
673 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
675 tmp
= load_cpu_field(VF
);
676 tmp2
= load_cpu_field(NF
);
677 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
679 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
682 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
688 static const uint8_t table_logic_cc
[16] = {
707 /* Set PC and Thumb state from an immediate address. */
708 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
712 s
->is_jmp
= DISAS_UPDATE
;
713 if (s
->thumb
!= (addr
& 1)) {
715 tcg_gen_movi_i32(tmp
, addr
& 1);
716 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUState
, thumb
));
719 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
722 /* Set PC and Thumb state from var. var is marked as dead. */
723 static inline void gen_bx(DisasContext
*s
, TCGv var
)
725 s
->is_jmp
= DISAS_UPDATE
;
726 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
727 tcg_gen_andi_i32(var
, var
, 1);
728 store_cpu_field(var
, thumb
);
731 /* Variant of store_reg which uses branch&exchange logic when storing
732 to r15 in ARM architecture v7 and above. The source must be a temporary
733 and will be marked as dead. */
734 static inline void store_reg_bx(CPUState
*env
, DisasContext
*s
,
737 if (reg
== 15 && ENABLE_ARCH_7
) {
740 store_reg(s
, reg
, var
);
744 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
746 TCGv tmp
= new_tmp();
747 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
750 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
752 TCGv tmp
= new_tmp();
753 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
756 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
758 TCGv tmp
= new_tmp();
759 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
762 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
764 TCGv tmp
= new_tmp();
765 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
768 static inline TCGv
gen_ld32(TCGv addr
, int index
)
770 TCGv tmp
= new_tmp();
771 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
774 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
776 TCGv_i64 tmp
= tcg_temp_new_i64();
777 tcg_gen_qemu_ld64(tmp
, addr
, index
);
780 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
782 tcg_gen_qemu_st8(val
, addr
, index
);
785 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
787 tcg_gen_qemu_st16(val
, addr
, index
);
790 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
792 tcg_gen_qemu_st32(val
, addr
, index
);
795 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
797 tcg_gen_qemu_st64(val
, addr
, index
);
798 tcg_temp_free_i64(val
);
801 static inline void gen_set_pc_im(uint32_t val
)
803 tcg_gen_movi_i32(cpu_R
[15], val
);
806 /* Force a TB lookup after an instruction that changes the CPU state. */
807 static inline void gen_lookup_tb(DisasContext
*s
)
809 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
810 s
->is_jmp
= DISAS_UPDATE
;
813 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
816 int val
, rm
, shift
, shiftop
;
819 if (!(insn
& (1 << 25))) {
822 if (!(insn
& (1 << 23)))
825 tcg_gen_addi_i32(var
, var
, val
);
829 shift
= (insn
>> 7) & 0x1f;
830 shiftop
= (insn
>> 5) & 3;
831 offset
= load_reg(s
, rm
);
832 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
833 if (!(insn
& (1 << 23)))
834 tcg_gen_sub_i32(var
, var
, offset
);
836 tcg_gen_add_i32(var
, var
, offset
);
841 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
847 if (insn
& (1 << 22)) {
849 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
850 if (!(insn
& (1 << 23)))
854 tcg_gen_addi_i32(var
, var
, val
);
858 tcg_gen_addi_i32(var
, var
, extra
);
860 offset
= load_reg(s
, rm
);
861 if (!(insn
& (1 << 23)))
862 tcg_gen_sub_i32(var
, var
, offset
);
864 tcg_gen_add_i32(var
, var
, offset
);
869 #define VFP_OP2(name) \
870 static inline void gen_vfp_##name(int dp) \
873 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
875 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
885 static inline void gen_vfp_abs(int dp
)
888 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
890 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
893 static inline void gen_vfp_neg(int dp
)
896 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
898 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
901 static inline void gen_vfp_sqrt(int dp
)
904 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
906 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
909 static inline void gen_vfp_cmp(int dp
)
912 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
914 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
917 static inline void gen_vfp_cmpe(int dp
)
920 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
922 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
925 static inline void gen_vfp_F1_ld0(int dp
)
928 tcg_gen_movi_i64(cpu_F1d
, 0);
930 tcg_gen_movi_i32(cpu_F1s
, 0);
933 static inline void gen_vfp_uito(int dp
)
936 gen_helper_vfp_uitod(cpu_F0d
, cpu_F0s
, cpu_env
);
938 gen_helper_vfp_uitos(cpu_F0s
, cpu_F0s
, cpu_env
);
941 static inline void gen_vfp_sito(int dp
)
944 gen_helper_vfp_sitod(cpu_F0d
, cpu_F0s
, cpu_env
);
946 gen_helper_vfp_sitos(cpu_F0s
, cpu_F0s
, cpu_env
);
949 static inline void gen_vfp_toui(int dp
)
952 gen_helper_vfp_touid(cpu_F0s
, cpu_F0d
, cpu_env
);
954 gen_helper_vfp_touis(cpu_F0s
, cpu_F0s
, cpu_env
);
957 static inline void gen_vfp_touiz(int dp
)
960 gen_helper_vfp_touizd(cpu_F0s
, cpu_F0d
, cpu_env
);
962 gen_helper_vfp_touizs(cpu_F0s
, cpu_F0s
, cpu_env
);
965 static inline void gen_vfp_tosi(int dp
)
968 gen_helper_vfp_tosid(cpu_F0s
, cpu_F0d
, cpu_env
);
970 gen_helper_vfp_tosis(cpu_F0s
, cpu_F0s
, cpu_env
);
973 static inline void gen_vfp_tosiz(int dp
)
976 gen_helper_vfp_tosizd(cpu_F0s
, cpu_F0d
, cpu_env
);
978 gen_helper_vfp_tosizs(cpu_F0s
, cpu_F0s
, cpu_env
);
981 #define VFP_GEN_FIX(name) \
982 static inline void gen_vfp_##name(int dp, int shift) \
984 TCGv tmp_shift = tcg_const_i32(shift); \
986 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
988 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
989 tcg_temp_free_i32(tmp_shift); \
1001 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1004 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1006 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1009 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1012 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1014 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1018 vfp_reg_offset (int dp
, int reg
)
1021 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1023 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1024 + offsetof(CPU_DoubleU
, l
.upper
);
1026 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1027 + offsetof(CPU_DoubleU
, l
.lower
);
1031 /* Return the offset of a 32-bit piece of a NEON register.
1032 zero is the least significant end of the register. */
1034 neon_reg_offset (int reg
, int n
)
1038 return vfp_reg_offset(0, sreg
);
1041 static TCGv
neon_load_reg(int reg
, int pass
)
1043 TCGv tmp
= new_tmp();
1044 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1048 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1050 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1054 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1056 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1059 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1061 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1064 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1065 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1066 #define tcg_gen_st_f32 tcg_gen_st_i32
1067 #define tcg_gen_st_f64 tcg_gen_st_i64
1069 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1072 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1074 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1077 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1080 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1082 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1085 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1088 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1090 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1093 #define ARM_CP_RW_BIT (1 << 20)
1095 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1097 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1100 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1102 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1105 static inline TCGv
iwmmxt_load_creg(int reg
)
1107 TCGv var
= new_tmp();
1108 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1112 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1114 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1117 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1119 iwmmxt_store_reg(cpu_M0
, rn
);
1122 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1124 iwmmxt_load_reg(cpu_M0
, rn
);
1127 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1129 iwmmxt_load_reg(cpu_V1
, rn
);
1130 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1133 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1135 iwmmxt_load_reg(cpu_V1
, rn
);
1136 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1139 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1141 iwmmxt_load_reg(cpu_V1
, rn
);
1142 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1145 #define IWMMXT_OP(name) \
1146 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1148 iwmmxt_load_reg(cpu_V1, rn); \
1149 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1152 #define IWMMXT_OP_ENV(name) \
1153 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1155 iwmmxt_load_reg(cpu_V1, rn); \
1156 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1159 #define IWMMXT_OP_ENV_SIZE(name) \
1160 IWMMXT_OP_ENV(name##b) \
1161 IWMMXT_OP_ENV(name##w) \
1162 IWMMXT_OP_ENV(name##l)
1164 #define IWMMXT_OP_ENV1(name) \
1165 static inline void gen_op_iwmmxt_##name##_M0(void) \
1167 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1181 IWMMXT_OP_ENV_SIZE(unpackl
)
1182 IWMMXT_OP_ENV_SIZE(unpackh
)
1184 IWMMXT_OP_ENV1(unpacklub
)
1185 IWMMXT_OP_ENV1(unpackluw
)
1186 IWMMXT_OP_ENV1(unpacklul
)
1187 IWMMXT_OP_ENV1(unpackhub
)
1188 IWMMXT_OP_ENV1(unpackhuw
)
1189 IWMMXT_OP_ENV1(unpackhul
)
1190 IWMMXT_OP_ENV1(unpacklsb
)
1191 IWMMXT_OP_ENV1(unpacklsw
)
1192 IWMMXT_OP_ENV1(unpacklsl
)
1193 IWMMXT_OP_ENV1(unpackhsb
)
1194 IWMMXT_OP_ENV1(unpackhsw
)
1195 IWMMXT_OP_ENV1(unpackhsl
)
1197 IWMMXT_OP_ENV_SIZE(cmpeq
)
1198 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1199 IWMMXT_OP_ENV_SIZE(cmpgts
)
1201 IWMMXT_OP_ENV_SIZE(mins
)
1202 IWMMXT_OP_ENV_SIZE(minu
)
1203 IWMMXT_OP_ENV_SIZE(maxs
)
1204 IWMMXT_OP_ENV_SIZE(maxu
)
1206 IWMMXT_OP_ENV_SIZE(subn
)
1207 IWMMXT_OP_ENV_SIZE(addn
)
1208 IWMMXT_OP_ENV_SIZE(subu
)
1209 IWMMXT_OP_ENV_SIZE(addu
)
1210 IWMMXT_OP_ENV_SIZE(subs
)
1211 IWMMXT_OP_ENV_SIZE(adds
)
1213 IWMMXT_OP_ENV(avgb0
)
1214 IWMMXT_OP_ENV(avgb1
)
1215 IWMMXT_OP_ENV(avgw0
)
1216 IWMMXT_OP_ENV(avgw1
)
1220 IWMMXT_OP_ENV(packuw
)
1221 IWMMXT_OP_ENV(packul
)
1222 IWMMXT_OP_ENV(packuq
)
1223 IWMMXT_OP_ENV(packsw
)
1224 IWMMXT_OP_ENV(packsl
)
1225 IWMMXT_OP_ENV(packsq
)
1227 static void gen_op_iwmmxt_set_mup(void)
1230 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1231 tcg_gen_ori_i32(tmp
, tmp
, 2);
1232 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1235 static void gen_op_iwmmxt_set_cup(void)
1238 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1239 tcg_gen_ori_i32(tmp
, tmp
, 1);
1240 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1243 static void gen_op_iwmmxt_setpsr_nz(void)
1245 TCGv tmp
= new_tmp();
1246 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1247 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1250 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1252 iwmmxt_load_reg(cpu_V1
, rn
);
1253 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1254 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1257 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1263 rd
= (insn
>> 16) & 0xf;
1264 tmp
= load_reg(s
, rd
);
1266 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1267 if (insn
& (1 << 24)) {
1269 if (insn
& (1 << 23))
1270 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1272 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1273 tcg_gen_mov_i32(dest
, tmp
);
1274 if (insn
& (1 << 21))
1275 store_reg(s
, rd
, tmp
);
1278 } else if (insn
& (1 << 21)) {
1280 tcg_gen_mov_i32(dest
, tmp
);
1281 if (insn
& (1 << 23))
1282 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1284 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1285 store_reg(s
, rd
, tmp
);
1286 } else if (!(insn
& (1 << 23)))
1291 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1293 int rd
= (insn
>> 0) & 0xf;
1296 if (insn
& (1 << 8)) {
1297 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1300 tmp
= iwmmxt_load_creg(rd
);
1304 iwmmxt_load_reg(cpu_V0
, rd
);
1305 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1307 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1308 tcg_gen_mov_i32(dest
, tmp
);
1313 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1314 (ie. an undefined instruction). */
1315 static int disas_iwmmxt_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
1318 int rdhi
, rdlo
, rd0
, rd1
, i
;
1320 TCGv tmp
, tmp2
, tmp3
;
1322 if ((insn
& 0x0e000e00) == 0x0c000000) {
1323 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1325 rdlo
= (insn
>> 12) & 0xf;
1326 rdhi
= (insn
>> 16) & 0xf;
1327 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1328 iwmmxt_load_reg(cpu_V0
, wrd
);
1329 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1330 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1331 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1332 } else { /* TMCRR */
1333 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1334 iwmmxt_store_reg(cpu_V0
, wrd
);
1335 gen_op_iwmmxt_set_mup();
1340 wrd
= (insn
>> 12) & 0xf;
1342 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1346 if (insn
& ARM_CP_RW_BIT
) {
1347 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1349 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1350 iwmmxt_store_creg(wrd
, tmp
);
1353 if (insn
& (1 << 8)) {
1354 if (insn
& (1 << 22)) { /* WLDRD */
1355 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1357 } else { /* WLDRW wRd */
1358 tmp
= gen_ld32(addr
, IS_USER(s
));
1361 if (insn
& (1 << 22)) { /* WLDRH */
1362 tmp
= gen_ld16u(addr
, IS_USER(s
));
1363 } else { /* WLDRB */
1364 tmp
= gen_ld8u(addr
, IS_USER(s
));
1368 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1371 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1374 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1375 tmp
= iwmmxt_load_creg(wrd
);
1376 gen_st32(tmp
, addr
, IS_USER(s
));
1378 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1380 if (insn
& (1 << 8)) {
1381 if (insn
& (1 << 22)) { /* WSTRD */
1383 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1384 } else { /* WSTRW wRd */
1385 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1386 gen_st32(tmp
, addr
, IS_USER(s
));
1389 if (insn
& (1 << 22)) { /* WSTRH */
1390 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1391 gen_st16(tmp
, addr
, IS_USER(s
));
1392 } else { /* WSTRB */
1393 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1394 gen_st8(tmp
, addr
, IS_USER(s
));
1402 if ((insn
& 0x0f000000) != 0x0e000000)
1405 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1406 case 0x000: /* WOR */
1407 wrd
= (insn
>> 12) & 0xf;
1408 rd0
= (insn
>> 0) & 0xf;
1409 rd1
= (insn
>> 16) & 0xf;
1410 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1411 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1412 gen_op_iwmmxt_setpsr_nz();
1413 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1414 gen_op_iwmmxt_set_mup();
1415 gen_op_iwmmxt_set_cup();
1417 case 0x011: /* TMCR */
1420 rd
= (insn
>> 12) & 0xf;
1421 wrd
= (insn
>> 16) & 0xf;
1423 case ARM_IWMMXT_wCID
:
1424 case ARM_IWMMXT_wCASF
:
1426 case ARM_IWMMXT_wCon
:
1427 gen_op_iwmmxt_set_cup();
1429 case ARM_IWMMXT_wCSSF
:
1430 tmp
= iwmmxt_load_creg(wrd
);
1431 tmp2
= load_reg(s
, rd
);
1432 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1434 iwmmxt_store_creg(wrd
, tmp
);
1436 case ARM_IWMMXT_wCGR0
:
1437 case ARM_IWMMXT_wCGR1
:
1438 case ARM_IWMMXT_wCGR2
:
1439 case ARM_IWMMXT_wCGR3
:
1440 gen_op_iwmmxt_set_cup();
1441 tmp
= load_reg(s
, rd
);
1442 iwmmxt_store_creg(wrd
, tmp
);
1448 case 0x100: /* WXOR */
1449 wrd
= (insn
>> 12) & 0xf;
1450 rd0
= (insn
>> 0) & 0xf;
1451 rd1
= (insn
>> 16) & 0xf;
1452 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1453 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1454 gen_op_iwmmxt_setpsr_nz();
1455 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1456 gen_op_iwmmxt_set_mup();
1457 gen_op_iwmmxt_set_cup();
1459 case 0x111: /* TMRC */
1462 rd
= (insn
>> 12) & 0xf;
1463 wrd
= (insn
>> 16) & 0xf;
1464 tmp
= iwmmxt_load_creg(wrd
);
1465 store_reg(s
, rd
, tmp
);
1467 case 0x300: /* WANDN */
1468 wrd
= (insn
>> 12) & 0xf;
1469 rd0
= (insn
>> 0) & 0xf;
1470 rd1
= (insn
>> 16) & 0xf;
1471 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1472 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1473 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1474 gen_op_iwmmxt_setpsr_nz();
1475 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1476 gen_op_iwmmxt_set_mup();
1477 gen_op_iwmmxt_set_cup();
1479 case 0x200: /* WAND */
1480 wrd
= (insn
>> 12) & 0xf;
1481 rd0
= (insn
>> 0) & 0xf;
1482 rd1
= (insn
>> 16) & 0xf;
1483 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1484 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1485 gen_op_iwmmxt_setpsr_nz();
1486 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1487 gen_op_iwmmxt_set_mup();
1488 gen_op_iwmmxt_set_cup();
1490 case 0x810: case 0xa10: /* WMADD */
1491 wrd
= (insn
>> 12) & 0xf;
1492 rd0
= (insn
>> 0) & 0xf;
1493 rd1
= (insn
>> 16) & 0xf;
1494 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1495 if (insn
& (1 << 21))
1496 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1498 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1499 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1500 gen_op_iwmmxt_set_mup();
1502 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1503 wrd
= (insn
>> 12) & 0xf;
1504 rd0
= (insn
>> 16) & 0xf;
1505 rd1
= (insn
>> 0) & 0xf;
1506 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1507 switch ((insn
>> 22) & 3) {
1509 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1512 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1515 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1520 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1521 gen_op_iwmmxt_set_mup();
1522 gen_op_iwmmxt_set_cup();
1524 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1525 wrd
= (insn
>> 12) & 0xf;
1526 rd0
= (insn
>> 16) & 0xf;
1527 rd1
= (insn
>> 0) & 0xf;
1528 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1529 switch ((insn
>> 22) & 3) {
1531 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1534 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1537 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1543 gen_op_iwmmxt_set_mup();
1544 gen_op_iwmmxt_set_cup();
1546 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1547 wrd
= (insn
>> 12) & 0xf;
1548 rd0
= (insn
>> 16) & 0xf;
1549 rd1
= (insn
>> 0) & 0xf;
1550 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1551 if (insn
& (1 << 22))
1552 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1554 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1555 if (!(insn
& (1 << 20)))
1556 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1557 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1558 gen_op_iwmmxt_set_mup();
1560 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1561 wrd
= (insn
>> 12) & 0xf;
1562 rd0
= (insn
>> 16) & 0xf;
1563 rd1
= (insn
>> 0) & 0xf;
1564 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1565 if (insn
& (1 << 21)) {
1566 if (insn
& (1 << 20))
1567 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1569 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1571 if (insn
& (1 << 20))
1572 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1574 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1576 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1577 gen_op_iwmmxt_set_mup();
1579 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1580 wrd
= (insn
>> 12) & 0xf;
1581 rd0
= (insn
>> 16) & 0xf;
1582 rd1
= (insn
>> 0) & 0xf;
1583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1584 if (insn
& (1 << 21))
1585 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1587 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1588 if (!(insn
& (1 << 20))) {
1589 iwmmxt_load_reg(cpu_V1
, wrd
);
1590 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1592 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1593 gen_op_iwmmxt_set_mup();
1595 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1596 wrd
= (insn
>> 12) & 0xf;
1597 rd0
= (insn
>> 16) & 0xf;
1598 rd1
= (insn
>> 0) & 0xf;
1599 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1600 switch ((insn
>> 22) & 3) {
1602 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1605 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1608 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1613 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1614 gen_op_iwmmxt_set_mup();
1615 gen_op_iwmmxt_set_cup();
1617 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1618 wrd
= (insn
>> 12) & 0xf;
1619 rd0
= (insn
>> 16) & 0xf;
1620 rd1
= (insn
>> 0) & 0xf;
1621 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1622 if (insn
& (1 << 22)) {
1623 if (insn
& (1 << 20))
1624 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1626 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1628 if (insn
& (1 << 20))
1629 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1631 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1633 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1634 gen_op_iwmmxt_set_mup();
1635 gen_op_iwmmxt_set_cup();
1637 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1638 wrd
= (insn
>> 12) & 0xf;
1639 rd0
= (insn
>> 16) & 0xf;
1640 rd1
= (insn
>> 0) & 0xf;
1641 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1642 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1643 tcg_gen_andi_i32(tmp
, tmp
, 7);
1644 iwmmxt_load_reg(cpu_V1
, rd1
);
1645 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1647 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1648 gen_op_iwmmxt_set_mup();
1650 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1651 if (((insn
>> 6) & 3) == 3)
1653 rd
= (insn
>> 12) & 0xf;
1654 wrd
= (insn
>> 16) & 0xf;
1655 tmp
= load_reg(s
, rd
);
1656 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1657 switch ((insn
>> 6) & 3) {
1659 tmp2
= tcg_const_i32(0xff);
1660 tmp3
= tcg_const_i32((insn
& 7) << 3);
1663 tmp2
= tcg_const_i32(0xffff);
1664 tmp3
= tcg_const_i32((insn
& 3) << 4);
1667 tmp2
= tcg_const_i32(0xffffffff);
1668 tmp3
= tcg_const_i32((insn
& 1) << 5);
1674 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1675 tcg_temp_free(tmp3
);
1676 tcg_temp_free(tmp2
);
1678 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1679 gen_op_iwmmxt_set_mup();
1681 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1682 rd
= (insn
>> 12) & 0xf;
1683 wrd
= (insn
>> 16) & 0xf;
1684 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1686 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1688 switch ((insn
>> 22) & 3) {
1690 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1691 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1693 tcg_gen_ext8s_i32(tmp
, tmp
);
1695 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1699 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1700 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1702 tcg_gen_ext16s_i32(tmp
, tmp
);
1704 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1708 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1709 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1712 store_reg(s
, rd
, tmp
);
1714 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1715 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1717 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1718 switch ((insn
>> 22) & 3) {
1720 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1723 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1726 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1729 tcg_gen_shli_i32(tmp
, tmp
, 28);
1733 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1734 if (((insn
>> 6) & 3) == 3)
1736 rd
= (insn
>> 12) & 0xf;
1737 wrd
= (insn
>> 16) & 0xf;
1738 tmp
= load_reg(s
, rd
);
1739 switch ((insn
>> 6) & 3) {
1741 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1744 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1747 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1751 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1752 gen_op_iwmmxt_set_mup();
1754 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1755 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1757 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1759 tcg_gen_mov_i32(tmp2
, tmp
);
1760 switch ((insn
>> 22) & 3) {
1762 for (i
= 0; i
< 7; i
++) {
1763 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1764 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1768 for (i
= 0; i
< 3; i
++) {
1769 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1770 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1774 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1775 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1782 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1783 wrd
= (insn
>> 12) & 0xf;
1784 rd0
= (insn
>> 16) & 0xf;
1785 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1786 switch ((insn
>> 22) & 3) {
1788 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1791 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1794 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1799 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1800 gen_op_iwmmxt_set_mup();
1802 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1803 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1805 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1807 tcg_gen_mov_i32(tmp2
, tmp
);
1808 switch ((insn
>> 22) & 3) {
1810 for (i
= 0; i
< 7; i
++) {
1811 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1812 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1816 for (i
= 0; i
< 3; i
++) {
1817 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1818 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1822 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1823 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1830 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1831 rd
= (insn
>> 12) & 0xf;
1832 rd0
= (insn
>> 16) & 0xf;
1833 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1835 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1837 switch ((insn
>> 22) & 3) {
1839 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1842 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1845 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1848 store_reg(s
, rd
, tmp
);
1850 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1851 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1852 wrd
= (insn
>> 12) & 0xf;
1853 rd0
= (insn
>> 16) & 0xf;
1854 rd1
= (insn
>> 0) & 0xf;
1855 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1856 switch ((insn
>> 22) & 3) {
1858 if (insn
& (1 << 21))
1859 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1861 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1864 if (insn
& (1 << 21))
1865 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1867 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1870 if (insn
& (1 << 21))
1871 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1873 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1879 gen_op_iwmmxt_set_mup();
1880 gen_op_iwmmxt_set_cup();
1882 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1883 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1884 wrd
= (insn
>> 12) & 0xf;
1885 rd0
= (insn
>> 16) & 0xf;
1886 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1887 switch ((insn
>> 22) & 3) {
1889 if (insn
& (1 << 21))
1890 gen_op_iwmmxt_unpacklsb_M0();
1892 gen_op_iwmmxt_unpacklub_M0();
1895 if (insn
& (1 << 21))
1896 gen_op_iwmmxt_unpacklsw_M0();
1898 gen_op_iwmmxt_unpackluw_M0();
1901 if (insn
& (1 << 21))
1902 gen_op_iwmmxt_unpacklsl_M0();
1904 gen_op_iwmmxt_unpacklul_M0();
1909 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1910 gen_op_iwmmxt_set_mup();
1911 gen_op_iwmmxt_set_cup();
1913 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1914 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1915 wrd
= (insn
>> 12) & 0xf;
1916 rd0
= (insn
>> 16) & 0xf;
1917 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1918 switch ((insn
>> 22) & 3) {
1920 if (insn
& (1 << 21))
1921 gen_op_iwmmxt_unpackhsb_M0();
1923 gen_op_iwmmxt_unpackhub_M0();
1926 if (insn
& (1 << 21))
1927 gen_op_iwmmxt_unpackhsw_M0();
1929 gen_op_iwmmxt_unpackhuw_M0();
1932 if (insn
& (1 << 21))
1933 gen_op_iwmmxt_unpackhsl_M0();
1935 gen_op_iwmmxt_unpackhul_M0();
1940 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1941 gen_op_iwmmxt_set_mup();
1942 gen_op_iwmmxt_set_cup();
1944 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1945 case 0x214: case 0x614: case 0xa14: case 0xe14:
1946 if (((insn
>> 22) & 3) == 0)
1948 wrd
= (insn
>> 12) & 0xf;
1949 rd0
= (insn
>> 16) & 0xf;
1950 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1952 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1956 switch ((insn
>> 22) & 3) {
1958 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1961 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1964 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1969 gen_op_iwmmxt_set_mup();
1970 gen_op_iwmmxt_set_cup();
1972 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
1973 case 0x014: case 0x414: case 0x814: case 0xc14:
1974 if (((insn
>> 22) & 3) == 0)
1976 wrd
= (insn
>> 12) & 0xf;
1977 rd0
= (insn
>> 16) & 0xf;
1978 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1980 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1984 switch ((insn
>> 22) & 3) {
1986 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1989 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1992 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1996 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1997 gen_op_iwmmxt_set_mup();
1998 gen_op_iwmmxt_set_cup();
2000 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2001 case 0x114: case 0x514: case 0x914: case 0xd14:
2002 if (((insn
>> 22) & 3) == 0)
2004 wrd
= (insn
>> 12) & 0xf;
2005 rd0
= (insn
>> 16) & 0xf;
2006 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2008 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2012 switch ((insn
>> 22) & 3) {
2014 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2017 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2020 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2024 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2025 gen_op_iwmmxt_set_mup();
2026 gen_op_iwmmxt_set_cup();
2028 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2029 case 0x314: case 0x714: case 0xb14: case 0xf14:
2030 if (((insn
>> 22) & 3) == 0)
2032 wrd
= (insn
>> 12) & 0xf;
2033 rd0
= (insn
>> 16) & 0xf;
2034 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2036 switch ((insn
>> 22) & 3) {
2038 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2042 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2045 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2049 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2052 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2056 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2060 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2061 gen_op_iwmmxt_set_mup();
2062 gen_op_iwmmxt_set_cup();
2064 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2065 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2066 wrd
= (insn
>> 12) & 0xf;
2067 rd0
= (insn
>> 16) & 0xf;
2068 rd1
= (insn
>> 0) & 0xf;
2069 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2070 switch ((insn
>> 22) & 3) {
2072 if (insn
& (1 << 21))
2073 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2075 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2078 if (insn
& (1 << 21))
2079 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2081 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2084 if (insn
& (1 << 21))
2085 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2087 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2092 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2093 gen_op_iwmmxt_set_mup();
2095 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2096 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2097 wrd
= (insn
>> 12) & 0xf;
2098 rd0
= (insn
>> 16) & 0xf;
2099 rd1
= (insn
>> 0) & 0xf;
2100 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2101 switch ((insn
>> 22) & 3) {
2103 if (insn
& (1 << 21))
2104 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2106 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2109 if (insn
& (1 << 21))
2110 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2112 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2115 if (insn
& (1 << 21))
2116 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2118 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2123 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2124 gen_op_iwmmxt_set_mup();
2126 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2127 case 0x402: case 0x502: case 0x602: case 0x702:
2128 wrd
= (insn
>> 12) & 0xf;
2129 rd0
= (insn
>> 16) & 0xf;
2130 rd1
= (insn
>> 0) & 0xf;
2131 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2132 tmp
= tcg_const_i32((insn
>> 20) & 3);
2133 iwmmxt_load_reg(cpu_V1
, rd1
);
2134 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2136 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2137 gen_op_iwmmxt_set_mup();
2139 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2140 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2141 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2142 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2143 wrd
= (insn
>> 12) & 0xf;
2144 rd0
= (insn
>> 16) & 0xf;
2145 rd1
= (insn
>> 0) & 0xf;
2146 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2147 switch ((insn
>> 20) & 0xf) {
2149 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2152 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2155 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2158 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2161 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2164 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2167 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2170 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2173 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2178 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2179 gen_op_iwmmxt_set_mup();
2180 gen_op_iwmmxt_set_cup();
2182 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2183 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2184 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2185 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2186 wrd
= (insn
>> 12) & 0xf;
2187 rd0
= (insn
>> 16) & 0xf;
2188 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2189 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2190 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2193 gen_op_iwmmxt_set_mup();
2194 gen_op_iwmmxt_set_cup();
2196 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2197 case 0x418: case 0x518: case 0x618: case 0x718:
2198 case 0x818: case 0x918: case 0xa18: case 0xb18:
2199 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2200 wrd
= (insn
>> 12) & 0xf;
2201 rd0
= (insn
>> 16) & 0xf;
2202 rd1
= (insn
>> 0) & 0xf;
2203 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2204 switch ((insn
>> 20) & 0xf) {
2206 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2209 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2212 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2215 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2218 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2221 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2224 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2227 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2230 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2235 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2236 gen_op_iwmmxt_set_mup();
2237 gen_op_iwmmxt_set_cup();
2239 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2240 case 0x408: case 0x508: case 0x608: case 0x708:
2241 case 0x808: case 0x908: case 0xa08: case 0xb08:
2242 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2243 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2245 wrd
= (insn
>> 12) & 0xf;
2246 rd0
= (insn
>> 16) & 0xf;
2247 rd1
= (insn
>> 0) & 0xf;
2248 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2249 switch ((insn
>> 22) & 3) {
2251 if (insn
& (1 << 21))
2252 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2254 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2257 if (insn
& (1 << 21))
2258 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2260 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2263 if (insn
& (1 << 21))
2264 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2266 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2269 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2270 gen_op_iwmmxt_set_mup();
2271 gen_op_iwmmxt_set_cup();
2273 case 0x201: case 0x203: case 0x205: case 0x207:
2274 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2275 case 0x211: case 0x213: case 0x215: case 0x217:
2276 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2277 wrd
= (insn
>> 5) & 0xf;
2278 rd0
= (insn
>> 12) & 0xf;
2279 rd1
= (insn
>> 0) & 0xf;
2280 if (rd0
== 0xf || rd1
== 0xf)
2282 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2283 tmp
= load_reg(s
, rd0
);
2284 tmp2
= load_reg(s
, rd1
);
2285 switch ((insn
>> 16) & 0xf) {
2286 case 0x0: /* TMIA */
2287 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2289 case 0x8: /* TMIAPH */
2290 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2292 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2293 if (insn
& (1 << 16))
2294 tcg_gen_shri_i32(tmp
, tmp
, 16);
2295 if (insn
& (1 << 17))
2296 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2297 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2306 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2307 gen_op_iwmmxt_set_mup();
2316 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2317 (ie. an undefined instruction). */
2318 static int disas_dsp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2320 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2323 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2324 /* Multiply with Internal Accumulate Format */
2325 rd0
= (insn
>> 12) & 0xf;
2327 acc
= (insn
>> 5) & 7;
2332 tmp
= load_reg(s
, rd0
);
2333 tmp2
= load_reg(s
, rd1
);
2334 switch ((insn
>> 16) & 0xf) {
2336 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2338 case 0x8: /* MIAPH */
2339 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2341 case 0xc: /* MIABB */
2342 case 0xd: /* MIABT */
2343 case 0xe: /* MIATB */
2344 case 0xf: /* MIATT */
2345 if (insn
& (1 << 16))
2346 tcg_gen_shri_i32(tmp
, tmp
, 16);
2347 if (insn
& (1 << 17))
2348 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2349 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2357 gen_op_iwmmxt_movq_wRn_M0(acc
);
2361 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2362 /* Internal Accumulator Access Format */
2363 rdhi
= (insn
>> 16) & 0xf;
2364 rdlo
= (insn
>> 12) & 0xf;
2370 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2371 iwmmxt_load_reg(cpu_V0
, acc
);
2372 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2373 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2374 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2375 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2377 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2378 iwmmxt_store_reg(cpu_V0
, acc
);
2386 /* Disassemble system coprocessor instruction. Return nonzero if
2387 instruction is not defined. */
2388 static int disas_cp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2391 uint32_t rd
= (insn
>> 12) & 0xf;
2392 uint32_t cp
= (insn
>> 8) & 0xf;
2397 if (insn
& ARM_CP_RW_BIT
) {
2398 if (!env
->cp
[cp
].cp_read
)
2400 gen_set_pc_im(s
->pc
);
2402 tmp2
= tcg_const_i32(insn
);
2403 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2404 tcg_temp_free(tmp2
);
2405 store_reg(s
, rd
, tmp
);
2407 if (!env
->cp
[cp
].cp_write
)
2409 gen_set_pc_im(s
->pc
);
2410 tmp
= load_reg(s
, rd
);
2411 tmp2
= tcg_const_i32(insn
);
2412 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2413 tcg_temp_free(tmp2
);
2419 static int cp15_user_ok(uint32_t insn
)
2421 int cpn
= (insn
>> 16) & 0xf;
2422 int cpm
= insn
& 0xf;
2423 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2425 if (cpn
== 13 && cpm
== 0) {
2427 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2431 /* ISB, DSB, DMB. */
2432 if ((cpm
== 5 && op
== 4)
2433 || (cpm
== 10 && (op
== 4 || op
== 5)))
2439 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2440 instruction is not defined. */
2441 static int disas_cp15_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2446 /* M profile cores use memory mapped registers instead of cp15. */
2447 if (arm_feature(env
, ARM_FEATURE_M
))
2450 if ((insn
& (1 << 25)) == 0) {
2451 if (insn
& (1 << 20)) {
2455 /* mcrr. Used for block cache operations, so implement as no-op. */
2458 if ((insn
& (1 << 4)) == 0) {
2462 if (IS_USER(s
) && !cp15_user_ok(insn
)) {
2465 if ((insn
& 0x0fff0fff) == 0x0e070f90
2466 || (insn
& 0x0fff0fff) == 0x0e070f58) {
2467 /* Wait for interrupt. */
2468 gen_set_pc_im(s
->pc
);
2469 s
->is_jmp
= DISAS_WFI
;
2472 rd
= (insn
>> 12) & 0xf;
2473 tmp2
= tcg_const_i32(insn
);
2474 if (insn
& ARM_CP_RW_BIT
) {
2476 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2477 /* If the destination register is r15 then sets condition codes. */
2479 store_reg(s
, rd
, tmp
);
2483 tmp
= load_reg(s
, rd
);
2484 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2486 /* Normally we would always end the TB here, but Linux
2487 * arch/arm/mach-pxa/sleep.S expects two instructions following
2488 * an MMU enable to execute from cache. Imitate this behaviour. */
2489 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2490 (insn
& 0x0fff0fff) != 0x0e010f10)
2493 tcg_temp_free_i32(tmp2
);
2497 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2498 #define VFP_SREG(insn, bigbit, smallbit) \
2499 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2500 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2501 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2502 reg = (((insn) >> (bigbit)) & 0x0f) \
2503 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2505 if (insn & (1 << (smallbit))) \
2507 reg = ((insn) >> (bigbit)) & 0x0f; \
2510 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2511 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2512 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2513 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2514 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2515 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2517 /* Move between integer and VFP cores. */
2518 static TCGv
gen_vfp_mrs(void)
2520 TCGv tmp
= new_tmp();
2521 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2525 static void gen_vfp_msr(TCGv tmp
)
2527 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2532 vfp_enabled(CPUState
* env
)
2534 return ((env
->vfp
.xregs
[ARM_VFP_FPEXC
] & (1 << 30)) != 0);
2537 static void gen_neon_dup_u8(TCGv var
, int shift
)
2539 TCGv tmp
= new_tmp();
2541 tcg_gen_shri_i32(var
, var
, shift
);
2542 tcg_gen_ext8u_i32(var
, var
);
2543 tcg_gen_shli_i32(tmp
, var
, 8);
2544 tcg_gen_or_i32(var
, var
, tmp
);
2545 tcg_gen_shli_i32(tmp
, var
, 16);
2546 tcg_gen_or_i32(var
, var
, tmp
);
2550 static void gen_neon_dup_low16(TCGv var
)
2552 TCGv tmp
= new_tmp();
2553 tcg_gen_ext16u_i32(var
, var
);
2554 tcg_gen_shli_i32(tmp
, var
, 16);
2555 tcg_gen_or_i32(var
, var
, tmp
);
2559 static void gen_neon_dup_high16(TCGv var
)
2561 TCGv tmp
= new_tmp();
2562 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2563 tcg_gen_shri_i32(tmp
, var
, 16);
2564 tcg_gen_or_i32(var
, var
, tmp
);
2568 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2569 (ie. an undefined instruction). */
2570 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2572 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2578 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2581 if (!vfp_enabled(env
)) {
2582 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2583 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2585 rn
= (insn
>> 16) & 0xf;
2586 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2587 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2590 dp
= ((insn
& 0xf00) == 0xb00);
2591 switch ((insn
>> 24) & 0xf) {
2593 if (insn
& (1 << 4)) {
2594 /* single register transfer */
2595 rd
= (insn
>> 12) & 0xf;
2600 VFP_DREG_N(rn
, insn
);
2603 if (insn
& 0x00c00060
2604 && !arm_feature(env
, ARM_FEATURE_NEON
))
2607 pass
= (insn
>> 21) & 1;
2608 if (insn
& (1 << 22)) {
2610 offset
= ((insn
>> 5) & 3) * 8;
2611 } else if (insn
& (1 << 5)) {
2613 offset
= (insn
& (1 << 6)) ? 16 : 0;
2618 if (insn
& ARM_CP_RW_BIT
) {
2620 tmp
= neon_load_reg(rn
, pass
);
2624 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2625 if (insn
& (1 << 23))
2631 if (insn
& (1 << 23)) {
2633 tcg_gen_shri_i32(tmp
, tmp
, 16);
2639 tcg_gen_sari_i32(tmp
, tmp
, 16);
2648 store_reg(s
, rd
, tmp
);
2651 tmp
= load_reg(s
, rd
);
2652 if (insn
& (1 << 23)) {
2655 gen_neon_dup_u8(tmp
, 0);
2656 } else if (size
== 1) {
2657 gen_neon_dup_low16(tmp
);
2659 for (n
= 0; n
<= pass
* 2; n
++) {
2661 tcg_gen_mov_i32(tmp2
, tmp
);
2662 neon_store_reg(rn
, n
, tmp2
);
2664 neon_store_reg(rn
, n
, tmp
);
2669 tmp2
= neon_load_reg(rn
, pass
);
2670 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2674 tmp2
= neon_load_reg(rn
, pass
);
2675 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2681 neon_store_reg(rn
, pass
, tmp
);
2685 if ((insn
& 0x6f) != 0x00)
2687 rn
= VFP_SREG_N(insn
);
2688 if (insn
& ARM_CP_RW_BIT
) {
2690 if (insn
& (1 << 21)) {
2691 /* system register */
2696 /* VFP2 allows access to FSID from userspace.
2697 VFP3 restricts all id registers to privileged
2700 && arm_feature(env
, ARM_FEATURE_VFP3
))
2702 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2707 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2709 case ARM_VFP_FPINST
:
2710 case ARM_VFP_FPINST2
:
2711 /* Not present in VFP3. */
2713 || arm_feature(env
, ARM_FEATURE_VFP3
))
2715 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2719 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2720 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2723 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2729 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2731 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2737 gen_mov_F0_vreg(0, rn
);
2738 tmp
= gen_vfp_mrs();
2741 /* Set the 4 flag bits in the CPSR. */
2745 store_reg(s
, rd
, tmp
);
2749 tmp
= load_reg(s
, rd
);
2750 if (insn
& (1 << 21)) {
2752 /* system register */
2757 /* Writes are ignored. */
2760 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2767 /* TODO: VFP subarchitecture support.
2768 * For now, keep the EN bit only */
2769 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2770 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2773 case ARM_VFP_FPINST
:
2774 case ARM_VFP_FPINST2
:
2775 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2782 gen_mov_vreg_F0(0, rn
);
2787 /* data processing */
2788 /* The opcode is in bits 23, 21, 20 and 6. */
2789 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2793 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2795 /* rn is register number */
2796 VFP_DREG_N(rn
, insn
);
2799 if (op
== 15 && (rn
== 15 || rn
> 17)) {
2800 /* Integer or single precision destination. */
2801 rd
= VFP_SREG_D(insn
);
2803 VFP_DREG_D(rd
, insn
);
2806 if (op
== 15 && (rn
== 16 || rn
== 17)) {
2807 /* Integer source. */
2808 rm
= ((insn
<< 1) & 0x1e) | ((insn
>> 5) & 1);
2810 VFP_DREG_M(rm
, insn
);
2813 rn
= VFP_SREG_N(insn
);
2814 if (op
== 15 && rn
== 15) {
2815 /* Double precision destination. */
2816 VFP_DREG_D(rd
, insn
);
2818 rd
= VFP_SREG_D(insn
);
2820 rm
= VFP_SREG_M(insn
);
2823 veclen
= env
->vfp
.vec_len
;
2824 if (op
== 15 && rn
> 3)
2827 /* Shut up compiler warnings. */
2838 /* Figure out what type of vector operation this is. */
2839 if ((rd
& bank_mask
) == 0) {
2844 delta_d
= (env
->vfp
.vec_stride
>> 1) + 1;
2846 delta_d
= env
->vfp
.vec_stride
+ 1;
2848 if ((rm
& bank_mask
) == 0) {
2849 /* mixed scalar/vector */
2858 /* Load the initial operands. */
2863 /* Integer source */
2864 gen_mov_F0_vreg(0, rm
);
2869 gen_mov_F0_vreg(dp
, rd
);
2870 gen_mov_F1_vreg(dp
, rm
);
2874 /* Compare with zero */
2875 gen_mov_F0_vreg(dp
, rd
);
2886 /* Source and destination the same. */
2887 gen_mov_F0_vreg(dp
, rd
);
2890 /* One source operand. */
2891 gen_mov_F0_vreg(dp
, rm
);
2895 /* Two source operands. */
2896 gen_mov_F0_vreg(dp
, rn
);
2897 gen_mov_F1_vreg(dp
, rm
);
2901 /* Perform the calculation. */
2903 case 0: /* mac: fd + (fn * fm) */
2905 gen_mov_F1_vreg(dp
, rd
);
2908 case 1: /* nmac: fd - (fn * fm) */
2911 gen_mov_F1_vreg(dp
, rd
);
2914 case 2: /* msc: -fd + (fn * fm) */
2916 gen_mov_F1_vreg(dp
, rd
);
2919 case 3: /* nmsc: -fd - (fn * fm) */
2922 gen_mov_F1_vreg(dp
, rd
);
2925 case 4: /* mul: fn * fm */
2928 case 5: /* nmul: -(fn * fm) */
2932 case 6: /* add: fn + fm */
2935 case 7: /* sub: fn - fm */
2938 case 8: /* div: fn / fm */
2941 case 14: /* fconst */
2942 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
2945 n
= (insn
<< 12) & 0x80000000;
2946 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
2953 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
2960 tcg_gen_movi_i32(cpu_F0s
, n
);
2963 case 15: /* extension space */
2986 case 11: /* cmpez */
2990 case 15: /* single<->double conversion */
2992 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
2994 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
2996 case 16: /* fuito */
2999 case 17: /* fsito */
3002 case 20: /* fshto */
3003 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3005 gen_vfp_shto(dp
, 16 - rm
);
3007 case 21: /* fslto */
3008 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3010 gen_vfp_slto(dp
, 32 - rm
);
3012 case 22: /* fuhto */
3013 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3015 gen_vfp_uhto(dp
, 16 - rm
);
3017 case 23: /* fulto */
3018 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3020 gen_vfp_ulto(dp
, 32 - rm
);
3022 case 24: /* ftoui */
3025 case 25: /* ftouiz */
3028 case 26: /* ftosi */
3031 case 27: /* ftosiz */
3034 case 28: /* ftosh */
3035 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3037 gen_vfp_tosh(dp
, 16 - rm
);
3039 case 29: /* ftosl */
3040 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3042 gen_vfp_tosl(dp
, 32 - rm
);
3044 case 30: /* ftouh */
3045 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3047 gen_vfp_touh(dp
, 16 - rm
);
3049 case 31: /* ftoul */
3050 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3052 gen_vfp_toul(dp
, 32 - rm
);
3054 default: /* undefined */
3055 printf ("rn:%d\n", rn
);
3059 default: /* undefined */
3060 printf ("op:%d\n", op
);
3064 /* Write back the result. */
3065 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3066 ; /* Comparison, do nothing. */
3067 else if (op
== 15 && rn
> 17)
3068 /* Integer result. */
3069 gen_mov_vreg_F0(0, rd
);
3070 else if (op
== 15 && rn
== 15)
3072 gen_mov_vreg_F0(!dp
, rd
);
3074 gen_mov_vreg_F0(dp
, rd
);
3076 /* break out of the loop if we have finished */
3080 if (op
== 15 && delta_m
== 0) {
3081 /* single source one-many */
3083 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3085 gen_mov_vreg_F0(dp
, rd
);
3089 /* Setup the next operands. */
3091 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3095 /* One source operand. */
3096 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3098 gen_mov_F0_vreg(dp
, rm
);
3100 /* Two source operands. */
3101 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3103 gen_mov_F0_vreg(dp
, rn
);
3105 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3107 gen_mov_F1_vreg(dp
, rm
);
3115 if (dp
&& (insn
& 0x03e00000) == 0x00400000) {
3116 /* two-register transfer */
3117 rn
= (insn
>> 16) & 0xf;
3118 rd
= (insn
>> 12) & 0xf;
3120 VFP_DREG_M(rm
, insn
);
3122 rm
= VFP_SREG_M(insn
);
3125 if (insn
& ARM_CP_RW_BIT
) {
3128 gen_mov_F0_vreg(0, rm
* 2);
3129 tmp
= gen_vfp_mrs();
3130 store_reg(s
, rd
, tmp
);
3131 gen_mov_F0_vreg(0, rm
* 2 + 1);
3132 tmp
= gen_vfp_mrs();
3133 store_reg(s
, rn
, tmp
);
3135 gen_mov_F0_vreg(0, rm
);
3136 tmp
= gen_vfp_mrs();
3137 store_reg(s
, rn
, tmp
);
3138 gen_mov_F0_vreg(0, rm
+ 1);
3139 tmp
= gen_vfp_mrs();
3140 store_reg(s
, rd
, tmp
);
3145 tmp
= load_reg(s
, rd
);
3147 gen_mov_vreg_F0(0, rm
* 2);
3148 tmp
= load_reg(s
, rn
);
3150 gen_mov_vreg_F0(0, rm
* 2 + 1);
3152 tmp
= load_reg(s
, rn
);
3154 gen_mov_vreg_F0(0, rm
);
3155 tmp
= load_reg(s
, rd
);
3157 gen_mov_vreg_F0(0, rm
+ 1);
3162 rn
= (insn
>> 16) & 0xf;
3164 VFP_DREG_D(rd
, insn
);
3166 rd
= VFP_SREG_D(insn
);
3167 if (s
->thumb
&& rn
== 15) {
3169 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3171 addr
= load_reg(s
, rn
);
3173 if ((insn
& 0x01200000) == 0x01000000) {
3174 /* Single load/store */
3175 offset
= (insn
& 0xff) << 2;
3176 if ((insn
& (1 << 23)) == 0)
3178 tcg_gen_addi_i32(addr
, addr
, offset
);
3179 if (insn
& (1 << 20)) {
3180 gen_vfp_ld(s
, dp
, addr
);
3181 gen_mov_vreg_F0(dp
, rd
);
3183 gen_mov_F0_vreg(dp
, rd
);
3184 gen_vfp_st(s
, dp
, addr
);
3188 /* load/store multiple */
3190 n
= (insn
>> 1) & 0x7f;
3194 if (insn
& (1 << 24)) /* pre-decrement */
3195 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3201 for (i
= 0; i
< n
; i
++) {
3202 if (insn
& ARM_CP_RW_BIT
) {
3204 gen_vfp_ld(s
, dp
, addr
);
3205 gen_mov_vreg_F0(dp
, rd
+ i
);
3208 gen_mov_F0_vreg(dp
, rd
+ i
);
3209 gen_vfp_st(s
, dp
, addr
);
3211 tcg_gen_addi_i32(addr
, addr
, offset
);
3213 if (insn
& (1 << 21)) {
3215 if (insn
& (1 << 24))
3216 offset
= -offset
* n
;
3217 else if (dp
&& (insn
& 1))
3223 tcg_gen_addi_i32(addr
, addr
, offset
);
3224 store_reg(s
, rn
, addr
);
3232 /* Should never happen. */
3238 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3240 TranslationBlock
*tb
;
3243 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3245 gen_set_pc_im(dest
);
3246 tcg_gen_exit_tb((long)tb
+ n
);
3248 gen_set_pc_im(dest
);
3253 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3255 if (unlikely(s
->singlestep_enabled
)) {
3256 /* An indirect jump so that we still trigger the debug exception. */
3261 gen_goto_tb(s
, 0, dest
);
3262 s
->is_jmp
= DISAS_TB_JUMP
;
3266 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3269 tcg_gen_sari_i32(t0
, t0
, 16);
3273 tcg_gen_sari_i32(t1
, t1
, 16);
3276 tcg_gen_mul_i32(t0
, t0
, t1
);
3279 /* Return the mask of PSR bits set by a MSR instruction. */
3280 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3284 if (flags
& (1 << 0))
3286 if (flags
& (1 << 1))
3288 if (flags
& (1 << 2))
3290 if (flags
& (1 << 3))
3293 /* Mask out undefined bits. */
3294 mask
&= ~CPSR_RESERVED
;
3295 if (!arm_feature(env
, ARM_FEATURE_V6
))
3296 mask
&= ~(CPSR_E
| CPSR_GE
);
3297 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3299 /* Mask out execution state bits. */
3302 /* Mask out privileged bits. */
3308 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3309 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3313 /* ??? This is also undefined in system mode. */
3317 tmp
= load_cpu_field(spsr
);
3318 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3319 tcg_gen_andi_i32(t0
, t0
, mask
);
3320 tcg_gen_or_i32(tmp
, tmp
, t0
);
3321 store_cpu_field(tmp
, spsr
);
3323 gen_set_cpsr(t0
, mask
);
3330 /* Returns nonzero if access to the PSR is not permitted. */
3331 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3335 tcg_gen_movi_i32(tmp
, val
);
3336 return gen_set_psr(s
, mask
, spsr
, tmp
);
3339 /* Generate an old-style exception return. Marks pc as dead. */
3340 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3343 store_reg(s
, 15, pc
);
3344 tmp
= load_cpu_field(spsr
);
3345 gen_set_cpsr(tmp
, 0xffffffff);
3347 s
->is_jmp
= DISAS_UPDATE
;
3350 /* Generate a v6 exception return. Marks both values as dead. */
3351 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3353 gen_set_cpsr(cpsr
, 0xffffffff);
3355 store_reg(s
, 15, pc
);
3356 s
->is_jmp
= DISAS_UPDATE
;
3360 gen_set_condexec (DisasContext
*s
)
3362 if (s
->condexec_mask
) {
3363 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3364 TCGv tmp
= new_tmp();
3365 tcg_gen_movi_i32(tmp
, val
);
3366 store_cpu_field(tmp
, condexec_bits
);
3370 static void gen_nop_hint(DisasContext
*s
, int val
)
3374 gen_set_pc_im(s
->pc
);
3375 s
->is_jmp
= DISAS_WFI
;
3379 /* TODO: Implement SEV and WFE. May help SMP performance. */
3385 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3387 static inline int gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3390 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3391 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3392 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3398 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3401 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3402 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3403 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3408 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3409 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3410 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3411 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3412 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3414 /* FIXME: This is wrong. They set the wrong overflow bit. */
3415 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3416 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3417 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3418 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3420 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3421 switch ((size << 1) | u) { \
3423 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3426 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3429 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3432 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3435 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3438 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3440 default: return 1; \
3443 #define GEN_NEON_INTEGER_OP(name) do { \
3444 switch ((size << 1) | u) { \
3446 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3449 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3452 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3455 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3458 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3461 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3463 default: return 1; \
3466 static TCGv
neon_load_scratch(int scratch
)
3468 TCGv tmp
= new_tmp();
3469 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3473 static void neon_store_scratch(int scratch
, TCGv var
)
3475 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3479 static inline TCGv
neon_get_scalar(int size
, int reg
)
3483 tmp
= neon_load_reg(reg
>> 1, reg
& 1);
3485 tmp
= neon_load_reg(reg
>> 2, (reg
>> 1) & 1);
3487 gen_neon_dup_low16(tmp
);
3489 gen_neon_dup_high16(tmp
);
3495 static void gen_neon_unzip_u8(TCGv t0
, TCGv t1
)
3503 tcg_gen_andi_i32(rd
, t0
, 0xff);
3504 tcg_gen_shri_i32(tmp
, t0
, 8);
3505 tcg_gen_andi_i32(tmp
, tmp
, 0xff00);
3506 tcg_gen_or_i32(rd
, rd
, tmp
);
3507 tcg_gen_shli_i32(tmp
, t1
, 16);
3508 tcg_gen_andi_i32(tmp
, tmp
, 0xff0000);
3509 tcg_gen_or_i32(rd
, rd
, tmp
);
3510 tcg_gen_shli_i32(tmp
, t1
, 8);
3511 tcg_gen_andi_i32(tmp
, tmp
, 0xff000000);
3512 tcg_gen_or_i32(rd
, rd
, tmp
);
3514 tcg_gen_shri_i32(rm
, t0
, 8);
3515 tcg_gen_andi_i32(rm
, rm
, 0xff);
3516 tcg_gen_shri_i32(tmp
, t0
, 16);
3517 tcg_gen_andi_i32(tmp
, tmp
, 0xff00);
3518 tcg_gen_or_i32(rm
, rm
, tmp
);
3519 tcg_gen_shli_i32(tmp
, t1
, 8);
3520 tcg_gen_andi_i32(tmp
, tmp
, 0xff0000);
3521 tcg_gen_or_i32(rm
, rm
, tmp
);
3522 tcg_gen_andi_i32(tmp
, t1
, 0xff000000);
3523 tcg_gen_or_i32(t1
, rm
, tmp
);
3524 tcg_gen_mov_i32(t0
, rd
);
3531 static void gen_neon_zip_u8(TCGv t0
, TCGv t1
)
3539 tcg_gen_andi_i32(rd
, t0
, 0xff);
3540 tcg_gen_shli_i32(tmp
, t1
, 8);
3541 tcg_gen_andi_i32(tmp
, tmp
, 0xff00);
3542 tcg_gen_or_i32(rd
, rd
, tmp
);
3543 tcg_gen_shli_i32(tmp
, t0
, 16);
3544 tcg_gen_andi_i32(tmp
, tmp
, 0xff0000);
3545 tcg_gen_or_i32(rd
, rd
, tmp
);
3546 tcg_gen_shli_i32(tmp
, t1
, 24);
3547 tcg_gen_andi_i32(tmp
, tmp
, 0xff000000);
3548 tcg_gen_or_i32(rd
, rd
, tmp
);
3550 tcg_gen_andi_i32(rm
, t1
, 0xff000000);
3551 tcg_gen_shri_i32(tmp
, t0
, 8);
3552 tcg_gen_andi_i32(tmp
, tmp
, 0xff0000);
3553 tcg_gen_or_i32(rm
, rm
, tmp
);
3554 tcg_gen_shri_i32(tmp
, t1
, 8);
3555 tcg_gen_andi_i32(tmp
, tmp
, 0xff00);
3556 tcg_gen_or_i32(rm
, rm
, tmp
);
3557 tcg_gen_shri_i32(tmp
, t0
, 16);
3558 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
3559 tcg_gen_or_i32(t1
, rm
, tmp
);
3560 tcg_gen_mov_i32(t0
, rd
);
3567 static void gen_neon_zip_u16(TCGv t0
, TCGv t1
)
3574 tcg_gen_andi_i32(tmp
, t0
, 0xffff);
3575 tcg_gen_shli_i32(tmp2
, t1
, 16);
3576 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3577 tcg_gen_andi_i32(t1
, t1
, 0xffff0000);
3578 tcg_gen_shri_i32(tmp2
, t0
, 16);
3579 tcg_gen_or_i32(t1
, t1
, tmp2
);
3580 tcg_gen_mov_i32(t0
, tmp
);
3586 static void gen_neon_unzip(int reg
, int q
, int tmp
, int size
)
3591 for (n
= 0; n
< q
+ 1; n
+= 2) {
3592 t0
= neon_load_reg(reg
, n
);
3593 t1
= neon_load_reg(reg
, n
+ 1);
3595 case 0: gen_neon_unzip_u8(t0
, t1
); break;
3596 case 1: gen_neon_zip_u16(t0
, t1
); break; /* zip and unzip are the same. */
3597 case 2: /* no-op */; break;
3600 neon_store_scratch(tmp
+ n
, t0
);
3601 neon_store_scratch(tmp
+ n
+ 1, t1
);
3605 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3612 tcg_gen_shli_i32(rd
, t0
, 8);
3613 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3614 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3615 tcg_gen_or_i32(rd
, rd
, tmp
);
3617 tcg_gen_shri_i32(t1
, t1
, 8);
3618 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3619 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3620 tcg_gen_or_i32(t1
, t1
, tmp
);
3621 tcg_gen_mov_i32(t0
, rd
);
3627 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3634 tcg_gen_shli_i32(rd
, t0
, 16);
3635 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3636 tcg_gen_or_i32(rd
, rd
, tmp
);
3637 tcg_gen_shri_i32(t1
, t1
, 16);
3638 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3639 tcg_gen_or_i32(t1
, t1
, tmp
);
3640 tcg_gen_mov_i32(t0
, rd
);
3651 } neon_ls_element_type
[11] = {
3665 /* Translate a NEON load/store element instruction. Return nonzero if the
3666 instruction is invalid. */
3667 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3686 if (!vfp_enabled(env
))
3688 VFP_DREG_D(rd
, insn
);
3689 rn
= (insn
>> 16) & 0xf;
3691 load
= (insn
& (1 << 21)) != 0;
3693 if ((insn
& (1 << 23)) == 0) {
3694 /* Load store all elements. */
3695 op
= (insn
>> 8) & 0xf;
3696 size
= (insn
>> 6) & 3;
3699 nregs
= neon_ls_element_type
[op
].nregs
;
3700 interleave
= neon_ls_element_type
[op
].interleave
;
3701 spacing
= neon_ls_element_type
[op
].spacing
;
3702 if (size
== 3 && (interleave
| spacing
) != 1)
3704 load_reg_var(s
, addr
, rn
);
3705 stride
= (1 << size
) * interleave
;
3706 for (reg
= 0; reg
< nregs
; reg
++) {
3707 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3708 load_reg_var(s
, addr
, rn
);
3709 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3710 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3711 load_reg_var(s
, addr
, rn
);
3712 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3716 tmp64
= gen_ld64(addr
, IS_USER(s
));
3717 neon_store_reg64(tmp64
, rd
);
3718 tcg_temp_free_i64(tmp64
);
3720 tmp64
= tcg_temp_new_i64();
3721 neon_load_reg64(tmp64
, rd
);
3722 gen_st64(tmp64
, addr
, IS_USER(s
));
3724 tcg_gen_addi_i32(addr
, addr
, stride
);
3726 for (pass
= 0; pass
< 2; pass
++) {
3729 tmp
= gen_ld32(addr
, IS_USER(s
));
3730 neon_store_reg(rd
, pass
, tmp
);
3732 tmp
= neon_load_reg(rd
, pass
);
3733 gen_st32(tmp
, addr
, IS_USER(s
));
3735 tcg_gen_addi_i32(addr
, addr
, stride
);
3736 } else if (size
== 1) {
3738 tmp
= gen_ld16u(addr
, IS_USER(s
));
3739 tcg_gen_addi_i32(addr
, addr
, stride
);
3740 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3741 tcg_gen_addi_i32(addr
, addr
, stride
);
3742 gen_bfi(tmp
, tmp
, tmp2
, 16, 0xffff);
3744 neon_store_reg(rd
, pass
, tmp
);
3746 tmp
= neon_load_reg(rd
, pass
);
3748 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3749 gen_st16(tmp
, addr
, IS_USER(s
));
3750 tcg_gen_addi_i32(addr
, addr
, stride
);
3751 gen_st16(tmp2
, addr
, IS_USER(s
));
3752 tcg_gen_addi_i32(addr
, addr
, stride
);
3754 } else /* size == 0 */ {
3757 for (n
= 0; n
< 4; n
++) {
3758 tmp
= gen_ld8u(addr
, IS_USER(s
));
3759 tcg_gen_addi_i32(addr
, addr
, stride
);
3763 gen_bfi(tmp2
, tmp2
, tmp
, n
* 8, 0xff);
3767 neon_store_reg(rd
, pass
, tmp2
);
3769 tmp2
= neon_load_reg(rd
, pass
);
3770 for (n
= 0; n
< 4; n
++) {
3773 tcg_gen_mov_i32(tmp
, tmp2
);
3775 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3777 gen_st8(tmp
, addr
, IS_USER(s
));
3778 tcg_gen_addi_i32(addr
, addr
, stride
);
3789 size
= (insn
>> 10) & 3;
3791 /* Load single element to all lanes. */
3794 size
= (insn
>> 6) & 3;
3795 nregs
= ((insn
>> 8) & 3) + 1;
3796 stride
= (insn
& (1 << 5)) ? 2 : 1;
3797 load_reg_var(s
, addr
, rn
);
3798 for (reg
= 0; reg
< nregs
; reg
++) {
3801 tmp
= gen_ld8u(addr
, IS_USER(s
));
3802 gen_neon_dup_u8(tmp
, 0);
3805 tmp
= gen_ld16u(addr
, IS_USER(s
));
3806 gen_neon_dup_low16(tmp
);
3809 tmp
= gen_ld32(addr
, IS_USER(s
));
3813 default: /* Avoid compiler warnings. */
3816 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3818 tcg_gen_mov_i32(tmp2
, tmp
);
3819 neon_store_reg(rd
, 0, tmp2
);
3820 neon_store_reg(rd
, 1, tmp
);
3823 stride
= (1 << size
) * nregs
;
3825 /* Single element. */
3826 pass
= (insn
>> 7) & 1;
3829 shift
= ((insn
>> 5) & 3) * 8;
3833 shift
= ((insn
>> 6) & 1) * 16;
3834 stride
= (insn
& (1 << 5)) ? 2 : 1;
3838 stride
= (insn
& (1 << 6)) ? 2 : 1;
3843 nregs
= ((insn
>> 8) & 3) + 1;
3844 load_reg_var(s
, addr
, rn
);
3845 for (reg
= 0; reg
< nregs
; reg
++) {
3849 tmp
= gen_ld8u(addr
, IS_USER(s
));
3852 tmp
= gen_ld16u(addr
, IS_USER(s
));
3855 tmp
= gen_ld32(addr
, IS_USER(s
));
3857 default: /* Avoid compiler warnings. */
3861 tmp2
= neon_load_reg(rd
, pass
);
3862 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
3865 neon_store_reg(rd
, pass
, tmp
);
3866 } else { /* Store */
3867 tmp
= neon_load_reg(rd
, pass
);
3869 tcg_gen_shri_i32(tmp
, tmp
, shift
);
3872 gen_st8(tmp
, addr
, IS_USER(s
));
3875 gen_st16(tmp
, addr
, IS_USER(s
));
3878 gen_st32(tmp
, addr
, IS_USER(s
));
3883 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3885 stride
= nregs
* (1 << size
);
3892 base
= load_reg(s
, rn
);
3894 tcg_gen_addi_i32(base
, base
, stride
);
3897 index
= load_reg(s
, rm
);
3898 tcg_gen_add_i32(base
, base
, index
);
3901 store_reg(s
, rn
, base
);
3906 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3907 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
3909 tcg_gen_and_i32(t
, t
, c
);
3910 tcg_gen_andc_i32(f
, f
, c
);
3911 tcg_gen_or_i32(dest
, t
, f
);
3914 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
3917 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
3918 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
3919 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
3924 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
3927 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
3928 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
3929 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
3934 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
3937 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
3938 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
3939 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
3944 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
3950 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
3951 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
3956 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
3957 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
3964 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
3965 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
3970 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
3971 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
3978 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
3982 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
3983 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
3984 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
3989 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
3990 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
3991 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
3998 static inline void gen_neon_addl(int size
)
4001 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4002 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4003 case 2: tcg_gen_add_i64(CPU_V001
); break;
4008 static inline void gen_neon_subl(int size
)
4011 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4012 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4013 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4018 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4021 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4022 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4023 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4028 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4031 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4032 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4037 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4041 switch ((size
<< 1) | u
) {
4042 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4043 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4044 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4045 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4047 tmp
= gen_muls_i64_i32(a
, b
);
4048 tcg_gen_mov_i64(dest
, tmp
);
4051 tmp
= gen_mulu_i64_i32(a
, b
);
4052 tcg_gen_mov_i64(dest
, tmp
);
4058 /* Translate a NEON data processing instruction. Return nonzero if the
4059 instruction is invalid.
4060 We process data in a mixture of 32-bit and 64-bit chunks.
4061 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4063 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4076 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4079 if (!vfp_enabled(env
))
4081 q
= (insn
& (1 << 6)) != 0;
4082 u
= (insn
>> 24) & 1;
4083 VFP_DREG_D(rd
, insn
);
4084 VFP_DREG_N(rn
, insn
);
4085 VFP_DREG_M(rm
, insn
);
4086 size
= (insn
>> 20) & 3;
4087 if ((insn
& (1 << 23)) == 0) {
4088 /* Three register same length. */
4089 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4090 if (size
== 3 && (op
== 1 || op
== 5 || op
== 8 || op
== 9
4091 || op
== 10 || op
== 11 || op
== 16)) {
4092 /* 64-bit element instructions. */
4093 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4094 neon_load_reg64(cpu_V0
, rn
+ pass
);
4095 neon_load_reg64(cpu_V1
, rm
+ pass
);
4099 gen_helper_neon_add_saturate_u64(CPU_V001
);
4101 gen_helper_neon_add_saturate_s64(CPU_V001
);
4106 gen_helper_neon_sub_saturate_u64(CPU_V001
);
4108 gen_helper_neon_sub_saturate_s64(CPU_V001
);
4113 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4115 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4120 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4123 gen_helper_neon_qshl_s64(cpu_V1
, cpu_env
,
4127 case 10: /* VRSHL */
4129 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4131 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4134 case 11: /* VQRSHL */
4136 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4139 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4145 tcg_gen_sub_i64(CPU_V001
);
4147 tcg_gen_add_i64(CPU_V001
);
4153 neon_store_reg64(cpu_V0
, rd
+ pass
);
4160 case 10: /* VRSHL */
4161 case 11: /* VQRSHL */
4164 /* Shift instruction operands are reversed. */
4171 case 20: /* VPMAX */
4172 case 21: /* VPMIN */
4173 case 23: /* VPADD */
4176 case 26: /* VPADD (float) */
4177 pairwise
= (u
&& size
< 2);
4179 case 30: /* VPMIN/VPMAX (float) */
4187 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4196 tmp
= neon_load_reg(rn
, n
);
4197 tmp2
= neon_load_reg(rn
, n
+ 1);
4199 tmp
= neon_load_reg(rm
, n
);
4200 tmp2
= neon_load_reg(rm
, n
+ 1);
4204 tmp
= neon_load_reg(rn
, pass
);
4205 tmp2
= neon_load_reg(rm
, pass
);
4209 GEN_NEON_INTEGER_OP(hadd
);
4212 GEN_NEON_INTEGER_OP_ENV(qadd
);
4214 case 2: /* VRHADD */
4215 GEN_NEON_INTEGER_OP(rhadd
);
4217 case 3: /* Logic ops. */
4218 switch ((u
<< 2) | size
) {
4220 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4223 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4226 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4229 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4232 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4235 tmp3
= neon_load_reg(rd
, pass
);
4236 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4240 tmp3
= neon_load_reg(rd
, pass
);
4241 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4245 tmp3
= neon_load_reg(rd
, pass
);
4246 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4252 GEN_NEON_INTEGER_OP(hsub
);
4255 GEN_NEON_INTEGER_OP_ENV(qsub
);
4258 GEN_NEON_INTEGER_OP(cgt
);
4261 GEN_NEON_INTEGER_OP(cge
);
4264 GEN_NEON_INTEGER_OP(shl
);
4267 GEN_NEON_INTEGER_OP_ENV(qshl
);
4269 case 10: /* VRSHL */
4270 GEN_NEON_INTEGER_OP(rshl
);
4272 case 11: /* VQRSHL */
4273 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4276 GEN_NEON_INTEGER_OP(max
);
4279 GEN_NEON_INTEGER_OP(min
);
4282 GEN_NEON_INTEGER_OP(abd
);
4285 GEN_NEON_INTEGER_OP(abd
);
4287 tmp2
= neon_load_reg(rd
, pass
);
4288 gen_neon_add(size
, tmp
, tmp2
);
4291 if (!u
) { /* VADD */
4292 if (gen_neon_add(size
, tmp
, tmp2
))
4296 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4297 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4298 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4304 if (!u
) { /* VTST */
4306 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4307 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4308 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4313 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4314 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4315 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4320 case 18: /* Multiply. */
4322 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4323 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4324 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4328 tmp2
= neon_load_reg(rd
, pass
);
4330 gen_neon_rsb(size
, tmp
, tmp2
);
4332 gen_neon_add(size
, tmp
, tmp2
);
4336 if (u
) { /* polynomial */
4337 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4338 } else { /* Integer */
4340 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4341 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4342 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4347 case 20: /* VPMAX */
4348 GEN_NEON_INTEGER_OP(pmax
);
4350 case 21: /* VPMIN */
4351 GEN_NEON_INTEGER_OP(pmin
);
4353 case 22: /* Hultiply high. */
4354 if (!u
) { /* VQDMULH */
4356 case 1: gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4357 case 2: gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4360 } else { /* VQRDHMUL */
4362 case 1: gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4363 case 2: gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4368 case 23: /* VPADD */
4372 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4373 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4374 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4378 case 26: /* Floating point arithnetic. */
4379 switch ((u
<< 2) | size
) {
4381 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4384 gen_helper_neon_sub_f32(tmp
, tmp
, tmp2
);
4387 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4390 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
);
4396 case 27: /* Float multiply. */
4397 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
4400 tmp2
= neon_load_reg(rd
, pass
);
4402 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4404 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
4408 case 28: /* Float compare. */
4410 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
4413 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
4415 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
4418 case 29: /* Float compare absolute. */
4422 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
);
4424 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
);
4426 case 30: /* Float min/max. */
4428 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
);
4430 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
);
4434 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4436 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4443 /* Save the result. For elementwise operations we can put it
4444 straight into the destination register. For pairwise operations
4445 we have to be careful to avoid clobbering the source operands. */
4446 if (pairwise
&& rd
== rm
) {
4447 neon_store_scratch(pass
, tmp
);
4449 neon_store_reg(rd
, pass
, tmp
);
4453 if (pairwise
&& rd
== rm
) {
4454 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4455 tmp
= neon_load_scratch(pass
);
4456 neon_store_reg(rd
, pass
, tmp
);
4459 /* End of 3 register same size operations. */
4460 } else if (insn
& (1 << 4)) {
4461 if ((insn
& 0x00380080) != 0) {
4462 /* Two registers and shift. */
4463 op
= (insn
>> 8) & 0xf;
4464 if (insn
& (1 << 7)) {
4469 while ((insn
& (1 << (size
+ 19))) == 0)
4472 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4473 /* To avoid excessive dumplication of ops we implement shift
4474 by immediate using the variable shift operations. */
4476 /* Shift by immediate:
4477 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4478 /* Right shifts are encoded as N - shift, where N is the
4479 element size in bits. */
4481 shift
= shift
- (1 << (size
+ 3));
4489 imm
= (uint8_t) shift
;
4494 imm
= (uint16_t) shift
;
4505 for (pass
= 0; pass
< count
; pass
++) {
4507 neon_load_reg64(cpu_V0
, rm
+ pass
);
4508 tcg_gen_movi_i64(cpu_V1
, imm
);
4513 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4515 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4520 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4522 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4527 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4529 case 5: /* VSHL, VSLI */
4530 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4534 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
, cpu_V0
, cpu_V1
);
4536 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
, cpu_V0
, cpu_V1
);
4538 case 7: /* VQSHLU */
4539 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
, cpu_V0
, cpu_V1
);
4542 if (op
== 1 || op
== 3) {
4544 neon_load_reg64(cpu_V0
, rd
+ pass
);
4545 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4546 } else if (op
== 4 || (op
== 5 && u
)) {
4548 cpu_abort(env
, "VS[LR]I.64 not implemented");
4550 neon_store_reg64(cpu_V0
, rd
+ pass
);
4551 } else { /* size < 3 */
4552 /* Operands in T0 and T1. */
4553 tmp
= neon_load_reg(rm
, pass
);
4555 tcg_gen_movi_i32(tmp2
, imm
);
4559 GEN_NEON_INTEGER_OP(shl
);
4563 GEN_NEON_INTEGER_OP(rshl
);
4568 GEN_NEON_INTEGER_OP(shl
);
4570 case 5: /* VSHL, VSLI */
4572 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
4573 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
4574 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
4579 GEN_NEON_INTEGER_OP_ENV(qshl
);
4581 case 7: /* VQSHLU */
4583 case 0: gen_helper_neon_qshl_u8(tmp
, cpu_env
, tmp
, tmp2
); break;
4584 case 1: gen_helper_neon_qshl_u16(tmp
, cpu_env
, tmp
, tmp2
); break;
4585 case 2: gen_helper_neon_qshl_u32(tmp
, cpu_env
, tmp
, tmp2
); break;
4592 if (op
== 1 || op
== 3) {
4594 tmp2
= neon_load_reg(rd
, pass
);
4595 gen_neon_add(size
, tmp2
, tmp
);
4597 } else if (op
== 4 || (op
== 5 && u
)) {
4602 mask
= 0xff >> -shift
;
4604 mask
= (uint8_t)(0xff << shift
);
4610 mask
= 0xffff >> -shift
;
4612 mask
= (uint16_t)(0xffff << shift
);
4616 if (shift
< -31 || shift
> 31) {
4620 mask
= 0xffffffffu
>> -shift
;
4622 mask
= 0xffffffffu
<< shift
;
4628 tmp2
= neon_load_reg(rd
, pass
);
4629 tcg_gen_andi_i32(tmp
, tmp
, mask
);
4630 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
4631 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4634 neon_store_reg(rd
, pass
, tmp
);
4637 } else if (op
< 10) {
4638 /* Shift by immediate and narrow:
4639 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4640 shift
= shift
- (1 << (size
+ 3));
4644 imm
= (uint16_t)shift
;
4646 tmp2
= tcg_const_i32(imm
);
4647 TCGV_UNUSED_I64(tmp64
);
4650 imm
= (uint32_t)shift
;
4651 tmp2
= tcg_const_i32(imm
);
4652 TCGV_UNUSED_I64(tmp64
);
4655 tmp64
= tcg_const_i64(shift
);
4662 for (pass
= 0; pass
< 2; pass
++) {
4664 neon_load_reg64(cpu_V0
, rm
+ pass
);
4667 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, tmp64
);
4669 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, tmp64
);
4672 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, tmp64
);
4674 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, tmp64
);
4677 tmp
= neon_load_reg(rm
+ pass
, 0);
4678 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
, u
);
4679 tmp3
= neon_load_reg(rm
+ pass
, 1);
4680 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
, u
);
4681 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
4686 if (op
== 8 && !u
) {
4687 gen_neon_narrow(size
- 1, tmp
, cpu_V0
);
4690 gen_neon_narrow_sats(size
- 1, tmp
, cpu_V0
);
4692 gen_neon_narrow_satu(size
- 1, tmp
, cpu_V0
);
4694 neon_store_reg(rd
, pass
, tmp
);
4697 tcg_temp_free_i64(tmp64
);
4701 } else if (op
== 10) {
4705 tmp
= neon_load_reg(rm
, 0);
4706 tmp2
= neon_load_reg(rm
, 1);
4707 for (pass
= 0; pass
< 2; pass
++) {
4711 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
4714 /* The shift is less than the width of the source
4715 type, so we can just shift the whole register. */
4716 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
4717 if (size
< 2 || !u
) {
4720 imm
= (0xffu
>> (8 - shift
));
4723 imm
= 0xffff >> (16 - shift
);
4725 imm64
= imm
| (((uint64_t)imm
) << 32);
4726 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, imm64
);
4729 neon_store_reg64(cpu_V0
, rd
+ pass
);
4731 } else if (op
== 15 || op
== 16) {
4732 /* VCVT fixed-point. */
4733 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4734 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
4737 gen_vfp_ulto(0, shift
);
4739 gen_vfp_slto(0, shift
);
4742 gen_vfp_toul(0, shift
);
4744 gen_vfp_tosl(0, shift
);
4746 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
4751 } else { /* (insn & 0x00380080) == 0 */
4754 op
= (insn
>> 8) & 0xf;
4755 /* One register and immediate. */
4756 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
4757 invert
= (insn
& (1 << 5)) != 0;
4775 imm
= (imm
<< 8) | (imm
<< 24);
4778 imm
= (imm
< 8) | 0xff;
4781 imm
= (imm
<< 16) | 0xffff;
4784 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
4789 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
4790 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
4796 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4797 if (op
& 1 && op
< 12) {
4798 tmp
= neon_load_reg(rd
, pass
);
4800 /* The immediate value has already been inverted, so
4802 tcg_gen_andi_i32(tmp
, tmp
, imm
);
4804 tcg_gen_ori_i32(tmp
, tmp
, imm
);
4809 if (op
== 14 && invert
) {
4812 for (n
= 0; n
< 4; n
++) {
4813 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
4814 val
|= 0xff << (n
* 8);
4816 tcg_gen_movi_i32(tmp
, val
);
4818 tcg_gen_movi_i32(tmp
, imm
);
4821 neon_store_reg(rd
, pass
, tmp
);
4824 } else { /* (insn & 0x00800010 == 0x00800000) */
4826 op
= (insn
>> 8) & 0xf;
4827 if ((insn
& (1 << 6)) == 0) {
4828 /* Three registers of different lengths. */
4832 /* prewiden, src1_wide, src2_wide */
4833 static const int neon_3reg_wide
[16][3] = {
4834 {1, 0, 0}, /* VADDL */
4835 {1, 1, 0}, /* VADDW */
4836 {1, 0, 0}, /* VSUBL */
4837 {1, 1, 0}, /* VSUBW */
4838 {0, 1, 1}, /* VADDHN */
4839 {0, 0, 0}, /* VABAL */
4840 {0, 1, 1}, /* VSUBHN */
4841 {0, 0, 0}, /* VABDL */
4842 {0, 0, 0}, /* VMLAL */
4843 {0, 0, 0}, /* VQDMLAL */
4844 {0, 0, 0}, /* VMLSL */
4845 {0, 0, 0}, /* VQDMLSL */
4846 {0, 0, 0}, /* Integer VMULL */
4847 {0, 0, 0}, /* VQDMULL */
4848 {0, 0, 0} /* Polynomial VMULL */
4851 prewiden
= neon_3reg_wide
[op
][0];
4852 src1_wide
= neon_3reg_wide
[op
][1];
4853 src2_wide
= neon_3reg_wide
[op
][2];
4855 if (size
== 0 && (op
== 9 || op
== 11 || op
== 13))
4858 /* Avoid overlapping operands. Wide source operands are
4859 always aligned so will never overlap with wide
4860 destinations in problematic ways. */
4861 if (rd
== rm
&& !src2_wide
) {
4862 tmp
= neon_load_reg(rm
, 1);
4863 neon_store_scratch(2, tmp
);
4864 } else if (rd
== rn
&& !src1_wide
) {
4865 tmp
= neon_load_reg(rn
, 1);
4866 neon_store_scratch(2, tmp
);
4869 for (pass
= 0; pass
< 2; pass
++) {
4871 neon_load_reg64(cpu_V0
, rn
+ pass
);
4874 if (pass
== 1 && rd
== rn
) {
4875 tmp
= neon_load_scratch(2);
4877 tmp
= neon_load_reg(rn
, pass
);
4880 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
4884 neon_load_reg64(cpu_V1
, rm
+ pass
);
4887 if (pass
== 1 && rd
== rm
) {
4888 tmp2
= neon_load_scratch(2);
4890 tmp2
= neon_load_reg(rm
, pass
);
4893 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
4897 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4898 gen_neon_addl(size
);
4900 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4901 gen_neon_subl(size
);
4903 case 5: case 7: /* VABAL, VABDL */
4904 switch ((size
<< 1) | u
) {
4906 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
4909 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
4912 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
4915 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
4918 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
4921 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
4928 case 8: case 9: case 10: case 11: case 12: case 13:
4929 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4930 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
4934 case 14: /* Polynomial VMULL */
4935 cpu_abort(env
, "Polynomial VMULL not implemented");
4937 default: /* 15 is RESERVED. */
4940 if (op
== 5 || op
== 13 || (op
>= 8 && op
<= 11)) {
4942 if (op
== 10 || op
== 11) {
4943 gen_neon_negl(cpu_V0
, size
);
4947 neon_load_reg64(cpu_V1
, rd
+ pass
);
4951 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4952 gen_neon_addl(size
);
4954 case 9: case 11: /* VQDMLAL, VQDMLSL */
4955 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
4956 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
4959 case 13: /* VQDMULL */
4960 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
4965 neon_store_reg64(cpu_V0
, rd
+ pass
);
4966 } else if (op
== 4 || op
== 6) {
4967 /* Narrowing operation. */
4972 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
4975 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
4978 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
4979 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
4986 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
4989 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
4992 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
4993 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
4994 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5002 neon_store_reg(rd
, 0, tmp3
);
5003 neon_store_reg(rd
, 1, tmp
);
5006 /* Write back the result. */
5007 neon_store_reg64(cpu_V0
, rd
+ pass
);
5011 /* Two registers and a scalar. */
5013 case 0: /* Integer VMLA scalar */
5014 case 1: /* Float VMLA scalar */
5015 case 4: /* Integer VMLS scalar */
5016 case 5: /* Floating point VMLS scalar */
5017 case 8: /* Integer VMUL scalar */
5018 case 9: /* Floating point VMUL scalar */
5019 case 12: /* VQDMULH scalar */
5020 case 13: /* VQRDMULH scalar */
5021 tmp
= neon_get_scalar(size
, rm
);
5022 neon_store_scratch(0, tmp
);
5023 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5024 tmp
= neon_load_scratch(0);
5025 tmp2
= neon_load_reg(rn
, pass
);
5028 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5030 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5032 } else if (op
== 13) {
5034 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5036 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5038 } else if (op
& 1) {
5039 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
5042 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5043 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5044 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5051 tmp2
= neon_load_reg(rd
, pass
);
5054 gen_neon_add(size
, tmp
, tmp2
);
5057 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
5060 gen_neon_rsb(size
, tmp
, tmp2
);
5063 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
5070 neon_store_reg(rd
, pass
, tmp
);
5073 case 2: /* VMLAL sclar */
5074 case 3: /* VQDMLAL scalar */
5075 case 6: /* VMLSL scalar */
5076 case 7: /* VQDMLSL scalar */
5077 case 10: /* VMULL scalar */
5078 case 11: /* VQDMULL scalar */
5079 if (size
== 0 && (op
== 3 || op
== 7 || op
== 11))
5082 tmp2
= neon_get_scalar(size
, rm
);
5083 tmp3
= neon_load_reg(rn
, 1);
5085 for (pass
= 0; pass
< 2; pass
++) {
5087 tmp
= neon_load_reg(rn
, 0);
5091 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5093 if (op
== 6 || op
== 7) {
5094 gen_neon_negl(cpu_V0
, size
);
5097 neon_load_reg64(cpu_V1
, rd
+ pass
);
5101 gen_neon_addl(size
);
5104 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5105 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5111 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5116 neon_store_reg64(cpu_V0
, rd
+ pass
);
5122 default: /* 14 and 15 are RESERVED */
5126 } else { /* size == 3 */
5129 imm
= (insn
>> 8) & 0xf;
5136 neon_load_reg64(cpu_V0
, rn
);
5138 neon_load_reg64(cpu_V1
, rn
+ 1);
5140 } else if (imm
== 8) {
5141 neon_load_reg64(cpu_V0
, rn
+ 1);
5143 neon_load_reg64(cpu_V1
, rm
);
5146 tmp64
= tcg_temp_new_i64();
5148 neon_load_reg64(cpu_V0
, rn
);
5149 neon_load_reg64(tmp64
, rn
+ 1);
5151 neon_load_reg64(cpu_V0
, rn
+ 1);
5152 neon_load_reg64(tmp64
, rm
);
5154 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5155 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5156 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5158 neon_load_reg64(cpu_V1
, rm
);
5160 neon_load_reg64(cpu_V1
, rm
+ 1);
5163 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5164 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5165 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5166 tcg_temp_free_i64(tmp64
);
5169 neon_load_reg64(cpu_V0
, rn
);
5170 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5171 neon_load_reg64(cpu_V1
, rm
);
5172 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5173 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5175 neon_store_reg64(cpu_V0
, rd
);
5177 neon_store_reg64(cpu_V1
, rd
+ 1);
5179 } else if ((insn
& (1 << 11)) == 0) {
5180 /* Two register misc. */
5181 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5182 size
= (insn
>> 18) & 3;
5184 case 0: /* VREV64 */
5187 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5188 tmp
= neon_load_reg(rm
, pass
* 2);
5189 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5191 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5192 case 1: gen_swap_half(tmp
); break;
5193 case 2: /* no-op */ break;
5196 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5198 neon_store_reg(rd
, pass
* 2, tmp2
);
5201 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5202 case 1: gen_swap_half(tmp2
); break;
5205 neon_store_reg(rd
, pass
* 2, tmp2
);
5209 case 4: case 5: /* VPADDL */
5210 case 12: case 13: /* VPADAL */
5213 for (pass
= 0; pass
< q
+ 1; pass
++) {
5214 tmp
= neon_load_reg(rm
, pass
* 2);
5215 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5216 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5217 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5219 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5220 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5221 case 2: tcg_gen_add_i64(CPU_V001
); break;
5226 neon_load_reg64(cpu_V1
, rd
+ pass
);
5227 gen_neon_addl(size
);
5229 neon_store_reg64(cpu_V0
, rd
+ pass
);
5234 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5235 tmp
= neon_load_reg(rm
, n
);
5236 tmp2
= neon_load_reg(rd
, n
+ 1);
5237 neon_store_reg(rm
, n
, tmp2
);
5238 neon_store_reg(rd
, n
+ 1, tmp
);
5246 Rd A3 A2 A1 A0 B2 B0 A2 A0
5247 Rm B3 B2 B1 B0 B3 B1 A3 A1
5251 gen_neon_unzip(rd
, q
, 0, size
);
5252 gen_neon_unzip(rm
, q
, 4, size
);
5254 static int unzip_order_q
[8] =
5255 {0, 2, 4, 6, 1, 3, 5, 7};
5256 for (n
= 0; n
< 8; n
++) {
5257 int reg
= (n
< 4) ? rd
: rm
;
5258 tmp
= neon_load_scratch(unzip_order_q
[n
]);
5259 neon_store_reg(reg
, n
% 4, tmp
);
5262 static int unzip_order
[4] =
5264 for (n
= 0; n
< 4; n
++) {
5265 int reg
= (n
< 2) ? rd
: rm
;
5266 tmp
= neon_load_scratch(unzip_order
[n
]);
5267 neon_store_reg(reg
, n
% 2, tmp
);
5273 Rd A3 A2 A1 A0 B1 A1 B0 A0
5274 Rm B3 B2 B1 B0 B3 A3 B2 A2
5278 count
= (q
? 4 : 2);
5279 for (n
= 0; n
< count
; n
++) {
5280 tmp
= neon_load_reg(rd
, n
);
5281 tmp2
= neon_load_reg(rd
, n
);
5283 case 0: gen_neon_zip_u8(tmp
, tmp2
); break;
5284 case 1: gen_neon_zip_u16(tmp
, tmp2
); break;
5285 case 2: /* no-op */; break;
5288 neon_store_scratch(n
* 2, tmp
);
5289 neon_store_scratch(n
* 2 + 1, tmp2
);
5291 for (n
= 0; n
< count
* 2; n
++) {
5292 int reg
= (n
< count
) ? rd
: rm
;
5293 tmp
= neon_load_scratch(n
);
5294 neon_store_reg(reg
, n
% count
, tmp
);
5297 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5301 for (pass
= 0; pass
< 2; pass
++) {
5302 neon_load_reg64(cpu_V0
, rm
+ pass
);
5304 if (op
== 36 && q
== 0) {
5305 gen_neon_narrow(size
, tmp
, cpu_V0
);
5307 gen_neon_narrow_satu(size
, tmp
, cpu_V0
);
5309 gen_neon_narrow_sats(size
, tmp
, cpu_V0
);
5314 neon_store_reg(rd
, 0, tmp2
);
5315 neon_store_reg(rd
, 1, tmp
);
5319 case 38: /* VSHLL */
5322 tmp
= neon_load_reg(rm
, 0);
5323 tmp2
= neon_load_reg(rm
, 1);
5324 for (pass
= 0; pass
< 2; pass
++) {
5327 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5328 neon_store_reg64(cpu_V0
, rd
+ pass
);
5333 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5334 if (op
== 30 || op
== 31 || op
>= 58) {
5335 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5336 neon_reg_offset(rm
, pass
));
5339 tmp
= neon_load_reg(rm
, pass
);
5342 case 1: /* VREV32 */
5344 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5345 case 1: gen_swap_half(tmp
); break;
5349 case 2: /* VREV16 */
5356 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5357 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5358 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5364 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5365 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5366 case 2: gen_helper_clz(tmp
, tmp
); break;
5373 gen_helper_neon_cnt_u8(tmp
, tmp
);
5378 tcg_gen_not_i32(tmp
, tmp
);
5380 case 14: /* VQABS */
5382 case 0: gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
); break;
5383 case 1: gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
); break;
5384 case 2: gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
); break;
5388 case 15: /* VQNEG */
5390 case 0: gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
); break;
5391 case 1: gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
); break;
5392 case 2: gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
); break;
5396 case 16: case 19: /* VCGT #0, VCLE #0 */
5397 tmp2
= tcg_const_i32(0);
5399 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5400 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5401 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5404 tcg_temp_free(tmp2
);
5406 tcg_gen_not_i32(tmp
, tmp
);
5408 case 17: case 20: /* VCGE #0, VCLT #0 */
5409 tmp2
= tcg_const_i32(0);
5411 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5412 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5413 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5416 tcg_temp_free(tmp2
);
5418 tcg_gen_not_i32(tmp
, tmp
);
5420 case 18: /* VCEQ #0 */
5421 tmp2
= tcg_const_i32(0);
5423 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5424 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5425 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5428 tcg_temp_free(tmp2
);
5432 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
5433 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
5434 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
5441 tmp2
= tcg_const_i32(0);
5442 gen_neon_rsb(size
, tmp
, tmp2
);
5443 tcg_temp_free(tmp2
);
5445 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5446 tmp2
= tcg_const_i32(0);
5447 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
5448 tcg_temp_free(tmp2
);
5450 tcg_gen_not_i32(tmp
, tmp
);
5452 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5453 tmp2
= tcg_const_i32(0);
5454 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
5455 tcg_temp_free(tmp2
);
5457 tcg_gen_not_i32(tmp
, tmp
);
5459 case 26: /* Float VCEQ #0 */
5460 tmp2
= tcg_const_i32(0);
5461 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
5462 tcg_temp_free(tmp2
);
5464 case 30: /* Float VABS */
5467 case 31: /* Float VNEG */
5471 tmp2
= neon_load_reg(rd
, pass
);
5472 neon_store_reg(rm
, pass
, tmp2
);
5475 tmp2
= neon_load_reg(rd
, pass
);
5477 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
5478 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
5482 neon_store_reg(rm
, pass
, tmp2
);
5484 case 56: /* Integer VRECPE */
5485 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
5487 case 57: /* Integer VRSQRTE */
5488 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
5490 case 58: /* Float VRECPE */
5491 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5493 case 59: /* Float VRSQRTE */
5494 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5496 case 60: /* VCVT.F32.S32 */
5499 case 61: /* VCVT.F32.U32 */
5502 case 62: /* VCVT.S32.F32 */
5505 case 63: /* VCVT.U32.F32 */
5509 /* Reserved: 21, 29, 39-56 */
5512 if (op
== 30 || op
== 31 || op
>= 58) {
5513 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
5514 neon_reg_offset(rd
, pass
));
5516 neon_store_reg(rd
, pass
, tmp
);
5521 } else if ((insn
& (1 << 10)) == 0) {
5523 n
= ((insn
>> 5) & 0x18) + 8;
5524 if (insn
& (1 << 6)) {
5525 tmp
= neon_load_reg(rd
, 0);
5528 tcg_gen_movi_i32(tmp
, 0);
5530 tmp2
= neon_load_reg(rm
, 0);
5531 tmp4
= tcg_const_i32(rn
);
5532 tmp5
= tcg_const_i32(n
);
5533 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
5535 if (insn
& (1 << 6)) {
5536 tmp
= neon_load_reg(rd
, 1);
5539 tcg_gen_movi_i32(tmp
, 0);
5541 tmp3
= neon_load_reg(rm
, 1);
5542 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
5543 tcg_temp_free_i32(tmp5
);
5544 tcg_temp_free_i32(tmp4
);
5545 neon_store_reg(rd
, 0, tmp2
);
5546 neon_store_reg(rd
, 1, tmp3
);
5548 } else if ((insn
& 0x380) == 0) {
5550 if (insn
& (1 << 19)) {
5551 tmp
= neon_load_reg(rm
, 1);
5553 tmp
= neon_load_reg(rm
, 0);
5555 if (insn
& (1 << 16)) {
5556 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
5557 } else if (insn
& (1 << 17)) {
5558 if ((insn
>> 18) & 1)
5559 gen_neon_dup_high16(tmp
);
5561 gen_neon_dup_low16(tmp
);
5563 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5565 tcg_gen_mov_i32(tmp2
, tmp
);
5566 neon_store_reg(rd
, pass
, tmp2
);
5577 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5579 int crn
= (insn
>> 16) & 0xf;
5580 int crm
= insn
& 0xf;
5581 int op1
= (insn
>> 21) & 7;
5582 int op2
= (insn
>> 5) & 7;
5583 int rt
= (insn
>> 12) & 0xf;
5586 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5587 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5591 tmp
= load_cpu_field(teecr
);
5592 store_reg(s
, rt
, tmp
);
5595 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5597 if (IS_USER(s
) && (env
->teecr
& 1))
5599 tmp
= load_cpu_field(teehbr
);
5600 store_reg(s
, rt
, tmp
);
5604 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5605 op1
, crn
, crm
, op2
);
5609 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5611 int crn
= (insn
>> 16) & 0xf;
5612 int crm
= insn
& 0xf;
5613 int op1
= (insn
>> 21) & 7;
5614 int op2
= (insn
>> 5) & 7;
5615 int rt
= (insn
>> 12) & 0xf;
5618 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5619 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5623 tmp
= load_reg(s
, rt
);
5624 gen_helper_set_teecr(cpu_env
, tmp
);
5628 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5630 if (IS_USER(s
) && (env
->teecr
& 1))
5632 tmp
= load_reg(s
, rt
);
5633 store_cpu_field(tmp
, teehbr
);
5637 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5638 op1
, crn
, crm
, op2
);
5642 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5646 cpnum
= (insn
>> 8) & 0xf;
5647 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
5648 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
5654 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
5655 return disas_iwmmxt_insn(env
, s
, insn
);
5656 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
5657 return disas_dsp_insn(env
, s
, insn
);
5662 return disas_vfp_insn (env
, s
, insn
);
5664 /* Coprocessors 7-15 are architecturally reserved by ARM.
5665 Unfortunately Intel decided to ignore this. */
5666 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
5668 if (insn
& (1 << 20))
5669 return disas_cp14_read(env
, s
, insn
);
5671 return disas_cp14_write(env
, s
, insn
);
5673 return disas_cp15_insn (env
, s
, insn
);
5676 /* Unknown coprocessor. See if the board has hooked it. */
5677 return disas_cp_insn (env
, s
, insn
);
5682 /* Store a 64-bit value to a register pair. Clobbers val. */
5683 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
5687 tcg_gen_trunc_i64_i32(tmp
, val
);
5688 store_reg(s
, rlow
, tmp
);
5690 tcg_gen_shri_i64(val
, val
, 32);
5691 tcg_gen_trunc_i64_i32(tmp
, val
);
5692 store_reg(s
, rhigh
, tmp
);
5695 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5696 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
5701 /* Load value and extend to 64 bits. */
5702 tmp
= tcg_temp_new_i64();
5703 tmp2
= load_reg(s
, rlow
);
5704 tcg_gen_extu_i32_i64(tmp
, tmp2
);
5706 tcg_gen_add_i64(val
, val
, tmp
);
5707 tcg_temp_free_i64(tmp
);
5710 /* load and add a 64-bit value from a register pair. */
5711 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
5717 /* Load 64-bit value rd:rn. */
5718 tmpl
= load_reg(s
, rlow
);
5719 tmph
= load_reg(s
, rhigh
);
5720 tmp
= tcg_temp_new_i64();
5721 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
5724 tcg_gen_add_i64(val
, val
, tmp
);
5725 tcg_temp_free_i64(tmp
);
5728 /* Set N and Z flags from a 64-bit value. */
5729 static void gen_logicq_cc(TCGv_i64 val
)
5731 TCGv tmp
= new_tmp();
5732 gen_helper_logicq_cc(tmp
, val
);
5737 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
5739 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
5746 insn
= ldl_code(s
->pc
);
5749 /* M variants do not implement ARM mode. */
5754 /* Unconditional instructions. */
5755 if (((insn
>> 25) & 7) == 1) {
5756 /* NEON Data processing. */
5757 if (!arm_feature(env
, ARM_FEATURE_NEON
))
5760 if (disas_neon_data_insn(env
, s
, insn
))
5764 if ((insn
& 0x0f100000) == 0x04000000) {
5765 /* NEON load/store. */
5766 if (!arm_feature(env
, ARM_FEATURE_NEON
))
5769 if (disas_neon_ls_insn(env
, s
, insn
))
5773 if ((insn
& 0x0d70f000) == 0x0550f000)
5775 else if ((insn
& 0x0ffffdff) == 0x01010000) {
5778 if (insn
& (1 << 9)) {
5779 /* BE8 mode not implemented. */
5783 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
5784 switch ((insn
>> 4) & 0xf) {
5787 gen_helper_clrex(cpu_env
);
5793 /* We don't emulate caches so these are a no-op. */
5798 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
5804 op1
= (insn
& 0x1f);
5805 if (op1
== (env
->uncached_cpsr
& CPSR_M
)) {
5806 addr
= load_reg(s
, 13);
5809 tmp
= tcg_const_i32(op1
);
5810 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
5811 tcg_temp_free_i32(tmp
);
5813 i
= (insn
>> 23) & 3;
5815 case 0: offset
= -4; break; /* DA */
5816 case 1: offset
= 0; break; /* IA */
5817 case 2: offset
= -8; break; /* DB */
5818 case 3: offset
= 4; break; /* IB */
5822 tcg_gen_addi_i32(addr
, addr
, offset
);
5823 tmp
= load_reg(s
, 14);
5824 gen_st32(tmp
, addr
, 0);
5825 tmp
= load_cpu_field(spsr
);
5826 tcg_gen_addi_i32(addr
, addr
, 4);
5827 gen_st32(tmp
, addr
, 0);
5828 if (insn
& (1 << 21)) {
5829 /* Base writeback. */
5831 case 0: offset
= -8; break;
5832 case 1: offset
= 4; break;
5833 case 2: offset
= -4; break;
5834 case 3: offset
= 0; break;
5838 tcg_gen_addi_i32(addr
, addr
, offset
);
5839 if (op1
== (env
->uncached_cpsr
& CPSR_M
)) {
5840 store_reg(s
, 13, addr
);
5842 tmp
= tcg_const_i32(op1
);
5843 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
5844 tcg_temp_free_i32(tmp
);
5850 } else if ((insn
& 0x0e5fffe0) == 0x081d0a00) {
5856 rn
= (insn
>> 16) & 0xf;
5857 addr
= load_reg(s
, rn
);
5858 i
= (insn
>> 23) & 3;
5860 case 0: offset
= -4; break; /* DA */
5861 case 1: offset
= 0; break; /* IA */
5862 case 2: offset
= -8; break; /* DB */
5863 case 3: offset
= 4; break; /* IB */
5867 tcg_gen_addi_i32(addr
, addr
, offset
);
5868 /* Load PC into tmp and CPSR into tmp2. */
5869 tmp
= gen_ld32(addr
, 0);
5870 tcg_gen_addi_i32(addr
, addr
, 4);
5871 tmp2
= gen_ld32(addr
, 0);
5872 if (insn
& (1 << 21)) {
5873 /* Base writeback. */
5875 case 0: offset
= -8; break;
5876 case 1: offset
= 4; break;
5877 case 2: offset
= -4; break;
5878 case 3: offset
= 0; break;
5882 tcg_gen_addi_i32(addr
, addr
, offset
);
5883 store_reg(s
, rn
, addr
);
5887 gen_rfe(s
, tmp
, tmp2
);
5889 } else if ((insn
& 0x0e000000) == 0x0a000000) {
5890 /* branch link and change to thumb (blx <offset>) */
5893 val
= (uint32_t)s
->pc
;
5895 tcg_gen_movi_i32(tmp
, val
);
5896 store_reg(s
, 14, tmp
);
5897 /* Sign-extend the 24-bit offset */
5898 offset
= (((int32_t)insn
) << 8) >> 8;
5899 /* offset * 4 + bit24 * 2 + (thumb bit) */
5900 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
5901 /* pipeline offset */
5905 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
5906 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
5907 /* iWMMXt register transfer. */
5908 if (env
->cp15
.c15_cpar
& (1 << 1))
5909 if (!disas_iwmmxt_insn(env
, s
, insn
))
5912 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
5913 /* Coprocessor double register transfer. */
5914 } else if ((insn
& 0x0f000010) == 0x0e000010) {
5915 /* Additional coprocessor register transfer. */
5916 } else if ((insn
& 0x0ff10020) == 0x01000000) {
5919 /* cps (privileged) */
5923 if (insn
& (1 << 19)) {
5924 if (insn
& (1 << 8))
5926 if (insn
& (1 << 7))
5928 if (insn
& (1 << 6))
5930 if (insn
& (1 << 18))
5933 if (insn
& (1 << 17)) {
5935 val
|= (insn
& 0x1f);
5938 gen_set_psr_im(s
, mask
, 0, val
);
5945 /* if not always execute, we generate a conditional jump to
5947 s
->condlabel
= gen_new_label();
5948 gen_test_cc(cond
^ 1, s
->condlabel
);
5951 if ((insn
& 0x0f900000) == 0x03000000) {
5952 if ((insn
& (1 << 21)) == 0) {
5954 rd
= (insn
>> 12) & 0xf;
5955 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
5956 if ((insn
& (1 << 22)) == 0) {
5959 tcg_gen_movi_i32(tmp
, val
);
5962 tmp
= load_reg(s
, rd
);
5963 tcg_gen_ext16u_i32(tmp
, tmp
);
5964 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
5966 store_reg(s
, rd
, tmp
);
5968 if (((insn
>> 12) & 0xf) != 0xf)
5970 if (((insn
>> 16) & 0xf) == 0) {
5971 gen_nop_hint(s
, insn
& 0xff);
5973 /* CPSR = immediate */
5975 shift
= ((insn
>> 8) & 0xf) * 2;
5977 val
= (val
>> shift
) | (val
<< (32 - shift
));
5978 i
= ((insn
& (1 << 22)) != 0);
5979 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
5983 } else if ((insn
& 0x0f900000) == 0x01000000
5984 && (insn
& 0x00000090) != 0x00000090) {
5985 /* miscellaneous instructions */
5986 op1
= (insn
>> 21) & 3;
5987 sh
= (insn
>> 4) & 0xf;
5990 case 0x0: /* move program status register */
5993 tmp
= load_reg(s
, rm
);
5994 i
= ((op1
& 2) != 0);
5995 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
5999 rd
= (insn
>> 12) & 0xf;
6003 tmp
= load_cpu_field(spsr
);
6006 gen_helper_cpsr_read(tmp
);
6008 store_reg(s
, rd
, tmp
);
6013 /* branch/exchange thumb (bx). */
6014 tmp
= load_reg(s
, rm
);
6016 } else if (op1
== 3) {
6018 rd
= (insn
>> 12) & 0xf;
6019 tmp
= load_reg(s
, rm
);
6020 gen_helper_clz(tmp
, tmp
);
6021 store_reg(s
, rd
, tmp
);
6029 /* Trivial implementation equivalent to bx. */
6030 tmp
= load_reg(s
, rm
);
6040 /* branch link/exchange thumb (blx) */
6041 tmp
= load_reg(s
, rm
);
6043 tcg_gen_movi_i32(tmp2
, s
->pc
);
6044 store_reg(s
, 14, tmp2
);
6047 case 0x5: /* saturating add/subtract */
6048 rd
= (insn
>> 12) & 0xf;
6049 rn
= (insn
>> 16) & 0xf;
6050 tmp
= load_reg(s
, rm
);
6051 tmp2
= load_reg(s
, rn
);
6053 gen_helper_double_saturate(tmp2
, tmp2
);
6055 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6057 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6059 store_reg(s
, rd
, tmp
);
6062 gen_set_condexec(s
);
6063 gen_set_pc_im(s
->pc
- 4);
6064 gen_exception(EXCP_BKPT
);
6065 s
->is_jmp
= DISAS_JUMP
;
6067 case 0x8: /* signed multiply */
6071 rs
= (insn
>> 8) & 0xf;
6072 rn
= (insn
>> 12) & 0xf;
6073 rd
= (insn
>> 16) & 0xf;
6075 /* (32 * 16) >> 16 */
6076 tmp
= load_reg(s
, rm
);
6077 tmp2
= load_reg(s
, rs
);
6079 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6082 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6083 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6085 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6086 tcg_temp_free_i64(tmp64
);
6087 if ((sh
& 2) == 0) {
6088 tmp2
= load_reg(s
, rn
);
6089 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6092 store_reg(s
, rd
, tmp
);
6095 tmp
= load_reg(s
, rm
);
6096 tmp2
= load_reg(s
, rs
);
6097 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6100 tmp64
= tcg_temp_new_i64();
6101 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6103 gen_addq(s
, tmp64
, rn
, rd
);
6104 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6105 tcg_temp_free_i64(tmp64
);
6108 tmp2
= load_reg(s
, rn
);
6109 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6112 store_reg(s
, rd
, tmp
);
6119 } else if (((insn
& 0x0e000000) == 0 &&
6120 (insn
& 0x00000090) != 0x90) ||
6121 ((insn
& 0x0e000000) == (1 << 25))) {
6122 int set_cc
, logic_cc
, shiftop
;
6124 op1
= (insn
>> 21) & 0xf;
6125 set_cc
= (insn
>> 20) & 1;
6126 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6128 /* data processing instruction */
6129 if (insn
& (1 << 25)) {
6130 /* immediate operand */
6132 shift
= ((insn
>> 8) & 0xf) * 2;
6134 val
= (val
>> shift
) | (val
<< (32 - shift
));
6137 tcg_gen_movi_i32(tmp2
, val
);
6138 if (logic_cc
&& shift
) {
6139 gen_set_CF_bit31(tmp2
);
6144 tmp2
= load_reg(s
, rm
);
6145 shiftop
= (insn
>> 5) & 3;
6146 if (!(insn
& (1 << 4))) {
6147 shift
= (insn
>> 7) & 0x1f;
6148 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6150 rs
= (insn
>> 8) & 0xf;
6151 tmp
= load_reg(s
, rs
);
6152 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6155 if (op1
!= 0x0f && op1
!= 0x0d) {
6156 rn
= (insn
>> 16) & 0xf;
6157 tmp
= load_reg(s
, rn
);
6161 rd
= (insn
>> 12) & 0xf;
6164 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6168 store_reg_bx(env
, s
, rd
, tmp
);
6171 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6175 store_reg_bx(env
, s
, rd
, tmp
);
6178 if (set_cc
&& rd
== 15) {
6179 /* SUBS r15, ... is used for exception return. */
6183 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6184 gen_exception_return(s
, tmp
);
6187 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6189 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6191 store_reg_bx(env
, s
, rd
, tmp
);
6196 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
6198 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6200 store_reg_bx(env
, s
, rd
, tmp
);
6204 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6206 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6208 store_reg_bx(env
, s
, rd
, tmp
);
6212 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
6214 gen_add_carry(tmp
, tmp
, tmp2
);
6216 store_reg_bx(env
, s
, rd
, tmp
);
6220 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
6222 gen_sub_carry(tmp
, tmp
, tmp2
);
6224 store_reg_bx(env
, s
, rd
, tmp
);
6228 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
6230 gen_sub_carry(tmp
, tmp2
, tmp
);
6232 store_reg_bx(env
, s
, rd
, tmp
);
6236 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6243 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6250 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6256 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6261 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6265 store_reg_bx(env
, s
, rd
, tmp
);
6268 if (logic_cc
&& rd
== 15) {
6269 /* MOVS r15, ... is used for exception return. */
6273 gen_exception_return(s
, tmp2
);
6278 store_reg_bx(env
, s
, rd
, tmp2
);
6282 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
6286 store_reg_bx(env
, s
, rd
, tmp
);
6290 tcg_gen_not_i32(tmp2
, tmp2
);
6294 store_reg_bx(env
, s
, rd
, tmp2
);
6297 if (op1
!= 0x0f && op1
!= 0x0d) {
6301 /* other instructions */
6302 op1
= (insn
>> 24) & 0xf;
6306 /* multiplies, extra load/stores */
6307 sh
= (insn
>> 5) & 3;
6310 rd
= (insn
>> 16) & 0xf;
6311 rn
= (insn
>> 12) & 0xf;
6312 rs
= (insn
>> 8) & 0xf;
6314 op1
= (insn
>> 20) & 0xf;
6316 case 0: case 1: case 2: case 3: case 6:
6318 tmp
= load_reg(s
, rs
);
6319 tmp2
= load_reg(s
, rm
);
6320 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
6322 if (insn
& (1 << 22)) {
6323 /* Subtract (mls) */
6325 tmp2
= load_reg(s
, rn
);
6326 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6328 } else if (insn
& (1 << 21)) {
6330 tmp2
= load_reg(s
, rn
);
6331 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6334 if (insn
& (1 << 20))
6336 store_reg(s
, rd
, tmp
);
6340 tmp
= load_reg(s
, rs
);
6341 tmp2
= load_reg(s
, rm
);
6342 if (insn
& (1 << 22))
6343 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6345 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6346 if (insn
& (1 << 21)) /* mult accumulate */
6347 gen_addq(s
, tmp64
, rn
, rd
);
6348 if (!(insn
& (1 << 23))) { /* double accumulate */
6350 gen_addq_lo(s
, tmp64
, rn
);
6351 gen_addq_lo(s
, tmp64
, rd
);
6353 if (insn
& (1 << 20))
6354 gen_logicq_cc(tmp64
);
6355 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6356 tcg_temp_free_i64(tmp64
);
6360 rn
= (insn
>> 16) & 0xf;
6361 rd
= (insn
>> 12) & 0xf;
6362 if (insn
& (1 << 23)) {
6363 /* load/store exclusive */
6364 op1
= (insn
>> 21) & 0x3;
6369 addr
= tcg_temp_local_new_i32();
6370 load_reg_var(s
, addr
, rn
);
6371 if (insn
& (1 << 20)) {
6372 gen_helper_mark_exclusive(cpu_env
, addr
);
6375 tmp
= gen_ld32(addr
, IS_USER(s
));
6377 case 1: /* ldrexd */
6378 tmp
= gen_ld32(addr
, IS_USER(s
));
6379 store_reg(s
, rd
, tmp
);
6380 tcg_gen_addi_i32(addr
, addr
, 4);
6381 tmp
= gen_ld32(addr
, IS_USER(s
));
6384 case 2: /* ldrexb */
6385 tmp
= gen_ld8u(addr
, IS_USER(s
));
6387 case 3: /* ldrexh */
6388 tmp
= gen_ld16u(addr
, IS_USER(s
));
6393 store_reg(s
, rd
, tmp
);
6395 int label
= gen_new_label();
6397 tmp2
= tcg_temp_local_new_i32();
6398 gen_helper_test_exclusive(tmp2
, cpu_env
, addr
);
6399 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp2
, 0, label
);
6400 tmp
= load_reg(s
,rm
);
6403 gen_st32(tmp
, addr
, IS_USER(s
));
6405 case 1: /* strexd */
6406 gen_st32(tmp
, addr
, IS_USER(s
));
6407 tcg_gen_addi_i32(addr
, addr
, 4);
6408 tmp
= load_reg(s
, rm
+ 1);
6409 gen_st32(tmp
, addr
, IS_USER(s
));
6411 case 2: /* strexb */
6412 gen_st8(tmp
, addr
, IS_USER(s
));
6414 case 3: /* strexh */
6415 gen_st16(tmp
, addr
, IS_USER(s
));
6420 gen_set_label(label
);
6421 tcg_gen_mov_i32(cpu_R
[rd
], tmp2
);
6422 tcg_temp_free(tmp2
);
6424 tcg_temp_free(addr
);
6426 /* SWP instruction */
6429 /* ??? This is not really atomic. However we know
6430 we never have multiple CPUs running in parallel,
6431 so it is good enough. */
6432 addr
= load_reg(s
, rn
);
6433 tmp
= load_reg(s
, rm
);
6434 if (insn
& (1 << 22)) {
6435 tmp2
= gen_ld8u(addr
, IS_USER(s
));
6436 gen_st8(tmp
, addr
, IS_USER(s
));
6438 tmp2
= gen_ld32(addr
, IS_USER(s
));
6439 gen_st32(tmp
, addr
, IS_USER(s
));
6442 store_reg(s
, rd
, tmp2
);
6448 /* Misc load/store */
6449 rn
= (insn
>> 16) & 0xf;
6450 rd
= (insn
>> 12) & 0xf;
6451 addr
= load_reg(s
, rn
);
6452 if (insn
& (1 << 24))
6453 gen_add_datah_offset(s
, insn
, 0, addr
);
6455 if (insn
& (1 << 20)) {
6459 tmp
= gen_ld16u(addr
, IS_USER(s
));
6462 tmp
= gen_ld8s(addr
, IS_USER(s
));
6466 tmp
= gen_ld16s(addr
, IS_USER(s
));
6470 } else if (sh
& 2) {
6474 tmp
= load_reg(s
, rd
);
6475 gen_st32(tmp
, addr
, IS_USER(s
));
6476 tcg_gen_addi_i32(addr
, addr
, 4);
6477 tmp
= load_reg(s
, rd
+ 1);
6478 gen_st32(tmp
, addr
, IS_USER(s
));
6482 tmp
= gen_ld32(addr
, IS_USER(s
));
6483 store_reg(s
, rd
, tmp
);
6484 tcg_gen_addi_i32(addr
, addr
, 4);
6485 tmp
= gen_ld32(addr
, IS_USER(s
));
6489 address_offset
= -4;
6492 tmp
= load_reg(s
, rd
);
6493 gen_st16(tmp
, addr
, IS_USER(s
));
6496 /* Perform base writeback before the loaded value to
6497 ensure correct behavior with overlapping index registers.
6498 ldrd with base writeback is is undefined if the
6499 destination and index registers overlap. */
6500 if (!(insn
& (1 << 24))) {
6501 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
6502 store_reg(s
, rn
, addr
);
6503 } else if (insn
& (1 << 21)) {
6505 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6506 store_reg(s
, rn
, addr
);
6511 /* Complete the load. */
6512 store_reg(s
, rd
, tmp
);
6521 if (insn
& (1 << 4)) {
6523 /* Armv6 Media instructions. */
6525 rn
= (insn
>> 16) & 0xf;
6526 rd
= (insn
>> 12) & 0xf;
6527 rs
= (insn
>> 8) & 0xf;
6528 switch ((insn
>> 23) & 3) {
6529 case 0: /* Parallel add/subtract. */
6530 op1
= (insn
>> 20) & 7;
6531 tmp
= load_reg(s
, rn
);
6532 tmp2
= load_reg(s
, rm
);
6533 sh
= (insn
>> 5) & 7;
6534 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
6536 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
6538 store_reg(s
, rd
, tmp
);
6541 if ((insn
& 0x00700020) == 0) {
6542 /* Halfword pack. */
6543 tmp
= load_reg(s
, rn
);
6544 tmp2
= load_reg(s
, rm
);
6545 shift
= (insn
>> 7) & 0x1f;
6546 if (insn
& (1 << 6)) {
6550 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
6551 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
6552 tcg_gen_ext16u_i32(tmp2
, tmp2
);
6556 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
6557 tcg_gen_ext16u_i32(tmp
, tmp
);
6558 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
6560 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6562 store_reg(s
, rd
, tmp
);
6563 } else if ((insn
& 0x00200020) == 0x00200000) {
6565 tmp
= load_reg(s
, rm
);
6566 shift
= (insn
>> 7) & 0x1f;
6567 if (insn
& (1 << 6)) {
6570 tcg_gen_sari_i32(tmp
, tmp
, shift
);
6572 tcg_gen_shli_i32(tmp
, tmp
, shift
);
6574 sh
= (insn
>> 16) & 0x1f;
6576 tmp2
= tcg_const_i32(sh
);
6577 if (insn
& (1 << 22))
6578 gen_helper_usat(tmp
, tmp
, tmp2
);
6580 gen_helper_ssat(tmp
, tmp
, tmp2
);
6581 tcg_temp_free_i32(tmp2
);
6583 store_reg(s
, rd
, tmp
);
6584 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
6586 tmp
= load_reg(s
, rm
);
6587 sh
= (insn
>> 16) & 0x1f;
6589 tmp2
= tcg_const_i32(sh
);
6590 if (insn
& (1 << 22))
6591 gen_helper_usat16(tmp
, tmp
, tmp2
);
6593 gen_helper_ssat16(tmp
, tmp
, tmp2
);
6594 tcg_temp_free_i32(tmp2
);
6596 store_reg(s
, rd
, tmp
);
6597 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
6599 tmp
= load_reg(s
, rn
);
6600 tmp2
= load_reg(s
, rm
);
6602 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
6603 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
6606 store_reg(s
, rd
, tmp
);
6607 } else if ((insn
& 0x000003e0) == 0x00000060) {
6608 tmp
= load_reg(s
, rm
);
6609 shift
= (insn
>> 10) & 3;
6610 /* ??? In many cases it's not neccessary to do a
6611 rotate, a shift is sufficient. */
6613 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
6614 op1
= (insn
>> 20) & 7;
6616 case 0: gen_sxtb16(tmp
); break;
6617 case 2: gen_sxtb(tmp
); break;
6618 case 3: gen_sxth(tmp
); break;
6619 case 4: gen_uxtb16(tmp
); break;
6620 case 6: gen_uxtb(tmp
); break;
6621 case 7: gen_uxth(tmp
); break;
6622 default: goto illegal_op
;
6625 tmp2
= load_reg(s
, rn
);
6626 if ((op1
& 3) == 0) {
6627 gen_add16(tmp
, tmp2
);
6629 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6633 store_reg(s
, rd
, tmp
);
6634 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
6636 tmp
= load_reg(s
, rm
);
6637 if (insn
& (1 << 22)) {
6638 if (insn
& (1 << 7)) {
6642 gen_helper_rbit(tmp
, tmp
);
6645 if (insn
& (1 << 7))
6648 tcg_gen_bswap32_i32(tmp
, tmp
);
6650 store_reg(s
, rd
, tmp
);
6655 case 2: /* Multiplies (Type 3). */
6656 tmp
= load_reg(s
, rm
);
6657 tmp2
= load_reg(s
, rs
);
6658 if (insn
& (1 << 20)) {
6659 /* Signed multiply most significant [accumulate]. */
6660 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6661 if (insn
& (1 << 5))
6662 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
6663 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6665 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6666 tcg_temp_free_i64(tmp64
);
6668 tmp2
= load_reg(s
, rd
);
6669 if (insn
& (1 << 6)) {
6670 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6672 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6676 store_reg(s
, rn
, tmp
);
6678 if (insn
& (1 << 5))
6679 gen_swap_half(tmp2
);
6680 gen_smul_dual(tmp
, tmp2
);
6681 /* This addition cannot overflow. */
6682 if (insn
& (1 << 6)) {
6683 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6685 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6688 if (insn
& (1 << 22)) {
6689 /* smlald, smlsld */
6690 tmp64
= tcg_temp_new_i64();
6691 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6693 gen_addq(s
, tmp64
, rd
, rn
);
6694 gen_storeq_reg(s
, rd
, rn
, tmp64
);
6695 tcg_temp_free_i64(tmp64
);
6697 /* smuad, smusd, smlad, smlsd */
6700 tmp2
= load_reg(s
, rd
);
6701 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6704 store_reg(s
, rn
, tmp
);
6709 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
6711 case 0: /* Unsigned sum of absolute differences. */
6713 tmp
= load_reg(s
, rm
);
6714 tmp2
= load_reg(s
, rs
);
6715 gen_helper_usad8(tmp
, tmp
, tmp2
);
6718 tmp2
= load_reg(s
, rd
);
6719 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6722 store_reg(s
, rn
, tmp
);
6724 case 0x20: case 0x24: case 0x28: case 0x2c:
6725 /* Bitfield insert/clear. */
6727 shift
= (insn
>> 7) & 0x1f;
6728 i
= (insn
>> 16) & 0x1f;
6732 tcg_gen_movi_i32(tmp
, 0);
6734 tmp
= load_reg(s
, rm
);
6737 tmp2
= load_reg(s
, rd
);
6738 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
6741 store_reg(s
, rd
, tmp
);
6743 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6744 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6746 tmp
= load_reg(s
, rm
);
6747 shift
= (insn
>> 7) & 0x1f;
6748 i
= ((insn
>> 16) & 0x1f) + 1;
6753 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
6755 gen_sbfx(tmp
, shift
, i
);
6758 store_reg(s
, rd
, tmp
);
6768 /* Check for undefined extension instructions
6769 * per the ARM Bible IE:
6770 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6772 sh
= (0xf << 20) | (0xf << 4);
6773 if (op1
== 0x7 && ((insn
& sh
) == sh
))
6777 /* load/store byte/word */
6778 rn
= (insn
>> 16) & 0xf;
6779 rd
= (insn
>> 12) & 0xf;
6780 tmp2
= load_reg(s
, rn
);
6781 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
6782 if (insn
& (1 << 24))
6783 gen_add_data_offset(s
, insn
, tmp2
);
6784 if (insn
& (1 << 20)) {
6786 if (insn
& (1 << 22)) {
6787 tmp
= gen_ld8u(tmp2
, i
);
6789 tmp
= gen_ld32(tmp2
, i
);
6793 tmp
= load_reg(s
, rd
);
6794 if (insn
& (1 << 22))
6795 gen_st8(tmp
, tmp2
, i
);
6797 gen_st32(tmp
, tmp2
, i
);
6799 if (!(insn
& (1 << 24))) {
6800 gen_add_data_offset(s
, insn
, tmp2
);
6801 store_reg(s
, rn
, tmp2
);
6802 } else if (insn
& (1 << 21)) {
6803 store_reg(s
, rn
, tmp2
);
6807 if (insn
& (1 << 20)) {
6808 /* Complete the load. */
6812 store_reg(s
, rd
, tmp
);
6818 int j
, n
, user
, loaded_base
;
6820 /* load/store multiple words */
6821 /* XXX: store correct base if write back */
6823 if (insn
& (1 << 22)) {
6825 goto illegal_op
; /* only usable in supervisor mode */
6827 if ((insn
& (1 << 15)) == 0)
6830 rn
= (insn
>> 16) & 0xf;
6831 addr
= load_reg(s
, rn
);
6833 /* compute total size */
6835 TCGV_UNUSED(loaded_var
);
6838 if (insn
& (1 << i
))
6841 /* XXX: test invalid n == 0 case ? */
6842 if (insn
& (1 << 23)) {
6843 if (insn
& (1 << 24)) {
6845 tcg_gen_addi_i32(addr
, addr
, 4);
6847 /* post increment */
6850 if (insn
& (1 << 24)) {
6852 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
6854 /* post decrement */
6856 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
6861 if (insn
& (1 << i
)) {
6862 if (insn
& (1 << 20)) {
6864 tmp
= gen_ld32(addr
, IS_USER(s
));
6868 tmp2
= tcg_const_i32(i
);
6869 gen_helper_set_user_reg(tmp2
, tmp
);
6870 tcg_temp_free_i32(tmp2
);
6872 } else if (i
== rn
) {
6876 store_reg(s
, i
, tmp
);
6881 /* special case: r15 = PC + 8 */
6882 val
= (long)s
->pc
+ 4;
6884 tcg_gen_movi_i32(tmp
, val
);
6887 tmp2
= tcg_const_i32(i
);
6888 gen_helper_get_user_reg(tmp
, tmp2
);
6889 tcg_temp_free_i32(tmp2
);
6891 tmp
= load_reg(s
, i
);
6893 gen_st32(tmp
, addr
, IS_USER(s
));
6896 /* no need to add after the last transfer */
6898 tcg_gen_addi_i32(addr
, addr
, 4);
6901 if (insn
& (1 << 21)) {
6903 if (insn
& (1 << 23)) {
6904 if (insn
& (1 << 24)) {
6907 /* post increment */
6908 tcg_gen_addi_i32(addr
, addr
, 4);
6911 if (insn
& (1 << 24)) {
6914 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
6916 /* post decrement */
6917 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
6920 store_reg(s
, rn
, addr
);
6925 store_reg(s
, rn
, loaded_var
);
6927 if ((insn
& (1 << 22)) && !user
) {
6928 /* Restore CPSR from SPSR. */
6929 tmp
= load_cpu_field(spsr
);
6930 gen_set_cpsr(tmp
, 0xffffffff);
6932 s
->is_jmp
= DISAS_UPDATE
;
6941 /* branch (and link) */
6942 val
= (int32_t)s
->pc
;
6943 if (insn
& (1 << 24)) {
6945 tcg_gen_movi_i32(tmp
, val
);
6946 store_reg(s
, 14, tmp
);
6948 offset
= (((int32_t)insn
<< 8) >> 8);
6949 val
+= (offset
<< 2) + 4;
6957 if (disas_coproc_insn(env
, s
, insn
))
6962 gen_set_pc_im(s
->pc
);
6963 s
->is_jmp
= DISAS_SWI
;
6967 gen_set_condexec(s
);
6968 gen_set_pc_im(s
->pc
- 4);
6969 gen_exception(EXCP_UDEF
);
6970 s
->is_jmp
= DISAS_JUMP
;
6976 /* Return true if this is a Thumb-2 logical op. */
6978 thumb2_logic_op(int op
)
6983 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6984 then set condition code flags based on the result of the operation.
6985 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6986 to the high bit of T1.
6987 Returns zero if the opcode is valid. */
6990 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
6997 tcg_gen_and_i32(t0
, t0
, t1
);
7001 tcg_gen_andc_i32(t0
, t0
, t1
);
7005 tcg_gen_or_i32(t0
, t0
, t1
);
7009 tcg_gen_not_i32(t1
, t1
);
7010 tcg_gen_or_i32(t0
, t0
, t1
);
7014 tcg_gen_xor_i32(t0
, t0
, t1
);
7019 gen_helper_add_cc(t0
, t0
, t1
);
7021 tcg_gen_add_i32(t0
, t0
, t1
);
7025 gen_helper_adc_cc(t0
, t0
, t1
);
7031 gen_helper_sbc_cc(t0
, t0
, t1
);
7033 gen_sub_carry(t0
, t0
, t1
);
7037 gen_helper_sub_cc(t0
, t0
, t1
);
7039 tcg_gen_sub_i32(t0
, t0
, t1
);
7043 gen_helper_sub_cc(t0
, t1
, t0
);
7045 tcg_gen_sub_i32(t0
, t1
, t0
);
7047 default: /* 5, 6, 7, 9, 12, 15. */
7053 gen_set_CF_bit31(t1
);
7058 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7060 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7062 uint32_t insn
, imm
, shift
, offset
;
7063 uint32_t rd
, rn
, rm
, rs
;
7074 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7075 || arm_feature (env
, ARM_FEATURE_M
))) {
7076 /* Thumb-1 cores may need to treat bl and blx as a pair of
7077 16-bit instructions to get correct prefetch abort behavior. */
7079 if ((insn
& (1 << 12)) == 0) {
7080 /* Second half of blx. */
7081 offset
= ((insn
& 0x7ff) << 1);
7082 tmp
= load_reg(s
, 14);
7083 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7084 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7087 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7088 store_reg(s
, 14, tmp2
);
7092 if (insn
& (1 << 11)) {
7093 /* Second half of bl. */
7094 offset
= ((insn
& 0x7ff) << 1) | 1;
7095 tmp
= load_reg(s
, 14);
7096 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7099 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7100 store_reg(s
, 14, tmp2
);
7104 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7105 /* Instruction spans a page boundary. Implement it as two
7106 16-bit instructions in case the second half causes an
7108 offset
= ((int32_t)insn
<< 21) >> 9;
7109 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7112 /* Fall through to 32-bit decode. */
7115 insn
= lduw_code(s
->pc
);
7117 insn
|= (uint32_t)insn_hw1
<< 16;
7119 if ((insn
& 0xf800e800) != 0xf000e800) {
7123 rn
= (insn
>> 16) & 0xf;
7124 rs
= (insn
>> 12) & 0xf;
7125 rd
= (insn
>> 8) & 0xf;
7127 switch ((insn
>> 25) & 0xf) {
7128 case 0: case 1: case 2: case 3:
7129 /* 16-bit instructions. Should never happen. */
7132 if (insn
& (1 << 22)) {
7133 /* Other load/store, table branch. */
7134 if (insn
& 0x01200000) {
7135 /* Load/store doubleword. */
7138 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7140 addr
= load_reg(s
, rn
);
7142 offset
= (insn
& 0xff) * 4;
7143 if ((insn
& (1 << 23)) == 0)
7145 if (insn
& (1 << 24)) {
7146 tcg_gen_addi_i32(addr
, addr
, offset
);
7149 if (insn
& (1 << 20)) {
7151 tmp
= gen_ld32(addr
, IS_USER(s
));
7152 store_reg(s
, rs
, tmp
);
7153 tcg_gen_addi_i32(addr
, addr
, 4);
7154 tmp
= gen_ld32(addr
, IS_USER(s
));
7155 store_reg(s
, rd
, tmp
);
7158 tmp
= load_reg(s
, rs
);
7159 gen_st32(tmp
, addr
, IS_USER(s
));
7160 tcg_gen_addi_i32(addr
, addr
, 4);
7161 tmp
= load_reg(s
, rd
);
7162 gen_st32(tmp
, addr
, IS_USER(s
));
7164 if (insn
& (1 << 21)) {
7165 /* Base writeback. */
7168 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
7169 store_reg(s
, rn
, addr
);
7173 } else if ((insn
& (1 << 23)) == 0) {
7174 /* Load/store exclusive word. */
7175 addr
= tcg_temp_local_new();
7176 load_reg_var(s
, addr
, rn
);
7177 if (insn
& (1 << 20)) {
7178 gen_helper_mark_exclusive(cpu_env
, addr
);
7179 tmp
= gen_ld32(addr
, IS_USER(s
));
7180 store_reg(s
, rd
, tmp
);
7182 int label
= gen_new_label();
7183 tmp2
= tcg_temp_local_new();
7184 gen_helper_test_exclusive(tmp2
, cpu_env
, addr
);
7185 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp2
, 0, label
);
7186 tmp
= load_reg(s
, rs
);
7187 gen_st32(tmp
, addr
, IS_USER(s
));
7188 gen_set_label(label
);
7189 tcg_gen_mov_i32(cpu_R
[rd
], tmp2
);
7190 tcg_temp_free(tmp2
);
7192 tcg_temp_free(addr
);
7193 } else if ((insn
& (1 << 6)) == 0) {
7197 tcg_gen_movi_i32(addr
, s
->pc
);
7199 addr
= load_reg(s
, rn
);
7201 tmp
= load_reg(s
, rm
);
7202 tcg_gen_add_i32(addr
, addr
, tmp
);
7203 if (insn
& (1 << 4)) {
7205 tcg_gen_add_i32(addr
, addr
, tmp
);
7207 tmp
= gen_ld16u(addr
, IS_USER(s
));
7210 tmp
= gen_ld8u(addr
, IS_USER(s
));
7213 tcg_gen_shli_i32(tmp
, tmp
, 1);
7214 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
7215 store_reg(s
, 15, tmp
);
7217 /* Load/store exclusive byte/halfword/doubleword. */
7218 /* ??? These are not really atomic. However we know
7219 we never have multiple CPUs running in parallel,
7220 so it is good enough. */
7221 op
= (insn
>> 4) & 0x3;
7222 addr
= tcg_temp_local_new();
7223 load_reg_var(s
, addr
, rn
);
7224 if (insn
& (1 << 20)) {
7225 gen_helper_mark_exclusive(cpu_env
, addr
);
7228 tmp
= gen_ld8u(addr
, IS_USER(s
));
7231 tmp
= gen_ld16u(addr
, IS_USER(s
));
7234 tmp
= gen_ld32(addr
, IS_USER(s
));
7235 tcg_gen_addi_i32(addr
, addr
, 4);
7236 tmp2
= gen_ld32(addr
, IS_USER(s
));
7237 store_reg(s
, rd
, tmp2
);
7242 store_reg(s
, rs
, tmp
);
7244 int label
= gen_new_label();
7245 tmp2
= tcg_temp_local_new();
7246 gen_helper_test_exclusive(tmp2
, cpu_env
, addr
);
7247 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp2
, 0, label
);
7248 tmp
= load_reg(s
, rs
);
7251 gen_st8(tmp
, addr
, IS_USER(s
));
7254 gen_st16(tmp
, addr
, IS_USER(s
));
7257 gen_st32(tmp
, addr
, IS_USER(s
));
7258 tcg_gen_addi_i32(addr
, addr
, 4);
7259 tmp
= load_reg(s
, rd
);
7260 gen_st32(tmp
, addr
, IS_USER(s
));
7265 gen_set_label(label
);
7266 tcg_gen_mov_i32(cpu_R
[rm
], tmp2
);
7267 tcg_temp_free(tmp2
);
7269 tcg_temp_free(addr
);
7272 /* Load/store multiple, RFE, SRS. */
7273 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
7274 /* Not available in user mode. */
7277 if (insn
& (1 << 20)) {
7279 addr
= load_reg(s
, rn
);
7280 if ((insn
& (1 << 24)) == 0)
7281 tcg_gen_addi_i32(addr
, addr
, -8);
7282 /* Load PC into tmp and CPSR into tmp2. */
7283 tmp
= gen_ld32(addr
, 0);
7284 tcg_gen_addi_i32(addr
, addr
, 4);
7285 tmp2
= gen_ld32(addr
, 0);
7286 if (insn
& (1 << 21)) {
7287 /* Base writeback. */
7288 if (insn
& (1 << 24)) {
7289 tcg_gen_addi_i32(addr
, addr
, 4);
7291 tcg_gen_addi_i32(addr
, addr
, -4);
7293 store_reg(s
, rn
, addr
);
7297 gen_rfe(s
, tmp
, tmp2
);
7301 if (op
== (env
->uncached_cpsr
& CPSR_M
)) {
7302 addr
= load_reg(s
, 13);
7305 tmp
= tcg_const_i32(op
);
7306 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7307 tcg_temp_free_i32(tmp
);
7309 if ((insn
& (1 << 24)) == 0) {
7310 tcg_gen_addi_i32(addr
, addr
, -8);
7312 tmp
= load_reg(s
, 14);
7313 gen_st32(tmp
, addr
, 0);
7314 tcg_gen_addi_i32(addr
, addr
, 4);
7316 gen_helper_cpsr_read(tmp
);
7317 gen_st32(tmp
, addr
, 0);
7318 if (insn
& (1 << 21)) {
7319 if ((insn
& (1 << 24)) == 0) {
7320 tcg_gen_addi_i32(addr
, addr
, -4);
7322 tcg_gen_addi_i32(addr
, addr
, 4);
7324 if (op
== (env
->uncached_cpsr
& CPSR_M
)) {
7325 store_reg(s
, 13, addr
);
7327 tmp
= tcg_const_i32(op
);
7328 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7329 tcg_temp_free_i32(tmp
);
7337 /* Load/store multiple. */
7338 addr
= load_reg(s
, rn
);
7340 for (i
= 0; i
< 16; i
++) {
7341 if (insn
& (1 << i
))
7344 if (insn
& (1 << 24)) {
7345 tcg_gen_addi_i32(addr
, addr
, -offset
);
7348 for (i
= 0; i
< 16; i
++) {
7349 if ((insn
& (1 << i
)) == 0)
7351 if (insn
& (1 << 20)) {
7353 tmp
= gen_ld32(addr
, IS_USER(s
));
7357 store_reg(s
, i
, tmp
);
7361 tmp
= load_reg(s
, i
);
7362 gen_st32(tmp
, addr
, IS_USER(s
));
7364 tcg_gen_addi_i32(addr
, addr
, 4);
7366 if (insn
& (1 << 21)) {
7367 /* Base register writeback. */
7368 if (insn
& (1 << 24)) {
7369 tcg_gen_addi_i32(addr
, addr
, -offset
);
7371 /* Fault if writeback register is in register list. */
7372 if (insn
& (1 << rn
))
7374 store_reg(s
, rn
, addr
);
7381 case 5: /* Data processing register constant shift. */
7384 tcg_gen_movi_i32(tmp
, 0);
7386 tmp
= load_reg(s
, rn
);
7388 tmp2
= load_reg(s
, rm
);
7389 op
= (insn
>> 21) & 0xf;
7390 shiftop
= (insn
>> 4) & 3;
7391 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
7392 conds
= (insn
& (1 << 20)) != 0;
7393 logic_cc
= (conds
&& thumb2_logic_op(op
));
7394 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7395 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
7399 store_reg(s
, rd
, tmp
);
7404 case 13: /* Misc data processing. */
7405 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
7406 if (op
< 4 && (insn
& 0xf000) != 0xf000)
7409 case 0: /* Register controlled shift. */
7410 tmp
= load_reg(s
, rn
);
7411 tmp2
= load_reg(s
, rm
);
7412 if ((insn
& 0x70) != 0)
7414 op
= (insn
>> 21) & 3;
7415 logic_cc
= (insn
& (1 << 20)) != 0;
7416 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
7419 store_reg_bx(env
, s
, rd
, tmp
);
7421 case 1: /* Sign/zero extend. */
7422 tmp
= load_reg(s
, rm
);
7423 shift
= (insn
>> 4) & 3;
7424 /* ??? In many cases it's not neccessary to do a
7425 rotate, a shift is sufficient. */
7427 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7428 op
= (insn
>> 20) & 7;
7430 case 0: gen_sxth(tmp
); break;
7431 case 1: gen_uxth(tmp
); break;
7432 case 2: gen_sxtb16(tmp
); break;
7433 case 3: gen_uxtb16(tmp
); break;
7434 case 4: gen_sxtb(tmp
); break;
7435 case 5: gen_uxtb(tmp
); break;
7436 default: goto illegal_op
;
7439 tmp2
= load_reg(s
, rn
);
7440 if ((op
>> 1) == 1) {
7441 gen_add16(tmp
, tmp2
);
7443 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7447 store_reg(s
, rd
, tmp
);
7449 case 2: /* SIMD add/subtract. */
7450 op
= (insn
>> 20) & 7;
7451 shift
= (insn
>> 4) & 7;
7452 if ((op
& 3) == 3 || (shift
& 3) == 3)
7454 tmp
= load_reg(s
, rn
);
7455 tmp2
= load_reg(s
, rm
);
7456 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
7458 store_reg(s
, rd
, tmp
);
7460 case 3: /* Other data processing. */
7461 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
7463 /* Saturating add/subtract. */
7464 tmp
= load_reg(s
, rn
);
7465 tmp2
= load_reg(s
, rm
);
7467 gen_helper_double_saturate(tmp
, tmp
);
7469 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
7471 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
7474 tmp
= load_reg(s
, rn
);
7476 case 0x0a: /* rbit */
7477 gen_helper_rbit(tmp
, tmp
);
7479 case 0x08: /* rev */
7480 tcg_gen_bswap32_i32(tmp
, tmp
);
7482 case 0x09: /* rev16 */
7485 case 0x0b: /* revsh */
7488 case 0x10: /* sel */
7489 tmp2
= load_reg(s
, rm
);
7491 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7492 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7496 case 0x18: /* clz */
7497 gen_helper_clz(tmp
, tmp
);
7503 store_reg(s
, rd
, tmp
);
7505 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7506 op
= (insn
>> 4) & 0xf;
7507 tmp
= load_reg(s
, rn
);
7508 tmp2
= load_reg(s
, rm
);
7509 switch ((insn
>> 20) & 7) {
7510 case 0: /* 32 x 32 -> 32 */
7511 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7514 tmp2
= load_reg(s
, rs
);
7516 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7518 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7522 case 1: /* 16 x 16 -> 32 */
7523 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7526 tmp2
= load_reg(s
, rs
);
7527 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7531 case 2: /* Dual multiply add. */
7532 case 4: /* Dual multiply subtract. */
7534 gen_swap_half(tmp2
);
7535 gen_smul_dual(tmp
, tmp2
);
7536 /* This addition cannot overflow. */
7537 if (insn
& (1 << 22)) {
7538 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7540 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7545 tmp2
= load_reg(s
, rs
);
7546 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7550 case 3: /* 32 * 16 -> 32msb */
7552 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7555 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7556 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7558 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7559 tcg_temp_free_i64(tmp64
);
7562 tmp2
= load_reg(s
, rs
);
7563 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7567 case 5: case 6: /* 32 * 32 -> 32msb */
7568 gen_imull(tmp
, tmp2
);
7569 if (insn
& (1 << 5)) {
7570 gen_roundqd(tmp
, tmp2
);
7577 tmp2
= load_reg(s
, rs
);
7578 if (insn
& (1 << 21)) {
7579 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7581 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7586 case 7: /* Unsigned sum of absolute differences. */
7587 gen_helper_usad8(tmp
, tmp
, tmp2
);
7590 tmp2
= load_reg(s
, rs
);
7591 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7596 store_reg(s
, rd
, tmp
);
7598 case 6: case 7: /* 64-bit multiply, Divide. */
7599 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
7600 tmp
= load_reg(s
, rn
);
7601 tmp2
= load_reg(s
, rm
);
7602 if ((op
& 0x50) == 0x10) {
7604 if (!arm_feature(env
, ARM_FEATURE_DIV
))
7607 gen_helper_udiv(tmp
, tmp
, tmp2
);
7609 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7611 store_reg(s
, rd
, tmp
);
7612 } else if ((op
& 0xe) == 0xc) {
7613 /* Dual multiply accumulate long. */
7615 gen_swap_half(tmp2
);
7616 gen_smul_dual(tmp
, tmp2
);
7618 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7620 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7624 tmp64
= tcg_temp_new_i64();
7625 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7627 gen_addq(s
, tmp64
, rs
, rd
);
7628 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7629 tcg_temp_free_i64(tmp64
);
7632 /* Unsigned 64-bit multiply */
7633 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7637 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7639 tmp64
= tcg_temp_new_i64();
7640 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7643 /* Signed 64-bit multiply */
7644 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7649 gen_addq_lo(s
, tmp64
, rs
);
7650 gen_addq_lo(s
, tmp64
, rd
);
7651 } else if (op
& 0x40) {
7652 /* 64-bit accumulate. */
7653 gen_addq(s
, tmp64
, rs
, rd
);
7655 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7656 tcg_temp_free_i64(tmp64
);
7661 case 6: case 7: case 14: case 15:
7663 if (((insn
>> 24) & 3) == 3) {
7664 /* Translate into the equivalent ARM encoding. */
7665 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4);
7666 if (disas_neon_data_insn(env
, s
, insn
))
7669 if (insn
& (1 << 28))
7671 if (disas_coproc_insn (env
, s
, insn
))
7675 case 8: case 9: case 10: case 11:
7676 if (insn
& (1 << 15)) {
7677 /* Branches, misc control. */
7678 if (insn
& 0x5000) {
7679 /* Unconditional branch. */
7680 /* signextend(hw1[10:0]) -> offset[:12]. */
7681 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
7682 /* hw1[10:0] -> offset[11:1]. */
7683 offset
|= (insn
& 0x7ff) << 1;
7684 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7685 offset[24:22] already have the same value because of the
7686 sign extension above. */
7687 offset
^= ((~insn
) & (1 << 13)) << 10;
7688 offset
^= ((~insn
) & (1 << 11)) << 11;
7690 if (insn
& (1 << 14)) {
7691 /* Branch and link. */
7692 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
7696 if (insn
& (1 << 12)) {
7701 offset
&= ~(uint32_t)2;
7702 gen_bx_im(s
, offset
);
7704 } else if (((insn
>> 23) & 7) == 7) {
7706 if (insn
& (1 << 13))
7709 if (insn
& (1 << 26)) {
7710 /* Secure monitor call (v6Z) */
7711 goto illegal_op
; /* not implemented. */
7713 op
= (insn
>> 20) & 7;
7715 case 0: /* msr cpsr. */
7717 tmp
= load_reg(s
, rn
);
7718 addr
= tcg_const_i32(insn
& 0xff);
7719 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
7720 tcg_temp_free_i32(addr
);
7726 case 1: /* msr spsr. */
7729 tmp
= load_reg(s
, rn
);
7731 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
7735 case 2: /* cps, nop-hint. */
7736 if (((insn
>> 8) & 7) == 0) {
7737 gen_nop_hint(s
, insn
& 0xff);
7739 /* Implemented as NOP in user mode. */
7744 if (insn
& (1 << 10)) {
7745 if (insn
& (1 << 7))
7747 if (insn
& (1 << 6))
7749 if (insn
& (1 << 5))
7751 if (insn
& (1 << 9))
7752 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
7754 if (insn
& (1 << 8)) {
7756 imm
|= (insn
& 0x1f);
7759 gen_set_psr_im(s
, offset
, 0, imm
);
7762 case 3: /* Special control operations. */
7763 op
= (insn
>> 4) & 0xf;
7766 gen_helper_clrex(cpu_env
);
7771 /* These execute as NOPs. */
7779 /* Trivial implementation equivalent to bx. */
7780 tmp
= load_reg(s
, rn
);
7783 case 5: /* Exception return. */
7784 /* Unpredictable in user mode. */
7786 case 6: /* mrs cpsr. */
7789 addr
= tcg_const_i32(insn
& 0xff);
7790 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
7791 tcg_temp_free_i32(addr
);
7793 gen_helper_cpsr_read(tmp
);
7795 store_reg(s
, rd
, tmp
);
7797 case 7: /* mrs spsr. */
7798 /* Not accessible in user mode. */
7799 if (IS_USER(s
) || IS_M(env
))
7801 tmp
= load_cpu_field(spsr
);
7802 store_reg(s
, rd
, tmp
);
7807 /* Conditional branch. */
7808 op
= (insn
>> 22) & 0xf;
7809 /* Generate a conditional jump to next instruction. */
7810 s
->condlabel
= gen_new_label();
7811 gen_test_cc(op
^ 1, s
->condlabel
);
7814 /* offset[11:1] = insn[10:0] */
7815 offset
= (insn
& 0x7ff) << 1;
7816 /* offset[17:12] = insn[21:16]. */
7817 offset
|= (insn
& 0x003f0000) >> 4;
7818 /* offset[31:20] = insn[26]. */
7819 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
7820 /* offset[18] = insn[13]. */
7821 offset
|= (insn
& (1 << 13)) << 5;
7822 /* offset[19] = insn[11]. */
7823 offset
|= (insn
& (1 << 11)) << 8;
7825 /* jump to the offset */
7826 gen_jmp(s
, s
->pc
+ offset
);
7829 /* Data processing immediate. */
7830 if (insn
& (1 << 25)) {
7831 if (insn
& (1 << 24)) {
7832 if (insn
& (1 << 20))
7834 /* Bitfield/Saturate. */
7835 op
= (insn
>> 21) & 7;
7837 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
7840 tcg_gen_movi_i32(tmp
, 0);
7842 tmp
= load_reg(s
, rn
);
7845 case 2: /* Signed bitfield extract. */
7847 if (shift
+ imm
> 32)
7850 gen_sbfx(tmp
, shift
, imm
);
7852 case 6: /* Unsigned bitfield extract. */
7854 if (shift
+ imm
> 32)
7857 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
7859 case 3: /* Bitfield insert/clear. */
7862 imm
= imm
+ 1 - shift
;
7864 tmp2
= load_reg(s
, rd
);
7865 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
7871 default: /* Saturate. */
7874 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7876 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7878 tmp2
= tcg_const_i32(imm
);
7881 if ((op
& 1) && shift
== 0)
7882 gen_helper_usat16(tmp
, tmp
, tmp2
);
7884 gen_helper_usat(tmp
, tmp
, tmp2
);
7887 if ((op
& 1) && shift
== 0)
7888 gen_helper_ssat16(tmp
, tmp
, tmp2
);
7890 gen_helper_ssat(tmp
, tmp
, tmp2
);
7892 tcg_temp_free_i32(tmp2
);
7895 store_reg(s
, rd
, tmp
);
7897 imm
= ((insn
& 0x04000000) >> 15)
7898 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
7899 if (insn
& (1 << 22)) {
7900 /* 16-bit immediate. */
7901 imm
|= (insn
>> 4) & 0xf000;
7902 if (insn
& (1 << 23)) {
7904 tmp
= load_reg(s
, rd
);
7905 tcg_gen_ext16u_i32(tmp
, tmp
);
7906 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
7910 tcg_gen_movi_i32(tmp
, imm
);
7913 /* Add/sub 12-bit immediate. */
7915 offset
= s
->pc
& ~(uint32_t)3;
7916 if (insn
& (1 << 23))
7921 tcg_gen_movi_i32(tmp
, offset
);
7923 tmp
= load_reg(s
, rn
);
7924 if (insn
& (1 << 23))
7925 tcg_gen_subi_i32(tmp
, tmp
, imm
);
7927 tcg_gen_addi_i32(tmp
, tmp
, imm
);
7930 store_reg(s
, rd
, tmp
);
7933 int shifter_out
= 0;
7934 /* modified 12-bit immediate. */
7935 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
7936 imm
= (insn
& 0xff);
7939 /* Nothing to do. */
7941 case 1: /* 00XY00XY */
7944 case 2: /* XY00XY00 */
7948 case 3: /* XYXYXYXY */
7952 default: /* Rotated constant. */
7953 shift
= (shift
<< 1) | (imm
>> 7);
7955 imm
= imm
<< (32 - shift
);
7960 tcg_gen_movi_i32(tmp2
, imm
);
7961 rn
= (insn
>> 16) & 0xf;
7964 tcg_gen_movi_i32(tmp
, 0);
7966 tmp
= load_reg(s
, rn
);
7968 op
= (insn
>> 21) & 0xf;
7969 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
7970 shifter_out
, tmp
, tmp2
))
7973 rd
= (insn
>> 8) & 0xf;
7975 store_reg(s
, rd
, tmp
);
7982 case 12: /* Load/store single data item. */
7987 if ((insn
& 0x01100000) == 0x01000000) {
7988 if (disas_neon_ls_insn(env
, s
, insn
))
7996 /* s->pc has already been incremented by 4. */
7997 imm
= s
->pc
& 0xfffffffc;
7998 if (insn
& (1 << 23))
7999 imm
+= insn
& 0xfff;
8001 imm
-= insn
& 0xfff;
8002 tcg_gen_movi_i32(addr
, imm
);
8004 addr
= load_reg(s
, rn
);
8005 if (insn
& (1 << 23)) {
8006 /* Positive offset. */
8008 tcg_gen_addi_i32(addr
, addr
, imm
);
8010 op
= (insn
>> 8) & 7;
8013 case 0: case 8: /* Shifted Register. */
8014 shift
= (insn
>> 4) & 0xf;
8017 tmp
= load_reg(s
, rm
);
8019 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8020 tcg_gen_add_i32(addr
, addr
, tmp
);
8023 case 4: /* Negative offset. */
8024 tcg_gen_addi_i32(addr
, addr
, -imm
);
8026 case 6: /* User privilege. */
8027 tcg_gen_addi_i32(addr
, addr
, imm
);
8030 case 1: /* Post-decrement. */
8033 case 3: /* Post-increment. */
8037 case 5: /* Pre-decrement. */
8040 case 7: /* Pre-increment. */
8041 tcg_gen_addi_i32(addr
, addr
, imm
);
8049 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8050 if (insn
& (1 << 20)) {
8052 if (rs
== 15 && op
!= 2) {
8055 /* Memory hint. Implemented as NOP. */
8058 case 0: tmp
= gen_ld8u(addr
, user
); break;
8059 case 4: tmp
= gen_ld8s(addr
, user
); break;
8060 case 1: tmp
= gen_ld16u(addr
, user
); break;
8061 case 5: tmp
= gen_ld16s(addr
, user
); break;
8062 case 2: tmp
= gen_ld32(addr
, user
); break;
8063 default: goto illegal_op
;
8068 store_reg(s
, rs
, tmp
);
8075 tmp
= load_reg(s
, rs
);
8077 case 0: gen_st8(tmp
, addr
, user
); break;
8078 case 1: gen_st16(tmp
, addr
, user
); break;
8079 case 2: gen_st32(tmp
, addr
, user
); break;
8080 default: goto illegal_op
;
8084 tcg_gen_addi_i32(addr
, addr
, imm
);
8086 store_reg(s
, rn
, addr
);
8100 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
8102 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8109 if (s
->condexec_mask
) {
8110 cond
= s
->condexec_cond
;
8111 s
->condlabel
= gen_new_label();
8112 gen_test_cc(cond
^ 1, s
->condlabel
);
8116 insn
= lduw_code(s
->pc
);
8119 switch (insn
>> 12) {
8123 op
= (insn
>> 11) & 3;
8126 rn
= (insn
>> 3) & 7;
8127 tmp
= load_reg(s
, rn
);
8128 if (insn
& (1 << 10)) {
8131 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
8134 rm
= (insn
>> 6) & 7;
8135 tmp2
= load_reg(s
, rm
);
8137 if (insn
& (1 << 9)) {
8138 if (s
->condexec_mask
)
8139 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8141 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8143 if (s
->condexec_mask
)
8144 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8146 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8149 store_reg(s
, rd
, tmp
);
8151 /* shift immediate */
8152 rm
= (insn
>> 3) & 7;
8153 shift
= (insn
>> 6) & 0x1f;
8154 tmp
= load_reg(s
, rm
);
8155 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
8156 if (!s
->condexec_mask
)
8158 store_reg(s
, rd
, tmp
);
8162 /* arithmetic large immediate */
8163 op
= (insn
>> 11) & 3;
8164 rd
= (insn
>> 8) & 0x7;
8165 if (op
== 0) { /* mov */
8167 tcg_gen_movi_i32(tmp
, insn
& 0xff);
8168 if (!s
->condexec_mask
)
8170 store_reg(s
, rd
, tmp
);
8172 tmp
= load_reg(s
, rd
);
8174 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
8177 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8182 if (s
->condexec_mask
)
8183 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8185 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8187 store_reg(s
, rd
, tmp
);
8190 if (s
->condexec_mask
)
8191 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8193 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8195 store_reg(s
, rd
, tmp
);
8201 if (insn
& (1 << 11)) {
8202 rd
= (insn
>> 8) & 7;
8203 /* load pc-relative. Bit 1 of PC is ignored. */
8204 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
8205 val
&= ~(uint32_t)2;
8207 tcg_gen_movi_i32(addr
, val
);
8208 tmp
= gen_ld32(addr
, IS_USER(s
));
8210 store_reg(s
, rd
, tmp
);
8213 if (insn
& (1 << 10)) {
8214 /* data processing extended or blx */
8215 rd
= (insn
& 7) | ((insn
>> 4) & 8);
8216 rm
= (insn
>> 3) & 0xf;
8217 op
= (insn
>> 8) & 3;
8220 tmp
= load_reg(s
, rd
);
8221 tmp2
= load_reg(s
, rm
);
8222 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8224 store_reg(s
, rd
, tmp
);
8227 tmp
= load_reg(s
, rd
);
8228 tmp2
= load_reg(s
, rm
);
8229 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8233 case 2: /* mov/cpy */
8234 tmp
= load_reg(s
, rm
);
8235 store_reg(s
, rd
, tmp
);
8237 case 3:/* branch [and link] exchange thumb register */
8238 tmp
= load_reg(s
, rm
);
8239 if (insn
& (1 << 7)) {
8240 val
= (uint32_t)s
->pc
| 1;
8242 tcg_gen_movi_i32(tmp2
, val
);
8243 store_reg(s
, 14, tmp2
);
8251 /* data processing register */
8253 rm
= (insn
>> 3) & 7;
8254 op
= (insn
>> 6) & 0xf;
8255 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
8256 /* the shift/rotate ops want the operands backwards */
8265 if (op
== 9) { /* neg */
8267 tcg_gen_movi_i32(tmp
, 0);
8268 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
8269 tmp
= load_reg(s
, rd
);
8274 tmp2
= load_reg(s
, rm
);
8277 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8278 if (!s
->condexec_mask
)
8282 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8283 if (!s
->condexec_mask
)
8287 if (s
->condexec_mask
) {
8288 gen_helper_shl(tmp2
, tmp2
, tmp
);
8290 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
8295 if (s
->condexec_mask
) {
8296 gen_helper_shr(tmp2
, tmp2
, tmp
);
8298 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
8303 if (s
->condexec_mask
) {
8304 gen_helper_sar(tmp2
, tmp2
, tmp
);
8306 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
8311 if (s
->condexec_mask
)
8314 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
8317 if (s
->condexec_mask
)
8318 gen_sub_carry(tmp
, tmp
, tmp2
);
8320 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
8323 if (s
->condexec_mask
) {
8324 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
8325 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
8327 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
8332 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8337 if (s
->condexec_mask
)
8338 tcg_gen_neg_i32(tmp
, tmp2
);
8340 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8343 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8347 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8351 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8352 if (!s
->condexec_mask
)
8356 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8357 if (!s
->condexec_mask
)
8361 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8362 if (!s
->condexec_mask
)
8366 tcg_gen_not_i32(tmp2
, tmp2
);
8367 if (!s
->condexec_mask
)
8375 store_reg(s
, rm
, tmp2
);
8379 store_reg(s
, rd
, tmp
);
8389 /* load/store register offset. */
8391 rn
= (insn
>> 3) & 7;
8392 rm
= (insn
>> 6) & 7;
8393 op
= (insn
>> 9) & 7;
8394 addr
= load_reg(s
, rn
);
8395 tmp
= load_reg(s
, rm
);
8396 tcg_gen_add_i32(addr
, addr
, tmp
);
8399 if (op
< 3) /* store */
8400 tmp
= load_reg(s
, rd
);
8404 gen_st32(tmp
, addr
, IS_USER(s
));
8407 gen_st16(tmp
, addr
, IS_USER(s
));
8410 gen_st8(tmp
, addr
, IS_USER(s
));
8413 tmp
= gen_ld8s(addr
, IS_USER(s
));
8416 tmp
= gen_ld32(addr
, IS_USER(s
));
8419 tmp
= gen_ld16u(addr
, IS_USER(s
));
8422 tmp
= gen_ld8u(addr
, IS_USER(s
));
8425 tmp
= gen_ld16s(addr
, IS_USER(s
));
8428 if (op
>= 3) /* load */
8429 store_reg(s
, rd
, tmp
);
8434 /* load/store word immediate offset */
8436 rn
= (insn
>> 3) & 7;
8437 addr
= load_reg(s
, rn
);
8438 val
= (insn
>> 4) & 0x7c;
8439 tcg_gen_addi_i32(addr
, addr
, val
);
8441 if (insn
& (1 << 11)) {
8443 tmp
= gen_ld32(addr
, IS_USER(s
));
8444 store_reg(s
, rd
, tmp
);
8447 tmp
= load_reg(s
, rd
);
8448 gen_st32(tmp
, addr
, IS_USER(s
));
8454 /* load/store byte immediate offset */
8456 rn
= (insn
>> 3) & 7;
8457 addr
= load_reg(s
, rn
);
8458 val
= (insn
>> 6) & 0x1f;
8459 tcg_gen_addi_i32(addr
, addr
, val
);
8461 if (insn
& (1 << 11)) {
8463 tmp
= gen_ld8u(addr
, IS_USER(s
));
8464 store_reg(s
, rd
, tmp
);
8467 tmp
= load_reg(s
, rd
);
8468 gen_st8(tmp
, addr
, IS_USER(s
));
8474 /* load/store halfword immediate offset */
8476 rn
= (insn
>> 3) & 7;
8477 addr
= load_reg(s
, rn
);
8478 val
= (insn
>> 5) & 0x3e;
8479 tcg_gen_addi_i32(addr
, addr
, val
);
8481 if (insn
& (1 << 11)) {
8483 tmp
= gen_ld16u(addr
, IS_USER(s
));
8484 store_reg(s
, rd
, tmp
);
8487 tmp
= load_reg(s
, rd
);
8488 gen_st16(tmp
, addr
, IS_USER(s
));
8494 /* load/store from stack */
8495 rd
= (insn
>> 8) & 7;
8496 addr
= load_reg(s
, 13);
8497 val
= (insn
& 0xff) * 4;
8498 tcg_gen_addi_i32(addr
, addr
, val
);
8500 if (insn
& (1 << 11)) {
8502 tmp
= gen_ld32(addr
, IS_USER(s
));
8503 store_reg(s
, rd
, tmp
);
8506 tmp
= load_reg(s
, rd
);
8507 gen_st32(tmp
, addr
, IS_USER(s
));
8513 /* add to high reg */
8514 rd
= (insn
>> 8) & 7;
8515 if (insn
& (1 << 11)) {
8517 tmp
= load_reg(s
, 13);
8519 /* PC. bit 1 is ignored. */
8521 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
8523 val
= (insn
& 0xff) * 4;
8524 tcg_gen_addi_i32(tmp
, tmp
, val
);
8525 store_reg(s
, rd
, tmp
);
8530 op
= (insn
>> 8) & 0xf;
8533 /* adjust stack pointer */
8534 tmp
= load_reg(s
, 13);
8535 val
= (insn
& 0x7f) * 4;
8536 if (insn
& (1 << 7))
8537 val
= -(int32_t)val
;
8538 tcg_gen_addi_i32(tmp
, tmp
, val
);
8539 store_reg(s
, 13, tmp
);
8542 case 2: /* sign/zero extend. */
8545 rm
= (insn
>> 3) & 7;
8546 tmp
= load_reg(s
, rm
);
8547 switch ((insn
>> 6) & 3) {
8548 case 0: gen_sxth(tmp
); break;
8549 case 1: gen_sxtb(tmp
); break;
8550 case 2: gen_uxth(tmp
); break;
8551 case 3: gen_uxtb(tmp
); break;
8553 store_reg(s
, rd
, tmp
);
8555 case 4: case 5: case 0xc: case 0xd:
8557 addr
= load_reg(s
, 13);
8558 if (insn
& (1 << 8))
8562 for (i
= 0; i
< 8; i
++) {
8563 if (insn
& (1 << i
))
8566 if ((insn
& (1 << 11)) == 0) {
8567 tcg_gen_addi_i32(addr
, addr
, -offset
);
8569 for (i
= 0; i
< 8; i
++) {
8570 if (insn
& (1 << i
)) {
8571 if (insn
& (1 << 11)) {
8573 tmp
= gen_ld32(addr
, IS_USER(s
));
8574 store_reg(s
, i
, tmp
);
8577 tmp
= load_reg(s
, i
);
8578 gen_st32(tmp
, addr
, IS_USER(s
));
8580 /* advance to the next address. */
8581 tcg_gen_addi_i32(addr
, addr
, 4);
8585 if (insn
& (1 << 8)) {
8586 if (insn
& (1 << 11)) {
8588 tmp
= gen_ld32(addr
, IS_USER(s
));
8589 /* don't set the pc until the rest of the instruction
8593 tmp
= load_reg(s
, 14);
8594 gen_st32(tmp
, addr
, IS_USER(s
));
8596 tcg_gen_addi_i32(addr
, addr
, 4);
8598 if ((insn
& (1 << 11)) == 0) {
8599 tcg_gen_addi_i32(addr
, addr
, -offset
);
8601 /* write back the new stack pointer */
8602 store_reg(s
, 13, addr
);
8603 /* set the new PC value */
8604 if ((insn
& 0x0900) == 0x0900)
8608 case 1: case 3: case 9: case 11: /* czb */
8610 tmp
= load_reg(s
, rm
);
8611 s
->condlabel
= gen_new_label();
8613 if (insn
& (1 << 11))
8614 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
8616 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
8618 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
8619 val
= (uint32_t)s
->pc
+ 2;
8624 case 15: /* IT, nop-hint. */
8625 if ((insn
& 0xf) == 0) {
8626 gen_nop_hint(s
, (insn
>> 4) & 0xf);
8630 s
->condexec_cond
= (insn
>> 4) & 0xe;
8631 s
->condexec_mask
= insn
& 0x1f;
8632 /* No actual code generated for this insn, just setup state. */
8635 case 0xe: /* bkpt */
8636 gen_set_condexec(s
);
8637 gen_set_pc_im(s
->pc
- 2);
8638 gen_exception(EXCP_BKPT
);
8639 s
->is_jmp
= DISAS_JUMP
;
8644 rn
= (insn
>> 3) & 0x7;
8646 tmp
= load_reg(s
, rn
);
8647 switch ((insn
>> 6) & 3) {
8648 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
8649 case 1: gen_rev16(tmp
); break;
8650 case 3: gen_revsh(tmp
); break;
8651 default: goto illegal_op
;
8653 store_reg(s
, rd
, tmp
);
8661 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
8664 addr
= tcg_const_i32(16);
8665 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8666 tcg_temp_free_i32(addr
);
8670 addr
= tcg_const_i32(17);
8671 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8672 tcg_temp_free_i32(addr
);
8674 tcg_temp_free_i32(tmp
);
8677 if (insn
& (1 << 4))
8678 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
8681 gen_set_psr_im(s
, shift
, 0, ((insn
& 7) << 6) & shift
);
8691 /* load/store multiple */
8692 rn
= (insn
>> 8) & 0x7;
8693 addr
= load_reg(s
, rn
);
8694 for (i
= 0; i
< 8; i
++) {
8695 if (insn
& (1 << i
)) {
8696 if (insn
& (1 << 11)) {
8698 tmp
= gen_ld32(addr
, IS_USER(s
));
8699 store_reg(s
, i
, tmp
);
8702 tmp
= load_reg(s
, i
);
8703 gen_st32(tmp
, addr
, IS_USER(s
));
8705 /* advance to the next address */
8706 tcg_gen_addi_i32(addr
, addr
, 4);
8709 /* Base register writeback. */
8710 if ((insn
& (1 << rn
)) == 0) {
8711 store_reg(s
, rn
, addr
);
8718 /* conditional branch or swi */
8719 cond
= (insn
>> 8) & 0xf;
8725 gen_set_condexec(s
);
8726 gen_set_pc_im(s
->pc
);
8727 s
->is_jmp
= DISAS_SWI
;
8730 /* generate a conditional jump to next instruction */
8731 s
->condlabel
= gen_new_label();
8732 gen_test_cc(cond
^ 1, s
->condlabel
);
8735 /* jump to the offset */
8736 val
= (uint32_t)s
->pc
+ 2;
8737 offset
= ((int32_t)insn
<< 24) >> 24;
8743 if (insn
& (1 << 11)) {
8744 if (disas_thumb2_insn(env
, s
, insn
))
8748 /* unconditional branch */
8749 val
= (uint32_t)s
->pc
;
8750 offset
= ((int32_t)insn
<< 21) >> 21;
8751 val
+= (offset
<< 1) + 2;
8756 if (disas_thumb2_insn(env
, s
, insn
))
8762 gen_set_condexec(s
);
8763 gen_set_pc_im(s
->pc
- 4);
8764 gen_exception(EXCP_UDEF
);
8765 s
->is_jmp
= DISAS_JUMP
;
8769 gen_set_condexec(s
);
8770 gen_set_pc_im(s
->pc
- 2);
8771 gen_exception(EXCP_UDEF
);
8772 s
->is_jmp
= DISAS_JUMP
;
8775 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8776 basic block 'tb'. If search_pc is TRUE, also generate PC
8777 information for each intermediate instruction. */
8778 static inline void gen_intermediate_code_internal(CPUState
*env
,
8779 TranslationBlock
*tb
,
8782 DisasContext dc1
, *dc
= &dc1
;
8784 uint16_t *gen_opc_end
;
8786 target_ulong pc_start
;
8787 uint32_t next_page_start
;
8791 /* generate intermediate code */
8798 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
8800 dc
->is_jmp
= DISAS_NEXT
;
8802 dc
->singlestep_enabled
= env
->singlestep_enabled
;
8804 dc
->thumb
= env
->thumb
;
8805 dc
->condexec_mask
= (env
->condexec_bits
& 0xf) << 1;
8806 dc
->condexec_cond
= env
->condexec_bits
>> 4;
8807 #if !defined(CONFIG_USER_ONLY)
8809 dc
->user
= ((env
->v7m
.exception
== 0) && (env
->v7m
.control
& 1));
8811 dc
->user
= (env
->uncached_cpsr
& 0x1f) == ARM_CPU_MODE_USR
;
8814 cpu_F0s
= tcg_temp_new_i32();
8815 cpu_F1s
= tcg_temp_new_i32();
8816 cpu_F0d
= tcg_temp_new_i64();
8817 cpu_F1d
= tcg_temp_new_i64();
8820 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8821 cpu_M0
= tcg_temp_new_i64();
8822 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
8825 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8827 max_insns
= CF_COUNT_MASK
;
8830 /* Reset the conditional execution bits immediately. This avoids
8831 complications trying to do it at the end of the block. */
8832 if (env
->condexec_bits
)
8834 TCGv tmp
= new_tmp();
8835 tcg_gen_movi_i32(tmp
, 0);
8836 store_cpu_field(tmp
, condexec_bits
);
8839 #ifdef CONFIG_USER_ONLY
8840 /* Intercept jump to the magic kernel page. */
8841 if (dc
->pc
>= 0xffff0000) {
8842 /* We always get here via a jump, so know we are not in a
8843 conditional execution block. */
8844 gen_exception(EXCP_KERNEL_TRAP
);
8845 dc
->is_jmp
= DISAS_UPDATE
;
8849 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
8850 /* We always get here via a jump, so know we are not in a
8851 conditional execution block. */
8852 gen_exception(EXCP_EXCEPTION_EXIT
);
8853 dc
->is_jmp
= DISAS_UPDATE
;
8858 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8859 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8860 if (bp
->pc
== dc
->pc
) {
8861 gen_set_condexec(dc
);
8862 gen_set_pc_im(dc
->pc
);
8863 gen_exception(EXCP_DEBUG
);
8864 dc
->is_jmp
= DISAS_JUMP
;
8865 /* Advance PC so that clearing the breakpoint will
8866 invalidate this TB. */
8868 goto done_generating
;
8874 j
= gen_opc_ptr
- gen_opc_buf
;
8878 gen_opc_instr_start
[lj
++] = 0;
8880 gen_opc_pc
[lj
] = dc
->pc
;
8881 gen_opc_instr_start
[lj
] = 1;
8882 gen_opc_icount
[lj
] = num_insns
;
8885 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8889 disas_thumb_insn(env
, dc
);
8890 if (dc
->condexec_mask
) {
8891 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
8892 | ((dc
->condexec_mask
>> 4) & 1);
8893 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
8894 if (dc
->condexec_mask
== 0) {
8895 dc
->condexec_cond
= 0;
8899 disas_arm_insn(env
, dc
);
8902 fprintf(stderr
, "Internal resource leak before %08x\n", dc
->pc
);
8906 if (dc
->condjmp
&& !dc
->is_jmp
) {
8907 gen_set_label(dc
->condlabel
);
8910 /* Translation stops when a conditional branch is encountered.
8911 * Otherwise the subsequent code could get translated several times.
8912 * Also stop translation when a page boundary is reached. This
8913 * ensures prefetch aborts occur at the right place. */
8915 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
8916 !env
->singlestep_enabled
&&
8918 dc
->pc
< next_page_start
&&
8919 num_insns
< max_insns
);
8921 if (tb
->cflags
& CF_LAST_IO
) {
8923 /* FIXME: This can theoretically happen with self-modifying
8925 cpu_abort(env
, "IO on conditional branch instruction");
8930 /* At this stage dc->condjmp will only be set when the skipped
8931 instruction was a conditional branch or trap, and the PC has
8932 already been written. */
8933 if (unlikely(env
->singlestep_enabled
)) {
8934 /* Make sure the pc is updated, and raise a debug exception. */
8936 gen_set_condexec(dc
);
8937 if (dc
->is_jmp
== DISAS_SWI
) {
8938 gen_exception(EXCP_SWI
);
8940 gen_exception(EXCP_DEBUG
);
8942 gen_set_label(dc
->condlabel
);
8944 if (dc
->condjmp
|| !dc
->is_jmp
) {
8945 gen_set_pc_im(dc
->pc
);
8948 gen_set_condexec(dc
);
8949 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
8950 gen_exception(EXCP_SWI
);
8952 /* FIXME: Single stepping a WFI insn will not halt
8954 gen_exception(EXCP_DEBUG
);
8957 /* While branches must always occur at the end of an IT block,
8958 there are a few other things that can cause us to terminate
8959 the TB in the middel of an IT block:
8960 - Exception generating instructions (bkpt, swi, undefined).
8962 - Hardware watchpoints.
8963 Hardware breakpoints have already been handled and skip this code.
8965 gen_set_condexec(dc
);
8966 switch(dc
->is_jmp
) {
8968 gen_goto_tb(dc
, 1, dc
->pc
);
8973 /* indicate that the hash table must be used to find the next TB */
8977 /* nothing more to generate */
8983 gen_exception(EXCP_SWI
);
8987 gen_set_label(dc
->condlabel
);
8988 gen_set_condexec(dc
);
8989 gen_goto_tb(dc
, 1, dc
->pc
);
8995 gen_icount_end(tb
, num_insns
);
8996 *gen_opc_ptr
= INDEX_op_end
;
8999 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9000 qemu_log("----------------\n");
9001 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9002 log_target_disas(pc_start
, dc
->pc
- pc_start
, env
->thumb
);
9007 j
= gen_opc_ptr
- gen_opc_buf
;
9010 gen_opc_instr_start
[lj
++] = 0;
9012 tb
->size
= dc
->pc
- pc_start
;
9013 tb
->icount
= num_insns
;
9017 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9019 gen_intermediate_code_internal(env
, tb
, 0);
9022 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9024 gen_intermediate_code_internal(env
, tb
, 1);
9027 static const char *cpu_mode_names
[16] = {
9028 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9029 "???", "???", "???", "und", "???", "???", "???", "sys"
9032 void cpu_dump_state(CPUState
*env
, FILE *f
,
9033 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
9043 /* ??? This assumes float64 and double have the same layout.
9044 Oh well, it's only debug dumps. */
9053 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9055 cpu_fprintf(f
, "\n");
9057 cpu_fprintf(f
, " ");
9059 psr
= cpsr_read(env
);
9060 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9062 psr
& (1 << 31) ? 'N' : '-',
9063 psr
& (1 << 30) ? 'Z' : '-',
9064 psr
& (1 << 29) ? 'C' : '-',
9065 psr
& (1 << 28) ? 'V' : '-',
9066 psr
& CPSR_T
? 'T' : 'A',
9067 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9070 for (i
= 0; i
< 16; i
++) {
9071 d
.d
= env
->vfp
.regs
[i
];
9075 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9076 i
* 2, (int)s0
.i
, s0
.s
,
9077 i
* 2 + 1, (int)s1
.i
, s1
.s
,
9078 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
9081 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
9085 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
9086 unsigned long searched_pc
, int pc_pos
, void *puc
)
9088 env
->regs
[15] = gen_opc_pc
[pc_pos
];