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 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2652 (ie. an undefined instruction). */
2653 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2655 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2661 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2664 if (!s
->vfp_enabled
) {
2665 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2666 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2668 rn
= (insn
>> 16) & 0xf;
2669 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2670 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2673 dp
= ((insn
& 0xf00) == 0xb00);
2674 switch ((insn
>> 24) & 0xf) {
2676 if (insn
& (1 << 4)) {
2677 /* single register transfer */
2678 rd
= (insn
>> 12) & 0xf;
2683 VFP_DREG_N(rn
, insn
);
2686 if (insn
& 0x00c00060
2687 && !arm_feature(env
, ARM_FEATURE_NEON
))
2690 pass
= (insn
>> 21) & 1;
2691 if (insn
& (1 << 22)) {
2693 offset
= ((insn
>> 5) & 3) * 8;
2694 } else if (insn
& (1 << 5)) {
2696 offset
= (insn
& (1 << 6)) ? 16 : 0;
2701 if (insn
& ARM_CP_RW_BIT
) {
2703 tmp
= neon_load_reg(rn
, pass
);
2707 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2708 if (insn
& (1 << 23))
2714 if (insn
& (1 << 23)) {
2716 tcg_gen_shri_i32(tmp
, tmp
, 16);
2722 tcg_gen_sari_i32(tmp
, tmp
, 16);
2731 store_reg(s
, rd
, tmp
);
2734 tmp
= load_reg(s
, rd
);
2735 if (insn
& (1 << 23)) {
2738 gen_neon_dup_u8(tmp
, 0);
2739 } else if (size
== 1) {
2740 gen_neon_dup_low16(tmp
);
2742 for (n
= 0; n
<= pass
* 2; n
++) {
2743 tmp2
= tcg_temp_new_i32();
2744 tcg_gen_mov_i32(tmp2
, tmp
);
2745 neon_store_reg(rn
, n
, tmp2
);
2747 neon_store_reg(rn
, n
, tmp
);
2752 tmp2
= neon_load_reg(rn
, pass
);
2753 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2754 tcg_temp_free_i32(tmp2
);
2757 tmp2
= neon_load_reg(rn
, pass
);
2758 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2759 tcg_temp_free_i32(tmp2
);
2764 neon_store_reg(rn
, pass
, tmp
);
2768 if ((insn
& 0x6f) != 0x00)
2770 rn
= VFP_SREG_N(insn
);
2771 if (insn
& ARM_CP_RW_BIT
) {
2773 if (insn
& (1 << 21)) {
2774 /* system register */
2779 /* VFP2 allows access to FSID from userspace.
2780 VFP3 restricts all id registers to privileged
2783 && arm_feature(env
, ARM_FEATURE_VFP3
))
2785 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2790 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2792 case ARM_VFP_FPINST
:
2793 case ARM_VFP_FPINST2
:
2794 /* Not present in VFP3. */
2796 || arm_feature(env
, ARM_FEATURE_VFP3
))
2798 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2802 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2803 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2805 tmp
= tcg_temp_new_i32();
2806 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2812 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2814 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2820 gen_mov_F0_vreg(0, rn
);
2821 tmp
= gen_vfp_mrs();
2824 /* Set the 4 flag bits in the CPSR. */
2826 tcg_temp_free_i32(tmp
);
2828 store_reg(s
, rd
, tmp
);
2832 tmp
= load_reg(s
, rd
);
2833 if (insn
& (1 << 21)) {
2835 /* system register */
2840 /* Writes are ignored. */
2843 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2844 tcg_temp_free_i32(tmp
);
2850 /* TODO: VFP subarchitecture support.
2851 * For now, keep the EN bit only */
2852 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2853 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2856 case ARM_VFP_FPINST
:
2857 case ARM_VFP_FPINST2
:
2858 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2865 gen_mov_vreg_F0(0, rn
);
2870 /* data processing */
2871 /* The opcode is in bits 23, 21, 20 and 6. */
2872 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2876 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2878 /* rn is register number */
2879 VFP_DREG_N(rn
, insn
);
2882 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2883 /* Integer or single precision destination. */
2884 rd
= VFP_SREG_D(insn
);
2886 VFP_DREG_D(rd
, insn
);
2889 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2890 /* VCVT from int is always from S reg regardless of dp bit.
2891 * VCVT with immediate frac_bits has same format as SREG_M
2893 rm
= VFP_SREG_M(insn
);
2895 VFP_DREG_M(rm
, insn
);
2898 rn
= VFP_SREG_N(insn
);
2899 if (op
== 15 && rn
== 15) {
2900 /* Double precision destination. */
2901 VFP_DREG_D(rd
, insn
);
2903 rd
= VFP_SREG_D(insn
);
2905 /* NB that we implicitly rely on the encoding for the frac_bits
2906 * in VCVT of fixed to float being the same as that of an SREG_M
2908 rm
= VFP_SREG_M(insn
);
2911 veclen
= s
->vec_len
;
2912 if (op
== 15 && rn
> 3)
2915 /* Shut up compiler warnings. */
2926 /* Figure out what type of vector operation this is. */
2927 if ((rd
& bank_mask
) == 0) {
2932 delta_d
= (s
->vec_stride
>> 1) + 1;
2934 delta_d
= s
->vec_stride
+ 1;
2936 if ((rm
& bank_mask
) == 0) {
2937 /* mixed scalar/vector */
2946 /* Load the initial operands. */
2951 /* Integer source */
2952 gen_mov_F0_vreg(0, rm
);
2957 gen_mov_F0_vreg(dp
, rd
);
2958 gen_mov_F1_vreg(dp
, rm
);
2962 /* Compare with zero */
2963 gen_mov_F0_vreg(dp
, rd
);
2974 /* Source and destination the same. */
2975 gen_mov_F0_vreg(dp
, rd
);
2978 /* One source operand. */
2979 gen_mov_F0_vreg(dp
, rm
);
2983 /* Two source operands. */
2984 gen_mov_F0_vreg(dp
, rn
);
2985 gen_mov_F1_vreg(dp
, rm
);
2989 /* Perform the calculation. */
2991 case 0: /* mac: fd + (fn * fm) */
2993 gen_mov_F1_vreg(dp
, rd
);
2996 case 1: /* nmac: fd - (fn * fm) */
2999 gen_mov_F1_vreg(dp
, rd
);
3002 case 2: /* msc: -fd + (fn * fm) */
3004 gen_mov_F1_vreg(dp
, rd
);
3007 case 3: /* nmsc: -fd - (fn * fm) */
3010 gen_mov_F1_vreg(dp
, rd
);
3013 case 4: /* mul: fn * fm */
3016 case 5: /* nmul: -(fn * fm) */
3020 case 6: /* add: fn + fm */
3023 case 7: /* sub: fn - fm */
3026 case 8: /* div: fn / fm */
3029 case 14: /* fconst */
3030 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3033 n
= (insn
<< 12) & 0x80000000;
3034 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3041 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3048 tcg_gen_movi_i32(cpu_F0s
, n
);
3051 case 15: /* extension space */
3065 case 4: /* vcvtb.f32.f16 */
3066 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3068 tmp
= gen_vfp_mrs();
3069 tcg_gen_ext16u_i32(tmp
, tmp
);
3070 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3071 tcg_temp_free_i32(tmp
);
3073 case 5: /* vcvtt.f32.f16 */
3074 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3076 tmp
= gen_vfp_mrs();
3077 tcg_gen_shri_i32(tmp
, tmp
, 16);
3078 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3079 tcg_temp_free_i32(tmp
);
3081 case 6: /* vcvtb.f16.f32 */
3082 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3084 tmp
= tcg_temp_new_i32();
3085 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3086 gen_mov_F0_vreg(0, rd
);
3087 tmp2
= gen_vfp_mrs();
3088 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3089 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3090 tcg_temp_free_i32(tmp2
);
3093 case 7: /* vcvtt.f16.f32 */
3094 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3096 tmp
= tcg_temp_new_i32();
3097 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3098 tcg_gen_shli_i32(tmp
, tmp
, 16);
3099 gen_mov_F0_vreg(0, rd
);
3100 tmp2
= gen_vfp_mrs();
3101 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3102 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3103 tcg_temp_free_i32(tmp2
);
3115 case 11: /* cmpez */
3119 case 15: /* single<->double conversion */
3121 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3123 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3125 case 16: /* fuito */
3128 case 17: /* fsito */
3131 case 20: /* fshto */
3132 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3134 gen_vfp_shto(dp
, 16 - rm
);
3136 case 21: /* fslto */
3137 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3139 gen_vfp_slto(dp
, 32 - rm
);
3141 case 22: /* fuhto */
3142 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3144 gen_vfp_uhto(dp
, 16 - rm
);
3146 case 23: /* fulto */
3147 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3149 gen_vfp_ulto(dp
, 32 - rm
);
3151 case 24: /* ftoui */
3154 case 25: /* ftouiz */
3157 case 26: /* ftosi */
3160 case 27: /* ftosiz */
3163 case 28: /* ftosh */
3164 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3166 gen_vfp_tosh(dp
, 16 - rm
);
3168 case 29: /* ftosl */
3169 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3171 gen_vfp_tosl(dp
, 32 - rm
);
3173 case 30: /* ftouh */
3174 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3176 gen_vfp_touh(dp
, 16 - rm
);
3178 case 31: /* ftoul */
3179 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3181 gen_vfp_toul(dp
, 32 - rm
);
3183 default: /* undefined */
3184 printf ("rn:%d\n", rn
);
3188 default: /* undefined */
3189 printf ("op:%d\n", op
);
3193 /* Write back the result. */
3194 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3195 ; /* Comparison, do nothing. */
3196 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3197 /* VCVT double to int: always integer result. */
3198 gen_mov_vreg_F0(0, rd
);
3199 else if (op
== 15 && rn
== 15)
3201 gen_mov_vreg_F0(!dp
, rd
);
3203 gen_mov_vreg_F0(dp
, rd
);
3205 /* break out of the loop if we have finished */
3209 if (op
== 15 && delta_m
== 0) {
3210 /* single source one-many */
3212 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3214 gen_mov_vreg_F0(dp
, rd
);
3218 /* Setup the next operands. */
3220 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3224 /* One source operand. */
3225 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3227 gen_mov_F0_vreg(dp
, rm
);
3229 /* Two source operands. */
3230 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3232 gen_mov_F0_vreg(dp
, rn
);
3234 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3236 gen_mov_F1_vreg(dp
, rm
);
3244 if ((insn
& 0x03e00000) == 0x00400000) {
3245 /* two-register transfer */
3246 rn
= (insn
>> 16) & 0xf;
3247 rd
= (insn
>> 12) & 0xf;
3249 VFP_DREG_M(rm
, insn
);
3251 rm
= VFP_SREG_M(insn
);
3254 if (insn
& ARM_CP_RW_BIT
) {
3257 gen_mov_F0_vreg(0, rm
* 2);
3258 tmp
= gen_vfp_mrs();
3259 store_reg(s
, rd
, tmp
);
3260 gen_mov_F0_vreg(0, rm
* 2 + 1);
3261 tmp
= gen_vfp_mrs();
3262 store_reg(s
, rn
, tmp
);
3264 gen_mov_F0_vreg(0, rm
);
3265 tmp
= gen_vfp_mrs();
3266 store_reg(s
, rd
, tmp
);
3267 gen_mov_F0_vreg(0, rm
+ 1);
3268 tmp
= gen_vfp_mrs();
3269 store_reg(s
, rn
, tmp
);
3274 tmp
= load_reg(s
, rd
);
3276 gen_mov_vreg_F0(0, rm
* 2);
3277 tmp
= load_reg(s
, rn
);
3279 gen_mov_vreg_F0(0, rm
* 2 + 1);
3281 tmp
= load_reg(s
, rd
);
3283 gen_mov_vreg_F0(0, rm
);
3284 tmp
= load_reg(s
, rn
);
3286 gen_mov_vreg_F0(0, rm
+ 1);
3291 rn
= (insn
>> 16) & 0xf;
3293 VFP_DREG_D(rd
, insn
);
3295 rd
= VFP_SREG_D(insn
);
3296 if (s
->thumb
&& rn
== 15) {
3297 addr
= tcg_temp_new_i32();
3298 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3300 addr
= load_reg(s
, rn
);
3302 if ((insn
& 0x01200000) == 0x01000000) {
3303 /* Single load/store */
3304 offset
= (insn
& 0xff) << 2;
3305 if ((insn
& (1 << 23)) == 0)
3307 tcg_gen_addi_i32(addr
, addr
, offset
);
3308 if (insn
& (1 << 20)) {
3309 gen_vfp_ld(s
, dp
, addr
);
3310 gen_mov_vreg_F0(dp
, rd
);
3312 gen_mov_F0_vreg(dp
, rd
);
3313 gen_vfp_st(s
, dp
, addr
);
3315 tcg_temp_free_i32(addr
);
3317 /* load/store multiple */
3319 n
= (insn
>> 1) & 0x7f;
3323 if (insn
& (1 << 24)) /* pre-decrement */
3324 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3330 for (i
= 0; i
< n
; i
++) {
3331 if (insn
& ARM_CP_RW_BIT
) {
3333 gen_vfp_ld(s
, dp
, addr
);
3334 gen_mov_vreg_F0(dp
, rd
+ i
);
3337 gen_mov_F0_vreg(dp
, rd
+ i
);
3338 gen_vfp_st(s
, dp
, addr
);
3340 tcg_gen_addi_i32(addr
, addr
, offset
);
3342 if (insn
& (1 << 21)) {
3344 if (insn
& (1 << 24))
3345 offset
= -offset
* n
;
3346 else if (dp
&& (insn
& 1))
3352 tcg_gen_addi_i32(addr
, addr
, offset
);
3353 store_reg(s
, rn
, addr
);
3355 tcg_temp_free_i32(addr
);
3361 /* Should never happen. */
3367 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3369 TranslationBlock
*tb
;
3372 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3374 gen_set_pc_im(dest
);
3375 tcg_gen_exit_tb((long)tb
+ n
);
3377 gen_set_pc_im(dest
);
3382 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3384 if (unlikely(s
->singlestep_enabled
)) {
3385 /* An indirect jump so that we still trigger the debug exception. */
3390 gen_goto_tb(s
, 0, dest
);
3391 s
->is_jmp
= DISAS_TB_JUMP
;
3395 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3398 tcg_gen_sari_i32(t0
, t0
, 16);
3402 tcg_gen_sari_i32(t1
, t1
, 16);
3405 tcg_gen_mul_i32(t0
, t0
, t1
);
3408 /* Return the mask of PSR bits set by a MSR instruction. */
3409 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3413 if (flags
& (1 << 0))
3415 if (flags
& (1 << 1))
3417 if (flags
& (1 << 2))
3419 if (flags
& (1 << 3))
3422 /* Mask out undefined bits. */
3423 mask
&= ~CPSR_RESERVED
;
3424 if (!arm_feature(env
, ARM_FEATURE_V6
))
3425 mask
&= ~(CPSR_E
| CPSR_GE
);
3426 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3428 /* Mask out execution state bits. */
3431 /* Mask out privileged bits. */
3437 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3438 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3442 /* ??? This is also undefined in system mode. */
3446 tmp
= load_cpu_field(spsr
);
3447 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3448 tcg_gen_andi_i32(t0
, t0
, mask
);
3449 tcg_gen_or_i32(tmp
, tmp
, t0
);
3450 store_cpu_field(tmp
, spsr
);
3452 gen_set_cpsr(t0
, mask
);
3454 tcg_temp_free_i32(t0
);
3459 /* Returns nonzero if access to the PSR is not permitted. */
3460 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3463 tmp
= tcg_temp_new_i32();
3464 tcg_gen_movi_i32(tmp
, val
);
3465 return gen_set_psr(s
, mask
, spsr
, tmp
);
3468 /* Generate an old-style exception return. Marks pc as dead. */
3469 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3472 store_reg(s
, 15, pc
);
3473 tmp
= load_cpu_field(spsr
);
3474 gen_set_cpsr(tmp
, 0xffffffff);
3475 tcg_temp_free_i32(tmp
);
3476 s
->is_jmp
= DISAS_UPDATE
;
3479 /* Generate a v6 exception return. Marks both values as dead. */
3480 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3482 gen_set_cpsr(cpsr
, 0xffffffff);
3483 tcg_temp_free_i32(cpsr
);
3484 store_reg(s
, 15, pc
);
3485 s
->is_jmp
= DISAS_UPDATE
;
3489 gen_set_condexec (DisasContext
*s
)
3491 if (s
->condexec_mask
) {
3492 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3493 TCGv tmp
= tcg_temp_new_i32();
3494 tcg_gen_movi_i32(tmp
, val
);
3495 store_cpu_field(tmp
, condexec_bits
);
3499 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3501 gen_set_condexec(s
);
3502 gen_set_pc_im(s
->pc
- offset
);
3503 gen_exception(excp
);
3504 s
->is_jmp
= DISAS_JUMP
;
3507 static void gen_nop_hint(DisasContext
*s
, int val
)
3511 gen_set_pc_im(s
->pc
);
3512 s
->is_jmp
= DISAS_WFI
;
3516 /* TODO: Implement SEV and WFE. May help SMP performance. */
3522 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3524 static inline int gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3527 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3528 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3529 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3535 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3538 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3539 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3540 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3545 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3546 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3547 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3548 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3549 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3551 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3552 switch ((size << 1) | u) { \
3554 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3557 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3560 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3563 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3566 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3569 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3571 default: return 1; \
3574 #define GEN_NEON_INTEGER_OP(name) do { \
3575 switch ((size << 1) | u) { \
3577 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3580 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3583 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3586 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3589 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3592 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3594 default: return 1; \
3597 static TCGv
neon_load_scratch(int scratch
)
3599 TCGv tmp
= tcg_temp_new_i32();
3600 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3604 static void neon_store_scratch(int scratch
, TCGv var
)
3606 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3607 tcg_temp_free_i32(var
);
3610 static inline TCGv
neon_get_scalar(int size
, int reg
)
3614 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3616 gen_neon_dup_high16(tmp
);
3618 gen_neon_dup_low16(tmp
);
3621 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3626 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3629 if (size
== 3 || (!q
&& size
== 2)) {
3632 tmp
= tcg_const_i32(rd
);
3633 tmp2
= tcg_const_i32(rm
);
3637 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3640 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3643 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3651 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3654 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3660 tcg_temp_free_i32(tmp
);
3661 tcg_temp_free_i32(tmp2
);
3665 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3668 if (size
== 3 || (!q
&& size
== 2)) {
3671 tmp
= tcg_const_i32(rd
);
3672 tmp2
= tcg_const_i32(rm
);
3676 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3679 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3682 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3690 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3693 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3699 tcg_temp_free_i32(tmp
);
3700 tcg_temp_free_i32(tmp2
);
3704 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3708 rd
= tcg_temp_new_i32();
3709 tmp
= tcg_temp_new_i32();
3711 tcg_gen_shli_i32(rd
, t0
, 8);
3712 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3713 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3714 tcg_gen_or_i32(rd
, rd
, tmp
);
3716 tcg_gen_shri_i32(t1
, t1
, 8);
3717 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3718 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3719 tcg_gen_or_i32(t1
, t1
, tmp
);
3720 tcg_gen_mov_i32(t0
, rd
);
3722 tcg_temp_free_i32(tmp
);
3723 tcg_temp_free_i32(rd
);
3726 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3730 rd
= tcg_temp_new_i32();
3731 tmp
= tcg_temp_new_i32();
3733 tcg_gen_shli_i32(rd
, t0
, 16);
3734 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3735 tcg_gen_or_i32(rd
, rd
, tmp
);
3736 tcg_gen_shri_i32(t1
, t1
, 16);
3737 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3738 tcg_gen_or_i32(t1
, t1
, tmp
);
3739 tcg_gen_mov_i32(t0
, rd
);
3741 tcg_temp_free_i32(tmp
);
3742 tcg_temp_free_i32(rd
);
3750 } neon_ls_element_type
[11] = {
3764 /* Translate a NEON load/store element instruction. Return nonzero if the
3765 instruction is invalid. */
3766 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3785 if (!s
->vfp_enabled
)
3787 VFP_DREG_D(rd
, insn
);
3788 rn
= (insn
>> 16) & 0xf;
3790 load
= (insn
& (1 << 21)) != 0;
3791 addr
= tcg_temp_new_i32();
3792 if ((insn
& (1 << 23)) == 0) {
3793 /* Load store all elements. */
3794 op
= (insn
>> 8) & 0xf;
3795 size
= (insn
>> 6) & 3;
3798 nregs
= neon_ls_element_type
[op
].nregs
;
3799 interleave
= neon_ls_element_type
[op
].interleave
;
3800 spacing
= neon_ls_element_type
[op
].spacing
;
3801 if (size
== 3 && (interleave
| spacing
) != 1)
3803 load_reg_var(s
, addr
, rn
);
3804 stride
= (1 << size
) * interleave
;
3805 for (reg
= 0; reg
< nregs
; reg
++) {
3806 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3807 load_reg_var(s
, addr
, rn
);
3808 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3809 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3810 load_reg_var(s
, addr
, rn
);
3811 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3815 tmp64
= gen_ld64(addr
, IS_USER(s
));
3816 neon_store_reg64(tmp64
, rd
);
3817 tcg_temp_free_i64(tmp64
);
3819 tmp64
= tcg_temp_new_i64();
3820 neon_load_reg64(tmp64
, rd
);
3821 gen_st64(tmp64
, addr
, IS_USER(s
));
3823 tcg_gen_addi_i32(addr
, addr
, stride
);
3825 for (pass
= 0; pass
< 2; pass
++) {
3828 tmp
= gen_ld32(addr
, IS_USER(s
));
3829 neon_store_reg(rd
, pass
, tmp
);
3831 tmp
= neon_load_reg(rd
, pass
);
3832 gen_st32(tmp
, addr
, IS_USER(s
));
3834 tcg_gen_addi_i32(addr
, addr
, stride
);
3835 } else if (size
== 1) {
3837 tmp
= gen_ld16u(addr
, IS_USER(s
));
3838 tcg_gen_addi_i32(addr
, addr
, stride
);
3839 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3840 tcg_gen_addi_i32(addr
, addr
, stride
);
3841 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3842 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3843 tcg_temp_free_i32(tmp2
);
3844 neon_store_reg(rd
, pass
, tmp
);
3846 tmp
= neon_load_reg(rd
, pass
);
3847 tmp2
= tcg_temp_new_i32();
3848 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3849 gen_st16(tmp
, addr
, IS_USER(s
));
3850 tcg_gen_addi_i32(addr
, addr
, stride
);
3851 gen_st16(tmp2
, addr
, IS_USER(s
));
3852 tcg_gen_addi_i32(addr
, addr
, stride
);
3854 } else /* size == 0 */ {
3857 for (n
= 0; n
< 4; n
++) {
3858 tmp
= gen_ld8u(addr
, IS_USER(s
));
3859 tcg_gen_addi_i32(addr
, addr
, stride
);
3863 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3864 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3865 tcg_temp_free_i32(tmp
);
3868 neon_store_reg(rd
, pass
, tmp2
);
3870 tmp2
= neon_load_reg(rd
, pass
);
3871 for (n
= 0; n
< 4; n
++) {
3872 tmp
= tcg_temp_new_i32();
3874 tcg_gen_mov_i32(tmp
, tmp2
);
3876 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3878 gen_st8(tmp
, addr
, IS_USER(s
));
3879 tcg_gen_addi_i32(addr
, addr
, stride
);
3881 tcg_temp_free_i32(tmp2
);
3890 size
= (insn
>> 10) & 3;
3892 /* Load single element to all lanes. */
3895 size
= (insn
>> 6) & 3;
3896 nregs
= ((insn
>> 8) & 3) + 1;
3897 stride
= (insn
& (1 << 5)) ? 2 : 1;
3898 load_reg_var(s
, addr
, rn
);
3899 for (reg
= 0; reg
< nregs
; reg
++) {
3902 tmp
= gen_ld8u(addr
, IS_USER(s
));
3903 gen_neon_dup_u8(tmp
, 0);
3906 tmp
= gen_ld16u(addr
, IS_USER(s
));
3907 gen_neon_dup_low16(tmp
);
3910 tmp
= gen_ld32(addr
, IS_USER(s
));
3914 default: /* Avoid compiler warnings. */
3917 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3918 tmp2
= tcg_temp_new_i32();
3919 tcg_gen_mov_i32(tmp2
, tmp
);
3920 neon_store_reg(rd
, 0, tmp2
);
3921 neon_store_reg(rd
, 1, tmp
);
3924 stride
= (1 << size
) * nregs
;
3926 /* Single element. */
3927 pass
= (insn
>> 7) & 1;
3930 shift
= ((insn
>> 5) & 3) * 8;
3934 shift
= ((insn
>> 6) & 1) * 16;
3935 stride
= (insn
& (1 << 5)) ? 2 : 1;
3939 stride
= (insn
& (1 << 6)) ? 2 : 1;
3944 nregs
= ((insn
>> 8) & 3) + 1;
3945 load_reg_var(s
, addr
, rn
);
3946 for (reg
= 0; reg
< nregs
; reg
++) {
3950 tmp
= gen_ld8u(addr
, IS_USER(s
));
3953 tmp
= gen_ld16u(addr
, IS_USER(s
));
3956 tmp
= gen_ld32(addr
, IS_USER(s
));
3958 default: /* Avoid compiler warnings. */
3962 tmp2
= neon_load_reg(rd
, pass
);
3963 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
3964 tcg_temp_free_i32(tmp2
);
3966 neon_store_reg(rd
, pass
, tmp
);
3967 } else { /* Store */
3968 tmp
= neon_load_reg(rd
, pass
);
3970 tcg_gen_shri_i32(tmp
, tmp
, shift
);
3973 gen_st8(tmp
, addr
, IS_USER(s
));
3976 gen_st16(tmp
, addr
, IS_USER(s
));
3979 gen_st32(tmp
, addr
, IS_USER(s
));
3984 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3986 stride
= nregs
* (1 << size
);
3989 tcg_temp_free_i32(addr
);
3993 base
= load_reg(s
, rn
);
3995 tcg_gen_addi_i32(base
, base
, stride
);
3998 index
= load_reg(s
, rm
);
3999 tcg_gen_add_i32(base
, base
, index
);
4000 tcg_temp_free_i32(index
);
4002 store_reg(s
, rn
, base
);
4007 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4008 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4010 tcg_gen_and_i32(t
, t
, c
);
4011 tcg_gen_andc_i32(f
, f
, c
);
4012 tcg_gen_or_i32(dest
, t
, f
);
4015 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4018 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4019 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4020 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4025 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4028 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4029 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4030 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4035 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4038 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4039 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4040 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4045 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4048 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4049 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4050 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4055 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4061 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4062 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4067 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4068 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4075 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4076 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4081 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4082 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4089 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4093 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4094 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4095 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4100 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4101 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4102 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4106 tcg_temp_free_i32(src
);
4109 static inline void gen_neon_addl(int size
)
4112 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4113 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4114 case 2: tcg_gen_add_i64(CPU_V001
); break;
4119 static inline void gen_neon_subl(int size
)
4122 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4123 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4124 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4129 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4132 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4133 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4134 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4139 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4142 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4143 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4148 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4152 switch ((size
<< 1) | u
) {
4153 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4154 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4155 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4156 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4158 tmp
= gen_muls_i64_i32(a
, b
);
4159 tcg_gen_mov_i64(dest
, tmp
);
4162 tmp
= gen_mulu_i64_i32(a
, b
);
4163 tcg_gen_mov_i64(dest
, tmp
);
4168 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4169 Don't forget to clean them now. */
4171 tcg_temp_free_i32(a
);
4172 tcg_temp_free_i32(b
);
4176 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4180 gen_neon_unarrow_sats(size
, dest
, src
);
4182 gen_neon_narrow(size
, dest
, src
);
4186 gen_neon_narrow_satu(size
, dest
, src
);
4188 gen_neon_narrow_sats(size
, dest
, src
);
4193 /* Translate a NEON data processing instruction. Return nonzero if the
4194 instruction is invalid.
4195 We process data in a mixture of 32-bit and 64-bit chunks.
4196 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4198 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4211 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4214 if (!s
->vfp_enabled
)
4216 q
= (insn
& (1 << 6)) != 0;
4217 u
= (insn
>> 24) & 1;
4218 VFP_DREG_D(rd
, insn
);
4219 VFP_DREG_N(rn
, insn
);
4220 VFP_DREG_M(rm
, insn
);
4221 size
= (insn
>> 20) & 3;
4222 if ((insn
& (1 << 23)) == 0) {
4223 /* Three register same length. */
4224 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4225 if (size
== 3 && (op
== 1 || op
== 5 || op
== 8 || op
== 9
4226 || op
== 10 || op
== 11 || op
== 16)) {
4227 /* 64-bit element instructions. */
4228 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4229 neon_load_reg64(cpu_V0
, rn
+ pass
);
4230 neon_load_reg64(cpu_V1
, rm
+ pass
);
4234 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4237 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4243 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4246 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4252 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4254 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4259 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4262 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4266 case 10: /* VRSHL */
4268 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4270 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4273 case 11: /* VQRSHL */
4275 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4278 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4284 tcg_gen_sub_i64(CPU_V001
);
4286 tcg_gen_add_i64(CPU_V001
);
4292 neon_store_reg64(cpu_V0
, rd
+ pass
);
4299 case 10: /* VRSHL */
4300 case 11: /* VQRSHL */
4303 /* Shift instruction operands are reversed. */
4310 case 20: /* VPMAX */
4311 case 21: /* VPMIN */
4312 case 23: /* VPADD */
4315 case 26: /* VPADD (float) */
4316 pairwise
= (u
&& size
< 2);
4318 case 30: /* VPMIN/VPMAX (float) */
4326 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4335 tmp
= neon_load_reg(rn
, n
);
4336 tmp2
= neon_load_reg(rn
, n
+ 1);
4338 tmp
= neon_load_reg(rm
, n
);
4339 tmp2
= neon_load_reg(rm
, n
+ 1);
4343 tmp
= neon_load_reg(rn
, pass
);
4344 tmp2
= neon_load_reg(rm
, pass
);
4348 GEN_NEON_INTEGER_OP(hadd
);
4351 GEN_NEON_INTEGER_OP_ENV(qadd
);
4353 case 2: /* VRHADD */
4354 GEN_NEON_INTEGER_OP(rhadd
);
4356 case 3: /* Logic ops. */
4357 switch ((u
<< 2) | size
) {
4359 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4362 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4365 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4368 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4371 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4374 tmp3
= neon_load_reg(rd
, pass
);
4375 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4376 tcg_temp_free_i32(tmp3
);
4379 tmp3
= neon_load_reg(rd
, pass
);
4380 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4381 tcg_temp_free_i32(tmp3
);
4384 tmp3
= neon_load_reg(rd
, pass
);
4385 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4386 tcg_temp_free_i32(tmp3
);
4391 GEN_NEON_INTEGER_OP(hsub
);
4394 GEN_NEON_INTEGER_OP_ENV(qsub
);
4397 GEN_NEON_INTEGER_OP(cgt
);
4400 GEN_NEON_INTEGER_OP(cge
);
4403 GEN_NEON_INTEGER_OP(shl
);
4406 GEN_NEON_INTEGER_OP_ENV(qshl
);
4408 case 10: /* VRSHL */
4409 GEN_NEON_INTEGER_OP(rshl
);
4411 case 11: /* VQRSHL */
4412 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4415 GEN_NEON_INTEGER_OP(max
);
4418 GEN_NEON_INTEGER_OP(min
);
4421 GEN_NEON_INTEGER_OP(abd
);
4424 GEN_NEON_INTEGER_OP(abd
);
4425 tcg_temp_free_i32(tmp2
);
4426 tmp2
= neon_load_reg(rd
, pass
);
4427 gen_neon_add(size
, tmp
, tmp2
);
4430 if (!u
) { /* VADD */
4431 if (gen_neon_add(size
, tmp
, tmp2
))
4435 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4436 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4437 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4443 if (!u
) { /* VTST */
4445 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4446 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4447 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4452 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4453 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4454 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4459 case 18: /* Multiply. */
4461 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4462 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4463 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4466 tcg_temp_free_i32(tmp2
);
4467 tmp2
= neon_load_reg(rd
, pass
);
4469 gen_neon_rsb(size
, tmp
, tmp2
);
4471 gen_neon_add(size
, tmp
, tmp2
);
4475 if (u
) { /* polynomial */
4476 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4477 } else { /* Integer */
4479 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4480 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4481 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4486 case 20: /* VPMAX */
4487 GEN_NEON_INTEGER_OP(pmax
);
4489 case 21: /* VPMIN */
4490 GEN_NEON_INTEGER_OP(pmin
);
4492 case 22: /* Hultiply high. */
4493 if (!u
) { /* VQDMULH */
4495 case 1: gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4496 case 2: gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4499 } else { /* VQRDHMUL */
4501 case 1: gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
); break;
4502 case 2: gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
); break;
4507 case 23: /* VPADD */
4511 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4512 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4513 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4517 case 26: /* Floating point arithnetic. */
4518 switch ((u
<< 2) | size
) {
4520 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4523 gen_helper_neon_sub_f32(tmp
, tmp
, tmp2
);
4526 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4529 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
);
4535 case 27: /* Float multiply. */
4536 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
4538 tcg_temp_free_i32(tmp2
);
4539 tmp2
= neon_load_reg(rd
, pass
);
4541 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4543 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
4547 case 28: /* Float compare. */
4549 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
4552 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
4554 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
4557 case 29: /* Float compare absolute. */
4561 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
);
4563 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
);
4565 case 30: /* Float min/max. */
4567 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
);
4569 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
);
4573 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4575 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4580 tcg_temp_free_i32(tmp2
);
4582 /* Save the result. For elementwise operations we can put it
4583 straight into the destination register. For pairwise operations
4584 we have to be careful to avoid clobbering the source operands. */
4585 if (pairwise
&& rd
== rm
) {
4586 neon_store_scratch(pass
, tmp
);
4588 neon_store_reg(rd
, pass
, tmp
);
4592 if (pairwise
&& rd
== rm
) {
4593 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4594 tmp
= neon_load_scratch(pass
);
4595 neon_store_reg(rd
, pass
, tmp
);
4598 /* End of 3 register same size operations. */
4599 } else if (insn
& (1 << 4)) {
4600 if ((insn
& 0x00380080) != 0) {
4601 /* Two registers and shift. */
4602 op
= (insn
>> 8) & 0xf;
4603 if (insn
& (1 << 7)) {
4608 while ((insn
& (1 << (size
+ 19))) == 0)
4611 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4612 /* To avoid excessive dumplication of ops we implement shift
4613 by immediate using the variable shift operations. */
4615 /* Shift by immediate:
4616 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4617 /* Right shifts are encoded as N - shift, where N is the
4618 element size in bits. */
4620 shift
= shift
- (1 << (size
+ 3));
4628 imm
= (uint8_t) shift
;
4633 imm
= (uint16_t) shift
;
4644 for (pass
= 0; pass
< count
; pass
++) {
4646 neon_load_reg64(cpu_V0
, rm
+ pass
);
4647 tcg_gen_movi_i64(cpu_V1
, imm
);
4652 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4654 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4659 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4661 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4666 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4668 case 5: /* VSHL, VSLI */
4669 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4671 case 6: /* VQSHLU */
4673 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
4681 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4684 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4689 if (op
== 1 || op
== 3) {
4691 neon_load_reg64(cpu_V1
, rd
+ pass
);
4692 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4693 } else if (op
== 4 || (op
== 5 && u
)) {
4695 neon_load_reg64(cpu_V1
, rd
+ pass
);
4697 if (shift
< -63 || shift
> 63) {
4701 mask
= 0xffffffffffffffffull
>> -shift
;
4703 mask
= 0xffffffffffffffffull
<< shift
;
4706 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
4707 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4709 neon_store_reg64(cpu_V0
, rd
+ pass
);
4710 } else { /* size < 3 */
4711 /* Operands in T0 and T1. */
4712 tmp
= neon_load_reg(rm
, pass
);
4713 tmp2
= tcg_temp_new_i32();
4714 tcg_gen_movi_i32(tmp2
, imm
);
4718 GEN_NEON_INTEGER_OP(shl
);
4722 GEN_NEON_INTEGER_OP(rshl
);
4727 GEN_NEON_INTEGER_OP(shl
);
4729 case 5: /* VSHL, VSLI */
4731 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
4732 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
4733 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
4737 case 6: /* VQSHLU */
4743 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
4747 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
4751 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
4759 GEN_NEON_INTEGER_OP_ENV(qshl
);
4762 tcg_temp_free_i32(tmp2
);
4764 if (op
== 1 || op
== 3) {
4766 tmp2
= neon_load_reg(rd
, pass
);
4767 gen_neon_add(size
, tmp
, tmp2
);
4768 tcg_temp_free_i32(tmp2
);
4769 } else if (op
== 4 || (op
== 5 && u
)) {
4774 mask
= 0xff >> -shift
;
4776 mask
= (uint8_t)(0xff << shift
);
4782 mask
= 0xffff >> -shift
;
4784 mask
= (uint16_t)(0xffff << shift
);
4788 if (shift
< -31 || shift
> 31) {
4792 mask
= 0xffffffffu
>> -shift
;
4794 mask
= 0xffffffffu
<< shift
;
4800 tmp2
= neon_load_reg(rd
, pass
);
4801 tcg_gen_andi_i32(tmp
, tmp
, mask
);
4802 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
4803 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4804 tcg_temp_free_i32(tmp2
);
4806 neon_store_reg(rd
, pass
, tmp
);
4809 } else if (op
< 10) {
4810 /* Shift by immediate and narrow:
4811 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4812 int input_unsigned
= (op
== 8) ? !u
: u
;
4814 shift
= shift
- (1 << (size
+ 3));
4817 tmp64
= tcg_const_i64(shift
);
4818 neon_load_reg64(cpu_V0
, rm
);
4819 neon_load_reg64(cpu_V1
, rm
+ 1);
4820 for (pass
= 0; pass
< 2; pass
++) {
4828 if (input_unsigned
) {
4829 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
4831 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
4834 if (input_unsigned
) {
4835 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
4837 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
4840 tmp
= tcg_temp_new_i32();
4841 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4842 neon_store_reg(rd
, pass
, tmp
);
4844 tcg_temp_free_i64(tmp64
);
4847 imm
= (uint16_t)shift
;
4851 imm
= (uint32_t)shift
;
4853 tmp2
= tcg_const_i32(imm
);
4854 tmp4
= neon_load_reg(rm
+ 1, 0);
4855 tmp5
= neon_load_reg(rm
+ 1, 1);
4856 for (pass
= 0; pass
< 2; pass
++) {
4858 tmp
= neon_load_reg(rm
, 0);
4862 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
4865 tmp3
= neon_load_reg(rm
, 1);
4869 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
4871 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
4872 tcg_temp_free_i32(tmp
);
4873 tcg_temp_free_i32(tmp3
);
4874 tmp
= tcg_temp_new_i32();
4875 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4876 neon_store_reg(rd
, pass
, tmp
);
4878 tcg_temp_free_i32(tmp2
);
4880 } else if (op
== 10) {
4884 tmp
= neon_load_reg(rm
, 0);
4885 tmp2
= neon_load_reg(rm
, 1);
4886 for (pass
= 0; pass
< 2; pass
++) {
4890 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
4893 /* The shift is less than the width of the source
4894 type, so we can just shift the whole register. */
4895 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
4896 /* Widen the result of shift: we need to clear
4897 * the potential overflow bits resulting from
4898 * left bits of the narrow input appearing as
4899 * right bits of left the neighbour narrow
4901 if (size
< 2 || !u
) {
4904 imm
= (0xffu
>> (8 - shift
));
4906 } else if (size
== 1) {
4907 imm
= 0xffff >> (16 - shift
);
4910 imm
= 0xffffffff >> (32 - shift
);
4913 imm64
= imm
| (((uint64_t)imm
) << 32);
4917 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
4920 neon_store_reg64(cpu_V0
, rd
+ pass
);
4922 } else if (op
>= 14) {
4923 /* VCVT fixed-point. */
4924 /* We have already masked out the must-be-1 top bit of imm6,
4925 * hence this 32-shift where the ARM ARM has 64-imm6.
4928 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4929 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
4932 gen_vfp_ulto(0, shift
);
4934 gen_vfp_slto(0, shift
);
4937 gen_vfp_toul(0, shift
);
4939 gen_vfp_tosl(0, shift
);
4941 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
4946 } else { /* (insn & 0x00380080) == 0 */
4949 op
= (insn
>> 8) & 0xf;
4950 /* One register and immediate. */
4951 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
4952 invert
= (insn
& (1 << 5)) != 0;
4970 imm
= (imm
<< 8) | (imm
<< 24);
4973 imm
= (imm
<< 8) | 0xff;
4976 imm
= (imm
<< 16) | 0xffff;
4979 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
4984 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
4985 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
4991 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4992 if (op
& 1 && op
< 12) {
4993 tmp
= neon_load_reg(rd
, pass
);
4995 /* The immediate value has already been inverted, so
4997 tcg_gen_andi_i32(tmp
, tmp
, imm
);
4999 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5003 tmp
= tcg_temp_new_i32();
5004 if (op
== 14 && invert
) {
5007 for (n
= 0; n
< 4; n
++) {
5008 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5009 val
|= 0xff << (n
* 8);
5011 tcg_gen_movi_i32(tmp
, val
);
5013 tcg_gen_movi_i32(tmp
, imm
);
5016 neon_store_reg(rd
, pass
, tmp
);
5019 } else { /* (insn & 0x00800010 == 0x00800000) */
5021 op
= (insn
>> 8) & 0xf;
5022 if ((insn
& (1 << 6)) == 0) {
5023 /* Three registers of different lengths. */
5027 /* prewiden, src1_wide, src2_wide */
5028 static const int neon_3reg_wide
[16][3] = {
5029 {1, 0, 0}, /* VADDL */
5030 {1, 1, 0}, /* VADDW */
5031 {1, 0, 0}, /* VSUBL */
5032 {1, 1, 0}, /* VSUBW */
5033 {0, 1, 1}, /* VADDHN */
5034 {0, 0, 0}, /* VABAL */
5035 {0, 1, 1}, /* VSUBHN */
5036 {0, 0, 0}, /* VABDL */
5037 {0, 0, 0}, /* VMLAL */
5038 {0, 0, 0}, /* VQDMLAL */
5039 {0, 0, 0}, /* VMLSL */
5040 {0, 0, 0}, /* VQDMLSL */
5041 {0, 0, 0}, /* Integer VMULL */
5042 {0, 0, 0}, /* VQDMULL */
5043 {0, 0, 0} /* Polynomial VMULL */
5046 prewiden
= neon_3reg_wide
[op
][0];
5047 src1_wide
= neon_3reg_wide
[op
][1];
5048 src2_wide
= neon_3reg_wide
[op
][2];
5050 if (size
== 0 && (op
== 9 || op
== 11 || op
== 13))
5053 /* Avoid overlapping operands. Wide source operands are
5054 always aligned so will never overlap with wide
5055 destinations in problematic ways. */
5056 if (rd
== rm
&& !src2_wide
) {
5057 tmp
= neon_load_reg(rm
, 1);
5058 neon_store_scratch(2, tmp
);
5059 } else if (rd
== rn
&& !src1_wide
) {
5060 tmp
= neon_load_reg(rn
, 1);
5061 neon_store_scratch(2, tmp
);
5064 for (pass
= 0; pass
< 2; pass
++) {
5066 neon_load_reg64(cpu_V0
, rn
+ pass
);
5069 if (pass
== 1 && rd
== rn
) {
5070 tmp
= neon_load_scratch(2);
5072 tmp
= neon_load_reg(rn
, pass
);
5075 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5079 neon_load_reg64(cpu_V1
, rm
+ pass
);
5082 if (pass
== 1 && rd
== rm
) {
5083 tmp2
= neon_load_scratch(2);
5085 tmp2
= neon_load_reg(rm
, pass
);
5088 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5092 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5093 gen_neon_addl(size
);
5095 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5096 gen_neon_subl(size
);
5098 case 5: case 7: /* VABAL, VABDL */
5099 switch ((size
<< 1) | u
) {
5101 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5104 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5107 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5110 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5113 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5116 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5120 tcg_temp_free_i32(tmp2
);
5121 tcg_temp_free_i32(tmp
);
5123 case 8: case 9: case 10: case 11: case 12: case 13:
5124 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5125 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5127 case 14: /* Polynomial VMULL */
5128 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5129 tcg_temp_free_i32(tmp2
);
5130 tcg_temp_free_i32(tmp
);
5132 default: /* 15 is RESERVED. */
5137 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5138 neon_store_reg64(cpu_V0
, rd
+ pass
);
5139 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5141 neon_load_reg64(cpu_V1
, rd
+ pass
);
5143 case 10: /* VMLSL */
5144 gen_neon_negl(cpu_V0
, size
);
5146 case 5: case 8: /* VABAL, VMLAL */
5147 gen_neon_addl(size
);
5149 case 9: case 11: /* VQDMLAL, VQDMLSL */
5150 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5152 gen_neon_negl(cpu_V0
, size
);
5154 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5159 neon_store_reg64(cpu_V0
, rd
+ pass
);
5160 } else if (op
== 4 || op
== 6) {
5161 /* Narrowing operation. */
5162 tmp
= tcg_temp_new_i32();
5166 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5169 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5172 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5173 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5180 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5183 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5186 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5187 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5188 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5196 neon_store_reg(rd
, 0, tmp3
);
5197 neon_store_reg(rd
, 1, tmp
);
5200 /* Write back the result. */
5201 neon_store_reg64(cpu_V0
, rd
+ pass
);
5205 /* Two registers and a scalar. */
5207 case 0: /* Integer VMLA scalar */
5208 case 1: /* Float VMLA scalar */
5209 case 4: /* Integer VMLS scalar */
5210 case 5: /* Floating point VMLS scalar */
5211 case 8: /* Integer VMUL scalar */
5212 case 9: /* Floating point VMUL scalar */
5213 case 12: /* VQDMULH scalar */
5214 case 13: /* VQRDMULH scalar */
5215 tmp
= neon_get_scalar(size
, rm
);
5216 neon_store_scratch(0, tmp
);
5217 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5218 tmp
= neon_load_scratch(0);
5219 tmp2
= neon_load_reg(rn
, pass
);
5222 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5224 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5226 } else if (op
== 13) {
5228 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5230 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5232 } else if (op
& 1) {
5233 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
5236 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5237 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5238 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5242 tcg_temp_free_i32(tmp2
);
5245 tmp2
= neon_load_reg(rd
, pass
);
5248 gen_neon_add(size
, tmp
, tmp2
);
5251 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
5254 gen_neon_rsb(size
, tmp
, tmp2
);
5257 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
5262 tcg_temp_free_i32(tmp2
);
5264 neon_store_reg(rd
, pass
, tmp
);
5267 case 2: /* VMLAL sclar */
5268 case 3: /* VQDMLAL scalar */
5269 case 6: /* VMLSL scalar */
5270 case 7: /* VQDMLSL scalar */
5271 case 10: /* VMULL scalar */
5272 case 11: /* VQDMULL scalar */
5273 if (size
== 0 && (op
== 3 || op
== 7 || op
== 11))
5276 tmp2
= neon_get_scalar(size
, rm
);
5277 /* We need a copy of tmp2 because gen_neon_mull
5278 * deletes it during pass 0. */
5279 tmp4
= tcg_temp_new_i32();
5280 tcg_gen_mov_i32(tmp4
, tmp2
);
5281 tmp3
= neon_load_reg(rn
, 1);
5283 for (pass
= 0; pass
< 2; pass
++) {
5285 tmp
= neon_load_reg(rn
, 0);
5290 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5292 neon_load_reg64(cpu_V1
, rd
+ pass
);
5296 gen_neon_negl(cpu_V0
, size
);
5299 gen_neon_addl(size
);
5302 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5304 gen_neon_negl(cpu_V0
, size
);
5306 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5312 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5317 neon_store_reg64(cpu_V0
, rd
+ pass
);
5322 default: /* 14 and 15 are RESERVED */
5326 } else { /* size == 3 */
5329 imm
= (insn
>> 8) & 0xf;
5335 neon_load_reg64(cpu_V0
, rn
);
5337 neon_load_reg64(cpu_V1
, rn
+ 1);
5339 } else if (imm
== 8) {
5340 neon_load_reg64(cpu_V0
, rn
+ 1);
5342 neon_load_reg64(cpu_V1
, rm
);
5345 tmp64
= tcg_temp_new_i64();
5347 neon_load_reg64(cpu_V0
, rn
);
5348 neon_load_reg64(tmp64
, rn
+ 1);
5350 neon_load_reg64(cpu_V0
, rn
+ 1);
5351 neon_load_reg64(tmp64
, rm
);
5353 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5354 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5355 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5357 neon_load_reg64(cpu_V1
, rm
);
5359 neon_load_reg64(cpu_V1
, rm
+ 1);
5362 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5363 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5364 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5365 tcg_temp_free_i64(tmp64
);
5368 neon_load_reg64(cpu_V0
, rn
);
5369 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5370 neon_load_reg64(cpu_V1
, rm
);
5371 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5372 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5374 neon_store_reg64(cpu_V0
, rd
);
5376 neon_store_reg64(cpu_V1
, rd
+ 1);
5378 } else if ((insn
& (1 << 11)) == 0) {
5379 /* Two register misc. */
5380 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5381 size
= (insn
>> 18) & 3;
5383 case 0: /* VREV64 */
5386 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5387 tmp
= neon_load_reg(rm
, pass
* 2);
5388 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5390 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5391 case 1: gen_swap_half(tmp
); break;
5392 case 2: /* no-op */ break;
5395 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5397 neon_store_reg(rd
, pass
* 2, tmp2
);
5400 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5401 case 1: gen_swap_half(tmp2
); break;
5404 neon_store_reg(rd
, pass
* 2, tmp2
);
5408 case 4: case 5: /* VPADDL */
5409 case 12: case 13: /* VPADAL */
5412 for (pass
= 0; pass
< q
+ 1; pass
++) {
5413 tmp
= neon_load_reg(rm
, pass
* 2);
5414 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5415 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5416 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5418 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5419 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5420 case 2: tcg_gen_add_i64(CPU_V001
); break;
5425 neon_load_reg64(cpu_V1
, rd
+ pass
);
5426 gen_neon_addl(size
);
5428 neon_store_reg64(cpu_V0
, rd
+ pass
);
5433 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5434 tmp
= neon_load_reg(rm
, n
);
5435 tmp2
= neon_load_reg(rd
, n
+ 1);
5436 neon_store_reg(rm
, n
, tmp2
);
5437 neon_store_reg(rd
, n
+ 1, tmp
);
5444 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5449 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5453 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5457 for (pass
= 0; pass
< 2; pass
++) {
5458 neon_load_reg64(cpu_V0
, rm
+ pass
);
5459 tmp
= tcg_temp_new_i32();
5460 gen_neon_narrow_op(op
== 36, q
, size
, tmp
, cpu_V0
);
5464 neon_store_reg(rd
, 0, tmp2
);
5465 neon_store_reg(rd
, 1, tmp
);
5469 case 38: /* VSHLL */
5472 tmp
= neon_load_reg(rm
, 0);
5473 tmp2
= neon_load_reg(rm
, 1);
5474 for (pass
= 0; pass
< 2; pass
++) {
5477 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5478 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5479 neon_store_reg64(cpu_V0
, rd
+ pass
);
5482 case 44: /* VCVT.F16.F32 */
5483 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5485 tmp
= tcg_temp_new_i32();
5486 tmp2
= tcg_temp_new_i32();
5487 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5488 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5489 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5490 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5491 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5492 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5493 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5494 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5495 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5496 neon_store_reg(rd
, 0, tmp2
);
5497 tmp2
= tcg_temp_new_i32();
5498 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5499 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5500 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5501 neon_store_reg(rd
, 1, tmp2
);
5502 tcg_temp_free_i32(tmp
);
5504 case 46: /* VCVT.F32.F16 */
5505 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5507 tmp3
= tcg_temp_new_i32();
5508 tmp
= neon_load_reg(rm
, 0);
5509 tmp2
= neon_load_reg(rm
, 1);
5510 tcg_gen_ext16u_i32(tmp3
, tmp
);
5511 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5512 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5513 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5514 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5515 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5516 tcg_temp_free_i32(tmp
);
5517 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5518 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5519 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5520 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5521 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5522 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5523 tcg_temp_free_i32(tmp2
);
5524 tcg_temp_free_i32(tmp3
);
5528 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5529 if (op
== 30 || op
== 31 || op
>= 58) {
5530 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5531 neon_reg_offset(rm
, pass
));
5534 tmp
= neon_load_reg(rm
, pass
);
5537 case 1: /* VREV32 */
5539 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5540 case 1: gen_swap_half(tmp
); break;
5544 case 2: /* VREV16 */
5551 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5552 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5553 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5559 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5560 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5561 case 2: gen_helper_clz(tmp
, tmp
); break;
5568 gen_helper_neon_cnt_u8(tmp
, tmp
);
5573 tcg_gen_not_i32(tmp
, tmp
);
5575 case 14: /* VQABS */
5577 case 0: gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
); break;
5578 case 1: gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
); break;
5579 case 2: gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
); break;
5583 case 15: /* VQNEG */
5585 case 0: gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
); break;
5586 case 1: gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
); break;
5587 case 2: gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
); break;
5591 case 16: case 19: /* VCGT #0, VCLE #0 */
5592 tmp2
= tcg_const_i32(0);
5594 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5595 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5596 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5599 tcg_temp_free(tmp2
);
5601 tcg_gen_not_i32(tmp
, tmp
);
5603 case 17: case 20: /* VCGE #0, VCLT #0 */
5604 tmp2
= tcg_const_i32(0);
5606 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5607 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5608 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5611 tcg_temp_free(tmp2
);
5613 tcg_gen_not_i32(tmp
, tmp
);
5615 case 18: /* VCEQ #0 */
5616 tmp2
= tcg_const_i32(0);
5618 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5619 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5620 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5623 tcg_temp_free(tmp2
);
5627 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
5628 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
5629 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
5636 tmp2
= tcg_const_i32(0);
5637 gen_neon_rsb(size
, tmp
, tmp2
);
5638 tcg_temp_free(tmp2
);
5640 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5641 tmp2
= tcg_const_i32(0);
5642 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
5643 tcg_temp_free(tmp2
);
5645 tcg_gen_not_i32(tmp
, tmp
);
5647 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5648 tmp2
= tcg_const_i32(0);
5649 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
5650 tcg_temp_free(tmp2
);
5652 tcg_gen_not_i32(tmp
, tmp
);
5654 case 26: /* Float VCEQ #0 */
5655 tmp2
= tcg_const_i32(0);
5656 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
5657 tcg_temp_free(tmp2
);
5659 case 30: /* Float VABS */
5662 case 31: /* Float VNEG */
5666 tmp2
= neon_load_reg(rd
, pass
);
5667 neon_store_reg(rm
, pass
, tmp2
);
5670 tmp2
= neon_load_reg(rd
, pass
);
5672 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
5673 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
5677 neon_store_reg(rm
, pass
, tmp2
);
5679 case 56: /* Integer VRECPE */
5680 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
5682 case 57: /* Integer VRSQRTE */
5683 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
5685 case 58: /* Float VRECPE */
5686 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5688 case 59: /* Float VRSQRTE */
5689 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5691 case 60: /* VCVT.F32.S32 */
5694 case 61: /* VCVT.F32.U32 */
5697 case 62: /* VCVT.S32.F32 */
5700 case 63: /* VCVT.U32.F32 */
5704 /* Reserved: 21, 29, 39-56 */
5707 if (op
== 30 || op
== 31 || op
>= 58) {
5708 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
5709 neon_reg_offset(rd
, pass
));
5711 neon_store_reg(rd
, pass
, tmp
);
5716 } else if ((insn
& (1 << 10)) == 0) {
5718 n
= ((insn
>> 5) & 0x18) + 8;
5719 if (insn
& (1 << 6)) {
5720 tmp
= neon_load_reg(rd
, 0);
5722 tmp
= tcg_temp_new_i32();
5723 tcg_gen_movi_i32(tmp
, 0);
5725 tmp2
= neon_load_reg(rm
, 0);
5726 tmp4
= tcg_const_i32(rn
);
5727 tmp5
= tcg_const_i32(n
);
5728 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
5729 tcg_temp_free_i32(tmp
);
5730 if (insn
& (1 << 6)) {
5731 tmp
= neon_load_reg(rd
, 1);
5733 tmp
= tcg_temp_new_i32();
5734 tcg_gen_movi_i32(tmp
, 0);
5736 tmp3
= neon_load_reg(rm
, 1);
5737 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
5738 tcg_temp_free_i32(tmp5
);
5739 tcg_temp_free_i32(tmp4
);
5740 neon_store_reg(rd
, 0, tmp2
);
5741 neon_store_reg(rd
, 1, tmp3
);
5742 tcg_temp_free_i32(tmp
);
5743 } else if ((insn
& 0x380) == 0) {
5745 if (insn
& (1 << 19)) {
5746 tmp
= neon_load_reg(rm
, 1);
5748 tmp
= neon_load_reg(rm
, 0);
5750 if (insn
& (1 << 16)) {
5751 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
5752 } else if (insn
& (1 << 17)) {
5753 if ((insn
>> 18) & 1)
5754 gen_neon_dup_high16(tmp
);
5756 gen_neon_dup_low16(tmp
);
5758 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5759 tmp2
= tcg_temp_new_i32();
5760 tcg_gen_mov_i32(tmp2
, tmp
);
5761 neon_store_reg(rd
, pass
, tmp2
);
5763 tcg_temp_free_i32(tmp
);
5772 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5774 int crn
= (insn
>> 16) & 0xf;
5775 int crm
= insn
& 0xf;
5776 int op1
= (insn
>> 21) & 7;
5777 int op2
= (insn
>> 5) & 7;
5778 int rt
= (insn
>> 12) & 0xf;
5781 /* Minimal set of debug registers, since we don't support debug */
5782 if (op1
== 0 && crn
== 0 && op2
== 0) {
5785 /* DBGDIDR: just RAZ. In particular this means the
5786 * "debug architecture version" bits will read as
5787 * a reserved value, which should cause Linux to
5788 * not try to use the debug hardware.
5790 tmp
= tcg_const_i32(0);
5791 store_reg(s
, rt
, tmp
);
5795 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
5796 * don't implement memory mapped debug components
5798 if (ENABLE_ARCH_7
) {
5799 tmp
= tcg_const_i32(0);
5800 store_reg(s
, rt
, tmp
);
5809 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5810 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5814 tmp
= load_cpu_field(teecr
);
5815 store_reg(s
, rt
, tmp
);
5818 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5820 if (IS_USER(s
) && (env
->teecr
& 1))
5822 tmp
= load_cpu_field(teehbr
);
5823 store_reg(s
, rt
, tmp
);
5827 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5828 op1
, crn
, crm
, op2
);
5832 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5834 int crn
= (insn
>> 16) & 0xf;
5835 int crm
= insn
& 0xf;
5836 int op1
= (insn
>> 21) & 7;
5837 int op2
= (insn
>> 5) & 7;
5838 int rt
= (insn
>> 12) & 0xf;
5841 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5842 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5846 tmp
= load_reg(s
, rt
);
5847 gen_helper_set_teecr(cpu_env
, tmp
);
5848 tcg_temp_free_i32(tmp
);
5851 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5853 if (IS_USER(s
) && (env
->teecr
& 1))
5855 tmp
= load_reg(s
, rt
);
5856 store_cpu_field(tmp
, teehbr
);
5860 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5861 op1
, crn
, crm
, op2
);
5865 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5869 cpnum
= (insn
>> 8) & 0xf;
5870 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
5871 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
5877 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
5878 return disas_iwmmxt_insn(env
, s
, insn
);
5879 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
5880 return disas_dsp_insn(env
, s
, insn
);
5885 return disas_vfp_insn (env
, s
, insn
);
5887 /* Coprocessors 7-15 are architecturally reserved by ARM.
5888 Unfortunately Intel decided to ignore this. */
5889 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
5891 if (insn
& (1 << 20))
5892 return disas_cp14_read(env
, s
, insn
);
5894 return disas_cp14_write(env
, s
, insn
);
5896 return disas_cp15_insn (env
, s
, insn
);
5899 /* Unknown coprocessor. See if the board has hooked it. */
5900 return disas_cp_insn (env
, s
, insn
);
5905 /* Store a 64-bit value to a register pair. Clobbers val. */
5906 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
5909 tmp
= tcg_temp_new_i32();
5910 tcg_gen_trunc_i64_i32(tmp
, val
);
5911 store_reg(s
, rlow
, tmp
);
5912 tmp
= tcg_temp_new_i32();
5913 tcg_gen_shri_i64(val
, val
, 32);
5914 tcg_gen_trunc_i64_i32(tmp
, val
);
5915 store_reg(s
, rhigh
, tmp
);
5918 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5919 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
5924 /* Load value and extend to 64 bits. */
5925 tmp
= tcg_temp_new_i64();
5926 tmp2
= load_reg(s
, rlow
);
5927 tcg_gen_extu_i32_i64(tmp
, tmp2
);
5928 tcg_temp_free_i32(tmp2
);
5929 tcg_gen_add_i64(val
, val
, tmp
);
5930 tcg_temp_free_i64(tmp
);
5933 /* load and add a 64-bit value from a register pair. */
5934 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
5940 /* Load 64-bit value rd:rn. */
5941 tmpl
= load_reg(s
, rlow
);
5942 tmph
= load_reg(s
, rhigh
);
5943 tmp
= tcg_temp_new_i64();
5944 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
5945 tcg_temp_free_i32(tmpl
);
5946 tcg_temp_free_i32(tmph
);
5947 tcg_gen_add_i64(val
, val
, tmp
);
5948 tcg_temp_free_i64(tmp
);
5951 /* Set N and Z flags from a 64-bit value. */
5952 static void gen_logicq_cc(TCGv_i64 val
)
5954 TCGv tmp
= tcg_temp_new_i32();
5955 gen_helper_logicq_cc(tmp
, val
);
5957 tcg_temp_free_i32(tmp
);
5960 /* Load/Store exclusive instructions are implemented by remembering
5961 the value/address loaded, and seeing if these are the same
5962 when the store is performed. This should be is sufficient to implement
5963 the architecturally mandated semantics, and avoids having to monitor
5966 In system emulation mode only one CPU will be running at once, so
5967 this sequence is effectively atomic. In user emulation mode we
5968 throw an exception and handle the atomic operation elsewhere. */
5969 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
5970 TCGv addr
, int size
)
5976 tmp
= gen_ld8u(addr
, IS_USER(s
));
5979 tmp
= gen_ld16u(addr
, IS_USER(s
));
5983 tmp
= gen_ld32(addr
, IS_USER(s
));
5988 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
5989 store_reg(s
, rt
, tmp
);
5991 TCGv tmp2
= tcg_temp_new_i32();
5992 tcg_gen_addi_i32(tmp2
, addr
, 4);
5993 tmp
= gen_ld32(tmp2
, IS_USER(s
));
5994 tcg_temp_free_i32(tmp2
);
5995 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
5996 store_reg(s
, rt2
, tmp
);
5998 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6001 static void gen_clrex(DisasContext
*s
)
6003 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6006 #ifdef CONFIG_USER_ONLY
6007 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6008 TCGv addr
, int size
)
6010 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6011 tcg_gen_movi_i32(cpu_exclusive_info
,
6012 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6013 gen_exception_insn(s
, 4, EXCP_STREX
);
6016 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6017 TCGv addr
, int size
)
6023 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6029 fail_label
= gen_new_label();
6030 done_label
= gen_new_label();
6031 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6034 tmp
= gen_ld8u(addr
, IS_USER(s
));
6037 tmp
= gen_ld16u(addr
, IS_USER(s
));
6041 tmp
= gen_ld32(addr
, IS_USER(s
));
6046 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6047 tcg_temp_free_i32(tmp
);
6049 TCGv tmp2
= tcg_temp_new_i32();
6050 tcg_gen_addi_i32(tmp2
, addr
, 4);
6051 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6052 tcg_temp_free_i32(tmp2
);
6053 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6054 tcg_temp_free_i32(tmp
);
6056 tmp
= load_reg(s
, rt
);
6059 gen_st8(tmp
, addr
, IS_USER(s
));
6062 gen_st16(tmp
, addr
, IS_USER(s
));
6066 gen_st32(tmp
, addr
, IS_USER(s
));
6072 tcg_gen_addi_i32(addr
, addr
, 4);
6073 tmp
= load_reg(s
, rt2
);
6074 gen_st32(tmp
, addr
, IS_USER(s
));
6076 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6077 tcg_gen_br(done_label
);
6078 gen_set_label(fail_label
);
6079 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6080 gen_set_label(done_label
);
6081 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6085 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
6087 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6094 insn
= ldl_code(s
->pc
);
6097 /* M variants do not implement ARM mode. */
6102 /* Unconditional instructions. */
6103 if (((insn
>> 25) & 7) == 1) {
6104 /* NEON Data processing. */
6105 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6108 if (disas_neon_data_insn(env
, s
, insn
))
6112 if ((insn
& 0x0f100000) == 0x04000000) {
6113 /* NEON load/store. */
6114 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6117 if (disas_neon_ls_insn(env
, s
, insn
))
6121 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6122 ((insn
& 0x0f30f010) == 0x0710f000)) {
6123 if ((insn
& (1 << 22)) == 0) {
6125 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6129 /* Otherwise PLD; v5TE+ */
6132 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6133 ((insn
& 0x0f70f010) == 0x0650f000)) {
6135 return; /* PLI; V7 */
6137 if (((insn
& 0x0f700000) == 0x04100000) ||
6138 ((insn
& 0x0f700010) == 0x06100000)) {
6139 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6142 return; /* v7MP: Unallocated memory hint: must NOP */
6145 if ((insn
& 0x0ffffdff) == 0x01010000) {
6148 if (insn
& (1 << 9)) {
6149 /* BE8 mode not implemented. */
6153 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6154 switch ((insn
>> 4) & 0xf) {
6163 /* We don't emulate caches so these are a no-op. */
6168 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6174 op1
= (insn
& 0x1f);
6175 addr
= tcg_temp_new_i32();
6176 tmp
= tcg_const_i32(op1
);
6177 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6178 tcg_temp_free_i32(tmp
);
6179 i
= (insn
>> 23) & 3;
6181 case 0: offset
= -4; break; /* DA */
6182 case 1: offset
= 0; break; /* IA */
6183 case 2: offset
= -8; break; /* DB */
6184 case 3: offset
= 4; break; /* IB */
6188 tcg_gen_addi_i32(addr
, addr
, offset
);
6189 tmp
= load_reg(s
, 14);
6190 gen_st32(tmp
, addr
, 0);
6191 tmp
= load_cpu_field(spsr
);
6192 tcg_gen_addi_i32(addr
, addr
, 4);
6193 gen_st32(tmp
, addr
, 0);
6194 if (insn
& (1 << 21)) {
6195 /* Base writeback. */
6197 case 0: offset
= -8; break;
6198 case 1: offset
= 4; break;
6199 case 2: offset
= -4; break;
6200 case 3: offset
= 0; break;
6204 tcg_gen_addi_i32(addr
, addr
, offset
);
6205 tmp
= tcg_const_i32(op1
);
6206 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6207 tcg_temp_free_i32(tmp
);
6208 tcg_temp_free_i32(addr
);
6210 tcg_temp_free_i32(addr
);
6213 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6219 rn
= (insn
>> 16) & 0xf;
6220 addr
= load_reg(s
, rn
);
6221 i
= (insn
>> 23) & 3;
6223 case 0: offset
= -4; break; /* DA */
6224 case 1: offset
= 0; break; /* IA */
6225 case 2: offset
= -8; break; /* DB */
6226 case 3: offset
= 4; break; /* IB */
6230 tcg_gen_addi_i32(addr
, addr
, offset
);
6231 /* Load PC into tmp and CPSR into tmp2. */
6232 tmp
= gen_ld32(addr
, 0);
6233 tcg_gen_addi_i32(addr
, addr
, 4);
6234 tmp2
= gen_ld32(addr
, 0);
6235 if (insn
& (1 << 21)) {
6236 /* Base writeback. */
6238 case 0: offset
= -8; break;
6239 case 1: offset
= 4; break;
6240 case 2: offset
= -4; break;
6241 case 3: offset
= 0; break;
6245 tcg_gen_addi_i32(addr
, addr
, offset
);
6246 store_reg(s
, rn
, addr
);
6248 tcg_temp_free_i32(addr
);
6250 gen_rfe(s
, tmp
, tmp2
);
6252 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6253 /* branch link and change to thumb (blx <offset>) */
6256 val
= (uint32_t)s
->pc
;
6257 tmp
= tcg_temp_new_i32();
6258 tcg_gen_movi_i32(tmp
, val
);
6259 store_reg(s
, 14, tmp
);
6260 /* Sign-extend the 24-bit offset */
6261 offset
= (((int32_t)insn
) << 8) >> 8;
6262 /* offset * 4 + bit24 * 2 + (thumb bit) */
6263 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6264 /* pipeline offset */
6268 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6269 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6270 /* iWMMXt register transfer. */
6271 if (env
->cp15
.c15_cpar
& (1 << 1))
6272 if (!disas_iwmmxt_insn(env
, s
, insn
))
6275 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6276 /* Coprocessor double register transfer. */
6277 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6278 /* Additional coprocessor register transfer. */
6279 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6282 /* cps (privileged) */
6286 if (insn
& (1 << 19)) {
6287 if (insn
& (1 << 8))
6289 if (insn
& (1 << 7))
6291 if (insn
& (1 << 6))
6293 if (insn
& (1 << 18))
6296 if (insn
& (1 << 17)) {
6298 val
|= (insn
& 0x1f);
6301 gen_set_psr_im(s
, mask
, 0, val
);
6308 /* if not always execute, we generate a conditional jump to
6310 s
->condlabel
= gen_new_label();
6311 gen_test_cc(cond
^ 1, s
->condlabel
);
6314 if ((insn
& 0x0f900000) == 0x03000000) {
6315 if ((insn
& (1 << 21)) == 0) {
6317 rd
= (insn
>> 12) & 0xf;
6318 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6319 if ((insn
& (1 << 22)) == 0) {
6321 tmp
= tcg_temp_new_i32();
6322 tcg_gen_movi_i32(tmp
, val
);
6325 tmp
= load_reg(s
, rd
);
6326 tcg_gen_ext16u_i32(tmp
, tmp
);
6327 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6329 store_reg(s
, rd
, tmp
);
6331 if (((insn
>> 12) & 0xf) != 0xf)
6333 if (((insn
>> 16) & 0xf) == 0) {
6334 gen_nop_hint(s
, insn
& 0xff);
6336 /* CPSR = immediate */
6338 shift
= ((insn
>> 8) & 0xf) * 2;
6340 val
= (val
>> shift
) | (val
<< (32 - shift
));
6341 i
= ((insn
& (1 << 22)) != 0);
6342 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6346 } else if ((insn
& 0x0f900000) == 0x01000000
6347 && (insn
& 0x00000090) != 0x00000090) {
6348 /* miscellaneous instructions */
6349 op1
= (insn
>> 21) & 3;
6350 sh
= (insn
>> 4) & 0xf;
6353 case 0x0: /* move program status register */
6356 tmp
= load_reg(s
, rm
);
6357 i
= ((op1
& 2) != 0);
6358 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6362 rd
= (insn
>> 12) & 0xf;
6366 tmp
= load_cpu_field(spsr
);
6368 tmp
= tcg_temp_new_i32();
6369 gen_helper_cpsr_read(tmp
);
6371 store_reg(s
, rd
, tmp
);
6376 /* branch/exchange thumb (bx). */
6377 tmp
= load_reg(s
, rm
);
6379 } else if (op1
== 3) {
6381 rd
= (insn
>> 12) & 0xf;
6382 tmp
= load_reg(s
, rm
);
6383 gen_helper_clz(tmp
, tmp
);
6384 store_reg(s
, rd
, tmp
);
6392 /* Trivial implementation equivalent to bx. */
6393 tmp
= load_reg(s
, rm
);
6403 /* branch link/exchange thumb (blx) */
6404 tmp
= load_reg(s
, rm
);
6405 tmp2
= tcg_temp_new_i32();
6406 tcg_gen_movi_i32(tmp2
, s
->pc
);
6407 store_reg(s
, 14, tmp2
);
6410 case 0x5: /* saturating add/subtract */
6411 rd
= (insn
>> 12) & 0xf;
6412 rn
= (insn
>> 16) & 0xf;
6413 tmp
= load_reg(s
, rm
);
6414 tmp2
= load_reg(s
, rn
);
6416 gen_helper_double_saturate(tmp2
, tmp2
);
6418 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6420 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6421 tcg_temp_free_i32(tmp2
);
6422 store_reg(s
, rd
, tmp
);
6425 /* SMC instruction (op1 == 3)
6426 and undefined instructions (op1 == 0 || op1 == 2)
6432 gen_exception_insn(s
, 4, EXCP_BKPT
);
6434 case 0x8: /* signed multiply */
6438 rs
= (insn
>> 8) & 0xf;
6439 rn
= (insn
>> 12) & 0xf;
6440 rd
= (insn
>> 16) & 0xf;
6442 /* (32 * 16) >> 16 */
6443 tmp
= load_reg(s
, rm
);
6444 tmp2
= load_reg(s
, rs
);
6446 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6449 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6450 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6451 tmp
= tcg_temp_new_i32();
6452 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6453 tcg_temp_free_i64(tmp64
);
6454 if ((sh
& 2) == 0) {
6455 tmp2
= load_reg(s
, rn
);
6456 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6457 tcg_temp_free_i32(tmp2
);
6459 store_reg(s
, rd
, tmp
);
6462 tmp
= load_reg(s
, rm
);
6463 tmp2
= load_reg(s
, rs
);
6464 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6465 tcg_temp_free_i32(tmp2
);
6467 tmp64
= tcg_temp_new_i64();
6468 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6469 tcg_temp_free_i32(tmp
);
6470 gen_addq(s
, tmp64
, rn
, rd
);
6471 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6472 tcg_temp_free_i64(tmp64
);
6475 tmp2
= load_reg(s
, rn
);
6476 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6477 tcg_temp_free_i32(tmp2
);
6479 store_reg(s
, rd
, tmp
);
6486 } else if (((insn
& 0x0e000000) == 0 &&
6487 (insn
& 0x00000090) != 0x90) ||
6488 ((insn
& 0x0e000000) == (1 << 25))) {
6489 int set_cc
, logic_cc
, shiftop
;
6491 op1
= (insn
>> 21) & 0xf;
6492 set_cc
= (insn
>> 20) & 1;
6493 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6495 /* data processing instruction */
6496 if (insn
& (1 << 25)) {
6497 /* immediate operand */
6499 shift
= ((insn
>> 8) & 0xf) * 2;
6501 val
= (val
>> shift
) | (val
<< (32 - shift
));
6503 tmp2
= tcg_temp_new_i32();
6504 tcg_gen_movi_i32(tmp2
, val
);
6505 if (logic_cc
&& shift
) {
6506 gen_set_CF_bit31(tmp2
);
6511 tmp2
= load_reg(s
, rm
);
6512 shiftop
= (insn
>> 5) & 3;
6513 if (!(insn
& (1 << 4))) {
6514 shift
= (insn
>> 7) & 0x1f;
6515 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6517 rs
= (insn
>> 8) & 0xf;
6518 tmp
= load_reg(s
, rs
);
6519 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6522 if (op1
!= 0x0f && op1
!= 0x0d) {
6523 rn
= (insn
>> 16) & 0xf;
6524 tmp
= load_reg(s
, rn
);
6528 rd
= (insn
>> 12) & 0xf;
6531 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6535 store_reg_bx(env
, s
, rd
, tmp
);
6538 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6542 store_reg_bx(env
, s
, rd
, tmp
);
6545 if (set_cc
&& rd
== 15) {
6546 /* SUBS r15, ... is used for exception return. */
6550 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6551 gen_exception_return(s
, tmp
);
6554 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6556 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6558 store_reg_bx(env
, s
, rd
, tmp
);
6563 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
6565 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6567 store_reg_bx(env
, s
, rd
, tmp
);
6571 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6573 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6575 store_reg_bx(env
, s
, rd
, tmp
);
6579 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
6581 gen_add_carry(tmp
, tmp
, tmp2
);
6583 store_reg_bx(env
, s
, rd
, tmp
);
6587 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
6589 gen_sub_carry(tmp
, tmp
, tmp2
);
6591 store_reg_bx(env
, s
, rd
, tmp
);
6595 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
6597 gen_sub_carry(tmp
, tmp2
, tmp
);
6599 store_reg_bx(env
, s
, rd
, tmp
);
6603 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6606 tcg_temp_free_i32(tmp
);
6610 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6613 tcg_temp_free_i32(tmp
);
6617 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6619 tcg_temp_free_i32(tmp
);
6623 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6625 tcg_temp_free_i32(tmp
);
6628 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6632 store_reg_bx(env
, s
, rd
, tmp
);
6635 if (logic_cc
&& rd
== 15) {
6636 /* MOVS r15, ... is used for exception return. */
6640 gen_exception_return(s
, tmp2
);
6645 store_reg_bx(env
, s
, rd
, tmp2
);
6649 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
6653 store_reg_bx(env
, s
, rd
, tmp
);
6657 tcg_gen_not_i32(tmp2
, tmp2
);
6661 store_reg_bx(env
, s
, rd
, tmp2
);
6664 if (op1
!= 0x0f && op1
!= 0x0d) {
6665 tcg_temp_free_i32(tmp2
);
6668 /* other instructions */
6669 op1
= (insn
>> 24) & 0xf;
6673 /* multiplies, extra load/stores */
6674 sh
= (insn
>> 5) & 3;
6677 rd
= (insn
>> 16) & 0xf;
6678 rn
= (insn
>> 12) & 0xf;
6679 rs
= (insn
>> 8) & 0xf;
6681 op1
= (insn
>> 20) & 0xf;
6683 case 0: case 1: case 2: case 3: case 6:
6685 tmp
= load_reg(s
, rs
);
6686 tmp2
= load_reg(s
, rm
);
6687 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
6688 tcg_temp_free_i32(tmp2
);
6689 if (insn
& (1 << 22)) {
6690 /* Subtract (mls) */
6692 tmp2
= load_reg(s
, rn
);
6693 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6694 tcg_temp_free_i32(tmp2
);
6695 } else if (insn
& (1 << 21)) {
6697 tmp2
= load_reg(s
, rn
);
6698 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6699 tcg_temp_free_i32(tmp2
);
6701 if (insn
& (1 << 20))
6703 store_reg(s
, rd
, tmp
);
6706 /* 64 bit mul double accumulate (UMAAL) */
6708 tmp
= load_reg(s
, rs
);
6709 tmp2
= load_reg(s
, rm
);
6710 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6711 gen_addq_lo(s
, tmp64
, rn
);
6712 gen_addq_lo(s
, tmp64
, rd
);
6713 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6714 tcg_temp_free_i64(tmp64
);
6716 case 8: case 9: case 10: case 11:
6717 case 12: case 13: case 14: case 15:
6718 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6719 tmp
= load_reg(s
, rs
);
6720 tmp2
= load_reg(s
, rm
);
6721 if (insn
& (1 << 22)) {
6722 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6724 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6726 if (insn
& (1 << 21)) { /* mult accumulate */
6727 gen_addq(s
, tmp64
, rn
, rd
);
6729 if (insn
& (1 << 20)) {
6730 gen_logicq_cc(tmp64
);
6732 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6733 tcg_temp_free_i64(tmp64
);
6739 rn
= (insn
>> 16) & 0xf;
6740 rd
= (insn
>> 12) & 0xf;
6741 if (insn
& (1 << 23)) {
6742 /* load/store exclusive */
6743 op1
= (insn
>> 21) & 0x3;
6748 addr
= tcg_temp_local_new_i32();
6749 load_reg_var(s
, addr
, rn
);
6750 if (insn
& (1 << 20)) {
6753 gen_load_exclusive(s
, rd
, 15, addr
, 2);
6755 case 1: /* ldrexd */
6756 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
6758 case 2: /* ldrexb */
6759 gen_load_exclusive(s
, rd
, 15, addr
, 0);
6761 case 3: /* ldrexh */
6762 gen_load_exclusive(s
, rd
, 15, addr
, 1);
6771 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
6773 case 1: /* strexd */
6774 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
6776 case 2: /* strexb */
6777 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
6779 case 3: /* strexh */
6780 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
6786 tcg_temp_free(addr
);
6788 /* SWP instruction */
6791 /* ??? This is not really atomic. However we know
6792 we never have multiple CPUs running in parallel,
6793 so it is good enough. */
6794 addr
= load_reg(s
, rn
);
6795 tmp
= load_reg(s
, rm
);
6796 if (insn
& (1 << 22)) {
6797 tmp2
= gen_ld8u(addr
, IS_USER(s
));
6798 gen_st8(tmp
, addr
, IS_USER(s
));
6800 tmp2
= gen_ld32(addr
, IS_USER(s
));
6801 gen_st32(tmp
, addr
, IS_USER(s
));
6803 tcg_temp_free_i32(addr
);
6804 store_reg(s
, rd
, tmp2
);
6810 /* Misc load/store */
6811 rn
= (insn
>> 16) & 0xf;
6812 rd
= (insn
>> 12) & 0xf;
6813 addr
= load_reg(s
, rn
);
6814 if (insn
& (1 << 24))
6815 gen_add_datah_offset(s
, insn
, 0, addr
);
6817 if (insn
& (1 << 20)) {
6821 tmp
= gen_ld16u(addr
, IS_USER(s
));
6824 tmp
= gen_ld8s(addr
, IS_USER(s
));
6828 tmp
= gen_ld16s(addr
, IS_USER(s
));
6832 } else if (sh
& 2) {
6836 tmp
= load_reg(s
, rd
);
6837 gen_st32(tmp
, addr
, IS_USER(s
));
6838 tcg_gen_addi_i32(addr
, addr
, 4);
6839 tmp
= load_reg(s
, rd
+ 1);
6840 gen_st32(tmp
, addr
, IS_USER(s
));
6844 tmp
= gen_ld32(addr
, IS_USER(s
));
6845 store_reg(s
, rd
, tmp
);
6846 tcg_gen_addi_i32(addr
, addr
, 4);
6847 tmp
= gen_ld32(addr
, IS_USER(s
));
6851 address_offset
= -4;
6854 tmp
= load_reg(s
, rd
);
6855 gen_st16(tmp
, addr
, IS_USER(s
));
6858 /* Perform base writeback before the loaded value to
6859 ensure correct behavior with overlapping index registers.
6860 ldrd with base writeback is is undefined if the
6861 destination and index registers overlap. */
6862 if (!(insn
& (1 << 24))) {
6863 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
6864 store_reg(s
, rn
, addr
);
6865 } else if (insn
& (1 << 21)) {
6867 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6868 store_reg(s
, rn
, addr
);
6870 tcg_temp_free_i32(addr
);
6873 /* Complete the load. */
6874 store_reg(s
, rd
, tmp
);
6883 if (insn
& (1 << 4)) {
6885 /* Armv6 Media instructions. */
6887 rn
= (insn
>> 16) & 0xf;
6888 rd
= (insn
>> 12) & 0xf;
6889 rs
= (insn
>> 8) & 0xf;
6890 switch ((insn
>> 23) & 3) {
6891 case 0: /* Parallel add/subtract. */
6892 op1
= (insn
>> 20) & 7;
6893 tmp
= load_reg(s
, rn
);
6894 tmp2
= load_reg(s
, rm
);
6895 sh
= (insn
>> 5) & 7;
6896 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
6898 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
6899 tcg_temp_free_i32(tmp2
);
6900 store_reg(s
, rd
, tmp
);
6903 if ((insn
& 0x00700020) == 0) {
6904 /* Halfword pack. */
6905 tmp
= load_reg(s
, rn
);
6906 tmp2
= load_reg(s
, rm
);
6907 shift
= (insn
>> 7) & 0x1f;
6908 if (insn
& (1 << 6)) {
6912 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
6913 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
6914 tcg_gen_ext16u_i32(tmp2
, tmp2
);
6918 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
6919 tcg_gen_ext16u_i32(tmp
, tmp
);
6920 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
6922 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6923 tcg_temp_free_i32(tmp2
);
6924 store_reg(s
, rd
, tmp
);
6925 } else if ((insn
& 0x00200020) == 0x00200000) {
6927 tmp
= load_reg(s
, rm
);
6928 shift
= (insn
>> 7) & 0x1f;
6929 if (insn
& (1 << 6)) {
6932 tcg_gen_sari_i32(tmp
, tmp
, shift
);
6934 tcg_gen_shli_i32(tmp
, tmp
, shift
);
6936 sh
= (insn
>> 16) & 0x1f;
6937 tmp2
= tcg_const_i32(sh
);
6938 if (insn
& (1 << 22))
6939 gen_helper_usat(tmp
, tmp
, tmp2
);
6941 gen_helper_ssat(tmp
, tmp
, tmp2
);
6942 tcg_temp_free_i32(tmp2
);
6943 store_reg(s
, rd
, tmp
);
6944 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
6946 tmp
= load_reg(s
, rm
);
6947 sh
= (insn
>> 16) & 0x1f;
6948 tmp2
= tcg_const_i32(sh
);
6949 if (insn
& (1 << 22))
6950 gen_helper_usat16(tmp
, tmp
, tmp2
);
6952 gen_helper_ssat16(tmp
, tmp
, tmp2
);
6953 tcg_temp_free_i32(tmp2
);
6954 store_reg(s
, rd
, tmp
);
6955 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
6957 tmp
= load_reg(s
, rn
);
6958 tmp2
= load_reg(s
, rm
);
6959 tmp3
= tcg_temp_new_i32();
6960 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
6961 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
6962 tcg_temp_free_i32(tmp3
);
6963 tcg_temp_free_i32(tmp2
);
6964 store_reg(s
, rd
, tmp
);
6965 } else if ((insn
& 0x000003e0) == 0x00000060) {
6966 tmp
= load_reg(s
, rm
);
6967 shift
= (insn
>> 10) & 3;
6968 /* ??? In many cases it's not neccessary to do a
6969 rotate, a shift is sufficient. */
6971 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
6972 op1
= (insn
>> 20) & 7;
6974 case 0: gen_sxtb16(tmp
); break;
6975 case 2: gen_sxtb(tmp
); break;
6976 case 3: gen_sxth(tmp
); break;
6977 case 4: gen_uxtb16(tmp
); break;
6978 case 6: gen_uxtb(tmp
); break;
6979 case 7: gen_uxth(tmp
); break;
6980 default: goto illegal_op
;
6983 tmp2
= load_reg(s
, rn
);
6984 if ((op1
& 3) == 0) {
6985 gen_add16(tmp
, tmp2
);
6987 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6988 tcg_temp_free_i32(tmp2
);
6991 store_reg(s
, rd
, tmp
);
6992 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
6994 tmp
= load_reg(s
, rm
);
6995 if (insn
& (1 << 22)) {
6996 if (insn
& (1 << 7)) {
7000 gen_helper_rbit(tmp
, tmp
);
7003 if (insn
& (1 << 7))
7006 tcg_gen_bswap32_i32(tmp
, tmp
);
7008 store_reg(s
, rd
, tmp
);
7013 case 2: /* Multiplies (Type 3). */
7014 tmp
= load_reg(s
, rm
);
7015 tmp2
= load_reg(s
, rs
);
7016 if (insn
& (1 << 20)) {
7017 /* Signed multiply most significant [accumulate].
7018 (SMMUL, SMMLA, SMMLS) */
7019 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7022 tmp
= load_reg(s
, rd
);
7023 if (insn
& (1 << 6)) {
7024 tmp64
= gen_subq_msw(tmp64
, tmp
);
7026 tmp64
= gen_addq_msw(tmp64
, tmp
);
7029 if (insn
& (1 << 5)) {
7030 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7032 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7033 tmp
= tcg_temp_new_i32();
7034 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7035 tcg_temp_free_i64(tmp64
);
7036 store_reg(s
, rn
, tmp
);
7038 if (insn
& (1 << 5))
7039 gen_swap_half(tmp2
);
7040 gen_smul_dual(tmp
, tmp2
);
7041 /* This addition cannot overflow. */
7042 if (insn
& (1 << 6)) {
7043 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7045 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7047 tcg_temp_free_i32(tmp2
);
7048 if (insn
& (1 << 22)) {
7049 /* smlald, smlsld */
7050 tmp64
= tcg_temp_new_i64();
7051 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7052 tcg_temp_free_i32(tmp
);
7053 gen_addq(s
, tmp64
, rd
, rn
);
7054 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7055 tcg_temp_free_i64(tmp64
);
7057 /* smuad, smusd, smlad, smlsd */
7060 tmp2
= load_reg(s
, rd
);
7061 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7062 tcg_temp_free_i32(tmp2
);
7064 store_reg(s
, rn
, tmp
);
7069 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7071 case 0: /* Unsigned sum of absolute differences. */
7073 tmp
= load_reg(s
, rm
);
7074 tmp2
= load_reg(s
, rs
);
7075 gen_helper_usad8(tmp
, tmp
, tmp2
);
7076 tcg_temp_free_i32(tmp2
);
7078 tmp2
= load_reg(s
, rd
);
7079 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7080 tcg_temp_free_i32(tmp2
);
7082 store_reg(s
, rn
, tmp
);
7084 case 0x20: case 0x24: case 0x28: case 0x2c:
7085 /* Bitfield insert/clear. */
7087 shift
= (insn
>> 7) & 0x1f;
7088 i
= (insn
>> 16) & 0x1f;
7091 tmp
= tcg_temp_new_i32();
7092 tcg_gen_movi_i32(tmp
, 0);
7094 tmp
= load_reg(s
, rm
);
7097 tmp2
= load_reg(s
, rd
);
7098 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7099 tcg_temp_free_i32(tmp2
);
7101 store_reg(s
, rd
, tmp
);
7103 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7104 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7106 tmp
= load_reg(s
, rm
);
7107 shift
= (insn
>> 7) & 0x1f;
7108 i
= ((insn
>> 16) & 0x1f) + 1;
7113 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7115 gen_sbfx(tmp
, shift
, i
);
7118 store_reg(s
, rd
, tmp
);
7128 /* Check for undefined extension instructions
7129 * per the ARM Bible IE:
7130 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7132 sh
= (0xf << 20) | (0xf << 4);
7133 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7137 /* load/store byte/word */
7138 rn
= (insn
>> 16) & 0xf;
7139 rd
= (insn
>> 12) & 0xf;
7140 tmp2
= load_reg(s
, rn
);
7141 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7142 if (insn
& (1 << 24))
7143 gen_add_data_offset(s
, insn
, tmp2
);
7144 if (insn
& (1 << 20)) {
7146 if (insn
& (1 << 22)) {
7147 tmp
= gen_ld8u(tmp2
, i
);
7149 tmp
= gen_ld32(tmp2
, i
);
7153 tmp
= load_reg(s
, rd
);
7154 if (insn
& (1 << 22))
7155 gen_st8(tmp
, tmp2
, i
);
7157 gen_st32(tmp
, tmp2
, i
);
7159 if (!(insn
& (1 << 24))) {
7160 gen_add_data_offset(s
, insn
, tmp2
);
7161 store_reg(s
, rn
, tmp2
);
7162 } else if (insn
& (1 << 21)) {
7163 store_reg(s
, rn
, tmp2
);
7165 tcg_temp_free_i32(tmp2
);
7167 if (insn
& (1 << 20)) {
7168 /* Complete the load. */
7172 store_reg(s
, rd
, tmp
);
7178 int j
, n
, user
, loaded_base
;
7180 /* load/store multiple words */
7181 /* XXX: store correct base if write back */
7183 if (insn
& (1 << 22)) {
7185 goto illegal_op
; /* only usable in supervisor mode */
7187 if ((insn
& (1 << 15)) == 0)
7190 rn
= (insn
>> 16) & 0xf;
7191 addr
= load_reg(s
, rn
);
7193 /* compute total size */
7195 TCGV_UNUSED(loaded_var
);
7198 if (insn
& (1 << i
))
7201 /* XXX: test invalid n == 0 case ? */
7202 if (insn
& (1 << 23)) {
7203 if (insn
& (1 << 24)) {
7205 tcg_gen_addi_i32(addr
, addr
, 4);
7207 /* post increment */
7210 if (insn
& (1 << 24)) {
7212 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7214 /* post decrement */
7216 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7221 if (insn
& (1 << i
)) {
7222 if (insn
& (1 << 20)) {
7224 tmp
= gen_ld32(addr
, IS_USER(s
));
7228 tmp2
= tcg_const_i32(i
);
7229 gen_helper_set_user_reg(tmp2
, tmp
);
7230 tcg_temp_free_i32(tmp2
);
7231 tcg_temp_free_i32(tmp
);
7232 } else if (i
== rn
) {
7236 store_reg(s
, i
, tmp
);
7241 /* special case: r15 = PC + 8 */
7242 val
= (long)s
->pc
+ 4;
7243 tmp
= tcg_temp_new_i32();
7244 tcg_gen_movi_i32(tmp
, val
);
7246 tmp
= tcg_temp_new_i32();
7247 tmp2
= tcg_const_i32(i
);
7248 gen_helper_get_user_reg(tmp
, tmp2
);
7249 tcg_temp_free_i32(tmp2
);
7251 tmp
= load_reg(s
, i
);
7253 gen_st32(tmp
, addr
, IS_USER(s
));
7256 /* no need to add after the last transfer */
7258 tcg_gen_addi_i32(addr
, addr
, 4);
7261 if (insn
& (1 << 21)) {
7263 if (insn
& (1 << 23)) {
7264 if (insn
& (1 << 24)) {
7267 /* post increment */
7268 tcg_gen_addi_i32(addr
, addr
, 4);
7271 if (insn
& (1 << 24)) {
7274 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7276 /* post decrement */
7277 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7280 store_reg(s
, rn
, addr
);
7282 tcg_temp_free_i32(addr
);
7285 store_reg(s
, rn
, loaded_var
);
7287 if ((insn
& (1 << 22)) && !user
) {
7288 /* Restore CPSR from SPSR. */
7289 tmp
= load_cpu_field(spsr
);
7290 gen_set_cpsr(tmp
, 0xffffffff);
7291 tcg_temp_free_i32(tmp
);
7292 s
->is_jmp
= DISAS_UPDATE
;
7301 /* branch (and link) */
7302 val
= (int32_t)s
->pc
;
7303 if (insn
& (1 << 24)) {
7304 tmp
= tcg_temp_new_i32();
7305 tcg_gen_movi_i32(tmp
, val
);
7306 store_reg(s
, 14, tmp
);
7308 offset
= (((int32_t)insn
<< 8) >> 8);
7309 val
+= (offset
<< 2) + 4;
7317 if (disas_coproc_insn(env
, s
, insn
))
7322 gen_set_pc_im(s
->pc
);
7323 s
->is_jmp
= DISAS_SWI
;
7327 gen_exception_insn(s
, 4, EXCP_UDEF
);
7333 /* Return true if this is a Thumb-2 logical op. */
7335 thumb2_logic_op(int op
)
7340 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7341 then set condition code flags based on the result of the operation.
7342 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7343 to the high bit of T1.
7344 Returns zero if the opcode is valid. */
7347 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7354 tcg_gen_and_i32(t0
, t0
, t1
);
7358 tcg_gen_andc_i32(t0
, t0
, t1
);
7362 tcg_gen_or_i32(t0
, t0
, t1
);
7366 tcg_gen_orc_i32(t0
, t0
, t1
);
7370 tcg_gen_xor_i32(t0
, t0
, t1
);
7375 gen_helper_add_cc(t0
, t0
, t1
);
7377 tcg_gen_add_i32(t0
, t0
, t1
);
7381 gen_helper_adc_cc(t0
, t0
, t1
);
7387 gen_helper_sbc_cc(t0
, t0
, t1
);
7389 gen_sub_carry(t0
, t0
, t1
);
7393 gen_helper_sub_cc(t0
, t0
, t1
);
7395 tcg_gen_sub_i32(t0
, t0
, t1
);
7399 gen_helper_sub_cc(t0
, t1
, t0
);
7401 tcg_gen_sub_i32(t0
, t1
, t0
);
7403 default: /* 5, 6, 7, 9, 12, 15. */
7409 gen_set_CF_bit31(t1
);
7414 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7416 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7418 uint32_t insn
, imm
, shift
, offset
;
7419 uint32_t rd
, rn
, rm
, rs
;
7430 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7431 || arm_feature (env
, ARM_FEATURE_M
))) {
7432 /* Thumb-1 cores may need to treat bl and blx as a pair of
7433 16-bit instructions to get correct prefetch abort behavior. */
7435 if ((insn
& (1 << 12)) == 0) {
7436 /* Second half of blx. */
7437 offset
= ((insn
& 0x7ff) << 1);
7438 tmp
= load_reg(s
, 14);
7439 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7440 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7442 tmp2
= tcg_temp_new_i32();
7443 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7444 store_reg(s
, 14, tmp2
);
7448 if (insn
& (1 << 11)) {
7449 /* Second half of bl. */
7450 offset
= ((insn
& 0x7ff) << 1) | 1;
7451 tmp
= load_reg(s
, 14);
7452 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7454 tmp2
= tcg_temp_new_i32();
7455 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7456 store_reg(s
, 14, tmp2
);
7460 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7461 /* Instruction spans a page boundary. Implement it as two
7462 16-bit instructions in case the second half causes an
7464 offset
= ((int32_t)insn
<< 21) >> 9;
7465 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7468 /* Fall through to 32-bit decode. */
7471 insn
= lduw_code(s
->pc
);
7473 insn
|= (uint32_t)insn_hw1
<< 16;
7475 if ((insn
& 0xf800e800) != 0xf000e800) {
7479 rn
= (insn
>> 16) & 0xf;
7480 rs
= (insn
>> 12) & 0xf;
7481 rd
= (insn
>> 8) & 0xf;
7483 switch ((insn
>> 25) & 0xf) {
7484 case 0: case 1: case 2: case 3:
7485 /* 16-bit instructions. Should never happen. */
7488 if (insn
& (1 << 22)) {
7489 /* Other load/store, table branch. */
7490 if (insn
& 0x01200000) {
7491 /* Load/store doubleword. */
7493 addr
= tcg_temp_new_i32();
7494 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7496 addr
= load_reg(s
, rn
);
7498 offset
= (insn
& 0xff) * 4;
7499 if ((insn
& (1 << 23)) == 0)
7501 if (insn
& (1 << 24)) {
7502 tcg_gen_addi_i32(addr
, addr
, offset
);
7505 if (insn
& (1 << 20)) {
7507 tmp
= gen_ld32(addr
, IS_USER(s
));
7508 store_reg(s
, rs
, tmp
);
7509 tcg_gen_addi_i32(addr
, addr
, 4);
7510 tmp
= gen_ld32(addr
, IS_USER(s
));
7511 store_reg(s
, rd
, tmp
);
7514 tmp
= load_reg(s
, rs
);
7515 gen_st32(tmp
, addr
, IS_USER(s
));
7516 tcg_gen_addi_i32(addr
, addr
, 4);
7517 tmp
= load_reg(s
, rd
);
7518 gen_st32(tmp
, addr
, IS_USER(s
));
7520 if (insn
& (1 << 21)) {
7521 /* Base writeback. */
7524 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
7525 store_reg(s
, rn
, addr
);
7527 tcg_temp_free_i32(addr
);
7529 } else if ((insn
& (1 << 23)) == 0) {
7530 /* Load/store exclusive word. */
7531 addr
= tcg_temp_local_new();
7532 load_reg_var(s
, addr
, rn
);
7533 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
7534 if (insn
& (1 << 20)) {
7535 gen_load_exclusive(s
, rs
, 15, addr
, 2);
7537 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
7539 tcg_temp_free(addr
);
7540 } else if ((insn
& (1 << 6)) == 0) {
7543 addr
= tcg_temp_new_i32();
7544 tcg_gen_movi_i32(addr
, s
->pc
);
7546 addr
= load_reg(s
, rn
);
7548 tmp
= load_reg(s
, rm
);
7549 tcg_gen_add_i32(addr
, addr
, tmp
);
7550 if (insn
& (1 << 4)) {
7552 tcg_gen_add_i32(addr
, addr
, tmp
);
7553 tcg_temp_free_i32(tmp
);
7554 tmp
= gen_ld16u(addr
, IS_USER(s
));
7556 tcg_temp_free_i32(tmp
);
7557 tmp
= gen_ld8u(addr
, IS_USER(s
));
7559 tcg_temp_free_i32(addr
);
7560 tcg_gen_shli_i32(tmp
, tmp
, 1);
7561 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
7562 store_reg(s
, 15, tmp
);
7564 /* Load/store exclusive byte/halfword/doubleword. */
7566 op
= (insn
>> 4) & 0x3;
7570 addr
= tcg_temp_local_new();
7571 load_reg_var(s
, addr
, rn
);
7572 if (insn
& (1 << 20)) {
7573 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
7575 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
7577 tcg_temp_free(addr
);
7580 /* Load/store multiple, RFE, SRS. */
7581 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
7582 /* Not available in user mode. */
7585 if (insn
& (1 << 20)) {
7587 addr
= load_reg(s
, rn
);
7588 if ((insn
& (1 << 24)) == 0)
7589 tcg_gen_addi_i32(addr
, addr
, -8);
7590 /* Load PC into tmp and CPSR into tmp2. */
7591 tmp
= gen_ld32(addr
, 0);
7592 tcg_gen_addi_i32(addr
, addr
, 4);
7593 tmp2
= gen_ld32(addr
, 0);
7594 if (insn
& (1 << 21)) {
7595 /* Base writeback. */
7596 if (insn
& (1 << 24)) {
7597 tcg_gen_addi_i32(addr
, addr
, 4);
7599 tcg_gen_addi_i32(addr
, addr
, -4);
7601 store_reg(s
, rn
, addr
);
7603 tcg_temp_free_i32(addr
);
7605 gen_rfe(s
, tmp
, tmp2
);
7609 addr
= tcg_temp_new_i32();
7610 tmp
= tcg_const_i32(op
);
7611 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7612 tcg_temp_free_i32(tmp
);
7613 if ((insn
& (1 << 24)) == 0) {
7614 tcg_gen_addi_i32(addr
, addr
, -8);
7616 tmp
= load_reg(s
, 14);
7617 gen_st32(tmp
, addr
, 0);
7618 tcg_gen_addi_i32(addr
, addr
, 4);
7619 tmp
= tcg_temp_new_i32();
7620 gen_helper_cpsr_read(tmp
);
7621 gen_st32(tmp
, addr
, 0);
7622 if (insn
& (1 << 21)) {
7623 if ((insn
& (1 << 24)) == 0) {
7624 tcg_gen_addi_i32(addr
, addr
, -4);
7626 tcg_gen_addi_i32(addr
, addr
, 4);
7628 tmp
= tcg_const_i32(op
);
7629 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7630 tcg_temp_free_i32(tmp
);
7632 tcg_temp_free_i32(addr
);
7637 /* Load/store multiple. */
7638 addr
= load_reg(s
, rn
);
7640 for (i
= 0; i
< 16; i
++) {
7641 if (insn
& (1 << i
))
7644 if (insn
& (1 << 24)) {
7645 tcg_gen_addi_i32(addr
, addr
, -offset
);
7648 for (i
= 0; i
< 16; i
++) {
7649 if ((insn
& (1 << i
)) == 0)
7651 if (insn
& (1 << 20)) {
7653 tmp
= gen_ld32(addr
, IS_USER(s
));
7657 store_reg(s
, i
, tmp
);
7661 tmp
= load_reg(s
, i
);
7662 gen_st32(tmp
, addr
, IS_USER(s
));
7664 tcg_gen_addi_i32(addr
, addr
, 4);
7666 if (insn
& (1 << 21)) {
7667 /* Base register writeback. */
7668 if (insn
& (1 << 24)) {
7669 tcg_gen_addi_i32(addr
, addr
, -offset
);
7671 /* Fault if writeback register is in register list. */
7672 if (insn
& (1 << rn
))
7674 store_reg(s
, rn
, addr
);
7676 tcg_temp_free_i32(addr
);
7683 op
= (insn
>> 21) & 0xf;
7685 /* Halfword pack. */
7686 tmp
= load_reg(s
, rn
);
7687 tmp2
= load_reg(s
, rm
);
7688 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
7689 if (insn
& (1 << 5)) {
7693 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7694 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7695 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7699 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7700 tcg_gen_ext16u_i32(tmp
, tmp
);
7701 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7703 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7704 tcg_temp_free_i32(tmp2
);
7705 store_reg(s
, rd
, tmp
);
7707 /* Data processing register constant shift. */
7709 tmp
= tcg_temp_new_i32();
7710 tcg_gen_movi_i32(tmp
, 0);
7712 tmp
= load_reg(s
, rn
);
7714 tmp2
= load_reg(s
, rm
);
7716 shiftop
= (insn
>> 4) & 3;
7717 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
7718 conds
= (insn
& (1 << 20)) != 0;
7719 logic_cc
= (conds
&& thumb2_logic_op(op
));
7720 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7721 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
7723 tcg_temp_free_i32(tmp2
);
7725 store_reg(s
, rd
, tmp
);
7727 tcg_temp_free_i32(tmp
);
7731 case 13: /* Misc data processing. */
7732 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
7733 if (op
< 4 && (insn
& 0xf000) != 0xf000)
7736 case 0: /* Register controlled shift. */
7737 tmp
= load_reg(s
, rn
);
7738 tmp2
= load_reg(s
, rm
);
7739 if ((insn
& 0x70) != 0)
7741 op
= (insn
>> 21) & 3;
7742 logic_cc
= (insn
& (1 << 20)) != 0;
7743 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
7746 store_reg_bx(env
, s
, rd
, tmp
);
7748 case 1: /* Sign/zero extend. */
7749 tmp
= load_reg(s
, rm
);
7750 shift
= (insn
>> 4) & 3;
7751 /* ??? In many cases it's not neccessary to do a
7752 rotate, a shift is sufficient. */
7754 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7755 op
= (insn
>> 20) & 7;
7757 case 0: gen_sxth(tmp
); break;
7758 case 1: gen_uxth(tmp
); break;
7759 case 2: gen_sxtb16(tmp
); break;
7760 case 3: gen_uxtb16(tmp
); break;
7761 case 4: gen_sxtb(tmp
); break;
7762 case 5: gen_uxtb(tmp
); break;
7763 default: goto illegal_op
;
7766 tmp2
= load_reg(s
, rn
);
7767 if ((op
>> 1) == 1) {
7768 gen_add16(tmp
, tmp2
);
7770 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7771 tcg_temp_free_i32(tmp2
);
7774 store_reg(s
, rd
, tmp
);
7776 case 2: /* SIMD add/subtract. */
7777 op
= (insn
>> 20) & 7;
7778 shift
= (insn
>> 4) & 7;
7779 if ((op
& 3) == 3 || (shift
& 3) == 3)
7781 tmp
= load_reg(s
, rn
);
7782 tmp2
= load_reg(s
, rm
);
7783 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
7784 tcg_temp_free_i32(tmp2
);
7785 store_reg(s
, rd
, tmp
);
7787 case 3: /* Other data processing. */
7788 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
7790 /* Saturating add/subtract. */
7791 tmp
= load_reg(s
, rn
);
7792 tmp2
= load_reg(s
, rm
);
7794 gen_helper_double_saturate(tmp
, tmp
);
7796 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
7798 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
7799 tcg_temp_free_i32(tmp2
);
7801 tmp
= load_reg(s
, rn
);
7803 case 0x0a: /* rbit */
7804 gen_helper_rbit(tmp
, tmp
);
7806 case 0x08: /* rev */
7807 tcg_gen_bswap32_i32(tmp
, tmp
);
7809 case 0x09: /* rev16 */
7812 case 0x0b: /* revsh */
7815 case 0x10: /* sel */
7816 tmp2
= load_reg(s
, rm
);
7817 tmp3
= tcg_temp_new_i32();
7818 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7819 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7820 tcg_temp_free_i32(tmp3
);
7821 tcg_temp_free_i32(tmp2
);
7823 case 0x18: /* clz */
7824 gen_helper_clz(tmp
, tmp
);
7830 store_reg(s
, rd
, tmp
);
7832 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7833 op
= (insn
>> 4) & 0xf;
7834 tmp
= load_reg(s
, rn
);
7835 tmp2
= load_reg(s
, rm
);
7836 switch ((insn
>> 20) & 7) {
7837 case 0: /* 32 x 32 -> 32 */
7838 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7839 tcg_temp_free_i32(tmp2
);
7841 tmp2
= load_reg(s
, rs
);
7843 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7845 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7846 tcg_temp_free_i32(tmp2
);
7849 case 1: /* 16 x 16 -> 32 */
7850 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7851 tcg_temp_free_i32(tmp2
);
7853 tmp2
= load_reg(s
, rs
);
7854 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7855 tcg_temp_free_i32(tmp2
);
7858 case 2: /* Dual multiply add. */
7859 case 4: /* Dual multiply subtract. */
7861 gen_swap_half(tmp2
);
7862 gen_smul_dual(tmp
, tmp2
);
7863 /* This addition cannot overflow. */
7864 if (insn
& (1 << 22)) {
7865 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7867 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7869 tcg_temp_free_i32(tmp2
);
7872 tmp2
= load_reg(s
, rs
);
7873 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7874 tcg_temp_free_i32(tmp2
);
7877 case 3: /* 32 * 16 -> 32msb */
7879 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7882 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7883 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7884 tmp
= tcg_temp_new_i32();
7885 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7886 tcg_temp_free_i64(tmp64
);
7889 tmp2
= load_reg(s
, rs
);
7890 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7891 tcg_temp_free_i32(tmp2
);
7894 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7895 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7897 tmp
= load_reg(s
, rs
);
7898 if (insn
& (1 << 20)) {
7899 tmp64
= gen_addq_msw(tmp64
, tmp
);
7901 tmp64
= gen_subq_msw(tmp64
, tmp
);
7904 if (insn
& (1 << 4)) {
7905 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7907 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7908 tmp
= tcg_temp_new_i32();
7909 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7910 tcg_temp_free_i64(tmp64
);
7912 case 7: /* Unsigned sum of absolute differences. */
7913 gen_helper_usad8(tmp
, tmp
, tmp2
);
7914 tcg_temp_free_i32(tmp2
);
7916 tmp2
= load_reg(s
, rs
);
7917 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7918 tcg_temp_free_i32(tmp2
);
7922 store_reg(s
, rd
, tmp
);
7924 case 6: case 7: /* 64-bit multiply, Divide. */
7925 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
7926 tmp
= load_reg(s
, rn
);
7927 tmp2
= load_reg(s
, rm
);
7928 if ((op
& 0x50) == 0x10) {
7930 if (!arm_feature(env
, ARM_FEATURE_DIV
))
7933 gen_helper_udiv(tmp
, tmp
, tmp2
);
7935 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7936 tcg_temp_free_i32(tmp2
);
7937 store_reg(s
, rd
, tmp
);
7938 } else if ((op
& 0xe) == 0xc) {
7939 /* Dual multiply accumulate long. */
7941 gen_swap_half(tmp2
);
7942 gen_smul_dual(tmp
, tmp2
);
7944 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7946 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7948 tcg_temp_free_i32(tmp2
);
7950 tmp64
= tcg_temp_new_i64();
7951 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7952 tcg_temp_free_i32(tmp
);
7953 gen_addq(s
, tmp64
, rs
, rd
);
7954 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7955 tcg_temp_free_i64(tmp64
);
7958 /* Unsigned 64-bit multiply */
7959 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7963 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7964 tcg_temp_free_i32(tmp2
);
7965 tmp64
= tcg_temp_new_i64();
7966 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7967 tcg_temp_free_i32(tmp
);
7969 /* Signed 64-bit multiply */
7970 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7975 gen_addq_lo(s
, tmp64
, rs
);
7976 gen_addq_lo(s
, tmp64
, rd
);
7977 } else if (op
& 0x40) {
7978 /* 64-bit accumulate. */
7979 gen_addq(s
, tmp64
, rs
, rd
);
7981 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7982 tcg_temp_free_i64(tmp64
);
7987 case 6: case 7: case 14: case 15:
7989 if (((insn
>> 24) & 3) == 3) {
7990 /* Translate into the equivalent ARM encoding. */
7991 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
7992 if (disas_neon_data_insn(env
, s
, insn
))
7995 if (insn
& (1 << 28))
7997 if (disas_coproc_insn (env
, s
, insn
))
8001 case 8: case 9: case 10: case 11:
8002 if (insn
& (1 << 15)) {
8003 /* Branches, misc control. */
8004 if (insn
& 0x5000) {
8005 /* Unconditional branch. */
8006 /* signextend(hw1[10:0]) -> offset[:12]. */
8007 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8008 /* hw1[10:0] -> offset[11:1]. */
8009 offset
|= (insn
& 0x7ff) << 1;
8010 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8011 offset[24:22] already have the same value because of the
8012 sign extension above. */
8013 offset
^= ((~insn
) & (1 << 13)) << 10;
8014 offset
^= ((~insn
) & (1 << 11)) << 11;
8016 if (insn
& (1 << 14)) {
8017 /* Branch and link. */
8018 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8022 if (insn
& (1 << 12)) {
8027 offset
&= ~(uint32_t)2;
8028 gen_bx_im(s
, offset
);
8030 } else if (((insn
>> 23) & 7) == 7) {
8032 if (insn
& (1 << 13))
8035 if (insn
& (1 << 26)) {
8036 /* Secure monitor call (v6Z) */
8037 goto illegal_op
; /* not implemented. */
8039 op
= (insn
>> 20) & 7;
8041 case 0: /* msr cpsr. */
8043 tmp
= load_reg(s
, rn
);
8044 addr
= tcg_const_i32(insn
& 0xff);
8045 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8046 tcg_temp_free_i32(addr
);
8047 tcg_temp_free_i32(tmp
);
8052 case 1: /* msr spsr. */
8055 tmp
= load_reg(s
, rn
);
8057 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8061 case 2: /* cps, nop-hint. */
8062 if (((insn
>> 8) & 7) == 0) {
8063 gen_nop_hint(s
, insn
& 0xff);
8065 /* Implemented as NOP in user mode. */
8070 if (insn
& (1 << 10)) {
8071 if (insn
& (1 << 7))
8073 if (insn
& (1 << 6))
8075 if (insn
& (1 << 5))
8077 if (insn
& (1 << 9))
8078 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8080 if (insn
& (1 << 8)) {
8082 imm
|= (insn
& 0x1f);
8085 gen_set_psr_im(s
, offset
, 0, imm
);
8088 case 3: /* Special control operations. */
8090 op
= (insn
>> 4) & 0xf;
8098 /* These execute as NOPs. */
8105 /* Trivial implementation equivalent to bx. */
8106 tmp
= load_reg(s
, rn
);
8109 case 5: /* Exception return. */
8113 if (rn
!= 14 || rd
!= 15) {
8116 tmp
= load_reg(s
, rn
);
8117 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8118 gen_exception_return(s
, tmp
);
8120 case 6: /* mrs cpsr. */
8121 tmp
= tcg_temp_new_i32();
8123 addr
= tcg_const_i32(insn
& 0xff);
8124 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8125 tcg_temp_free_i32(addr
);
8127 gen_helper_cpsr_read(tmp
);
8129 store_reg(s
, rd
, tmp
);
8131 case 7: /* mrs spsr. */
8132 /* Not accessible in user mode. */
8133 if (IS_USER(s
) || IS_M(env
))
8135 tmp
= load_cpu_field(spsr
);
8136 store_reg(s
, rd
, tmp
);
8141 /* Conditional branch. */
8142 op
= (insn
>> 22) & 0xf;
8143 /* Generate a conditional jump to next instruction. */
8144 s
->condlabel
= gen_new_label();
8145 gen_test_cc(op
^ 1, s
->condlabel
);
8148 /* offset[11:1] = insn[10:0] */
8149 offset
= (insn
& 0x7ff) << 1;
8150 /* offset[17:12] = insn[21:16]. */
8151 offset
|= (insn
& 0x003f0000) >> 4;
8152 /* offset[31:20] = insn[26]. */
8153 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8154 /* offset[18] = insn[13]. */
8155 offset
|= (insn
& (1 << 13)) << 5;
8156 /* offset[19] = insn[11]. */
8157 offset
|= (insn
& (1 << 11)) << 8;
8159 /* jump to the offset */
8160 gen_jmp(s
, s
->pc
+ offset
);
8163 /* Data processing immediate. */
8164 if (insn
& (1 << 25)) {
8165 if (insn
& (1 << 24)) {
8166 if (insn
& (1 << 20))
8168 /* Bitfield/Saturate. */
8169 op
= (insn
>> 21) & 7;
8171 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8173 tmp
= tcg_temp_new_i32();
8174 tcg_gen_movi_i32(tmp
, 0);
8176 tmp
= load_reg(s
, rn
);
8179 case 2: /* Signed bitfield extract. */
8181 if (shift
+ imm
> 32)
8184 gen_sbfx(tmp
, shift
, imm
);
8186 case 6: /* Unsigned bitfield extract. */
8188 if (shift
+ imm
> 32)
8191 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8193 case 3: /* Bitfield insert/clear. */
8196 imm
= imm
+ 1 - shift
;
8198 tmp2
= load_reg(s
, rd
);
8199 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8200 tcg_temp_free_i32(tmp2
);
8205 default: /* Saturate. */
8208 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8210 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8212 tmp2
= tcg_const_i32(imm
);
8215 if ((op
& 1) && shift
== 0)
8216 gen_helper_usat16(tmp
, tmp
, tmp2
);
8218 gen_helper_usat(tmp
, tmp
, tmp2
);
8221 if ((op
& 1) && shift
== 0)
8222 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8224 gen_helper_ssat(tmp
, tmp
, tmp2
);
8226 tcg_temp_free_i32(tmp2
);
8229 store_reg(s
, rd
, tmp
);
8231 imm
= ((insn
& 0x04000000) >> 15)
8232 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8233 if (insn
& (1 << 22)) {
8234 /* 16-bit immediate. */
8235 imm
|= (insn
>> 4) & 0xf000;
8236 if (insn
& (1 << 23)) {
8238 tmp
= load_reg(s
, rd
);
8239 tcg_gen_ext16u_i32(tmp
, tmp
);
8240 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8243 tmp
= tcg_temp_new_i32();
8244 tcg_gen_movi_i32(tmp
, imm
);
8247 /* Add/sub 12-bit immediate. */
8249 offset
= s
->pc
& ~(uint32_t)3;
8250 if (insn
& (1 << 23))
8254 tmp
= tcg_temp_new_i32();
8255 tcg_gen_movi_i32(tmp
, offset
);
8257 tmp
= load_reg(s
, rn
);
8258 if (insn
& (1 << 23))
8259 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8261 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8264 store_reg(s
, rd
, tmp
);
8267 int shifter_out
= 0;
8268 /* modified 12-bit immediate. */
8269 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8270 imm
= (insn
& 0xff);
8273 /* Nothing to do. */
8275 case 1: /* 00XY00XY */
8278 case 2: /* XY00XY00 */
8282 case 3: /* XYXYXYXY */
8286 default: /* Rotated constant. */
8287 shift
= (shift
<< 1) | (imm
>> 7);
8289 imm
= imm
<< (32 - shift
);
8293 tmp2
= tcg_temp_new_i32();
8294 tcg_gen_movi_i32(tmp2
, imm
);
8295 rn
= (insn
>> 16) & 0xf;
8297 tmp
= tcg_temp_new_i32();
8298 tcg_gen_movi_i32(tmp
, 0);
8300 tmp
= load_reg(s
, rn
);
8302 op
= (insn
>> 21) & 0xf;
8303 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8304 shifter_out
, tmp
, tmp2
))
8306 tcg_temp_free_i32(tmp2
);
8307 rd
= (insn
>> 8) & 0xf;
8309 store_reg(s
, rd
, tmp
);
8311 tcg_temp_free_i32(tmp
);
8316 case 12: /* Load/store single data item. */
8321 if ((insn
& 0x01100000) == 0x01000000) {
8322 if (disas_neon_ls_insn(env
, s
, insn
))
8326 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8328 if (!(insn
& (1 << 20))) {
8332 /* Byte or halfword load space with dest == r15 : memory hints.
8333 * Catch them early so we don't emit pointless addressing code.
8334 * This space is a mix of:
8335 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8336 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8338 * unallocated hints, which must be treated as NOPs
8339 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8340 * which is easiest for the decoding logic
8341 * Some space which must UNDEF
8343 int op1
= (insn
>> 23) & 3;
8344 int op2
= (insn
>> 6) & 0x3f;
8349 /* UNPREDICTABLE or unallocated hint */
8353 return 0; /* PLD* or unallocated hint */
8355 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8356 return 0; /* PLD* or unallocated hint */
8358 /* UNDEF space, or an UNPREDICTABLE */
8364 addr
= tcg_temp_new_i32();
8366 /* s->pc has already been incremented by 4. */
8367 imm
= s
->pc
& 0xfffffffc;
8368 if (insn
& (1 << 23))
8369 imm
+= insn
& 0xfff;
8371 imm
-= insn
& 0xfff;
8372 tcg_gen_movi_i32(addr
, imm
);
8374 addr
= load_reg(s
, rn
);
8375 if (insn
& (1 << 23)) {
8376 /* Positive offset. */
8378 tcg_gen_addi_i32(addr
, addr
, imm
);
8381 switch ((insn
>> 8) & 0xf) {
8382 case 0x0: /* Shifted Register. */
8383 shift
= (insn
>> 4) & 0xf;
8385 tcg_temp_free_i32(addr
);
8388 tmp
= load_reg(s
, rm
);
8390 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8391 tcg_gen_add_i32(addr
, addr
, tmp
);
8392 tcg_temp_free_i32(tmp
);
8394 case 0xc: /* Negative offset. */
8395 tcg_gen_addi_i32(addr
, addr
, -imm
);
8397 case 0xe: /* User privilege. */
8398 tcg_gen_addi_i32(addr
, addr
, imm
);
8401 case 0x9: /* Post-decrement. */
8404 case 0xb: /* Post-increment. */
8408 case 0xd: /* Pre-decrement. */
8411 case 0xf: /* Pre-increment. */
8412 tcg_gen_addi_i32(addr
, addr
, imm
);
8416 tcg_temp_free_i32(addr
);
8421 if (insn
& (1 << 20)) {
8424 case 0: tmp
= gen_ld8u(addr
, user
); break;
8425 case 4: tmp
= gen_ld8s(addr
, user
); break;
8426 case 1: tmp
= gen_ld16u(addr
, user
); break;
8427 case 5: tmp
= gen_ld16s(addr
, user
); break;
8428 case 2: tmp
= gen_ld32(addr
, user
); break;
8430 tcg_temp_free_i32(addr
);
8436 store_reg(s
, rs
, tmp
);
8440 tmp
= load_reg(s
, rs
);
8442 case 0: gen_st8(tmp
, addr
, user
); break;
8443 case 1: gen_st16(tmp
, addr
, user
); break;
8444 case 2: gen_st32(tmp
, addr
, user
); break;
8446 tcg_temp_free_i32(addr
);
8451 tcg_gen_addi_i32(addr
, addr
, imm
);
8453 store_reg(s
, rn
, addr
);
8455 tcg_temp_free_i32(addr
);
8467 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
8469 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8476 if (s
->condexec_mask
) {
8477 cond
= s
->condexec_cond
;
8478 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
8479 s
->condlabel
= gen_new_label();
8480 gen_test_cc(cond
^ 1, s
->condlabel
);
8485 insn
= lduw_code(s
->pc
);
8488 switch (insn
>> 12) {
8492 op
= (insn
>> 11) & 3;
8495 rn
= (insn
>> 3) & 7;
8496 tmp
= load_reg(s
, rn
);
8497 if (insn
& (1 << 10)) {
8499 tmp2
= tcg_temp_new_i32();
8500 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
8503 rm
= (insn
>> 6) & 7;
8504 tmp2
= load_reg(s
, rm
);
8506 if (insn
& (1 << 9)) {
8507 if (s
->condexec_mask
)
8508 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8510 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8512 if (s
->condexec_mask
)
8513 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8515 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8517 tcg_temp_free_i32(tmp2
);
8518 store_reg(s
, rd
, tmp
);
8520 /* shift immediate */
8521 rm
= (insn
>> 3) & 7;
8522 shift
= (insn
>> 6) & 0x1f;
8523 tmp
= load_reg(s
, rm
);
8524 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
8525 if (!s
->condexec_mask
)
8527 store_reg(s
, rd
, tmp
);
8531 /* arithmetic large immediate */
8532 op
= (insn
>> 11) & 3;
8533 rd
= (insn
>> 8) & 0x7;
8534 if (op
== 0) { /* mov */
8535 tmp
= tcg_temp_new_i32();
8536 tcg_gen_movi_i32(tmp
, insn
& 0xff);
8537 if (!s
->condexec_mask
)
8539 store_reg(s
, rd
, tmp
);
8541 tmp
= load_reg(s
, rd
);
8542 tmp2
= tcg_temp_new_i32();
8543 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
8546 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8547 tcg_temp_free_i32(tmp
);
8548 tcg_temp_free_i32(tmp2
);
8551 if (s
->condexec_mask
)
8552 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8554 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8555 tcg_temp_free_i32(tmp2
);
8556 store_reg(s
, rd
, tmp
);
8559 if (s
->condexec_mask
)
8560 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8562 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8563 tcg_temp_free_i32(tmp2
);
8564 store_reg(s
, rd
, tmp
);
8570 if (insn
& (1 << 11)) {
8571 rd
= (insn
>> 8) & 7;
8572 /* load pc-relative. Bit 1 of PC is ignored. */
8573 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
8574 val
&= ~(uint32_t)2;
8575 addr
= tcg_temp_new_i32();
8576 tcg_gen_movi_i32(addr
, val
);
8577 tmp
= gen_ld32(addr
, IS_USER(s
));
8578 tcg_temp_free_i32(addr
);
8579 store_reg(s
, rd
, tmp
);
8582 if (insn
& (1 << 10)) {
8583 /* data processing extended or blx */
8584 rd
= (insn
& 7) | ((insn
>> 4) & 8);
8585 rm
= (insn
>> 3) & 0xf;
8586 op
= (insn
>> 8) & 3;
8589 tmp
= load_reg(s
, rd
);
8590 tmp2
= load_reg(s
, rm
);
8591 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8592 tcg_temp_free_i32(tmp2
);
8593 store_reg(s
, rd
, tmp
);
8596 tmp
= load_reg(s
, rd
);
8597 tmp2
= load_reg(s
, rm
);
8598 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8599 tcg_temp_free_i32(tmp2
);
8600 tcg_temp_free_i32(tmp
);
8602 case 2: /* mov/cpy */
8603 tmp
= load_reg(s
, rm
);
8604 store_reg(s
, rd
, tmp
);
8606 case 3:/* branch [and link] exchange thumb register */
8607 tmp
= load_reg(s
, rm
);
8608 if (insn
& (1 << 7)) {
8609 val
= (uint32_t)s
->pc
| 1;
8610 tmp2
= tcg_temp_new_i32();
8611 tcg_gen_movi_i32(tmp2
, val
);
8612 store_reg(s
, 14, tmp2
);
8620 /* data processing register */
8622 rm
= (insn
>> 3) & 7;
8623 op
= (insn
>> 6) & 0xf;
8624 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
8625 /* the shift/rotate ops want the operands backwards */
8634 if (op
== 9) { /* neg */
8635 tmp
= tcg_temp_new_i32();
8636 tcg_gen_movi_i32(tmp
, 0);
8637 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
8638 tmp
= load_reg(s
, rd
);
8643 tmp2
= load_reg(s
, rm
);
8646 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8647 if (!s
->condexec_mask
)
8651 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8652 if (!s
->condexec_mask
)
8656 if (s
->condexec_mask
) {
8657 gen_helper_shl(tmp2
, tmp2
, tmp
);
8659 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
8664 if (s
->condexec_mask
) {
8665 gen_helper_shr(tmp2
, tmp2
, tmp
);
8667 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
8672 if (s
->condexec_mask
) {
8673 gen_helper_sar(tmp2
, tmp2
, tmp
);
8675 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
8680 if (s
->condexec_mask
)
8683 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
8686 if (s
->condexec_mask
)
8687 gen_sub_carry(tmp
, tmp
, tmp2
);
8689 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
8692 if (s
->condexec_mask
) {
8693 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
8694 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
8696 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
8701 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8706 if (s
->condexec_mask
)
8707 tcg_gen_neg_i32(tmp
, tmp2
);
8709 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8712 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8716 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8720 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8721 if (!s
->condexec_mask
)
8725 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8726 if (!s
->condexec_mask
)
8730 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8731 if (!s
->condexec_mask
)
8735 tcg_gen_not_i32(tmp2
, tmp2
);
8736 if (!s
->condexec_mask
)
8744 store_reg(s
, rm
, tmp2
);
8746 tcg_temp_free_i32(tmp
);
8748 store_reg(s
, rd
, tmp
);
8749 tcg_temp_free_i32(tmp2
);
8752 tcg_temp_free_i32(tmp
);
8753 tcg_temp_free_i32(tmp2
);
8758 /* load/store register offset. */
8760 rn
= (insn
>> 3) & 7;
8761 rm
= (insn
>> 6) & 7;
8762 op
= (insn
>> 9) & 7;
8763 addr
= load_reg(s
, rn
);
8764 tmp
= load_reg(s
, rm
);
8765 tcg_gen_add_i32(addr
, addr
, tmp
);
8766 tcg_temp_free_i32(tmp
);
8768 if (op
< 3) /* store */
8769 tmp
= load_reg(s
, rd
);
8773 gen_st32(tmp
, addr
, IS_USER(s
));
8776 gen_st16(tmp
, addr
, IS_USER(s
));
8779 gen_st8(tmp
, addr
, IS_USER(s
));
8782 tmp
= gen_ld8s(addr
, IS_USER(s
));
8785 tmp
= gen_ld32(addr
, IS_USER(s
));
8788 tmp
= gen_ld16u(addr
, IS_USER(s
));
8791 tmp
= gen_ld8u(addr
, IS_USER(s
));
8794 tmp
= gen_ld16s(addr
, IS_USER(s
));
8797 if (op
>= 3) /* load */
8798 store_reg(s
, rd
, tmp
);
8799 tcg_temp_free_i32(addr
);
8803 /* load/store word immediate offset */
8805 rn
= (insn
>> 3) & 7;
8806 addr
= load_reg(s
, rn
);
8807 val
= (insn
>> 4) & 0x7c;
8808 tcg_gen_addi_i32(addr
, addr
, val
);
8810 if (insn
& (1 << 11)) {
8812 tmp
= gen_ld32(addr
, IS_USER(s
));
8813 store_reg(s
, rd
, tmp
);
8816 tmp
= load_reg(s
, rd
);
8817 gen_st32(tmp
, addr
, IS_USER(s
));
8819 tcg_temp_free_i32(addr
);
8823 /* load/store byte immediate offset */
8825 rn
= (insn
>> 3) & 7;
8826 addr
= load_reg(s
, rn
);
8827 val
= (insn
>> 6) & 0x1f;
8828 tcg_gen_addi_i32(addr
, addr
, val
);
8830 if (insn
& (1 << 11)) {
8832 tmp
= gen_ld8u(addr
, IS_USER(s
));
8833 store_reg(s
, rd
, tmp
);
8836 tmp
= load_reg(s
, rd
);
8837 gen_st8(tmp
, addr
, IS_USER(s
));
8839 tcg_temp_free_i32(addr
);
8843 /* load/store halfword immediate offset */
8845 rn
= (insn
>> 3) & 7;
8846 addr
= load_reg(s
, rn
);
8847 val
= (insn
>> 5) & 0x3e;
8848 tcg_gen_addi_i32(addr
, addr
, val
);
8850 if (insn
& (1 << 11)) {
8852 tmp
= gen_ld16u(addr
, IS_USER(s
));
8853 store_reg(s
, rd
, tmp
);
8856 tmp
= load_reg(s
, rd
);
8857 gen_st16(tmp
, addr
, IS_USER(s
));
8859 tcg_temp_free_i32(addr
);
8863 /* load/store from stack */
8864 rd
= (insn
>> 8) & 7;
8865 addr
= load_reg(s
, 13);
8866 val
= (insn
& 0xff) * 4;
8867 tcg_gen_addi_i32(addr
, addr
, val
);
8869 if (insn
& (1 << 11)) {
8871 tmp
= gen_ld32(addr
, IS_USER(s
));
8872 store_reg(s
, rd
, tmp
);
8875 tmp
= load_reg(s
, rd
);
8876 gen_st32(tmp
, addr
, IS_USER(s
));
8878 tcg_temp_free_i32(addr
);
8882 /* add to high reg */
8883 rd
= (insn
>> 8) & 7;
8884 if (insn
& (1 << 11)) {
8886 tmp
= load_reg(s
, 13);
8888 /* PC. bit 1 is ignored. */
8889 tmp
= tcg_temp_new_i32();
8890 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
8892 val
= (insn
& 0xff) * 4;
8893 tcg_gen_addi_i32(tmp
, tmp
, val
);
8894 store_reg(s
, rd
, tmp
);
8899 op
= (insn
>> 8) & 0xf;
8902 /* adjust stack pointer */
8903 tmp
= load_reg(s
, 13);
8904 val
= (insn
& 0x7f) * 4;
8905 if (insn
& (1 << 7))
8906 val
= -(int32_t)val
;
8907 tcg_gen_addi_i32(tmp
, tmp
, val
);
8908 store_reg(s
, 13, tmp
);
8911 case 2: /* sign/zero extend. */
8914 rm
= (insn
>> 3) & 7;
8915 tmp
= load_reg(s
, rm
);
8916 switch ((insn
>> 6) & 3) {
8917 case 0: gen_sxth(tmp
); break;
8918 case 1: gen_sxtb(tmp
); break;
8919 case 2: gen_uxth(tmp
); break;
8920 case 3: gen_uxtb(tmp
); break;
8922 store_reg(s
, rd
, tmp
);
8924 case 4: case 5: case 0xc: case 0xd:
8926 addr
= load_reg(s
, 13);
8927 if (insn
& (1 << 8))
8931 for (i
= 0; i
< 8; i
++) {
8932 if (insn
& (1 << i
))
8935 if ((insn
& (1 << 11)) == 0) {
8936 tcg_gen_addi_i32(addr
, addr
, -offset
);
8938 for (i
= 0; i
< 8; i
++) {
8939 if (insn
& (1 << i
)) {
8940 if (insn
& (1 << 11)) {
8942 tmp
= gen_ld32(addr
, IS_USER(s
));
8943 store_reg(s
, i
, tmp
);
8946 tmp
= load_reg(s
, i
);
8947 gen_st32(tmp
, addr
, IS_USER(s
));
8949 /* advance to the next address. */
8950 tcg_gen_addi_i32(addr
, addr
, 4);
8954 if (insn
& (1 << 8)) {
8955 if (insn
& (1 << 11)) {
8957 tmp
= gen_ld32(addr
, IS_USER(s
));
8958 /* don't set the pc until the rest of the instruction
8962 tmp
= load_reg(s
, 14);
8963 gen_st32(tmp
, addr
, IS_USER(s
));
8965 tcg_gen_addi_i32(addr
, addr
, 4);
8967 if ((insn
& (1 << 11)) == 0) {
8968 tcg_gen_addi_i32(addr
, addr
, -offset
);
8970 /* write back the new stack pointer */
8971 store_reg(s
, 13, addr
);
8972 /* set the new PC value */
8973 if ((insn
& 0x0900) == 0x0900)
8977 case 1: case 3: case 9: case 11: /* czb */
8979 tmp
= load_reg(s
, rm
);
8980 s
->condlabel
= gen_new_label();
8982 if (insn
& (1 << 11))
8983 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
8985 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
8986 tcg_temp_free_i32(tmp
);
8987 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
8988 val
= (uint32_t)s
->pc
+ 2;
8993 case 15: /* IT, nop-hint. */
8994 if ((insn
& 0xf) == 0) {
8995 gen_nop_hint(s
, (insn
>> 4) & 0xf);
8999 s
->condexec_cond
= (insn
>> 4) & 0xe;
9000 s
->condexec_mask
= insn
& 0x1f;
9001 /* No actual code generated for this insn, just setup state. */
9004 case 0xe: /* bkpt */
9005 gen_exception_insn(s
, 2, EXCP_BKPT
);
9010 rn
= (insn
>> 3) & 0x7;
9012 tmp
= load_reg(s
, rn
);
9013 switch ((insn
>> 6) & 3) {
9014 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9015 case 1: gen_rev16(tmp
); break;
9016 case 3: gen_revsh(tmp
); break;
9017 default: goto illegal_op
;
9019 store_reg(s
, rd
, tmp
);
9027 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9030 addr
= tcg_const_i32(16);
9031 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9032 tcg_temp_free_i32(addr
);
9036 addr
= tcg_const_i32(17);
9037 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9038 tcg_temp_free_i32(addr
);
9040 tcg_temp_free_i32(tmp
);
9043 if (insn
& (1 << 4))
9044 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9047 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9057 /* load/store multiple */
9058 rn
= (insn
>> 8) & 0x7;
9059 addr
= load_reg(s
, rn
);
9060 for (i
= 0; i
< 8; i
++) {
9061 if (insn
& (1 << i
)) {
9062 if (insn
& (1 << 11)) {
9064 tmp
= gen_ld32(addr
, IS_USER(s
));
9065 store_reg(s
, i
, tmp
);
9068 tmp
= load_reg(s
, i
);
9069 gen_st32(tmp
, addr
, IS_USER(s
));
9071 /* advance to the next address */
9072 tcg_gen_addi_i32(addr
, addr
, 4);
9075 /* Base register writeback. */
9076 if ((insn
& (1 << rn
)) == 0) {
9077 store_reg(s
, rn
, addr
);
9079 tcg_temp_free_i32(addr
);
9084 /* conditional branch or swi */
9085 cond
= (insn
>> 8) & 0xf;
9091 gen_set_pc_im(s
->pc
);
9092 s
->is_jmp
= DISAS_SWI
;
9095 /* generate a conditional jump to next instruction */
9096 s
->condlabel
= gen_new_label();
9097 gen_test_cc(cond
^ 1, s
->condlabel
);
9100 /* jump to the offset */
9101 val
= (uint32_t)s
->pc
+ 2;
9102 offset
= ((int32_t)insn
<< 24) >> 24;
9108 if (insn
& (1 << 11)) {
9109 if (disas_thumb2_insn(env
, s
, insn
))
9113 /* unconditional branch */
9114 val
= (uint32_t)s
->pc
;
9115 offset
= ((int32_t)insn
<< 21) >> 21;
9116 val
+= (offset
<< 1) + 2;
9121 if (disas_thumb2_insn(env
, s
, insn
))
9127 gen_exception_insn(s
, 4, EXCP_UDEF
);
9131 gen_exception_insn(s
, 2, EXCP_UDEF
);
9134 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9135 basic block 'tb'. If search_pc is TRUE, also generate PC
9136 information for each intermediate instruction. */
9137 static inline void gen_intermediate_code_internal(CPUState
*env
,
9138 TranslationBlock
*tb
,
9141 DisasContext dc1
, *dc
= &dc1
;
9143 uint16_t *gen_opc_end
;
9145 target_ulong pc_start
;
9146 uint32_t next_page_start
;
9150 /* generate intermediate code */
9155 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9157 dc
->is_jmp
= DISAS_NEXT
;
9159 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9161 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9162 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9163 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9164 #if !defined(CONFIG_USER_ONLY)
9165 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9167 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9168 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9169 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9170 cpu_F0s
= tcg_temp_new_i32();
9171 cpu_F1s
= tcg_temp_new_i32();
9172 cpu_F0d
= tcg_temp_new_i64();
9173 cpu_F1d
= tcg_temp_new_i64();
9176 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9177 cpu_M0
= tcg_temp_new_i64();
9178 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9181 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9183 max_insns
= CF_COUNT_MASK
;
9187 tcg_clear_temp_count();
9189 /* A note on handling of the condexec (IT) bits:
9191 * We want to avoid the overhead of having to write the updated condexec
9192 * bits back to the CPUState for every instruction in an IT block. So:
9193 * (1) if the condexec bits are not already zero then we write
9194 * zero back into the CPUState now. This avoids complications trying
9195 * to do it at the end of the block. (For example if we don't do this
9196 * it's hard to identify whether we can safely skip writing condexec
9197 * at the end of the TB, which we definitely want to do for the case
9198 * where a TB doesn't do anything with the IT state at all.)
9199 * (2) if we are going to leave the TB then we call gen_set_condexec()
9200 * which will write the correct value into CPUState if zero is wrong.
9201 * This is done both for leaving the TB at the end, and for leaving
9202 * it because of an exception we know will happen, which is done in
9203 * gen_exception_insn(). The latter is necessary because we need to
9204 * leave the TB with the PC/IT state just prior to execution of the
9205 * instruction which caused the exception.
9206 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9207 * then the CPUState will be wrong and we need to reset it.
9208 * This is handled in the same way as restoration of the
9209 * PC in these situations: we will be called again with search_pc=1
9210 * and generate a mapping of the condexec bits for each PC in
9211 * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9212 * the condexec bits.
9214 * Note that there are no instructions which can read the condexec
9215 * bits, and none which can write non-static values to them, so
9216 * we don't need to care about whether CPUState is correct in the
9220 /* Reset the conditional execution bits immediately. This avoids
9221 complications trying to do it at the end of the block. */
9222 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9224 TCGv tmp
= tcg_temp_new_i32();
9225 tcg_gen_movi_i32(tmp
, 0);
9226 store_cpu_field(tmp
, condexec_bits
);
9229 #ifdef CONFIG_USER_ONLY
9230 /* Intercept jump to the magic kernel page. */
9231 if (dc
->pc
>= 0xffff0000) {
9232 /* We always get here via a jump, so know we are not in a
9233 conditional execution block. */
9234 gen_exception(EXCP_KERNEL_TRAP
);
9235 dc
->is_jmp
= DISAS_UPDATE
;
9239 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9240 /* We always get here via a jump, so know we are not in a
9241 conditional execution block. */
9242 gen_exception(EXCP_EXCEPTION_EXIT
);
9243 dc
->is_jmp
= DISAS_UPDATE
;
9248 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9249 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9250 if (bp
->pc
== dc
->pc
) {
9251 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9252 /* Advance PC so that clearing the breakpoint will
9253 invalidate this TB. */
9255 goto done_generating
;
9261 j
= gen_opc_ptr
- gen_opc_buf
;
9265 gen_opc_instr_start
[lj
++] = 0;
9267 gen_opc_pc
[lj
] = dc
->pc
;
9268 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9269 gen_opc_instr_start
[lj
] = 1;
9270 gen_opc_icount
[lj
] = num_insns
;
9273 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9276 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9277 tcg_gen_debug_insn_start(dc
->pc
);
9281 disas_thumb_insn(env
, dc
);
9282 if (dc
->condexec_mask
) {
9283 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9284 | ((dc
->condexec_mask
>> 4) & 1);
9285 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9286 if (dc
->condexec_mask
== 0) {
9287 dc
->condexec_cond
= 0;
9291 disas_arm_insn(env
, dc
);
9294 if (dc
->condjmp
&& !dc
->is_jmp
) {
9295 gen_set_label(dc
->condlabel
);
9299 if (tcg_check_temp_count()) {
9300 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9303 /* Translation stops when a conditional branch is encountered.
9304 * Otherwise the subsequent code could get translated several times.
9305 * Also stop translation when a page boundary is reached. This
9306 * ensures prefetch aborts occur at the right place. */
9308 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9309 !env
->singlestep_enabled
&&
9311 dc
->pc
< next_page_start
&&
9312 num_insns
< max_insns
);
9314 if (tb
->cflags
& CF_LAST_IO
) {
9316 /* FIXME: This can theoretically happen with self-modifying
9318 cpu_abort(env
, "IO on conditional branch instruction");
9323 /* At this stage dc->condjmp will only be set when the skipped
9324 instruction was a conditional branch or trap, and the PC has
9325 already been written. */
9326 if (unlikely(env
->singlestep_enabled
)) {
9327 /* Make sure the pc is updated, and raise a debug exception. */
9329 gen_set_condexec(dc
);
9330 if (dc
->is_jmp
== DISAS_SWI
) {
9331 gen_exception(EXCP_SWI
);
9333 gen_exception(EXCP_DEBUG
);
9335 gen_set_label(dc
->condlabel
);
9337 if (dc
->condjmp
|| !dc
->is_jmp
) {
9338 gen_set_pc_im(dc
->pc
);
9341 gen_set_condexec(dc
);
9342 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9343 gen_exception(EXCP_SWI
);
9345 /* FIXME: Single stepping a WFI insn will not halt
9347 gen_exception(EXCP_DEBUG
);
9350 /* While branches must always occur at the end of an IT block,
9351 there are a few other things that can cause us to terminate
9352 the TB in the middel of an IT block:
9353 - Exception generating instructions (bkpt, swi, undefined).
9355 - Hardware watchpoints.
9356 Hardware breakpoints have already been handled and skip this code.
9358 gen_set_condexec(dc
);
9359 switch(dc
->is_jmp
) {
9361 gen_goto_tb(dc
, 1, dc
->pc
);
9366 /* indicate that the hash table must be used to find the next TB */
9370 /* nothing more to generate */
9376 gen_exception(EXCP_SWI
);
9380 gen_set_label(dc
->condlabel
);
9381 gen_set_condexec(dc
);
9382 gen_goto_tb(dc
, 1, dc
->pc
);
9388 gen_icount_end(tb
, num_insns
);
9389 *gen_opc_ptr
= INDEX_op_end
;
9392 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9393 qemu_log("----------------\n");
9394 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9395 log_target_disas(pc_start
, dc
->pc
- pc_start
, dc
->thumb
);
9400 j
= gen_opc_ptr
- gen_opc_buf
;
9403 gen_opc_instr_start
[lj
++] = 0;
9405 tb
->size
= dc
->pc
- pc_start
;
9406 tb
->icount
= num_insns
;
9410 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9412 gen_intermediate_code_internal(env
, tb
, 0);
9415 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9417 gen_intermediate_code_internal(env
, tb
, 1);
9420 static const char *cpu_mode_names
[16] = {
9421 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9422 "???", "???", "???", "und", "???", "???", "???", "sys"
9425 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
9435 /* ??? This assumes float64 and double have the same layout.
9436 Oh well, it's only debug dumps. */
9445 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9447 cpu_fprintf(f
, "\n");
9449 cpu_fprintf(f
, " ");
9451 psr
= cpsr_read(env
);
9452 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9454 psr
& (1 << 31) ? 'N' : '-',
9455 psr
& (1 << 30) ? 'Z' : '-',
9456 psr
& (1 << 29) ? 'C' : '-',
9457 psr
& (1 << 28) ? 'V' : '-',
9458 psr
& CPSR_T
? 'T' : 'A',
9459 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9462 for (i
= 0; i
< 16; i
++) {
9463 d
.d
= env
->vfp
.regs
[i
];
9467 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9468 i
* 2, (int)s0
.i
, s0
.s
,
9469 i
* 2 + 1, (int)s1
.i
, s1
.s
,
9470 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
9473 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
9477 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
9478 unsigned long searched_pc
, int pc_pos
, void *puc
)
9480 env
->regs
[15] = gen_opc_pc
[pc_pos
];
9481 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];