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/>.
28 #include "disas/disas.h"
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 "exec/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 /* Return (b << 32) + a. Mark inputs as dead */
281 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
283 TCGv_i64 tmp64
= tcg_temp_new_i64();
285 tcg_gen_extu_i32_i64(tmp64
, b
);
286 tcg_temp_free_i32(b
);
287 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
288 tcg_gen_add_i64(a
, tmp64
, a
);
290 tcg_temp_free_i64(tmp64
);
294 /* Return (b << 32) - a. Mark inputs as dead. */
295 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
297 TCGv_i64 tmp64
= tcg_temp_new_i64();
299 tcg_gen_extu_i32_i64(tmp64
, b
);
300 tcg_temp_free_i32(b
);
301 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
302 tcg_gen_sub_i64(a
, tmp64
, a
);
304 tcg_temp_free_i64(tmp64
);
308 /* FIXME: Most targets have native widening multiplication.
309 It would be good to use that instead of a full wide multiply. */
310 /* 32x32->64 multiply. Marks inputs as dead. */
311 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
313 TCGv_i64 tmp1
= tcg_temp_new_i64();
314 TCGv_i64 tmp2
= tcg_temp_new_i64();
316 tcg_gen_extu_i32_i64(tmp1
, a
);
317 tcg_temp_free_i32(a
);
318 tcg_gen_extu_i32_i64(tmp2
, b
);
319 tcg_temp_free_i32(b
);
320 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
321 tcg_temp_free_i64(tmp2
);
325 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
327 TCGv_i64 tmp1
= tcg_temp_new_i64();
328 TCGv_i64 tmp2
= tcg_temp_new_i64();
330 tcg_gen_ext_i32_i64(tmp1
, a
);
331 tcg_temp_free_i32(a
);
332 tcg_gen_ext_i32_i64(tmp2
, b
);
333 tcg_temp_free_i32(b
);
334 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
335 tcg_temp_free_i64(tmp2
);
339 /* Swap low and high halfwords. */
340 static void gen_swap_half(TCGv var
)
342 TCGv tmp
= tcg_temp_new_i32();
343 tcg_gen_shri_i32(tmp
, var
, 16);
344 tcg_gen_shli_i32(var
, var
, 16);
345 tcg_gen_or_i32(var
, var
, tmp
);
346 tcg_temp_free_i32(tmp
);
349 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
350 tmp = (t0 ^ t1) & 0x8000;
353 t0 = (t0 + t1) ^ tmp;
356 static void gen_add16(TCGv t0
, TCGv t1
)
358 TCGv tmp
= tcg_temp_new_i32();
359 tcg_gen_xor_i32(tmp
, t0
, t1
);
360 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
361 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
362 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
363 tcg_gen_add_i32(t0
, t0
, t1
);
364 tcg_gen_xor_i32(t0
, t0
, tmp
);
365 tcg_temp_free_i32(tmp
);
366 tcg_temp_free_i32(t1
);
369 /* Set CF to the top bit of var. */
370 static void gen_set_CF_bit31(TCGv var
)
372 tcg_gen_shri_i32(cpu_CF
, var
, 31);
375 /* Set N and Z flags from var. */
376 static inline void gen_logic_CC(TCGv var
)
378 tcg_gen_mov_i32(cpu_NF
, var
);
379 tcg_gen_mov_i32(cpu_ZF
, var
);
383 static void gen_adc(TCGv t0
, TCGv t1
)
385 tcg_gen_add_i32(t0
, t0
, t1
);
386 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
389 /* dest = T0 + T1 + CF. */
390 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
392 tcg_gen_add_i32(dest
, t0
, t1
);
393 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
396 /* dest = T0 - T1 + CF - 1. */
397 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
399 tcg_gen_sub_i32(dest
, t0
, t1
);
400 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
401 tcg_gen_subi_i32(dest
, dest
, 1);
404 /* dest = T0 + T1. Compute C, N, V and Z flags */
405 static void gen_add_CC(TCGv dest
, TCGv t0
, TCGv t1
)
408 tcg_gen_add_i32(cpu_NF
, t0
, t1
);
409 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
410 tcg_gen_setcond_i32(TCG_COND_LTU
, cpu_CF
, cpu_NF
, t0
);
411 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
412 tmp
= tcg_temp_new_i32();
413 tcg_gen_xor_i32(tmp
, t0
, t1
);
414 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
415 tcg_temp_free_i32(tmp
);
416 tcg_gen_mov_i32(dest
, cpu_NF
);
419 /* dest = T0 - T1. Compute C, N, V and Z flags */
420 static void gen_sub_CC(TCGv dest
, TCGv t0
, TCGv t1
)
423 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
424 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
425 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
426 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
427 tmp
= tcg_temp_new_i32();
428 tcg_gen_xor_i32(tmp
, t0
, t1
);
429 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
430 tcg_temp_free_i32(tmp
);
431 tcg_gen_mov_i32(dest
, cpu_NF
);
434 #define GEN_SHIFT(name) \
435 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
437 TCGv tmp1, tmp2, tmp3; \
438 tmp1 = tcg_temp_new_i32(); \
439 tcg_gen_andi_i32(tmp1, t1, 0xff); \
440 tmp2 = tcg_const_i32(0); \
441 tmp3 = tcg_const_i32(0x1f); \
442 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
443 tcg_temp_free_i32(tmp3); \
444 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
445 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
446 tcg_temp_free_i32(tmp2); \
447 tcg_temp_free_i32(tmp1); \
453 static void gen_sar(TCGv dest
, TCGv t0
, TCGv t1
)
456 tmp1
= tcg_temp_new_i32();
457 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
458 tmp2
= tcg_const_i32(0x1f);
459 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
460 tcg_temp_free_i32(tmp2
);
461 tcg_gen_sar_i32(dest
, t0
, tmp1
);
462 tcg_temp_free_i32(tmp1
);
465 static void tcg_gen_abs_i32(TCGv dest
, TCGv src
)
467 TCGv c0
= tcg_const_i32(0);
468 TCGv tmp
= tcg_temp_new_i32();
469 tcg_gen_neg_i32(tmp
, src
);
470 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
471 tcg_temp_free_i32(c0
);
472 tcg_temp_free_i32(tmp
);
475 static void shifter_out_im(TCGv var
, int shift
)
478 tcg_gen_andi_i32(cpu_CF
, var
, 1);
480 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
482 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
487 /* Shift by immediate. Includes special handling for shift == 0. */
488 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
494 shifter_out_im(var
, 32 - shift
);
495 tcg_gen_shli_i32(var
, var
, shift
);
501 tcg_gen_shri_i32(cpu_CF
, var
, 31);
503 tcg_gen_movi_i32(var
, 0);
506 shifter_out_im(var
, shift
- 1);
507 tcg_gen_shri_i32(var
, var
, shift
);
514 shifter_out_im(var
, shift
- 1);
517 tcg_gen_sari_i32(var
, var
, shift
);
519 case 3: /* ROR/RRX */
522 shifter_out_im(var
, shift
- 1);
523 tcg_gen_rotri_i32(var
, var
, shift
); break;
525 TCGv tmp
= tcg_temp_new_i32();
526 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
528 shifter_out_im(var
, 0);
529 tcg_gen_shri_i32(var
, var
, 1);
530 tcg_gen_or_i32(var
, var
, tmp
);
531 tcg_temp_free_i32(tmp
);
536 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
537 TCGv shift
, int flags
)
541 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
542 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
543 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
544 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
549 gen_shl(var
, var
, shift
);
552 gen_shr(var
, var
, shift
);
555 gen_sar(var
, var
, shift
);
557 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
558 tcg_gen_rotr_i32(var
, var
, shift
); break;
561 tcg_temp_free_i32(shift
);
564 #define PAS_OP(pfx) \
566 case 0: gen_pas_helper(glue(pfx,add16)); break; \
567 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
568 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
569 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
570 case 4: gen_pas_helper(glue(pfx,add8)); break; \
571 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
573 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
578 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
580 tmp
= tcg_temp_new_ptr();
581 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
583 tcg_temp_free_ptr(tmp
);
586 tmp
= tcg_temp_new_ptr();
587 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
589 tcg_temp_free_ptr(tmp
);
591 #undef gen_pas_helper
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
605 #undef gen_pas_helper
610 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
611 #define PAS_OP(pfx) \
613 case 0: gen_pas_helper(glue(pfx,add8)); break; \
614 case 1: gen_pas_helper(glue(pfx,add16)); break; \
615 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
616 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
617 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
618 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
620 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
625 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
627 tmp
= tcg_temp_new_ptr();
628 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
630 tcg_temp_free_ptr(tmp
);
633 tmp
= tcg_temp_new_ptr();
634 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
636 tcg_temp_free_ptr(tmp
);
638 #undef gen_pas_helper
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
652 #undef gen_pas_helper
657 static void gen_test_cc(int cc
, int label
)
664 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
667 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
670 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
673 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
676 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
679 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
682 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
685 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
687 case 8: /* hi: C && !Z */
688 inv
= gen_new_label();
689 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
690 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
693 case 9: /* ls: !C || Z */
694 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
695 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
697 case 10: /* ge: N == V -> N ^ V == 0 */
698 tmp
= tcg_temp_new_i32();
699 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
700 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
701 tcg_temp_free_i32(tmp
);
703 case 11: /* lt: N != V -> N ^ V != 0 */
704 tmp
= tcg_temp_new_i32();
705 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
706 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
707 tcg_temp_free_i32(tmp
);
709 case 12: /* gt: !Z && N == V */
710 inv
= gen_new_label();
711 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
712 tmp
= tcg_temp_new_i32();
713 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
714 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
715 tcg_temp_free_i32(tmp
);
718 case 13: /* le: Z || N != V */
719 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
720 tmp
= tcg_temp_new_i32();
721 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
722 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
723 tcg_temp_free_i32(tmp
);
726 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
731 static const uint8_t table_logic_cc
[16] = {
750 /* Set PC and Thumb state from an immediate address. */
751 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
755 s
->is_jmp
= DISAS_UPDATE
;
756 if (s
->thumb
!= (addr
& 1)) {
757 tmp
= tcg_temp_new_i32();
758 tcg_gen_movi_i32(tmp
, addr
& 1);
759 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
760 tcg_temp_free_i32(tmp
);
762 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
765 /* Set PC and Thumb state from var. var is marked as dead. */
766 static inline void gen_bx(DisasContext
*s
, TCGv var
)
768 s
->is_jmp
= DISAS_UPDATE
;
769 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
770 tcg_gen_andi_i32(var
, var
, 1);
771 store_cpu_field(var
, thumb
);
774 /* Variant of store_reg which uses branch&exchange logic when storing
775 to r15 in ARM architecture v7 and above. The source must be a temporary
776 and will be marked as dead. */
777 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
780 if (reg
== 15 && ENABLE_ARCH_7
) {
783 store_reg(s
, reg
, var
);
787 /* Variant of store_reg which uses branch&exchange logic when storing
788 * to r15 in ARM architecture v5T and above. This is used for storing
789 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
790 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
791 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
794 if (reg
== 15 && ENABLE_ARCH_5
) {
797 store_reg(s
, reg
, var
);
801 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
803 TCGv tmp
= tcg_temp_new_i32();
804 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
807 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
809 TCGv tmp
= tcg_temp_new_i32();
810 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
813 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
815 TCGv tmp
= tcg_temp_new_i32();
816 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
819 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
821 TCGv tmp
= tcg_temp_new_i32();
822 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
825 static inline TCGv
gen_ld32(TCGv addr
, int index
)
827 TCGv tmp
= tcg_temp_new_i32();
828 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
831 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
833 TCGv_i64 tmp
= tcg_temp_new_i64();
834 tcg_gen_qemu_ld64(tmp
, addr
, index
);
837 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
839 tcg_gen_qemu_st8(val
, addr
, index
);
840 tcg_temp_free_i32(val
);
842 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
844 tcg_gen_qemu_st16(val
, addr
, index
);
845 tcg_temp_free_i32(val
);
847 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
849 tcg_gen_qemu_st32(val
, addr
, index
);
850 tcg_temp_free_i32(val
);
852 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
854 tcg_gen_qemu_st64(val
, addr
, index
);
855 tcg_temp_free_i64(val
);
858 static inline void gen_set_pc_im(uint32_t val
)
860 tcg_gen_movi_i32(cpu_R
[15], val
);
863 /* Force a TB lookup after an instruction that changes the CPU state. */
864 static inline void gen_lookup_tb(DisasContext
*s
)
866 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
867 s
->is_jmp
= DISAS_UPDATE
;
870 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
873 int val
, rm
, shift
, shiftop
;
876 if (!(insn
& (1 << 25))) {
879 if (!(insn
& (1 << 23)))
882 tcg_gen_addi_i32(var
, var
, val
);
886 shift
= (insn
>> 7) & 0x1f;
887 shiftop
= (insn
>> 5) & 3;
888 offset
= load_reg(s
, rm
);
889 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
890 if (!(insn
& (1 << 23)))
891 tcg_gen_sub_i32(var
, var
, offset
);
893 tcg_gen_add_i32(var
, var
, offset
);
894 tcg_temp_free_i32(offset
);
898 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
904 if (insn
& (1 << 22)) {
906 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
907 if (!(insn
& (1 << 23)))
911 tcg_gen_addi_i32(var
, var
, val
);
915 tcg_gen_addi_i32(var
, var
, extra
);
917 offset
= load_reg(s
, rm
);
918 if (!(insn
& (1 << 23)))
919 tcg_gen_sub_i32(var
, var
, offset
);
921 tcg_gen_add_i32(var
, var
, offset
);
922 tcg_temp_free_i32(offset
);
926 static TCGv_ptr
get_fpstatus_ptr(int neon
)
928 TCGv_ptr statusptr
= tcg_temp_new_ptr();
931 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
933 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
935 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
939 #define VFP_OP2(name) \
940 static inline void gen_vfp_##name(int dp) \
942 TCGv_ptr fpst = get_fpstatus_ptr(0); \
944 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
946 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
948 tcg_temp_free_ptr(fpst); \
958 static inline void gen_vfp_F1_mul(int dp
)
960 /* Like gen_vfp_mul() but put result in F1 */
961 TCGv_ptr fpst
= get_fpstatus_ptr(0);
963 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
965 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
967 tcg_temp_free_ptr(fpst
);
970 static inline void gen_vfp_F1_neg(int dp
)
972 /* Like gen_vfp_neg() but put result in F1 */
974 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
976 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
980 static inline void gen_vfp_abs(int dp
)
983 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
985 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
988 static inline void gen_vfp_neg(int dp
)
991 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
993 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
996 static inline void gen_vfp_sqrt(int dp
)
999 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1001 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1004 static inline void gen_vfp_cmp(int dp
)
1007 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1009 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1012 static inline void gen_vfp_cmpe(int dp
)
1015 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1017 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1020 static inline void gen_vfp_F1_ld0(int dp
)
1023 tcg_gen_movi_i64(cpu_F1d
, 0);
1025 tcg_gen_movi_i32(cpu_F1s
, 0);
1028 #define VFP_GEN_ITOF(name) \
1029 static inline void gen_vfp_##name(int dp, int neon) \
1031 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1033 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1035 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1037 tcg_temp_free_ptr(statusptr); \
1044 #define VFP_GEN_FTOI(name) \
1045 static inline void gen_vfp_##name(int dp, int neon) \
1047 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1049 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1051 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1053 tcg_temp_free_ptr(statusptr); \
1062 #define VFP_GEN_FIX(name) \
1063 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1065 TCGv tmp_shift = tcg_const_i32(shift); \
1066 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1068 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1070 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1072 tcg_temp_free_i32(tmp_shift); \
1073 tcg_temp_free_ptr(statusptr); \
1085 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1088 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1090 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1093 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1096 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1098 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1102 vfp_reg_offset (int dp
, int reg
)
1105 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1107 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1108 + offsetof(CPU_DoubleU
, l
.upper
);
1110 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1111 + offsetof(CPU_DoubleU
, l
.lower
);
1115 /* Return the offset of a 32-bit piece of a NEON register.
1116 zero is the least significant end of the register. */
1118 neon_reg_offset (int reg
, int n
)
1122 return vfp_reg_offset(0, sreg
);
1125 static TCGv
neon_load_reg(int reg
, int pass
)
1127 TCGv tmp
= tcg_temp_new_i32();
1128 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1132 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1134 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1135 tcg_temp_free_i32(var
);
1138 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1140 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1143 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1145 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1148 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1149 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1150 #define tcg_gen_st_f32 tcg_gen_st_i32
1151 #define tcg_gen_st_f64 tcg_gen_st_i64
1153 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1156 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1158 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1161 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1164 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1166 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1169 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1172 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1174 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1177 #define ARM_CP_RW_BIT (1 << 20)
1179 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1181 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1184 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1186 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1189 static inline TCGv
iwmmxt_load_creg(int reg
)
1191 TCGv var
= tcg_temp_new_i32();
1192 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1196 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1198 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1199 tcg_temp_free_i32(var
);
1202 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1204 iwmmxt_store_reg(cpu_M0
, rn
);
1207 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1209 iwmmxt_load_reg(cpu_M0
, rn
);
1212 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1214 iwmmxt_load_reg(cpu_V1
, rn
);
1215 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1218 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1220 iwmmxt_load_reg(cpu_V1
, rn
);
1221 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1224 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1226 iwmmxt_load_reg(cpu_V1
, rn
);
1227 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1230 #define IWMMXT_OP(name) \
1231 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1233 iwmmxt_load_reg(cpu_V1, rn); \
1234 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1237 #define IWMMXT_OP_ENV(name) \
1238 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1240 iwmmxt_load_reg(cpu_V1, rn); \
1241 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1244 #define IWMMXT_OP_ENV_SIZE(name) \
1245 IWMMXT_OP_ENV(name##b) \
1246 IWMMXT_OP_ENV(name##w) \
1247 IWMMXT_OP_ENV(name##l)
1249 #define IWMMXT_OP_ENV1(name) \
1250 static inline void gen_op_iwmmxt_##name##_M0(void) \
1252 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1266 IWMMXT_OP_ENV_SIZE(unpackl
)
1267 IWMMXT_OP_ENV_SIZE(unpackh
)
1269 IWMMXT_OP_ENV1(unpacklub
)
1270 IWMMXT_OP_ENV1(unpackluw
)
1271 IWMMXT_OP_ENV1(unpacklul
)
1272 IWMMXT_OP_ENV1(unpackhub
)
1273 IWMMXT_OP_ENV1(unpackhuw
)
1274 IWMMXT_OP_ENV1(unpackhul
)
1275 IWMMXT_OP_ENV1(unpacklsb
)
1276 IWMMXT_OP_ENV1(unpacklsw
)
1277 IWMMXT_OP_ENV1(unpacklsl
)
1278 IWMMXT_OP_ENV1(unpackhsb
)
1279 IWMMXT_OP_ENV1(unpackhsw
)
1280 IWMMXT_OP_ENV1(unpackhsl
)
1282 IWMMXT_OP_ENV_SIZE(cmpeq
)
1283 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1284 IWMMXT_OP_ENV_SIZE(cmpgts
)
1286 IWMMXT_OP_ENV_SIZE(mins
)
1287 IWMMXT_OP_ENV_SIZE(minu
)
1288 IWMMXT_OP_ENV_SIZE(maxs
)
1289 IWMMXT_OP_ENV_SIZE(maxu
)
1291 IWMMXT_OP_ENV_SIZE(subn
)
1292 IWMMXT_OP_ENV_SIZE(addn
)
1293 IWMMXT_OP_ENV_SIZE(subu
)
1294 IWMMXT_OP_ENV_SIZE(addu
)
1295 IWMMXT_OP_ENV_SIZE(subs
)
1296 IWMMXT_OP_ENV_SIZE(adds
)
1298 IWMMXT_OP_ENV(avgb0
)
1299 IWMMXT_OP_ENV(avgb1
)
1300 IWMMXT_OP_ENV(avgw0
)
1301 IWMMXT_OP_ENV(avgw1
)
1305 IWMMXT_OP_ENV(packuw
)
1306 IWMMXT_OP_ENV(packul
)
1307 IWMMXT_OP_ENV(packuq
)
1308 IWMMXT_OP_ENV(packsw
)
1309 IWMMXT_OP_ENV(packsl
)
1310 IWMMXT_OP_ENV(packsq
)
1312 static void gen_op_iwmmxt_set_mup(void)
1315 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1316 tcg_gen_ori_i32(tmp
, tmp
, 2);
1317 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1320 static void gen_op_iwmmxt_set_cup(void)
1323 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1324 tcg_gen_ori_i32(tmp
, tmp
, 1);
1325 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1328 static void gen_op_iwmmxt_setpsr_nz(void)
1330 TCGv tmp
= tcg_temp_new_i32();
1331 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1332 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1335 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1337 iwmmxt_load_reg(cpu_V1
, rn
);
1338 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1339 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1342 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1348 rd
= (insn
>> 16) & 0xf;
1349 tmp
= load_reg(s
, rd
);
1351 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1352 if (insn
& (1 << 24)) {
1354 if (insn
& (1 << 23))
1355 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1357 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1358 tcg_gen_mov_i32(dest
, tmp
);
1359 if (insn
& (1 << 21))
1360 store_reg(s
, rd
, tmp
);
1362 tcg_temp_free_i32(tmp
);
1363 } else if (insn
& (1 << 21)) {
1365 tcg_gen_mov_i32(dest
, tmp
);
1366 if (insn
& (1 << 23))
1367 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1369 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1370 store_reg(s
, rd
, tmp
);
1371 } else if (!(insn
& (1 << 23)))
1376 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1378 int rd
= (insn
>> 0) & 0xf;
1381 if (insn
& (1 << 8)) {
1382 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1385 tmp
= iwmmxt_load_creg(rd
);
1388 tmp
= tcg_temp_new_i32();
1389 iwmmxt_load_reg(cpu_V0
, rd
);
1390 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1392 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1393 tcg_gen_mov_i32(dest
, tmp
);
1394 tcg_temp_free_i32(tmp
);
1398 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1399 (ie. an undefined instruction). */
1400 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1403 int rdhi
, rdlo
, rd0
, rd1
, i
;
1405 TCGv tmp
, tmp2
, tmp3
;
1407 if ((insn
& 0x0e000e00) == 0x0c000000) {
1408 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1410 rdlo
= (insn
>> 12) & 0xf;
1411 rdhi
= (insn
>> 16) & 0xf;
1412 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1413 iwmmxt_load_reg(cpu_V0
, wrd
);
1414 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1415 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1416 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1417 } else { /* TMCRR */
1418 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1419 iwmmxt_store_reg(cpu_V0
, wrd
);
1420 gen_op_iwmmxt_set_mup();
1425 wrd
= (insn
>> 12) & 0xf;
1426 addr
= tcg_temp_new_i32();
1427 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1428 tcg_temp_free_i32(addr
);
1431 if (insn
& ARM_CP_RW_BIT
) {
1432 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1433 tmp
= tcg_temp_new_i32();
1434 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1435 iwmmxt_store_creg(wrd
, tmp
);
1438 if (insn
& (1 << 8)) {
1439 if (insn
& (1 << 22)) { /* WLDRD */
1440 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1442 } else { /* WLDRW wRd */
1443 tmp
= gen_ld32(addr
, IS_USER(s
));
1446 if (insn
& (1 << 22)) { /* WLDRH */
1447 tmp
= gen_ld16u(addr
, IS_USER(s
));
1448 } else { /* WLDRB */
1449 tmp
= gen_ld8u(addr
, IS_USER(s
));
1453 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1454 tcg_temp_free_i32(tmp
);
1456 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1459 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1460 tmp
= iwmmxt_load_creg(wrd
);
1461 gen_st32(tmp
, addr
, IS_USER(s
));
1463 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1464 tmp
= tcg_temp_new_i32();
1465 if (insn
& (1 << 8)) {
1466 if (insn
& (1 << 22)) { /* WSTRD */
1467 tcg_temp_free_i32(tmp
);
1468 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1469 } else { /* WSTRW wRd */
1470 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1471 gen_st32(tmp
, addr
, IS_USER(s
));
1474 if (insn
& (1 << 22)) { /* WSTRH */
1475 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1476 gen_st16(tmp
, addr
, IS_USER(s
));
1477 } else { /* WSTRB */
1478 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1479 gen_st8(tmp
, addr
, IS_USER(s
));
1484 tcg_temp_free_i32(addr
);
1488 if ((insn
& 0x0f000000) != 0x0e000000)
1491 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1492 case 0x000: /* WOR */
1493 wrd
= (insn
>> 12) & 0xf;
1494 rd0
= (insn
>> 0) & 0xf;
1495 rd1
= (insn
>> 16) & 0xf;
1496 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1497 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1498 gen_op_iwmmxt_setpsr_nz();
1499 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1500 gen_op_iwmmxt_set_mup();
1501 gen_op_iwmmxt_set_cup();
1503 case 0x011: /* TMCR */
1506 rd
= (insn
>> 12) & 0xf;
1507 wrd
= (insn
>> 16) & 0xf;
1509 case ARM_IWMMXT_wCID
:
1510 case ARM_IWMMXT_wCASF
:
1512 case ARM_IWMMXT_wCon
:
1513 gen_op_iwmmxt_set_cup();
1515 case ARM_IWMMXT_wCSSF
:
1516 tmp
= iwmmxt_load_creg(wrd
);
1517 tmp2
= load_reg(s
, rd
);
1518 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1519 tcg_temp_free_i32(tmp2
);
1520 iwmmxt_store_creg(wrd
, tmp
);
1522 case ARM_IWMMXT_wCGR0
:
1523 case ARM_IWMMXT_wCGR1
:
1524 case ARM_IWMMXT_wCGR2
:
1525 case ARM_IWMMXT_wCGR3
:
1526 gen_op_iwmmxt_set_cup();
1527 tmp
= load_reg(s
, rd
);
1528 iwmmxt_store_creg(wrd
, tmp
);
1534 case 0x100: /* WXOR */
1535 wrd
= (insn
>> 12) & 0xf;
1536 rd0
= (insn
>> 0) & 0xf;
1537 rd1
= (insn
>> 16) & 0xf;
1538 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1539 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1540 gen_op_iwmmxt_setpsr_nz();
1541 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1542 gen_op_iwmmxt_set_mup();
1543 gen_op_iwmmxt_set_cup();
1545 case 0x111: /* TMRC */
1548 rd
= (insn
>> 12) & 0xf;
1549 wrd
= (insn
>> 16) & 0xf;
1550 tmp
= iwmmxt_load_creg(wrd
);
1551 store_reg(s
, rd
, tmp
);
1553 case 0x300: /* WANDN */
1554 wrd
= (insn
>> 12) & 0xf;
1555 rd0
= (insn
>> 0) & 0xf;
1556 rd1
= (insn
>> 16) & 0xf;
1557 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1558 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1559 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1560 gen_op_iwmmxt_setpsr_nz();
1561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1562 gen_op_iwmmxt_set_mup();
1563 gen_op_iwmmxt_set_cup();
1565 case 0x200: /* WAND */
1566 wrd
= (insn
>> 12) & 0xf;
1567 rd0
= (insn
>> 0) & 0xf;
1568 rd1
= (insn
>> 16) & 0xf;
1569 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1570 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1571 gen_op_iwmmxt_setpsr_nz();
1572 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1573 gen_op_iwmmxt_set_mup();
1574 gen_op_iwmmxt_set_cup();
1576 case 0x810: case 0xa10: /* WMADD */
1577 wrd
= (insn
>> 12) & 0xf;
1578 rd0
= (insn
>> 0) & 0xf;
1579 rd1
= (insn
>> 16) & 0xf;
1580 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1581 if (insn
& (1 << 21))
1582 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1584 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1585 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1586 gen_op_iwmmxt_set_mup();
1588 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1589 wrd
= (insn
>> 12) & 0xf;
1590 rd0
= (insn
>> 16) & 0xf;
1591 rd1
= (insn
>> 0) & 0xf;
1592 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1593 switch ((insn
>> 22) & 3) {
1595 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1598 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1601 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1606 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1607 gen_op_iwmmxt_set_mup();
1608 gen_op_iwmmxt_set_cup();
1610 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1611 wrd
= (insn
>> 12) & 0xf;
1612 rd0
= (insn
>> 16) & 0xf;
1613 rd1
= (insn
>> 0) & 0xf;
1614 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1615 switch ((insn
>> 22) & 3) {
1617 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1620 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1623 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1628 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1629 gen_op_iwmmxt_set_mup();
1630 gen_op_iwmmxt_set_cup();
1632 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1633 wrd
= (insn
>> 12) & 0xf;
1634 rd0
= (insn
>> 16) & 0xf;
1635 rd1
= (insn
>> 0) & 0xf;
1636 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1637 if (insn
& (1 << 22))
1638 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1640 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1641 if (!(insn
& (1 << 20)))
1642 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1643 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1644 gen_op_iwmmxt_set_mup();
1646 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1647 wrd
= (insn
>> 12) & 0xf;
1648 rd0
= (insn
>> 16) & 0xf;
1649 rd1
= (insn
>> 0) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1651 if (insn
& (1 << 21)) {
1652 if (insn
& (1 << 20))
1653 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1655 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1657 if (insn
& (1 << 20))
1658 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1660 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1662 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1663 gen_op_iwmmxt_set_mup();
1665 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1666 wrd
= (insn
>> 12) & 0xf;
1667 rd0
= (insn
>> 16) & 0xf;
1668 rd1
= (insn
>> 0) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1670 if (insn
& (1 << 21))
1671 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1673 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1674 if (!(insn
& (1 << 20))) {
1675 iwmmxt_load_reg(cpu_V1
, wrd
);
1676 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1678 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1679 gen_op_iwmmxt_set_mup();
1681 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1682 wrd
= (insn
>> 12) & 0xf;
1683 rd0
= (insn
>> 16) & 0xf;
1684 rd1
= (insn
>> 0) & 0xf;
1685 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1686 switch ((insn
>> 22) & 3) {
1688 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1691 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1694 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1699 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1700 gen_op_iwmmxt_set_mup();
1701 gen_op_iwmmxt_set_cup();
1703 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1704 wrd
= (insn
>> 12) & 0xf;
1705 rd0
= (insn
>> 16) & 0xf;
1706 rd1
= (insn
>> 0) & 0xf;
1707 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1708 if (insn
& (1 << 22)) {
1709 if (insn
& (1 << 20))
1710 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1712 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1714 if (insn
& (1 << 20))
1715 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1717 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1719 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1720 gen_op_iwmmxt_set_mup();
1721 gen_op_iwmmxt_set_cup();
1723 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1724 wrd
= (insn
>> 12) & 0xf;
1725 rd0
= (insn
>> 16) & 0xf;
1726 rd1
= (insn
>> 0) & 0xf;
1727 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1728 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1729 tcg_gen_andi_i32(tmp
, tmp
, 7);
1730 iwmmxt_load_reg(cpu_V1
, rd1
);
1731 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1732 tcg_temp_free_i32(tmp
);
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 gen_op_iwmmxt_set_mup();
1736 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1737 if (((insn
>> 6) & 3) == 3)
1739 rd
= (insn
>> 12) & 0xf;
1740 wrd
= (insn
>> 16) & 0xf;
1741 tmp
= load_reg(s
, rd
);
1742 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1743 switch ((insn
>> 6) & 3) {
1745 tmp2
= tcg_const_i32(0xff);
1746 tmp3
= tcg_const_i32((insn
& 7) << 3);
1749 tmp2
= tcg_const_i32(0xffff);
1750 tmp3
= tcg_const_i32((insn
& 3) << 4);
1753 tmp2
= tcg_const_i32(0xffffffff);
1754 tmp3
= tcg_const_i32((insn
& 1) << 5);
1760 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1761 tcg_temp_free(tmp3
);
1762 tcg_temp_free(tmp2
);
1763 tcg_temp_free_i32(tmp
);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1765 gen_op_iwmmxt_set_mup();
1767 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1768 rd
= (insn
>> 12) & 0xf;
1769 wrd
= (insn
>> 16) & 0xf;
1770 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1772 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1773 tmp
= tcg_temp_new_i32();
1774 switch ((insn
>> 22) & 3) {
1776 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1777 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1779 tcg_gen_ext8s_i32(tmp
, tmp
);
1781 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1785 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1786 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1788 tcg_gen_ext16s_i32(tmp
, tmp
);
1790 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1794 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1795 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1798 store_reg(s
, rd
, tmp
);
1800 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1801 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1803 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1804 switch ((insn
>> 22) & 3) {
1806 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1809 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1812 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1815 tcg_gen_shli_i32(tmp
, tmp
, 28);
1817 tcg_temp_free_i32(tmp
);
1819 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1820 if (((insn
>> 6) & 3) == 3)
1822 rd
= (insn
>> 12) & 0xf;
1823 wrd
= (insn
>> 16) & 0xf;
1824 tmp
= load_reg(s
, rd
);
1825 switch ((insn
>> 6) & 3) {
1827 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1830 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1833 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1836 tcg_temp_free_i32(tmp
);
1837 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1838 gen_op_iwmmxt_set_mup();
1840 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1841 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1843 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1844 tmp2
= tcg_temp_new_i32();
1845 tcg_gen_mov_i32(tmp2
, tmp
);
1846 switch ((insn
>> 22) & 3) {
1848 for (i
= 0; i
< 7; i
++) {
1849 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1850 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1854 for (i
= 0; i
< 3; i
++) {
1855 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1856 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1860 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1861 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1865 tcg_temp_free_i32(tmp2
);
1866 tcg_temp_free_i32(tmp
);
1868 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1869 wrd
= (insn
>> 12) & 0xf;
1870 rd0
= (insn
>> 16) & 0xf;
1871 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1872 switch ((insn
>> 22) & 3) {
1874 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1877 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1880 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1885 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1886 gen_op_iwmmxt_set_mup();
1888 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1889 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1891 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1892 tmp2
= tcg_temp_new_i32();
1893 tcg_gen_mov_i32(tmp2
, tmp
);
1894 switch ((insn
>> 22) & 3) {
1896 for (i
= 0; i
< 7; i
++) {
1897 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1898 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1902 for (i
= 0; i
< 3; i
++) {
1903 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1904 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1908 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1909 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1913 tcg_temp_free_i32(tmp2
);
1914 tcg_temp_free_i32(tmp
);
1916 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1917 rd
= (insn
>> 12) & 0xf;
1918 rd0
= (insn
>> 16) & 0xf;
1919 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1921 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1922 tmp
= tcg_temp_new_i32();
1923 switch ((insn
>> 22) & 3) {
1925 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1928 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1931 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1934 store_reg(s
, rd
, tmp
);
1936 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1937 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1938 wrd
= (insn
>> 12) & 0xf;
1939 rd0
= (insn
>> 16) & 0xf;
1940 rd1
= (insn
>> 0) & 0xf;
1941 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1942 switch ((insn
>> 22) & 3) {
1944 if (insn
& (1 << 21))
1945 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1947 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1950 if (insn
& (1 << 21))
1951 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1953 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1956 if (insn
& (1 << 21))
1957 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1959 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1964 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1965 gen_op_iwmmxt_set_mup();
1966 gen_op_iwmmxt_set_cup();
1968 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1969 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1970 wrd
= (insn
>> 12) & 0xf;
1971 rd0
= (insn
>> 16) & 0xf;
1972 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1973 switch ((insn
>> 22) & 3) {
1975 if (insn
& (1 << 21))
1976 gen_op_iwmmxt_unpacklsb_M0();
1978 gen_op_iwmmxt_unpacklub_M0();
1981 if (insn
& (1 << 21))
1982 gen_op_iwmmxt_unpacklsw_M0();
1984 gen_op_iwmmxt_unpackluw_M0();
1987 if (insn
& (1 << 21))
1988 gen_op_iwmmxt_unpacklsl_M0();
1990 gen_op_iwmmxt_unpacklul_M0();
1995 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2000 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2001 wrd
= (insn
>> 12) & 0xf;
2002 rd0
= (insn
>> 16) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2004 switch ((insn
>> 22) & 3) {
2006 if (insn
& (1 << 21))
2007 gen_op_iwmmxt_unpackhsb_M0();
2009 gen_op_iwmmxt_unpackhub_M0();
2012 if (insn
& (1 << 21))
2013 gen_op_iwmmxt_unpackhsw_M0();
2015 gen_op_iwmmxt_unpackhuw_M0();
2018 if (insn
& (1 << 21))
2019 gen_op_iwmmxt_unpackhsl_M0();
2021 gen_op_iwmmxt_unpackhul_M0();
2026 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2027 gen_op_iwmmxt_set_mup();
2028 gen_op_iwmmxt_set_cup();
2030 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2031 case 0x214: case 0x614: case 0xa14: case 0xe14:
2032 if (((insn
>> 22) & 3) == 0)
2034 wrd
= (insn
>> 12) & 0xf;
2035 rd0
= (insn
>> 16) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2037 tmp
= tcg_temp_new_i32();
2038 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2039 tcg_temp_free_i32(tmp
);
2042 switch ((insn
>> 22) & 3) {
2044 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2047 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2050 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2053 tcg_temp_free_i32(tmp
);
2054 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2058 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2059 case 0x014: case 0x414: case 0x814: case 0xc14:
2060 if (((insn
>> 22) & 3) == 0)
2062 wrd
= (insn
>> 12) & 0xf;
2063 rd0
= (insn
>> 16) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2065 tmp
= tcg_temp_new_i32();
2066 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2067 tcg_temp_free_i32(tmp
);
2070 switch ((insn
>> 22) & 3) {
2072 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2075 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2078 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2081 tcg_temp_free_i32(tmp
);
2082 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2083 gen_op_iwmmxt_set_mup();
2084 gen_op_iwmmxt_set_cup();
2086 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2087 case 0x114: case 0x514: case 0x914: case 0xd14:
2088 if (((insn
>> 22) & 3) == 0)
2090 wrd
= (insn
>> 12) & 0xf;
2091 rd0
= (insn
>> 16) & 0xf;
2092 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2093 tmp
= tcg_temp_new_i32();
2094 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2095 tcg_temp_free_i32(tmp
);
2098 switch ((insn
>> 22) & 3) {
2100 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2103 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2106 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2109 tcg_temp_free_i32(tmp
);
2110 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2111 gen_op_iwmmxt_set_mup();
2112 gen_op_iwmmxt_set_cup();
2114 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2115 case 0x314: case 0x714: case 0xb14: case 0xf14:
2116 if (((insn
>> 22) & 3) == 0)
2118 wrd
= (insn
>> 12) & 0xf;
2119 rd0
= (insn
>> 16) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2121 tmp
= tcg_temp_new_i32();
2122 switch ((insn
>> 22) & 3) {
2124 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2125 tcg_temp_free_i32(tmp
);
2128 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2131 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2132 tcg_temp_free_i32(tmp
);
2135 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2138 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2139 tcg_temp_free_i32(tmp
);
2142 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2145 tcg_temp_free_i32(tmp
);
2146 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2147 gen_op_iwmmxt_set_mup();
2148 gen_op_iwmmxt_set_cup();
2150 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2151 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2152 wrd
= (insn
>> 12) & 0xf;
2153 rd0
= (insn
>> 16) & 0xf;
2154 rd1
= (insn
>> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2156 switch ((insn
>> 22) & 3) {
2158 if (insn
& (1 << 21))
2159 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2161 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2164 if (insn
& (1 << 21))
2165 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2167 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2170 if (insn
& (1 << 21))
2171 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2173 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2178 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2179 gen_op_iwmmxt_set_mup();
2181 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2182 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2183 wrd
= (insn
>> 12) & 0xf;
2184 rd0
= (insn
>> 16) & 0xf;
2185 rd1
= (insn
>> 0) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2187 switch ((insn
>> 22) & 3) {
2189 if (insn
& (1 << 21))
2190 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2192 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2195 if (insn
& (1 << 21))
2196 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2198 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2201 if (insn
& (1 << 21))
2202 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2204 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2210 gen_op_iwmmxt_set_mup();
2212 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2213 case 0x402: case 0x502: case 0x602: case 0x702:
2214 wrd
= (insn
>> 12) & 0xf;
2215 rd0
= (insn
>> 16) & 0xf;
2216 rd1
= (insn
>> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2218 tmp
= tcg_const_i32((insn
>> 20) & 3);
2219 iwmmxt_load_reg(cpu_V1
, rd1
);
2220 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2222 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2223 gen_op_iwmmxt_set_mup();
2225 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2226 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2227 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2228 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2229 wrd
= (insn
>> 12) & 0xf;
2230 rd0
= (insn
>> 16) & 0xf;
2231 rd1
= (insn
>> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2233 switch ((insn
>> 20) & 0xf) {
2235 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2238 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2241 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2244 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2247 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2250 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2253 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2256 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2259 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2264 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2265 gen_op_iwmmxt_set_mup();
2266 gen_op_iwmmxt_set_cup();
2268 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2269 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2270 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2271 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2272 wrd
= (insn
>> 12) & 0xf;
2273 rd0
= (insn
>> 16) & 0xf;
2274 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2275 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2276 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2278 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2279 gen_op_iwmmxt_set_mup();
2280 gen_op_iwmmxt_set_cup();
2282 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2283 case 0x418: case 0x518: case 0x618: case 0x718:
2284 case 0x818: case 0x918: case 0xa18: case 0xb18:
2285 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2286 wrd
= (insn
>> 12) & 0xf;
2287 rd0
= (insn
>> 16) & 0xf;
2288 rd1
= (insn
>> 0) & 0xf;
2289 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2290 switch ((insn
>> 20) & 0xf) {
2292 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2295 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2298 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2301 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2304 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2307 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2310 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2313 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2316 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2321 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2322 gen_op_iwmmxt_set_mup();
2323 gen_op_iwmmxt_set_cup();
2325 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2326 case 0x408: case 0x508: case 0x608: case 0x708:
2327 case 0x808: case 0x908: case 0xa08: case 0xb08:
2328 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2329 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2331 wrd
= (insn
>> 12) & 0xf;
2332 rd0
= (insn
>> 16) & 0xf;
2333 rd1
= (insn
>> 0) & 0xf;
2334 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2335 switch ((insn
>> 22) & 3) {
2337 if (insn
& (1 << 21))
2338 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2340 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2343 if (insn
& (1 << 21))
2344 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2346 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2349 if (insn
& (1 << 21))
2350 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2352 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2355 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2356 gen_op_iwmmxt_set_mup();
2357 gen_op_iwmmxt_set_cup();
2359 case 0x201: case 0x203: case 0x205: case 0x207:
2360 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2361 case 0x211: case 0x213: case 0x215: case 0x217:
2362 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2363 wrd
= (insn
>> 5) & 0xf;
2364 rd0
= (insn
>> 12) & 0xf;
2365 rd1
= (insn
>> 0) & 0xf;
2366 if (rd0
== 0xf || rd1
== 0xf)
2368 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2369 tmp
= load_reg(s
, rd0
);
2370 tmp2
= load_reg(s
, rd1
);
2371 switch ((insn
>> 16) & 0xf) {
2372 case 0x0: /* TMIA */
2373 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2375 case 0x8: /* TMIAPH */
2376 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2378 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2379 if (insn
& (1 << 16))
2380 tcg_gen_shri_i32(tmp
, tmp
, 16);
2381 if (insn
& (1 << 17))
2382 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2383 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2386 tcg_temp_free_i32(tmp2
);
2387 tcg_temp_free_i32(tmp
);
2390 tcg_temp_free_i32(tmp2
);
2391 tcg_temp_free_i32(tmp
);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2393 gen_op_iwmmxt_set_mup();
2402 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2403 (ie. an undefined instruction). */
2404 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2406 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2409 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2410 /* Multiply with Internal Accumulate Format */
2411 rd0
= (insn
>> 12) & 0xf;
2413 acc
= (insn
>> 5) & 7;
2418 tmp
= load_reg(s
, rd0
);
2419 tmp2
= load_reg(s
, rd1
);
2420 switch ((insn
>> 16) & 0xf) {
2422 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2424 case 0x8: /* MIAPH */
2425 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2427 case 0xc: /* MIABB */
2428 case 0xd: /* MIABT */
2429 case 0xe: /* MIATB */
2430 case 0xf: /* MIATT */
2431 if (insn
& (1 << 16))
2432 tcg_gen_shri_i32(tmp
, tmp
, 16);
2433 if (insn
& (1 << 17))
2434 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2435 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2440 tcg_temp_free_i32(tmp2
);
2441 tcg_temp_free_i32(tmp
);
2443 gen_op_iwmmxt_movq_wRn_M0(acc
);
2447 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2448 /* Internal Accumulator Access Format */
2449 rdhi
= (insn
>> 16) & 0xf;
2450 rdlo
= (insn
>> 12) & 0xf;
2456 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2457 iwmmxt_load_reg(cpu_V0
, acc
);
2458 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2459 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2460 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2461 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2463 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2464 iwmmxt_store_reg(cpu_V0
, acc
);
2472 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2473 #define VFP_SREG(insn, bigbit, smallbit) \
2474 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2475 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2476 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2477 reg = (((insn) >> (bigbit)) & 0x0f) \
2478 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2480 if (insn & (1 << (smallbit))) \
2482 reg = ((insn) >> (bigbit)) & 0x0f; \
2485 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2486 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2487 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2488 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2489 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2490 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2492 /* Move between integer and VFP cores. */
2493 static TCGv
gen_vfp_mrs(void)
2495 TCGv tmp
= tcg_temp_new_i32();
2496 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2500 static void gen_vfp_msr(TCGv tmp
)
2502 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2503 tcg_temp_free_i32(tmp
);
2506 static void gen_neon_dup_u8(TCGv var
, int shift
)
2508 TCGv tmp
= tcg_temp_new_i32();
2510 tcg_gen_shri_i32(var
, var
, shift
);
2511 tcg_gen_ext8u_i32(var
, var
);
2512 tcg_gen_shli_i32(tmp
, var
, 8);
2513 tcg_gen_or_i32(var
, var
, tmp
);
2514 tcg_gen_shli_i32(tmp
, var
, 16);
2515 tcg_gen_or_i32(var
, var
, tmp
);
2516 tcg_temp_free_i32(tmp
);
2519 static void gen_neon_dup_low16(TCGv var
)
2521 TCGv tmp
= tcg_temp_new_i32();
2522 tcg_gen_ext16u_i32(var
, var
);
2523 tcg_gen_shli_i32(tmp
, var
, 16);
2524 tcg_gen_or_i32(var
, var
, tmp
);
2525 tcg_temp_free_i32(tmp
);
2528 static void gen_neon_dup_high16(TCGv var
)
2530 TCGv tmp
= tcg_temp_new_i32();
2531 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2532 tcg_gen_shri_i32(tmp
, var
, 16);
2533 tcg_gen_or_i32(var
, var
, tmp
);
2534 tcg_temp_free_i32(tmp
);
2537 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2539 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2543 tmp
= gen_ld8u(addr
, IS_USER(s
));
2544 gen_neon_dup_u8(tmp
, 0);
2547 tmp
= gen_ld16u(addr
, IS_USER(s
));
2548 gen_neon_dup_low16(tmp
);
2551 tmp
= gen_ld32(addr
, IS_USER(s
));
2553 default: /* Avoid compiler warnings. */
2559 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2560 (ie. an undefined instruction). */
2561 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2563 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2569 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2572 if (!s
->vfp_enabled
) {
2573 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2574 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2576 rn
= (insn
>> 16) & 0xf;
2577 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2578 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2581 dp
= ((insn
& 0xf00) == 0xb00);
2582 switch ((insn
>> 24) & 0xf) {
2584 if (insn
& (1 << 4)) {
2585 /* single register transfer */
2586 rd
= (insn
>> 12) & 0xf;
2591 VFP_DREG_N(rn
, insn
);
2594 if (insn
& 0x00c00060
2595 && !arm_feature(env
, ARM_FEATURE_NEON
))
2598 pass
= (insn
>> 21) & 1;
2599 if (insn
& (1 << 22)) {
2601 offset
= ((insn
>> 5) & 3) * 8;
2602 } else if (insn
& (1 << 5)) {
2604 offset
= (insn
& (1 << 6)) ? 16 : 0;
2609 if (insn
& ARM_CP_RW_BIT
) {
2611 tmp
= neon_load_reg(rn
, pass
);
2615 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2616 if (insn
& (1 << 23))
2622 if (insn
& (1 << 23)) {
2624 tcg_gen_shri_i32(tmp
, tmp
, 16);
2630 tcg_gen_sari_i32(tmp
, tmp
, 16);
2639 store_reg(s
, rd
, tmp
);
2642 tmp
= load_reg(s
, rd
);
2643 if (insn
& (1 << 23)) {
2646 gen_neon_dup_u8(tmp
, 0);
2647 } else if (size
== 1) {
2648 gen_neon_dup_low16(tmp
);
2650 for (n
= 0; n
<= pass
* 2; n
++) {
2651 tmp2
= tcg_temp_new_i32();
2652 tcg_gen_mov_i32(tmp2
, tmp
);
2653 neon_store_reg(rn
, n
, tmp2
);
2655 neon_store_reg(rn
, n
, tmp
);
2660 tmp2
= neon_load_reg(rn
, pass
);
2661 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2662 tcg_temp_free_i32(tmp2
);
2665 tmp2
= neon_load_reg(rn
, pass
);
2666 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2667 tcg_temp_free_i32(tmp2
);
2672 neon_store_reg(rn
, pass
, tmp
);
2676 if ((insn
& 0x6f) != 0x00)
2678 rn
= VFP_SREG_N(insn
);
2679 if (insn
& ARM_CP_RW_BIT
) {
2681 if (insn
& (1 << 21)) {
2682 /* system register */
2687 /* VFP2 allows access to FSID from userspace.
2688 VFP3 restricts all id registers to privileged
2691 && arm_feature(env
, ARM_FEATURE_VFP3
))
2693 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2698 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2700 case ARM_VFP_FPINST
:
2701 case ARM_VFP_FPINST2
:
2702 /* Not present in VFP3. */
2704 || arm_feature(env
, ARM_FEATURE_VFP3
))
2706 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2710 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2711 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2713 tmp
= tcg_temp_new_i32();
2714 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2720 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2722 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2728 gen_mov_F0_vreg(0, rn
);
2729 tmp
= gen_vfp_mrs();
2732 /* Set the 4 flag bits in the CPSR. */
2734 tcg_temp_free_i32(tmp
);
2736 store_reg(s
, rd
, tmp
);
2740 if (insn
& (1 << 21)) {
2742 /* system register */
2747 /* Writes are ignored. */
2750 tmp
= load_reg(s
, rd
);
2751 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2752 tcg_temp_free_i32(tmp
);
2758 /* TODO: VFP subarchitecture support.
2759 * For now, keep the EN bit only */
2760 tmp
= load_reg(s
, rd
);
2761 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2762 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2765 case ARM_VFP_FPINST
:
2766 case ARM_VFP_FPINST2
:
2767 tmp
= load_reg(s
, rd
);
2768 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2774 tmp
= load_reg(s
, rd
);
2776 gen_mov_vreg_F0(0, rn
);
2781 /* data processing */
2782 /* The opcode is in bits 23, 21, 20 and 6. */
2783 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2787 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2789 /* rn is register number */
2790 VFP_DREG_N(rn
, insn
);
2793 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2794 /* Integer or single precision destination. */
2795 rd
= VFP_SREG_D(insn
);
2797 VFP_DREG_D(rd
, insn
);
2800 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2801 /* VCVT from int is always from S reg regardless of dp bit.
2802 * VCVT with immediate frac_bits has same format as SREG_M
2804 rm
= VFP_SREG_M(insn
);
2806 VFP_DREG_M(rm
, insn
);
2809 rn
= VFP_SREG_N(insn
);
2810 if (op
== 15 && rn
== 15) {
2811 /* Double precision destination. */
2812 VFP_DREG_D(rd
, insn
);
2814 rd
= VFP_SREG_D(insn
);
2816 /* NB that we implicitly rely on the encoding for the frac_bits
2817 * in VCVT of fixed to float being the same as that of an SREG_M
2819 rm
= VFP_SREG_M(insn
);
2822 veclen
= s
->vec_len
;
2823 if (op
== 15 && rn
> 3)
2826 /* Shut up compiler warnings. */
2837 /* Figure out what type of vector operation this is. */
2838 if ((rd
& bank_mask
) == 0) {
2843 delta_d
= (s
->vec_stride
>> 1) + 1;
2845 delta_d
= s
->vec_stride
+ 1;
2847 if ((rm
& bank_mask
) == 0) {
2848 /* mixed scalar/vector */
2857 /* Load the initial operands. */
2862 /* Integer source */
2863 gen_mov_F0_vreg(0, rm
);
2868 gen_mov_F0_vreg(dp
, rd
);
2869 gen_mov_F1_vreg(dp
, rm
);
2873 /* Compare with zero */
2874 gen_mov_F0_vreg(dp
, rd
);
2885 /* Source and destination the same. */
2886 gen_mov_F0_vreg(dp
, rd
);
2892 /* VCVTB, VCVTT: only present with the halfprec extension,
2893 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2895 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2898 /* Otherwise fall through */
2900 /* One source operand. */
2901 gen_mov_F0_vreg(dp
, rm
);
2905 /* Two source operands. */
2906 gen_mov_F0_vreg(dp
, rn
);
2907 gen_mov_F1_vreg(dp
, rm
);
2911 /* Perform the calculation. */
2913 case 0: /* VMLA: fd + (fn * fm) */
2914 /* Note that order of inputs to the add matters for NaNs */
2916 gen_mov_F0_vreg(dp
, rd
);
2919 case 1: /* VMLS: fd + -(fn * fm) */
2922 gen_mov_F0_vreg(dp
, rd
);
2925 case 2: /* VNMLS: -fd + (fn * fm) */
2926 /* Note that it isn't valid to replace (-A + B) with (B - A)
2927 * or similar plausible looking simplifications
2928 * because this will give wrong results for NaNs.
2931 gen_mov_F0_vreg(dp
, rd
);
2935 case 3: /* VNMLA: -fd + -(fn * fm) */
2938 gen_mov_F0_vreg(dp
, rd
);
2942 case 4: /* mul: fn * fm */
2945 case 5: /* nmul: -(fn * fm) */
2949 case 6: /* add: fn + fm */
2952 case 7: /* sub: fn - fm */
2955 case 8: /* div: fn / fm */
2958 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2959 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2960 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2961 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2962 /* These are fused multiply-add, and must be done as one
2963 * floating point operation with no rounding between the
2964 * multiplication and addition steps.
2965 * NB that doing the negations here as separate steps is
2966 * correct : an input NaN should come out with its sign bit
2967 * flipped if it is a negated-input.
2969 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
2977 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
2979 frd
= tcg_temp_new_i64();
2980 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
2983 gen_helper_vfp_negd(frd
, frd
);
2985 fpst
= get_fpstatus_ptr(0);
2986 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
2987 cpu_F1d
, frd
, fpst
);
2988 tcg_temp_free_ptr(fpst
);
2989 tcg_temp_free_i64(frd
);
2995 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
2997 frd
= tcg_temp_new_i32();
2998 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3000 gen_helper_vfp_negs(frd
, frd
);
3002 fpst
= get_fpstatus_ptr(0);
3003 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3004 cpu_F1s
, frd
, fpst
);
3005 tcg_temp_free_ptr(fpst
);
3006 tcg_temp_free_i32(frd
);
3009 case 14: /* fconst */
3010 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3013 n
= (insn
<< 12) & 0x80000000;
3014 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3021 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3028 tcg_gen_movi_i32(cpu_F0s
, n
);
3031 case 15: /* extension space */
3045 case 4: /* vcvtb.f32.f16 */
3046 tmp
= gen_vfp_mrs();
3047 tcg_gen_ext16u_i32(tmp
, tmp
);
3048 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3049 tcg_temp_free_i32(tmp
);
3051 case 5: /* vcvtt.f32.f16 */
3052 tmp
= gen_vfp_mrs();
3053 tcg_gen_shri_i32(tmp
, tmp
, 16);
3054 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3055 tcg_temp_free_i32(tmp
);
3057 case 6: /* vcvtb.f16.f32 */
3058 tmp
= tcg_temp_new_i32();
3059 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3060 gen_mov_F0_vreg(0, rd
);
3061 tmp2
= gen_vfp_mrs();
3062 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3063 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3064 tcg_temp_free_i32(tmp2
);
3067 case 7: /* vcvtt.f16.f32 */
3068 tmp
= tcg_temp_new_i32();
3069 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3070 tcg_gen_shli_i32(tmp
, tmp
, 16);
3071 gen_mov_F0_vreg(0, rd
);
3072 tmp2
= gen_vfp_mrs();
3073 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3074 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3075 tcg_temp_free_i32(tmp2
);
3087 case 11: /* cmpez */
3091 case 15: /* single<->double conversion */
3093 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3095 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3097 case 16: /* fuito */
3098 gen_vfp_uito(dp
, 0);
3100 case 17: /* fsito */
3101 gen_vfp_sito(dp
, 0);
3103 case 20: /* fshto */
3104 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3106 gen_vfp_shto(dp
, 16 - rm
, 0);
3108 case 21: /* fslto */
3109 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3111 gen_vfp_slto(dp
, 32 - rm
, 0);
3113 case 22: /* fuhto */
3114 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3116 gen_vfp_uhto(dp
, 16 - rm
, 0);
3118 case 23: /* fulto */
3119 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3121 gen_vfp_ulto(dp
, 32 - rm
, 0);
3123 case 24: /* ftoui */
3124 gen_vfp_toui(dp
, 0);
3126 case 25: /* ftouiz */
3127 gen_vfp_touiz(dp
, 0);
3129 case 26: /* ftosi */
3130 gen_vfp_tosi(dp
, 0);
3132 case 27: /* ftosiz */
3133 gen_vfp_tosiz(dp
, 0);
3135 case 28: /* ftosh */
3136 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3138 gen_vfp_tosh(dp
, 16 - rm
, 0);
3140 case 29: /* ftosl */
3141 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3143 gen_vfp_tosl(dp
, 32 - rm
, 0);
3145 case 30: /* ftouh */
3146 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3148 gen_vfp_touh(dp
, 16 - rm
, 0);
3150 case 31: /* ftoul */
3151 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3153 gen_vfp_toul(dp
, 32 - rm
, 0);
3155 default: /* undefined */
3159 default: /* undefined */
3163 /* Write back the result. */
3164 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3165 ; /* Comparison, do nothing. */
3166 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3167 /* VCVT double to int: always integer result. */
3168 gen_mov_vreg_F0(0, rd
);
3169 else if (op
== 15 && rn
== 15)
3171 gen_mov_vreg_F0(!dp
, rd
);
3173 gen_mov_vreg_F0(dp
, rd
);
3175 /* break out of the loop if we have finished */
3179 if (op
== 15 && delta_m
== 0) {
3180 /* single source one-many */
3182 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3184 gen_mov_vreg_F0(dp
, rd
);
3188 /* Setup the next operands. */
3190 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3194 /* One source operand. */
3195 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3197 gen_mov_F0_vreg(dp
, rm
);
3199 /* Two source operands. */
3200 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3202 gen_mov_F0_vreg(dp
, rn
);
3204 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3206 gen_mov_F1_vreg(dp
, rm
);
3214 if ((insn
& 0x03e00000) == 0x00400000) {
3215 /* two-register transfer */
3216 rn
= (insn
>> 16) & 0xf;
3217 rd
= (insn
>> 12) & 0xf;
3219 VFP_DREG_M(rm
, insn
);
3221 rm
= VFP_SREG_M(insn
);
3224 if (insn
& ARM_CP_RW_BIT
) {
3227 gen_mov_F0_vreg(0, rm
* 2);
3228 tmp
= gen_vfp_mrs();
3229 store_reg(s
, rd
, tmp
);
3230 gen_mov_F0_vreg(0, rm
* 2 + 1);
3231 tmp
= gen_vfp_mrs();
3232 store_reg(s
, rn
, tmp
);
3234 gen_mov_F0_vreg(0, rm
);
3235 tmp
= gen_vfp_mrs();
3236 store_reg(s
, rd
, tmp
);
3237 gen_mov_F0_vreg(0, rm
+ 1);
3238 tmp
= gen_vfp_mrs();
3239 store_reg(s
, rn
, tmp
);
3244 tmp
= load_reg(s
, rd
);
3246 gen_mov_vreg_F0(0, rm
* 2);
3247 tmp
= load_reg(s
, rn
);
3249 gen_mov_vreg_F0(0, rm
* 2 + 1);
3251 tmp
= load_reg(s
, rd
);
3253 gen_mov_vreg_F0(0, rm
);
3254 tmp
= load_reg(s
, rn
);
3256 gen_mov_vreg_F0(0, rm
+ 1);
3261 rn
= (insn
>> 16) & 0xf;
3263 VFP_DREG_D(rd
, insn
);
3265 rd
= VFP_SREG_D(insn
);
3266 if ((insn
& 0x01200000) == 0x01000000) {
3267 /* Single load/store */
3268 offset
= (insn
& 0xff) << 2;
3269 if ((insn
& (1 << 23)) == 0)
3271 if (s
->thumb
&& rn
== 15) {
3272 /* This is actually UNPREDICTABLE */
3273 addr
= tcg_temp_new_i32();
3274 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3276 addr
= load_reg(s
, rn
);
3278 tcg_gen_addi_i32(addr
, addr
, offset
);
3279 if (insn
& (1 << 20)) {
3280 gen_vfp_ld(s
, dp
, addr
);
3281 gen_mov_vreg_F0(dp
, rd
);
3283 gen_mov_F0_vreg(dp
, rd
);
3284 gen_vfp_st(s
, dp
, addr
);
3286 tcg_temp_free_i32(addr
);
3288 /* load/store multiple */
3289 int w
= insn
& (1 << 21);
3291 n
= (insn
>> 1) & 0x7f;
3295 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3296 /* P == U , W == 1 => UNDEF */
3299 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3300 /* UNPREDICTABLE cases for bad immediates: we choose to
3301 * UNDEF to avoid generating huge numbers of TCG ops
3305 if (rn
== 15 && w
) {
3306 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3310 if (s
->thumb
&& rn
== 15) {
3311 /* This is actually UNPREDICTABLE */
3312 addr
= tcg_temp_new_i32();
3313 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3315 addr
= load_reg(s
, rn
);
3317 if (insn
& (1 << 24)) /* pre-decrement */
3318 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3324 for (i
= 0; i
< n
; i
++) {
3325 if (insn
& ARM_CP_RW_BIT
) {
3327 gen_vfp_ld(s
, dp
, addr
);
3328 gen_mov_vreg_F0(dp
, rd
+ i
);
3331 gen_mov_F0_vreg(dp
, rd
+ i
);
3332 gen_vfp_st(s
, dp
, addr
);
3334 tcg_gen_addi_i32(addr
, addr
, offset
);
3338 if (insn
& (1 << 24))
3339 offset
= -offset
* n
;
3340 else if (dp
&& (insn
& 1))
3346 tcg_gen_addi_i32(addr
, addr
, offset
);
3347 store_reg(s
, rn
, addr
);
3349 tcg_temp_free_i32(addr
);
3355 /* Should never happen. */
3361 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3363 TranslationBlock
*tb
;
3366 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3368 gen_set_pc_im(dest
);
3369 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3371 gen_set_pc_im(dest
);
3376 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3378 if (unlikely(s
->singlestep_enabled
)) {
3379 /* An indirect jump so that we still trigger the debug exception. */
3384 gen_goto_tb(s
, 0, dest
);
3385 s
->is_jmp
= DISAS_TB_JUMP
;
3389 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3392 tcg_gen_sari_i32(t0
, t0
, 16);
3396 tcg_gen_sari_i32(t1
, t1
, 16);
3399 tcg_gen_mul_i32(t0
, t0
, t1
);
3402 /* Return the mask of PSR bits set by a MSR instruction. */
3403 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3407 if (flags
& (1 << 0))
3409 if (flags
& (1 << 1))
3411 if (flags
& (1 << 2))
3413 if (flags
& (1 << 3))
3416 /* Mask out undefined bits. */
3417 mask
&= ~CPSR_RESERVED
;
3418 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3420 if (!arm_feature(env
, ARM_FEATURE_V5
))
3421 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3422 if (!arm_feature(env
, ARM_FEATURE_V6
))
3423 mask
&= ~(CPSR_E
| CPSR_GE
);
3424 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3426 /* Mask out execution state bits. */
3429 /* Mask out privileged bits. */
3435 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3436 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3440 /* ??? This is also undefined in system mode. */
3444 tmp
= load_cpu_field(spsr
);
3445 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3446 tcg_gen_andi_i32(t0
, t0
, mask
);
3447 tcg_gen_or_i32(tmp
, tmp
, t0
);
3448 store_cpu_field(tmp
, spsr
);
3450 gen_set_cpsr(t0
, mask
);
3452 tcg_temp_free_i32(t0
);
3457 /* Returns nonzero if access to the PSR is not permitted. */
3458 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3461 tmp
= tcg_temp_new_i32();
3462 tcg_gen_movi_i32(tmp
, val
);
3463 return gen_set_psr(s
, mask
, spsr
, tmp
);
3466 /* Generate an old-style exception return. Marks pc as dead. */
3467 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3470 store_reg(s
, 15, pc
);
3471 tmp
= load_cpu_field(spsr
);
3472 gen_set_cpsr(tmp
, 0xffffffff);
3473 tcg_temp_free_i32(tmp
);
3474 s
->is_jmp
= DISAS_UPDATE
;
3477 /* Generate a v6 exception return. Marks both values as dead. */
3478 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3480 gen_set_cpsr(cpsr
, 0xffffffff);
3481 tcg_temp_free_i32(cpsr
);
3482 store_reg(s
, 15, pc
);
3483 s
->is_jmp
= DISAS_UPDATE
;
3487 gen_set_condexec (DisasContext
*s
)
3489 if (s
->condexec_mask
) {
3490 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3491 TCGv tmp
= tcg_temp_new_i32();
3492 tcg_gen_movi_i32(tmp
, val
);
3493 store_cpu_field(tmp
, condexec_bits
);
3497 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3499 gen_set_condexec(s
);
3500 gen_set_pc_im(s
->pc
- offset
);
3501 gen_exception(excp
);
3502 s
->is_jmp
= DISAS_JUMP
;
3505 static void gen_nop_hint(DisasContext
*s
, int val
)
3509 gen_set_pc_im(s
->pc
);
3510 s
->is_jmp
= DISAS_WFI
;
3514 /* TODO: Implement SEV and WFE. May help SMP performance. */
3520 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3522 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3525 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3526 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3527 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3532 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3535 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3536 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3537 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3542 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3543 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3544 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3545 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3546 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3548 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3549 switch ((size << 1) | u) { \
3551 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3554 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3557 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3560 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3563 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3566 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3568 default: return 1; \
3571 #define GEN_NEON_INTEGER_OP(name) do { \
3572 switch ((size << 1) | u) { \
3574 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3577 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3580 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3583 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3586 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3589 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3591 default: return 1; \
3594 static TCGv
neon_load_scratch(int scratch
)
3596 TCGv tmp
= tcg_temp_new_i32();
3597 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3601 static void neon_store_scratch(int scratch
, TCGv var
)
3603 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3604 tcg_temp_free_i32(var
);
3607 static inline TCGv
neon_get_scalar(int size
, int reg
)
3611 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3613 gen_neon_dup_high16(tmp
);
3615 gen_neon_dup_low16(tmp
);
3618 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3623 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3626 if (!q
&& size
== 2) {
3629 tmp
= tcg_const_i32(rd
);
3630 tmp2
= tcg_const_i32(rm
);
3634 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3637 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3640 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3648 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3651 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3657 tcg_temp_free_i32(tmp
);
3658 tcg_temp_free_i32(tmp2
);
3662 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3665 if (!q
&& size
== 2) {
3668 tmp
= tcg_const_i32(rd
);
3669 tmp2
= tcg_const_i32(rm
);
3673 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3676 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3679 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3687 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3690 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3696 tcg_temp_free_i32(tmp
);
3697 tcg_temp_free_i32(tmp2
);
3701 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3705 rd
= tcg_temp_new_i32();
3706 tmp
= tcg_temp_new_i32();
3708 tcg_gen_shli_i32(rd
, t0
, 8);
3709 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3710 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3711 tcg_gen_or_i32(rd
, rd
, tmp
);
3713 tcg_gen_shri_i32(t1
, t1
, 8);
3714 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3715 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3716 tcg_gen_or_i32(t1
, t1
, tmp
);
3717 tcg_gen_mov_i32(t0
, rd
);
3719 tcg_temp_free_i32(tmp
);
3720 tcg_temp_free_i32(rd
);
3723 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3727 rd
= tcg_temp_new_i32();
3728 tmp
= tcg_temp_new_i32();
3730 tcg_gen_shli_i32(rd
, t0
, 16);
3731 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3732 tcg_gen_or_i32(rd
, rd
, tmp
);
3733 tcg_gen_shri_i32(t1
, t1
, 16);
3734 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3735 tcg_gen_or_i32(t1
, t1
, tmp
);
3736 tcg_gen_mov_i32(t0
, rd
);
3738 tcg_temp_free_i32(tmp
);
3739 tcg_temp_free_i32(rd
);
3747 } neon_ls_element_type
[11] = {
3761 /* Translate a NEON load/store element instruction. Return nonzero if the
3762 instruction is invalid. */
3763 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3782 if (!s
->vfp_enabled
)
3784 VFP_DREG_D(rd
, insn
);
3785 rn
= (insn
>> 16) & 0xf;
3787 load
= (insn
& (1 << 21)) != 0;
3788 if ((insn
& (1 << 23)) == 0) {
3789 /* Load store all elements. */
3790 op
= (insn
>> 8) & 0xf;
3791 size
= (insn
>> 6) & 3;
3794 /* Catch UNDEF cases for bad values of align field */
3797 if (((insn
>> 5) & 1) == 1) {
3802 if (((insn
>> 4) & 3) == 3) {
3809 nregs
= neon_ls_element_type
[op
].nregs
;
3810 interleave
= neon_ls_element_type
[op
].interleave
;
3811 spacing
= neon_ls_element_type
[op
].spacing
;
3812 if (size
== 3 && (interleave
| spacing
) != 1)
3814 addr
= tcg_temp_new_i32();
3815 load_reg_var(s
, addr
, rn
);
3816 stride
= (1 << size
) * interleave
;
3817 for (reg
= 0; reg
< nregs
; reg
++) {
3818 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3819 load_reg_var(s
, addr
, rn
);
3820 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3821 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3822 load_reg_var(s
, addr
, rn
);
3823 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3827 tmp64
= gen_ld64(addr
, IS_USER(s
));
3828 neon_store_reg64(tmp64
, rd
);
3829 tcg_temp_free_i64(tmp64
);
3831 tmp64
= tcg_temp_new_i64();
3832 neon_load_reg64(tmp64
, rd
);
3833 gen_st64(tmp64
, addr
, IS_USER(s
));
3835 tcg_gen_addi_i32(addr
, addr
, stride
);
3837 for (pass
= 0; pass
< 2; pass
++) {
3840 tmp
= gen_ld32(addr
, IS_USER(s
));
3841 neon_store_reg(rd
, pass
, tmp
);
3843 tmp
= neon_load_reg(rd
, pass
);
3844 gen_st32(tmp
, addr
, IS_USER(s
));
3846 tcg_gen_addi_i32(addr
, addr
, stride
);
3847 } else if (size
== 1) {
3849 tmp
= gen_ld16u(addr
, IS_USER(s
));
3850 tcg_gen_addi_i32(addr
, addr
, stride
);
3851 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3852 tcg_gen_addi_i32(addr
, addr
, stride
);
3853 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3854 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3855 tcg_temp_free_i32(tmp2
);
3856 neon_store_reg(rd
, pass
, tmp
);
3858 tmp
= neon_load_reg(rd
, pass
);
3859 tmp2
= tcg_temp_new_i32();
3860 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3861 gen_st16(tmp
, addr
, IS_USER(s
));
3862 tcg_gen_addi_i32(addr
, addr
, stride
);
3863 gen_st16(tmp2
, addr
, IS_USER(s
));
3864 tcg_gen_addi_i32(addr
, addr
, stride
);
3866 } else /* size == 0 */ {
3869 for (n
= 0; n
< 4; n
++) {
3870 tmp
= gen_ld8u(addr
, IS_USER(s
));
3871 tcg_gen_addi_i32(addr
, addr
, stride
);
3875 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3876 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3877 tcg_temp_free_i32(tmp
);
3880 neon_store_reg(rd
, pass
, tmp2
);
3882 tmp2
= neon_load_reg(rd
, pass
);
3883 for (n
= 0; n
< 4; n
++) {
3884 tmp
= tcg_temp_new_i32();
3886 tcg_gen_mov_i32(tmp
, tmp2
);
3888 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3890 gen_st8(tmp
, addr
, IS_USER(s
));
3891 tcg_gen_addi_i32(addr
, addr
, stride
);
3893 tcg_temp_free_i32(tmp2
);
3900 tcg_temp_free_i32(addr
);
3903 size
= (insn
>> 10) & 3;
3905 /* Load single element to all lanes. */
3906 int a
= (insn
>> 4) & 1;
3910 size
= (insn
>> 6) & 3;
3911 nregs
= ((insn
>> 8) & 3) + 1;
3914 if (nregs
!= 4 || a
== 0) {
3917 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3920 if (nregs
== 1 && a
== 1 && size
== 0) {
3923 if (nregs
== 3 && a
== 1) {
3926 addr
= tcg_temp_new_i32();
3927 load_reg_var(s
, addr
, rn
);
3929 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3930 tmp
= gen_load_and_replicate(s
, addr
, size
);
3931 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3932 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3933 if (insn
& (1 << 5)) {
3934 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3935 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3937 tcg_temp_free_i32(tmp
);
3939 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3940 stride
= (insn
& (1 << 5)) ? 2 : 1;
3941 for (reg
= 0; reg
< nregs
; reg
++) {
3942 tmp
= gen_load_and_replicate(s
, addr
, size
);
3943 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3944 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3945 tcg_temp_free_i32(tmp
);
3946 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3950 tcg_temp_free_i32(addr
);
3951 stride
= (1 << size
) * nregs
;
3953 /* Single element. */
3954 int idx
= (insn
>> 4) & 0xf;
3955 pass
= (insn
>> 7) & 1;
3958 shift
= ((insn
>> 5) & 3) * 8;
3962 shift
= ((insn
>> 6) & 1) * 16;
3963 stride
= (insn
& (1 << 5)) ? 2 : 1;
3967 stride
= (insn
& (1 << 6)) ? 2 : 1;
3972 nregs
= ((insn
>> 8) & 3) + 1;
3973 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3976 if (((idx
& (1 << size
)) != 0) ||
3977 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3982 if ((idx
& 1) != 0) {
3987 if (size
== 2 && (idx
& 2) != 0) {
3992 if ((size
== 2) && ((idx
& 3) == 3)) {
3999 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4000 /* Attempts to write off the end of the register file
4001 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4002 * the neon_load_reg() would write off the end of the array.
4006 addr
= tcg_temp_new_i32();
4007 load_reg_var(s
, addr
, rn
);
4008 for (reg
= 0; reg
< nregs
; reg
++) {
4012 tmp
= gen_ld8u(addr
, IS_USER(s
));
4015 tmp
= gen_ld16u(addr
, IS_USER(s
));
4018 tmp
= gen_ld32(addr
, IS_USER(s
));
4020 default: /* Avoid compiler warnings. */
4024 tmp2
= neon_load_reg(rd
, pass
);
4025 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4026 shift
, size
? 16 : 8);
4027 tcg_temp_free_i32(tmp2
);
4029 neon_store_reg(rd
, pass
, tmp
);
4030 } else { /* Store */
4031 tmp
= neon_load_reg(rd
, pass
);
4033 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4036 gen_st8(tmp
, addr
, IS_USER(s
));
4039 gen_st16(tmp
, addr
, IS_USER(s
));
4042 gen_st32(tmp
, addr
, IS_USER(s
));
4047 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4049 tcg_temp_free_i32(addr
);
4050 stride
= nregs
* (1 << size
);
4056 base
= load_reg(s
, rn
);
4058 tcg_gen_addi_i32(base
, base
, stride
);
4061 index
= load_reg(s
, rm
);
4062 tcg_gen_add_i32(base
, base
, index
);
4063 tcg_temp_free_i32(index
);
4065 store_reg(s
, rn
, base
);
4070 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4071 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4073 tcg_gen_and_i32(t
, t
, c
);
4074 tcg_gen_andc_i32(f
, f
, c
);
4075 tcg_gen_or_i32(dest
, t
, f
);
4078 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4081 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4082 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4083 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4088 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4091 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4092 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4093 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4098 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4101 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4102 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4103 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4108 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4111 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4112 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4113 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4118 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4124 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4125 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4130 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4131 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4138 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4139 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4144 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4145 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4152 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4156 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4157 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4158 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4163 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4164 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4165 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4169 tcg_temp_free_i32(src
);
4172 static inline void gen_neon_addl(int size
)
4175 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4176 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4177 case 2: tcg_gen_add_i64(CPU_V001
); break;
4182 static inline void gen_neon_subl(int size
)
4185 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4186 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4187 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4192 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4195 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4196 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4198 tcg_gen_neg_i64(var
, var
);
4204 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4207 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4208 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4213 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4217 switch ((size
<< 1) | u
) {
4218 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4219 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4220 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4221 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4223 tmp
= gen_muls_i64_i32(a
, b
);
4224 tcg_gen_mov_i64(dest
, tmp
);
4225 tcg_temp_free_i64(tmp
);
4228 tmp
= gen_mulu_i64_i32(a
, b
);
4229 tcg_gen_mov_i64(dest
, tmp
);
4230 tcg_temp_free_i64(tmp
);
4235 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4236 Don't forget to clean them now. */
4238 tcg_temp_free_i32(a
);
4239 tcg_temp_free_i32(b
);
4243 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4247 gen_neon_unarrow_sats(size
, dest
, src
);
4249 gen_neon_narrow(size
, dest
, src
);
4253 gen_neon_narrow_satu(size
, dest
, src
);
4255 gen_neon_narrow_sats(size
, dest
, src
);
4260 /* Symbolic constants for op fields for Neon 3-register same-length.
4261 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4264 #define NEON_3R_VHADD 0
4265 #define NEON_3R_VQADD 1
4266 #define NEON_3R_VRHADD 2
4267 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4268 #define NEON_3R_VHSUB 4
4269 #define NEON_3R_VQSUB 5
4270 #define NEON_3R_VCGT 6
4271 #define NEON_3R_VCGE 7
4272 #define NEON_3R_VSHL 8
4273 #define NEON_3R_VQSHL 9
4274 #define NEON_3R_VRSHL 10
4275 #define NEON_3R_VQRSHL 11
4276 #define NEON_3R_VMAX 12
4277 #define NEON_3R_VMIN 13
4278 #define NEON_3R_VABD 14
4279 #define NEON_3R_VABA 15
4280 #define NEON_3R_VADD_VSUB 16
4281 #define NEON_3R_VTST_VCEQ 17
4282 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4283 #define NEON_3R_VMUL 19
4284 #define NEON_3R_VPMAX 20
4285 #define NEON_3R_VPMIN 21
4286 #define NEON_3R_VQDMULH_VQRDMULH 22
4287 #define NEON_3R_VPADD 23
4288 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4289 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4290 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4291 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4292 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4293 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4294 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4296 static const uint8_t neon_3r_sizes
[] = {
4297 [NEON_3R_VHADD
] = 0x7,
4298 [NEON_3R_VQADD
] = 0xf,
4299 [NEON_3R_VRHADD
] = 0x7,
4300 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4301 [NEON_3R_VHSUB
] = 0x7,
4302 [NEON_3R_VQSUB
] = 0xf,
4303 [NEON_3R_VCGT
] = 0x7,
4304 [NEON_3R_VCGE
] = 0x7,
4305 [NEON_3R_VSHL
] = 0xf,
4306 [NEON_3R_VQSHL
] = 0xf,
4307 [NEON_3R_VRSHL
] = 0xf,
4308 [NEON_3R_VQRSHL
] = 0xf,
4309 [NEON_3R_VMAX
] = 0x7,
4310 [NEON_3R_VMIN
] = 0x7,
4311 [NEON_3R_VABD
] = 0x7,
4312 [NEON_3R_VABA
] = 0x7,
4313 [NEON_3R_VADD_VSUB
] = 0xf,
4314 [NEON_3R_VTST_VCEQ
] = 0x7,
4315 [NEON_3R_VML
] = 0x7,
4316 [NEON_3R_VMUL
] = 0x7,
4317 [NEON_3R_VPMAX
] = 0x7,
4318 [NEON_3R_VPMIN
] = 0x7,
4319 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4320 [NEON_3R_VPADD
] = 0x7,
4321 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4322 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4323 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4324 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4325 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4326 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4327 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4330 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4331 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4334 #define NEON_2RM_VREV64 0
4335 #define NEON_2RM_VREV32 1
4336 #define NEON_2RM_VREV16 2
4337 #define NEON_2RM_VPADDL 4
4338 #define NEON_2RM_VPADDL_U 5
4339 #define NEON_2RM_VCLS 8
4340 #define NEON_2RM_VCLZ 9
4341 #define NEON_2RM_VCNT 10
4342 #define NEON_2RM_VMVN 11
4343 #define NEON_2RM_VPADAL 12
4344 #define NEON_2RM_VPADAL_U 13
4345 #define NEON_2RM_VQABS 14
4346 #define NEON_2RM_VQNEG 15
4347 #define NEON_2RM_VCGT0 16
4348 #define NEON_2RM_VCGE0 17
4349 #define NEON_2RM_VCEQ0 18
4350 #define NEON_2RM_VCLE0 19
4351 #define NEON_2RM_VCLT0 20
4352 #define NEON_2RM_VABS 22
4353 #define NEON_2RM_VNEG 23
4354 #define NEON_2RM_VCGT0_F 24
4355 #define NEON_2RM_VCGE0_F 25
4356 #define NEON_2RM_VCEQ0_F 26
4357 #define NEON_2RM_VCLE0_F 27
4358 #define NEON_2RM_VCLT0_F 28
4359 #define NEON_2RM_VABS_F 30
4360 #define NEON_2RM_VNEG_F 31
4361 #define NEON_2RM_VSWP 32
4362 #define NEON_2RM_VTRN 33
4363 #define NEON_2RM_VUZP 34
4364 #define NEON_2RM_VZIP 35
4365 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4366 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4367 #define NEON_2RM_VSHLL 38
4368 #define NEON_2RM_VCVT_F16_F32 44
4369 #define NEON_2RM_VCVT_F32_F16 46
4370 #define NEON_2RM_VRECPE 56
4371 #define NEON_2RM_VRSQRTE 57
4372 #define NEON_2RM_VRECPE_F 58
4373 #define NEON_2RM_VRSQRTE_F 59
4374 #define NEON_2RM_VCVT_FS 60
4375 #define NEON_2RM_VCVT_FU 61
4376 #define NEON_2RM_VCVT_SF 62
4377 #define NEON_2RM_VCVT_UF 63
4379 static int neon_2rm_is_float_op(int op
)
4381 /* Return true if this neon 2reg-misc op is float-to-float */
4382 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4383 op
>= NEON_2RM_VRECPE_F
);
4386 /* Each entry in this array has bit n set if the insn allows
4387 * size value n (otherwise it will UNDEF). Since unallocated
4388 * op values will have no bits set they always UNDEF.
4390 static const uint8_t neon_2rm_sizes
[] = {
4391 [NEON_2RM_VREV64
] = 0x7,
4392 [NEON_2RM_VREV32
] = 0x3,
4393 [NEON_2RM_VREV16
] = 0x1,
4394 [NEON_2RM_VPADDL
] = 0x7,
4395 [NEON_2RM_VPADDL_U
] = 0x7,
4396 [NEON_2RM_VCLS
] = 0x7,
4397 [NEON_2RM_VCLZ
] = 0x7,
4398 [NEON_2RM_VCNT
] = 0x1,
4399 [NEON_2RM_VMVN
] = 0x1,
4400 [NEON_2RM_VPADAL
] = 0x7,
4401 [NEON_2RM_VPADAL_U
] = 0x7,
4402 [NEON_2RM_VQABS
] = 0x7,
4403 [NEON_2RM_VQNEG
] = 0x7,
4404 [NEON_2RM_VCGT0
] = 0x7,
4405 [NEON_2RM_VCGE0
] = 0x7,
4406 [NEON_2RM_VCEQ0
] = 0x7,
4407 [NEON_2RM_VCLE0
] = 0x7,
4408 [NEON_2RM_VCLT0
] = 0x7,
4409 [NEON_2RM_VABS
] = 0x7,
4410 [NEON_2RM_VNEG
] = 0x7,
4411 [NEON_2RM_VCGT0_F
] = 0x4,
4412 [NEON_2RM_VCGE0_F
] = 0x4,
4413 [NEON_2RM_VCEQ0_F
] = 0x4,
4414 [NEON_2RM_VCLE0_F
] = 0x4,
4415 [NEON_2RM_VCLT0_F
] = 0x4,
4416 [NEON_2RM_VABS_F
] = 0x4,
4417 [NEON_2RM_VNEG_F
] = 0x4,
4418 [NEON_2RM_VSWP
] = 0x1,
4419 [NEON_2RM_VTRN
] = 0x7,
4420 [NEON_2RM_VUZP
] = 0x7,
4421 [NEON_2RM_VZIP
] = 0x7,
4422 [NEON_2RM_VMOVN
] = 0x7,
4423 [NEON_2RM_VQMOVN
] = 0x7,
4424 [NEON_2RM_VSHLL
] = 0x7,
4425 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4426 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4427 [NEON_2RM_VRECPE
] = 0x4,
4428 [NEON_2RM_VRSQRTE
] = 0x4,
4429 [NEON_2RM_VRECPE_F
] = 0x4,
4430 [NEON_2RM_VRSQRTE_F
] = 0x4,
4431 [NEON_2RM_VCVT_FS
] = 0x4,
4432 [NEON_2RM_VCVT_FU
] = 0x4,
4433 [NEON_2RM_VCVT_SF
] = 0x4,
4434 [NEON_2RM_VCVT_UF
] = 0x4,
4437 /* Translate a NEON data processing instruction. Return nonzero if the
4438 instruction is invalid.
4439 We process data in a mixture of 32-bit and 64-bit chunks.
4440 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4442 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4454 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4457 if (!s
->vfp_enabled
)
4459 q
= (insn
& (1 << 6)) != 0;
4460 u
= (insn
>> 24) & 1;
4461 VFP_DREG_D(rd
, insn
);
4462 VFP_DREG_N(rn
, insn
);
4463 VFP_DREG_M(rm
, insn
);
4464 size
= (insn
>> 20) & 3;
4465 if ((insn
& (1 << 23)) == 0) {
4466 /* Three register same length. */
4467 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4468 /* Catch invalid op and bad size combinations: UNDEF */
4469 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4472 /* All insns of this form UNDEF for either this condition or the
4473 * superset of cases "Q==1"; we catch the latter later.
4475 if (q
&& ((rd
| rn
| rm
) & 1)) {
4478 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4479 /* 64-bit element instructions. */
4480 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4481 neon_load_reg64(cpu_V0
, rn
+ pass
);
4482 neon_load_reg64(cpu_V1
, rm
+ pass
);
4486 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4489 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4495 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4498 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4504 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4506 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4511 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4514 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4520 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4522 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4525 case NEON_3R_VQRSHL
:
4527 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4530 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4534 case NEON_3R_VADD_VSUB
:
4536 tcg_gen_sub_i64(CPU_V001
);
4538 tcg_gen_add_i64(CPU_V001
);
4544 neon_store_reg64(cpu_V0
, rd
+ pass
);
4553 case NEON_3R_VQRSHL
:
4556 /* Shift instruction operands are reversed. */
4571 case NEON_3R_FLOAT_ARITH
:
4572 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4574 case NEON_3R_FLOAT_MINMAX
:
4575 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4577 case NEON_3R_FLOAT_CMP
:
4579 /* no encoding for U=0 C=1x */
4583 case NEON_3R_FLOAT_ACMP
:
4588 case NEON_3R_VRECPS_VRSQRTS
:
4594 if (u
&& (size
!= 0)) {
4595 /* UNDEF on invalid size for polynomial subcase */
4600 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4608 if (pairwise
&& q
) {
4609 /* All the pairwise insns UNDEF if Q is set */
4613 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4618 tmp
= neon_load_reg(rn
, 0);
4619 tmp2
= neon_load_reg(rn
, 1);
4621 tmp
= neon_load_reg(rm
, 0);
4622 tmp2
= neon_load_reg(rm
, 1);
4626 tmp
= neon_load_reg(rn
, pass
);
4627 tmp2
= neon_load_reg(rm
, pass
);
4631 GEN_NEON_INTEGER_OP(hadd
);
4634 GEN_NEON_INTEGER_OP_ENV(qadd
);
4636 case NEON_3R_VRHADD
:
4637 GEN_NEON_INTEGER_OP(rhadd
);
4639 case NEON_3R_LOGIC
: /* Logic ops. */
4640 switch ((u
<< 2) | size
) {
4642 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4645 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4648 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4651 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4654 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4657 tmp3
= neon_load_reg(rd
, pass
);
4658 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4659 tcg_temp_free_i32(tmp3
);
4662 tmp3
= neon_load_reg(rd
, pass
);
4663 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4664 tcg_temp_free_i32(tmp3
);
4667 tmp3
= neon_load_reg(rd
, pass
);
4668 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4669 tcg_temp_free_i32(tmp3
);
4674 GEN_NEON_INTEGER_OP(hsub
);
4677 GEN_NEON_INTEGER_OP_ENV(qsub
);
4680 GEN_NEON_INTEGER_OP(cgt
);
4683 GEN_NEON_INTEGER_OP(cge
);
4686 GEN_NEON_INTEGER_OP(shl
);
4689 GEN_NEON_INTEGER_OP_ENV(qshl
);
4692 GEN_NEON_INTEGER_OP(rshl
);
4694 case NEON_3R_VQRSHL
:
4695 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4698 GEN_NEON_INTEGER_OP(max
);
4701 GEN_NEON_INTEGER_OP(min
);
4704 GEN_NEON_INTEGER_OP(abd
);
4707 GEN_NEON_INTEGER_OP(abd
);
4708 tcg_temp_free_i32(tmp2
);
4709 tmp2
= neon_load_reg(rd
, pass
);
4710 gen_neon_add(size
, tmp
, tmp2
);
4712 case NEON_3R_VADD_VSUB
:
4713 if (!u
) { /* VADD */
4714 gen_neon_add(size
, tmp
, tmp2
);
4717 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4718 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4719 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4724 case NEON_3R_VTST_VCEQ
:
4725 if (!u
) { /* VTST */
4727 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4728 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4729 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4734 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4735 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4736 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4741 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4743 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4744 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4745 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4748 tcg_temp_free_i32(tmp2
);
4749 tmp2
= neon_load_reg(rd
, pass
);
4751 gen_neon_rsb(size
, tmp
, tmp2
);
4753 gen_neon_add(size
, tmp
, tmp2
);
4757 if (u
) { /* polynomial */
4758 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4759 } else { /* Integer */
4761 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4762 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4763 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4769 GEN_NEON_INTEGER_OP(pmax
);
4772 GEN_NEON_INTEGER_OP(pmin
);
4774 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4775 if (!u
) { /* VQDMULH */
4778 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4781 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4785 } else { /* VQRDMULH */
4788 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4791 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4799 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4800 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4801 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4805 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4807 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4808 switch ((u
<< 2) | size
) {
4811 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4814 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4817 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4822 tcg_temp_free_ptr(fpstatus
);
4825 case NEON_3R_FLOAT_MULTIPLY
:
4827 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4828 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4830 tcg_temp_free_i32(tmp2
);
4831 tmp2
= neon_load_reg(rd
, pass
);
4833 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4835 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4838 tcg_temp_free_ptr(fpstatus
);
4841 case NEON_3R_FLOAT_CMP
:
4843 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4845 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4848 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4850 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4853 tcg_temp_free_ptr(fpstatus
);
4856 case NEON_3R_FLOAT_ACMP
:
4858 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4860 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4862 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4864 tcg_temp_free_ptr(fpstatus
);
4867 case NEON_3R_FLOAT_MINMAX
:
4869 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4871 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4873 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4875 tcg_temp_free_ptr(fpstatus
);
4878 case NEON_3R_VRECPS_VRSQRTS
:
4880 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4882 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4886 /* VFMA, VFMS: fused multiply-add */
4887 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4888 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4891 gen_helper_vfp_negs(tmp
, tmp
);
4893 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4894 tcg_temp_free_i32(tmp3
);
4895 tcg_temp_free_ptr(fpstatus
);
4901 tcg_temp_free_i32(tmp2
);
4903 /* Save the result. For elementwise operations we can put it
4904 straight into the destination register. For pairwise operations
4905 we have to be careful to avoid clobbering the source operands. */
4906 if (pairwise
&& rd
== rm
) {
4907 neon_store_scratch(pass
, tmp
);
4909 neon_store_reg(rd
, pass
, tmp
);
4913 if (pairwise
&& rd
== rm
) {
4914 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4915 tmp
= neon_load_scratch(pass
);
4916 neon_store_reg(rd
, pass
, tmp
);
4919 /* End of 3 register same size operations. */
4920 } else if (insn
& (1 << 4)) {
4921 if ((insn
& 0x00380080) != 0) {
4922 /* Two registers and shift. */
4923 op
= (insn
>> 8) & 0xf;
4924 if (insn
& (1 << 7)) {
4932 while ((insn
& (1 << (size
+ 19))) == 0)
4935 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4936 /* To avoid excessive duplication of ops we implement shift
4937 by immediate using the variable shift operations. */
4939 /* Shift by immediate:
4940 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4941 if (q
&& ((rd
| rm
) & 1)) {
4944 if (!u
&& (op
== 4 || op
== 6)) {
4947 /* Right shifts are encoded as N - shift, where N is the
4948 element size in bits. */
4950 shift
= shift
- (1 << (size
+ 3));
4958 imm
= (uint8_t) shift
;
4963 imm
= (uint16_t) shift
;
4974 for (pass
= 0; pass
< count
; pass
++) {
4976 neon_load_reg64(cpu_V0
, rm
+ pass
);
4977 tcg_gen_movi_i64(cpu_V1
, imm
);
4982 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4984 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4989 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4991 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4994 case 5: /* VSHL, VSLI */
4995 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4997 case 6: /* VQSHLU */
4998 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5003 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5006 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5011 if (op
== 1 || op
== 3) {
5013 neon_load_reg64(cpu_V1
, rd
+ pass
);
5014 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5015 } else if (op
== 4 || (op
== 5 && u
)) {
5017 neon_load_reg64(cpu_V1
, rd
+ pass
);
5019 if (shift
< -63 || shift
> 63) {
5023 mask
= 0xffffffffffffffffull
>> -shift
;
5025 mask
= 0xffffffffffffffffull
<< shift
;
5028 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5029 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5031 neon_store_reg64(cpu_V0
, rd
+ pass
);
5032 } else { /* size < 3 */
5033 /* Operands in T0 and T1. */
5034 tmp
= neon_load_reg(rm
, pass
);
5035 tmp2
= tcg_temp_new_i32();
5036 tcg_gen_movi_i32(tmp2
, imm
);
5040 GEN_NEON_INTEGER_OP(shl
);
5044 GEN_NEON_INTEGER_OP(rshl
);
5047 case 5: /* VSHL, VSLI */
5049 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5050 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5051 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5055 case 6: /* VQSHLU */
5058 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5062 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5066 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5074 GEN_NEON_INTEGER_OP_ENV(qshl
);
5077 tcg_temp_free_i32(tmp2
);
5079 if (op
== 1 || op
== 3) {
5081 tmp2
= neon_load_reg(rd
, pass
);
5082 gen_neon_add(size
, tmp
, tmp2
);
5083 tcg_temp_free_i32(tmp2
);
5084 } else if (op
== 4 || (op
== 5 && u
)) {
5089 mask
= 0xff >> -shift
;
5091 mask
= (uint8_t)(0xff << shift
);
5097 mask
= 0xffff >> -shift
;
5099 mask
= (uint16_t)(0xffff << shift
);
5103 if (shift
< -31 || shift
> 31) {
5107 mask
= 0xffffffffu
>> -shift
;
5109 mask
= 0xffffffffu
<< shift
;
5115 tmp2
= neon_load_reg(rd
, pass
);
5116 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5117 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5118 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5119 tcg_temp_free_i32(tmp2
);
5121 neon_store_reg(rd
, pass
, tmp
);
5124 } else if (op
< 10) {
5125 /* Shift by immediate and narrow:
5126 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5127 int input_unsigned
= (op
== 8) ? !u
: u
;
5131 shift
= shift
- (1 << (size
+ 3));
5134 tmp64
= tcg_const_i64(shift
);
5135 neon_load_reg64(cpu_V0
, rm
);
5136 neon_load_reg64(cpu_V1
, rm
+ 1);
5137 for (pass
= 0; pass
< 2; pass
++) {
5145 if (input_unsigned
) {
5146 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5148 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5151 if (input_unsigned
) {
5152 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5154 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5157 tmp
= tcg_temp_new_i32();
5158 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5159 neon_store_reg(rd
, pass
, tmp
);
5161 tcg_temp_free_i64(tmp64
);
5164 imm
= (uint16_t)shift
;
5168 imm
= (uint32_t)shift
;
5170 tmp2
= tcg_const_i32(imm
);
5171 tmp4
= neon_load_reg(rm
+ 1, 0);
5172 tmp5
= neon_load_reg(rm
+ 1, 1);
5173 for (pass
= 0; pass
< 2; pass
++) {
5175 tmp
= neon_load_reg(rm
, 0);
5179 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5182 tmp3
= neon_load_reg(rm
, 1);
5186 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5188 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5189 tcg_temp_free_i32(tmp
);
5190 tcg_temp_free_i32(tmp3
);
5191 tmp
= tcg_temp_new_i32();
5192 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5193 neon_store_reg(rd
, pass
, tmp
);
5195 tcg_temp_free_i32(tmp2
);
5197 } else if (op
== 10) {
5199 if (q
|| (rd
& 1)) {
5202 tmp
= neon_load_reg(rm
, 0);
5203 tmp2
= neon_load_reg(rm
, 1);
5204 for (pass
= 0; pass
< 2; pass
++) {
5208 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5211 /* The shift is less than the width of the source
5212 type, so we can just shift the whole register. */
5213 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5214 /* Widen the result of shift: we need to clear
5215 * the potential overflow bits resulting from
5216 * left bits of the narrow input appearing as
5217 * right bits of left the neighbour narrow
5219 if (size
< 2 || !u
) {
5222 imm
= (0xffu
>> (8 - shift
));
5224 } else if (size
== 1) {
5225 imm
= 0xffff >> (16 - shift
);
5228 imm
= 0xffffffff >> (32 - shift
);
5231 imm64
= imm
| (((uint64_t)imm
) << 32);
5235 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5238 neon_store_reg64(cpu_V0
, rd
+ pass
);
5240 } else if (op
>= 14) {
5241 /* VCVT fixed-point. */
5242 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5245 /* We have already masked out the must-be-1 top bit of imm6,
5246 * hence this 32-shift where the ARM ARM has 64-imm6.
5249 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5250 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5253 gen_vfp_ulto(0, shift
, 1);
5255 gen_vfp_slto(0, shift
, 1);
5258 gen_vfp_toul(0, shift
, 1);
5260 gen_vfp_tosl(0, shift
, 1);
5262 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5267 } else { /* (insn & 0x00380080) == 0 */
5269 if (q
&& (rd
& 1)) {
5273 op
= (insn
>> 8) & 0xf;
5274 /* One register and immediate. */
5275 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5276 invert
= (insn
& (1 << 5)) != 0;
5277 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5278 * We choose to not special-case this and will behave as if a
5279 * valid constant encoding of 0 had been given.
5298 imm
= (imm
<< 8) | (imm
<< 24);
5301 imm
= (imm
<< 8) | 0xff;
5304 imm
= (imm
<< 16) | 0xffff;
5307 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5315 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5316 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5322 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5323 if (op
& 1 && op
< 12) {
5324 tmp
= neon_load_reg(rd
, pass
);
5326 /* The immediate value has already been inverted, so
5328 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5330 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5334 tmp
= tcg_temp_new_i32();
5335 if (op
== 14 && invert
) {
5339 for (n
= 0; n
< 4; n
++) {
5340 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5341 val
|= 0xff << (n
* 8);
5343 tcg_gen_movi_i32(tmp
, val
);
5345 tcg_gen_movi_i32(tmp
, imm
);
5348 neon_store_reg(rd
, pass
, tmp
);
5351 } else { /* (insn & 0x00800010 == 0x00800000) */
5353 op
= (insn
>> 8) & 0xf;
5354 if ((insn
& (1 << 6)) == 0) {
5355 /* Three registers of different lengths. */
5359 /* undefreq: bit 0 : UNDEF if size != 0
5360 * bit 1 : UNDEF if size == 0
5361 * bit 2 : UNDEF if U == 1
5362 * Note that [1:0] set implies 'always UNDEF'
5365 /* prewiden, src1_wide, src2_wide, undefreq */
5366 static const int neon_3reg_wide
[16][4] = {
5367 {1, 0, 0, 0}, /* VADDL */
5368 {1, 1, 0, 0}, /* VADDW */
5369 {1, 0, 0, 0}, /* VSUBL */
5370 {1, 1, 0, 0}, /* VSUBW */
5371 {0, 1, 1, 0}, /* VADDHN */
5372 {0, 0, 0, 0}, /* VABAL */
5373 {0, 1, 1, 0}, /* VSUBHN */
5374 {0, 0, 0, 0}, /* VABDL */
5375 {0, 0, 0, 0}, /* VMLAL */
5376 {0, 0, 0, 6}, /* VQDMLAL */
5377 {0, 0, 0, 0}, /* VMLSL */
5378 {0, 0, 0, 6}, /* VQDMLSL */
5379 {0, 0, 0, 0}, /* Integer VMULL */
5380 {0, 0, 0, 2}, /* VQDMULL */
5381 {0, 0, 0, 5}, /* Polynomial VMULL */
5382 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5385 prewiden
= neon_3reg_wide
[op
][0];
5386 src1_wide
= neon_3reg_wide
[op
][1];
5387 src2_wide
= neon_3reg_wide
[op
][2];
5388 undefreq
= neon_3reg_wide
[op
][3];
5390 if (((undefreq
& 1) && (size
!= 0)) ||
5391 ((undefreq
& 2) && (size
== 0)) ||
5392 ((undefreq
& 4) && u
)) {
5395 if ((src1_wide
&& (rn
& 1)) ||
5396 (src2_wide
&& (rm
& 1)) ||
5397 (!src2_wide
&& (rd
& 1))) {
5401 /* Avoid overlapping operands. Wide source operands are
5402 always aligned so will never overlap with wide
5403 destinations in problematic ways. */
5404 if (rd
== rm
&& !src2_wide
) {
5405 tmp
= neon_load_reg(rm
, 1);
5406 neon_store_scratch(2, tmp
);
5407 } else if (rd
== rn
&& !src1_wide
) {
5408 tmp
= neon_load_reg(rn
, 1);
5409 neon_store_scratch(2, tmp
);
5412 for (pass
= 0; pass
< 2; pass
++) {
5414 neon_load_reg64(cpu_V0
, rn
+ pass
);
5417 if (pass
== 1 && rd
== rn
) {
5418 tmp
= neon_load_scratch(2);
5420 tmp
= neon_load_reg(rn
, pass
);
5423 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5427 neon_load_reg64(cpu_V1
, rm
+ pass
);
5430 if (pass
== 1 && rd
== rm
) {
5431 tmp2
= neon_load_scratch(2);
5433 tmp2
= neon_load_reg(rm
, pass
);
5436 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5440 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5441 gen_neon_addl(size
);
5443 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5444 gen_neon_subl(size
);
5446 case 5: case 7: /* VABAL, VABDL */
5447 switch ((size
<< 1) | u
) {
5449 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5452 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5455 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5458 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5461 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5464 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5468 tcg_temp_free_i32(tmp2
);
5469 tcg_temp_free_i32(tmp
);
5471 case 8: case 9: case 10: case 11: case 12: case 13:
5472 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5473 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5475 case 14: /* Polynomial VMULL */
5476 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5477 tcg_temp_free_i32(tmp2
);
5478 tcg_temp_free_i32(tmp
);
5480 default: /* 15 is RESERVED: caught earlier */
5485 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5486 neon_store_reg64(cpu_V0
, rd
+ pass
);
5487 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5489 neon_load_reg64(cpu_V1
, rd
+ pass
);
5491 case 10: /* VMLSL */
5492 gen_neon_negl(cpu_V0
, size
);
5494 case 5: case 8: /* VABAL, VMLAL */
5495 gen_neon_addl(size
);
5497 case 9: case 11: /* VQDMLAL, VQDMLSL */
5498 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5500 gen_neon_negl(cpu_V0
, size
);
5502 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5507 neon_store_reg64(cpu_V0
, rd
+ pass
);
5508 } else if (op
== 4 || op
== 6) {
5509 /* Narrowing operation. */
5510 tmp
= tcg_temp_new_i32();
5514 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5517 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5520 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5521 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5528 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5531 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5534 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5535 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5536 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5544 neon_store_reg(rd
, 0, tmp3
);
5545 neon_store_reg(rd
, 1, tmp
);
5548 /* Write back the result. */
5549 neon_store_reg64(cpu_V0
, rd
+ pass
);
5553 /* Two registers and a scalar. NB that for ops of this form
5554 * the ARM ARM labels bit 24 as Q, but it is in our variable
5561 case 1: /* Float VMLA scalar */
5562 case 5: /* Floating point VMLS scalar */
5563 case 9: /* Floating point VMUL scalar */
5568 case 0: /* Integer VMLA scalar */
5569 case 4: /* Integer VMLS scalar */
5570 case 8: /* Integer VMUL scalar */
5571 case 12: /* VQDMULH scalar */
5572 case 13: /* VQRDMULH scalar */
5573 if (u
&& ((rd
| rn
) & 1)) {
5576 tmp
= neon_get_scalar(size
, rm
);
5577 neon_store_scratch(0, tmp
);
5578 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5579 tmp
= neon_load_scratch(0);
5580 tmp2
= neon_load_reg(rn
, pass
);
5583 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5585 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5587 } else if (op
== 13) {
5589 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5591 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5593 } else if (op
& 1) {
5594 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5595 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5596 tcg_temp_free_ptr(fpstatus
);
5599 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5600 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5601 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5605 tcg_temp_free_i32(tmp2
);
5608 tmp2
= neon_load_reg(rd
, pass
);
5611 gen_neon_add(size
, tmp
, tmp2
);
5615 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5616 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5617 tcg_temp_free_ptr(fpstatus
);
5621 gen_neon_rsb(size
, tmp
, tmp2
);
5625 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5626 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5627 tcg_temp_free_ptr(fpstatus
);
5633 tcg_temp_free_i32(tmp2
);
5635 neon_store_reg(rd
, pass
, tmp
);
5638 case 3: /* VQDMLAL scalar */
5639 case 7: /* VQDMLSL scalar */
5640 case 11: /* VQDMULL scalar */
5645 case 2: /* VMLAL sclar */
5646 case 6: /* VMLSL scalar */
5647 case 10: /* VMULL scalar */
5651 tmp2
= neon_get_scalar(size
, rm
);
5652 /* We need a copy of tmp2 because gen_neon_mull
5653 * deletes it during pass 0. */
5654 tmp4
= tcg_temp_new_i32();
5655 tcg_gen_mov_i32(tmp4
, tmp2
);
5656 tmp3
= neon_load_reg(rn
, 1);
5658 for (pass
= 0; pass
< 2; pass
++) {
5660 tmp
= neon_load_reg(rn
, 0);
5665 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5667 neon_load_reg64(cpu_V1
, rd
+ pass
);
5671 gen_neon_negl(cpu_V0
, size
);
5674 gen_neon_addl(size
);
5677 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5679 gen_neon_negl(cpu_V0
, size
);
5681 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5687 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5692 neon_store_reg64(cpu_V0
, rd
+ pass
);
5697 default: /* 14 and 15 are RESERVED */
5701 } else { /* size == 3 */
5704 imm
= (insn
>> 8) & 0xf;
5709 if (q
&& ((rd
| rn
| rm
) & 1)) {
5714 neon_load_reg64(cpu_V0
, rn
);
5716 neon_load_reg64(cpu_V1
, rn
+ 1);
5718 } else if (imm
== 8) {
5719 neon_load_reg64(cpu_V0
, rn
+ 1);
5721 neon_load_reg64(cpu_V1
, rm
);
5724 tmp64
= tcg_temp_new_i64();
5726 neon_load_reg64(cpu_V0
, rn
);
5727 neon_load_reg64(tmp64
, rn
+ 1);
5729 neon_load_reg64(cpu_V0
, rn
+ 1);
5730 neon_load_reg64(tmp64
, rm
);
5732 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5733 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5734 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5736 neon_load_reg64(cpu_V1
, rm
);
5738 neon_load_reg64(cpu_V1
, rm
+ 1);
5741 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5742 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5743 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5744 tcg_temp_free_i64(tmp64
);
5747 neon_load_reg64(cpu_V0
, rn
);
5748 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5749 neon_load_reg64(cpu_V1
, rm
);
5750 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5751 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5753 neon_store_reg64(cpu_V0
, rd
);
5755 neon_store_reg64(cpu_V1
, rd
+ 1);
5757 } else if ((insn
& (1 << 11)) == 0) {
5758 /* Two register misc. */
5759 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5760 size
= (insn
>> 18) & 3;
5761 /* UNDEF for unknown op values and bad op-size combinations */
5762 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5765 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5766 q
&& ((rm
| rd
) & 1)) {
5770 case NEON_2RM_VREV64
:
5771 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5772 tmp
= neon_load_reg(rm
, pass
* 2);
5773 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5775 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5776 case 1: gen_swap_half(tmp
); break;
5777 case 2: /* no-op */ break;
5780 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5782 neon_store_reg(rd
, pass
* 2, tmp2
);
5785 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5786 case 1: gen_swap_half(tmp2
); break;
5789 neon_store_reg(rd
, pass
* 2, tmp2
);
5793 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5794 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5795 for (pass
= 0; pass
< q
+ 1; pass
++) {
5796 tmp
= neon_load_reg(rm
, pass
* 2);
5797 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5798 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5799 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5801 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5802 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5803 case 2: tcg_gen_add_i64(CPU_V001
); break;
5806 if (op
>= NEON_2RM_VPADAL
) {
5808 neon_load_reg64(cpu_V1
, rd
+ pass
);
5809 gen_neon_addl(size
);
5811 neon_store_reg64(cpu_V0
, rd
+ pass
);
5817 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5818 tmp
= neon_load_reg(rm
, n
);
5819 tmp2
= neon_load_reg(rd
, n
+ 1);
5820 neon_store_reg(rm
, n
, tmp2
);
5821 neon_store_reg(rd
, n
+ 1, tmp
);
5828 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5833 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5837 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5838 /* also VQMOVUN; op field and mnemonics don't line up */
5843 for (pass
= 0; pass
< 2; pass
++) {
5844 neon_load_reg64(cpu_V0
, rm
+ pass
);
5845 tmp
= tcg_temp_new_i32();
5846 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5851 neon_store_reg(rd
, 0, tmp2
);
5852 neon_store_reg(rd
, 1, tmp
);
5856 case NEON_2RM_VSHLL
:
5857 if (q
|| (rd
& 1)) {
5860 tmp
= neon_load_reg(rm
, 0);
5861 tmp2
= neon_load_reg(rm
, 1);
5862 for (pass
= 0; pass
< 2; pass
++) {
5865 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5866 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5867 neon_store_reg64(cpu_V0
, rd
+ pass
);
5870 case NEON_2RM_VCVT_F16_F32
:
5871 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5875 tmp
= tcg_temp_new_i32();
5876 tmp2
= tcg_temp_new_i32();
5877 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5878 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5879 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5880 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5881 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5882 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5883 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5884 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5885 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5886 neon_store_reg(rd
, 0, tmp2
);
5887 tmp2
= tcg_temp_new_i32();
5888 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5889 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5890 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5891 neon_store_reg(rd
, 1, tmp2
);
5892 tcg_temp_free_i32(tmp
);
5894 case NEON_2RM_VCVT_F32_F16
:
5895 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5899 tmp3
= tcg_temp_new_i32();
5900 tmp
= neon_load_reg(rm
, 0);
5901 tmp2
= neon_load_reg(rm
, 1);
5902 tcg_gen_ext16u_i32(tmp3
, tmp
);
5903 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5904 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5905 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5906 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5907 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5908 tcg_temp_free_i32(tmp
);
5909 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5910 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5911 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5912 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5913 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5914 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5915 tcg_temp_free_i32(tmp2
);
5916 tcg_temp_free_i32(tmp3
);
5920 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5921 if (neon_2rm_is_float_op(op
)) {
5922 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5923 neon_reg_offset(rm
, pass
));
5926 tmp
= neon_load_reg(rm
, pass
);
5929 case NEON_2RM_VREV32
:
5931 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5932 case 1: gen_swap_half(tmp
); break;
5936 case NEON_2RM_VREV16
:
5941 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5942 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5943 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5949 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5950 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5951 case 2: gen_helper_clz(tmp
, tmp
); break;
5956 gen_helper_neon_cnt_u8(tmp
, tmp
);
5959 tcg_gen_not_i32(tmp
, tmp
);
5961 case NEON_2RM_VQABS
:
5964 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
5967 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
5970 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
5975 case NEON_2RM_VQNEG
:
5978 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
5981 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
5984 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
5989 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
5990 tmp2
= tcg_const_i32(0);
5992 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5993 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5994 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5997 tcg_temp_free(tmp2
);
5998 if (op
== NEON_2RM_VCLE0
) {
5999 tcg_gen_not_i32(tmp
, tmp
);
6002 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6003 tmp2
= tcg_const_i32(0);
6005 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6006 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6007 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6010 tcg_temp_free(tmp2
);
6011 if (op
== NEON_2RM_VCLT0
) {
6012 tcg_gen_not_i32(tmp
, tmp
);
6015 case NEON_2RM_VCEQ0
:
6016 tmp2
= tcg_const_i32(0);
6018 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6019 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6020 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6023 tcg_temp_free(tmp2
);
6027 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6028 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6029 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6034 tmp2
= tcg_const_i32(0);
6035 gen_neon_rsb(size
, tmp
, tmp2
);
6036 tcg_temp_free(tmp2
);
6038 case NEON_2RM_VCGT0_F
:
6040 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6041 tmp2
= tcg_const_i32(0);
6042 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6043 tcg_temp_free(tmp2
);
6044 tcg_temp_free_ptr(fpstatus
);
6047 case NEON_2RM_VCGE0_F
:
6049 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6050 tmp2
= tcg_const_i32(0);
6051 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6052 tcg_temp_free(tmp2
);
6053 tcg_temp_free_ptr(fpstatus
);
6056 case NEON_2RM_VCEQ0_F
:
6058 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6059 tmp2
= tcg_const_i32(0);
6060 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6061 tcg_temp_free(tmp2
);
6062 tcg_temp_free_ptr(fpstatus
);
6065 case NEON_2RM_VCLE0_F
:
6067 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6068 tmp2
= tcg_const_i32(0);
6069 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6070 tcg_temp_free(tmp2
);
6071 tcg_temp_free_ptr(fpstatus
);
6074 case NEON_2RM_VCLT0_F
:
6076 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6077 tmp2
= tcg_const_i32(0);
6078 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6079 tcg_temp_free(tmp2
);
6080 tcg_temp_free_ptr(fpstatus
);
6083 case NEON_2RM_VABS_F
:
6086 case NEON_2RM_VNEG_F
:
6090 tmp2
= neon_load_reg(rd
, pass
);
6091 neon_store_reg(rm
, pass
, tmp2
);
6094 tmp2
= neon_load_reg(rd
, pass
);
6096 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6097 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6100 neon_store_reg(rm
, pass
, tmp2
);
6102 case NEON_2RM_VRECPE
:
6103 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6105 case NEON_2RM_VRSQRTE
:
6106 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6108 case NEON_2RM_VRECPE_F
:
6109 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6111 case NEON_2RM_VRSQRTE_F
:
6112 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6114 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6117 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6120 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6121 gen_vfp_tosiz(0, 1);
6123 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6124 gen_vfp_touiz(0, 1);
6127 /* Reserved op values were caught by the
6128 * neon_2rm_sizes[] check earlier.
6132 if (neon_2rm_is_float_op(op
)) {
6133 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6134 neon_reg_offset(rd
, pass
));
6136 neon_store_reg(rd
, pass
, tmp
);
6141 } else if ((insn
& (1 << 10)) == 0) {
6143 int n
= ((insn
>> 8) & 3) + 1;
6144 if ((rn
+ n
) > 32) {
6145 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6146 * helper function running off the end of the register file.
6151 if (insn
& (1 << 6)) {
6152 tmp
= neon_load_reg(rd
, 0);
6154 tmp
= tcg_temp_new_i32();
6155 tcg_gen_movi_i32(tmp
, 0);
6157 tmp2
= neon_load_reg(rm
, 0);
6158 tmp4
= tcg_const_i32(rn
);
6159 tmp5
= tcg_const_i32(n
);
6160 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6161 tcg_temp_free_i32(tmp
);
6162 if (insn
& (1 << 6)) {
6163 tmp
= neon_load_reg(rd
, 1);
6165 tmp
= tcg_temp_new_i32();
6166 tcg_gen_movi_i32(tmp
, 0);
6168 tmp3
= neon_load_reg(rm
, 1);
6169 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6170 tcg_temp_free_i32(tmp5
);
6171 tcg_temp_free_i32(tmp4
);
6172 neon_store_reg(rd
, 0, tmp2
);
6173 neon_store_reg(rd
, 1, tmp3
);
6174 tcg_temp_free_i32(tmp
);
6175 } else if ((insn
& 0x380) == 0) {
6177 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6180 if (insn
& (1 << 19)) {
6181 tmp
= neon_load_reg(rm
, 1);
6183 tmp
= neon_load_reg(rm
, 0);
6185 if (insn
& (1 << 16)) {
6186 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6187 } else if (insn
& (1 << 17)) {
6188 if ((insn
>> 18) & 1)
6189 gen_neon_dup_high16(tmp
);
6191 gen_neon_dup_low16(tmp
);
6193 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6194 tmp2
= tcg_temp_new_i32();
6195 tcg_gen_mov_i32(tmp2
, tmp
);
6196 neon_store_reg(rd
, pass
, tmp2
);
6198 tcg_temp_free_i32(tmp
);
6207 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6209 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6210 const ARMCPRegInfo
*ri
;
6211 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6213 cpnum
= (insn
>> 8) & 0xf;
6214 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6215 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6218 /* First check for coprocessor space used for actual instructions */
6222 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6223 return disas_iwmmxt_insn(env
, s
, insn
);
6224 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6225 return disas_dsp_insn(env
, s
, insn
);
6230 return disas_vfp_insn (env
, s
, insn
);
6235 /* Otherwise treat as a generic register access */
6236 is64
= (insn
& (1 << 25)) == 0;
6237 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6245 opc1
= (insn
>> 4) & 0xf;
6247 rt2
= (insn
>> 16) & 0xf;
6249 crn
= (insn
>> 16) & 0xf;
6250 opc1
= (insn
>> 21) & 7;
6251 opc2
= (insn
>> 5) & 7;
6254 isread
= (insn
>> 20) & 1;
6255 rt
= (insn
>> 12) & 0xf;
6257 ri
= get_arm_cp_reginfo(cpu
,
6258 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6260 /* Check access permissions */
6261 if (!cp_access_ok(env
, ri
, isread
)) {
6265 /* Handle special cases first */
6266 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6273 gen_set_pc_im(s
->pc
);
6274 s
->is_jmp
= DISAS_WFI
;
6285 if (ri
->type
& ARM_CP_CONST
) {
6286 tmp64
= tcg_const_i64(ri
->resetvalue
);
6287 } else if (ri
->readfn
) {
6289 gen_set_pc_im(s
->pc
);
6290 tmp64
= tcg_temp_new_i64();
6291 tmpptr
= tcg_const_ptr(ri
);
6292 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6293 tcg_temp_free_ptr(tmpptr
);
6295 tmp64
= tcg_temp_new_i64();
6296 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6298 tmp
= tcg_temp_new_i32();
6299 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6300 store_reg(s
, rt
, tmp
);
6301 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6302 tmp
= tcg_temp_new_i32();
6303 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6304 tcg_temp_free_i64(tmp64
);
6305 store_reg(s
, rt2
, tmp
);
6308 if (ri
->type
& ARM_CP_CONST
) {
6309 tmp
= tcg_const_i32(ri
->resetvalue
);
6310 } else if (ri
->readfn
) {
6312 gen_set_pc_im(s
->pc
);
6313 tmp
= tcg_temp_new_i32();
6314 tmpptr
= tcg_const_ptr(ri
);
6315 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6316 tcg_temp_free_ptr(tmpptr
);
6318 tmp
= load_cpu_offset(ri
->fieldoffset
);
6321 /* Destination register of r15 for 32 bit loads sets
6322 * the condition codes from the high 4 bits of the value
6325 tcg_temp_free_i32(tmp
);
6327 store_reg(s
, rt
, tmp
);
6332 if (ri
->type
& ARM_CP_CONST
) {
6333 /* If not forbidden by access permissions, treat as WI */
6339 TCGv_i64 tmp64
= tcg_temp_new_i64();
6340 tmplo
= load_reg(s
, rt
);
6341 tmphi
= load_reg(s
, rt2
);
6342 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6343 tcg_temp_free_i32(tmplo
);
6344 tcg_temp_free_i32(tmphi
);
6346 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6347 gen_set_pc_im(s
->pc
);
6348 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6349 tcg_temp_free_ptr(tmpptr
);
6351 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6353 tcg_temp_free_i64(tmp64
);
6358 gen_set_pc_im(s
->pc
);
6359 tmp
= load_reg(s
, rt
);
6360 tmpptr
= tcg_const_ptr(ri
);
6361 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6362 tcg_temp_free_ptr(tmpptr
);
6363 tcg_temp_free_i32(tmp
);
6365 TCGv tmp
= load_reg(s
, rt
);
6366 store_cpu_offset(tmp
, ri
->fieldoffset
);
6369 /* We default to ending the TB on a coprocessor register write,
6370 * but allow this to be suppressed by the register definition
6371 * (usually only necessary to work around guest bugs).
6373 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6384 /* Store a 64-bit value to a register pair. Clobbers val. */
6385 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6388 tmp
= tcg_temp_new_i32();
6389 tcg_gen_trunc_i64_i32(tmp
, val
);
6390 store_reg(s
, rlow
, tmp
);
6391 tmp
= tcg_temp_new_i32();
6392 tcg_gen_shri_i64(val
, val
, 32);
6393 tcg_gen_trunc_i64_i32(tmp
, val
);
6394 store_reg(s
, rhigh
, tmp
);
6397 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6398 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6403 /* Load value and extend to 64 bits. */
6404 tmp
= tcg_temp_new_i64();
6405 tmp2
= load_reg(s
, rlow
);
6406 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6407 tcg_temp_free_i32(tmp2
);
6408 tcg_gen_add_i64(val
, val
, tmp
);
6409 tcg_temp_free_i64(tmp
);
6412 /* load and add a 64-bit value from a register pair. */
6413 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6419 /* Load 64-bit value rd:rn. */
6420 tmpl
= load_reg(s
, rlow
);
6421 tmph
= load_reg(s
, rhigh
);
6422 tmp
= tcg_temp_new_i64();
6423 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6424 tcg_temp_free_i32(tmpl
);
6425 tcg_temp_free_i32(tmph
);
6426 tcg_gen_add_i64(val
, val
, tmp
);
6427 tcg_temp_free_i64(tmp
);
6430 /* Set N and Z flags from a 64-bit value. */
6431 static void gen_logicq_cc(TCGv_i64 val
)
6433 TCGv tmp
= tcg_temp_new_i32();
6434 gen_helper_logicq_cc(tmp
, val
);
6436 tcg_temp_free_i32(tmp
);
6439 /* Load/Store exclusive instructions are implemented by remembering
6440 the value/address loaded, and seeing if these are the same
6441 when the store is performed. This should be sufficient to implement
6442 the architecturally mandated semantics, and avoids having to monitor
6445 In system emulation mode only one CPU will be running at once, so
6446 this sequence is effectively atomic. In user emulation mode we
6447 throw an exception and handle the atomic operation elsewhere. */
6448 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6449 TCGv addr
, int size
)
6455 tmp
= gen_ld8u(addr
, IS_USER(s
));
6458 tmp
= gen_ld16u(addr
, IS_USER(s
));
6462 tmp
= gen_ld32(addr
, IS_USER(s
));
6467 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6468 store_reg(s
, rt
, tmp
);
6470 TCGv tmp2
= tcg_temp_new_i32();
6471 tcg_gen_addi_i32(tmp2
, addr
, 4);
6472 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6473 tcg_temp_free_i32(tmp2
);
6474 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6475 store_reg(s
, rt2
, tmp
);
6477 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6480 static void gen_clrex(DisasContext
*s
)
6482 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6485 #ifdef CONFIG_USER_ONLY
6486 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6487 TCGv addr
, int size
)
6489 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6490 tcg_gen_movi_i32(cpu_exclusive_info
,
6491 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6492 gen_exception_insn(s
, 4, EXCP_STREX
);
6495 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6496 TCGv addr
, int size
)
6502 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6508 fail_label
= gen_new_label();
6509 done_label
= gen_new_label();
6510 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6513 tmp
= gen_ld8u(addr
, IS_USER(s
));
6516 tmp
= gen_ld16u(addr
, IS_USER(s
));
6520 tmp
= gen_ld32(addr
, IS_USER(s
));
6525 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6526 tcg_temp_free_i32(tmp
);
6528 TCGv tmp2
= tcg_temp_new_i32();
6529 tcg_gen_addi_i32(tmp2
, addr
, 4);
6530 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6531 tcg_temp_free_i32(tmp2
);
6532 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6533 tcg_temp_free_i32(tmp
);
6535 tmp
= load_reg(s
, rt
);
6538 gen_st8(tmp
, addr
, IS_USER(s
));
6541 gen_st16(tmp
, addr
, IS_USER(s
));
6545 gen_st32(tmp
, addr
, IS_USER(s
));
6551 tcg_gen_addi_i32(addr
, addr
, 4);
6552 tmp
= load_reg(s
, rt2
);
6553 gen_st32(tmp
, addr
, IS_USER(s
));
6555 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6556 tcg_gen_br(done_label
);
6557 gen_set_label(fail_label
);
6558 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6559 gen_set_label(done_label
);
6560 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6564 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6566 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6573 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6576 /* M variants do not implement ARM mode. */
6581 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6582 * choose to UNDEF. In ARMv5 and above the space is used
6583 * for miscellaneous unconditional instructions.
6587 /* Unconditional instructions. */
6588 if (((insn
>> 25) & 7) == 1) {
6589 /* NEON Data processing. */
6590 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6593 if (disas_neon_data_insn(env
, s
, insn
))
6597 if ((insn
& 0x0f100000) == 0x04000000) {
6598 /* NEON load/store. */
6599 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6602 if (disas_neon_ls_insn(env
, s
, insn
))
6606 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6607 ((insn
& 0x0f30f010) == 0x0710f000)) {
6608 if ((insn
& (1 << 22)) == 0) {
6610 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6614 /* Otherwise PLD; v5TE+ */
6618 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6619 ((insn
& 0x0f70f010) == 0x0650f000)) {
6621 return; /* PLI; V7 */
6623 if (((insn
& 0x0f700000) == 0x04100000) ||
6624 ((insn
& 0x0f700010) == 0x06100000)) {
6625 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6628 return; /* v7MP: Unallocated memory hint: must NOP */
6631 if ((insn
& 0x0ffffdff) == 0x01010000) {
6634 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6635 /* Dynamic endianness switching not implemented. */
6639 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6640 switch ((insn
>> 4) & 0xf) {
6649 /* We don't emulate caches so these are a no-op. */
6654 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6660 op1
= (insn
& 0x1f);
6661 addr
= tcg_temp_new_i32();
6662 tmp
= tcg_const_i32(op1
);
6663 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6664 tcg_temp_free_i32(tmp
);
6665 i
= (insn
>> 23) & 3;
6667 case 0: offset
= -4; break; /* DA */
6668 case 1: offset
= 0; break; /* IA */
6669 case 2: offset
= -8; break; /* DB */
6670 case 3: offset
= 4; break; /* IB */
6674 tcg_gen_addi_i32(addr
, addr
, offset
);
6675 tmp
= load_reg(s
, 14);
6676 gen_st32(tmp
, addr
, 0);
6677 tmp
= load_cpu_field(spsr
);
6678 tcg_gen_addi_i32(addr
, addr
, 4);
6679 gen_st32(tmp
, 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 tmp
= tcg_const_i32(op1
);
6692 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6693 tcg_temp_free_i32(tmp
);
6694 tcg_temp_free_i32(addr
);
6696 tcg_temp_free_i32(addr
);
6699 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6705 rn
= (insn
>> 16) & 0xf;
6706 addr
= load_reg(s
, rn
);
6707 i
= (insn
>> 23) & 3;
6709 case 0: offset
= -4; break; /* DA */
6710 case 1: offset
= 0; break; /* IA */
6711 case 2: offset
= -8; break; /* DB */
6712 case 3: offset
= 4; break; /* IB */
6716 tcg_gen_addi_i32(addr
, addr
, offset
);
6717 /* Load PC into tmp and CPSR into tmp2. */
6718 tmp
= gen_ld32(addr
, 0);
6719 tcg_gen_addi_i32(addr
, addr
, 4);
6720 tmp2
= gen_ld32(addr
, 0);
6721 if (insn
& (1 << 21)) {
6722 /* Base writeback. */
6724 case 0: offset
= -8; break;
6725 case 1: offset
= 4; break;
6726 case 2: offset
= -4; break;
6727 case 3: offset
= 0; break;
6731 tcg_gen_addi_i32(addr
, addr
, offset
);
6732 store_reg(s
, rn
, addr
);
6734 tcg_temp_free_i32(addr
);
6736 gen_rfe(s
, tmp
, tmp2
);
6738 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6739 /* branch link and change to thumb (blx <offset>) */
6742 val
= (uint32_t)s
->pc
;
6743 tmp
= tcg_temp_new_i32();
6744 tcg_gen_movi_i32(tmp
, val
);
6745 store_reg(s
, 14, tmp
);
6746 /* Sign-extend the 24-bit offset */
6747 offset
= (((int32_t)insn
) << 8) >> 8;
6748 /* offset * 4 + bit24 * 2 + (thumb bit) */
6749 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6750 /* pipeline offset */
6752 /* protected by ARCH(5); above, near the start of uncond block */
6755 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6756 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6757 /* iWMMXt register transfer. */
6758 if (env
->cp15
.c15_cpar
& (1 << 1))
6759 if (!disas_iwmmxt_insn(env
, s
, insn
))
6762 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6763 /* Coprocessor double register transfer. */
6765 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6766 /* Additional coprocessor register transfer. */
6767 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6770 /* cps (privileged) */
6774 if (insn
& (1 << 19)) {
6775 if (insn
& (1 << 8))
6777 if (insn
& (1 << 7))
6779 if (insn
& (1 << 6))
6781 if (insn
& (1 << 18))
6784 if (insn
& (1 << 17)) {
6786 val
|= (insn
& 0x1f);
6789 gen_set_psr_im(s
, mask
, 0, val
);
6796 /* if not always execute, we generate a conditional jump to
6798 s
->condlabel
= gen_new_label();
6799 gen_test_cc(cond
^ 1, s
->condlabel
);
6802 if ((insn
& 0x0f900000) == 0x03000000) {
6803 if ((insn
& (1 << 21)) == 0) {
6805 rd
= (insn
>> 12) & 0xf;
6806 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6807 if ((insn
& (1 << 22)) == 0) {
6809 tmp
= tcg_temp_new_i32();
6810 tcg_gen_movi_i32(tmp
, val
);
6813 tmp
= load_reg(s
, rd
);
6814 tcg_gen_ext16u_i32(tmp
, tmp
);
6815 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6817 store_reg(s
, rd
, tmp
);
6819 if (((insn
>> 12) & 0xf) != 0xf)
6821 if (((insn
>> 16) & 0xf) == 0) {
6822 gen_nop_hint(s
, insn
& 0xff);
6824 /* CPSR = immediate */
6826 shift
= ((insn
>> 8) & 0xf) * 2;
6828 val
= (val
>> shift
) | (val
<< (32 - shift
));
6829 i
= ((insn
& (1 << 22)) != 0);
6830 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6834 } else if ((insn
& 0x0f900000) == 0x01000000
6835 && (insn
& 0x00000090) != 0x00000090) {
6836 /* miscellaneous instructions */
6837 op1
= (insn
>> 21) & 3;
6838 sh
= (insn
>> 4) & 0xf;
6841 case 0x0: /* move program status register */
6844 tmp
= load_reg(s
, rm
);
6845 i
= ((op1
& 2) != 0);
6846 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6850 rd
= (insn
>> 12) & 0xf;
6854 tmp
= load_cpu_field(spsr
);
6856 tmp
= tcg_temp_new_i32();
6857 gen_helper_cpsr_read(tmp
, cpu_env
);
6859 store_reg(s
, rd
, tmp
);
6864 /* branch/exchange thumb (bx). */
6866 tmp
= load_reg(s
, rm
);
6868 } else if (op1
== 3) {
6871 rd
= (insn
>> 12) & 0xf;
6872 tmp
= load_reg(s
, rm
);
6873 gen_helper_clz(tmp
, tmp
);
6874 store_reg(s
, rd
, tmp
);
6882 /* Trivial implementation equivalent to bx. */
6883 tmp
= load_reg(s
, rm
);
6894 /* branch link/exchange thumb (blx) */
6895 tmp
= load_reg(s
, rm
);
6896 tmp2
= tcg_temp_new_i32();
6897 tcg_gen_movi_i32(tmp2
, s
->pc
);
6898 store_reg(s
, 14, tmp2
);
6901 case 0x5: /* saturating add/subtract */
6903 rd
= (insn
>> 12) & 0xf;
6904 rn
= (insn
>> 16) & 0xf;
6905 tmp
= load_reg(s
, rm
);
6906 tmp2
= load_reg(s
, rn
);
6908 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6910 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6912 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6913 tcg_temp_free_i32(tmp2
);
6914 store_reg(s
, rd
, tmp
);
6917 /* SMC instruction (op1 == 3)
6918 and undefined instructions (op1 == 0 || op1 == 2)
6925 gen_exception_insn(s
, 4, EXCP_BKPT
);
6927 case 0x8: /* signed multiply */
6932 rs
= (insn
>> 8) & 0xf;
6933 rn
= (insn
>> 12) & 0xf;
6934 rd
= (insn
>> 16) & 0xf;
6936 /* (32 * 16) >> 16 */
6937 tmp
= load_reg(s
, rm
);
6938 tmp2
= load_reg(s
, rs
);
6940 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6943 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6944 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6945 tmp
= tcg_temp_new_i32();
6946 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6947 tcg_temp_free_i64(tmp64
);
6948 if ((sh
& 2) == 0) {
6949 tmp2
= load_reg(s
, rn
);
6950 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6951 tcg_temp_free_i32(tmp2
);
6953 store_reg(s
, rd
, tmp
);
6956 tmp
= load_reg(s
, rm
);
6957 tmp2
= load_reg(s
, rs
);
6958 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6959 tcg_temp_free_i32(tmp2
);
6961 tmp64
= tcg_temp_new_i64();
6962 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6963 tcg_temp_free_i32(tmp
);
6964 gen_addq(s
, tmp64
, rn
, rd
);
6965 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6966 tcg_temp_free_i64(tmp64
);
6969 tmp2
= load_reg(s
, rn
);
6970 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6971 tcg_temp_free_i32(tmp2
);
6973 store_reg(s
, rd
, tmp
);
6980 } else if (((insn
& 0x0e000000) == 0 &&
6981 (insn
& 0x00000090) != 0x90) ||
6982 ((insn
& 0x0e000000) == (1 << 25))) {
6983 int set_cc
, logic_cc
, shiftop
;
6985 op1
= (insn
>> 21) & 0xf;
6986 set_cc
= (insn
>> 20) & 1;
6987 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6989 /* data processing instruction */
6990 if (insn
& (1 << 25)) {
6991 /* immediate operand */
6993 shift
= ((insn
>> 8) & 0xf) * 2;
6995 val
= (val
>> shift
) | (val
<< (32 - shift
));
6997 tmp2
= tcg_temp_new_i32();
6998 tcg_gen_movi_i32(tmp2
, val
);
6999 if (logic_cc
&& shift
) {
7000 gen_set_CF_bit31(tmp2
);
7005 tmp2
= load_reg(s
, rm
);
7006 shiftop
= (insn
>> 5) & 3;
7007 if (!(insn
& (1 << 4))) {
7008 shift
= (insn
>> 7) & 0x1f;
7009 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7011 rs
= (insn
>> 8) & 0xf;
7012 tmp
= load_reg(s
, rs
);
7013 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7016 if (op1
!= 0x0f && op1
!= 0x0d) {
7017 rn
= (insn
>> 16) & 0xf;
7018 tmp
= load_reg(s
, rn
);
7022 rd
= (insn
>> 12) & 0xf;
7025 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7029 store_reg_bx(env
, s
, rd
, tmp
);
7032 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7036 store_reg_bx(env
, s
, rd
, tmp
);
7039 if (set_cc
&& rd
== 15) {
7040 /* SUBS r15, ... is used for exception return. */
7044 gen_sub_CC(tmp
, tmp
, tmp2
);
7045 gen_exception_return(s
, tmp
);
7048 gen_sub_CC(tmp
, tmp
, tmp2
);
7050 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7052 store_reg_bx(env
, s
, rd
, tmp
);
7057 gen_sub_CC(tmp
, tmp2
, tmp
);
7059 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7061 store_reg_bx(env
, s
, rd
, tmp
);
7065 gen_add_CC(tmp
, tmp
, tmp2
);
7067 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7069 store_reg_bx(env
, s
, rd
, tmp
);
7073 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7075 gen_add_carry(tmp
, tmp
, tmp2
);
7077 store_reg_bx(env
, s
, rd
, tmp
);
7081 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7083 gen_sub_carry(tmp
, tmp
, tmp2
);
7085 store_reg_bx(env
, s
, rd
, tmp
);
7089 gen_helper_sbc_cc(tmp
, cpu_env
, tmp2
, tmp
);
7091 gen_sub_carry(tmp
, tmp2
, tmp
);
7093 store_reg_bx(env
, s
, rd
, tmp
);
7097 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7100 tcg_temp_free_i32(tmp
);
7104 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7107 tcg_temp_free_i32(tmp
);
7111 gen_sub_CC(tmp
, tmp
, tmp2
);
7113 tcg_temp_free_i32(tmp
);
7117 gen_add_CC(tmp
, tmp
, tmp2
);
7119 tcg_temp_free_i32(tmp
);
7122 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7126 store_reg_bx(env
, s
, rd
, tmp
);
7129 if (logic_cc
&& rd
== 15) {
7130 /* MOVS r15, ... is used for exception return. */
7134 gen_exception_return(s
, tmp2
);
7139 store_reg_bx(env
, s
, rd
, tmp2
);
7143 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7147 store_reg_bx(env
, s
, rd
, tmp
);
7151 tcg_gen_not_i32(tmp2
, tmp2
);
7155 store_reg_bx(env
, s
, rd
, tmp2
);
7158 if (op1
!= 0x0f && op1
!= 0x0d) {
7159 tcg_temp_free_i32(tmp2
);
7162 /* other instructions */
7163 op1
= (insn
>> 24) & 0xf;
7167 /* multiplies, extra load/stores */
7168 sh
= (insn
>> 5) & 3;
7171 rd
= (insn
>> 16) & 0xf;
7172 rn
= (insn
>> 12) & 0xf;
7173 rs
= (insn
>> 8) & 0xf;
7175 op1
= (insn
>> 20) & 0xf;
7177 case 0: case 1: case 2: case 3: case 6:
7179 tmp
= load_reg(s
, rs
);
7180 tmp2
= load_reg(s
, rm
);
7181 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7182 tcg_temp_free_i32(tmp2
);
7183 if (insn
& (1 << 22)) {
7184 /* Subtract (mls) */
7186 tmp2
= load_reg(s
, rn
);
7187 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7188 tcg_temp_free_i32(tmp2
);
7189 } else if (insn
& (1 << 21)) {
7191 tmp2
= load_reg(s
, rn
);
7192 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7193 tcg_temp_free_i32(tmp2
);
7195 if (insn
& (1 << 20))
7197 store_reg(s
, rd
, tmp
);
7200 /* 64 bit mul double accumulate (UMAAL) */
7202 tmp
= load_reg(s
, rs
);
7203 tmp2
= load_reg(s
, rm
);
7204 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7205 gen_addq_lo(s
, tmp64
, rn
);
7206 gen_addq_lo(s
, tmp64
, rd
);
7207 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7208 tcg_temp_free_i64(tmp64
);
7210 case 8: case 9: case 10: case 11:
7211 case 12: case 13: case 14: case 15:
7212 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7213 tmp
= load_reg(s
, rs
);
7214 tmp2
= load_reg(s
, rm
);
7215 if (insn
& (1 << 22)) {
7216 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7218 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7220 if (insn
& (1 << 21)) { /* mult accumulate */
7221 gen_addq(s
, tmp64
, rn
, rd
);
7223 if (insn
& (1 << 20)) {
7224 gen_logicq_cc(tmp64
);
7226 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7227 tcg_temp_free_i64(tmp64
);
7233 rn
= (insn
>> 16) & 0xf;
7234 rd
= (insn
>> 12) & 0xf;
7235 if (insn
& (1 << 23)) {
7236 /* load/store exclusive */
7237 op1
= (insn
>> 21) & 0x3;
7242 addr
= tcg_temp_local_new_i32();
7243 load_reg_var(s
, addr
, rn
);
7244 if (insn
& (1 << 20)) {
7247 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7249 case 1: /* ldrexd */
7250 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7252 case 2: /* ldrexb */
7253 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7255 case 3: /* ldrexh */
7256 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7265 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7267 case 1: /* strexd */
7268 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7270 case 2: /* strexb */
7271 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7273 case 3: /* strexh */
7274 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7280 tcg_temp_free(addr
);
7282 /* SWP instruction */
7285 /* ??? This is not really atomic. However we know
7286 we never have multiple CPUs running in parallel,
7287 so it is good enough. */
7288 addr
= load_reg(s
, rn
);
7289 tmp
= load_reg(s
, rm
);
7290 if (insn
& (1 << 22)) {
7291 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7292 gen_st8(tmp
, addr
, IS_USER(s
));
7294 tmp2
= gen_ld32(addr
, IS_USER(s
));
7295 gen_st32(tmp
, addr
, IS_USER(s
));
7297 tcg_temp_free_i32(addr
);
7298 store_reg(s
, rd
, tmp2
);
7304 /* Misc load/store */
7305 rn
= (insn
>> 16) & 0xf;
7306 rd
= (insn
>> 12) & 0xf;
7307 addr
= load_reg(s
, rn
);
7308 if (insn
& (1 << 24))
7309 gen_add_datah_offset(s
, insn
, 0, addr
);
7311 if (insn
& (1 << 20)) {
7315 tmp
= gen_ld16u(addr
, IS_USER(s
));
7318 tmp
= gen_ld8s(addr
, IS_USER(s
));
7322 tmp
= gen_ld16s(addr
, IS_USER(s
));
7326 } else if (sh
& 2) {
7331 tmp
= load_reg(s
, rd
);
7332 gen_st32(tmp
, addr
, IS_USER(s
));
7333 tcg_gen_addi_i32(addr
, addr
, 4);
7334 tmp
= load_reg(s
, rd
+ 1);
7335 gen_st32(tmp
, addr
, IS_USER(s
));
7339 tmp
= gen_ld32(addr
, IS_USER(s
));
7340 store_reg(s
, rd
, tmp
);
7341 tcg_gen_addi_i32(addr
, addr
, 4);
7342 tmp
= gen_ld32(addr
, IS_USER(s
));
7346 address_offset
= -4;
7349 tmp
= load_reg(s
, rd
);
7350 gen_st16(tmp
, addr
, IS_USER(s
));
7353 /* Perform base writeback before the loaded value to
7354 ensure correct behavior with overlapping index registers.
7355 ldrd with base writeback is is undefined if the
7356 destination and index registers overlap. */
7357 if (!(insn
& (1 << 24))) {
7358 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7359 store_reg(s
, rn
, addr
);
7360 } else if (insn
& (1 << 21)) {
7362 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7363 store_reg(s
, rn
, addr
);
7365 tcg_temp_free_i32(addr
);
7368 /* Complete the load. */
7369 store_reg(s
, rd
, tmp
);
7378 if (insn
& (1 << 4)) {
7380 /* Armv6 Media instructions. */
7382 rn
= (insn
>> 16) & 0xf;
7383 rd
= (insn
>> 12) & 0xf;
7384 rs
= (insn
>> 8) & 0xf;
7385 switch ((insn
>> 23) & 3) {
7386 case 0: /* Parallel add/subtract. */
7387 op1
= (insn
>> 20) & 7;
7388 tmp
= load_reg(s
, rn
);
7389 tmp2
= load_reg(s
, rm
);
7390 sh
= (insn
>> 5) & 7;
7391 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7393 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7394 tcg_temp_free_i32(tmp2
);
7395 store_reg(s
, rd
, tmp
);
7398 if ((insn
& 0x00700020) == 0) {
7399 /* Halfword pack. */
7400 tmp
= load_reg(s
, rn
);
7401 tmp2
= load_reg(s
, rm
);
7402 shift
= (insn
>> 7) & 0x1f;
7403 if (insn
& (1 << 6)) {
7407 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7408 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7409 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7413 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7414 tcg_gen_ext16u_i32(tmp
, tmp
);
7415 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7417 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7418 tcg_temp_free_i32(tmp2
);
7419 store_reg(s
, rd
, tmp
);
7420 } else if ((insn
& 0x00200020) == 0x00200000) {
7422 tmp
= load_reg(s
, rm
);
7423 shift
= (insn
>> 7) & 0x1f;
7424 if (insn
& (1 << 6)) {
7427 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7429 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7431 sh
= (insn
>> 16) & 0x1f;
7432 tmp2
= tcg_const_i32(sh
);
7433 if (insn
& (1 << 22))
7434 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7436 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7437 tcg_temp_free_i32(tmp2
);
7438 store_reg(s
, rd
, tmp
);
7439 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7441 tmp
= load_reg(s
, rm
);
7442 sh
= (insn
>> 16) & 0x1f;
7443 tmp2
= tcg_const_i32(sh
);
7444 if (insn
& (1 << 22))
7445 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7447 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7448 tcg_temp_free_i32(tmp2
);
7449 store_reg(s
, rd
, tmp
);
7450 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7452 tmp
= load_reg(s
, rn
);
7453 tmp2
= load_reg(s
, rm
);
7454 tmp3
= tcg_temp_new_i32();
7455 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7456 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7457 tcg_temp_free_i32(tmp3
);
7458 tcg_temp_free_i32(tmp2
);
7459 store_reg(s
, rd
, tmp
);
7460 } else if ((insn
& 0x000003e0) == 0x00000060) {
7461 tmp
= load_reg(s
, rm
);
7462 shift
= (insn
>> 10) & 3;
7463 /* ??? In many cases it's not necessary to do a
7464 rotate, a shift is sufficient. */
7466 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7467 op1
= (insn
>> 20) & 7;
7469 case 0: gen_sxtb16(tmp
); break;
7470 case 2: gen_sxtb(tmp
); break;
7471 case 3: gen_sxth(tmp
); break;
7472 case 4: gen_uxtb16(tmp
); break;
7473 case 6: gen_uxtb(tmp
); break;
7474 case 7: gen_uxth(tmp
); break;
7475 default: goto illegal_op
;
7478 tmp2
= load_reg(s
, rn
);
7479 if ((op1
& 3) == 0) {
7480 gen_add16(tmp
, tmp2
);
7482 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7483 tcg_temp_free_i32(tmp2
);
7486 store_reg(s
, rd
, tmp
);
7487 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7489 tmp
= load_reg(s
, rm
);
7490 if (insn
& (1 << 22)) {
7491 if (insn
& (1 << 7)) {
7495 gen_helper_rbit(tmp
, tmp
);
7498 if (insn
& (1 << 7))
7501 tcg_gen_bswap32_i32(tmp
, tmp
);
7503 store_reg(s
, rd
, tmp
);
7508 case 2: /* Multiplies (Type 3). */
7509 switch ((insn
>> 20) & 0x7) {
7511 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7512 /* op2 not 00x or 11x : UNDEF */
7515 /* Signed multiply most significant [accumulate].
7516 (SMMUL, SMMLA, SMMLS) */
7517 tmp
= load_reg(s
, rm
);
7518 tmp2
= load_reg(s
, rs
);
7519 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7522 tmp
= load_reg(s
, rd
);
7523 if (insn
& (1 << 6)) {
7524 tmp64
= gen_subq_msw(tmp64
, tmp
);
7526 tmp64
= gen_addq_msw(tmp64
, tmp
);
7529 if (insn
& (1 << 5)) {
7530 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7532 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7533 tmp
= tcg_temp_new_i32();
7534 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7535 tcg_temp_free_i64(tmp64
);
7536 store_reg(s
, rn
, tmp
);
7540 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7541 if (insn
& (1 << 7)) {
7544 tmp
= load_reg(s
, rm
);
7545 tmp2
= load_reg(s
, rs
);
7546 if (insn
& (1 << 5))
7547 gen_swap_half(tmp2
);
7548 gen_smul_dual(tmp
, tmp2
);
7549 if (insn
& (1 << 6)) {
7550 /* This subtraction cannot overflow. */
7551 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7553 /* This addition cannot overflow 32 bits;
7554 * however it may overflow considered as a signed
7555 * operation, in which case we must set the Q flag.
7557 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7559 tcg_temp_free_i32(tmp2
);
7560 if (insn
& (1 << 22)) {
7561 /* smlald, smlsld */
7562 tmp64
= tcg_temp_new_i64();
7563 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7564 tcg_temp_free_i32(tmp
);
7565 gen_addq(s
, tmp64
, rd
, rn
);
7566 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7567 tcg_temp_free_i64(tmp64
);
7569 /* smuad, smusd, smlad, smlsd */
7572 tmp2
= load_reg(s
, rd
);
7573 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7574 tcg_temp_free_i32(tmp2
);
7576 store_reg(s
, rn
, tmp
);
7582 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7585 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7588 tmp
= load_reg(s
, rm
);
7589 tmp2
= load_reg(s
, rs
);
7590 if (insn
& (1 << 21)) {
7591 gen_helper_udiv(tmp
, tmp
, tmp2
);
7593 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7595 tcg_temp_free_i32(tmp2
);
7596 store_reg(s
, rn
, tmp
);
7603 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7605 case 0: /* Unsigned sum of absolute differences. */
7607 tmp
= load_reg(s
, rm
);
7608 tmp2
= load_reg(s
, rs
);
7609 gen_helper_usad8(tmp
, tmp
, tmp2
);
7610 tcg_temp_free_i32(tmp2
);
7612 tmp2
= load_reg(s
, rd
);
7613 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7614 tcg_temp_free_i32(tmp2
);
7616 store_reg(s
, rn
, tmp
);
7618 case 0x20: case 0x24: case 0x28: case 0x2c:
7619 /* Bitfield insert/clear. */
7621 shift
= (insn
>> 7) & 0x1f;
7622 i
= (insn
>> 16) & 0x1f;
7625 tmp
= tcg_temp_new_i32();
7626 tcg_gen_movi_i32(tmp
, 0);
7628 tmp
= load_reg(s
, rm
);
7631 tmp2
= load_reg(s
, rd
);
7632 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7633 tcg_temp_free_i32(tmp2
);
7635 store_reg(s
, rd
, tmp
);
7637 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7638 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7640 tmp
= load_reg(s
, rm
);
7641 shift
= (insn
>> 7) & 0x1f;
7642 i
= ((insn
>> 16) & 0x1f) + 1;
7647 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7649 gen_sbfx(tmp
, shift
, i
);
7652 store_reg(s
, rd
, tmp
);
7662 /* Check for undefined extension instructions
7663 * per the ARM Bible IE:
7664 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7666 sh
= (0xf << 20) | (0xf << 4);
7667 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7671 /* load/store byte/word */
7672 rn
= (insn
>> 16) & 0xf;
7673 rd
= (insn
>> 12) & 0xf;
7674 tmp2
= load_reg(s
, rn
);
7675 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7676 if (insn
& (1 << 24))
7677 gen_add_data_offset(s
, insn
, tmp2
);
7678 if (insn
& (1 << 20)) {
7680 if (insn
& (1 << 22)) {
7681 tmp
= gen_ld8u(tmp2
, i
);
7683 tmp
= gen_ld32(tmp2
, i
);
7687 tmp
= load_reg(s
, rd
);
7688 if (insn
& (1 << 22))
7689 gen_st8(tmp
, tmp2
, i
);
7691 gen_st32(tmp
, tmp2
, i
);
7693 if (!(insn
& (1 << 24))) {
7694 gen_add_data_offset(s
, insn
, tmp2
);
7695 store_reg(s
, rn
, tmp2
);
7696 } else if (insn
& (1 << 21)) {
7697 store_reg(s
, rn
, tmp2
);
7699 tcg_temp_free_i32(tmp2
);
7701 if (insn
& (1 << 20)) {
7702 /* Complete the load. */
7703 store_reg_from_load(env
, s
, rd
, tmp
);
7709 int j
, n
, user
, loaded_base
;
7711 /* load/store multiple words */
7712 /* XXX: store correct base if write back */
7714 if (insn
& (1 << 22)) {
7716 goto illegal_op
; /* only usable in supervisor mode */
7718 if ((insn
& (1 << 15)) == 0)
7721 rn
= (insn
>> 16) & 0xf;
7722 addr
= load_reg(s
, rn
);
7724 /* compute total size */
7726 TCGV_UNUSED(loaded_var
);
7729 if (insn
& (1 << i
))
7732 /* XXX: test invalid n == 0 case ? */
7733 if (insn
& (1 << 23)) {
7734 if (insn
& (1 << 24)) {
7736 tcg_gen_addi_i32(addr
, addr
, 4);
7738 /* post increment */
7741 if (insn
& (1 << 24)) {
7743 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7745 /* post decrement */
7747 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7752 if (insn
& (1 << i
)) {
7753 if (insn
& (1 << 20)) {
7755 tmp
= gen_ld32(addr
, IS_USER(s
));
7757 tmp2
= tcg_const_i32(i
);
7758 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7759 tcg_temp_free_i32(tmp2
);
7760 tcg_temp_free_i32(tmp
);
7761 } else if (i
== rn
) {
7765 store_reg_from_load(env
, s
, i
, tmp
);
7770 /* special case: r15 = PC + 8 */
7771 val
= (long)s
->pc
+ 4;
7772 tmp
= tcg_temp_new_i32();
7773 tcg_gen_movi_i32(tmp
, val
);
7775 tmp
= tcg_temp_new_i32();
7776 tmp2
= tcg_const_i32(i
);
7777 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7778 tcg_temp_free_i32(tmp2
);
7780 tmp
= load_reg(s
, i
);
7782 gen_st32(tmp
, addr
, IS_USER(s
));
7785 /* no need to add after the last transfer */
7787 tcg_gen_addi_i32(addr
, addr
, 4);
7790 if (insn
& (1 << 21)) {
7792 if (insn
& (1 << 23)) {
7793 if (insn
& (1 << 24)) {
7796 /* post increment */
7797 tcg_gen_addi_i32(addr
, addr
, 4);
7800 if (insn
& (1 << 24)) {
7803 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7805 /* post decrement */
7806 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7809 store_reg(s
, rn
, addr
);
7811 tcg_temp_free_i32(addr
);
7814 store_reg(s
, rn
, loaded_var
);
7816 if ((insn
& (1 << 22)) && !user
) {
7817 /* Restore CPSR from SPSR. */
7818 tmp
= load_cpu_field(spsr
);
7819 gen_set_cpsr(tmp
, 0xffffffff);
7820 tcg_temp_free_i32(tmp
);
7821 s
->is_jmp
= DISAS_UPDATE
;
7830 /* branch (and link) */
7831 val
= (int32_t)s
->pc
;
7832 if (insn
& (1 << 24)) {
7833 tmp
= tcg_temp_new_i32();
7834 tcg_gen_movi_i32(tmp
, val
);
7835 store_reg(s
, 14, tmp
);
7837 offset
= (((int32_t)insn
<< 8) >> 8);
7838 val
+= (offset
<< 2) + 4;
7846 if (disas_coproc_insn(env
, s
, insn
))
7851 gen_set_pc_im(s
->pc
);
7852 s
->is_jmp
= DISAS_SWI
;
7856 gen_exception_insn(s
, 4, EXCP_UDEF
);
7862 /* Return true if this is a Thumb-2 logical op. */
7864 thumb2_logic_op(int op
)
7869 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7870 then set condition code flags based on the result of the operation.
7871 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7872 to the high bit of T1.
7873 Returns zero if the opcode is valid. */
7876 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7883 tcg_gen_and_i32(t0
, t0
, t1
);
7887 tcg_gen_andc_i32(t0
, t0
, t1
);
7891 tcg_gen_or_i32(t0
, t0
, t1
);
7895 tcg_gen_orc_i32(t0
, t0
, t1
);
7899 tcg_gen_xor_i32(t0
, t0
, t1
);
7904 gen_add_CC(t0
, t0
, t1
);
7906 tcg_gen_add_i32(t0
, t0
, t1
);
7910 gen_helper_adc_cc(t0
, cpu_env
, t0
, t1
);
7916 gen_helper_sbc_cc(t0
, cpu_env
, t0
, t1
);
7918 gen_sub_carry(t0
, t0
, t1
);
7922 gen_sub_CC(t0
, t0
, t1
);
7924 tcg_gen_sub_i32(t0
, t0
, t1
);
7928 gen_sub_CC(t0
, t1
, t0
);
7930 tcg_gen_sub_i32(t0
, t1
, t0
);
7932 default: /* 5, 6, 7, 9, 12, 15. */
7938 gen_set_CF_bit31(t1
);
7943 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7945 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7947 uint32_t insn
, imm
, shift
, offset
;
7948 uint32_t rd
, rn
, rm
, rs
;
7959 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7960 || arm_feature (env
, ARM_FEATURE_M
))) {
7961 /* Thumb-1 cores may need to treat bl and blx as a pair of
7962 16-bit instructions to get correct prefetch abort behavior. */
7964 if ((insn
& (1 << 12)) == 0) {
7966 /* Second half of blx. */
7967 offset
= ((insn
& 0x7ff) << 1);
7968 tmp
= load_reg(s
, 14);
7969 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7970 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7972 tmp2
= tcg_temp_new_i32();
7973 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7974 store_reg(s
, 14, tmp2
);
7978 if (insn
& (1 << 11)) {
7979 /* Second half of bl. */
7980 offset
= ((insn
& 0x7ff) << 1) | 1;
7981 tmp
= load_reg(s
, 14);
7982 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7984 tmp2
= tcg_temp_new_i32();
7985 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7986 store_reg(s
, 14, tmp2
);
7990 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7991 /* Instruction spans a page boundary. Implement it as two
7992 16-bit instructions in case the second half causes an
7994 offset
= ((int32_t)insn
<< 21) >> 9;
7995 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7998 /* Fall through to 32-bit decode. */
8001 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8003 insn
|= (uint32_t)insn_hw1
<< 16;
8005 if ((insn
& 0xf800e800) != 0xf000e800) {
8009 rn
= (insn
>> 16) & 0xf;
8010 rs
= (insn
>> 12) & 0xf;
8011 rd
= (insn
>> 8) & 0xf;
8013 switch ((insn
>> 25) & 0xf) {
8014 case 0: case 1: case 2: case 3:
8015 /* 16-bit instructions. Should never happen. */
8018 if (insn
& (1 << 22)) {
8019 /* Other load/store, table branch. */
8020 if (insn
& 0x01200000) {
8021 /* Load/store doubleword. */
8023 addr
= tcg_temp_new_i32();
8024 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8026 addr
= load_reg(s
, rn
);
8028 offset
= (insn
& 0xff) * 4;
8029 if ((insn
& (1 << 23)) == 0)
8031 if (insn
& (1 << 24)) {
8032 tcg_gen_addi_i32(addr
, addr
, offset
);
8035 if (insn
& (1 << 20)) {
8037 tmp
= gen_ld32(addr
, IS_USER(s
));
8038 store_reg(s
, rs
, tmp
);
8039 tcg_gen_addi_i32(addr
, addr
, 4);
8040 tmp
= gen_ld32(addr
, IS_USER(s
));
8041 store_reg(s
, rd
, tmp
);
8044 tmp
= load_reg(s
, rs
);
8045 gen_st32(tmp
, addr
, IS_USER(s
));
8046 tcg_gen_addi_i32(addr
, addr
, 4);
8047 tmp
= load_reg(s
, rd
);
8048 gen_st32(tmp
, addr
, IS_USER(s
));
8050 if (insn
& (1 << 21)) {
8051 /* Base writeback. */
8054 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8055 store_reg(s
, rn
, addr
);
8057 tcg_temp_free_i32(addr
);
8059 } else if ((insn
& (1 << 23)) == 0) {
8060 /* Load/store exclusive word. */
8061 addr
= tcg_temp_local_new();
8062 load_reg_var(s
, addr
, rn
);
8063 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8064 if (insn
& (1 << 20)) {
8065 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8067 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8069 tcg_temp_free(addr
);
8070 } else if ((insn
& (1 << 6)) == 0) {
8073 addr
= tcg_temp_new_i32();
8074 tcg_gen_movi_i32(addr
, s
->pc
);
8076 addr
= load_reg(s
, rn
);
8078 tmp
= load_reg(s
, rm
);
8079 tcg_gen_add_i32(addr
, addr
, tmp
);
8080 if (insn
& (1 << 4)) {
8082 tcg_gen_add_i32(addr
, addr
, tmp
);
8083 tcg_temp_free_i32(tmp
);
8084 tmp
= gen_ld16u(addr
, IS_USER(s
));
8086 tcg_temp_free_i32(tmp
);
8087 tmp
= gen_ld8u(addr
, IS_USER(s
));
8089 tcg_temp_free_i32(addr
);
8090 tcg_gen_shli_i32(tmp
, tmp
, 1);
8091 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8092 store_reg(s
, 15, tmp
);
8094 /* Load/store exclusive byte/halfword/doubleword. */
8096 op
= (insn
>> 4) & 0x3;
8100 addr
= tcg_temp_local_new();
8101 load_reg_var(s
, addr
, rn
);
8102 if (insn
& (1 << 20)) {
8103 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8105 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8107 tcg_temp_free(addr
);
8110 /* Load/store multiple, RFE, SRS. */
8111 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8112 /* Not available in user mode. */
8115 if (insn
& (1 << 20)) {
8117 addr
= load_reg(s
, rn
);
8118 if ((insn
& (1 << 24)) == 0)
8119 tcg_gen_addi_i32(addr
, addr
, -8);
8120 /* Load PC into tmp and CPSR into tmp2. */
8121 tmp
= gen_ld32(addr
, 0);
8122 tcg_gen_addi_i32(addr
, addr
, 4);
8123 tmp2
= gen_ld32(addr
, 0);
8124 if (insn
& (1 << 21)) {
8125 /* Base writeback. */
8126 if (insn
& (1 << 24)) {
8127 tcg_gen_addi_i32(addr
, addr
, 4);
8129 tcg_gen_addi_i32(addr
, addr
, -4);
8131 store_reg(s
, rn
, addr
);
8133 tcg_temp_free_i32(addr
);
8135 gen_rfe(s
, tmp
, tmp2
);
8139 addr
= tcg_temp_new_i32();
8140 tmp
= tcg_const_i32(op
);
8141 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8142 tcg_temp_free_i32(tmp
);
8143 if ((insn
& (1 << 24)) == 0) {
8144 tcg_gen_addi_i32(addr
, addr
, -8);
8146 tmp
= load_reg(s
, 14);
8147 gen_st32(tmp
, addr
, 0);
8148 tcg_gen_addi_i32(addr
, addr
, 4);
8149 tmp
= tcg_temp_new_i32();
8150 gen_helper_cpsr_read(tmp
, cpu_env
);
8151 gen_st32(tmp
, addr
, 0);
8152 if (insn
& (1 << 21)) {
8153 if ((insn
& (1 << 24)) == 0) {
8154 tcg_gen_addi_i32(addr
, addr
, -4);
8156 tcg_gen_addi_i32(addr
, addr
, 4);
8158 tmp
= tcg_const_i32(op
);
8159 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8160 tcg_temp_free_i32(tmp
);
8162 tcg_temp_free_i32(addr
);
8166 int i
, loaded_base
= 0;
8168 /* Load/store multiple. */
8169 addr
= load_reg(s
, rn
);
8171 for (i
= 0; i
< 16; i
++) {
8172 if (insn
& (1 << i
))
8175 if (insn
& (1 << 24)) {
8176 tcg_gen_addi_i32(addr
, addr
, -offset
);
8179 TCGV_UNUSED(loaded_var
);
8180 for (i
= 0; i
< 16; i
++) {
8181 if ((insn
& (1 << i
)) == 0)
8183 if (insn
& (1 << 20)) {
8185 tmp
= gen_ld32(addr
, IS_USER(s
));
8188 } else if (i
== rn
) {
8192 store_reg(s
, i
, tmp
);
8196 tmp
= load_reg(s
, i
);
8197 gen_st32(tmp
, addr
, IS_USER(s
));
8199 tcg_gen_addi_i32(addr
, addr
, 4);
8202 store_reg(s
, rn
, loaded_var
);
8204 if (insn
& (1 << 21)) {
8205 /* Base register writeback. */
8206 if (insn
& (1 << 24)) {
8207 tcg_gen_addi_i32(addr
, addr
, -offset
);
8209 /* Fault if writeback register is in register list. */
8210 if (insn
& (1 << rn
))
8212 store_reg(s
, rn
, addr
);
8214 tcg_temp_free_i32(addr
);
8221 op
= (insn
>> 21) & 0xf;
8223 /* Halfword pack. */
8224 tmp
= load_reg(s
, rn
);
8225 tmp2
= load_reg(s
, rm
);
8226 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8227 if (insn
& (1 << 5)) {
8231 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8232 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8233 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8237 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8238 tcg_gen_ext16u_i32(tmp
, tmp
);
8239 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8241 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8242 tcg_temp_free_i32(tmp2
);
8243 store_reg(s
, rd
, tmp
);
8245 /* Data processing register constant shift. */
8247 tmp
= tcg_temp_new_i32();
8248 tcg_gen_movi_i32(tmp
, 0);
8250 tmp
= load_reg(s
, rn
);
8252 tmp2
= load_reg(s
, rm
);
8254 shiftop
= (insn
>> 4) & 3;
8255 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8256 conds
= (insn
& (1 << 20)) != 0;
8257 logic_cc
= (conds
&& thumb2_logic_op(op
));
8258 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8259 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8261 tcg_temp_free_i32(tmp2
);
8263 store_reg(s
, rd
, tmp
);
8265 tcg_temp_free_i32(tmp
);
8269 case 13: /* Misc data processing. */
8270 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8271 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8274 case 0: /* Register controlled shift. */
8275 tmp
= load_reg(s
, rn
);
8276 tmp2
= load_reg(s
, rm
);
8277 if ((insn
& 0x70) != 0)
8279 op
= (insn
>> 21) & 3;
8280 logic_cc
= (insn
& (1 << 20)) != 0;
8281 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8284 store_reg_bx(env
, s
, rd
, tmp
);
8286 case 1: /* Sign/zero extend. */
8287 tmp
= load_reg(s
, rm
);
8288 shift
= (insn
>> 4) & 3;
8289 /* ??? In many cases it's not necessary to do a
8290 rotate, a shift is sufficient. */
8292 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8293 op
= (insn
>> 20) & 7;
8295 case 0: gen_sxth(tmp
); break;
8296 case 1: gen_uxth(tmp
); break;
8297 case 2: gen_sxtb16(tmp
); break;
8298 case 3: gen_uxtb16(tmp
); break;
8299 case 4: gen_sxtb(tmp
); break;
8300 case 5: gen_uxtb(tmp
); break;
8301 default: goto illegal_op
;
8304 tmp2
= load_reg(s
, rn
);
8305 if ((op
>> 1) == 1) {
8306 gen_add16(tmp
, tmp2
);
8308 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8309 tcg_temp_free_i32(tmp2
);
8312 store_reg(s
, rd
, tmp
);
8314 case 2: /* SIMD add/subtract. */
8315 op
= (insn
>> 20) & 7;
8316 shift
= (insn
>> 4) & 7;
8317 if ((op
& 3) == 3 || (shift
& 3) == 3)
8319 tmp
= load_reg(s
, rn
);
8320 tmp2
= load_reg(s
, rm
);
8321 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8322 tcg_temp_free_i32(tmp2
);
8323 store_reg(s
, rd
, tmp
);
8325 case 3: /* Other data processing. */
8326 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8328 /* Saturating add/subtract. */
8329 tmp
= load_reg(s
, rn
);
8330 tmp2
= load_reg(s
, rm
);
8332 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8334 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8336 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8337 tcg_temp_free_i32(tmp2
);
8339 tmp
= load_reg(s
, rn
);
8341 case 0x0a: /* rbit */
8342 gen_helper_rbit(tmp
, tmp
);
8344 case 0x08: /* rev */
8345 tcg_gen_bswap32_i32(tmp
, tmp
);
8347 case 0x09: /* rev16 */
8350 case 0x0b: /* revsh */
8353 case 0x10: /* sel */
8354 tmp2
= load_reg(s
, rm
);
8355 tmp3
= tcg_temp_new_i32();
8356 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8357 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8358 tcg_temp_free_i32(tmp3
);
8359 tcg_temp_free_i32(tmp2
);
8361 case 0x18: /* clz */
8362 gen_helper_clz(tmp
, tmp
);
8368 store_reg(s
, rd
, tmp
);
8370 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8371 op
= (insn
>> 4) & 0xf;
8372 tmp
= load_reg(s
, rn
);
8373 tmp2
= load_reg(s
, rm
);
8374 switch ((insn
>> 20) & 7) {
8375 case 0: /* 32 x 32 -> 32 */
8376 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8377 tcg_temp_free_i32(tmp2
);
8379 tmp2
= load_reg(s
, rs
);
8381 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8383 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8384 tcg_temp_free_i32(tmp2
);
8387 case 1: /* 16 x 16 -> 32 */
8388 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8389 tcg_temp_free_i32(tmp2
);
8391 tmp2
= load_reg(s
, rs
);
8392 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8393 tcg_temp_free_i32(tmp2
);
8396 case 2: /* Dual multiply add. */
8397 case 4: /* Dual multiply subtract. */
8399 gen_swap_half(tmp2
);
8400 gen_smul_dual(tmp
, tmp2
);
8401 if (insn
& (1 << 22)) {
8402 /* This subtraction cannot overflow. */
8403 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8405 /* This addition cannot overflow 32 bits;
8406 * however it may overflow considered as a signed
8407 * operation, in which case we must set the Q flag.
8409 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8411 tcg_temp_free_i32(tmp2
);
8414 tmp2
= load_reg(s
, rs
);
8415 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8416 tcg_temp_free_i32(tmp2
);
8419 case 3: /* 32 * 16 -> 32msb */
8421 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8424 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8425 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8426 tmp
= tcg_temp_new_i32();
8427 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8428 tcg_temp_free_i64(tmp64
);
8431 tmp2
= load_reg(s
, rs
);
8432 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8433 tcg_temp_free_i32(tmp2
);
8436 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8437 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8439 tmp
= load_reg(s
, rs
);
8440 if (insn
& (1 << 20)) {
8441 tmp64
= gen_addq_msw(tmp64
, tmp
);
8443 tmp64
= gen_subq_msw(tmp64
, tmp
);
8446 if (insn
& (1 << 4)) {
8447 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8449 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8450 tmp
= tcg_temp_new_i32();
8451 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8452 tcg_temp_free_i64(tmp64
);
8454 case 7: /* Unsigned sum of absolute differences. */
8455 gen_helper_usad8(tmp
, tmp
, tmp2
);
8456 tcg_temp_free_i32(tmp2
);
8458 tmp2
= load_reg(s
, rs
);
8459 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8460 tcg_temp_free_i32(tmp2
);
8464 store_reg(s
, rd
, tmp
);
8466 case 6: case 7: /* 64-bit multiply, Divide. */
8467 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8468 tmp
= load_reg(s
, rn
);
8469 tmp2
= load_reg(s
, rm
);
8470 if ((op
& 0x50) == 0x10) {
8472 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8476 gen_helper_udiv(tmp
, tmp
, tmp2
);
8478 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8479 tcg_temp_free_i32(tmp2
);
8480 store_reg(s
, rd
, tmp
);
8481 } else if ((op
& 0xe) == 0xc) {
8482 /* Dual multiply accumulate long. */
8484 gen_swap_half(tmp2
);
8485 gen_smul_dual(tmp
, tmp2
);
8487 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8489 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8491 tcg_temp_free_i32(tmp2
);
8493 tmp64
= tcg_temp_new_i64();
8494 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8495 tcg_temp_free_i32(tmp
);
8496 gen_addq(s
, tmp64
, rs
, rd
);
8497 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8498 tcg_temp_free_i64(tmp64
);
8501 /* Unsigned 64-bit multiply */
8502 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8506 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8507 tcg_temp_free_i32(tmp2
);
8508 tmp64
= tcg_temp_new_i64();
8509 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8510 tcg_temp_free_i32(tmp
);
8512 /* Signed 64-bit multiply */
8513 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8518 gen_addq_lo(s
, tmp64
, rs
);
8519 gen_addq_lo(s
, tmp64
, rd
);
8520 } else if (op
& 0x40) {
8521 /* 64-bit accumulate. */
8522 gen_addq(s
, tmp64
, rs
, rd
);
8524 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8525 tcg_temp_free_i64(tmp64
);
8530 case 6: case 7: case 14: case 15:
8532 if (((insn
>> 24) & 3) == 3) {
8533 /* Translate into the equivalent ARM encoding. */
8534 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8535 if (disas_neon_data_insn(env
, s
, insn
))
8538 if (insn
& (1 << 28))
8540 if (disas_coproc_insn (env
, s
, insn
))
8544 case 8: case 9: case 10: case 11:
8545 if (insn
& (1 << 15)) {
8546 /* Branches, misc control. */
8547 if (insn
& 0x5000) {
8548 /* Unconditional branch. */
8549 /* signextend(hw1[10:0]) -> offset[:12]. */
8550 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8551 /* hw1[10:0] -> offset[11:1]. */
8552 offset
|= (insn
& 0x7ff) << 1;
8553 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8554 offset[24:22] already have the same value because of the
8555 sign extension above. */
8556 offset
^= ((~insn
) & (1 << 13)) << 10;
8557 offset
^= ((~insn
) & (1 << 11)) << 11;
8559 if (insn
& (1 << 14)) {
8560 /* Branch and link. */
8561 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8565 if (insn
& (1 << 12)) {
8570 offset
&= ~(uint32_t)2;
8571 /* thumb2 bx, no need to check */
8572 gen_bx_im(s
, offset
);
8574 } else if (((insn
>> 23) & 7) == 7) {
8576 if (insn
& (1 << 13))
8579 if (insn
& (1 << 26)) {
8580 /* Secure monitor call (v6Z) */
8581 goto illegal_op
; /* not implemented. */
8583 op
= (insn
>> 20) & 7;
8585 case 0: /* msr cpsr. */
8587 tmp
= load_reg(s
, rn
);
8588 addr
= tcg_const_i32(insn
& 0xff);
8589 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8590 tcg_temp_free_i32(addr
);
8591 tcg_temp_free_i32(tmp
);
8596 case 1: /* msr spsr. */
8599 tmp
= load_reg(s
, rn
);
8601 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8605 case 2: /* cps, nop-hint. */
8606 if (((insn
>> 8) & 7) == 0) {
8607 gen_nop_hint(s
, insn
& 0xff);
8609 /* Implemented as NOP in user mode. */
8614 if (insn
& (1 << 10)) {
8615 if (insn
& (1 << 7))
8617 if (insn
& (1 << 6))
8619 if (insn
& (1 << 5))
8621 if (insn
& (1 << 9))
8622 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8624 if (insn
& (1 << 8)) {
8626 imm
|= (insn
& 0x1f);
8629 gen_set_psr_im(s
, offset
, 0, imm
);
8632 case 3: /* Special control operations. */
8634 op
= (insn
>> 4) & 0xf;
8642 /* These execute as NOPs. */
8649 /* Trivial implementation equivalent to bx. */
8650 tmp
= load_reg(s
, rn
);
8653 case 5: /* Exception return. */
8657 if (rn
!= 14 || rd
!= 15) {
8660 tmp
= load_reg(s
, rn
);
8661 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8662 gen_exception_return(s
, tmp
);
8664 case 6: /* mrs cpsr. */
8665 tmp
= tcg_temp_new_i32();
8667 addr
= tcg_const_i32(insn
& 0xff);
8668 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8669 tcg_temp_free_i32(addr
);
8671 gen_helper_cpsr_read(tmp
, cpu_env
);
8673 store_reg(s
, rd
, tmp
);
8675 case 7: /* mrs spsr. */
8676 /* Not accessible in user mode. */
8677 if (IS_USER(s
) || IS_M(env
))
8679 tmp
= load_cpu_field(spsr
);
8680 store_reg(s
, rd
, tmp
);
8685 /* Conditional branch. */
8686 op
= (insn
>> 22) & 0xf;
8687 /* Generate a conditional jump to next instruction. */
8688 s
->condlabel
= gen_new_label();
8689 gen_test_cc(op
^ 1, s
->condlabel
);
8692 /* offset[11:1] = insn[10:0] */
8693 offset
= (insn
& 0x7ff) << 1;
8694 /* offset[17:12] = insn[21:16]. */
8695 offset
|= (insn
& 0x003f0000) >> 4;
8696 /* offset[31:20] = insn[26]. */
8697 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8698 /* offset[18] = insn[13]. */
8699 offset
|= (insn
& (1 << 13)) << 5;
8700 /* offset[19] = insn[11]. */
8701 offset
|= (insn
& (1 << 11)) << 8;
8703 /* jump to the offset */
8704 gen_jmp(s
, s
->pc
+ offset
);
8707 /* Data processing immediate. */
8708 if (insn
& (1 << 25)) {
8709 if (insn
& (1 << 24)) {
8710 if (insn
& (1 << 20))
8712 /* Bitfield/Saturate. */
8713 op
= (insn
>> 21) & 7;
8715 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8717 tmp
= tcg_temp_new_i32();
8718 tcg_gen_movi_i32(tmp
, 0);
8720 tmp
= load_reg(s
, rn
);
8723 case 2: /* Signed bitfield extract. */
8725 if (shift
+ imm
> 32)
8728 gen_sbfx(tmp
, shift
, imm
);
8730 case 6: /* Unsigned bitfield extract. */
8732 if (shift
+ imm
> 32)
8735 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8737 case 3: /* Bitfield insert/clear. */
8740 imm
= imm
+ 1 - shift
;
8742 tmp2
= load_reg(s
, rd
);
8743 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8744 tcg_temp_free_i32(tmp2
);
8749 default: /* Saturate. */
8752 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8754 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8756 tmp2
= tcg_const_i32(imm
);
8759 if ((op
& 1) && shift
== 0)
8760 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8762 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8765 if ((op
& 1) && shift
== 0)
8766 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8768 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8770 tcg_temp_free_i32(tmp2
);
8773 store_reg(s
, rd
, tmp
);
8775 imm
= ((insn
& 0x04000000) >> 15)
8776 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8777 if (insn
& (1 << 22)) {
8778 /* 16-bit immediate. */
8779 imm
|= (insn
>> 4) & 0xf000;
8780 if (insn
& (1 << 23)) {
8782 tmp
= load_reg(s
, rd
);
8783 tcg_gen_ext16u_i32(tmp
, tmp
);
8784 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8787 tmp
= tcg_temp_new_i32();
8788 tcg_gen_movi_i32(tmp
, imm
);
8791 /* Add/sub 12-bit immediate. */
8793 offset
= s
->pc
& ~(uint32_t)3;
8794 if (insn
& (1 << 23))
8798 tmp
= tcg_temp_new_i32();
8799 tcg_gen_movi_i32(tmp
, offset
);
8801 tmp
= load_reg(s
, rn
);
8802 if (insn
& (1 << 23))
8803 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8805 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8808 store_reg(s
, rd
, tmp
);
8811 int shifter_out
= 0;
8812 /* modified 12-bit immediate. */
8813 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8814 imm
= (insn
& 0xff);
8817 /* Nothing to do. */
8819 case 1: /* 00XY00XY */
8822 case 2: /* XY00XY00 */
8826 case 3: /* XYXYXYXY */
8830 default: /* Rotated constant. */
8831 shift
= (shift
<< 1) | (imm
>> 7);
8833 imm
= imm
<< (32 - shift
);
8837 tmp2
= tcg_temp_new_i32();
8838 tcg_gen_movi_i32(tmp2
, imm
);
8839 rn
= (insn
>> 16) & 0xf;
8841 tmp
= tcg_temp_new_i32();
8842 tcg_gen_movi_i32(tmp
, 0);
8844 tmp
= load_reg(s
, rn
);
8846 op
= (insn
>> 21) & 0xf;
8847 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8848 shifter_out
, tmp
, tmp2
))
8850 tcg_temp_free_i32(tmp2
);
8851 rd
= (insn
>> 8) & 0xf;
8853 store_reg(s
, rd
, tmp
);
8855 tcg_temp_free_i32(tmp
);
8860 case 12: /* Load/store single data item. */
8865 if ((insn
& 0x01100000) == 0x01000000) {
8866 if (disas_neon_ls_insn(env
, s
, insn
))
8870 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8872 if (!(insn
& (1 << 20))) {
8876 /* Byte or halfword load space with dest == r15 : memory hints.
8877 * Catch them early so we don't emit pointless addressing code.
8878 * This space is a mix of:
8879 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8880 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8882 * unallocated hints, which must be treated as NOPs
8883 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8884 * which is easiest for the decoding logic
8885 * Some space which must UNDEF
8887 int op1
= (insn
>> 23) & 3;
8888 int op2
= (insn
>> 6) & 0x3f;
8893 /* UNPREDICTABLE, unallocated hint or
8894 * PLD/PLDW/PLI (literal)
8899 return 0; /* PLD/PLDW/PLI or unallocated hint */
8901 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8902 return 0; /* PLD/PLDW/PLI or unallocated hint */
8904 /* UNDEF space, or an UNPREDICTABLE */
8910 addr
= tcg_temp_new_i32();
8912 /* s->pc has already been incremented by 4. */
8913 imm
= s
->pc
& 0xfffffffc;
8914 if (insn
& (1 << 23))
8915 imm
+= insn
& 0xfff;
8917 imm
-= insn
& 0xfff;
8918 tcg_gen_movi_i32(addr
, imm
);
8920 addr
= load_reg(s
, rn
);
8921 if (insn
& (1 << 23)) {
8922 /* Positive offset. */
8924 tcg_gen_addi_i32(addr
, addr
, imm
);
8927 switch ((insn
>> 8) & 0xf) {
8928 case 0x0: /* Shifted Register. */
8929 shift
= (insn
>> 4) & 0xf;
8931 tcg_temp_free_i32(addr
);
8934 tmp
= load_reg(s
, rm
);
8936 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8937 tcg_gen_add_i32(addr
, addr
, tmp
);
8938 tcg_temp_free_i32(tmp
);
8940 case 0xc: /* Negative offset. */
8941 tcg_gen_addi_i32(addr
, addr
, -imm
);
8943 case 0xe: /* User privilege. */
8944 tcg_gen_addi_i32(addr
, addr
, imm
);
8947 case 0x9: /* Post-decrement. */
8950 case 0xb: /* Post-increment. */
8954 case 0xd: /* Pre-decrement. */
8957 case 0xf: /* Pre-increment. */
8958 tcg_gen_addi_i32(addr
, addr
, imm
);
8962 tcg_temp_free_i32(addr
);
8967 if (insn
& (1 << 20)) {
8970 case 0: tmp
= gen_ld8u(addr
, user
); break;
8971 case 4: tmp
= gen_ld8s(addr
, user
); break;
8972 case 1: tmp
= gen_ld16u(addr
, user
); break;
8973 case 5: tmp
= gen_ld16s(addr
, user
); break;
8974 case 2: tmp
= gen_ld32(addr
, user
); break;
8976 tcg_temp_free_i32(addr
);
8982 store_reg(s
, rs
, tmp
);
8986 tmp
= load_reg(s
, rs
);
8988 case 0: gen_st8(tmp
, addr
, user
); break;
8989 case 1: gen_st16(tmp
, addr
, user
); break;
8990 case 2: gen_st32(tmp
, addr
, user
); break;
8992 tcg_temp_free_i32(addr
);
8997 tcg_gen_addi_i32(addr
, addr
, imm
);
8999 store_reg(s
, rn
, addr
);
9001 tcg_temp_free_i32(addr
);
9013 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9015 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9022 if (s
->condexec_mask
) {
9023 cond
= s
->condexec_cond
;
9024 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9025 s
->condlabel
= gen_new_label();
9026 gen_test_cc(cond
^ 1, s
->condlabel
);
9031 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9034 switch (insn
>> 12) {
9038 op
= (insn
>> 11) & 3;
9041 rn
= (insn
>> 3) & 7;
9042 tmp
= load_reg(s
, rn
);
9043 if (insn
& (1 << 10)) {
9045 tmp2
= tcg_temp_new_i32();
9046 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9049 rm
= (insn
>> 6) & 7;
9050 tmp2
= load_reg(s
, rm
);
9052 if (insn
& (1 << 9)) {
9053 if (s
->condexec_mask
)
9054 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9056 gen_sub_CC(tmp
, tmp
, tmp2
);
9058 if (s
->condexec_mask
)
9059 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9061 gen_add_CC(tmp
, tmp
, tmp2
);
9063 tcg_temp_free_i32(tmp2
);
9064 store_reg(s
, rd
, tmp
);
9066 /* shift immediate */
9067 rm
= (insn
>> 3) & 7;
9068 shift
= (insn
>> 6) & 0x1f;
9069 tmp
= load_reg(s
, rm
);
9070 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9071 if (!s
->condexec_mask
)
9073 store_reg(s
, rd
, tmp
);
9077 /* arithmetic large immediate */
9078 op
= (insn
>> 11) & 3;
9079 rd
= (insn
>> 8) & 0x7;
9080 if (op
== 0) { /* mov */
9081 tmp
= tcg_temp_new_i32();
9082 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9083 if (!s
->condexec_mask
)
9085 store_reg(s
, rd
, tmp
);
9087 tmp
= load_reg(s
, rd
);
9088 tmp2
= tcg_temp_new_i32();
9089 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9092 gen_sub_CC(tmp
, tmp
, tmp2
);
9093 tcg_temp_free_i32(tmp
);
9094 tcg_temp_free_i32(tmp2
);
9097 if (s
->condexec_mask
)
9098 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9100 gen_add_CC(tmp
, tmp
, tmp2
);
9101 tcg_temp_free_i32(tmp2
);
9102 store_reg(s
, rd
, tmp
);
9105 if (s
->condexec_mask
)
9106 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9108 gen_sub_CC(tmp
, tmp
, tmp2
);
9109 tcg_temp_free_i32(tmp2
);
9110 store_reg(s
, rd
, tmp
);
9116 if (insn
& (1 << 11)) {
9117 rd
= (insn
>> 8) & 7;
9118 /* load pc-relative. Bit 1 of PC is ignored. */
9119 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9120 val
&= ~(uint32_t)2;
9121 addr
= tcg_temp_new_i32();
9122 tcg_gen_movi_i32(addr
, val
);
9123 tmp
= gen_ld32(addr
, IS_USER(s
));
9124 tcg_temp_free_i32(addr
);
9125 store_reg(s
, rd
, tmp
);
9128 if (insn
& (1 << 10)) {
9129 /* data processing extended or blx */
9130 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9131 rm
= (insn
>> 3) & 0xf;
9132 op
= (insn
>> 8) & 3;
9135 tmp
= load_reg(s
, rd
);
9136 tmp2
= load_reg(s
, rm
);
9137 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9138 tcg_temp_free_i32(tmp2
);
9139 store_reg(s
, rd
, tmp
);
9142 tmp
= load_reg(s
, rd
);
9143 tmp2
= load_reg(s
, rm
);
9144 gen_sub_CC(tmp
, tmp
, tmp2
);
9145 tcg_temp_free_i32(tmp2
);
9146 tcg_temp_free_i32(tmp
);
9148 case 2: /* mov/cpy */
9149 tmp
= load_reg(s
, rm
);
9150 store_reg(s
, rd
, tmp
);
9152 case 3:/* branch [and link] exchange thumb register */
9153 tmp
= load_reg(s
, rm
);
9154 if (insn
& (1 << 7)) {
9156 val
= (uint32_t)s
->pc
| 1;
9157 tmp2
= tcg_temp_new_i32();
9158 tcg_gen_movi_i32(tmp2
, val
);
9159 store_reg(s
, 14, tmp2
);
9161 /* already thumb, no need to check */
9168 /* data processing register */
9170 rm
= (insn
>> 3) & 7;
9171 op
= (insn
>> 6) & 0xf;
9172 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9173 /* the shift/rotate ops want the operands backwards */
9182 if (op
== 9) { /* neg */
9183 tmp
= tcg_temp_new_i32();
9184 tcg_gen_movi_i32(tmp
, 0);
9185 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9186 tmp
= load_reg(s
, rd
);
9191 tmp2
= load_reg(s
, rm
);
9194 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9195 if (!s
->condexec_mask
)
9199 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9200 if (!s
->condexec_mask
)
9204 if (s
->condexec_mask
) {
9205 gen_shl(tmp2
, tmp2
, tmp
);
9207 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9212 if (s
->condexec_mask
) {
9213 gen_shr(tmp2
, tmp2
, tmp
);
9215 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9220 if (s
->condexec_mask
) {
9221 gen_sar(tmp2
, tmp2
, tmp
);
9223 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9228 if (s
->condexec_mask
)
9231 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9234 if (s
->condexec_mask
)
9235 gen_sub_carry(tmp
, tmp
, tmp2
);
9237 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9240 if (s
->condexec_mask
) {
9241 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9242 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9244 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9249 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9254 if (s
->condexec_mask
)
9255 tcg_gen_neg_i32(tmp
, tmp2
);
9257 gen_sub_CC(tmp
, tmp
, tmp2
);
9260 gen_sub_CC(tmp
, tmp
, tmp2
);
9264 gen_add_CC(tmp
, tmp
, tmp2
);
9268 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9269 if (!s
->condexec_mask
)
9273 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9274 if (!s
->condexec_mask
)
9278 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9279 if (!s
->condexec_mask
)
9283 tcg_gen_not_i32(tmp2
, tmp2
);
9284 if (!s
->condexec_mask
)
9292 store_reg(s
, rm
, tmp2
);
9294 tcg_temp_free_i32(tmp
);
9296 store_reg(s
, rd
, tmp
);
9297 tcg_temp_free_i32(tmp2
);
9300 tcg_temp_free_i32(tmp
);
9301 tcg_temp_free_i32(tmp2
);
9306 /* load/store register offset. */
9308 rn
= (insn
>> 3) & 7;
9309 rm
= (insn
>> 6) & 7;
9310 op
= (insn
>> 9) & 7;
9311 addr
= load_reg(s
, rn
);
9312 tmp
= load_reg(s
, rm
);
9313 tcg_gen_add_i32(addr
, addr
, tmp
);
9314 tcg_temp_free_i32(tmp
);
9316 if (op
< 3) /* store */
9317 tmp
= load_reg(s
, rd
);
9321 gen_st32(tmp
, addr
, IS_USER(s
));
9324 gen_st16(tmp
, addr
, IS_USER(s
));
9327 gen_st8(tmp
, addr
, IS_USER(s
));
9330 tmp
= gen_ld8s(addr
, IS_USER(s
));
9333 tmp
= gen_ld32(addr
, IS_USER(s
));
9336 tmp
= gen_ld16u(addr
, IS_USER(s
));
9339 tmp
= gen_ld8u(addr
, IS_USER(s
));
9342 tmp
= gen_ld16s(addr
, IS_USER(s
));
9345 if (op
>= 3) /* load */
9346 store_reg(s
, rd
, tmp
);
9347 tcg_temp_free_i32(addr
);
9351 /* load/store word immediate offset */
9353 rn
= (insn
>> 3) & 7;
9354 addr
= load_reg(s
, rn
);
9355 val
= (insn
>> 4) & 0x7c;
9356 tcg_gen_addi_i32(addr
, addr
, val
);
9358 if (insn
& (1 << 11)) {
9360 tmp
= gen_ld32(addr
, IS_USER(s
));
9361 store_reg(s
, rd
, tmp
);
9364 tmp
= load_reg(s
, rd
);
9365 gen_st32(tmp
, addr
, IS_USER(s
));
9367 tcg_temp_free_i32(addr
);
9371 /* load/store byte immediate offset */
9373 rn
= (insn
>> 3) & 7;
9374 addr
= load_reg(s
, rn
);
9375 val
= (insn
>> 6) & 0x1f;
9376 tcg_gen_addi_i32(addr
, addr
, val
);
9378 if (insn
& (1 << 11)) {
9380 tmp
= gen_ld8u(addr
, IS_USER(s
));
9381 store_reg(s
, rd
, tmp
);
9384 tmp
= load_reg(s
, rd
);
9385 gen_st8(tmp
, addr
, IS_USER(s
));
9387 tcg_temp_free_i32(addr
);
9391 /* load/store halfword immediate offset */
9393 rn
= (insn
>> 3) & 7;
9394 addr
= load_reg(s
, rn
);
9395 val
= (insn
>> 5) & 0x3e;
9396 tcg_gen_addi_i32(addr
, addr
, val
);
9398 if (insn
& (1 << 11)) {
9400 tmp
= gen_ld16u(addr
, IS_USER(s
));
9401 store_reg(s
, rd
, tmp
);
9404 tmp
= load_reg(s
, rd
);
9405 gen_st16(tmp
, addr
, IS_USER(s
));
9407 tcg_temp_free_i32(addr
);
9411 /* load/store from stack */
9412 rd
= (insn
>> 8) & 7;
9413 addr
= load_reg(s
, 13);
9414 val
= (insn
& 0xff) * 4;
9415 tcg_gen_addi_i32(addr
, addr
, val
);
9417 if (insn
& (1 << 11)) {
9419 tmp
= gen_ld32(addr
, IS_USER(s
));
9420 store_reg(s
, rd
, tmp
);
9423 tmp
= load_reg(s
, rd
);
9424 gen_st32(tmp
, addr
, IS_USER(s
));
9426 tcg_temp_free_i32(addr
);
9430 /* add to high reg */
9431 rd
= (insn
>> 8) & 7;
9432 if (insn
& (1 << 11)) {
9434 tmp
= load_reg(s
, 13);
9436 /* PC. bit 1 is ignored. */
9437 tmp
= tcg_temp_new_i32();
9438 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9440 val
= (insn
& 0xff) * 4;
9441 tcg_gen_addi_i32(tmp
, tmp
, val
);
9442 store_reg(s
, rd
, tmp
);
9447 op
= (insn
>> 8) & 0xf;
9450 /* adjust stack pointer */
9451 tmp
= load_reg(s
, 13);
9452 val
= (insn
& 0x7f) * 4;
9453 if (insn
& (1 << 7))
9454 val
= -(int32_t)val
;
9455 tcg_gen_addi_i32(tmp
, tmp
, val
);
9456 store_reg(s
, 13, tmp
);
9459 case 2: /* sign/zero extend. */
9462 rm
= (insn
>> 3) & 7;
9463 tmp
= load_reg(s
, rm
);
9464 switch ((insn
>> 6) & 3) {
9465 case 0: gen_sxth(tmp
); break;
9466 case 1: gen_sxtb(tmp
); break;
9467 case 2: gen_uxth(tmp
); break;
9468 case 3: gen_uxtb(tmp
); break;
9470 store_reg(s
, rd
, tmp
);
9472 case 4: case 5: case 0xc: case 0xd:
9474 addr
= load_reg(s
, 13);
9475 if (insn
& (1 << 8))
9479 for (i
= 0; i
< 8; i
++) {
9480 if (insn
& (1 << i
))
9483 if ((insn
& (1 << 11)) == 0) {
9484 tcg_gen_addi_i32(addr
, addr
, -offset
);
9486 for (i
= 0; i
< 8; i
++) {
9487 if (insn
& (1 << i
)) {
9488 if (insn
& (1 << 11)) {
9490 tmp
= gen_ld32(addr
, IS_USER(s
));
9491 store_reg(s
, i
, tmp
);
9494 tmp
= load_reg(s
, i
);
9495 gen_st32(tmp
, addr
, IS_USER(s
));
9497 /* advance to the next address. */
9498 tcg_gen_addi_i32(addr
, addr
, 4);
9502 if (insn
& (1 << 8)) {
9503 if (insn
& (1 << 11)) {
9505 tmp
= gen_ld32(addr
, IS_USER(s
));
9506 /* don't set the pc until the rest of the instruction
9510 tmp
= load_reg(s
, 14);
9511 gen_st32(tmp
, addr
, IS_USER(s
));
9513 tcg_gen_addi_i32(addr
, addr
, 4);
9515 if ((insn
& (1 << 11)) == 0) {
9516 tcg_gen_addi_i32(addr
, addr
, -offset
);
9518 /* write back the new stack pointer */
9519 store_reg(s
, 13, addr
);
9520 /* set the new PC value */
9521 if ((insn
& 0x0900) == 0x0900) {
9522 store_reg_from_load(env
, s
, 15, tmp
);
9526 case 1: case 3: case 9: case 11: /* czb */
9528 tmp
= load_reg(s
, rm
);
9529 s
->condlabel
= gen_new_label();
9531 if (insn
& (1 << 11))
9532 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9534 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9535 tcg_temp_free_i32(tmp
);
9536 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9537 val
= (uint32_t)s
->pc
+ 2;
9542 case 15: /* IT, nop-hint. */
9543 if ((insn
& 0xf) == 0) {
9544 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9548 s
->condexec_cond
= (insn
>> 4) & 0xe;
9549 s
->condexec_mask
= insn
& 0x1f;
9550 /* No actual code generated for this insn, just setup state. */
9553 case 0xe: /* bkpt */
9555 gen_exception_insn(s
, 2, EXCP_BKPT
);
9560 rn
= (insn
>> 3) & 0x7;
9562 tmp
= load_reg(s
, rn
);
9563 switch ((insn
>> 6) & 3) {
9564 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9565 case 1: gen_rev16(tmp
); break;
9566 case 3: gen_revsh(tmp
); break;
9567 default: goto illegal_op
;
9569 store_reg(s
, rd
, tmp
);
9573 switch ((insn
>> 5) & 7) {
9577 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9578 /* Dynamic endianness switching not implemented. */
9589 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9592 addr
= tcg_const_i32(19);
9593 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9594 tcg_temp_free_i32(addr
);
9598 addr
= tcg_const_i32(16);
9599 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9600 tcg_temp_free_i32(addr
);
9602 tcg_temp_free_i32(tmp
);
9605 if (insn
& (1 << 4)) {
9606 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9610 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9625 /* load/store multiple */
9627 TCGV_UNUSED(loaded_var
);
9628 rn
= (insn
>> 8) & 0x7;
9629 addr
= load_reg(s
, rn
);
9630 for (i
= 0; i
< 8; i
++) {
9631 if (insn
& (1 << i
)) {
9632 if (insn
& (1 << 11)) {
9634 tmp
= gen_ld32(addr
, IS_USER(s
));
9638 store_reg(s
, i
, tmp
);
9642 tmp
= load_reg(s
, i
);
9643 gen_st32(tmp
, addr
, IS_USER(s
));
9645 /* advance to the next address */
9646 tcg_gen_addi_i32(addr
, addr
, 4);
9649 if ((insn
& (1 << rn
)) == 0) {
9650 /* base reg not in list: base register writeback */
9651 store_reg(s
, rn
, addr
);
9653 /* base reg in list: if load, complete it now */
9654 if (insn
& (1 << 11)) {
9655 store_reg(s
, rn
, loaded_var
);
9657 tcg_temp_free_i32(addr
);
9662 /* conditional branch or swi */
9663 cond
= (insn
>> 8) & 0xf;
9669 gen_set_pc_im(s
->pc
);
9670 s
->is_jmp
= DISAS_SWI
;
9673 /* generate a conditional jump to next instruction */
9674 s
->condlabel
= gen_new_label();
9675 gen_test_cc(cond
^ 1, s
->condlabel
);
9678 /* jump to the offset */
9679 val
= (uint32_t)s
->pc
+ 2;
9680 offset
= ((int32_t)insn
<< 24) >> 24;
9686 if (insn
& (1 << 11)) {
9687 if (disas_thumb2_insn(env
, s
, insn
))
9691 /* unconditional branch */
9692 val
= (uint32_t)s
->pc
;
9693 offset
= ((int32_t)insn
<< 21) >> 21;
9694 val
+= (offset
<< 1) + 2;
9699 if (disas_thumb2_insn(env
, s
, insn
))
9705 gen_exception_insn(s
, 4, EXCP_UDEF
);
9709 gen_exception_insn(s
, 2, EXCP_UDEF
);
9712 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9713 basic block 'tb'. If search_pc is TRUE, also generate PC
9714 information for each intermediate instruction. */
9715 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9716 TranslationBlock
*tb
,
9719 DisasContext dc1
, *dc
= &dc1
;
9721 uint16_t *gen_opc_end
;
9723 target_ulong pc_start
;
9724 uint32_t next_page_start
;
9728 /* generate intermediate code */
9733 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
9735 dc
->is_jmp
= DISAS_NEXT
;
9737 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9739 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9740 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9741 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9742 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9743 #if !defined(CONFIG_USER_ONLY)
9744 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9746 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9747 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9748 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9749 cpu_F0s
= tcg_temp_new_i32();
9750 cpu_F1s
= tcg_temp_new_i32();
9751 cpu_F0d
= tcg_temp_new_i64();
9752 cpu_F1d
= tcg_temp_new_i64();
9755 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9756 cpu_M0
= tcg_temp_new_i64();
9757 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9760 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9762 max_insns
= CF_COUNT_MASK
;
9766 tcg_clear_temp_count();
9768 /* A note on handling of the condexec (IT) bits:
9770 * We want to avoid the overhead of having to write the updated condexec
9771 * bits back to the CPUARMState for every instruction in an IT block. So:
9772 * (1) if the condexec bits are not already zero then we write
9773 * zero back into the CPUARMState now. This avoids complications trying
9774 * to do it at the end of the block. (For example if we don't do this
9775 * it's hard to identify whether we can safely skip writing condexec
9776 * at the end of the TB, which we definitely want to do for the case
9777 * where a TB doesn't do anything with the IT state at all.)
9778 * (2) if we are going to leave the TB then we call gen_set_condexec()
9779 * which will write the correct value into CPUARMState if zero is wrong.
9780 * This is done both for leaving the TB at the end, and for leaving
9781 * it because of an exception we know will happen, which is done in
9782 * gen_exception_insn(). The latter is necessary because we need to
9783 * leave the TB with the PC/IT state just prior to execution of the
9784 * instruction which caused the exception.
9785 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9786 * then the CPUARMState will be wrong and we need to reset it.
9787 * This is handled in the same way as restoration of the
9788 * PC in these situations: we will be called again with search_pc=1
9789 * and generate a mapping of the condexec bits for each PC in
9790 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9791 * this to restore the condexec bits.
9793 * Note that there are no instructions which can read the condexec
9794 * bits, and none which can write non-static values to them, so
9795 * we don't need to care about whether CPUARMState is correct in the
9799 /* Reset the conditional execution bits immediately. This avoids
9800 complications trying to do it at the end of the block. */
9801 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9803 TCGv tmp
= tcg_temp_new_i32();
9804 tcg_gen_movi_i32(tmp
, 0);
9805 store_cpu_field(tmp
, condexec_bits
);
9808 #ifdef CONFIG_USER_ONLY
9809 /* Intercept jump to the magic kernel page. */
9810 if (dc
->pc
>= 0xffff0000) {
9811 /* We always get here via a jump, so know we are not in a
9812 conditional execution block. */
9813 gen_exception(EXCP_KERNEL_TRAP
);
9814 dc
->is_jmp
= DISAS_UPDATE
;
9818 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9819 /* We always get here via a jump, so know we are not in a
9820 conditional execution block. */
9821 gen_exception(EXCP_EXCEPTION_EXIT
);
9822 dc
->is_jmp
= DISAS_UPDATE
;
9827 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9828 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9829 if (bp
->pc
== dc
->pc
) {
9830 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9831 /* Advance PC so that clearing the breakpoint will
9832 invalidate this TB. */
9834 goto done_generating
;
9840 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9844 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9846 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
9847 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9848 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
9849 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
9852 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9855 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9856 tcg_gen_debug_insn_start(dc
->pc
);
9860 disas_thumb_insn(env
, dc
);
9861 if (dc
->condexec_mask
) {
9862 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9863 | ((dc
->condexec_mask
>> 4) & 1);
9864 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9865 if (dc
->condexec_mask
== 0) {
9866 dc
->condexec_cond
= 0;
9870 disas_arm_insn(env
, dc
);
9873 if (dc
->condjmp
&& !dc
->is_jmp
) {
9874 gen_set_label(dc
->condlabel
);
9878 if (tcg_check_temp_count()) {
9879 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9882 /* Translation stops when a conditional branch is encountered.
9883 * Otherwise the subsequent code could get translated several times.
9884 * Also stop translation when a page boundary is reached. This
9885 * ensures prefetch aborts occur at the right place. */
9887 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
9888 !env
->singlestep_enabled
&&
9890 dc
->pc
< next_page_start
&&
9891 num_insns
< max_insns
);
9893 if (tb
->cflags
& CF_LAST_IO
) {
9895 /* FIXME: This can theoretically happen with self-modifying
9897 cpu_abort(env
, "IO on conditional branch instruction");
9902 /* At this stage dc->condjmp will only be set when the skipped
9903 instruction was a conditional branch or trap, and the PC has
9904 already been written. */
9905 if (unlikely(env
->singlestep_enabled
)) {
9906 /* Make sure the pc is updated, and raise a debug exception. */
9908 gen_set_condexec(dc
);
9909 if (dc
->is_jmp
== DISAS_SWI
) {
9910 gen_exception(EXCP_SWI
);
9912 gen_exception(EXCP_DEBUG
);
9914 gen_set_label(dc
->condlabel
);
9916 if (dc
->condjmp
|| !dc
->is_jmp
) {
9917 gen_set_pc_im(dc
->pc
);
9920 gen_set_condexec(dc
);
9921 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9922 gen_exception(EXCP_SWI
);
9924 /* FIXME: Single stepping a WFI insn will not halt
9926 gen_exception(EXCP_DEBUG
);
9929 /* While branches must always occur at the end of an IT block,
9930 there are a few other things that can cause us to terminate
9931 the TB in the middle of an IT block:
9932 - Exception generating instructions (bkpt, swi, undefined).
9934 - Hardware watchpoints.
9935 Hardware breakpoints have already been handled and skip this code.
9937 gen_set_condexec(dc
);
9938 switch(dc
->is_jmp
) {
9940 gen_goto_tb(dc
, 1, dc
->pc
);
9945 /* indicate that the hash table must be used to find the next TB */
9949 /* nothing more to generate */
9952 gen_helper_wfi(cpu_env
);
9955 gen_exception(EXCP_SWI
);
9959 gen_set_label(dc
->condlabel
);
9960 gen_set_condexec(dc
);
9961 gen_goto_tb(dc
, 1, dc
->pc
);
9967 gen_icount_end(tb
, num_insns
);
9968 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
9971 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9972 qemu_log("----------------\n");
9973 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9974 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
9975 dc
->thumb
| (dc
->bswap_code
<< 1));
9980 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9983 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9985 tb
->size
= dc
->pc
- pc_start
;
9986 tb
->icount
= num_insns
;
9990 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
9992 gen_intermediate_code_internal(env
, tb
, 0);
9995 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
9997 gen_intermediate_code_internal(env
, tb
, 1);
10000 static const char *cpu_mode_names
[16] = {
10001 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10002 "???", "???", "???", "und", "???", "???", "???", "sys"
10005 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10011 for(i
=0;i
<16;i
++) {
10012 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10014 cpu_fprintf(f
, "\n");
10016 cpu_fprintf(f
, " ");
10018 psr
= cpsr_read(env
);
10019 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10021 psr
& (1 << 31) ? 'N' : '-',
10022 psr
& (1 << 30) ? 'Z' : '-',
10023 psr
& (1 << 29) ? 'C' : '-',
10024 psr
& (1 << 28) ? 'V' : '-',
10025 psr
& CPSR_T
? 'T' : 'A',
10026 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10028 if (flags
& CPU_DUMP_FPU
) {
10029 int numvfpregs
= 0;
10030 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10033 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10036 for (i
= 0; i
< numvfpregs
; i
++) {
10037 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10038 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10039 i
* 2, (uint32_t)v
,
10040 i
* 2 + 1, (uint32_t)(v
>> 32),
10043 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10047 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10049 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10050 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];