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 conditional 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 execution 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_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
89 static TCGv_i32 cpu_exclusive_addr
;
90 static TCGv_i32 cpu_exclusive_val
;
91 static TCGv_i32 cpu_exclusive_high
;
92 #ifdef CONFIG_USER_ONLY
93 static TCGv_i32 cpu_exclusive_test
;
94 static TCGv_i32 cpu_exclusive_info
;
97 /* FIXME: These should be removed. */
98 static TCGv cpu_F0s
, cpu_F1s
;
99 static TCGv_i64 cpu_F0d
, cpu_F1d
;
101 #include "gen-icount.h"
103 static const char *regnames
[] =
104 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
107 /* initialize TCG globals. */
108 void arm_translate_init(void)
112 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
114 for (i
= 0; i
< 16; i
++) {
115 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
116 offsetof(CPUARMState
, regs
[i
]),
119 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
120 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
121 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
122 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
124 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
125 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
126 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
127 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
128 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
129 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
130 #ifdef CONFIG_USER_ONLY
131 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
132 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
133 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
134 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
141 static inline TCGv
load_cpu_offset(int offset
)
143 TCGv tmp
= tcg_temp_new_i32();
144 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
148 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
150 static inline void store_cpu_offset(TCGv var
, int offset
)
152 tcg_gen_st_i32(var
, cpu_env
, offset
);
153 tcg_temp_free_i32(var
);
156 #define store_cpu_field(var, name) \
157 store_cpu_offset(var, offsetof(CPUARMState, name))
159 /* Set a variable to the value of a CPU register. */
160 static void load_reg_var(DisasContext
*s
, TCGv var
, int reg
)
164 /* normally, since we updated PC, we need only to add one insn */
166 addr
= (long)s
->pc
+ 2;
168 addr
= (long)s
->pc
+ 4;
169 tcg_gen_movi_i32(var
, addr
);
171 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
175 /* Create a new temporary and set it to the value of a CPU register. */
176 static inline TCGv
load_reg(DisasContext
*s
, int reg
)
178 TCGv tmp
= tcg_temp_new_i32();
179 load_reg_var(s
, tmp
, reg
);
183 /* Set a CPU register. The source must be a temporary and will be
185 static void store_reg(DisasContext
*s
, int reg
, TCGv var
)
188 tcg_gen_andi_i32(var
, var
, ~1);
189 s
->is_jmp
= DISAS_JUMP
;
191 tcg_gen_mov_i32(cpu_R
[reg
], var
);
192 tcg_temp_free_i32(var
);
195 /* Value extensions. */
196 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
197 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
198 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
199 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
201 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
202 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
205 static inline void gen_set_cpsr(TCGv var
, uint32_t mask
)
207 TCGv tmp_mask
= tcg_const_i32(mask
);
208 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
209 tcg_temp_free_i32(tmp_mask
);
211 /* Set NZCV flags from the high 4 bits of var. */
212 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214 static void gen_exception(int excp
)
216 TCGv tmp
= tcg_temp_new_i32();
217 tcg_gen_movi_i32(tmp
, excp
);
218 gen_helper_exception(cpu_env
, tmp
);
219 tcg_temp_free_i32(tmp
);
222 static void gen_smul_dual(TCGv a
, TCGv b
)
224 TCGv tmp1
= tcg_temp_new_i32();
225 TCGv tmp2
= tcg_temp_new_i32();
226 tcg_gen_ext16s_i32(tmp1
, a
);
227 tcg_gen_ext16s_i32(tmp2
, b
);
228 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
229 tcg_temp_free_i32(tmp2
);
230 tcg_gen_sari_i32(a
, a
, 16);
231 tcg_gen_sari_i32(b
, b
, 16);
232 tcg_gen_mul_i32(b
, b
, a
);
233 tcg_gen_mov_i32(a
, tmp1
);
234 tcg_temp_free_i32(tmp1
);
237 /* Byteswap each halfword. */
238 static void gen_rev16(TCGv var
)
240 TCGv tmp
= tcg_temp_new_i32();
241 tcg_gen_shri_i32(tmp
, var
, 8);
242 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
243 tcg_gen_shli_i32(var
, var
, 8);
244 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
245 tcg_gen_or_i32(var
, var
, tmp
);
246 tcg_temp_free_i32(tmp
);
249 /* Byteswap low halfword and sign extend. */
250 static void gen_revsh(TCGv var
)
252 tcg_gen_ext16u_i32(var
, var
);
253 tcg_gen_bswap16_i32(var
, var
);
254 tcg_gen_ext16s_i32(var
, var
);
257 /* Unsigned bitfield extract. */
258 static void gen_ubfx(TCGv var
, int shift
, uint32_t mask
)
261 tcg_gen_shri_i32(var
, var
, shift
);
262 tcg_gen_andi_i32(var
, var
, mask
);
265 /* Signed bitfield extract. */
266 static void gen_sbfx(TCGv var
, int shift
, int width
)
271 tcg_gen_sari_i32(var
, var
, shift
);
272 if (shift
+ width
< 32) {
273 signbit
= 1u << (width
- 1);
274 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
275 tcg_gen_xori_i32(var
, var
, signbit
);
276 tcg_gen_subi_i32(var
, var
, signbit
);
280 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
281 static void gen_bfi(TCGv dest
, TCGv base
, TCGv val
, int shift
, uint32_t mask
)
283 tcg_gen_andi_i32(val
, val
, mask
);
284 tcg_gen_shli_i32(val
, val
, shift
);
285 tcg_gen_andi_i32(base
, base
, ~(mask
<< shift
));
286 tcg_gen_or_i32(dest
, base
, val
);
289 /* Return (b << 32) + a. Mark inputs as dead */
290 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
292 TCGv_i64 tmp64
= tcg_temp_new_i64();
294 tcg_gen_extu_i32_i64(tmp64
, b
);
295 tcg_temp_free_i32(b
);
296 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
297 tcg_gen_add_i64(a
, tmp64
, a
);
299 tcg_temp_free_i64(tmp64
);
303 /* Return (b << 32) - a. Mark inputs as dead. */
304 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
306 TCGv_i64 tmp64
= tcg_temp_new_i64();
308 tcg_gen_extu_i32_i64(tmp64
, b
);
309 tcg_temp_free_i32(b
);
310 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
311 tcg_gen_sub_i64(a
, tmp64
, a
);
313 tcg_temp_free_i64(tmp64
);
317 /* FIXME: Most targets have native widening multiplication.
318 It would be good to use that instead of a full wide multiply. */
319 /* 32x32->64 multiply. Marks inputs as dead. */
320 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
322 TCGv_i64 tmp1
= tcg_temp_new_i64();
323 TCGv_i64 tmp2
= tcg_temp_new_i64();
325 tcg_gen_extu_i32_i64(tmp1
, a
);
326 tcg_temp_free_i32(a
);
327 tcg_gen_extu_i32_i64(tmp2
, b
);
328 tcg_temp_free_i32(b
);
329 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
330 tcg_temp_free_i64(tmp2
);
334 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
336 TCGv_i64 tmp1
= tcg_temp_new_i64();
337 TCGv_i64 tmp2
= tcg_temp_new_i64();
339 tcg_gen_ext_i32_i64(tmp1
, a
);
340 tcg_temp_free_i32(a
);
341 tcg_gen_ext_i32_i64(tmp2
, b
);
342 tcg_temp_free_i32(b
);
343 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
344 tcg_temp_free_i64(tmp2
);
348 /* Swap low and high halfwords. */
349 static void gen_swap_half(TCGv var
)
351 TCGv tmp
= tcg_temp_new_i32();
352 tcg_gen_shri_i32(tmp
, var
, 16);
353 tcg_gen_shli_i32(var
, var
, 16);
354 tcg_gen_or_i32(var
, var
, tmp
);
355 tcg_temp_free_i32(tmp
);
358 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
359 tmp = (t0 ^ t1) & 0x8000;
362 t0 = (t0 + t1) ^ tmp;
365 static void gen_add16(TCGv t0
, TCGv t1
)
367 TCGv tmp
= tcg_temp_new_i32();
368 tcg_gen_xor_i32(tmp
, t0
, t1
);
369 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
370 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
371 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
372 tcg_gen_add_i32(t0
, t0
, t1
);
373 tcg_gen_xor_i32(t0
, t0
, tmp
);
374 tcg_temp_free_i32(tmp
);
375 tcg_temp_free_i32(t1
);
378 /* Set CF to the top bit of var. */
379 static void gen_set_CF_bit31(TCGv var
)
381 tcg_gen_shri_i32(cpu_CF
, var
, 31);
384 /* Set N and Z flags from var. */
385 static inline void gen_logic_CC(TCGv var
)
387 tcg_gen_mov_i32(cpu_NF
, var
);
388 tcg_gen_mov_i32(cpu_ZF
, var
);
392 static void gen_adc(TCGv t0
, TCGv t1
)
394 tcg_gen_add_i32(t0
, t0
, t1
);
395 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
398 /* dest = T0 + T1 + CF. */
399 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
401 tcg_gen_add_i32(dest
, t0
, t1
);
402 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
405 /* dest = T0 - T1 + CF - 1. */
406 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
408 tcg_gen_sub_i32(dest
, t0
, t1
);
409 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
410 tcg_gen_subi_i32(dest
, dest
, 1);
413 /* dest = T0 + T1. Compute C, N, V and Z flags */
414 static void gen_add_CC(TCGv dest
, TCGv t0
, TCGv t1
)
417 tcg_gen_add_i32(cpu_NF
, t0
, t1
);
418 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
419 tcg_gen_setcond_i32(TCG_COND_LTU
, cpu_CF
, cpu_NF
, t0
);
420 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
421 tmp
= tcg_temp_new_i32();
422 tcg_gen_xor_i32(tmp
, t0
, t1
);
423 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
424 tcg_temp_free_i32(tmp
);
425 tcg_gen_mov_i32(dest
, cpu_NF
);
428 /* dest = T0 - T1. Compute C, N, V and Z flags */
429 static void gen_sub_CC(TCGv dest
, TCGv t0
, TCGv t1
)
432 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
433 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
434 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
435 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
436 tmp
= tcg_temp_new_i32();
437 tcg_gen_xor_i32(tmp
, t0
, t1
);
438 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
439 tcg_temp_free_i32(tmp
);
440 tcg_gen_mov_i32(dest
, cpu_NF
);
443 /* FIXME: Implement this natively. */
444 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
446 static void shifter_out_im(TCGv var
, int shift
)
449 tcg_gen_andi_i32(cpu_CF
, var
, 1);
451 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
453 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
458 /* Shift by immediate. Includes special handling for shift == 0. */
459 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
465 shifter_out_im(var
, 32 - shift
);
466 tcg_gen_shli_i32(var
, var
, shift
);
472 tcg_gen_shri_i32(cpu_CF
, var
, 31);
474 tcg_gen_movi_i32(var
, 0);
477 shifter_out_im(var
, shift
- 1);
478 tcg_gen_shri_i32(var
, var
, shift
);
485 shifter_out_im(var
, shift
- 1);
488 tcg_gen_sari_i32(var
, var
, shift
);
490 case 3: /* ROR/RRX */
493 shifter_out_im(var
, shift
- 1);
494 tcg_gen_rotri_i32(var
, var
, shift
); break;
496 TCGv tmp
= tcg_temp_new_i32();
498 shifter_out_im(var
, 0);
499 tcg_gen_shri_i32(var
, var
, 1);
500 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
501 tcg_gen_or_i32(var
, var
, tmp
);
502 tcg_temp_free_i32(tmp
);
507 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
508 TCGv shift
, int flags
)
512 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
513 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
514 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
515 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
519 case 0: gen_helper_shl(var
, cpu_env
, var
, shift
); break;
520 case 1: gen_helper_shr(var
, cpu_env
, var
, shift
); break;
521 case 2: gen_helper_sar(var
, cpu_env
, var
, shift
); break;
522 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
523 tcg_gen_rotr_i32(var
, var
, shift
); break;
526 tcg_temp_free_i32(shift
);
529 #define PAS_OP(pfx) \
531 case 0: gen_pas_helper(glue(pfx,add16)); break; \
532 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
533 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
534 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
535 case 4: gen_pas_helper(glue(pfx,add8)); break; \
536 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
538 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
543 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
545 tmp
= tcg_temp_new_ptr();
546 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
548 tcg_temp_free_ptr(tmp
);
551 tmp
= tcg_temp_new_ptr();
552 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
554 tcg_temp_free_ptr(tmp
);
556 #undef gen_pas_helper
557 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
570 #undef gen_pas_helper
575 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
576 #define PAS_OP(pfx) \
578 case 0: gen_pas_helper(glue(pfx,add8)); break; \
579 case 1: gen_pas_helper(glue(pfx,add16)); break; \
580 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
581 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
582 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
583 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
585 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
590 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
592 tmp
= tcg_temp_new_ptr();
593 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
595 tcg_temp_free_ptr(tmp
);
598 tmp
= tcg_temp_new_ptr();
599 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
601 tcg_temp_free_ptr(tmp
);
603 #undef gen_pas_helper
604 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
617 #undef gen_pas_helper
622 static void gen_test_cc(int cc
, int label
)
629 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
632 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
635 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
638 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
641 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
644 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
647 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
650 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
652 case 8: /* hi: C && !Z */
653 inv
= gen_new_label();
654 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
655 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
658 case 9: /* ls: !C || Z */
659 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
660 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
662 case 10: /* ge: N == V -> N ^ V == 0 */
663 tmp
= tcg_temp_new_i32();
664 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
665 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
666 tcg_temp_free_i32(tmp
);
668 case 11: /* lt: N != V -> N ^ V != 0 */
669 tmp
= tcg_temp_new_i32();
670 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
671 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
672 tcg_temp_free_i32(tmp
);
674 case 12: /* gt: !Z && N == V */
675 inv
= gen_new_label();
676 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
677 tmp
= tcg_temp_new_i32();
678 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
679 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
680 tcg_temp_free_i32(tmp
);
683 case 13: /* le: Z || N != V */
684 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
685 tmp
= tcg_temp_new_i32();
686 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
687 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
688 tcg_temp_free_i32(tmp
);
691 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
696 static const uint8_t table_logic_cc
[16] = {
715 /* Set PC and Thumb state from an immediate address. */
716 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
720 s
->is_jmp
= DISAS_UPDATE
;
721 if (s
->thumb
!= (addr
& 1)) {
722 tmp
= tcg_temp_new_i32();
723 tcg_gen_movi_i32(tmp
, addr
& 1);
724 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
725 tcg_temp_free_i32(tmp
);
727 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
730 /* Set PC and Thumb state from var. var is marked as dead. */
731 static inline void gen_bx(DisasContext
*s
, TCGv var
)
733 s
->is_jmp
= DISAS_UPDATE
;
734 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
735 tcg_gen_andi_i32(var
, var
, 1);
736 store_cpu_field(var
, thumb
);
739 /* Variant of store_reg which uses branch&exchange logic when storing
740 to r15 in ARM architecture v7 and above. The source must be a temporary
741 and will be marked as dead. */
742 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
745 if (reg
== 15 && ENABLE_ARCH_7
) {
748 store_reg(s
, reg
, var
);
752 /* Variant of store_reg which uses branch&exchange logic when storing
753 * to r15 in ARM architecture v5T and above. This is used for storing
754 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
755 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
756 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
759 if (reg
== 15 && ENABLE_ARCH_5
) {
762 store_reg(s
, reg
, var
);
766 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
768 TCGv tmp
= tcg_temp_new_i32();
769 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
772 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
774 TCGv tmp
= tcg_temp_new_i32();
775 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
778 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
780 TCGv tmp
= tcg_temp_new_i32();
781 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
784 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
786 TCGv tmp
= tcg_temp_new_i32();
787 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
790 static inline TCGv
gen_ld32(TCGv addr
, int index
)
792 TCGv tmp
= tcg_temp_new_i32();
793 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
796 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
798 TCGv_i64 tmp
= tcg_temp_new_i64();
799 tcg_gen_qemu_ld64(tmp
, addr
, index
);
802 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
804 tcg_gen_qemu_st8(val
, addr
, index
);
805 tcg_temp_free_i32(val
);
807 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
809 tcg_gen_qemu_st16(val
, addr
, index
);
810 tcg_temp_free_i32(val
);
812 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
814 tcg_gen_qemu_st32(val
, addr
, index
);
815 tcg_temp_free_i32(val
);
817 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
819 tcg_gen_qemu_st64(val
, addr
, index
);
820 tcg_temp_free_i64(val
);
823 static inline void gen_set_pc_im(uint32_t val
)
825 tcg_gen_movi_i32(cpu_R
[15], val
);
828 /* Force a TB lookup after an instruction that changes the CPU state. */
829 static inline void gen_lookup_tb(DisasContext
*s
)
831 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
832 s
->is_jmp
= DISAS_UPDATE
;
835 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
838 int val
, rm
, shift
, shiftop
;
841 if (!(insn
& (1 << 25))) {
844 if (!(insn
& (1 << 23)))
847 tcg_gen_addi_i32(var
, var
, val
);
851 shift
= (insn
>> 7) & 0x1f;
852 shiftop
= (insn
>> 5) & 3;
853 offset
= load_reg(s
, rm
);
854 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
855 if (!(insn
& (1 << 23)))
856 tcg_gen_sub_i32(var
, var
, offset
);
858 tcg_gen_add_i32(var
, var
, offset
);
859 tcg_temp_free_i32(offset
);
863 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
869 if (insn
& (1 << 22)) {
871 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
872 if (!(insn
& (1 << 23)))
876 tcg_gen_addi_i32(var
, var
, val
);
880 tcg_gen_addi_i32(var
, var
, extra
);
882 offset
= load_reg(s
, rm
);
883 if (!(insn
& (1 << 23)))
884 tcg_gen_sub_i32(var
, var
, offset
);
886 tcg_gen_add_i32(var
, var
, offset
);
887 tcg_temp_free_i32(offset
);
891 static TCGv_ptr
get_fpstatus_ptr(int neon
)
893 TCGv_ptr statusptr
= tcg_temp_new_ptr();
896 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
898 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
900 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
904 #define VFP_OP2(name) \
905 static inline void gen_vfp_##name(int dp) \
907 TCGv_ptr fpst = get_fpstatus_ptr(0); \
909 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
911 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
913 tcg_temp_free_ptr(fpst); \
923 static inline void gen_vfp_F1_mul(int dp
)
925 /* Like gen_vfp_mul() but put result in F1 */
926 TCGv_ptr fpst
= get_fpstatus_ptr(0);
928 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
930 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
932 tcg_temp_free_ptr(fpst
);
935 static inline void gen_vfp_F1_neg(int dp
)
937 /* Like gen_vfp_neg() but put result in F1 */
939 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
941 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
945 static inline void gen_vfp_abs(int dp
)
948 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
950 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
953 static inline void gen_vfp_neg(int dp
)
956 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
958 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
961 static inline void gen_vfp_sqrt(int dp
)
964 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
966 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
969 static inline void gen_vfp_cmp(int dp
)
972 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
974 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
977 static inline void gen_vfp_cmpe(int dp
)
980 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
982 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
985 static inline void gen_vfp_F1_ld0(int dp
)
988 tcg_gen_movi_i64(cpu_F1d
, 0);
990 tcg_gen_movi_i32(cpu_F1s
, 0);
993 #define VFP_GEN_ITOF(name) \
994 static inline void gen_vfp_##name(int dp, int neon) \
996 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
998 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1000 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1002 tcg_temp_free_ptr(statusptr); \
1009 #define VFP_GEN_FTOI(name) \
1010 static inline void gen_vfp_##name(int dp, int neon) \
1012 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1014 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1016 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1018 tcg_temp_free_ptr(statusptr); \
1027 #define VFP_GEN_FIX(name) \
1028 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1030 TCGv tmp_shift = tcg_const_i32(shift); \
1031 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1033 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1035 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1037 tcg_temp_free_i32(tmp_shift); \
1038 tcg_temp_free_ptr(statusptr); \
1050 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1053 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1055 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1058 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1061 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1063 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1067 vfp_reg_offset (int dp
, int reg
)
1070 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1072 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1073 + offsetof(CPU_DoubleU
, l
.upper
);
1075 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1076 + offsetof(CPU_DoubleU
, l
.lower
);
1080 /* Return the offset of a 32-bit piece of a NEON register.
1081 zero is the least significant end of the register. */
1083 neon_reg_offset (int reg
, int n
)
1087 return vfp_reg_offset(0, sreg
);
1090 static TCGv
neon_load_reg(int reg
, int pass
)
1092 TCGv tmp
= tcg_temp_new_i32();
1093 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1097 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1099 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1100 tcg_temp_free_i32(var
);
1103 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1105 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1108 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1110 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1113 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1114 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1115 #define tcg_gen_st_f32 tcg_gen_st_i32
1116 #define tcg_gen_st_f64 tcg_gen_st_i64
1118 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1121 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1123 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1126 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1129 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1131 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1134 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1137 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1139 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1142 #define ARM_CP_RW_BIT (1 << 20)
1144 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1146 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1149 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1151 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1154 static inline TCGv
iwmmxt_load_creg(int reg
)
1156 TCGv var
= tcg_temp_new_i32();
1157 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1161 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1163 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1164 tcg_temp_free_i32(var
);
1167 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1169 iwmmxt_store_reg(cpu_M0
, rn
);
1172 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1174 iwmmxt_load_reg(cpu_M0
, rn
);
1177 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1179 iwmmxt_load_reg(cpu_V1
, rn
);
1180 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1183 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1185 iwmmxt_load_reg(cpu_V1
, rn
);
1186 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1189 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1191 iwmmxt_load_reg(cpu_V1
, rn
);
1192 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1195 #define IWMMXT_OP(name) \
1196 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1198 iwmmxt_load_reg(cpu_V1, rn); \
1199 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1202 #define IWMMXT_OP_ENV(name) \
1203 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1205 iwmmxt_load_reg(cpu_V1, rn); \
1206 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1209 #define IWMMXT_OP_ENV_SIZE(name) \
1210 IWMMXT_OP_ENV(name##b) \
1211 IWMMXT_OP_ENV(name##w) \
1212 IWMMXT_OP_ENV(name##l)
1214 #define IWMMXT_OP_ENV1(name) \
1215 static inline void gen_op_iwmmxt_##name##_M0(void) \
1217 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1231 IWMMXT_OP_ENV_SIZE(unpackl
)
1232 IWMMXT_OP_ENV_SIZE(unpackh
)
1234 IWMMXT_OP_ENV1(unpacklub
)
1235 IWMMXT_OP_ENV1(unpackluw
)
1236 IWMMXT_OP_ENV1(unpacklul
)
1237 IWMMXT_OP_ENV1(unpackhub
)
1238 IWMMXT_OP_ENV1(unpackhuw
)
1239 IWMMXT_OP_ENV1(unpackhul
)
1240 IWMMXT_OP_ENV1(unpacklsb
)
1241 IWMMXT_OP_ENV1(unpacklsw
)
1242 IWMMXT_OP_ENV1(unpacklsl
)
1243 IWMMXT_OP_ENV1(unpackhsb
)
1244 IWMMXT_OP_ENV1(unpackhsw
)
1245 IWMMXT_OP_ENV1(unpackhsl
)
1247 IWMMXT_OP_ENV_SIZE(cmpeq
)
1248 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1249 IWMMXT_OP_ENV_SIZE(cmpgts
)
1251 IWMMXT_OP_ENV_SIZE(mins
)
1252 IWMMXT_OP_ENV_SIZE(minu
)
1253 IWMMXT_OP_ENV_SIZE(maxs
)
1254 IWMMXT_OP_ENV_SIZE(maxu
)
1256 IWMMXT_OP_ENV_SIZE(subn
)
1257 IWMMXT_OP_ENV_SIZE(addn
)
1258 IWMMXT_OP_ENV_SIZE(subu
)
1259 IWMMXT_OP_ENV_SIZE(addu
)
1260 IWMMXT_OP_ENV_SIZE(subs
)
1261 IWMMXT_OP_ENV_SIZE(adds
)
1263 IWMMXT_OP_ENV(avgb0
)
1264 IWMMXT_OP_ENV(avgb1
)
1265 IWMMXT_OP_ENV(avgw0
)
1266 IWMMXT_OP_ENV(avgw1
)
1270 IWMMXT_OP_ENV(packuw
)
1271 IWMMXT_OP_ENV(packul
)
1272 IWMMXT_OP_ENV(packuq
)
1273 IWMMXT_OP_ENV(packsw
)
1274 IWMMXT_OP_ENV(packsl
)
1275 IWMMXT_OP_ENV(packsq
)
1277 static void gen_op_iwmmxt_set_mup(void)
1280 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1281 tcg_gen_ori_i32(tmp
, tmp
, 2);
1282 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1285 static void gen_op_iwmmxt_set_cup(void)
1288 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1289 tcg_gen_ori_i32(tmp
, tmp
, 1);
1290 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1293 static void gen_op_iwmmxt_setpsr_nz(void)
1295 TCGv tmp
= tcg_temp_new_i32();
1296 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1297 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1300 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1302 iwmmxt_load_reg(cpu_V1
, rn
);
1303 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1304 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1307 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1313 rd
= (insn
>> 16) & 0xf;
1314 tmp
= load_reg(s
, rd
);
1316 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1317 if (insn
& (1 << 24)) {
1319 if (insn
& (1 << 23))
1320 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1322 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1323 tcg_gen_mov_i32(dest
, tmp
);
1324 if (insn
& (1 << 21))
1325 store_reg(s
, rd
, tmp
);
1327 tcg_temp_free_i32(tmp
);
1328 } else if (insn
& (1 << 21)) {
1330 tcg_gen_mov_i32(dest
, tmp
);
1331 if (insn
& (1 << 23))
1332 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1334 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1335 store_reg(s
, rd
, tmp
);
1336 } else if (!(insn
& (1 << 23)))
1341 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1343 int rd
= (insn
>> 0) & 0xf;
1346 if (insn
& (1 << 8)) {
1347 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1350 tmp
= iwmmxt_load_creg(rd
);
1353 tmp
= tcg_temp_new_i32();
1354 iwmmxt_load_reg(cpu_V0
, rd
);
1355 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1357 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1358 tcg_gen_mov_i32(dest
, tmp
);
1359 tcg_temp_free_i32(tmp
);
1363 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1364 (ie. an undefined instruction). */
1365 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1368 int rdhi
, rdlo
, rd0
, rd1
, i
;
1370 TCGv tmp
, tmp2
, tmp3
;
1372 if ((insn
& 0x0e000e00) == 0x0c000000) {
1373 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1375 rdlo
= (insn
>> 12) & 0xf;
1376 rdhi
= (insn
>> 16) & 0xf;
1377 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1378 iwmmxt_load_reg(cpu_V0
, wrd
);
1379 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1380 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1381 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1382 } else { /* TMCRR */
1383 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1384 iwmmxt_store_reg(cpu_V0
, wrd
);
1385 gen_op_iwmmxt_set_mup();
1390 wrd
= (insn
>> 12) & 0xf;
1391 addr
= tcg_temp_new_i32();
1392 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1393 tcg_temp_free_i32(addr
);
1396 if (insn
& ARM_CP_RW_BIT
) {
1397 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1398 tmp
= tcg_temp_new_i32();
1399 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1400 iwmmxt_store_creg(wrd
, tmp
);
1403 if (insn
& (1 << 8)) {
1404 if (insn
& (1 << 22)) { /* WLDRD */
1405 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1407 } else { /* WLDRW wRd */
1408 tmp
= gen_ld32(addr
, IS_USER(s
));
1411 if (insn
& (1 << 22)) { /* WLDRH */
1412 tmp
= gen_ld16u(addr
, IS_USER(s
));
1413 } else { /* WLDRB */
1414 tmp
= gen_ld8u(addr
, IS_USER(s
));
1418 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1419 tcg_temp_free_i32(tmp
);
1421 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1424 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1425 tmp
= iwmmxt_load_creg(wrd
);
1426 gen_st32(tmp
, addr
, IS_USER(s
));
1428 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1429 tmp
= tcg_temp_new_i32();
1430 if (insn
& (1 << 8)) {
1431 if (insn
& (1 << 22)) { /* WSTRD */
1432 tcg_temp_free_i32(tmp
);
1433 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1434 } else { /* WSTRW wRd */
1435 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1436 gen_st32(tmp
, addr
, IS_USER(s
));
1439 if (insn
& (1 << 22)) { /* WSTRH */
1440 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1441 gen_st16(tmp
, addr
, IS_USER(s
));
1442 } else { /* WSTRB */
1443 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1444 gen_st8(tmp
, addr
, IS_USER(s
));
1449 tcg_temp_free_i32(addr
);
1453 if ((insn
& 0x0f000000) != 0x0e000000)
1456 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1457 case 0x000: /* WOR */
1458 wrd
= (insn
>> 12) & 0xf;
1459 rd0
= (insn
>> 0) & 0xf;
1460 rd1
= (insn
>> 16) & 0xf;
1461 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1462 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1463 gen_op_iwmmxt_setpsr_nz();
1464 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1465 gen_op_iwmmxt_set_mup();
1466 gen_op_iwmmxt_set_cup();
1468 case 0x011: /* TMCR */
1471 rd
= (insn
>> 12) & 0xf;
1472 wrd
= (insn
>> 16) & 0xf;
1474 case ARM_IWMMXT_wCID
:
1475 case ARM_IWMMXT_wCASF
:
1477 case ARM_IWMMXT_wCon
:
1478 gen_op_iwmmxt_set_cup();
1480 case ARM_IWMMXT_wCSSF
:
1481 tmp
= iwmmxt_load_creg(wrd
);
1482 tmp2
= load_reg(s
, rd
);
1483 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1484 tcg_temp_free_i32(tmp2
);
1485 iwmmxt_store_creg(wrd
, tmp
);
1487 case ARM_IWMMXT_wCGR0
:
1488 case ARM_IWMMXT_wCGR1
:
1489 case ARM_IWMMXT_wCGR2
:
1490 case ARM_IWMMXT_wCGR3
:
1491 gen_op_iwmmxt_set_cup();
1492 tmp
= load_reg(s
, rd
);
1493 iwmmxt_store_creg(wrd
, tmp
);
1499 case 0x100: /* WXOR */
1500 wrd
= (insn
>> 12) & 0xf;
1501 rd0
= (insn
>> 0) & 0xf;
1502 rd1
= (insn
>> 16) & 0xf;
1503 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1504 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1505 gen_op_iwmmxt_setpsr_nz();
1506 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1507 gen_op_iwmmxt_set_mup();
1508 gen_op_iwmmxt_set_cup();
1510 case 0x111: /* TMRC */
1513 rd
= (insn
>> 12) & 0xf;
1514 wrd
= (insn
>> 16) & 0xf;
1515 tmp
= iwmmxt_load_creg(wrd
);
1516 store_reg(s
, rd
, tmp
);
1518 case 0x300: /* WANDN */
1519 wrd
= (insn
>> 12) & 0xf;
1520 rd0
= (insn
>> 0) & 0xf;
1521 rd1
= (insn
>> 16) & 0xf;
1522 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1523 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1524 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1525 gen_op_iwmmxt_setpsr_nz();
1526 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1527 gen_op_iwmmxt_set_mup();
1528 gen_op_iwmmxt_set_cup();
1530 case 0x200: /* WAND */
1531 wrd
= (insn
>> 12) & 0xf;
1532 rd0
= (insn
>> 0) & 0xf;
1533 rd1
= (insn
>> 16) & 0xf;
1534 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1535 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1536 gen_op_iwmmxt_setpsr_nz();
1537 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1538 gen_op_iwmmxt_set_mup();
1539 gen_op_iwmmxt_set_cup();
1541 case 0x810: case 0xa10: /* WMADD */
1542 wrd
= (insn
>> 12) & 0xf;
1543 rd0
= (insn
>> 0) & 0xf;
1544 rd1
= (insn
>> 16) & 0xf;
1545 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1546 if (insn
& (1 << 21))
1547 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1549 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1550 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1551 gen_op_iwmmxt_set_mup();
1553 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1554 wrd
= (insn
>> 12) & 0xf;
1555 rd0
= (insn
>> 16) & 0xf;
1556 rd1
= (insn
>> 0) & 0xf;
1557 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1558 switch ((insn
>> 22) & 3) {
1560 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1563 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1566 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1571 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1572 gen_op_iwmmxt_set_mup();
1573 gen_op_iwmmxt_set_cup();
1575 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1576 wrd
= (insn
>> 12) & 0xf;
1577 rd0
= (insn
>> 16) & 0xf;
1578 rd1
= (insn
>> 0) & 0xf;
1579 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1580 switch ((insn
>> 22) & 3) {
1582 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1585 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1588 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1593 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1594 gen_op_iwmmxt_set_mup();
1595 gen_op_iwmmxt_set_cup();
1597 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1598 wrd
= (insn
>> 12) & 0xf;
1599 rd0
= (insn
>> 16) & 0xf;
1600 rd1
= (insn
>> 0) & 0xf;
1601 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1602 if (insn
& (1 << 22))
1603 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1605 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1606 if (!(insn
& (1 << 20)))
1607 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1608 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1609 gen_op_iwmmxt_set_mup();
1611 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1612 wrd
= (insn
>> 12) & 0xf;
1613 rd0
= (insn
>> 16) & 0xf;
1614 rd1
= (insn
>> 0) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1616 if (insn
& (1 << 21)) {
1617 if (insn
& (1 << 20))
1618 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1620 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1622 if (insn
& (1 << 20))
1623 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1625 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1627 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1628 gen_op_iwmmxt_set_mup();
1630 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1631 wrd
= (insn
>> 12) & 0xf;
1632 rd0
= (insn
>> 16) & 0xf;
1633 rd1
= (insn
>> 0) & 0xf;
1634 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1635 if (insn
& (1 << 21))
1636 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1638 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1639 if (!(insn
& (1 << 20))) {
1640 iwmmxt_load_reg(cpu_V1
, wrd
);
1641 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1643 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1644 gen_op_iwmmxt_set_mup();
1646 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1647 wrd
= (insn
>> 12) & 0xf;
1648 rd0
= (insn
>> 16) & 0xf;
1649 rd1
= (insn
>> 0) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1651 switch ((insn
>> 22) & 3) {
1653 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1656 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1659 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1664 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1665 gen_op_iwmmxt_set_mup();
1666 gen_op_iwmmxt_set_cup();
1668 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1669 wrd
= (insn
>> 12) & 0xf;
1670 rd0
= (insn
>> 16) & 0xf;
1671 rd1
= (insn
>> 0) & 0xf;
1672 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1673 if (insn
& (1 << 22)) {
1674 if (insn
& (1 << 20))
1675 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1677 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1679 if (insn
& (1 << 20))
1680 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1682 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1684 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1685 gen_op_iwmmxt_set_mup();
1686 gen_op_iwmmxt_set_cup();
1688 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1689 wrd
= (insn
>> 12) & 0xf;
1690 rd0
= (insn
>> 16) & 0xf;
1691 rd1
= (insn
>> 0) & 0xf;
1692 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1693 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1694 tcg_gen_andi_i32(tmp
, tmp
, 7);
1695 iwmmxt_load_reg(cpu_V1
, rd1
);
1696 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1697 tcg_temp_free_i32(tmp
);
1698 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1699 gen_op_iwmmxt_set_mup();
1701 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1702 if (((insn
>> 6) & 3) == 3)
1704 rd
= (insn
>> 12) & 0xf;
1705 wrd
= (insn
>> 16) & 0xf;
1706 tmp
= load_reg(s
, rd
);
1707 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1708 switch ((insn
>> 6) & 3) {
1710 tmp2
= tcg_const_i32(0xff);
1711 tmp3
= tcg_const_i32((insn
& 7) << 3);
1714 tmp2
= tcg_const_i32(0xffff);
1715 tmp3
= tcg_const_i32((insn
& 3) << 4);
1718 tmp2
= tcg_const_i32(0xffffffff);
1719 tmp3
= tcg_const_i32((insn
& 1) << 5);
1725 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1726 tcg_temp_free(tmp3
);
1727 tcg_temp_free(tmp2
);
1728 tcg_temp_free_i32(tmp
);
1729 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1730 gen_op_iwmmxt_set_mup();
1732 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1733 rd
= (insn
>> 12) & 0xf;
1734 wrd
= (insn
>> 16) & 0xf;
1735 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1737 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1738 tmp
= tcg_temp_new_i32();
1739 switch ((insn
>> 22) & 3) {
1741 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1742 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1744 tcg_gen_ext8s_i32(tmp
, tmp
);
1746 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1750 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1751 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1753 tcg_gen_ext16s_i32(tmp
, tmp
);
1755 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1759 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1760 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1763 store_reg(s
, rd
, tmp
);
1765 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1766 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1768 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1769 switch ((insn
>> 22) & 3) {
1771 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1774 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1777 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1780 tcg_gen_shli_i32(tmp
, tmp
, 28);
1782 tcg_temp_free_i32(tmp
);
1784 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1785 if (((insn
>> 6) & 3) == 3)
1787 rd
= (insn
>> 12) & 0xf;
1788 wrd
= (insn
>> 16) & 0xf;
1789 tmp
= load_reg(s
, rd
);
1790 switch ((insn
>> 6) & 3) {
1792 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1795 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1798 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1801 tcg_temp_free_i32(tmp
);
1802 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1803 gen_op_iwmmxt_set_mup();
1805 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1806 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1808 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1809 tmp2
= tcg_temp_new_i32();
1810 tcg_gen_mov_i32(tmp2
, tmp
);
1811 switch ((insn
>> 22) & 3) {
1813 for (i
= 0; i
< 7; i
++) {
1814 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1815 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1819 for (i
= 0; i
< 3; i
++) {
1820 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1821 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1825 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1826 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1830 tcg_temp_free_i32(tmp2
);
1831 tcg_temp_free_i32(tmp
);
1833 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1834 wrd
= (insn
>> 12) & 0xf;
1835 rd0
= (insn
>> 16) & 0xf;
1836 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1837 switch ((insn
>> 22) & 3) {
1839 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1842 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1845 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1854 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1856 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1857 tmp2
= tcg_temp_new_i32();
1858 tcg_gen_mov_i32(tmp2
, tmp
);
1859 switch ((insn
>> 22) & 3) {
1861 for (i
= 0; i
< 7; i
++) {
1862 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1863 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1867 for (i
= 0; i
< 3; i
++) {
1868 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1869 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1873 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1874 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1878 tcg_temp_free_i32(tmp2
);
1879 tcg_temp_free_i32(tmp
);
1881 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1882 rd
= (insn
>> 12) & 0xf;
1883 rd0
= (insn
>> 16) & 0xf;
1884 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1886 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1887 tmp
= tcg_temp_new_i32();
1888 switch ((insn
>> 22) & 3) {
1890 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1893 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1896 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1899 store_reg(s
, rd
, tmp
);
1901 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1902 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1903 wrd
= (insn
>> 12) & 0xf;
1904 rd0
= (insn
>> 16) & 0xf;
1905 rd1
= (insn
>> 0) & 0xf;
1906 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1907 switch ((insn
>> 22) & 3) {
1909 if (insn
& (1 << 21))
1910 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1912 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1915 if (insn
& (1 << 21))
1916 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1918 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1921 if (insn
& (1 << 21))
1922 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1924 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1929 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1930 gen_op_iwmmxt_set_mup();
1931 gen_op_iwmmxt_set_cup();
1933 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1934 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1935 wrd
= (insn
>> 12) & 0xf;
1936 rd0
= (insn
>> 16) & 0xf;
1937 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1938 switch ((insn
>> 22) & 3) {
1940 if (insn
& (1 << 21))
1941 gen_op_iwmmxt_unpacklsb_M0();
1943 gen_op_iwmmxt_unpacklub_M0();
1946 if (insn
& (1 << 21))
1947 gen_op_iwmmxt_unpacklsw_M0();
1949 gen_op_iwmmxt_unpackluw_M0();
1952 if (insn
& (1 << 21))
1953 gen_op_iwmmxt_unpacklsl_M0();
1955 gen_op_iwmmxt_unpacklul_M0();
1960 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1961 gen_op_iwmmxt_set_mup();
1962 gen_op_iwmmxt_set_cup();
1964 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1965 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1966 wrd
= (insn
>> 12) & 0xf;
1967 rd0
= (insn
>> 16) & 0xf;
1968 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1969 switch ((insn
>> 22) & 3) {
1971 if (insn
& (1 << 21))
1972 gen_op_iwmmxt_unpackhsb_M0();
1974 gen_op_iwmmxt_unpackhub_M0();
1977 if (insn
& (1 << 21))
1978 gen_op_iwmmxt_unpackhsw_M0();
1980 gen_op_iwmmxt_unpackhuw_M0();
1983 if (insn
& (1 << 21))
1984 gen_op_iwmmxt_unpackhsl_M0();
1986 gen_op_iwmmxt_unpackhul_M0();
1991 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1992 gen_op_iwmmxt_set_mup();
1993 gen_op_iwmmxt_set_cup();
1995 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1996 case 0x214: case 0x614: case 0xa14: case 0xe14:
1997 if (((insn
>> 22) & 3) == 0)
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2002 tmp
= tcg_temp_new_i32();
2003 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2004 tcg_temp_free_i32(tmp
);
2007 switch ((insn
>> 22) & 3) {
2009 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2012 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2015 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2018 tcg_temp_free_i32(tmp
);
2019 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2020 gen_op_iwmmxt_set_mup();
2021 gen_op_iwmmxt_set_cup();
2023 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2024 case 0x014: case 0x414: case 0x814: case 0xc14:
2025 if (((insn
>> 22) & 3) == 0)
2027 wrd
= (insn
>> 12) & 0xf;
2028 rd0
= (insn
>> 16) & 0xf;
2029 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2030 tmp
= tcg_temp_new_i32();
2031 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2032 tcg_temp_free_i32(tmp
);
2035 switch ((insn
>> 22) & 3) {
2037 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2040 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2043 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2046 tcg_temp_free_i32(tmp
);
2047 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2052 case 0x114: case 0x514: case 0x914: case 0xd14:
2053 if (((insn
>> 22) & 3) == 0)
2055 wrd
= (insn
>> 12) & 0xf;
2056 rd0
= (insn
>> 16) & 0xf;
2057 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2058 tmp
= tcg_temp_new_i32();
2059 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2060 tcg_temp_free_i32(tmp
);
2063 switch ((insn
>> 22) & 3) {
2065 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2068 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2071 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2074 tcg_temp_free_i32(tmp
);
2075 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2076 gen_op_iwmmxt_set_mup();
2077 gen_op_iwmmxt_set_cup();
2079 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2080 case 0x314: case 0x714: case 0xb14: case 0xf14:
2081 if (((insn
>> 22) & 3) == 0)
2083 wrd
= (insn
>> 12) & 0xf;
2084 rd0
= (insn
>> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2086 tmp
= tcg_temp_new_i32();
2087 switch ((insn
>> 22) & 3) {
2089 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2090 tcg_temp_free_i32(tmp
);
2093 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2096 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2097 tcg_temp_free_i32(tmp
);
2100 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2103 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2104 tcg_temp_free_i32(tmp
);
2107 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2110 tcg_temp_free_i32(tmp
);
2111 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2112 gen_op_iwmmxt_set_mup();
2113 gen_op_iwmmxt_set_cup();
2115 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2116 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2117 wrd
= (insn
>> 12) & 0xf;
2118 rd0
= (insn
>> 16) & 0xf;
2119 rd1
= (insn
>> 0) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2121 switch ((insn
>> 22) & 3) {
2123 if (insn
& (1 << 21))
2124 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2126 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2129 if (insn
& (1 << 21))
2130 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2132 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2135 if (insn
& (1 << 21))
2136 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2138 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2143 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2144 gen_op_iwmmxt_set_mup();
2146 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2147 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2148 wrd
= (insn
>> 12) & 0xf;
2149 rd0
= (insn
>> 16) & 0xf;
2150 rd1
= (insn
>> 0) & 0xf;
2151 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2152 switch ((insn
>> 22) & 3) {
2154 if (insn
& (1 << 21))
2155 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2157 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2160 if (insn
& (1 << 21))
2161 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2163 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2166 if (insn
& (1 << 21))
2167 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2169 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2174 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2175 gen_op_iwmmxt_set_mup();
2177 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2178 case 0x402: case 0x502: case 0x602: case 0x702:
2179 wrd
= (insn
>> 12) & 0xf;
2180 rd0
= (insn
>> 16) & 0xf;
2181 rd1
= (insn
>> 0) & 0xf;
2182 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2183 tmp
= tcg_const_i32((insn
>> 20) & 3);
2184 iwmmxt_load_reg(cpu_V1
, rd1
);
2185 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2187 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2188 gen_op_iwmmxt_set_mup();
2190 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2191 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2192 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2193 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2194 wrd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 rd1
= (insn
>> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2198 switch ((insn
>> 20) & 0xf) {
2200 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2203 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2206 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2209 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2212 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2215 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2218 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2221 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2224 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2229 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2233 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2234 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2235 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2236 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2240 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2241 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2243 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2244 gen_op_iwmmxt_set_mup();
2245 gen_op_iwmmxt_set_cup();
2247 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2248 case 0x418: case 0x518: case 0x618: case 0x718:
2249 case 0x818: case 0x918: case 0xa18: case 0xb18:
2250 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2251 wrd
= (insn
>> 12) & 0xf;
2252 rd0
= (insn
>> 16) & 0xf;
2253 rd1
= (insn
>> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2255 switch ((insn
>> 20) & 0xf) {
2257 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2260 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2263 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2266 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2269 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2272 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2275 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2278 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2281 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2287 gen_op_iwmmxt_set_mup();
2288 gen_op_iwmmxt_set_cup();
2290 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2291 case 0x408: case 0x508: case 0x608: case 0x708:
2292 case 0x808: case 0x908: case 0xa08: case 0xb08:
2293 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2294 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2296 wrd
= (insn
>> 12) & 0xf;
2297 rd0
= (insn
>> 16) & 0xf;
2298 rd1
= (insn
>> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2300 switch ((insn
>> 22) & 3) {
2302 if (insn
& (1 << 21))
2303 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2308 if (insn
& (1 << 21))
2309 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2311 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2314 if (insn
& (1 << 21))
2315 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2317 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2320 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2321 gen_op_iwmmxt_set_mup();
2322 gen_op_iwmmxt_set_cup();
2324 case 0x201: case 0x203: case 0x205: case 0x207:
2325 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2326 case 0x211: case 0x213: case 0x215: case 0x217:
2327 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2328 wrd
= (insn
>> 5) & 0xf;
2329 rd0
= (insn
>> 12) & 0xf;
2330 rd1
= (insn
>> 0) & 0xf;
2331 if (rd0
== 0xf || rd1
== 0xf)
2333 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2334 tmp
= load_reg(s
, rd0
);
2335 tmp2
= load_reg(s
, rd1
);
2336 switch ((insn
>> 16) & 0xf) {
2337 case 0x0: /* TMIA */
2338 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2340 case 0x8: /* TMIAPH */
2341 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2343 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2344 if (insn
& (1 << 16))
2345 tcg_gen_shri_i32(tmp
, tmp
, 16);
2346 if (insn
& (1 << 17))
2347 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2348 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2351 tcg_temp_free_i32(tmp2
);
2352 tcg_temp_free_i32(tmp
);
2355 tcg_temp_free_i32(tmp2
);
2356 tcg_temp_free_i32(tmp
);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2358 gen_op_iwmmxt_set_mup();
2367 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2368 (ie. an undefined instruction). */
2369 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2371 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2374 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2375 /* Multiply with Internal Accumulate Format */
2376 rd0
= (insn
>> 12) & 0xf;
2378 acc
= (insn
>> 5) & 7;
2383 tmp
= load_reg(s
, rd0
);
2384 tmp2
= load_reg(s
, rd1
);
2385 switch ((insn
>> 16) & 0xf) {
2387 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2389 case 0x8: /* MIAPH */
2390 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2392 case 0xc: /* MIABB */
2393 case 0xd: /* MIABT */
2394 case 0xe: /* MIATB */
2395 case 0xf: /* MIATT */
2396 if (insn
& (1 << 16))
2397 tcg_gen_shri_i32(tmp
, tmp
, 16);
2398 if (insn
& (1 << 17))
2399 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2400 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2405 tcg_temp_free_i32(tmp2
);
2406 tcg_temp_free_i32(tmp
);
2408 gen_op_iwmmxt_movq_wRn_M0(acc
);
2412 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2413 /* Internal Accumulator Access Format */
2414 rdhi
= (insn
>> 16) & 0xf;
2415 rdlo
= (insn
>> 12) & 0xf;
2421 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2422 iwmmxt_load_reg(cpu_V0
, acc
);
2423 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2424 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2425 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2426 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2428 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2429 iwmmxt_store_reg(cpu_V0
, acc
);
2437 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2438 #define VFP_SREG(insn, bigbit, smallbit) \
2439 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2440 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2441 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2442 reg = (((insn) >> (bigbit)) & 0x0f) \
2443 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2445 if (insn & (1 << (smallbit))) \
2447 reg = ((insn) >> (bigbit)) & 0x0f; \
2450 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2451 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2452 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2453 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2454 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2455 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2457 /* Move between integer and VFP cores. */
2458 static TCGv
gen_vfp_mrs(void)
2460 TCGv tmp
= tcg_temp_new_i32();
2461 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2465 static void gen_vfp_msr(TCGv tmp
)
2467 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2468 tcg_temp_free_i32(tmp
);
2471 static void gen_neon_dup_u8(TCGv var
, int shift
)
2473 TCGv tmp
= tcg_temp_new_i32();
2475 tcg_gen_shri_i32(var
, var
, shift
);
2476 tcg_gen_ext8u_i32(var
, var
);
2477 tcg_gen_shli_i32(tmp
, var
, 8);
2478 tcg_gen_or_i32(var
, var
, tmp
);
2479 tcg_gen_shli_i32(tmp
, var
, 16);
2480 tcg_gen_or_i32(var
, var
, tmp
);
2481 tcg_temp_free_i32(tmp
);
2484 static void gen_neon_dup_low16(TCGv var
)
2486 TCGv tmp
= tcg_temp_new_i32();
2487 tcg_gen_ext16u_i32(var
, var
);
2488 tcg_gen_shli_i32(tmp
, var
, 16);
2489 tcg_gen_or_i32(var
, var
, tmp
);
2490 tcg_temp_free_i32(tmp
);
2493 static void gen_neon_dup_high16(TCGv var
)
2495 TCGv tmp
= tcg_temp_new_i32();
2496 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2497 tcg_gen_shri_i32(tmp
, var
, 16);
2498 tcg_gen_or_i32(var
, var
, tmp
);
2499 tcg_temp_free_i32(tmp
);
2502 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2504 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2508 tmp
= gen_ld8u(addr
, IS_USER(s
));
2509 gen_neon_dup_u8(tmp
, 0);
2512 tmp
= gen_ld16u(addr
, IS_USER(s
));
2513 gen_neon_dup_low16(tmp
);
2516 tmp
= gen_ld32(addr
, IS_USER(s
));
2518 default: /* Avoid compiler warnings. */
2524 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2525 (ie. an undefined instruction). */
2526 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2528 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2534 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2537 if (!s
->vfp_enabled
) {
2538 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2539 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2541 rn
= (insn
>> 16) & 0xf;
2542 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2543 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2546 dp
= ((insn
& 0xf00) == 0xb00);
2547 switch ((insn
>> 24) & 0xf) {
2549 if (insn
& (1 << 4)) {
2550 /* single register transfer */
2551 rd
= (insn
>> 12) & 0xf;
2556 VFP_DREG_N(rn
, insn
);
2559 if (insn
& 0x00c00060
2560 && !arm_feature(env
, ARM_FEATURE_NEON
))
2563 pass
= (insn
>> 21) & 1;
2564 if (insn
& (1 << 22)) {
2566 offset
= ((insn
>> 5) & 3) * 8;
2567 } else if (insn
& (1 << 5)) {
2569 offset
= (insn
& (1 << 6)) ? 16 : 0;
2574 if (insn
& ARM_CP_RW_BIT
) {
2576 tmp
= neon_load_reg(rn
, pass
);
2580 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2581 if (insn
& (1 << 23))
2587 if (insn
& (1 << 23)) {
2589 tcg_gen_shri_i32(tmp
, tmp
, 16);
2595 tcg_gen_sari_i32(tmp
, tmp
, 16);
2604 store_reg(s
, rd
, tmp
);
2607 tmp
= load_reg(s
, rd
);
2608 if (insn
& (1 << 23)) {
2611 gen_neon_dup_u8(tmp
, 0);
2612 } else if (size
== 1) {
2613 gen_neon_dup_low16(tmp
);
2615 for (n
= 0; n
<= pass
* 2; n
++) {
2616 tmp2
= tcg_temp_new_i32();
2617 tcg_gen_mov_i32(tmp2
, tmp
);
2618 neon_store_reg(rn
, n
, tmp2
);
2620 neon_store_reg(rn
, n
, tmp
);
2625 tmp2
= neon_load_reg(rn
, pass
);
2626 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2627 tcg_temp_free_i32(tmp2
);
2630 tmp2
= neon_load_reg(rn
, pass
);
2631 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2632 tcg_temp_free_i32(tmp2
);
2637 neon_store_reg(rn
, pass
, tmp
);
2641 if ((insn
& 0x6f) != 0x00)
2643 rn
= VFP_SREG_N(insn
);
2644 if (insn
& ARM_CP_RW_BIT
) {
2646 if (insn
& (1 << 21)) {
2647 /* system register */
2652 /* VFP2 allows access to FSID from userspace.
2653 VFP3 restricts all id registers to privileged
2656 && arm_feature(env
, ARM_FEATURE_VFP3
))
2658 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2663 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2665 case ARM_VFP_FPINST
:
2666 case ARM_VFP_FPINST2
:
2667 /* Not present in VFP3. */
2669 || arm_feature(env
, ARM_FEATURE_VFP3
))
2671 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2675 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2676 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2678 tmp
= tcg_temp_new_i32();
2679 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2685 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2687 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2693 gen_mov_F0_vreg(0, rn
);
2694 tmp
= gen_vfp_mrs();
2697 /* Set the 4 flag bits in the CPSR. */
2699 tcg_temp_free_i32(tmp
);
2701 store_reg(s
, rd
, tmp
);
2705 tmp
= load_reg(s
, rd
);
2706 if (insn
& (1 << 21)) {
2708 /* system register */
2713 /* Writes are ignored. */
2716 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2717 tcg_temp_free_i32(tmp
);
2723 /* TODO: VFP subarchitecture support.
2724 * For now, keep the EN bit only */
2725 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2726 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2729 case ARM_VFP_FPINST
:
2730 case ARM_VFP_FPINST2
:
2731 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2738 gen_mov_vreg_F0(0, rn
);
2743 /* data processing */
2744 /* The opcode is in bits 23, 21, 20 and 6. */
2745 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2749 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2751 /* rn is register number */
2752 VFP_DREG_N(rn
, insn
);
2755 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2756 /* Integer or single precision destination. */
2757 rd
= VFP_SREG_D(insn
);
2759 VFP_DREG_D(rd
, insn
);
2762 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2763 /* VCVT from int is always from S reg regardless of dp bit.
2764 * VCVT with immediate frac_bits has same format as SREG_M
2766 rm
= VFP_SREG_M(insn
);
2768 VFP_DREG_M(rm
, insn
);
2771 rn
= VFP_SREG_N(insn
);
2772 if (op
== 15 && rn
== 15) {
2773 /* Double precision destination. */
2774 VFP_DREG_D(rd
, insn
);
2776 rd
= VFP_SREG_D(insn
);
2778 /* NB that we implicitly rely on the encoding for the frac_bits
2779 * in VCVT of fixed to float being the same as that of an SREG_M
2781 rm
= VFP_SREG_M(insn
);
2784 veclen
= s
->vec_len
;
2785 if (op
== 15 && rn
> 3)
2788 /* Shut up compiler warnings. */
2799 /* Figure out what type of vector operation this is. */
2800 if ((rd
& bank_mask
) == 0) {
2805 delta_d
= (s
->vec_stride
>> 1) + 1;
2807 delta_d
= s
->vec_stride
+ 1;
2809 if ((rm
& bank_mask
) == 0) {
2810 /* mixed scalar/vector */
2819 /* Load the initial operands. */
2824 /* Integer source */
2825 gen_mov_F0_vreg(0, rm
);
2830 gen_mov_F0_vreg(dp
, rd
);
2831 gen_mov_F1_vreg(dp
, rm
);
2835 /* Compare with zero */
2836 gen_mov_F0_vreg(dp
, rd
);
2847 /* Source and destination the same. */
2848 gen_mov_F0_vreg(dp
, rd
);
2854 /* VCVTB, VCVTT: only present with the halfprec extension,
2855 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2857 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2860 /* Otherwise fall through */
2862 /* One source operand. */
2863 gen_mov_F0_vreg(dp
, rm
);
2867 /* Two source operands. */
2868 gen_mov_F0_vreg(dp
, rn
);
2869 gen_mov_F1_vreg(dp
, rm
);
2873 /* Perform the calculation. */
2875 case 0: /* VMLA: fd + (fn * fm) */
2876 /* Note that order of inputs to the add matters for NaNs */
2878 gen_mov_F0_vreg(dp
, rd
);
2881 case 1: /* VMLS: fd + -(fn * fm) */
2884 gen_mov_F0_vreg(dp
, rd
);
2887 case 2: /* VNMLS: -fd + (fn * fm) */
2888 /* Note that it isn't valid to replace (-A + B) with (B - A)
2889 * or similar plausible looking simplifications
2890 * because this will give wrong results for NaNs.
2893 gen_mov_F0_vreg(dp
, rd
);
2897 case 3: /* VNMLA: -fd + -(fn * fm) */
2900 gen_mov_F0_vreg(dp
, rd
);
2904 case 4: /* mul: fn * fm */
2907 case 5: /* nmul: -(fn * fm) */
2911 case 6: /* add: fn + fm */
2914 case 7: /* sub: fn - fm */
2917 case 8: /* div: fn / fm */
2920 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2921 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2922 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2923 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2924 /* These are fused multiply-add, and must be done as one
2925 * floating point operation with no rounding between the
2926 * multiplication and addition steps.
2927 * NB that doing the negations here as separate steps is
2928 * correct : an input NaN should come out with its sign bit
2929 * flipped if it is a negated-input.
2931 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
2939 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
2941 frd
= tcg_temp_new_i64();
2942 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
2945 gen_helper_vfp_negd(frd
, frd
);
2947 fpst
= get_fpstatus_ptr(0);
2948 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
2949 cpu_F1d
, frd
, fpst
);
2950 tcg_temp_free_ptr(fpst
);
2951 tcg_temp_free_i64(frd
);
2957 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
2959 frd
= tcg_temp_new_i32();
2960 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
2962 gen_helper_vfp_negs(frd
, frd
);
2964 fpst
= get_fpstatus_ptr(0);
2965 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
2966 cpu_F1s
, frd
, fpst
);
2967 tcg_temp_free_ptr(fpst
);
2968 tcg_temp_free_i32(frd
);
2971 case 14: /* fconst */
2972 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
2975 n
= (insn
<< 12) & 0x80000000;
2976 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
2983 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
2990 tcg_gen_movi_i32(cpu_F0s
, n
);
2993 case 15: /* extension space */
3007 case 4: /* vcvtb.f32.f16 */
3008 tmp
= gen_vfp_mrs();
3009 tcg_gen_ext16u_i32(tmp
, tmp
);
3010 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3011 tcg_temp_free_i32(tmp
);
3013 case 5: /* vcvtt.f32.f16 */
3014 tmp
= gen_vfp_mrs();
3015 tcg_gen_shri_i32(tmp
, tmp
, 16);
3016 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3017 tcg_temp_free_i32(tmp
);
3019 case 6: /* vcvtb.f16.f32 */
3020 tmp
= tcg_temp_new_i32();
3021 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3022 gen_mov_F0_vreg(0, rd
);
3023 tmp2
= gen_vfp_mrs();
3024 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3025 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3026 tcg_temp_free_i32(tmp2
);
3029 case 7: /* vcvtt.f16.f32 */
3030 tmp
= tcg_temp_new_i32();
3031 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3032 tcg_gen_shli_i32(tmp
, tmp
, 16);
3033 gen_mov_F0_vreg(0, rd
);
3034 tmp2
= gen_vfp_mrs();
3035 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3036 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3037 tcg_temp_free_i32(tmp2
);
3049 case 11: /* cmpez */
3053 case 15: /* single<->double conversion */
3055 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3057 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3059 case 16: /* fuito */
3060 gen_vfp_uito(dp
, 0);
3062 case 17: /* fsito */
3063 gen_vfp_sito(dp
, 0);
3065 case 20: /* fshto */
3066 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3068 gen_vfp_shto(dp
, 16 - rm
, 0);
3070 case 21: /* fslto */
3071 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3073 gen_vfp_slto(dp
, 32 - rm
, 0);
3075 case 22: /* fuhto */
3076 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3078 gen_vfp_uhto(dp
, 16 - rm
, 0);
3080 case 23: /* fulto */
3081 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3083 gen_vfp_ulto(dp
, 32 - rm
, 0);
3085 case 24: /* ftoui */
3086 gen_vfp_toui(dp
, 0);
3088 case 25: /* ftouiz */
3089 gen_vfp_touiz(dp
, 0);
3091 case 26: /* ftosi */
3092 gen_vfp_tosi(dp
, 0);
3094 case 27: /* ftosiz */
3095 gen_vfp_tosiz(dp
, 0);
3097 case 28: /* ftosh */
3098 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3100 gen_vfp_tosh(dp
, 16 - rm
, 0);
3102 case 29: /* ftosl */
3103 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3105 gen_vfp_tosl(dp
, 32 - rm
, 0);
3107 case 30: /* ftouh */
3108 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3110 gen_vfp_touh(dp
, 16 - rm
, 0);
3112 case 31: /* ftoul */
3113 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3115 gen_vfp_toul(dp
, 32 - rm
, 0);
3117 default: /* undefined */
3121 default: /* undefined */
3125 /* Write back the result. */
3126 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3127 ; /* Comparison, do nothing. */
3128 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3129 /* VCVT double to int: always integer result. */
3130 gen_mov_vreg_F0(0, rd
);
3131 else if (op
== 15 && rn
== 15)
3133 gen_mov_vreg_F0(!dp
, rd
);
3135 gen_mov_vreg_F0(dp
, rd
);
3137 /* break out of the loop if we have finished */
3141 if (op
== 15 && delta_m
== 0) {
3142 /* single source one-many */
3144 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3146 gen_mov_vreg_F0(dp
, rd
);
3150 /* Setup the next operands. */
3152 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3156 /* One source operand. */
3157 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3159 gen_mov_F0_vreg(dp
, rm
);
3161 /* Two source operands. */
3162 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3164 gen_mov_F0_vreg(dp
, rn
);
3166 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3168 gen_mov_F1_vreg(dp
, rm
);
3176 if ((insn
& 0x03e00000) == 0x00400000) {
3177 /* two-register transfer */
3178 rn
= (insn
>> 16) & 0xf;
3179 rd
= (insn
>> 12) & 0xf;
3181 VFP_DREG_M(rm
, insn
);
3183 rm
= VFP_SREG_M(insn
);
3186 if (insn
& ARM_CP_RW_BIT
) {
3189 gen_mov_F0_vreg(0, rm
* 2);
3190 tmp
= gen_vfp_mrs();
3191 store_reg(s
, rd
, tmp
);
3192 gen_mov_F0_vreg(0, rm
* 2 + 1);
3193 tmp
= gen_vfp_mrs();
3194 store_reg(s
, rn
, tmp
);
3196 gen_mov_F0_vreg(0, rm
);
3197 tmp
= gen_vfp_mrs();
3198 store_reg(s
, rd
, tmp
);
3199 gen_mov_F0_vreg(0, rm
+ 1);
3200 tmp
= gen_vfp_mrs();
3201 store_reg(s
, rn
, tmp
);
3206 tmp
= load_reg(s
, rd
);
3208 gen_mov_vreg_F0(0, rm
* 2);
3209 tmp
= load_reg(s
, rn
);
3211 gen_mov_vreg_F0(0, rm
* 2 + 1);
3213 tmp
= load_reg(s
, rd
);
3215 gen_mov_vreg_F0(0, rm
);
3216 tmp
= load_reg(s
, rn
);
3218 gen_mov_vreg_F0(0, rm
+ 1);
3223 rn
= (insn
>> 16) & 0xf;
3225 VFP_DREG_D(rd
, insn
);
3227 rd
= VFP_SREG_D(insn
);
3228 if ((insn
& 0x01200000) == 0x01000000) {
3229 /* Single load/store */
3230 offset
= (insn
& 0xff) << 2;
3231 if ((insn
& (1 << 23)) == 0)
3233 if (s
->thumb
&& rn
== 15) {
3234 /* This is actually UNPREDICTABLE */
3235 addr
= tcg_temp_new_i32();
3236 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3238 addr
= load_reg(s
, rn
);
3240 tcg_gen_addi_i32(addr
, addr
, offset
);
3241 if (insn
& (1 << 20)) {
3242 gen_vfp_ld(s
, dp
, addr
);
3243 gen_mov_vreg_F0(dp
, rd
);
3245 gen_mov_F0_vreg(dp
, rd
);
3246 gen_vfp_st(s
, dp
, addr
);
3248 tcg_temp_free_i32(addr
);
3250 /* load/store multiple */
3251 int w
= insn
& (1 << 21);
3253 n
= (insn
>> 1) & 0x7f;
3257 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3258 /* P == U , W == 1 => UNDEF */
3261 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3262 /* UNPREDICTABLE cases for bad immediates: we choose to
3263 * UNDEF to avoid generating huge numbers of TCG ops
3267 if (rn
== 15 && w
) {
3268 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3272 if (s
->thumb
&& rn
== 15) {
3273 /* This is actually UNPREDICTABLE */
3274 addr
= tcg_temp_new_i32();
3275 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3277 addr
= load_reg(s
, rn
);
3279 if (insn
& (1 << 24)) /* pre-decrement */
3280 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3286 for (i
= 0; i
< n
; i
++) {
3287 if (insn
& ARM_CP_RW_BIT
) {
3289 gen_vfp_ld(s
, dp
, addr
);
3290 gen_mov_vreg_F0(dp
, rd
+ i
);
3293 gen_mov_F0_vreg(dp
, rd
+ i
);
3294 gen_vfp_st(s
, dp
, addr
);
3296 tcg_gen_addi_i32(addr
, addr
, offset
);
3300 if (insn
& (1 << 24))
3301 offset
= -offset
* n
;
3302 else if (dp
&& (insn
& 1))
3308 tcg_gen_addi_i32(addr
, addr
, offset
);
3309 store_reg(s
, rn
, addr
);
3311 tcg_temp_free_i32(addr
);
3317 /* Should never happen. */
3323 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3325 TranslationBlock
*tb
;
3328 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3330 gen_set_pc_im(dest
);
3331 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3333 gen_set_pc_im(dest
);
3338 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3340 if (unlikely(s
->singlestep_enabled
)) {
3341 /* An indirect jump so that we still trigger the debug exception. */
3346 gen_goto_tb(s
, 0, dest
);
3347 s
->is_jmp
= DISAS_TB_JUMP
;
3351 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3354 tcg_gen_sari_i32(t0
, t0
, 16);
3358 tcg_gen_sari_i32(t1
, t1
, 16);
3361 tcg_gen_mul_i32(t0
, t0
, t1
);
3364 /* Return the mask of PSR bits set by a MSR instruction. */
3365 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3369 if (flags
& (1 << 0))
3371 if (flags
& (1 << 1))
3373 if (flags
& (1 << 2))
3375 if (flags
& (1 << 3))
3378 /* Mask out undefined bits. */
3379 mask
&= ~CPSR_RESERVED
;
3380 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3382 if (!arm_feature(env
, ARM_FEATURE_V5
))
3383 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3384 if (!arm_feature(env
, ARM_FEATURE_V6
))
3385 mask
&= ~(CPSR_E
| CPSR_GE
);
3386 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3388 /* Mask out execution state bits. */
3391 /* Mask out privileged bits. */
3397 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3398 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3402 /* ??? This is also undefined in system mode. */
3406 tmp
= load_cpu_field(spsr
);
3407 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3408 tcg_gen_andi_i32(t0
, t0
, mask
);
3409 tcg_gen_or_i32(tmp
, tmp
, t0
);
3410 store_cpu_field(tmp
, spsr
);
3412 gen_set_cpsr(t0
, mask
);
3414 tcg_temp_free_i32(t0
);
3419 /* Returns nonzero if access to the PSR is not permitted. */
3420 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3423 tmp
= tcg_temp_new_i32();
3424 tcg_gen_movi_i32(tmp
, val
);
3425 return gen_set_psr(s
, mask
, spsr
, tmp
);
3428 /* Generate an old-style exception return. Marks pc as dead. */
3429 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3432 store_reg(s
, 15, pc
);
3433 tmp
= load_cpu_field(spsr
);
3434 gen_set_cpsr(tmp
, 0xffffffff);
3435 tcg_temp_free_i32(tmp
);
3436 s
->is_jmp
= DISAS_UPDATE
;
3439 /* Generate a v6 exception return. Marks both values as dead. */
3440 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3442 gen_set_cpsr(cpsr
, 0xffffffff);
3443 tcg_temp_free_i32(cpsr
);
3444 store_reg(s
, 15, pc
);
3445 s
->is_jmp
= DISAS_UPDATE
;
3449 gen_set_condexec (DisasContext
*s
)
3451 if (s
->condexec_mask
) {
3452 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3453 TCGv tmp
= tcg_temp_new_i32();
3454 tcg_gen_movi_i32(tmp
, val
);
3455 store_cpu_field(tmp
, condexec_bits
);
3459 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3461 gen_set_condexec(s
);
3462 gen_set_pc_im(s
->pc
- offset
);
3463 gen_exception(excp
);
3464 s
->is_jmp
= DISAS_JUMP
;
3467 static void gen_nop_hint(DisasContext
*s
, int val
)
3471 gen_set_pc_im(s
->pc
);
3472 s
->is_jmp
= DISAS_WFI
;
3476 /* TODO: Implement SEV and WFE. May help SMP performance. */
3482 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3484 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3487 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3488 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3489 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3494 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3497 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3498 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3499 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3504 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3505 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3506 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3507 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3508 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3510 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3511 switch ((size << 1) | u) { \
3513 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3516 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3519 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3522 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3525 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3528 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3530 default: return 1; \
3533 #define GEN_NEON_INTEGER_OP(name) do { \
3534 switch ((size << 1) | u) { \
3536 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3539 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3542 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3545 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3548 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3551 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3553 default: return 1; \
3556 static TCGv
neon_load_scratch(int scratch
)
3558 TCGv tmp
= tcg_temp_new_i32();
3559 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3563 static void neon_store_scratch(int scratch
, TCGv var
)
3565 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3566 tcg_temp_free_i32(var
);
3569 static inline TCGv
neon_get_scalar(int size
, int reg
)
3573 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3575 gen_neon_dup_high16(tmp
);
3577 gen_neon_dup_low16(tmp
);
3580 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3585 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3588 if (!q
&& size
== 2) {
3591 tmp
= tcg_const_i32(rd
);
3592 tmp2
= tcg_const_i32(rm
);
3596 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3599 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3602 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3610 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3613 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3619 tcg_temp_free_i32(tmp
);
3620 tcg_temp_free_i32(tmp2
);
3624 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3627 if (!q
&& size
== 2) {
3630 tmp
= tcg_const_i32(rd
);
3631 tmp2
= tcg_const_i32(rm
);
3635 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3638 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3641 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3649 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3652 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3658 tcg_temp_free_i32(tmp
);
3659 tcg_temp_free_i32(tmp2
);
3663 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3667 rd
= tcg_temp_new_i32();
3668 tmp
= tcg_temp_new_i32();
3670 tcg_gen_shli_i32(rd
, t0
, 8);
3671 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3672 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3673 tcg_gen_or_i32(rd
, rd
, tmp
);
3675 tcg_gen_shri_i32(t1
, t1
, 8);
3676 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3677 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3678 tcg_gen_or_i32(t1
, t1
, tmp
);
3679 tcg_gen_mov_i32(t0
, rd
);
3681 tcg_temp_free_i32(tmp
);
3682 tcg_temp_free_i32(rd
);
3685 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3689 rd
= tcg_temp_new_i32();
3690 tmp
= tcg_temp_new_i32();
3692 tcg_gen_shli_i32(rd
, t0
, 16);
3693 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3694 tcg_gen_or_i32(rd
, rd
, tmp
);
3695 tcg_gen_shri_i32(t1
, t1
, 16);
3696 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3697 tcg_gen_or_i32(t1
, t1
, tmp
);
3698 tcg_gen_mov_i32(t0
, rd
);
3700 tcg_temp_free_i32(tmp
);
3701 tcg_temp_free_i32(rd
);
3709 } neon_ls_element_type
[11] = {
3723 /* Translate a NEON load/store element instruction. Return nonzero if the
3724 instruction is invalid. */
3725 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3744 if (!s
->vfp_enabled
)
3746 VFP_DREG_D(rd
, insn
);
3747 rn
= (insn
>> 16) & 0xf;
3749 load
= (insn
& (1 << 21)) != 0;
3750 if ((insn
& (1 << 23)) == 0) {
3751 /* Load store all elements. */
3752 op
= (insn
>> 8) & 0xf;
3753 size
= (insn
>> 6) & 3;
3756 /* Catch UNDEF cases for bad values of align field */
3759 if (((insn
>> 5) & 1) == 1) {
3764 if (((insn
>> 4) & 3) == 3) {
3771 nregs
= neon_ls_element_type
[op
].nregs
;
3772 interleave
= neon_ls_element_type
[op
].interleave
;
3773 spacing
= neon_ls_element_type
[op
].spacing
;
3774 if (size
== 3 && (interleave
| spacing
) != 1)
3776 addr
= tcg_temp_new_i32();
3777 load_reg_var(s
, addr
, rn
);
3778 stride
= (1 << size
) * interleave
;
3779 for (reg
= 0; reg
< nregs
; reg
++) {
3780 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3781 load_reg_var(s
, addr
, rn
);
3782 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3783 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3784 load_reg_var(s
, addr
, rn
);
3785 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3789 tmp64
= gen_ld64(addr
, IS_USER(s
));
3790 neon_store_reg64(tmp64
, rd
);
3791 tcg_temp_free_i64(tmp64
);
3793 tmp64
= tcg_temp_new_i64();
3794 neon_load_reg64(tmp64
, rd
);
3795 gen_st64(tmp64
, addr
, IS_USER(s
));
3797 tcg_gen_addi_i32(addr
, addr
, stride
);
3799 for (pass
= 0; pass
< 2; pass
++) {
3802 tmp
= gen_ld32(addr
, IS_USER(s
));
3803 neon_store_reg(rd
, pass
, tmp
);
3805 tmp
= neon_load_reg(rd
, pass
);
3806 gen_st32(tmp
, addr
, IS_USER(s
));
3808 tcg_gen_addi_i32(addr
, addr
, stride
);
3809 } else if (size
== 1) {
3811 tmp
= gen_ld16u(addr
, IS_USER(s
));
3812 tcg_gen_addi_i32(addr
, addr
, stride
);
3813 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3814 tcg_gen_addi_i32(addr
, addr
, stride
);
3815 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3816 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3817 tcg_temp_free_i32(tmp2
);
3818 neon_store_reg(rd
, pass
, tmp
);
3820 tmp
= neon_load_reg(rd
, pass
);
3821 tmp2
= tcg_temp_new_i32();
3822 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3823 gen_st16(tmp
, addr
, IS_USER(s
));
3824 tcg_gen_addi_i32(addr
, addr
, stride
);
3825 gen_st16(tmp2
, addr
, IS_USER(s
));
3826 tcg_gen_addi_i32(addr
, addr
, stride
);
3828 } else /* size == 0 */ {
3831 for (n
= 0; n
< 4; n
++) {
3832 tmp
= gen_ld8u(addr
, IS_USER(s
));
3833 tcg_gen_addi_i32(addr
, addr
, stride
);
3837 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3838 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3839 tcg_temp_free_i32(tmp
);
3842 neon_store_reg(rd
, pass
, tmp2
);
3844 tmp2
= neon_load_reg(rd
, pass
);
3845 for (n
= 0; n
< 4; n
++) {
3846 tmp
= tcg_temp_new_i32();
3848 tcg_gen_mov_i32(tmp
, tmp2
);
3850 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3852 gen_st8(tmp
, addr
, IS_USER(s
));
3853 tcg_gen_addi_i32(addr
, addr
, stride
);
3855 tcg_temp_free_i32(tmp2
);
3862 tcg_temp_free_i32(addr
);
3865 size
= (insn
>> 10) & 3;
3867 /* Load single element to all lanes. */
3868 int a
= (insn
>> 4) & 1;
3872 size
= (insn
>> 6) & 3;
3873 nregs
= ((insn
>> 8) & 3) + 1;
3876 if (nregs
!= 4 || a
== 0) {
3879 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3882 if (nregs
== 1 && a
== 1 && size
== 0) {
3885 if (nregs
== 3 && a
== 1) {
3888 addr
= tcg_temp_new_i32();
3889 load_reg_var(s
, addr
, rn
);
3891 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3892 tmp
= gen_load_and_replicate(s
, addr
, size
);
3893 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3894 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3895 if (insn
& (1 << 5)) {
3896 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3897 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3899 tcg_temp_free_i32(tmp
);
3901 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3902 stride
= (insn
& (1 << 5)) ? 2 : 1;
3903 for (reg
= 0; reg
< nregs
; reg
++) {
3904 tmp
= gen_load_and_replicate(s
, addr
, size
);
3905 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3906 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3907 tcg_temp_free_i32(tmp
);
3908 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3912 tcg_temp_free_i32(addr
);
3913 stride
= (1 << size
) * nregs
;
3915 /* Single element. */
3916 int idx
= (insn
>> 4) & 0xf;
3917 pass
= (insn
>> 7) & 1;
3920 shift
= ((insn
>> 5) & 3) * 8;
3924 shift
= ((insn
>> 6) & 1) * 16;
3925 stride
= (insn
& (1 << 5)) ? 2 : 1;
3929 stride
= (insn
& (1 << 6)) ? 2 : 1;
3934 nregs
= ((insn
>> 8) & 3) + 1;
3935 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3938 if (((idx
& (1 << size
)) != 0) ||
3939 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3944 if ((idx
& 1) != 0) {
3949 if (size
== 2 && (idx
& 2) != 0) {
3954 if ((size
== 2) && ((idx
& 3) == 3)) {
3961 if ((rd
+ stride
* (nregs
- 1)) > 31) {
3962 /* Attempts to write off the end of the register file
3963 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3964 * the neon_load_reg() would write off the end of the array.
3968 addr
= tcg_temp_new_i32();
3969 load_reg_var(s
, addr
, rn
);
3970 for (reg
= 0; reg
< nregs
; reg
++) {
3974 tmp
= gen_ld8u(addr
, IS_USER(s
));
3977 tmp
= gen_ld16u(addr
, IS_USER(s
));
3980 tmp
= gen_ld32(addr
, IS_USER(s
));
3982 default: /* Avoid compiler warnings. */
3986 tmp2
= neon_load_reg(rd
, pass
);
3987 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
3988 tcg_temp_free_i32(tmp2
);
3990 neon_store_reg(rd
, pass
, tmp
);
3991 } else { /* Store */
3992 tmp
= neon_load_reg(rd
, pass
);
3994 tcg_gen_shri_i32(tmp
, tmp
, shift
);
3997 gen_st8(tmp
, addr
, IS_USER(s
));
4000 gen_st16(tmp
, addr
, IS_USER(s
));
4003 gen_st32(tmp
, addr
, IS_USER(s
));
4008 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4010 tcg_temp_free_i32(addr
);
4011 stride
= nregs
* (1 << size
);
4017 base
= load_reg(s
, rn
);
4019 tcg_gen_addi_i32(base
, base
, stride
);
4022 index
= load_reg(s
, rm
);
4023 tcg_gen_add_i32(base
, base
, index
);
4024 tcg_temp_free_i32(index
);
4026 store_reg(s
, rn
, base
);
4031 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4032 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4034 tcg_gen_and_i32(t
, t
, c
);
4035 tcg_gen_andc_i32(f
, f
, c
);
4036 tcg_gen_or_i32(dest
, t
, f
);
4039 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4042 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4043 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4044 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4049 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4052 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4053 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4054 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4059 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4062 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4063 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4064 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4069 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4072 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4073 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4074 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4079 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4085 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4086 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4091 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4092 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4099 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4100 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4105 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4106 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4113 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4117 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4118 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4119 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4124 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4125 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4126 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4130 tcg_temp_free_i32(src
);
4133 static inline void gen_neon_addl(int size
)
4136 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4137 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4138 case 2: tcg_gen_add_i64(CPU_V001
); break;
4143 static inline void gen_neon_subl(int size
)
4146 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4147 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4148 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4153 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4156 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4157 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4158 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4163 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4166 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4167 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4172 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4176 switch ((size
<< 1) | u
) {
4177 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4178 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4179 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4180 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4182 tmp
= gen_muls_i64_i32(a
, b
);
4183 tcg_gen_mov_i64(dest
, tmp
);
4184 tcg_temp_free_i64(tmp
);
4187 tmp
= gen_mulu_i64_i32(a
, b
);
4188 tcg_gen_mov_i64(dest
, tmp
);
4189 tcg_temp_free_i64(tmp
);
4194 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4195 Don't forget to clean them now. */
4197 tcg_temp_free_i32(a
);
4198 tcg_temp_free_i32(b
);
4202 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4206 gen_neon_unarrow_sats(size
, dest
, src
);
4208 gen_neon_narrow(size
, dest
, src
);
4212 gen_neon_narrow_satu(size
, dest
, src
);
4214 gen_neon_narrow_sats(size
, dest
, src
);
4219 /* Symbolic constants for op fields for Neon 3-register same-length.
4220 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4223 #define NEON_3R_VHADD 0
4224 #define NEON_3R_VQADD 1
4225 #define NEON_3R_VRHADD 2
4226 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4227 #define NEON_3R_VHSUB 4
4228 #define NEON_3R_VQSUB 5
4229 #define NEON_3R_VCGT 6
4230 #define NEON_3R_VCGE 7
4231 #define NEON_3R_VSHL 8
4232 #define NEON_3R_VQSHL 9
4233 #define NEON_3R_VRSHL 10
4234 #define NEON_3R_VQRSHL 11
4235 #define NEON_3R_VMAX 12
4236 #define NEON_3R_VMIN 13
4237 #define NEON_3R_VABD 14
4238 #define NEON_3R_VABA 15
4239 #define NEON_3R_VADD_VSUB 16
4240 #define NEON_3R_VTST_VCEQ 17
4241 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4242 #define NEON_3R_VMUL 19
4243 #define NEON_3R_VPMAX 20
4244 #define NEON_3R_VPMIN 21
4245 #define NEON_3R_VQDMULH_VQRDMULH 22
4246 #define NEON_3R_VPADD 23
4247 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4248 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4249 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4250 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4251 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4252 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4253 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4255 static const uint8_t neon_3r_sizes
[] = {
4256 [NEON_3R_VHADD
] = 0x7,
4257 [NEON_3R_VQADD
] = 0xf,
4258 [NEON_3R_VRHADD
] = 0x7,
4259 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4260 [NEON_3R_VHSUB
] = 0x7,
4261 [NEON_3R_VQSUB
] = 0xf,
4262 [NEON_3R_VCGT
] = 0x7,
4263 [NEON_3R_VCGE
] = 0x7,
4264 [NEON_3R_VSHL
] = 0xf,
4265 [NEON_3R_VQSHL
] = 0xf,
4266 [NEON_3R_VRSHL
] = 0xf,
4267 [NEON_3R_VQRSHL
] = 0xf,
4268 [NEON_3R_VMAX
] = 0x7,
4269 [NEON_3R_VMIN
] = 0x7,
4270 [NEON_3R_VABD
] = 0x7,
4271 [NEON_3R_VABA
] = 0x7,
4272 [NEON_3R_VADD_VSUB
] = 0xf,
4273 [NEON_3R_VTST_VCEQ
] = 0x7,
4274 [NEON_3R_VML
] = 0x7,
4275 [NEON_3R_VMUL
] = 0x7,
4276 [NEON_3R_VPMAX
] = 0x7,
4277 [NEON_3R_VPMIN
] = 0x7,
4278 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4279 [NEON_3R_VPADD
] = 0x7,
4280 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4281 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4282 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4283 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4284 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4285 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4286 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4289 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4290 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4293 #define NEON_2RM_VREV64 0
4294 #define NEON_2RM_VREV32 1
4295 #define NEON_2RM_VREV16 2
4296 #define NEON_2RM_VPADDL 4
4297 #define NEON_2RM_VPADDL_U 5
4298 #define NEON_2RM_VCLS 8
4299 #define NEON_2RM_VCLZ 9
4300 #define NEON_2RM_VCNT 10
4301 #define NEON_2RM_VMVN 11
4302 #define NEON_2RM_VPADAL 12
4303 #define NEON_2RM_VPADAL_U 13
4304 #define NEON_2RM_VQABS 14
4305 #define NEON_2RM_VQNEG 15
4306 #define NEON_2RM_VCGT0 16
4307 #define NEON_2RM_VCGE0 17
4308 #define NEON_2RM_VCEQ0 18
4309 #define NEON_2RM_VCLE0 19
4310 #define NEON_2RM_VCLT0 20
4311 #define NEON_2RM_VABS 22
4312 #define NEON_2RM_VNEG 23
4313 #define NEON_2RM_VCGT0_F 24
4314 #define NEON_2RM_VCGE0_F 25
4315 #define NEON_2RM_VCEQ0_F 26
4316 #define NEON_2RM_VCLE0_F 27
4317 #define NEON_2RM_VCLT0_F 28
4318 #define NEON_2RM_VABS_F 30
4319 #define NEON_2RM_VNEG_F 31
4320 #define NEON_2RM_VSWP 32
4321 #define NEON_2RM_VTRN 33
4322 #define NEON_2RM_VUZP 34
4323 #define NEON_2RM_VZIP 35
4324 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4325 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4326 #define NEON_2RM_VSHLL 38
4327 #define NEON_2RM_VCVT_F16_F32 44
4328 #define NEON_2RM_VCVT_F32_F16 46
4329 #define NEON_2RM_VRECPE 56
4330 #define NEON_2RM_VRSQRTE 57
4331 #define NEON_2RM_VRECPE_F 58
4332 #define NEON_2RM_VRSQRTE_F 59
4333 #define NEON_2RM_VCVT_FS 60
4334 #define NEON_2RM_VCVT_FU 61
4335 #define NEON_2RM_VCVT_SF 62
4336 #define NEON_2RM_VCVT_UF 63
4338 static int neon_2rm_is_float_op(int op
)
4340 /* Return true if this neon 2reg-misc op is float-to-float */
4341 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4342 op
>= NEON_2RM_VRECPE_F
);
4345 /* Each entry in this array has bit n set if the insn allows
4346 * size value n (otherwise it will UNDEF). Since unallocated
4347 * op values will have no bits set they always UNDEF.
4349 static const uint8_t neon_2rm_sizes
[] = {
4350 [NEON_2RM_VREV64
] = 0x7,
4351 [NEON_2RM_VREV32
] = 0x3,
4352 [NEON_2RM_VREV16
] = 0x1,
4353 [NEON_2RM_VPADDL
] = 0x7,
4354 [NEON_2RM_VPADDL_U
] = 0x7,
4355 [NEON_2RM_VCLS
] = 0x7,
4356 [NEON_2RM_VCLZ
] = 0x7,
4357 [NEON_2RM_VCNT
] = 0x1,
4358 [NEON_2RM_VMVN
] = 0x1,
4359 [NEON_2RM_VPADAL
] = 0x7,
4360 [NEON_2RM_VPADAL_U
] = 0x7,
4361 [NEON_2RM_VQABS
] = 0x7,
4362 [NEON_2RM_VQNEG
] = 0x7,
4363 [NEON_2RM_VCGT0
] = 0x7,
4364 [NEON_2RM_VCGE0
] = 0x7,
4365 [NEON_2RM_VCEQ0
] = 0x7,
4366 [NEON_2RM_VCLE0
] = 0x7,
4367 [NEON_2RM_VCLT0
] = 0x7,
4368 [NEON_2RM_VABS
] = 0x7,
4369 [NEON_2RM_VNEG
] = 0x7,
4370 [NEON_2RM_VCGT0_F
] = 0x4,
4371 [NEON_2RM_VCGE0_F
] = 0x4,
4372 [NEON_2RM_VCEQ0_F
] = 0x4,
4373 [NEON_2RM_VCLE0_F
] = 0x4,
4374 [NEON_2RM_VCLT0_F
] = 0x4,
4375 [NEON_2RM_VABS_F
] = 0x4,
4376 [NEON_2RM_VNEG_F
] = 0x4,
4377 [NEON_2RM_VSWP
] = 0x1,
4378 [NEON_2RM_VTRN
] = 0x7,
4379 [NEON_2RM_VUZP
] = 0x7,
4380 [NEON_2RM_VZIP
] = 0x7,
4381 [NEON_2RM_VMOVN
] = 0x7,
4382 [NEON_2RM_VQMOVN
] = 0x7,
4383 [NEON_2RM_VSHLL
] = 0x7,
4384 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4385 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4386 [NEON_2RM_VRECPE
] = 0x4,
4387 [NEON_2RM_VRSQRTE
] = 0x4,
4388 [NEON_2RM_VRECPE_F
] = 0x4,
4389 [NEON_2RM_VRSQRTE_F
] = 0x4,
4390 [NEON_2RM_VCVT_FS
] = 0x4,
4391 [NEON_2RM_VCVT_FU
] = 0x4,
4392 [NEON_2RM_VCVT_SF
] = 0x4,
4393 [NEON_2RM_VCVT_UF
] = 0x4,
4396 /* Translate a NEON data processing instruction. Return nonzero if the
4397 instruction is invalid.
4398 We process data in a mixture of 32-bit and 64-bit chunks.
4399 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4401 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4413 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4416 if (!s
->vfp_enabled
)
4418 q
= (insn
& (1 << 6)) != 0;
4419 u
= (insn
>> 24) & 1;
4420 VFP_DREG_D(rd
, insn
);
4421 VFP_DREG_N(rn
, insn
);
4422 VFP_DREG_M(rm
, insn
);
4423 size
= (insn
>> 20) & 3;
4424 if ((insn
& (1 << 23)) == 0) {
4425 /* Three register same length. */
4426 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4427 /* Catch invalid op and bad size combinations: UNDEF */
4428 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4431 /* All insns of this form UNDEF for either this condition or the
4432 * superset of cases "Q==1"; we catch the latter later.
4434 if (q
&& ((rd
| rn
| rm
) & 1)) {
4437 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4438 /* 64-bit element instructions. */
4439 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4440 neon_load_reg64(cpu_V0
, rn
+ pass
);
4441 neon_load_reg64(cpu_V1
, rm
+ pass
);
4445 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4448 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4454 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4457 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4463 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4465 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4470 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4473 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4479 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4481 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4484 case NEON_3R_VQRSHL
:
4486 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4489 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4493 case NEON_3R_VADD_VSUB
:
4495 tcg_gen_sub_i64(CPU_V001
);
4497 tcg_gen_add_i64(CPU_V001
);
4503 neon_store_reg64(cpu_V0
, rd
+ pass
);
4512 case NEON_3R_VQRSHL
:
4515 /* Shift instruction operands are reversed. */
4530 case NEON_3R_FLOAT_ARITH
:
4531 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4533 case NEON_3R_FLOAT_MINMAX
:
4534 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4536 case NEON_3R_FLOAT_CMP
:
4538 /* no encoding for U=0 C=1x */
4542 case NEON_3R_FLOAT_ACMP
:
4547 case NEON_3R_VRECPS_VRSQRTS
:
4553 if (u
&& (size
!= 0)) {
4554 /* UNDEF on invalid size for polynomial subcase */
4559 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4567 if (pairwise
&& q
) {
4568 /* All the pairwise insns UNDEF if Q is set */
4572 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4577 tmp
= neon_load_reg(rn
, 0);
4578 tmp2
= neon_load_reg(rn
, 1);
4580 tmp
= neon_load_reg(rm
, 0);
4581 tmp2
= neon_load_reg(rm
, 1);
4585 tmp
= neon_load_reg(rn
, pass
);
4586 tmp2
= neon_load_reg(rm
, pass
);
4590 GEN_NEON_INTEGER_OP(hadd
);
4593 GEN_NEON_INTEGER_OP_ENV(qadd
);
4595 case NEON_3R_VRHADD
:
4596 GEN_NEON_INTEGER_OP(rhadd
);
4598 case NEON_3R_LOGIC
: /* Logic ops. */
4599 switch ((u
<< 2) | size
) {
4601 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4604 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4607 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4610 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4613 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4616 tmp3
= neon_load_reg(rd
, pass
);
4617 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4618 tcg_temp_free_i32(tmp3
);
4621 tmp3
= neon_load_reg(rd
, pass
);
4622 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4623 tcg_temp_free_i32(tmp3
);
4626 tmp3
= neon_load_reg(rd
, pass
);
4627 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4628 tcg_temp_free_i32(tmp3
);
4633 GEN_NEON_INTEGER_OP(hsub
);
4636 GEN_NEON_INTEGER_OP_ENV(qsub
);
4639 GEN_NEON_INTEGER_OP(cgt
);
4642 GEN_NEON_INTEGER_OP(cge
);
4645 GEN_NEON_INTEGER_OP(shl
);
4648 GEN_NEON_INTEGER_OP_ENV(qshl
);
4651 GEN_NEON_INTEGER_OP(rshl
);
4653 case NEON_3R_VQRSHL
:
4654 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4657 GEN_NEON_INTEGER_OP(max
);
4660 GEN_NEON_INTEGER_OP(min
);
4663 GEN_NEON_INTEGER_OP(abd
);
4666 GEN_NEON_INTEGER_OP(abd
);
4667 tcg_temp_free_i32(tmp2
);
4668 tmp2
= neon_load_reg(rd
, pass
);
4669 gen_neon_add(size
, tmp
, tmp2
);
4671 case NEON_3R_VADD_VSUB
:
4672 if (!u
) { /* VADD */
4673 gen_neon_add(size
, tmp
, tmp2
);
4676 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4677 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4678 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4683 case NEON_3R_VTST_VCEQ
:
4684 if (!u
) { /* VTST */
4686 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4687 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4688 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4693 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4694 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4695 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4700 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4702 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4703 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4704 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4707 tcg_temp_free_i32(tmp2
);
4708 tmp2
= neon_load_reg(rd
, pass
);
4710 gen_neon_rsb(size
, tmp
, tmp2
);
4712 gen_neon_add(size
, tmp
, tmp2
);
4716 if (u
) { /* polynomial */
4717 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4718 } else { /* Integer */
4720 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4721 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4722 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4728 GEN_NEON_INTEGER_OP(pmax
);
4731 GEN_NEON_INTEGER_OP(pmin
);
4733 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4734 if (!u
) { /* VQDMULH */
4737 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4740 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4744 } else { /* VQRDMULH */
4747 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4750 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4758 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4759 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4760 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4764 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4766 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4767 switch ((u
<< 2) | size
) {
4770 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4773 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4776 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4781 tcg_temp_free_ptr(fpstatus
);
4784 case NEON_3R_FLOAT_MULTIPLY
:
4786 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4787 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4789 tcg_temp_free_i32(tmp2
);
4790 tmp2
= neon_load_reg(rd
, pass
);
4792 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4794 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4797 tcg_temp_free_ptr(fpstatus
);
4800 case NEON_3R_FLOAT_CMP
:
4802 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4804 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4807 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4809 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4812 tcg_temp_free_ptr(fpstatus
);
4815 case NEON_3R_FLOAT_ACMP
:
4817 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4819 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4821 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4823 tcg_temp_free_ptr(fpstatus
);
4826 case NEON_3R_FLOAT_MINMAX
:
4828 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4830 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4832 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4834 tcg_temp_free_ptr(fpstatus
);
4837 case NEON_3R_VRECPS_VRSQRTS
:
4839 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4841 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4845 /* VFMA, VFMS: fused multiply-add */
4846 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4847 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4850 gen_helper_vfp_negs(tmp
, tmp
);
4852 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4853 tcg_temp_free_i32(tmp3
);
4854 tcg_temp_free_ptr(fpstatus
);
4860 tcg_temp_free_i32(tmp2
);
4862 /* Save the result. For elementwise operations we can put it
4863 straight into the destination register. For pairwise operations
4864 we have to be careful to avoid clobbering the source operands. */
4865 if (pairwise
&& rd
== rm
) {
4866 neon_store_scratch(pass
, tmp
);
4868 neon_store_reg(rd
, pass
, tmp
);
4872 if (pairwise
&& rd
== rm
) {
4873 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4874 tmp
= neon_load_scratch(pass
);
4875 neon_store_reg(rd
, pass
, tmp
);
4878 /* End of 3 register same size operations. */
4879 } else if (insn
& (1 << 4)) {
4880 if ((insn
& 0x00380080) != 0) {
4881 /* Two registers and shift. */
4882 op
= (insn
>> 8) & 0xf;
4883 if (insn
& (1 << 7)) {
4891 while ((insn
& (1 << (size
+ 19))) == 0)
4894 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4895 /* To avoid excessive duplication of ops we implement shift
4896 by immediate using the variable shift operations. */
4898 /* Shift by immediate:
4899 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4900 if (q
&& ((rd
| rm
) & 1)) {
4903 if (!u
&& (op
== 4 || op
== 6)) {
4906 /* Right shifts are encoded as N - shift, where N is the
4907 element size in bits. */
4909 shift
= shift
- (1 << (size
+ 3));
4917 imm
= (uint8_t) shift
;
4922 imm
= (uint16_t) shift
;
4933 for (pass
= 0; pass
< count
; pass
++) {
4935 neon_load_reg64(cpu_V0
, rm
+ pass
);
4936 tcg_gen_movi_i64(cpu_V1
, imm
);
4941 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4943 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4948 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4950 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4953 case 5: /* VSHL, VSLI */
4954 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4956 case 6: /* VQSHLU */
4957 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
4962 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4965 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4970 if (op
== 1 || op
== 3) {
4972 neon_load_reg64(cpu_V1
, rd
+ pass
);
4973 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4974 } else if (op
== 4 || (op
== 5 && u
)) {
4976 neon_load_reg64(cpu_V1
, rd
+ pass
);
4978 if (shift
< -63 || shift
> 63) {
4982 mask
= 0xffffffffffffffffull
>> -shift
;
4984 mask
= 0xffffffffffffffffull
<< shift
;
4987 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
4988 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
4990 neon_store_reg64(cpu_V0
, rd
+ pass
);
4991 } else { /* size < 3 */
4992 /* Operands in T0 and T1. */
4993 tmp
= neon_load_reg(rm
, pass
);
4994 tmp2
= tcg_temp_new_i32();
4995 tcg_gen_movi_i32(tmp2
, imm
);
4999 GEN_NEON_INTEGER_OP(shl
);
5003 GEN_NEON_INTEGER_OP(rshl
);
5006 case 5: /* VSHL, VSLI */
5008 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5009 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5010 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5014 case 6: /* VQSHLU */
5017 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5021 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5025 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5033 GEN_NEON_INTEGER_OP_ENV(qshl
);
5036 tcg_temp_free_i32(tmp2
);
5038 if (op
== 1 || op
== 3) {
5040 tmp2
= neon_load_reg(rd
, pass
);
5041 gen_neon_add(size
, tmp
, tmp2
);
5042 tcg_temp_free_i32(tmp2
);
5043 } else if (op
== 4 || (op
== 5 && u
)) {
5048 mask
= 0xff >> -shift
;
5050 mask
= (uint8_t)(0xff << shift
);
5056 mask
= 0xffff >> -shift
;
5058 mask
= (uint16_t)(0xffff << shift
);
5062 if (shift
< -31 || shift
> 31) {
5066 mask
= 0xffffffffu
>> -shift
;
5068 mask
= 0xffffffffu
<< shift
;
5074 tmp2
= neon_load_reg(rd
, pass
);
5075 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5076 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5077 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5078 tcg_temp_free_i32(tmp2
);
5080 neon_store_reg(rd
, pass
, tmp
);
5083 } else if (op
< 10) {
5084 /* Shift by immediate and narrow:
5085 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5086 int input_unsigned
= (op
== 8) ? !u
: u
;
5090 shift
= shift
- (1 << (size
+ 3));
5093 tmp64
= tcg_const_i64(shift
);
5094 neon_load_reg64(cpu_V0
, rm
);
5095 neon_load_reg64(cpu_V1
, rm
+ 1);
5096 for (pass
= 0; pass
< 2; pass
++) {
5104 if (input_unsigned
) {
5105 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5107 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5110 if (input_unsigned
) {
5111 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5113 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5116 tmp
= tcg_temp_new_i32();
5117 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5118 neon_store_reg(rd
, pass
, tmp
);
5120 tcg_temp_free_i64(tmp64
);
5123 imm
= (uint16_t)shift
;
5127 imm
= (uint32_t)shift
;
5129 tmp2
= tcg_const_i32(imm
);
5130 tmp4
= neon_load_reg(rm
+ 1, 0);
5131 tmp5
= neon_load_reg(rm
+ 1, 1);
5132 for (pass
= 0; pass
< 2; pass
++) {
5134 tmp
= neon_load_reg(rm
, 0);
5138 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5141 tmp3
= neon_load_reg(rm
, 1);
5145 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5147 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5148 tcg_temp_free_i32(tmp
);
5149 tcg_temp_free_i32(tmp3
);
5150 tmp
= tcg_temp_new_i32();
5151 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5152 neon_store_reg(rd
, pass
, tmp
);
5154 tcg_temp_free_i32(tmp2
);
5156 } else if (op
== 10) {
5158 if (q
|| (rd
& 1)) {
5161 tmp
= neon_load_reg(rm
, 0);
5162 tmp2
= neon_load_reg(rm
, 1);
5163 for (pass
= 0; pass
< 2; pass
++) {
5167 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5170 /* The shift is less than the width of the source
5171 type, so we can just shift the whole register. */
5172 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5173 /* Widen the result of shift: we need to clear
5174 * the potential overflow bits resulting from
5175 * left bits of the narrow input appearing as
5176 * right bits of left the neighbour narrow
5178 if (size
< 2 || !u
) {
5181 imm
= (0xffu
>> (8 - shift
));
5183 } else if (size
== 1) {
5184 imm
= 0xffff >> (16 - shift
);
5187 imm
= 0xffffffff >> (32 - shift
);
5190 imm64
= imm
| (((uint64_t)imm
) << 32);
5194 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5197 neon_store_reg64(cpu_V0
, rd
+ pass
);
5199 } else if (op
>= 14) {
5200 /* VCVT fixed-point. */
5201 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5204 /* We have already masked out the must-be-1 top bit of imm6,
5205 * hence this 32-shift where the ARM ARM has 64-imm6.
5208 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5209 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5212 gen_vfp_ulto(0, shift
, 1);
5214 gen_vfp_slto(0, shift
, 1);
5217 gen_vfp_toul(0, shift
, 1);
5219 gen_vfp_tosl(0, shift
, 1);
5221 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5226 } else { /* (insn & 0x00380080) == 0 */
5228 if (q
&& (rd
& 1)) {
5232 op
= (insn
>> 8) & 0xf;
5233 /* One register and immediate. */
5234 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5235 invert
= (insn
& (1 << 5)) != 0;
5236 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5237 * We choose to not special-case this and will behave as if a
5238 * valid constant encoding of 0 had been given.
5257 imm
= (imm
<< 8) | (imm
<< 24);
5260 imm
= (imm
<< 8) | 0xff;
5263 imm
= (imm
<< 16) | 0xffff;
5266 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5274 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5275 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5281 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5282 if (op
& 1 && op
< 12) {
5283 tmp
= neon_load_reg(rd
, pass
);
5285 /* The immediate value has already been inverted, so
5287 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5289 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5293 tmp
= tcg_temp_new_i32();
5294 if (op
== 14 && invert
) {
5298 for (n
= 0; n
< 4; n
++) {
5299 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5300 val
|= 0xff << (n
* 8);
5302 tcg_gen_movi_i32(tmp
, val
);
5304 tcg_gen_movi_i32(tmp
, imm
);
5307 neon_store_reg(rd
, pass
, tmp
);
5310 } else { /* (insn & 0x00800010 == 0x00800000) */
5312 op
= (insn
>> 8) & 0xf;
5313 if ((insn
& (1 << 6)) == 0) {
5314 /* Three registers of different lengths. */
5318 /* undefreq: bit 0 : UNDEF if size != 0
5319 * bit 1 : UNDEF if size == 0
5320 * bit 2 : UNDEF if U == 1
5321 * Note that [1:0] set implies 'always UNDEF'
5324 /* prewiden, src1_wide, src2_wide, undefreq */
5325 static const int neon_3reg_wide
[16][4] = {
5326 {1, 0, 0, 0}, /* VADDL */
5327 {1, 1, 0, 0}, /* VADDW */
5328 {1, 0, 0, 0}, /* VSUBL */
5329 {1, 1, 0, 0}, /* VSUBW */
5330 {0, 1, 1, 0}, /* VADDHN */
5331 {0, 0, 0, 0}, /* VABAL */
5332 {0, 1, 1, 0}, /* VSUBHN */
5333 {0, 0, 0, 0}, /* VABDL */
5334 {0, 0, 0, 0}, /* VMLAL */
5335 {0, 0, 0, 6}, /* VQDMLAL */
5336 {0, 0, 0, 0}, /* VMLSL */
5337 {0, 0, 0, 6}, /* VQDMLSL */
5338 {0, 0, 0, 0}, /* Integer VMULL */
5339 {0, 0, 0, 2}, /* VQDMULL */
5340 {0, 0, 0, 5}, /* Polynomial VMULL */
5341 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5344 prewiden
= neon_3reg_wide
[op
][0];
5345 src1_wide
= neon_3reg_wide
[op
][1];
5346 src2_wide
= neon_3reg_wide
[op
][2];
5347 undefreq
= neon_3reg_wide
[op
][3];
5349 if (((undefreq
& 1) && (size
!= 0)) ||
5350 ((undefreq
& 2) && (size
== 0)) ||
5351 ((undefreq
& 4) && u
)) {
5354 if ((src1_wide
&& (rn
& 1)) ||
5355 (src2_wide
&& (rm
& 1)) ||
5356 (!src2_wide
&& (rd
& 1))) {
5360 /* Avoid overlapping operands. Wide source operands are
5361 always aligned so will never overlap with wide
5362 destinations in problematic ways. */
5363 if (rd
== rm
&& !src2_wide
) {
5364 tmp
= neon_load_reg(rm
, 1);
5365 neon_store_scratch(2, tmp
);
5366 } else if (rd
== rn
&& !src1_wide
) {
5367 tmp
= neon_load_reg(rn
, 1);
5368 neon_store_scratch(2, tmp
);
5371 for (pass
= 0; pass
< 2; pass
++) {
5373 neon_load_reg64(cpu_V0
, rn
+ pass
);
5376 if (pass
== 1 && rd
== rn
) {
5377 tmp
= neon_load_scratch(2);
5379 tmp
= neon_load_reg(rn
, pass
);
5382 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5386 neon_load_reg64(cpu_V1
, rm
+ pass
);
5389 if (pass
== 1 && rd
== rm
) {
5390 tmp2
= neon_load_scratch(2);
5392 tmp2
= neon_load_reg(rm
, pass
);
5395 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5399 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5400 gen_neon_addl(size
);
5402 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5403 gen_neon_subl(size
);
5405 case 5: case 7: /* VABAL, VABDL */
5406 switch ((size
<< 1) | u
) {
5408 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5411 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5414 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5417 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5420 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5423 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5427 tcg_temp_free_i32(tmp2
);
5428 tcg_temp_free_i32(tmp
);
5430 case 8: case 9: case 10: case 11: case 12: case 13:
5431 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5432 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5434 case 14: /* Polynomial VMULL */
5435 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5436 tcg_temp_free_i32(tmp2
);
5437 tcg_temp_free_i32(tmp
);
5439 default: /* 15 is RESERVED: caught earlier */
5444 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5445 neon_store_reg64(cpu_V0
, rd
+ pass
);
5446 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5448 neon_load_reg64(cpu_V1
, rd
+ pass
);
5450 case 10: /* VMLSL */
5451 gen_neon_negl(cpu_V0
, size
);
5453 case 5: case 8: /* VABAL, VMLAL */
5454 gen_neon_addl(size
);
5456 case 9: case 11: /* VQDMLAL, VQDMLSL */
5457 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5459 gen_neon_negl(cpu_V0
, size
);
5461 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5466 neon_store_reg64(cpu_V0
, rd
+ pass
);
5467 } else if (op
== 4 || op
== 6) {
5468 /* Narrowing operation. */
5469 tmp
= tcg_temp_new_i32();
5473 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5476 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5479 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5480 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5487 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5490 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5493 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5494 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5495 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5503 neon_store_reg(rd
, 0, tmp3
);
5504 neon_store_reg(rd
, 1, tmp
);
5507 /* Write back the result. */
5508 neon_store_reg64(cpu_V0
, rd
+ pass
);
5512 /* Two registers and a scalar. NB that for ops of this form
5513 * the ARM ARM labels bit 24 as Q, but it is in our variable
5520 case 1: /* Float VMLA scalar */
5521 case 5: /* Floating point VMLS scalar */
5522 case 9: /* Floating point VMUL scalar */
5527 case 0: /* Integer VMLA scalar */
5528 case 4: /* Integer VMLS scalar */
5529 case 8: /* Integer VMUL scalar */
5530 case 12: /* VQDMULH scalar */
5531 case 13: /* VQRDMULH scalar */
5532 if (u
&& ((rd
| rn
) & 1)) {
5535 tmp
= neon_get_scalar(size
, rm
);
5536 neon_store_scratch(0, tmp
);
5537 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5538 tmp
= neon_load_scratch(0);
5539 tmp2
= neon_load_reg(rn
, pass
);
5542 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5544 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5546 } else if (op
== 13) {
5548 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5550 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5552 } else if (op
& 1) {
5553 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5554 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5555 tcg_temp_free_ptr(fpstatus
);
5558 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5559 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5560 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5564 tcg_temp_free_i32(tmp2
);
5567 tmp2
= neon_load_reg(rd
, pass
);
5570 gen_neon_add(size
, tmp
, tmp2
);
5574 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5575 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5576 tcg_temp_free_ptr(fpstatus
);
5580 gen_neon_rsb(size
, tmp
, tmp2
);
5584 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5585 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5586 tcg_temp_free_ptr(fpstatus
);
5592 tcg_temp_free_i32(tmp2
);
5594 neon_store_reg(rd
, pass
, tmp
);
5597 case 3: /* VQDMLAL scalar */
5598 case 7: /* VQDMLSL scalar */
5599 case 11: /* VQDMULL scalar */
5604 case 2: /* VMLAL sclar */
5605 case 6: /* VMLSL scalar */
5606 case 10: /* VMULL scalar */
5610 tmp2
= neon_get_scalar(size
, rm
);
5611 /* We need a copy of tmp2 because gen_neon_mull
5612 * deletes it during pass 0. */
5613 tmp4
= tcg_temp_new_i32();
5614 tcg_gen_mov_i32(tmp4
, tmp2
);
5615 tmp3
= neon_load_reg(rn
, 1);
5617 for (pass
= 0; pass
< 2; pass
++) {
5619 tmp
= neon_load_reg(rn
, 0);
5624 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5626 neon_load_reg64(cpu_V1
, rd
+ pass
);
5630 gen_neon_negl(cpu_V0
, size
);
5633 gen_neon_addl(size
);
5636 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5638 gen_neon_negl(cpu_V0
, size
);
5640 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5646 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5651 neon_store_reg64(cpu_V0
, rd
+ pass
);
5656 default: /* 14 and 15 are RESERVED */
5660 } else { /* size == 3 */
5663 imm
= (insn
>> 8) & 0xf;
5668 if (q
&& ((rd
| rn
| rm
) & 1)) {
5673 neon_load_reg64(cpu_V0
, rn
);
5675 neon_load_reg64(cpu_V1
, rn
+ 1);
5677 } else if (imm
== 8) {
5678 neon_load_reg64(cpu_V0
, rn
+ 1);
5680 neon_load_reg64(cpu_V1
, rm
);
5683 tmp64
= tcg_temp_new_i64();
5685 neon_load_reg64(cpu_V0
, rn
);
5686 neon_load_reg64(tmp64
, rn
+ 1);
5688 neon_load_reg64(cpu_V0
, rn
+ 1);
5689 neon_load_reg64(tmp64
, rm
);
5691 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5692 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5693 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5695 neon_load_reg64(cpu_V1
, rm
);
5697 neon_load_reg64(cpu_V1
, rm
+ 1);
5700 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5701 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5702 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5703 tcg_temp_free_i64(tmp64
);
5706 neon_load_reg64(cpu_V0
, rn
);
5707 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5708 neon_load_reg64(cpu_V1
, rm
);
5709 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5710 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5712 neon_store_reg64(cpu_V0
, rd
);
5714 neon_store_reg64(cpu_V1
, rd
+ 1);
5716 } else if ((insn
& (1 << 11)) == 0) {
5717 /* Two register misc. */
5718 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5719 size
= (insn
>> 18) & 3;
5720 /* UNDEF for unknown op values and bad op-size combinations */
5721 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5724 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5725 q
&& ((rm
| rd
) & 1)) {
5729 case NEON_2RM_VREV64
:
5730 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5731 tmp
= neon_load_reg(rm
, pass
* 2);
5732 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5734 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5735 case 1: gen_swap_half(tmp
); break;
5736 case 2: /* no-op */ break;
5739 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5741 neon_store_reg(rd
, pass
* 2, tmp2
);
5744 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5745 case 1: gen_swap_half(tmp2
); break;
5748 neon_store_reg(rd
, pass
* 2, tmp2
);
5752 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5753 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5754 for (pass
= 0; pass
< q
+ 1; pass
++) {
5755 tmp
= neon_load_reg(rm
, pass
* 2);
5756 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5757 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5758 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5760 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5761 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5762 case 2: tcg_gen_add_i64(CPU_V001
); break;
5765 if (op
>= NEON_2RM_VPADAL
) {
5767 neon_load_reg64(cpu_V1
, rd
+ pass
);
5768 gen_neon_addl(size
);
5770 neon_store_reg64(cpu_V0
, rd
+ pass
);
5776 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5777 tmp
= neon_load_reg(rm
, n
);
5778 tmp2
= neon_load_reg(rd
, n
+ 1);
5779 neon_store_reg(rm
, n
, tmp2
);
5780 neon_store_reg(rd
, n
+ 1, tmp
);
5787 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5792 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5796 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5797 /* also VQMOVUN; op field and mnemonics don't line up */
5802 for (pass
= 0; pass
< 2; pass
++) {
5803 neon_load_reg64(cpu_V0
, rm
+ pass
);
5804 tmp
= tcg_temp_new_i32();
5805 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5810 neon_store_reg(rd
, 0, tmp2
);
5811 neon_store_reg(rd
, 1, tmp
);
5815 case NEON_2RM_VSHLL
:
5816 if (q
|| (rd
& 1)) {
5819 tmp
= neon_load_reg(rm
, 0);
5820 tmp2
= neon_load_reg(rm
, 1);
5821 for (pass
= 0; pass
< 2; pass
++) {
5824 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5825 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5826 neon_store_reg64(cpu_V0
, rd
+ pass
);
5829 case NEON_2RM_VCVT_F16_F32
:
5830 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5834 tmp
= tcg_temp_new_i32();
5835 tmp2
= tcg_temp_new_i32();
5836 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5837 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5838 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5839 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5840 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5841 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5842 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5843 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5844 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5845 neon_store_reg(rd
, 0, tmp2
);
5846 tmp2
= tcg_temp_new_i32();
5847 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5848 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5849 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5850 neon_store_reg(rd
, 1, tmp2
);
5851 tcg_temp_free_i32(tmp
);
5853 case NEON_2RM_VCVT_F32_F16
:
5854 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5858 tmp3
= tcg_temp_new_i32();
5859 tmp
= neon_load_reg(rm
, 0);
5860 tmp2
= neon_load_reg(rm
, 1);
5861 tcg_gen_ext16u_i32(tmp3
, tmp
);
5862 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5863 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5864 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5865 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5866 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5867 tcg_temp_free_i32(tmp
);
5868 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5869 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5870 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5871 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5872 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5873 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5874 tcg_temp_free_i32(tmp2
);
5875 tcg_temp_free_i32(tmp3
);
5879 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5880 if (neon_2rm_is_float_op(op
)) {
5881 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5882 neon_reg_offset(rm
, pass
));
5885 tmp
= neon_load_reg(rm
, pass
);
5888 case NEON_2RM_VREV32
:
5890 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5891 case 1: gen_swap_half(tmp
); break;
5895 case NEON_2RM_VREV16
:
5900 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5901 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5902 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5908 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5909 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5910 case 2: gen_helper_clz(tmp
, tmp
); break;
5915 gen_helper_neon_cnt_u8(tmp
, tmp
);
5918 tcg_gen_not_i32(tmp
, tmp
);
5920 case NEON_2RM_VQABS
:
5923 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
5926 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
5929 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
5934 case NEON_2RM_VQNEG
:
5937 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
5940 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
5943 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
5948 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
5949 tmp2
= tcg_const_i32(0);
5951 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5952 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5953 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5956 tcg_temp_free(tmp2
);
5957 if (op
== NEON_2RM_VCLE0
) {
5958 tcg_gen_not_i32(tmp
, tmp
);
5961 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
5962 tmp2
= tcg_const_i32(0);
5964 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5965 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5966 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5969 tcg_temp_free(tmp2
);
5970 if (op
== NEON_2RM_VCLT0
) {
5971 tcg_gen_not_i32(tmp
, tmp
);
5974 case NEON_2RM_VCEQ0
:
5975 tmp2
= tcg_const_i32(0);
5977 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5978 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5979 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5982 tcg_temp_free(tmp2
);
5986 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
5987 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
5988 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
5993 tmp2
= tcg_const_i32(0);
5994 gen_neon_rsb(size
, tmp
, tmp2
);
5995 tcg_temp_free(tmp2
);
5997 case NEON_2RM_VCGT0_F
:
5999 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6000 tmp2
= tcg_const_i32(0);
6001 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6002 tcg_temp_free(tmp2
);
6003 tcg_temp_free_ptr(fpstatus
);
6006 case NEON_2RM_VCGE0_F
:
6008 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6009 tmp2
= tcg_const_i32(0);
6010 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6011 tcg_temp_free(tmp2
);
6012 tcg_temp_free_ptr(fpstatus
);
6015 case NEON_2RM_VCEQ0_F
:
6017 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6018 tmp2
= tcg_const_i32(0);
6019 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6020 tcg_temp_free(tmp2
);
6021 tcg_temp_free_ptr(fpstatus
);
6024 case NEON_2RM_VCLE0_F
:
6026 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6027 tmp2
= tcg_const_i32(0);
6028 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6029 tcg_temp_free(tmp2
);
6030 tcg_temp_free_ptr(fpstatus
);
6033 case NEON_2RM_VCLT0_F
:
6035 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6036 tmp2
= tcg_const_i32(0);
6037 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6038 tcg_temp_free(tmp2
);
6039 tcg_temp_free_ptr(fpstatus
);
6042 case NEON_2RM_VABS_F
:
6045 case NEON_2RM_VNEG_F
:
6049 tmp2
= neon_load_reg(rd
, pass
);
6050 neon_store_reg(rm
, pass
, tmp2
);
6053 tmp2
= neon_load_reg(rd
, pass
);
6055 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6056 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6059 neon_store_reg(rm
, pass
, tmp2
);
6061 case NEON_2RM_VRECPE
:
6062 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6064 case NEON_2RM_VRSQRTE
:
6065 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6067 case NEON_2RM_VRECPE_F
:
6068 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6070 case NEON_2RM_VRSQRTE_F
:
6071 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6073 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6076 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6079 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6080 gen_vfp_tosiz(0, 1);
6082 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6083 gen_vfp_touiz(0, 1);
6086 /* Reserved op values were caught by the
6087 * neon_2rm_sizes[] check earlier.
6091 if (neon_2rm_is_float_op(op
)) {
6092 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6093 neon_reg_offset(rd
, pass
));
6095 neon_store_reg(rd
, pass
, tmp
);
6100 } else if ((insn
& (1 << 10)) == 0) {
6102 int n
= ((insn
>> 8) & 3) + 1;
6103 if ((rn
+ n
) > 32) {
6104 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6105 * helper function running off the end of the register file.
6110 if (insn
& (1 << 6)) {
6111 tmp
= neon_load_reg(rd
, 0);
6113 tmp
= tcg_temp_new_i32();
6114 tcg_gen_movi_i32(tmp
, 0);
6116 tmp2
= neon_load_reg(rm
, 0);
6117 tmp4
= tcg_const_i32(rn
);
6118 tmp5
= tcg_const_i32(n
);
6119 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6120 tcg_temp_free_i32(tmp
);
6121 if (insn
& (1 << 6)) {
6122 tmp
= neon_load_reg(rd
, 1);
6124 tmp
= tcg_temp_new_i32();
6125 tcg_gen_movi_i32(tmp
, 0);
6127 tmp3
= neon_load_reg(rm
, 1);
6128 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6129 tcg_temp_free_i32(tmp5
);
6130 tcg_temp_free_i32(tmp4
);
6131 neon_store_reg(rd
, 0, tmp2
);
6132 neon_store_reg(rd
, 1, tmp3
);
6133 tcg_temp_free_i32(tmp
);
6134 } else if ((insn
& 0x380) == 0) {
6136 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6139 if (insn
& (1 << 19)) {
6140 tmp
= neon_load_reg(rm
, 1);
6142 tmp
= neon_load_reg(rm
, 0);
6144 if (insn
& (1 << 16)) {
6145 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6146 } else if (insn
& (1 << 17)) {
6147 if ((insn
>> 18) & 1)
6148 gen_neon_dup_high16(tmp
);
6150 gen_neon_dup_low16(tmp
);
6152 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6153 tmp2
= tcg_temp_new_i32();
6154 tcg_gen_mov_i32(tmp2
, tmp
);
6155 neon_store_reg(rd
, pass
, tmp2
);
6157 tcg_temp_free_i32(tmp
);
6166 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6168 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6169 const ARMCPRegInfo
*ri
;
6170 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6172 cpnum
= (insn
>> 8) & 0xf;
6173 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6174 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6177 /* First check for coprocessor space used for actual instructions */
6181 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6182 return disas_iwmmxt_insn(env
, s
, insn
);
6183 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6184 return disas_dsp_insn(env
, s
, insn
);
6189 return disas_vfp_insn (env
, s
, insn
);
6194 /* Otherwise treat as a generic register access */
6195 is64
= (insn
& (1 << 25)) == 0;
6196 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6204 opc1
= (insn
>> 4) & 0xf;
6206 rt2
= (insn
>> 16) & 0xf;
6208 crn
= (insn
>> 16) & 0xf;
6209 opc1
= (insn
>> 21) & 7;
6210 opc2
= (insn
>> 5) & 7;
6213 isread
= (insn
>> 20) & 1;
6214 rt
= (insn
>> 12) & 0xf;
6216 ri
= get_arm_cp_reginfo(cpu
,
6217 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6219 /* Check access permissions */
6220 if (!cp_access_ok(env
, ri
, isread
)) {
6224 /* Handle special cases first */
6225 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6232 gen_set_pc_im(s
->pc
);
6233 s
->is_jmp
= DISAS_WFI
;
6244 if (ri
->type
& ARM_CP_CONST
) {
6245 tmp64
= tcg_const_i64(ri
->resetvalue
);
6246 } else if (ri
->readfn
) {
6248 gen_set_pc_im(s
->pc
);
6249 tmp64
= tcg_temp_new_i64();
6250 tmpptr
= tcg_const_ptr(ri
);
6251 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6252 tcg_temp_free_ptr(tmpptr
);
6254 tmp64
= tcg_temp_new_i64();
6255 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6257 tmp
= tcg_temp_new_i32();
6258 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6259 store_reg(s
, rt
, tmp
);
6260 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6261 tmp
= tcg_temp_new_i32();
6262 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6263 tcg_temp_free_i64(tmp64
);
6264 store_reg(s
, rt2
, tmp
);
6267 if (ri
->type
& ARM_CP_CONST
) {
6268 tmp
= tcg_const_i32(ri
->resetvalue
);
6269 } else if (ri
->readfn
) {
6271 gen_set_pc_im(s
->pc
);
6272 tmp
= tcg_temp_new_i32();
6273 tmpptr
= tcg_const_ptr(ri
);
6274 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6275 tcg_temp_free_ptr(tmpptr
);
6277 tmp
= load_cpu_offset(ri
->fieldoffset
);
6280 /* Destination register of r15 for 32 bit loads sets
6281 * the condition codes from the high 4 bits of the value
6284 tcg_temp_free_i32(tmp
);
6286 store_reg(s
, rt
, tmp
);
6291 if (ri
->type
& ARM_CP_CONST
) {
6292 /* If not forbidden by access permissions, treat as WI */
6298 TCGv_i64 tmp64
= tcg_temp_new_i64();
6299 tmplo
= load_reg(s
, rt
);
6300 tmphi
= load_reg(s
, rt2
);
6301 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6302 tcg_temp_free_i32(tmplo
);
6303 tcg_temp_free_i32(tmphi
);
6305 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6306 gen_set_pc_im(s
->pc
);
6307 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6308 tcg_temp_free_ptr(tmpptr
);
6310 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6312 tcg_temp_free_i64(tmp64
);
6317 gen_set_pc_im(s
->pc
);
6318 tmp
= load_reg(s
, rt
);
6319 tmpptr
= tcg_const_ptr(ri
);
6320 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6321 tcg_temp_free_ptr(tmpptr
);
6322 tcg_temp_free_i32(tmp
);
6324 TCGv tmp
= load_reg(s
, rt
);
6325 store_cpu_offset(tmp
, ri
->fieldoffset
);
6328 /* We default to ending the TB on a coprocessor register write,
6329 * but allow this to be suppressed by the register definition
6330 * (usually only necessary to work around guest bugs).
6332 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6343 /* Store a 64-bit value to a register pair. Clobbers val. */
6344 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6347 tmp
= tcg_temp_new_i32();
6348 tcg_gen_trunc_i64_i32(tmp
, val
);
6349 store_reg(s
, rlow
, tmp
);
6350 tmp
= tcg_temp_new_i32();
6351 tcg_gen_shri_i64(val
, val
, 32);
6352 tcg_gen_trunc_i64_i32(tmp
, val
);
6353 store_reg(s
, rhigh
, tmp
);
6356 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6357 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6362 /* Load value and extend to 64 bits. */
6363 tmp
= tcg_temp_new_i64();
6364 tmp2
= load_reg(s
, rlow
);
6365 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6366 tcg_temp_free_i32(tmp2
);
6367 tcg_gen_add_i64(val
, val
, tmp
);
6368 tcg_temp_free_i64(tmp
);
6371 /* load and add a 64-bit value from a register pair. */
6372 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6378 /* Load 64-bit value rd:rn. */
6379 tmpl
= load_reg(s
, rlow
);
6380 tmph
= load_reg(s
, rhigh
);
6381 tmp
= tcg_temp_new_i64();
6382 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6383 tcg_temp_free_i32(tmpl
);
6384 tcg_temp_free_i32(tmph
);
6385 tcg_gen_add_i64(val
, val
, tmp
);
6386 tcg_temp_free_i64(tmp
);
6389 /* Set N and Z flags from a 64-bit value. */
6390 static void gen_logicq_cc(TCGv_i64 val
)
6392 TCGv tmp
= tcg_temp_new_i32();
6393 gen_helper_logicq_cc(tmp
, val
);
6395 tcg_temp_free_i32(tmp
);
6398 /* Load/Store exclusive instructions are implemented by remembering
6399 the value/address loaded, and seeing if these are the same
6400 when the store is performed. This should be sufficient to implement
6401 the architecturally mandated semantics, and avoids having to monitor
6404 In system emulation mode only one CPU will be running at once, so
6405 this sequence is effectively atomic. In user emulation mode we
6406 throw an exception and handle the atomic operation elsewhere. */
6407 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6408 TCGv addr
, int size
)
6414 tmp
= gen_ld8u(addr
, IS_USER(s
));
6417 tmp
= gen_ld16u(addr
, IS_USER(s
));
6421 tmp
= gen_ld32(addr
, IS_USER(s
));
6426 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6427 store_reg(s
, rt
, tmp
);
6429 TCGv tmp2
= tcg_temp_new_i32();
6430 tcg_gen_addi_i32(tmp2
, addr
, 4);
6431 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6432 tcg_temp_free_i32(tmp2
);
6433 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6434 store_reg(s
, rt2
, tmp
);
6436 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6439 static void gen_clrex(DisasContext
*s
)
6441 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6444 #ifdef CONFIG_USER_ONLY
6445 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6446 TCGv addr
, int size
)
6448 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6449 tcg_gen_movi_i32(cpu_exclusive_info
,
6450 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6451 gen_exception_insn(s
, 4, EXCP_STREX
);
6454 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6455 TCGv addr
, int size
)
6461 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6467 fail_label
= gen_new_label();
6468 done_label
= gen_new_label();
6469 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6472 tmp
= gen_ld8u(addr
, IS_USER(s
));
6475 tmp
= gen_ld16u(addr
, IS_USER(s
));
6479 tmp
= gen_ld32(addr
, IS_USER(s
));
6484 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6485 tcg_temp_free_i32(tmp
);
6487 TCGv tmp2
= tcg_temp_new_i32();
6488 tcg_gen_addi_i32(tmp2
, addr
, 4);
6489 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6490 tcg_temp_free_i32(tmp2
);
6491 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6492 tcg_temp_free_i32(tmp
);
6494 tmp
= load_reg(s
, rt
);
6497 gen_st8(tmp
, addr
, IS_USER(s
));
6500 gen_st16(tmp
, addr
, IS_USER(s
));
6504 gen_st32(tmp
, addr
, IS_USER(s
));
6510 tcg_gen_addi_i32(addr
, addr
, 4);
6511 tmp
= load_reg(s
, rt2
);
6512 gen_st32(tmp
, addr
, IS_USER(s
));
6514 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6515 tcg_gen_br(done_label
);
6516 gen_set_label(fail_label
);
6517 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6518 gen_set_label(done_label
);
6519 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6523 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6525 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6532 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6535 /* M variants do not implement ARM mode. */
6540 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6541 * choose to UNDEF. In ARMv5 and above the space is used
6542 * for miscellaneous unconditional instructions.
6546 /* Unconditional instructions. */
6547 if (((insn
>> 25) & 7) == 1) {
6548 /* NEON Data processing. */
6549 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6552 if (disas_neon_data_insn(env
, s
, insn
))
6556 if ((insn
& 0x0f100000) == 0x04000000) {
6557 /* NEON load/store. */
6558 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6561 if (disas_neon_ls_insn(env
, s
, insn
))
6565 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6566 ((insn
& 0x0f30f010) == 0x0710f000)) {
6567 if ((insn
& (1 << 22)) == 0) {
6569 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6573 /* Otherwise PLD; v5TE+ */
6577 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6578 ((insn
& 0x0f70f010) == 0x0650f000)) {
6580 return; /* PLI; V7 */
6582 if (((insn
& 0x0f700000) == 0x04100000) ||
6583 ((insn
& 0x0f700010) == 0x06100000)) {
6584 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6587 return; /* v7MP: Unallocated memory hint: must NOP */
6590 if ((insn
& 0x0ffffdff) == 0x01010000) {
6593 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6594 /* Dynamic endianness switching not implemented. */
6598 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6599 switch ((insn
>> 4) & 0xf) {
6608 /* We don't emulate caches so these are a no-op. */
6613 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6619 op1
= (insn
& 0x1f);
6620 addr
= tcg_temp_new_i32();
6621 tmp
= tcg_const_i32(op1
);
6622 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6623 tcg_temp_free_i32(tmp
);
6624 i
= (insn
>> 23) & 3;
6626 case 0: offset
= -4; break; /* DA */
6627 case 1: offset
= 0; break; /* IA */
6628 case 2: offset
= -8; break; /* DB */
6629 case 3: offset
= 4; break; /* IB */
6633 tcg_gen_addi_i32(addr
, addr
, offset
);
6634 tmp
= load_reg(s
, 14);
6635 gen_st32(tmp
, addr
, 0);
6636 tmp
= load_cpu_field(spsr
);
6637 tcg_gen_addi_i32(addr
, addr
, 4);
6638 gen_st32(tmp
, addr
, 0);
6639 if (insn
& (1 << 21)) {
6640 /* Base writeback. */
6642 case 0: offset
= -8; break;
6643 case 1: offset
= 4; break;
6644 case 2: offset
= -4; break;
6645 case 3: offset
= 0; break;
6649 tcg_gen_addi_i32(addr
, addr
, offset
);
6650 tmp
= tcg_const_i32(op1
);
6651 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6652 tcg_temp_free_i32(tmp
);
6653 tcg_temp_free_i32(addr
);
6655 tcg_temp_free_i32(addr
);
6658 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6664 rn
= (insn
>> 16) & 0xf;
6665 addr
= load_reg(s
, rn
);
6666 i
= (insn
>> 23) & 3;
6668 case 0: offset
= -4; break; /* DA */
6669 case 1: offset
= 0; break; /* IA */
6670 case 2: offset
= -8; break; /* DB */
6671 case 3: offset
= 4; break; /* IB */
6675 tcg_gen_addi_i32(addr
, addr
, offset
);
6676 /* Load PC into tmp and CPSR into tmp2. */
6677 tmp
= gen_ld32(addr
, 0);
6678 tcg_gen_addi_i32(addr
, addr
, 4);
6679 tmp2
= gen_ld32(addr
, 0);
6680 if (insn
& (1 << 21)) {
6681 /* Base writeback. */
6683 case 0: offset
= -8; break;
6684 case 1: offset
= 4; break;
6685 case 2: offset
= -4; break;
6686 case 3: offset
= 0; break;
6690 tcg_gen_addi_i32(addr
, addr
, offset
);
6691 store_reg(s
, rn
, addr
);
6693 tcg_temp_free_i32(addr
);
6695 gen_rfe(s
, tmp
, tmp2
);
6697 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6698 /* branch link and change to thumb (blx <offset>) */
6701 val
= (uint32_t)s
->pc
;
6702 tmp
= tcg_temp_new_i32();
6703 tcg_gen_movi_i32(tmp
, val
);
6704 store_reg(s
, 14, tmp
);
6705 /* Sign-extend the 24-bit offset */
6706 offset
= (((int32_t)insn
) << 8) >> 8;
6707 /* offset * 4 + bit24 * 2 + (thumb bit) */
6708 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6709 /* pipeline offset */
6711 /* protected by ARCH(5); above, near the start of uncond block */
6714 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6715 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6716 /* iWMMXt register transfer. */
6717 if (env
->cp15
.c15_cpar
& (1 << 1))
6718 if (!disas_iwmmxt_insn(env
, s
, insn
))
6721 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6722 /* Coprocessor double register transfer. */
6724 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6725 /* Additional coprocessor register transfer. */
6726 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6729 /* cps (privileged) */
6733 if (insn
& (1 << 19)) {
6734 if (insn
& (1 << 8))
6736 if (insn
& (1 << 7))
6738 if (insn
& (1 << 6))
6740 if (insn
& (1 << 18))
6743 if (insn
& (1 << 17)) {
6745 val
|= (insn
& 0x1f);
6748 gen_set_psr_im(s
, mask
, 0, val
);
6755 /* if not always execute, we generate a conditional jump to
6757 s
->condlabel
= gen_new_label();
6758 gen_test_cc(cond
^ 1, s
->condlabel
);
6761 if ((insn
& 0x0f900000) == 0x03000000) {
6762 if ((insn
& (1 << 21)) == 0) {
6764 rd
= (insn
>> 12) & 0xf;
6765 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6766 if ((insn
& (1 << 22)) == 0) {
6768 tmp
= tcg_temp_new_i32();
6769 tcg_gen_movi_i32(tmp
, val
);
6772 tmp
= load_reg(s
, rd
);
6773 tcg_gen_ext16u_i32(tmp
, tmp
);
6774 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6776 store_reg(s
, rd
, tmp
);
6778 if (((insn
>> 12) & 0xf) != 0xf)
6780 if (((insn
>> 16) & 0xf) == 0) {
6781 gen_nop_hint(s
, insn
& 0xff);
6783 /* CPSR = immediate */
6785 shift
= ((insn
>> 8) & 0xf) * 2;
6787 val
= (val
>> shift
) | (val
<< (32 - shift
));
6788 i
= ((insn
& (1 << 22)) != 0);
6789 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6793 } else if ((insn
& 0x0f900000) == 0x01000000
6794 && (insn
& 0x00000090) != 0x00000090) {
6795 /* miscellaneous instructions */
6796 op1
= (insn
>> 21) & 3;
6797 sh
= (insn
>> 4) & 0xf;
6800 case 0x0: /* move program status register */
6803 tmp
= load_reg(s
, rm
);
6804 i
= ((op1
& 2) != 0);
6805 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6809 rd
= (insn
>> 12) & 0xf;
6813 tmp
= load_cpu_field(spsr
);
6815 tmp
= tcg_temp_new_i32();
6816 gen_helper_cpsr_read(tmp
, cpu_env
);
6818 store_reg(s
, rd
, tmp
);
6823 /* branch/exchange thumb (bx). */
6825 tmp
= load_reg(s
, rm
);
6827 } else if (op1
== 3) {
6830 rd
= (insn
>> 12) & 0xf;
6831 tmp
= load_reg(s
, rm
);
6832 gen_helper_clz(tmp
, tmp
);
6833 store_reg(s
, rd
, tmp
);
6841 /* Trivial implementation equivalent to bx. */
6842 tmp
= load_reg(s
, rm
);
6853 /* branch link/exchange thumb (blx) */
6854 tmp
= load_reg(s
, rm
);
6855 tmp2
= tcg_temp_new_i32();
6856 tcg_gen_movi_i32(tmp2
, s
->pc
);
6857 store_reg(s
, 14, tmp2
);
6860 case 0x5: /* saturating add/subtract */
6862 rd
= (insn
>> 12) & 0xf;
6863 rn
= (insn
>> 16) & 0xf;
6864 tmp
= load_reg(s
, rm
);
6865 tmp2
= load_reg(s
, rn
);
6867 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6869 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6871 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6872 tcg_temp_free_i32(tmp2
);
6873 store_reg(s
, rd
, tmp
);
6876 /* SMC instruction (op1 == 3)
6877 and undefined instructions (op1 == 0 || op1 == 2)
6884 gen_exception_insn(s
, 4, EXCP_BKPT
);
6886 case 0x8: /* signed multiply */
6891 rs
= (insn
>> 8) & 0xf;
6892 rn
= (insn
>> 12) & 0xf;
6893 rd
= (insn
>> 16) & 0xf;
6895 /* (32 * 16) >> 16 */
6896 tmp
= load_reg(s
, rm
);
6897 tmp2
= load_reg(s
, rs
);
6899 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6902 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6903 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6904 tmp
= tcg_temp_new_i32();
6905 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6906 tcg_temp_free_i64(tmp64
);
6907 if ((sh
& 2) == 0) {
6908 tmp2
= load_reg(s
, rn
);
6909 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6910 tcg_temp_free_i32(tmp2
);
6912 store_reg(s
, rd
, tmp
);
6915 tmp
= load_reg(s
, rm
);
6916 tmp2
= load_reg(s
, rs
);
6917 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6918 tcg_temp_free_i32(tmp2
);
6920 tmp64
= tcg_temp_new_i64();
6921 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6922 tcg_temp_free_i32(tmp
);
6923 gen_addq(s
, tmp64
, rn
, rd
);
6924 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6925 tcg_temp_free_i64(tmp64
);
6928 tmp2
= load_reg(s
, rn
);
6929 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6930 tcg_temp_free_i32(tmp2
);
6932 store_reg(s
, rd
, tmp
);
6939 } else if (((insn
& 0x0e000000) == 0 &&
6940 (insn
& 0x00000090) != 0x90) ||
6941 ((insn
& 0x0e000000) == (1 << 25))) {
6942 int set_cc
, logic_cc
, shiftop
;
6944 op1
= (insn
>> 21) & 0xf;
6945 set_cc
= (insn
>> 20) & 1;
6946 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6948 /* data processing instruction */
6949 if (insn
& (1 << 25)) {
6950 /* immediate operand */
6952 shift
= ((insn
>> 8) & 0xf) * 2;
6954 val
= (val
>> shift
) | (val
<< (32 - shift
));
6956 tmp2
= tcg_temp_new_i32();
6957 tcg_gen_movi_i32(tmp2
, val
);
6958 if (logic_cc
&& shift
) {
6959 gen_set_CF_bit31(tmp2
);
6964 tmp2
= load_reg(s
, rm
);
6965 shiftop
= (insn
>> 5) & 3;
6966 if (!(insn
& (1 << 4))) {
6967 shift
= (insn
>> 7) & 0x1f;
6968 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6970 rs
= (insn
>> 8) & 0xf;
6971 tmp
= load_reg(s
, rs
);
6972 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6975 if (op1
!= 0x0f && op1
!= 0x0d) {
6976 rn
= (insn
>> 16) & 0xf;
6977 tmp
= load_reg(s
, rn
);
6981 rd
= (insn
>> 12) & 0xf;
6984 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6988 store_reg_bx(env
, s
, rd
, tmp
);
6991 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6995 store_reg_bx(env
, s
, rd
, tmp
);
6998 if (set_cc
&& rd
== 15) {
6999 /* SUBS r15, ... is used for exception return. */
7003 gen_sub_CC(tmp
, tmp
, tmp2
);
7004 gen_exception_return(s
, tmp
);
7007 gen_sub_CC(tmp
, tmp
, tmp2
);
7009 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7011 store_reg_bx(env
, s
, rd
, tmp
);
7016 gen_sub_CC(tmp
, tmp2
, tmp
);
7018 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7020 store_reg_bx(env
, s
, rd
, tmp
);
7024 gen_add_CC(tmp
, tmp
, tmp2
);
7026 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7028 store_reg_bx(env
, s
, rd
, tmp
);
7032 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7034 gen_add_carry(tmp
, tmp
, tmp2
);
7036 store_reg_bx(env
, s
, rd
, tmp
);
7040 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7042 gen_sub_carry(tmp
, tmp
, tmp2
);
7044 store_reg_bx(env
, s
, rd
, tmp
);
7048 gen_helper_sbc_cc(tmp
, cpu_env
, tmp2
, tmp
);
7050 gen_sub_carry(tmp
, tmp2
, tmp
);
7052 store_reg_bx(env
, s
, rd
, tmp
);
7056 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7059 tcg_temp_free_i32(tmp
);
7063 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7066 tcg_temp_free_i32(tmp
);
7070 gen_sub_CC(tmp
, tmp
, tmp2
);
7072 tcg_temp_free_i32(tmp
);
7076 gen_add_CC(tmp
, tmp
, tmp2
);
7078 tcg_temp_free_i32(tmp
);
7081 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7085 store_reg_bx(env
, s
, rd
, tmp
);
7088 if (logic_cc
&& rd
== 15) {
7089 /* MOVS r15, ... is used for exception return. */
7093 gen_exception_return(s
, tmp2
);
7098 store_reg_bx(env
, s
, rd
, tmp2
);
7102 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7106 store_reg_bx(env
, s
, rd
, tmp
);
7110 tcg_gen_not_i32(tmp2
, tmp2
);
7114 store_reg_bx(env
, s
, rd
, tmp2
);
7117 if (op1
!= 0x0f && op1
!= 0x0d) {
7118 tcg_temp_free_i32(tmp2
);
7121 /* other instructions */
7122 op1
= (insn
>> 24) & 0xf;
7126 /* multiplies, extra load/stores */
7127 sh
= (insn
>> 5) & 3;
7130 rd
= (insn
>> 16) & 0xf;
7131 rn
= (insn
>> 12) & 0xf;
7132 rs
= (insn
>> 8) & 0xf;
7134 op1
= (insn
>> 20) & 0xf;
7136 case 0: case 1: case 2: case 3: case 6:
7138 tmp
= load_reg(s
, rs
);
7139 tmp2
= load_reg(s
, rm
);
7140 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7141 tcg_temp_free_i32(tmp2
);
7142 if (insn
& (1 << 22)) {
7143 /* Subtract (mls) */
7145 tmp2
= load_reg(s
, rn
);
7146 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7147 tcg_temp_free_i32(tmp2
);
7148 } else if (insn
& (1 << 21)) {
7150 tmp2
= load_reg(s
, rn
);
7151 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7152 tcg_temp_free_i32(tmp2
);
7154 if (insn
& (1 << 20))
7156 store_reg(s
, rd
, tmp
);
7159 /* 64 bit mul double accumulate (UMAAL) */
7161 tmp
= load_reg(s
, rs
);
7162 tmp2
= load_reg(s
, rm
);
7163 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7164 gen_addq_lo(s
, tmp64
, rn
);
7165 gen_addq_lo(s
, tmp64
, rd
);
7166 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7167 tcg_temp_free_i64(tmp64
);
7169 case 8: case 9: case 10: case 11:
7170 case 12: case 13: case 14: case 15:
7171 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7172 tmp
= load_reg(s
, rs
);
7173 tmp2
= load_reg(s
, rm
);
7174 if (insn
& (1 << 22)) {
7175 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7177 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7179 if (insn
& (1 << 21)) { /* mult accumulate */
7180 gen_addq(s
, tmp64
, rn
, rd
);
7182 if (insn
& (1 << 20)) {
7183 gen_logicq_cc(tmp64
);
7185 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7186 tcg_temp_free_i64(tmp64
);
7192 rn
= (insn
>> 16) & 0xf;
7193 rd
= (insn
>> 12) & 0xf;
7194 if (insn
& (1 << 23)) {
7195 /* load/store exclusive */
7196 op1
= (insn
>> 21) & 0x3;
7201 addr
= tcg_temp_local_new_i32();
7202 load_reg_var(s
, addr
, rn
);
7203 if (insn
& (1 << 20)) {
7206 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7208 case 1: /* ldrexd */
7209 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7211 case 2: /* ldrexb */
7212 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7214 case 3: /* ldrexh */
7215 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7224 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7226 case 1: /* strexd */
7227 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7229 case 2: /* strexb */
7230 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7232 case 3: /* strexh */
7233 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7239 tcg_temp_free(addr
);
7241 /* SWP instruction */
7244 /* ??? This is not really atomic. However we know
7245 we never have multiple CPUs running in parallel,
7246 so it is good enough. */
7247 addr
= load_reg(s
, rn
);
7248 tmp
= load_reg(s
, rm
);
7249 if (insn
& (1 << 22)) {
7250 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7251 gen_st8(tmp
, addr
, IS_USER(s
));
7253 tmp2
= gen_ld32(addr
, IS_USER(s
));
7254 gen_st32(tmp
, addr
, IS_USER(s
));
7256 tcg_temp_free_i32(addr
);
7257 store_reg(s
, rd
, tmp2
);
7263 /* Misc load/store */
7264 rn
= (insn
>> 16) & 0xf;
7265 rd
= (insn
>> 12) & 0xf;
7266 addr
= load_reg(s
, rn
);
7267 if (insn
& (1 << 24))
7268 gen_add_datah_offset(s
, insn
, 0, addr
);
7270 if (insn
& (1 << 20)) {
7274 tmp
= gen_ld16u(addr
, IS_USER(s
));
7277 tmp
= gen_ld8s(addr
, IS_USER(s
));
7281 tmp
= gen_ld16s(addr
, IS_USER(s
));
7285 } else if (sh
& 2) {
7290 tmp
= load_reg(s
, rd
);
7291 gen_st32(tmp
, addr
, IS_USER(s
));
7292 tcg_gen_addi_i32(addr
, addr
, 4);
7293 tmp
= load_reg(s
, rd
+ 1);
7294 gen_st32(tmp
, addr
, IS_USER(s
));
7298 tmp
= gen_ld32(addr
, IS_USER(s
));
7299 store_reg(s
, rd
, tmp
);
7300 tcg_gen_addi_i32(addr
, addr
, 4);
7301 tmp
= gen_ld32(addr
, IS_USER(s
));
7305 address_offset
= -4;
7308 tmp
= load_reg(s
, rd
);
7309 gen_st16(tmp
, addr
, IS_USER(s
));
7312 /* Perform base writeback before the loaded value to
7313 ensure correct behavior with overlapping index registers.
7314 ldrd with base writeback is is undefined if the
7315 destination and index registers overlap. */
7316 if (!(insn
& (1 << 24))) {
7317 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7318 store_reg(s
, rn
, addr
);
7319 } else if (insn
& (1 << 21)) {
7321 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7322 store_reg(s
, rn
, addr
);
7324 tcg_temp_free_i32(addr
);
7327 /* Complete the load. */
7328 store_reg(s
, rd
, tmp
);
7337 if (insn
& (1 << 4)) {
7339 /* Armv6 Media instructions. */
7341 rn
= (insn
>> 16) & 0xf;
7342 rd
= (insn
>> 12) & 0xf;
7343 rs
= (insn
>> 8) & 0xf;
7344 switch ((insn
>> 23) & 3) {
7345 case 0: /* Parallel add/subtract. */
7346 op1
= (insn
>> 20) & 7;
7347 tmp
= load_reg(s
, rn
);
7348 tmp2
= load_reg(s
, rm
);
7349 sh
= (insn
>> 5) & 7;
7350 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7352 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7353 tcg_temp_free_i32(tmp2
);
7354 store_reg(s
, rd
, tmp
);
7357 if ((insn
& 0x00700020) == 0) {
7358 /* Halfword pack. */
7359 tmp
= load_reg(s
, rn
);
7360 tmp2
= load_reg(s
, rm
);
7361 shift
= (insn
>> 7) & 0x1f;
7362 if (insn
& (1 << 6)) {
7366 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7367 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7368 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7372 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7373 tcg_gen_ext16u_i32(tmp
, tmp
);
7374 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7376 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7377 tcg_temp_free_i32(tmp2
);
7378 store_reg(s
, rd
, tmp
);
7379 } else if ((insn
& 0x00200020) == 0x00200000) {
7381 tmp
= load_reg(s
, rm
);
7382 shift
= (insn
>> 7) & 0x1f;
7383 if (insn
& (1 << 6)) {
7386 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7388 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7390 sh
= (insn
>> 16) & 0x1f;
7391 tmp2
= tcg_const_i32(sh
);
7392 if (insn
& (1 << 22))
7393 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7395 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7396 tcg_temp_free_i32(tmp2
);
7397 store_reg(s
, rd
, tmp
);
7398 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7400 tmp
= load_reg(s
, rm
);
7401 sh
= (insn
>> 16) & 0x1f;
7402 tmp2
= tcg_const_i32(sh
);
7403 if (insn
& (1 << 22))
7404 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7406 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7407 tcg_temp_free_i32(tmp2
);
7408 store_reg(s
, rd
, tmp
);
7409 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7411 tmp
= load_reg(s
, rn
);
7412 tmp2
= load_reg(s
, rm
);
7413 tmp3
= tcg_temp_new_i32();
7414 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7415 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7416 tcg_temp_free_i32(tmp3
);
7417 tcg_temp_free_i32(tmp2
);
7418 store_reg(s
, rd
, tmp
);
7419 } else if ((insn
& 0x000003e0) == 0x00000060) {
7420 tmp
= load_reg(s
, rm
);
7421 shift
= (insn
>> 10) & 3;
7422 /* ??? In many cases it's not necessary to do a
7423 rotate, a shift is sufficient. */
7425 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7426 op1
= (insn
>> 20) & 7;
7428 case 0: gen_sxtb16(tmp
); break;
7429 case 2: gen_sxtb(tmp
); break;
7430 case 3: gen_sxth(tmp
); break;
7431 case 4: gen_uxtb16(tmp
); break;
7432 case 6: gen_uxtb(tmp
); break;
7433 case 7: gen_uxth(tmp
); break;
7434 default: goto illegal_op
;
7437 tmp2
= load_reg(s
, rn
);
7438 if ((op1
& 3) == 0) {
7439 gen_add16(tmp
, tmp2
);
7441 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7442 tcg_temp_free_i32(tmp2
);
7445 store_reg(s
, rd
, tmp
);
7446 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7448 tmp
= load_reg(s
, rm
);
7449 if (insn
& (1 << 22)) {
7450 if (insn
& (1 << 7)) {
7454 gen_helper_rbit(tmp
, tmp
);
7457 if (insn
& (1 << 7))
7460 tcg_gen_bswap32_i32(tmp
, tmp
);
7462 store_reg(s
, rd
, tmp
);
7467 case 2: /* Multiplies (Type 3). */
7468 switch ((insn
>> 20) & 0x7) {
7470 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7471 /* op2 not 00x or 11x : UNDEF */
7474 /* Signed multiply most significant [accumulate].
7475 (SMMUL, SMMLA, SMMLS) */
7476 tmp
= load_reg(s
, rm
);
7477 tmp2
= load_reg(s
, rs
);
7478 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7481 tmp
= load_reg(s
, rd
);
7482 if (insn
& (1 << 6)) {
7483 tmp64
= gen_subq_msw(tmp64
, tmp
);
7485 tmp64
= gen_addq_msw(tmp64
, tmp
);
7488 if (insn
& (1 << 5)) {
7489 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7491 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7492 tmp
= tcg_temp_new_i32();
7493 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7494 tcg_temp_free_i64(tmp64
);
7495 store_reg(s
, rn
, tmp
);
7499 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7500 if (insn
& (1 << 7)) {
7503 tmp
= load_reg(s
, rm
);
7504 tmp2
= load_reg(s
, rs
);
7505 if (insn
& (1 << 5))
7506 gen_swap_half(tmp2
);
7507 gen_smul_dual(tmp
, tmp2
);
7508 if (insn
& (1 << 6)) {
7509 /* This subtraction cannot overflow. */
7510 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7512 /* This addition cannot overflow 32 bits;
7513 * however it may overflow considered as a signed
7514 * operation, in which case we must set the Q flag.
7516 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7518 tcg_temp_free_i32(tmp2
);
7519 if (insn
& (1 << 22)) {
7520 /* smlald, smlsld */
7521 tmp64
= tcg_temp_new_i64();
7522 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7523 tcg_temp_free_i32(tmp
);
7524 gen_addq(s
, tmp64
, rd
, rn
);
7525 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7526 tcg_temp_free_i64(tmp64
);
7528 /* smuad, smusd, smlad, smlsd */
7531 tmp2
= load_reg(s
, rd
);
7532 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7533 tcg_temp_free_i32(tmp2
);
7535 store_reg(s
, rn
, tmp
);
7541 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7544 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7547 tmp
= load_reg(s
, rm
);
7548 tmp2
= load_reg(s
, rs
);
7549 if (insn
& (1 << 21)) {
7550 gen_helper_udiv(tmp
, tmp
, tmp2
);
7552 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7554 tcg_temp_free_i32(tmp2
);
7555 store_reg(s
, rn
, tmp
);
7562 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7564 case 0: /* Unsigned sum of absolute differences. */
7566 tmp
= load_reg(s
, rm
);
7567 tmp2
= load_reg(s
, rs
);
7568 gen_helper_usad8(tmp
, tmp
, tmp2
);
7569 tcg_temp_free_i32(tmp2
);
7571 tmp2
= load_reg(s
, rd
);
7572 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7573 tcg_temp_free_i32(tmp2
);
7575 store_reg(s
, rn
, tmp
);
7577 case 0x20: case 0x24: case 0x28: case 0x2c:
7578 /* Bitfield insert/clear. */
7580 shift
= (insn
>> 7) & 0x1f;
7581 i
= (insn
>> 16) & 0x1f;
7584 tmp
= tcg_temp_new_i32();
7585 tcg_gen_movi_i32(tmp
, 0);
7587 tmp
= load_reg(s
, rm
);
7590 tmp2
= load_reg(s
, rd
);
7591 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7592 tcg_temp_free_i32(tmp2
);
7594 store_reg(s
, rd
, tmp
);
7596 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7597 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7599 tmp
= load_reg(s
, rm
);
7600 shift
= (insn
>> 7) & 0x1f;
7601 i
= ((insn
>> 16) & 0x1f) + 1;
7606 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7608 gen_sbfx(tmp
, shift
, i
);
7611 store_reg(s
, rd
, tmp
);
7621 /* Check for undefined extension instructions
7622 * per the ARM Bible IE:
7623 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7625 sh
= (0xf << 20) | (0xf << 4);
7626 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7630 /* load/store byte/word */
7631 rn
= (insn
>> 16) & 0xf;
7632 rd
= (insn
>> 12) & 0xf;
7633 tmp2
= load_reg(s
, rn
);
7634 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7635 if (insn
& (1 << 24))
7636 gen_add_data_offset(s
, insn
, tmp2
);
7637 if (insn
& (1 << 20)) {
7639 if (insn
& (1 << 22)) {
7640 tmp
= gen_ld8u(tmp2
, i
);
7642 tmp
= gen_ld32(tmp2
, i
);
7646 tmp
= load_reg(s
, rd
);
7647 if (insn
& (1 << 22))
7648 gen_st8(tmp
, tmp2
, i
);
7650 gen_st32(tmp
, tmp2
, i
);
7652 if (!(insn
& (1 << 24))) {
7653 gen_add_data_offset(s
, insn
, tmp2
);
7654 store_reg(s
, rn
, tmp2
);
7655 } else if (insn
& (1 << 21)) {
7656 store_reg(s
, rn
, tmp2
);
7658 tcg_temp_free_i32(tmp2
);
7660 if (insn
& (1 << 20)) {
7661 /* Complete the load. */
7662 store_reg_from_load(env
, s
, rd
, tmp
);
7668 int j
, n
, user
, loaded_base
;
7670 /* load/store multiple words */
7671 /* XXX: store correct base if write back */
7673 if (insn
& (1 << 22)) {
7675 goto illegal_op
; /* only usable in supervisor mode */
7677 if ((insn
& (1 << 15)) == 0)
7680 rn
= (insn
>> 16) & 0xf;
7681 addr
= load_reg(s
, rn
);
7683 /* compute total size */
7685 TCGV_UNUSED(loaded_var
);
7688 if (insn
& (1 << i
))
7691 /* XXX: test invalid n == 0 case ? */
7692 if (insn
& (1 << 23)) {
7693 if (insn
& (1 << 24)) {
7695 tcg_gen_addi_i32(addr
, addr
, 4);
7697 /* post increment */
7700 if (insn
& (1 << 24)) {
7702 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7704 /* post decrement */
7706 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7711 if (insn
& (1 << i
)) {
7712 if (insn
& (1 << 20)) {
7714 tmp
= gen_ld32(addr
, IS_USER(s
));
7716 tmp2
= tcg_const_i32(i
);
7717 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7718 tcg_temp_free_i32(tmp2
);
7719 tcg_temp_free_i32(tmp
);
7720 } else if (i
== rn
) {
7724 store_reg_from_load(env
, s
, i
, tmp
);
7729 /* special case: r15 = PC + 8 */
7730 val
= (long)s
->pc
+ 4;
7731 tmp
= tcg_temp_new_i32();
7732 tcg_gen_movi_i32(tmp
, val
);
7734 tmp
= tcg_temp_new_i32();
7735 tmp2
= tcg_const_i32(i
);
7736 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7737 tcg_temp_free_i32(tmp2
);
7739 tmp
= load_reg(s
, i
);
7741 gen_st32(tmp
, addr
, IS_USER(s
));
7744 /* no need to add after the last transfer */
7746 tcg_gen_addi_i32(addr
, addr
, 4);
7749 if (insn
& (1 << 21)) {
7751 if (insn
& (1 << 23)) {
7752 if (insn
& (1 << 24)) {
7755 /* post increment */
7756 tcg_gen_addi_i32(addr
, addr
, 4);
7759 if (insn
& (1 << 24)) {
7762 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7764 /* post decrement */
7765 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7768 store_reg(s
, rn
, addr
);
7770 tcg_temp_free_i32(addr
);
7773 store_reg(s
, rn
, loaded_var
);
7775 if ((insn
& (1 << 22)) && !user
) {
7776 /* Restore CPSR from SPSR. */
7777 tmp
= load_cpu_field(spsr
);
7778 gen_set_cpsr(tmp
, 0xffffffff);
7779 tcg_temp_free_i32(tmp
);
7780 s
->is_jmp
= DISAS_UPDATE
;
7789 /* branch (and link) */
7790 val
= (int32_t)s
->pc
;
7791 if (insn
& (1 << 24)) {
7792 tmp
= tcg_temp_new_i32();
7793 tcg_gen_movi_i32(tmp
, val
);
7794 store_reg(s
, 14, tmp
);
7796 offset
= (((int32_t)insn
<< 8) >> 8);
7797 val
+= (offset
<< 2) + 4;
7805 if (disas_coproc_insn(env
, s
, insn
))
7810 gen_set_pc_im(s
->pc
);
7811 s
->is_jmp
= DISAS_SWI
;
7815 gen_exception_insn(s
, 4, EXCP_UDEF
);
7821 /* Return true if this is a Thumb-2 logical op. */
7823 thumb2_logic_op(int op
)
7828 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7829 then set condition code flags based on the result of the operation.
7830 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7831 to the high bit of T1.
7832 Returns zero if the opcode is valid. */
7835 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7842 tcg_gen_and_i32(t0
, t0
, t1
);
7846 tcg_gen_andc_i32(t0
, t0
, t1
);
7850 tcg_gen_or_i32(t0
, t0
, t1
);
7854 tcg_gen_orc_i32(t0
, t0
, t1
);
7858 tcg_gen_xor_i32(t0
, t0
, t1
);
7863 gen_add_CC(t0
, t0
, t1
);
7865 tcg_gen_add_i32(t0
, t0
, t1
);
7869 gen_helper_adc_cc(t0
, cpu_env
, t0
, t1
);
7875 gen_helper_sbc_cc(t0
, cpu_env
, t0
, t1
);
7877 gen_sub_carry(t0
, t0
, t1
);
7881 gen_sub_CC(t0
, t0
, t1
);
7883 tcg_gen_sub_i32(t0
, t0
, t1
);
7887 gen_sub_CC(t0
, t1
, t0
);
7889 tcg_gen_sub_i32(t0
, t1
, t0
);
7891 default: /* 5, 6, 7, 9, 12, 15. */
7897 gen_set_CF_bit31(t1
);
7902 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7904 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7906 uint32_t insn
, imm
, shift
, offset
;
7907 uint32_t rd
, rn
, rm
, rs
;
7918 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7919 || arm_feature (env
, ARM_FEATURE_M
))) {
7920 /* Thumb-1 cores may need to treat bl and blx as a pair of
7921 16-bit instructions to get correct prefetch abort behavior. */
7923 if ((insn
& (1 << 12)) == 0) {
7925 /* Second half of blx. */
7926 offset
= ((insn
& 0x7ff) << 1);
7927 tmp
= load_reg(s
, 14);
7928 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7929 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7931 tmp2
= tcg_temp_new_i32();
7932 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7933 store_reg(s
, 14, tmp2
);
7937 if (insn
& (1 << 11)) {
7938 /* Second half of bl. */
7939 offset
= ((insn
& 0x7ff) << 1) | 1;
7940 tmp
= load_reg(s
, 14);
7941 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7943 tmp2
= tcg_temp_new_i32();
7944 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7945 store_reg(s
, 14, tmp2
);
7949 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7950 /* Instruction spans a page boundary. Implement it as two
7951 16-bit instructions in case the second half causes an
7953 offset
= ((int32_t)insn
<< 21) >> 9;
7954 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7957 /* Fall through to 32-bit decode. */
7960 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
7962 insn
|= (uint32_t)insn_hw1
<< 16;
7964 if ((insn
& 0xf800e800) != 0xf000e800) {
7968 rn
= (insn
>> 16) & 0xf;
7969 rs
= (insn
>> 12) & 0xf;
7970 rd
= (insn
>> 8) & 0xf;
7972 switch ((insn
>> 25) & 0xf) {
7973 case 0: case 1: case 2: case 3:
7974 /* 16-bit instructions. Should never happen. */
7977 if (insn
& (1 << 22)) {
7978 /* Other load/store, table branch. */
7979 if (insn
& 0x01200000) {
7980 /* Load/store doubleword. */
7982 addr
= tcg_temp_new_i32();
7983 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7985 addr
= load_reg(s
, rn
);
7987 offset
= (insn
& 0xff) * 4;
7988 if ((insn
& (1 << 23)) == 0)
7990 if (insn
& (1 << 24)) {
7991 tcg_gen_addi_i32(addr
, addr
, offset
);
7994 if (insn
& (1 << 20)) {
7996 tmp
= gen_ld32(addr
, IS_USER(s
));
7997 store_reg(s
, rs
, tmp
);
7998 tcg_gen_addi_i32(addr
, addr
, 4);
7999 tmp
= gen_ld32(addr
, IS_USER(s
));
8000 store_reg(s
, rd
, tmp
);
8003 tmp
= load_reg(s
, rs
);
8004 gen_st32(tmp
, addr
, IS_USER(s
));
8005 tcg_gen_addi_i32(addr
, addr
, 4);
8006 tmp
= load_reg(s
, rd
);
8007 gen_st32(tmp
, addr
, IS_USER(s
));
8009 if (insn
& (1 << 21)) {
8010 /* Base writeback. */
8013 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8014 store_reg(s
, rn
, addr
);
8016 tcg_temp_free_i32(addr
);
8018 } else if ((insn
& (1 << 23)) == 0) {
8019 /* Load/store exclusive word. */
8020 addr
= tcg_temp_local_new();
8021 load_reg_var(s
, addr
, rn
);
8022 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8023 if (insn
& (1 << 20)) {
8024 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8026 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8028 tcg_temp_free(addr
);
8029 } else if ((insn
& (1 << 6)) == 0) {
8032 addr
= tcg_temp_new_i32();
8033 tcg_gen_movi_i32(addr
, s
->pc
);
8035 addr
= load_reg(s
, rn
);
8037 tmp
= load_reg(s
, rm
);
8038 tcg_gen_add_i32(addr
, addr
, tmp
);
8039 if (insn
& (1 << 4)) {
8041 tcg_gen_add_i32(addr
, addr
, tmp
);
8042 tcg_temp_free_i32(tmp
);
8043 tmp
= gen_ld16u(addr
, IS_USER(s
));
8045 tcg_temp_free_i32(tmp
);
8046 tmp
= gen_ld8u(addr
, IS_USER(s
));
8048 tcg_temp_free_i32(addr
);
8049 tcg_gen_shli_i32(tmp
, tmp
, 1);
8050 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8051 store_reg(s
, 15, tmp
);
8053 /* Load/store exclusive byte/halfword/doubleword. */
8055 op
= (insn
>> 4) & 0x3;
8059 addr
= tcg_temp_local_new();
8060 load_reg_var(s
, addr
, rn
);
8061 if (insn
& (1 << 20)) {
8062 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8064 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8066 tcg_temp_free(addr
);
8069 /* Load/store multiple, RFE, SRS. */
8070 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8071 /* Not available in user mode. */
8074 if (insn
& (1 << 20)) {
8076 addr
= load_reg(s
, rn
);
8077 if ((insn
& (1 << 24)) == 0)
8078 tcg_gen_addi_i32(addr
, addr
, -8);
8079 /* Load PC into tmp and CPSR into tmp2. */
8080 tmp
= gen_ld32(addr
, 0);
8081 tcg_gen_addi_i32(addr
, addr
, 4);
8082 tmp2
= gen_ld32(addr
, 0);
8083 if (insn
& (1 << 21)) {
8084 /* Base writeback. */
8085 if (insn
& (1 << 24)) {
8086 tcg_gen_addi_i32(addr
, addr
, 4);
8088 tcg_gen_addi_i32(addr
, addr
, -4);
8090 store_reg(s
, rn
, addr
);
8092 tcg_temp_free_i32(addr
);
8094 gen_rfe(s
, tmp
, tmp2
);
8098 addr
= tcg_temp_new_i32();
8099 tmp
= tcg_const_i32(op
);
8100 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8101 tcg_temp_free_i32(tmp
);
8102 if ((insn
& (1 << 24)) == 0) {
8103 tcg_gen_addi_i32(addr
, addr
, -8);
8105 tmp
= load_reg(s
, 14);
8106 gen_st32(tmp
, addr
, 0);
8107 tcg_gen_addi_i32(addr
, addr
, 4);
8108 tmp
= tcg_temp_new_i32();
8109 gen_helper_cpsr_read(tmp
, cpu_env
);
8110 gen_st32(tmp
, addr
, 0);
8111 if (insn
& (1 << 21)) {
8112 if ((insn
& (1 << 24)) == 0) {
8113 tcg_gen_addi_i32(addr
, addr
, -4);
8115 tcg_gen_addi_i32(addr
, addr
, 4);
8117 tmp
= tcg_const_i32(op
);
8118 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8119 tcg_temp_free_i32(tmp
);
8121 tcg_temp_free_i32(addr
);
8125 int i
, loaded_base
= 0;
8127 /* Load/store multiple. */
8128 addr
= load_reg(s
, rn
);
8130 for (i
= 0; i
< 16; i
++) {
8131 if (insn
& (1 << i
))
8134 if (insn
& (1 << 24)) {
8135 tcg_gen_addi_i32(addr
, addr
, -offset
);
8138 TCGV_UNUSED(loaded_var
);
8139 for (i
= 0; i
< 16; i
++) {
8140 if ((insn
& (1 << i
)) == 0)
8142 if (insn
& (1 << 20)) {
8144 tmp
= gen_ld32(addr
, IS_USER(s
));
8147 } else if (i
== rn
) {
8151 store_reg(s
, i
, tmp
);
8155 tmp
= load_reg(s
, i
);
8156 gen_st32(tmp
, addr
, IS_USER(s
));
8158 tcg_gen_addi_i32(addr
, addr
, 4);
8161 store_reg(s
, rn
, loaded_var
);
8163 if (insn
& (1 << 21)) {
8164 /* Base register writeback. */
8165 if (insn
& (1 << 24)) {
8166 tcg_gen_addi_i32(addr
, addr
, -offset
);
8168 /* Fault if writeback register is in register list. */
8169 if (insn
& (1 << rn
))
8171 store_reg(s
, rn
, addr
);
8173 tcg_temp_free_i32(addr
);
8180 op
= (insn
>> 21) & 0xf;
8182 /* Halfword pack. */
8183 tmp
= load_reg(s
, rn
);
8184 tmp2
= load_reg(s
, rm
);
8185 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8186 if (insn
& (1 << 5)) {
8190 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8191 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8192 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8196 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8197 tcg_gen_ext16u_i32(tmp
, tmp
);
8198 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8200 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8201 tcg_temp_free_i32(tmp2
);
8202 store_reg(s
, rd
, tmp
);
8204 /* Data processing register constant shift. */
8206 tmp
= tcg_temp_new_i32();
8207 tcg_gen_movi_i32(tmp
, 0);
8209 tmp
= load_reg(s
, rn
);
8211 tmp2
= load_reg(s
, rm
);
8213 shiftop
= (insn
>> 4) & 3;
8214 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8215 conds
= (insn
& (1 << 20)) != 0;
8216 logic_cc
= (conds
&& thumb2_logic_op(op
));
8217 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8218 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8220 tcg_temp_free_i32(tmp2
);
8222 store_reg(s
, rd
, tmp
);
8224 tcg_temp_free_i32(tmp
);
8228 case 13: /* Misc data processing. */
8229 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8230 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8233 case 0: /* Register controlled shift. */
8234 tmp
= load_reg(s
, rn
);
8235 tmp2
= load_reg(s
, rm
);
8236 if ((insn
& 0x70) != 0)
8238 op
= (insn
>> 21) & 3;
8239 logic_cc
= (insn
& (1 << 20)) != 0;
8240 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8243 store_reg_bx(env
, s
, rd
, tmp
);
8245 case 1: /* Sign/zero extend. */
8246 tmp
= load_reg(s
, rm
);
8247 shift
= (insn
>> 4) & 3;
8248 /* ??? In many cases it's not necessary to do a
8249 rotate, a shift is sufficient. */
8251 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8252 op
= (insn
>> 20) & 7;
8254 case 0: gen_sxth(tmp
); break;
8255 case 1: gen_uxth(tmp
); break;
8256 case 2: gen_sxtb16(tmp
); break;
8257 case 3: gen_uxtb16(tmp
); break;
8258 case 4: gen_sxtb(tmp
); break;
8259 case 5: gen_uxtb(tmp
); break;
8260 default: goto illegal_op
;
8263 tmp2
= load_reg(s
, rn
);
8264 if ((op
>> 1) == 1) {
8265 gen_add16(tmp
, tmp2
);
8267 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8268 tcg_temp_free_i32(tmp2
);
8271 store_reg(s
, rd
, tmp
);
8273 case 2: /* SIMD add/subtract. */
8274 op
= (insn
>> 20) & 7;
8275 shift
= (insn
>> 4) & 7;
8276 if ((op
& 3) == 3 || (shift
& 3) == 3)
8278 tmp
= load_reg(s
, rn
);
8279 tmp2
= load_reg(s
, rm
);
8280 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8281 tcg_temp_free_i32(tmp2
);
8282 store_reg(s
, rd
, tmp
);
8284 case 3: /* Other data processing. */
8285 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8287 /* Saturating add/subtract. */
8288 tmp
= load_reg(s
, rn
);
8289 tmp2
= load_reg(s
, rm
);
8291 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8293 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8295 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8296 tcg_temp_free_i32(tmp2
);
8298 tmp
= load_reg(s
, rn
);
8300 case 0x0a: /* rbit */
8301 gen_helper_rbit(tmp
, tmp
);
8303 case 0x08: /* rev */
8304 tcg_gen_bswap32_i32(tmp
, tmp
);
8306 case 0x09: /* rev16 */
8309 case 0x0b: /* revsh */
8312 case 0x10: /* sel */
8313 tmp2
= load_reg(s
, rm
);
8314 tmp3
= tcg_temp_new_i32();
8315 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8316 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8317 tcg_temp_free_i32(tmp3
);
8318 tcg_temp_free_i32(tmp2
);
8320 case 0x18: /* clz */
8321 gen_helper_clz(tmp
, tmp
);
8327 store_reg(s
, rd
, tmp
);
8329 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8330 op
= (insn
>> 4) & 0xf;
8331 tmp
= load_reg(s
, rn
);
8332 tmp2
= load_reg(s
, rm
);
8333 switch ((insn
>> 20) & 7) {
8334 case 0: /* 32 x 32 -> 32 */
8335 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8336 tcg_temp_free_i32(tmp2
);
8338 tmp2
= load_reg(s
, rs
);
8340 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8342 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8343 tcg_temp_free_i32(tmp2
);
8346 case 1: /* 16 x 16 -> 32 */
8347 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8348 tcg_temp_free_i32(tmp2
);
8350 tmp2
= load_reg(s
, rs
);
8351 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8352 tcg_temp_free_i32(tmp2
);
8355 case 2: /* Dual multiply add. */
8356 case 4: /* Dual multiply subtract. */
8358 gen_swap_half(tmp2
);
8359 gen_smul_dual(tmp
, tmp2
);
8360 if (insn
& (1 << 22)) {
8361 /* This subtraction cannot overflow. */
8362 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8364 /* This addition cannot overflow 32 bits;
8365 * however it may overflow considered as a signed
8366 * operation, in which case we must set the Q flag.
8368 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8370 tcg_temp_free_i32(tmp2
);
8373 tmp2
= load_reg(s
, rs
);
8374 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8375 tcg_temp_free_i32(tmp2
);
8378 case 3: /* 32 * 16 -> 32msb */
8380 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8383 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8384 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8385 tmp
= tcg_temp_new_i32();
8386 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8387 tcg_temp_free_i64(tmp64
);
8390 tmp2
= load_reg(s
, rs
);
8391 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8392 tcg_temp_free_i32(tmp2
);
8395 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8396 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8398 tmp
= load_reg(s
, rs
);
8399 if (insn
& (1 << 20)) {
8400 tmp64
= gen_addq_msw(tmp64
, tmp
);
8402 tmp64
= gen_subq_msw(tmp64
, tmp
);
8405 if (insn
& (1 << 4)) {
8406 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8408 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8409 tmp
= tcg_temp_new_i32();
8410 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8411 tcg_temp_free_i64(tmp64
);
8413 case 7: /* Unsigned sum of absolute differences. */
8414 gen_helper_usad8(tmp
, tmp
, tmp2
);
8415 tcg_temp_free_i32(tmp2
);
8417 tmp2
= load_reg(s
, rs
);
8418 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8419 tcg_temp_free_i32(tmp2
);
8423 store_reg(s
, rd
, tmp
);
8425 case 6: case 7: /* 64-bit multiply, Divide. */
8426 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8427 tmp
= load_reg(s
, rn
);
8428 tmp2
= load_reg(s
, rm
);
8429 if ((op
& 0x50) == 0x10) {
8431 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8435 gen_helper_udiv(tmp
, tmp
, tmp2
);
8437 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8438 tcg_temp_free_i32(tmp2
);
8439 store_reg(s
, rd
, tmp
);
8440 } else if ((op
& 0xe) == 0xc) {
8441 /* Dual multiply accumulate long. */
8443 gen_swap_half(tmp2
);
8444 gen_smul_dual(tmp
, tmp2
);
8446 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8448 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8450 tcg_temp_free_i32(tmp2
);
8452 tmp64
= tcg_temp_new_i64();
8453 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8454 tcg_temp_free_i32(tmp
);
8455 gen_addq(s
, tmp64
, rs
, rd
);
8456 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8457 tcg_temp_free_i64(tmp64
);
8460 /* Unsigned 64-bit multiply */
8461 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8465 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8466 tcg_temp_free_i32(tmp2
);
8467 tmp64
= tcg_temp_new_i64();
8468 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8469 tcg_temp_free_i32(tmp
);
8471 /* Signed 64-bit multiply */
8472 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8477 gen_addq_lo(s
, tmp64
, rs
);
8478 gen_addq_lo(s
, tmp64
, rd
);
8479 } else if (op
& 0x40) {
8480 /* 64-bit accumulate. */
8481 gen_addq(s
, tmp64
, rs
, rd
);
8483 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8484 tcg_temp_free_i64(tmp64
);
8489 case 6: case 7: case 14: case 15:
8491 if (((insn
>> 24) & 3) == 3) {
8492 /* Translate into the equivalent ARM encoding. */
8493 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8494 if (disas_neon_data_insn(env
, s
, insn
))
8497 if (insn
& (1 << 28))
8499 if (disas_coproc_insn (env
, s
, insn
))
8503 case 8: case 9: case 10: case 11:
8504 if (insn
& (1 << 15)) {
8505 /* Branches, misc control. */
8506 if (insn
& 0x5000) {
8507 /* Unconditional branch. */
8508 /* signextend(hw1[10:0]) -> offset[:12]. */
8509 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8510 /* hw1[10:0] -> offset[11:1]. */
8511 offset
|= (insn
& 0x7ff) << 1;
8512 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8513 offset[24:22] already have the same value because of the
8514 sign extension above. */
8515 offset
^= ((~insn
) & (1 << 13)) << 10;
8516 offset
^= ((~insn
) & (1 << 11)) << 11;
8518 if (insn
& (1 << 14)) {
8519 /* Branch and link. */
8520 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8524 if (insn
& (1 << 12)) {
8529 offset
&= ~(uint32_t)2;
8530 /* thumb2 bx, no need to check */
8531 gen_bx_im(s
, offset
);
8533 } else if (((insn
>> 23) & 7) == 7) {
8535 if (insn
& (1 << 13))
8538 if (insn
& (1 << 26)) {
8539 /* Secure monitor call (v6Z) */
8540 goto illegal_op
; /* not implemented. */
8542 op
= (insn
>> 20) & 7;
8544 case 0: /* msr cpsr. */
8546 tmp
= load_reg(s
, rn
);
8547 addr
= tcg_const_i32(insn
& 0xff);
8548 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8549 tcg_temp_free_i32(addr
);
8550 tcg_temp_free_i32(tmp
);
8555 case 1: /* msr spsr. */
8558 tmp
= load_reg(s
, rn
);
8560 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8564 case 2: /* cps, nop-hint. */
8565 if (((insn
>> 8) & 7) == 0) {
8566 gen_nop_hint(s
, insn
& 0xff);
8568 /* Implemented as NOP in user mode. */
8573 if (insn
& (1 << 10)) {
8574 if (insn
& (1 << 7))
8576 if (insn
& (1 << 6))
8578 if (insn
& (1 << 5))
8580 if (insn
& (1 << 9))
8581 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8583 if (insn
& (1 << 8)) {
8585 imm
|= (insn
& 0x1f);
8588 gen_set_psr_im(s
, offset
, 0, imm
);
8591 case 3: /* Special control operations. */
8593 op
= (insn
>> 4) & 0xf;
8601 /* These execute as NOPs. */
8608 /* Trivial implementation equivalent to bx. */
8609 tmp
= load_reg(s
, rn
);
8612 case 5: /* Exception return. */
8616 if (rn
!= 14 || rd
!= 15) {
8619 tmp
= load_reg(s
, rn
);
8620 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8621 gen_exception_return(s
, tmp
);
8623 case 6: /* mrs cpsr. */
8624 tmp
= tcg_temp_new_i32();
8626 addr
= tcg_const_i32(insn
& 0xff);
8627 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8628 tcg_temp_free_i32(addr
);
8630 gen_helper_cpsr_read(tmp
, cpu_env
);
8632 store_reg(s
, rd
, tmp
);
8634 case 7: /* mrs spsr. */
8635 /* Not accessible in user mode. */
8636 if (IS_USER(s
) || IS_M(env
))
8638 tmp
= load_cpu_field(spsr
);
8639 store_reg(s
, rd
, tmp
);
8644 /* Conditional branch. */
8645 op
= (insn
>> 22) & 0xf;
8646 /* Generate a conditional jump to next instruction. */
8647 s
->condlabel
= gen_new_label();
8648 gen_test_cc(op
^ 1, s
->condlabel
);
8651 /* offset[11:1] = insn[10:0] */
8652 offset
= (insn
& 0x7ff) << 1;
8653 /* offset[17:12] = insn[21:16]. */
8654 offset
|= (insn
& 0x003f0000) >> 4;
8655 /* offset[31:20] = insn[26]. */
8656 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8657 /* offset[18] = insn[13]. */
8658 offset
|= (insn
& (1 << 13)) << 5;
8659 /* offset[19] = insn[11]. */
8660 offset
|= (insn
& (1 << 11)) << 8;
8662 /* jump to the offset */
8663 gen_jmp(s
, s
->pc
+ offset
);
8666 /* Data processing immediate. */
8667 if (insn
& (1 << 25)) {
8668 if (insn
& (1 << 24)) {
8669 if (insn
& (1 << 20))
8671 /* Bitfield/Saturate. */
8672 op
= (insn
>> 21) & 7;
8674 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8676 tmp
= tcg_temp_new_i32();
8677 tcg_gen_movi_i32(tmp
, 0);
8679 tmp
= load_reg(s
, rn
);
8682 case 2: /* Signed bitfield extract. */
8684 if (shift
+ imm
> 32)
8687 gen_sbfx(tmp
, shift
, imm
);
8689 case 6: /* Unsigned bitfield extract. */
8691 if (shift
+ imm
> 32)
8694 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8696 case 3: /* Bitfield insert/clear. */
8699 imm
= imm
+ 1 - shift
;
8701 tmp2
= load_reg(s
, rd
);
8702 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8703 tcg_temp_free_i32(tmp2
);
8708 default: /* Saturate. */
8711 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8713 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8715 tmp2
= tcg_const_i32(imm
);
8718 if ((op
& 1) && shift
== 0)
8719 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8721 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8724 if ((op
& 1) && shift
== 0)
8725 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8727 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8729 tcg_temp_free_i32(tmp2
);
8732 store_reg(s
, rd
, tmp
);
8734 imm
= ((insn
& 0x04000000) >> 15)
8735 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8736 if (insn
& (1 << 22)) {
8737 /* 16-bit immediate. */
8738 imm
|= (insn
>> 4) & 0xf000;
8739 if (insn
& (1 << 23)) {
8741 tmp
= load_reg(s
, rd
);
8742 tcg_gen_ext16u_i32(tmp
, tmp
);
8743 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8746 tmp
= tcg_temp_new_i32();
8747 tcg_gen_movi_i32(tmp
, imm
);
8750 /* Add/sub 12-bit immediate. */
8752 offset
= s
->pc
& ~(uint32_t)3;
8753 if (insn
& (1 << 23))
8757 tmp
= tcg_temp_new_i32();
8758 tcg_gen_movi_i32(tmp
, offset
);
8760 tmp
= load_reg(s
, rn
);
8761 if (insn
& (1 << 23))
8762 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8764 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8767 store_reg(s
, rd
, tmp
);
8770 int shifter_out
= 0;
8771 /* modified 12-bit immediate. */
8772 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8773 imm
= (insn
& 0xff);
8776 /* Nothing to do. */
8778 case 1: /* 00XY00XY */
8781 case 2: /* XY00XY00 */
8785 case 3: /* XYXYXYXY */
8789 default: /* Rotated constant. */
8790 shift
= (shift
<< 1) | (imm
>> 7);
8792 imm
= imm
<< (32 - shift
);
8796 tmp2
= tcg_temp_new_i32();
8797 tcg_gen_movi_i32(tmp2
, imm
);
8798 rn
= (insn
>> 16) & 0xf;
8800 tmp
= tcg_temp_new_i32();
8801 tcg_gen_movi_i32(tmp
, 0);
8803 tmp
= load_reg(s
, rn
);
8805 op
= (insn
>> 21) & 0xf;
8806 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8807 shifter_out
, tmp
, tmp2
))
8809 tcg_temp_free_i32(tmp2
);
8810 rd
= (insn
>> 8) & 0xf;
8812 store_reg(s
, rd
, tmp
);
8814 tcg_temp_free_i32(tmp
);
8819 case 12: /* Load/store single data item. */
8824 if ((insn
& 0x01100000) == 0x01000000) {
8825 if (disas_neon_ls_insn(env
, s
, insn
))
8829 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8831 if (!(insn
& (1 << 20))) {
8835 /* Byte or halfword load space with dest == r15 : memory hints.
8836 * Catch them early so we don't emit pointless addressing code.
8837 * This space is a mix of:
8838 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8839 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8841 * unallocated hints, which must be treated as NOPs
8842 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8843 * which is easiest for the decoding logic
8844 * Some space which must UNDEF
8846 int op1
= (insn
>> 23) & 3;
8847 int op2
= (insn
>> 6) & 0x3f;
8852 /* UNPREDICTABLE, unallocated hint or
8853 * PLD/PLDW/PLI (literal)
8858 return 0; /* PLD/PLDW/PLI or unallocated hint */
8860 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8861 return 0; /* PLD/PLDW/PLI or unallocated hint */
8863 /* UNDEF space, or an UNPREDICTABLE */
8869 addr
= tcg_temp_new_i32();
8871 /* s->pc has already been incremented by 4. */
8872 imm
= s
->pc
& 0xfffffffc;
8873 if (insn
& (1 << 23))
8874 imm
+= insn
& 0xfff;
8876 imm
-= insn
& 0xfff;
8877 tcg_gen_movi_i32(addr
, imm
);
8879 addr
= load_reg(s
, rn
);
8880 if (insn
& (1 << 23)) {
8881 /* Positive offset. */
8883 tcg_gen_addi_i32(addr
, addr
, imm
);
8886 switch ((insn
>> 8) & 0xf) {
8887 case 0x0: /* Shifted Register. */
8888 shift
= (insn
>> 4) & 0xf;
8890 tcg_temp_free_i32(addr
);
8893 tmp
= load_reg(s
, rm
);
8895 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8896 tcg_gen_add_i32(addr
, addr
, tmp
);
8897 tcg_temp_free_i32(tmp
);
8899 case 0xc: /* Negative offset. */
8900 tcg_gen_addi_i32(addr
, addr
, -imm
);
8902 case 0xe: /* User privilege. */
8903 tcg_gen_addi_i32(addr
, addr
, imm
);
8906 case 0x9: /* Post-decrement. */
8909 case 0xb: /* Post-increment. */
8913 case 0xd: /* Pre-decrement. */
8916 case 0xf: /* Pre-increment. */
8917 tcg_gen_addi_i32(addr
, addr
, imm
);
8921 tcg_temp_free_i32(addr
);
8926 if (insn
& (1 << 20)) {
8929 case 0: tmp
= gen_ld8u(addr
, user
); break;
8930 case 4: tmp
= gen_ld8s(addr
, user
); break;
8931 case 1: tmp
= gen_ld16u(addr
, user
); break;
8932 case 5: tmp
= gen_ld16s(addr
, user
); break;
8933 case 2: tmp
= gen_ld32(addr
, user
); break;
8935 tcg_temp_free_i32(addr
);
8941 store_reg(s
, rs
, tmp
);
8945 tmp
= load_reg(s
, rs
);
8947 case 0: gen_st8(tmp
, addr
, user
); break;
8948 case 1: gen_st16(tmp
, addr
, user
); break;
8949 case 2: gen_st32(tmp
, addr
, user
); break;
8951 tcg_temp_free_i32(addr
);
8956 tcg_gen_addi_i32(addr
, addr
, imm
);
8958 store_reg(s
, rn
, addr
);
8960 tcg_temp_free_i32(addr
);
8972 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
8974 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8981 if (s
->condexec_mask
) {
8982 cond
= s
->condexec_cond
;
8983 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
8984 s
->condlabel
= gen_new_label();
8985 gen_test_cc(cond
^ 1, s
->condlabel
);
8990 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8993 switch (insn
>> 12) {
8997 op
= (insn
>> 11) & 3;
9000 rn
= (insn
>> 3) & 7;
9001 tmp
= load_reg(s
, rn
);
9002 if (insn
& (1 << 10)) {
9004 tmp2
= tcg_temp_new_i32();
9005 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9008 rm
= (insn
>> 6) & 7;
9009 tmp2
= load_reg(s
, rm
);
9011 if (insn
& (1 << 9)) {
9012 if (s
->condexec_mask
)
9013 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9015 gen_sub_CC(tmp
, tmp
, tmp2
);
9017 if (s
->condexec_mask
)
9018 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9020 gen_add_CC(tmp
, tmp
, tmp2
);
9022 tcg_temp_free_i32(tmp2
);
9023 store_reg(s
, rd
, tmp
);
9025 /* shift immediate */
9026 rm
= (insn
>> 3) & 7;
9027 shift
= (insn
>> 6) & 0x1f;
9028 tmp
= load_reg(s
, rm
);
9029 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9030 if (!s
->condexec_mask
)
9032 store_reg(s
, rd
, tmp
);
9036 /* arithmetic large immediate */
9037 op
= (insn
>> 11) & 3;
9038 rd
= (insn
>> 8) & 0x7;
9039 if (op
== 0) { /* mov */
9040 tmp
= tcg_temp_new_i32();
9041 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9042 if (!s
->condexec_mask
)
9044 store_reg(s
, rd
, tmp
);
9046 tmp
= load_reg(s
, rd
);
9047 tmp2
= tcg_temp_new_i32();
9048 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9051 gen_sub_CC(tmp
, tmp
, tmp2
);
9052 tcg_temp_free_i32(tmp
);
9053 tcg_temp_free_i32(tmp2
);
9056 if (s
->condexec_mask
)
9057 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9059 gen_add_CC(tmp
, tmp
, tmp2
);
9060 tcg_temp_free_i32(tmp2
);
9061 store_reg(s
, rd
, tmp
);
9064 if (s
->condexec_mask
)
9065 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9067 gen_sub_CC(tmp
, tmp
, tmp2
);
9068 tcg_temp_free_i32(tmp2
);
9069 store_reg(s
, rd
, tmp
);
9075 if (insn
& (1 << 11)) {
9076 rd
= (insn
>> 8) & 7;
9077 /* load pc-relative. Bit 1 of PC is ignored. */
9078 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9079 val
&= ~(uint32_t)2;
9080 addr
= tcg_temp_new_i32();
9081 tcg_gen_movi_i32(addr
, val
);
9082 tmp
= gen_ld32(addr
, IS_USER(s
));
9083 tcg_temp_free_i32(addr
);
9084 store_reg(s
, rd
, tmp
);
9087 if (insn
& (1 << 10)) {
9088 /* data processing extended or blx */
9089 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9090 rm
= (insn
>> 3) & 0xf;
9091 op
= (insn
>> 8) & 3;
9094 tmp
= load_reg(s
, rd
);
9095 tmp2
= load_reg(s
, rm
);
9096 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9097 tcg_temp_free_i32(tmp2
);
9098 store_reg(s
, rd
, tmp
);
9101 tmp
= load_reg(s
, rd
);
9102 tmp2
= load_reg(s
, rm
);
9103 gen_sub_CC(tmp
, tmp
, tmp2
);
9104 tcg_temp_free_i32(tmp2
);
9105 tcg_temp_free_i32(tmp
);
9107 case 2: /* mov/cpy */
9108 tmp
= load_reg(s
, rm
);
9109 store_reg(s
, rd
, tmp
);
9111 case 3:/* branch [and link] exchange thumb register */
9112 tmp
= load_reg(s
, rm
);
9113 if (insn
& (1 << 7)) {
9115 val
= (uint32_t)s
->pc
| 1;
9116 tmp2
= tcg_temp_new_i32();
9117 tcg_gen_movi_i32(tmp2
, val
);
9118 store_reg(s
, 14, tmp2
);
9120 /* already thumb, no need to check */
9127 /* data processing register */
9129 rm
= (insn
>> 3) & 7;
9130 op
= (insn
>> 6) & 0xf;
9131 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9132 /* the shift/rotate ops want the operands backwards */
9141 if (op
== 9) { /* neg */
9142 tmp
= tcg_temp_new_i32();
9143 tcg_gen_movi_i32(tmp
, 0);
9144 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9145 tmp
= load_reg(s
, rd
);
9150 tmp2
= load_reg(s
, rm
);
9153 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9154 if (!s
->condexec_mask
)
9158 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9159 if (!s
->condexec_mask
)
9163 if (s
->condexec_mask
) {
9164 gen_helper_shl(tmp2
, cpu_env
, tmp2
, tmp
);
9166 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9171 if (s
->condexec_mask
) {
9172 gen_helper_shr(tmp2
, cpu_env
, tmp2
, tmp
);
9174 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9179 if (s
->condexec_mask
) {
9180 gen_helper_sar(tmp2
, cpu_env
, tmp2
, tmp
);
9182 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9187 if (s
->condexec_mask
)
9190 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9193 if (s
->condexec_mask
)
9194 gen_sub_carry(tmp
, tmp
, tmp2
);
9196 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9199 if (s
->condexec_mask
) {
9200 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9201 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9203 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9208 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9213 if (s
->condexec_mask
)
9214 tcg_gen_neg_i32(tmp
, tmp2
);
9216 gen_sub_CC(tmp
, tmp
, tmp2
);
9219 gen_sub_CC(tmp
, tmp
, tmp2
);
9223 gen_add_CC(tmp
, tmp
, tmp2
);
9227 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9228 if (!s
->condexec_mask
)
9232 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9233 if (!s
->condexec_mask
)
9237 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9238 if (!s
->condexec_mask
)
9242 tcg_gen_not_i32(tmp2
, tmp2
);
9243 if (!s
->condexec_mask
)
9251 store_reg(s
, rm
, tmp2
);
9253 tcg_temp_free_i32(tmp
);
9255 store_reg(s
, rd
, tmp
);
9256 tcg_temp_free_i32(tmp2
);
9259 tcg_temp_free_i32(tmp
);
9260 tcg_temp_free_i32(tmp2
);
9265 /* load/store register offset. */
9267 rn
= (insn
>> 3) & 7;
9268 rm
= (insn
>> 6) & 7;
9269 op
= (insn
>> 9) & 7;
9270 addr
= load_reg(s
, rn
);
9271 tmp
= load_reg(s
, rm
);
9272 tcg_gen_add_i32(addr
, addr
, tmp
);
9273 tcg_temp_free_i32(tmp
);
9275 if (op
< 3) /* store */
9276 tmp
= load_reg(s
, rd
);
9280 gen_st32(tmp
, addr
, IS_USER(s
));
9283 gen_st16(tmp
, addr
, IS_USER(s
));
9286 gen_st8(tmp
, addr
, IS_USER(s
));
9289 tmp
= gen_ld8s(addr
, IS_USER(s
));
9292 tmp
= gen_ld32(addr
, IS_USER(s
));
9295 tmp
= gen_ld16u(addr
, IS_USER(s
));
9298 tmp
= gen_ld8u(addr
, IS_USER(s
));
9301 tmp
= gen_ld16s(addr
, IS_USER(s
));
9304 if (op
>= 3) /* load */
9305 store_reg(s
, rd
, tmp
);
9306 tcg_temp_free_i32(addr
);
9310 /* load/store word immediate offset */
9312 rn
= (insn
>> 3) & 7;
9313 addr
= load_reg(s
, rn
);
9314 val
= (insn
>> 4) & 0x7c;
9315 tcg_gen_addi_i32(addr
, addr
, val
);
9317 if (insn
& (1 << 11)) {
9319 tmp
= gen_ld32(addr
, IS_USER(s
));
9320 store_reg(s
, rd
, tmp
);
9323 tmp
= load_reg(s
, rd
);
9324 gen_st32(tmp
, addr
, IS_USER(s
));
9326 tcg_temp_free_i32(addr
);
9330 /* load/store byte immediate offset */
9332 rn
= (insn
>> 3) & 7;
9333 addr
= load_reg(s
, rn
);
9334 val
= (insn
>> 6) & 0x1f;
9335 tcg_gen_addi_i32(addr
, addr
, val
);
9337 if (insn
& (1 << 11)) {
9339 tmp
= gen_ld8u(addr
, IS_USER(s
));
9340 store_reg(s
, rd
, tmp
);
9343 tmp
= load_reg(s
, rd
);
9344 gen_st8(tmp
, addr
, IS_USER(s
));
9346 tcg_temp_free_i32(addr
);
9350 /* load/store halfword immediate offset */
9352 rn
= (insn
>> 3) & 7;
9353 addr
= load_reg(s
, rn
);
9354 val
= (insn
>> 5) & 0x3e;
9355 tcg_gen_addi_i32(addr
, addr
, val
);
9357 if (insn
& (1 << 11)) {
9359 tmp
= gen_ld16u(addr
, IS_USER(s
));
9360 store_reg(s
, rd
, tmp
);
9363 tmp
= load_reg(s
, rd
);
9364 gen_st16(tmp
, addr
, IS_USER(s
));
9366 tcg_temp_free_i32(addr
);
9370 /* load/store from stack */
9371 rd
= (insn
>> 8) & 7;
9372 addr
= load_reg(s
, 13);
9373 val
= (insn
& 0xff) * 4;
9374 tcg_gen_addi_i32(addr
, addr
, val
);
9376 if (insn
& (1 << 11)) {
9378 tmp
= gen_ld32(addr
, IS_USER(s
));
9379 store_reg(s
, rd
, tmp
);
9382 tmp
= load_reg(s
, rd
);
9383 gen_st32(tmp
, addr
, IS_USER(s
));
9385 tcg_temp_free_i32(addr
);
9389 /* add to high reg */
9390 rd
= (insn
>> 8) & 7;
9391 if (insn
& (1 << 11)) {
9393 tmp
= load_reg(s
, 13);
9395 /* PC. bit 1 is ignored. */
9396 tmp
= tcg_temp_new_i32();
9397 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9399 val
= (insn
& 0xff) * 4;
9400 tcg_gen_addi_i32(tmp
, tmp
, val
);
9401 store_reg(s
, rd
, tmp
);
9406 op
= (insn
>> 8) & 0xf;
9409 /* adjust stack pointer */
9410 tmp
= load_reg(s
, 13);
9411 val
= (insn
& 0x7f) * 4;
9412 if (insn
& (1 << 7))
9413 val
= -(int32_t)val
;
9414 tcg_gen_addi_i32(tmp
, tmp
, val
);
9415 store_reg(s
, 13, tmp
);
9418 case 2: /* sign/zero extend. */
9421 rm
= (insn
>> 3) & 7;
9422 tmp
= load_reg(s
, rm
);
9423 switch ((insn
>> 6) & 3) {
9424 case 0: gen_sxth(tmp
); break;
9425 case 1: gen_sxtb(tmp
); break;
9426 case 2: gen_uxth(tmp
); break;
9427 case 3: gen_uxtb(tmp
); break;
9429 store_reg(s
, rd
, tmp
);
9431 case 4: case 5: case 0xc: case 0xd:
9433 addr
= load_reg(s
, 13);
9434 if (insn
& (1 << 8))
9438 for (i
= 0; i
< 8; i
++) {
9439 if (insn
& (1 << i
))
9442 if ((insn
& (1 << 11)) == 0) {
9443 tcg_gen_addi_i32(addr
, addr
, -offset
);
9445 for (i
= 0; i
< 8; i
++) {
9446 if (insn
& (1 << i
)) {
9447 if (insn
& (1 << 11)) {
9449 tmp
= gen_ld32(addr
, IS_USER(s
));
9450 store_reg(s
, i
, tmp
);
9453 tmp
= load_reg(s
, i
);
9454 gen_st32(tmp
, addr
, IS_USER(s
));
9456 /* advance to the next address. */
9457 tcg_gen_addi_i32(addr
, addr
, 4);
9461 if (insn
& (1 << 8)) {
9462 if (insn
& (1 << 11)) {
9464 tmp
= gen_ld32(addr
, IS_USER(s
));
9465 /* don't set the pc until the rest of the instruction
9469 tmp
= load_reg(s
, 14);
9470 gen_st32(tmp
, addr
, IS_USER(s
));
9472 tcg_gen_addi_i32(addr
, addr
, 4);
9474 if ((insn
& (1 << 11)) == 0) {
9475 tcg_gen_addi_i32(addr
, addr
, -offset
);
9477 /* write back the new stack pointer */
9478 store_reg(s
, 13, addr
);
9479 /* set the new PC value */
9480 if ((insn
& 0x0900) == 0x0900) {
9481 store_reg_from_load(env
, s
, 15, tmp
);
9485 case 1: case 3: case 9: case 11: /* czb */
9487 tmp
= load_reg(s
, rm
);
9488 s
->condlabel
= gen_new_label();
9490 if (insn
& (1 << 11))
9491 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9493 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9494 tcg_temp_free_i32(tmp
);
9495 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9496 val
= (uint32_t)s
->pc
+ 2;
9501 case 15: /* IT, nop-hint. */
9502 if ((insn
& 0xf) == 0) {
9503 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9507 s
->condexec_cond
= (insn
>> 4) & 0xe;
9508 s
->condexec_mask
= insn
& 0x1f;
9509 /* No actual code generated for this insn, just setup state. */
9512 case 0xe: /* bkpt */
9514 gen_exception_insn(s
, 2, EXCP_BKPT
);
9519 rn
= (insn
>> 3) & 0x7;
9521 tmp
= load_reg(s
, rn
);
9522 switch ((insn
>> 6) & 3) {
9523 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9524 case 1: gen_rev16(tmp
); break;
9525 case 3: gen_revsh(tmp
); break;
9526 default: goto illegal_op
;
9528 store_reg(s
, rd
, tmp
);
9532 switch ((insn
>> 5) & 7) {
9536 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9537 /* Dynamic endianness switching not implemented. */
9548 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9551 addr
= tcg_const_i32(19);
9552 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9553 tcg_temp_free_i32(addr
);
9557 addr
= tcg_const_i32(16);
9558 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9559 tcg_temp_free_i32(addr
);
9561 tcg_temp_free_i32(tmp
);
9564 if (insn
& (1 << 4)) {
9565 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9569 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9584 /* load/store multiple */
9586 TCGV_UNUSED(loaded_var
);
9587 rn
= (insn
>> 8) & 0x7;
9588 addr
= load_reg(s
, rn
);
9589 for (i
= 0; i
< 8; i
++) {
9590 if (insn
& (1 << i
)) {
9591 if (insn
& (1 << 11)) {
9593 tmp
= gen_ld32(addr
, IS_USER(s
));
9597 store_reg(s
, i
, tmp
);
9601 tmp
= load_reg(s
, i
);
9602 gen_st32(tmp
, addr
, IS_USER(s
));
9604 /* advance to the next address */
9605 tcg_gen_addi_i32(addr
, addr
, 4);
9608 if ((insn
& (1 << rn
)) == 0) {
9609 /* base reg not in list: base register writeback */
9610 store_reg(s
, rn
, addr
);
9612 /* base reg in list: if load, complete it now */
9613 if (insn
& (1 << 11)) {
9614 store_reg(s
, rn
, loaded_var
);
9616 tcg_temp_free_i32(addr
);
9621 /* conditional branch or swi */
9622 cond
= (insn
>> 8) & 0xf;
9628 gen_set_pc_im(s
->pc
);
9629 s
->is_jmp
= DISAS_SWI
;
9632 /* generate a conditional jump to next instruction */
9633 s
->condlabel
= gen_new_label();
9634 gen_test_cc(cond
^ 1, s
->condlabel
);
9637 /* jump to the offset */
9638 val
= (uint32_t)s
->pc
+ 2;
9639 offset
= ((int32_t)insn
<< 24) >> 24;
9645 if (insn
& (1 << 11)) {
9646 if (disas_thumb2_insn(env
, s
, insn
))
9650 /* unconditional branch */
9651 val
= (uint32_t)s
->pc
;
9652 offset
= ((int32_t)insn
<< 21) >> 21;
9653 val
+= (offset
<< 1) + 2;
9658 if (disas_thumb2_insn(env
, s
, insn
))
9664 gen_exception_insn(s
, 4, EXCP_UDEF
);
9668 gen_exception_insn(s
, 2, EXCP_UDEF
);
9671 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9672 basic block 'tb'. If search_pc is TRUE, also generate PC
9673 information for each intermediate instruction. */
9674 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9675 TranslationBlock
*tb
,
9678 DisasContext dc1
, *dc
= &dc1
;
9680 uint16_t *gen_opc_end
;
9682 target_ulong pc_start
;
9683 uint32_t next_page_start
;
9687 /* generate intermediate code */
9692 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9694 dc
->is_jmp
= DISAS_NEXT
;
9696 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9698 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9699 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9700 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9701 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9702 #if !defined(CONFIG_USER_ONLY)
9703 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9705 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9706 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9707 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9708 cpu_F0s
= tcg_temp_new_i32();
9709 cpu_F1s
= tcg_temp_new_i32();
9710 cpu_F0d
= tcg_temp_new_i64();
9711 cpu_F1d
= tcg_temp_new_i64();
9714 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9715 cpu_M0
= tcg_temp_new_i64();
9716 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9719 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9721 max_insns
= CF_COUNT_MASK
;
9725 tcg_clear_temp_count();
9727 /* A note on handling of the condexec (IT) bits:
9729 * We want to avoid the overhead of having to write the updated condexec
9730 * bits back to the CPUARMState for every instruction in an IT block. So:
9731 * (1) if the condexec bits are not already zero then we write
9732 * zero back into the CPUARMState now. This avoids complications trying
9733 * to do it at the end of the block. (For example if we don't do this
9734 * it's hard to identify whether we can safely skip writing condexec
9735 * at the end of the TB, which we definitely want to do for the case
9736 * where a TB doesn't do anything with the IT state at all.)
9737 * (2) if we are going to leave the TB then we call gen_set_condexec()
9738 * which will write the correct value into CPUARMState if zero is wrong.
9739 * This is done both for leaving the TB at the end, and for leaving
9740 * it because of an exception we know will happen, which is done in
9741 * gen_exception_insn(). The latter is necessary because we need to
9742 * leave the TB with the PC/IT state just prior to execution of the
9743 * instruction which caused the exception.
9744 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9745 * then the CPUARMState will be wrong and we need to reset it.
9746 * This is handled in the same way as restoration of the
9747 * PC in these situations: we will be called again with search_pc=1
9748 * and generate a mapping of the condexec bits for each PC in
9749 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9750 * this to restore the condexec bits.
9752 * Note that there are no instructions which can read the condexec
9753 * bits, and none which can write non-static values to them, so
9754 * we don't need to care about whether CPUARMState is correct in the
9758 /* Reset the conditional execution bits immediately. This avoids
9759 complications trying to do it at the end of the block. */
9760 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9762 TCGv tmp
= tcg_temp_new_i32();
9763 tcg_gen_movi_i32(tmp
, 0);
9764 store_cpu_field(tmp
, condexec_bits
);
9767 #ifdef CONFIG_USER_ONLY
9768 /* Intercept jump to the magic kernel page. */
9769 if (dc
->pc
>= 0xffff0000) {
9770 /* We always get here via a jump, so know we are not in a
9771 conditional execution block. */
9772 gen_exception(EXCP_KERNEL_TRAP
);
9773 dc
->is_jmp
= DISAS_UPDATE
;
9777 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9778 /* We always get here via a jump, so know we are not in a
9779 conditional execution block. */
9780 gen_exception(EXCP_EXCEPTION_EXIT
);
9781 dc
->is_jmp
= DISAS_UPDATE
;
9786 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9787 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9788 if (bp
->pc
== dc
->pc
) {
9789 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9790 /* Advance PC so that clearing the breakpoint will
9791 invalidate this TB. */
9793 goto done_generating
;
9799 j
= gen_opc_ptr
- gen_opc_buf
;
9803 gen_opc_instr_start
[lj
++] = 0;
9805 gen_opc_pc
[lj
] = dc
->pc
;
9806 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9807 gen_opc_instr_start
[lj
] = 1;
9808 gen_opc_icount
[lj
] = num_insns
;
9811 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9814 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9815 tcg_gen_debug_insn_start(dc
->pc
);
9819 disas_thumb_insn(env
, dc
);
9820 if (dc
->condexec_mask
) {
9821 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9822 | ((dc
->condexec_mask
>> 4) & 1);
9823 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9824 if (dc
->condexec_mask
== 0) {
9825 dc
->condexec_cond
= 0;
9829 disas_arm_insn(env
, dc
);
9832 if (dc
->condjmp
&& !dc
->is_jmp
) {
9833 gen_set_label(dc
->condlabel
);
9837 if (tcg_check_temp_count()) {
9838 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9841 /* Translation stops when a conditional branch is encountered.
9842 * Otherwise the subsequent code could get translated several times.
9843 * Also stop translation when a page boundary is reached. This
9844 * ensures prefetch aborts occur at the right place. */
9846 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9847 !env
->singlestep_enabled
&&
9849 dc
->pc
< next_page_start
&&
9850 num_insns
< max_insns
);
9852 if (tb
->cflags
& CF_LAST_IO
) {
9854 /* FIXME: This can theoretically happen with self-modifying
9856 cpu_abort(env
, "IO on conditional branch instruction");
9861 /* At this stage dc->condjmp will only be set when the skipped
9862 instruction was a conditional branch or trap, and the PC has
9863 already been written. */
9864 if (unlikely(env
->singlestep_enabled
)) {
9865 /* Make sure the pc is updated, and raise a debug exception. */
9867 gen_set_condexec(dc
);
9868 if (dc
->is_jmp
== DISAS_SWI
) {
9869 gen_exception(EXCP_SWI
);
9871 gen_exception(EXCP_DEBUG
);
9873 gen_set_label(dc
->condlabel
);
9875 if (dc
->condjmp
|| !dc
->is_jmp
) {
9876 gen_set_pc_im(dc
->pc
);
9879 gen_set_condexec(dc
);
9880 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9881 gen_exception(EXCP_SWI
);
9883 /* FIXME: Single stepping a WFI insn will not halt
9885 gen_exception(EXCP_DEBUG
);
9888 /* While branches must always occur at the end of an IT block,
9889 there are a few other things that can cause us to terminate
9890 the TB in the middle of an IT block:
9891 - Exception generating instructions (bkpt, swi, undefined).
9893 - Hardware watchpoints.
9894 Hardware breakpoints have already been handled and skip this code.
9896 gen_set_condexec(dc
);
9897 switch(dc
->is_jmp
) {
9899 gen_goto_tb(dc
, 1, dc
->pc
);
9904 /* indicate that the hash table must be used to find the next TB */
9908 /* nothing more to generate */
9911 gen_helper_wfi(cpu_env
);
9914 gen_exception(EXCP_SWI
);
9918 gen_set_label(dc
->condlabel
);
9919 gen_set_condexec(dc
);
9920 gen_goto_tb(dc
, 1, dc
->pc
);
9926 gen_icount_end(tb
, num_insns
);
9927 *gen_opc_ptr
= INDEX_op_end
;
9930 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9931 qemu_log("----------------\n");
9932 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9933 log_target_disas(pc_start
, dc
->pc
- pc_start
,
9934 dc
->thumb
| (dc
->bswap_code
<< 1));
9939 j
= gen_opc_ptr
- gen_opc_buf
;
9942 gen_opc_instr_start
[lj
++] = 0;
9944 tb
->size
= dc
->pc
- pc_start
;
9945 tb
->icount
= num_insns
;
9949 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
9951 gen_intermediate_code_internal(env
, tb
, 0);
9954 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
9956 gen_intermediate_code_internal(env
, tb
, 1);
9959 static const char *cpu_mode_names
[16] = {
9960 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9961 "???", "???", "???", "und", "???", "???", "???", "sys"
9964 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
9971 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9973 cpu_fprintf(f
, "\n");
9975 cpu_fprintf(f
, " ");
9977 psr
= cpsr_read(env
);
9978 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9980 psr
& (1 << 31) ? 'N' : '-',
9981 psr
& (1 << 30) ? 'Z' : '-',
9982 psr
& (1 << 29) ? 'C' : '-',
9983 psr
& (1 << 28) ? 'V' : '-',
9984 psr
& CPSR_T
? 'T' : 'A',
9985 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9987 if (flags
& CPU_DUMP_FPU
) {
9989 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
9992 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
9995 for (i
= 0; i
< numvfpregs
; i
++) {
9996 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
9997 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
9999 i
* 2 + 1, (uint32_t)(v
>> 32),
10002 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10006 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10008 env
->regs
[15] = gen_opc_pc
[pc_pos
];
10009 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];