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_SIZE(name) \
1163 IWMMXT_OP(name##b) \
1164 IWMMXT_OP(name##w) \
1167 #define IWMMXT_OP_1(name) \
1168 static inline void gen_op_iwmmxt_##name##_M0(void) \
1170 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \
1184 IWMMXT_OP_SIZE(unpackl
)
1185 IWMMXT_OP_SIZE(unpackh
)
1187 IWMMXT_OP_1(unpacklub
)
1188 IWMMXT_OP_1(unpackluw
)
1189 IWMMXT_OP_1(unpacklul
)
1190 IWMMXT_OP_1(unpackhub
)
1191 IWMMXT_OP_1(unpackhuw
)
1192 IWMMXT_OP_1(unpackhul
)
1193 IWMMXT_OP_1(unpacklsb
)
1194 IWMMXT_OP_1(unpacklsw
)
1195 IWMMXT_OP_1(unpacklsl
)
1196 IWMMXT_OP_1(unpackhsb
)
1197 IWMMXT_OP_1(unpackhsw
)
1198 IWMMXT_OP_1(unpackhsl
)
1200 IWMMXT_OP_SIZE(cmpeq
)
1201 IWMMXT_OP_SIZE(cmpgtu
)
1202 IWMMXT_OP_SIZE(cmpgts
)
1204 IWMMXT_OP_SIZE(mins
)
1205 IWMMXT_OP_SIZE(minu
)
1206 IWMMXT_OP_SIZE(maxs
)
1207 IWMMXT_OP_SIZE(maxu
)
1209 IWMMXT_OP_SIZE(subn
)
1210 IWMMXT_OP_SIZE(addn
)
1211 IWMMXT_OP_SIZE(subu
)
1212 IWMMXT_OP_SIZE(addu
)
1213 IWMMXT_OP_SIZE(subs
)
1214 IWMMXT_OP_SIZE(adds
)
1230 static void gen_op_iwmmxt_set_mup(void)
1233 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1234 tcg_gen_ori_i32(tmp
, tmp
, 2);
1235 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1238 static void gen_op_iwmmxt_set_cup(void)
1241 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1242 tcg_gen_ori_i32(tmp
, tmp
, 1);
1243 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1246 static void gen_op_iwmmxt_setpsr_nz(void)
1248 TCGv tmp
= tcg_temp_new_i32();
1249 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1250 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1253 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1255 iwmmxt_load_reg(cpu_V1
, rn
);
1256 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1257 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1260 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1266 rd
= (insn
>> 16) & 0xf;
1267 tmp
= load_reg(s
, rd
);
1269 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1270 if (insn
& (1 << 24)) {
1272 if (insn
& (1 << 23))
1273 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1275 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1276 tcg_gen_mov_i32(dest
, tmp
);
1277 if (insn
& (1 << 21))
1278 store_reg(s
, rd
, tmp
);
1280 tcg_temp_free_i32(tmp
);
1281 } else if (insn
& (1 << 21)) {
1283 tcg_gen_mov_i32(dest
, tmp
);
1284 if (insn
& (1 << 23))
1285 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1287 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1288 store_reg(s
, rd
, tmp
);
1289 } else if (!(insn
& (1 << 23)))
1294 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1296 int rd
= (insn
>> 0) & 0xf;
1299 if (insn
& (1 << 8)) {
1300 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1303 tmp
= iwmmxt_load_creg(rd
);
1306 tmp
= tcg_temp_new_i32();
1307 iwmmxt_load_reg(cpu_V0
, rd
);
1308 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1310 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1311 tcg_gen_mov_i32(dest
, tmp
);
1312 tcg_temp_free_i32(tmp
);
1316 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1317 (ie. an undefined instruction). */
1318 static int disas_iwmmxt_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
1321 int rdhi
, rdlo
, rd0
, rd1
, i
;
1323 TCGv tmp
, tmp2
, tmp3
;
1325 if ((insn
& 0x0e000e00) == 0x0c000000) {
1326 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1328 rdlo
= (insn
>> 12) & 0xf;
1329 rdhi
= (insn
>> 16) & 0xf;
1330 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1331 iwmmxt_load_reg(cpu_V0
, wrd
);
1332 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1333 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1334 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1335 } else { /* TMCRR */
1336 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1337 iwmmxt_store_reg(cpu_V0
, wrd
);
1338 gen_op_iwmmxt_set_mup();
1343 wrd
= (insn
>> 12) & 0xf;
1344 addr
= tcg_temp_new_i32();
1345 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1346 tcg_temp_free_i32(addr
);
1349 if (insn
& ARM_CP_RW_BIT
) {
1350 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1351 tmp
= tcg_temp_new_i32();
1352 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1353 iwmmxt_store_creg(wrd
, tmp
);
1356 if (insn
& (1 << 8)) {
1357 if (insn
& (1 << 22)) { /* WLDRD */
1358 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1360 } else { /* WLDRW wRd */
1361 tmp
= gen_ld32(addr
, IS_USER(s
));
1364 if (insn
& (1 << 22)) { /* WLDRH */
1365 tmp
= gen_ld16u(addr
, IS_USER(s
));
1366 } else { /* WLDRB */
1367 tmp
= gen_ld8u(addr
, IS_USER(s
));
1371 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1372 tcg_temp_free_i32(tmp
);
1374 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1377 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1378 tmp
= iwmmxt_load_creg(wrd
);
1379 gen_st32(tmp
, addr
, IS_USER(s
));
1381 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1382 tmp
= tcg_temp_new_i32();
1383 if (insn
& (1 << 8)) {
1384 if (insn
& (1 << 22)) { /* WSTRD */
1385 tcg_temp_free_i32(tmp
);
1386 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1387 } else { /* WSTRW wRd */
1388 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1389 gen_st32(tmp
, addr
, IS_USER(s
));
1392 if (insn
& (1 << 22)) { /* WSTRH */
1393 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1394 gen_st16(tmp
, addr
, IS_USER(s
));
1395 } else { /* WSTRB */
1396 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1397 gen_st8(tmp
, addr
, IS_USER(s
));
1402 tcg_temp_free_i32(addr
);
1406 if ((insn
& 0x0f000000) != 0x0e000000)
1409 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1410 case 0x000: /* WOR */
1411 wrd
= (insn
>> 12) & 0xf;
1412 rd0
= (insn
>> 0) & 0xf;
1413 rd1
= (insn
>> 16) & 0xf;
1414 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1415 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1416 gen_op_iwmmxt_setpsr_nz();
1417 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1418 gen_op_iwmmxt_set_mup();
1419 gen_op_iwmmxt_set_cup();
1421 case 0x011: /* TMCR */
1424 rd
= (insn
>> 12) & 0xf;
1425 wrd
= (insn
>> 16) & 0xf;
1427 case ARM_IWMMXT_wCID
:
1428 case ARM_IWMMXT_wCASF
:
1430 case ARM_IWMMXT_wCon
:
1431 gen_op_iwmmxt_set_cup();
1433 case ARM_IWMMXT_wCSSF
:
1434 tmp
= iwmmxt_load_creg(wrd
);
1435 tmp2
= load_reg(s
, rd
);
1436 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1437 tcg_temp_free_i32(tmp2
);
1438 iwmmxt_store_creg(wrd
, tmp
);
1440 case ARM_IWMMXT_wCGR0
:
1441 case ARM_IWMMXT_wCGR1
:
1442 case ARM_IWMMXT_wCGR2
:
1443 case ARM_IWMMXT_wCGR3
:
1444 gen_op_iwmmxt_set_cup();
1445 tmp
= load_reg(s
, rd
);
1446 iwmmxt_store_creg(wrd
, tmp
);
1452 case 0x100: /* WXOR */
1453 wrd
= (insn
>> 12) & 0xf;
1454 rd0
= (insn
>> 0) & 0xf;
1455 rd1
= (insn
>> 16) & 0xf;
1456 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1457 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1458 gen_op_iwmmxt_setpsr_nz();
1459 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1460 gen_op_iwmmxt_set_mup();
1461 gen_op_iwmmxt_set_cup();
1463 case 0x111: /* TMRC */
1466 rd
= (insn
>> 12) & 0xf;
1467 wrd
= (insn
>> 16) & 0xf;
1468 tmp
= iwmmxt_load_creg(wrd
);
1469 store_reg(s
, rd
, tmp
);
1471 case 0x300: /* WANDN */
1472 wrd
= (insn
>> 12) & 0xf;
1473 rd0
= (insn
>> 0) & 0xf;
1474 rd1
= (insn
>> 16) & 0xf;
1475 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1476 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1477 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1478 gen_op_iwmmxt_setpsr_nz();
1479 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1480 gen_op_iwmmxt_set_mup();
1481 gen_op_iwmmxt_set_cup();
1483 case 0x200: /* WAND */
1484 wrd
= (insn
>> 12) & 0xf;
1485 rd0
= (insn
>> 0) & 0xf;
1486 rd1
= (insn
>> 16) & 0xf;
1487 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1488 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1489 gen_op_iwmmxt_setpsr_nz();
1490 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1491 gen_op_iwmmxt_set_mup();
1492 gen_op_iwmmxt_set_cup();
1494 case 0x810: case 0xa10: /* WMADD */
1495 wrd
= (insn
>> 12) & 0xf;
1496 rd0
= (insn
>> 0) & 0xf;
1497 rd1
= (insn
>> 16) & 0xf;
1498 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1499 if (insn
& (1 << 21))
1500 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1502 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1503 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1504 gen_op_iwmmxt_set_mup();
1506 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1507 wrd
= (insn
>> 12) & 0xf;
1508 rd0
= (insn
>> 16) & 0xf;
1509 rd1
= (insn
>> 0) & 0xf;
1510 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1511 switch ((insn
>> 22) & 3) {
1513 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1516 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1519 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1524 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1525 gen_op_iwmmxt_set_mup();
1526 gen_op_iwmmxt_set_cup();
1528 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1529 wrd
= (insn
>> 12) & 0xf;
1530 rd0
= (insn
>> 16) & 0xf;
1531 rd1
= (insn
>> 0) & 0xf;
1532 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1533 switch ((insn
>> 22) & 3) {
1535 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1538 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1541 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1546 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1547 gen_op_iwmmxt_set_mup();
1548 gen_op_iwmmxt_set_cup();
1550 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1551 wrd
= (insn
>> 12) & 0xf;
1552 rd0
= (insn
>> 16) & 0xf;
1553 rd1
= (insn
>> 0) & 0xf;
1554 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1555 if (insn
& (1 << 22))
1556 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1558 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1559 if (!(insn
& (1 << 20)))
1560 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1562 gen_op_iwmmxt_set_mup();
1564 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1565 wrd
= (insn
>> 12) & 0xf;
1566 rd0
= (insn
>> 16) & 0xf;
1567 rd1
= (insn
>> 0) & 0xf;
1568 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1569 if (insn
& (1 << 21)) {
1570 if (insn
& (1 << 20))
1571 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1573 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1575 if (insn
& (1 << 20))
1576 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1578 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1580 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1581 gen_op_iwmmxt_set_mup();
1583 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1584 wrd
= (insn
>> 12) & 0xf;
1585 rd0
= (insn
>> 16) & 0xf;
1586 rd1
= (insn
>> 0) & 0xf;
1587 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1588 if (insn
& (1 << 21))
1589 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1591 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1592 if (!(insn
& (1 << 20))) {
1593 iwmmxt_load_reg(cpu_V1
, wrd
);
1594 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1596 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1597 gen_op_iwmmxt_set_mup();
1599 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1600 wrd
= (insn
>> 12) & 0xf;
1601 rd0
= (insn
>> 16) & 0xf;
1602 rd1
= (insn
>> 0) & 0xf;
1603 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1604 switch ((insn
>> 22) & 3) {
1606 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1609 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1612 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1617 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1618 gen_op_iwmmxt_set_mup();
1619 gen_op_iwmmxt_set_cup();
1621 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1622 wrd
= (insn
>> 12) & 0xf;
1623 rd0
= (insn
>> 16) & 0xf;
1624 rd1
= (insn
>> 0) & 0xf;
1625 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1626 if (insn
& (1 << 22)) {
1627 if (insn
& (1 << 20))
1628 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1630 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1632 if (insn
& (1 << 20))
1633 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1635 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1638 gen_op_iwmmxt_set_mup();
1639 gen_op_iwmmxt_set_cup();
1641 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1642 wrd
= (insn
>> 12) & 0xf;
1643 rd0
= (insn
>> 16) & 0xf;
1644 rd1
= (insn
>> 0) & 0xf;
1645 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1646 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1647 tcg_gen_andi_i32(tmp
, tmp
, 7);
1648 iwmmxt_load_reg(cpu_V1
, rd1
);
1649 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1650 tcg_temp_free_i32(tmp
);
1651 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1652 gen_op_iwmmxt_set_mup();
1654 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1655 if (((insn
>> 6) & 3) == 3)
1657 rd
= (insn
>> 12) & 0xf;
1658 wrd
= (insn
>> 16) & 0xf;
1659 tmp
= load_reg(s
, rd
);
1660 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1661 switch ((insn
>> 6) & 3) {
1663 tmp2
= tcg_const_i32(0xff);
1664 tmp3
= tcg_const_i32((insn
& 7) << 3);
1667 tmp2
= tcg_const_i32(0xffff);
1668 tmp3
= tcg_const_i32((insn
& 3) << 4);
1671 tmp2
= tcg_const_i32(0xffffffff);
1672 tmp3
= tcg_const_i32((insn
& 1) << 5);
1678 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1679 tcg_temp_free(tmp3
);
1680 tcg_temp_free(tmp2
);
1681 tcg_temp_free_i32(tmp
);
1682 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1683 gen_op_iwmmxt_set_mup();
1685 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1686 rd
= (insn
>> 12) & 0xf;
1687 wrd
= (insn
>> 16) & 0xf;
1688 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1690 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1691 tmp
= tcg_temp_new_i32();
1692 switch ((insn
>> 22) & 3) {
1694 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1695 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1697 tcg_gen_ext8s_i32(tmp
, tmp
);
1699 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1703 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1704 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1706 tcg_gen_ext16s_i32(tmp
, tmp
);
1708 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1712 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1713 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1716 store_reg(s
, rd
, tmp
);
1718 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1719 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1721 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1722 switch ((insn
>> 22) & 3) {
1724 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1727 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1730 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1733 tcg_gen_shli_i32(tmp
, tmp
, 28);
1735 tcg_temp_free_i32(tmp
);
1737 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1738 if (((insn
>> 6) & 3) == 3)
1740 rd
= (insn
>> 12) & 0xf;
1741 wrd
= (insn
>> 16) & 0xf;
1742 tmp
= load_reg(s
, rd
);
1743 switch ((insn
>> 6) & 3) {
1745 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1748 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1751 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1754 tcg_temp_free_i32(tmp
);
1755 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1756 gen_op_iwmmxt_set_mup();
1758 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1759 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1761 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1762 tmp2
= tcg_temp_new_i32();
1763 tcg_gen_mov_i32(tmp2
, tmp
);
1764 switch ((insn
>> 22) & 3) {
1766 for (i
= 0; i
< 7; i
++) {
1767 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1768 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1772 for (i
= 0; i
< 3; i
++) {
1773 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1774 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1778 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1779 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1783 tcg_temp_free_i32(tmp2
);
1784 tcg_temp_free_i32(tmp
);
1786 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1787 wrd
= (insn
>> 12) & 0xf;
1788 rd0
= (insn
>> 16) & 0xf;
1789 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1790 switch ((insn
>> 22) & 3) {
1792 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1795 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1798 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1803 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1804 gen_op_iwmmxt_set_mup();
1806 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1807 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1809 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1810 tmp2
= tcg_temp_new_i32();
1811 tcg_gen_mov_i32(tmp2
, tmp
);
1812 switch ((insn
>> 22) & 3) {
1814 for (i
= 0; i
< 7; i
++) {
1815 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1816 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1820 for (i
= 0; i
< 3; i
++) {
1821 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1822 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1826 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1827 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1831 tcg_temp_free_i32(tmp2
);
1832 tcg_temp_free_i32(tmp
);
1834 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1835 rd
= (insn
>> 12) & 0xf;
1836 rd0
= (insn
>> 16) & 0xf;
1837 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1839 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1840 tmp
= tcg_temp_new_i32();
1841 switch ((insn
>> 22) & 3) {
1843 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1846 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1849 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1852 store_reg(s
, rd
, tmp
);
1854 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1855 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1856 wrd
= (insn
>> 12) & 0xf;
1857 rd0
= (insn
>> 16) & 0xf;
1858 rd1
= (insn
>> 0) & 0xf;
1859 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1860 switch ((insn
>> 22) & 3) {
1862 if (insn
& (1 << 21))
1863 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1865 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1868 if (insn
& (1 << 21))
1869 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1871 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1874 if (insn
& (1 << 21))
1875 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1877 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1882 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1883 gen_op_iwmmxt_set_mup();
1884 gen_op_iwmmxt_set_cup();
1886 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1887 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1888 wrd
= (insn
>> 12) & 0xf;
1889 rd0
= (insn
>> 16) & 0xf;
1890 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1891 switch ((insn
>> 22) & 3) {
1893 if (insn
& (1 << 21))
1894 gen_op_iwmmxt_unpacklsb_M0();
1896 gen_op_iwmmxt_unpacklub_M0();
1899 if (insn
& (1 << 21))
1900 gen_op_iwmmxt_unpacklsw_M0();
1902 gen_op_iwmmxt_unpackluw_M0();
1905 if (insn
& (1 << 21))
1906 gen_op_iwmmxt_unpacklsl_M0();
1908 gen_op_iwmmxt_unpacklul_M0();
1913 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1914 gen_op_iwmmxt_set_mup();
1915 gen_op_iwmmxt_set_cup();
1917 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1918 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1919 wrd
= (insn
>> 12) & 0xf;
1920 rd0
= (insn
>> 16) & 0xf;
1921 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1922 switch ((insn
>> 22) & 3) {
1924 if (insn
& (1 << 21))
1925 gen_op_iwmmxt_unpackhsb_M0();
1927 gen_op_iwmmxt_unpackhub_M0();
1930 if (insn
& (1 << 21))
1931 gen_op_iwmmxt_unpackhsw_M0();
1933 gen_op_iwmmxt_unpackhuw_M0();
1936 if (insn
& (1 << 21))
1937 gen_op_iwmmxt_unpackhsl_M0();
1939 gen_op_iwmmxt_unpackhul_M0();
1944 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1945 gen_op_iwmmxt_set_mup();
1946 gen_op_iwmmxt_set_cup();
1948 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1949 case 0x214: case 0x614: case 0xa14: case 0xe14:
1950 if (((insn
>> 22) & 3) == 0)
1952 wrd
= (insn
>> 12) & 0xf;
1953 rd0
= (insn
>> 16) & 0xf;
1954 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1955 tmp
= tcg_temp_new_i32();
1956 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1957 tcg_temp_free_i32(tmp
);
1960 switch ((insn
>> 22) & 3) {
1962 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_M0
, tmp
);
1965 gen_helper_iwmmxt_srll(cpu_M0
, cpu_M0
, tmp
);
1968 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_M0
, tmp
);
1971 tcg_temp_free_i32(tmp
);
1972 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1973 gen_op_iwmmxt_set_mup();
1974 gen_op_iwmmxt_set_cup();
1976 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
1977 case 0x014: case 0x414: case 0x814: case 0xc14:
1978 if (((insn
>> 22) & 3) == 0)
1980 wrd
= (insn
>> 12) & 0xf;
1981 rd0
= (insn
>> 16) & 0xf;
1982 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1983 tmp
= tcg_temp_new_i32();
1984 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
1985 tcg_temp_free_i32(tmp
);
1988 switch ((insn
>> 22) & 3) {
1990 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_M0
, tmp
);
1993 gen_helper_iwmmxt_sral(cpu_M0
, cpu_M0
, tmp
);
1996 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_M0
, tmp
);
1999 tcg_temp_free_i32(tmp
);
2000 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2001 gen_op_iwmmxt_set_mup();
2002 gen_op_iwmmxt_set_cup();
2004 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2005 case 0x114: case 0x514: case 0x914: case 0xd14:
2006 if (((insn
>> 22) & 3) == 0)
2008 wrd
= (insn
>> 12) & 0xf;
2009 rd0
= (insn
>> 16) & 0xf;
2010 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2011 tmp
= tcg_temp_new_i32();
2012 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2013 tcg_temp_free_i32(tmp
);
2016 switch ((insn
>> 22) & 3) {
2018 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_M0
, tmp
);
2021 gen_helper_iwmmxt_slll(cpu_M0
, cpu_M0
, tmp
);
2024 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_M0
, tmp
);
2027 tcg_temp_free_i32(tmp
);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2029 gen_op_iwmmxt_set_mup();
2030 gen_op_iwmmxt_set_cup();
2032 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2033 case 0x314: case 0x714: case 0xb14: case 0xf14:
2034 if (((insn
>> 22) & 3) == 0)
2036 wrd
= (insn
>> 12) & 0xf;
2037 rd0
= (insn
>> 16) & 0xf;
2038 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2039 tmp
= tcg_temp_new_i32();
2040 switch ((insn
>> 22) & 3) {
2042 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2043 tcg_temp_free_i32(tmp
);
2046 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_M0
, tmp
);
2049 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2050 tcg_temp_free_i32(tmp
);
2053 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_M0
, tmp
);
2056 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2057 tcg_temp_free_i32(tmp
);
2060 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_M0
, tmp
);
2063 tcg_temp_free_i32(tmp
);
2064 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2065 gen_op_iwmmxt_set_mup();
2066 gen_op_iwmmxt_set_cup();
2068 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2069 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2070 wrd
= (insn
>> 12) & 0xf;
2071 rd0
= (insn
>> 16) & 0xf;
2072 rd1
= (insn
>> 0) & 0xf;
2073 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2074 switch ((insn
>> 22) & 3) {
2076 if (insn
& (1 << 21))
2077 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2079 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2082 if (insn
& (1 << 21))
2083 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2085 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2088 if (insn
& (1 << 21))
2089 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2091 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2096 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2097 gen_op_iwmmxt_set_mup();
2099 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2100 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2101 wrd
= (insn
>> 12) & 0xf;
2102 rd0
= (insn
>> 16) & 0xf;
2103 rd1
= (insn
>> 0) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2105 switch ((insn
>> 22) & 3) {
2107 if (insn
& (1 << 21))
2108 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2110 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2113 if (insn
& (1 << 21))
2114 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2116 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2119 if (insn
& (1 << 21))
2120 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2122 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2127 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2128 gen_op_iwmmxt_set_mup();
2130 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2131 case 0x402: case 0x502: case 0x602: case 0x702:
2132 wrd
= (insn
>> 12) & 0xf;
2133 rd0
= (insn
>> 16) & 0xf;
2134 rd1
= (insn
>> 0) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2136 tmp
= tcg_const_i32((insn
>> 20) & 3);
2137 iwmmxt_load_reg(cpu_V1
, rd1
);
2138 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2141 gen_op_iwmmxt_set_mup();
2143 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2144 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2145 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2146 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2147 wrd
= (insn
>> 12) & 0xf;
2148 rd0
= (insn
>> 16) & 0xf;
2149 rd1
= (insn
>> 0) & 0xf;
2150 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2151 switch ((insn
>> 20) & 0xf) {
2153 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2156 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2159 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2162 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2165 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2168 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2171 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2174 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2177 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2182 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2183 gen_op_iwmmxt_set_mup();
2184 gen_op_iwmmxt_set_cup();
2186 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2187 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2188 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2189 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2190 wrd
= (insn
>> 12) & 0xf;
2191 rd0
= (insn
>> 16) & 0xf;
2192 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2193 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2194 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_M0
, tmp
);
2196 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2197 gen_op_iwmmxt_set_mup();
2198 gen_op_iwmmxt_set_cup();
2200 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2201 case 0x418: case 0x518: case 0x618: case 0x718:
2202 case 0x818: case 0x918: case 0xa18: case 0xb18:
2203 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2204 wrd
= (insn
>> 12) & 0xf;
2205 rd0
= (insn
>> 16) & 0xf;
2206 rd1
= (insn
>> 0) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2208 switch ((insn
>> 20) & 0xf) {
2210 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2213 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2216 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2219 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2222 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2225 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2228 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2231 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2234 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2239 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2240 gen_op_iwmmxt_set_mup();
2241 gen_op_iwmmxt_set_cup();
2243 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2244 case 0x408: case 0x508: case 0x608: case 0x708:
2245 case 0x808: case 0x908: case 0xa08: case 0xb08:
2246 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2247 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2249 wrd
= (insn
>> 12) & 0xf;
2250 rd0
= (insn
>> 16) & 0xf;
2251 rd1
= (insn
>> 0) & 0xf;
2252 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2253 switch ((insn
>> 22) & 3) {
2255 if (insn
& (1 << 21))
2256 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2258 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2261 if (insn
& (1 << 21))
2262 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2264 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2267 if (insn
& (1 << 21))
2268 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2270 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2273 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2274 gen_op_iwmmxt_set_mup();
2275 gen_op_iwmmxt_set_cup();
2277 case 0x201: case 0x203: case 0x205: case 0x207:
2278 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2279 case 0x211: case 0x213: case 0x215: case 0x217:
2280 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2281 wrd
= (insn
>> 5) & 0xf;
2282 rd0
= (insn
>> 12) & 0xf;
2283 rd1
= (insn
>> 0) & 0xf;
2284 if (rd0
== 0xf || rd1
== 0xf)
2286 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2287 tmp
= load_reg(s
, rd0
);
2288 tmp2
= load_reg(s
, rd1
);
2289 switch ((insn
>> 16) & 0xf) {
2290 case 0x0: /* TMIA */
2291 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2293 case 0x8: /* TMIAPH */
2294 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2296 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2297 if (insn
& (1 << 16))
2298 tcg_gen_shri_i32(tmp
, tmp
, 16);
2299 if (insn
& (1 << 17))
2300 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2301 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2304 tcg_temp_free_i32(tmp2
);
2305 tcg_temp_free_i32(tmp
);
2308 tcg_temp_free_i32(tmp2
);
2309 tcg_temp_free_i32(tmp
);
2310 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2311 gen_op_iwmmxt_set_mup();
2320 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2321 (ie. an undefined instruction). */
2322 static int disas_dsp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2324 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2327 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2328 /* Multiply with Internal Accumulate Format */
2329 rd0
= (insn
>> 12) & 0xf;
2331 acc
= (insn
>> 5) & 7;
2336 tmp
= load_reg(s
, rd0
);
2337 tmp2
= load_reg(s
, rd1
);
2338 switch ((insn
>> 16) & 0xf) {
2340 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2342 case 0x8: /* MIAPH */
2343 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2345 case 0xc: /* MIABB */
2346 case 0xd: /* MIABT */
2347 case 0xe: /* MIATB */
2348 case 0xf: /* MIATT */
2349 if (insn
& (1 << 16))
2350 tcg_gen_shri_i32(tmp
, tmp
, 16);
2351 if (insn
& (1 << 17))
2352 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2353 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2358 tcg_temp_free_i32(tmp2
);
2359 tcg_temp_free_i32(tmp
);
2361 gen_op_iwmmxt_movq_wRn_M0(acc
);
2365 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2366 /* Internal Accumulator Access Format */
2367 rdhi
= (insn
>> 16) & 0xf;
2368 rdlo
= (insn
>> 12) & 0xf;
2374 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2375 iwmmxt_load_reg(cpu_V0
, acc
);
2376 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2377 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2378 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2379 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2381 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2382 iwmmxt_store_reg(cpu_V0
, acc
);
2390 /* Disassemble system coprocessor instruction. Return nonzero if
2391 instruction is not defined. */
2392 static int disas_cp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2395 uint32_t rd
= (insn
>> 12) & 0xf;
2396 uint32_t cp
= (insn
>> 8) & 0xf;
2401 if (insn
& ARM_CP_RW_BIT
) {
2402 if (!env
->cp
[cp
].cp_read
)
2404 gen_set_pc_im(s
->pc
);
2405 tmp
= tcg_temp_new_i32();
2406 tmp2
= tcg_const_i32(insn
);
2407 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2408 tcg_temp_free(tmp2
);
2409 store_reg(s
, rd
, tmp
);
2411 if (!env
->cp
[cp
].cp_write
)
2413 gen_set_pc_im(s
->pc
);
2414 tmp
= load_reg(s
, rd
);
2415 tmp2
= tcg_const_i32(insn
);
2416 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2417 tcg_temp_free(tmp2
);
2418 tcg_temp_free_i32(tmp
);
2423 static int cp15_user_ok(uint32_t insn
)
2425 int cpn
= (insn
>> 16) & 0xf;
2426 int cpm
= insn
& 0xf;
2427 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2429 if (cpn
== 13 && cpm
== 0) {
2431 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2435 /* ISB, DSB, DMB. */
2436 if ((cpm
== 5 && op
== 4)
2437 || (cpm
== 10 && (op
== 4 || op
== 5)))
2443 static int cp15_tls_load_store(CPUState
*env
, DisasContext
*s
, uint32_t insn
, uint32_t rd
)
2446 int cpn
= (insn
>> 16) & 0xf;
2447 int cpm
= insn
& 0xf;
2448 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2450 if (!arm_feature(env
, ARM_FEATURE_V6K
))
2453 if (!(cpn
== 13 && cpm
== 0))
2456 if (insn
& ARM_CP_RW_BIT
) {
2459 tmp
= load_cpu_field(cp15
.c13_tls1
);
2462 tmp
= load_cpu_field(cp15
.c13_tls2
);
2465 tmp
= load_cpu_field(cp15
.c13_tls3
);
2470 store_reg(s
, rd
, tmp
);
2473 tmp
= load_reg(s
, rd
);
2476 store_cpu_field(tmp
, cp15
.c13_tls1
);
2479 store_cpu_field(tmp
, cp15
.c13_tls2
);
2482 store_cpu_field(tmp
, cp15
.c13_tls3
);
2485 tcg_temp_free_i32(tmp
);
2492 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2493 instruction is not defined. */
2494 static int disas_cp15_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2499 /* M profile cores use memory mapped registers instead of cp15. */
2500 if (arm_feature(env
, ARM_FEATURE_M
))
2503 if ((insn
& (1 << 25)) == 0) {
2504 if (insn
& (1 << 20)) {
2508 /* mcrr. Used for block cache operations, so implement as no-op. */
2511 if ((insn
& (1 << 4)) == 0) {
2515 if (IS_USER(s
) && !cp15_user_ok(insn
)) {
2519 /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2520 * instructions rather than a separate instruction.
2522 if ((insn
& 0x0fff0fff) == 0x0e070f90) {
2523 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2524 * In v7, this must NOP.
2526 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
2527 /* Wait for interrupt. */
2528 gen_set_pc_im(s
->pc
);
2529 s
->is_jmp
= DISAS_WFI
;
2534 if ((insn
& 0x0fff0fff) == 0x0e070f58) {
2535 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2536 * so this is slightly over-broad.
2538 if (!arm_feature(env
, ARM_FEATURE_V6
)) {
2539 /* Wait for interrupt. */
2540 gen_set_pc_im(s
->pc
);
2541 s
->is_jmp
= DISAS_WFI
;
2544 /* Otherwise fall through to handle via helper function.
2545 * In particular, on v7 and some v6 cores this is one of
2546 * the VA-PA registers.
2550 rd
= (insn
>> 12) & 0xf;
2552 if (cp15_tls_load_store(env
, s
, insn
, rd
))
2555 tmp2
= tcg_const_i32(insn
);
2556 if (insn
& ARM_CP_RW_BIT
) {
2557 tmp
= tcg_temp_new_i32();
2558 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2559 /* If the destination register is r15 then sets condition codes. */
2561 store_reg(s
, rd
, tmp
);
2563 tcg_temp_free_i32(tmp
);
2565 tmp
= load_reg(s
, rd
);
2566 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2567 tcg_temp_free_i32(tmp
);
2568 /* Normally we would always end the TB here, but Linux
2569 * arch/arm/mach-pxa/sleep.S expects two instructions following
2570 * an MMU enable to execute from cache. Imitate this behaviour. */
2571 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2572 (insn
& 0x0fff0fff) != 0x0e010f10)
2575 tcg_temp_free_i32(tmp2
);
2579 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2580 #define VFP_SREG(insn, bigbit, smallbit) \
2581 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2582 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2583 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2584 reg = (((insn) >> (bigbit)) & 0x0f) \
2585 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2587 if (insn & (1 << (smallbit))) \
2589 reg = ((insn) >> (bigbit)) & 0x0f; \
2592 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2593 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2594 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2595 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2596 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2597 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2599 /* Move between integer and VFP cores. */
2600 static TCGv
gen_vfp_mrs(void)
2602 TCGv tmp
= tcg_temp_new_i32();
2603 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2607 static void gen_vfp_msr(TCGv tmp
)
2609 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2610 tcg_temp_free_i32(tmp
);
2613 static void gen_neon_dup_u8(TCGv var
, int shift
)
2615 TCGv tmp
= tcg_temp_new_i32();
2617 tcg_gen_shri_i32(var
, var
, shift
);
2618 tcg_gen_ext8u_i32(var
, var
);
2619 tcg_gen_shli_i32(tmp
, var
, 8);
2620 tcg_gen_or_i32(var
, var
, tmp
);
2621 tcg_gen_shli_i32(tmp
, var
, 16);
2622 tcg_gen_or_i32(var
, var
, tmp
);
2623 tcg_temp_free_i32(tmp
);
2626 static void gen_neon_dup_low16(TCGv var
)
2628 TCGv tmp
= tcg_temp_new_i32();
2629 tcg_gen_ext16u_i32(var
, var
);
2630 tcg_gen_shli_i32(tmp
, var
, 16);
2631 tcg_gen_or_i32(var
, var
, tmp
);
2632 tcg_temp_free_i32(tmp
);
2635 static void gen_neon_dup_high16(TCGv var
)
2637 TCGv tmp
= tcg_temp_new_i32();
2638 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2639 tcg_gen_shri_i32(tmp
, var
, 16);
2640 tcg_gen_or_i32(var
, var
, tmp
);
2641 tcg_temp_free_i32(tmp
);
2644 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2646 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2650 tmp
= gen_ld8u(addr
, IS_USER(s
));
2651 gen_neon_dup_u8(tmp
, 0);
2654 tmp
= gen_ld16u(addr
, IS_USER(s
));
2655 gen_neon_dup_low16(tmp
);
2658 tmp
= gen_ld32(addr
, IS_USER(s
));
2660 default: /* Avoid compiler warnings. */
2666 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2667 (ie. an undefined instruction). */
2668 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2670 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2676 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2679 if (!s
->vfp_enabled
) {
2680 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2681 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2683 rn
= (insn
>> 16) & 0xf;
2684 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2685 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2688 dp
= ((insn
& 0xf00) == 0xb00);
2689 switch ((insn
>> 24) & 0xf) {
2691 if (insn
& (1 << 4)) {
2692 /* single register transfer */
2693 rd
= (insn
>> 12) & 0xf;
2698 VFP_DREG_N(rn
, insn
);
2701 if (insn
& 0x00c00060
2702 && !arm_feature(env
, ARM_FEATURE_NEON
))
2705 pass
= (insn
>> 21) & 1;
2706 if (insn
& (1 << 22)) {
2708 offset
= ((insn
>> 5) & 3) * 8;
2709 } else if (insn
& (1 << 5)) {
2711 offset
= (insn
& (1 << 6)) ? 16 : 0;
2716 if (insn
& ARM_CP_RW_BIT
) {
2718 tmp
= neon_load_reg(rn
, pass
);
2722 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2723 if (insn
& (1 << 23))
2729 if (insn
& (1 << 23)) {
2731 tcg_gen_shri_i32(tmp
, tmp
, 16);
2737 tcg_gen_sari_i32(tmp
, tmp
, 16);
2746 store_reg(s
, rd
, tmp
);
2749 tmp
= load_reg(s
, rd
);
2750 if (insn
& (1 << 23)) {
2753 gen_neon_dup_u8(tmp
, 0);
2754 } else if (size
== 1) {
2755 gen_neon_dup_low16(tmp
);
2757 for (n
= 0; n
<= pass
* 2; n
++) {
2758 tmp2
= tcg_temp_new_i32();
2759 tcg_gen_mov_i32(tmp2
, tmp
);
2760 neon_store_reg(rn
, n
, tmp2
);
2762 neon_store_reg(rn
, n
, tmp
);
2767 tmp2
= neon_load_reg(rn
, pass
);
2768 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2769 tcg_temp_free_i32(tmp2
);
2772 tmp2
= neon_load_reg(rn
, pass
);
2773 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2774 tcg_temp_free_i32(tmp2
);
2779 neon_store_reg(rn
, pass
, tmp
);
2783 if ((insn
& 0x6f) != 0x00)
2785 rn
= VFP_SREG_N(insn
);
2786 if (insn
& ARM_CP_RW_BIT
) {
2788 if (insn
& (1 << 21)) {
2789 /* system register */
2794 /* VFP2 allows access to FSID from userspace.
2795 VFP3 restricts all id registers to privileged
2798 && arm_feature(env
, ARM_FEATURE_VFP3
))
2800 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2805 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2807 case ARM_VFP_FPINST
:
2808 case ARM_VFP_FPINST2
:
2809 /* Not present in VFP3. */
2811 || arm_feature(env
, ARM_FEATURE_VFP3
))
2813 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2817 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2818 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2820 tmp
= tcg_temp_new_i32();
2821 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2827 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2829 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2835 gen_mov_F0_vreg(0, rn
);
2836 tmp
= gen_vfp_mrs();
2839 /* Set the 4 flag bits in the CPSR. */
2841 tcg_temp_free_i32(tmp
);
2843 store_reg(s
, rd
, tmp
);
2847 tmp
= load_reg(s
, rd
);
2848 if (insn
& (1 << 21)) {
2850 /* system register */
2855 /* Writes are ignored. */
2858 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2859 tcg_temp_free_i32(tmp
);
2865 /* TODO: VFP subarchitecture support.
2866 * For now, keep the EN bit only */
2867 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2868 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2871 case ARM_VFP_FPINST
:
2872 case ARM_VFP_FPINST2
:
2873 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2880 gen_mov_vreg_F0(0, rn
);
2885 /* data processing */
2886 /* The opcode is in bits 23, 21, 20 and 6. */
2887 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2891 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2893 /* rn is register number */
2894 VFP_DREG_N(rn
, insn
);
2897 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2898 /* Integer or single precision destination. */
2899 rd
= VFP_SREG_D(insn
);
2901 VFP_DREG_D(rd
, insn
);
2904 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2905 /* VCVT from int is always from S reg regardless of dp bit.
2906 * VCVT with immediate frac_bits has same format as SREG_M
2908 rm
= VFP_SREG_M(insn
);
2910 VFP_DREG_M(rm
, insn
);
2913 rn
= VFP_SREG_N(insn
);
2914 if (op
== 15 && rn
== 15) {
2915 /* Double precision destination. */
2916 VFP_DREG_D(rd
, insn
);
2918 rd
= VFP_SREG_D(insn
);
2920 /* NB that we implicitly rely on the encoding for the frac_bits
2921 * in VCVT of fixed to float being the same as that of an SREG_M
2923 rm
= VFP_SREG_M(insn
);
2926 veclen
= s
->vec_len
;
2927 if (op
== 15 && rn
> 3)
2930 /* Shut up compiler warnings. */
2941 /* Figure out what type of vector operation this is. */
2942 if ((rd
& bank_mask
) == 0) {
2947 delta_d
= (s
->vec_stride
>> 1) + 1;
2949 delta_d
= s
->vec_stride
+ 1;
2951 if ((rm
& bank_mask
) == 0) {
2952 /* mixed scalar/vector */
2961 /* Load the initial operands. */
2966 /* Integer source */
2967 gen_mov_F0_vreg(0, rm
);
2972 gen_mov_F0_vreg(dp
, rd
);
2973 gen_mov_F1_vreg(dp
, rm
);
2977 /* Compare with zero */
2978 gen_mov_F0_vreg(dp
, rd
);
2989 /* Source and destination the same. */
2990 gen_mov_F0_vreg(dp
, rd
);
2993 /* One source operand. */
2994 gen_mov_F0_vreg(dp
, rm
);
2998 /* Two source operands. */
2999 gen_mov_F0_vreg(dp
, rn
);
3000 gen_mov_F1_vreg(dp
, rm
);
3004 /* Perform the calculation. */
3006 case 0: /* mac: fd + (fn * fm) */
3008 gen_mov_F1_vreg(dp
, rd
);
3011 case 1: /* nmac: fd - (fn * fm) */
3014 gen_mov_F1_vreg(dp
, rd
);
3017 case 2: /* msc: -fd + (fn * fm) */
3019 gen_mov_F1_vreg(dp
, rd
);
3022 case 3: /* nmsc: -fd - (fn * fm) */
3025 gen_mov_F1_vreg(dp
, rd
);
3028 case 4: /* mul: fn * fm */
3031 case 5: /* nmul: -(fn * fm) */
3035 case 6: /* add: fn + fm */
3038 case 7: /* sub: fn - fm */
3041 case 8: /* div: fn / fm */
3044 case 14: /* fconst */
3045 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3048 n
= (insn
<< 12) & 0x80000000;
3049 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3056 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3063 tcg_gen_movi_i32(cpu_F0s
, n
);
3066 case 15: /* extension space */
3080 case 4: /* vcvtb.f32.f16 */
3081 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3083 tmp
= gen_vfp_mrs();
3084 tcg_gen_ext16u_i32(tmp
, tmp
);
3085 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3086 tcg_temp_free_i32(tmp
);
3088 case 5: /* vcvtt.f32.f16 */
3089 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3091 tmp
= gen_vfp_mrs();
3092 tcg_gen_shri_i32(tmp
, tmp
, 16);
3093 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3094 tcg_temp_free_i32(tmp
);
3096 case 6: /* vcvtb.f16.f32 */
3097 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3099 tmp
= tcg_temp_new_i32();
3100 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3101 gen_mov_F0_vreg(0, rd
);
3102 tmp2
= gen_vfp_mrs();
3103 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3104 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3105 tcg_temp_free_i32(tmp2
);
3108 case 7: /* vcvtt.f16.f32 */
3109 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3111 tmp
= tcg_temp_new_i32();
3112 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3113 tcg_gen_shli_i32(tmp
, tmp
, 16);
3114 gen_mov_F0_vreg(0, rd
);
3115 tmp2
= gen_vfp_mrs();
3116 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3117 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3118 tcg_temp_free_i32(tmp2
);
3130 case 11: /* cmpez */
3134 case 15: /* single<->double conversion */
3136 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3138 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3140 case 16: /* fuito */
3143 case 17: /* fsito */
3146 case 20: /* fshto */
3147 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3149 gen_vfp_shto(dp
, 16 - rm
);
3151 case 21: /* fslto */
3152 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3154 gen_vfp_slto(dp
, 32 - rm
);
3156 case 22: /* fuhto */
3157 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3159 gen_vfp_uhto(dp
, 16 - rm
);
3161 case 23: /* fulto */
3162 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3164 gen_vfp_ulto(dp
, 32 - rm
);
3166 case 24: /* ftoui */
3169 case 25: /* ftouiz */
3172 case 26: /* ftosi */
3175 case 27: /* ftosiz */
3178 case 28: /* ftosh */
3179 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3181 gen_vfp_tosh(dp
, 16 - rm
);
3183 case 29: /* ftosl */
3184 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3186 gen_vfp_tosl(dp
, 32 - rm
);
3188 case 30: /* ftouh */
3189 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3191 gen_vfp_touh(dp
, 16 - rm
);
3193 case 31: /* ftoul */
3194 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3196 gen_vfp_toul(dp
, 32 - rm
);
3198 default: /* undefined */
3199 printf ("rn:%d\n", rn
);
3203 default: /* undefined */
3204 printf ("op:%d\n", op
);
3208 /* Write back the result. */
3209 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3210 ; /* Comparison, do nothing. */
3211 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3212 /* VCVT double to int: always integer result. */
3213 gen_mov_vreg_F0(0, rd
);
3214 else if (op
== 15 && rn
== 15)
3216 gen_mov_vreg_F0(!dp
, rd
);
3218 gen_mov_vreg_F0(dp
, rd
);
3220 /* break out of the loop if we have finished */
3224 if (op
== 15 && delta_m
== 0) {
3225 /* single source one-many */
3227 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3229 gen_mov_vreg_F0(dp
, rd
);
3233 /* Setup the next operands. */
3235 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3239 /* One source operand. */
3240 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3242 gen_mov_F0_vreg(dp
, rm
);
3244 /* Two source operands. */
3245 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3247 gen_mov_F0_vreg(dp
, rn
);
3249 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3251 gen_mov_F1_vreg(dp
, rm
);
3259 if ((insn
& 0x03e00000) == 0x00400000) {
3260 /* two-register transfer */
3261 rn
= (insn
>> 16) & 0xf;
3262 rd
= (insn
>> 12) & 0xf;
3264 VFP_DREG_M(rm
, insn
);
3266 rm
= VFP_SREG_M(insn
);
3269 if (insn
& ARM_CP_RW_BIT
) {
3272 gen_mov_F0_vreg(0, rm
* 2);
3273 tmp
= gen_vfp_mrs();
3274 store_reg(s
, rd
, tmp
);
3275 gen_mov_F0_vreg(0, rm
* 2 + 1);
3276 tmp
= gen_vfp_mrs();
3277 store_reg(s
, rn
, tmp
);
3279 gen_mov_F0_vreg(0, rm
);
3280 tmp
= gen_vfp_mrs();
3281 store_reg(s
, rd
, tmp
);
3282 gen_mov_F0_vreg(0, rm
+ 1);
3283 tmp
= gen_vfp_mrs();
3284 store_reg(s
, rn
, tmp
);
3289 tmp
= load_reg(s
, rd
);
3291 gen_mov_vreg_F0(0, rm
* 2);
3292 tmp
= load_reg(s
, rn
);
3294 gen_mov_vreg_F0(0, rm
* 2 + 1);
3296 tmp
= load_reg(s
, rd
);
3298 gen_mov_vreg_F0(0, rm
);
3299 tmp
= load_reg(s
, rn
);
3301 gen_mov_vreg_F0(0, rm
+ 1);
3306 rn
= (insn
>> 16) & 0xf;
3308 VFP_DREG_D(rd
, insn
);
3310 rd
= VFP_SREG_D(insn
);
3311 if (s
->thumb
&& rn
== 15) {
3312 addr
= tcg_temp_new_i32();
3313 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3315 addr
= load_reg(s
, rn
);
3317 if ((insn
& 0x01200000) == 0x01000000) {
3318 /* Single load/store */
3319 offset
= (insn
& 0xff) << 2;
3320 if ((insn
& (1 << 23)) == 0)
3322 tcg_gen_addi_i32(addr
, addr
, offset
);
3323 if (insn
& (1 << 20)) {
3324 gen_vfp_ld(s
, dp
, addr
);
3325 gen_mov_vreg_F0(dp
, rd
);
3327 gen_mov_F0_vreg(dp
, rd
);
3328 gen_vfp_st(s
, dp
, addr
);
3330 tcg_temp_free_i32(addr
);
3332 /* load/store multiple */
3334 n
= (insn
>> 1) & 0x7f;
3338 if (insn
& (1 << 24)) /* pre-decrement */
3339 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3345 for (i
= 0; i
< n
; i
++) {
3346 if (insn
& ARM_CP_RW_BIT
) {
3348 gen_vfp_ld(s
, dp
, addr
);
3349 gen_mov_vreg_F0(dp
, rd
+ i
);
3352 gen_mov_F0_vreg(dp
, rd
+ i
);
3353 gen_vfp_st(s
, dp
, addr
);
3355 tcg_gen_addi_i32(addr
, addr
, offset
);
3357 if (insn
& (1 << 21)) {
3359 if (insn
& (1 << 24))
3360 offset
= -offset
* n
;
3361 else if (dp
&& (insn
& 1))
3367 tcg_gen_addi_i32(addr
, addr
, offset
);
3368 store_reg(s
, rn
, addr
);
3370 tcg_temp_free_i32(addr
);
3376 /* Should never happen. */
3382 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3384 TranslationBlock
*tb
;
3387 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3389 gen_set_pc_im(dest
);
3390 tcg_gen_exit_tb((long)tb
+ n
);
3392 gen_set_pc_im(dest
);
3397 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3399 if (unlikely(s
->singlestep_enabled
)) {
3400 /* An indirect jump so that we still trigger the debug exception. */
3405 gen_goto_tb(s
, 0, dest
);
3406 s
->is_jmp
= DISAS_TB_JUMP
;
3410 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3413 tcg_gen_sari_i32(t0
, t0
, 16);
3417 tcg_gen_sari_i32(t1
, t1
, 16);
3420 tcg_gen_mul_i32(t0
, t0
, t1
);
3423 /* Return the mask of PSR bits set by a MSR instruction. */
3424 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3428 if (flags
& (1 << 0))
3430 if (flags
& (1 << 1))
3432 if (flags
& (1 << 2))
3434 if (flags
& (1 << 3))
3437 /* Mask out undefined bits. */
3438 mask
&= ~CPSR_RESERVED
;
3439 if (!arm_feature(env
, ARM_FEATURE_V6
))
3440 mask
&= ~(CPSR_E
| CPSR_GE
);
3441 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3443 /* Mask out execution state bits. */
3446 /* Mask out privileged bits. */
3452 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3453 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3457 /* ??? This is also undefined in system mode. */
3461 tmp
= load_cpu_field(spsr
);
3462 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3463 tcg_gen_andi_i32(t0
, t0
, mask
);
3464 tcg_gen_or_i32(tmp
, tmp
, t0
);
3465 store_cpu_field(tmp
, spsr
);
3467 gen_set_cpsr(t0
, mask
);
3469 tcg_temp_free_i32(t0
);
3474 /* Returns nonzero if access to the PSR is not permitted. */
3475 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3478 tmp
= tcg_temp_new_i32();
3479 tcg_gen_movi_i32(tmp
, val
);
3480 return gen_set_psr(s
, mask
, spsr
, tmp
);
3483 /* Generate an old-style exception return. Marks pc as dead. */
3484 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3487 store_reg(s
, 15, pc
);
3488 tmp
= load_cpu_field(spsr
);
3489 gen_set_cpsr(tmp
, 0xffffffff);
3490 tcg_temp_free_i32(tmp
);
3491 s
->is_jmp
= DISAS_UPDATE
;
3494 /* Generate a v6 exception return. Marks both values as dead. */
3495 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3497 gen_set_cpsr(cpsr
, 0xffffffff);
3498 tcg_temp_free_i32(cpsr
);
3499 store_reg(s
, 15, pc
);
3500 s
->is_jmp
= DISAS_UPDATE
;
3504 gen_set_condexec (DisasContext
*s
)
3506 if (s
->condexec_mask
) {
3507 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3508 TCGv tmp
= tcg_temp_new_i32();
3509 tcg_gen_movi_i32(tmp
, val
);
3510 store_cpu_field(tmp
, condexec_bits
);
3514 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3516 gen_set_condexec(s
);
3517 gen_set_pc_im(s
->pc
- offset
);
3518 gen_exception(excp
);
3519 s
->is_jmp
= DISAS_JUMP
;
3522 static void gen_nop_hint(DisasContext
*s
, int val
)
3526 gen_set_pc_im(s
->pc
);
3527 s
->is_jmp
= DISAS_WFI
;
3531 /* TODO: Implement SEV and WFE. May help SMP performance. */
3537 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3539 static inline int gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3542 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3543 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3544 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3550 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3553 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3554 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3555 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3560 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3561 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3562 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3563 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3564 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3566 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3567 switch ((size << 1) | u) { \
3569 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3572 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3575 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3578 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3581 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3584 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3586 default: return 1; \
3589 #define GEN_NEON_INTEGER_OP(name) do { \
3590 switch ((size << 1) | u) { \
3592 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3595 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3598 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3601 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3604 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3607 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3609 default: return 1; \
3612 static TCGv
neon_load_scratch(int scratch
)
3614 TCGv tmp
= tcg_temp_new_i32();
3615 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3619 static void neon_store_scratch(int scratch
, TCGv var
)
3621 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3622 tcg_temp_free_i32(var
);
3625 static inline TCGv
neon_get_scalar(int size
, int reg
)
3629 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3631 gen_neon_dup_high16(tmp
);
3633 gen_neon_dup_low16(tmp
);
3636 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3641 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3644 if (size
== 3 || (!q
&& size
== 2)) {
3647 tmp
= tcg_const_i32(rd
);
3648 tmp2
= tcg_const_i32(rm
);
3652 gen_helper_neon_qunzip8(tmp
, tmp2
);
3655 gen_helper_neon_qunzip16(tmp
, tmp2
);
3658 gen_helper_neon_qunzip32(tmp
, tmp2
);
3666 gen_helper_neon_unzip8(tmp
, tmp2
);
3669 gen_helper_neon_unzip16(tmp
, tmp2
);
3675 tcg_temp_free_i32(tmp
);
3676 tcg_temp_free_i32(tmp2
);
3680 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3683 if (size
== 3 || (!q
&& size
== 2)) {
3686 tmp
= tcg_const_i32(rd
);
3687 tmp2
= tcg_const_i32(rm
);
3691 gen_helper_neon_qzip8(tmp
, tmp2
);
3694 gen_helper_neon_qzip16(tmp
, tmp2
);
3697 gen_helper_neon_qzip32(tmp
, tmp2
);
3705 gen_helper_neon_zip8(tmp
, tmp2
);
3708 gen_helper_neon_zip16(tmp
, tmp2
);
3714 tcg_temp_free_i32(tmp
);
3715 tcg_temp_free_i32(tmp2
);
3719 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3723 rd
= tcg_temp_new_i32();
3724 tmp
= tcg_temp_new_i32();
3726 tcg_gen_shli_i32(rd
, t0
, 8);
3727 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3728 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3729 tcg_gen_or_i32(rd
, rd
, tmp
);
3731 tcg_gen_shri_i32(t1
, t1
, 8);
3732 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3733 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3734 tcg_gen_or_i32(t1
, t1
, tmp
);
3735 tcg_gen_mov_i32(t0
, rd
);
3737 tcg_temp_free_i32(tmp
);
3738 tcg_temp_free_i32(rd
);
3741 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3745 rd
= tcg_temp_new_i32();
3746 tmp
= tcg_temp_new_i32();
3748 tcg_gen_shli_i32(rd
, t0
, 16);
3749 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3750 tcg_gen_or_i32(rd
, rd
, tmp
);
3751 tcg_gen_shri_i32(t1
, t1
, 16);
3752 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3753 tcg_gen_or_i32(t1
, t1
, tmp
);
3754 tcg_gen_mov_i32(t0
, rd
);
3756 tcg_temp_free_i32(tmp
);
3757 tcg_temp_free_i32(rd
);
3765 } neon_ls_element_type
[11] = {
3779 /* Translate a NEON load/store element instruction. Return nonzero if the
3780 instruction is invalid. */
3781 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3800 if (!s
->vfp_enabled
)
3802 VFP_DREG_D(rd
, insn
);
3803 rn
= (insn
>> 16) & 0xf;
3805 load
= (insn
& (1 << 21)) != 0;
3806 if ((insn
& (1 << 23)) == 0) {
3807 /* Load store all elements. */
3808 op
= (insn
>> 8) & 0xf;
3809 size
= (insn
>> 6) & 3;
3812 nregs
= neon_ls_element_type
[op
].nregs
;
3813 interleave
= neon_ls_element_type
[op
].interleave
;
3814 spacing
= neon_ls_element_type
[op
].spacing
;
3815 if (size
== 3 && (interleave
| spacing
) != 1)
3817 addr
= tcg_temp_new_i32();
3818 load_reg_var(s
, addr
, rn
);
3819 stride
= (1 << size
) * interleave
;
3820 for (reg
= 0; reg
< nregs
; reg
++) {
3821 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3822 load_reg_var(s
, addr
, rn
);
3823 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3824 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3825 load_reg_var(s
, addr
, rn
);
3826 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3830 tmp64
= gen_ld64(addr
, IS_USER(s
));
3831 neon_store_reg64(tmp64
, rd
);
3832 tcg_temp_free_i64(tmp64
);
3834 tmp64
= tcg_temp_new_i64();
3835 neon_load_reg64(tmp64
, rd
);
3836 gen_st64(tmp64
, addr
, IS_USER(s
));
3838 tcg_gen_addi_i32(addr
, addr
, stride
);
3840 for (pass
= 0; pass
< 2; pass
++) {
3843 tmp
= gen_ld32(addr
, IS_USER(s
));
3844 neon_store_reg(rd
, pass
, tmp
);
3846 tmp
= neon_load_reg(rd
, pass
);
3847 gen_st32(tmp
, addr
, IS_USER(s
));
3849 tcg_gen_addi_i32(addr
, addr
, stride
);
3850 } else if (size
== 1) {
3852 tmp
= gen_ld16u(addr
, IS_USER(s
));
3853 tcg_gen_addi_i32(addr
, addr
, stride
);
3854 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3855 tcg_gen_addi_i32(addr
, addr
, stride
);
3856 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3857 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3858 tcg_temp_free_i32(tmp2
);
3859 neon_store_reg(rd
, pass
, tmp
);
3861 tmp
= neon_load_reg(rd
, pass
);
3862 tmp2
= tcg_temp_new_i32();
3863 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3864 gen_st16(tmp
, addr
, IS_USER(s
));
3865 tcg_gen_addi_i32(addr
, addr
, stride
);
3866 gen_st16(tmp2
, addr
, IS_USER(s
));
3867 tcg_gen_addi_i32(addr
, addr
, stride
);
3869 } else /* size == 0 */ {
3872 for (n
= 0; n
< 4; n
++) {
3873 tmp
= gen_ld8u(addr
, IS_USER(s
));
3874 tcg_gen_addi_i32(addr
, addr
, stride
);
3878 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3879 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3880 tcg_temp_free_i32(tmp
);
3883 neon_store_reg(rd
, pass
, tmp2
);
3885 tmp2
= neon_load_reg(rd
, pass
);
3886 for (n
= 0; n
< 4; n
++) {
3887 tmp
= tcg_temp_new_i32();
3889 tcg_gen_mov_i32(tmp
, tmp2
);
3891 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3893 gen_st8(tmp
, addr
, IS_USER(s
));
3894 tcg_gen_addi_i32(addr
, addr
, stride
);
3896 tcg_temp_free_i32(tmp2
);
3903 tcg_temp_free_i32(addr
);
3906 size
= (insn
>> 10) & 3;
3908 /* Load single element to all lanes. */
3909 int a
= (insn
>> 4) & 1;
3913 size
= (insn
>> 6) & 3;
3914 nregs
= ((insn
>> 8) & 3) + 1;
3917 if (nregs
!= 4 || a
== 0) {
3920 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3923 if (nregs
== 1 && a
== 1 && size
== 0) {
3926 if (nregs
== 3 && a
== 1) {
3929 addr
= tcg_temp_new_i32();
3930 load_reg_var(s
, addr
, rn
);
3932 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3933 tmp
= gen_load_and_replicate(s
, addr
, size
);
3934 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3935 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3936 if (insn
& (1 << 5)) {
3937 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3938 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3940 tcg_temp_free_i32(tmp
);
3942 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3943 stride
= (insn
& (1 << 5)) ? 2 : 1;
3944 for (reg
= 0; reg
< nregs
; reg
++) {
3945 tmp
= gen_load_and_replicate(s
, addr
, size
);
3946 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3947 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3948 tcg_temp_free_i32(tmp
);
3949 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3953 tcg_temp_free_i32(addr
);
3954 stride
= (1 << size
) * nregs
;
3956 /* Single element. */
3957 pass
= (insn
>> 7) & 1;
3960 shift
= ((insn
>> 5) & 3) * 8;
3964 shift
= ((insn
>> 6) & 1) * 16;
3965 stride
= (insn
& (1 << 5)) ? 2 : 1;
3969 stride
= (insn
& (1 << 6)) ? 2 : 1;
3974 nregs
= ((insn
>> 8) & 3) + 1;
3975 addr
= tcg_temp_new_i32();
3976 load_reg_var(s
, addr
, rn
);
3977 for (reg
= 0; reg
< nregs
; reg
++) {
3981 tmp
= gen_ld8u(addr
, IS_USER(s
));
3984 tmp
= gen_ld16u(addr
, IS_USER(s
));
3987 tmp
= gen_ld32(addr
, IS_USER(s
));
3989 default: /* Avoid compiler warnings. */
3993 tmp2
= neon_load_reg(rd
, pass
);
3994 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
3995 tcg_temp_free_i32(tmp2
);
3997 neon_store_reg(rd
, pass
, tmp
);
3998 } else { /* Store */
3999 tmp
= neon_load_reg(rd
, pass
);
4001 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4004 gen_st8(tmp
, addr
, IS_USER(s
));
4007 gen_st16(tmp
, addr
, IS_USER(s
));
4010 gen_st32(tmp
, addr
, IS_USER(s
));
4015 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4017 tcg_temp_free_i32(addr
);
4018 stride
= nregs
* (1 << size
);
4024 base
= load_reg(s
, rn
);
4026 tcg_gen_addi_i32(base
, base
, stride
);
4029 index
= load_reg(s
, rm
);
4030 tcg_gen_add_i32(base
, base
, index
);
4031 tcg_temp_free_i32(index
);
4033 store_reg(s
, rn
, base
);
4038 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4039 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4041 tcg_gen_and_i32(t
, t
, c
);
4042 tcg_gen_andc_i32(f
, f
, c
);
4043 tcg_gen_or_i32(dest
, t
, f
);
4046 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4049 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4050 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4051 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4056 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4059 case 0: gen_helper_neon_narrow_sat_s8(dest
, src
); break;
4060 case 1: gen_helper_neon_narrow_sat_s16(dest
, src
); break;
4061 case 2: gen_helper_neon_narrow_sat_s32(dest
, src
); break;
4066 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4069 case 0: gen_helper_neon_narrow_sat_u8(dest
, src
); break;
4070 case 1: gen_helper_neon_narrow_sat_u16(dest
, src
); break;
4071 case 2: gen_helper_neon_narrow_sat_u32(dest
, src
); break;
4076 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4079 case 0: gen_helper_neon_unarrow_sat8(dest
, src
); break;
4080 case 1: gen_helper_neon_unarrow_sat16(dest
, src
); break;
4081 case 2: gen_helper_neon_unarrow_sat32(dest
, src
); break;
4086 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4092 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4093 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4098 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4099 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4106 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4107 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4112 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4113 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4120 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4124 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4125 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4126 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4131 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4132 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4133 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4137 tcg_temp_free_i32(src
);
4140 static inline void gen_neon_addl(int size
)
4143 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4144 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4145 case 2: tcg_gen_add_i64(CPU_V001
); break;
4150 static inline void gen_neon_subl(int size
)
4153 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4154 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4155 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4160 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4163 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4164 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4165 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4170 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4173 case 1: gen_helper_neon_addl_saturate_s32(op0
, op0
, op1
); break;
4174 case 2: gen_helper_neon_addl_saturate_s64(op0
, op0
, op1
); break;
4179 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4183 switch ((size
<< 1) | u
) {
4184 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4185 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4186 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4187 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4189 tmp
= gen_muls_i64_i32(a
, b
);
4190 tcg_gen_mov_i64(dest
, tmp
);
4191 tcg_temp_free_i64(tmp
);
4194 tmp
= gen_mulu_i64_i32(a
, b
);
4195 tcg_gen_mov_i64(dest
, tmp
);
4196 tcg_temp_free_i64(tmp
);
4201 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4202 Don't forget to clean them now. */
4204 tcg_temp_free_i32(a
);
4205 tcg_temp_free_i32(b
);
4209 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4213 gen_neon_unarrow_sats(size
, dest
, src
);
4215 gen_neon_narrow(size
, dest
, src
);
4219 gen_neon_narrow_satu(size
, dest
, src
);
4221 gen_neon_narrow_sats(size
, dest
, src
);
4226 /* Translate a NEON data processing instruction. Return nonzero if the
4227 instruction is invalid.
4228 We process data in a mixture of 32-bit and 64-bit chunks.
4229 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4231 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4244 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4247 if (!s
->vfp_enabled
)
4249 q
= (insn
& (1 << 6)) != 0;
4250 u
= (insn
>> 24) & 1;
4251 VFP_DREG_D(rd
, insn
);
4252 VFP_DREG_N(rn
, insn
);
4253 VFP_DREG_M(rm
, insn
);
4254 size
= (insn
>> 20) & 3;
4255 if ((insn
& (1 << 23)) == 0) {
4256 /* Three register same length. */
4257 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4258 if (size
== 3 && (op
== 1 || op
== 5 || op
== 8 || op
== 9
4259 || op
== 10 || op
== 11 || op
== 16)) {
4260 /* 64-bit element instructions. */
4261 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4262 neon_load_reg64(cpu_V0
, rn
+ pass
);
4263 neon_load_reg64(cpu_V1
, rm
+ pass
);
4267 gen_helper_neon_qadd_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4269 gen_helper_neon_qadd_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4274 gen_helper_neon_qsub_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4276 gen_helper_neon_qsub_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4281 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4283 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4288 gen_helper_neon_qshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4290 gen_helper_neon_qshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4293 case 10: /* VRSHL */
4295 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4297 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4300 case 11: /* VQRSHL */
4302 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4304 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4309 tcg_gen_sub_i64(CPU_V001
);
4311 tcg_gen_add_i64(CPU_V001
);
4317 neon_store_reg64(cpu_V0
, rd
+ pass
);
4324 case 10: /* VRSHL */
4325 case 11: /* VQRSHL */
4328 /* Shift instruction operands are reversed. */
4335 case 20: /* VPMAX */
4336 case 21: /* VPMIN */
4337 case 23: /* VPADD */
4340 case 26: /* VPADD (float) */
4341 pairwise
= (u
&& size
< 2);
4343 case 30: /* VPMIN/VPMAX (float) */
4351 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4360 tmp
= neon_load_reg(rn
, n
);
4361 tmp2
= neon_load_reg(rn
, n
+ 1);
4363 tmp
= neon_load_reg(rm
, n
);
4364 tmp2
= neon_load_reg(rm
, n
+ 1);
4368 tmp
= neon_load_reg(rn
, pass
);
4369 tmp2
= neon_load_reg(rm
, pass
);
4373 GEN_NEON_INTEGER_OP(hadd
);
4376 GEN_NEON_INTEGER_OP(qadd
);
4378 case 2: /* VRHADD */
4379 GEN_NEON_INTEGER_OP(rhadd
);
4381 case 3: /* Logic ops. */
4382 switch ((u
<< 2) | size
) {
4384 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4387 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4390 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4393 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4396 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4399 tmp3
= neon_load_reg(rd
, pass
);
4400 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4401 tcg_temp_free_i32(tmp3
);
4404 tmp3
= neon_load_reg(rd
, pass
);
4405 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4406 tcg_temp_free_i32(tmp3
);
4409 tmp3
= neon_load_reg(rd
, pass
);
4410 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4411 tcg_temp_free_i32(tmp3
);
4416 GEN_NEON_INTEGER_OP(hsub
);
4419 GEN_NEON_INTEGER_OP(qsub
);
4422 GEN_NEON_INTEGER_OP(cgt
);
4425 GEN_NEON_INTEGER_OP(cge
);
4428 GEN_NEON_INTEGER_OP(shl
);
4431 GEN_NEON_INTEGER_OP(qshl
);
4433 case 10: /* VRSHL */
4434 GEN_NEON_INTEGER_OP(rshl
);
4436 case 11: /* VQRSHL */
4437 GEN_NEON_INTEGER_OP(qrshl
);
4440 GEN_NEON_INTEGER_OP(max
);
4443 GEN_NEON_INTEGER_OP(min
);
4446 GEN_NEON_INTEGER_OP(abd
);
4449 GEN_NEON_INTEGER_OP(abd
);
4450 tcg_temp_free_i32(tmp2
);
4451 tmp2
= neon_load_reg(rd
, pass
);
4452 gen_neon_add(size
, tmp
, tmp2
);
4455 if (!u
) { /* VADD */
4456 if (gen_neon_add(size
, tmp
, tmp2
))
4460 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4461 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4462 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4468 if (!u
) { /* VTST */
4470 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4471 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4472 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4477 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4478 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4479 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4484 case 18: /* Multiply. */
4486 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4487 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4488 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4491 tcg_temp_free_i32(tmp2
);
4492 tmp2
= neon_load_reg(rd
, pass
);
4494 gen_neon_rsb(size
, tmp
, tmp2
);
4496 gen_neon_add(size
, tmp
, tmp2
);
4500 if (u
) { /* polynomial */
4501 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4502 } else { /* Integer */
4504 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4505 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4506 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4511 case 20: /* VPMAX */
4512 GEN_NEON_INTEGER_OP(pmax
);
4514 case 21: /* VPMIN */
4515 GEN_NEON_INTEGER_OP(pmin
);
4517 case 22: /* Hultiply high. */
4518 if (!u
) { /* VQDMULH */
4520 case 1: gen_helper_neon_qdmulh_s16(tmp
, tmp
, tmp2
); break;
4521 case 2: gen_helper_neon_qdmulh_s32(tmp
, tmp
, tmp2
); break;
4524 } else { /* VQRDHMUL */
4526 case 1: gen_helper_neon_qrdmulh_s16(tmp
, tmp
, tmp2
); break;
4527 case 2: gen_helper_neon_qrdmulh_s32(tmp
, tmp
, tmp2
); break;
4532 case 23: /* VPADD */
4536 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4537 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4538 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4542 case 26: /* Floating point arithnetic. */
4543 switch ((u
<< 2) | size
) {
4545 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4548 gen_helper_neon_sub_f32(tmp
, tmp
, tmp2
);
4551 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4554 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
);
4560 case 27: /* Float multiply. */
4561 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
4563 tcg_temp_free_i32(tmp2
);
4564 tmp2
= neon_load_reg(rd
, pass
);
4566 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4568 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
4572 case 28: /* Float compare. */
4574 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
4577 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
4579 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
4582 case 29: /* Float compare absolute. */
4586 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
);
4588 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
);
4590 case 30: /* Float min/max. */
4592 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
);
4594 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
);
4598 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4600 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4605 tcg_temp_free_i32(tmp2
);
4607 /* Save the result. For elementwise operations we can put it
4608 straight into the destination register. For pairwise operations
4609 we have to be careful to avoid clobbering the source operands. */
4610 if (pairwise
&& rd
== rm
) {
4611 neon_store_scratch(pass
, tmp
);
4613 neon_store_reg(rd
, pass
, tmp
);
4617 if (pairwise
&& rd
== rm
) {
4618 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4619 tmp
= neon_load_scratch(pass
);
4620 neon_store_reg(rd
, pass
, tmp
);
4623 /* End of 3 register same size operations. */
4624 } else if (insn
& (1 << 4)) {
4625 if ((insn
& 0x00380080) != 0) {
4626 /* Two registers and shift. */
4627 op
= (insn
>> 8) & 0xf;
4628 if (insn
& (1 << 7)) {
4633 while ((insn
& (1 << (size
+ 19))) == 0)
4636 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4637 /* To avoid excessive dumplication of ops we implement shift
4638 by immediate using the variable shift operations. */
4640 /* Shift by immediate:
4641 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4642 /* Right shifts are encoded as N - shift, where N is the
4643 element size in bits. */
4645 shift
= shift
- (1 << (size
+ 3));
4653 imm
= (uint8_t) shift
;
4658 imm
= (uint16_t) shift
;
4669 for (pass
= 0; pass
< count
; pass
++) {
4671 neon_load_reg64(cpu_V0
, rm
+ pass
);
4672 tcg_gen_movi_i64(cpu_V1
, imm
);
4677 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4679 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4684 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4686 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4691 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4693 case 5: /* VSHL, VSLI */
4694 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4696 case 6: /* VQSHLU */
4698 gen_helper_neon_qshlu_s64(cpu_V0
,
4706 gen_helper_neon_qshl_u64(cpu_V0
,
4709 gen_helper_neon_qshl_s64(cpu_V0
,
4714 if (op
== 1 || op
== 3) {
4716 neon_load_reg64(cpu_V1
, rd
+ pass
);
4717 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4718 } else if (op
== 4 || (op
== 5 && u
)) {
4720 neon_load_reg64(cpu_V1
, rd
+ pass
);
4722 if (shift
< -63 || shift
> 63) {
4726 mask
= 0xffffffffffffffffull
>> -shift
;
4728 mask
= 0xffffffffffffffffull
<< shift
;
4731 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
4732 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4734 neon_store_reg64(cpu_V0
, rd
+ pass
);
4735 } else { /* size < 3 */
4736 /* Operands in T0 and T1. */
4737 tmp
= neon_load_reg(rm
, pass
);
4738 tmp2
= tcg_temp_new_i32();
4739 tcg_gen_movi_i32(tmp2
, imm
);
4743 GEN_NEON_INTEGER_OP(shl
);
4747 GEN_NEON_INTEGER_OP(rshl
);
4752 GEN_NEON_INTEGER_OP(shl
);
4754 case 5: /* VSHL, VSLI */
4756 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
4757 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
4758 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
4762 case 6: /* VQSHLU */
4768 gen_helper_neon_qshlu_s8(tmp
, tmp
, tmp2
);
4771 gen_helper_neon_qshlu_s16(tmp
, tmp
, tmp2
);
4774 gen_helper_neon_qshlu_s32(tmp
, tmp
, tmp2
);
4781 GEN_NEON_INTEGER_OP(qshl
);
4784 tcg_temp_free_i32(tmp2
);
4786 if (op
== 1 || op
== 3) {
4788 tmp2
= neon_load_reg(rd
, pass
);
4789 gen_neon_add(size
, tmp
, tmp2
);
4790 tcg_temp_free_i32(tmp2
);
4791 } else if (op
== 4 || (op
== 5 && u
)) {
4796 mask
= 0xff >> -shift
;
4798 mask
= (uint8_t)(0xff << shift
);
4804 mask
= 0xffff >> -shift
;
4806 mask
= (uint16_t)(0xffff << shift
);
4810 if (shift
< -31 || shift
> 31) {
4814 mask
= 0xffffffffu
>> -shift
;
4816 mask
= 0xffffffffu
<< shift
;
4822 tmp2
= neon_load_reg(rd
, pass
);
4823 tcg_gen_andi_i32(tmp
, tmp
, mask
);
4824 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
4825 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4826 tcg_temp_free_i32(tmp2
);
4828 neon_store_reg(rd
, pass
, tmp
);
4831 } else if (op
< 10) {
4832 /* Shift by immediate and narrow:
4833 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4834 int input_unsigned
= (op
== 8) ? !u
: u
;
4836 shift
= shift
- (1 << (size
+ 3));
4839 tmp64
= tcg_const_i64(shift
);
4840 neon_load_reg64(cpu_V0
, rm
);
4841 neon_load_reg64(cpu_V1
, rm
+ 1);
4842 for (pass
= 0; pass
< 2; pass
++) {
4850 if (input_unsigned
) {
4851 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
4853 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
4856 if (input_unsigned
) {
4857 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
4859 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
4862 tmp
= tcg_temp_new_i32();
4863 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4864 neon_store_reg(rd
, pass
, tmp
);
4866 tcg_temp_free_i64(tmp64
);
4869 imm
= (uint16_t)shift
;
4873 imm
= (uint32_t)shift
;
4875 tmp2
= tcg_const_i32(imm
);
4876 tmp4
= neon_load_reg(rm
+ 1, 0);
4877 tmp5
= neon_load_reg(rm
+ 1, 1);
4878 for (pass
= 0; pass
< 2; pass
++) {
4880 tmp
= neon_load_reg(rm
, 0);
4884 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
4887 tmp3
= neon_load_reg(rm
, 1);
4891 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
4893 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
4894 tcg_temp_free_i32(tmp
);
4895 tcg_temp_free_i32(tmp3
);
4896 tmp
= tcg_temp_new_i32();
4897 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
4898 neon_store_reg(rd
, pass
, tmp
);
4900 tcg_temp_free_i32(tmp2
);
4902 } else if (op
== 10) {
4906 tmp
= neon_load_reg(rm
, 0);
4907 tmp2
= neon_load_reg(rm
, 1);
4908 for (pass
= 0; pass
< 2; pass
++) {
4912 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
4915 /* The shift is less than the width of the source
4916 type, so we can just shift the whole register. */
4917 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
4918 /* Widen the result of shift: we need to clear
4919 * the potential overflow bits resulting from
4920 * left bits of the narrow input appearing as
4921 * right bits of left the neighbour narrow
4923 if (size
< 2 || !u
) {
4926 imm
= (0xffu
>> (8 - shift
));
4928 } else if (size
== 1) {
4929 imm
= 0xffff >> (16 - shift
);
4932 imm
= 0xffffffff >> (32 - shift
);
4935 imm64
= imm
| (((uint64_t)imm
) << 32);
4939 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
4942 neon_store_reg64(cpu_V0
, rd
+ pass
);
4944 } else if (op
>= 14) {
4945 /* VCVT fixed-point. */
4946 /* We have already masked out the must-be-1 top bit of imm6,
4947 * hence this 32-shift where the ARM ARM has 64-imm6.
4950 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4951 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
4954 gen_vfp_ulto(0, shift
);
4956 gen_vfp_slto(0, shift
);
4959 gen_vfp_toul(0, shift
);
4961 gen_vfp_tosl(0, shift
);
4963 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
4968 } else { /* (insn & 0x00380080) == 0 */
4971 op
= (insn
>> 8) & 0xf;
4972 /* One register and immediate. */
4973 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
4974 invert
= (insn
& (1 << 5)) != 0;
4992 imm
= (imm
<< 8) | (imm
<< 24);
4995 imm
= (imm
<< 8) | 0xff;
4998 imm
= (imm
<< 16) | 0xffff;
5001 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5006 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5007 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5013 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5014 if (op
& 1 && op
< 12) {
5015 tmp
= neon_load_reg(rd
, pass
);
5017 /* The immediate value has already been inverted, so
5019 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5021 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5025 tmp
= tcg_temp_new_i32();
5026 if (op
== 14 && invert
) {
5029 for (n
= 0; n
< 4; n
++) {
5030 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5031 val
|= 0xff << (n
* 8);
5033 tcg_gen_movi_i32(tmp
, val
);
5035 tcg_gen_movi_i32(tmp
, imm
);
5038 neon_store_reg(rd
, pass
, tmp
);
5041 } else { /* (insn & 0x00800010 == 0x00800000) */
5043 op
= (insn
>> 8) & 0xf;
5044 if ((insn
& (1 << 6)) == 0) {
5045 /* Three registers of different lengths. */
5049 /* prewiden, src1_wide, src2_wide */
5050 static const int neon_3reg_wide
[16][3] = {
5051 {1, 0, 0}, /* VADDL */
5052 {1, 1, 0}, /* VADDW */
5053 {1, 0, 0}, /* VSUBL */
5054 {1, 1, 0}, /* VSUBW */
5055 {0, 1, 1}, /* VADDHN */
5056 {0, 0, 0}, /* VABAL */
5057 {0, 1, 1}, /* VSUBHN */
5058 {0, 0, 0}, /* VABDL */
5059 {0, 0, 0}, /* VMLAL */
5060 {0, 0, 0}, /* VQDMLAL */
5061 {0, 0, 0}, /* VMLSL */
5062 {0, 0, 0}, /* VQDMLSL */
5063 {0, 0, 0}, /* Integer VMULL */
5064 {0, 0, 0}, /* VQDMULL */
5065 {0, 0, 0} /* Polynomial VMULL */
5068 prewiden
= neon_3reg_wide
[op
][0];
5069 src1_wide
= neon_3reg_wide
[op
][1];
5070 src2_wide
= neon_3reg_wide
[op
][2];
5072 if (size
== 0 && (op
== 9 || op
== 11 || op
== 13))
5075 /* Avoid overlapping operands. Wide source operands are
5076 always aligned so will never overlap with wide
5077 destinations in problematic ways. */
5078 if (rd
== rm
&& !src2_wide
) {
5079 tmp
= neon_load_reg(rm
, 1);
5080 neon_store_scratch(2, tmp
);
5081 } else if (rd
== rn
&& !src1_wide
) {
5082 tmp
= neon_load_reg(rn
, 1);
5083 neon_store_scratch(2, tmp
);
5086 for (pass
= 0; pass
< 2; pass
++) {
5088 neon_load_reg64(cpu_V0
, rn
+ pass
);
5091 if (pass
== 1 && rd
== rn
) {
5092 tmp
= neon_load_scratch(2);
5094 tmp
= neon_load_reg(rn
, pass
);
5097 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5101 neon_load_reg64(cpu_V1
, rm
+ pass
);
5104 if (pass
== 1 && rd
== rm
) {
5105 tmp2
= neon_load_scratch(2);
5107 tmp2
= neon_load_reg(rm
, pass
);
5110 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5114 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5115 gen_neon_addl(size
);
5117 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5118 gen_neon_subl(size
);
5120 case 5: case 7: /* VABAL, VABDL */
5121 switch ((size
<< 1) | u
) {
5123 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5126 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5129 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5132 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5135 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5138 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5142 tcg_temp_free_i32(tmp2
);
5143 tcg_temp_free_i32(tmp
);
5145 case 8: case 9: case 10: case 11: case 12: case 13:
5146 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5147 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5149 case 14: /* Polynomial VMULL */
5150 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5151 tcg_temp_free_i32(tmp2
);
5152 tcg_temp_free_i32(tmp
);
5154 default: /* 15 is RESERVED. */
5159 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5160 neon_store_reg64(cpu_V0
, rd
+ pass
);
5161 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5163 neon_load_reg64(cpu_V1
, rd
+ pass
);
5165 case 10: /* VMLSL */
5166 gen_neon_negl(cpu_V0
, size
);
5168 case 5: case 8: /* VABAL, VMLAL */
5169 gen_neon_addl(size
);
5171 case 9: case 11: /* VQDMLAL, VQDMLSL */
5172 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5174 gen_neon_negl(cpu_V0
, size
);
5176 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5181 neon_store_reg64(cpu_V0
, rd
+ pass
);
5182 } else if (op
== 4 || op
== 6) {
5183 /* Narrowing operation. */
5184 tmp
= tcg_temp_new_i32();
5188 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5191 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5194 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5195 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5202 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5205 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5208 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5209 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5210 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5218 neon_store_reg(rd
, 0, tmp3
);
5219 neon_store_reg(rd
, 1, tmp
);
5222 /* Write back the result. */
5223 neon_store_reg64(cpu_V0
, rd
+ pass
);
5227 /* Two registers and a scalar. */
5229 case 0: /* Integer VMLA scalar */
5230 case 1: /* Float VMLA scalar */
5231 case 4: /* Integer VMLS scalar */
5232 case 5: /* Floating point VMLS scalar */
5233 case 8: /* Integer VMUL scalar */
5234 case 9: /* Floating point VMUL scalar */
5235 case 12: /* VQDMULH scalar */
5236 case 13: /* VQRDMULH scalar */
5237 tmp
= neon_get_scalar(size
, rm
);
5238 neon_store_scratch(0, tmp
);
5239 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5240 tmp
= neon_load_scratch(0);
5241 tmp2
= neon_load_reg(rn
, pass
);
5244 gen_helper_neon_qdmulh_s16(tmp
, tmp
, tmp2
);
5246 gen_helper_neon_qdmulh_s32(tmp
, tmp
, tmp2
);
5248 } else if (op
== 13) {
5250 gen_helper_neon_qrdmulh_s16(tmp
, tmp
, tmp2
);
5252 gen_helper_neon_qrdmulh_s32(tmp
, tmp
, tmp2
);
5254 } else if (op
& 1) {
5255 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
5258 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5259 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5260 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5264 tcg_temp_free_i32(tmp2
);
5267 tmp2
= neon_load_reg(rd
, pass
);
5270 gen_neon_add(size
, tmp
, tmp2
);
5273 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
5276 gen_neon_rsb(size
, tmp
, tmp2
);
5279 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
5284 tcg_temp_free_i32(tmp2
);
5286 neon_store_reg(rd
, pass
, tmp
);
5289 case 2: /* VMLAL sclar */
5290 case 3: /* VQDMLAL scalar */
5291 case 6: /* VMLSL scalar */
5292 case 7: /* VQDMLSL scalar */
5293 case 10: /* VMULL scalar */
5294 case 11: /* VQDMULL scalar */
5295 if (size
== 0 && (op
== 3 || op
== 7 || op
== 11))
5298 tmp2
= neon_get_scalar(size
, rm
);
5299 /* We need a copy of tmp2 because gen_neon_mull
5300 * deletes it during pass 0. */
5301 tmp4
= tcg_temp_new_i32();
5302 tcg_gen_mov_i32(tmp4
, tmp2
);
5303 tmp3
= neon_load_reg(rn
, 1);
5305 for (pass
= 0; pass
< 2; pass
++) {
5307 tmp
= neon_load_reg(rn
, 0);
5312 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5314 neon_load_reg64(cpu_V1
, rd
+ pass
);
5318 gen_neon_negl(cpu_V0
, size
);
5321 gen_neon_addl(size
);
5324 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5326 gen_neon_negl(cpu_V0
, size
);
5328 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5334 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5339 neon_store_reg64(cpu_V0
, rd
+ pass
);
5344 default: /* 14 and 15 are RESERVED */
5348 } else { /* size == 3 */
5351 imm
= (insn
>> 8) & 0xf;
5357 neon_load_reg64(cpu_V0
, rn
);
5359 neon_load_reg64(cpu_V1
, rn
+ 1);
5361 } else if (imm
== 8) {
5362 neon_load_reg64(cpu_V0
, rn
+ 1);
5364 neon_load_reg64(cpu_V1
, rm
);
5367 tmp64
= tcg_temp_new_i64();
5369 neon_load_reg64(cpu_V0
, rn
);
5370 neon_load_reg64(tmp64
, rn
+ 1);
5372 neon_load_reg64(cpu_V0
, rn
+ 1);
5373 neon_load_reg64(tmp64
, rm
);
5375 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5376 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5377 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5379 neon_load_reg64(cpu_V1
, rm
);
5381 neon_load_reg64(cpu_V1
, rm
+ 1);
5384 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5385 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5386 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5387 tcg_temp_free_i64(tmp64
);
5390 neon_load_reg64(cpu_V0
, rn
);
5391 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5392 neon_load_reg64(cpu_V1
, rm
);
5393 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5394 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5396 neon_store_reg64(cpu_V0
, rd
);
5398 neon_store_reg64(cpu_V1
, rd
+ 1);
5400 } else if ((insn
& (1 << 11)) == 0) {
5401 /* Two register misc. */
5402 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5403 size
= (insn
>> 18) & 3;
5405 case 0: /* VREV64 */
5408 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5409 tmp
= neon_load_reg(rm
, pass
* 2);
5410 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5412 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5413 case 1: gen_swap_half(tmp
); break;
5414 case 2: /* no-op */ break;
5417 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5419 neon_store_reg(rd
, pass
* 2, tmp2
);
5422 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5423 case 1: gen_swap_half(tmp2
); break;
5426 neon_store_reg(rd
, pass
* 2, tmp2
);
5430 case 4: case 5: /* VPADDL */
5431 case 12: case 13: /* VPADAL */
5434 for (pass
= 0; pass
< q
+ 1; pass
++) {
5435 tmp
= neon_load_reg(rm
, pass
* 2);
5436 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5437 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5438 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5440 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5441 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5442 case 2: tcg_gen_add_i64(CPU_V001
); break;
5447 neon_load_reg64(cpu_V1
, rd
+ pass
);
5448 gen_neon_addl(size
);
5450 neon_store_reg64(cpu_V0
, rd
+ pass
);
5455 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5456 tmp
= neon_load_reg(rm
, n
);
5457 tmp2
= neon_load_reg(rd
, n
+ 1);
5458 neon_store_reg(rm
, n
, tmp2
);
5459 neon_store_reg(rd
, n
+ 1, tmp
);
5466 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5471 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5475 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5479 for (pass
= 0; pass
< 2; pass
++) {
5480 neon_load_reg64(cpu_V0
, rm
+ pass
);
5481 tmp
= tcg_temp_new_i32();
5482 gen_neon_narrow_op(op
== 36, q
, size
, tmp
, cpu_V0
);
5486 neon_store_reg(rd
, 0, tmp2
);
5487 neon_store_reg(rd
, 1, tmp
);
5491 case 38: /* VSHLL */
5494 tmp
= neon_load_reg(rm
, 0);
5495 tmp2
= neon_load_reg(rm
, 1);
5496 for (pass
= 0; pass
< 2; pass
++) {
5499 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5500 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5501 neon_store_reg64(cpu_V0
, rd
+ pass
);
5504 case 44: /* VCVT.F16.F32 */
5505 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5507 tmp
= tcg_temp_new_i32();
5508 tmp2
= tcg_temp_new_i32();
5509 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5510 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5511 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5512 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5513 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5514 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5515 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5516 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5517 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5518 neon_store_reg(rd
, 0, tmp2
);
5519 tmp2
= tcg_temp_new_i32();
5520 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5521 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5522 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5523 neon_store_reg(rd
, 1, tmp2
);
5524 tcg_temp_free_i32(tmp
);
5526 case 46: /* VCVT.F32.F16 */
5527 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
5529 tmp3
= tcg_temp_new_i32();
5530 tmp
= neon_load_reg(rm
, 0);
5531 tmp2
= neon_load_reg(rm
, 1);
5532 tcg_gen_ext16u_i32(tmp3
, tmp
);
5533 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5534 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5535 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5536 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5537 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5538 tcg_temp_free_i32(tmp
);
5539 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5540 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5541 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5542 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5543 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5544 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5545 tcg_temp_free_i32(tmp2
);
5546 tcg_temp_free_i32(tmp3
);
5550 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5551 if (op
== 30 || op
== 31 || op
>= 58) {
5552 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5553 neon_reg_offset(rm
, pass
));
5556 tmp
= neon_load_reg(rm
, pass
);
5559 case 1: /* VREV32 */
5561 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5562 case 1: gen_swap_half(tmp
); break;
5566 case 2: /* VREV16 */
5573 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5574 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5575 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5581 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5582 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5583 case 2: gen_helper_clz(tmp
, tmp
); break;
5590 gen_helper_neon_cnt_u8(tmp
, tmp
);
5595 tcg_gen_not_i32(tmp
, tmp
);
5597 case 14: /* VQABS */
5599 case 0: gen_helper_neon_qabs_s8(tmp
, tmp
); break;
5600 case 1: gen_helper_neon_qabs_s16(tmp
, tmp
); break;
5601 case 2: gen_helper_neon_qabs_s32(tmp
, tmp
); break;
5605 case 15: /* VQNEG */
5607 case 0: gen_helper_neon_qneg_s8(tmp
, tmp
); break;
5608 case 1: gen_helper_neon_qneg_s16(tmp
, tmp
); break;
5609 case 2: gen_helper_neon_qneg_s32(tmp
, tmp
); break;
5613 case 16: case 19: /* VCGT #0, VCLE #0 */
5614 tmp2
= tcg_const_i32(0);
5616 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5617 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5618 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5621 tcg_temp_free(tmp2
);
5623 tcg_gen_not_i32(tmp
, tmp
);
5625 case 17: case 20: /* VCGE #0, VCLT #0 */
5626 tmp2
= tcg_const_i32(0);
5628 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5629 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5630 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5633 tcg_temp_free(tmp2
);
5635 tcg_gen_not_i32(tmp
, tmp
);
5637 case 18: /* VCEQ #0 */
5638 tmp2
= tcg_const_i32(0);
5640 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5641 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5642 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5645 tcg_temp_free(tmp2
);
5649 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
5650 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
5651 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
5658 tmp2
= tcg_const_i32(0);
5659 gen_neon_rsb(size
, tmp
, tmp2
);
5660 tcg_temp_free(tmp2
);
5662 case 24: /* Float VCGT #0 */
5663 tmp2
= tcg_const_i32(0);
5664 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
5665 tcg_temp_free(tmp2
);
5667 case 25: /* Float VCGE #0 */
5668 tmp2
= tcg_const_i32(0);
5669 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
5670 tcg_temp_free(tmp2
);
5672 case 26: /* Float VCEQ #0 */
5673 tmp2
= tcg_const_i32(0);
5674 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
5675 tcg_temp_free(tmp2
);
5677 case 27: /* Float VCLE #0 */
5678 tmp2
= tcg_const_i32(0);
5679 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
);
5680 tcg_temp_free(tmp2
);
5682 case 28: /* Float VCLT #0 */
5683 tmp2
= tcg_const_i32(0);
5684 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
);
5685 tcg_temp_free(tmp2
);
5687 case 30: /* Float VABS */
5690 case 31: /* Float VNEG */
5694 tmp2
= neon_load_reg(rd
, pass
);
5695 neon_store_reg(rm
, pass
, tmp2
);
5698 tmp2
= neon_load_reg(rd
, pass
);
5700 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
5701 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
5705 neon_store_reg(rm
, pass
, tmp2
);
5707 case 56: /* Integer VRECPE */
5708 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
5710 case 57: /* Integer VRSQRTE */
5711 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
5713 case 58: /* Float VRECPE */
5714 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5716 case 59: /* Float VRSQRTE */
5717 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
5719 case 60: /* VCVT.F32.S32 */
5722 case 61: /* VCVT.F32.U32 */
5725 case 62: /* VCVT.S32.F32 */
5728 case 63: /* VCVT.U32.F32 */
5732 /* Reserved: 21, 29, 39-56 */
5735 if (op
== 30 || op
== 31 || op
>= 58) {
5736 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
5737 neon_reg_offset(rd
, pass
));
5739 neon_store_reg(rd
, pass
, tmp
);
5744 } else if ((insn
& (1 << 10)) == 0) {
5746 n
= ((insn
>> 5) & 0x18) + 8;
5747 if (insn
& (1 << 6)) {
5748 tmp
= neon_load_reg(rd
, 0);
5750 tmp
= tcg_temp_new_i32();
5751 tcg_gen_movi_i32(tmp
, 0);
5753 tmp2
= neon_load_reg(rm
, 0);
5754 tmp4
= tcg_const_i32(rn
);
5755 tmp5
= tcg_const_i32(n
);
5756 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
5757 tcg_temp_free_i32(tmp
);
5758 if (insn
& (1 << 6)) {
5759 tmp
= neon_load_reg(rd
, 1);
5761 tmp
= tcg_temp_new_i32();
5762 tcg_gen_movi_i32(tmp
, 0);
5764 tmp3
= neon_load_reg(rm
, 1);
5765 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
5766 tcg_temp_free_i32(tmp5
);
5767 tcg_temp_free_i32(tmp4
);
5768 neon_store_reg(rd
, 0, tmp2
);
5769 neon_store_reg(rd
, 1, tmp3
);
5770 tcg_temp_free_i32(tmp
);
5771 } else if ((insn
& 0x380) == 0) {
5773 if (insn
& (1 << 19)) {
5774 tmp
= neon_load_reg(rm
, 1);
5776 tmp
= neon_load_reg(rm
, 0);
5778 if (insn
& (1 << 16)) {
5779 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
5780 } else if (insn
& (1 << 17)) {
5781 if ((insn
>> 18) & 1)
5782 gen_neon_dup_high16(tmp
);
5784 gen_neon_dup_low16(tmp
);
5786 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5787 tmp2
= tcg_temp_new_i32();
5788 tcg_gen_mov_i32(tmp2
, tmp
);
5789 neon_store_reg(rd
, pass
, tmp2
);
5791 tcg_temp_free_i32(tmp
);
5800 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5802 int crn
= (insn
>> 16) & 0xf;
5803 int crm
= insn
& 0xf;
5804 int op1
= (insn
>> 21) & 7;
5805 int op2
= (insn
>> 5) & 7;
5806 int rt
= (insn
>> 12) & 0xf;
5809 /* Minimal set of debug registers, since we don't support debug */
5810 if (op1
== 0 && crn
== 0 && op2
== 0) {
5813 /* DBGDIDR: just RAZ. In particular this means the
5814 * "debug architecture version" bits will read as
5815 * a reserved value, which should cause Linux to
5816 * not try to use the debug hardware.
5818 tmp
= tcg_const_i32(0);
5819 store_reg(s
, rt
, tmp
);
5823 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
5824 * don't implement memory mapped debug components
5826 if (ENABLE_ARCH_7
) {
5827 tmp
= tcg_const_i32(0);
5828 store_reg(s
, rt
, tmp
);
5837 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5838 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5842 tmp
= load_cpu_field(teecr
);
5843 store_reg(s
, rt
, tmp
);
5846 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5848 if (IS_USER(s
) && (env
->teecr
& 1))
5850 tmp
= load_cpu_field(teehbr
);
5851 store_reg(s
, rt
, tmp
);
5855 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5856 op1
, crn
, crm
, op2
);
5860 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5862 int crn
= (insn
>> 16) & 0xf;
5863 int crm
= insn
& 0xf;
5864 int op1
= (insn
>> 21) & 7;
5865 int op2
= (insn
>> 5) & 7;
5866 int rt
= (insn
>> 12) & 0xf;
5869 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
5870 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
5874 tmp
= load_reg(s
, rt
);
5875 gen_helper_set_teecr(cpu_env
, tmp
);
5876 tcg_temp_free_i32(tmp
);
5879 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
5881 if (IS_USER(s
) && (env
->teecr
& 1))
5883 tmp
= load_reg(s
, rt
);
5884 store_cpu_field(tmp
, teehbr
);
5888 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5889 op1
, crn
, crm
, op2
);
5893 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
5897 cpnum
= (insn
>> 8) & 0xf;
5898 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
5899 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
5905 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
5906 return disas_iwmmxt_insn(env
, s
, insn
);
5907 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
5908 return disas_dsp_insn(env
, s
, insn
);
5913 return disas_vfp_insn (env
, s
, insn
);
5915 /* Coprocessors 7-15 are architecturally reserved by ARM.
5916 Unfortunately Intel decided to ignore this. */
5917 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
5919 if (insn
& (1 << 20))
5920 return disas_cp14_read(env
, s
, insn
);
5922 return disas_cp14_write(env
, s
, insn
);
5924 return disas_cp15_insn (env
, s
, insn
);
5927 /* Unknown coprocessor. See if the board has hooked it. */
5928 return disas_cp_insn (env
, s
, insn
);
5933 /* Store a 64-bit value to a register pair. Clobbers val. */
5934 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
5937 tmp
= tcg_temp_new_i32();
5938 tcg_gen_trunc_i64_i32(tmp
, val
);
5939 store_reg(s
, rlow
, tmp
);
5940 tmp
= tcg_temp_new_i32();
5941 tcg_gen_shri_i64(val
, val
, 32);
5942 tcg_gen_trunc_i64_i32(tmp
, val
);
5943 store_reg(s
, rhigh
, tmp
);
5946 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5947 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
5952 /* Load value and extend to 64 bits. */
5953 tmp
= tcg_temp_new_i64();
5954 tmp2
= load_reg(s
, rlow
);
5955 tcg_gen_extu_i32_i64(tmp
, tmp2
);
5956 tcg_temp_free_i32(tmp2
);
5957 tcg_gen_add_i64(val
, val
, tmp
);
5958 tcg_temp_free_i64(tmp
);
5961 /* load and add a 64-bit value from a register pair. */
5962 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
5968 /* Load 64-bit value rd:rn. */
5969 tmpl
= load_reg(s
, rlow
);
5970 tmph
= load_reg(s
, rhigh
);
5971 tmp
= tcg_temp_new_i64();
5972 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
5973 tcg_temp_free_i32(tmpl
);
5974 tcg_temp_free_i32(tmph
);
5975 tcg_gen_add_i64(val
, val
, tmp
);
5976 tcg_temp_free_i64(tmp
);
5979 /* Set N and Z flags from a 64-bit value. */
5980 static void gen_logicq_cc(TCGv_i64 val
)
5982 TCGv tmp
= tcg_temp_new_i32();
5983 gen_helper_logicq_cc(tmp
, val
);
5985 tcg_temp_free_i32(tmp
);
5988 /* Load/Store exclusive instructions are implemented by remembering
5989 the value/address loaded, and seeing if these are the same
5990 when the store is performed. This should be is sufficient to implement
5991 the architecturally mandated semantics, and avoids having to monitor
5994 In system emulation mode only one CPU will be running at once, so
5995 this sequence is effectively atomic. In user emulation mode we
5996 throw an exception and handle the atomic operation elsewhere. */
5997 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
5998 TCGv addr
, int size
)
6004 tmp
= gen_ld8u(addr
, IS_USER(s
));
6007 tmp
= gen_ld16u(addr
, IS_USER(s
));
6011 tmp
= gen_ld32(addr
, IS_USER(s
));
6016 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6017 store_reg(s
, rt
, tmp
);
6019 TCGv tmp2
= tcg_temp_new_i32();
6020 tcg_gen_addi_i32(tmp2
, addr
, 4);
6021 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6022 tcg_temp_free_i32(tmp2
);
6023 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6024 store_reg(s
, rt2
, tmp
);
6026 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6029 static void gen_clrex(DisasContext
*s
)
6031 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6034 #ifdef CONFIG_USER_ONLY
6035 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6036 TCGv addr
, int size
)
6038 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6039 tcg_gen_movi_i32(cpu_exclusive_info
,
6040 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6041 gen_exception_insn(s
, 4, EXCP_STREX
);
6044 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6045 TCGv addr
, int size
)
6051 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6057 fail_label
= gen_new_label();
6058 done_label
= gen_new_label();
6059 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6062 tmp
= gen_ld8u(addr
, IS_USER(s
));
6065 tmp
= gen_ld16u(addr
, IS_USER(s
));
6069 tmp
= gen_ld32(addr
, IS_USER(s
));
6074 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6075 tcg_temp_free_i32(tmp
);
6077 TCGv tmp2
= tcg_temp_new_i32();
6078 tcg_gen_addi_i32(tmp2
, addr
, 4);
6079 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6080 tcg_temp_free_i32(tmp2
);
6081 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6082 tcg_temp_free_i32(tmp
);
6084 tmp
= load_reg(s
, rt
);
6087 gen_st8(tmp
, addr
, IS_USER(s
));
6090 gen_st16(tmp
, addr
, IS_USER(s
));
6094 gen_st32(tmp
, addr
, IS_USER(s
));
6100 tcg_gen_addi_i32(addr
, addr
, 4);
6101 tmp
= load_reg(s
, rt2
);
6102 gen_st32(tmp
, addr
, IS_USER(s
));
6104 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6105 tcg_gen_br(done_label
);
6106 gen_set_label(fail_label
);
6107 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6108 gen_set_label(done_label
);
6109 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6113 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
6115 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6122 insn
= ldl_code(s
->pc
);
6125 /* M variants do not implement ARM mode. */
6130 /* Unconditional instructions. */
6131 if (((insn
>> 25) & 7) == 1) {
6132 /* NEON Data processing. */
6133 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6136 if (disas_neon_data_insn(env
, s
, insn
))
6140 if ((insn
& 0x0f100000) == 0x04000000) {
6141 /* NEON load/store. */
6142 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6145 if (disas_neon_ls_insn(env
, s
, insn
))
6149 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6150 ((insn
& 0x0f30f010) == 0x0710f000)) {
6151 if ((insn
& (1 << 22)) == 0) {
6153 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6157 /* Otherwise PLD; v5TE+ */
6160 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6161 ((insn
& 0x0f70f010) == 0x0650f000)) {
6163 return; /* PLI; V7 */
6165 if (((insn
& 0x0f700000) == 0x04100000) ||
6166 ((insn
& 0x0f700010) == 0x06100000)) {
6167 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6170 return; /* v7MP: Unallocated memory hint: must NOP */
6173 if ((insn
& 0x0ffffdff) == 0x01010000) {
6176 if (insn
& (1 << 9)) {
6177 /* BE8 mode not implemented. */
6181 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6182 switch ((insn
>> 4) & 0xf) {
6191 /* We don't emulate caches so these are a no-op. */
6196 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6202 op1
= (insn
& 0x1f);
6203 addr
= tcg_temp_new_i32();
6204 tmp
= tcg_const_i32(op1
);
6205 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6206 tcg_temp_free_i32(tmp
);
6207 i
= (insn
>> 23) & 3;
6209 case 0: offset
= -4; break; /* DA */
6210 case 1: offset
= 0; break; /* IA */
6211 case 2: offset
= -8; break; /* DB */
6212 case 3: offset
= 4; break; /* IB */
6216 tcg_gen_addi_i32(addr
, addr
, offset
);
6217 tmp
= load_reg(s
, 14);
6218 gen_st32(tmp
, addr
, 0);
6219 tmp
= load_cpu_field(spsr
);
6220 tcg_gen_addi_i32(addr
, addr
, 4);
6221 gen_st32(tmp
, addr
, 0);
6222 if (insn
& (1 << 21)) {
6223 /* Base writeback. */
6225 case 0: offset
= -8; break;
6226 case 1: offset
= 4; break;
6227 case 2: offset
= -4; break;
6228 case 3: offset
= 0; break;
6232 tcg_gen_addi_i32(addr
, addr
, offset
);
6233 tmp
= tcg_const_i32(op1
);
6234 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6235 tcg_temp_free_i32(tmp
);
6236 tcg_temp_free_i32(addr
);
6238 tcg_temp_free_i32(addr
);
6241 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6247 rn
= (insn
>> 16) & 0xf;
6248 addr
= load_reg(s
, rn
);
6249 i
= (insn
>> 23) & 3;
6251 case 0: offset
= -4; break; /* DA */
6252 case 1: offset
= 0; break; /* IA */
6253 case 2: offset
= -8; break; /* DB */
6254 case 3: offset
= 4; break; /* IB */
6258 tcg_gen_addi_i32(addr
, addr
, offset
);
6259 /* Load PC into tmp and CPSR into tmp2. */
6260 tmp
= gen_ld32(addr
, 0);
6261 tcg_gen_addi_i32(addr
, addr
, 4);
6262 tmp2
= gen_ld32(addr
, 0);
6263 if (insn
& (1 << 21)) {
6264 /* Base writeback. */
6266 case 0: offset
= -8; break;
6267 case 1: offset
= 4; break;
6268 case 2: offset
= -4; break;
6269 case 3: offset
= 0; break;
6273 tcg_gen_addi_i32(addr
, addr
, offset
);
6274 store_reg(s
, rn
, addr
);
6276 tcg_temp_free_i32(addr
);
6278 gen_rfe(s
, tmp
, tmp2
);
6280 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6281 /* branch link and change to thumb (blx <offset>) */
6284 val
= (uint32_t)s
->pc
;
6285 tmp
= tcg_temp_new_i32();
6286 tcg_gen_movi_i32(tmp
, val
);
6287 store_reg(s
, 14, tmp
);
6288 /* Sign-extend the 24-bit offset */
6289 offset
= (((int32_t)insn
) << 8) >> 8;
6290 /* offset * 4 + bit24 * 2 + (thumb bit) */
6291 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6292 /* pipeline offset */
6296 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6297 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6298 /* iWMMXt register transfer. */
6299 if (env
->cp15
.c15_cpar
& (1 << 1))
6300 if (!disas_iwmmxt_insn(env
, s
, insn
))
6303 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6304 /* Coprocessor double register transfer. */
6305 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6306 /* Additional coprocessor register transfer. */
6307 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6310 /* cps (privileged) */
6314 if (insn
& (1 << 19)) {
6315 if (insn
& (1 << 8))
6317 if (insn
& (1 << 7))
6319 if (insn
& (1 << 6))
6321 if (insn
& (1 << 18))
6324 if (insn
& (1 << 17)) {
6326 val
|= (insn
& 0x1f);
6329 gen_set_psr_im(s
, mask
, 0, val
);
6336 /* if not always execute, we generate a conditional jump to
6338 s
->condlabel
= gen_new_label();
6339 gen_test_cc(cond
^ 1, s
->condlabel
);
6342 if ((insn
& 0x0f900000) == 0x03000000) {
6343 if ((insn
& (1 << 21)) == 0) {
6345 rd
= (insn
>> 12) & 0xf;
6346 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6347 if ((insn
& (1 << 22)) == 0) {
6349 tmp
= tcg_temp_new_i32();
6350 tcg_gen_movi_i32(tmp
, val
);
6353 tmp
= load_reg(s
, rd
);
6354 tcg_gen_ext16u_i32(tmp
, tmp
);
6355 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6357 store_reg(s
, rd
, tmp
);
6359 if (((insn
>> 12) & 0xf) != 0xf)
6361 if (((insn
>> 16) & 0xf) == 0) {
6362 gen_nop_hint(s
, insn
& 0xff);
6364 /* CPSR = immediate */
6366 shift
= ((insn
>> 8) & 0xf) * 2;
6368 val
= (val
>> shift
) | (val
<< (32 - shift
));
6369 i
= ((insn
& (1 << 22)) != 0);
6370 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6374 } else if ((insn
& 0x0f900000) == 0x01000000
6375 && (insn
& 0x00000090) != 0x00000090) {
6376 /* miscellaneous instructions */
6377 op1
= (insn
>> 21) & 3;
6378 sh
= (insn
>> 4) & 0xf;
6381 case 0x0: /* move program status register */
6384 tmp
= load_reg(s
, rm
);
6385 i
= ((op1
& 2) != 0);
6386 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6390 rd
= (insn
>> 12) & 0xf;
6394 tmp
= load_cpu_field(spsr
);
6396 tmp
= tcg_temp_new_i32();
6397 gen_helper_cpsr_read(tmp
);
6399 store_reg(s
, rd
, tmp
);
6404 /* branch/exchange thumb (bx). */
6405 tmp
= load_reg(s
, rm
);
6407 } else if (op1
== 3) {
6409 rd
= (insn
>> 12) & 0xf;
6410 tmp
= load_reg(s
, rm
);
6411 gen_helper_clz(tmp
, tmp
);
6412 store_reg(s
, rd
, tmp
);
6420 /* Trivial implementation equivalent to bx. */
6421 tmp
= load_reg(s
, rm
);
6431 /* branch link/exchange thumb (blx) */
6432 tmp
= load_reg(s
, rm
);
6433 tmp2
= tcg_temp_new_i32();
6434 tcg_gen_movi_i32(tmp2
, s
->pc
);
6435 store_reg(s
, 14, tmp2
);
6438 case 0x5: /* saturating add/subtract */
6439 rd
= (insn
>> 12) & 0xf;
6440 rn
= (insn
>> 16) & 0xf;
6441 tmp
= load_reg(s
, rm
);
6442 tmp2
= load_reg(s
, rn
);
6444 gen_helper_double_saturate(tmp2
, tmp2
);
6446 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6448 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6449 tcg_temp_free_i32(tmp2
);
6450 store_reg(s
, rd
, tmp
);
6453 /* SMC instruction (op1 == 3)
6454 and undefined instructions (op1 == 0 || op1 == 2)
6460 gen_exception_insn(s
, 4, EXCP_BKPT
);
6462 case 0x8: /* signed multiply */
6466 rs
= (insn
>> 8) & 0xf;
6467 rn
= (insn
>> 12) & 0xf;
6468 rd
= (insn
>> 16) & 0xf;
6470 /* (32 * 16) >> 16 */
6471 tmp
= load_reg(s
, rm
);
6472 tmp2
= load_reg(s
, rs
);
6474 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6477 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6478 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6479 tmp
= tcg_temp_new_i32();
6480 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6481 tcg_temp_free_i64(tmp64
);
6482 if ((sh
& 2) == 0) {
6483 tmp2
= load_reg(s
, rn
);
6484 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6485 tcg_temp_free_i32(tmp2
);
6487 store_reg(s
, rd
, tmp
);
6490 tmp
= load_reg(s
, rm
);
6491 tmp2
= load_reg(s
, rs
);
6492 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6493 tcg_temp_free_i32(tmp2
);
6495 tmp64
= tcg_temp_new_i64();
6496 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6497 tcg_temp_free_i32(tmp
);
6498 gen_addq(s
, tmp64
, rn
, rd
);
6499 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6500 tcg_temp_free_i64(tmp64
);
6503 tmp2
= load_reg(s
, rn
);
6504 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6505 tcg_temp_free_i32(tmp2
);
6507 store_reg(s
, rd
, tmp
);
6514 } else if (((insn
& 0x0e000000) == 0 &&
6515 (insn
& 0x00000090) != 0x90) ||
6516 ((insn
& 0x0e000000) == (1 << 25))) {
6517 int set_cc
, logic_cc
, shiftop
;
6519 op1
= (insn
>> 21) & 0xf;
6520 set_cc
= (insn
>> 20) & 1;
6521 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6523 /* data processing instruction */
6524 if (insn
& (1 << 25)) {
6525 /* immediate operand */
6527 shift
= ((insn
>> 8) & 0xf) * 2;
6529 val
= (val
>> shift
) | (val
<< (32 - shift
));
6531 tmp2
= tcg_temp_new_i32();
6532 tcg_gen_movi_i32(tmp2
, val
);
6533 if (logic_cc
&& shift
) {
6534 gen_set_CF_bit31(tmp2
);
6539 tmp2
= load_reg(s
, rm
);
6540 shiftop
= (insn
>> 5) & 3;
6541 if (!(insn
& (1 << 4))) {
6542 shift
= (insn
>> 7) & 0x1f;
6543 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6545 rs
= (insn
>> 8) & 0xf;
6546 tmp
= load_reg(s
, rs
);
6547 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6550 if (op1
!= 0x0f && op1
!= 0x0d) {
6551 rn
= (insn
>> 16) & 0xf;
6552 tmp
= load_reg(s
, rn
);
6556 rd
= (insn
>> 12) & 0xf;
6559 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6563 store_reg_bx(env
, s
, rd
, tmp
);
6566 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6570 store_reg_bx(env
, s
, rd
, tmp
);
6573 if (set_cc
&& rd
== 15) {
6574 /* SUBS r15, ... is used for exception return. */
6578 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6579 gen_exception_return(s
, tmp
);
6582 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6584 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6586 store_reg_bx(env
, s
, rd
, tmp
);
6591 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
6593 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6595 store_reg_bx(env
, s
, rd
, tmp
);
6599 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6601 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6603 store_reg_bx(env
, s
, rd
, tmp
);
6607 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
6609 gen_add_carry(tmp
, tmp
, tmp2
);
6611 store_reg_bx(env
, s
, rd
, tmp
);
6615 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
6617 gen_sub_carry(tmp
, tmp
, tmp2
);
6619 store_reg_bx(env
, s
, rd
, tmp
);
6623 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
6625 gen_sub_carry(tmp
, tmp2
, tmp
);
6627 store_reg_bx(env
, s
, rd
, tmp
);
6631 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6634 tcg_temp_free_i32(tmp
);
6638 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6641 tcg_temp_free_i32(tmp
);
6645 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6647 tcg_temp_free_i32(tmp
);
6651 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6653 tcg_temp_free_i32(tmp
);
6656 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6660 store_reg_bx(env
, s
, rd
, tmp
);
6663 if (logic_cc
&& rd
== 15) {
6664 /* MOVS r15, ... is used for exception return. */
6668 gen_exception_return(s
, tmp2
);
6673 store_reg_bx(env
, s
, rd
, tmp2
);
6677 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
6681 store_reg_bx(env
, s
, rd
, tmp
);
6685 tcg_gen_not_i32(tmp2
, tmp2
);
6689 store_reg_bx(env
, s
, rd
, tmp2
);
6692 if (op1
!= 0x0f && op1
!= 0x0d) {
6693 tcg_temp_free_i32(tmp2
);
6696 /* other instructions */
6697 op1
= (insn
>> 24) & 0xf;
6701 /* multiplies, extra load/stores */
6702 sh
= (insn
>> 5) & 3;
6705 rd
= (insn
>> 16) & 0xf;
6706 rn
= (insn
>> 12) & 0xf;
6707 rs
= (insn
>> 8) & 0xf;
6709 op1
= (insn
>> 20) & 0xf;
6711 case 0: case 1: case 2: case 3: case 6:
6713 tmp
= load_reg(s
, rs
);
6714 tmp2
= load_reg(s
, rm
);
6715 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
6716 tcg_temp_free_i32(tmp2
);
6717 if (insn
& (1 << 22)) {
6718 /* Subtract (mls) */
6720 tmp2
= load_reg(s
, rn
);
6721 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6722 tcg_temp_free_i32(tmp2
);
6723 } else if (insn
& (1 << 21)) {
6725 tmp2
= load_reg(s
, rn
);
6726 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6727 tcg_temp_free_i32(tmp2
);
6729 if (insn
& (1 << 20))
6731 store_reg(s
, rd
, tmp
);
6734 /* 64 bit mul double accumulate (UMAAL) */
6736 tmp
= load_reg(s
, rs
);
6737 tmp2
= load_reg(s
, rm
);
6738 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6739 gen_addq_lo(s
, tmp64
, rn
);
6740 gen_addq_lo(s
, tmp64
, rd
);
6741 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6742 tcg_temp_free_i64(tmp64
);
6744 case 8: case 9: case 10: case 11:
6745 case 12: case 13: case 14: case 15:
6746 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6747 tmp
= load_reg(s
, rs
);
6748 tmp2
= load_reg(s
, rm
);
6749 if (insn
& (1 << 22)) {
6750 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6752 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
6754 if (insn
& (1 << 21)) { /* mult accumulate */
6755 gen_addq(s
, tmp64
, rn
, rd
);
6757 if (insn
& (1 << 20)) {
6758 gen_logicq_cc(tmp64
);
6760 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6761 tcg_temp_free_i64(tmp64
);
6767 rn
= (insn
>> 16) & 0xf;
6768 rd
= (insn
>> 12) & 0xf;
6769 if (insn
& (1 << 23)) {
6770 /* load/store exclusive */
6771 op1
= (insn
>> 21) & 0x3;
6776 addr
= tcg_temp_local_new_i32();
6777 load_reg_var(s
, addr
, rn
);
6778 if (insn
& (1 << 20)) {
6781 gen_load_exclusive(s
, rd
, 15, addr
, 2);
6783 case 1: /* ldrexd */
6784 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
6786 case 2: /* ldrexb */
6787 gen_load_exclusive(s
, rd
, 15, addr
, 0);
6789 case 3: /* ldrexh */
6790 gen_load_exclusive(s
, rd
, 15, addr
, 1);
6799 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
6801 case 1: /* strexd */
6802 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
6804 case 2: /* strexb */
6805 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
6807 case 3: /* strexh */
6808 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
6814 tcg_temp_free(addr
);
6816 /* SWP instruction */
6819 /* ??? This is not really atomic. However we know
6820 we never have multiple CPUs running in parallel,
6821 so it is good enough. */
6822 addr
= load_reg(s
, rn
);
6823 tmp
= load_reg(s
, rm
);
6824 if (insn
& (1 << 22)) {
6825 tmp2
= gen_ld8u(addr
, IS_USER(s
));
6826 gen_st8(tmp
, addr
, IS_USER(s
));
6828 tmp2
= gen_ld32(addr
, IS_USER(s
));
6829 gen_st32(tmp
, addr
, IS_USER(s
));
6831 tcg_temp_free_i32(addr
);
6832 store_reg(s
, rd
, tmp2
);
6838 /* Misc load/store */
6839 rn
= (insn
>> 16) & 0xf;
6840 rd
= (insn
>> 12) & 0xf;
6841 addr
= load_reg(s
, rn
);
6842 if (insn
& (1 << 24))
6843 gen_add_datah_offset(s
, insn
, 0, addr
);
6845 if (insn
& (1 << 20)) {
6849 tmp
= gen_ld16u(addr
, IS_USER(s
));
6852 tmp
= gen_ld8s(addr
, IS_USER(s
));
6856 tmp
= gen_ld16s(addr
, IS_USER(s
));
6860 } else if (sh
& 2) {
6864 tmp
= load_reg(s
, rd
);
6865 gen_st32(tmp
, addr
, IS_USER(s
));
6866 tcg_gen_addi_i32(addr
, addr
, 4);
6867 tmp
= load_reg(s
, rd
+ 1);
6868 gen_st32(tmp
, addr
, IS_USER(s
));
6872 tmp
= gen_ld32(addr
, IS_USER(s
));
6873 store_reg(s
, rd
, tmp
);
6874 tcg_gen_addi_i32(addr
, addr
, 4);
6875 tmp
= gen_ld32(addr
, IS_USER(s
));
6879 address_offset
= -4;
6882 tmp
= load_reg(s
, rd
);
6883 gen_st16(tmp
, addr
, IS_USER(s
));
6886 /* Perform base writeback before the loaded value to
6887 ensure correct behavior with overlapping index registers.
6888 ldrd with base writeback is is undefined if the
6889 destination and index registers overlap. */
6890 if (!(insn
& (1 << 24))) {
6891 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
6892 store_reg(s
, rn
, addr
);
6893 } else if (insn
& (1 << 21)) {
6895 tcg_gen_addi_i32(addr
, addr
, address_offset
);
6896 store_reg(s
, rn
, addr
);
6898 tcg_temp_free_i32(addr
);
6901 /* Complete the load. */
6902 store_reg(s
, rd
, tmp
);
6911 if (insn
& (1 << 4)) {
6913 /* Armv6 Media instructions. */
6915 rn
= (insn
>> 16) & 0xf;
6916 rd
= (insn
>> 12) & 0xf;
6917 rs
= (insn
>> 8) & 0xf;
6918 switch ((insn
>> 23) & 3) {
6919 case 0: /* Parallel add/subtract. */
6920 op1
= (insn
>> 20) & 7;
6921 tmp
= load_reg(s
, rn
);
6922 tmp2
= load_reg(s
, rm
);
6923 sh
= (insn
>> 5) & 7;
6924 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
6926 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
6927 tcg_temp_free_i32(tmp2
);
6928 store_reg(s
, rd
, tmp
);
6931 if ((insn
& 0x00700020) == 0) {
6932 /* Halfword pack. */
6933 tmp
= load_reg(s
, rn
);
6934 tmp2
= load_reg(s
, rm
);
6935 shift
= (insn
>> 7) & 0x1f;
6936 if (insn
& (1 << 6)) {
6940 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
6941 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
6942 tcg_gen_ext16u_i32(tmp2
, tmp2
);
6946 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
6947 tcg_gen_ext16u_i32(tmp
, tmp
);
6948 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
6950 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6951 tcg_temp_free_i32(tmp2
);
6952 store_reg(s
, rd
, tmp
);
6953 } else if ((insn
& 0x00200020) == 0x00200000) {
6955 tmp
= load_reg(s
, rm
);
6956 shift
= (insn
>> 7) & 0x1f;
6957 if (insn
& (1 << 6)) {
6960 tcg_gen_sari_i32(tmp
, tmp
, shift
);
6962 tcg_gen_shli_i32(tmp
, tmp
, shift
);
6964 sh
= (insn
>> 16) & 0x1f;
6965 tmp2
= tcg_const_i32(sh
);
6966 if (insn
& (1 << 22))
6967 gen_helper_usat(tmp
, tmp
, tmp2
);
6969 gen_helper_ssat(tmp
, tmp
, tmp2
);
6970 tcg_temp_free_i32(tmp2
);
6971 store_reg(s
, rd
, tmp
);
6972 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
6974 tmp
= load_reg(s
, rm
);
6975 sh
= (insn
>> 16) & 0x1f;
6976 tmp2
= tcg_const_i32(sh
);
6977 if (insn
& (1 << 22))
6978 gen_helper_usat16(tmp
, tmp
, tmp2
);
6980 gen_helper_ssat16(tmp
, tmp
, tmp2
);
6981 tcg_temp_free_i32(tmp2
);
6982 store_reg(s
, rd
, tmp
);
6983 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
6985 tmp
= load_reg(s
, rn
);
6986 tmp2
= load_reg(s
, rm
);
6987 tmp3
= tcg_temp_new_i32();
6988 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
6989 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
6990 tcg_temp_free_i32(tmp3
);
6991 tcg_temp_free_i32(tmp2
);
6992 store_reg(s
, rd
, tmp
);
6993 } else if ((insn
& 0x000003e0) == 0x00000060) {
6994 tmp
= load_reg(s
, rm
);
6995 shift
= (insn
>> 10) & 3;
6996 /* ??? In many cases it's not neccessary to do a
6997 rotate, a shift is sufficient. */
6999 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7000 op1
= (insn
>> 20) & 7;
7002 case 0: gen_sxtb16(tmp
); break;
7003 case 2: gen_sxtb(tmp
); break;
7004 case 3: gen_sxth(tmp
); break;
7005 case 4: gen_uxtb16(tmp
); break;
7006 case 6: gen_uxtb(tmp
); break;
7007 case 7: gen_uxth(tmp
); break;
7008 default: goto illegal_op
;
7011 tmp2
= load_reg(s
, rn
);
7012 if ((op1
& 3) == 0) {
7013 gen_add16(tmp
, tmp2
);
7015 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7016 tcg_temp_free_i32(tmp2
);
7019 store_reg(s
, rd
, tmp
);
7020 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7022 tmp
= load_reg(s
, rm
);
7023 if (insn
& (1 << 22)) {
7024 if (insn
& (1 << 7)) {
7028 gen_helper_rbit(tmp
, tmp
);
7031 if (insn
& (1 << 7))
7034 tcg_gen_bswap32_i32(tmp
, tmp
);
7036 store_reg(s
, rd
, tmp
);
7041 case 2: /* Multiplies (Type 3). */
7042 tmp
= load_reg(s
, rm
);
7043 tmp2
= load_reg(s
, rs
);
7044 if (insn
& (1 << 20)) {
7045 /* Signed multiply most significant [accumulate].
7046 (SMMUL, SMMLA, SMMLS) */
7047 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7050 tmp
= load_reg(s
, rd
);
7051 if (insn
& (1 << 6)) {
7052 tmp64
= gen_subq_msw(tmp64
, tmp
);
7054 tmp64
= gen_addq_msw(tmp64
, tmp
);
7057 if (insn
& (1 << 5)) {
7058 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7060 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7061 tmp
= tcg_temp_new_i32();
7062 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7063 tcg_temp_free_i64(tmp64
);
7064 store_reg(s
, rn
, tmp
);
7066 if (insn
& (1 << 5))
7067 gen_swap_half(tmp2
);
7068 gen_smul_dual(tmp
, tmp2
);
7069 if (insn
& (1 << 6)) {
7070 /* This subtraction cannot overflow. */
7071 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7073 /* This addition cannot overflow 32 bits;
7074 * however it may overflow considered as a signed
7075 * operation, in which case we must set the Q flag.
7077 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7079 tcg_temp_free_i32(tmp2
);
7080 if (insn
& (1 << 22)) {
7081 /* smlald, smlsld */
7082 tmp64
= tcg_temp_new_i64();
7083 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7084 tcg_temp_free_i32(tmp
);
7085 gen_addq(s
, tmp64
, rd
, rn
);
7086 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7087 tcg_temp_free_i64(tmp64
);
7089 /* smuad, smusd, smlad, smlsd */
7092 tmp2
= load_reg(s
, rd
);
7093 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7094 tcg_temp_free_i32(tmp2
);
7096 store_reg(s
, rn
, tmp
);
7101 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7103 case 0: /* Unsigned sum of absolute differences. */
7105 tmp
= load_reg(s
, rm
);
7106 tmp2
= load_reg(s
, rs
);
7107 gen_helper_usad8(tmp
, tmp
, tmp2
);
7108 tcg_temp_free_i32(tmp2
);
7110 tmp2
= load_reg(s
, rd
);
7111 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7112 tcg_temp_free_i32(tmp2
);
7114 store_reg(s
, rn
, tmp
);
7116 case 0x20: case 0x24: case 0x28: case 0x2c:
7117 /* Bitfield insert/clear. */
7119 shift
= (insn
>> 7) & 0x1f;
7120 i
= (insn
>> 16) & 0x1f;
7123 tmp
= tcg_temp_new_i32();
7124 tcg_gen_movi_i32(tmp
, 0);
7126 tmp
= load_reg(s
, rm
);
7129 tmp2
= load_reg(s
, rd
);
7130 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7131 tcg_temp_free_i32(tmp2
);
7133 store_reg(s
, rd
, tmp
);
7135 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7136 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7138 tmp
= load_reg(s
, rm
);
7139 shift
= (insn
>> 7) & 0x1f;
7140 i
= ((insn
>> 16) & 0x1f) + 1;
7145 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7147 gen_sbfx(tmp
, shift
, i
);
7150 store_reg(s
, rd
, tmp
);
7160 /* Check for undefined extension instructions
7161 * per the ARM Bible IE:
7162 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7164 sh
= (0xf << 20) | (0xf << 4);
7165 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7169 /* load/store byte/word */
7170 rn
= (insn
>> 16) & 0xf;
7171 rd
= (insn
>> 12) & 0xf;
7172 tmp2
= load_reg(s
, rn
);
7173 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7174 if (insn
& (1 << 24))
7175 gen_add_data_offset(s
, insn
, tmp2
);
7176 if (insn
& (1 << 20)) {
7178 if (insn
& (1 << 22)) {
7179 tmp
= gen_ld8u(tmp2
, i
);
7181 tmp
= gen_ld32(tmp2
, i
);
7185 tmp
= load_reg(s
, rd
);
7186 if (insn
& (1 << 22))
7187 gen_st8(tmp
, tmp2
, i
);
7189 gen_st32(tmp
, tmp2
, i
);
7191 if (!(insn
& (1 << 24))) {
7192 gen_add_data_offset(s
, insn
, tmp2
);
7193 store_reg(s
, rn
, tmp2
);
7194 } else if (insn
& (1 << 21)) {
7195 store_reg(s
, rn
, tmp2
);
7197 tcg_temp_free_i32(tmp2
);
7199 if (insn
& (1 << 20)) {
7200 /* Complete the load. */
7204 store_reg(s
, rd
, tmp
);
7210 int j
, n
, user
, loaded_base
;
7212 /* load/store multiple words */
7213 /* XXX: store correct base if write back */
7215 if (insn
& (1 << 22)) {
7217 goto illegal_op
; /* only usable in supervisor mode */
7219 if ((insn
& (1 << 15)) == 0)
7222 rn
= (insn
>> 16) & 0xf;
7223 addr
= load_reg(s
, rn
);
7225 /* compute total size */
7227 TCGV_UNUSED(loaded_var
);
7230 if (insn
& (1 << i
))
7233 /* XXX: test invalid n == 0 case ? */
7234 if (insn
& (1 << 23)) {
7235 if (insn
& (1 << 24)) {
7237 tcg_gen_addi_i32(addr
, addr
, 4);
7239 /* post increment */
7242 if (insn
& (1 << 24)) {
7244 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7246 /* post decrement */
7248 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7253 if (insn
& (1 << i
)) {
7254 if (insn
& (1 << 20)) {
7256 tmp
= gen_ld32(addr
, IS_USER(s
));
7260 tmp2
= tcg_const_i32(i
);
7261 gen_helper_set_user_reg(tmp2
, tmp
);
7262 tcg_temp_free_i32(tmp2
);
7263 tcg_temp_free_i32(tmp
);
7264 } else if (i
== rn
) {
7268 store_reg(s
, i
, tmp
);
7273 /* special case: r15 = PC + 8 */
7274 val
= (long)s
->pc
+ 4;
7275 tmp
= tcg_temp_new_i32();
7276 tcg_gen_movi_i32(tmp
, val
);
7278 tmp
= tcg_temp_new_i32();
7279 tmp2
= tcg_const_i32(i
);
7280 gen_helper_get_user_reg(tmp
, tmp2
);
7281 tcg_temp_free_i32(tmp2
);
7283 tmp
= load_reg(s
, i
);
7285 gen_st32(tmp
, addr
, IS_USER(s
));
7288 /* no need to add after the last transfer */
7290 tcg_gen_addi_i32(addr
, addr
, 4);
7293 if (insn
& (1 << 21)) {
7295 if (insn
& (1 << 23)) {
7296 if (insn
& (1 << 24)) {
7299 /* post increment */
7300 tcg_gen_addi_i32(addr
, addr
, 4);
7303 if (insn
& (1 << 24)) {
7306 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7308 /* post decrement */
7309 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7312 store_reg(s
, rn
, addr
);
7314 tcg_temp_free_i32(addr
);
7317 store_reg(s
, rn
, loaded_var
);
7319 if ((insn
& (1 << 22)) && !user
) {
7320 /* Restore CPSR from SPSR. */
7321 tmp
= load_cpu_field(spsr
);
7322 gen_set_cpsr(tmp
, 0xffffffff);
7323 tcg_temp_free_i32(tmp
);
7324 s
->is_jmp
= DISAS_UPDATE
;
7333 /* branch (and link) */
7334 val
= (int32_t)s
->pc
;
7335 if (insn
& (1 << 24)) {
7336 tmp
= tcg_temp_new_i32();
7337 tcg_gen_movi_i32(tmp
, val
);
7338 store_reg(s
, 14, tmp
);
7340 offset
= (((int32_t)insn
<< 8) >> 8);
7341 val
+= (offset
<< 2) + 4;
7349 if (disas_coproc_insn(env
, s
, insn
))
7354 gen_set_pc_im(s
->pc
);
7355 s
->is_jmp
= DISAS_SWI
;
7359 gen_exception_insn(s
, 4, EXCP_UDEF
);
7365 /* Return true if this is a Thumb-2 logical op. */
7367 thumb2_logic_op(int op
)
7372 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7373 then set condition code flags based on the result of the operation.
7374 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7375 to the high bit of T1.
7376 Returns zero if the opcode is valid. */
7379 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7386 tcg_gen_and_i32(t0
, t0
, t1
);
7390 tcg_gen_andc_i32(t0
, t0
, t1
);
7394 tcg_gen_or_i32(t0
, t0
, t1
);
7398 tcg_gen_orc_i32(t0
, t0
, t1
);
7402 tcg_gen_xor_i32(t0
, t0
, t1
);
7407 gen_helper_add_cc(t0
, t0
, t1
);
7409 tcg_gen_add_i32(t0
, t0
, t1
);
7413 gen_helper_adc_cc(t0
, t0
, t1
);
7419 gen_helper_sbc_cc(t0
, t0
, t1
);
7421 gen_sub_carry(t0
, t0
, t1
);
7425 gen_helper_sub_cc(t0
, t0
, t1
);
7427 tcg_gen_sub_i32(t0
, t0
, t1
);
7431 gen_helper_sub_cc(t0
, t1
, t0
);
7433 tcg_gen_sub_i32(t0
, t1
, t0
);
7435 default: /* 5, 6, 7, 9, 12, 15. */
7441 gen_set_CF_bit31(t1
);
7446 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7448 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7450 uint32_t insn
, imm
, shift
, offset
;
7451 uint32_t rd
, rn
, rm
, rs
;
7462 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7463 || arm_feature (env
, ARM_FEATURE_M
))) {
7464 /* Thumb-1 cores may need to treat bl and blx as a pair of
7465 16-bit instructions to get correct prefetch abort behavior. */
7467 if ((insn
& (1 << 12)) == 0) {
7468 /* Second half of blx. */
7469 offset
= ((insn
& 0x7ff) << 1);
7470 tmp
= load_reg(s
, 14);
7471 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7472 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7474 tmp2
= tcg_temp_new_i32();
7475 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7476 store_reg(s
, 14, tmp2
);
7480 if (insn
& (1 << 11)) {
7481 /* Second half of bl. */
7482 offset
= ((insn
& 0x7ff) << 1) | 1;
7483 tmp
= load_reg(s
, 14);
7484 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7486 tmp2
= tcg_temp_new_i32();
7487 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7488 store_reg(s
, 14, tmp2
);
7492 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7493 /* Instruction spans a page boundary. Implement it as two
7494 16-bit instructions in case the second half causes an
7496 offset
= ((int32_t)insn
<< 21) >> 9;
7497 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7500 /* Fall through to 32-bit decode. */
7503 insn
= lduw_code(s
->pc
);
7505 insn
|= (uint32_t)insn_hw1
<< 16;
7507 if ((insn
& 0xf800e800) != 0xf000e800) {
7511 rn
= (insn
>> 16) & 0xf;
7512 rs
= (insn
>> 12) & 0xf;
7513 rd
= (insn
>> 8) & 0xf;
7515 switch ((insn
>> 25) & 0xf) {
7516 case 0: case 1: case 2: case 3:
7517 /* 16-bit instructions. Should never happen. */
7520 if (insn
& (1 << 22)) {
7521 /* Other load/store, table branch. */
7522 if (insn
& 0x01200000) {
7523 /* Load/store doubleword. */
7525 addr
= tcg_temp_new_i32();
7526 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7528 addr
= load_reg(s
, rn
);
7530 offset
= (insn
& 0xff) * 4;
7531 if ((insn
& (1 << 23)) == 0)
7533 if (insn
& (1 << 24)) {
7534 tcg_gen_addi_i32(addr
, addr
, offset
);
7537 if (insn
& (1 << 20)) {
7539 tmp
= gen_ld32(addr
, IS_USER(s
));
7540 store_reg(s
, rs
, tmp
);
7541 tcg_gen_addi_i32(addr
, addr
, 4);
7542 tmp
= gen_ld32(addr
, IS_USER(s
));
7543 store_reg(s
, rd
, tmp
);
7546 tmp
= load_reg(s
, rs
);
7547 gen_st32(tmp
, addr
, IS_USER(s
));
7548 tcg_gen_addi_i32(addr
, addr
, 4);
7549 tmp
= load_reg(s
, rd
);
7550 gen_st32(tmp
, addr
, IS_USER(s
));
7552 if (insn
& (1 << 21)) {
7553 /* Base writeback. */
7556 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
7557 store_reg(s
, rn
, addr
);
7559 tcg_temp_free_i32(addr
);
7561 } else if ((insn
& (1 << 23)) == 0) {
7562 /* Load/store exclusive word. */
7563 addr
= tcg_temp_local_new();
7564 load_reg_var(s
, addr
, rn
);
7565 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
7566 if (insn
& (1 << 20)) {
7567 gen_load_exclusive(s
, rs
, 15, addr
, 2);
7569 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
7571 tcg_temp_free(addr
);
7572 } else if ((insn
& (1 << 6)) == 0) {
7575 addr
= tcg_temp_new_i32();
7576 tcg_gen_movi_i32(addr
, s
->pc
);
7578 addr
= load_reg(s
, rn
);
7580 tmp
= load_reg(s
, rm
);
7581 tcg_gen_add_i32(addr
, addr
, tmp
);
7582 if (insn
& (1 << 4)) {
7584 tcg_gen_add_i32(addr
, addr
, tmp
);
7585 tcg_temp_free_i32(tmp
);
7586 tmp
= gen_ld16u(addr
, IS_USER(s
));
7588 tcg_temp_free_i32(tmp
);
7589 tmp
= gen_ld8u(addr
, IS_USER(s
));
7591 tcg_temp_free_i32(addr
);
7592 tcg_gen_shli_i32(tmp
, tmp
, 1);
7593 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
7594 store_reg(s
, 15, tmp
);
7596 /* Load/store exclusive byte/halfword/doubleword. */
7598 op
= (insn
>> 4) & 0x3;
7602 addr
= tcg_temp_local_new();
7603 load_reg_var(s
, addr
, rn
);
7604 if (insn
& (1 << 20)) {
7605 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
7607 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
7609 tcg_temp_free(addr
);
7612 /* Load/store multiple, RFE, SRS. */
7613 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
7614 /* Not available in user mode. */
7617 if (insn
& (1 << 20)) {
7619 addr
= load_reg(s
, rn
);
7620 if ((insn
& (1 << 24)) == 0)
7621 tcg_gen_addi_i32(addr
, addr
, -8);
7622 /* Load PC into tmp and CPSR into tmp2. */
7623 tmp
= gen_ld32(addr
, 0);
7624 tcg_gen_addi_i32(addr
, addr
, 4);
7625 tmp2
= gen_ld32(addr
, 0);
7626 if (insn
& (1 << 21)) {
7627 /* Base writeback. */
7628 if (insn
& (1 << 24)) {
7629 tcg_gen_addi_i32(addr
, addr
, 4);
7631 tcg_gen_addi_i32(addr
, addr
, -4);
7633 store_reg(s
, rn
, addr
);
7635 tcg_temp_free_i32(addr
);
7637 gen_rfe(s
, tmp
, tmp2
);
7641 addr
= tcg_temp_new_i32();
7642 tmp
= tcg_const_i32(op
);
7643 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7644 tcg_temp_free_i32(tmp
);
7645 if ((insn
& (1 << 24)) == 0) {
7646 tcg_gen_addi_i32(addr
, addr
, -8);
7648 tmp
= load_reg(s
, 14);
7649 gen_st32(tmp
, addr
, 0);
7650 tcg_gen_addi_i32(addr
, addr
, 4);
7651 tmp
= tcg_temp_new_i32();
7652 gen_helper_cpsr_read(tmp
);
7653 gen_st32(tmp
, addr
, 0);
7654 if (insn
& (1 << 21)) {
7655 if ((insn
& (1 << 24)) == 0) {
7656 tcg_gen_addi_i32(addr
, addr
, -4);
7658 tcg_gen_addi_i32(addr
, addr
, 4);
7660 tmp
= tcg_const_i32(op
);
7661 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7662 tcg_temp_free_i32(tmp
);
7664 tcg_temp_free_i32(addr
);
7669 /* Load/store multiple. */
7670 addr
= load_reg(s
, rn
);
7672 for (i
= 0; i
< 16; i
++) {
7673 if (insn
& (1 << i
))
7676 if (insn
& (1 << 24)) {
7677 tcg_gen_addi_i32(addr
, addr
, -offset
);
7680 for (i
= 0; i
< 16; i
++) {
7681 if ((insn
& (1 << i
)) == 0)
7683 if (insn
& (1 << 20)) {
7685 tmp
= gen_ld32(addr
, IS_USER(s
));
7689 store_reg(s
, i
, tmp
);
7693 tmp
= load_reg(s
, i
);
7694 gen_st32(tmp
, addr
, IS_USER(s
));
7696 tcg_gen_addi_i32(addr
, addr
, 4);
7698 if (insn
& (1 << 21)) {
7699 /* Base register writeback. */
7700 if (insn
& (1 << 24)) {
7701 tcg_gen_addi_i32(addr
, addr
, -offset
);
7703 /* Fault if writeback register is in register list. */
7704 if (insn
& (1 << rn
))
7706 store_reg(s
, rn
, addr
);
7708 tcg_temp_free_i32(addr
);
7715 op
= (insn
>> 21) & 0xf;
7717 /* Halfword pack. */
7718 tmp
= load_reg(s
, rn
);
7719 tmp2
= load_reg(s
, rm
);
7720 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
7721 if (insn
& (1 << 5)) {
7725 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7726 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7727 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7731 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7732 tcg_gen_ext16u_i32(tmp
, tmp
);
7733 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7735 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7736 tcg_temp_free_i32(tmp2
);
7737 store_reg(s
, rd
, tmp
);
7739 /* Data processing register constant shift. */
7741 tmp
= tcg_temp_new_i32();
7742 tcg_gen_movi_i32(tmp
, 0);
7744 tmp
= load_reg(s
, rn
);
7746 tmp2
= load_reg(s
, rm
);
7748 shiftop
= (insn
>> 4) & 3;
7749 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
7750 conds
= (insn
& (1 << 20)) != 0;
7751 logic_cc
= (conds
&& thumb2_logic_op(op
));
7752 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7753 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
7755 tcg_temp_free_i32(tmp2
);
7757 store_reg(s
, rd
, tmp
);
7759 tcg_temp_free_i32(tmp
);
7763 case 13: /* Misc data processing. */
7764 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
7765 if (op
< 4 && (insn
& 0xf000) != 0xf000)
7768 case 0: /* Register controlled shift. */
7769 tmp
= load_reg(s
, rn
);
7770 tmp2
= load_reg(s
, rm
);
7771 if ((insn
& 0x70) != 0)
7773 op
= (insn
>> 21) & 3;
7774 logic_cc
= (insn
& (1 << 20)) != 0;
7775 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
7778 store_reg_bx(env
, s
, rd
, tmp
);
7780 case 1: /* Sign/zero extend. */
7781 tmp
= load_reg(s
, rm
);
7782 shift
= (insn
>> 4) & 3;
7783 /* ??? In many cases it's not neccessary to do a
7784 rotate, a shift is sufficient. */
7786 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7787 op
= (insn
>> 20) & 7;
7789 case 0: gen_sxth(tmp
); break;
7790 case 1: gen_uxth(tmp
); break;
7791 case 2: gen_sxtb16(tmp
); break;
7792 case 3: gen_uxtb16(tmp
); break;
7793 case 4: gen_sxtb(tmp
); break;
7794 case 5: gen_uxtb(tmp
); break;
7795 default: goto illegal_op
;
7798 tmp2
= load_reg(s
, rn
);
7799 if ((op
>> 1) == 1) {
7800 gen_add16(tmp
, tmp2
);
7802 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7803 tcg_temp_free_i32(tmp2
);
7806 store_reg(s
, rd
, tmp
);
7808 case 2: /* SIMD add/subtract. */
7809 op
= (insn
>> 20) & 7;
7810 shift
= (insn
>> 4) & 7;
7811 if ((op
& 3) == 3 || (shift
& 3) == 3)
7813 tmp
= load_reg(s
, rn
);
7814 tmp2
= load_reg(s
, rm
);
7815 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
7816 tcg_temp_free_i32(tmp2
);
7817 store_reg(s
, rd
, tmp
);
7819 case 3: /* Other data processing. */
7820 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
7822 /* Saturating add/subtract. */
7823 tmp
= load_reg(s
, rn
);
7824 tmp2
= load_reg(s
, rm
);
7826 gen_helper_double_saturate(tmp
, tmp
);
7828 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
7830 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
7831 tcg_temp_free_i32(tmp2
);
7833 tmp
= load_reg(s
, rn
);
7835 case 0x0a: /* rbit */
7836 gen_helper_rbit(tmp
, tmp
);
7838 case 0x08: /* rev */
7839 tcg_gen_bswap32_i32(tmp
, tmp
);
7841 case 0x09: /* rev16 */
7844 case 0x0b: /* revsh */
7847 case 0x10: /* sel */
7848 tmp2
= load_reg(s
, rm
);
7849 tmp3
= tcg_temp_new_i32();
7850 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7851 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7852 tcg_temp_free_i32(tmp3
);
7853 tcg_temp_free_i32(tmp2
);
7855 case 0x18: /* clz */
7856 gen_helper_clz(tmp
, tmp
);
7862 store_reg(s
, rd
, tmp
);
7864 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7865 op
= (insn
>> 4) & 0xf;
7866 tmp
= load_reg(s
, rn
);
7867 tmp2
= load_reg(s
, rm
);
7868 switch ((insn
>> 20) & 7) {
7869 case 0: /* 32 x 32 -> 32 */
7870 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7871 tcg_temp_free_i32(tmp2
);
7873 tmp2
= load_reg(s
, rs
);
7875 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7877 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7878 tcg_temp_free_i32(tmp2
);
7881 case 1: /* 16 x 16 -> 32 */
7882 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
7883 tcg_temp_free_i32(tmp2
);
7885 tmp2
= load_reg(s
, rs
);
7886 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7887 tcg_temp_free_i32(tmp2
);
7890 case 2: /* Dual multiply add. */
7891 case 4: /* Dual multiply subtract. */
7893 gen_swap_half(tmp2
);
7894 gen_smul_dual(tmp
, tmp2
);
7895 if (insn
& (1 << 22)) {
7896 /* This subtraction cannot overflow. */
7897 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7899 /* This addition cannot overflow 32 bits;
7900 * however it may overflow considered as a signed
7901 * operation, in which case we must set the Q flag.
7903 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7905 tcg_temp_free_i32(tmp2
);
7908 tmp2
= load_reg(s
, rs
);
7909 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7910 tcg_temp_free_i32(tmp2
);
7913 case 3: /* 32 * 16 -> 32msb */
7915 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7918 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7919 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7920 tmp
= tcg_temp_new_i32();
7921 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7922 tcg_temp_free_i64(tmp64
);
7925 tmp2
= load_reg(s
, rs
);
7926 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7927 tcg_temp_free_i32(tmp2
);
7930 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7931 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7933 tmp
= load_reg(s
, rs
);
7934 if (insn
& (1 << 20)) {
7935 tmp64
= gen_addq_msw(tmp64
, tmp
);
7937 tmp64
= gen_subq_msw(tmp64
, tmp
);
7940 if (insn
& (1 << 4)) {
7941 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7943 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7944 tmp
= tcg_temp_new_i32();
7945 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7946 tcg_temp_free_i64(tmp64
);
7948 case 7: /* Unsigned sum of absolute differences. */
7949 gen_helper_usad8(tmp
, tmp
, tmp2
);
7950 tcg_temp_free_i32(tmp2
);
7952 tmp2
= load_reg(s
, rs
);
7953 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7954 tcg_temp_free_i32(tmp2
);
7958 store_reg(s
, rd
, tmp
);
7960 case 6: case 7: /* 64-bit multiply, Divide. */
7961 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
7962 tmp
= load_reg(s
, rn
);
7963 tmp2
= load_reg(s
, rm
);
7964 if ((op
& 0x50) == 0x10) {
7966 if (!arm_feature(env
, ARM_FEATURE_DIV
))
7969 gen_helper_udiv(tmp
, tmp
, tmp2
);
7971 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7972 tcg_temp_free_i32(tmp2
);
7973 store_reg(s
, rd
, tmp
);
7974 } else if ((op
& 0xe) == 0xc) {
7975 /* Dual multiply accumulate long. */
7977 gen_swap_half(tmp2
);
7978 gen_smul_dual(tmp
, tmp2
);
7980 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7982 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7984 tcg_temp_free_i32(tmp2
);
7986 tmp64
= tcg_temp_new_i64();
7987 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7988 tcg_temp_free_i32(tmp
);
7989 gen_addq(s
, tmp64
, rs
, rd
);
7990 gen_storeq_reg(s
, rs
, rd
, tmp64
);
7991 tcg_temp_free_i64(tmp64
);
7994 /* Unsigned 64-bit multiply */
7995 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7999 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8000 tcg_temp_free_i32(tmp2
);
8001 tmp64
= tcg_temp_new_i64();
8002 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8003 tcg_temp_free_i32(tmp
);
8005 /* Signed 64-bit multiply */
8006 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8011 gen_addq_lo(s
, tmp64
, rs
);
8012 gen_addq_lo(s
, tmp64
, rd
);
8013 } else if (op
& 0x40) {
8014 /* 64-bit accumulate. */
8015 gen_addq(s
, tmp64
, rs
, rd
);
8017 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8018 tcg_temp_free_i64(tmp64
);
8023 case 6: case 7: case 14: case 15:
8025 if (((insn
>> 24) & 3) == 3) {
8026 /* Translate into the equivalent ARM encoding. */
8027 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8028 if (disas_neon_data_insn(env
, s
, insn
))
8031 if (insn
& (1 << 28))
8033 if (disas_coproc_insn (env
, s
, insn
))
8037 case 8: case 9: case 10: case 11:
8038 if (insn
& (1 << 15)) {
8039 /* Branches, misc control. */
8040 if (insn
& 0x5000) {
8041 /* Unconditional branch. */
8042 /* signextend(hw1[10:0]) -> offset[:12]. */
8043 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8044 /* hw1[10:0] -> offset[11:1]. */
8045 offset
|= (insn
& 0x7ff) << 1;
8046 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8047 offset[24:22] already have the same value because of the
8048 sign extension above. */
8049 offset
^= ((~insn
) & (1 << 13)) << 10;
8050 offset
^= ((~insn
) & (1 << 11)) << 11;
8052 if (insn
& (1 << 14)) {
8053 /* Branch and link. */
8054 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8058 if (insn
& (1 << 12)) {
8063 offset
&= ~(uint32_t)2;
8064 gen_bx_im(s
, offset
);
8066 } else if (((insn
>> 23) & 7) == 7) {
8068 if (insn
& (1 << 13))
8071 if (insn
& (1 << 26)) {
8072 /* Secure monitor call (v6Z) */
8073 goto illegal_op
; /* not implemented. */
8075 op
= (insn
>> 20) & 7;
8077 case 0: /* msr cpsr. */
8079 tmp
= load_reg(s
, rn
);
8080 addr
= tcg_const_i32(insn
& 0xff);
8081 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8082 tcg_temp_free_i32(addr
);
8083 tcg_temp_free_i32(tmp
);
8088 case 1: /* msr spsr. */
8091 tmp
= load_reg(s
, rn
);
8093 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8097 case 2: /* cps, nop-hint. */
8098 if (((insn
>> 8) & 7) == 0) {
8099 gen_nop_hint(s
, insn
& 0xff);
8101 /* Implemented as NOP in user mode. */
8106 if (insn
& (1 << 10)) {
8107 if (insn
& (1 << 7))
8109 if (insn
& (1 << 6))
8111 if (insn
& (1 << 5))
8113 if (insn
& (1 << 9))
8114 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8116 if (insn
& (1 << 8)) {
8118 imm
|= (insn
& 0x1f);
8121 gen_set_psr_im(s
, offset
, 0, imm
);
8124 case 3: /* Special control operations. */
8126 op
= (insn
>> 4) & 0xf;
8134 /* These execute as NOPs. */
8141 /* Trivial implementation equivalent to bx. */
8142 tmp
= load_reg(s
, rn
);
8145 case 5: /* Exception return. */
8149 if (rn
!= 14 || rd
!= 15) {
8152 tmp
= load_reg(s
, rn
);
8153 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8154 gen_exception_return(s
, tmp
);
8156 case 6: /* mrs cpsr. */
8157 tmp
= tcg_temp_new_i32();
8159 addr
= tcg_const_i32(insn
& 0xff);
8160 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8161 tcg_temp_free_i32(addr
);
8163 gen_helper_cpsr_read(tmp
);
8165 store_reg(s
, rd
, tmp
);
8167 case 7: /* mrs spsr. */
8168 /* Not accessible in user mode. */
8169 if (IS_USER(s
) || IS_M(env
))
8171 tmp
= load_cpu_field(spsr
);
8172 store_reg(s
, rd
, tmp
);
8177 /* Conditional branch. */
8178 op
= (insn
>> 22) & 0xf;
8179 /* Generate a conditional jump to next instruction. */
8180 s
->condlabel
= gen_new_label();
8181 gen_test_cc(op
^ 1, s
->condlabel
);
8184 /* offset[11:1] = insn[10:0] */
8185 offset
= (insn
& 0x7ff) << 1;
8186 /* offset[17:12] = insn[21:16]. */
8187 offset
|= (insn
& 0x003f0000) >> 4;
8188 /* offset[31:20] = insn[26]. */
8189 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8190 /* offset[18] = insn[13]. */
8191 offset
|= (insn
& (1 << 13)) << 5;
8192 /* offset[19] = insn[11]. */
8193 offset
|= (insn
& (1 << 11)) << 8;
8195 /* jump to the offset */
8196 gen_jmp(s
, s
->pc
+ offset
);
8199 /* Data processing immediate. */
8200 if (insn
& (1 << 25)) {
8201 if (insn
& (1 << 24)) {
8202 if (insn
& (1 << 20))
8204 /* Bitfield/Saturate. */
8205 op
= (insn
>> 21) & 7;
8207 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8209 tmp
= tcg_temp_new_i32();
8210 tcg_gen_movi_i32(tmp
, 0);
8212 tmp
= load_reg(s
, rn
);
8215 case 2: /* Signed bitfield extract. */
8217 if (shift
+ imm
> 32)
8220 gen_sbfx(tmp
, shift
, imm
);
8222 case 6: /* Unsigned bitfield extract. */
8224 if (shift
+ imm
> 32)
8227 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8229 case 3: /* Bitfield insert/clear. */
8232 imm
= imm
+ 1 - shift
;
8234 tmp2
= load_reg(s
, rd
);
8235 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8236 tcg_temp_free_i32(tmp2
);
8241 default: /* Saturate. */
8244 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8246 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8248 tmp2
= tcg_const_i32(imm
);
8251 if ((op
& 1) && shift
== 0)
8252 gen_helper_usat16(tmp
, tmp
, tmp2
);
8254 gen_helper_usat(tmp
, tmp
, tmp2
);
8257 if ((op
& 1) && shift
== 0)
8258 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8260 gen_helper_ssat(tmp
, tmp
, tmp2
);
8262 tcg_temp_free_i32(tmp2
);
8265 store_reg(s
, rd
, tmp
);
8267 imm
= ((insn
& 0x04000000) >> 15)
8268 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8269 if (insn
& (1 << 22)) {
8270 /* 16-bit immediate. */
8271 imm
|= (insn
>> 4) & 0xf000;
8272 if (insn
& (1 << 23)) {
8274 tmp
= load_reg(s
, rd
);
8275 tcg_gen_ext16u_i32(tmp
, tmp
);
8276 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8279 tmp
= tcg_temp_new_i32();
8280 tcg_gen_movi_i32(tmp
, imm
);
8283 /* Add/sub 12-bit immediate. */
8285 offset
= s
->pc
& ~(uint32_t)3;
8286 if (insn
& (1 << 23))
8290 tmp
= tcg_temp_new_i32();
8291 tcg_gen_movi_i32(tmp
, offset
);
8293 tmp
= load_reg(s
, rn
);
8294 if (insn
& (1 << 23))
8295 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8297 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8300 store_reg(s
, rd
, tmp
);
8303 int shifter_out
= 0;
8304 /* modified 12-bit immediate. */
8305 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8306 imm
= (insn
& 0xff);
8309 /* Nothing to do. */
8311 case 1: /* 00XY00XY */
8314 case 2: /* XY00XY00 */
8318 case 3: /* XYXYXYXY */
8322 default: /* Rotated constant. */
8323 shift
= (shift
<< 1) | (imm
>> 7);
8325 imm
= imm
<< (32 - shift
);
8329 tmp2
= tcg_temp_new_i32();
8330 tcg_gen_movi_i32(tmp2
, imm
);
8331 rn
= (insn
>> 16) & 0xf;
8333 tmp
= tcg_temp_new_i32();
8334 tcg_gen_movi_i32(tmp
, 0);
8336 tmp
= load_reg(s
, rn
);
8338 op
= (insn
>> 21) & 0xf;
8339 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8340 shifter_out
, tmp
, tmp2
))
8342 tcg_temp_free_i32(tmp2
);
8343 rd
= (insn
>> 8) & 0xf;
8345 store_reg(s
, rd
, tmp
);
8347 tcg_temp_free_i32(tmp
);
8352 case 12: /* Load/store single data item. */
8357 if ((insn
& 0x01100000) == 0x01000000) {
8358 if (disas_neon_ls_insn(env
, s
, insn
))
8362 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8364 if (!(insn
& (1 << 20))) {
8368 /* Byte or halfword load space with dest == r15 : memory hints.
8369 * Catch them early so we don't emit pointless addressing code.
8370 * This space is a mix of:
8371 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8372 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8374 * unallocated hints, which must be treated as NOPs
8375 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8376 * which is easiest for the decoding logic
8377 * Some space which must UNDEF
8379 int op1
= (insn
>> 23) & 3;
8380 int op2
= (insn
>> 6) & 0x3f;
8385 /* UNPREDICTABLE or unallocated hint */
8389 return 0; /* PLD* or unallocated hint */
8391 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8392 return 0; /* PLD* or unallocated hint */
8394 /* UNDEF space, or an UNPREDICTABLE */
8400 addr
= tcg_temp_new_i32();
8402 /* s->pc has already been incremented by 4. */
8403 imm
= s
->pc
& 0xfffffffc;
8404 if (insn
& (1 << 23))
8405 imm
+= insn
& 0xfff;
8407 imm
-= insn
& 0xfff;
8408 tcg_gen_movi_i32(addr
, imm
);
8410 addr
= load_reg(s
, rn
);
8411 if (insn
& (1 << 23)) {
8412 /* Positive offset. */
8414 tcg_gen_addi_i32(addr
, addr
, imm
);
8417 switch ((insn
>> 8) & 0xf) {
8418 case 0x0: /* Shifted Register. */
8419 shift
= (insn
>> 4) & 0xf;
8421 tcg_temp_free_i32(addr
);
8424 tmp
= load_reg(s
, rm
);
8426 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8427 tcg_gen_add_i32(addr
, addr
, tmp
);
8428 tcg_temp_free_i32(tmp
);
8430 case 0xc: /* Negative offset. */
8431 tcg_gen_addi_i32(addr
, addr
, -imm
);
8433 case 0xe: /* User privilege. */
8434 tcg_gen_addi_i32(addr
, addr
, imm
);
8437 case 0x9: /* Post-decrement. */
8440 case 0xb: /* Post-increment. */
8444 case 0xd: /* Pre-decrement. */
8447 case 0xf: /* Pre-increment. */
8448 tcg_gen_addi_i32(addr
, addr
, imm
);
8452 tcg_temp_free_i32(addr
);
8457 if (insn
& (1 << 20)) {
8460 case 0: tmp
= gen_ld8u(addr
, user
); break;
8461 case 4: tmp
= gen_ld8s(addr
, user
); break;
8462 case 1: tmp
= gen_ld16u(addr
, user
); break;
8463 case 5: tmp
= gen_ld16s(addr
, user
); break;
8464 case 2: tmp
= gen_ld32(addr
, user
); break;
8466 tcg_temp_free_i32(addr
);
8472 store_reg(s
, rs
, tmp
);
8476 tmp
= load_reg(s
, rs
);
8478 case 0: gen_st8(tmp
, addr
, user
); break;
8479 case 1: gen_st16(tmp
, addr
, user
); break;
8480 case 2: gen_st32(tmp
, addr
, user
); break;
8482 tcg_temp_free_i32(addr
);
8487 tcg_gen_addi_i32(addr
, addr
, imm
);
8489 store_reg(s
, rn
, addr
);
8491 tcg_temp_free_i32(addr
);
8503 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
8505 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8512 if (s
->condexec_mask
) {
8513 cond
= s
->condexec_cond
;
8514 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
8515 s
->condlabel
= gen_new_label();
8516 gen_test_cc(cond
^ 1, s
->condlabel
);
8521 insn
= lduw_code(s
->pc
);
8524 switch (insn
>> 12) {
8528 op
= (insn
>> 11) & 3;
8531 rn
= (insn
>> 3) & 7;
8532 tmp
= load_reg(s
, rn
);
8533 if (insn
& (1 << 10)) {
8535 tmp2
= tcg_temp_new_i32();
8536 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
8539 rm
= (insn
>> 6) & 7;
8540 tmp2
= load_reg(s
, rm
);
8542 if (insn
& (1 << 9)) {
8543 if (s
->condexec_mask
)
8544 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8546 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8548 if (s
->condexec_mask
)
8549 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8551 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8553 tcg_temp_free_i32(tmp2
);
8554 store_reg(s
, rd
, tmp
);
8556 /* shift immediate */
8557 rm
= (insn
>> 3) & 7;
8558 shift
= (insn
>> 6) & 0x1f;
8559 tmp
= load_reg(s
, rm
);
8560 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
8561 if (!s
->condexec_mask
)
8563 store_reg(s
, rd
, tmp
);
8567 /* arithmetic large immediate */
8568 op
= (insn
>> 11) & 3;
8569 rd
= (insn
>> 8) & 0x7;
8570 if (op
== 0) { /* mov */
8571 tmp
= tcg_temp_new_i32();
8572 tcg_gen_movi_i32(tmp
, insn
& 0xff);
8573 if (!s
->condexec_mask
)
8575 store_reg(s
, rd
, tmp
);
8577 tmp
= load_reg(s
, rd
);
8578 tmp2
= tcg_temp_new_i32();
8579 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
8582 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8583 tcg_temp_free_i32(tmp
);
8584 tcg_temp_free_i32(tmp2
);
8587 if (s
->condexec_mask
)
8588 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8590 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8591 tcg_temp_free_i32(tmp2
);
8592 store_reg(s
, rd
, tmp
);
8595 if (s
->condexec_mask
)
8596 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8598 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8599 tcg_temp_free_i32(tmp2
);
8600 store_reg(s
, rd
, tmp
);
8606 if (insn
& (1 << 11)) {
8607 rd
= (insn
>> 8) & 7;
8608 /* load pc-relative. Bit 1 of PC is ignored. */
8609 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
8610 val
&= ~(uint32_t)2;
8611 addr
= tcg_temp_new_i32();
8612 tcg_gen_movi_i32(addr
, val
);
8613 tmp
= gen_ld32(addr
, IS_USER(s
));
8614 tcg_temp_free_i32(addr
);
8615 store_reg(s
, rd
, tmp
);
8618 if (insn
& (1 << 10)) {
8619 /* data processing extended or blx */
8620 rd
= (insn
& 7) | ((insn
>> 4) & 8);
8621 rm
= (insn
>> 3) & 0xf;
8622 op
= (insn
>> 8) & 3;
8625 tmp
= load_reg(s
, rd
);
8626 tmp2
= load_reg(s
, rm
);
8627 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8628 tcg_temp_free_i32(tmp2
);
8629 store_reg(s
, rd
, tmp
);
8632 tmp
= load_reg(s
, rd
);
8633 tmp2
= load_reg(s
, rm
);
8634 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8635 tcg_temp_free_i32(tmp2
);
8636 tcg_temp_free_i32(tmp
);
8638 case 2: /* mov/cpy */
8639 tmp
= load_reg(s
, rm
);
8640 store_reg(s
, rd
, tmp
);
8642 case 3:/* branch [and link] exchange thumb register */
8643 tmp
= load_reg(s
, rm
);
8644 if (insn
& (1 << 7)) {
8645 val
= (uint32_t)s
->pc
| 1;
8646 tmp2
= tcg_temp_new_i32();
8647 tcg_gen_movi_i32(tmp2
, val
);
8648 store_reg(s
, 14, tmp2
);
8656 /* data processing register */
8658 rm
= (insn
>> 3) & 7;
8659 op
= (insn
>> 6) & 0xf;
8660 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
8661 /* the shift/rotate ops want the operands backwards */
8670 if (op
== 9) { /* neg */
8671 tmp
= tcg_temp_new_i32();
8672 tcg_gen_movi_i32(tmp
, 0);
8673 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
8674 tmp
= load_reg(s
, rd
);
8679 tmp2
= load_reg(s
, rm
);
8682 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8683 if (!s
->condexec_mask
)
8687 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8688 if (!s
->condexec_mask
)
8692 if (s
->condexec_mask
) {
8693 gen_helper_shl(tmp2
, tmp2
, tmp
);
8695 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
8700 if (s
->condexec_mask
) {
8701 gen_helper_shr(tmp2
, tmp2
, tmp
);
8703 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
8708 if (s
->condexec_mask
) {
8709 gen_helper_sar(tmp2
, tmp2
, tmp
);
8711 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
8716 if (s
->condexec_mask
)
8719 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
8722 if (s
->condexec_mask
)
8723 gen_sub_carry(tmp
, tmp
, tmp2
);
8725 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
8728 if (s
->condexec_mask
) {
8729 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
8730 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
8732 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
8737 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8742 if (s
->condexec_mask
)
8743 tcg_gen_neg_i32(tmp
, tmp2
);
8745 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8748 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8752 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8756 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8757 if (!s
->condexec_mask
)
8761 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8762 if (!s
->condexec_mask
)
8766 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8767 if (!s
->condexec_mask
)
8771 tcg_gen_not_i32(tmp2
, tmp2
);
8772 if (!s
->condexec_mask
)
8780 store_reg(s
, rm
, tmp2
);
8782 tcg_temp_free_i32(tmp
);
8784 store_reg(s
, rd
, tmp
);
8785 tcg_temp_free_i32(tmp2
);
8788 tcg_temp_free_i32(tmp
);
8789 tcg_temp_free_i32(tmp2
);
8794 /* load/store register offset. */
8796 rn
= (insn
>> 3) & 7;
8797 rm
= (insn
>> 6) & 7;
8798 op
= (insn
>> 9) & 7;
8799 addr
= load_reg(s
, rn
);
8800 tmp
= load_reg(s
, rm
);
8801 tcg_gen_add_i32(addr
, addr
, tmp
);
8802 tcg_temp_free_i32(tmp
);
8804 if (op
< 3) /* store */
8805 tmp
= load_reg(s
, rd
);
8809 gen_st32(tmp
, addr
, IS_USER(s
));
8812 gen_st16(tmp
, addr
, IS_USER(s
));
8815 gen_st8(tmp
, addr
, IS_USER(s
));
8818 tmp
= gen_ld8s(addr
, IS_USER(s
));
8821 tmp
= gen_ld32(addr
, IS_USER(s
));
8824 tmp
= gen_ld16u(addr
, IS_USER(s
));
8827 tmp
= gen_ld8u(addr
, IS_USER(s
));
8830 tmp
= gen_ld16s(addr
, IS_USER(s
));
8833 if (op
>= 3) /* load */
8834 store_reg(s
, rd
, tmp
);
8835 tcg_temp_free_i32(addr
);
8839 /* load/store word immediate offset */
8841 rn
= (insn
>> 3) & 7;
8842 addr
= load_reg(s
, rn
);
8843 val
= (insn
>> 4) & 0x7c;
8844 tcg_gen_addi_i32(addr
, addr
, val
);
8846 if (insn
& (1 << 11)) {
8848 tmp
= gen_ld32(addr
, IS_USER(s
));
8849 store_reg(s
, rd
, tmp
);
8852 tmp
= load_reg(s
, rd
);
8853 gen_st32(tmp
, addr
, IS_USER(s
));
8855 tcg_temp_free_i32(addr
);
8859 /* load/store byte immediate offset */
8861 rn
= (insn
>> 3) & 7;
8862 addr
= load_reg(s
, rn
);
8863 val
= (insn
>> 6) & 0x1f;
8864 tcg_gen_addi_i32(addr
, addr
, val
);
8866 if (insn
& (1 << 11)) {
8868 tmp
= gen_ld8u(addr
, IS_USER(s
));
8869 store_reg(s
, rd
, tmp
);
8872 tmp
= load_reg(s
, rd
);
8873 gen_st8(tmp
, addr
, IS_USER(s
));
8875 tcg_temp_free_i32(addr
);
8879 /* load/store halfword immediate offset */
8881 rn
= (insn
>> 3) & 7;
8882 addr
= load_reg(s
, rn
);
8883 val
= (insn
>> 5) & 0x3e;
8884 tcg_gen_addi_i32(addr
, addr
, val
);
8886 if (insn
& (1 << 11)) {
8888 tmp
= gen_ld16u(addr
, IS_USER(s
));
8889 store_reg(s
, rd
, tmp
);
8892 tmp
= load_reg(s
, rd
);
8893 gen_st16(tmp
, addr
, IS_USER(s
));
8895 tcg_temp_free_i32(addr
);
8899 /* load/store from stack */
8900 rd
= (insn
>> 8) & 7;
8901 addr
= load_reg(s
, 13);
8902 val
= (insn
& 0xff) * 4;
8903 tcg_gen_addi_i32(addr
, addr
, val
);
8905 if (insn
& (1 << 11)) {
8907 tmp
= gen_ld32(addr
, IS_USER(s
));
8908 store_reg(s
, rd
, tmp
);
8911 tmp
= load_reg(s
, rd
);
8912 gen_st32(tmp
, addr
, IS_USER(s
));
8914 tcg_temp_free_i32(addr
);
8918 /* add to high reg */
8919 rd
= (insn
>> 8) & 7;
8920 if (insn
& (1 << 11)) {
8922 tmp
= load_reg(s
, 13);
8924 /* PC. bit 1 is ignored. */
8925 tmp
= tcg_temp_new_i32();
8926 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
8928 val
= (insn
& 0xff) * 4;
8929 tcg_gen_addi_i32(tmp
, tmp
, val
);
8930 store_reg(s
, rd
, tmp
);
8935 op
= (insn
>> 8) & 0xf;
8938 /* adjust stack pointer */
8939 tmp
= load_reg(s
, 13);
8940 val
= (insn
& 0x7f) * 4;
8941 if (insn
& (1 << 7))
8942 val
= -(int32_t)val
;
8943 tcg_gen_addi_i32(tmp
, tmp
, val
);
8944 store_reg(s
, 13, tmp
);
8947 case 2: /* sign/zero extend. */
8950 rm
= (insn
>> 3) & 7;
8951 tmp
= load_reg(s
, rm
);
8952 switch ((insn
>> 6) & 3) {
8953 case 0: gen_sxth(tmp
); break;
8954 case 1: gen_sxtb(tmp
); break;
8955 case 2: gen_uxth(tmp
); break;
8956 case 3: gen_uxtb(tmp
); break;
8958 store_reg(s
, rd
, tmp
);
8960 case 4: case 5: case 0xc: case 0xd:
8962 addr
= load_reg(s
, 13);
8963 if (insn
& (1 << 8))
8967 for (i
= 0; i
< 8; i
++) {
8968 if (insn
& (1 << i
))
8971 if ((insn
& (1 << 11)) == 0) {
8972 tcg_gen_addi_i32(addr
, addr
, -offset
);
8974 for (i
= 0; i
< 8; i
++) {
8975 if (insn
& (1 << i
)) {
8976 if (insn
& (1 << 11)) {
8978 tmp
= gen_ld32(addr
, IS_USER(s
));
8979 store_reg(s
, i
, tmp
);
8982 tmp
= load_reg(s
, i
);
8983 gen_st32(tmp
, addr
, IS_USER(s
));
8985 /* advance to the next address. */
8986 tcg_gen_addi_i32(addr
, addr
, 4);
8990 if (insn
& (1 << 8)) {
8991 if (insn
& (1 << 11)) {
8993 tmp
= gen_ld32(addr
, IS_USER(s
));
8994 /* don't set the pc until the rest of the instruction
8998 tmp
= load_reg(s
, 14);
8999 gen_st32(tmp
, addr
, IS_USER(s
));
9001 tcg_gen_addi_i32(addr
, addr
, 4);
9003 if ((insn
& (1 << 11)) == 0) {
9004 tcg_gen_addi_i32(addr
, addr
, -offset
);
9006 /* write back the new stack pointer */
9007 store_reg(s
, 13, addr
);
9008 /* set the new PC value */
9009 if ((insn
& 0x0900) == 0x0900)
9013 case 1: case 3: case 9: case 11: /* czb */
9015 tmp
= load_reg(s
, rm
);
9016 s
->condlabel
= gen_new_label();
9018 if (insn
& (1 << 11))
9019 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9021 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9022 tcg_temp_free_i32(tmp
);
9023 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9024 val
= (uint32_t)s
->pc
+ 2;
9029 case 15: /* IT, nop-hint. */
9030 if ((insn
& 0xf) == 0) {
9031 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9035 s
->condexec_cond
= (insn
>> 4) & 0xe;
9036 s
->condexec_mask
= insn
& 0x1f;
9037 /* No actual code generated for this insn, just setup state. */
9040 case 0xe: /* bkpt */
9041 gen_exception_insn(s
, 2, EXCP_BKPT
);
9046 rn
= (insn
>> 3) & 0x7;
9048 tmp
= load_reg(s
, rn
);
9049 switch ((insn
>> 6) & 3) {
9050 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9051 case 1: gen_rev16(tmp
); break;
9052 case 3: gen_revsh(tmp
); break;
9053 default: goto illegal_op
;
9055 store_reg(s
, rd
, tmp
);
9063 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9066 addr
= tcg_const_i32(16);
9067 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9068 tcg_temp_free_i32(addr
);
9072 addr
= tcg_const_i32(17);
9073 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9074 tcg_temp_free_i32(addr
);
9076 tcg_temp_free_i32(tmp
);
9079 if (insn
& (1 << 4))
9080 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9083 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9093 /* load/store multiple */
9094 rn
= (insn
>> 8) & 0x7;
9095 addr
= load_reg(s
, rn
);
9096 for (i
= 0; i
< 8; i
++) {
9097 if (insn
& (1 << i
)) {
9098 if (insn
& (1 << 11)) {
9100 tmp
= gen_ld32(addr
, IS_USER(s
));
9101 store_reg(s
, i
, tmp
);
9104 tmp
= load_reg(s
, i
);
9105 gen_st32(tmp
, addr
, IS_USER(s
));
9107 /* advance to the next address */
9108 tcg_gen_addi_i32(addr
, addr
, 4);
9111 /* Base register writeback. */
9112 if ((insn
& (1 << rn
)) == 0) {
9113 store_reg(s
, rn
, addr
);
9115 tcg_temp_free_i32(addr
);
9120 /* conditional branch or swi */
9121 cond
= (insn
>> 8) & 0xf;
9127 gen_set_pc_im(s
->pc
);
9128 s
->is_jmp
= DISAS_SWI
;
9131 /* generate a conditional jump to next instruction */
9132 s
->condlabel
= gen_new_label();
9133 gen_test_cc(cond
^ 1, s
->condlabel
);
9136 /* jump to the offset */
9137 val
= (uint32_t)s
->pc
+ 2;
9138 offset
= ((int32_t)insn
<< 24) >> 24;
9144 if (insn
& (1 << 11)) {
9145 if (disas_thumb2_insn(env
, s
, insn
))
9149 /* unconditional branch */
9150 val
= (uint32_t)s
->pc
;
9151 offset
= ((int32_t)insn
<< 21) >> 21;
9152 val
+= (offset
<< 1) + 2;
9157 if (disas_thumb2_insn(env
, s
, insn
))
9163 gen_exception_insn(s
, 4, EXCP_UDEF
);
9167 gen_exception_insn(s
, 2, EXCP_UDEF
);
9170 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9171 basic block 'tb'. If search_pc is TRUE, also generate PC
9172 information for each intermediate instruction. */
9173 static inline void gen_intermediate_code_internal(CPUState
*env
,
9174 TranslationBlock
*tb
,
9177 DisasContext dc1
, *dc
= &dc1
;
9179 uint16_t *gen_opc_end
;
9181 target_ulong pc_start
;
9182 uint32_t next_page_start
;
9186 /* generate intermediate code */
9191 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9193 dc
->is_jmp
= DISAS_NEXT
;
9195 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9197 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9198 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9199 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9200 #if !defined(CONFIG_USER_ONLY)
9201 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9203 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9204 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9205 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9206 cpu_F0s
= tcg_temp_new_i32();
9207 cpu_F1s
= tcg_temp_new_i32();
9208 cpu_F0d
= tcg_temp_new_i64();
9209 cpu_F1d
= tcg_temp_new_i64();
9212 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9213 cpu_M0
= tcg_temp_new_i64();
9214 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9217 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9219 max_insns
= CF_COUNT_MASK
;
9223 tcg_clear_temp_count();
9225 /* A note on handling of the condexec (IT) bits:
9227 * We want to avoid the overhead of having to write the updated condexec
9228 * bits back to the CPUState for every instruction in an IT block. So:
9229 * (1) if the condexec bits are not already zero then we write
9230 * zero back into the CPUState now. This avoids complications trying
9231 * to do it at the end of the block. (For example if we don't do this
9232 * it's hard to identify whether we can safely skip writing condexec
9233 * at the end of the TB, which we definitely want to do for the case
9234 * where a TB doesn't do anything with the IT state at all.)
9235 * (2) if we are going to leave the TB then we call gen_set_condexec()
9236 * which will write the correct value into CPUState if zero is wrong.
9237 * This is done both for leaving the TB at the end, and for leaving
9238 * it because of an exception we know will happen, which is done in
9239 * gen_exception_insn(). The latter is necessary because we need to
9240 * leave the TB with the PC/IT state just prior to execution of the
9241 * instruction which caused the exception.
9242 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9243 * then the CPUState will be wrong and we need to reset it.
9244 * This is handled in the same way as restoration of the
9245 * PC in these situations: we will be called again with search_pc=1
9246 * and generate a mapping of the condexec bits for each PC in
9247 * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9248 * the condexec bits.
9250 * Note that there are no instructions which can read the condexec
9251 * bits, and none which can write non-static values to them, so
9252 * we don't need to care about whether CPUState is correct in the
9256 /* Reset the conditional execution bits immediately. This avoids
9257 complications trying to do it at the end of the block. */
9258 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9260 TCGv tmp
= tcg_temp_new_i32();
9261 tcg_gen_movi_i32(tmp
, 0);
9262 store_cpu_field(tmp
, condexec_bits
);
9265 #ifdef CONFIG_USER_ONLY
9266 /* Intercept jump to the magic kernel page. */
9267 if (dc
->pc
>= 0xffff0000) {
9268 /* We always get here via a jump, so know we are not in a
9269 conditional execution block. */
9270 gen_exception(EXCP_KERNEL_TRAP
);
9271 dc
->is_jmp
= DISAS_UPDATE
;
9275 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9276 /* We always get here via a jump, so know we are not in a
9277 conditional execution block. */
9278 gen_exception(EXCP_EXCEPTION_EXIT
);
9279 dc
->is_jmp
= DISAS_UPDATE
;
9284 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9285 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9286 if (bp
->pc
== dc
->pc
) {
9287 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9288 /* Advance PC so that clearing the breakpoint will
9289 invalidate this TB. */
9291 goto done_generating
;
9297 j
= gen_opc_ptr
- gen_opc_buf
;
9301 gen_opc_instr_start
[lj
++] = 0;
9303 gen_opc_pc
[lj
] = dc
->pc
;
9304 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9305 gen_opc_instr_start
[lj
] = 1;
9306 gen_opc_icount
[lj
] = num_insns
;
9309 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9312 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9313 tcg_gen_debug_insn_start(dc
->pc
);
9317 disas_thumb_insn(env
, dc
);
9318 if (dc
->condexec_mask
) {
9319 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9320 | ((dc
->condexec_mask
>> 4) & 1);
9321 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9322 if (dc
->condexec_mask
== 0) {
9323 dc
->condexec_cond
= 0;
9327 disas_arm_insn(env
, dc
);
9330 if (dc
->condjmp
&& !dc
->is_jmp
) {
9331 gen_set_label(dc
->condlabel
);
9335 if (tcg_check_temp_count()) {
9336 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9339 /* Translation stops when a conditional branch is encountered.
9340 * Otherwise the subsequent code could get translated several times.
9341 * Also stop translation when a page boundary is reached. This
9342 * ensures prefetch aborts occur at the right place. */
9344 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9345 !env
->singlestep_enabled
&&
9347 dc
->pc
< next_page_start
&&
9348 num_insns
< max_insns
);
9350 if (tb
->cflags
& CF_LAST_IO
) {
9352 /* FIXME: This can theoretically happen with self-modifying
9354 cpu_abort(env
, "IO on conditional branch instruction");
9359 /* At this stage dc->condjmp will only be set when the skipped
9360 instruction was a conditional branch or trap, and the PC has
9361 already been written. */
9362 if (unlikely(env
->singlestep_enabled
)) {
9363 /* Make sure the pc is updated, and raise a debug exception. */
9365 gen_set_condexec(dc
);
9366 if (dc
->is_jmp
== DISAS_SWI
) {
9367 gen_exception(EXCP_SWI
);
9369 gen_exception(EXCP_DEBUG
);
9371 gen_set_label(dc
->condlabel
);
9373 if (dc
->condjmp
|| !dc
->is_jmp
) {
9374 gen_set_pc_im(dc
->pc
);
9377 gen_set_condexec(dc
);
9378 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9379 gen_exception(EXCP_SWI
);
9381 /* FIXME: Single stepping a WFI insn will not halt
9383 gen_exception(EXCP_DEBUG
);
9386 /* While branches must always occur at the end of an IT block,
9387 there are a few other things that can cause us to terminate
9388 the TB in the middel of an IT block:
9389 - Exception generating instructions (bkpt, swi, undefined).
9391 - Hardware watchpoints.
9392 Hardware breakpoints have already been handled and skip this code.
9394 gen_set_condexec(dc
);
9395 switch(dc
->is_jmp
) {
9397 gen_goto_tb(dc
, 1, dc
->pc
);
9402 /* indicate that the hash table must be used to find the next TB */
9406 /* nothing more to generate */
9412 gen_exception(EXCP_SWI
);
9416 gen_set_label(dc
->condlabel
);
9417 gen_set_condexec(dc
);
9418 gen_goto_tb(dc
, 1, dc
->pc
);
9424 gen_icount_end(tb
, num_insns
);
9425 *gen_opc_ptr
= INDEX_op_end
;
9428 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9429 qemu_log("----------------\n");
9430 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9431 log_target_disas(pc_start
, dc
->pc
- pc_start
, dc
->thumb
);
9436 j
= gen_opc_ptr
- gen_opc_buf
;
9439 gen_opc_instr_start
[lj
++] = 0;
9441 tb
->size
= dc
->pc
- pc_start
;
9442 tb
->icount
= num_insns
;
9446 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9448 gen_intermediate_code_internal(env
, tb
, 0);
9451 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9453 gen_intermediate_code_internal(env
, tb
, 1);
9456 static const char *cpu_mode_names
[16] = {
9457 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9458 "???", "???", "???", "und", "???", "???", "???", "sys"
9461 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
9471 /* ??? This assumes float64 and double have the same layout.
9472 Oh well, it's only debug dumps. */
9481 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9483 cpu_fprintf(f
, "\n");
9485 cpu_fprintf(f
, " ");
9487 psr
= cpsr_read(env
);
9488 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9490 psr
& (1 << 31) ? 'N' : '-',
9491 psr
& (1 << 30) ? 'Z' : '-',
9492 psr
& (1 << 29) ? 'C' : '-',
9493 psr
& (1 << 28) ? 'V' : '-',
9494 psr
& CPSR_T
? 'T' : 'A',
9495 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9498 for (i
= 0; i
< 16; i
++) {
9499 d
.d
= env
->vfp
.regs
[i
];
9503 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9504 i
* 2, (int)s0
.i
, s0
.s
,
9505 i
* 2 + 1, (int)s1
.i
, s1
.s
,
9506 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
9509 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
9513 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
9514 unsigned long searched_pc
, int pc_pos
, void *puc
)
9516 env
->regs
[15] = gen_opc_pc
[pc_pos
];
9517 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];