4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
37 #define ENABLE_ARCH_5J 0
38 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
39 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
40 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
41 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
43 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
45 /* internal defines */
46 typedef struct DisasContext
{
49 /* Nonzero if this instruction has been conditionally skipped. */
51 /* The label that will be jumped to when the instruction is skipped. */
53 /* Thumb-2 condtional execution bits. */
56 struct TranslationBlock
*tb
;
57 int singlestep_enabled
;
59 #if !defined(CONFIG_USER_ONLY)
67 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
69 #if defined(CONFIG_USER_ONLY)
72 #define IS_USER(s) (s->user)
75 /* These instructions trap after executing, so defer them until after the
76 conditional executions state has been updated. */
80 static TCGv_ptr cpu_env
;
81 /* We reuse the same 64-bit temporaries for efficiency. */
82 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
83 static TCGv_i32 cpu_R
[16];
84 static TCGv_i32 cpu_exclusive_addr
;
85 static TCGv_i32 cpu_exclusive_val
;
86 static TCGv_i32 cpu_exclusive_high
;
87 #ifdef CONFIG_USER_ONLY
88 static TCGv_i32 cpu_exclusive_test
;
89 static TCGv_i32 cpu_exclusive_info
;
92 /* FIXME: These should be removed. */
93 static TCGv cpu_F0s
, cpu_F1s
;
94 static TCGv_i64 cpu_F0d
, cpu_F1d
;
96 #include "gen-icount.h"
98 static const char *regnames
[] =
99 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
100 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
102 /* initialize TCG globals. */
103 void arm_translate_init(void)
107 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
109 for (i
= 0; i
< 16; i
++) {
110 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
111 offsetof(CPUState
, regs
[i
]),
114 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
115 offsetof(CPUState
, exclusive_addr
), "exclusive_addr");
116 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
117 offsetof(CPUState
, exclusive_val
), "exclusive_val");
118 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
119 offsetof(CPUState
, exclusive_high
), "exclusive_high");
120 #ifdef CONFIG_USER_ONLY
121 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
122 offsetof(CPUState
, exclusive_test
), "exclusive_test");
123 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
124 offsetof(CPUState
, exclusive_info
), "exclusive_info");
131 static inline TCGv
load_cpu_offset(int offset
)
133 TCGv tmp
= tcg_temp_new_i32();
134 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
138 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
140 static inline void store_cpu_offset(TCGv var
, int offset
)
142 tcg_gen_st_i32(var
, cpu_env
, offset
);
143 tcg_temp_free_i32(var
);
146 #define store_cpu_field(var, name) \
147 store_cpu_offset(var, offsetof(CPUState, name))
149 /* Set a variable to the value of a CPU register. */
150 static void load_reg_var(DisasContext
*s
, TCGv var
, int reg
)
154 /* normaly, since we updated PC, we need only to add one insn */
156 addr
= (long)s
->pc
+ 2;
158 addr
= (long)s
->pc
+ 4;
159 tcg_gen_movi_i32(var
, addr
);
161 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
165 /* Create a new temporary and set it to the value of a CPU register. */
166 static inline TCGv
load_reg(DisasContext
*s
, int reg
)
168 TCGv tmp
= tcg_temp_new_i32();
169 load_reg_var(s
, tmp
, reg
);
173 /* Set a CPU register. The source must be a temporary and will be
175 static void store_reg(DisasContext
*s
, int reg
, TCGv var
)
178 tcg_gen_andi_i32(var
, var
, ~1);
179 s
->is_jmp
= DISAS_JUMP
;
181 tcg_gen_mov_i32(cpu_R
[reg
], var
);
182 tcg_temp_free_i32(var
);
185 /* Value extensions. */
186 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
187 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
188 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
189 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
191 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
192 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
195 static inline void gen_set_cpsr(TCGv var
, uint32_t mask
)
197 TCGv tmp_mask
= tcg_const_i32(mask
);
198 gen_helper_cpsr_write(var
, tmp_mask
);
199 tcg_temp_free_i32(tmp_mask
);
201 /* Set NZCV flags from the high 4 bits of var. */
202 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
204 static void gen_exception(int excp
)
206 TCGv tmp
= tcg_temp_new_i32();
207 tcg_gen_movi_i32(tmp
, excp
);
208 gen_helper_exception(tmp
);
209 tcg_temp_free_i32(tmp
);
212 static void gen_smul_dual(TCGv a
, TCGv b
)
214 TCGv tmp1
= tcg_temp_new_i32();
215 TCGv tmp2
= tcg_temp_new_i32();
216 tcg_gen_ext16s_i32(tmp1
, a
);
217 tcg_gen_ext16s_i32(tmp2
, b
);
218 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
219 tcg_temp_free_i32(tmp2
);
220 tcg_gen_sari_i32(a
, a
, 16);
221 tcg_gen_sari_i32(b
, b
, 16);
222 tcg_gen_mul_i32(b
, b
, a
);
223 tcg_gen_mov_i32(a
, tmp1
);
224 tcg_temp_free_i32(tmp1
);
227 /* Byteswap each halfword. */
228 static void gen_rev16(TCGv var
)
230 TCGv tmp
= tcg_temp_new_i32();
231 tcg_gen_shri_i32(tmp
, var
, 8);
232 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
233 tcg_gen_shli_i32(var
, var
, 8);
234 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
235 tcg_gen_or_i32(var
, var
, tmp
);
236 tcg_temp_free_i32(tmp
);
239 /* Byteswap low halfword and sign extend. */
240 static void gen_revsh(TCGv var
)
242 tcg_gen_ext16u_i32(var
, var
);
243 tcg_gen_bswap16_i32(var
, var
);
244 tcg_gen_ext16s_i32(var
, var
);
247 /* Unsigned bitfield extract. */
248 static void gen_ubfx(TCGv var
, int shift
, uint32_t mask
)
251 tcg_gen_shri_i32(var
, var
, shift
);
252 tcg_gen_andi_i32(var
, var
, mask
);
255 /* Signed bitfield extract. */
256 static void gen_sbfx(TCGv var
, int shift
, int width
)
261 tcg_gen_sari_i32(var
, var
, shift
);
262 if (shift
+ width
< 32) {
263 signbit
= 1u << (width
- 1);
264 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
265 tcg_gen_xori_i32(var
, var
, signbit
);
266 tcg_gen_subi_i32(var
, var
, signbit
);
270 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
271 static void gen_bfi(TCGv dest
, TCGv base
, TCGv val
, int shift
, uint32_t mask
)
273 tcg_gen_andi_i32(val
, val
, mask
);
274 tcg_gen_shli_i32(val
, val
, shift
);
275 tcg_gen_andi_i32(base
, base
, ~(mask
<< shift
));
276 tcg_gen_or_i32(dest
, base
, val
);
279 /* Return (b << 32) + a. Mark inputs as dead */
280 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
282 TCGv_i64 tmp64
= tcg_temp_new_i64();
284 tcg_gen_extu_i32_i64(tmp64
, b
);
285 tcg_temp_free_i32(b
);
286 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
287 tcg_gen_add_i64(a
, tmp64
, a
);
289 tcg_temp_free_i64(tmp64
);
293 /* Return (b << 32) - a. Mark inputs as dead. */
294 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
296 TCGv_i64 tmp64
= tcg_temp_new_i64();
298 tcg_gen_extu_i32_i64(tmp64
, b
);
299 tcg_temp_free_i32(b
);
300 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
301 tcg_gen_sub_i64(a
, tmp64
, a
);
303 tcg_temp_free_i64(tmp64
);
307 /* FIXME: Most targets have native widening multiplication.
308 It would be good to use that instead of a full wide multiply. */
309 /* 32x32->64 multiply. Marks inputs as dead. */
310 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
312 TCGv_i64 tmp1
= tcg_temp_new_i64();
313 TCGv_i64 tmp2
= tcg_temp_new_i64();
315 tcg_gen_extu_i32_i64(tmp1
, a
);
316 tcg_temp_free_i32(a
);
317 tcg_gen_extu_i32_i64(tmp2
, b
);
318 tcg_temp_free_i32(b
);
319 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
320 tcg_temp_free_i64(tmp2
);
324 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
326 TCGv_i64 tmp1
= tcg_temp_new_i64();
327 TCGv_i64 tmp2
= tcg_temp_new_i64();
329 tcg_gen_ext_i32_i64(tmp1
, a
);
330 tcg_temp_free_i32(a
);
331 tcg_gen_ext_i32_i64(tmp2
, b
);
332 tcg_temp_free_i32(b
);
333 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
334 tcg_temp_free_i64(tmp2
);
338 /* Swap low and high halfwords. */
339 static void gen_swap_half(TCGv var
)
341 TCGv tmp
= tcg_temp_new_i32();
342 tcg_gen_shri_i32(tmp
, var
, 16);
343 tcg_gen_shli_i32(var
, var
, 16);
344 tcg_gen_or_i32(var
, var
, tmp
);
345 tcg_temp_free_i32(tmp
);
348 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
349 tmp = (t0 ^ t1) & 0x8000;
352 t0 = (t0 + t1) ^ tmp;
355 static void gen_add16(TCGv t0
, TCGv t1
)
357 TCGv tmp
= tcg_temp_new_i32();
358 tcg_gen_xor_i32(tmp
, t0
, t1
);
359 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
360 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
361 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
362 tcg_gen_add_i32(t0
, t0
, t1
);
363 tcg_gen_xor_i32(t0
, t0
, tmp
);
364 tcg_temp_free_i32(tmp
);
365 tcg_temp_free_i32(t1
);
368 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
370 /* Set CF to the top bit of var. */
371 static void gen_set_CF_bit31(TCGv var
)
373 TCGv tmp
= tcg_temp_new_i32();
374 tcg_gen_shri_i32(tmp
, var
, 31);
376 tcg_temp_free_i32(tmp
);
379 /* Set N and Z flags from var. */
380 static inline void gen_logic_CC(TCGv var
)
382 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, NF
));
383 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, ZF
));
387 static void gen_adc(TCGv t0
, TCGv t1
)
390 tcg_gen_add_i32(t0
, t0
, t1
);
391 tmp
= load_cpu_field(CF
);
392 tcg_gen_add_i32(t0
, t0
, tmp
);
393 tcg_temp_free_i32(tmp
);
396 /* dest = T0 + T1 + CF. */
397 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
400 tcg_gen_add_i32(dest
, t0
, t1
);
401 tmp
= load_cpu_field(CF
);
402 tcg_gen_add_i32(dest
, dest
, tmp
);
403 tcg_temp_free_i32(tmp
);
406 /* dest = T0 - T1 + CF - 1. */
407 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
410 tcg_gen_sub_i32(dest
, t0
, t1
);
411 tmp
= load_cpu_field(CF
);
412 tcg_gen_add_i32(dest
, dest
, tmp
);
413 tcg_gen_subi_i32(dest
, dest
, 1);
414 tcg_temp_free_i32(tmp
);
417 /* FIXME: Implement this natively. */
418 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
420 static void shifter_out_im(TCGv var
, int shift
)
422 TCGv tmp
= tcg_temp_new_i32();
424 tcg_gen_andi_i32(tmp
, var
, 1);
426 tcg_gen_shri_i32(tmp
, var
, shift
);
428 tcg_gen_andi_i32(tmp
, tmp
, 1);
431 tcg_temp_free_i32(tmp
);
434 /* Shift by immediate. Includes special handling for shift == 0. */
435 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
441 shifter_out_im(var
, 32 - shift
);
442 tcg_gen_shli_i32(var
, var
, shift
);
448 tcg_gen_shri_i32(var
, var
, 31);
451 tcg_gen_movi_i32(var
, 0);
454 shifter_out_im(var
, shift
- 1);
455 tcg_gen_shri_i32(var
, var
, shift
);
462 shifter_out_im(var
, shift
- 1);
465 tcg_gen_sari_i32(var
, var
, shift
);
467 case 3: /* ROR/RRX */
470 shifter_out_im(var
, shift
- 1);
471 tcg_gen_rotri_i32(var
, var
, shift
); break;
473 TCGv tmp
= load_cpu_field(CF
);
475 shifter_out_im(var
, 0);
476 tcg_gen_shri_i32(var
, var
, 1);
477 tcg_gen_shli_i32(tmp
, tmp
, 31);
478 tcg_gen_or_i32(var
, var
, tmp
);
479 tcg_temp_free_i32(tmp
);
484 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
485 TCGv shift
, int flags
)
489 case 0: gen_helper_shl_cc(var
, var
, shift
); break;
490 case 1: gen_helper_shr_cc(var
, var
, shift
); break;
491 case 2: gen_helper_sar_cc(var
, var
, shift
); break;
492 case 3: gen_helper_ror_cc(var
, var
, shift
); break;
496 case 0: gen_helper_shl(var
, var
, shift
); break;
497 case 1: gen_helper_shr(var
, var
, shift
); break;
498 case 2: gen_helper_sar(var
, var
, shift
); break;
499 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
500 tcg_gen_rotr_i32(var
, var
, shift
); break;
503 tcg_temp_free_i32(shift
);
506 #define PAS_OP(pfx) \
508 case 0: gen_pas_helper(glue(pfx,add16)); break; \
509 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
510 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
511 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
512 case 4: gen_pas_helper(glue(pfx,add8)); break; \
513 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
515 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
520 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
522 tmp
= tcg_temp_new_ptr();
523 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
525 tcg_temp_free_ptr(tmp
);
528 tmp
= tcg_temp_new_ptr();
529 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
531 tcg_temp_free_ptr(tmp
);
533 #undef gen_pas_helper
534 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
547 #undef gen_pas_helper
552 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
553 #define PAS_OP(pfx) \
555 case 0: gen_pas_helper(glue(pfx,add8)); break; \
556 case 1: gen_pas_helper(glue(pfx,add16)); break; \
557 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
558 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
559 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
560 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
562 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
567 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
569 tmp
= tcg_temp_new_ptr();
570 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
572 tcg_temp_free_ptr(tmp
);
575 tmp
= tcg_temp_new_ptr();
576 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
578 tcg_temp_free_ptr(tmp
);
580 #undef gen_pas_helper
581 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
594 #undef gen_pas_helper
599 static void gen_test_cc(int cc
, int label
)
607 tmp
= load_cpu_field(ZF
);
608 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
611 tmp
= load_cpu_field(ZF
);
612 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
615 tmp
= load_cpu_field(CF
);
616 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
619 tmp
= load_cpu_field(CF
);
620 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
623 tmp
= load_cpu_field(NF
);
624 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
627 tmp
= load_cpu_field(NF
);
628 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
631 tmp
= load_cpu_field(VF
);
632 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
635 tmp
= load_cpu_field(VF
);
636 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
638 case 8: /* hi: C && !Z */
639 inv
= gen_new_label();
640 tmp
= load_cpu_field(CF
);
641 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
642 tcg_temp_free_i32(tmp
);
643 tmp
= load_cpu_field(ZF
);
644 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
647 case 9: /* ls: !C || Z */
648 tmp
= load_cpu_field(CF
);
649 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
650 tcg_temp_free_i32(tmp
);
651 tmp
= load_cpu_field(ZF
);
652 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
654 case 10: /* ge: N == V -> N ^ V == 0 */
655 tmp
= load_cpu_field(VF
);
656 tmp2
= load_cpu_field(NF
);
657 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
658 tcg_temp_free_i32(tmp2
);
659 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
661 case 11: /* lt: N != V -> N ^ V != 0 */
662 tmp
= load_cpu_field(VF
);
663 tmp2
= load_cpu_field(NF
);
664 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
665 tcg_temp_free_i32(tmp2
);
666 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
668 case 12: /* gt: !Z && N == V */
669 inv
= gen_new_label();
670 tmp
= load_cpu_field(ZF
);
671 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
672 tcg_temp_free_i32(tmp
);
673 tmp
= load_cpu_field(VF
);
674 tmp2
= load_cpu_field(NF
);
675 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
676 tcg_temp_free_i32(tmp2
);
677 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
680 case 13: /* le: Z || N != V */
681 tmp
= load_cpu_field(ZF
);
682 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
683 tcg_temp_free_i32(tmp
);
684 tmp
= load_cpu_field(VF
);
685 tmp2
= load_cpu_field(NF
);
686 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
687 tcg_temp_free_i32(tmp2
);
688 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
691 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
694 tcg_temp_free_i32(tmp
);
697 static const uint8_t table_logic_cc
[16] = {
716 /* Set PC and Thumb state from an immediate address. */
717 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
721 s
->is_jmp
= DISAS_UPDATE
;
722 if (s
->thumb
!= (addr
& 1)) {
723 tmp
= tcg_temp_new_i32();
724 tcg_gen_movi_i32(tmp
, addr
& 1);
725 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUState
, thumb
));
726 tcg_temp_free_i32(tmp
);
728 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
731 /* Set PC and Thumb state from var. var is marked as dead. */
732 static inline void gen_bx(DisasContext
*s
, TCGv var
)
734 s
->is_jmp
= DISAS_UPDATE
;
735 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
736 tcg_gen_andi_i32(var
, var
, 1);
737 store_cpu_field(var
, thumb
);
740 /* Variant of store_reg which uses branch&exchange logic when storing
741 to r15 in ARM architecture v7 and above. The source must be a temporary
742 and will be marked as dead. */
743 static inline void store_reg_bx(CPUState
*env
, DisasContext
*s
,
746 if (reg
== 15 && ENABLE_ARCH_7
) {
749 store_reg(s
, reg
, var
);
753 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
755 TCGv tmp
= tcg_temp_new_i32();
756 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
759 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
761 TCGv tmp
= tcg_temp_new_i32();
762 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
765 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
767 TCGv tmp
= tcg_temp_new_i32();
768 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
771 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
773 TCGv tmp
= tcg_temp_new_i32();
774 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
777 static inline TCGv
gen_ld32(TCGv addr
, int index
)
779 TCGv tmp
= tcg_temp_new_i32();
780 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
783 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
785 TCGv_i64 tmp
= tcg_temp_new_i64();
786 tcg_gen_qemu_ld64(tmp
, addr
, index
);
789 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
791 tcg_gen_qemu_st8(val
, addr
, index
);
792 tcg_temp_free_i32(val
);
794 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
796 tcg_gen_qemu_st16(val
, addr
, index
);
797 tcg_temp_free_i32(val
);
799 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
801 tcg_gen_qemu_st32(val
, addr
, index
);
802 tcg_temp_free_i32(val
);
804 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
806 tcg_gen_qemu_st64(val
, addr
, index
);
807 tcg_temp_free_i64(val
);
810 static inline void gen_set_pc_im(uint32_t val
)
812 tcg_gen_movi_i32(cpu_R
[15], val
);
815 /* Force a TB lookup after an instruction that changes the CPU state. */
816 static inline void gen_lookup_tb(DisasContext
*s
)
818 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
819 s
->is_jmp
= DISAS_UPDATE
;
822 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
825 int val
, rm
, shift
, shiftop
;
828 if (!(insn
& (1 << 25))) {
831 if (!(insn
& (1 << 23)))
834 tcg_gen_addi_i32(var
, var
, val
);
838 shift
= (insn
>> 7) & 0x1f;
839 shiftop
= (insn
>> 5) & 3;
840 offset
= load_reg(s
, rm
);
841 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
842 if (!(insn
& (1 << 23)))
843 tcg_gen_sub_i32(var
, var
, offset
);
845 tcg_gen_add_i32(var
, var
, offset
);
846 tcg_temp_free_i32(offset
);
850 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
856 if (insn
& (1 << 22)) {
858 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
859 if (!(insn
& (1 << 23)))
863 tcg_gen_addi_i32(var
, var
, val
);
867 tcg_gen_addi_i32(var
, var
, extra
);
869 offset
= load_reg(s
, rm
);
870 if (!(insn
& (1 << 23)))
871 tcg_gen_sub_i32(var
, var
, offset
);
873 tcg_gen_add_i32(var
, var
, offset
);
874 tcg_temp_free_i32(offset
);
878 #define VFP_OP2(name) \
879 static inline void gen_vfp_##name(int dp) \
882 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
884 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
894 static inline void gen_vfp_abs(int dp
)
897 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
899 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
902 static inline void gen_vfp_neg(int dp
)
905 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
907 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
910 static inline void gen_vfp_sqrt(int dp
)
913 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
915 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
918 static inline void gen_vfp_cmp(int dp
)
921 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
923 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
926 static inline void gen_vfp_cmpe(int dp
)
929 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
931 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
934 static inline void gen_vfp_F1_ld0(int dp
)
937 tcg_gen_movi_i64(cpu_F1d
, 0);
939 tcg_gen_movi_i32(cpu_F1s
, 0);
942 static inline void gen_vfp_uito(int dp
)
945 gen_helper_vfp_uitod(cpu_F0d
, cpu_F0s
, cpu_env
);
947 gen_helper_vfp_uitos(cpu_F0s
, cpu_F0s
, cpu_env
);
950 static inline void gen_vfp_sito(int dp
)
953 gen_helper_vfp_sitod(cpu_F0d
, cpu_F0s
, cpu_env
);
955 gen_helper_vfp_sitos(cpu_F0s
, cpu_F0s
, cpu_env
);
958 static inline void gen_vfp_toui(int dp
)
961 gen_helper_vfp_touid(cpu_F0s
, cpu_F0d
, cpu_env
);
963 gen_helper_vfp_touis(cpu_F0s
, cpu_F0s
, cpu_env
);
966 static inline void gen_vfp_touiz(int dp
)
969 gen_helper_vfp_touizd(cpu_F0s
, cpu_F0d
, cpu_env
);
971 gen_helper_vfp_touizs(cpu_F0s
, cpu_F0s
, cpu_env
);
974 static inline void gen_vfp_tosi(int dp
)
977 gen_helper_vfp_tosid(cpu_F0s
, cpu_F0d
, cpu_env
);
979 gen_helper_vfp_tosis(cpu_F0s
, cpu_F0s
, cpu_env
);
982 static inline void gen_vfp_tosiz(int dp
)
985 gen_helper_vfp_tosizd(cpu_F0s
, cpu_F0d
, cpu_env
);
987 gen_helper_vfp_tosizs(cpu_F0s
, cpu_F0s
, cpu_env
);
990 #define VFP_GEN_FIX(name) \
991 static inline void gen_vfp_##name(int dp, int shift) \
993 TCGv tmp_shift = tcg_const_i32(shift); \
995 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
997 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
998 tcg_temp_free_i32(tmp_shift); \
1010 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1013 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1015 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1018 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1021 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1023 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1027 vfp_reg_offset (int dp
, int reg
)
1030 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1032 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1033 + offsetof(CPU_DoubleU
, l
.upper
);
1035 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1036 + offsetof(CPU_DoubleU
, l
.lower
);
1040 /* Return the offset of a 32-bit piece of a NEON register.
1041 zero is the least significant end of the register. */
1043 neon_reg_offset (int reg
, int n
)
1047 return vfp_reg_offset(0, sreg
);
1050 static TCGv
neon_load_reg(int reg
, int pass
)
1052 TCGv tmp
= tcg_temp_new_i32();
1053 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1057 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1059 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1060 tcg_temp_free_i32(var
);
1063 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1065 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1068 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1070 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1073 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1074 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1075 #define tcg_gen_st_f32 tcg_gen_st_i32
1076 #define tcg_gen_st_f64 tcg_gen_st_i64
1078 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1081 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1083 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1086 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1089 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1091 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1094 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1097 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1099 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1102 #define ARM_CP_RW_BIT (1 << 20)
1104 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1106 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1109 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1111 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1114 static inline TCGv
iwmmxt_load_creg(int reg
)
1116 TCGv var
= tcg_temp_new_i32();
1117 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1121 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1123 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1124 tcg_temp_free_i32(var
);
1127 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1129 iwmmxt_store_reg(cpu_M0
, rn
);
1132 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1134 iwmmxt_load_reg(cpu_M0
, rn
);
1137 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1139 iwmmxt_load_reg(cpu_V1
, rn
);
1140 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1143 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1145 iwmmxt_load_reg(cpu_V1
, rn
);
1146 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1149 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1151 iwmmxt_load_reg(cpu_V1
, rn
);
1152 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1155 #define IWMMXT_OP(name) \
1156 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1158 iwmmxt_load_reg(cpu_V1, rn); \
1159 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1162 #define IWMMXT_OP_ENV(name) \
1163 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1165 iwmmxt_load_reg(cpu_V1, rn); \
1166 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1169 #define IWMMXT_OP_ENV_SIZE(name) \
1170 IWMMXT_OP_ENV(name##b) \
1171 IWMMXT_OP_ENV(name##w) \
1172 IWMMXT_OP_ENV(name##l)
1174 #define IWMMXT_OP_ENV1(name) \
1175 static inline void gen_op_iwmmxt_##name##_M0(void) \
1177 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1191 IWMMXT_OP_ENV_SIZE(unpackl
)
1192 IWMMXT_OP_ENV_SIZE(unpackh
)
1194 IWMMXT_OP_ENV1(unpacklub
)
1195 IWMMXT_OP_ENV1(unpackluw
)
1196 IWMMXT_OP_ENV1(unpacklul
)
1197 IWMMXT_OP_ENV1(unpackhub
)
1198 IWMMXT_OP_ENV1(unpackhuw
)
1199 IWMMXT_OP_ENV1(unpackhul
)
1200 IWMMXT_OP_ENV1(unpacklsb
)
1201 IWMMXT_OP_ENV1(unpacklsw
)
1202 IWMMXT_OP_ENV1(unpacklsl
)
1203 IWMMXT_OP_ENV1(unpackhsb
)
1204 IWMMXT_OP_ENV1(unpackhsw
)
1205 IWMMXT_OP_ENV1(unpackhsl
)
1207 IWMMXT_OP_ENV_SIZE(cmpeq
)
1208 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1209 IWMMXT_OP_ENV_SIZE(cmpgts
)
1211 IWMMXT_OP_ENV_SIZE(mins
)
1212 IWMMXT_OP_ENV_SIZE(minu
)
1213 IWMMXT_OP_ENV_SIZE(maxs
)
1214 IWMMXT_OP_ENV_SIZE(maxu
)
1216 IWMMXT_OP_ENV_SIZE(subn
)
1217 IWMMXT_OP_ENV_SIZE(addn
)
1218 IWMMXT_OP_ENV_SIZE(subu
)
1219 IWMMXT_OP_ENV_SIZE(addu
)
1220 IWMMXT_OP_ENV_SIZE(subs
)
1221 IWMMXT_OP_ENV_SIZE(adds
)
1223 IWMMXT_OP_ENV(avgb0
)
1224 IWMMXT_OP_ENV(avgb1
)
1225 IWMMXT_OP_ENV(avgw0
)
1226 IWMMXT_OP_ENV(avgw1
)
1230 IWMMXT_OP_ENV(packuw
)
1231 IWMMXT_OP_ENV(packul
)
1232 IWMMXT_OP_ENV(packuq
)
1233 IWMMXT_OP_ENV(packsw
)
1234 IWMMXT_OP_ENV(packsl
)
1235 IWMMXT_OP_ENV(packsq
)
1237 static void gen_op_iwmmxt_set_mup(void)
1240 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1241 tcg_gen_ori_i32(tmp
, tmp
, 2);
1242 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1245 static void gen_op_iwmmxt_set_cup(void)
1248 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1249 tcg_gen_ori_i32(tmp
, tmp
, 1);
1250 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1253 static void gen_op_iwmmxt_setpsr_nz(void)
1255 TCGv tmp
= tcg_temp_new_i32();
1256 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1257 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1260 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1262 iwmmxt_load_reg(cpu_V1
, rn
);
1263 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1264 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1267 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1273 rd
= (insn
>> 16) & 0xf;
1274 tmp
= load_reg(s
, rd
);
1276 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1277 if (insn
& (1 << 24)) {
1279 if (insn
& (1 << 23))
1280 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1282 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1283 tcg_gen_mov_i32(dest
, tmp
);
1284 if (insn
& (1 << 21))
1285 store_reg(s
, rd
, tmp
);
1287 tcg_temp_free_i32(tmp
);
1288 } else if (insn
& (1 << 21)) {
1290 tcg_gen_mov_i32(dest
, tmp
);
1291 if (insn
& (1 << 23))
1292 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1294 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1295 store_reg(s
, rd
, tmp
);
1296 } else if (!(insn
& (1 << 23)))
1301 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1303 int rd
= (insn
>> 0) & 0xf;
1306 if (insn
& (1 << 8)) {
1307 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1310 tmp
= iwmmxt_load_creg(rd
);
1313 tmp
= tcg_temp_new_i32();
1314 iwmmxt_load_reg(cpu_V0
, rd
);
1315 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1317 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1318 tcg_gen_mov_i32(dest
, tmp
);
1319 tcg_temp_free_i32(tmp
);
1323 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1324 (ie. an undefined instruction). */
1325 static int disas_iwmmxt_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
1328 int rdhi
, rdlo
, rd0
, rd1
, i
;
1330 TCGv tmp
, tmp2
, tmp3
;
1332 if ((insn
& 0x0e000e00) == 0x0c000000) {
1333 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1335 rdlo
= (insn
>> 12) & 0xf;
1336 rdhi
= (insn
>> 16) & 0xf;
1337 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1338 iwmmxt_load_reg(cpu_V0
, wrd
);
1339 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1340 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1341 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1342 } else { /* TMCRR */
1343 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1344 iwmmxt_store_reg(cpu_V0
, wrd
);
1345 gen_op_iwmmxt_set_mup();
1350 wrd
= (insn
>> 12) & 0xf;
1351 addr
= tcg_temp_new_i32();
1352 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1353 tcg_temp_free_i32(addr
);
1356 if (insn
& ARM_CP_RW_BIT
) {
1357 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1358 tmp
= tcg_temp_new_i32();
1359 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1360 iwmmxt_store_creg(wrd
, tmp
);
1363 if (insn
& (1 << 8)) {
1364 if (insn
& (1 << 22)) { /* WLDRD */
1365 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1367 } else { /* WLDRW wRd */
1368 tmp
= gen_ld32(addr
, IS_USER(s
));
1371 if (insn
& (1 << 22)) { /* WLDRH */
1372 tmp
= gen_ld16u(addr
, IS_USER(s
));
1373 } else { /* WLDRB */
1374 tmp
= gen_ld8u(addr
, IS_USER(s
));
1378 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1379 tcg_temp_free_i32(tmp
);
1381 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1384 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1385 tmp
= iwmmxt_load_creg(wrd
);
1386 gen_st32(tmp
, addr
, IS_USER(s
));
1388 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1389 tmp
= tcg_temp_new_i32();
1390 if (insn
& (1 << 8)) {
1391 if (insn
& (1 << 22)) { /* WSTRD */
1392 tcg_temp_free_i32(tmp
);
1393 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1394 } else { /* WSTRW wRd */
1395 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1396 gen_st32(tmp
, addr
, IS_USER(s
));
1399 if (insn
& (1 << 22)) { /* WSTRH */
1400 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1401 gen_st16(tmp
, addr
, IS_USER(s
));
1402 } else { /* WSTRB */
1403 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1404 gen_st8(tmp
, addr
, IS_USER(s
));
1409 tcg_temp_free_i32(addr
);
1413 if ((insn
& 0x0f000000) != 0x0e000000)
1416 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1417 case 0x000: /* WOR */
1418 wrd
= (insn
>> 12) & 0xf;
1419 rd0
= (insn
>> 0) & 0xf;
1420 rd1
= (insn
>> 16) & 0xf;
1421 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1422 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1423 gen_op_iwmmxt_setpsr_nz();
1424 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1425 gen_op_iwmmxt_set_mup();
1426 gen_op_iwmmxt_set_cup();
1428 case 0x011: /* TMCR */
1431 rd
= (insn
>> 12) & 0xf;
1432 wrd
= (insn
>> 16) & 0xf;
1434 case ARM_IWMMXT_wCID
:
1435 case ARM_IWMMXT_wCASF
:
1437 case ARM_IWMMXT_wCon
:
1438 gen_op_iwmmxt_set_cup();
1440 case ARM_IWMMXT_wCSSF
:
1441 tmp
= iwmmxt_load_creg(wrd
);
1442 tmp2
= load_reg(s
, rd
);
1443 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1444 tcg_temp_free_i32(tmp2
);
1445 iwmmxt_store_creg(wrd
, tmp
);
1447 case ARM_IWMMXT_wCGR0
:
1448 case ARM_IWMMXT_wCGR1
:
1449 case ARM_IWMMXT_wCGR2
:
1450 case ARM_IWMMXT_wCGR3
:
1451 gen_op_iwmmxt_set_cup();
1452 tmp
= load_reg(s
, rd
);
1453 iwmmxt_store_creg(wrd
, tmp
);
1459 case 0x100: /* WXOR */
1460 wrd
= (insn
>> 12) & 0xf;
1461 rd0
= (insn
>> 0) & 0xf;
1462 rd1
= (insn
>> 16) & 0xf;
1463 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1464 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1465 gen_op_iwmmxt_setpsr_nz();
1466 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1467 gen_op_iwmmxt_set_mup();
1468 gen_op_iwmmxt_set_cup();
1470 case 0x111: /* TMRC */
1473 rd
= (insn
>> 12) & 0xf;
1474 wrd
= (insn
>> 16) & 0xf;
1475 tmp
= iwmmxt_load_creg(wrd
);
1476 store_reg(s
, rd
, tmp
);
1478 case 0x300: /* WANDN */
1479 wrd
= (insn
>> 12) & 0xf;
1480 rd0
= (insn
>> 0) & 0xf;
1481 rd1
= (insn
>> 16) & 0xf;
1482 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1483 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
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 0x200: /* WAND */
1491 wrd
= (insn
>> 12) & 0xf;
1492 rd0
= (insn
>> 0) & 0xf;
1493 rd1
= (insn
>> 16) & 0xf;
1494 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1495 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1496 gen_op_iwmmxt_setpsr_nz();
1497 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1498 gen_op_iwmmxt_set_mup();
1499 gen_op_iwmmxt_set_cup();
1501 case 0x810: case 0xa10: /* WMADD */
1502 wrd
= (insn
>> 12) & 0xf;
1503 rd0
= (insn
>> 0) & 0xf;
1504 rd1
= (insn
>> 16) & 0xf;
1505 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1506 if (insn
& (1 << 21))
1507 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1509 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1510 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1511 gen_op_iwmmxt_set_mup();
1513 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1514 wrd
= (insn
>> 12) & 0xf;
1515 rd0
= (insn
>> 16) & 0xf;
1516 rd1
= (insn
>> 0) & 0xf;
1517 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1518 switch ((insn
>> 22) & 3) {
1520 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1523 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1526 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1531 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1532 gen_op_iwmmxt_set_mup();
1533 gen_op_iwmmxt_set_cup();
1535 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1536 wrd
= (insn
>> 12) & 0xf;
1537 rd0
= (insn
>> 16) & 0xf;
1538 rd1
= (insn
>> 0) & 0xf;
1539 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1540 switch ((insn
>> 22) & 3) {
1542 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1545 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1548 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1553 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1554 gen_op_iwmmxt_set_mup();
1555 gen_op_iwmmxt_set_cup();
1557 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1558 wrd
= (insn
>> 12) & 0xf;
1559 rd0
= (insn
>> 16) & 0xf;
1560 rd1
= (insn
>> 0) & 0xf;
1561 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1562 if (insn
& (1 << 22))
1563 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1565 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1566 if (!(insn
& (1 << 20)))
1567 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1568 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1569 gen_op_iwmmxt_set_mup();
1571 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1572 wrd
= (insn
>> 12) & 0xf;
1573 rd0
= (insn
>> 16) & 0xf;
1574 rd1
= (insn
>> 0) & 0xf;
1575 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1576 if (insn
& (1 << 21)) {
1577 if (insn
& (1 << 20))
1578 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1580 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1582 if (insn
& (1 << 20))
1583 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1585 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1587 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1588 gen_op_iwmmxt_set_mup();
1590 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1591 wrd
= (insn
>> 12) & 0xf;
1592 rd0
= (insn
>> 16) & 0xf;
1593 rd1
= (insn
>> 0) & 0xf;
1594 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1595 if (insn
& (1 << 21))
1596 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1598 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1599 if (!(insn
& (1 << 20))) {
1600 iwmmxt_load_reg(cpu_V1
, wrd
);
1601 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1603 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1604 gen_op_iwmmxt_set_mup();
1606 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1607 wrd
= (insn
>> 12) & 0xf;
1608 rd0
= (insn
>> 16) & 0xf;
1609 rd1
= (insn
>> 0) & 0xf;
1610 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1611 switch ((insn
>> 22) & 3) {
1613 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1616 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1619 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1624 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1625 gen_op_iwmmxt_set_mup();
1626 gen_op_iwmmxt_set_cup();
1628 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1629 wrd
= (insn
>> 12) & 0xf;
1630 rd0
= (insn
>> 16) & 0xf;
1631 rd1
= (insn
>> 0) & 0xf;
1632 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1633 if (insn
& (1 << 22)) {
1634 if (insn
& (1 << 20))
1635 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1637 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1639 if (insn
& (1 << 20))
1640 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1642 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1644 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1645 gen_op_iwmmxt_set_mup();
1646 gen_op_iwmmxt_set_cup();
1648 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1649 wrd
= (insn
>> 12) & 0xf;
1650 rd0
= (insn
>> 16) & 0xf;
1651 rd1
= (insn
>> 0) & 0xf;
1652 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1653 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1654 tcg_gen_andi_i32(tmp
, tmp
, 7);
1655 iwmmxt_load_reg(cpu_V1
, rd1
);
1656 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1657 tcg_temp_free_i32(tmp
);
1658 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1659 gen_op_iwmmxt_set_mup();
1661 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1662 if (((insn
>> 6) & 3) == 3)
1664 rd
= (insn
>> 12) & 0xf;
1665 wrd
= (insn
>> 16) & 0xf;
1666 tmp
= load_reg(s
, rd
);
1667 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1668 switch ((insn
>> 6) & 3) {
1670 tmp2
= tcg_const_i32(0xff);
1671 tmp3
= tcg_const_i32((insn
& 7) << 3);
1674 tmp2
= tcg_const_i32(0xffff);
1675 tmp3
= tcg_const_i32((insn
& 3) << 4);
1678 tmp2
= tcg_const_i32(0xffffffff);
1679 tmp3
= tcg_const_i32((insn
& 1) << 5);
1685 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1686 tcg_temp_free(tmp3
);
1687 tcg_temp_free(tmp2
);
1688 tcg_temp_free_i32(tmp
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1692 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1693 rd
= (insn
>> 12) & 0xf;
1694 wrd
= (insn
>> 16) & 0xf;
1695 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1697 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1698 tmp
= tcg_temp_new_i32();
1699 switch ((insn
>> 22) & 3) {
1701 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1702 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1704 tcg_gen_ext8s_i32(tmp
, tmp
);
1706 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1710 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1711 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1713 tcg_gen_ext16s_i32(tmp
, tmp
);
1715 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1719 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1720 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1723 store_reg(s
, rd
, tmp
);
1725 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1726 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1728 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1729 switch ((insn
>> 22) & 3) {
1731 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1734 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1737 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1740 tcg_gen_shli_i32(tmp
, tmp
, 28);
1742 tcg_temp_free_i32(tmp
);
1744 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1745 if (((insn
>> 6) & 3) == 3)
1747 rd
= (insn
>> 12) & 0xf;
1748 wrd
= (insn
>> 16) & 0xf;
1749 tmp
= load_reg(s
, rd
);
1750 switch ((insn
>> 6) & 3) {
1752 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1755 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1758 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1761 tcg_temp_free_i32(tmp
);
1762 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1763 gen_op_iwmmxt_set_mup();
1765 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1766 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1768 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1769 tmp2
= tcg_temp_new_i32();
1770 tcg_gen_mov_i32(tmp2
, tmp
);
1771 switch ((insn
>> 22) & 3) {
1773 for (i
= 0; i
< 7; i
++) {
1774 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1775 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1779 for (i
= 0; i
< 3; i
++) {
1780 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1781 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1785 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1786 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1790 tcg_temp_free_i32(tmp2
);
1791 tcg_temp_free_i32(tmp
);
1793 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1794 wrd
= (insn
>> 12) & 0xf;
1795 rd0
= (insn
>> 16) & 0xf;
1796 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1797 switch ((insn
>> 22) & 3) {
1799 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1802 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1805 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1810 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1811 gen_op_iwmmxt_set_mup();
1813 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1814 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1816 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1817 tmp2
= tcg_temp_new_i32();
1818 tcg_gen_mov_i32(tmp2
, tmp
);
1819 switch ((insn
>> 22) & 3) {
1821 for (i
= 0; i
< 7; i
++) {
1822 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1823 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1827 for (i
= 0; i
< 3; i
++) {
1828 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1829 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1833 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1834 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1838 tcg_temp_free_i32(tmp2
);
1839 tcg_temp_free_i32(tmp
);
1841 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1842 rd
= (insn
>> 12) & 0xf;
1843 rd0
= (insn
>> 16) & 0xf;
1844 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1846 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1847 tmp
= tcg_temp_new_i32();
1848 switch ((insn
>> 22) & 3) {
1850 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1853 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1856 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1859 store_reg(s
, rd
, tmp
);
1861 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1862 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1863 wrd
= (insn
>> 12) & 0xf;
1864 rd0
= (insn
>> 16) & 0xf;
1865 rd1
= (insn
>> 0) & 0xf;
1866 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1867 switch ((insn
>> 22) & 3) {
1869 if (insn
& (1 << 21))
1870 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1872 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1875 if (insn
& (1 << 21))
1876 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1878 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1881 if (insn
& (1 << 21))
1882 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1884 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1889 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1890 gen_op_iwmmxt_set_mup();
1891 gen_op_iwmmxt_set_cup();
1893 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1894 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1895 wrd
= (insn
>> 12) & 0xf;
1896 rd0
= (insn
>> 16) & 0xf;
1897 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1898 switch ((insn
>> 22) & 3) {
1900 if (insn
& (1 << 21))
1901 gen_op_iwmmxt_unpacklsb_M0();
1903 gen_op_iwmmxt_unpacklub_M0();
1906 if (insn
& (1 << 21))
1907 gen_op_iwmmxt_unpacklsw_M0();
1909 gen_op_iwmmxt_unpackluw_M0();
1912 if (insn
& (1 << 21))
1913 gen_op_iwmmxt_unpacklsl_M0();
1915 gen_op_iwmmxt_unpacklul_M0();
1920 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1921 gen_op_iwmmxt_set_mup();
1922 gen_op_iwmmxt_set_cup();
1924 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1925 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1926 wrd
= (insn
>> 12) & 0xf;
1927 rd0
= (insn
>> 16) & 0xf;
1928 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1929 switch ((insn
>> 22) & 3) {
1931 if (insn
& (1 << 21))
1932 gen_op_iwmmxt_unpackhsb_M0();
1934 gen_op_iwmmxt_unpackhub_M0();
1937 if (insn
& (1 << 21))
1938 gen_op_iwmmxt_unpackhsw_M0();
1940 gen_op_iwmmxt_unpackhuw_M0();
1943 if (insn
& (1 << 21))
1944 gen_op_iwmmxt_unpackhsl_M0();
1946 gen_op_iwmmxt_unpackhul_M0();
1951 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1952 gen_op_iwmmxt_set_mup();
1953 gen_op_iwmmxt_set_cup();
1955 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1956 case 0x214: case 0x614: case 0xa14: case 0xe14:
1957 if (((insn
>> 22) & 3) == 0)
1959 wrd
= (insn
>> 12) & 0xf;
1960 rd0
= (insn
>> 16) & 0xf;
1961 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1962 tmp
= tcg_temp_new_i32();
1963 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1964 tcg_temp_free_i32(tmp
);
1967 switch ((insn
>> 22) & 3) {
1969 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1972 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1975 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
1978 tcg_temp_free_i32(tmp
);
1979 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1980 gen_op_iwmmxt_set_mup();
1981 gen_op_iwmmxt_set_cup();
1983 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
1984 case 0x014: case 0x414: case 0x814: case 0xc14:
1985 if (((insn
>> 22) & 3) == 0)
1987 wrd
= (insn
>> 12) & 0xf;
1988 rd0
= (insn
>> 16) & 0xf;
1989 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1990 tmp
= tcg_temp_new_i32();
1991 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1992 tcg_temp_free_i32(tmp
);
1995 switch ((insn
>> 22) & 3) {
1997 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2000 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2003 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2006 tcg_temp_free_i32(tmp
);
2007 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2008 gen_op_iwmmxt_set_mup();
2009 gen_op_iwmmxt_set_cup();
2011 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2012 case 0x114: case 0x514: case 0x914: case 0xd14:
2013 if (((insn
>> 22) & 3) == 0)
2015 wrd
= (insn
>> 12) & 0xf;
2016 rd0
= (insn
>> 16) & 0xf;
2017 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2018 tmp
= tcg_temp_new_i32();
2019 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2020 tcg_temp_free_i32(tmp
);
2023 switch ((insn
>> 22) & 3) {
2025 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2028 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2031 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2034 tcg_temp_free_i32(tmp
);
2035 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2036 gen_op_iwmmxt_set_mup();
2037 gen_op_iwmmxt_set_cup();
2039 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2040 case 0x314: case 0x714: case 0xb14: case 0xf14:
2041 if (((insn
>> 22) & 3) == 0)
2043 wrd
= (insn
>> 12) & 0xf;
2044 rd0
= (insn
>> 16) & 0xf;
2045 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2046 tmp
= tcg_temp_new_i32();
2047 switch ((insn
>> 22) & 3) {
2049 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2050 tcg_temp_free_i32(tmp
);
2053 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2056 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2057 tcg_temp_free_i32(tmp
);
2060 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2063 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2064 tcg_temp_free_i32(tmp
);
2067 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2070 tcg_temp_free_i32(tmp
);
2071 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2072 gen_op_iwmmxt_set_mup();
2073 gen_op_iwmmxt_set_cup();
2075 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2076 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2077 wrd
= (insn
>> 12) & 0xf;
2078 rd0
= (insn
>> 16) & 0xf;
2079 rd1
= (insn
>> 0) & 0xf;
2080 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2081 switch ((insn
>> 22) & 3) {
2083 if (insn
& (1 << 21))
2084 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2086 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2089 if (insn
& (1 << 21))
2090 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2092 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2095 if (insn
& (1 << 21))
2096 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2098 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2103 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2104 gen_op_iwmmxt_set_mup();
2106 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2107 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2108 wrd
= (insn
>> 12) & 0xf;
2109 rd0
= (insn
>> 16) & 0xf;
2110 rd1
= (insn
>> 0) & 0xf;
2111 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2112 switch ((insn
>> 22) & 3) {
2114 if (insn
& (1 << 21))
2115 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2117 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2120 if (insn
& (1 << 21))
2121 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2123 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2126 if (insn
& (1 << 21))
2127 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2129 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2135 gen_op_iwmmxt_set_mup();
2137 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2138 case 0x402: case 0x502: case 0x602: case 0x702:
2139 wrd
= (insn
>> 12) & 0xf;
2140 rd0
= (insn
>> 16) & 0xf;
2141 rd1
= (insn
>> 0) & 0xf;
2142 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2143 tmp
= tcg_const_i32((insn
>> 20) & 3);
2144 iwmmxt_load_reg(cpu_V1
, rd1
);
2145 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2148 gen_op_iwmmxt_set_mup();
2150 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2151 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2152 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2153 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2154 wrd
= (insn
>> 12) & 0xf;
2155 rd0
= (insn
>> 16) & 0xf;
2156 rd1
= (insn
>> 0) & 0xf;
2157 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2158 switch ((insn
>> 20) & 0xf) {
2160 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2163 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2166 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2169 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2172 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2175 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2178 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2181 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2184 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2189 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2190 gen_op_iwmmxt_set_mup();
2191 gen_op_iwmmxt_set_cup();
2193 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2194 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2195 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2196 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2197 wrd
= (insn
>> 12) & 0xf;
2198 rd0
= (insn
>> 16) & 0xf;
2199 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2200 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2201 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2203 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2204 gen_op_iwmmxt_set_mup();
2205 gen_op_iwmmxt_set_cup();
2207 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2208 case 0x418: case 0x518: case 0x618: case 0x718:
2209 case 0x818: case 0x918: case 0xa18: case 0xb18:
2210 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2211 wrd
= (insn
>> 12) & 0xf;
2212 rd0
= (insn
>> 16) & 0xf;
2213 rd1
= (insn
>> 0) & 0xf;
2214 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2215 switch ((insn
>> 20) & 0xf) {
2217 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2220 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2223 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2226 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2229 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2232 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2235 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2238 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2241 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2246 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2247 gen_op_iwmmxt_set_mup();
2248 gen_op_iwmmxt_set_cup();
2250 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2251 case 0x408: case 0x508: case 0x608: case 0x708:
2252 case 0x808: case 0x908: case 0xa08: case 0xb08:
2253 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2254 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2256 wrd
= (insn
>> 12) & 0xf;
2257 rd0
= (insn
>> 16) & 0xf;
2258 rd1
= (insn
>> 0) & 0xf;
2259 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2260 switch ((insn
>> 22) & 3) {
2262 if (insn
& (1 << 21))
2263 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2265 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2268 if (insn
& (1 << 21))
2269 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2271 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2274 if (insn
& (1 << 21))
2275 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2277 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2281 gen_op_iwmmxt_set_mup();
2282 gen_op_iwmmxt_set_cup();
2284 case 0x201: case 0x203: case 0x205: case 0x207:
2285 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2286 case 0x211: case 0x213: case 0x215: case 0x217:
2287 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2288 wrd
= (insn
>> 5) & 0xf;
2289 rd0
= (insn
>> 12) & 0xf;
2290 rd1
= (insn
>> 0) & 0xf;
2291 if (rd0
== 0xf || rd1
== 0xf)
2293 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2294 tmp
= load_reg(s
, rd0
);
2295 tmp2
= load_reg(s
, rd1
);
2296 switch ((insn
>> 16) & 0xf) {
2297 case 0x0: /* TMIA */
2298 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2300 case 0x8: /* TMIAPH */
2301 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2303 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2304 if (insn
& (1 << 16))
2305 tcg_gen_shri_i32(tmp
, tmp
, 16);
2306 if (insn
& (1 << 17))
2307 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2308 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2311 tcg_temp_free_i32(tmp2
);
2312 tcg_temp_free_i32(tmp
);
2315 tcg_temp_free_i32(tmp2
);
2316 tcg_temp_free_i32(tmp
);
2317 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2318 gen_op_iwmmxt_set_mup();
2327 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2328 (ie. an undefined instruction). */
2329 static int disas_dsp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2331 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2334 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2335 /* Multiply with Internal Accumulate Format */
2336 rd0
= (insn
>> 12) & 0xf;
2338 acc
= (insn
>> 5) & 7;
2343 tmp
= load_reg(s
, rd0
);
2344 tmp2
= load_reg(s
, rd1
);
2345 switch ((insn
>> 16) & 0xf) {
2347 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2349 case 0x8: /* MIAPH */
2350 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2352 case 0xc: /* MIABB */
2353 case 0xd: /* MIABT */
2354 case 0xe: /* MIATB */
2355 case 0xf: /* MIATT */
2356 if (insn
& (1 << 16))
2357 tcg_gen_shri_i32(tmp
, tmp
, 16);
2358 if (insn
& (1 << 17))
2359 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2360 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2365 tcg_temp_free_i32(tmp2
);
2366 tcg_temp_free_i32(tmp
);
2368 gen_op_iwmmxt_movq_wRn_M0(acc
);
2372 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2373 /* Internal Accumulator Access Format */
2374 rdhi
= (insn
>> 16) & 0xf;
2375 rdlo
= (insn
>> 12) & 0xf;
2381 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2382 iwmmxt_load_reg(cpu_V0
, acc
);
2383 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2384 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2385 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2386 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2388 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2389 iwmmxt_store_reg(cpu_V0
, acc
);
2397 /* Disassemble system coprocessor instruction. Return nonzero if
2398 instruction is not defined. */
2399 static int disas_cp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2402 uint32_t rd
= (insn
>> 12) & 0xf;
2403 uint32_t cp
= (insn
>> 8) & 0xf;
2408 if (insn
& ARM_CP_RW_BIT
) {
2409 if (!env
->cp
[cp
].cp_read
)
2411 gen_set_pc_im(s
->pc
);
2412 tmp
= tcg_temp_new_i32();
2413 tmp2
= tcg_const_i32(insn
);
2414 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2415 tcg_temp_free(tmp2
);
2416 store_reg(s
, rd
, tmp
);
2418 if (!env
->cp
[cp
].cp_write
)
2420 gen_set_pc_im(s
->pc
);
2421 tmp
= load_reg(s
, rd
);
2422 tmp2
= tcg_const_i32(insn
);
2423 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2424 tcg_temp_free(tmp2
);
2425 tcg_temp_free_i32(tmp
);
2430 static int cp15_user_ok(uint32_t insn
)
2432 int cpn
= (insn
>> 16) & 0xf;
2433 int cpm
= insn
& 0xf;
2434 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2436 if (cpn
== 13 && cpm
== 0) {
2438 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2442 /* ISB, DSB, DMB. */
2443 if ((cpm
== 5 && op
== 4)
2444 || (cpm
== 10 && (op
== 4 || op
== 5)))
2450 static int cp15_tls_load_store(CPUState
*env
, DisasContext
*s
, uint32_t insn
, uint32_t rd
)
2453 int cpn
= (insn
>> 16) & 0xf;
2454 int cpm
= insn
& 0xf;
2455 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2457 if (!arm_feature(env
, ARM_FEATURE_V6K
))
2460 if (!(cpn
== 13 && cpm
== 0))
2463 if (insn
& ARM_CP_RW_BIT
) {
2466 tmp
= load_cpu_field(cp15
.c13_tls1
);
2469 tmp
= load_cpu_field(cp15
.c13_tls2
);
2472 tmp
= load_cpu_field(cp15
.c13_tls3
);
2477 store_reg(s
, rd
, tmp
);
2480 tmp
= load_reg(s
, rd
);
2483 store_cpu_field(tmp
, cp15
.c13_tls1
);
2486 store_cpu_field(tmp
, cp15
.c13_tls2
);
2489 store_cpu_field(tmp
, cp15
.c13_tls3
);
2492 tcg_temp_free_i32(tmp
);
2499 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2500 instruction is not defined. */
2501 static int disas_cp15_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2506 /* M profile cores use memory mapped registers instead of cp15. */
2507 if (arm_feature(env
, ARM_FEATURE_M
))
2510 if ((insn
& (1 << 25)) == 0) {
2511 if (insn
& (1 << 20)) {
2515 /* mcrr. Used for block cache operations, so implement as no-op. */
2518 if ((insn
& (1 << 4)) == 0) {
2522 if (IS_USER(s
) && !cp15_user_ok(insn
)) {
2526 /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2527 * instructions rather than a separate instruction.
2529 if ((insn
& 0x0fff0fff) == 0x0e070f90) {
2530 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2531 * In v7, this must NOP.
2533 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
2534 /* Wait for interrupt. */
2535 gen_set_pc_im(s
->pc
);
2536 s
->is_jmp
= DISAS_WFI
;
2541 if ((insn
& 0x0fff0fff) == 0x0e070f58) {
2542 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2543 * so this is slightly over-broad.
2545 if (!arm_feature(env
, ARM_FEATURE_V6
)) {
2546 /* Wait for interrupt. */
2547 gen_set_pc_im(s
->pc
);
2548 s
->is_jmp
= DISAS_WFI
;
2551 /* Otherwise fall through to handle via helper function.
2552 * In particular, on v7 and some v6 cores this is one of
2553 * the VA-PA registers.
2557 rd
= (insn
>> 12) & 0xf;
2559 if (cp15_tls_load_store(env
, s
, insn
, rd
))
2562 tmp2
= tcg_const_i32(insn
);
2563 if (insn
& ARM_CP_RW_BIT
) {
2564 tmp
= tcg_temp_new_i32();
2565 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2566 /* If the destination register is r15 then sets condition codes. */
2568 store_reg(s
, rd
, tmp
);
2570 tcg_temp_free_i32(tmp
);
2572 tmp
= load_reg(s
, rd
);
2573 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2574 tcg_temp_free_i32(tmp
);
2575 /* Normally we would always end the TB here, but Linux
2576 * arch/arm/mach-pxa/sleep.S expects two instructions following
2577 * an MMU enable to execute from cache. Imitate this behaviour. */
2578 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2579 (insn
& 0x0fff0fff) != 0x0e010f10)
2582 tcg_temp_free_i32(tmp2
);
2586 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2587 #define VFP_SREG(insn, bigbit, smallbit) \
2588 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2589 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2590 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2591 reg = (((insn) >> (bigbit)) & 0x0f) \
2592 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2594 if (insn & (1 << (smallbit))) \
2596 reg = ((insn) >> (bigbit)) & 0x0f; \
2599 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2600 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2601 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2602 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2603 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2604 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2606 /* Move between integer and VFP cores. */
2607 static TCGv
gen_vfp_mrs(void)
2609 TCGv tmp
= tcg_temp_new_i32();
2610 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2614 static void gen_vfp_msr(TCGv tmp
)
2616 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2617 tcg_temp_free_i32(tmp
);
2620 static void gen_neon_dup_u8(TCGv var
, int shift
)
2622 TCGv tmp
= tcg_temp_new_i32();
2624 tcg_gen_shri_i32(var
, var
, shift
);
2625 tcg_gen_ext8u_i32(var
, var
);
2626 tcg_gen_shli_i32(tmp
, var
, 8);
2627 tcg_gen_or_i32(var
, var
, tmp
);
2628 tcg_gen_shli_i32(tmp
, var
, 16);
2629 tcg_gen_or_i32(var
, var
, tmp
);
2630 tcg_temp_free_i32(tmp
);
2633 static void gen_neon_dup_low16(TCGv var
)
2635 TCGv tmp
= tcg_temp_new_i32();
2636 tcg_gen_ext16u_i32(var
, var
);
2637 tcg_gen_shli_i32(tmp
, var
, 16);
2638 tcg_gen_or_i32(var
, var
, tmp
);
2639 tcg_temp_free_i32(tmp
);
2642 static void gen_neon_dup_high16(TCGv var
)
2644 TCGv tmp
= tcg_temp_new_i32();
2645 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2646 tcg_gen_shri_i32(tmp
, var
, 16);
2647 tcg_gen_or_i32(var
, var
, tmp
);
2648 tcg_temp_free_i32(tmp
);
2651 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2653 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2657 tmp
= gen_ld8u(addr
, IS_USER(s
));
2658 gen_neon_dup_u8(tmp
, 0);
2661 tmp
= gen_ld16u(addr
, IS_USER(s
));
2662 gen_neon_dup_low16(tmp
);
2665 tmp
= gen_ld32(addr
, IS_USER(s
));
2667 default: /* Avoid compiler warnings. */
2673 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2674 (ie. an undefined instruction). */
2675 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2677 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2683 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2686 if (!s
->vfp_enabled
) {
2687 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2688 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2690 rn
= (insn
>> 16) & 0xf;
2691 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2692 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2695 dp
= ((insn
& 0xf00) == 0xb00);
2696 switch ((insn
>> 24) & 0xf) {
2698 if (insn
& (1 << 4)) {
2699 /* single register transfer */
2700 rd
= (insn
>> 12) & 0xf;
2705 VFP_DREG_N(rn
, insn
);
2708 if (insn
& 0x00c00060
2709 && !arm_feature(env
, ARM_FEATURE_NEON
))
2712 pass
= (insn
>> 21) & 1;
2713 if (insn
& (1 << 22)) {
2715 offset
= ((insn
>> 5) & 3) * 8;
2716 } else if (insn
& (1 << 5)) {
2718 offset
= (insn
& (1 << 6)) ? 16 : 0;
2723 if (insn
& ARM_CP_RW_BIT
) {
2725 tmp
= neon_load_reg(rn
, pass
);
2729 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2730 if (insn
& (1 << 23))
2736 if (insn
& (1 << 23)) {
2738 tcg_gen_shri_i32(tmp
, tmp
, 16);
2744 tcg_gen_sari_i32(tmp
, tmp
, 16);
2753 store_reg(s
, rd
, tmp
);
2756 tmp
= load_reg(s
, rd
);
2757 if (insn
& (1 << 23)) {
2760 gen_neon_dup_u8(tmp
, 0);
2761 } else if (size
== 1) {
2762 gen_neon_dup_low16(tmp
);
2764 for (n
= 0; n
<= pass
* 2; n
++) {
2765 tmp2
= tcg_temp_new_i32();
2766 tcg_gen_mov_i32(tmp2
, tmp
);
2767 neon_store_reg(rn
, n
, tmp2
);
2769 neon_store_reg(rn
, n
, tmp
);
2774 tmp2
= neon_load_reg(rn
, pass
);
2775 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2776 tcg_temp_free_i32(tmp2
);
2779 tmp2
= neon_load_reg(rn
, pass
);
2780 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2781 tcg_temp_free_i32(tmp2
);
2786 neon_store_reg(rn
, pass
, tmp
);
2790 if ((insn
& 0x6f) != 0x00)
2792 rn
= VFP_SREG_N(insn
);
2793 if (insn
& ARM_CP_RW_BIT
) {
2795 if (insn
& (1 << 21)) {
2796 /* system register */
2801 /* VFP2 allows access to FSID from userspace.
2802 VFP3 restricts all id registers to privileged
2805 && arm_feature(env
, ARM_FEATURE_VFP3
))
2807 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2812 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2814 case ARM_VFP_FPINST
:
2815 case ARM_VFP_FPINST2
:
2816 /* Not present in VFP3. */
2818 || arm_feature(env
, ARM_FEATURE_VFP3
))
2820 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2824 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2825 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2827 tmp
= tcg_temp_new_i32();
2828 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2834 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2836 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2842 gen_mov_F0_vreg(0, rn
);
2843 tmp
= gen_vfp_mrs();
2846 /* Set the 4 flag bits in the CPSR. */
2848 tcg_temp_free_i32(tmp
);
2850 store_reg(s
, rd
, tmp
);
2854 tmp
= load_reg(s
, rd
);
2855 if (insn
& (1 << 21)) {
2857 /* system register */
2862 /* Writes are ignored. */
2865 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2866 tcg_temp_free_i32(tmp
);
2872 /* TODO: VFP subarchitecture support.
2873 * For now, keep the EN bit only */
2874 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2875 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2878 case ARM_VFP_FPINST
:
2879 case ARM_VFP_FPINST2
:
2880 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2887 gen_mov_vreg_F0(0, rn
);
2892 /* data processing */
2893 /* The opcode is in bits 23, 21, 20 and 6. */
2894 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2898 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2900 /* rn is register number */
2901 VFP_DREG_N(rn
, insn
);
2904 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2905 /* Integer or single precision destination. */
2906 rd
= VFP_SREG_D(insn
);
2908 VFP_DREG_D(rd
, insn
);
2911 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2912 /* VCVT from int is always from S reg regardless of dp bit.
2913 * VCVT with immediate frac_bits has same format as SREG_M
2915 rm
= VFP_SREG_M(insn
);
2917 VFP_DREG_M(rm
, insn
);
2920 rn
= VFP_SREG_N(insn
);
2921 if (op
== 15 && rn
== 15) {
2922 /* Double precision destination. */
2923 VFP_DREG_D(rd
, insn
);
2925 rd
= VFP_SREG_D(insn
);
2927 /* NB that we implicitly rely on the encoding for the frac_bits
2928 * in VCVT of fixed to float being the same as that of an SREG_M
2930 rm
= VFP_SREG_M(insn
);
2933 veclen
= s
->vec_len
;
2934 if (op
== 15 && rn
> 3)
2937 /* Shut up compiler warnings. */
2948 /* Figure out what type of vector operation this is. */
2949 if ((rd
& bank_mask
) == 0) {
2954 delta_d
= (s
->vec_stride
>> 1) + 1;
2956 delta_d
= s
->vec_stride
+ 1;
2958 if ((rm
& bank_mask
) == 0) {
2959 /* mixed scalar/vector */
2968 /* Load the initial operands. */
2973 /* Integer source */
2974 gen_mov_F0_vreg(0, rm
);
2979 gen_mov_F0_vreg(dp
, rd
);
2980 gen_mov_F1_vreg(dp
, rm
);
2984 /* Compare with zero */
2985 gen_mov_F0_vreg(dp
, rd
);
2996 /* Source and destination the same. */
2997 gen_mov_F0_vreg(dp
, rd
);
3000 /* One source operand. */
3001 gen_mov_F0_vreg(dp
, rm
);
3005 /* Two source operands. */
3006 gen_mov_F0_vreg(dp
, rn
);
3007 gen_mov_F1_vreg(dp
, rm
);
3011 /* Perform the calculation. */
3013 case 0: /* mac: fd + (fn * fm) */
3015 gen_mov_F1_vreg(dp
, rd
);
3018 case 1: /* nmac: fd - (fn * fm) */
3021 gen_mov_F1_vreg(dp
, rd
);
3024 case 2: /* msc: -fd + (fn * fm) */
3026 gen_mov_F1_vreg(dp
, rd
);
3029 case 3: /* nmsc: -fd - (fn * fm) */
3032 gen_mov_F1_vreg(dp
, rd
);
3035 case 4: /* mul: fn * fm */
3038 case 5: /* nmul: -(fn * fm) */
3042 case 6: /* add: fn + fm */
3045 case 7: /* sub: fn - fm */
3048 case 8: /* div: fn / fm */
3051 case 14: /* fconst */
3052 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3055 n
= (insn
<< 12) & 0x80000000;
3056 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3063 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3070 tcg_gen_movi_i32(cpu_F0s
, n
);
3073 case 15: /* extension space */
3087 case 4: /* vcvtb.f32.f16 */
3088 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3090 tmp
= gen_vfp_mrs();
3091 tcg_gen_ext16u_i32(tmp
, tmp
);
3092 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3093 tcg_temp_free_i32(tmp
);
3095 case 5: /* vcvtt.f32.f16 */
3096 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3098 tmp
= gen_vfp_mrs();
3099 tcg_gen_shri_i32(tmp
, tmp
, 16);
3100 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3101 tcg_temp_free_i32(tmp
);
3103 case 6: /* vcvtb.f16.f32 */
3104 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3106 tmp
= tcg_temp_new_i32();
3107 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3108 gen_mov_F0_vreg(0, rd
);
3109 tmp2
= gen_vfp_mrs();
3110 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3111 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3112 tcg_temp_free_i32(tmp2
);
3115 case 7: /* vcvtt.f16.f32 */
3116 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3118 tmp
= tcg_temp_new_i32();
3119 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3120 tcg_gen_shli_i32(tmp
, tmp
, 16);
3121 gen_mov_F0_vreg(0, rd
);
3122 tmp2
= gen_vfp_mrs();
3123 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3124 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3125 tcg_temp_free_i32(tmp2
);
3137 case 11: /* cmpez */
3141 case 15: /* single<->double conversion */
3143 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3145 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3147 case 16: /* fuito */
3150 case 17: /* fsito */
3153 case 20: /* fshto */
3154 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3156 gen_vfp_shto(dp
, 16 - rm
);
3158 case 21: /* fslto */
3159 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3161 gen_vfp_slto(dp
, 32 - rm
);
3163 case 22: /* fuhto */
3164 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3166 gen_vfp_uhto(dp
, 16 - rm
);
3168 case 23: /* fulto */
3169 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3171 gen_vfp_ulto(dp
, 32 - rm
);
3173 case 24: /* ftoui */
3176 case 25: /* ftouiz */
3179 case 26: /* ftosi */
3182 case 27: /* ftosiz */
3185 case 28: /* ftosh */
3186 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3188 gen_vfp_tosh(dp
, 16 - rm
);
3190 case 29: /* ftosl */
3191 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3193 gen_vfp_tosl(dp
, 32 - rm
);
3195 case 30: /* ftouh */
3196 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3198 gen_vfp_touh(dp
, 16 - rm
);
3200 case 31: /* ftoul */
3201 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3203 gen_vfp_toul(dp
, 32 - rm
);
3205 default: /* undefined */
3206 printf ("rn:%d\n", rn
);
3210 default: /* undefined */
3211 printf ("op:%d\n", op
);
3215 /* Write back the result. */
3216 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3217 ; /* Comparison, do nothing. */
3218 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3219 /* VCVT double to int: always integer result. */
3220 gen_mov_vreg_F0(0, rd
);
3221 else if (op
== 15 && rn
== 15)
3223 gen_mov_vreg_F0(!dp
, rd
);
3225 gen_mov_vreg_F0(dp
, rd
);
3227 /* break out of the loop if we have finished */
3231 if (op
== 15 && delta_m
== 0) {
3232 /* single source one-many */
3234 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3236 gen_mov_vreg_F0(dp
, rd
);
3240 /* Setup the next operands. */
3242 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3246 /* One source operand. */
3247 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3249 gen_mov_F0_vreg(dp
, rm
);
3251 /* Two source operands. */
3252 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3254 gen_mov_F0_vreg(dp
, rn
);
3256 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3258 gen_mov_F1_vreg(dp
, rm
);
3266 if ((insn
& 0x03e00000) == 0x00400000) {
3267 /* two-register transfer */
3268 rn
= (insn
>> 16) & 0xf;
3269 rd
= (insn
>> 12) & 0xf;
3271 VFP_DREG_M(rm
, insn
);
3273 rm
= VFP_SREG_M(insn
);
3276 if (insn
& ARM_CP_RW_BIT
) {
3279 gen_mov_F0_vreg(0, rm
* 2);
3280 tmp
= gen_vfp_mrs();
3281 store_reg(s
, rd
, tmp
);
3282 gen_mov_F0_vreg(0, rm
* 2 + 1);
3283 tmp
= gen_vfp_mrs();
3284 store_reg(s
, rn
, tmp
);
3286 gen_mov_F0_vreg(0, rm
);
3287 tmp
= gen_vfp_mrs();
3288 store_reg(s
, rd
, tmp
);
3289 gen_mov_F0_vreg(0, rm
+ 1);
3290 tmp
= gen_vfp_mrs();
3291 store_reg(s
, rn
, tmp
);
3296 tmp
= load_reg(s
, rd
);
3298 gen_mov_vreg_F0(0, rm
* 2);
3299 tmp
= load_reg(s
, rn
);
3301 gen_mov_vreg_F0(0, rm
* 2 + 1);
3303 tmp
= load_reg(s
, rd
);
3305 gen_mov_vreg_F0(0, rm
);
3306 tmp
= load_reg(s
, rn
);
3308 gen_mov_vreg_F0(0, rm
+ 1);
3313 rn
= (insn
>> 16) & 0xf;
3315 VFP_DREG_D(rd
, insn
);
3317 rd
= VFP_SREG_D(insn
);
3318 if (s
->thumb
&& rn
== 15) {
3319 addr
= tcg_temp_new_i32();
3320 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3322 addr
= load_reg(s
, rn
);
3324 if ((insn
& 0x01200000) == 0x01000000) {
3325 /* Single load/store */
3326 offset
= (insn
& 0xff) << 2;
3327 if ((insn
& (1 << 23)) == 0)
3329 tcg_gen_addi_i32(addr
, addr
, offset
);
3330 if (insn
& (1 << 20)) {
3331 gen_vfp_ld(s
, dp
, addr
);
3332 gen_mov_vreg_F0(dp
, rd
);
3334 gen_mov_F0_vreg(dp
, rd
);
3335 gen_vfp_st(s
, dp
, addr
);
3337 tcg_temp_free_i32(addr
);
3339 /* load/store multiple */
3341 n
= (insn
>> 1) & 0x7f;
3345 if (insn
& (1 << 24)) /* pre-decrement */
3346 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3352 for (i
= 0; i
< n
; i
++) {
3353 if (insn
& ARM_CP_RW_BIT
) {
3355 gen_vfp_ld(s
, dp
, addr
);
3356 gen_mov_vreg_F0(dp
, rd
+ i
);
3359 gen_mov_F0_vreg(dp
, rd
+ i
);
3360 gen_vfp_st(s
, dp
, addr
);
3362 tcg_gen_addi_i32(addr
, addr
, offset
);
3364 if (insn
& (1 << 21)) {
3366 if (insn
& (1 << 24))
3367 offset
= -offset
* n
;
3368 else if (dp
&& (insn
& 1))
3374 tcg_gen_addi_i32(addr
, addr
, offset
);
3375 store_reg(s
, rn
, addr
);
3377 tcg_temp_free_i32(addr
);
3383 /* Should never happen. */
3389 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3391 TranslationBlock
*tb
;
3394 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3396 gen_set_pc_im(dest
);
3397 tcg_gen_exit_tb((long)tb
+ n
);
3399 gen_set_pc_im(dest
);
3404 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3406 if (unlikely(s
->singlestep_enabled
)) {
3407 /* An indirect jump so that we still trigger the debug exception. */
3412 gen_goto_tb(s
, 0, dest
);
3413 s
->is_jmp
= DISAS_TB_JUMP
;
3417 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3420 tcg_gen_sari_i32(t0
, t0
, 16);
3424 tcg_gen_sari_i32(t1
, t1
, 16);
3427 tcg_gen_mul_i32(t0
, t0
, t1
);
3430 /* Return the mask of PSR bits set by a MSR instruction. */
3431 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3435 if (flags
& (1 << 0))
3437 if (flags
& (1 << 1))
3439 if (flags
& (1 << 2))
3441 if (flags
& (1 << 3))
3444 /* Mask out undefined bits. */
3445 mask
&= ~CPSR_RESERVED
;
3446 if (!arm_feature(env
, ARM_FEATURE_V6
))
3447 mask
&= ~(CPSR_E
| CPSR_GE
);
3448 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3450 /* Mask out execution state bits. */
3453 /* Mask out privileged bits. */
3459 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3460 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3464 /* ??? This is also undefined in system mode. */
3468 tmp
= load_cpu_field(spsr
);
3469 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3470 tcg_gen_andi_i32(t0
, t0
, mask
);
3471 tcg_gen_or_i32(tmp
, tmp
, t0
);
3472 store_cpu_field(tmp
, spsr
);
3474 gen_set_cpsr(t0
, mask
);
3476 tcg_temp_free_i32(t0
);
3481 /* Returns nonzero if access to the PSR is not permitted. */
3482 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3485 tmp
= tcg_temp_new_i32();
3486 tcg_gen_movi_i32(tmp
, val
);
3487 return gen_set_psr(s
, mask
, spsr
, tmp
);
3490 /* Generate an old-style exception return. Marks pc as dead. */
3491 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3494 store_reg(s
, 15, pc
);
3495 tmp
= load_cpu_field(spsr
);
3496 gen_set_cpsr(tmp
, 0xffffffff);
3497 tcg_temp_free_i32(tmp
);
3498 s
->is_jmp
= DISAS_UPDATE
;
3501 /* Generate a v6 exception return. Marks both values as dead. */
3502 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3504 gen_set_cpsr(cpsr
, 0xffffffff);
3505 tcg_temp_free_i32(cpsr
);
3506 store_reg(s
, 15, pc
);
3507 s
->is_jmp
= DISAS_UPDATE
;
3511 gen_set_condexec (DisasContext
*s
)
3513 if (s
->condexec_mask
) {
3514 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3515 TCGv tmp
= tcg_temp_new_i32();
3516 tcg_gen_movi_i32(tmp
, val
);
3517 store_cpu_field(tmp
, condexec_bits
);
3521 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3523 gen_set_condexec(s
);
3524 gen_set_pc_im(s
->pc
- offset
);
3525 gen_exception(excp
);
3526 s
->is_jmp
= DISAS_JUMP
;
3529 static void gen_nop_hint(DisasContext
*s
, int val
)
3533 gen_set_pc_im(s
->pc
);
3534 s
->is_jmp
= DISAS_WFI
;
3538 /* TODO: Implement SEV and WFE. May help SMP performance. */
3544 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3546 static inline int gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3549 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3550 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3551 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3557 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3560 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3561 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3562 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3567 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3568 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3569 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3570 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3571 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3573 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3574 switch ((size << 1) | u) { \
3576 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3579 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3582 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3585 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3588 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3591 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3593 default: return 1; \
3596 #define GEN_NEON_INTEGER_OP(name) do { \
3597 switch ((size << 1) | u) { \
3599 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3602 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3605 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3608 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3611 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3614 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3616 default: return 1; \
3619 static TCGv
neon_load_scratch(int scratch
)
3621 TCGv tmp
= tcg_temp_new_i32();
3622 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3626 static void neon_store_scratch(int scratch
, TCGv var
)
3628 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3629 tcg_temp_free_i32(var
);
3632 static inline TCGv
neon_get_scalar(int size
, int reg
)
3636 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3638 gen_neon_dup_high16(tmp
);
3640 gen_neon_dup_low16(tmp
);
3643 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3648 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3651 if (size
== 3 || (!q
&& size
== 2)) {
3654 tmp
= tcg_const_i32(rd
);
3655 tmp2
= tcg_const_i32(rm
);
3659 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3662 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3665 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3673 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3676 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3682 tcg_temp_free_i32(tmp
);
3683 tcg_temp_free_i32(tmp2
);
3687 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3690 if (size
== 3 || (!q
&& size
== 2)) {
3693 tmp
= tcg_const_i32(rd
);
3694 tmp2
= tcg_const_i32(rm
);
3698 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3701 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3704 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3712 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3715 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3721 tcg_temp_free_i32(tmp
);
3722 tcg_temp_free_i32(tmp2
);
3726 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3730 rd
= tcg_temp_new_i32();
3731 tmp
= tcg_temp_new_i32();
3733 tcg_gen_shli_i32(rd
, t0
, 8);
3734 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3735 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3736 tcg_gen_or_i32(rd
, rd
, tmp
);
3738 tcg_gen_shri_i32(t1
, t1
, 8);
3739 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3740 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3741 tcg_gen_or_i32(t1
, t1
, tmp
);
3742 tcg_gen_mov_i32(t0
, rd
);
3744 tcg_temp_free_i32(tmp
);
3745 tcg_temp_free_i32(rd
);
3748 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3752 rd
= tcg_temp_new_i32();
3753 tmp
= tcg_temp_new_i32();
3755 tcg_gen_shli_i32(rd
, t0
, 16);
3756 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3757 tcg_gen_or_i32(rd
, rd
, tmp
);
3758 tcg_gen_shri_i32(t1
, t1
, 16);
3759 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3760 tcg_gen_or_i32(t1
, t1
, tmp
);
3761 tcg_gen_mov_i32(t0
, rd
);
3763 tcg_temp_free_i32(tmp
);
3764 tcg_temp_free_i32(rd
);
3772 } neon_ls_element_type
[11] = {
3786 /* Translate a NEON load/store element instruction. Return nonzero if the
3787 instruction is invalid. */
3788 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3807 if (!s
->vfp_enabled
)
3809 VFP_DREG_D(rd
, insn
);
3810 rn
= (insn
>> 16) & 0xf;
3812 load
= (insn
& (1 << 21)) != 0;
3813 addr
= tcg_temp_new_i32();
3814 if ((insn
& (1 << 23)) == 0) {
3815 /* Load store all elements. */
3816 op
= (insn
>> 8) & 0xf;
3817 size
= (insn
>> 6) & 3;
3820 nregs
= neon_ls_element_type
[op
].nregs
;
3821 interleave
= neon_ls_element_type
[op
].interleave
;
3822 spacing
= neon_ls_element_type
[op
].spacing
;
3823 if (size
== 3 && (interleave
| spacing
) != 1)
3825 load_reg_var(s
, addr
, rn
);
3826 stride
= (1 << size
) * interleave
;
3827 for (reg
= 0; reg
< nregs
; reg
++) {
3828 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3829 load_reg_var(s
, addr
, rn
);
3830 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3831 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3832 load_reg_var(s
, addr
, rn
);
3833 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3837 tmp64
= gen_ld64(addr
, IS_USER(s
));
3838 neon_store_reg64(tmp64
, rd
);
3839 tcg_temp_free_i64(tmp64
);
3841 tmp64
= tcg_temp_new_i64();
3842 neon_load_reg64(tmp64
, rd
);
3843 gen_st64(tmp64
, addr
, IS_USER(s
));
3845 tcg_gen_addi_i32(addr
, addr
, stride
);
3847 for (pass
= 0; pass
< 2; pass
++) {
3850 tmp
= gen_ld32(addr
, IS_USER(s
));
3851 neon_store_reg(rd
, pass
, tmp
);
3853 tmp
= neon_load_reg(rd
, pass
);
3854 gen_st32(tmp
, addr
, IS_USER(s
));
3856 tcg_gen_addi_i32(addr
, addr
, stride
);
3857 } else if (size
== 1) {
3859 tmp
= gen_ld16u(addr
, IS_USER(s
));
3860 tcg_gen_addi_i32(addr
, addr
, stride
);
3861 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3862 tcg_gen_addi_i32(addr
, addr
, stride
);
3863 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3864 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3865 tcg_temp_free_i32(tmp2
);
3866 neon_store_reg(rd
, pass
, tmp
);
3868 tmp
= neon_load_reg(rd
, pass
);
3869 tmp2
= tcg_temp_new_i32();
3870 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3871 gen_st16(tmp
, addr
, IS_USER(s
));
3872 tcg_gen_addi_i32(addr
, addr
, stride
);
3873 gen_st16(tmp2
, addr
, IS_USER(s
));
3874 tcg_gen_addi_i32(addr
, addr
, stride
);
3876 } else /* size == 0 */ {
3879 for (n
= 0; n
< 4; n
++) {
3880 tmp
= gen_ld8u(addr
, IS_USER(s
));
3881 tcg_gen_addi_i32(addr
, addr
, stride
);
3885 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3886 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3887 tcg_temp_free_i32(tmp
);
3890 neon_store_reg(rd
, pass
, tmp2
);
3892 tmp2
= neon_load_reg(rd
, pass
);
3893 for (n
= 0; n
< 4; n
++) {
3894 tmp
= tcg_temp_new_i32();
3896 tcg_gen_mov_i32(tmp
, tmp2
);
3898 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3900 gen_st8(tmp
, addr
, IS_USER(s
));
3901 tcg_gen_addi_i32(addr
, addr
, stride
);
3903 tcg_temp_free_i32(tmp2
);
3912 size
= (insn
>> 10) & 3;
3914 /* Load single element to all lanes. */
3915 int a
= (insn
>> 4) & 1;
3919 size
= (insn
>> 6) & 3;
3920 nregs
= ((insn
>> 8) & 3) + 1;
3923 if (nregs
!= 4 || a
== 0) {
3926 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3929 if (nregs
== 1 && a
== 1 && size
== 0) {
3932 if (nregs
== 3 && a
== 1) {
3935 load_reg_var(s
, addr
, rn
);
3937 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3938 tmp
= gen_load_and_replicate(s
, addr
, size
);
3939 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3940 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3941 if (insn
& (1 << 5)) {
3942 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3943 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3945 tcg_temp_free_i32(tmp
);
3947 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3948 stride
= (insn
& (1 << 5)) ? 2 : 1;
3949 for (reg
= 0; reg
< nregs
; reg
++) {
3950 tmp
= gen_load_and_replicate(s
, addr
, size
);
3951 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3952 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3953 tcg_temp_free_i32(tmp
);
3954 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3958 stride
= (1 << size
) * nregs
;
3960 /* Single element. */
3961 pass
= (insn
>> 7) & 1;
3964 shift
= ((insn
>> 5) & 3) * 8;
3968 shift
= ((insn
>> 6) & 1) * 16;
3969 stride
= (insn
& (1 << 5)) ? 2 : 1;
3973 stride
= (insn
& (1 << 6)) ? 2 : 1;
3978 nregs
= ((insn
>> 8) & 3) + 1;
3979 load_reg_var(s
, addr
, rn
);
3980 for (reg
= 0; reg
< nregs
; reg
++) {
3984 tmp
= gen_ld8u(addr
, IS_USER(s
));
3987 tmp
= gen_ld16u(addr
, IS_USER(s
));
3990 tmp
= gen_ld32(addr
, IS_USER(s
));
3992 default: /* Avoid compiler warnings. */
3996 tmp2
= neon_load_reg(rd
, pass
);
3997 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
3998 tcg_temp_free_i32(tmp2
);
4000 neon_store_reg(rd
, pass
, tmp
);
4001 } else { /* Store */
4002 tmp
= neon_load_reg(rd
, pass
);
4004 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4007 gen_st8(tmp
, addr
, IS_USER(s
));
4010 gen_st16(tmp
, addr
, IS_USER(s
));
4013 gen_st32(tmp
, addr
, IS_USER(s
));
4018 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4020 stride
= nregs
* (1 << size
);
4023 tcg_temp_free_i32(addr
);
4027 base
= load_reg(s
, rn
);
4029 tcg_gen_addi_i32(base
, base
, stride
);
4032 index
= load_reg(s
, rm
);
4033 tcg_gen_add_i32(base
, base
, index
);
4034 tcg_temp_free_i32(index
);
4036 store_reg(s
, rn
, base
);
4041 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4042 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4044 tcg_gen_and_i32(t
, t
, c
);
4045 tcg_gen_andc_i32(f
, f
, c
);
4046 tcg_gen_or_i32(dest
, t
, f
);
4049 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4052 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4053 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4054 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4059 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4062 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4063 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4064 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4069 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4072 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4073 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4074 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4079 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4082 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4083 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4084 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4089 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4095 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4096 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4101 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4102 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4109 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4110 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4115 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4116 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4123 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4127 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4128 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4129 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4134 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4135 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4136 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4140 tcg_temp_free_i32(src
);
4143 static inline void gen_neon_addl(int size
)
4146 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4147 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4148 case 2: tcg_gen_add_i64(CPU_V001
); break;
4153 static inline void gen_neon_subl(int size
)
4156 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4157 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4158 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4163 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4166 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4167 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4168 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4173 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4176 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4177 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4182 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4186 switch ((size
<< 1) | u
) {
4187 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4188 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4189 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4190 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4192 tmp
= gen_muls_i64_i32(a
, b
);
4193 tcg_gen_mov_i64(dest
, tmp
);
4194 tcg_temp_free_i64(tmp
);
4197 tmp
= gen_mulu_i64_i32(a
, b
);
4198 tcg_gen_mov_i64(dest
, tmp
);
4199 tcg_temp_free_i64(tmp
);
4204 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4205 Don't forget to clean them now. */
4207 tcg_temp_free_i32(a
);
4208 tcg_temp_free_i32(b
);
4212 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4216 gen_neon_unarrow_sats(size
, dest
, src
);
4218 gen_neon_narrow(size
, dest
, src
);
4222 gen_neon_narrow_satu(size
, dest
, src
);
4224 gen_neon_narrow_sats(size
, dest
, src
);
4229 /* Translate a NEON data processing instruction. Return nonzero if the
4230 instruction is invalid.
4231 We process data in a mixture of 32-bit and 64-bit chunks.
4232 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4234 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4247 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4250 if (!s
->vfp_enabled
)
4252 q
= (insn
& (1 << 6)) != 0;
4253 u
= (insn
>> 24) & 1;
4254 VFP_DREG_D(rd
, insn
);
4255 VFP_DREG_N(rn
, insn
);
4256 VFP_DREG_M(rm
, insn
);
4257 size
= (insn
>> 20) & 3;
4258 if ((insn
& (1 << 23)) == 0) {
4259 /* Three register same length. */
4260 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4261 if (size
== 3 && (op
== 1 || op
== 5 || op
== 8 || op
== 9
4262 || op
== 10 || op
== 11 || op
== 16)) {
4263 /* 64-bit element instructions. */
4264 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4265 neon_load_reg64(cpu_V0
, rn
+ pass
);
4266 neon_load_reg64(cpu_V1
, rm
+ pass
);
4270 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4273 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4279 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4282 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4288 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4290 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4295 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4298 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4302 case 10: /* VRSHL */
4304 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4306 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4309 case 11: /* VQRSHL */
4311 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4314 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4320 tcg_gen_sub_i64(CPU_V001
);
4322 tcg_gen_add_i64(CPU_V001
);
4328 neon_store_reg64(cpu_V0
, rd
+ pass
);
4335 case 10: /* VRSHL */
4336 case 11: /* VQRSHL */
4339 /* Shift instruction operands are reversed. */
4346 case 20: /* VPMAX */
4347 case 21: /* VPMIN */
4348 case 23: /* VPADD */
4351 case 26: /* VPADD (float) */
4352 pairwise
= (u
&& size
< 2);
4354 case 30: /* VPMIN/VPMAX (float) */
4362 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4371 tmp
= neon_load_reg(rn
, n
);
4372 tmp2
= neon_load_reg(rn
, n
+ 1);
4374 tmp
= neon_load_reg(rm
, n
);
4375 tmp2
= neon_load_reg(rm
, n
+ 1);
4379 tmp
= neon_load_reg(rn
, pass
);
4380 tmp2
= neon_load_reg(rm
, pass
);
4384 GEN_NEON_INTEGER_OP(hadd
);
4387 GEN_NEON_INTEGER_OP_ENV(qadd
);
4389 case 2: /* VRHADD */
4390 GEN_NEON_INTEGER_OP(rhadd
);
4392 case 3: /* Logic ops. */
4393 switch ((u
<< 2) | size
) {
4395 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4398 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4401 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4404 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4407 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4410 tmp3
= neon_load_reg(rd
, pass
);
4411 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4412 tcg_temp_free_i32(tmp3
);
4415 tmp3
= neon_load_reg(rd
, pass
);
4416 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4417 tcg_temp_free_i32(tmp3
);
4420 tmp3
= neon_load_reg(rd
, pass
);
4421 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4422 tcg_temp_free_i32(tmp3
);
4427 GEN_NEON_INTEGER_OP(hsub
);
4430 GEN_NEON_INTEGER_OP_ENV(qsub
);
4433 GEN_NEON_INTEGER_OP(cgt
);
4436 GEN_NEON_INTEGER_OP(cge
);
4439 GEN_NEON_INTEGER_OP(shl
);
4442 GEN_NEON_INTEGER_OP_ENV(qshl
);
4444 case 10: /* VRSHL */
4445 GEN_NEON_INTEGER_OP(rshl
);
4447 case 11: /* VQRSHL */
4448 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4451 GEN_NEON_INTEGER_OP(max
);
4454 GEN_NEON_INTEGER_OP(min
);
4457 GEN_NEON_INTEGER_OP(abd
);
4460 GEN_NEON_INTEGER_OP(abd
);
4461 tcg_temp_free_i32(tmp2
);
4462 tmp2
= neon_load_reg(rd
, pass
);
4463 gen_neon_add(size
, tmp
, tmp2
);
4466 if (!u
) { /* VADD */
4467 if (gen_neon_add(size
, tmp
, tmp2
))
4471 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4472 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4473 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4479 if (!u
) { /* VTST */
4481 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4482 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4483 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4488 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4489 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4490 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4495 case 18: /* Multiply. */
4497 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4498 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4499 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4502 tcg_temp_free_i32(tmp2
);
4503 tmp2
= neon_load_reg(rd
, pass
);
4505 gen_neon_rsb(size
, tmp
, tmp2
);
4507 gen_neon_add(size
, tmp
, tmp2
);
4511 if (u
) { /* polynomial */
4512 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4513 } else { /* Integer */
4515 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4516 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4517 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4522 case 20: /* VPMAX */
4523 GEN_NEON_INTEGER_OP(pmax
);
4525 case 21: /* VPMIN */
4526 GEN_NEON_INTEGER_OP(pmin
);
4528 case 22: /* Hultiply high. */
4529 if (!u
) { /* VQDMULH */
4531 case 1: gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4532 case 2: gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4535 } else { /* VQRDHMUL */
4537 case 1: gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4538 case 2: gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4543 case 23: /* VPADD */
4547 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4548 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4549 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4553 case 26: /* Floating point arithnetic. */
4554 switch ((u
<< 2) | size
) {
4556 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4559 gen_helper_neon_sub_f32(tmp
, tmp
, tmp2
);
4562 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4565 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
);
4571 case 27: /* Float multiply. */
4572 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
4574 tcg_temp_free_i32(tmp2
);
4575 tmp2
= neon_load_reg(rd
, pass
);
4577 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4579 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
4583 case 28: /* Float compare. */
4585 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
4588 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
4590 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
4593 case 29: /* Float compare absolute. */
4597 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
);
4599 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
);
4601 case 30: /* Float min/max. */
4603 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
);
4605 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
);
4609 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4611 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4616 tcg_temp_free_i32(tmp2
);
4618 /* Save the result. For elementwise operations we can put it
4619 straight into the destination register. For pairwise operations
4620 we have to be careful to avoid clobbering the source operands. */
4621 if (pairwise
&& rd
== rm
) {
4622 neon_store_scratch(pass
, tmp
);
4624 neon_store_reg(rd
, pass
, tmp
);
4628 if (pairwise
&& rd
== rm
) {
4629 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4630 tmp
= neon_load_scratch(pass
);
4631 neon_store_reg(rd
, pass
, tmp
);
4634 /* End of 3 register same size operations. */
4635 } else if (insn
& (1 << 4)) {
4636 if ((insn
& 0x00380080) != 0) {
4637 /* Two registers and shift. */
4638 op
= (insn
>> 8) & 0xf;
4639 if (insn
& (1 << 7)) {
4644 while ((insn
& (1 << (size
+ 19))) == 0)
4647 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4648 /* To avoid excessive dumplication of ops we implement shift
4649 by immediate using the variable shift operations. */
4651 /* Shift by immediate:
4652 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4653 /* Right shifts are encoded as N - shift, where N is the
4654 element size in bits. */
4656 shift
= shift
- (1 << (size
+ 3));
4664 imm
= (uint8_t) shift
;
4669 imm
= (uint16_t) shift
;
4680 for (pass
= 0; pass
< count
; pass
++) {
4682 neon_load_reg64(cpu_V0
, rm
+ pass
);
4683 tcg_gen_movi_i64(cpu_V1
, imm
);
4688 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4690 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4695 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4697 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4702 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4704 case 5: /* VSHL, VSLI */
4705 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4707 case 6: /* VQSHLU */
4709 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
4717 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4720 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4725 if (op
== 1 || op
== 3) {
4727 neon_load_reg64(cpu_V1
, rd
+ pass
);
4728 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4729 } else if (op
== 4 || (op
== 5 && u
)) {
4731 neon_load_reg64(cpu_V1
, rd
+ pass
);
4733 if (shift
< -63 || shift
> 63) {
4737 mask
= 0xffffffffffffffffull
>> -shift
;
4739 mask
= 0xffffffffffffffffull
<< shift
;
4742 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
4743 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4745 neon_store_reg64(cpu_V0
, rd
+ pass
);
4746 } else { /* size < 3 */
4747 /* Operands in T0 and T1. */
4748 tmp
= neon_load_reg(rm
, pass
);
4749 tmp2
= tcg_temp_new_i32();
4750 tcg_gen_movi_i32(tmp2
, imm
);
4754 GEN_NEON_INTEGER_OP(shl
);
4758 GEN_NEON_INTEGER_OP(rshl
);
4763 GEN_NEON_INTEGER_OP(shl
);
4765 case 5: /* VSHL, VSLI */
4767 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
4768 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
4769 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
4773 case 6: /* VQSHLU */
4779 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
4783 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
4787 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
4795 GEN_NEON_INTEGER_OP_ENV(qshl
);
4798 tcg_temp_free_i32(tmp2
);
4800 if (op
== 1 || op
== 3) {
4802 tmp2
= neon_load_reg(rd
, pass
);
4803 gen_neon_add(size
, tmp
, tmp2
);
4804 tcg_temp_free_i32(tmp2
);
4805 } else if (op
== 4 || (op
== 5 && u
)) {
4810 mask
= 0xff >> -shift
;
4812 mask
= (uint8_t)(0xff << shift
);
4818 mask
= 0xffff >> -shift
;
4820 mask
= (uint16_t)(0xffff << shift
);
4824 if (shift
< -31 || shift
> 31) {
4828 mask
= 0xffffffffu
>> -shift
;
4830 mask
= 0xffffffffu
<< shift
;
4836 tmp2
= neon_load_reg(rd
, pass
);
4837 tcg_gen_andi_i32(tmp
, tmp
, mask
);
4838 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
4839 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4840 tcg_temp_free_i32(tmp2
);
4842 neon_store_reg(rd
, pass
, tmp
);
4845 } else if (op
< 10) {
4846 /* Shift by immediate and narrow:
4847 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4848 int input_unsigned
= (op
== 8) ? !u
: u
;
4850 shift
= shift
- (1 << (size
+ 3));
4853 tmp64
= tcg_const_i64(shift
);
4854 neon_load_reg64(cpu_V0
, rm
);
4855 neon_load_reg64(cpu_V1
, rm
+ 1);
4856 for (pass
= 0; pass
< 2; pass
++) {
4864 if (input_unsigned
) {
4865 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
4867 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
4870 if (input_unsigned
) {
4871 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
4873 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
4876 tmp
= tcg_temp_new_i32();
4877 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4878 neon_store_reg(rd
, pass
, tmp
);
4880 tcg_temp_free_i64(tmp64
);
4883 imm
= (uint16_t)shift
;
4887 imm
= (uint32_t)shift
;
4889 tmp2
= tcg_const_i32(imm
);
4890 tmp4
= neon_load_reg(rm
+ 1, 0);
4891 tmp5
= neon_load_reg(rm
+ 1, 1);
4892 for (pass
= 0; pass
< 2; pass
++) {
4894 tmp
= neon_load_reg(rm
, 0);
4898 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
4901 tmp3
= neon_load_reg(rm
, 1);
4905 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
4907 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
4908 tcg_temp_free_i32(tmp
);
4909 tcg_temp_free_i32(tmp3
);
4910 tmp
= tcg_temp_new_i32();
4911 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4912 neon_store_reg(rd
, pass
, tmp
);
4914 tcg_temp_free_i32(tmp2
);
4916 } else if (op
== 10) {
4920 tmp
= neon_load_reg(rm
, 0);
4921 tmp2
= neon_load_reg(rm
, 1);
4922 for (pass
= 0; pass
< 2; pass
++) {
4926 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
4929 /* The shift is less than the width of the source
4930 type, so we can just shift the whole register. */
4931 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
4932 /* Widen the result of shift: we need to clear
4933 * the potential overflow bits resulting from
4934 * left bits of the narrow input appearing as
4935 * right bits of left the neighbour narrow
4937 if (size
< 2 || !u
) {
4940 imm
= (0xffu
>> (8 - shift
));
4942 } else if (size
== 1) {
4943 imm
= 0xffff >> (16 - shift
);
4946 imm
= 0xffffffff >> (32 - shift
);
4949 imm64
= imm
| (((uint64_t)imm
) << 32);
4953 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
4956 neon_store_reg64(cpu_V0
, rd
+ pass
);
4958 } else if (op
>= 14) {
4959 /* VCVT fixed-point. */
4960 /* We have already masked out the must-be-1 top bit of imm6,
4961 * hence this 32-shift where the ARM ARM has 64-imm6.
4964 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4965 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
4968 gen_vfp_ulto(0, shift
);
4970 gen_vfp_slto(0, shift
);
4973 gen_vfp_toul(0, shift
);
4975 gen_vfp_tosl(0, shift
);
4977 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
4982 } else { /* (insn & 0x00380080) == 0 */
4985 op
= (insn
>> 8) & 0xf;
4986 /* One register and immediate. */
4987 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
4988 invert
= (insn
& (1 << 5)) != 0;
5006 imm
= (imm
<< 8) | (imm
<< 24);
5009 imm
= (imm
<< 8) | 0xff;
5012 imm
= (imm
<< 16) | 0xffff;
5015 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5020 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5021 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5027 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5028 if (op
& 1 && op
< 12) {
5029 tmp
= neon_load_reg(rd
, pass
);
5031 /* The immediate value has already been inverted, so
5033 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5035 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5039 tmp
= tcg_temp_new_i32();
5040 if (op
== 14 && invert
) {
5043 for (n
= 0; n
< 4; n
++) {
5044 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5045 val
|= 0xff << (n
* 8);
5047 tcg_gen_movi_i32(tmp
, val
);
5049 tcg_gen_movi_i32(tmp
, imm
);
5052 neon_store_reg(rd
, pass
, tmp
);
5055 } else { /* (insn & 0x00800010 == 0x00800000) */
5057 op
= (insn
>> 8) & 0xf;
5058 if ((insn
& (1 << 6)) == 0) {
5059 /* Three registers of different lengths. */
5063 /* prewiden, src1_wide, src2_wide */
5064 static const int neon_3reg_wide
[16][3] = {
5065 {1, 0, 0}, /* VADDL */
5066 {1, 1, 0}, /* VADDW */
5067 {1, 0, 0}, /* VSUBL */
5068 {1, 1, 0}, /* VSUBW */
5069 {0, 1, 1}, /* VADDHN */
5070 {0, 0, 0}, /* VABAL */
5071 {0, 1, 1}, /* VSUBHN */
5072 {0, 0, 0}, /* VABDL */
5073 {0, 0, 0}, /* VMLAL */
5074 {0, 0, 0}, /* VQDMLAL */
5075 {0, 0, 0}, /* VMLSL */
5076 {0, 0, 0}, /* VQDMLSL */
5077 {0, 0, 0}, /* Integer VMULL */
5078 {0, 0, 0}, /* VQDMULL */
5079 {0, 0, 0} /* Polynomial VMULL */
5082 prewiden
= neon_3reg_wide
[op
][0];
5083 src1_wide
= neon_3reg_wide
[op
][1];
5084 src2_wide
= neon_3reg_wide
[op
][2];
5086 if (size
== 0 && (op
== 9 || op
== 11 || op
== 13))
5089 /* Avoid overlapping operands. Wide source operands are
5090 always aligned so will never overlap with wide
5091 destinations in problematic ways. */
5092 if (rd
== rm
&& !src2_wide
) {
5093 tmp
= neon_load_reg(rm
, 1);
5094 neon_store_scratch(2, tmp
);
5095 } else if (rd
== rn
&& !src1_wide
) {
5096 tmp
= neon_load_reg(rn
, 1);
5097 neon_store_scratch(2, tmp
);
5100 for (pass
= 0; pass
< 2; pass
++) {
5102 neon_load_reg64(cpu_V0
, rn
+ pass
);
5105 if (pass
== 1 && rd
== rn
) {
5106 tmp
= neon_load_scratch(2);
5108 tmp
= neon_load_reg(rn
, pass
);
5111 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5115 neon_load_reg64(cpu_V1
, rm
+ pass
);
5118 if (pass
== 1 && rd
== rm
) {
5119 tmp2
= neon_load_scratch(2);
5121 tmp2
= neon_load_reg(rm
, pass
);
5124 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5128 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5129 gen_neon_addl(size
);
5131 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5132 gen_neon_subl(size
);
5134 case 5: case 7: /* VABAL, VABDL */
5135 switch ((size
<< 1) | u
) {
5137 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5140 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5143 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5146 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5149 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5152 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5156 tcg_temp_free_i32(tmp2
);
5157 tcg_temp_free_i32(tmp
);
5159 case 8: case 9: case 10: case 11: case 12: case 13:
5160 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5161 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5163 case 14: /* Polynomial VMULL */
5164 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5165 tcg_temp_free_i32(tmp2
);
5166 tcg_temp_free_i32(tmp
);
5168 default: /* 15 is RESERVED. */
5173 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5174 neon_store_reg64(cpu_V0
, rd
+ pass
);
5175 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5177 neon_load_reg64(cpu_V1
, rd
+ pass
);
5179 case 10: /* VMLSL */
5180 gen_neon_negl(cpu_V0
, size
);
5182 case 5: case 8: /* VABAL, VMLAL */
5183 gen_neon_addl(size
);
5185 case 9: case 11: /* VQDMLAL, VQDMLSL */
5186 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5188 gen_neon_negl(cpu_V0
, size
);
5190 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5195 neon_store_reg64(cpu_V0
, rd
+ pass
);
5196 } else if (op
== 4 || op
== 6) {
5197 /* Narrowing operation. */
5198 tmp
= tcg_temp_new_i32();
5202 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5205 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5208 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5209 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5216 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5219 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5222 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5223 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5224 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5232 neon_store_reg(rd
, 0, tmp3
);
5233 neon_store_reg(rd
, 1, tmp
);
5236 /* Write back the result. */
5237 neon_store_reg64(cpu_V0
, rd
+ pass
);
5241 /* Two registers and a scalar. */
5243 case 0: /* Integer VMLA scalar */
5244 case 1: /* Float VMLA scalar */
5245 case 4: /* Integer VMLS scalar */
5246 case 5: /* Floating point VMLS scalar */
5247 case 8: /* Integer VMUL scalar */
5248 case 9: /* Floating point VMUL scalar */
5249 case 12: /* VQDMULH scalar */
5250 case 13: /* VQRDMULH scalar */
5251 tmp
= neon_get_scalar(size
, rm
);
5252 neon_store_scratch(0, tmp
);
5253 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5254 tmp
= neon_load_scratch(0);
5255 tmp2
= neon_load_reg(rn
, pass
);
5258 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5260 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5262 } else if (op
== 13) {
5264 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5266 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5268 } else if (op
& 1) {
5269 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
5272 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5273 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5274 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5278 tcg_temp_free_i32(tmp2
);
5281 tmp2
= neon_load_reg(rd
, pass
);
5284 gen_neon_add(size
, tmp
, tmp2
);
5287 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
5290 gen_neon_rsb(size
, tmp
, tmp2
);
5293 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
5298 tcg_temp_free_i32(tmp2
);
5300 neon_store_reg(rd
, pass
, tmp
);
5303 case 2: /* VMLAL sclar */
5304 case 3: /* VQDMLAL scalar */
5305 case 6: /* VMLSL scalar */
5306 case 7: /* VQDMLSL scalar */
5307 case 10: /* VMULL scalar */
5308 case 11: /* VQDMULL scalar */
5309 if (size
== 0 && (op
== 3 || op
== 7 || op
== 11))
5312 tmp2
= neon_get_scalar(size
, rm
);
5313 /* We need a copy of tmp2 because gen_neon_mull
5314 * deletes it during pass 0. */
5315 tmp4
= tcg_temp_new_i32();
5316 tcg_gen_mov_i32(tmp4
, tmp2
);
5317 tmp3
= neon_load_reg(rn
, 1);
5319 for (pass
= 0; pass
< 2; pass
++) {
5321 tmp
= neon_load_reg(rn
, 0);
5326 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5328 neon_load_reg64(cpu_V1
, rd
+ pass
);
5332 gen_neon_negl(cpu_V0
, size
);
5335 gen_neon_addl(size
);
5338 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5340 gen_neon_negl(cpu_V0
, size
);
5342 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5348 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5353 neon_store_reg64(cpu_V0
, rd
+ pass
);
5358 default: /* 14 and 15 are RESERVED */
5362 } else { /* size == 3 */
5365 imm
= (insn
>> 8) & 0xf;
5371 neon_load_reg64(cpu_V0
, rn
);
5373 neon_load_reg64(cpu_V1
, rn
+ 1);
5375 } else if (imm
== 8) {
5376 neon_load_reg64(cpu_V0
, rn
+ 1);
5378 neon_load_reg64(cpu_V1
, rm
);
5381 tmp64
= tcg_temp_new_i64();
5383 neon_load_reg64(cpu_V0
, rn
);
5384 neon_load_reg64(tmp64
, rn
+ 1);
5386 neon_load_reg64(cpu_V0
, rn
+ 1);
5387 neon_load_reg64(tmp64
, rm
);
5389 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5390 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5391 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5393 neon_load_reg64(cpu_V1
, rm
);
5395 neon_load_reg64(cpu_V1
, rm
+ 1);
5398 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5399 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5400 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5401 tcg_temp_free_i64(tmp64
);
5404 neon_load_reg64(cpu_V0
, rn
);
5405 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5406 neon_load_reg64(cpu_V1
, rm
);
5407 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5408 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5410 neon_store_reg64(cpu_V0
, rd
);
5412 neon_store_reg64(cpu_V1
, rd
+ 1);
5414 } else if ((insn
& (1 << 11)) == 0) {
5415 /* Two register misc. */
5416 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5417 size
= (insn
>> 18) & 3;
5419 case 0: /* VREV64 */
5422 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5423 tmp
= neon_load_reg(rm
, pass
* 2);
5424 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5426 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5427 case 1: gen_swap_half(tmp
); break;
5428 case 2: /* no-op */ break;
5431 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5433 neon_store_reg(rd
, pass
* 2, tmp2
);
5436 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5437 case 1: gen_swap_half(tmp2
); break;
5440 neon_store_reg(rd
, pass
* 2, tmp2
);
5444 case 4: case 5: /* VPADDL */
5445 case 12: case 13: /* VPADAL */
5448 for (pass
= 0; pass
< q
+ 1; pass
++) {
5449 tmp
= neon_load_reg(rm
, pass
* 2);
5450 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5451 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5452 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5454 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5455 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5456 case 2: tcg_gen_add_i64(CPU_V001
); break;
5461 neon_load_reg64(cpu_V1
, rd
+ pass
);
5462 gen_neon_addl(size
);
5464 neon_store_reg64(cpu_V0
, rd
+ pass
);
5469 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5470 tmp
= neon_load_reg(rm
, n
);
5471 tmp2
= neon_load_reg(rd
, n
+ 1);
5472 neon_store_reg(rm
, n
, tmp2
);
5473 neon_store_reg(rd
, n
+ 1, tmp
);
5480 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5485 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5489 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5493 for (pass
= 0; pass
< 2; pass
++) {
5494 neon_load_reg64(cpu_V0
, rm
+ pass
);
5495 tmp
= tcg_temp_new_i32();
5496 gen_neon_narrow_op(op
== 36, q
, size
, tmp
, cpu_V0
);
5500 neon_store_reg(rd
, 0, tmp2
);
5501 neon_store_reg(rd
, 1, tmp
);
5505 case 38: /* VSHLL */
5508 tmp
= neon_load_reg(rm
, 0);
5509 tmp2
= neon_load_reg(rm
, 1);
5510 for (pass
= 0; pass
< 2; pass
++) {
5513 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5514 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5515 neon_store_reg64(cpu_V0
, rd
+ pass
);
5518 case 44: /* VCVT.F16.F32 */
5519 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5521 tmp
= tcg_temp_new_i32();
5522 tmp2
= tcg_temp_new_i32();
5523 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5524 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5525 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5526 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5527 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5528 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5529 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5530 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5531 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5532 neon_store_reg(rd
, 0, tmp2
);
5533 tmp2
= tcg_temp_new_i32();
5534 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5535 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5536 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5537 neon_store_reg(rd
, 1, tmp2
);
5538 tcg_temp_free_i32(tmp
);
5540 case 46: /* VCVT.F32.F16 */
5541 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5543 tmp3
= tcg_temp_new_i32();
5544 tmp
= neon_load_reg(rm
, 0);
5545 tmp2
= neon_load_reg(rm
, 1);
5546 tcg_gen_ext16u_i32(tmp3
, tmp
);
5547 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5548 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5549 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5550 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5551 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5552 tcg_temp_free_i32(tmp
);
5553 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5554 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5555 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5556 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5557 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5558 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5559 tcg_temp_free_i32(tmp2
);
5560 tcg_temp_free_i32(tmp3
);
5564 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5565 if (op
== 30 || op
== 31 || op
>= 58) {
5566 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5567 neon_reg_offset(rm
, pass
));
5570 tmp
= neon_load_reg(rm
, pass
);
5573 case 1: /* VREV32 */
5575 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5576 case 1: gen_swap_half(tmp
); break;
5580 case 2: /* VREV16 */
5587 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5588 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5589 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5595 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5596 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5597 case 2: gen_helper_clz(tmp
, tmp
); break;
5604 gen_helper_neon_cnt_u8(tmp
, tmp
);
5609 tcg_gen_not_i32(tmp
, tmp
);
5611 case 14: /* VQABS */
5613 case 0: gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
); break;
5614 case 1: gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
); break;
5615 case 2: gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
); break;
5619 case 15: /* VQNEG */
5621 case 0: gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
); break;
5622 case 1: gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
); break;
5623 case 2: gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
); break;
5627 case 16: case 19: /* VCGT #0, VCLE #0 */
5628 tmp2
= tcg_const_i32(0);
5630 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5631 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5632 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5635 tcg_temp_free(tmp2
);
5637 tcg_gen_not_i32(tmp
, tmp
);
5639 case 17: case 20: /* VCGE #0, VCLT #0 */
5640 tmp2
= tcg_const_i32(0);
5642 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5643 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5644 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5647 tcg_temp_free(tmp2
);
5649 tcg_gen_not_i32(tmp
, tmp
);
5651 case 18: /* VCEQ #0 */
5652 tmp2
= tcg_const_i32(0);
5654 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5655 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5656 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5659 tcg_temp_free(tmp2
);
5663 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
5664 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
5665 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
5672 tmp2
= tcg_const_i32(0);
5673 gen_neon_rsb(size
, tmp
, tmp2
);
5674 tcg_temp_free(tmp2
);
5676 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5677 tmp2
= tcg_const_i32(0);
5678 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
5679 tcg_temp_free(tmp2
);
5681 tcg_gen_not_i32(tmp
, tmp
);
5683 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5684 tmp2
= tcg_const_i32(0);
5685 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
5686 tcg_temp_free(tmp2
);
5688 tcg_gen_not_i32(tmp
, tmp
);
5690 case 26: /* Float VCEQ #0 */
5691 tmp2
= tcg_const_i32(0);
5692 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
5693 tcg_temp_free(tmp2
);
5695 case 30: /* Float VABS */
5698 case 31: /* Float VNEG */
5702 tmp2
= neon_load_reg(rd
, pass
);
5703 neon_store_reg(rm
, pass
, tmp2
);
5706 tmp2
= neon_load_reg(rd
, pass
);
5708 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
5709 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
5713 neon_store_reg(rm
, pass
, tmp2
);
5715 case 56: /* Integer VRECPE */
5716 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
5718 case 57: /* Integer VRSQRTE */
5719 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
5721 case 58: /* Float VRECPE */
5722 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5724 case 59: /* Float VRSQRTE */
5725 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5727 case 60: /* VCVT.F32.S32 */
5730 case 61: /* VCVT.F32.U32 */
5733 case 62: /* VCVT.S32.F32 */
5736 case 63: /* VCVT.U32.F32 */
5740 /* Reserved: 21, 29, 39-56 */
5743 if (op
== 30 || op
== 31 || op
>= 58) {
5744 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
5745 neon_reg_offset(rd
, pass
));
5747 neon_store_reg(rd
, pass
, tmp
);
5752 } else if ((insn
& (1 << 10)) == 0) {
5754 n
= ((insn
>> 5) & 0x18) + 8;
5755 if (insn
& (1 << 6)) {
5756 tmp
= neon_load_reg(rd
, 0);
5758 tmp
= tcg_temp_new_i32();
5759 tcg_gen_movi_i32(tmp
, 0);
5761 tmp2
= neon_load_reg(rm
, 0);
5762 tmp4
= tcg_const_i32(rn
);
5763 tmp5
= tcg_const_i32(n
);
5764 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
5765 tcg_temp_free_i32(tmp
);
5766 if (insn
& (1 << 6)) {
5767 tmp
= neon_load_reg(rd
, 1);
5769 tmp
= tcg_temp_new_i32();
5770 tcg_gen_movi_i32(tmp
, 0);
5772 tmp3
= neon_load_reg(rm
, 1);
5773 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
5774 tcg_temp_free_i32(tmp5
);
5775 tcg_temp_free_i32(tmp4
);
5776 neon_store_reg(rd
, 0, tmp2
);
5777 neon_store_reg(rd
, 1, tmp3
);
5778 tcg_temp_free_i32(tmp
);
5779 } else if ((insn
& 0x380) == 0) {
5781 if (insn
& (1 << 19)) {
5782 tmp
= neon_load_reg(rm
, 1);
5784 tmp
= neon_load_reg(rm
, 0);
5786 if (insn
& (1 << 16)) {
5787 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
5788 } else if (insn
& (1 << 17)) {
5789 if ((insn
>> 18) & 1)
5790 gen_neon_dup_high16(tmp
);
5792 gen_neon_dup_low16(tmp
);
5794 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5795 tmp2
= tcg_temp_new_i32();
5796 tcg_gen_mov_i32(tmp2
, tmp
);
5797 neon_store_reg(rd
, pass
, tmp2
);
5799 tcg_temp_free_i32(tmp
);
5808 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5810 int crn
= (insn
>> 16) & 0xf;
5811 int crm
= insn
& 0xf;
5812 int op1
= (insn
>> 21) & 7;
5813 int op2
= (insn
>> 5) & 7;
5814 int rt
= (insn
>> 12) & 0xf;
5817 /* Minimal set of debug registers, since we don't support debug */
5818 if (op1
== 0 && crn
== 0 && op2
== 0) {
5821 /* DBGDIDR: just RAZ. In particular this means the
5822 * "debug architecture version" bits will read as
5823 * a reserved value, which should cause Linux to
5824 * not try to use the debug hardware.
5826 tmp
= tcg_const_i32(0);
5827 store_reg(s
, rt
, tmp
);
5831 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
5832 * don't implement memory mapped debug components
5834 if (ENABLE_ARCH_7
) {
5835 tmp
= tcg_const_i32(0);
5836 store_reg(s
, rt
, tmp
);
5845 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5846 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5850 tmp
= load_cpu_field(teecr
);
5851 store_reg(s
, rt
, tmp
);
5854 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5856 if (IS_USER(s
) && (env
->teecr
& 1))
5858 tmp
= load_cpu_field(teehbr
);
5859 store_reg(s
, rt
, tmp
);
5863 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5864 op1
, crn
, crm
, op2
);
5868 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5870 int crn
= (insn
>> 16) & 0xf;
5871 int crm
= insn
& 0xf;
5872 int op1
= (insn
>> 21) & 7;
5873 int op2
= (insn
>> 5) & 7;
5874 int rt
= (insn
>> 12) & 0xf;
5877 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5878 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5882 tmp
= load_reg(s
, rt
);
5883 gen_helper_set_teecr(cpu_env
, tmp
);
5884 tcg_temp_free_i32(tmp
);
5887 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5889 if (IS_USER(s
) && (env
->teecr
& 1))
5891 tmp
= load_reg(s
, rt
);
5892 store_cpu_field(tmp
, teehbr
);
5896 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5897 op1
, crn
, crm
, op2
);
5901 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5905 cpnum
= (insn
>> 8) & 0xf;
5906 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
5907 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
5913 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
5914 return disas_iwmmxt_insn(env
, s
, insn
);
5915 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
5916 return disas_dsp_insn(env
, s
, insn
);
5921 return disas_vfp_insn (env
, s
, insn
);
5923 /* Coprocessors 7-15 are architecturally reserved by ARM.
5924 Unfortunately Intel decided to ignore this. */
5925 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
5927 if (insn
& (1 << 20))
5928 return disas_cp14_read(env
, s
, insn
);
5930 return disas_cp14_write(env
, s
, insn
);
5932 return disas_cp15_insn (env
, s
, insn
);
5935 /* Unknown coprocessor. See if the board has hooked it. */
5936 return disas_cp_insn (env
, s
, insn
);
5941 /* Store a 64-bit value to a register pair. Clobbers val. */
5942 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
5945 tmp
= tcg_temp_new_i32();
5946 tcg_gen_trunc_i64_i32(tmp
, val
);
5947 store_reg(s
, rlow
, tmp
);
5948 tmp
= tcg_temp_new_i32();
5949 tcg_gen_shri_i64(val
, val
, 32);
5950 tcg_gen_trunc_i64_i32(tmp
, val
);
5951 store_reg(s
, rhigh
, tmp
);
5954 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5955 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
5960 /* Load value and extend to 64 bits. */
5961 tmp
= tcg_temp_new_i64();
5962 tmp2
= load_reg(s
, rlow
);
5963 tcg_gen_extu_i32_i64(tmp
, tmp2
);
5964 tcg_temp_free_i32(tmp2
);
5965 tcg_gen_add_i64(val
, val
, tmp
);
5966 tcg_temp_free_i64(tmp
);
5969 /* load and add a 64-bit value from a register pair. */
5970 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
5976 /* Load 64-bit value rd:rn. */
5977 tmpl
= load_reg(s
, rlow
);
5978 tmph
= load_reg(s
, rhigh
);
5979 tmp
= tcg_temp_new_i64();
5980 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
5981 tcg_temp_free_i32(tmpl
);
5982 tcg_temp_free_i32(tmph
);
5983 tcg_gen_add_i64(val
, val
, tmp
);
5984 tcg_temp_free_i64(tmp
);
5987 /* Set N and Z flags from a 64-bit value. */
5988 static void gen_logicq_cc(TCGv_i64 val
)
5990 TCGv tmp
= tcg_temp_new_i32();
5991 gen_helper_logicq_cc(tmp
, val
);
5993 tcg_temp_free_i32(tmp
);
5996 /* Load/Store exclusive instructions are implemented by remembering
5997 the value/address loaded, and seeing if these are the same
5998 when the store is performed. This should be is sufficient to implement
5999 the architecturally mandated semantics, and avoids having to monitor
6002 In system emulation mode only one CPU will be running at once, so
6003 this sequence is effectively atomic. In user emulation mode we
6004 throw an exception and handle the atomic operation elsewhere. */
6005 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6006 TCGv addr
, int size
)
6012 tmp
= gen_ld8u(addr
, IS_USER(s
));
6015 tmp
= gen_ld16u(addr
, IS_USER(s
));
6019 tmp
= gen_ld32(addr
, IS_USER(s
));
6024 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6025 store_reg(s
, rt
, tmp
);
6027 TCGv tmp2
= tcg_temp_new_i32();
6028 tcg_gen_addi_i32(tmp2
, addr
, 4);
6029 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6030 tcg_temp_free_i32(tmp2
);
6031 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6032 store_reg(s
, rt2
, tmp
);
6034 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6037 static void gen_clrex(DisasContext
*s
)
6039 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6042 #ifdef CONFIG_USER_ONLY
6043 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6044 TCGv addr
, int size
)
6046 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6047 tcg_gen_movi_i32(cpu_exclusive_info
,
6048 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6049 gen_exception_insn(s
, 4, EXCP_STREX
);
6052 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6053 TCGv addr
, int size
)
6059 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6065 fail_label
= gen_new_label();
6066 done_label
= gen_new_label();
6067 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6070 tmp
= gen_ld8u(addr
, IS_USER(s
));
6073 tmp
= gen_ld16u(addr
, IS_USER(s
));
6077 tmp
= gen_ld32(addr
, IS_USER(s
));
6082 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6083 tcg_temp_free_i32(tmp
);
6085 TCGv tmp2
= tcg_temp_new_i32();
6086 tcg_gen_addi_i32(tmp2
, addr
, 4);
6087 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6088 tcg_temp_free_i32(tmp2
);
6089 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6090 tcg_temp_free_i32(tmp
);
6092 tmp
= load_reg(s
, rt
);
6095 gen_st8(tmp
, addr
, IS_USER(s
));
6098 gen_st16(tmp
, addr
, IS_USER(s
));
6102 gen_st32(tmp
, addr
, IS_USER(s
));
6108 tcg_gen_addi_i32(addr
, addr
, 4);
6109 tmp
= load_reg(s
, rt2
);
6110 gen_st32(tmp
, addr
, IS_USER(s
));
6112 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6113 tcg_gen_br(done_label
);
6114 gen_set_label(fail_label
);
6115 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6116 gen_set_label(done_label
);
6117 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6121 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
6123 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6130 insn
= ldl_code(s
->pc
);
6133 /* M variants do not implement ARM mode. */
6138 /* Unconditional instructions. */
6139 if (((insn
>> 25) & 7) == 1) {
6140 /* NEON Data processing. */
6141 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6144 if (disas_neon_data_insn(env
, s
, insn
))
6148 if ((insn
& 0x0f100000) == 0x04000000) {
6149 /* NEON load/store. */
6150 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6153 if (disas_neon_ls_insn(env
, s
, insn
))
6157 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6158 ((insn
& 0x0f30f010) == 0x0710f000)) {
6159 if ((insn
& (1 << 22)) == 0) {
6161 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6165 /* Otherwise PLD; v5TE+ */
6168 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6169 ((insn
& 0x0f70f010) == 0x0650f000)) {
6171 return; /* PLI; V7 */
6173 if (((insn
& 0x0f700000) == 0x04100000) ||
6174 ((insn
& 0x0f700010) == 0x06100000)) {
6175 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6178 return; /* v7MP: Unallocated memory hint: must NOP */
6181 if ((insn
& 0x0ffffdff) == 0x01010000) {
6184 if (insn
& (1 << 9)) {
6185 /* BE8 mode not implemented. */
6189 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6190 switch ((insn
>> 4) & 0xf) {
6199 /* We don't emulate caches so these are a no-op. */
6204 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6210 op1
= (insn
& 0x1f);
6211 addr
= tcg_temp_new_i32();
6212 tmp
= tcg_const_i32(op1
);
6213 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6214 tcg_temp_free_i32(tmp
);
6215 i
= (insn
>> 23) & 3;
6217 case 0: offset
= -4; break; /* DA */
6218 case 1: offset
= 0; break; /* IA */
6219 case 2: offset
= -8; break; /* DB */
6220 case 3: offset
= 4; break; /* IB */
6224 tcg_gen_addi_i32(addr
, addr
, offset
);
6225 tmp
= load_reg(s
, 14);
6226 gen_st32(tmp
, addr
, 0);
6227 tmp
= load_cpu_field(spsr
);
6228 tcg_gen_addi_i32(addr
, addr
, 4);
6229 gen_st32(tmp
, addr
, 0);
6230 if (insn
& (1 << 21)) {
6231 /* Base writeback. */
6233 case 0: offset
= -8; break;
6234 case 1: offset
= 4; break;
6235 case 2: offset
= -4; break;
6236 case 3: offset
= 0; break;
6240 tcg_gen_addi_i32(addr
, addr
, offset
);
6241 tmp
= tcg_const_i32(op1
);
6242 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6243 tcg_temp_free_i32(tmp
);
6244 tcg_temp_free_i32(addr
);
6246 tcg_temp_free_i32(addr
);
6249 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6255 rn
= (insn
>> 16) & 0xf;
6256 addr
= load_reg(s
, rn
);
6257 i
= (insn
>> 23) & 3;
6259 case 0: offset
= -4; break; /* DA */
6260 case 1: offset
= 0; break; /* IA */
6261 case 2: offset
= -8; break; /* DB */
6262 case 3: offset
= 4; break; /* IB */
6266 tcg_gen_addi_i32(addr
, addr
, offset
);
6267 /* Load PC into tmp and CPSR into tmp2. */
6268 tmp
= gen_ld32(addr
, 0);
6269 tcg_gen_addi_i32(addr
, addr
, 4);
6270 tmp2
= gen_ld32(addr
, 0);
6271 if (insn
& (1 << 21)) {
6272 /* Base writeback. */
6274 case 0: offset
= -8; break;
6275 case 1: offset
= 4; break;
6276 case 2: offset
= -4; break;
6277 case 3: offset
= 0; break;
6281 tcg_gen_addi_i32(addr
, addr
, offset
);
6282 store_reg(s
, rn
, addr
);
6284 tcg_temp_free_i32(addr
);
6286 gen_rfe(s
, tmp
, tmp2
);
6288 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6289 /* branch link and change to thumb (blx <offset>) */
6292 val
= (uint32_t)s
->pc
;
6293 tmp
= tcg_temp_new_i32();
6294 tcg_gen_movi_i32(tmp
, val
);
6295 store_reg(s
, 14, tmp
);
6296 /* Sign-extend the 24-bit offset */
6297 offset
= (((int32_t)insn
) << 8) >> 8;
6298 /* offset * 4 + bit24 * 2 + (thumb bit) */
6299 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6300 /* pipeline offset */
6304 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6305 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6306 /* iWMMXt register transfer. */
6307 if (env
->cp15
.c15_cpar
& (1 << 1))
6308 if (!disas_iwmmxt_insn(env
, s
, insn
))
6311 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6312 /* Coprocessor double register transfer. */
6313 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6314 /* Additional coprocessor register transfer. */
6315 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6318 /* cps (privileged) */
6322 if (insn
& (1 << 19)) {
6323 if (insn
& (1 << 8))
6325 if (insn
& (1 << 7))
6327 if (insn
& (1 << 6))
6329 if (insn
& (1 << 18))
6332 if (insn
& (1 << 17)) {
6334 val
|= (insn
& 0x1f);
6337 gen_set_psr_im(s
, mask
, 0, val
);
6344 /* if not always execute, we generate a conditional jump to
6346 s
->condlabel
= gen_new_label();
6347 gen_test_cc(cond
^ 1, s
->condlabel
);
6350 if ((insn
& 0x0f900000) == 0x03000000) {
6351 if ((insn
& (1 << 21)) == 0) {
6353 rd
= (insn
>> 12) & 0xf;
6354 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6355 if ((insn
& (1 << 22)) == 0) {
6357 tmp
= tcg_temp_new_i32();
6358 tcg_gen_movi_i32(tmp
, val
);
6361 tmp
= load_reg(s
, rd
);
6362 tcg_gen_ext16u_i32(tmp
, tmp
);
6363 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6365 store_reg(s
, rd
, tmp
);
6367 if (((insn
>> 12) & 0xf) != 0xf)
6369 if (((insn
>> 16) & 0xf) == 0) {
6370 gen_nop_hint(s
, insn
& 0xff);
6372 /* CPSR = immediate */
6374 shift
= ((insn
>> 8) & 0xf) * 2;
6376 val
= (val
>> shift
) | (val
<< (32 - shift
));
6377 i
= ((insn
& (1 << 22)) != 0);
6378 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6382 } else if ((insn
& 0x0f900000) == 0x01000000
6383 && (insn
& 0x00000090) != 0x00000090) {
6384 /* miscellaneous instructions */
6385 op1
= (insn
>> 21) & 3;
6386 sh
= (insn
>> 4) & 0xf;
6389 case 0x0: /* move program status register */
6392 tmp
= load_reg(s
, rm
);
6393 i
= ((op1
& 2) != 0);
6394 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6398 rd
= (insn
>> 12) & 0xf;
6402 tmp
= load_cpu_field(spsr
);
6404 tmp
= tcg_temp_new_i32();
6405 gen_helper_cpsr_read(tmp
);
6407 store_reg(s
, rd
, tmp
);
6412 /* branch/exchange thumb (bx). */
6413 tmp
= load_reg(s
, rm
);
6415 } else if (op1
== 3) {
6417 rd
= (insn
>> 12) & 0xf;
6418 tmp
= load_reg(s
, rm
);
6419 gen_helper_clz(tmp
, tmp
);
6420 store_reg(s
, rd
, tmp
);
6428 /* Trivial implementation equivalent to bx. */
6429 tmp
= load_reg(s
, rm
);
6439 /* branch link/exchange thumb (blx) */
6440 tmp
= load_reg(s
, rm
);
6441 tmp2
= tcg_temp_new_i32();
6442 tcg_gen_movi_i32(tmp2
, s
->pc
);
6443 store_reg(s
, 14, tmp2
);
6446 case 0x5: /* saturating add/subtract */
6447 rd
= (insn
>> 12) & 0xf;
6448 rn
= (insn
>> 16) & 0xf;
6449 tmp
= load_reg(s
, rm
);
6450 tmp2
= load_reg(s
, rn
);
6452 gen_helper_double_saturate(tmp2
, tmp2
);
6454 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6456 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6457 tcg_temp_free_i32(tmp2
);
6458 store_reg(s
, rd
, tmp
);
6461 /* SMC instruction (op1 == 3)
6462 and undefined instructions (op1 == 0 || op1 == 2)
6468 gen_exception_insn(s
, 4, EXCP_BKPT
);
6470 case 0x8: /* signed multiply */
6474 rs
= (insn
>> 8) & 0xf;
6475 rn
= (insn
>> 12) & 0xf;
6476 rd
= (insn
>> 16) & 0xf;
6478 /* (32 * 16) >> 16 */
6479 tmp
= load_reg(s
, rm
);
6480 tmp2
= load_reg(s
, rs
);
6482 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6485 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6486 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6487 tmp
= tcg_temp_new_i32();
6488 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6489 tcg_temp_free_i64(tmp64
);
6490 if ((sh
& 2) == 0) {
6491 tmp2
= load_reg(s
, rn
);
6492 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6493 tcg_temp_free_i32(tmp2
);
6495 store_reg(s
, rd
, tmp
);
6498 tmp
= load_reg(s
, rm
);
6499 tmp2
= load_reg(s
, rs
);
6500 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6501 tcg_temp_free_i32(tmp2
);
6503 tmp64
= tcg_temp_new_i64();
6504 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6505 tcg_temp_free_i32(tmp
);
6506 gen_addq(s
, tmp64
, rn
, rd
);
6507 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6508 tcg_temp_free_i64(tmp64
);
6511 tmp2
= load_reg(s
, rn
);
6512 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6513 tcg_temp_free_i32(tmp2
);
6515 store_reg(s
, rd
, tmp
);
6522 } else if (((insn
& 0x0e000000) == 0 &&
6523 (insn
& 0x00000090) != 0x90) ||
6524 ((insn
& 0x0e000000) == (1 << 25))) {
6525 int set_cc
, logic_cc
, shiftop
;
6527 op1
= (insn
>> 21) & 0xf;
6528 set_cc
= (insn
>> 20) & 1;
6529 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6531 /* data processing instruction */
6532 if (insn
& (1 << 25)) {
6533 /* immediate operand */
6535 shift
= ((insn
>> 8) & 0xf) * 2;
6537 val
= (val
>> shift
) | (val
<< (32 - shift
));
6539 tmp2
= tcg_temp_new_i32();
6540 tcg_gen_movi_i32(tmp2
, val
);
6541 if (logic_cc
&& shift
) {
6542 gen_set_CF_bit31(tmp2
);
6547 tmp2
= load_reg(s
, rm
);
6548 shiftop
= (insn
>> 5) & 3;
6549 if (!(insn
& (1 << 4))) {
6550 shift
= (insn
>> 7) & 0x1f;
6551 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6553 rs
= (insn
>> 8) & 0xf;
6554 tmp
= load_reg(s
, rs
);
6555 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6558 if (op1
!= 0x0f && op1
!= 0x0d) {
6559 rn
= (insn
>> 16) & 0xf;
6560 tmp
= load_reg(s
, rn
);
6564 rd
= (insn
>> 12) & 0xf;
6567 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6571 store_reg_bx(env
, s
, rd
, tmp
);
6574 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6578 store_reg_bx(env
, s
, rd
, tmp
);
6581 if (set_cc
&& rd
== 15) {
6582 /* SUBS r15, ... is used for exception return. */
6586 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6587 gen_exception_return(s
, tmp
);
6590 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6592 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6594 store_reg_bx(env
, s
, rd
, tmp
);
6599 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
6601 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6603 store_reg_bx(env
, s
, rd
, tmp
);
6607 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6609 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6611 store_reg_bx(env
, s
, rd
, tmp
);
6615 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
6617 gen_add_carry(tmp
, tmp
, tmp2
);
6619 store_reg_bx(env
, s
, rd
, tmp
);
6623 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
6625 gen_sub_carry(tmp
, tmp
, tmp2
);
6627 store_reg_bx(env
, s
, rd
, tmp
);
6631 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
6633 gen_sub_carry(tmp
, tmp2
, tmp
);
6635 store_reg_bx(env
, s
, rd
, tmp
);
6639 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6642 tcg_temp_free_i32(tmp
);
6646 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6649 tcg_temp_free_i32(tmp
);
6653 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6655 tcg_temp_free_i32(tmp
);
6659 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6661 tcg_temp_free_i32(tmp
);
6664 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6668 store_reg_bx(env
, s
, rd
, tmp
);
6671 if (logic_cc
&& rd
== 15) {
6672 /* MOVS r15, ... is used for exception return. */
6676 gen_exception_return(s
, tmp2
);
6681 store_reg_bx(env
, s
, rd
, tmp2
);
6685 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
6689 store_reg_bx(env
, s
, rd
, tmp
);
6693 tcg_gen_not_i32(tmp2
, tmp2
);
6697 store_reg_bx(env
, s
, rd
, tmp2
);
6700 if (op1
!= 0x0f && op1
!= 0x0d) {
6701 tcg_temp_free_i32(tmp2
);
6704 /* other instructions */
6705 op1
= (insn
>> 24) & 0xf;
6709 /* multiplies, extra load/stores */
6710 sh
= (insn
>> 5) & 3;
6713 rd
= (insn
>> 16) & 0xf;
6714 rn
= (insn
>> 12) & 0xf;
6715 rs
= (insn
>> 8) & 0xf;
6717 op1
= (insn
>> 20) & 0xf;
6719 case 0: case 1: case 2: case 3: case 6:
6721 tmp
= load_reg(s
, rs
);
6722 tmp2
= load_reg(s
, rm
);
6723 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
6724 tcg_temp_free_i32(tmp2
);
6725 if (insn
& (1 << 22)) {
6726 /* Subtract (mls) */
6728 tmp2
= load_reg(s
, rn
);
6729 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6730 tcg_temp_free_i32(tmp2
);
6731 } else if (insn
& (1 << 21)) {
6733 tmp2
= load_reg(s
, rn
);
6734 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6735 tcg_temp_free_i32(tmp2
);
6737 if (insn
& (1 << 20))
6739 store_reg(s
, rd
, tmp
);
6742 /* 64 bit mul double accumulate (UMAAL) */
6744 tmp
= load_reg(s
, rs
);
6745 tmp2
= load_reg(s
, rm
);
6746 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6747 gen_addq_lo(s
, tmp64
, rn
);
6748 gen_addq_lo(s
, tmp64
, rd
);
6749 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6750 tcg_temp_free_i64(tmp64
);
6752 case 8: case 9: case 10: case 11:
6753 case 12: case 13: case 14: case 15:
6754 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6755 tmp
= load_reg(s
, rs
);
6756 tmp2
= load_reg(s
, rm
);
6757 if (insn
& (1 << 22)) {
6758 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6760 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6762 if (insn
& (1 << 21)) { /* mult accumulate */
6763 gen_addq(s
, tmp64
, rn
, rd
);
6765 if (insn
& (1 << 20)) {
6766 gen_logicq_cc(tmp64
);
6768 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6769 tcg_temp_free_i64(tmp64
);
6775 rn
= (insn
>> 16) & 0xf;
6776 rd
= (insn
>> 12) & 0xf;
6777 if (insn
& (1 << 23)) {
6778 /* load/store exclusive */
6779 op1
= (insn
>> 21) & 0x3;
6784 addr
= tcg_temp_local_new_i32();
6785 load_reg_var(s
, addr
, rn
);
6786 if (insn
& (1 << 20)) {
6789 gen_load_exclusive(s
, rd
, 15, addr
, 2);
6791 case 1: /* ldrexd */
6792 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
6794 case 2: /* ldrexb */
6795 gen_load_exclusive(s
, rd
, 15, addr
, 0);
6797 case 3: /* ldrexh */
6798 gen_load_exclusive(s
, rd
, 15, addr
, 1);
6807 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
6809 case 1: /* strexd */
6810 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
6812 case 2: /* strexb */
6813 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
6815 case 3: /* strexh */
6816 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
6822 tcg_temp_free(addr
);
6824 /* SWP instruction */
6827 /* ??? This is not really atomic. However we know
6828 we never have multiple CPUs running in parallel,
6829 so it is good enough. */
6830 addr
= load_reg(s
, rn
);
6831 tmp
= load_reg(s
, rm
);
6832 if (insn
& (1 << 22)) {
6833 tmp2
= gen_ld8u(addr
, IS_USER(s
));
6834 gen_st8(tmp
, addr
, IS_USER(s
));
6836 tmp2
= gen_ld32(addr
, IS_USER(s
));
6837 gen_st32(tmp
, addr
, IS_USER(s
));
6839 tcg_temp_free_i32(addr
);
6840 store_reg(s
, rd
, tmp2
);
6846 /* Misc load/store */
6847 rn
= (insn
>> 16) & 0xf;
6848 rd
= (insn
>> 12) & 0xf;
6849 addr
= load_reg(s
, rn
);
6850 if (insn
& (1 << 24))
6851 gen_add_datah_offset(s
, insn
, 0, addr
);
6853 if (insn
& (1 << 20)) {
6857 tmp
= gen_ld16u(addr
, IS_USER(s
));
6860 tmp
= gen_ld8s(addr
, IS_USER(s
));
6864 tmp
= gen_ld16s(addr
, IS_USER(s
));
6868 } else if (sh
& 2) {
6872 tmp
= load_reg(s
, rd
);
6873 gen_st32(tmp
, addr
, IS_USER(s
));
6874 tcg_gen_addi_i32(addr
, addr
, 4);
6875 tmp
= load_reg(s
, rd
+ 1);
6876 gen_st32(tmp
, addr
, IS_USER(s
));
6880 tmp
= gen_ld32(addr
, IS_USER(s
));
6881 store_reg(s
, rd
, tmp
);
6882 tcg_gen_addi_i32(addr
, addr
, 4);
6883 tmp
= gen_ld32(addr
, IS_USER(s
));
6887 address_offset
= -4;
6890 tmp
= load_reg(s
, rd
);
6891 gen_st16(tmp
, addr
, IS_USER(s
));
6894 /* Perform base writeback before the loaded value to
6895 ensure correct behavior with overlapping index registers.
6896 ldrd with base writeback is is undefined if the
6897 destination and index registers overlap. */
6898 if (!(insn
& (1 << 24))) {
6899 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
6900 store_reg(s
, rn
, addr
);
6901 } else if (insn
& (1 << 21)) {
6903 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6904 store_reg(s
, rn
, addr
);
6906 tcg_temp_free_i32(addr
);
6909 /* Complete the load. */
6910 store_reg(s
, rd
, tmp
);
6919 if (insn
& (1 << 4)) {
6921 /* Armv6 Media instructions. */
6923 rn
= (insn
>> 16) & 0xf;
6924 rd
= (insn
>> 12) & 0xf;
6925 rs
= (insn
>> 8) & 0xf;
6926 switch ((insn
>> 23) & 3) {
6927 case 0: /* Parallel add/subtract. */
6928 op1
= (insn
>> 20) & 7;
6929 tmp
= load_reg(s
, rn
);
6930 tmp2
= load_reg(s
, rm
);
6931 sh
= (insn
>> 5) & 7;
6932 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
6934 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
6935 tcg_temp_free_i32(tmp2
);
6936 store_reg(s
, rd
, tmp
);
6939 if ((insn
& 0x00700020) == 0) {
6940 /* Halfword pack. */
6941 tmp
= load_reg(s
, rn
);
6942 tmp2
= load_reg(s
, rm
);
6943 shift
= (insn
>> 7) & 0x1f;
6944 if (insn
& (1 << 6)) {
6948 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
6949 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
6950 tcg_gen_ext16u_i32(tmp2
, tmp2
);
6954 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
6955 tcg_gen_ext16u_i32(tmp
, tmp
);
6956 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
6958 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6959 tcg_temp_free_i32(tmp2
);
6960 store_reg(s
, rd
, tmp
);
6961 } else if ((insn
& 0x00200020) == 0x00200000) {
6963 tmp
= load_reg(s
, rm
);
6964 shift
= (insn
>> 7) & 0x1f;
6965 if (insn
& (1 << 6)) {
6968 tcg_gen_sari_i32(tmp
, tmp
, shift
);
6970 tcg_gen_shli_i32(tmp
, tmp
, shift
);
6972 sh
= (insn
>> 16) & 0x1f;
6973 tmp2
= tcg_const_i32(sh
);
6974 if (insn
& (1 << 22))
6975 gen_helper_usat(tmp
, tmp
, tmp2
);
6977 gen_helper_ssat(tmp
, tmp
, tmp2
);
6978 tcg_temp_free_i32(tmp2
);
6979 store_reg(s
, rd
, tmp
);
6980 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
6982 tmp
= load_reg(s
, rm
);
6983 sh
= (insn
>> 16) & 0x1f;
6984 tmp2
= tcg_const_i32(sh
);
6985 if (insn
& (1 << 22))
6986 gen_helper_usat16(tmp
, tmp
, tmp2
);
6988 gen_helper_ssat16(tmp
, tmp
, tmp2
);
6989 tcg_temp_free_i32(tmp2
);
6990 store_reg(s
, rd
, tmp
);
6991 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
6993 tmp
= load_reg(s
, rn
);
6994 tmp2
= load_reg(s
, rm
);
6995 tmp3
= tcg_temp_new_i32();
6996 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
6997 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
6998 tcg_temp_free_i32(tmp3
);
6999 tcg_temp_free_i32(tmp2
);
7000 store_reg(s
, rd
, tmp
);
7001 } else if ((insn
& 0x000003e0) == 0x00000060) {
7002 tmp
= load_reg(s
, rm
);
7003 shift
= (insn
>> 10) & 3;
7004 /* ??? In many cases it's not neccessary to do a
7005 rotate, a shift is sufficient. */
7007 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7008 op1
= (insn
>> 20) & 7;
7010 case 0: gen_sxtb16(tmp
); break;
7011 case 2: gen_sxtb(tmp
); break;
7012 case 3: gen_sxth(tmp
); break;
7013 case 4: gen_uxtb16(tmp
); break;
7014 case 6: gen_uxtb(tmp
); break;
7015 case 7: gen_uxth(tmp
); break;
7016 default: goto illegal_op
;
7019 tmp2
= load_reg(s
, rn
);
7020 if ((op1
& 3) == 0) {
7021 gen_add16(tmp
, tmp2
);
7023 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7024 tcg_temp_free_i32(tmp2
);
7027 store_reg(s
, rd
, tmp
);
7028 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7030 tmp
= load_reg(s
, rm
);
7031 if (insn
& (1 << 22)) {
7032 if (insn
& (1 << 7)) {
7036 gen_helper_rbit(tmp
, tmp
);
7039 if (insn
& (1 << 7))
7042 tcg_gen_bswap32_i32(tmp
, tmp
);
7044 store_reg(s
, rd
, tmp
);
7049 case 2: /* Multiplies (Type 3). */
7050 tmp
= load_reg(s
, rm
);
7051 tmp2
= load_reg(s
, rs
);
7052 if (insn
& (1 << 20)) {
7053 /* Signed multiply most significant [accumulate].
7054 (SMMUL, SMMLA, SMMLS) */
7055 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7058 tmp
= load_reg(s
, rd
);
7059 if (insn
& (1 << 6)) {
7060 tmp64
= gen_subq_msw(tmp64
, tmp
);
7062 tmp64
= gen_addq_msw(tmp64
, tmp
);
7065 if (insn
& (1 << 5)) {
7066 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7068 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7069 tmp
= tcg_temp_new_i32();
7070 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7071 tcg_temp_free_i64(tmp64
);
7072 store_reg(s
, rn
, tmp
);
7074 if (insn
& (1 << 5))
7075 gen_swap_half(tmp2
);
7076 gen_smul_dual(tmp
, tmp2
);
7077 if (insn
& (1 << 6)) {
7078 /* This subtraction cannot overflow. */
7079 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7081 /* This addition cannot overflow 32 bits;
7082 * however it may overflow considered as a signed
7083 * operation, in which case we must set the Q flag.
7085 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7087 tcg_temp_free_i32(tmp2
);
7088 if (insn
& (1 << 22)) {
7089 /* smlald, smlsld */
7090 tmp64
= tcg_temp_new_i64();
7091 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7092 tcg_temp_free_i32(tmp
);
7093 gen_addq(s
, tmp64
, rd
, rn
);
7094 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7095 tcg_temp_free_i64(tmp64
);
7097 /* smuad, smusd, smlad, smlsd */
7100 tmp2
= load_reg(s
, rd
);
7101 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7102 tcg_temp_free_i32(tmp2
);
7104 store_reg(s
, rn
, tmp
);
7109 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7111 case 0: /* Unsigned sum of absolute differences. */
7113 tmp
= load_reg(s
, rm
);
7114 tmp2
= load_reg(s
, rs
);
7115 gen_helper_usad8(tmp
, tmp
, tmp2
);
7116 tcg_temp_free_i32(tmp2
);
7118 tmp2
= load_reg(s
, rd
);
7119 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7120 tcg_temp_free_i32(tmp2
);
7122 store_reg(s
, rn
, tmp
);
7124 case 0x20: case 0x24: case 0x28: case 0x2c:
7125 /* Bitfield insert/clear. */
7127 shift
= (insn
>> 7) & 0x1f;
7128 i
= (insn
>> 16) & 0x1f;
7131 tmp
= tcg_temp_new_i32();
7132 tcg_gen_movi_i32(tmp
, 0);
7134 tmp
= load_reg(s
, rm
);
7137 tmp2
= load_reg(s
, rd
);
7138 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7139 tcg_temp_free_i32(tmp2
);
7141 store_reg(s
, rd
, tmp
);
7143 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7144 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7146 tmp
= load_reg(s
, rm
);
7147 shift
= (insn
>> 7) & 0x1f;
7148 i
= ((insn
>> 16) & 0x1f) + 1;
7153 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7155 gen_sbfx(tmp
, shift
, i
);
7158 store_reg(s
, rd
, tmp
);
7168 /* Check for undefined extension instructions
7169 * per the ARM Bible IE:
7170 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7172 sh
= (0xf << 20) | (0xf << 4);
7173 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7177 /* load/store byte/word */
7178 rn
= (insn
>> 16) & 0xf;
7179 rd
= (insn
>> 12) & 0xf;
7180 tmp2
= load_reg(s
, rn
);
7181 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7182 if (insn
& (1 << 24))
7183 gen_add_data_offset(s
, insn
, tmp2
);
7184 if (insn
& (1 << 20)) {
7186 if (insn
& (1 << 22)) {
7187 tmp
= gen_ld8u(tmp2
, i
);
7189 tmp
= gen_ld32(tmp2
, i
);
7193 tmp
= load_reg(s
, rd
);
7194 if (insn
& (1 << 22))
7195 gen_st8(tmp
, tmp2
, i
);
7197 gen_st32(tmp
, tmp2
, i
);
7199 if (!(insn
& (1 << 24))) {
7200 gen_add_data_offset(s
, insn
, tmp2
);
7201 store_reg(s
, rn
, tmp2
);
7202 } else if (insn
& (1 << 21)) {
7203 store_reg(s
, rn
, tmp2
);
7205 tcg_temp_free_i32(tmp2
);
7207 if (insn
& (1 << 20)) {
7208 /* Complete the load. */
7212 store_reg(s
, rd
, tmp
);
7218 int j
, n
, user
, loaded_base
;
7220 /* load/store multiple words */
7221 /* XXX: store correct base if write back */
7223 if (insn
& (1 << 22)) {
7225 goto illegal_op
; /* only usable in supervisor mode */
7227 if ((insn
& (1 << 15)) == 0)
7230 rn
= (insn
>> 16) & 0xf;
7231 addr
= load_reg(s
, rn
);
7233 /* compute total size */
7235 TCGV_UNUSED(loaded_var
);
7238 if (insn
& (1 << i
))
7241 /* XXX: test invalid n == 0 case ? */
7242 if (insn
& (1 << 23)) {
7243 if (insn
& (1 << 24)) {
7245 tcg_gen_addi_i32(addr
, addr
, 4);
7247 /* post increment */
7250 if (insn
& (1 << 24)) {
7252 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7254 /* post decrement */
7256 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7261 if (insn
& (1 << i
)) {
7262 if (insn
& (1 << 20)) {
7264 tmp
= gen_ld32(addr
, IS_USER(s
));
7268 tmp2
= tcg_const_i32(i
);
7269 gen_helper_set_user_reg(tmp2
, tmp
);
7270 tcg_temp_free_i32(tmp2
);
7271 tcg_temp_free_i32(tmp
);
7272 } else if (i
== rn
) {
7276 store_reg(s
, i
, tmp
);
7281 /* special case: r15 = PC + 8 */
7282 val
= (long)s
->pc
+ 4;
7283 tmp
= tcg_temp_new_i32();
7284 tcg_gen_movi_i32(tmp
, val
);
7286 tmp
= tcg_temp_new_i32();
7287 tmp2
= tcg_const_i32(i
);
7288 gen_helper_get_user_reg(tmp
, tmp2
);
7289 tcg_temp_free_i32(tmp2
);
7291 tmp
= load_reg(s
, i
);
7293 gen_st32(tmp
, addr
, IS_USER(s
));
7296 /* no need to add after the last transfer */
7298 tcg_gen_addi_i32(addr
, addr
, 4);
7301 if (insn
& (1 << 21)) {
7303 if (insn
& (1 << 23)) {
7304 if (insn
& (1 << 24)) {
7307 /* post increment */
7308 tcg_gen_addi_i32(addr
, addr
, 4);
7311 if (insn
& (1 << 24)) {
7314 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7316 /* post decrement */
7317 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7320 store_reg(s
, rn
, addr
);
7322 tcg_temp_free_i32(addr
);
7325 store_reg(s
, rn
, loaded_var
);
7327 if ((insn
& (1 << 22)) && !user
) {
7328 /* Restore CPSR from SPSR. */
7329 tmp
= load_cpu_field(spsr
);
7330 gen_set_cpsr(tmp
, 0xffffffff);
7331 tcg_temp_free_i32(tmp
);
7332 s
->is_jmp
= DISAS_UPDATE
;
7341 /* branch (and link) */
7342 val
= (int32_t)s
->pc
;
7343 if (insn
& (1 << 24)) {
7344 tmp
= tcg_temp_new_i32();
7345 tcg_gen_movi_i32(tmp
, val
);
7346 store_reg(s
, 14, tmp
);
7348 offset
= (((int32_t)insn
<< 8) >> 8);
7349 val
+= (offset
<< 2) + 4;
7357 if (disas_coproc_insn(env
, s
, insn
))
7362 gen_set_pc_im(s
->pc
);
7363 s
->is_jmp
= DISAS_SWI
;
7367 gen_exception_insn(s
, 4, EXCP_UDEF
);
7373 /* Return true if this is a Thumb-2 logical op. */
7375 thumb2_logic_op(int op
)
7380 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7381 then set condition code flags based on the result of the operation.
7382 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7383 to the high bit of T1.
7384 Returns zero if the opcode is valid. */
7387 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7394 tcg_gen_and_i32(t0
, t0
, t1
);
7398 tcg_gen_andc_i32(t0
, t0
, t1
);
7402 tcg_gen_or_i32(t0
, t0
, t1
);
7406 tcg_gen_orc_i32(t0
, t0
, t1
);
7410 tcg_gen_xor_i32(t0
, t0
, t1
);
7415 gen_helper_add_cc(t0
, t0
, t1
);
7417 tcg_gen_add_i32(t0
, t0
, t1
);
7421 gen_helper_adc_cc(t0
, t0
, t1
);
7427 gen_helper_sbc_cc(t0
, t0
, t1
);
7429 gen_sub_carry(t0
, t0
, t1
);
7433 gen_helper_sub_cc(t0
, t0
, t1
);
7435 tcg_gen_sub_i32(t0
, t0
, t1
);
7439 gen_helper_sub_cc(t0
, t1
, t0
);
7441 tcg_gen_sub_i32(t0
, t1
, t0
);
7443 default: /* 5, 6, 7, 9, 12, 15. */
7449 gen_set_CF_bit31(t1
);
7454 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7456 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7458 uint32_t insn
, imm
, shift
, offset
;
7459 uint32_t rd
, rn
, rm
, rs
;
7470 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7471 || arm_feature (env
, ARM_FEATURE_M
))) {
7472 /* Thumb-1 cores may need to treat bl and blx as a pair of
7473 16-bit instructions to get correct prefetch abort behavior. */
7475 if ((insn
& (1 << 12)) == 0) {
7476 /* Second half of blx. */
7477 offset
= ((insn
& 0x7ff) << 1);
7478 tmp
= load_reg(s
, 14);
7479 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7480 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7482 tmp2
= tcg_temp_new_i32();
7483 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7484 store_reg(s
, 14, tmp2
);
7488 if (insn
& (1 << 11)) {
7489 /* Second half of bl. */
7490 offset
= ((insn
& 0x7ff) << 1) | 1;
7491 tmp
= load_reg(s
, 14);
7492 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7494 tmp2
= tcg_temp_new_i32();
7495 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7496 store_reg(s
, 14, tmp2
);
7500 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7501 /* Instruction spans a page boundary. Implement it as two
7502 16-bit instructions in case the second half causes an
7504 offset
= ((int32_t)insn
<< 21) >> 9;
7505 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7508 /* Fall through to 32-bit decode. */
7511 insn
= lduw_code(s
->pc
);
7513 insn
|= (uint32_t)insn_hw1
<< 16;
7515 if ((insn
& 0xf800e800) != 0xf000e800) {
7519 rn
= (insn
>> 16) & 0xf;
7520 rs
= (insn
>> 12) & 0xf;
7521 rd
= (insn
>> 8) & 0xf;
7523 switch ((insn
>> 25) & 0xf) {
7524 case 0: case 1: case 2: case 3:
7525 /* 16-bit instructions. Should never happen. */
7528 if (insn
& (1 << 22)) {
7529 /* Other load/store, table branch. */
7530 if (insn
& 0x01200000) {
7531 /* Load/store doubleword. */
7533 addr
= tcg_temp_new_i32();
7534 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7536 addr
= load_reg(s
, rn
);
7538 offset
= (insn
& 0xff) * 4;
7539 if ((insn
& (1 << 23)) == 0)
7541 if (insn
& (1 << 24)) {
7542 tcg_gen_addi_i32(addr
, addr
, offset
);
7545 if (insn
& (1 << 20)) {
7547 tmp
= gen_ld32(addr
, IS_USER(s
));
7548 store_reg(s
, rs
, tmp
);
7549 tcg_gen_addi_i32(addr
, addr
, 4);
7550 tmp
= gen_ld32(addr
, IS_USER(s
));
7551 store_reg(s
, rd
, tmp
);
7554 tmp
= load_reg(s
, rs
);
7555 gen_st32(tmp
, addr
, IS_USER(s
));
7556 tcg_gen_addi_i32(addr
, addr
, 4);
7557 tmp
= load_reg(s
, rd
);
7558 gen_st32(tmp
, addr
, IS_USER(s
));
7560 if (insn
& (1 << 21)) {
7561 /* Base writeback. */
7564 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
7565 store_reg(s
, rn
, addr
);
7567 tcg_temp_free_i32(addr
);
7569 } else if ((insn
& (1 << 23)) == 0) {
7570 /* Load/store exclusive word. */
7571 addr
= tcg_temp_local_new();
7572 load_reg_var(s
, addr
, rn
);
7573 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
7574 if (insn
& (1 << 20)) {
7575 gen_load_exclusive(s
, rs
, 15, addr
, 2);
7577 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
7579 tcg_temp_free(addr
);
7580 } else if ((insn
& (1 << 6)) == 0) {
7583 addr
= tcg_temp_new_i32();
7584 tcg_gen_movi_i32(addr
, s
->pc
);
7586 addr
= load_reg(s
, rn
);
7588 tmp
= load_reg(s
, rm
);
7589 tcg_gen_add_i32(addr
, addr
, tmp
);
7590 if (insn
& (1 << 4)) {
7592 tcg_gen_add_i32(addr
, addr
, tmp
);
7593 tcg_temp_free_i32(tmp
);
7594 tmp
= gen_ld16u(addr
, IS_USER(s
));
7596 tcg_temp_free_i32(tmp
);
7597 tmp
= gen_ld8u(addr
, IS_USER(s
));
7599 tcg_temp_free_i32(addr
);
7600 tcg_gen_shli_i32(tmp
, tmp
, 1);
7601 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
7602 store_reg(s
, 15, tmp
);
7604 /* Load/store exclusive byte/halfword/doubleword. */
7606 op
= (insn
>> 4) & 0x3;
7610 addr
= tcg_temp_local_new();
7611 load_reg_var(s
, addr
, rn
);
7612 if (insn
& (1 << 20)) {
7613 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
7615 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
7617 tcg_temp_free(addr
);
7620 /* Load/store multiple, RFE, SRS. */
7621 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
7622 /* Not available in user mode. */
7625 if (insn
& (1 << 20)) {
7627 addr
= load_reg(s
, rn
);
7628 if ((insn
& (1 << 24)) == 0)
7629 tcg_gen_addi_i32(addr
, addr
, -8);
7630 /* Load PC into tmp and CPSR into tmp2. */
7631 tmp
= gen_ld32(addr
, 0);
7632 tcg_gen_addi_i32(addr
, addr
, 4);
7633 tmp2
= gen_ld32(addr
, 0);
7634 if (insn
& (1 << 21)) {
7635 /* Base writeback. */
7636 if (insn
& (1 << 24)) {
7637 tcg_gen_addi_i32(addr
, addr
, 4);
7639 tcg_gen_addi_i32(addr
, addr
, -4);
7641 store_reg(s
, rn
, addr
);
7643 tcg_temp_free_i32(addr
);
7645 gen_rfe(s
, tmp
, tmp2
);
7649 addr
= tcg_temp_new_i32();
7650 tmp
= tcg_const_i32(op
);
7651 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7652 tcg_temp_free_i32(tmp
);
7653 if ((insn
& (1 << 24)) == 0) {
7654 tcg_gen_addi_i32(addr
, addr
, -8);
7656 tmp
= load_reg(s
, 14);
7657 gen_st32(tmp
, addr
, 0);
7658 tcg_gen_addi_i32(addr
, addr
, 4);
7659 tmp
= tcg_temp_new_i32();
7660 gen_helper_cpsr_read(tmp
);
7661 gen_st32(tmp
, addr
, 0);
7662 if (insn
& (1 << 21)) {
7663 if ((insn
& (1 << 24)) == 0) {
7664 tcg_gen_addi_i32(addr
, addr
, -4);
7666 tcg_gen_addi_i32(addr
, addr
, 4);
7668 tmp
= tcg_const_i32(op
);
7669 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7670 tcg_temp_free_i32(tmp
);
7672 tcg_temp_free_i32(addr
);
7677 /* Load/store multiple. */
7678 addr
= load_reg(s
, rn
);
7680 for (i
= 0; i
< 16; i
++) {
7681 if (insn
& (1 << i
))
7684 if (insn
& (1 << 24)) {
7685 tcg_gen_addi_i32(addr
, addr
, -offset
);
7688 for (i
= 0; i
< 16; i
++) {
7689 if ((insn
& (1 << i
)) == 0)
7691 if (insn
& (1 << 20)) {
7693 tmp
= gen_ld32(addr
, IS_USER(s
));
7697 store_reg(s
, i
, tmp
);
7701 tmp
= load_reg(s
, i
);
7702 gen_st32(tmp
, addr
, IS_USER(s
));
7704 tcg_gen_addi_i32(addr
, addr
, 4);
7706 if (insn
& (1 << 21)) {
7707 /* Base register writeback. */
7708 if (insn
& (1 << 24)) {
7709 tcg_gen_addi_i32(addr
, addr
, -offset
);
7711 /* Fault if writeback register is in register list. */
7712 if (insn
& (1 << rn
))
7714 store_reg(s
, rn
, addr
);
7716 tcg_temp_free_i32(addr
);
7723 op
= (insn
>> 21) & 0xf;
7725 /* Halfword pack. */
7726 tmp
= load_reg(s
, rn
);
7727 tmp2
= load_reg(s
, rm
);
7728 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
7729 if (insn
& (1 << 5)) {
7733 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7734 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7735 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7739 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7740 tcg_gen_ext16u_i32(tmp
, tmp
);
7741 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7743 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7744 tcg_temp_free_i32(tmp2
);
7745 store_reg(s
, rd
, tmp
);
7747 /* Data processing register constant shift. */
7749 tmp
= tcg_temp_new_i32();
7750 tcg_gen_movi_i32(tmp
, 0);
7752 tmp
= load_reg(s
, rn
);
7754 tmp2
= load_reg(s
, rm
);
7756 shiftop
= (insn
>> 4) & 3;
7757 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
7758 conds
= (insn
& (1 << 20)) != 0;
7759 logic_cc
= (conds
&& thumb2_logic_op(op
));
7760 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7761 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
7763 tcg_temp_free_i32(tmp2
);
7765 store_reg(s
, rd
, tmp
);
7767 tcg_temp_free_i32(tmp
);
7771 case 13: /* Misc data processing. */
7772 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
7773 if (op
< 4 && (insn
& 0xf000) != 0xf000)
7776 case 0: /* Register controlled shift. */
7777 tmp
= load_reg(s
, rn
);
7778 tmp2
= load_reg(s
, rm
);
7779 if ((insn
& 0x70) != 0)
7781 op
= (insn
>> 21) & 3;
7782 logic_cc
= (insn
& (1 << 20)) != 0;
7783 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
7786 store_reg_bx(env
, s
, rd
, tmp
);
7788 case 1: /* Sign/zero extend. */
7789 tmp
= load_reg(s
, rm
);
7790 shift
= (insn
>> 4) & 3;
7791 /* ??? In many cases it's not neccessary to do a
7792 rotate, a shift is sufficient. */
7794 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7795 op
= (insn
>> 20) & 7;
7797 case 0: gen_sxth(tmp
); break;
7798 case 1: gen_uxth(tmp
); break;
7799 case 2: gen_sxtb16(tmp
); break;
7800 case 3: gen_uxtb16(tmp
); break;
7801 case 4: gen_sxtb(tmp
); break;
7802 case 5: gen_uxtb(tmp
); break;
7803 default: goto illegal_op
;
7806 tmp2
= load_reg(s
, rn
);
7807 if ((op
>> 1) == 1) {
7808 gen_add16(tmp
, tmp2
);
7810 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7811 tcg_temp_free_i32(tmp2
);
7814 store_reg(s
, rd
, tmp
);
7816 case 2: /* SIMD add/subtract. */
7817 op
= (insn
>> 20) & 7;
7818 shift
= (insn
>> 4) & 7;
7819 if ((op
& 3) == 3 || (shift
& 3) == 3)
7821 tmp
= load_reg(s
, rn
);
7822 tmp2
= load_reg(s
, rm
);
7823 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
7824 tcg_temp_free_i32(tmp2
);
7825 store_reg(s
, rd
, tmp
);
7827 case 3: /* Other data processing. */
7828 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
7830 /* Saturating add/subtract. */
7831 tmp
= load_reg(s
, rn
);
7832 tmp2
= load_reg(s
, rm
);
7834 gen_helper_double_saturate(tmp
, tmp
);
7836 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
7838 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
7839 tcg_temp_free_i32(tmp2
);
7841 tmp
= load_reg(s
, rn
);
7843 case 0x0a: /* rbit */
7844 gen_helper_rbit(tmp
, tmp
);
7846 case 0x08: /* rev */
7847 tcg_gen_bswap32_i32(tmp
, tmp
);
7849 case 0x09: /* rev16 */
7852 case 0x0b: /* revsh */
7855 case 0x10: /* sel */
7856 tmp2
= load_reg(s
, rm
);
7857 tmp3
= tcg_temp_new_i32();
7858 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7859 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7860 tcg_temp_free_i32(tmp3
);
7861 tcg_temp_free_i32(tmp2
);
7863 case 0x18: /* clz */
7864 gen_helper_clz(tmp
, tmp
);
7870 store_reg(s
, rd
, tmp
);
7872 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7873 op
= (insn
>> 4) & 0xf;
7874 tmp
= load_reg(s
, rn
);
7875 tmp2
= load_reg(s
, rm
);
7876 switch ((insn
>> 20) & 7) {
7877 case 0: /* 32 x 32 -> 32 */
7878 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7879 tcg_temp_free_i32(tmp2
);
7881 tmp2
= load_reg(s
, rs
);
7883 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7885 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7886 tcg_temp_free_i32(tmp2
);
7889 case 1: /* 16 x 16 -> 32 */
7890 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7891 tcg_temp_free_i32(tmp2
);
7893 tmp2
= load_reg(s
, rs
);
7894 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7895 tcg_temp_free_i32(tmp2
);
7898 case 2: /* Dual multiply add. */
7899 case 4: /* Dual multiply subtract. */
7901 gen_swap_half(tmp2
);
7902 gen_smul_dual(tmp
, tmp2
);
7903 if (insn
& (1 << 22)) {
7904 /* This subtraction cannot overflow. */
7905 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7907 /* This addition cannot overflow 32 bits;
7908 * however it may overflow considered as a signed
7909 * operation, in which case we must set the Q flag.
7911 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7913 tcg_temp_free_i32(tmp2
);
7916 tmp2
= load_reg(s
, rs
);
7917 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7918 tcg_temp_free_i32(tmp2
);
7921 case 3: /* 32 * 16 -> 32msb */
7923 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7926 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7927 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7928 tmp
= tcg_temp_new_i32();
7929 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7930 tcg_temp_free_i64(tmp64
);
7933 tmp2
= load_reg(s
, rs
);
7934 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7935 tcg_temp_free_i32(tmp2
);
7938 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7939 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7941 tmp
= load_reg(s
, rs
);
7942 if (insn
& (1 << 20)) {
7943 tmp64
= gen_addq_msw(tmp64
, tmp
);
7945 tmp64
= gen_subq_msw(tmp64
, tmp
);
7948 if (insn
& (1 << 4)) {
7949 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7951 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7952 tmp
= tcg_temp_new_i32();
7953 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7954 tcg_temp_free_i64(tmp64
);
7956 case 7: /* Unsigned sum of absolute differences. */
7957 gen_helper_usad8(tmp
, tmp
, tmp2
);
7958 tcg_temp_free_i32(tmp2
);
7960 tmp2
= load_reg(s
, rs
);
7961 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7962 tcg_temp_free_i32(tmp2
);
7966 store_reg(s
, rd
, tmp
);
7968 case 6: case 7: /* 64-bit multiply, Divide. */
7969 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
7970 tmp
= load_reg(s
, rn
);
7971 tmp2
= load_reg(s
, rm
);
7972 if ((op
& 0x50) == 0x10) {
7974 if (!arm_feature(env
, ARM_FEATURE_DIV
))
7977 gen_helper_udiv(tmp
, tmp
, tmp2
);
7979 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7980 tcg_temp_free_i32(tmp2
);
7981 store_reg(s
, rd
, tmp
);
7982 } else if ((op
& 0xe) == 0xc) {
7983 /* Dual multiply accumulate long. */
7985 gen_swap_half(tmp2
);
7986 gen_smul_dual(tmp
, tmp2
);
7988 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7990 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7992 tcg_temp_free_i32(tmp2
);
7994 tmp64
= tcg_temp_new_i64();
7995 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7996 tcg_temp_free_i32(tmp
);
7997 gen_addq(s
, tmp64
, rs
, rd
);
7998 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7999 tcg_temp_free_i64(tmp64
);
8002 /* Unsigned 64-bit multiply */
8003 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8007 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8008 tcg_temp_free_i32(tmp2
);
8009 tmp64
= tcg_temp_new_i64();
8010 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8011 tcg_temp_free_i32(tmp
);
8013 /* Signed 64-bit multiply */
8014 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8019 gen_addq_lo(s
, tmp64
, rs
);
8020 gen_addq_lo(s
, tmp64
, rd
);
8021 } else if (op
& 0x40) {
8022 /* 64-bit accumulate. */
8023 gen_addq(s
, tmp64
, rs
, rd
);
8025 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8026 tcg_temp_free_i64(tmp64
);
8031 case 6: case 7: case 14: case 15:
8033 if (((insn
>> 24) & 3) == 3) {
8034 /* Translate into the equivalent ARM encoding. */
8035 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8036 if (disas_neon_data_insn(env
, s
, insn
))
8039 if (insn
& (1 << 28))
8041 if (disas_coproc_insn (env
, s
, insn
))
8045 case 8: case 9: case 10: case 11:
8046 if (insn
& (1 << 15)) {
8047 /* Branches, misc control. */
8048 if (insn
& 0x5000) {
8049 /* Unconditional branch. */
8050 /* signextend(hw1[10:0]) -> offset[:12]. */
8051 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8052 /* hw1[10:0] -> offset[11:1]. */
8053 offset
|= (insn
& 0x7ff) << 1;
8054 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8055 offset[24:22] already have the same value because of the
8056 sign extension above. */
8057 offset
^= ((~insn
) & (1 << 13)) << 10;
8058 offset
^= ((~insn
) & (1 << 11)) << 11;
8060 if (insn
& (1 << 14)) {
8061 /* Branch and link. */
8062 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8066 if (insn
& (1 << 12)) {
8071 offset
&= ~(uint32_t)2;
8072 gen_bx_im(s
, offset
);
8074 } else if (((insn
>> 23) & 7) == 7) {
8076 if (insn
& (1 << 13))
8079 if (insn
& (1 << 26)) {
8080 /* Secure monitor call (v6Z) */
8081 goto illegal_op
; /* not implemented. */
8083 op
= (insn
>> 20) & 7;
8085 case 0: /* msr cpsr. */
8087 tmp
= load_reg(s
, rn
);
8088 addr
= tcg_const_i32(insn
& 0xff);
8089 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8090 tcg_temp_free_i32(addr
);
8091 tcg_temp_free_i32(tmp
);
8096 case 1: /* msr spsr. */
8099 tmp
= load_reg(s
, rn
);
8101 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8105 case 2: /* cps, nop-hint. */
8106 if (((insn
>> 8) & 7) == 0) {
8107 gen_nop_hint(s
, insn
& 0xff);
8109 /* Implemented as NOP in user mode. */
8114 if (insn
& (1 << 10)) {
8115 if (insn
& (1 << 7))
8117 if (insn
& (1 << 6))
8119 if (insn
& (1 << 5))
8121 if (insn
& (1 << 9))
8122 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8124 if (insn
& (1 << 8)) {
8126 imm
|= (insn
& 0x1f);
8129 gen_set_psr_im(s
, offset
, 0, imm
);
8132 case 3: /* Special control operations. */
8134 op
= (insn
>> 4) & 0xf;
8142 /* These execute as NOPs. */
8149 /* Trivial implementation equivalent to bx. */
8150 tmp
= load_reg(s
, rn
);
8153 case 5: /* Exception return. */
8157 if (rn
!= 14 || rd
!= 15) {
8160 tmp
= load_reg(s
, rn
);
8161 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8162 gen_exception_return(s
, tmp
);
8164 case 6: /* mrs cpsr. */
8165 tmp
= tcg_temp_new_i32();
8167 addr
= tcg_const_i32(insn
& 0xff);
8168 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8169 tcg_temp_free_i32(addr
);
8171 gen_helper_cpsr_read(tmp
);
8173 store_reg(s
, rd
, tmp
);
8175 case 7: /* mrs spsr. */
8176 /* Not accessible in user mode. */
8177 if (IS_USER(s
) || IS_M(env
))
8179 tmp
= load_cpu_field(spsr
);
8180 store_reg(s
, rd
, tmp
);
8185 /* Conditional branch. */
8186 op
= (insn
>> 22) & 0xf;
8187 /* Generate a conditional jump to next instruction. */
8188 s
->condlabel
= gen_new_label();
8189 gen_test_cc(op
^ 1, s
->condlabel
);
8192 /* offset[11:1] = insn[10:0] */
8193 offset
= (insn
& 0x7ff) << 1;
8194 /* offset[17:12] = insn[21:16]. */
8195 offset
|= (insn
& 0x003f0000) >> 4;
8196 /* offset[31:20] = insn[26]. */
8197 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8198 /* offset[18] = insn[13]. */
8199 offset
|= (insn
& (1 << 13)) << 5;
8200 /* offset[19] = insn[11]. */
8201 offset
|= (insn
& (1 << 11)) << 8;
8203 /* jump to the offset */
8204 gen_jmp(s
, s
->pc
+ offset
);
8207 /* Data processing immediate. */
8208 if (insn
& (1 << 25)) {
8209 if (insn
& (1 << 24)) {
8210 if (insn
& (1 << 20))
8212 /* Bitfield/Saturate. */
8213 op
= (insn
>> 21) & 7;
8215 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8217 tmp
= tcg_temp_new_i32();
8218 tcg_gen_movi_i32(tmp
, 0);
8220 tmp
= load_reg(s
, rn
);
8223 case 2: /* Signed bitfield extract. */
8225 if (shift
+ imm
> 32)
8228 gen_sbfx(tmp
, shift
, imm
);
8230 case 6: /* Unsigned bitfield extract. */
8232 if (shift
+ imm
> 32)
8235 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8237 case 3: /* Bitfield insert/clear. */
8240 imm
= imm
+ 1 - shift
;
8242 tmp2
= load_reg(s
, rd
);
8243 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8244 tcg_temp_free_i32(tmp2
);
8249 default: /* Saturate. */
8252 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8254 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8256 tmp2
= tcg_const_i32(imm
);
8259 if ((op
& 1) && shift
== 0)
8260 gen_helper_usat16(tmp
, tmp
, tmp2
);
8262 gen_helper_usat(tmp
, tmp
, tmp2
);
8265 if ((op
& 1) && shift
== 0)
8266 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8268 gen_helper_ssat(tmp
, tmp
, tmp2
);
8270 tcg_temp_free_i32(tmp2
);
8273 store_reg(s
, rd
, tmp
);
8275 imm
= ((insn
& 0x04000000) >> 15)
8276 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8277 if (insn
& (1 << 22)) {
8278 /* 16-bit immediate. */
8279 imm
|= (insn
>> 4) & 0xf000;
8280 if (insn
& (1 << 23)) {
8282 tmp
= load_reg(s
, rd
);
8283 tcg_gen_ext16u_i32(tmp
, tmp
);
8284 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8287 tmp
= tcg_temp_new_i32();
8288 tcg_gen_movi_i32(tmp
, imm
);
8291 /* Add/sub 12-bit immediate. */
8293 offset
= s
->pc
& ~(uint32_t)3;
8294 if (insn
& (1 << 23))
8298 tmp
= tcg_temp_new_i32();
8299 tcg_gen_movi_i32(tmp
, offset
);
8301 tmp
= load_reg(s
, rn
);
8302 if (insn
& (1 << 23))
8303 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8305 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8308 store_reg(s
, rd
, tmp
);
8311 int shifter_out
= 0;
8312 /* modified 12-bit immediate. */
8313 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8314 imm
= (insn
& 0xff);
8317 /* Nothing to do. */
8319 case 1: /* 00XY00XY */
8322 case 2: /* XY00XY00 */
8326 case 3: /* XYXYXYXY */
8330 default: /* Rotated constant. */
8331 shift
= (shift
<< 1) | (imm
>> 7);
8333 imm
= imm
<< (32 - shift
);
8337 tmp2
= tcg_temp_new_i32();
8338 tcg_gen_movi_i32(tmp2
, imm
);
8339 rn
= (insn
>> 16) & 0xf;
8341 tmp
= tcg_temp_new_i32();
8342 tcg_gen_movi_i32(tmp
, 0);
8344 tmp
= load_reg(s
, rn
);
8346 op
= (insn
>> 21) & 0xf;
8347 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8348 shifter_out
, tmp
, tmp2
))
8350 tcg_temp_free_i32(tmp2
);
8351 rd
= (insn
>> 8) & 0xf;
8353 store_reg(s
, rd
, tmp
);
8355 tcg_temp_free_i32(tmp
);
8360 case 12: /* Load/store single data item. */
8365 if ((insn
& 0x01100000) == 0x01000000) {
8366 if (disas_neon_ls_insn(env
, s
, insn
))
8370 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8372 if (!(insn
& (1 << 20))) {
8376 /* Byte or halfword load space with dest == r15 : memory hints.
8377 * Catch them early so we don't emit pointless addressing code.
8378 * This space is a mix of:
8379 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8380 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8382 * unallocated hints, which must be treated as NOPs
8383 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8384 * which is easiest for the decoding logic
8385 * Some space which must UNDEF
8387 int op1
= (insn
>> 23) & 3;
8388 int op2
= (insn
>> 6) & 0x3f;
8393 /* UNPREDICTABLE or unallocated hint */
8397 return 0; /* PLD* or unallocated hint */
8399 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8400 return 0; /* PLD* or unallocated hint */
8402 /* UNDEF space, or an UNPREDICTABLE */
8408 addr
= tcg_temp_new_i32();
8410 /* s->pc has already been incremented by 4. */
8411 imm
= s
->pc
& 0xfffffffc;
8412 if (insn
& (1 << 23))
8413 imm
+= insn
& 0xfff;
8415 imm
-= insn
& 0xfff;
8416 tcg_gen_movi_i32(addr
, imm
);
8418 addr
= load_reg(s
, rn
);
8419 if (insn
& (1 << 23)) {
8420 /* Positive offset. */
8422 tcg_gen_addi_i32(addr
, addr
, imm
);
8425 switch ((insn
>> 8) & 0xf) {
8426 case 0x0: /* Shifted Register. */
8427 shift
= (insn
>> 4) & 0xf;
8429 tcg_temp_free_i32(addr
);
8432 tmp
= load_reg(s
, rm
);
8434 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8435 tcg_gen_add_i32(addr
, addr
, tmp
);
8436 tcg_temp_free_i32(tmp
);
8438 case 0xc: /* Negative offset. */
8439 tcg_gen_addi_i32(addr
, addr
, -imm
);
8441 case 0xe: /* User privilege. */
8442 tcg_gen_addi_i32(addr
, addr
, imm
);
8445 case 0x9: /* Post-decrement. */
8448 case 0xb: /* Post-increment. */
8452 case 0xd: /* Pre-decrement. */
8455 case 0xf: /* Pre-increment. */
8456 tcg_gen_addi_i32(addr
, addr
, imm
);
8460 tcg_temp_free_i32(addr
);
8465 if (insn
& (1 << 20)) {
8468 case 0: tmp
= gen_ld8u(addr
, user
); break;
8469 case 4: tmp
= gen_ld8s(addr
, user
); break;
8470 case 1: tmp
= gen_ld16u(addr
, user
); break;
8471 case 5: tmp
= gen_ld16s(addr
, user
); break;
8472 case 2: tmp
= gen_ld32(addr
, user
); break;
8474 tcg_temp_free_i32(addr
);
8480 store_reg(s
, rs
, tmp
);
8484 tmp
= load_reg(s
, rs
);
8486 case 0: gen_st8(tmp
, addr
, user
); break;
8487 case 1: gen_st16(tmp
, addr
, user
); break;
8488 case 2: gen_st32(tmp
, addr
, user
); break;
8490 tcg_temp_free_i32(addr
);
8495 tcg_gen_addi_i32(addr
, addr
, imm
);
8497 store_reg(s
, rn
, addr
);
8499 tcg_temp_free_i32(addr
);
8511 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
8513 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8520 if (s
->condexec_mask
) {
8521 cond
= s
->condexec_cond
;
8522 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
8523 s
->condlabel
= gen_new_label();
8524 gen_test_cc(cond
^ 1, s
->condlabel
);
8529 insn
= lduw_code(s
->pc
);
8532 switch (insn
>> 12) {
8536 op
= (insn
>> 11) & 3;
8539 rn
= (insn
>> 3) & 7;
8540 tmp
= load_reg(s
, rn
);
8541 if (insn
& (1 << 10)) {
8543 tmp2
= tcg_temp_new_i32();
8544 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
8547 rm
= (insn
>> 6) & 7;
8548 tmp2
= load_reg(s
, rm
);
8550 if (insn
& (1 << 9)) {
8551 if (s
->condexec_mask
)
8552 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8554 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8556 if (s
->condexec_mask
)
8557 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8559 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8561 tcg_temp_free_i32(tmp2
);
8562 store_reg(s
, rd
, tmp
);
8564 /* shift immediate */
8565 rm
= (insn
>> 3) & 7;
8566 shift
= (insn
>> 6) & 0x1f;
8567 tmp
= load_reg(s
, rm
);
8568 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
8569 if (!s
->condexec_mask
)
8571 store_reg(s
, rd
, tmp
);
8575 /* arithmetic large immediate */
8576 op
= (insn
>> 11) & 3;
8577 rd
= (insn
>> 8) & 0x7;
8578 if (op
== 0) { /* mov */
8579 tmp
= tcg_temp_new_i32();
8580 tcg_gen_movi_i32(tmp
, insn
& 0xff);
8581 if (!s
->condexec_mask
)
8583 store_reg(s
, rd
, tmp
);
8585 tmp
= load_reg(s
, rd
);
8586 tmp2
= tcg_temp_new_i32();
8587 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
8590 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8591 tcg_temp_free_i32(tmp
);
8592 tcg_temp_free_i32(tmp2
);
8595 if (s
->condexec_mask
)
8596 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8598 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8599 tcg_temp_free_i32(tmp2
);
8600 store_reg(s
, rd
, tmp
);
8603 if (s
->condexec_mask
)
8604 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8606 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8607 tcg_temp_free_i32(tmp2
);
8608 store_reg(s
, rd
, tmp
);
8614 if (insn
& (1 << 11)) {
8615 rd
= (insn
>> 8) & 7;
8616 /* load pc-relative. Bit 1 of PC is ignored. */
8617 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
8618 val
&= ~(uint32_t)2;
8619 addr
= tcg_temp_new_i32();
8620 tcg_gen_movi_i32(addr
, val
);
8621 tmp
= gen_ld32(addr
, IS_USER(s
));
8622 tcg_temp_free_i32(addr
);
8623 store_reg(s
, rd
, tmp
);
8626 if (insn
& (1 << 10)) {
8627 /* data processing extended or blx */
8628 rd
= (insn
& 7) | ((insn
>> 4) & 8);
8629 rm
= (insn
>> 3) & 0xf;
8630 op
= (insn
>> 8) & 3;
8633 tmp
= load_reg(s
, rd
);
8634 tmp2
= load_reg(s
, rm
);
8635 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8636 tcg_temp_free_i32(tmp2
);
8637 store_reg(s
, rd
, tmp
);
8640 tmp
= load_reg(s
, rd
);
8641 tmp2
= load_reg(s
, rm
);
8642 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8643 tcg_temp_free_i32(tmp2
);
8644 tcg_temp_free_i32(tmp
);
8646 case 2: /* mov/cpy */
8647 tmp
= load_reg(s
, rm
);
8648 store_reg(s
, rd
, tmp
);
8650 case 3:/* branch [and link] exchange thumb register */
8651 tmp
= load_reg(s
, rm
);
8652 if (insn
& (1 << 7)) {
8653 val
= (uint32_t)s
->pc
| 1;
8654 tmp2
= tcg_temp_new_i32();
8655 tcg_gen_movi_i32(tmp2
, val
);
8656 store_reg(s
, 14, tmp2
);
8664 /* data processing register */
8666 rm
= (insn
>> 3) & 7;
8667 op
= (insn
>> 6) & 0xf;
8668 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
8669 /* the shift/rotate ops want the operands backwards */
8678 if (op
== 9) { /* neg */
8679 tmp
= tcg_temp_new_i32();
8680 tcg_gen_movi_i32(tmp
, 0);
8681 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
8682 tmp
= load_reg(s
, rd
);
8687 tmp2
= load_reg(s
, rm
);
8690 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8691 if (!s
->condexec_mask
)
8695 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8696 if (!s
->condexec_mask
)
8700 if (s
->condexec_mask
) {
8701 gen_helper_shl(tmp2
, tmp2
, tmp
);
8703 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
8708 if (s
->condexec_mask
) {
8709 gen_helper_shr(tmp2
, tmp2
, tmp
);
8711 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
8716 if (s
->condexec_mask
) {
8717 gen_helper_sar(tmp2
, tmp2
, tmp
);
8719 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
8724 if (s
->condexec_mask
)
8727 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
8730 if (s
->condexec_mask
)
8731 gen_sub_carry(tmp
, tmp
, tmp2
);
8733 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
8736 if (s
->condexec_mask
) {
8737 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
8738 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
8740 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
8745 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8750 if (s
->condexec_mask
)
8751 tcg_gen_neg_i32(tmp
, tmp2
);
8753 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8756 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8760 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8764 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8765 if (!s
->condexec_mask
)
8769 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8770 if (!s
->condexec_mask
)
8774 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8775 if (!s
->condexec_mask
)
8779 tcg_gen_not_i32(tmp2
, tmp2
);
8780 if (!s
->condexec_mask
)
8788 store_reg(s
, rm
, tmp2
);
8790 tcg_temp_free_i32(tmp
);
8792 store_reg(s
, rd
, tmp
);
8793 tcg_temp_free_i32(tmp2
);
8796 tcg_temp_free_i32(tmp
);
8797 tcg_temp_free_i32(tmp2
);
8802 /* load/store register offset. */
8804 rn
= (insn
>> 3) & 7;
8805 rm
= (insn
>> 6) & 7;
8806 op
= (insn
>> 9) & 7;
8807 addr
= load_reg(s
, rn
);
8808 tmp
= load_reg(s
, rm
);
8809 tcg_gen_add_i32(addr
, addr
, tmp
);
8810 tcg_temp_free_i32(tmp
);
8812 if (op
< 3) /* store */
8813 tmp
= load_reg(s
, rd
);
8817 gen_st32(tmp
, addr
, IS_USER(s
));
8820 gen_st16(tmp
, addr
, IS_USER(s
));
8823 gen_st8(tmp
, addr
, IS_USER(s
));
8826 tmp
= gen_ld8s(addr
, IS_USER(s
));
8829 tmp
= gen_ld32(addr
, IS_USER(s
));
8832 tmp
= gen_ld16u(addr
, IS_USER(s
));
8835 tmp
= gen_ld8u(addr
, IS_USER(s
));
8838 tmp
= gen_ld16s(addr
, IS_USER(s
));
8841 if (op
>= 3) /* load */
8842 store_reg(s
, rd
, tmp
);
8843 tcg_temp_free_i32(addr
);
8847 /* load/store word immediate offset */
8849 rn
= (insn
>> 3) & 7;
8850 addr
= load_reg(s
, rn
);
8851 val
= (insn
>> 4) & 0x7c;
8852 tcg_gen_addi_i32(addr
, addr
, val
);
8854 if (insn
& (1 << 11)) {
8856 tmp
= gen_ld32(addr
, IS_USER(s
));
8857 store_reg(s
, rd
, tmp
);
8860 tmp
= load_reg(s
, rd
);
8861 gen_st32(tmp
, addr
, IS_USER(s
));
8863 tcg_temp_free_i32(addr
);
8867 /* load/store byte immediate offset */
8869 rn
= (insn
>> 3) & 7;
8870 addr
= load_reg(s
, rn
);
8871 val
= (insn
>> 6) & 0x1f;
8872 tcg_gen_addi_i32(addr
, addr
, val
);
8874 if (insn
& (1 << 11)) {
8876 tmp
= gen_ld8u(addr
, IS_USER(s
));
8877 store_reg(s
, rd
, tmp
);
8880 tmp
= load_reg(s
, rd
);
8881 gen_st8(tmp
, addr
, IS_USER(s
));
8883 tcg_temp_free_i32(addr
);
8887 /* load/store halfword immediate offset */
8889 rn
= (insn
>> 3) & 7;
8890 addr
= load_reg(s
, rn
);
8891 val
= (insn
>> 5) & 0x3e;
8892 tcg_gen_addi_i32(addr
, addr
, val
);
8894 if (insn
& (1 << 11)) {
8896 tmp
= gen_ld16u(addr
, IS_USER(s
));
8897 store_reg(s
, rd
, tmp
);
8900 tmp
= load_reg(s
, rd
);
8901 gen_st16(tmp
, addr
, IS_USER(s
));
8903 tcg_temp_free_i32(addr
);
8907 /* load/store from stack */
8908 rd
= (insn
>> 8) & 7;
8909 addr
= load_reg(s
, 13);
8910 val
= (insn
& 0xff) * 4;
8911 tcg_gen_addi_i32(addr
, addr
, val
);
8913 if (insn
& (1 << 11)) {
8915 tmp
= gen_ld32(addr
, IS_USER(s
));
8916 store_reg(s
, rd
, tmp
);
8919 tmp
= load_reg(s
, rd
);
8920 gen_st32(tmp
, addr
, IS_USER(s
));
8922 tcg_temp_free_i32(addr
);
8926 /* add to high reg */
8927 rd
= (insn
>> 8) & 7;
8928 if (insn
& (1 << 11)) {
8930 tmp
= load_reg(s
, 13);
8932 /* PC. bit 1 is ignored. */
8933 tmp
= tcg_temp_new_i32();
8934 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
8936 val
= (insn
& 0xff) * 4;
8937 tcg_gen_addi_i32(tmp
, tmp
, val
);
8938 store_reg(s
, rd
, tmp
);
8943 op
= (insn
>> 8) & 0xf;
8946 /* adjust stack pointer */
8947 tmp
= load_reg(s
, 13);
8948 val
= (insn
& 0x7f) * 4;
8949 if (insn
& (1 << 7))
8950 val
= -(int32_t)val
;
8951 tcg_gen_addi_i32(tmp
, tmp
, val
);
8952 store_reg(s
, 13, tmp
);
8955 case 2: /* sign/zero extend. */
8958 rm
= (insn
>> 3) & 7;
8959 tmp
= load_reg(s
, rm
);
8960 switch ((insn
>> 6) & 3) {
8961 case 0: gen_sxth(tmp
); break;
8962 case 1: gen_sxtb(tmp
); break;
8963 case 2: gen_uxth(tmp
); break;
8964 case 3: gen_uxtb(tmp
); break;
8966 store_reg(s
, rd
, tmp
);
8968 case 4: case 5: case 0xc: case 0xd:
8970 addr
= load_reg(s
, 13);
8971 if (insn
& (1 << 8))
8975 for (i
= 0; i
< 8; i
++) {
8976 if (insn
& (1 << i
))
8979 if ((insn
& (1 << 11)) == 0) {
8980 tcg_gen_addi_i32(addr
, addr
, -offset
);
8982 for (i
= 0; i
< 8; i
++) {
8983 if (insn
& (1 << i
)) {
8984 if (insn
& (1 << 11)) {
8986 tmp
= gen_ld32(addr
, IS_USER(s
));
8987 store_reg(s
, i
, tmp
);
8990 tmp
= load_reg(s
, i
);
8991 gen_st32(tmp
, addr
, IS_USER(s
));
8993 /* advance to the next address. */
8994 tcg_gen_addi_i32(addr
, addr
, 4);
8998 if (insn
& (1 << 8)) {
8999 if (insn
& (1 << 11)) {
9001 tmp
= gen_ld32(addr
, IS_USER(s
));
9002 /* don't set the pc until the rest of the instruction
9006 tmp
= load_reg(s
, 14);
9007 gen_st32(tmp
, addr
, IS_USER(s
));
9009 tcg_gen_addi_i32(addr
, addr
, 4);
9011 if ((insn
& (1 << 11)) == 0) {
9012 tcg_gen_addi_i32(addr
, addr
, -offset
);
9014 /* write back the new stack pointer */
9015 store_reg(s
, 13, addr
);
9016 /* set the new PC value */
9017 if ((insn
& 0x0900) == 0x0900)
9021 case 1: case 3: case 9: case 11: /* czb */
9023 tmp
= load_reg(s
, rm
);
9024 s
->condlabel
= gen_new_label();
9026 if (insn
& (1 << 11))
9027 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9029 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9030 tcg_temp_free_i32(tmp
);
9031 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9032 val
= (uint32_t)s
->pc
+ 2;
9037 case 15: /* IT, nop-hint. */
9038 if ((insn
& 0xf) == 0) {
9039 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9043 s
->condexec_cond
= (insn
>> 4) & 0xe;
9044 s
->condexec_mask
= insn
& 0x1f;
9045 /* No actual code generated for this insn, just setup state. */
9048 case 0xe: /* bkpt */
9049 gen_exception_insn(s
, 2, EXCP_BKPT
);
9054 rn
= (insn
>> 3) & 0x7;
9056 tmp
= load_reg(s
, rn
);
9057 switch ((insn
>> 6) & 3) {
9058 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9059 case 1: gen_rev16(tmp
); break;
9060 case 3: gen_revsh(tmp
); break;
9061 default: goto illegal_op
;
9063 store_reg(s
, rd
, tmp
);
9071 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9074 addr
= tcg_const_i32(16);
9075 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9076 tcg_temp_free_i32(addr
);
9080 addr
= tcg_const_i32(17);
9081 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9082 tcg_temp_free_i32(addr
);
9084 tcg_temp_free_i32(tmp
);
9087 if (insn
& (1 << 4))
9088 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9091 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9101 /* load/store multiple */
9102 rn
= (insn
>> 8) & 0x7;
9103 addr
= load_reg(s
, rn
);
9104 for (i
= 0; i
< 8; i
++) {
9105 if (insn
& (1 << i
)) {
9106 if (insn
& (1 << 11)) {
9108 tmp
= gen_ld32(addr
, IS_USER(s
));
9109 store_reg(s
, i
, tmp
);
9112 tmp
= load_reg(s
, i
);
9113 gen_st32(tmp
, addr
, IS_USER(s
));
9115 /* advance to the next address */
9116 tcg_gen_addi_i32(addr
, addr
, 4);
9119 /* Base register writeback. */
9120 if ((insn
& (1 << rn
)) == 0) {
9121 store_reg(s
, rn
, addr
);
9123 tcg_temp_free_i32(addr
);
9128 /* conditional branch or swi */
9129 cond
= (insn
>> 8) & 0xf;
9135 gen_set_pc_im(s
->pc
);
9136 s
->is_jmp
= DISAS_SWI
;
9139 /* generate a conditional jump to next instruction */
9140 s
->condlabel
= gen_new_label();
9141 gen_test_cc(cond
^ 1, s
->condlabel
);
9144 /* jump to the offset */
9145 val
= (uint32_t)s
->pc
+ 2;
9146 offset
= ((int32_t)insn
<< 24) >> 24;
9152 if (insn
& (1 << 11)) {
9153 if (disas_thumb2_insn(env
, s
, insn
))
9157 /* unconditional branch */
9158 val
= (uint32_t)s
->pc
;
9159 offset
= ((int32_t)insn
<< 21) >> 21;
9160 val
+= (offset
<< 1) + 2;
9165 if (disas_thumb2_insn(env
, s
, insn
))
9171 gen_exception_insn(s
, 4, EXCP_UDEF
);
9175 gen_exception_insn(s
, 2, EXCP_UDEF
);
9178 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9179 basic block 'tb'. If search_pc is TRUE, also generate PC
9180 information for each intermediate instruction. */
9181 static inline void gen_intermediate_code_internal(CPUState
*env
,
9182 TranslationBlock
*tb
,
9185 DisasContext dc1
, *dc
= &dc1
;
9187 uint16_t *gen_opc_end
;
9189 target_ulong pc_start
;
9190 uint32_t next_page_start
;
9194 /* generate intermediate code */
9199 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9201 dc
->is_jmp
= DISAS_NEXT
;
9203 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9205 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9206 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9207 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9208 #if !defined(CONFIG_USER_ONLY)
9209 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9211 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9212 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9213 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9214 cpu_F0s
= tcg_temp_new_i32();
9215 cpu_F1s
= tcg_temp_new_i32();
9216 cpu_F0d
= tcg_temp_new_i64();
9217 cpu_F1d
= tcg_temp_new_i64();
9220 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9221 cpu_M0
= tcg_temp_new_i64();
9222 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9225 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9227 max_insns
= CF_COUNT_MASK
;
9231 tcg_clear_temp_count();
9233 /* A note on handling of the condexec (IT) bits:
9235 * We want to avoid the overhead of having to write the updated condexec
9236 * bits back to the CPUState for every instruction in an IT block. So:
9237 * (1) if the condexec bits are not already zero then we write
9238 * zero back into the CPUState now. This avoids complications trying
9239 * to do it at the end of the block. (For example if we don't do this
9240 * it's hard to identify whether we can safely skip writing condexec
9241 * at the end of the TB, which we definitely want to do for the case
9242 * where a TB doesn't do anything with the IT state at all.)
9243 * (2) if we are going to leave the TB then we call gen_set_condexec()
9244 * which will write the correct value into CPUState if zero is wrong.
9245 * This is done both for leaving the TB at the end, and for leaving
9246 * it because of an exception we know will happen, which is done in
9247 * gen_exception_insn(). The latter is necessary because we need to
9248 * leave the TB with the PC/IT state just prior to execution of the
9249 * instruction which caused the exception.
9250 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9251 * then the CPUState will be wrong and we need to reset it.
9252 * This is handled in the same way as restoration of the
9253 * PC in these situations: we will be called again with search_pc=1
9254 * and generate a mapping of the condexec bits for each PC in
9255 * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9256 * the condexec bits.
9258 * Note that there are no instructions which can read the condexec
9259 * bits, and none which can write non-static values to them, so
9260 * we don't need to care about whether CPUState is correct in the
9264 /* Reset the conditional execution bits immediately. This avoids
9265 complications trying to do it at the end of the block. */
9266 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9268 TCGv tmp
= tcg_temp_new_i32();
9269 tcg_gen_movi_i32(tmp
, 0);
9270 store_cpu_field(tmp
, condexec_bits
);
9273 #ifdef CONFIG_USER_ONLY
9274 /* Intercept jump to the magic kernel page. */
9275 if (dc
->pc
>= 0xffff0000) {
9276 /* We always get here via a jump, so know we are not in a
9277 conditional execution block. */
9278 gen_exception(EXCP_KERNEL_TRAP
);
9279 dc
->is_jmp
= DISAS_UPDATE
;
9283 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9284 /* We always get here via a jump, so know we are not in a
9285 conditional execution block. */
9286 gen_exception(EXCP_EXCEPTION_EXIT
);
9287 dc
->is_jmp
= DISAS_UPDATE
;
9292 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9293 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9294 if (bp
->pc
== dc
->pc
) {
9295 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9296 /* Advance PC so that clearing the breakpoint will
9297 invalidate this TB. */
9299 goto done_generating
;
9305 j
= gen_opc_ptr
- gen_opc_buf
;
9309 gen_opc_instr_start
[lj
++] = 0;
9311 gen_opc_pc
[lj
] = dc
->pc
;
9312 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9313 gen_opc_instr_start
[lj
] = 1;
9314 gen_opc_icount
[lj
] = num_insns
;
9317 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9320 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9321 tcg_gen_debug_insn_start(dc
->pc
);
9325 disas_thumb_insn(env
, dc
);
9326 if (dc
->condexec_mask
) {
9327 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9328 | ((dc
->condexec_mask
>> 4) & 1);
9329 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9330 if (dc
->condexec_mask
== 0) {
9331 dc
->condexec_cond
= 0;
9335 disas_arm_insn(env
, dc
);
9338 if (dc
->condjmp
&& !dc
->is_jmp
) {
9339 gen_set_label(dc
->condlabel
);
9343 if (tcg_check_temp_count()) {
9344 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9347 /* Translation stops when a conditional branch is encountered.
9348 * Otherwise the subsequent code could get translated several times.
9349 * Also stop translation when a page boundary is reached. This
9350 * ensures prefetch aborts occur at the right place. */
9352 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9353 !env
->singlestep_enabled
&&
9355 dc
->pc
< next_page_start
&&
9356 num_insns
< max_insns
);
9358 if (tb
->cflags
& CF_LAST_IO
) {
9360 /* FIXME: This can theoretically happen with self-modifying
9362 cpu_abort(env
, "IO on conditional branch instruction");
9367 /* At this stage dc->condjmp will only be set when the skipped
9368 instruction was a conditional branch or trap, and the PC has
9369 already been written. */
9370 if (unlikely(env
->singlestep_enabled
)) {
9371 /* Make sure the pc is updated, and raise a debug exception. */
9373 gen_set_condexec(dc
);
9374 if (dc
->is_jmp
== DISAS_SWI
) {
9375 gen_exception(EXCP_SWI
);
9377 gen_exception(EXCP_DEBUG
);
9379 gen_set_label(dc
->condlabel
);
9381 if (dc
->condjmp
|| !dc
->is_jmp
) {
9382 gen_set_pc_im(dc
->pc
);
9385 gen_set_condexec(dc
);
9386 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9387 gen_exception(EXCP_SWI
);
9389 /* FIXME: Single stepping a WFI insn will not halt
9391 gen_exception(EXCP_DEBUG
);
9394 /* While branches must always occur at the end of an IT block,
9395 there are a few other things that can cause us to terminate
9396 the TB in the middel of an IT block:
9397 - Exception generating instructions (bkpt, swi, undefined).
9399 - Hardware watchpoints.
9400 Hardware breakpoints have already been handled and skip this code.
9402 gen_set_condexec(dc
);
9403 switch(dc
->is_jmp
) {
9405 gen_goto_tb(dc
, 1, dc
->pc
);
9410 /* indicate that the hash table must be used to find the next TB */
9414 /* nothing more to generate */
9420 gen_exception(EXCP_SWI
);
9424 gen_set_label(dc
->condlabel
);
9425 gen_set_condexec(dc
);
9426 gen_goto_tb(dc
, 1, dc
->pc
);
9432 gen_icount_end(tb
, num_insns
);
9433 *gen_opc_ptr
= INDEX_op_end
;
9436 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9437 qemu_log("----------------\n");
9438 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9439 log_target_disas(pc_start
, dc
->pc
- pc_start
, dc
->thumb
);
9444 j
= gen_opc_ptr
- gen_opc_buf
;
9447 gen_opc_instr_start
[lj
++] = 0;
9449 tb
->size
= dc
->pc
- pc_start
;
9450 tb
->icount
= num_insns
;
9454 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9456 gen_intermediate_code_internal(env
, tb
, 0);
9459 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9461 gen_intermediate_code_internal(env
, tb
, 1);
9464 static const char *cpu_mode_names
[16] = {
9465 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9466 "???", "???", "???", "und", "???", "???", "???", "sys"
9469 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
9479 /* ??? This assumes float64 and double have the same layout.
9480 Oh well, it's only debug dumps. */
9489 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9491 cpu_fprintf(f
, "\n");
9493 cpu_fprintf(f
, " ");
9495 psr
= cpsr_read(env
);
9496 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9498 psr
& (1 << 31) ? 'N' : '-',
9499 psr
& (1 << 30) ? 'Z' : '-',
9500 psr
& (1 << 29) ? 'C' : '-',
9501 psr
& (1 << 28) ? 'V' : '-',
9502 psr
& CPSR_T
? 'T' : 'A',
9503 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9506 for (i
= 0; i
< 16; i
++) {
9507 d
.d
= env
->vfp
.regs
[i
];
9511 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9512 i
* 2, (int)s0
.i
, s0
.s
,
9513 i
* 2 + 1, (int)s1
.i
, s1
.s
,
9514 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
9517 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
9521 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
9522 unsigned long searched_pc
, int pc_pos
, void *puc
)
9524 env
->regs
[15] = gen_opc_pc
[pc_pos
];
9525 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];