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/>.
36 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
37 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
38 /* currently all emulated v5 cores are also v5TE, so don't bother */
39 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
40 #define ENABLE_ARCH_5J 0
41 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
42 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
43 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
44 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
48 /* internal defines */
49 typedef struct DisasContext
{
52 /* Nonzero if this instruction has been conditionally skipped. */
54 /* The label that will be jumped to when the instruction is skipped. */
56 /* Thumb-2 condtional execution bits. */
59 struct TranslationBlock
*tb
;
60 int singlestep_enabled
;
63 #if !defined(CONFIG_USER_ONLY)
71 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
73 #if defined(CONFIG_USER_ONLY)
76 #define IS_USER(s) (s->user)
79 /* These instructions trap after executing, so defer them until after the
80 conditional executions state has been updated. */
84 static TCGv_ptr cpu_env
;
85 /* We reuse the same 64-bit temporaries for efficiency. */
86 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
87 static TCGv_i32 cpu_R
[16];
88 static TCGv_i32 cpu_exclusive_addr
;
89 static TCGv_i32 cpu_exclusive_val
;
90 static TCGv_i32 cpu_exclusive_high
;
91 #ifdef CONFIG_USER_ONLY
92 static TCGv_i32 cpu_exclusive_test
;
93 static TCGv_i32 cpu_exclusive_info
;
96 /* FIXME: These should be removed. */
97 static TCGv cpu_F0s
, cpu_F1s
;
98 static TCGv_i64 cpu_F0d
, cpu_F1d
;
100 #include "gen-icount.h"
102 static const char *regnames
[] =
103 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
104 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
106 /* initialize TCG globals. */
107 void arm_translate_init(void)
111 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
113 for (i
= 0; i
< 16; i
++) {
114 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
115 offsetof(CPUARMState
, regs
[i
]),
118 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
119 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
120 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
121 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
122 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
123 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
124 #ifdef CONFIG_USER_ONLY
125 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
126 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
127 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
128 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
135 static inline TCGv
load_cpu_offset(int offset
)
137 TCGv tmp
= tcg_temp_new_i32();
138 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
142 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
144 static inline void store_cpu_offset(TCGv var
, int offset
)
146 tcg_gen_st_i32(var
, cpu_env
, offset
);
147 tcg_temp_free_i32(var
);
150 #define store_cpu_field(var, name) \
151 store_cpu_offset(var, offsetof(CPUARMState, name))
153 /* Set a variable to the value of a CPU register. */
154 static void load_reg_var(DisasContext
*s
, TCGv var
, int reg
)
158 /* normaly, since we updated PC, we need only to add one insn */
160 addr
= (long)s
->pc
+ 2;
162 addr
= (long)s
->pc
+ 4;
163 tcg_gen_movi_i32(var
, addr
);
165 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
169 /* Create a new temporary and set it to the value of a CPU register. */
170 static inline TCGv
load_reg(DisasContext
*s
, int reg
)
172 TCGv tmp
= tcg_temp_new_i32();
173 load_reg_var(s
, tmp
, reg
);
177 /* Set a CPU register. The source must be a temporary and will be
179 static void store_reg(DisasContext
*s
, int reg
, TCGv var
)
182 tcg_gen_andi_i32(var
, var
, ~1);
183 s
->is_jmp
= DISAS_JUMP
;
185 tcg_gen_mov_i32(cpu_R
[reg
], var
);
186 tcg_temp_free_i32(var
);
189 /* Value extensions. */
190 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
191 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
192 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
193 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
195 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
196 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
199 static inline void gen_set_cpsr(TCGv var
, uint32_t mask
)
201 TCGv tmp_mask
= tcg_const_i32(mask
);
202 gen_helper_cpsr_write(var
, tmp_mask
);
203 tcg_temp_free_i32(tmp_mask
);
205 /* Set NZCV flags from the high 4 bits of var. */
206 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
208 static void gen_exception(int excp
)
210 TCGv tmp
= tcg_temp_new_i32();
211 tcg_gen_movi_i32(tmp
, excp
);
212 gen_helper_exception(tmp
);
213 tcg_temp_free_i32(tmp
);
216 static void gen_smul_dual(TCGv a
, TCGv b
)
218 TCGv tmp1
= tcg_temp_new_i32();
219 TCGv tmp2
= tcg_temp_new_i32();
220 tcg_gen_ext16s_i32(tmp1
, a
);
221 tcg_gen_ext16s_i32(tmp2
, b
);
222 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
223 tcg_temp_free_i32(tmp2
);
224 tcg_gen_sari_i32(a
, a
, 16);
225 tcg_gen_sari_i32(b
, b
, 16);
226 tcg_gen_mul_i32(b
, b
, a
);
227 tcg_gen_mov_i32(a
, tmp1
);
228 tcg_temp_free_i32(tmp1
);
231 /* Byteswap each halfword. */
232 static void gen_rev16(TCGv var
)
234 TCGv tmp
= tcg_temp_new_i32();
235 tcg_gen_shri_i32(tmp
, var
, 8);
236 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
237 tcg_gen_shli_i32(var
, var
, 8);
238 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
239 tcg_gen_or_i32(var
, var
, tmp
);
240 tcg_temp_free_i32(tmp
);
243 /* Byteswap low halfword and sign extend. */
244 static void gen_revsh(TCGv var
)
246 tcg_gen_ext16u_i32(var
, var
);
247 tcg_gen_bswap16_i32(var
, var
);
248 tcg_gen_ext16s_i32(var
, var
);
251 /* Unsigned bitfield extract. */
252 static void gen_ubfx(TCGv var
, int shift
, uint32_t mask
)
255 tcg_gen_shri_i32(var
, var
, shift
);
256 tcg_gen_andi_i32(var
, var
, mask
);
259 /* Signed bitfield extract. */
260 static void gen_sbfx(TCGv var
, int shift
, int width
)
265 tcg_gen_sari_i32(var
, var
, shift
);
266 if (shift
+ width
< 32) {
267 signbit
= 1u << (width
- 1);
268 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
269 tcg_gen_xori_i32(var
, var
, signbit
);
270 tcg_gen_subi_i32(var
, var
, signbit
);
274 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
275 static void gen_bfi(TCGv dest
, TCGv base
, TCGv val
, int shift
, uint32_t mask
)
277 tcg_gen_andi_i32(val
, val
, mask
);
278 tcg_gen_shli_i32(val
, val
, shift
);
279 tcg_gen_andi_i32(base
, base
, ~(mask
<< shift
));
280 tcg_gen_or_i32(dest
, base
, val
);
283 /* Return (b << 32) + a. Mark inputs as dead */
284 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
286 TCGv_i64 tmp64
= tcg_temp_new_i64();
288 tcg_gen_extu_i32_i64(tmp64
, b
);
289 tcg_temp_free_i32(b
);
290 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
291 tcg_gen_add_i64(a
, tmp64
, a
);
293 tcg_temp_free_i64(tmp64
);
297 /* Return (b << 32) - a. Mark inputs as dead. */
298 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
300 TCGv_i64 tmp64
= tcg_temp_new_i64();
302 tcg_gen_extu_i32_i64(tmp64
, b
);
303 tcg_temp_free_i32(b
);
304 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
305 tcg_gen_sub_i64(a
, tmp64
, a
);
307 tcg_temp_free_i64(tmp64
);
311 /* FIXME: Most targets have native widening multiplication.
312 It would be good to use that instead of a full wide multiply. */
313 /* 32x32->64 multiply. Marks inputs as dead. */
314 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
316 TCGv_i64 tmp1
= tcg_temp_new_i64();
317 TCGv_i64 tmp2
= tcg_temp_new_i64();
319 tcg_gen_extu_i32_i64(tmp1
, a
);
320 tcg_temp_free_i32(a
);
321 tcg_gen_extu_i32_i64(tmp2
, b
);
322 tcg_temp_free_i32(b
);
323 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
324 tcg_temp_free_i64(tmp2
);
328 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
330 TCGv_i64 tmp1
= tcg_temp_new_i64();
331 TCGv_i64 tmp2
= tcg_temp_new_i64();
333 tcg_gen_ext_i32_i64(tmp1
, a
);
334 tcg_temp_free_i32(a
);
335 tcg_gen_ext_i32_i64(tmp2
, b
);
336 tcg_temp_free_i32(b
);
337 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
338 tcg_temp_free_i64(tmp2
);
342 /* Swap low and high halfwords. */
343 static void gen_swap_half(TCGv var
)
345 TCGv tmp
= tcg_temp_new_i32();
346 tcg_gen_shri_i32(tmp
, var
, 16);
347 tcg_gen_shli_i32(var
, var
, 16);
348 tcg_gen_or_i32(var
, var
, tmp
);
349 tcg_temp_free_i32(tmp
);
352 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
353 tmp = (t0 ^ t1) & 0x8000;
356 t0 = (t0 + t1) ^ tmp;
359 static void gen_add16(TCGv t0
, TCGv t1
)
361 TCGv tmp
= tcg_temp_new_i32();
362 tcg_gen_xor_i32(tmp
, t0
, t1
);
363 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
364 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
365 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
366 tcg_gen_add_i32(t0
, t0
, t1
);
367 tcg_gen_xor_i32(t0
, t0
, tmp
);
368 tcg_temp_free_i32(tmp
);
369 tcg_temp_free_i32(t1
);
372 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, CF))
374 /* Set CF to the top bit of var. */
375 static void gen_set_CF_bit31(TCGv var
)
377 TCGv tmp
= tcg_temp_new_i32();
378 tcg_gen_shri_i32(tmp
, var
, 31);
380 tcg_temp_free_i32(tmp
);
383 /* Set N and Z flags from var. */
384 static inline void gen_logic_CC(TCGv var
)
386 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, NF
));
387 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, ZF
));
391 static void gen_adc(TCGv t0
, TCGv t1
)
394 tcg_gen_add_i32(t0
, t0
, t1
);
395 tmp
= load_cpu_field(CF
);
396 tcg_gen_add_i32(t0
, t0
, tmp
);
397 tcg_temp_free_i32(tmp
);
400 /* dest = T0 + T1 + CF. */
401 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
404 tcg_gen_add_i32(dest
, t0
, t1
);
405 tmp
= load_cpu_field(CF
);
406 tcg_gen_add_i32(dest
, dest
, tmp
);
407 tcg_temp_free_i32(tmp
);
410 /* dest = T0 - T1 + CF - 1. */
411 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
414 tcg_gen_sub_i32(dest
, t0
, t1
);
415 tmp
= load_cpu_field(CF
);
416 tcg_gen_add_i32(dest
, dest
, tmp
);
417 tcg_gen_subi_i32(dest
, dest
, 1);
418 tcg_temp_free_i32(tmp
);
421 /* FIXME: Implement this natively. */
422 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
424 static void shifter_out_im(TCGv var
, int shift
)
426 TCGv tmp
= tcg_temp_new_i32();
428 tcg_gen_andi_i32(tmp
, var
, 1);
430 tcg_gen_shri_i32(tmp
, var
, shift
);
432 tcg_gen_andi_i32(tmp
, tmp
, 1);
435 tcg_temp_free_i32(tmp
);
438 /* Shift by immediate. Includes special handling for shift == 0. */
439 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
445 shifter_out_im(var
, 32 - shift
);
446 tcg_gen_shli_i32(var
, var
, shift
);
452 tcg_gen_shri_i32(var
, var
, 31);
455 tcg_gen_movi_i32(var
, 0);
458 shifter_out_im(var
, shift
- 1);
459 tcg_gen_shri_i32(var
, var
, shift
);
466 shifter_out_im(var
, shift
- 1);
469 tcg_gen_sari_i32(var
, var
, shift
);
471 case 3: /* ROR/RRX */
474 shifter_out_im(var
, shift
- 1);
475 tcg_gen_rotri_i32(var
, var
, shift
); break;
477 TCGv tmp
= load_cpu_field(CF
);
479 shifter_out_im(var
, 0);
480 tcg_gen_shri_i32(var
, var
, 1);
481 tcg_gen_shli_i32(tmp
, tmp
, 31);
482 tcg_gen_or_i32(var
, var
, tmp
);
483 tcg_temp_free_i32(tmp
);
488 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
489 TCGv shift
, int flags
)
493 case 0: gen_helper_shl_cc(var
, var
, shift
); break;
494 case 1: gen_helper_shr_cc(var
, var
, shift
); break;
495 case 2: gen_helper_sar_cc(var
, var
, shift
); break;
496 case 3: gen_helper_ror_cc(var
, var
, shift
); break;
500 case 0: gen_helper_shl(var
, var
, shift
); break;
501 case 1: gen_helper_shr(var
, var
, shift
); break;
502 case 2: gen_helper_sar(var
, var
, shift
); break;
503 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
504 tcg_gen_rotr_i32(var
, var
, shift
); break;
507 tcg_temp_free_i32(shift
);
510 #define PAS_OP(pfx) \
512 case 0: gen_pas_helper(glue(pfx,add16)); break; \
513 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
514 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
515 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
516 case 4: gen_pas_helper(glue(pfx,add8)); break; \
517 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
519 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
524 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
526 tmp
= tcg_temp_new_ptr();
527 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
529 tcg_temp_free_ptr(tmp
);
532 tmp
= tcg_temp_new_ptr();
533 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
535 tcg_temp_free_ptr(tmp
);
537 #undef gen_pas_helper
538 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
551 #undef gen_pas_helper
556 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
557 #define PAS_OP(pfx) \
559 case 0: gen_pas_helper(glue(pfx,add8)); break; \
560 case 1: gen_pas_helper(glue(pfx,add16)); break; \
561 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
562 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
563 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
564 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
566 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
571 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
573 tmp
= tcg_temp_new_ptr();
574 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
576 tcg_temp_free_ptr(tmp
);
579 tmp
= tcg_temp_new_ptr();
580 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
582 tcg_temp_free_ptr(tmp
);
584 #undef gen_pas_helper
585 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
598 #undef gen_pas_helper
603 static void gen_test_cc(int cc
, int label
)
611 tmp
= load_cpu_field(ZF
);
612 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
615 tmp
= load_cpu_field(ZF
);
616 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
619 tmp
= load_cpu_field(CF
);
620 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
623 tmp
= load_cpu_field(CF
);
624 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
627 tmp
= load_cpu_field(NF
);
628 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
631 tmp
= load_cpu_field(NF
);
632 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
635 tmp
= load_cpu_field(VF
);
636 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
639 tmp
= load_cpu_field(VF
);
640 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
642 case 8: /* hi: C && !Z */
643 inv
= gen_new_label();
644 tmp
= load_cpu_field(CF
);
645 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
646 tcg_temp_free_i32(tmp
);
647 tmp
= load_cpu_field(ZF
);
648 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
651 case 9: /* ls: !C || Z */
652 tmp
= load_cpu_field(CF
);
653 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
654 tcg_temp_free_i32(tmp
);
655 tmp
= load_cpu_field(ZF
);
656 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
658 case 10: /* ge: N == V -> N ^ V == 0 */
659 tmp
= load_cpu_field(VF
);
660 tmp2
= load_cpu_field(NF
);
661 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
662 tcg_temp_free_i32(tmp2
);
663 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
665 case 11: /* lt: N != V -> N ^ V != 0 */
666 tmp
= load_cpu_field(VF
);
667 tmp2
= load_cpu_field(NF
);
668 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
669 tcg_temp_free_i32(tmp2
);
670 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
672 case 12: /* gt: !Z && N == V */
673 inv
= gen_new_label();
674 tmp
= load_cpu_field(ZF
);
675 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
676 tcg_temp_free_i32(tmp
);
677 tmp
= load_cpu_field(VF
);
678 tmp2
= load_cpu_field(NF
);
679 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
680 tcg_temp_free_i32(tmp2
);
681 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
684 case 13: /* le: Z || N != V */
685 tmp
= load_cpu_field(ZF
);
686 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
687 tcg_temp_free_i32(tmp
);
688 tmp
= load_cpu_field(VF
);
689 tmp2
= load_cpu_field(NF
);
690 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
691 tcg_temp_free_i32(tmp2
);
692 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
695 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
698 tcg_temp_free_i32(tmp
);
701 static const uint8_t table_logic_cc
[16] = {
720 /* Set PC and Thumb state from an immediate address. */
721 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
725 s
->is_jmp
= DISAS_UPDATE
;
726 if (s
->thumb
!= (addr
& 1)) {
727 tmp
= tcg_temp_new_i32();
728 tcg_gen_movi_i32(tmp
, addr
& 1);
729 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
730 tcg_temp_free_i32(tmp
);
732 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
735 /* Set PC and Thumb state from var. var is marked as dead. */
736 static inline void gen_bx(DisasContext
*s
, TCGv var
)
738 s
->is_jmp
= DISAS_UPDATE
;
739 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
740 tcg_gen_andi_i32(var
, var
, 1);
741 store_cpu_field(var
, thumb
);
744 /* Variant of store_reg which uses branch&exchange logic when storing
745 to r15 in ARM architecture v7 and above. The source must be a temporary
746 and will be marked as dead. */
747 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
750 if (reg
== 15 && ENABLE_ARCH_7
) {
753 store_reg(s
, reg
, var
);
757 /* Variant of store_reg which uses branch&exchange logic when storing
758 * to r15 in ARM architecture v5T and above. This is used for storing
759 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
760 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
761 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
764 if (reg
== 15 && ENABLE_ARCH_5
) {
767 store_reg(s
, reg
, var
);
771 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
773 TCGv tmp
= tcg_temp_new_i32();
774 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
777 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
779 TCGv tmp
= tcg_temp_new_i32();
780 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
783 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
785 TCGv tmp
= tcg_temp_new_i32();
786 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
789 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
791 TCGv tmp
= tcg_temp_new_i32();
792 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
795 static inline TCGv
gen_ld32(TCGv addr
, int index
)
797 TCGv tmp
= tcg_temp_new_i32();
798 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
801 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
803 TCGv_i64 tmp
= tcg_temp_new_i64();
804 tcg_gen_qemu_ld64(tmp
, addr
, index
);
807 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
809 tcg_gen_qemu_st8(val
, addr
, index
);
810 tcg_temp_free_i32(val
);
812 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
814 tcg_gen_qemu_st16(val
, addr
, index
);
815 tcg_temp_free_i32(val
);
817 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
819 tcg_gen_qemu_st32(val
, addr
, index
);
820 tcg_temp_free_i32(val
);
822 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
824 tcg_gen_qemu_st64(val
, addr
, index
);
825 tcg_temp_free_i64(val
);
828 static inline void gen_set_pc_im(uint32_t val
)
830 tcg_gen_movi_i32(cpu_R
[15], val
);
833 /* Force a TB lookup after an instruction that changes the CPU state. */
834 static inline void gen_lookup_tb(DisasContext
*s
)
836 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
837 s
->is_jmp
= DISAS_UPDATE
;
840 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
843 int val
, rm
, shift
, shiftop
;
846 if (!(insn
& (1 << 25))) {
849 if (!(insn
& (1 << 23)))
852 tcg_gen_addi_i32(var
, var
, val
);
856 shift
= (insn
>> 7) & 0x1f;
857 shiftop
= (insn
>> 5) & 3;
858 offset
= load_reg(s
, rm
);
859 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
860 if (!(insn
& (1 << 23)))
861 tcg_gen_sub_i32(var
, var
, offset
);
863 tcg_gen_add_i32(var
, var
, offset
);
864 tcg_temp_free_i32(offset
);
868 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
874 if (insn
& (1 << 22)) {
876 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
877 if (!(insn
& (1 << 23)))
881 tcg_gen_addi_i32(var
, var
, val
);
885 tcg_gen_addi_i32(var
, var
, extra
);
887 offset
= load_reg(s
, rm
);
888 if (!(insn
& (1 << 23)))
889 tcg_gen_sub_i32(var
, var
, offset
);
891 tcg_gen_add_i32(var
, var
, offset
);
892 tcg_temp_free_i32(offset
);
896 static TCGv_ptr
get_fpstatus_ptr(int neon
)
898 TCGv_ptr statusptr
= tcg_temp_new_ptr();
901 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
903 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
905 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
909 #define VFP_OP2(name) \
910 static inline void gen_vfp_##name(int dp) \
912 TCGv_ptr fpst = get_fpstatus_ptr(0); \
914 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
916 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
918 tcg_temp_free_ptr(fpst); \
928 static inline void gen_vfp_F1_mul(int dp
)
930 /* Like gen_vfp_mul() but put result in F1 */
931 TCGv_ptr fpst
= get_fpstatus_ptr(0);
933 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
935 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
937 tcg_temp_free_ptr(fpst
);
940 static inline void gen_vfp_F1_neg(int dp
)
942 /* Like gen_vfp_neg() but put result in F1 */
944 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
946 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
950 static inline void gen_vfp_abs(int dp
)
953 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
955 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
958 static inline void gen_vfp_neg(int dp
)
961 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
963 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
966 static inline void gen_vfp_sqrt(int dp
)
969 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
971 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
974 static inline void gen_vfp_cmp(int dp
)
977 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
979 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
982 static inline void gen_vfp_cmpe(int dp
)
985 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
987 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
990 static inline void gen_vfp_F1_ld0(int dp
)
993 tcg_gen_movi_i64(cpu_F1d
, 0);
995 tcg_gen_movi_i32(cpu_F1s
, 0);
998 #define VFP_GEN_ITOF(name) \
999 static inline void gen_vfp_##name(int dp, int neon) \
1001 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1003 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1005 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1007 tcg_temp_free_ptr(statusptr); \
1014 #define VFP_GEN_FTOI(name) \
1015 static inline void gen_vfp_##name(int dp, int neon) \
1017 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1019 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1021 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1023 tcg_temp_free_ptr(statusptr); \
1032 #define VFP_GEN_FIX(name) \
1033 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1035 TCGv tmp_shift = tcg_const_i32(shift); \
1036 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1038 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1040 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1042 tcg_temp_free_i32(tmp_shift); \
1043 tcg_temp_free_ptr(statusptr); \
1055 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1058 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1060 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1063 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1066 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1068 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1072 vfp_reg_offset (int dp
, int reg
)
1075 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1077 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1078 + offsetof(CPU_DoubleU
, l
.upper
);
1080 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1081 + offsetof(CPU_DoubleU
, l
.lower
);
1085 /* Return the offset of a 32-bit piece of a NEON register.
1086 zero is the least significant end of the register. */
1088 neon_reg_offset (int reg
, int n
)
1092 return vfp_reg_offset(0, sreg
);
1095 static TCGv
neon_load_reg(int reg
, int pass
)
1097 TCGv tmp
= tcg_temp_new_i32();
1098 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1102 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1104 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1105 tcg_temp_free_i32(var
);
1108 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1110 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1113 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1115 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1118 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1119 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1120 #define tcg_gen_st_f32 tcg_gen_st_i32
1121 #define tcg_gen_st_f64 tcg_gen_st_i64
1123 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1126 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1128 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1131 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1134 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1136 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1139 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1142 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1144 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1147 #define ARM_CP_RW_BIT (1 << 20)
1149 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1151 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1154 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1156 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1159 static inline TCGv
iwmmxt_load_creg(int reg
)
1161 TCGv var
= tcg_temp_new_i32();
1162 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1166 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1168 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1169 tcg_temp_free_i32(var
);
1172 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1174 iwmmxt_store_reg(cpu_M0
, rn
);
1177 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1179 iwmmxt_load_reg(cpu_M0
, rn
);
1182 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1184 iwmmxt_load_reg(cpu_V1
, rn
);
1185 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1188 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1190 iwmmxt_load_reg(cpu_V1
, rn
);
1191 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1194 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1196 iwmmxt_load_reg(cpu_V1
, rn
);
1197 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1200 #define IWMMXT_OP(name) \
1201 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1203 iwmmxt_load_reg(cpu_V1, rn); \
1204 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1207 #define IWMMXT_OP_ENV(name) \
1208 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1210 iwmmxt_load_reg(cpu_V1, rn); \
1211 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1214 #define IWMMXT_OP_ENV_SIZE(name) \
1215 IWMMXT_OP_ENV(name##b) \
1216 IWMMXT_OP_ENV(name##w) \
1217 IWMMXT_OP_ENV(name##l)
1219 #define IWMMXT_OP_ENV1(name) \
1220 static inline void gen_op_iwmmxt_##name##_M0(void) \
1222 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1236 IWMMXT_OP_ENV_SIZE(unpackl
)
1237 IWMMXT_OP_ENV_SIZE(unpackh
)
1239 IWMMXT_OP_ENV1(unpacklub
)
1240 IWMMXT_OP_ENV1(unpackluw
)
1241 IWMMXT_OP_ENV1(unpacklul
)
1242 IWMMXT_OP_ENV1(unpackhub
)
1243 IWMMXT_OP_ENV1(unpackhuw
)
1244 IWMMXT_OP_ENV1(unpackhul
)
1245 IWMMXT_OP_ENV1(unpacklsb
)
1246 IWMMXT_OP_ENV1(unpacklsw
)
1247 IWMMXT_OP_ENV1(unpacklsl
)
1248 IWMMXT_OP_ENV1(unpackhsb
)
1249 IWMMXT_OP_ENV1(unpackhsw
)
1250 IWMMXT_OP_ENV1(unpackhsl
)
1252 IWMMXT_OP_ENV_SIZE(cmpeq
)
1253 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1254 IWMMXT_OP_ENV_SIZE(cmpgts
)
1256 IWMMXT_OP_ENV_SIZE(mins
)
1257 IWMMXT_OP_ENV_SIZE(minu
)
1258 IWMMXT_OP_ENV_SIZE(maxs
)
1259 IWMMXT_OP_ENV_SIZE(maxu
)
1261 IWMMXT_OP_ENV_SIZE(subn
)
1262 IWMMXT_OP_ENV_SIZE(addn
)
1263 IWMMXT_OP_ENV_SIZE(subu
)
1264 IWMMXT_OP_ENV_SIZE(addu
)
1265 IWMMXT_OP_ENV_SIZE(subs
)
1266 IWMMXT_OP_ENV_SIZE(adds
)
1268 IWMMXT_OP_ENV(avgb0
)
1269 IWMMXT_OP_ENV(avgb1
)
1270 IWMMXT_OP_ENV(avgw0
)
1271 IWMMXT_OP_ENV(avgw1
)
1275 IWMMXT_OP_ENV(packuw
)
1276 IWMMXT_OP_ENV(packul
)
1277 IWMMXT_OP_ENV(packuq
)
1278 IWMMXT_OP_ENV(packsw
)
1279 IWMMXT_OP_ENV(packsl
)
1280 IWMMXT_OP_ENV(packsq
)
1282 static void gen_op_iwmmxt_set_mup(void)
1285 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1286 tcg_gen_ori_i32(tmp
, tmp
, 2);
1287 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1290 static void gen_op_iwmmxt_set_cup(void)
1293 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1294 tcg_gen_ori_i32(tmp
, tmp
, 1);
1295 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1298 static void gen_op_iwmmxt_setpsr_nz(void)
1300 TCGv tmp
= tcg_temp_new_i32();
1301 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1302 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1305 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1307 iwmmxt_load_reg(cpu_V1
, rn
);
1308 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1309 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1312 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1318 rd
= (insn
>> 16) & 0xf;
1319 tmp
= load_reg(s
, rd
);
1321 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1322 if (insn
& (1 << 24)) {
1324 if (insn
& (1 << 23))
1325 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1327 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1328 tcg_gen_mov_i32(dest
, tmp
);
1329 if (insn
& (1 << 21))
1330 store_reg(s
, rd
, tmp
);
1332 tcg_temp_free_i32(tmp
);
1333 } else if (insn
& (1 << 21)) {
1335 tcg_gen_mov_i32(dest
, tmp
);
1336 if (insn
& (1 << 23))
1337 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1339 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1340 store_reg(s
, rd
, tmp
);
1341 } else if (!(insn
& (1 << 23)))
1346 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1348 int rd
= (insn
>> 0) & 0xf;
1351 if (insn
& (1 << 8)) {
1352 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1355 tmp
= iwmmxt_load_creg(rd
);
1358 tmp
= tcg_temp_new_i32();
1359 iwmmxt_load_reg(cpu_V0
, rd
);
1360 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1362 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1363 tcg_gen_mov_i32(dest
, tmp
);
1364 tcg_temp_free_i32(tmp
);
1368 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1369 (ie. an undefined instruction). */
1370 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1373 int rdhi
, rdlo
, rd0
, rd1
, i
;
1375 TCGv tmp
, tmp2
, tmp3
;
1377 if ((insn
& 0x0e000e00) == 0x0c000000) {
1378 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1380 rdlo
= (insn
>> 12) & 0xf;
1381 rdhi
= (insn
>> 16) & 0xf;
1382 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1383 iwmmxt_load_reg(cpu_V0
, wrd
);
1384 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1385 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1386 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1387 } else { /* TMCRR */
1388 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1389 iwmmxt_store_reg(cpu_V0
, wrd
);
1390 gen_op_iwmmxt_set_mup();
1395 wrd
= (insn
>> 12) & 0xf;
1396 addr
= tcg_temp_new_i32();
1397 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1398 tcg_temp_free_i32(addr
);
1401 if (insn
& ARM_CP_RW_BIT
) {
1402 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1403 tmp
= tcg_temp_new_i32();
1404 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1405 iwmmxt_store_creg(wrd
, tmp
);
1408 if (insn
& (1 << 8)) {
1409 if (insn
& (1 << 22)) { /* WLDRD */
1410 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1412 } else { /* WLDRW wRd */
1413 tmp
= gen_ld32(addr
, IS_USER(s
));
1416 if (insn
& (1 << 22)) { /* WLDRH */
1417 tmp
= gen_ld16u(addr
, IS_USER(s
));
1418 } else { /* WLDRB */
1419 tmp
= gen_ld8u(addr
, IS_USER(s
));
1423 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1424 tcg_temp_free_i32(tmp
);
1426 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1429 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1430 tmp
= iwmmxt_load_creg(wrd
);
1431 gen_st32(tmp
, addr
, IS_USER(s
));
1433 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1434 tmp
= tcg_temp_new_i32();
1435 if (insn
& (1 << 8)) {
1436 if (insn
& (1 << 22)) { /* WSTRD */
1437 tcg_temp_free_i32(tmp
);
1438 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1439 } else { /* WSTRW wRd */
1440 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1441 gen_st32(tmp
, addr
, IS_USER(s
));
1444 if (insn
& (1 << 22)) { /* WSTRH */
1445 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1446 gen_st16(tmp
, addr
, IS_USER(s
));
1447 } else { /* WSTRB */
1448 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1449 gen_st8(tmp
, addr
, IS_USER(s
));
1454 tcg_temp_free_i32(addr
);
1458 if ((insn
& 0x0f000000) != 0x0e000000)
1461 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1462 case 0x000: /* WOR */
1463 wrd
= (insn
>> 12) & 0xf;
1464 rd0
= (insn
>> 0) & 0xf;
1465 rd1
= (insn
>> 16) & 0xf;
1466 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1467 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1468 gen_op_iwmmxt_setpsr_nz();
1469 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1470 gen_op_iwmmxt_set_mup();
1471 gen_op_iwmmxt_set_cup();
1473 case 0x011: /* TMCR */
1476 rd
= (insn
>> 12) & 0xf;
1477 wrd
= (insn
>> 16) & 0xf;
1479 case ARM_IWMMXT_wCID
:
1480 case ARM_IWMMXT_wCASF
:
1482 case ARM_IWMMXT_wCon
:
1483 gen_op_iwmmxt_set_cup();
1485 case ARM_IWMMXT_wCSSF
:
1486 tmp
= iwmmxt_load_creg(wrd
);
1487 tmp2
= load_reg(s
, rd
);
1488 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1489 tcg_temp_free_i32(tmp2
);
1490 iwmmxt_store_creg(wrd
, tmp
);
1492 case ARM_IWMMXT_wCGR0
:
1493 case ARM_IWMMXT_wCGR1
:
1494 case ARM_IWMMXT_wCGR2
:
1495 case ARM_IWMMXT_wCGR3
:
1496 gen_op_iwmmxt_set_cup();
1497 tmp
= load_reg(s
, rd
);
1498 iwmmxt_store_creg(wrd
, tmp
);
1504 case 0x100: /* WXOR */
1505 wrd
= (insn
>> 12) & 0xf;
1506 rd0
= (insn
>> 0) & 0xf;
1507 rd1
= (insn
>> 16) & 0xf;
1508 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1509 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1510 gen_op_iwmmxt_setpsr_nz();
1511 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1512 gen_op_iwmmxt_set_mup();
1513 gen_op_iwmmxt_set_cup();
1515 case 0x111: /* TMRC */
1518 rd
= (insn
>> 12) & 0xf;
1519 wrd
= (insn
>> 16) & 0xf;
1520 tmp
= iwmmxt_load_creg(wrd
);
1521 store_reg(s
, rd
, tmp
);
1523 case 0x300: /* WANDN */
1524 wrd
= (insn
>> 12) & 0xf;
1525 rd0
= (insn
>> 0) & 0xf;
1526 rd1
= (insn
>> 16) & 0xf;
1527 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1528 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1529 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1530 gen_op_iwmmxt_setpsr_nz();
1531 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1532 gen_op_iwmmxt_set_mup();
1533 gen_op_iwmmxt_set_cup();
1535 case 0x200: /* WAND */
1536 wrd
= (insn
>> 12) & 0xf;
1537 rd0
= (insn
>> 0) & 0xf;
1538 rd1
= (insn
>> 16) & 0xf;
1539 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1540 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1541 gen_op_iwmmxt_setpsr_nz();
1542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1543 gen_op_iwmmxt_set_mup();
1544 gen_op_iwmmxt_set_cup();
1546 case 0x810: case 0xa10: /* WMADD */
1547 wrd
= (insn
>> 12) & 0xf;
1548 rd0
= (insn
>> 0) & 0xf;
1549 rd1
= (insn
>> 16) & 0xf;
1550 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1551 if (insn
& (1 << 21))
1552 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1554 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1555 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1556 gen_op_iwmmxt_set_mup();
1558 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1559 wrd
= (insn
>> 12) & 0xf;
1560 rd0
= (insn
>> 16) & 0xf;
1561 rd1
= (insn
>> 0) & 0xf;
1562 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1563 switch ((insn
>> 22) & 3) {
1565 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1568 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1571 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1576 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1577 gen_op_iwmmxt_set_mup();
1578 gen_op_iwmmxt_set_cup();
1580 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1581 wrd
= (insn
>> 12) & 0xf;
1582 rd0
= (insn
>> 16) & 0xf;
1583 rd1
= (insn
>> 0) & 0xf;
1584 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1585 switch ((insn
>> 22) & 3) {
1587 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1590 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1593 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1598 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1599 gen_op_iwmmxt_set_mup();
1600 gen_op_iwmmxt_set_cup();
1602 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1603 wrd
= (insn
>> 12) & 0xf;
1604 rd0
= (insn
>> 16) & 0xf;
1605 rd1
= (insn
>> 0) & 0xf;
1606 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1607 if (insn
& (1 << 22))
1608 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1610 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1611 if (!(insn
& (1 << 20)))
1612 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1613 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1614 gen_op_iwmmxt_set_mup();
1616 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1617 wrd
= (insn
>> 12) & 0xf;
1618 rd0
= (insn
>> 16) & 0xf;
1619 rd1
= (insn
>> 0) & 0xf;
1620 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1621 if (insn
& (1 << 21)) {
1622 if (insn
& (1 << 20))
1623 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1625 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1627 if (insn
& (1 << 20))
1628 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1630 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1632 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1633 gen_op_iwmmxt_set_mup();
1635 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1636 wrd
= (insn
>> 12) & 0xf;
1637 rd0
= (insn
>> 16) & 0xf;
1638 rd1
= (insn
>> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1640 if (insn
& (1 << 21))
1641 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1643 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1644 if (!(insn
& (1 << 20))) {
1645 iwmmxt_load_reg(cpu_V1
, wrd
);
1646 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1648 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1649 gen_op_iwmmxt_set_mup();
1651 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1652 wrd
= (insn
>> 12) & 0xf;
1653 rd0
= (insn
>> 16) & 0xf;
1654 rd1
= (insn
>> 0) & 0xf;
1655 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1656 switch ((insn
>> 22) & 3) {
1658 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1661 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1664 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1669 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1670 gen_op_iwmmxt_set_mup();
1671 gen_op_iwmmxt_set_cup();
1673 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1674 wrd
= (insn
>> 12) & 0xf;
1675 rd0
= (insn
>> 16) & 0xf;
1676 rd1
= (insn
>> 0) & 0xf;
1677 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1678 if (insn
& (1 << 22)) {
1679 if (insn
& (1 << 20))
1680 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1682 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1684 if (insn
& (1 << 20))
1685 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1687 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1691 gen_op_iwmmxt_set_cup();
1693 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1694 wrd
= (insn
>> 12) & 0xf;
1695 rd0
= (insn
>> 16) & 0xf;
1696 rd1
= (insn
>> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1698 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1699 tcg_gen_andi_i32(tmp
, tmp
, 7);
1700 iwmmxt_load_reg(cpu_V1
, rd1
);
1701 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1702 tcg_temp_free_i32(tmp
);
1703 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1704 gen_op_iwmmxt_set_mup();
1706 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1707 if (((insn
>> 6) & 3) == 3)
1709 rd
= (insn
>> 12) & 0xf;
1710 wrd
= (insn
>> 16) & 0xf;
1711 tmp
= load_reg(s
, rd
);
1712 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1713 switch ((insn
>> 6) & 3) {
1715 tmp2
= tcg_const_i32(0xff);
1716 tmp3
= tcg_const_i32((insn
& 7) << 3);
1719 tmp2
= tcg_const_i32(0xffff);
1720 tmp3
= tcg_const_i32((insn
& 3) << 4);
1723 tmp2
= tcg_const_i32(0xffffffff);
1724 tmp3
= tcg_const_i32((insn
& 1) << 5);
1730 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1731 tcg_temp_free(tmp3
);
1732 tcg_temp_free(tmp2
);
1733 tcg_temp_free_i32(tmp
);
1734 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1735 gen_op_iwmmxt_set_mup();
1737 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1738 rd
= (insn
>> 12) & 0xf;
1739 wrd
= (insn
>> 16) & 0xf;
1740 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1742 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1743 tmp
= tcg_temp_new_i32();
1744 switch ((insn
>> 22) & 3) {
1746 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1747 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1749 tcg_gen_ext8s_i32(tmp
, tmp
);
1751 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1755 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1756 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1758 tcg_gen_ext16s_i32(tmp
, tmp
);
1760 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1764 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1765 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1768 store_reg(s
, rd
, tmp
);
1770 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1771 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1773 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1774 switch ((insn
>> 22) & 3) {
1776 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1779 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1782 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1785 tcg_gen_shli_i32(tmp
, tmp
, 28);
1787 tcg_temp_free_i32(tmp
);
1789 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1790 if (((insn
>> 6) & 3) == 3)
1792 rd
= (insn
>> 12) & 0xf;
1793 wrd
= (insn
>> 16) & 0xf;
1794 tmp
= load_reg(s
, rd
);
1795 switch ((insn
>> 6) & 3) {
1797 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1800 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1803 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1806 tcg_temp_free_i32(tmp
);
1807 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1808 gen_op_iwmmxt_set_mup();
1810 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1811 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1813 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1814 tmp2
= tcg_temp_new_i32();
1815 tcg_gen_mov_i32(tmp2
, tmp
);
1816 switch ((insn
>> 22) & 3) {
1818 for (i
= 0; i
< 7; i
++) {
1819 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1820 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1824 for (i
= 0; i
< 3; i
++) {
1825 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1826 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1830 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1831 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1835 tcg_temp_free_i32(tmp2
);
1836 tcg_temp_free_i32(tmp
);
1838 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1839 wrd
= (insn
>> 12) & 0xf;
1840 rd0
= (insn
>> 16) & 0xf;
1841 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1842 switch ((insn
>> 22) & 3) {
1844 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1847 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1850 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1855 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1856 gen_op_iwmmxt_set_mup();
1858 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1859 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1861 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1862 tmp2
= tcg_temp_new_i32();
1863 tcg_gen_mov_i32(tmp2
, tmp
);
1864 switch ((insn
>> 22) & 3) {
1866 for (i
= 0; i
< 7; i
++) {
1867 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1868 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1872 for (i
= 0; i
< 3; i
++) {
1873 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1874 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1878 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1879 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1883 tcg_temp_free_i32(tmp2
);
1884 tcg_temp_free_i32(tmp
);
1886 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1887 rd
= (insn
>> 12) & 0xf;
1888 rd0
= (insn
>> 16) & 0xf;
1889 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1891 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1892 tmp
= tcg_temp_new_i32();
1893 switch ((insn
>> 22) & 3) {
1895 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1898 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1901 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1904 store_reg(s
, rd
, tmp
);
1906 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1907 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1908 wrd
= (insn
>> 12) & 0xf;
1909 rd0
= (insn
>> 16) & 0xf;
1910 rd1
= (insn
>> 0) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1912 switch ((insn
>> 22) & 3) {
1914 if (insn
& (1 << 21))
1915 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1917 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1920 if (insn
& (1 << 21))
1921 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1923 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1926 if (insn
& (1 << 21))
1927 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1929 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1934 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1935 gen_op_iwmmxt_set_mup();
1936 gen_op_iwmmxt_set_cup();
1938 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1939 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1940 wrd
= (insn
>> 12) & 0xf;
1941 rd0
= (insn
>> 16) & 0xf;
1942 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1943 switch ((insn
>> 22) & 3) {
1945 if (insn
& (1 << 21))
1946 gen_op_iwmmxt_unpacklsb_M0();
1948 gen_op_iwmmxt_unpacklub_M0();
1951 if (insn
& (1 << 21))
1952 gen_op_iwmmxt_unpacklsw_M0();
1954 gen_op_iwmmxt_unpackluw_M0();
1957 if (insn
& (1 << 21))
1958 gen_op_iwmmxt_unpacklsl_M0();
1960 gen_op_iwmmxt_unpacklul_M0();
1965 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1966 gen_op_iwmmxt_set_mup();
1967 gen_op_iwmmxt_set_cup();
1969 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1970 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1971 wrd
= (insn
>> 12) & 0xf;
1972 rd0
= (insn
>> 16) & 0xf;
1973 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1974 switch ((insn
>> 22) & 3) {
1976 if (insn
& (1 << 21))
1977 gen_op_iwmmxt_unpackhsb_M0();
1979 gen_op_iwmmxt_unpackhub_M0();
1982 if (insn
& (1 << 21))
1983 gen_op_iwmmxt_unpackhsw_M0();
1985 gen_op_iwmmxt_unpackhuw_M0();
1988 if (insn
& (1 << 21))
1989 gen_op_iwmmxt_unpackhsl_M0();
1991 gen_op_iwmmxt_unpackhul_M0();
1996 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1997 gen_op_iwmmxt_set_mup();
1998 gen_op_iwmmxt_set_cup();
2000 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2001 case 0x214: case 0x614: case 0xa14: case 0xe14:
2002 if (((insn
>> 22) & 3) == 0)
2004 wrd
= (insn
>> 12) & 0xf;
2005 rd0
= (insn
>> 16) & 0xf;
2006 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2007 tmp
= tcg_temp_new_i32();
2008 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2009 tcg_temp_free_i32(tmp
);
2012 switch ((insn
>> 22) & 3) {
2014 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2017 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2020 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2023 tcg_temp_free_i32(tmp
);
2024 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2025 gen_op_iwmmxt_set_mup();
2026 gen_op_iwmmxt_set_cup();
2028 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2029 case 0x014: case 0x414: case 0x814: case 0xc14:
2030 if (((insn
>> 22) & 3) == 0)
2032 wrd
= (insn
>> 12) & 0xf;
2033 rd0
= (insn
>> 16) & 0xf;
2034 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2035 tmp
= tcg_temp_new_i32();
2036 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2037 tcg_temp_free_i32(tmp
);
2040 switch ((insn
>> 22) & 3) {
2042 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2045 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2048 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2051 tcg_temp_free_i32(tmp
);
2052 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2053 gen_op_iwmmxt_set_mup();
2054 gen_op_iwmmxt_set_cup();
2056 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2057 case 0x114: case 0x514: case 0x914: case 0xd14:
2058 if (((insn
>> 22) & 3) == 0)
2060 wrd
= (insn
>> 12) & 0xf;
2061 rd0
= (insn
>> 16) & 0xf;
2062 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2063 tmp
= tcg_temp_new_i32();
2064 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2065 tcg_temp_free_i32(tmp
);
2068 switch ((insn
>> 22) & 3) {
2070 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2073 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2076 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2079 tcg_temp_free_i32(tmp
);
2080 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2081 gen_op_iwmmxt_set_mup();
2082 gen_op_iwmmxt_set_cup();
2084 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2085 case 0x314: case 0x714: case 0xb14: case 0xf14:
2086 if (((insn
>> 22) & 3) == 0)
2088 wrd
= (insn
>> 12) & 0xf;
2089 rd0
= (insn
>> 16) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2091 tmp
= tcg_temp_new_i32();
2092 switch ((insn
>> 22) & 3) {
2094 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2095 tcg_temp_free_i32(tmp
);
2098 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2101 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2102 tcg_temp_free_i32(tmp
);
2105 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2109 tcg_temp_free_i32(tmp
);
2112 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2115 tcg_temp_free_i32(tmp
);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2117 gen_op_iwmmxt_set_mup();
2118 gen_op_iwmmxt_set_cup();
2120 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2121 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2122 wrd
= (insn
>> 12) & 0xf;
2123 rd0
= (insn
>> 16) & 0xf;
2124 rd1
= (insn
>> 0) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2126 switch ((insn
>> 22) & 3) {
2128 if (insn
& (1 << 21))
2129 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2131 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2134 if (insn
& (1 << 21))
2135 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2137 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2140 if (insn
& (1 << 21))
2141 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2143 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2148 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2149 gen_op_iwmmxt_set_mup();
2151 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2152 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2153 wrd
= (insn
>> 12) & 0xf;
2154 rd0
= (insn
>> 16) & 0xf;
2155 rd1
= (insn
>> 0) & 0xf;
2156 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2157 switch ((insn
>> 22) & 3) {
2159 if (insn
& (1 << 21))
2160 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2162 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2165 if (insn
& (1 << 21))
2166 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2168 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2171 if (insn
& (1 << 21))
2172 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2174 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2179 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2180 gen_op_iwmmxt_set_mup();
2182 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2183 case 0x402: case 0x502: case 0x602: case 0x702:
2184 wrd
= (insn
>> 12) & 0xf;
2185 rd0
= (insn
>> 16) & 0xf;
2186 rd1
= (insn
>> 0) & 0xf;
2187 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2188 tmp
= tcg_const_i32((insn
>> 20) & 3);
2189 iwmmxt_load_reg(cpu_V1
, rd1
);
2190 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2193 gen_op_iwmmxt_set_mup();
2195 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2196 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2197 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2198 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2199 wrd
= (insn
>> 12) & 0xf;
2200 rd0
= (insn
>> 16) & 0xf;
2201 rd1
= (insn
>> 0) & 0xf;
2202 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2203 switch ((insn
>> 20) & 0xf) {
2205 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2208 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2211 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2214 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2217 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2220 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2223 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2226 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2229 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2234 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2235 gen_op_iwmmxt_set_mup();
2236 gen_op_iwmmxt_set_cup();
2238 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2239 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2240 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2241 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2242 wrd
= (insn
>> 12) & 0xf;
2243 rd0
= (insn
>> 16) & 0xf;
2244 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2245 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2246 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2248 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2249 gen_op_iwmmxt_set_mup();
2250 gen_op_iwmmxt_set_cup();
2252 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2253 case 0x418: case 0x518: case 0x618: case 0x718:
2254 case 0x818: case 0x918: case 0xa18: case 0xb18:
2255 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2256 wrd
= (insn
>> 12) & 0xf;
2257 rd0
= (insn
>> 16) & 0xf;
2258 rd1
= (insn
>> 0) & 0xf;
2259 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2260 switch ((insn
>> 20) & 0xf) {
2262 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2265 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2268 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2271 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2274 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2277 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2280 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2283 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2286 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2291 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2292 gen_op_iwmmxt_set_mup();
2293 gen_op_iwmmxt_set_cup();
2295 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2296 case 0x408: case 0x508: case 0x608: case 0x708:
2297 case 0x808: case 0x908: case 0xa08: case 0xb08:
2298 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2299 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2301 wrd
= (insn
>> 12) & 0xf;
2302 rd0
= (insn
>> 16) & 0xf;
2303 rd1
= (insn
>> 0) & 0xf;
2304 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2305 switch ((insn
>> 22) & 3) {
2307 if (insn
& (1 << 21))
2308 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2310 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2313 if (insn
& (1 << 21))
2314 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2316 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2319 if (insn
& (1 << 21))
2320 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2322 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2329 case 0x201: case 0x203: case 0x205: case 0x207:
2330 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2331 case 0x211: case 0x213: case 0x215: case 0x217:
2332 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2333 wrd
= (insn
>> 5) & 0xf;
2334 rd0
= (insn
>> 12) & 0xf;
2335 rd1
= (insn
>> 0) & 0xf;
2336 if (rd0
== 0xf || rd1
== 0xf)
2338 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2339 tmp
= load_reg(s
, rd0
);
2340 tmp2
= load_reg(s
, rd1
);
2341 switch ((insn
>> 16) & 0xf) {
2342 case 0x0: /* TMIA */
2343 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2345 case 0x8: /* TMIAPH */
2346 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2348 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
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
);
2356 tcg_temp_free_i32(tmp2
);
2357 tcg_temp_free_i32(tmp
);
2360 tcg_temp_free_i32(tmp2
);
2361 tcg_temp_free_i32(tmp
);
2362 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2363 gen_op_iwmmxt_set_mup();
2372 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2373 (ie. an undefined instruction). */
2374 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2376 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2379 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2380 /* Multiply with Internal Accumulate Format */
2381 rd0
= (insn
>> 12) & 0xf;
2383 acc
= (insn
>> 5) & 7;
2388 tmp
= load_reg(s
, rd0
);
2389 tmp2
= load_reg(s
, rd1
);
2390 switch ((insn
>> 16) & 0xf) {
2392 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2394 case 0x8: /* MIAPH */
2395 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2397 case 0xc: /* MIABB */
2398 case 0xd: /* MIABT */
2399 case 0xe: /* MIATB */
2400 case 0xf: /* MIATT */
2401 if (insn
& (1 << 16))
2402 tcg_gen_shri_i32(tmp
, tmp
, 16);
2403 if (insn
& (1 << 17))
2404 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2405 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2410 tcg_temp_free_i32(tmp2
);
2411 tcg_temp_free_i32(tmp
);
2413 gen_op_iwmmxt_movq_wRn_M0(acc
);
2417 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2418 /* Internal Accumulator Access Format */
2419 rdhi
= (insn
>> 16) & 0xf;
2420 rdlo
= (insn
>> 12) & 0xf;
2426 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2427 iwmmxt_load_reg(cpu_V0
, acc
);
2428 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2429 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2430 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2431 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2433 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2434 iwmmxt_store_reg(cpu_V0
, acc
);
2442 /* Disassemble system coprocessor instruction. Return nonzero if
2443 instruction is not defined. */
2444 static int disas_cp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2447 uint32_t rd
= (insn
>> 12) & 0xf;
2448 uint32_t cp
= (insn
>> 8) & 0xf;
2453 if (insn
& ARM_CP_RW_BIT
) {
2454 if (!env
->cp
[cp
].cp_read
)
2456 gen_set_pc_im(s
->pc
);
2457 tmp
= tcg_temp_new_i32();
2458 tmp2
= tcg_const_i32(insn
);
2459 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2460 tcg_temp_free(tmp2
);
2461 store_reg(s
, rd
, tmp
);
2463 if (!env
->cp
[cp
].cp_write
)
2465 gen_set_pc_im(s
->pc
);
2466 tmp
= load_reg(s
, rd
);
2467 tmp2
= tcg_const_i32(insn
);
2468 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2469 tcg_temp_free(tmp2
);
2470 tcg_temp_free_i32(tmp
);
2475 static int cp15_user_ok(CPUARMState
*env
, uint32_t insn
)
2477 int cpn
= (insn
>> 16) & 0xf;
2478 int cpm
= insn
& 0xf;
2479 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2481 if (arm_feature(env
, ARM_FEATURE_V7
) && cpn
== 9) {
2482 /* Performance monitor registers fall into three categories:
2483 * (a) always UNDEF in usermode
2484 * (b) UNDEF only if PMUSERENR.EN is 0
2485 * (c) always read OK and UNDEF on write (PMUSERENR only)
2487 if ((cpm
== 12 && (op
< 6)) ||
2488 (cpm
== 13 && (op
< 3))) {
2489 return env
->cp15
.c9_pmuserenr
;
2490 } else if (cpm
== 14 && op
== 0 && (insn
& ARM_CP_RW_BIT
)) {
2491 /* PMUSERENR, read only */
2497 if (cpn
== 13 && cpm
== 0) {
2499 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2505 static int cp15_tls_load_store(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
, uint32_t rd
)
2508 int cpn
= (insn
>> 16) & 0xf;
2509 int cpm
= insn
& 0xf;
2510 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2512 if (!arm_feature(env
, ARM_FEATURE_V6K
))
2515 if (!(cpn
== 13 && cpm
== 0))
2518 if (insn
& ARM_CP_RW_BIT
) {
2521 tmp
= load_cpu_field(cp15
.c13_tls1
);
2524 tmp
= load_cpu_field(cp15
.c13_tls2
);
2527 tmp
= load_cpu_field(cp15
.c13_tls3
);
2532 store_reg(s
, rd
, tmp
);
2535 tmp
= load_reg(s
, rd
);
2538 store_cpu_field(tmp
, cp15
.c13_tls1
);
2541 store_cpu_field(tmp
, cp15
.c13_tls2
);
2544 store_cpu_field(tmp
, cp15
.c13_tls3
);
2547 tcg_temp_free_i32(tmp
);
2554 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2555 instruction is not defined. */
2556 static int disas_cp15_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2561 /* M profile cores use memory mapped registers instead of cp15. */
2562 if (arm_feature(env
, ARM_FEATURE_M
))
2565 if ((insn
& (1 << 25)) == 0) {
2566 if (insn
& (1 << 20)) {
2570 /* mcrr. Used for block cache operations, so implement as no-op. */
2573 if ((insn
& (1 << 4)) == 0) {
2577 /* We special case a number of cp15 instructions which were used
2578 * for things which are real instructions in ARMv7. This allows
2579 * them to work in linux-user mode which doesn't provide functional
2580 * get_cp15/set_cp15 helpers, and is more efficient anyway.
2582 switch ((insn
& 0x0fff0fff)) {
2584 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2585 * In v7, this must NOP.
2590 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
2591 /* Wait for interrupt. */
2592 gen_set_pc_im(s
->pc
);
2593 s
->is_jmp
= DISAS_WFI
;
2597 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2598 * so this is slightly over-broad.
2600 if (!IS_USER(s
) && !arm_feature(env
, ARM_FEATURE_V6
)) {
2601 /* Wait for interrupt. */
2602 gen_set_pc_im(s
->pc
);
2603 s
->is_jmp
= DISAS_WFI
;
2606 /* Otherwise continue to handle via helper function.
2607 * In particular, on v7 and some v6 cores this is one of
2608 * the VA-PA registers.
2612 /* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */
2613 if (arm_feature(env
, ARM_FEATURE_V6
)) {
2614 return IS_USER(s
) ? 1 : 0;
2617 case 0x0e070f95: /* 0,c7,c5,4 : ISB */
2618 case 0x0e070f9a: /* 0,c7,c10,4: DSB */
2619 case 0x0e070fba: /* 0,c7,c10,5: DMB */
2620 /* Barriers in both v6 and v7 */
2621 if (arm_feature(env
, ARM_FEATURE_V6
)) {
2629 if (IS_USER(s
) && !cp15_user_ok(env
, insn
)) {
2633 rd
= (insn
>> 12) & 0xf;
2635 if (cp15_tls_load_store(env
, s
, insn
, rd
))
2638 tmp2
= tcg_const_i32(insn
);
2639 if (insn
& ARM_CP_RW_BIT
) {
2640 tmp
= tcg_temp_new_i32();
2641 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2642 /* If the destination register is r15 then sets condition codes. */
2644 store_reg(s
, rd
, tmp
);
2646 tcg_temp_free_i32(tmp
);
2648 tmp
= load_reg(s
, rd
);
2649 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2650 tcg_temp_free_i32(tmp
);
2651 /* Normally we would always end the TB here, but Linux
2652 * arch/arm/mach-pxa/sleep.S expects two instructions following
2653 * an MMU enable to execute from cache. Imitate this behaviour. */
2654 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2655 (insn
& 0x0fff0fff) != 0x0e010f10)
2658 tcg_temp_free_i32(tmp2
);
2662 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2663 #define VFP_SREG(insn, bigbit, smallbit) \
2664 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2665 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2666 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2667 reg = (((insn) >> (bigbit)) & 0x0f) \
2668 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2670 if (insn & (1 << (smallbit))) \
2672 reg = ((insn) >> (bigbit)) & 0x0f; \
2675 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2676 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2677 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2678 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2679 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2680 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2682 /* Move between integer and VFP cores. */
2683 static TCGv
gen_vfp_mrs(void)
2685 TCGv tmp
= tcg_temp_new_i32();
2686 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2690 static void gen_vfp_msr(TCGv tmp
)
2692 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2693 tcg_temp_free_i32(tmp
);
2696 static void gen_neon_dup_u8(TCGv var
, int shift
)
2698 TCGv tmp
= tcg_temp_new_i32();
2700 tcg_gen_shri_i32(var
, var
, shift
);
2701 tcg_gen_ext8u_i32(var
, var
);
2702 tcg_gen_shli_i32(tmp
, var
, 8);
2703 tcg_gen_or_i32(var
, var
, tmp
);
2704 tcg_gen_shli_i32(tmp
, var
, 16);
2705 tcg_gen_or_i32(var
, var
, tmp
);
2706 tcg_temp_free_i32(tmp
);
2709 static void gen_neon_dup_low16(TCGv var
)
2711 TCGv tmp
= tcg_temp_new_i32();
2712 tcg_gen_ext16u_i32(var
, var
);
2713 tcg_gen_shli_i32(tmp
, var
, 16);
2714 tcg_gen_or_i32(var
, var
, tmp
);
2715 tcg_temp_free_i32(tmp
);
2718 static void gen_neon_dup_high16(TCGv var
)
2720 TCGv tmp
= tcg_temp_new_i32();
2721 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2722 tcg_gen_shri_i32(tmp
, var
, 16);
2723 tcg_gen_or_i32(var
, var
, tmp
);
2724 tcg_temp_free_i32(tmp
);
2727 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2729 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2733 tmp
= gen_ld8u(addr
, IS_USER(s
));
2734 gen_neon_dup_u8(tmp
, 0);
2737 tmp
= gen_ld16u(addr
, IS_USER(s
));
2738 gen_neon_dup_low16(tmp
);
2741 tmp
= gen_ld32(addr
, IS_USER(s
));
2743 default: /* Avoid compiler warnings. */
2749 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2750 (ie. an undefined instruction). */
2751 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2753 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2759 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2762 if (!s
->vfp_enabled
) {
2763 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2764 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2766 rn
= (insn
>> 16) & 0xf;
2767 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2768 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2771 dp
= ((insn
& 0xf00) == 0xb00);
2772 switch ((insn
>> 24) & 0xf) {
2774 if (insn
& (1 << 4)) {
2775 /* single register transfer */
2776 rd
= (insn
>> 12) & 0xf;
2781 VFP_DREG_N(rn
, insn
);
2784 if (insn
& 0x00c00060
2785 && !arm_feature(env
, ARM_FEATURE_NEON
))
2788 pass
= (insn
>> 21) & 1;
2789 if (insn
& (1 << 22)) {
2791 offset
= ((insn
>> 5) & 3) * 8;
2792 } else if (insn
& (1 << 5)) {
2794 offset
= (insn
& (1 << 6)) ? 16 : 0;
2799 if (insn
& ARM_CP_RW_BIT
) {
2801 tmp
= neon_load_reg(rn
, pass
);
2805 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2806 if (insn
& (1 << 23))
2812 if (insn
& (1 << 23)) {
2814 tcg_gen_shri_i32(tmp
, tmp
, 16);
2820 tcg_gen_sari_i32(tmp
, tmp
, 16);
2829 store_reg(s
, rd
, tmp
);
2832 tmp
= load_reg(s
, rd
);
2833 if (insn
& (1 << 23)) {
2836 gen_neon_dup_u8(tmp
, 0);
2837 } else if (size
== 1) {
2838 gen_neon_dup_low16(tmp
);
2840 for (n
= 0; n
<= pass
* 2; n
++) {
2841 tmp2
= tcg_temp_new_i32();
2842 tcg_gen_mov_i32(tmp2
, tmp
);
2843 neon_store_reg(rn
, n
, tmp2
);
2845 neon_store_reg(rn
, n
, tmp
);
2850 tmp2
= neon_load_reg(rn
, pass
);
2851 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2852 tcg_temp_free_i32(tmp2
);
2855 tmp2
= neon_load_reg(rn
, pass
);
2856 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2857 tcg_temp_free_i32(tmp2
);
2862 neon_store_reg(rn
, pass
, tmp
);
2866 if ((insn
& 0x6f) != 0x00)
2868 rn
= VFP_SREG_N(insn
);
2869 if (insn
& ARM_CP_RW_BIT
) {
2871 if (insn
& (1 << 21)) {
2872 /* system register */
2877 /* VFP2 allows access to FSID from userspace.
2878 VFP3 restricts all id registers to privileged
2881 && arm_feature(env
, ARM_FEATURE_VFP3
))
2883 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2888 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2890 case ARM_VFP_FPINST
:
2891 case ARM_VFP_FPINST2
:
2892 /* Not present in VFP3. */
2894 || arm_feature(env
, ARM_FEATURE_VFP3
))
2896 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2900 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2901 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2903 tmp
= tcg_temp_new_i32();
2904 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2910 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2912 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2918 gen_mov_F0_vreg(0, rn
);
2919 tmp
= gen_vfp_mrs();
2922 /* Set the 4 flag bits in the CPSR. */
2924 tcg_temp_free_i32(tmp
);
2926 store_reg(s
, rd
, tmp
);
2930 tmp
= load_reg(s
, rd
);
2931 if (insn
& (1 << 21)) {
2933 /* system register */
2938 /* Writes are ignored. */
2941 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2942 tcg_temp_free_i32(tmp
);
2948 /* TODO: VFP subarchitecture support.
2949 * For now, keep the EN bit only */
2950 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2951 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2954 case ARM_VFP_FPINST
:
2955 case ARM_VFP_FPINST2
:
2956 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2963 gen_mov_vreg_F0(0, rn
);
2968 /* data processing */
2969 /* The opcode is in bits 23, 21, 20 and 6. */
2970 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2974 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2976 /* rn is register number */
2977 VFP_DREG_N(rn
, insn
);
2980 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2981 /* Integer or single precision destination. */
2982 rd
= VFP_SREG_D(insn
);
2984 VFP_DREG_D(rd
, insn
);
2987 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2988 /* VCVT from int is always from S reg regardless of dp bit.
2989 * VCVT with immediate frac_bits has same format as SREG_M
2991 rm
= VFP_SREG_M(insn
);
2993 VFP_DREG_M(rm
, insn
);
2996 rn
= VFP_SREG_N(insn
);
2997 if (op
== 15 && rn
== 15) {
2998 /* Double precision destination. */
2999 VFP_DREG_D(rd
, insn
);
3001 rd
= VFP_SREG_D(insn
);
3003 /* NB that we implicitly rely on the encoding for the frac_bits
3004 * in VCVT of fixed to float being the same as that of an SREG_M
3006 rm
= VFP_SREG_M(insn
);
3009 veclen
= s
->vec_len
;
3010 if (op
== 15 && rn
> 3)
3013 /* Shut up compiler warnings. */
3024 /* Figure out what type of vector operation this is. */
3025 if ((rd
& bank_mask
) == 0) {
3030 delta_d
= (s
->vec_stride
>> 1) + 1;
3032 delta_d
= s
->vec_stride
+ 1;
3034 if ((rm
& bank_mask
) == 0) {
3035 /* mixed scalar/vector */
3044 /* Load the initial operands. */
3049 /* Integer source */
3050 gen_mov_F0_vreg(0, rm
);
3055 gen_mov_F0_vreg(dp
, rd
);
3056 gen_mov_F1_vreg(dp
, rm
);
3060 /* Compare with zero */
3061 gen_mov_F0_vreg(dp
, rd
);
3072 /* Source and destination the same. */
3073 gen_mov_F0_vreg(dp
, rd
);
3079 /* VCVTB, VCVTT: only present with the halfprec extension,
3080 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3082 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3085 /* Otherwise fall through */
3087 /* One source operand. */
3088 gen_mov_F0_vreg(dp
, rm
);
3092 /* Two source operands. */
3093 gen_mov_F0_vreg(dp
, rn
);
3094 gen_mov_F1_vreg(dp
, rm
);
3098 /* Perform the calculation. */
3100 case 0: /* VMLA: fd + (fn * fm) */
3101 /* Note that order of inputs to the add matters for NaNs */
3103 gen_mov_F0_vreg(dp
, rd
);
3106 case 1: /* VMLS: fd + -(fn * fm) */
3109 gen_mov_F0_vreg(dp
, rd
);
3112 case 2: /* VNMLS: -fd + (fn * fm) */
3113 /* Note that it isn't valid to replace (-A + B) with (B - A)
3114 * or similar plausible looking simplifications
3115 * because this will give wrong results for NaNs.
3118 gen_mov_F0_vreg(dp
, rd
);
3122 case 3: /* VNMLA: -fd + -(fn * fm) */
3125 gen_mov_F0_vreg(dp
, rd
);
3129 case 4: /* mul: fn * fm */
3132 case 5: /* nmul: -(fn * fm) */
3136 case 6: /* add: fn + fm */
3139 case 7: /* sub: fn - fm */
3142 case 8: /* div: fn / fm */
3145 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3146 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3147 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3148 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3149 /* These are fused multiply-add, and must be done as one
3150 * floating point operation with no rounding between the
3151 * multiplication and addition steps.
3152 * NB that doing the negations here as separate steps is
3153 * correct : an input NaN should come out with its sign bit
3154 * flipped if it is a negated-input.
3156 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3164 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3166 frd
= tcg_temp_new_i64();
3167 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3170 gen_helper_vfp_negd(frd
, frd
);
3172 fpst
= get_fpstatus_ptr(0);
3173 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3174 cpu_F1d
, frd
, fpst
);
3175 tcg_temp_free_ptr(fpst
);
3176 tcg_temp_free_i64(frd
);
3182 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3184 frd
= tcg_temp_new_i32();
3185 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3187 gen_helper_vfp_negs(frd
, frd
);
3189 fpst
= get_fpstatus_ptr(0);
3190 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3191 cpu_F1s
, frd
, fpst
);
3192 tcg_temp_free_ptr(fpst
);
3193 tcg_temp_free_i32(frd
);
3196 case 14: /* fconst */
3197 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3200 n
= (insn
<< 12) & 0x80000000;
3201 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3208 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3215 tcg_gen_movi_i32(cpu_F0s
, n
);
3218 case 15: /* extension space */
3232 case 4: /* vcvtb.f32.f16 */
3233 tmp
= gen_vfp_mrs();
3234 tcg_gen_ext16u_i32(tmp
, tmp
);
3235 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3236 tcg_temp_free_i32(tmp
);
3238 case 5: /* vcvtt.f32.f16 */
3239 tmp
= gen_vfp_mrs();
3240 tcg_gen_shri_i32(tmp
, tmp
, 16);
3241 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3242 tcg_temp_free_i32(tmp
);
3244 case 6: /* vcvtb.f16.f32 */
3245 tmp
= tcg_temp_new_i32();
3246 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3247 gen_mov_F0_vreg(0, rd
);
3248 tmp2
= gen_vfp_mrs();
3249 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3250 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3251 tcg_temp_free_i32(tmp2
);
3254 case 7: /* vcvtt.f16.f32 */
3255 tmp
= tcg_temp_new_i32();
3256 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3257 tcg_gen_shli_i32(tmp
, tmp
, 16);
3258 gen_mov_F0_vreg(0, rd
);
3259 tmp2
= gen_vfp_mrs();
3260 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3261 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3262 tcg_temp_free_i32(tmp2
);
3274 case 11: /* cmpez */
3278 case 15: /* single<->double conversion */
3280 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3282 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3284 case 16: /* fuito */
3285 gen_vfp_uito(dp
, 0);
3287 case 17: /* fsito */
3288 gen_vfp_sito(dp
, 0);
3290 case 20: /* fshto */
3291 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3293 gen_vfp_shto(dp
, 16 - rm
, 0);
3295 case 21: /* fslto */
3296 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3298 gen_vfp_slto(dp
, 32 - rm
, 0);
3300 case 22: /* fuhto */
3301 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3303 gen_vfp_uhto(dp
, 16 - rm
, 0);
3305 case 23: /* fulto */
3306 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3308 gen_vfp_ulto(dp
, 32 - rm
, 0);
3310 case 24: /* ftoui */
3311 gen_vfp_toui(dp
, 0);
3313 case 25: /* ftouiz */
3314 gen_vfp_touiz(dp
, 0);
3316 case 26: /* ftosi */
3317 gen_vfp_tosi(dp
, 0);
3319 case 27: /* ftosiz */
3320 gen_vfp_tosiz(dp
, 0);
3322 case 28: /* ftosh */
3323 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3325 gen_vfp_tosh(dp
, 16 - rm
, 0);
3327 case 29: /* ftosl */
3328 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3330 gen_vfp_tosl(dp
, 32 - rm
, 0);
3332 case 30: /* ftouh */
3333 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3335 gen_vfp_touh(dp
, 16 - rm
, 0);
3337 case 31: /* ftoul */
3338 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3340 gen_vfp_toul(dp
, 32 - rm
, 0);
3342 default: /* undefined */
3346 default: /* undefined */
3350 /* Write back the result. */
3351 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3352 ; /* Comparison, do nothing. */
3353 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3354 /* VCVT double to int: always integer result. */
3355 gen_mov_vreg_F0(0, rd
);
3356 else if (op
== 15 && rn
== 15)
3358 gen_mov_vreg_F0(!dp
, rd
);
3360 gen_mov_vreg_F0(dp
, rd
);
3362 /* break out of the loop if we have finished */
3366 if (op
== 15 && delta_m
== 0) {
3367 /* single source one-many */
3369 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3371 gen_mov_vreg_F0(dp
, rd
);
3375 /* Setup the next operands. */
3377 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3381 /* One source operand. */
3382 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3384 gen_mov_F0_vreg(dp
, rm
);
3386 /* Two source operands. */
3387 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3389 gen_mov_F0_vreg(dp
, rn
);
3391 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3393 gen_mov_F1_vreg(dp
, rm
);
3401 if ((insn
& 0x03e00000) == 0x00400000) {
3402 /* two-register transfer */
3403 rn
= (insn
>> 16) & 0xf;
3404 rd
= (insn
>> 12) & 0xf;
3406 VFP_DREG_M(rm
, insn
);
3408 rm
= VFP_SREG_M(insn
);
3411 if (insn
& ARM_CP_RW_BIT
) {
3414 gen_mov_F0_vreg(0, rm
* 2);
3415 tmp
= gen_vfp_mrs();
3416 store_reg(s
, rd
, tmp
);
3417 gen_mov_F0_vreg(0, rm
* 2 + 1);
3418 tmp
= gen_vfp_mrs();
3419 store_reg(s
, rn
, tmp
);
3421 gen_mov_F0_vreg(0, rm
);
3422 tmp
= gen_vfp_mrs();
3423 store_reg(s
, rd
, tmp
);
3424 gen_mov_F0_vreg(0, rm
+ 1);
3425 tmp
= gen_vfp_mrs();
3426 store_reg(s
, rn
, tmp
);
3431 tmp
= load_reg(s
, rd
);
3433 gen_mov_vreg_F0(0, rm
* 2);
3434 tmp
= load_reg(s
, rn
);
3436 gen_mov_vreg_F0(0, rm
* 2 + 1);
3438 tmp
= load_reg(s
, rd
);
3440 gen_mov_vreg_F0(0, rm
);
3441 tmp
= load_reg(s
, rn
);
3443 gen_mov_vreg_F0(0, rm
+ 1);
3448 rn
= (insn
>> 16) & 0xf;
3450 VFP_DREG_D(rd
, insn
);
3452 rd
= VFP_SREG_D(insn
);
3453 if ((insn
& 0x01200000) == 0x01000000) {
3454 /* Single load/store */
3455 offset
= (insn
& 0xff) << 2;
3456 if ((insn
& (1 << 23)) == 0)
3458 if (s
->thumb
&& rn
== 15) {
3459 /* This is actually UNPREDICTABLE */
3460 addr
= tcg_temp_new_i32();
3461 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3463 addr
= load_reg(s
, rn
);
3465 tcg_gen_addi_i32(addr
, addr
, offset
);
3466 if (insn
& (1 << 20)) {
3467 gen_vfp_ld(s
, dp
, addr
);
3468 gen_mov_vreg_F0(dp
, rd
);
3470 gen_mov_F0_vreg(dp
, rd
);
3471 gen_vfp_st(s
, dp
, addr
);
3473 tcg_temp_free_i32(addr
);
3475 /* load/store multiple */
3476 int w
= insn
& (1 << 21);
3478 n
= (insn
>> 1) & 0x7f;
3482 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3483 /* P == U , W == 1 => UNDEF */
3486 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3487 /* UNPREDICTABLE cases for bad immediates: we choose to
3488 * UNDEF to avoid generating huge numbers of TCG ops
3492 if (rn
== 15 && w
) {
3493 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3497 if (s
->thumb
&& rn
== 15) {
3498 /* This is actually UNPREDICTABLE */
3499 addr
= tcg_temp_new_i32();
3500 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3502 addr
= load_reg(s
, rn
);
3504 if (insn
& (1 << 24)) /* pre-decrement */
3505 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3511 for (i
= 0; i
< n
; i
++) {
3512 if (insn
& ARM_CP_RW_BIT
) {
3514 gen_vfp_ld(s
, dp
, addr
);
3515 gen_mov_vreg_F0(dp
, rd
+ i
);
3518 gen_mov_F0_vreg(dp
, rd
+ i
);
3519 gen_vfp_st(s
, dp
, addr
);
3521 tcg_gen_addi_i32(addr
, addr
, offset
);
3525 if (insn
& (1 << 24))
3526 offset
= -offset
* n
;
3527 else if (dp
&& (insn
& 1))
3533 tcg_gen_addi_i32(addr
, addr
, offset
);
3534 store_reg(s
, rn
, addr
);
3536 tcg_temp_free_i32(addr
);
3542 /* Should never happen. */
3548 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3550 TranslationBlock
*tb
;
3553 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3555 gen_set_pc_im(dest
);
3556 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3558 gen_set_pc_im(dest
);
3563 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3565 if (unlikely(s
->singlestep_enabled
)) {
3566 /* An indirect jump so that we still trigger the debug exception. */
3571 gen_goto_tb(s
, 0, dest
);
3572 s
->is_jmp
= DISAS_TB_JUMP
;
3576 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3579 tcg_gen_sari_i32(t0
, t0
, 16);
3583 tcg_gen_sari_i32(t1
, t1
, 16);
3586 tcg_gen_mul_i32(t0
, t0
, t1
);
3589 /* Return the mask of PSR bits set by a MSR instruction. */
3590 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3594 if (flags
& (1 << 0))
3596 if (flags
& (1 << 1))
3598 if (flags
& (1 << 2))
3600 if (flags
& (1 << 3))
3603 /* Mask out undefined bits. */
3604 mask
&= ~CPSR_RESERVED
;
3605 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3607 if (!arm_feature(env
, ARM_FEATURE_V5
))
3608 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3609 if (!arm_feature(env
, ARM_FEATURE_V6
))
3610 mask
&= ~(CPSR_E
| CPSR_GE
);
3611 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3613 /* Mask out execution state bits. */
3616 /* Mask out privileged bits. */
3622 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3623 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3627 /* ??? This is also undefined in system mode. */
3631 tmp
= load_cpu_field(spsr
);
3632 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3633 tcg_gen_andi_i32(t0
, t0
, mask
);
3634 tcg_gen_or_i32(tmp
, tmp
, t0
);
3635 store_cpu_field(tmp
, spsr
);
3637 gen_set_cpsr(t0
, mask
);
3639 tcg_temp_free_i32(t0
);
3644 /* Returns nonzero if access to the PSR is not permitted. */
3645 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3648 tmp
= tcg_temp_new_i32();
3649 tcg_gen_movi_i32(tmp
, val
);
3650 return gen_set_psr(s
, mask
, spsr
, tmp
);
3653 /* Generate an old-style exception return. Marks pc as dead. */
3654 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3657 store_reg(s
, 15, pc
);
3658 tmp
= load_cpu_field(spsr
);
3659 gen_set_cpsr(tmp
, 0xffffffff);
3660 tcg_temp_free_i32(tmp
);
3661 s
->is_jmp
= DISAS_UPDATE
;
3664 /* Generate a v6 exception return. Marks both values as dead. */
3665 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3667 gen_set_cpsr(cpsr
, 0xffffffff);
3668 tcg_temp_free_i32(cpsr
);
3669 store_reg(s
, 15, pc
);
3670 s
->is_jmp
= DISAS_UPDATE
;
3674 gen_set_condexec (DisasContext
*s
)
3676 if (s
->condexec_mask
) {
3677 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3678 TCGv tmp
= tcg_temp_new_i32();
3679 tcg_gen_movi_i32(tmp
, val
);
3680 store_cpu_field(tmp
, condexec_bits
);
3684 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3686 gen_set_condexec(s
);
3687 gen_set_pc_im(s
->pc
- offset
);
3688 gen_exception(excp
);
3689 s
->is_jmp
= DISAS_JUMP
;
3692 static void gen_nop_hint(DisasContext
*s
, int val
)
3696 gen_set_pc_im(s
->pc
);
3697 s
->is_jmp
= DISAS_WFI
;
3701 /* TODO: Implement SEV and WFE. May help SMP performance. */
3707 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3709 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3712 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3713 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3714 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3719 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3722 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3723 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3724 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3729 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3730 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3731 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3732 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3733 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3735 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3736 switch ((size << 1) | u) { \
3738 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3741 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3744 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3747 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3750 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3753 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3755 default: return 1; \
3758 #define GEN_NEON_INTEGER_OP(name) do { \
3759 switch ((size << 1) | u) { \
3761 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3764 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3767 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3770 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3773 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3776 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3778 default: return 1; \
3781 static TCGv
neon_load_scratch(int scratch
)
3783 TCGv tmp
= tcg_temp_new_i32();
3784 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3788 static void neon_store_scratch(int scratch
, TCGv var
)
3790 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3791 tcg_temp_free_i32(var
);
3794 static inline TCGv
neon_get_scalar(int size
, int reg
)
3798 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3800 gen_neon_dup_high16(tmp
);
3802 gen_neon_dup_low16(tmp
);
3805 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3810 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3813 if (!q
&& size
== 2) {
3816 tmp
= tcg_const_i32(rd
);
3817 tmp2
= tcg_const_i32(rm
);
3821 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3824 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3827 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3835 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3838 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3844 tcg_temp_free_i32(tmp
);
3845 tcg_temp_free_i32(tmp2
);
3849 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3852 if (!q
&& size
== 2) {
3855 tmp
= tcg_const_i32(rd
);
3856 tmp2
= tcg_const_i32(rm
);
3860 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3863 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3866 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3874 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3877 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3883 tcg_temp_free_i32(tmp
);
3884 tcg_temp_free_i32(tmp2
);
3888 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3892 rd
= tcg_temp_new_i32();
3893 tmp
= tcg_temp_new_i32();
3895 tcg_gen_shli_i32(rd
, t0
, 8);
3896 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3897 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3898 tcg_gen_or_i32(rd
, rd
, tmp
);
3900 tcg_gen_shri_i32(t1
, t1
, 8);
3901 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3902 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3903 tcg_gen_or_i32(t1
, t1
, tmp
);
3904 tcg_gen_mov_i32(t0
, rd
);
3906 tcg_temp_free_i32(tmp
);
3907 tcg_temp_free_i32(rd
);
3910 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3914 rd
= tcg_temp_new_i32();
3915 tmp
= tcg_temp_new_i32();
3917 tcg_gen_shli_i32(rd
, t0
, 16);
3918 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3919 tcg_gen_or_i32(rd
, rd
, tmp
);
3920 tcg_gen_shri_i32(t1
, t1
, 16);
3921 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3922 tcg_gen_or_i32(t1
, t1
, tmp
);
3923 tcg_gen_mov_i32(t0
, rd
);
3925 tcg_temp_free_i32(tmp
);
3926 tcg_temp_free_i32(rd
);
3934 } neon_ls_element_type
[11] = {
3948 /* Translate a NEON load/store element instruction. Return nonzero if the
3949 instruction is invalid. */
3950 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3969 if (!s
->vfp_enabled
)
3971 VFP_DREG_D(rd
, insn
);
3972 rn
= (insn
>> 16) & 0xf;
3974 load
= (insn
& (1 << 21)) != 0;
3975 if ((insn
& (1 << 23)) == 0) {
3976 /* Load store all elements. */
3977 op
= (insn
>> 8) & 0xf;
3978 size
= (insn
>> 6) & 3;
3981 /* Catch UNDEF cases for bad values of align field */
3984 if (((insn
>> 5) & 1) == 1) {
3989 if (((insn
>> 4) & 3) == 3) {
3996 nregs
= neon_ls_element_type
[op
].nregs
;
3997 interleave
= neon_ls_element_type
[op
].interleave
;
3998 spacing
= neon_ls_element_type
[op
].spacing
;
3999 if (size
== 3 && (interleave
| spacing
) != 1)
4001 addr
= tcg_temp_new_i32();
4002 load_reg_var(s
, addr
, rn
);
4003 stride
= (1 << size
) * interleave
;
4004 for (reg
= 0; reg
< nregs
; reg
++) {
4005 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4006 load_reg_var(s
, addr
, rn
);
4007 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4008 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4009 load_reg_var(s
, addr
, rn
);
4010 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4014 tmp64
= gen_ld64(addr
, IS_USER(s
));
4015 neon_store_reg64(tmp64
, rd
);
4016 tcg_temp_free_i64(tmp64
);
4018 tmp64
= tcg_temp_new_i64();
4019 neon_load_reg64(tmp64
, rd
);
4020 gen_st64(tmp64
, addr
, IS_USER(s
));
4022 tcg_gen_addi_i32(addr
, addr
, stride
);
4024 for (pass
= 0; pass
< 2; pass
++) {
4027 tmp
= gen_ld32(addr
, IS_USER(s
));
4028 neon_store_reg(rd
, pass
, tmp
);
4030 tmp
= neon_load_reg(rd
, pass
);
4031 gen_st32(tmp
, addr
, IS_USER(s
));
4033 tcg_gen_addi_i32(addr
, addr
, stride
);
4034 } else if (size
== 1) {
4036 tmp
= gen_ld16u(addr
, IS_USER(s
));
4037 tcg_gen_addi_i32(addr
, addr
, stride
);
4038 tmp2
= gen_ld16u(addr
, IS_USER(s
));
4039 tcg_gen_addi_i32(addr
, addr
, stride
);
4040 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4041 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4042 tcg_temp_free_i32(tmp2
);
4043 neon_store_reg(rd
, pass
, tmp
);
4045 tmp
= neon_load_reg(rd
, pass
);
4046 tmp2
= tcg_temp_new_i32();
4047 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4048 gen_st16(tmp
, addr
, IS_USER(s
));
4049 tcg_gen_addi_i32(addr
, addr
, stride
);
4050 gen_st16(tmp2
, addr
, IS_USER(s
));
4051 tcg_gen_addi_i32(addr
, addr
, stride
);
4053 } else /* size == 0 */ {
4056 for (n
= 0; n
< 4; n
++) {
4057 tmp
= gen_ld8u(addr
, IS_USER(s
));
4058 tcg_gen_addi_i32(addr
, addr
, stride
);
4062 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4063 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4064 tcg_temp_free_i32(tmp
);
4067 neon_store_reg(rd
, pass
, tmp2
);
4069 tmp2
= neon_load_reg(rd
, pass
);
4070 for (n
= 0; n
< 4; n
++) {
4071 tmp
= tcg_temp_new_i32();
4073 tcg_gen_mov_i32(tmp
, tmp2
);
4075 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4077 gen_st8(tmp
, addr
, IS_USER(s
));
4078 tcg_gen_addi_i32(addr
, addr
, stride
);
4080 tcg_temp_free_i32(tmp2
);
4087 tcg_temp_free_i32(addr
);
4090 size
= (insn
>> 10) & 3;
4092 /* Load single element to all lanes. */
4093 int a
= (insn
>> 4) & 1;
4097 size
= (insn
>> 6) & 3;
4098 nregs
= ((insn
>> 8) & 3) + 1;
4101 if (nregs
!= 4 || a
== 0) {
4104 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4107 if (nregs
== 1 && a
== 1 && size
== 0) {
4110 if (nregs
== 3 && a
== 1) {
4113 addr
= tcg_temp_new_i32();
4114 load_reg_var(s
, addr
, rn
);
4116 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4117 tmp
= gen_load_and_replicate(s
, addr
, size
);
4118 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4119 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4120 if (insn
& (1 << 5)) {
4121 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4122 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4124 tcg_temp_free_i32(tmp
);
4126 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4127 stride
= (insn
& (1 << 5)) ? 2 : 1;
4128 for (reg
= 0; reg
< nregs
; reg
++) {
4129 tmp
= gen_load_and_replicate(s
, addr
, size
);
4130 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4131 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4132 tcg_temp_free_i32(tmp
);
4133 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4137 tcg_temp_free_i32(addr
);
4138 stride
= (1 << size
) * nregs
;
4140 /* Single element. */
4141 int idx
= (insn
>> 4) & 0xf;
4142 pass
= (insn
>> 7) & 1;
4145 shift
= ((insn
>> 5) & 3) * 8;
4149 shift
= ((insn
>> 6) & 1) * 16;
4150 stride
= (insn
& (1 << 5)) ? 2 : 1;
4154 stride
= (insn
& (1 << 6)) ? 2 : 1;
4159 nregs
= ((insn
>> 8) & 3) + 1;
4160 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4163 if (((idx
& (1 << size
)) != 0) ||
4164 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4169 if ((idx
& 1) != 0) {
4174 if (size
== 2 && (idx
& 2) != 0) {
4179 if ((size
== 2) && ((idx
& 3) == 3)) {
4186 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4187 /* Attempts to write off the end of the register file
4188 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4189 * the neon_load_reg() would write off the end of the array.
4193 addr
= tcg_temp_new_i32();
4194 load_reg_var(s
, addr
, rn
);
4195 for (reg
= 0; reg
< nregs
; reg
++) {
4199 tmp
= gen_ld8u(addr
, IS_USER(s
));
4202 tmp
= gen_ld16u(addr
, IS_USER(s
));
4205 tmp
= gen_ld32(addr
, IS_USER(s
));
4207 default: /* Avoid compiler warnings. */
4211 tmp2
= neon_load_reg(rd
, pass
);
4212 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
4213 tcg_temp_free_i32(tmp2
);
4215 neon_store_reg(rd
, pass
, tmp
);
4216 } else { /* Store */
4217 tmp
= neon_load_reg(rd
, pass
);
4219 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4222 gen_st8(tmp
, addr
, IS_USER(s
));
4225 gen_st16(tmp
, addr
, IS_USER(s
));
4228 gen_st32(tmp
, addr
, IS_USER(s
));
4233 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4235 tcg_temp_free_i32(addr
);
4236 stride
= nregs
* (1 << size
);
4242 base
= load_reg(s
, rn
);
4244 tcg_gen_addi_i32(base
, base
, stride
);
4247 index
= load_reg(s
, rm
);
4248 tcg_gen_add_i32(base
, base
, index
);
4249 tcg_temp_free_i32(index
);
4251 store_reg(s
, rn
, base
);
4256 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4257 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4259 tcg_gen_and_i32(t
, t
, c
);
4260 tcg_gen_andc_i32(f
, f
, c
);
4261 tcg_gen_or_i32(dest
, t
, f
);
4264 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4267 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4268 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4269 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4274 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4277 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4278 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4279 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4284 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4287 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4288 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4289 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4294 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4297 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4298 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4299 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4304 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4310 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4311 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4316 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4317 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4324 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4325 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4330 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4331 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4338 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4342 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4343 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4344 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4349 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4350 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4351 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4355 tcg_temp_free_i32(src
);
4358 static inline void gen_neon_addl(int size
)
4361 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4362 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4363 case 2: tcg_gen_add_i64(CPU_V001
); break;
4368 static inline void gen_neon_subl(int size
)
4371 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4372 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4373 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4378 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4381 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4382 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4383 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4388 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4391 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4392 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4397 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4401 switch ((size
<< 1) | u
) {
4402 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4403 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4404 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4405 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4407 tmp
= gen_muls_i64_i32(a
, b
);
4408 tcg_gen_mov_i64(dest
, tmp
);
4409 tcg_temp_free_i64(tmp
);
4412 tmp
= gen_mulu_i64_i32(a
, b
);
4413 tcg_gen_mov_i64(dest
, tmp
);
4414 tcg_temp_free_i64(tmp
);
4419 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4420 Don't forget to clean them now. */
4422 tcg_temp_free_i32(a
);
4423 tcg_temp_free_i32(b
);
4427 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4431 gen_neon_unarrow_sats(size
, dest
, src
);
4433 gen_neon_narrow(size
, dest
, src
);
4437 gen_neon_narrow_satu(size
, dest
, src
);
4439 gen_neon_narrow_sats(size
, dest
, src
);
4444 /* Symbolic constants for op fields for Neon 3-register same-length.
4445 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4448 #define NEON_3R_VHADD 0
4449 #define NEON_3R_VQADD 1
4450 #define NEON_3R_VRHADD 2
4451 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4452 #define NEON_3R_VHSUB 4
4453 #define NEON_3R_VQSUB 5
4454 #define NEON_3R_VCGT 6
4455 #define NEON_3R_VCGE 7
4456 #define NEON_3R_VSHL 8
4457 #define NEON_3R_VQSHL 9
4458 #define NEON_3R_VRSHL 10
4459 #define NEON_3R_VQRSHL 11
4460 #define NEON_3R_VMAX 12
4461 #define NEON_3R_VMIN 13
4462 #define NEON_3R_VABD 14
4463 #define NEON_3R_VABA 15
4464 #define NEON_3R_VADD_VSUB 16
4465 #define NEON_3R_VTST_VCEQ 17
4466 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4467 #define NEON_3R_VMUL 19
4468 #define NEON_3R_VPMAX 20
4469 #define NEON_3R_VPMIN 21
4470 #define NEON_3R_VQDMULH_VQRDMULH 22
4471 #define NEON_3R_VPADD 23
4472 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4473 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4474 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4475 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4476 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4477 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4478 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4480 static const uint8_t neon_3r_sizes
[] = {
4481 [NEON_3R_VHADD
] = 0x7,
4482 [NEON_3R_VQADD
] = 0xf,
4483 [NEON_3R_VRHADD
] = 0x7,
4484 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4485 [NEON_3R_VHSUB
] = 0x7,
4486 [NEON_3R_VQSUB
] = 0xf,
4487 [NEON_3R_VCGT
] = 0x7,
4488 [NEON_3R_VCGE
] = 0x7,
4489 [NEON_3R_VSHL
] = 0xf,
4490 [NEON_3R_VQSHL
] = 0xf,
4491 [NEON_3R_VRSHL
] = 0xf,
4492 [NEON_3R_VQRSHL
] = 0xf,
4493 [NEON_3R_VMAX
] = 0x7,
4494 [NEON_3R_VMIN
] = 0x7,
4495 [NEON_3R_VABD
] = 0x7,
4496 [NEON_3R_VABA
] = 0x7,
4497 [NEON_3R_VADD_VSUB
] = 0xf,
4498 [NEON_3R_VTST_VCEQ
] = 0x7,
4499 [NEON_3R_VML
] = 0x7,
4500 [NEON_3R_VMUL
] = 0x7,
4501 [NEON_3R_VPMAX
] = 0x7,
4502 [NEON_3R_VPMIN
] = 0x7,
4503 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4504 [NEON_3R_VPADD
] = 0x7,
4505 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4506 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4507 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4508 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4509 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4510 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4511 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4514 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4515 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4518 #define NEON_2RM_VREV64 0
4519 #define NEON_2RM_VREV32 1
4520 #define NEON_2RM_VREV16 2
4521 #define NEON_2RM_VPADDL 4
4522 #define NEON_2RM_VPADDL_U 5
4523 #define NEON_2RM_VCLS 8
4524 #define NEON_2RM_VCLZ 9
4525 #define NEON_2RM_VCNT 10
4526 #define NEON_2RM_VMVN 11
4527 #define NEON_2RM_VPADAL 12
4528 #define NEON_2RM_VPADAL_U 13
4529 #define NEON_2RM_VQABS 14
4530 #define NEON_2RM_VQNEG 15
4531 #define NEON_2RM_VCGT0 16
4532 #define NEON_2RM_VCGE0 17
4533 #define NEON_2RM_VCEQ0 18
4534 #define NEON_2RM_VCLE0 19
4535 #define NEON_2RM_VCLT0 20
4536 #define NEON_2RM_VABS 22
4537 #define NEON_2RM_VNEG 23
4538 #define NEON_2RM_VCGT0_F 24
4539 #define NEON_2RM_VCGE0_F 25
4540 #define NEON_2RM_VCEQ0_F 26
4541 #define NEON_2RM_VCLE0_F 27
4542 #define NEON_2RM_VCLT0_F 28
4543 #define NEON_2RM_VABS_F 30
4544 #define NEON_2RM_VNEG_F 31
4545 #define NEON_2RM_VSWP 32
4546 #define NEON_2RM_VTRN 33
4547 #define NEON_2RM_VUZP 34
4548 #define NEON_2RM_VZIP 35
4549 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4550 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4551 #define NEON_2RM_VSHLL 38
4552 #define NEON_2RM_VCVT_F16_F32 44
4553 #define NEON_2RM_VCVT_F32_F16 46
4554 #define NEON_2RM_VRECPE 56
4555 #define NEON_2RM_VRSQRTE 57
4556 #define NEON_2RM_VRECPE_F 58
4557 #define NEON_2RM_VRSQRTE_F 59
4558 #define NEON_2RM_VCVT_FS 60
4559 #define NEON_2RM_VCVT_FU 61
4560 #define NEON_2RM_VCVT_SF 62
4561 #define NEON_2RM_VCVT_UF 63
4563 static int neon_2rm_is_float_op(int op
)
4565 /* Return true if this neon 2reg-misc op is float-to-float */
4566 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4567 op
>= NEON_2RM_VRECPE_F
);
4570 /* Each entry in this array has bit n set if the insn allows
4571 * size value n (otherwise it will UNDEF). Since unallocated
4572 * op values will have no bits set they always UNDEF.
4574 static const uint8_t neon_2rm_sizes
[] = {
4575 [NEON_2RM_VREV64
] = 0x7,
4576 [NEON_2RM_VREV32
] = 0x3,
4577 [NEON_2RM_VREV16
] = 0x1,
4578 [NEON_2RM_VPADDL
] = 0x7,
4579 [NEON_2RM_VPADDL_U
] = 0x7,
4580 [NEON_2RM_VCLS
] = 0x7,
4581 [NEON_2RM_VCLZ
] = 0x7,
4582 [NEON_2RM_VCNT
] = 0x1,
4583 [NEON_2RM_VMVN
] = 0x1,
4584 [NEON_2RM_VPADAL
] = 0x7,
4585 [NEON_2RM_VPADAL_U
] = 0x7,
4586 [NEON_2RM_VQABS
] = 0x7,
4587 [NEON_2RM_VQNEG
] = 0x7,
4588 [NEON_2RM_VCGT0
] = 0x7,
4589 [NEON_2RM_VCGE0
] = 0x7,
4590 [NEON_2RM_VCEQ0
] = 0x7,
4591 [NEON_2RM_VCLE0
] = 0x7,
4592 [NEON_2RM_VCLT0
] = 0x7,
4593 [NEON_2RM_VABS
] = 0x7,
4594 [NEON_2RM_VNEG
] = 0x7,
4595 [NEON_2RM_VCGT0_F
] = 0x4,
4596 [NEON_2RM_VCGE0_F
] = 0x4,
4597 [NEON_2RM_VCEQ0_F
] = 0x4,
4598 [NEON_2RM_VCLE0_F
] = 0x4,
4599 [NEON_2RM_VCLT0_F
] = 0x4,
4600 [NEON_2RM_VABS_F
] = 0x4,
4601 [NEON_2RM_VNEG_F
] = 0x4,
4602 [NEON_2RM_VSWP
] = 0x1,
4603 [NEON_2RM_VTRN
] = 0x7,
4604 [NEON_2RM_VUZP
] = 0x7,
4605 [NEON_2RM_VZIP
] = 0x7,
4606 [NEON_2RM_VMOVN
] = 0x7,
4607 [NEON_2RM_VQMOVN
] = 0x7,
4608 [NEON_2RM_VSHLL
] = 0x7,
4609 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4610 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4611 [NEON_2RM_VRECPE
] = 0x4,
4612 [NEON_2RM_VRSQRTE
] = 0x4,
4613 [NEON_2RM_VRECPE_F
] = 0x4,
4614 [NEON_2RM_VRSQRTE_F
] = 0x4,
4615 [NEON_2RM_VCVT_FS
] = 0x4,
4616 [NEON_2RM_VCVT_FU
] = 0x4,
4617 [NEON_2RM_VCVT_SF
] = 0x4,
4618 [NEON_2RM_VCVT_UF
] = 0x4,
4621 /* Translate a NEON data processing instruction. Return nonzero if the
4622 instruction is invalid.
4623 We process data in a mixture of 32-bit and 64-bit chunks.
4624 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4626 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4638 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4641 if (!s
->vfp_enabled
)
4643 q
= (insn
& (1 << 6)) != 0;
4644 u
= (insn
>> 24) & 1;
4645 VFP_DREG_D(rd
, insn
);
4646 VFP_DREG_N(rn
, insn
);
4647 VFP_DREG_M(rm
, insn
);
4648 size
= (insn
>> 20) & 3;
4649 if ((insn
& (1 << 23)) == 0) {
4650 /* Three register same length. */
4651 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4652 /* Catch invalid op and bad size combinations: UNDEF */
4653 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4656 /* All insns of this form UNDEF for either this condition or the
4657 * superset of cases "Q==1"; we catch the latter later.
4659 if (q
&& ((rd
| rn
| rm
) & 1)) {
4662 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4663 /* 64-bit element instructions. */
4664 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4665 neon_load_reg64(cpu_V0
, rn
+ pass
);
4666 neon_load_reg64(cpu_V1
, rm
+ pass
);
4670 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4673 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4679 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4682 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4688 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4690 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4695 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4698 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4704 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4706 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4709 case NEON_3R_VQRSHL
:
4711 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4714 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4718 case NEON_3R_VADD_VSUB
:
4720 tcg_gen_sub_i64(CPU_V001
);
4722 tcg_gen_add_i64(CPU_V001
);
4728 neon_store_reg64(cpu_V0
, rd
+ pass
);
4737 case NEON_3R_VQRSHL
:
4740 /* Shift instruction operands are reversed. */
4755 case NEON_3R_FLOAT_ARITH
:
4756 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4758 case NEON_3R_FLOAT_MINMAX
:
4759 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4761 case NEON_3R_FLOAT_CMP
:
4763 /* no encoding for U=0 C=1x */
4767 case NEON_3R_FLOAT_ACMP
:
4772 case NEON_3R_VRECPS_VRSQRTS
:
4778 if (u
&& (size
!= 0)) {
4779 /* UNDEF on invalid size for polynomial subcase */
4784 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4792 if (pairwise
&& q
) {
4793 /* All the pairwise insns UNDEF if Q is set */
4797 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4802 tmp
= neon_load_reg(rn
, 0);
4803 tmp2
= neon_load_reg(rn
, 1);
4805 tmp
= neon_load_reg(rm
, 0);
4806 tmp2
= neon_load_reg(rm
, 1);
4810 tmp
= neon_load_reg(rn
, pass
);
4811 tmp2
= neon_load_reg(rm
, pass
);
4815 GEN_NEON_INTEGER_OP(hadd
);
4818 GEN_NEON_INTEGER_OP_ENV(qadd
);
4820 case NEON_3R_VRHADD
:
4821 GEN_NEON_INTEGER_OP(rhadd
);
4823 case NEON_3R_LOGIC
: /* Logic ops. */
4824 switch ((u
<< 2) | size
) {
4826 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4829 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4832 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4835 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4838 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4841 tmp3
= neon_load_reg(rd
, pass
);
4842 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4843 tcg_temp_free_i32(tmp3
);
4846 tmp3
= neon_load_reg(rd
, pass
);
4847 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4848 tcg_temp_free_i32(tmp3
);
4851 tmp3
= neon_load_reg(rd
, pass
);
4852 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4853 tcg_temp_free_i32(tmp3
);
4858 GEN_NEON_INTEGER_OP(hsub
);
4861 GEN_NEON_INTEGER_OP_ENV(qsub
);
4864 GEN_NEON_INTEGER_OP(cgt
);
4867 GEN_NEON_INTEGER_OP(cge
);
4870 GEN_NEON_INTEGER_OP(shl
);
4873 GEN_NEON_INTEGER_OP_ENV(qshl
);
4876 GEN_NEON_INTEGER_OP(rshl
);
4878 case NEON_3R_VQRSHL
:
4879 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4882 GEN_NEON_INTEGER_OP(max
);
4885 GEN_NEON_INTEGER_OP(min
);
4888 GEN_NEON_INTEGER_OP(abd
);
4891 GEN_NEON_INTEGER_OP(abd
);
4892 tcg_temp_free_i32(tmp2
);
4893 tmp2
= neon_load_reg(rd
, pass
);
4894 gen_neon_add(size
, tmp
, tmp2
);
4896 case NEON_3R_VADD_VSUB
:
4897 if (!u
) { /* VADD */
4898 gen_neon_add(size
, tmp
, tmp2
);
4901 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4902 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4903 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4908 case NEON_3R_VTST_VCEQ
:
4909 if (!u
) { /* VTST */
4911 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4912 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4913 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4918 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4919 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4920 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4925 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4927 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4928 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4929 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4932 tcg_temp_free_i32(tmp2
);
4933 tmp2
= neon_load_reg(rd
, pass
);
4935 gen_neon_rsb(size
, tmp
, tmp2
);
4937 gen_neon_add(size
, tmp
, tmp2
);
4941 if (u
) { /* polynomial */
4942 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4943 } else { /* Integer */
4945 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4946 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4947 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4953 GEN_NEON_INTEGER_OP(pmax
);
4956 GEN_NEON_INTEGER_OP(pmin
);
4958 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4959 if (!u
) { /* VQDMULH */
4962 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4965 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4969 } else { /* VQRDMULH */
4972 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4975 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4983 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4984 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4985 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4989 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4991 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4992 switch ((u
<< 2) | size
) {
4995 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4998 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5001 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5006 tcg_temp_free_ptr(fpstatus
);
5009 case NEON_3R_FLOAT_MULTIPLY
:
5011 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5012 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5014 tcg_temp_free_i32(tmp2
);
5015 tmp2
= neon_load_reg(rd
, pass
);
5017 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5019 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5022 tcg_temp_free_ptr(fpstatus
);
5025 case NEON_3R_FLOAT_CMP
:
5027 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5029 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5032 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5034 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5037 tcg_temp_free_ptr(fpstatus
);
5040 case NEON_3R_FLOAT_ACMP
:
5042 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5044 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5046 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5048 tcg_temp_free_ptr(fpstatus
);
5051 case NEON_3R_FLOAT_MINMAX
:
5053 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5055 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
5057 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
5059 tcg_temp_free_ptr(fpstatus
);
5062 case NEON_3R_VRECPS_VRSQRTS
:
5064 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5066 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5070 /* VFMA, VFMS: fused multiply-add */
5071 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5072 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5075 gen_helper_vfp_negs(tmp
, tmp
);
5077 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5078 tcg_temp_free_i32(tmp3
);
5079 tcg_temp_free_ptr(fpstatus
);
5085 tcg_temp_free_i32(tmp2
);
5087 /* Save the result. For elementwise operations we can put it
5088 straight into the destination register. For pairwise operations
5089 we have to be careful to avoid clobbering the source operands. */
5090 if (pairwise
&& rd
== rm
) {
5091 neon_store_scratch(pass
, tmp
);
5093 neon_store_reg(rd
, pass
, tmp
);
5097 if (pairwise
&& rd
== rm
) {
5098 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5099 tmp
= neon_load_scratch(pass
);
5100 neon_store_reg(rd
, pass
, tmp
);
5103 /* End of 3 register same size operations. */
5104 } else if (insn
& (1 << 4)) {
5105 if ((insn
& 0x00380080) != 0) {
5106 /* Two registers and shift. */
5107 op
= (insn
>> 8) & 0xf;
5108 if (insn
& (1 << 7)) {
5116 while ((insn
& (1 << (size
+ 19))) == 0)
5119 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5120 /* To avoid excessive dumplication of ops we implement shift
5121 by immediate using the variable shift operations. */
5123 /* Shift by immediate:
5124 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5125 if (q
&& ((rd
| rm
) & 1)) {
5128 if (!u
&& (op
== 4 || op
== 6)) {
5131 /* Right shifts are encoded as N - shift, where N is the
5132 element size in bits. */
5134 shift
= shift
- (1 << (size
+ 3));
5142 imm
= (uint8_t) shift
;
5147 imm
= (uint16_t) shift
;
5158 for (pass
= 0; pass
< count
; pass
++) {
5160 neon_load_reg64(cpu_V0
, rm
+ pass
);
5161 tcg_gen_movi_i64(cpu_V1
, imm
);
5166 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5168 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5173 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5175 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5178 case 5: /* VSHL, VSLI */
5179 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5181 case 6: /* VQSHLU */
5182 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5187 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5190 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5195 if (op
== 1 || op
== 3) {
5197 neon_load_reg64(cpu_V1
, rd
+ pass
);
5198 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5199 } else if (op
== 4 || (op
== 5 && u
)) {
5201 neon_load_reg64(cpu_V1
, rd
+ pass
);
5203 if (shift
< -63 || shift
> 63) {
5207 mask
= 0xffffffffffffffffull
>> -shift
;
5209 mask
= 0xffffffffffffffffull
<< shift
;
5212 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5213 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5215 neon_store_reg64(cpu_V0
, rd
+ pass
);
5216 } else { /* size < 3 */
5217 /* Operands in T0 and T1. */
5218 tmp
= neon_load_reg(rm
, pass
);
5219 tmp2
= tcg_temp_new_i32();
5220 tcg_gen_movi_i32(tmp2
, imm
);
5224 GEN_NEON_INTEGER_OP(shl
);
5228 GEN_NEON_INTEGER_OP(rshl
);
5231 case 5: /* VSHL, VSLI */
5233 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5234 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5235 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5239 case 6: /* VQSHLU */
5242 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5246 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5250 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5258 GEN_NEON_INTEGER_OP_ENV(qshl
);
5261 tcg_temp_free_i32(tmp2
);
5263 if (op
== 1 || op
== 3) {
5265 tmp2
= neon_load_reg(rd
, pass
);
5266 gen_neon_add(size
, tmp
, tmp2
);
5267 tcg_temp_free_i32(tmp2
);
5268 } else if (op
== 4 || (op
== 5 && u
)) {
5273 mask
= 0xff >> -shift
;
5275 mask
= (uint8_t)(0xff << shift
);
5281 mask
= 0xffff >> -shift
;
5283 mask
= (uint16_t)(0xffff << shift
);
5287 if (shift
< -31 || shift
> 31) {
5291 mask
= 0xffffffffu
>> -shift
;
5293 mask
= 0xffffffffu
<< shift
;
5299 tmp2
= neon_load_reg(rd
, pass
);
5300 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5301 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5302 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5303 tcg_temp_free_i32(tmp2
);
5305 neon_store_reg(rd
, pass
, tmp
);
5308 } else if (op
< 10) {
5309 /* Shift by immediate and narrow:
5310 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5311 int input_unsigned
= (op
== 8) ? !u
: u
;
5315 shift
= shift
- (1 << (size
+ 3));
5318 tmp64
= tcg_const_i64(shift
);
5319 neon_load_reg64(cpu_V0
, rm
);
5320 neon_load_reg64(cpu_V1
, rm
+ 1);
5321 for (pass
= 0; pass
< 2; pass
++) {
5329 if (input_unsigned
) {
5330 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5332 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5335 if (input_unsigned
) {
5336 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5338 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5341 tmp
= tcg_temp_new_i32();
5342 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5343 neon_store_reg(rd
, pass
, tmp
);
5345 tcg_temp_free_i64(tmp64
);
5348 imm
= (uint16_t)shift
;
5352 imm
= (uint32_t)shift
;
5354 tmp2
= tcg_const_i32(imm
);
5355 tmp4
= neon_load_reg(rm
+ 1, 0);
5356 tmp5
= neon_load_reg(rm
+ 1, 1);
5357 for (pass
= 0; pass
< 2; pass
++) {
5359 tmp
= neon_load_reg(rm
, 0);
5363 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5366 tmp3
= neon_load_reg(rm
, 1);
5370 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5372 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5373 tcg_temp_free_i32(tmp
);
5374 tcg_temp_free_i32(tmp3
);
5375 tmp
= tcg_temp_new_i32();
5376 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5377 neon_store_reg(rd
, pass
, tmp
);
5379 tcg_temp_free_i32(tmp2
);
5381 } else if (op
== 10) {
5383 if (q
|| (rd
& 1)) {
5386 tmp
= neon_load_reg(rm
, 0);
5387 tmp2
= neon_load_reg(rm
, 1);
5388 for (pass
= 0; pass
< 2; pass
++) {
5392 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5395 /* The shift is less than the width of the source
5396 type, so we can just shift the whole register. */
5397 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5398 /* Widen the result of shift: we need to clear
5399 * the potential overflow bits resulting from
5400 * left bits of the narrow input appearing as
5401 * right bits of left the neighbour narrow
5403 if (size
< 2 || !u
) {
5406 imm
= (0xffu
>> (8 - shift
));
5408 } else if (size
== 1) {
5409 imm
= 0xffff >> (16 - shift
);
5412 imm
= 0xffffffff >> (32 - shift
);
5415 imm64
= imm
| (((uint64_t)imm
) << 32);
5419 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5422 neon_store_reg64(cpu_V0
, rd
+ pass
);
5424 } else if (op
>= 14) {
5425 /* VCVT fixed-point. */
5426 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5429 /* We have already masked out the must-be-1 top bit of imm6,
5430 * hence this 32-shift where the ARM ARM has 64-imm6.
5433 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5434 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5437 gen_vfp_ulto(0, shift
, 1);
5439 gen_vfp_slto(0, shift
, 1);
5442 gen_vfp_toul(0, shift
, 1);
5444 gen_vfp_tosl(0, shift
, 1);
5446 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5451 } else { /* (insn & 0x00380080) == 0 */
5453 if (q
&& (rd
& 1)) {
5457 op
= (insn
>> 8) & 0xf;
5458 /* One register and immediate. */
5459 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5460 invert
= (insn
& (1 << 5)) != 0;
5461 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5462 * We choose to not special-case this and will behave as if a
5463 * valid constant encoding of 0 had been given.
5482 imm
= (imm
<< 8) | (imm
<< 24);
5485 imm
= (imm
<< 8) | 0xff;
5488 imm
= (imm
<< 16) | 0xffff;
5491 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5499 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5500 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5506 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5507 if (op
& 1 && op
< 12) {
5508 tmp
= neon_load_reg(rd
, pass
);
5510 /* The immediate value has already been inverted, so
5512 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5514 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5518 tmp
= tcg_temp_new_i32();
5519 if (op
== 14 && invert
) {
5523 for (n
= 0; n
< 4; n
++) {
5524 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5525 val
|= 0xff << (n
* 8);
5527 tcg_gen_movi_i32(tmp
, val
);
5529 tcg_gen_movi_i32(tmp
, imm
);
5532 neon_store_reg(rd
, pass
, tmp
);
5535 } else { /* (insn & 0x00800010 == 0x00800000) */
5537 op
= (insn
>> 8) & 0xf;
5538 if ((insn
& (1 << 6)) == 0) {
5539 /* Three registers of different lengths. */
5543 /* undefreq: bit 0 : UNDEF if size != 0
5544 * bit 1 : UNDEF if size == 0
5545 * bit 2 : UNDEF if U == 1
5546 * Note that [1:0] set implies 'always UNDEF'
5549 /* prewiden, src1_wide, src2_wide, undefreq */
5550 static const int neon_3reg_wide
[16][4] = {
5551 {1, 0, 0, 0}, /* VADDL */
5552 {1, 1, 0, 0}, /* VADDW */
5553 {1, 0, 0, 0}, /* VSUBL */
5554 {1, 1, 0, 0}, /* VSUBW */
5555 {0, 1, 1, 0}, /* VADDHN */
5556 {0, 0, 0, 0}, /* VABAL */
5557 {0, 1, 1, 0}, /* VSUBHN */
5558 {0, 0, 0, 0}, /* VABDL */
5559 {0, 0, 0, 0}, /* VMLAL */
5560 {0, 0, 0, 6}, /* VQDMLAL */
5561 {0, 0, 0, 0}, /* VMLSL */
5562 {0, 0, 0, 6}, /* VQDMLSL */
5563 {0, 0, 0, 0}, /* Integer VMULL */
5564 {0, 0, 0, 2}, /* VQDMULL */
5565 {0, 0, 0, 5}, /* Polynomial VMULL */
5566 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5569 prewiden
= neon_3reg_wide
[op
][0];
5570 src1_wide
= neon_3reg_wide
[op
][1];
5571 src2_wide
= neon_3reg_wide
[op
][2];
5572 undefreq
= neon_3reg_wide
[op
][3];
5574 if (((undefreq
& 1) && (size
!= 0)) ||
5575 ((undefreq
& 2) && (size
== 0)) ||
5576 ((undefreq
& 4) && u
)) {
5579 if ((src1_wide
&& (rn
& 1)) ||
5580 (src2_wide
&& (rm
& 1)) ||
5581 (!src2_wide
&& (rd
& 1))) {
5585 /* Avoid overlapping operands. Wide source operands are
5586 always aligned so will never overlap with wide
5587 destinations in problematic ways. */
5588 if (rd
== rm
&& !src2_wide
) {
5589 tmp
= neon_load_reg(rm
, 1);
5590 neon_store_scratch(2, tmp
);
5591 } else if (rd
== rn
&& !src1_wide
) {
5592 tmp
= neon_load_reg(rn
, 1);
5593 neon_store_scratch(2, tmp
);
5596 for (pass
= 0; pass
< 2; pass
++) {
5598 neon_load_reg64(cpu_V0
, rn
+ pass
);
5601 if (pass
== 1 && rd
== rn
) {
5602 tmp
= neon_load_scratch(2);
5604 tmp
= neon_load_reg(rn
, pass
);
5607 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5611 neon_load_reg64(cpu_V1
, rm
+ pass
);
5614 if (pass
== 1 && rd
== rm
) {
5615 tmp2
= neon_load_scratch(2);
5617 tmp2
= neon_load_reg(rm
, pass
);
5620 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5624 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5625 gen_neon_addl(size
);
5627 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5628 gen_neon_subl(size
);
5630 case 5: case 7: /* VABAL, VABDL */
5631 switch ((size
<< 1) | u
) {
5633 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5636 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5639 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5642 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5645 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5648 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5652 tcg_temp_free_i32(tmp2
);
5653 tcg_temp_free_i32(tmp
);
5655 case 8: case 9: case 10: case 11: case 12: case 13:
5656 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5657 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5659 case 14: /* Polynomial VMULL */
5660 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5661 tcg_temp_free_i32(tmp2
);
5662 tcg_temp_free_i32(tmp
);
5664 default: /* 15 is RESERVED: caught earlier */
5669 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5670 neon_store_reg64(cpu_V0
, rd
+ pass
);
5671 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5673 neon_load_reg64(cpu_V1
, rd
+ pass
);
5675 case 10: /* VMLSL */
5676 gen_neon_negl(cpu_V0
, size
);
5678 case 5: case 8: /* VABAL, VMLAL */
5679 gen_neon_addl(size
);
5681 case 9: case 11: /* VQDMLAL, VQDMLSL */
5682 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5684 gen_neon_negl(cpu_V0
, size
);
5686 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5691 neon_store_reg64(cpu_V0
, rd
+ pass
);
5692 } else if (op
== 4 || op
== 6) {
5693 /* Narrowing operation. */
5694 tmp
= tcg_temp_new_i32();
5698 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5701 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5704 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5705 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5712 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5715 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5718 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5719 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5720 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5728 neon_store_reg(rd
, 0, tmp3
);
5729 neon_store_reg(rd
, 1, tmp
);
5732 /* Write back the result. */
5733 neon_store_reg64(cpu_V0
, rd
+ pass
);
5737 /* Two registers and a scalar. NB that for ops of this form
5738 * the ARM ARM labels bit 24 as Q, but it is in our variable
5745 case 1: /* Float VMLA scalar */
5746 case 5: /* Floating point VMLS scalar */
5747 case 9: /* Floating point VMUL scalar */
5752 case 0: /* Integer VMLA scalar */
5753 case 4: /* Integer VMLS scalar */
5754 case 8: /* Integer VMUL scalar */
5755 case 12: /* VQDMULH scalar */
5756 case 13: /* VQRDMULH scalar */
5757 if (u
&& ((rd
| rn
) & 1)) {
5760 tmp
= neon_get_scalar(size
, rm
);
5761 neon_store_scratch(0, tmp
);
5762 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5763 tmp
= neon_load_scratch(0);
5764 tmp2
= neon_load_reg(rn
, pass
);
5767 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5769 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5771 } else if (op
== 13) {
5773 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5775 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5777 } else if (op
& 1) {
5778 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5779 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5780 tcg_temp_free_ptr(fpstatus
);
5783 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5784 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5785 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5789 tcg_temp_free_i32(tmp2
);
5792 tmp2
= neon_load_reg(rd
, pass
);
5795 gen_neon_add(size
, tmp
, tmp2
);
5799 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5800 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5801 tcg_temp_free_ptr(fpstatus
);
5805 gen_neon_rsb(size
, tmp
, tmp2
);
5809 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5810 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5811 tcg_temp_free_ptr(fpstatus
);
5817 tcg_temp_free_i32(tmp2
);
5819 neon_store_reg(rd
, pass
, tmp
);
5822 case 3: /* VQDMLAL scalar */
5823 case 7: /* VQDMLSL scalar */
5824 case 11: /* VQDMULL scalar */
5829 case 2: /* VMLAL sclar */
5830 case 6: /* VMLSL scalar */
5831 case 10: /* VMULL scalar */
5835 tmp2
= neon_get_scalar(size
, rm
);
5836 /* We need a copy of tmp2 because gen_neon_mull
5837 * deletes it during pass 0. */
5838 tmp4
= tcg_temp_new_i32();
5839 tcg_gen_mov_i32(tmp4
, tmp2
);
5840 tmp3
= neon_load_reg(rn
, 1);
5842 for (pass
= 0; pass
< 2; pass
++) {
5844 tmp
= neon_load_reg(rn
, 0);
5849 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5851 neon_load_reg64(cpu_V1
, rd
+ pass
);
5855 gen_neon_negl(cpu_V0
, size
);
5858 gen_neon_addl(size
);
5861 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5863 gen_neon_negl(cpu_V0
, size
);
5865 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5871 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5876 neon_store_reg64(cpu_V0
, rd
+ pass
);
5881 default: /* 14 and 15 are RESERVED */
5885 } else { /* size == 3 */
5888 imm
= (insn
>> 8) & 0xf;
5893 if (q
&& ((rd
| rn
| rm
) & 1)) {
5898 neon_load_reg64(cpu_V0
, rn
);
5900 neon_load_reg64(cpu_V1
, rn
+ 1);
5902 } else if (imm
== 8) {
5903 neon_load_reg64(cpu_V0
, rn
+ 1);
5905 neon_load_reg64(cpu_V1
, rm
);
5908 tmp64
= tcg_temp_new_i64();
5910 neon_load_reg64(cpu_V0
, rn
);
5911 neon_load_reg64(tmp64
, rn
+ 1);
5913 neon_load_reg64(cpu_V0
, rn
+ 1);
5914 neon_load_reg64(tmp64
, rm
);
5916 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5917 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5918 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5920 neon_load_reg64(cpu_V1
, rm
);
5922 neon_load_reg64(cpu_V1
, rm
+ 1);
5925 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5926 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5927 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5928 tcg_temp_free_i64(tmp64
);
5931 neon_load_reg64(cpu_V0
, rn
);
5932 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5933 neon_load_reg64(cpu_V1
, rm
);
5934 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5935 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5937 neon_store_reg64(cpu_V0
, rd
);
5939 neon_store_reg64(cpu_V1
, rd
+ 1);
5941 } else if ((insn
& (1 << 11)) == 0) {
5942 /* Two register misc. */
5943 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5944 size
= (insn
>> 18) & 3;
5945 /* UNDEF for unknown op values and bad op-size combinations */
5946 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5949 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5950 q
&& ((rm
| rd
) & 1)) {
5954 case NEON_2RM_VREV64
:
5955 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5956 tmp
= neon_load_reg(rm
, pass
* 2);
5957 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5959 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5960 case 1: gen_swap_half(tmp
); break;
5961 case 2: /* no-op */ break;
5964 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5966 neon_store_reg(rd
, pass
* 2, tmp2
);
5969 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5970 case 1: gen_swap_half(tmp2
); break;
5973 neon_store_reg(rd
, pass
* 2, tmp2
);
5977 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5978 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5979 for (pass
= 0; pass
< q
+ 1; pass
++) {
5980 tmp
= neon_load_reg(rm
, pass
* 2);
5981 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5982 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5983 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5985 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5986 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5987 case 2: tcg_gen_add_i64(CPU_V001
); break;
5990 if (op
>= NEON_2RM_VPADAL
) {
5992 neon_load_reg64(cpu_V1
, rd
+ pass
);
5993 gen_neon_addl(size
);
5995 neon_store_reg64(cpu_V0
, rd
+ pass
);
6001 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6002 tmp
= neon_load_reg(rm
, n
);
6003 tmp2
= neon_load_reg(rd
, n
+ 1);
6004 neon_store_reg(rm
, n
, tmp2
);
6005 neon_store_reg(rd
, n
+ 1, tmp
);
6012 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6017 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6021 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6022 /* also VQMOVUN; op field and mnemonics don't line up */
6027 for (pass
= 0; pass
< 2; pass
++) {
6028 neon_load_reg64(cpu_V0
, rm
+ pass
);
6029 tmp
= tcg_temp_new_i32();
6030 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6035 neon_store_reg(rd
, 0, tmp2
);
6036 neon_store_reg(rd
, 1, tmp
);
6040 case NEON_2RM_VSHLL
:
6041 if (q
|| (rd
& 1)) {
6044 tmp
= neon_load_reg(rm
, 0);
6045 tmp2
= neon_load_reg(rm
, 1);
6046 for (pass
= 0; pass
< 2; pass
++) {
6049 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6050 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6051 neon_store_reg64(cpu_V0
, rd
+ pass
);
6054 case NEON_2RM_VCVT_F16_F32
:
6055 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6059 tmp
= tcg_temp_new_i32();
6060 tmp2
= tcg_temp_new_i32();
6061 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6062 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6063 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6064 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6065 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6066 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6067 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6068 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6069 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6070 neon_store_reg(rd
, 0, tmp2
);
6071 tmp2
= tcg_temp_new_i32();
6072 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6073 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6074 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6075 neon_store_reg(rd
, 1, tmp2
);
6076 tcg_temp_free_i32(tmp
);
6078 case NEON_2RM_VCVT_F32_F16
:
6079 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6083 tmp3
= tcg_temp_new_i32();
6084 tmp
= neon_load_reg(rm
, 0);
6085 tmp2
= neon_load_reg(rm
, 1);
6086 tcg_gen_ext16u_i32(tmp3
, tmp
);
6087 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6088 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6089 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6090 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6091 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6092 tcg_temp_free_i32(tmp
);
6093 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6094 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6095 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6096 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6097 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6098 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6099 tcg_temp_free_i32(tmp2
);
6100 tcg_temp_free_i32(tmp3
);
6104 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6105 if (neon_2rm_is_float_op(op
)) {
6106 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6107 neon_reg_offset(rm
, pass
));
6110 tmp
= neon_load_reg(rm
, pass
);
6113 case NEON_2RM_VREV32
:
6115 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6116 case 1: gen_swap_half(tmp
); break;
6120 case NEON_2RM_VREV16
:
6125 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6126 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6127 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6133 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6134 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6135 case 2: gen_helper_clz(tmp
, tmp
); break;
6140 gen_helper_neon_cnt_u8(tmp
, tmp
);
6143 tcg_gen_not_i32(tmp
, tmp
);
6145 case NEON_2RM_VQABS
:
6148 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6151 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6154 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6159 case NEON_2RM_VQNEG
:
6162 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6165 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6168 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6173 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6174 tmp2
= tcg_const_i32(0);
6176 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6177 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6178 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6181 tcg_temp_free(tmp2
);
6182 if (op
== NEON_2RM_VCLE0
) {
6183 tcg_gen_not_i32(tmp
, tmp
);
6186 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6187 tmp2
= tcg_const_i32(0);
6189 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6190 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6191 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6194 tcg_temp_free(tmp2
);
6195 if (op
== NEON_2RM_VCLT0
) {
6196 tcg_gen_not_i32(tmp
, tmp
);
6199 case NEON_2RM_VCEQ0
:
6200 tmp2
= tcg_const_i32(0);
6202 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6203 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6204 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6207 tcg_temp_free(tmp2
);
6211 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6212 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6213 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6218 tmp2
= tcg_const_i32(0);
6219 gen_neon_rsb(size
, tmp
, tmp2
);
6220 tcg_temp_free(tmp2
);
6222 case NEON_2RM_VCGT0_F
:
6224 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6225 tmp2
= tcg_const_i32(0);
6226 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6227 tcg_temp_free(tmp2
);
6228 tcg_temp_free_ptr(fpstatus
);
6231 case NEON_2RM_VCGE0_F
:
6233 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6234 tmp2
= tcg_const_i32(0);
6235 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6236 tcg_temp_free(tmp2
);
6237 tcg_temp_free_ptr(fpstatus
);
6240 case NEON_2RM_VCEQ0_F
:
6242 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6243 tmp2
= tcg_const_i32(0);
6244 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6245 tcg_temp_free(tmp2
);
6246 tcg_temp_free_ptr(fpstatus
);
6249 case NEON_2RM_VCLE0_F
:
6251 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6252 tmp2
= tcg_const_i32(0);
6253 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6254 tcg_temp_free(tmp2
);
6255 tcg_temp_free_ptr(fpstatus
);
6258 case NEON_2RM_VCLT0_F
:
6260 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6261 tmp2
= tcg_const_i32(0);
6262 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6263 tcg_temp_free(tmp2
);
6264 tcg_temp_free_ptr(fpstatus
);
6267 case NEON_2RM_VABS_F
:
6270 case NEON_2RM_VNEG_F
:
6274 tmp2
= neon_load_reg(rd
, pass
);
6275 neon_store_reg(rm
, pass
, tmp2
);
6278 tmp2
= neon_load_reg(rd
, pass
);
6280 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6281 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6284 neon_store_reg(rm
, pass
, tmp2
);
6286 case NEON_2RM_VRECPE
:
6287 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6289 case NEON_2RM_VRSQRTE
:
6290 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6292 case NEON_2RM_VRECPE_F
:
6293 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6295 case NEON_2RM_VRSQRTE_F
:
6296 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6298 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6301 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6304 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6305 gen_vfp_tosiz(0, 1);
6307 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6308 gen_vfp_touiz(0, 1);
6311 /* Reserved op values were caught by the
6312 * neon_2rm_sizes[] check earlier.
6316 if (neon_2rm_is_float_op(op
)) {
6317 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6318 neon_reg_offset(rd
, pass
));
6320 neon_store_reg(rd
, pass
, tmp
);
6325 } else if ((insn
& (1 << 10)) == 0) {
6327 int n
= ((insn
>> 8) & 3) + 1;
6328 if ((rn
+ n
) > 32) {
6329 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6330 * helper function running off the end of the register file.
6335 if (insn
& (1 << 6)) {
6336 tmp
= neon_load_reg(rd
, 0);
6338 tmp
= tcg_temp_new_i32();
6339 tcg_gen_movi_i32(tmp
, 0);
6341 tmp2
= neon_load_reg(rm
, 0);
6342 tmp4
= tcg_const_i32(rn
);
6343 tmp5
= tcg_const_i32(n
);
6344 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
6345 tcg_temp_free_i32(tmp
);
6346 if (insn
& (1 << 6)) {
6347 tmp
= neon_load_reg(rd
, 1);
6349 tmp
= tcg_temp_new_i32();
6350 tcg_gen_movi_i32(tmp
, 0);
6352 tmp3
= neon_load_reg(rm
, 1);
6353 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
6354 tcg_temp_free_i32(tmp5
);
6355 tcg_temp_free_i32(tmp4
);
6356 neon_store_reg(rd
, 0, tmp2
);
6357 neon_store_reg(rd
, 1, tmp3
);
6358 tcg_temp_free_i32(tmp
);
6359 } else if ((insn
& 0x380) == 0) {
6361 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6364 if (insn
& (1 << 19)) {
6365 tmp
= neon_load_reg(rm
, 1);
6367 tmp
= neon_load_reg(rm
, 0);
6369 if (insn
& (1 << 16)) {
6370 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6371 } else if (insn
& (1 << 17)) {
6372 if ((insn
>> 18) & 1)
6373 gen_neon_dup_high16(tmp
);
6375 gen_neon_dup_low16(tmp
);
6377 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6378 tmp2
= tcg_temp_new_i32();
6379 tcg_gen_mov_i32(tmp2
, tmp
);
6380 neon_store_reg(rd
, pass
, tmp2
);
6382 tcg_temp_free_i32(tmp
);
6391 static int disas_cp14_read(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6393 int crn
= (insn
>> 16) & 0xf;
6394 int crm
= insn
& 0xf;
6395 int op1
= (insn
>> 21) & 7;
6396 int op2
= (insn
>> 5) & 7;
6397 int rt
= (insn
>> 12) & 0xf;
6400 /* Minimal set of debug registers, since we don't support debug */
6401 if (op1
== 0 && crn
== 0 && op2
== 0) {
6404 /* DBGDIDR: just RAZ. In particular this means the
6405 * "debug architecture version" bits will read as
6406 * a reserved value, which should cause Linux to
6407 * not try to use the debug hardware.
6409 tmp
= tcg_const_i32(0);
6410 store_reg(s
, rt
, tmp
);
6414 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
6415 * don't implement memory mapped debug components
6417 if (ENABLE_ARCH_7
) {
6418 tmp
= tcg_const_i32(0);
6419 store_reg(s
, rt
, tmp
);
6428 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6429 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6433 tmp
= load_cpu_field(teecr
);
6434 store_reg(s
, rt
, tmp
);
6437 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6439 if (IS_USER(s
) && (env
->teecr
& 1))
6441 tmp
= load_cpu_field(teehbr
);
6442 store_reg(s
, rt
, tmp
);
6449 static int disas_cp14_write(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6451 int crn
= (insn
>> 16) & 0xf;
6452 int crm
= insn
& 0xf;
6453 int op1
= (insn
>> 21) & 7;
6454 int op2
= (insn
>> 5) & 7;
6455 int rt
= (insn
>> 12) & 0xf;
6458 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6459 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6463 tmp
= load_reg(s
, rt
);
6464 gen_helper_set_teecr(cpu_env
, tmp
);
6465 tcg_temp_free_i32(tmp
);
6468 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6470 if (IS_USER(s
) && (env
->teecr
& 1))
6472 tmp
= load_reg(s
, rt
);
6473 store_cpu_field(tmp
, teehbr
);
6480 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6484 cpnum
= (insn
>> 8) & 0xf;
6485 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6486 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6492 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6493 return disas_iwmmxt_insn(env
, s
, insn
);
6494 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6495 return disas_dsp_insn(env
, s
, insn
);
6500 return disas_vfp_insn (env
, s
, insn
);
6502 /* Coprocessors 7-15 are architecturally reserved by ARM.
6503 Unfortunately Intel decided to ignore this. */
6504 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
6506 if (insn
& (1 << 20))
6507 return disas_cp14_read(env
, s
, insn
);
6509 return disas_cp14_write(env
, s
, insn
);
6511 return disas_cp15_insn (env
, s
, insn
);
6514 /* Unknown coprocessor. See if the board has hooked it. */
6515 return disas_cp_insn (env
, s
, insn
);
6520 /* Store a 64-bit value to a register pair. Clobbers val. */
6521 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6524 tmp
= tcg_temp_new_i32();
6525 tcg_gen_trunc_i64_i32(tmp
, val
);
6526 store_reg(s
, rlow
, tmp
);
6527 tmp
= tcg_temp_new_i32();
6528 tcg_gen_shri_i64(val
, val
, 32);
6529 tcg_gen_trunc_i64_i32(tmp
, val
);
6530 store_reg(s
, rhigh
, tmp
);
6533 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6534 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6539 /* Load value and extend to 64 bits. */
6540 tmp
= tcg_temp_new_i64();
6541 tmp2
= load_reg(s
, rlow
);
6542 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6543 tcg_temp_free_i32(tmp2
);
6544 tcg_gen_add_i64(val
, val
, tmp
);
6545 tcg_temp_free_i64(tmp
);
6548 /* load and add a 64-bit value from a register pair. */
6549 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6555 /* Load 64-bit value rd:rn. */
6556 tmpl
= load_reg(s
, rlow
);
6557 tmph
= load_reg(s
, rhigh
);
6558 tmp
= tcg_temp_new_i64();
6559 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6560 tcg_temp_free_i32(tmpl
);
6561 tcg_temp_free_i32(tmph
);
6562 tcg_gen_add_i64(val
, val
, tmp
);
6563 tcg_temp_free_i64(tmp
);
6566 /* Set N and Z flags from a 64-bit value. */
6567 static void gen_logicq_cc(TCGv_i64 val
)
6569 TCGv tmp
= tcg_temp_new_i32();
6570 gen_helper_logicq_cc(tmp
, val
);
6572 tcg_temp_free_i32(tmp
);
6575 /* Load/Store exclusive instructions are implemented by remembering
6576 the value/address loaded, and seeing if these are the same
6577 when the store is performed. This should be is sufficient to implement
6578 the architecturally mandated semantics, and avoids having to monitor
6581 In system emulation mode only one CPU will be running at once, so
6582 this sequence is effectively atomic. In user emulation mode we
6583 throw an exception and handle the atomic operation elsewhere. */
6584 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6585 TCGv addr
, int size
)
6591 tmp
= gen_ld8u(addr
, IS_USER(s
));
6594 tmp
= gen_ld16u(addr
, IS_USER(s
));
6598 tmp
= gen_ld32(addr
, IS_USER(s
));
6603 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6604 store_reg(s
, rt
, tmp
);
6606 TCGv tmp2
= tcg_temp_new_i32();
6607 tcg_gen_addi_i32(tmp2
, addr
, 4);
6608 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6609 tcg_temp_free_i32(tmp2
);
6610 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6611 store_reg(s
, rt2
, tmp
);
6613 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6616 static void gen_clrex(DisasContext
*s
)
6618 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6621 #ifdef CONFIG_USER_ONLY
6622 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6623 TCGv addr
, int size
)
6625 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6626 tcg_gen_movi_i32(cpu_exclusive_info
,
6627 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6628 gen_exception_insn(s
, 4, EXCP_STREX
);
6631 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6632 TCGv addr
, int size
)
6638 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6644 fail_label
= gen_new_label();
6645 done_label
= gen_new_label();
6646 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6649 tmp
= gen_ld8u(addr
, IS_USER(s
));
6652 tmp
= gen_ld16u(addr
, IS_USER(s
));
6656 tmp
= gen_ld32(addr
, IS_USER(s
));
6661 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6662 tcg_temp_free_i32(tmp
);
6664 TCGv tmp2
= tcg_temp_new_i32();
6665 tcg_gen_addi_i32(tmp2
, addr
, 4);
6666 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6667 tcg_temp_free_i32(tmp2
);
6668 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6669 tcg_temp_free_i32(tmp
);
6671 tmp
= load_reg(s
, rt
);
6674 gen_st8(tmp
, addr
, IS_USER(s
));
6677 gen_st16(tmp
, addr
, IS_USER(s
));
6681 gen_st32(tmp
, addr
, IS_USER(s
));
6687 tcg_gen_addi_i32(addr
, addr
, 4);
6688 tmp
= load_reg(s
, rt2
);
6689 gen_st32(tmp
, addr
, IS_USER(s
));
6691 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6692 tcg_gen_br(done_label
);
6693 gen_set_label(fail_label
);
6694 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6695 gen_set_label(done_label
);
6696 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6700 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6702 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6709 insn
= arm_ldl_code(s
->pc
, s
->bswap_code
);
6712 /* M variants do not implement ARM mode. */
6717 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6718 * choose to UNDEF. In ARMv5 and above the space is used
6719 * for miscellaneous unconditional instructions.
6723 /* Unconditional instructions. */
6724 if (((insn
>> 25) & 7) == 1) {
6725 /* NEON Data processing. */
6726 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6729 if (disas_neon_data_insn(env
, s
, insn
))
6733 if ((insn
& 0x0f100000) == 0x04000000) {
6734 /* NEON load/store. */
6735 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6738 if (disas_neon_ls_insn(env
, s
, insn
))
6742 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6743 ((insn
& 0x0f30f010) == 0x0710f000)) {
6744 if ((insn
& (1 << 22)) == 0) {
6746 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6750 /* Otherwise PLD; v5TE+ */
6754 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6755 ((insn
& 0x0f70f010) == 0x0650f000)) {
6757 return; /* PLI; V7 */
6759 if (((insn
& 0x0f700000) == 0x04100000) ||
6760 ((insn
& 0x0f700010) == 0x06100000)) {
6761 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6764 return; /* v7MP: Unallocated memory hint: must NOP */
6767 if ((insn
& 0x0ffffdff) == 0x01010000) {
6770 if (insn
& (1 << 9)) {
6771 /* BE8 mode not implemented. */
6775 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6776 switch ((insn
>> 4) & 0xf) {
6785 /* We don't emulate caches so these are a no-op. */
6790 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6796 op1
= (insn
& 0x1f);
6797 addr
= tcg_temp_new_i32();
6798 tmp
= tcg_const_i32(op1
);
6799 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6800 tcg_temp_free_i32(tmp
);
6801 i
= (insn
>> 23) & 3;
6803 case 0: offset
= -4; break; /* DA */
6804 case 1: offset
= 0; break; /* IA */
6805 case 2: offset
= -8; break; /* DB */
6806 case 3: offset
= 4; break; /* IB */
6810 tcg_gen_addi_i32(addr
, addr
, offset
);
6811 tmp
= load_reg(s
, 14);
6812 gen_st32(tmp
, addr
, 0);
6813 tmp
= load_cpu_field(spsr
);
6814 tcg_gen_addi_i32(addr
, addr
, 4);
6815 gen_st32(tmp
, addr
, 0);
6816 if (insn
& (1 << 21)) {
6817 /* Base writeback. */
6819 case 0: offset
= -8; break;
6820 case 1: offset
= 4; break;
6821 case 2: offset
= -4; break;
6822 case 3: offset
= 0; break;
6826 tcg_gen_addi_i32(addr
, addr
, offset
);
6827 tmp
= tcg_const_i32(op1
);
6828 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6829 tcg_temp_free_i32(tmp
);
6830 tcg_temp_free_i32(addr
);
6832 tcg_temp_free_i32(addr
);
6835 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6841 rn
= (insn
>> 16) & 0xf;
6842 addr
= load_reg(s
, rn
);
6843 i
= (insn
>> 23) & 3;
6845 case 0: offset
= -4; break; /* DA */
6846 case 1: offset
= 0; break; /* IA */
6847 case 2: offset
= -8; break; /* DB */
6848 case 3: offset
= 4; break; /* IB */
6852 tcg_gen_addi_i32(addr
, addr
, offset
);
6853 /* Load PC into tmp and CPSR into tmp2. */
6854 tmp
= gen_ld32(addr
, 0);
6855 tcg_gen_addi_i32(addr
, addr
, 4);
6856 tmp2
= gen_ld32(addr
, 0);
6857 if (insn
& (1 << 21)) {
6858 /* Base writeback. */
6860 case 0: offset
= -8; break;
6861 case 1: offset
= 4; break;
6862 case 2: offset
= -4; break;
6863 case 3: offset
= 0; break;
6867 tcg_gen_addi_i32(addr
, addr
, offset
);
6868 store_reg(s
, rn
, addr
);
6870 tcg_temp_free_i32(addr
);
6872 gen_rfe(s
, tmp
, tmp2
);
6874 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6875 /* branch link and change to thumb (blx <offset>) */
6878 val
= (uint32_t)s
->pc
;
6879 tmp
= tcg_temp_new_i32();
6880 tcg_gen_movi_i32(tmp
, val
);
6881 store_reg(s
, 14, tmp
);
6882 /* Sign-extend the 24-bit offset */
6883 offset
= (((int32_t)insn
) << 8) >> 8;
6884 /* offset * 4 + bit24 * 2 + (thumb bit) */
6885 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6886 /* pipeline offset */
6888 /* protected by ARCH(5); above, near the start of uncond block */
6891 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6892 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6893 /* iWMMXt register transfer. */
6894 if (env
->cp15
.c15_cpar
& (1 << 1))
6895 if (!disas_iwmmxt_insn(env
, s
, insn
))
6898 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6899 /* Coprocessor double register transfer. */
6901 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6902 /* Additional coprocessor register transfer. */
6903 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6906 /* cps (privileged) */
6910 if (insn
& (1 << 19)) {
6911 if (insn
& (1 << 8))
6913 if (insn
& (1 << 7))
6915 if (insn
& (1 << 6))
6917 if (insn
& (1 << 18))
6920 if (insn
& (1 << 17)) {
6922 val
|= (insn
& 0x1f);
6925 gen_set_psr_im(s
, mask
, 0, val
);
6932 /* if not always execute, we generate a conditional jump to
6934 s
->condlabel
= gen_new_label();
6935 gen_test_cc(cond
^ 1, s
->condlabel
);
6938 if ((insn
& 0x0f900000) == 0x03000000) {
6939 if ((insn
& (1 << 21)) == 0) {
6941 rd
= (insn
>> 12) & 0xf;
6942 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6943 if ((insn
& (1 << 22)) == 0) {
6945 tmp
= tcg_temp_new_i32();
6946 tcg_gen_movi_i32(tmp
, val
);
6949 tmp
= load_reg(s
, rd
);
6950 tcg_gen_ext16u_i32(tmp
, tmp
);
6951 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6953 store_reg(s
, rd
, tmp
);
6955 if (((insn
>> 12) & 0xf) != 0xf)
6957 if (((insn
>> 16) & 0xf) == 0) {
6958 gen_nop_hint(s
, insn
& 0xff);
6960 /* CPSR = immediate */
6962 shift
= ((insn
>> 8) & 0xf) * 2;
6964 val
= (val
>> shift
) | (val
<< (32 - shift
));
6965 i
= ((insn
& (1 << 22)) != 0);
6966 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6970 } else if ((insn
& 0x0f900000) == 0x01000000
6971 && (insn
& 0x00000090) != 0x00000090) {
6972 /* miscellaneous instructions */
6973 op1
= (insn
>> 21) & 3;
6974 sh
= (insn
>> 4) & 0xf;
6977 case 0x0: /* move program status register */
6980 tmp
= load_reg(s
, rm
);
6981 i
= ((op1
& 2) != 0);
6982 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6986 rd
= (insn
>> 12) & 0xf;
6990 tmp
= load_cpu_field(spsr
);
6992 tmp
= tcg_temp_new_i32();
6993 gen_helper_cpsr_read(tmp
);
6995 store_reg(s
, rd
, tmp
);
7000 /* branch/exchange thumb (bx). */
7002 tmp
= load_reg(s
, rm
);
7004 } else if (op1
== 3) {
7007 rd
= (insn
>> 12) & 0xf;
7008 tmp
= load_reg(s
, rm
);
7009 gen_helper_clz(tmp
, tmp
);
7010 store_reg(s
, rd
, tmp
);
7018 /* Trivial implementation equivalent to bx. */
7019 tmp
= load_reg(s
, rm
);
7030 /* branch link/exchange thumb (blx) */
7031 tmp
= load_reg(s
, rm
);
7032 tmp2
= tcg_temp_new_i32();
7033 tcg_gen_movi_i32(tmp2
, s
->pc
);
7034 store_reg(s
, 14, tmp2
);
7037 case 0x5: /* saturating add/subtract */
7039 rd
= (insn
>> 12) & 0xf;
7040 rn
= (insn
>> 16) & 0xf;
7041 tmp
= load_reg(s
, rm
);
7042 tmp2
= load_reg(s
, rn
);
7044 gen_helper_double_saturate(tmp2
, tmp2
);
7046 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
7048 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
7049 tcg_temp_free_i32(tmp2
);
7050 store_reg(s
, rd
, tmp
);
7053 /* SMC instruction (op1 == 3)
7054 and undefined instructions (op1 == 0 || op1 == 2)
7061 gen_exception_insn(s
, 4, EXCP_BKPT
);
7063 case 0x8: /* signed multiply */
7068 rs
= (insn
>> 8) & 0xf;
7069 rn
= (insn
>> 12) & 0xf;
7070 rd
= (insn
>> 16) & 0xf;
7072 /* (32 * 16) >> 16 */
7073 tmp
= load_reg(s
, rm
);
7074 tmp2
= load_reg(s
, rs
);
7076 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7079 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7080 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7081 tmp
= tcg_temp_new_i32();
7082 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7083 tcg_temp_free_i64(tmp64
);
7084 if ((sh
& 2) == 0) {
7085 tmp2
= load_reg(s
, rn
);
7086 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7087 tcg_temp_free_i32(tmp2
);
7089 store_reg(s
, rd
, tmp
);
7092 tmp
= load_reg(s
, rm
);
7093 tmp2
= load_reg(s
, rs
);
7094 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7095 tcg_temp_free_i32(tmp2
);
7097 tmp64
= tcg_temp_new_i64();
7098 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7099 tcg_temp_free_i32(tmp
);
7100 gen_addq(s
, tmp64
, rn
, rd
);
7101 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7102 tcg_temp_free_i64(tmp64
);
7105 tmp2
= load_reg(s
, rn
);
7106 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7107 tcg_temp_free_i32(tmp2
);
7109 store_reg(s
, rd
, tmp
);
7116 } else if (((insn
& 0x0e000000) == 0 &&
7117 (insn
& 0x00000090) != 0x90) ||
7118 ((insn
& 0x0e000000) == (1 << 25))) {
7119 int set_cc
, logic_cc
, shiftop
;
7121 op1
= (insn
>> 21) & 0xf;
7122 set_cc
= (insn
>> 20) & 1;
7123 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7125 /* data processing instruction */
7126 if (insn
& (1 << 25)) {
7127 /* immediate operand */
7129 shift
= ((insn
>> 8) & 0xf) * 2;
7131 val
= (val
>> shift
) | (val
<< (32 - shift
));
7133 tmp2
= tcg_temp_new_i32();
7134 tcg_gen_movi_i32(tmp2
, val
);
7135 if (logic_cc
&& shift
) {
7136 gen_set_CF_bit31(tmp2
);
7141 tmp2
= load_reg(s
, rm
);
7142 shiftop
= (insn
>> 5) & 3;
7143 if (!(insn
& (1 << 4))) {
7144 shift
= (insn
>> 7) & 0x1f;
7145 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7147 rs
= (insn
>> 8) & 0xf;
7148 tmp
= load_reg(s
, rs
);
7149 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7152 if (op1
!= 0x0f && op1
!= 0x0d) {
7153 rn
= (insn
>> 16) & 0xf;
7154 tmp
= load_reg(s
, rn
);
7158 rd
= (insn
>> 12) & 0xf;
7161 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7165 store_reg_bx(env
, s
, rd
, tmp
);
7168 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7172 store_reg_bx(env
, s
, rd
, tmp
);
7175 if (set_cc
&& rd
== 15) {
7176 /* SUBS r15, ... is used for exception return. */
7180 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7181 gen_exception_return(s
, tmp
);
7184 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7186 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7188 store_reg_bx(env
, s
, rd
, tmp
);
7193 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
7195 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7197 store_reg_bx(env
, s
, rd
, tmp
);
7201 gen_helper_add_cc(tmp
, tmp
, tmp2
);
7203 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7205 store_reg_bx(env
, s
, rd
, tmp
);
7209 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
7211 gen_add_carry(tmp
, tmp
, tmp2
);
7213 store_reg_bx(env
, s
, rd
, tmp
);
7217 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
7219 gen_sub_carry(tmp
, tmp
, tmp2
);
7221 store_reg_bx(env
, s
, rd
, tmp
);
7225 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
7227 gen_sub_carry(tmp
, tmp2
, tmp
);
7229 store_reg_bx(env
, s
, rd
, tmp
);
7233 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7236 tcg_temp_free_i32(tmp
);
7240 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7243 tcg_temp_free_i32(tmp
);
7247 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7249 tcg_temp_free_i32(tmp
);
7253 gen_helper_add_cc(tmp
, tmp
, tmp2
);
7255 tcg_temp_free_i32(tmp
);
7258 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7262 store_reg_bx(env
, s
, rd
, tmp
);
7265 if (logic_cc
&& rd
== 15) {
7266 /* MOVS r15, ... is used for exception return. */
7270 gen_exception_return(s
, tmp2
);
7275 store_reg_bx(env
, s
, rd
, tmp2
);
7279 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7283 store_reg_bx(env
, s
, rd
, tmp
);
7287 tcg_gen_not_i32(tmp2
, tmp2
);
7291 store_reg_bx(env
, s
, rd
, tmp2
);
7294 if (op1
!= 0x0f && op1
!= 0x0d) {
7295 tcg_temp_free_i32(tmp2
);
7298 /* other instructions */
7299 op1
= (insn
>> 24) & 0xf;
7303 /* multiplies, extra load/stores */
7304 sh
= (insn
>> 5) & 3;
7307 rd
= (insn
>> 16) & 0xf;
7308 rn
= (insn
>> 12) & 0xf;
7309 rs
= (insn
>> 8) & 0xf;
7311 op1
= (insn
>> 20) & 0xf;
7313 case 0: case 1: case 2: case 3: case 6:
7315 tmp
= load_reg(s
, rs
);
7316 tmp2
= load_reg(s
, rm
);
7317 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7318 tcg_temp_free_i32(tmp2
);
7319 if (insn
& (1 << 22)) {
7320 /* Subtract (mls) */
7322 tmp2
= load_reg(s
, rn
);
7323 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7324 tcg_temp_free_i32(tmp2
);
7325 } else if (insn
& (1 << 21)) {
7327 tmp2
= load_reg(s
, rn
);
7328 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7329 tcg_temp_free_i32(tmp2
);
7331 if (insn
& (1 << 20))
7333 store_reg(s
, rd
, tmp
);
7336 /* 64 bit mul double accumulate (UMAAL) */
7338 tmp
= load_reg(s
, rs
);
7339 tmp2
= load_reg(s
, rm
);
7340 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7341 gen_addq_lo(s
, tmp64
, rn
);
7342 gen_addq_lo(s
, tmp64
, rd
);
7343 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7344 tcg_temp_free_i64(tmp64
);
7346 case 8: case 9: case 10: case 11:
7347 case 12: case 13: case 14: case 15:
7348 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7349 tmp
= load_reg(s
, rs
);
7350 tmp2
= load_reg(s
, rm
);
7351 if (insn
& (1 << 22)) {
7352 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7354 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7356 if (insn
& (1 << 21)) { /* mult accumulate */
7357 gen_addq(s
, tmp64
, rn
, rd
);
7359 if (insn
& (1 << 20)) {
7360 gen_logicq_cc(tmp64
);
7362 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7363 tcg_temp_free_i64(tmp64
);
7369 rn
= (insn
>> 16) & 0xf;
7370 rd
= (insn
>> 12) & 0xf;
7371 if (insn
& (1 << 23)) {
7372 /* load/store exclusive */
7373 op1
= (insn
>> 21) & 0x3;
7378 addr
= tcg_temp_local_new_i32();
7379 load_reg_var(s
, addr
, rn
);
7380 if (insn
& (1 << 20)) {
7383 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7385 case 1: /* ldrexd */
7386 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7388 case 2: /* ldrexb */
7389 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7391 case 3: /* ldrexh */
7392 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7401 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7403 case 1: /* strexd */
7404 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7406 case 2: /* strexb */
7407 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7409 case 3: /* strexh */
7410 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7416 tcg_temp_free(addr
);
7418 /* SWP instruction */
7421 /* ??? This is not really atomic. However we know
7422 we never have multiple CPUs running in parallel,
7423 so it is good enough. */
7424 addr
= load_reg(s
, rn
);
7425 tmp
= load_reg(s
, rm
);
7426 if (insn
& (1 << 22)) {
7427 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7428 gen_st8(tmp
, addr
, IS_USER(s
));
7430 tmp2
= gen_ld32(addr
, IS_USER(s
));
7431 gen_st32(tmp
, addr
, IS_USER(s
));
7433 tcg_temp_free_i32(addr
);
7434 store_reg(s
, rd
, tmp2
);
7440 /* Misc load/store */
7441 rn
= (insn
>> 16) & 0xf;
7442 rd
= (insn
>> 12) & 0xf;
7443 addr
= load_reg(s
, rn
);
7444 if (insn
& (1 << 24))
7445 gen_add_datah_offset(s
, insn
, 0, addr
);
7447 if (insn
& (1 << 20)) {
7451 tmp
= gen_ld16u(addr
, IS_USER(s
));
7454 tmp
= gen_ld8s(addr
, IS_USER(s
));
7458 tmp
= gen_ld16s(addr
, IS_USER(s
));
7462 } else if (sh
& 2) {
7467 tmp
= load_reg(s
, rd
);
7468 gen_st32(tmp
, addr
, IS_USER(s
));
7469 tcg_gen_addi_i32(addr
, addr
, 4);
7470 tmp
= load_reg(s
, rd
+ 1);
7471 gen_st32(tmp
, addr
, IS_USER(s
));
7475 tmp
= gen_ld32(addr
, IS_USER(s
));
7476 store_reg(s
, rd
, tmp
);
7477 tcg_gen_addi_i32(addr
, addr
, 4);
7478 tmp
= gen_ld32(addr
, IS_USER(s
));
7482 address_offset
= -4;
7485 tmp
= load_reg(s
, rd
);
7486 gen_st16(tmp
, addr
, IS_USER(s
));
7489 /* Perform base writeback before the loaded value to
7490 ensure correct behavior with overlapping index registers.
7491 ldrd with base writeback is is undefined if the
7492 destination and index registers overlap. */
7493 if (!(insn
& (1 << 24))) {
7494 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7495 store_reg(s
, rn
, addr
);
7496 } else if (insn
& (1 << 21)) {
7498 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7499 store_reg(s
, rn
, addr
);
7501 tcg_temp_free_i32(addr
);
7504 /* Complete the load. */
7505 store_reg(s
, rd
, tmp
);
7514 if (insn
& (1 << 4)) {
7516 /* Armv6 Media instructions. */
7518 rn
= (insn
>> 16) & 0xf;
7519 rd
= (insn
>> 12) & 0xf;
7520 rs
= (insn
>> 8) & 0xf;
7521 switch ((insn
>> 23) & 3) {
7522 case 0: /* Parallel add/subtract. */
7523 op1
= (insn
>> 20) & 7;
7524 tmp
= load_reg(s
, rn
);
7525 tmp2
= load_reg(s
, rm
);
7526 sh
= (insn
>> 5) & 7;
7527 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7529 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7530 tcg_temp_free_i32(tmp2
);
7531 store_reg(s
, rd
, tmp
);
7534 if ((insn
& 0x00700020) == 0) {
7535 /* Halfword pack. */
7536 tmp
= load_reg(s
, rn
);
7537 tmp2
= load_reg(s
, rm
);
7538 shift
= (insn
>> 7) & 0x1f;
7539 if (insn
& (1 << 6)) {
7543 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7544 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7545 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7549 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7550 tcg_gen_ext16u_i32(tmp
, tmp
);
7551 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7553 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7554 tcg_temp_free_i32(tmp2
);
7555 store_reg(s
, rd
, tmp
);
7556 } else if ((insn
& 0x00200020) == 0x00200000) {
7558 tmp
= load_reg(s
, rm
);
7559 shift
= (insn
>> 7) & 0x1f;
7560 if (insn
& (1 << 6)) {
7563 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7565 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7567 sh
= (insn
>> 16) & 0x1f;
7568 tmp2
= tcg_const_i32(sh
);
7569 if (insn
& (1 << 22))
7570 gen_helper_usat(tmp
, tmp
, tmp2
);
7572 gen_helper_ssat(tmp
, tmp
, tmp2
);
7573 tcg_temp_free_i32(tmp2
);
7574 store_reg(s
, rd
, tmp
);
7575 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7577 tmp
= load_reg(s
, rm
);
7578 sh
= (insn
>> 16) & 0x1f;
7579 tmp2
= tcg_const_i32(sh
);
7580 if (insn
& (1 << 22))
7581 gen_helper_usat16(tmp
, tmp
, tmp2
);
7583 gen_helper_ssat16(tmp
, tmp
, tmp2
);
7584 tcg_temp_free_i32(tmp2
);
7585 store_reg(s
, rd
, tmp
);
7586 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7588 tmp
= load_reg(s
, rn
);
7589 tmp2
= load_reg(s
, rm
);
7590 tmp3
= tcg_temp_new_i32();
7591 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7592 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7593 tcg_temp_free_i32(tmp3
);
7594 tcg_temp_free_i32(tmp2
);
7595 store_reg(s
, rd
, tmp
);
7596 } else if ((insn
& 0x000003e0) == 0x00000060) {
7597 tmp
= load_reg(s
, rm
);
7598 shift
= (insn
>> 10) & 3;
7599 /* ??? In many cases it's not necessary to do a
7600 rotate, a shift is sufficient. */
7602 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7603 op1
= (insn
>> 20) & 7;
7605 case 0: gen_sxtb16(tmp
); break;
7606 case 2: gen_sxtb(tmp
); break;
7607 case 3: gen_sxth(tmp
); break;
7608 case 4: gen_uxtb16(tmp
); break;
7609 case 6: gen_uxtb(tmp
); break;
7610 case 7: gen_uxth(tmp
); break;
7611 default: goto illegal_op
;
7614 tmp2
= load_reg(s
, rn
);
7615 if ((op1
& 3) == 0) {
7616 gen_add16(tmp
, tmp2
);
7618 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7619 tcg_temp_free_i32(tmp2
);
7622 store_reg(s
, rd
, tmp
);
7623 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7625 tmp
= load_reg(s
, rm
);
7626 if (insn
& (1 << 22)) {
7627 if (insn
& (1 << 7)) {
7631 gen_helper_rbit(tmp
, tmp
);
7634 if (insn
& (1 << 7))
7637 tcg_gen_bswap32_i32(tmp
, tmp
);
7639 store_reg(s
, rd
, tmp
);
7644 case 2: /* Multiplies (Type 3). */
7645 switch ((insn
>> 20) & 0x7) {
7647 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7648 /* op2 not 00x or 11x : UNDEF */
7651 /* Signed multiply most significant [accumulate].
7652 (SMMUL, SMMLA, SMMLS) */
7653 tmp
= load_reg(s
, rm
);
7654 tmp2
= load_reg(s
, rs
);
7655 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7658 tmp
= load_reg(s
, rd
);
7659 if (insn
& (1 << 6)) {
7660 tmp64
= gen_subq_msw(tmp64
, tmp
);
7662 tmp64
= gen_addq_msw(tmp64
, tmp
);
7665 if (insn
& (1 << 5)) {
7666 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7668 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7669 tmp
= tcg_temp_new_i32();
7670 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7671 tcg_temp_free_i64(tmp64
);
7672 store_reg(s
, rn
, tmp
);
7676 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7677 if (insn
& (1 << 7)) {
7680 tmp
= load_reg(s
, rm
);
7681 tmp2
= load_reg(s
, rs
);
7682 if (insn
& (1 << 5))
7683 gen_swap_half(tmp2
);
7684 gen_smul_dual(tmp
, tmp2
);
7685 if (insn
& (1 << 6)) {
7686 /* This subtraction cannot overflow. */
7687 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7689 /* This addition cannot overflow 32 bits;
7690 * however it may overflow considered as a signed
7691 * operation, in which case we must set the Q flag.
7693 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7695 tcg_temp_free_i32(tmp2
);
7696 if (insn
& (1 << 22)) {
7697 /* smlald, smlsld */
7698 tmp64
= tcg_temp_new_i64();
7699 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7700 tcg_temp_free_i32(tmp
);
7701 gen_addq(s
, tmp64
, rd
, rn
);
7702 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7703 tcg_temp_free_i64(tmp64
);
7705 /* smuad, smusd, smlad, smlsd */
7708 tmp2
= load_reg(s
, rd
);
7709 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7710 tcg_temp_free_i32(tmp2
);
7712 store_reg(s
, rn
, tmp
);
7718 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7721 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7724 tmp
= load_reg(s
, rm
);
7725 tmp2
= load_reg(s
, rs
);
7726 if (insn
& (1 << 21)) {
7727 gen_helper_udiv(tmp
, tmp
, tmp2
);
7729 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7731 tcg_temp_free_i32(tmp2
);
7732 store_reg(s
, rn
, tmp
);
7739 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7741 case 0: /* Unsigned sum of absolute differences. */
7743 tmp
= load_reg(s
, rm
);
7744 tmp2
= load_reg(s
, rs
);
7745 gen_helper_usad8(tmp
, tmp
, tmp2
);
7746 tcg_temp_free_i32(tmp2
);
7748 tmp2
= load_reg(s
, rd
);
7749 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7750 tcg_temp_free_i32(tmp2
);
7752 store_reg(s
, rn
, tmp
);
7754 case 0x20: case 0x24: case 0x28: case 0x2c:
7755 /* Bitfield insert/clear. */
7757 shift
= (insn
>> 7) & 0x1f;
7758 i
= (insn
>> 16) & 0x1f;
7761 tmp
= tcg_temp_new_i32();
7762 tcg_gen_movi_i32(tmp
, 0);
7764 tmp
= load_reg(s
, rm
);
7767 tmp2
= load_reg(s
, rd
);
7768 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7769 tcg_temp_free_i32(tmp2
);
7771 store_reg(s
, rd
, tmp
);
7773 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7774 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7776 tmp
= load_reg(s
, rm
);
7777 shift
= (insn
>> 7) & 0x1f;
7778 i
= ((insn
>> 16) & 0x1f) + 1;
7783 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7785 gen_sbfx(tmp
, shift
, i
);
7788 store_reg(s
, rd
, tmp
);
7798 /* Check for undefined extension instructions
7799 * per the ARM Bible IE:
7800 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7802 sh
= (0xf << 20) | (0xf << 4);
7803 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7807 /* load/store byte/word */
7808 rn
= (insn
>> 16) & 0xf;
7809 rd
= (insn
>> 12) & 0xf;
7810 tmp2
= load_reg(s
, rn
);
7811 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7812 if (insn
& (1 << 24))
7813 gen_add_data_offset(s
, insn
, tmp2
);
7814 if (insn
& (1 << 20)) {
7816 if (insn
& (1 << 22)) {
7817 tmp
= gen_ld8u(tmp2
, i
);
7819 tmp
= gen_ld32(tmp2
, i
);
7823 tmp
= load_reg(s
, rd
);
7824 if (insn
& (1 << 22))
7825 gen_st8(tmp
, tmp2
, i
);
7827 gen_st32(tmp
, tmp2
, i
);
7829 if (!(insn
& (1 << 24))) {
7830 gen_add_data_offset(s
, insn
, tmp2
);
7831 store_reg(s
, rn
, tmp2
);
7832 } else if (insn
& (1 << 21)) {
7833 store_reg(s
, rn
, tmp2
);
7835 tcg_temp_free_i32(tmp2
);
7837 if (insn
& (1 << 20)) {
7838 /* Complete the load. */
7839 store_reg_from_load(env
, s
, rd
, tmp
);
7845 int j
, n
, user
, loaded_base
;
7847 /* load/store multiple words */
7848 /* XXX: store correct base if write back */
7850 if (insn
& (1 << 22)) {
7852 goto illegal_op
; /* only usable in supervisor mode */
7854 if ((insn
& (1 << 15)) == 0)
7857 rn
= (insn
>> 16) & 0xf;
7858 addr
= load_reg(s
, rn
);
7860 /* compute total size */
7862 TCGV_UNUSED(loaded_var
);
7865 if (insn
& (1 << i
))
7868 /* XXX: test invalid n == 0 case ? */
7869 if (insn
& (1 << 23)) {
7870 if (insn
& (1 << 24)) {
7872 tcg_gen_addi_i32(addr
, addr
, 4);
7874 /* post increment */
7877 if (insn
& (1 << 24)) {
7879 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7881 /* post decrement */
7883 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7888 if (insn
& (1 << i
)) {
7889 if (insn
& (1 << 20)) {
7891 tmp
= gen_ld32(addr
, IS_USER(s
));
7893 tmp2
= tcg_const_i32(i
);
7894 gen_helper_set_user_reg(tmp2
, tmp
);
7895 tcg_temp_free_i32(tmp2
);
7896 tcg_temp_free_i32(tmp
);
7897 } else if (i
== rn
) {
7901 store_reg_from_load(env
, s
, i
, tmp
);
7906 /* special case: r15 = PC + 8 */
7907 val
= (long)s
->pc
+ 4;
7908 tmp
= tcg_temp_new_i32();
7909 tcg_gen_movi_i32(tmp
, val
);
7911 tmp
= tcg_temp_new_i32();
7912 tmp2
= tcg_const_i32(i
);
7913 gen_helper_get_user_reg(tmp
, tmp2
);
7914 tcg_temp_free_i32(tmp2
);
7916 tmp
= load_reg(s
, i
);
7918 gen_st32(tmp
, addr
, IS_USER(s
));
7921 /* no need to add after the last transfer */
7923 tcg_gen_addi_i32(addr
, addr
, 4);
7926 if (insn
& (1 << 21)) {
7928 if (insn
& (1 << 23)) {
7929 if (insn
& (1 << 24)) {
7932 /* post increment */
7933 tcg_gen_addi_i32(addr
, addr
, 4);
7936 if (insn
& (1 << 24)) {
7939 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7941 /* post decrement */
7942 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7945 store_reg(s
, rn
, addr
);
7947 tcg_temp_free_i32(addr
);
7950 store_reg(s
, rn
, loaded_var
);
7952 if ((insn
& (1 << 22)) && !user
) {
7953 /* Restore CPSR from SPSR. */
7954 tmp
= load_cpu_field(spsr
);
7955 gen_set_cpsr(tmp
, 0xffffffff);
7956 tcg_temp_free_i32(tmp
);
7957 s
->is_jmp
= DISAS_UPDATE
;
7966 /* branch (and link) */
7967 val
= (int32_t)s
->pc
;
7968 if (insn
& (1 << 24)) {
7969 tmp
= tcg_temp_new_i32();
7970 tcg_gen_movi_i32(tmp
, val
);
7971 store_reg(s
, 14, tmp
);
7973 offset
= (((int32_t)insn
<< 8) >> 8);
7974 val
+= (offset
<< 2) + 4;
7982 if (disas_coproc_insn(env
, s
, insn
))
7987 gen_set_pc_im(s
->pc
);
7988 s
->is_jmp
= DISAS_SWI
;
7992 gen_exception_insn(s
, 4, EXCP_UDEF
);
7998 /* Return true if this is a Thumb-2 logical op. */
8000 thumb2_logic_op(int op
)
8005 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8006 then set condition code flags based on the result of the operation.
8007 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8008 to the high bit of T1.
8009 Returns zero if the opcode is valid. */
8012 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
8019 tcg_gen_and_i32(t0
, t0
, t1
);
8023 tcg_gen_andc_i32(t0
, t0
, t1
);
8027 tcg_gen_or_i32(t0
, t0
, t1
);
8031 tcg_gen_orc_i32(t0
, t0
, t1
);
8035 tcg_gen_xor_i32(t0
, t0
, t1
);
8040 gen_helper_add_cc(t0
, t0
, t1
);
8042 tcg_gen_add_i32(t0
, t0
, t1
);
8046 gen_helper_adc_cc(t0
, t0
, t1
);
8052 gen_helper_sbc_cc(t0
, t0
, t1
);
8054 gen_sub_carry(t0
, t0
, t1
);
8058 gen_helper_sub_cc(t0
, t0
, t1
);
8060 tcg_gen_sub_i32(t0
, t0
, t1
);
8064 gen_helper_sub_cc(t0
, t1
, t0
);
8066 tcg_gen_sub_i32(t0
, t1
, t0
);
8068 default: /* 5, 6, 7, 9, 12, 15. */
8074 gen_set_CF_bit31(t1
);
8079 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8081 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8083 uint32_t insn
, imm
, shift
, offset
;
8084 uint32_t rd
, rn
, rm
, rs
;
8095 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8096 || arm_feature (env
, ARM_FEATURE_M
))) {
8097 /* Thumb-1 cores may need to treat bl and blx as a pair of
8098 16-bit instructions to get correct prefetch abort behavior. */
8100 if ((insn
& (1 << 12)) == 0) {
8102 /* Second half of blx. */
8103 offset
= ((insn
& 0x7ff) << 1);
8104 tmp
= load_reg(s
, 14);
8105 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8106 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8108 tmp2
= tcg_temp_new_i32();
8109 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8110 store_reg(s
, 14, tmp2
);
8114 if (insn
& (1 << 11)) {
8115 /* Second half of bl. */
8116 offset
= ((insn
& 0x7ff) << 1) | 1;
8117 tmp
= load_reg(s
, 14);
8118 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8120 tmp2
= tcg_temp_new_i32();
8121 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8122 store_reg(s
, 14, tmp2
);
8126 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8127 /* Instruction spans a page boundary. Implement it as two
8128 16-bit instructions in case the second half causes an
8130 offset
= ((int32_t)insn
<< 21) >> 9;
8131 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8134 /* Fall through to 32-bit decode. */
8137 insn
= arm_lduw_code(s
->pc
, s
->bswap_code
);
8139 insn
|= (uint32_t)insn_hw1
<< 16;
8141 if ((insn
& 0xf800e800) != 0xf000e800) {
8145 rn
= (insn
>> 16) & 0xf;
8146 rs
= (insn
>> 12) & 0xf;
8147 rd
= (insn
>> 8) & 0xf;
8149 switch ((insn
>> 25) & 0xf) {
8150 case 0: case 1: case 2: case 3:
8151 /* 16-bit instructions. Should never happen. */
8154 if (insn
& (1 << 22)) {
8155 /* Other load/store, table branch. */
8156 if (insn
& 0x01200000) {
8157 /* Load/store doubleword. */
8159 addr
= tcg_temp_new_i32();
8160 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8162 addr
= load_reg(s
, rn
);
8164 offset
= (insn
& 0xff) * 4;
8165 if ((insn
& (1 << 23)) == 0)
8167 if (insn
& (1 << 24)) {
8168 tcg_gen_addi_i32(addr
, addr
, offset
);
8171 if (insn
& (1 << 20)) {
8173 tmp
= gen_ld32(addr
, IS_USER(s
));
8174 store_reg(s
, rs
, tmp
);
8175 tcg_gen_addi_i32(addr
, addr
, 4);
8176 tmp
= gen_ld32(addr
, IS_USER(s
));
8177 store_reg(s
, rd
, tmp
);
8180 tmp
= load_reg(s
, rs
);
8181 gen_st32(tmp
, addr
, IS_USER(s
));
8182 tcg_gen_addi_i32(addr
, addr
, 4);
8183 tmp
= load_reg(s
, rd
);
8184 gen_st32(tmp
, addr
, IS_USER(s
));
8186 if (insn
& (1 << 21)) {
8187 /* Base writeback. */
8190 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8191 store_reg(s
, rn
, addr
);
8193 tcg_temp_free_i32(addr
);
8195 } else if ((insn
& (1 << 23)) == 0) {
8196 /* Load/store exclusive word. */
8197 addr
= tcg_temp_local_new();
8198 load_reg_var(s
, addr
, rn
);
8199 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8200 if (insn
& (1 << 20)) {
8201 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8203 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8205 tcg_temp_free(addr
);
8206 } else if ((insn
& (1 << 6)) == 0) {
8209 addr
= tcg_temp_new_i32();
8210 tcg_gen_movi_i32(addr
, s
->pc
);
8212 addr
= load_reg(s
, rn
);
8214 tmp
= load_reg(s
, rm
);
8215 tcg_gen_add_i32(addr
, addr
, tmp
);
8216 if (insn
& (1 << 4)) {
8218 tcg_gen_add_i32(addr
, addr
, tmp
);
8219 tcg_temp_free_i32(tmp
);
8220 tmp
= gen_ld16u(addr
, IS_USER(s
));
8222 tcg_temp_free_i32(tmp
);
8223 tmp
= gen_ld8u(addr
, IS_USER(s
));
8225 tcg_temp_free_i32(addr
);
8226 tcg_gen_shli_i32(tmp
, tmp
, 1);
8227 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8228 store_reg(s
, 15, tmp
);
8230 /* Load/store exclusive byte/halfword/doubleword. */
8232 op
= (insn
>> 4) & 0x3;
8236 addr
= tcg_temp_local_new();
8237 load_reg_var(s
, addr
, rn
);
8238 if (insn
& (1 << 20)) {
8239 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8241 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8243 tcg_temp_free(addr
);
8246 /* Load/store multiple, RFE, SRS. */
8247 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8248 /* Not available in user mode. */
8251 if (insn
& (1 << 20)) {
8253 addr
= load_reg(s
, rn
);
8254 if ((insn
& (1 << 24)) == 0)
8255 tcg_gen_addi_i32(addr
, addr
, -8);
8256 /* Load PC into tmp and CPSR into tmp2. */
8257 tmp
= gen_ld32(addr
, 0);
8258 tcg_gen_addi_i32(addr
, addr
, 4);
8259 tmp2
= gen_ld32(addr
, 0);
8260 if (insn
& (1 << 21)) {
8261 /* Base writeback. */
8262 if (insn
& (1 << 24)) {
8263 tcg_gen_addi_i32(addr
, addr
, 4);
8265 tcg_gen_addi_i32(addr
, addr
, -4);
8267 store_reg(s
, rn
, addr
);
8269 tcg_temp_free_i32(addr
);
8271 gen_rfe(s
, tmp
, tmp2
);
8275 addr
= tcg_temp_new_i32();
8276 tmp
= tcg_const_i32(op
);
8277 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8278 tcg_temp_free_i32(tmp
);
8279 if ((insn
& (1 << 24)) == 0) {
8280 tcg_gen_addi_i32(addr
, addr
, -8);
8282 tmp
= load_reg(s
, 14);
8283 gen_st32(tmp
, addr
, 0);
8284 tcg_gen_addi_i32(addr
, addr
, 4);
8285 tmp
= tcg_temp_new_i32();
8286 gen_helper_cpsr_read(tmp
);
8287 gen_st32(tmp
, addr
, 0);
8288 if (insn
& (1 << 21)) {
8289 if ((insn
& (1 << 24)) == 0) {
8290 tcg_gen_addi_i32(addr
, addr
, -4);
8292 tcg_gen_addi_i32(addr
, addr
, 4);
8294 tmp
= tcg_const_i32(op
);
8295 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8296 tcg_temp_free_i32(tmp
);
8298 tcg_temp_free_i32(addr
);
8302 int i
, loaded_base
= 0;
8304 /* Load/store multiple. */
8305 addr
= load_reg(s
, rn
);
8307 for (i
= 0; i
< 16; i
++) {
8308 if (insn
& (1 << i
))
8311 if (insn
& (1 << 24)) {
8312 tcg_gen_addi_i32(addr
, addr
, -offset
);
8315 TCGV_UNUSED(loaded_var
);
8316 for (i
= 0; i
< 16; i
++) {
8317 if ((insn
& (1 << i
)) == 0)
8319 if (insn
& (1 << 20)) {
8321 tmp
= gen_ld32(addr
, IS_USER(s
));
8324 } else if (i
== rn
) {
8328 store_reg(s
, i
, tmp
);
8332 tmp
= load_reg(s
, i
);
8333 gen_st32(tmp
, addr
, IS_USER(s
));
8335 tcg_gen_addi_i32(addr
, addr
, 4);
8338 store_reg(s
, rn
, loaded_var
);
8340 if (insn
& (1 << 21)) {
8341 /* Base register writeback. */
8342 if (insn
& (1 << 24)) {
8343 tcg_gen_addi_i32(addr
, addr
, -offset
);
8345 /* Fault if writeback register is in register list. */
8346 if (insn
& (1 << rn
))
8348 store_reg(s
, rn
, addr
);
8350 tcg_temp_free_i32(addr
);
8357 op
= (insn
>> 21) & 0xf;
8359 /* Halfword pack. */
8360 tmp
= load_reg(s
, rn
);
8361 tmp2
= load_reg(s
, rm
);
8362 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8363 if (insn
& (1 << 5)) {
8367 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8368 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8369 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8373 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8374 tcg_gen_ext16u_i32(tmp
, tmp
);
8375 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8377 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8378 tcg_temp_free_i32(tmp2
);
8379 store_reg(s
, rd
, tmp
);
8381 /* Data processing register constant shift. */
8383 tmp
= tcg_temp_new_i32();
8384 tcg_gen_movi_i32(tmp
, 0);
8386 tmp
= load_reg(s
, rn
);
8388 tmp2
= load_reg(s
, rm
);
8390 shiftop
= (insn
>> 4) & 3;
8391 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8392 conds
= (insn
& (1 << 20)) != 0;
8393 logic_cc
= (conds
&& thumb2_logic_op(op
));
8394 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8395 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8397 tcg_temp_free_i32(tmp2
);
8399 store_reg(s
, rd
, tmp
);
8401 tcg_temp_free_i32(tmp
);
8405 case 13: /* Misc data processing. */
8406 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8407 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8410 case 0: /* Register controlled shift. */
8411 tmp
= load_reg(s
, rn
);
8412 tmp2
= load_reg(s
, rm
);
8413 if ((insn
& 0x70) != 0)
8415 op
= (insn
>> 21) & 3;
8416 logic_cc
= (insn
& (1 << 20)) != 0;
8417 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8420 store_reg_bx(env
, s
, rd
, tmp
);
8422 case 1: /* Sign/zero extend. */
8423 tmp
= load_reg(s
, rm
);
8424 shift
= (insn
>> 4) & 3;
8425 /* ??? In many cases it's not necessary to do a
8426 rotate, a shift is sufficient. */
8428 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8429 op
= (insn
>> 20) & 7;
8431 case 0: gen_sxth(tmp
); break;
8432 case 1: gen_uxth(tmp
); break;
8433 case 2: gen_sxtb16(tmp
); break;
8434 case 3: gen_uxtb16(tmp
); break;
8435 case 4: gen_sxtb(tmp
); break;
8436 case 5: gen_uxtb(tmp
); break;
8437 default: goto illegal_op
;
8440 tmp2
= load_reg(s
, rn
);
8441 if ((op
>> 1) == 1) {
8442 gen_add16(tmp
, tmp2
);
8444 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8445 tcg_temp_free_i32(tmp2
);
8448 store_reg(s
, rd
, tmp
);
8450 case 2: /* SIMD add/subtract. */
8451 op
= (insn
>> 20) & 7;
8452 shift
= (insn
>> 4) & 7;
8453 if ((op
& 3) == 3 || (shift
& 3) == 3)
8455 tmp
= load_reg(s
, rn
);
8456 tmp2
= load_reg(s
, rm
);
8457 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8458 tcg_temp_free_i32(tmp2
);
8459 store_reg(s
, rd
, tmp
);
8461 case 3: /* Other data processing. */
8462 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8464 /* Saturating add/subtract. */
8465 tmp
= load_reg(s
, rn
);
8466 tmp2
= load_reg(s
, rm
);
8468 gen_helper_double_saturate(tmp
, tmp
);
8470 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
8472 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
8473 tcg_temp_free_i32(tmp2
);
8475 tmp
= load_reg(s
, rn
);
8477 case 0x0a: /* rbit */
8478 gen_helper_rbit(tmp
, tmp
);
8480 case 0x08: /* rev */
8481 tcg_gen_bswap32_i32(tmp
, tmp
);
8483 case 0x09: /* rev16 */
8486 case 0x0b: /* revsh */
8489 case 0x10: /* sel */
8490 tmp2
= load_reg(s
, rm
);
8491 tmp3
= tcg_temp_new_i32();
8492 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8493 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8494 tcg_temp_free_i32(tmp3
);
8495 tcg_temp_free_i32(tmp2
);
8497 case 0x18: /* clz */
8498 gen_helper_clz(tmp
, tmp
);
8504 store_reg(s
, rd
, tmp
);
8506 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8507 op
= (insn
>> 4) & 0xf;
8508 tmp
= load_reg(s
, rn
);
8509 tmp2
= load_reg(s
, rm
);
8510 switch ((insn
>> 20) & 7) {
8511 case 0: /* 32 x 32 -> 32 */
8512 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8513 tcg_temp_free_i32(tmp2
);
8515 tmp2
= load_reg(s
, rs
);
8517 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8519 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8520 tcg_temp_free_i32(tmp2
);
8523 case 1: /* 16 x 16 -> 32 */
8524 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8525 tcg_temp_free_i32(tmp2
);
8527 tmp2
= load_reg(s
, rs
);
8528 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8529 tcg_temp_free_i32(tmp2
);
8532 case 2: /* Dual multiply add. */
8533 case 4: /* Dual multiply subtract. */
8535 gen_swap_half(tmp2
);
8536 gen_smul_dual(tmp
, tmp2
);
8537 if (insn
& (1 << 22)) {
8538 /* This subtraction cannot overflow. */
8539 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8541 /* This addition cannot overflow 32 bits;
8542 * however it may overflow considered as a signed
8543 * operation, in which case we must set the Q flag.
8545 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8547 tcg_temp_free_i32(tmp2
);
8550 tmp2
= load_reg(s
, rs
);
8551 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8552 tcg_temp_free_i32(tmp2
);
8555 case 3: /* 32 * 16 -> 32msb */
8557 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8560 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8561 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8562 tmp
= tcg_temp_new_i32();
8563 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8564 tcg_temp_free_i64(tmp64
);
8567 tmp2
= load_reg(s
, rs
);
8568 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8569 tcg_temp_free_i32(tmp2
);
8572 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8573 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8575 tmp
= load_reg(s
, rs
);
8576 if (insn
& (1 << 20)) {
8577 tmp64
= gen_addq_msw(tmp64
, tmp
);
8579 tmp64
= gen_subq_msw(tmp64
, tmp
);
8582 if (insn
& (1 << 4)) {
8583 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8585 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8586 tmp
= tcg_temp_new_i32();
8587 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8588 tcg_temp_free_i64(tmp64
);
8590 case 7: /* Unsigned sum of absolute differences. */
8591 gen_helper_usad8(tmp
, tmp
, tmp2
);
8592 tcg_temp_free_i32(tmp2
);
8594 tmp2
= load_reg(s
, rs
);
8595 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8596 tcg_temp_free_i32(tmp2
);
8600 store_reg(s
, rd
, tmp
);
8602 case 6: case 7: /* 64-bit multiply, Divide. */
8603 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8604 tmp
= load_reg(s
, rn
);
8605 tmp2
= load_reg(s
, rm
);
8606 if ((op
& 0x50) == 0x10) {
8608 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8612 gen_helper_udiv(tmp
, tmp
, tmp2
);
8614 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8615 tcg_temp_free_i32(tmp2
);
8616 store_reg(s
, rd
, tmp
);
8617 } else if ((op
& 0xe) == 0xc) {
8618 /* Dual multiply accumulate long. */
8620 gen_swap_half(tmp2
);
8621 gen_smul_dual(tmp
, tmp2
);
8623 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8625 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8627 tcg_temp_free_i32(tmp2
);
8629 tmp64
= tcg_temp_new_i64();
8630 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8631 tcg_temp_free_i32(tmp
);
8632 gen_addq(s
, tmp64
, rs
, rd
);
8633 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8634 tcg_temp_free_i64(tmp64
);
8637 /* Unsigned 64-bit multiply */
8638 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8642 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8643 tcg_temp_free_i32(tmp2
);
8644 tmp64
= tcg_temp_new_i64();
8645 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8646 tcg_temp_free_i32(tmp
);
8648 /* Signed 64-bit multiply */
8649 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8654 gen_addq_lo(s
, tmp64
, rs
);
8655 gen_addq_lo(s
, tmp64
, rd
);
8656 } else if (op
& 0x40) {
8657 /* 64-bit accumulate. */
8658 gen_addq(s
, tmp64
, rs
, rd
);
8660 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8661 tcg_temp_free_i64(tmp64
);
8666 case 6: case 7: case 14: case 15:
8668 if (((insn
>> 24) & 3) == 3) {
8669 /* Translate into the equivalent ARM encoding. */
8670 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8671 if (disas_neon_data_insn(env
, s
, insn
))
8674 if (insn
& (1 << 28))
8676 if (disas_coproc_insn (env
, s
, insn
))
8680 case 8: case 9: case 10: case 11:
8681 if (insn
& (1 << 15)) {
8682 /* Branches, misc control. */
8683 if (insn
& 0x5000) {
8684 /* Unconditional branch. */
8685 /* signextend(hw1[10:0]) -> offset[:12]. */
8686 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8687 /* hw1[10:0] -> offset[11:1]. */
8688 offset
|= (insn
& 0x7ff) << 1;
8689 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8690 offset[24:22] already have the same value because of the
8691 sign extension above. */
8692 offset
^= ((~insn
) & (1 << 13)) << 10;
8693 offset
^= ((~insn
) & (1 << 11)) << 11;
8695 if (insn
& (1 << 14)) {
8696 /* Branch and link. */
8697 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8701 if (insn
& (1 << 12)) {
8706 offset
&= ~(uint32_t)2;
8707 /* thumb2 bx, no need to check */
8708 gen_bx_im(s
, offset
);
8710 } else if (((insn
>> 23) & 7) == 7) {
8712 if (insn
& (1 << 13))
8715 if (insn
& (1 << 26)) {
8716 /* Secure monitor call (v6Z) */
8717 goto illegal_op
; /* not implemented. */
8719 op
= (insn
>> 20) & 7;
8721 case 0: /* msr cpsr. */
8723 tmp
= load_reg(s
, rn
);
8724 addr
= tcg_const_i32(insn
& 0xff);
8725 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8726 tcg_temp_free_i32(addr
);
8727 tcg_temp_free_i32(tmp
);
8732 case 1: /* msr spsr. */
8735 tmp
= load_reg(s
, rn
);
8737 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8741 case 2: /* cps, nop-hint. */
8742 if (((insn
>> 8) & 7) == 0) {
8743 gen_nop_hint(s
, insn
& 0xff);
8745 /* Implemented as NOP in user mode. */
8750 if (insn
& (1 << 10)) {
8751 if (insn
& (1 << 7))
8753 if (insn
& (1 << 6))
8755 if (insn
& (1 << 5))
8757 if (insn
& (1 << 9))
8758 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8760 if (insn
& (1 << 8)) {
8762 imm
|= (insn
& 0x1f);
8765 gen_set_psr_im(s
, offset
, 0, imm
);
8768 case 3: /* Special control operations. */
8770 op
= (insn
>> 4) & 0xf;
8778 /* These execute as NOPs. */
8785 /* Trivial implementation equivalent to bx. */
8786 tmp
= load_reg(s
, rn
);
8789 case 5: /* Exception return. */
8793 if (rn
!= 14 || rd
!= 15) {
8796 tmp
= load_reg(s
, rn
);
8797 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8798 gen_exception_return(s
, tmp
);
8800 case 6: /* mrs cpsr. */
8801 tmp
= tcg_temp_new_i32();
8803 addr
= tcg_const_i32(insn
& 0xff);
8804 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8805 tcg_temp_free_i32(addr
);
8807 gen_helper_cpsr_read(tmp
);
8809 store_reg(s
, rd
, tmp
);
8811 case 7: /* mrs spsr. */
8812 /* Not accessible in user mode. */
8813 if (IS_USER(s
) || IS_M(env
))
8815 tmp
= load_cpu_field(spsr
);
8816 store_reg(s
, rd
, tmp
);
8821 /* Conditional branch. */
8822 op
= (insn
>> 22) & 0xf;
8823 /* Generate a conditional jump to next instruction. */
8824 s
->condlabel
= gen_new_label();
8825 gen_test_cc(op
^ 1, s
->condlabel
);
8828 /* offset[11:1] = insn[10:0] */
8829 offset
= (insn
& 0x7ff) << 1;
8830 /* offset[17:12] = insn[21:16]. */
8831 offset
|= (insn
& 0x003f0000) >> 4;
8832 /* offset[31:20] = insn[26]. */
8833 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8834 /* offset[18] = insn[13]. */
8835 offset
|= (insn
& (1 << 13)) << 5;
8836 /* offset[19] = insn[11]. */
8837 offset
|= (insn
& (1 << 11)) << 8;
8839 /* jump to the offset */
8840 gen_jmp(s
, s
->pc
+ offset
);
8843 /* Data processing immediate. */
8844 if (insn
& (1 << 25)) {
8845 if (insn
& (1 << 24)) {
8846 if (insn
& (1 << 20))
8848 /* Bitfield/Saturate. */
8849 op
= (insn
>> 21) & 7;
8851 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8853 tmp
= tcg_temp_new_i32();
8854 tcg_gen_movi_i32(tmp
, 0);
8856 tmp
= load_reg(s
, rn
);
8859 case 2: /* Signed bitfield extract. */
8861 if (shift
+ imm
> 32)
8864 gen_sbfx(tmp
, shift
, imm
);
8866 case 6: /* Unsigned bitfield extract. */
8868 if (shift
+ imm
> 32)
8871 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8873 case 3: /* Bitfield insert/clear. */
8876 imm
= imm
+ 1 - shift
;
8878 tmp2
= load_reg(s
, rd
);
8879 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8880 tcg_temp_free_i32(tmp2
);
8885 default: /* Saturate. */
8888 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8890 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8892 tmp2
= tcg_const_i32(imm
);
8895 if ((op
& 1) && shift
== 0)
8896 gen_helper_usat16(tmp
, tmp
, tmp2
);
8898 gen_helper_usat(tmp
, tmp
, tmp2
);
8901 if ((op
& 1) && shift
== 0)
8902 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8904 gen_helper_ssat(tmp
, tmp
, tmp2
);
8906 tcg_temp_free_i32(tmp2
);
8909 store_reg(s
, rd
, tmp
);
8911 imm
= ((insn
& 0x04000000) >> 15)
8912 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8913 if (insn
& (1 << 22)) {
8914 /* 16-bit immediate. */
8915 imm
|= (insn
>> 4) & 0xf000;
8916 if (insn
& (1 << 23)) {
8918 tmp
= load_reg(s
, rd
);
8919 tcg_gen_ext16u_i32(tmp
, tmp
);
8920 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8923 tmp
= tcg_temp_new_i32();
8924 tcg_gen_movi_i32(tmp
, imm
);
8927 /* Add/sub 12-bit immediate. */
8929 offset
= s
->pc
& ~(uint32_t)3;
8930 if (insn
& (1 << 23))
8934 tmp
= tcg_temp_new_i32();
8935 tcg_gen_movi_i32(tmp
, offset
);
8937 tmp
= load_reg(s
, rn
);
8938 if (insn
& (1 << 23))
8939 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8941 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8944 store_reg(s
, rd
, tmp
);
8947 int shifter_out
= 0;
8948 /* modified 12-bit immediate. */
8949 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8950 imm
= (insn
& 0xff);
8953 /* Nothing to do. */
8955 case 1: /* 00XY00XY */
8958 case 2: /* XY00XY00 */
8962 case 3: /* XYXYXYXY */
8966 default: /* Rotated constant. */
8967 shift
= (shift
<< 1) | (imm
>> 7);
8969 imm
= imm
<< (32 - shift
);
8973 tmp2
= tcg_temp_new_i32();
8974 tcg_gen_movi_i32(tmp2
, imm
);
8975 rn
= (insn
>> 16) & 0xf;
8977 tmp
= tcg_temp_new_i32();
8978 tcg_gen_movi_i32(tmp
, 0);
8980 tmp
= load_reg(s
, rn
);
8982 op
= (insn
>> 21) & 0xf;
8983 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8984 shifter_out
, tmp
, tmp2
))
8986 tcg_temp_free_i32(tmp2
);
8987 rd
= (insn
>> 8) & 0xf;
8989 store_reg(s
, rd
, tmp
);
8991 tcg_temp_free_i32(tmp
);
8996 case 12: /* Load/store single data item. */
9001 if ((insn
& 0x01100000) == 0x01000000) {
9002 if (disas_neon_ls_insn(env
, s
, insn
))
9006 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9008 if (!(insn
& (1 << 20))) {
9012 /* Byte or halfword load space with dest == r15 : memory hints.
9013 * Catch them early so we don't emit pointless addressing code.
9014 * This space is a mix of:
9015 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9016 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9018 * unallocated hints, which must be treated as NOPs
9019 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9020 * which is easiest for the decoding logic
9021 * Some space which must UNDEF
9023 int op1
= (insn
>> 23) & 3;
9024 int op2
= (insn
>> 6) & 0x3f;
9029 /* UNPREDICTABLE, unallocated hint or
9030 * PLD/PLDW/PLI (literal)
9035 return 0; /* PLD/PLDW/PLI or unallocated hint */
9037 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9038 return 0; /* PLD/PLDW/PLI or unallocated hint */
9040 /* UNDEF space, or an UNPREDICTABLE */
9046 addr
= tcg_temp_new_i32();
9048 /* s->pc has already been incremented by 4. */
9049 imm
= s
->pc
& 0xfffffffc;
9050 if (insn
& (1 << 23))
9051 imm
+= insn
& 0xfff;
9053 imm
-= insn
& 0xfff;
9054 tcg_gen_movi_i32(addr
, imm
);
9056 addr
= load_reg(s
, rn
);
9057 if (insn
& (1 << 23)) {
9058 /* Positive offset. */
9060 tcg_gen_addi_i32(addr
, addr
, imm
);
9063 switch ((insn
>> 8) & 0xf) {
9064 case 0x0: /* Shifted Register. */
9065 shift
= (insn
>> 4) & 0xf;
9067 tcg_temp_free_i32(addr
);
9070 tmp
= load_reg(s
, rm
);
9072 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9073 tcg_gen_add_i32(addr
, addr
, tmp
);
9074 tcg_temp_free_i32(tmp
);
9076 case 0xc: /* Negative offset. */
9077 tcg_gen_addi_i32(addr
, addr
, -imm
);
9079 case 0xe: /* User privilege. */
9080 tcg_gen_addi_i32(addr
, addr
, imm
);
9083 case 0x9: /* Post-decrement. */
9086 case 0xb: /* Post-increment. */
9090 case 0xd: /* Pre-decrement. */
9093 case 0xf: /* Pre-increment. */
9094 tcg_gen_addi_i32(addr
, addr
, imm
);
9098 tcg_temp_free_i32(addr
);
9103 if (insn
& (1 << 20)) {
9106 case 0: tmp
= gen_ld8u(addr
, user
); break;
9107 case 4: tmp
= gen_ld8s(addr
, user
); break;
9108 case 1: tmp
= gen_ld16u(addr
, user
); break;
9109 case 5: tmp
= gen_ld16s(addr
, user
); break;
9110 case 2: tmp
= gen_ld32(addr
, user
); break;
9112 tcg_temp_free_i32(addr
);
9118 store_reg(s
, rs
, tmp
);
9122 tmp
= load_reg(s
, rs
);
9124 case 0: gen_st8(tmp
, addr
, user
); break;
9125 case 1: gen_st16(tmp
, addr
, user
); break;
9126 case 2: gen_st32(tmp
, addr
, user
); break;
9128 tcg_temp_free_i32(addr
);
9133 tcg_gen_addi_i32(addr
, addr
, imm
);
9135 store_reg(s
, rn
, addr
);
9137 tcg_temp_free_i32(addr
);
9149 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9151 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9158 if (s
->condexec_mask
) {
9159 cond
= s
->condexec_cond
;
9160 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9161 s
->condlabel
= gen_new_label();
9162 gen_test_cc(cond
^ 1, s
->condlabel
);
9167 insn
= arm_lduw_code(s
->pc
, s
->bswap_code
);
9170 switch (insn
>> 12) {
9174 op
= (insn
>> 11) & 3;
9177 rn
= (insn
>> 3) & 7;
9178 tmp
= load_reg(s
, rn
);
9179 if (insn
& (1 << 10)) {
9181 tmp2
= tcg_temp_new_i32();
9182 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9185 rm
= (insn
>> 6) & 7;
9186 tmp2
= load_reg(s
, rm
);
9188 if (insn
& (1 << 9)) {
9189 if (s
->condexec_mask
)
9190 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9192 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9194 if (s
->condexec_mask
)
9195 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9197 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9199 tcg_temp_free_i32(tmp2
);
9200 store_reg(s
, rd
, tmp
);
9202 /* shift immediate */
9203 rm
= (insn
>> 3) & 7;
9204 shift
= (insn
>> 6) & 0x1f;
9205 tmp
= load_reg(s
, rm
);
9206 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9207 if (!s
->condexec_mask
)
9209 store_reg(s
, rd
, tmp
);
9213 /* arithmetic large immediate */
9214 op
= (insn
>> 11) & 3;
9215 rd
= (insn
>> 8) & 0x7;
9216 if (op
== 0) { /* mov */
9217 tmp
= tcg_temp_new_i32();
9218 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9219 if (!s
->condexec_mask
)
9221 store_reg(s
, rd
, tmp
);
9223 tmp
= load_reg(s
, rd
);
9224 tmp2
= tcg_temp_new_i32();
9225 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9228 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9229 tcg_temp_free_i32(tmp
);
9230 tcg_temp_free_i32(tmp2
);
9233 if (s
->condexec_mask
)
9234 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9236 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9237 tcg_temp_free_i32(tmp2
);
9238 store_reg(s
, rd
, tmp
);
9241 if (s
->condexec_mask
)
9242 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9244 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9245 tcg_temp_free_i32(tmp2
);
9246 store_reg(s
, rd
, tmp
);
9252 if (insn
& (1 << 11)) {
9253 rd
= (insn
>> 8) & 7;
9254 /* load pc-relative. Bit 1 of PC is ignored. */
9255 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9256 val
&= ~(uint32_t)2;
9257 addr
= tcg_temp_new_i32();
9258 tcg_gen_movi_i32(addr
, val
);
9259 tmp
= gen_ld32(addr
, IS_USER(s
));
9260 tcg_temp_free_i32(addr
);
9261 store_reg(s
, rd
, tmp
);
9264 if (insn
& (1 << 10)) {
9265 /* data processing extended or blx */
9266 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9267 rm
= (insn
>> 3) & 0xf;
9268 op
= (insn
>> 8) & 3;
9271 tmp
= load_reg(s
, rd
);
9272 tmp2
= load_reg(s
, rm
);
9273 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9274 tcg_temp_free_i32(tmp2
);
9275 store_reg(s
, rd
, tmp
);
9278 tmp
= load_reg(s
, rd
);
9279 tmp2
= load_reg(s
, rm
);
9280 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9281 tcg_temp_free_i32(tmp2
);
9282 tcg_temp_free_i32(tmp
);
9284 case 2: /* mov/cpy */
9285 tmp
= load_reg(s
, rm
);
9286 store_reg(s
, rd
, tmp
);
9288 case 3:/* branch [and link] exchange thumb register */
9289 tmp
= load_reg(s
, rm
);
9290 if (insn
& (1 << 7)) {
9292 val
= (uint32_t)s
->pc
| 1;
9293 tmp2
= tcg_temp_new_i32();
9294 tcg_gen_movi_i32(tmp2
, val
);
9295 store_reg(s
, 14, tmp2
);
9297 /* already thumb, no need to check */
9304 /* data processing register */
9306 rm
= (insn
>> 3) & 7;
9307 op
= (insn
>> 6) & 0xf;
9308 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9309 /* the shift/rotate ops want the operands backwards */
9318 if (op
== 9) { /* neg */
9319 tmp
= tcg_temp_new_i32();
9320 tcg_gen_movi_i32(tmp
, 0);
9321 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9322 tmp
= load_reg(s
, rd
);
9327 tmp2
= load_reg(s
, rm
);
9330 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9331 if (!s
->condexec_mask
)
9335 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9336 if (!s
->condexec_mask
)
9340 if (s
->condexec_mask
) {
9341 gen_helper_shl(tmp2
, tmp2
, tmp
);
9343 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
9348 if (s
->condexec_mask
) {
9349 gen_helper_shr(tmp2
, tmp2
, tmp
);
9351 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
9356 if (s
->condexec_mask
) {
9357 gen_helper_sar(tmp2
, tmp2
, tmp
);
9359 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
9364 if (s
->condexec_mask
)
9367 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
9370 if (s
->condexec_mask
)
9371 gen_sub_carry(tmp
, tmp
, tmp2
);
9373 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
9376 if (s
->condexec_mask
) {
9377 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9378 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9380 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
9385 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9390 if (s
->condexec_mask
)
9391 tcg_gen_neg_i32(tmp
, tmp2
);
9393 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9396 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9400 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9404 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9405 if (!s
->condexec_mask
)
9409 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9410 if (!s
->condexec_mask
)
9414 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9415 if (!s
->condexec_mask
)
9419 tcg_gen_not_i32(tmp2
, tmp2
);
9420 if (!s
->condexec_mask
)
9428 store_reg(s
, rm
, tmp2
);
9430 tcg_temp_free_i32(tmp
);
9432 store_reg(s
, rd
, tmp
);
9433 tcg_temp_free_i32(tmp2
);
9436 tcg_temp_free_i32(tmp
);
9437 tcg_temp_free_i32(tmp2
);
9442 /* load/store register offset. */
9444 rn
= (insn
>> 3) & 7;
9445 rm
= (insn
>> 6) & 7;
9446 op
= (insn
>> 9) & 7;
9447 addr
= load_reg(s
, rn
);
9448 tmp
= load_reg(s
, rm
);
9449 tcg_gen_add_i32(addr
, addr
, tmp
);
9450 tcg_temp_free_i32(tmp
);
9452 if (op
< 3) /* store */
9453 tmp
= load_reg(s
, rd
);
9457 gen_st32(tmp
, addr
, IS_USER(s
));
9460 gen_st16(tmp
, addr
, IS_USER(s
));
9463 gen_st8(tmp
, addr
, IS_USER(s
));
9466 tmp
= gen_ld8s(addr
, IS_USER(s
));
9469 tmp
= gen_ld32(addr
, IS_USER(s
));
9472 tmp
= gen_ld16u(addr
, IS_USER(s
));
9475 tmp
= gen_ld8u(addr
, IS_USER(s
));
9478 tmp
= gen_ld16s(addr
, IS_USER(s
));
9481 if (op
>= 3) /* load */
9482 store_reg(s
, rd
, tmp
);
9483 tcg_temp_free_i32(addr
);
9487 /* load/store word immediate offset */
9489 rn
= (insn
>> 3) & 7;
9490 addr
= load_reg(s
, rn
);
9491 val
= (insn
>> 4) & 0x7c;
9492 tcg_gen_addi_i32(addr
, addr
, val
);
9494 if (insn
& (1 << 11)) {
9496 tmp
= gen_ld32(addr
, IS_USER(s
));
9497 store_reg(s
, rd
, tmp
);
9500 tmp
= load_reg(s
, rd
);
9501 gen_st32(tmp
, addr
, IS_USER(s
));
9503 tcg_temp_free_i32(addr
);
9507 /* load/store byte immediate offset */
9509 rn
= (insn
>> 3) & 7;
9510 addr
= load_reg(s
, rn
);
9511 val
= (insn
>> 6) & 0x1f;
9512 tcg_gen_addi_i32(addr
, addr
, val
);
9514 if (insn
& (1 << 11)) {
9516 tmp
= gen_ld8u(addr
, IS_USER(s
));
9517 store_reg(s
, rd
, tmp
);
9520 tmp
= load_reg(s
, rd
);
9521 gen_st8(tmp
, addr
, IS_USER(s
));
9523 tcg_temp_free_i32(addr
);
9527 /* load/store halfword immediate offset */
9529 rn
= (insn
>> 3) & 7;
9530 addr
= load_reg(s
, rn
);
9531 val
= (insn
>> 5) & 0x3e;
9532 tcg_gen_addi_i32(addr
, addr
, val
);
9534 if (insn
& (1 << 11)) {
9536 tmp
= gen_ld16u(addr
, IS_USER(s
));
9537 store_reg(s
, rd
, tmp
);
9540 tmp
= load_reg(s
, rd
);
9541 gen_st16(tmp
, addr
, IS_USER(s
));
9543 tcg_temp_free_i32(addr
);
9547 /* load/store from stack */
9548 rd
= (insn
>> 8) & 7;
9549 addr
= load_reg(s
, 13);
9550 val
= (insn
& 0xff) * 4;
9551 tcg_gen_addi_i32(addr
, addr
, val
);
9553 if (insn
& (1 << 11)) {
9555 tmp
= gen_ld32(addr
, IS_USER(s
));
9556 store_reg(s
, rd
, tmp
);
9559 tmp
= load_reg(s
, rd
);
9560 gen_st32(tmp
, addr
, IS_USER(s
));
9562 tcg_temp_free_i32(addr
);
9566 /* add to high reg */
9567 rd
= (insn
>> 8) & 7;
9568 if (insn
& (1 << 11)) {
9570 tmp
= load_reg(s
, 13);
9572 /* PC. bit 1 is ignored. */
9573 tmp
= tcg_temp_new_i32();
9574 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9576 val
= (insn
& 0xff) * 4;
9577 tcg_gen_addi_i32(tmp
, tmp
, val
);
9578 store_reg(s
, rd
, tmp
);
9583 op
= (insn
>> 8) & 0xf;
9586 /* adjust stack pointer */
9587 tmp
= load_reg(s
, 13);
9588 val
= (insn
& 0x7f) * 4;
9589 if (insn
& (1 << 7))
9590 val
= -(int32_t)val
;
9591 tcg_gen_addi_i32(tmp
, tmp
, val
);
9592 store_reg(s
, 13, tmp
);
9595 case 2: /* sign/zero extend. */
9598 rm
= (insn
>> 3) & 7;
9599 tmp
= load_reg(s
, rm
);
9600 switch ((insn
>> 6) & 3) {
9601 case 0: gen_sxth(tmp
); break;
9602 case 1: gen_sxtb(tmp
); break;
9603 case 2: gen_uxth(tmp
); break;
9604 case 3: gen_uxtb(tmp
); break;
9606 store_reg(s
, rd
, tmp
);
9608 case 4: case 5: case 0xc: case 0xd:
9610 addr
= load_reg(s
, 13);
9611 if (insn
& (1 << 8))
9615 for (i
= 0; i
< 8; i
++) {
9616 if (insn
& (1 << i
))
9619 if ((insn
& (1 << 11)) == 0) {
9620 tcg_gen_addi_i32(addr
, addr
, -offset
);
9622 for (i
= 0; i
< 8; i
++) {
9623 if (insn
& (1 << i
)) {
9624 if (insn
& (1 << 11)) {
9626 tmp
= gen_ld32(addr
, IS_USER(s
));
9627 store_reg(s
, i
, tmp
);
9630 tmp
= load_reg(s
, i
);
9631 gen_st32(tmp
, addr
, IS_USER(s
));
9633 /* advance to the next address. */
9634 tcg_gen_addi_i32(addr
, addr
, 4);
9638 if (insn
& (1 << 8)) {
9639 if (insn
& (1 << 11)) {
9641 tmp
= gen_ld32(addr
, IS_USER(s
));
9642 /* don't set the pc until the rest of the instruction
9646 tmp
= load_reg(s
, 14);
9647 gen_st32(tmp
, addr
, IS_USER(s
));
9649 tcg_gen_addi_i32(addr
, addr
, 4);
9651 if ((insn
& (1 << 11)) == 0) {
9652 tcg_gen_addi_i32(addr
, addr
, -offset
);
9654 /* write back the new stack pointer */
9655 store_reg(s
, 13, addr
);
9656 /* set the new PC value */
9657 if ((insn
& 0x0900) == 0x0900) {
9658 store_reg_from_load(env
, s
, 15, tmp
);
9662 case 1: case 3: case 9: case 11: /* czb */
9664 tmp
= load_reg(s
, rm
);
9665 s
->condlabel
= gen_new_label();
9667 if (insn
& (1 << 11))
9668 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9670 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9671 tcg_temp_free_i32(tmp
);
9672 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9673 val
= (uint32_t)s
->pc
+ 2;
9678 case 15: /* IT, nop-hint. */
9679 if ((insn
& 0xf) == 0) {
9680 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9684 s
->condexec_cond
= (insn
>> 4) & 0xe;
9685 s
->condexec_mask
= insn
& 0x1f;
9686 /* No actual code generated for this insn, just setup state. */
9689 case 0xe: /* bkpt */
9691 gen_exception_insn(s
, 2, EXCP_BKPT
);
9696 rn
= (insn
>> 3) & 0x7;
9698 tmp
= load_reg(s
, rn
);
9699 switch ((insn
>> 6) & 3) {
9700 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9701 case 1: gen_rev16(tmp
); break;
9702 case 3: gen_revsh(tmp
); break;
9703 default: goto illegal_op
;
9705 store_reg(s
, rd
, tmp
);
9709 switch ((insn
>> 5) & 7) {
9713 if (insn
& (1 << 3)) {
9714 /* BE8 mode not implemented. */
9725 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9728 addr
= tcg_const_i32(19);
9729 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9730 tcg_temp_free_i32(addr
);
9734 addr
= tcg_const_i32(16);
9735 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9736 tcg_temp_free_i32(addr
);
9738 tcg_temp_free_i32(tmp
);
9741 if (insn
& (1 << 4)) {
9742 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9746 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9761 /* load/store multiple */
9763 TCGV_UNUSED(loaded_var
);
9764 rn
= (insn
>> 8) & 0x7;
9765 addr
= load_reg(s
, rn
);
9766 for (i
= 0; i
< 8; i
++) {
9767 if (insn
& (1 << i
)) {
9768 if (insn
& (1 << 11)) {
9770 tmp
= gen_ld32(addr
, IS_USER(s
));
9774 store_reg(s
, i
, tmp
);
9778 tmp
= load_reg(s
, i
);
9779 gen_st32(tmp
, addr
, IS_USER(s
));
9781 /* advance to the next address */
9782 tcg_gen_addi_i32(addr
, addr
, 4);
9785 if ((insn
& (1 << rn
)) == 0) {
9786 /* base reg not in list: base register writeback */
9787 store_reg(s
, rn
, addr
);
9789 /* base reg in list: if load, complete it now */
9790 if (insn
& (1 << 11)) {
9791 store_reg(s
, rn
, loaded_var
);
9793 tcg_temp_free_i32(addr
);
9798 /* conditional branch or swi */
9799 cond
= (insn
>> 8) & 0xf;
9805 gen_set_pc_im(s
->pc
);
9806 s
->is_jmp
= DISAS_SWI
;
9809 /* generate a conditional jump to next instruction */
9810 s
->condlabel
= gen_new_label();
9811 gen_test_cc(cond
^ 1, s
->condlabel
);
9814 /* jump to the offset */
9815 val
= (uint32_t)s
->pc
+ 2;
9816 offset
= ((int32_t)insn
<< 24) >> 24;
9822 if (insn
& (1 << 11)) {
9823 if (disas_thumb2_insn(env
, s
, insn
))
9827 /* unconditional branch */
9828 val
= (uint32_t)s
->pc
;
9829 offset
= ((int32_t)insn
<< 21) >> 21;
9830 val
+= (offset
<< 1) + 2;
9835 if (disas_thumb2_insn(env
, s
, insn
))
9841 gen_exception_insn(s
, 4, EXCP_UDEF
);
9845 gen_exception_insn(s
, 2, EXCP_UDEF
);
9848 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9849 basic block 'tb'. If search_pc is TRUE, also generate PC
9850 information for each intermediate instruction. */
9851 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9852 TranslationBlock
*tb
,
9855 DisasContext dc1
, *dc
= &dc1
;
9857 uint16_t *gen_opc_end
;
9859 target_ulong pc_start
;
9860 uint32_t next_page_start
;
9864 /* generate intermediate code */
9869 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9871 dc
->is_jmp
= DISAS_NEXT
;
9873 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9875 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9876 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9877 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9878 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9879 #if !defined(CONFIG_USER_ONLY)
9880 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9882 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9883 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9884 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9885 cpu_F0s
= tcg_temp_new_i32();
9886 cpu_F1s
= tcg_temp_new_i32();
9887 cpu_F0d
= tcg_temp_new_i64();
9888 cpu_F1d
= tcg_temp_new_i64();
9891 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9892 cpu_M0
= tcg_temp_new_i64();
9893 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9896 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9898 max_insns
= CF_COUNT_MASK
;
9902 tcg_clear_temp_count();
9904 /* A note on handling of the condexec (IT) bits:
9906 * We want to avoid the overhead of having to write the updated condexec
9907 * bits back to the CPUARMState for every instruction in an IT block. So:
9908 * (1) if the condexec bits are not already zero then we write
9909 * zero back into the CPUARMState now. This avoids complications trying
9910 * to do it at the end of the block. (For example if we don't do this
9911 * it's hard to identify whether we can safely skip writing condexec
9912 * at the end of the TB, which we definitely want to do for the case
9913 * where a TB doesn't do anything with the IT state at all.)
9914 * (2) if we are going to leave the TB then we call gen_set_condexec()
9915 * which will write the correct value into CPUARMState if zero is wrong.
9916 * This is done both for leaving the TB at the end, and for leaving
9917 * it because of an exception we know will happen, which is done in
9918 * gen_exception_insn(). The latter is necessary because we need to
9919 * leave the TB with the PC/IT state just prior to execution of the
9920 * instruction which caused the exception.
9921 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9922 * then the CPUARMState will be wrong and we need to reset it.
9923 * This is handled in the same way as restoration of the
9924 * PC in these situations: we will be called again with search_pc=1
9925 * and generate a mapping of the condexec bits for each PC in
9926 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9927 * this to restore the condexec bits.
9929 * Note that there are no instructions which can read the condexec
9930 * bits, and none which can write non-static values to them, so
9931 * we don't need to care about whether CPUARMState is correct in the
9935 /* Reset the conditional execution bits immediately. This avoids
9936 complications trying to do it at the end of the block. */
9937 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9939 TCGv tmp
= tcg_temp_new_i32();
9940 tcg_gen_movi_i32(tmp
, 0);
9941 store_cpu_field(tmp
, condexec_bits
);
9944 #ifdef CONFIG_USER_ONLY
9945 /* Intercept jump to the magic kernel page. */
9946 if (dc
->pc
>= 0xffff0000) {
9947 /* We always get here via a jump, so know we are not in a
9948 conditional execution block. */
9949 gen_exception(EXCP_KERNEL_TRAP
);
9950 dc
->is_jmp
= DISAS_UPDATE
;
9954 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9955 /* We always get here via a jump, so know we are not in a
9956 conditional execution block. */
9957 gen_exception(EXCP_EXCEPTION_EXIT
);
9958 dc
->is_jmp
= DISAS_UPDATE
;
9963 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9964 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9965 if (bp
->pc
== dc
->pc
) {
9966 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9967 /* Advance PC so that clearing the breakpoint will
9968 invalidate this TB. */
9970 goto done_generating
;
9976 j
= gen_opc_ptr
- gen_opc_buf
;
9980 gen_opc_instr_start
[lj
++] = 0;
9982 gen_opc_pc
[lj
] = dc
->pc
;
9983 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9984 gen_opc_instr_start
[lj
] = 1;
9985 gen_opc_icount
[lj
] = num_insns
;
9988 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9991 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9992 tcg_gen_debug_insn_start(dc
->pc
);
9996 disas_thumb_insn(env
, dc
);
9997 if (dc
->condexec_mask
) {
9998 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9999 | ((dc
->condexec_mask
>> 4) & 1);
10000 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10001 if (dc
->condexec_mask
== 0) {
10002 dc
->condexec_cond
= 0;
10006 disas_arm_insn(env
, dc
);
10009 if (dc
->condjmp
&& !dc
->is_jmp
) {
10010 gen_set_label(dc
->condlabel
);
10014 if (tcg_check_temp_count()) {
10015 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
10018 /* Translation stops when a conditional branch is encountered.
10019 * Otherwise the subsequent code could get translated several times.
10020 * Also stop translation when a page boundary is reached. This
10021 * ensures prefetch aborts occur at the right place. */
10023 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
10024 !env
->singlestep_enabled
&&
10026 dc
->pc
< next_page_start
&&
10027 num_insns
< max_insns
);
10029 if (tb
->cflags
& CF_LAST_IO
) {
10031 /* FIXME: This can theoretically happen with self-modifying
10033 cpu_abort(env
, "IO on conditional branch instruction");
10038 /* At this stage dc->condjmp will only be set when the skipped
10039 instruction was a conditional branch or trap, and the PC has
10040 already been written. */
10041 if (unlikely(env
->singlestep_enabled
)) {
10042 /* Make sure the pc is updated, and raise a debug exception. */
10044 gen_set_condexec(dc
);
10045 if (dc
->is_jmp
== DISAS_SWI
) {
10046 gen_exception(EXCP_SWI
);
10048 gen_exception(EXCP_DEBUG
);
10050 gen_set_label(dc
->condlabel
);
10052 if (dc
->condjmp
|| !dc
->is_jmp
) {
10053 gen_set_pc_im(dc
->pc
);
10056 gen_set_condexec(dc
);
10057 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10058 gen_exception(EXCP_SWI
);
10060 /* FIXME: Single stepping a WFI insn will not halt
10062 gen_exception(EXCP_DEBUG
);
10065 /* While branches must always occur at the end of an IT block,
10066 there are a few other things that can cause us to terminate
10067 the TB in the middel of an IT block:
10068 - Exception generating instructions (bkpt, swi, undefined).
10070 - Hardware watchpoints.
10071 Hardware breakpoints have already been handled and skip this code.
10073 gen_set_condexec(dc
);
10074 switch(dc
->is_jmp
) {
10076 gen_goto_tb(dc
, 1, dc
->pc
);
10081 /* indicate that the hash table must be used to find the next TB */
10082 tcg_gen_exit_tb(0);
10084 case DISAS_TB_JUMP
:
10085 /* nothing more to generate */
10091 gen_exception(EXCP_SWI
);
10095 gen_set_label(dc
->condlabel
);
10096 gen_set_condexec(dc
);
10097 gen_goto_tb(dc
, 1, dc
->pc
);
10103 gen_icount_end(tb
, num_insns
);
10104 *gen_opc_ptr
= INDEX_op_end
;
10107 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10108 qemu_log("----------------\n");
10109 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10110 log_target_disas(pc_start
, dc
->pc
- pc_start
,
10111 dc
->thumb
| (dc
->bswap_code
<< 1));
10116 j
= gen_opc_ptr
- gen_opc_buf
;
10119 gen_opc_instr_start
[lj
++] = 0;
10121 tb
->size
= dc
->pc
- pc_start
;
10122 tb
->icount
= num_insns
;
10126 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10128 gen_intermediate_code_internal(env
, tb
, 0);
10131 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10133 gen_intermediate_code_internal(env
, tb
, 1);
10136 static const char *cpu_mode_names
[16] = {
10137 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10138 "???", "???", "???", "und", "???", "???", "???", "sys"
10141 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10151 /* ??? This assumes float64 and double have the same layout.
10152 Oh well, it's only debug dumps. */
10160 for(i
=0;i
<16;i
++) {
10161 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10163 cpu_fprintf(f
, "\n");
10165 cpu_fprintf(f
, " ");
10167 psr
= cpsr_read(env
);
10168 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10170 psr
& (1 << 31) ? 'N' : '-',
10171 psr
& (1 << 30) ? 'Z' : '-',
10172 psr
& (1 << 29) ? 'C' : '-',
10173 psr
& (1 << 28) ? 'V' : '-',
10174 psr
& CPSR_T
? 'T' : 'A',
10175 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10178 for (i
= 0; i
< 16; i
++) {
10179 d
.d
= env
->vfp
.regs
[i
];
10183 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
10184 i
* 2, (int)s0
.i
, s0
.s
,
10185 i
* 2 + 1, (int)s1
.i
, s1
.s
,
10186 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
10189 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10193 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10195 env
->regs
[15] = gen_opc_pc
[pc_pos
];
10196 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];