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 "internals.h"
29 #include "disas/disas.h"
32 #include "qemu/bitops.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
52 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
54 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) (s->user)
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
63 static TCGv_i32 cpu_R
[16];
64 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
65 static TCGv_i64 cpu_exclusive_addr
;
66 static TCGv_i64 cpu_exclusive_val
;
67 #ifdef CONFIG_USER_ONLY
68 static TCGv_i64 cpu_exclusive_test
;
69 static TCGv_i32 cpu_exclusive_info
;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s
, cpu_F1s
;
74 static TCGv_i64 cpu_F0d
, cpu_F1d
;
76 #include "exec/gen-icount.h"
78 static const char *regnames
[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
103 #ifdef CONFIG_USER_ONLY
104 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
106 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
107 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
110 a64_translate_init();
113 static inline TCGv_i32
load_cpu_offset(int offset
)
115 TCGv_i32 tmp
= tcg_temp_new_i32();
116 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
120 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
122 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
124 tcg_gen_st_i32(var
, cpu_env
, offset
);
125 tcg_temp_free_i32(var
);
128 #define store_cpu_field(var, name) \
129 store_cpu_offset(var, offsetof(CPUARMState, name))
131 /* Set a variable to the value of a CPU register. */
132 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
136 /* normally, since we updated PC, we need only to add one insn */
138 addr
= (long)s
->pc
+ 2;
140 addr
= (long)s
->pc
+ 4;
141 tcg_gen_movi_i32(var
, addr
);
143 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
147 /* Create a new temporary and set it to the value of a CPU register. */
148 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
150 TCGv_i32 tmp
= tcg_temp_new_i32();
151 load_reg_var(s
, tmp
, reg
);
155 /* Set a CPU register. The source must be a temporary and will be
157 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
160 tcg_gen_andi_i32(var
, var
, ~1);
161 s
->is_jmp
= DISAS_JUMP
;
163 tcg_gen_mov_i32(cpu_R
[reg
], var
);
164 tcg_temp_free_i32(var
);
167 /* Value extensions. */
168 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
169 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
170 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
171 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
173 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
174 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
177 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
179 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
180 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
181 tcg_temp_free_i32(tmp_mask
);
183 /* Set NZCV flags from the high 4 bits of var. */
184 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
186 static void gen_exception_internal(int excp
)
188 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
190 assert(excp_is_internal(excp
));
191 gen_helper_exception_internal(cpu_env
, tcg_excp
);
192 tcg_temp_free_i32(tcg_excp
);
195 static void gen_exception(int excp
, uint32_t syndrome
)
197 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
198 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
200 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
201 tcg_temp_free_i32(tcg_syn
);
202 tcg_temp_free_i32(tcg_excp
);
205 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
207 TCGv_i32 tmp1
= tcg_temp_new_i32();
208 TCGv_i32 tmp2
= tcg_temp_new_i32();
209 tcg_gen_ext16s_i32(tmp1
, a
);
210 tcg_gen_ext16s_i32(tmp2
, b
);
211 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
212 tcg_temp_free_i32(tmp2
);
213 tcg_gen_sari_i32(a
, a
, 16);
214 tcg_gen_sari_i32(b
, b
, 16);
215 tcg_gen_mul_i32(b
, b
, a
);
216 tcg_gen_mov_i32(a
, tmp1
);
217 tcg_temp_free_i32(tmp1
);
220 /* Byteswap each halfword. */
221 static void gen_rev16(TCGv_i32 var
)
223 TCGv_i32 tmp
= tcg_temp_new_i32();
224 tcg_gen_shri_i32(tmp
, var
, 8);
225 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
226 tcg_gen_shli_i32(var
, var
, 8);
227 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
228 tcg_gen_or_i32(var
, var
, tmp
);
229 tcg_temp_free_i32(tmp
);
232 /* Byteswap low halfword and sign extend. */
233 static void gen_revsh(TCGv_i32 var
)
235 tcg_gen_ext16u_i32(var
, var
);
236 tcg_gen_bswap16_i32(var
, var
);
237 tcg_gen_ext16s_i32(var
, var
);
240 /* Unsigned bitfield extract. */
241 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
244 tcg_gen_shri_i32(var
, var
, shift
);
245 tcg_gen_andi_i32(var
, var
, mask
);
248 /* Signed bitfield extract. */
249 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
254 tcg_gen_sari_i32(var
, var
, shift
);
255 if (shift
+ width
< 32) {
256 signbit
= 1u << (width
- 1);
257 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
258 tcg_gen_xori_i32(var
, var
, signbit
);
259 tcg_gen_subi_i32(var
, var
, signbit
);
263 /* Return (b << 32) + a. Mark inputs as dead */
264 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
266 TCGv_i64 tmp64
= tcg_temp_new_i64();
268 tcg_gen_extu_i32_i64(tmp64
, b
);
269 tcg_temp_free_i32(b
);
270 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
271 tcg_gen_add_i64(a
, tmp64
, a
);
273 tcg_temp_free_i64(tmp64
);
277 /* Return (b << 32) - a. Mark inputs as dead. */
278 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
280 TCGv_i64 tmp64
= tcg_temp_new_i64();
282 tcg_gen_extu_i32_i64(tmp64
, b
);
283 tcg_temp_free_i32(b
);
284 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
285 tcg_gen_sub_i64(a
, tmp64
, a
);
287 tcg_temp_free_i64(tmp64
);
291 /* 32x32->64 multiply. Marks inputs as dead. */
292 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
294 TCGv_i32 lo
= tcg_temp_new_i32();
295 TCGv_i32 hi
= tcg_temp_new_i32();
298 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
299 tcg_temp_free_i32(a
);
300 tcg_temp_free_i32(b
);
302 ret
= tcg_temp_new_i64();
303 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
304 tcg_temp_free_i32(lo
);
305 tcg_temp_free_i32(hi
);
310 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
312 TCGv_i32 lo
= tcg_temp_new_i32();
313 TCGv_i32 hi
= tcg_temp_new_i32();
316 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
317 tcg_temp_free_i32(a
);
318 tcg_temp_free_i32(b
);
320 ret
= tcg_temp_new_i64();
321 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
322 tcg_temp_free_i32(lo
);
323 tcg_temp_free_i32(hi
);
328 /* Swap low and high halfwords. */
329 static void gen_swap_half(TCGv_i32 var
)
331 TCGv_i32 tmp
= tcg_temp_new_i32();
332 tcg_gen_shri_i32(tmp
, var
, 16);
333 tcg_gen_shli_i32(var
, var
, 16);
334 tcg_gen_or_i32(var
, var
, tmp
);
335 tcg_temp_free_i32(tmp
);
338 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
339 tmp = (t0 ^ t1) & 0x8000;
342 t0 = (t0 + t1) ^ tmp;
345 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
347 TCGv_i32 tmp
= tcg_temp_new_i32();
348 tcg_gen_xor_i32(tmp
, t0
, t1
);
349 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
350 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
351 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
352 tcg_gen_add_i32(t0
, t0
, t1
);
353 tcg_gen_xor_i32(t0
, t0
, tmp
);
354 tcg_temp_free_i32(tmp
);
355 tcg_temp_free_i32(t1
);
358 /* Set CF to the top bit of var. */
359 static void gen_set_CF_bit31(TCGv_i32 var
)
361 tcg_gen_shri_i32(cpu_CF
, var
, 31);
364 /* Set N and Z flags from var. */
365 static inline void gen_logic_CC(TCGv_i32 var
)
367 tcg_gen_mov_i32(cpu_NF
, var
);
368 tcg_gen_mov_i32(cpu_ZF
, var
);
372 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
374 tcg_gen_add_i32(t0
, t0
, t1
);
375 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
378 /* dest = T0 + T1 + CF. */
379 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
381 tcg_gen_add_i32(dest
, t0
, t1
);
382 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
385 /* dest = T0 - T1 + CF - 1. */
386 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
388 tcg_gen_sub_i32(dest
, t0
, t1
);
389 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
390 tcg_gen_subi_i32(dest
, dest
, 1);
393 /* dest = T0 + T1. Compute C, N, V and Z flags */
394 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
396 TCGv_i32 tmp
= tcg_temp_new_i32();
397 tcg_gen_movi_i32(tmp
, 0);
398 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
399 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
400 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
401 tcg_gen_xor_i32(tmp
, t0
, t1
);
402 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
403 tcg_temp_free_i32(tmp
);
404 tcg_gen_mov_i32(dest
, cpu_NF
);
407 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
408 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
410 TCGv_i32 tmp
= tcg_temp_new_i32();
411 if (TCG_TARGET_HAS_add2_i32
) {
412 tcg_gen_movi_i32(tmp
, 0);
413 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
414 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
416 TCGv_i64 q0
= tcg_temp_new_i64();
417 TCGv_i64 q1
= tcg_temp_new_i64();
418 tcg_gen_extu_i32_i64(q0
, t0
);
419 tcg_gen_extu_i32_i64(q1
, t1
);
420 tcg_gen_add_i64(q0
, q0
, q1
);
421 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
422 tcg_gen_add_i64(q0
, q0
, q1
);
423 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
424 tcg_temp_free_i64(q0
);
425 tcg_temp_free_i64(q1
);
427 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
428 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
429 tcg_gen_xor_i32(tmp
, t0
, t1
);
430 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
431 tcg_temp_free_i32(tmp
);
432 tcg_gen_mov_i32(dest
, cpu_NF
);
435 /* dest = T0 - T1. Compute C, N, V and Z flags */
436 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
439 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
440 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
441 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
442 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
443 tmp
= tcg_temp_new_i32();
444 tcg_gen_xor_i32(tmp
, t0
, t1
);
445 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
446 tcg_temp_free_i32(tmp
);
447 tcg_gen_mov_i32(dest
, cpu_NF
);
450 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
451 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
453 TCGv_i32 tmp
= tcg_temp_new_i32();
454 tcg_gen_not_i32(tmp
, t1
);
455 gen_adc_CC(dest
, t0
, tmp
);
456 tcg_temp_free_i32(tmp
);
459 #define GEN_SHIFT(name) \
460 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
462 TCGv_i32 tmp1, tmp2, tmp3; \
463 tmp1 = tcg_temp_new_i32(); \
464 tcg_gen_andi_i32(tmp1, t1, 0xff); \
465 tmp2 = tcg_const_i32(0); \
466 tmp3 = tcg_const_i32(0x1f); \
467 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
468 tcg_temp_free_i32(tmp3); \
469 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
470 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
471 tcg_temp_free_i32(tmp2); \
472 tcg_temp_free_i32(tmp1); \
478 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
481 tmp1
= tcg_temp_new_i32();
482 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
483 tmp2
= tcg_const_i32(0x1f);
484 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
485 tcg_temp_free_i32(tmp2
);
486 tcg_gen_sar_i32(dest
, t0
, tmp1
);
487 tcg_temp_free_i32(tmp1
);
490 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
492 TCGv_i32 c0
= tcg_const_i32(0);
493 TCGv_i32 tmp
= tcg_temp_new_i32();
494 tcg_gen_neg_i32(tmp
, src
);
495 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
496 tcg_temp_free_i32(c0
);
497 tcg_temp_free_i32(tmp
);
500 static void shifter_out_im(TCGv_i32 var
, int shift
)
503 tcg_gen_andi_i32(cpu_CF
, var
, 1);
505 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
507 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
512 /* Shift by immediate. Includes special handling for shift == 0. */
513 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
514 int shift
, int flags
)
520 shifter_out_im(var
, 32 - shift
);
521 tcg_gen_shli_i32(var
, var
, shift
);
527 tcg_gen_shri_i32(cpu_CF
, var
, 31);
529 tcg_gen_movi_i32(var
, 0);
532 shifter_out_im(var
, shift
- 1);
533 tcg_gen_shri_i32(var
, var
, shift
);
540 shifter_out_im(var
, shift
- 1);
543 tcg_gen_sari_i32(var
, var
, shift
);
545 case 3: /* ROR/RRX */
548 shifter_out_im(var
, shift
- 1);
549 tcg_gen_rotri_i32(var
, var
, shift
); break;
551 TCGv_i32 tmp
= tcg_temp_new_i32();
552 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
554 shifter_out_im(var
, 0);
555 tcg_gen_shri_i32(var
, var
, 1);
556 tcg_gen_or_i32(var
, var
, tmp
);
557 tcg_temp_free_i32(tmp
);
562 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
563 TCGv_i32 shift
, int flags
)
567 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
568 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
569 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
570 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
575 gen_shl(var
, var
, shift
);
578 gen_shr(var
, var
, shift
);
581 gen_sar(var
, var
, shift
);
583 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
584 tcg_gen_rotr_i32(var
, var
, shift
); break;
587 tcg_temp_free_i32(shift
);
590 #define PAS_OP(pfx) \
592 case 0: gen_pas_helper(glue(pfx,add16)); break; \
593 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
594 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
595 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
596 case 4: gen_pas_helper(glue(pfx,add8)); break; \
597 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
599 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
604 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
606 tmp
= tcg_temp_new_ptr();
607 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
609 tcg_temp_free_ptr(tmp
);
612 tmp
= tcg_temp_new_ptr();
613 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
615 tcg_temp_free_ptr(tmp
);
617 #undef gen_pas_helper
618 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
631 #undef gen_pas_helper
636 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
637 #define PAS_OP(pfx) \
639 case 0: gen_pas_helper(glue(pfx,add8)); break; \
640 case 1: gen_pas_helper(glue(pfx,add16)); break; \
641 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
642 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
643 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
644 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
646 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
651 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
653 tmp
= tcg_temp_new_ptr();
654 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
656 tcg_temp_free_ptr(tmp
);
659 tmp
= tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
662 tcg_temp_free_ptr(tmp
);
664 #undef gen_pas_helper
665 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
678 #undef gen_pas_helper
684 * generate a conditional branch based on ARM condition code cc.
685 * This is common between ARM and Aarch64 targets.
687 void arm_gen_test_cc(int cc
, int label
)
694 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
697 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
706 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
709 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
712 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
715 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
717 case 8: /* hi: C && !Z */
718 inv
= gen_new_label();
719 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
720 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
723 case 9: /* ls: !C || Z */
724 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
725 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
727 case 10: /* ge: N == V -> N ^ V == 0 */
728 tmp
= tcg_temp_new_i32();
729 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
730 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
731 tcg_temp_free_i32(tmp
);
733 case 11: /* lt: N != V -> N ^ V != 0 */
734 tmp
= tcg_temp_new_i32();
735 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
736 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
737 tcg_temp_free_i32(tmp
);
739 case 12: /* gt: !Z && N == V */
740 inv
= gen_new_label();
741 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
742 tmp
= tcg_temp_new_i32();
743 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
744 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
745 tcg_temp_free_i32(tmp
);
748 case 13: /* le: Z || N != V */
749 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
750 tmp
= tcg_temp_new_i32();
751 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
752 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
753 tcg_temp_free_i32(tmp
);
756 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
761 static const uint8_t table_logic_cc
[16] = {
780 /* Set PC and Thumb state from an immediate address. */
781 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
785 s
->is_jmp
= DISAS_UPDATE
;
786 if (s
->thumb
!= (addr
& 1)) {
787 tmp
= tcg_temp_new_i32();
788 tcg_gen_movi_i32(tmp
, addr
& 1);
789 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
790 tcg_temp_free_i32(tmp
);
792 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
795 /* Set PC and Thumb state from var. var is marked as dead. */
796 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
798 s
->is_jmp
= DISAS_UPDATE
;
799 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
800 tcg_gen_andi_i32(var
, var
, 1);
801 store_cpu_field(var
, thumb
);
804 /* Variant of store_reg which uses branch&exchange logic when storing
805 to r15 in ARM architecture v7 and above. The source must be a temporary
806 and will be marked as dead. */
807 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
808 int reg
, TCGv_i32 var
)
810 if (reg
== 15 && ENABLE_ARCH_7
) {
813 store_reg(s
, reg
, var
);
817 /* Variant of store_reg which uses branch&exchange logic when storing
818 * to r15 in ARM architecture v5T and above. This is used for storing
819 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
820 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
821 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
822 int reg
, TCGv_i32 var
)
824 if (reg
== 15 && ENABLE_ARCH_5
) {
827 store_reg(s
, reg
, var
);
831 /* Abstractions of "generate code to do a guest load/store for
832 * AArch32", where a vaddr is always 32 bits (and is zero
833 * extended if we're a 64 bit core) and data is also
834 * 32 bits unless specifically doing a 64 bit access.
835 * These functions work like tcg_gen_qemu_{ld,st}* except
836 * that the address argument is TCGv_i32 rather than TCGv.
838 #if TARGET_LONG_BITS == 32
840 #define DO_GEN_LD(SUFF, OPC) \
841 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
843 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
846 #define DO_GEN_ST(SUFF, OPC) \
847 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
849 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
852 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
854 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
857 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
859 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
864 #define DO_GEN_LD(SUFF, OPC) \
865 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
867 TCGv addr64 = tcg_temp_new(); \
868 tcg_gen_extu_i32_i64(addr64, addr); \
869 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
870 tcg_temp_free(addr64); \
873 #define DO_GEN_ST(SUFF, OPC) \
874 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
876 TCGv addr64 = tcg_temp_new(); \
877 tcg_gen_extu_i32_i64(addr64, addr); \
878 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
879 tcg_temp_free(addr64); \
882 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
884 TCGv addr64
= tcg_temp_new();
885 tcg_gen_extu_i32_i64(addr64
, addr
);
886 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
887 tcg_temp_free(addr64
);
890 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
892 TCGv addr64
= tcg_temp_new();
893 tcg_gen_extu_i32_i64(addr64
, addr
);
894 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
895 tcg_temp_free(addr64
);
902 DO_GEN_LD(16s
, MO_TESW
)
903 DO_GEN_LD(16u, MO_TEUW
)
904 DO_GEN_LD(32u, MO_TEUL
)
906 DO_GEN_ST(16, MO_TEUW
)
907 DO_GEN_ST(32, MO_TEUL
)
909 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
911 tcg_gen_movi_i32(cpu_R
[15], val
);
915 gen_set_condexec (DisasContext
*s
)
917 if (s
->condexec_mask
) {
918 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
919 TCGv_i32 tmp
= tcg_temp_new_i32();
920 tcg_gen_movi_i32(tmp
, val
);
921 store_cpu_field(tmp
, condexec_bits
);
925 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
928 gen_set_pc_im(s
, s
->pc
- offset
);
929 gen_exception_internal(excp
);
930 s
->is_jmp
= DISAS_JUMP
;
933 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
936 gen_set_pc_im(s
, s
->pc
- offset
);
937 gen_exception(excp
, syn
);
938 s
->is_jmp
= DISAS_JUMP
;
941 /* Force a TB lookup after an instruction that changes the CPU state. */
942 static inline void gen_lookup_tb(DisasContext
*s
)
944 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
945 s
->is_jmp
= DISAS_UPDATE
;
948 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
951 int val
, rm
, shift
, shiftop
;
954 if (!(insn
& (1 << 25))) {
957 if (!(insn
& (1 << 23)))
960 tcg_gen_addi_i32(var
, var
, val
);
964 shift
= (insn
>> 7) & 0x1f;
965 shiftop
= (insn
>> 5) & 3;
966 offset
= load_reg(s
, rm
);
967 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
968 if (!(insn
& (1 << 23)))
969 tcg_gen_sub_i32(var
, var
, offset
);
971 tcg_gen_add_i32(var
, var
, offset
);
972 tcg_temp_free_i32(offset
);
976 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
977 int extra
, TCGv_i32 var
)
982 if (insn
& (1 << 22)) {
984 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
985 if (!(insn
& (1 << 23)))
989 tcg_gen_addi_i32(var
, var
, val
);
993 tcg_gen_addi_i32(var
, var
, extra
);
995 offset
= load_reg(s
, rm
);
996 if (!(insn
& (1 << 23)))
997 tcg_gen_sub_i32(var
, var
, offset
);
999 tcg_gen_add_i32(var
, var
, offset
);
1000 tcg_temp_free_i32(offset
);
1004 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1006 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1009 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1011 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1013 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1017 #define VFP_OP2(name) \
1018 static inline void gen_vfp_##name(int dp) \
1020 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1022 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1024 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1026 tcg_temp_free_ptr(fpst); \
1036 static inline void gen_vfp_F1_mul(int dp
)
1038 /* Like gen_vfp_mul() but put result in F1 */
1039 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1041 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1043 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1045 tcg_temp_free_ptr(fpst
);
1048 static inline void gen_vfp_F1_neg(int dp
)
1050 /* Like gen_vfp_neg() but put result in F1 */
1052 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1054 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1058 static inline void gen_vfp_abs(int dp
)
1061 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1063 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1066 static inline void gen_vfp_neg(int dp
)
1069 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1071 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1074 static inline void gen_vfp_sqrt(int dp
)
1077 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1079 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1082 static inline void gen_vfp_cmp(int dp
)
1085 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1087 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1090 static inline void gen_vfp_cmpe(int dp
)
1093 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1095 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1098 static inline void gen_vfp_F1_ld0(int dp
)
1101 tcg_gen_movi_i64(cpu_F1d
, 0);
1103 tcg_gen_movi_i32(cpu_F1s
, 0);
1106 #define VFP_GEN_ITOF(name) \
1107 static inline void gen_vfp_##name(int dp, int neon) \
1109 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1111 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1115 tcg_temp_free_ptr(statusptr); \
1122 #define VFP_GEN_FTOI(name) \
1123 static inline void gen_vfp_##name(int dp, int neon) \
1125 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1127 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1129 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1131 tcg_temp_free_ptr(statusptr); \
1140 #define VFP_GEN_FIX(name, round) \
1141 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1143 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1144 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1146 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1149 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1152 tcg_temp_free_i32(tmp_shift); \
1153 tcg_temp_free_ptr(statusptr); \
1155 VFP_GEN_FIX(tosh
, _round_to_zero
)
1156 VFP_GEN_FIX(tosl
, _round_to_zero
)
1157 VFP_GEN_FIX(touh
, _round_to_zero
)
1158 VFP_GEN_FIX(toul
, _round_to_zero
)
1165 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1168 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1170 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1174 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1177 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1179 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1184 vfp_reg_offset (int dp
, int reg
)
1187 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1189 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1190 + offsetof(CPU_DoubleU
, l
.upper
);
1192 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1193 + offsetof(CPU_DoubleU
, l
.lower
);
1197 /* Return the offset of a 32-bit piece of a NEON register.
1198 zero is the least significant end of the register. */
1200 neon_reg_offset (int reg
, int n
)
1204 return vfp_reg_offset(0, sreg
);
1207 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1209 TCGv_i32 tmp
= tcg_temp_new_i32();
1210 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1214 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1216 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1217 tcg_temp_free_i32(var
);
1220 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1222 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1225 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1227 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1230 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1231 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1232 #define tcg_gen_st_f32 tcg_gen_st_i32
1233 #define tcg_gen_st_f64 tcg_gen_st_i64
1235 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1238 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1240 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1243 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1246 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1248 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1251 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1254 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1256 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1259 #define ARM_CP_RW_BIT (1 << 20)
1261 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1263 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1266 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1268 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1271 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1273 TCGv_i32 var
= tcg_temp_new_i32();
1274 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1278 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1280 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1281 tcg_temp_free_i32(var
);
1284 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1286 iwmmxt_store_reg(cpu_M0
, rn
);
1289 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1291 iwmmxt_load_reg(cpu_M0
, rn
);
1294 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1296 iwmmxt_load_reg(cpu_V1
, rn
);
1297 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1300 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1302 iwmmxt_load_reg(cpu_V1
, rn
);
1303 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1306 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1308 iwmmxt_load_reg(cpu_V1
, rn
);
1309 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1312 #define IWMMXT_OP(name) \
1313 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1315 iwmmxt_load_reg(cpu_V1, rn); \
1316 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1319 #define IWMMXT_OP_ENV(name) \
1320 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1322 iwmmxt_load_reg(cpu_V1, rn); \
1323 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1326 #define IWMMXT_OP_ENV_SIZE(name) \
1327 IWMMXT_OP_ENV(name##b) \
1328 IWMMXT_OP_ENV(name##w) \
1329 IWMMXT_OP_ENV(name##l)
1331 #define IWMMXT_OP_ENV1(name) \
1332 static inline void gen_op_iwmmxt_##name##_M0(void) \
1334 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1348 IWMMXT_OP_ENV_SIZE(unpackl
)
1349 IWMMXT_OP_ENV_SIZE(unpackh
)
1351 IWMMXT_OP_ENV1(unpacklub
)
1352 IWMMXT_OP_ENV1(unpackluw
)
1353 IWMMXT_OP_ENV1(unpacklul
)
1354 IWMMXT_OP_ENV1(unpackhub
)
1355 IWMMXT_OP_ENV1(unpackhuw
)
1356 IWMMXT_OP_ENV1(unpackhul
)
1357 IWMMXT_OP_ENV1(unpacklsb
)
1358 IWMMXT_OP_ENV1(unpacklsw
)
1359 IWMMXT_OP_ENV1(unpacklsl
)
1360 IWMMXT_OP_ENV1(unpackhsb
)
1361 IWMMXT_OP_ENV1(unpackhsw
)
1362 IWMMXT_OP_ENV1(unpackhsl
)
1364 IWMMXT_OP_ENV_SIZE(cmpeq
)
1365 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1366 IWMMXT_OP_ENV_SIZE(cmpgts
)
1368 IWMMXT_OP_ENV_SIZE(mins
)
1369 IWMMXT_OP_ENV_SIZE(minu
)
1370 IWMMXT_OP_ENV_SIZE(maxs
)
1371 IWMMXT_OP_ENV_SIZE(maxu
)
1373 IWMMXT_OP_ENV_SIZE(subn
)
1374 IWMMXT_OP_ENV_SIZE(addn
)
1375 IWMMXT_OP_ENV_SIZE(subu
)
1376 IWMMXT_OP_ENV_SIZE(addu
)
1377 IWMMXT_OP_ENV_SIZE(subs
)
1378 IWMMXT_OP_ENV_SIZE(adds
)
1380 IWMMXT_OP_ENV(avgb0
)
1381 IWMMXT_OP_ENV(avgb1
)
1382 IWMMXT_OP_ENV(avgw0
)
1383 IWMMXT_OP_ENV(avgw1
)
1385 IWMMXT_OP_ENV(packuw
)
1386 IWMMXT_OP_ENV(packul
)
1387 IWMMXT_OP_ENV(packuq
)
1388 IWMMXT_OP_ENV(packsw
)
1389 IWMMXT_OP_ENV(packsl
)
1390 IWMMXT_OP_ENV(packsq
)
1392 static void gen_op_iwmmxt_set_mup(void)
1395 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1396 tcg_gen_ori_i32(tmp
, tmp
, 2);
1397 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1400 static void gen_op_iwmmxt_set_cup(void)
1403 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1404 tcg_gen_ori_i32(tmp
, tmp
, 1);
1405 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1408 static void gen_op_iwmmxt_setpsr_nz(void)
1410 TCGv_i32 tmp
= tcg_temp_new_i32();
1411 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1412 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1415 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1417 iwmmxt_load_reg(cpu_V1
, rn
);
1418 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1419 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1422 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1429 rd
= (insn
>> 16) & 0xf;
1430 tmp
= load_reg(s
, rd
);
1432 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1433 if (insn
& (1 << 24)) {
1435 if (insn
& (1 << 23))
1436 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1438 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1439 tcg_gen_mov_i32(dest
, tmp
);
1440 if (insn
& (1 << 21))
1441 store_reg(s
, rd
, tmp
);
1443 tcg_temp_free_i32(tmp
);
1444 } else if (insn
& (1 << 21)) {
1446 tcg_gen_mov_i32(dest
, tmp
);
1447 if (insn
& (1 << 23))
1448 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1450 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1451 store_reg(s
, rd
, tmp
);
1452 } else if (!(insn
& (1 << 23)))
1457 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1459 int rd
= (insn
>> 0) & 0xf;
1462 if (insn
& (1 << 8)) {
1463 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1466 tmp
= iwmmxt_load_creg(rd
);
1469 tmp
= tcg_temp_new_i32();
1470 iwmmxt_load_reg(cpu_V0
, rd
);
1471 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1473 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1474 tcg_gen_mov_i32(dest
, tmp
);
1475 tcg_temp_free_i32(tmp
);
1479 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1480 (ie. an undefined instruction). */
1481 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1484 int rdhi
, rdlo
, rd0
, rd1
, i
;
1486 TCGv_i32 tmp
, tmp2
, tmp3
;
1488 if ((insn
& 0x0e000e00) == 0x0c000000) {
1489 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1491 rdlo
= (insn
>> 12) & 0xf;
1492 rdhi
= (insn
>> 16) & 0xf;
1493 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1494 iwmmxt_load_reg(cpu_V0
, wrd
);
1495 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1496 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1497 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1498 } else { /* TMCRR */
1499 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1500 iwmmxt_store_reg(cpu_V0
, wrd
);
1501 gen_op_iwmmxt_set_mup();
1506 wrd
= (insn
>> 12) & 0xf;
1507 addr
= tcg_temp_new_i32();
1508 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1509 tcg_temp_free_i32(addr
);
1512 if (insn
& ARM_CP_RW_BIT
) {
1513 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1514 tmp
= tcg_temp_new_i32();
1515 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1516 iwmmxt_store_creg(wrd
, tmp
);
1519 if (insn
& (1 << 8)) {
1520 if (insn
& (1 << 22)) { /* WLDRD */
1521 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1523 } else { /* WLDRW wRd */
1524 tmp
= tcg_temp_new_i32();
1525 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1528 tmp
= tcg_temp_new_i32();
1529 if (insn
& (1 << 22)) { /* WLDRH */
1530 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1531 } else { /* WLDRB */
1532 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1536 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1537 tcg_temp_free_i32(tmp
);
1539 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1542 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1543 tmp
= iwmmxt_load_creg(wrd
);
1544 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1546 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1547 tmp
= tcg_temp_new_i32();
1548 if (insn
& (1 << 8)) {
1549 if (insn
& (1 << 22)) { /* WSTRD */
1550 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1551 } else { /* WSTRW wRd */
1552 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1553 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1556 if (insn
& (1 << 22)) { /* WSTRH */
1557 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1558 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1559 } else { /* WSTRB */
1560 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1561 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1565 tcg_temp_free_i32(tmp
);
1567 tcg_temp_free_i32(addr
);
1571 if ((insn
& 0x0f000000) != 0x0e000000)
1574 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1575 case 0x000: /* WOR */
1576 wrd
= (insn
>> 12) & 0xf;
1577 rd0
= (insn
>> 0) & 0xf;
1578 rd1
= (insn
>> 16) & 0xf;
1579 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1580 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1581 gen_op_iwmmxt_setpsr_nz();
1582 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1583 gen_op_iwmmxt_set_mup();
1584 gen_op_iwmmxt_set_cup();
1586 case 0x011: /* TMCR */
1589 rd
= (insn
>> 12) & 0xf;
1590 wrd
= (insn
>> 16) & 0xf;
1592 case ARM_IWMMXT_wCID
:
1593 case ARM_IWMMXT_wCASF
:
1595 case ARM_IWMMXT_wCon
:
1596 gen_op_iwmmxt_set_cup();
1598 case ARM_IWMMXT_wCSSF
:
1599 tmp
= iwmmxt_load_creg(wrd
);
1600 tmp2
= load_reg(s
, rd
);
1601 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1602 tcg_temp_free_i32(tmp2
);
1603 iwmmxt_store_creg(wrd
, tmp
);
1605 case ARM_IWMMXT_wCGR0
:
1606 case ARM_IWMMXT_wCGR1
:
1607 case ARM_IWMMXT_wCGR2
:
1608 case ARM_IWMMXT_wCGR3
:
1609 gen_op_iwmmxt_set_cup();
1610 tmp
= load_reg(s
, rd
);
1611 iwmmxt_store_creg(wrd
, tmp
);
1617 case 0x100: /* WXOR */
1618 wrd
= (insn
>> 12) & 0xf;
1619 rd0
= (insn
>> 0) & 0xf;
1620 rd1
= (insn
>> 16) & 0xf;
1621 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1622 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1623 gen_op_iwmmxt_setpsr_nz();
1624 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1625 gen_op_iwmmxt_set_mup();
1626 gen_op_iwmmxt_set_cup();
1628 case 0x111: /* TMRC */
1631 rd
= (insn
>> 12) & 0xf;
1632 wrd
= (insn
>> 16) & 0xf;
1633 tmp
= iwmmxt_load_creg(wrd
);
1634 store_reg(s
, rd
, tmp
);
1636 case 0x300: /* WANDN */
1637 wrd
= (insn
>> 12) & 0xf;
1638 rd0
= (insn
>> 0) & 0xf;
1639 rd1
= (insn
>> 16) & 0xf;
1640 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1641 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1642 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1643 gen_op_iwmmxt_setpsr_nz();
1644 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1645 gen_op_iwmmxt_set_mup();
1646 gen_op_iwmmxt_set_cup();
1648 case 0x200: /* WAND */
1649 wrd
= (insn
>> 12) & 0xf;
1650 rd0
= (insn
>> 0) & 0xf;
1651 rd1
= (insn
>> 16) & 0xf;
1652 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1653 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1654 gen_op_iwmmxt_setpsr_nz();
1655 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1656 gen_op_iwmmxt_set_mup();
1657 gen_op_iwmmxt_set_cup();
1659 case 0x810: case 0xa10: /* WMADD */
1660 wrd
= (insn
>> 12) & 0xf;
1661 rd0
= (insn
>> 0) & 0xf;
1662 rd1
= (insn
>> 16) & 0xf;
1663 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1664 if (insn
& (1 << 21))
1665 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1667 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1668 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1669 gen_op_iwmmxt_set_mup();
1671 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1672 wrd
= (insn
>> 12) & 0xf;
1673 rd0
= (insn
>> 16) & 0xf;
1674 rd1
= (insn
>> 0) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1676 switch ((insn
>> 22) & 3) {
1678 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1681 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1684 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1691 gen_op_iwmmxt_set_cup();
1693 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1694 wrd
= (insn
>> 12) & 0xf;
1695 rd0
= (insn
>> 16) & 0xf;
1696 rd1
= (insn
>> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1698 switch ((insn
>> 22) & 3) {
1700 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1703 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1706 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1711 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1712 gen_op_iwmmxt_set_mup();
1713 gen_op_iwmmxt_set_cup();
1715 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1716 wrd
= (insn
>> 12) & 0xf;
1717 rd0
= (insn
>> 16) & 0xf;
1718 rd1
= (insn
>> 0) & 0xf;
1719 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1720 if (insn
& (1 << 22))
1721 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1723 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1724 if (!(insn
& (1 << 20)))
1725 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1726 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1727 gen_op_iwmmxt_set_mup();
1729 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1730 wrd
= (insn
>> 12) & 0xf;
1731 rd0
= (insn
>> 16) & 0xf;
1732 rd1
= (insn
>> 0) & 0xf;
1733 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1734 if (insn
& (1 << 21)) {
1735 if (insn
& (1 << 20))
1736 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1738 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1740 if (insn
& (1 << 20))
1741 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1743 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1745 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1746 gen_op_iwmmxt_set_mup();
1748 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1749 wrd
= (insn
>> 12) & 0xf;
1750 rd0
= (insn
>> 16) & 0xf;
1751 rd1
= (insn
>> 0) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1753 if (insn
& (1 << 21))
1754 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1756 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1757 if (!(insn
& (1 << 20))) {
1758 iwmmxt_load_reg(cpu_V1
, wrd
);
1759 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1761 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1762 gen_op_iwmmxt_set_mup();
1764 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1765 wrd
= (insn
>> 12) & 0xf;
1766 rd0
= (insn
>> 16) & 0xf;
1767 rd1
= (insn
>> 0) & 0xf;
1768 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1769 switch ((insn
>> 22) & 3) {
1771 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1774 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1777 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1782 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1783 gen_op_iwmmxt_set_mup();
1784 gen_op_iwmmxt_set_cup();
1786 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1787 wrd
= (insn
>> 12) & 0xf;
1788 rd0
= (insn
>> 16) & 0xf;
1789 rd1
= (insn
>> 0) & 0xf;
1790 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1791 if (insn
& (1 << 22)) {
1792 if (insn
& (1 << 20))
1793 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1795 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1797 if (insn
& (1 << 20))
1798 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1800 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1802 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1803 gen_op_iwmmxt_set_mup();
1804 gen_op_iwmmxt_set_cup();
1806 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1807 wrd
= (insn
>> 12) & 0xf;
1808 rd0
= (insn
>> 16) & 0xf;
1809 rd1
= (insn
>> 0) & 0xf;
1810 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1811 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1812 tcg_gen_andi_i32(tmp
, tmp
, 7);
1813 iwmmxt_load_reg(cpu_V1
, rd1
);
1814 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1815 tcg_temp_free_i32(tmp
);
1816 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1817 gen_op_iwmmxt_set_mup();
1819 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1820 if (((insn
>> 6) & 3) == 3)
1822 rd
= (insn
>> 12) & 0xf;
1823 wrd
= (insn
>> 16) & 0xf;
1824 tmp
= load_reg(s
, rd
);
1825 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1826 switch ((insn
>> 6) & 3) {
1828 tmp2
= tcg_const_i32(0xff);
1829 tmp3
= tcg_const_i32((insn
& 7) << 3);
1832 tmp2
= tcg_const_i32(0xffff);
1833 tmp3
= tcg_const_i32((insn
& 3) << 4);
1836 tmp2
= tcg_const_i32(0xffffffff);
1837 tmp3
= tcg_const_i32((insn
& 1) << 5);
1840 TCGV_UNUSED_I32(tmp2
);
1841 TCGV_UNUSED_I32(tmp3
);
1843 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1844 tcg_temp_free_i32(tmp3
);
1845 tcg_temp_free_i32(tmp2
);
1846 tcg_temp_free_i32(tmp
);
1847 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1848 gen_op_iwmmxt_set_mup();
1850 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1851 rd
= (insn
>> 12) & 0xf;
1852 wrd
= (insn
>> 16) & 0xf;
1853 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1855 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1856 tmp
= tcg_temp_new_i32();
1857 switch ((insn
>> 22) & 3) {
1859 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1860 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1862 tcg_gen_ext8s_i32(tmp
, tmp
);
1864 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1868 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1869 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1871 tcg_gen_ext16s_i32(tmp
, tmp
);
1873 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1877 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1878 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1881 store_reg(s
, rd
, tmp
);
1883 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1884 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1886 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1887 switch ((insn
>> 22) & 3) {
1889 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1892 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1895 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1898 tcg_gen_shli_i32(tmp
, tmp
, 28);
1900 tcg_temp_free_i32(tmp
);
1902 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1903 if (((insn
>> 6) & 3) == 3)
1905 rd
= (insn
>> 12) & 0xf;
1906 wrd
= (insn
>> 16) & 0xf;
1907 tmp
= load_reg(s
, rd
);
1908 switch ((insn
>> 6) & 3) {
1910 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1913 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1916 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1919 tcg_temp_free_i32(tmp
);
1920 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1921 gen_op_iwmmxt_set_mup();
1923 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1924 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1926 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1927 tmp2
= tcg_temp_new_i32();
1928 tcg_gen_mov_i32(tmp2
, tmp
);
1929 switch ((insn
>> 22) & 3) {
1931 for (i
= 0; i
< 7; i
++) {
1932 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1933 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1937 for (i
= 0; i
< 3; i
++) {
1938 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1939 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1943 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1944 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1948 tcg_temp_free_i32(tmp2
);
1949 tcg_temp_free_i32(tmp
);
1951 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1952 wrd
= (insn
>> 12) & 0xf;
1953 rd0
= (insn
>> 16) & 0xf;
1954 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1955 switch ((insn
>> 22) & 3) {
1957 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1960 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1963 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1969 gen_op_iwmmxt_set_mup();
1971 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1972 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1974 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1975 tmp2
= tcg_temp_new_i32();
1976 tcg_gen_mov_i32(tmp2
, tmp
);
1977 switch ((insn
>> 22) & 3) {
1979 for (i
= 0; i
< 7; i
++) {
1980 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1981 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1985 for (i
= 0; i
< 3; i
++) {
1986 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1987 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1991 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1992 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1996 tcg_temp_free_i32(tmp2
);
1997 tcg_temp_free_i32(tmp
);
1999 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2000 rd
= (insn
>> 12) & 0xf;
2001 rd0
= (insn
>> 16) & 0xf;
2002 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2004 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2005 tmp
= tcg_temp_new_i32();
2006 switch ((insn
>> 22) & 3) {
2008 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2011 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2014 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2017 store_reg(s
, rd
, tmp
);
2019 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2020 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2021 wrd
= (insn
>> 12) & 0xf;
2022 rd0
= (insn
>> 16) & 0xf;
2023 rd1
= (insn
>> 0) & 0xf;
2024 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2025 switch ((insn
>> 22) & 3) {
2027 if (insn
& (1 << 21))
2028 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2030 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2033 if (insn
& (1 << 21))
2034 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2036 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2039 if (insn
& (1 << 21))
2040 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2042 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2047 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2052 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2053 wrd
= (insn
>> 12) & 0xf;
2054 rd0
= (insn
>> 16) & 0xf;
2055 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2056 switch ((insn
>> 22) & 3) {
2058 if (insn
& (1 << 21))
2059 gen_op_iwmmxt_unpacklsb_M0();
2061 gen_op_iwmmxt_unpacklub_M0();
2064 if (insn
& (1 << 21))
2065 gen_op_iwmmxt_unpacklsw_M0();
2067 gen_op_iwmmxt_unpackluw_M0();
2070 if (insn
& (1 << 21))
2071 gen_op_iwmmxt_unpacklsl_M0();
2073 gen_op_iwmmxt_unpacklul_M0();
2078 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2082 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2083 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2084 wrd
= (insn
>> 12) & 0xf;
2085 rd0
= (insn
>> 16) & 0xf;
2086 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2087 switch ((insn
>> 22) & 3) {
2089 if (insn
& (1 << 21))
2090 gen_op_iwmmxt_unpackhsb_M0();
2092 gen_op_iwmmxt_unpackhub_M0();
2095 if (insn
& (1 << 21))
2096 gen_op_iwmmxt_unpackhsw_M0();
2098 gen_op_iwmmxt_unpackhuw_M0();
2101 if (insn
& (1 << 21))
2102 gen_op_iwmmxt_unpackhsl_M0();
2104 gen_op_iwmmxt_unpackhul_M0();
2109 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2110 gen_op_iwmmxt_set_mup();
2111 gen_op_iwmmxt_set_cup();
2113 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2114 case 0x214: case 0x614: case 0xa14: case 0xe14:
2115 if (((insn
>> 22) & 3) == 0)
2117 wrd
= (insn
>> 12) & 0xf;
2118 rd0
= (insn
>> 16) & 0xf;
2119 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2120 tmp
= tcg_temp_new_i32();
2121 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2122 tcg_temp_free_i32(tmp
);
2125 switch ((insn
>> 22) & 3) {
2127 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2130 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2133 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 tcg_temp_free_i32(tmp
);
2137 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2138 gen_op_iwmmxt_set_mup();
2139 gen_op_iwmmxt_set_cup();
2141 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2142 case 0x014: case 0x414: case 0x814: case 0xc14:
2143 if (((insn
>> 22) & 3) == 0)
2145 wrd
= (insn
>> 12) & 0xf;
2146 rd0
= (insn
>> 16) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 tmp
= tcg_temp_new_i32();
2149 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2150 tcg_temp_free_i32(tmp
);
2153 switch ((insn
>> 22) & 3) {
2155 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2158 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2161 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 tcg_temp_free_i32(tmp
);
2165 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2166 gen_op_iwmmxt_set_mup();
2167 gen_op_iwmmxt_set_cup();
2169 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2170 case 0x114: case 0x514: case 0x914: case 0xd14:
2171 if (((insn
>> 22) & 3) == 0)
2173 wrd
= (insn
>> 12) & 0xf;
2174 rd0
= (insn
>> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2176 tmp
= tcg_temp_new_i32();
2177 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2178 tcg_temp_free_i32(tmp
);
2181 switch ((insn
>> 22) & 3) {
2183 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2186 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2189 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2192 tcg_temp_free_i32(tmp
);
2193 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2194 gen_op_iwmmxt_set_mup();
2195 gen_op_iwmmxt_set_cup();
2197 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2198 case 0x314: case 0x714: case 0xb14: case 0xf14:
2199 if (((insn
>> 22) & 3) == 0)
2201 wrd
= (insn
>> 12) & 0xf;
2202 rd0
= (insn
>> 16) & 0xf;
2203 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2204 tmp
= tcg_temp_new_i32();
2205 switch ((insn
>> 22) & 3) {
2207 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2208 tcg_temp_free_i32(tmp
);
2211 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2214 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2215 tcg_temp_free_i32(tmp
);
2218 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2221 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2222 tcg_temp_free_i32(tmp
);
2225 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2228 tcg_temp_free_i32(tmp
);
2229 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2233 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2234 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2235 wrd
= (insn
>> 12) & 0xf;
2236 rd0
= (insn
>> 16) & 0xf;
2237 rd1
= (insn
>> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 switch ((insn
>> 22) & 3) {
2241 if (insn
& (1 << 21))
2242 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2244 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2247 if (insn
& (1 << 21))
2248 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2250 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2253 if (insn
& (1 << 21))
2254 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2256 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2261 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2262 gen_op_iwmmxt_set_mup();
2264 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2265 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2266 wrd
= (insn
>> 12) & 0xf;
2267 rd0
= (insn
>> 16) & 0xf;
2268 rd1
= (insn
>> 0) & 0xf;
2269 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2270 switch ((insn
>> 22) & 3) {
2272 if (insn
& (1 << 21))
2273 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2275 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2278 if (insn
& (1 << 21))
2279 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2281 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2284 if (insn
& (1 << 21))
2285 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2287 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2292 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2293 gen_op_iwmmxt_set_mup();
2295 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2296 case 0x402: case 0x502: case 0x602: case 0x702:
2297 wrd
= (insn
>> 12) & 0xf;
2298 rd0
= (insn
>> 16) & 0xf;
2299 rd1
= (insn
>> 0) & 0xf;
2300 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2301 tmp
= tcg_const_i32((insn
>> 20) & 3);
2302 iwmmxt_load_reg(cpu_V1
, rd1
);
2303 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2304 tcg_temp_free_i32(tmp
);
2305 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2306 gen_op_iwmmxt_set_mup();
2308 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2309 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2310 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2311 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2312 wrd
= (insn
>> 12) & 0xf;
2313 rd0
= (insn
>> 16) & 0xf;
2314 rd1
= (insn
>> 0) & 0xf;
2315 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2316 switch ((insn
>> 20) & 0xf) {
2318 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2321 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2324 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2327 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2330 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2333 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2336 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2339 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2342 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2347 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2348 gen_op_iwmmxt_set_mup();
2349 gen_op_iwmmxt_set_cup();
2351 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2352 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2353 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2354 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2355 wrd
= (insn
>> 12) & 0xf;
2356 rd0
= (insn
>> 16) & 0xf;
2357 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2358 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2359 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2360 tcg_temp_free_i32(tmp
);
2361 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2365 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2366 case 0x418: case 0x518: case 0x618: case 0x718:
2367 case 0x818: case 0x918: case 0xa18: case 0xb18:
2368 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2369 wrd
= (insn
>> 12) & 0xf;
2370 rd0
= (insn
>> 16) & 0xf;
2371 rd1
= (insn
>> 0) & 0xf;
2372 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2373 switch ((insn
>> 20) & 0xf) {
2375 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2378 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2381 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2384 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2387 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2390 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2393 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2396 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2399 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2404 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2408 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2409 case 0x408: case 0x508: case 0x608: case 0x708:
2410 case 0x808: case 0x908: case 0xa08: case 0xb08:
2411 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2412 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2414 wrd
= (insn
>> 12) & 0xf;
2415 rd0
= (insn
>> 16) & 0xf;
2416 rd1
= (insn
>> 0) & 0xf;
2417 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2418 switch ((insn
>> 22) & 3) {
2420 if (insn
& (1 << 21))
2421 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2423 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2426 if (insn
& (1 << 21))
2427 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2429 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2432 if (insn
& (1 << 21))
2433 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2435 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2438 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2439 gen_op_iwmmxt_set_mup();
2440 gen_op_iwmmxt_set_cup();
2442 case 0x201: case 0x203: case 0x205: case 0x207:
2443 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2444 case 0x211: case 0x213: case 0x215: case 0x217:
2445 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2446 wrd
= (insn
>> 5) & 0xf;
2447 rd0
= (insn
>> 12) & 0xf;
2448 rd1
= (insn
>> 0) & 0xf;
2449 if (rd0
== 0xf || rd1
== 0xf)
2451 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2452 tmp
= load_reg(s
, rd0
);
2453 tmp2
= load_reg(s
, rd1
);
2454 switch ((insn
>> 16) & 0xf) {
2455 case 0x0: /* TMIA */
2456 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2458 case 0x8: /* TMIAPH */
2459 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2461 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2462 if (insn
& (1 << 16))
2463 tcg_gen_shri_i32(tmp
, tmp
, 16);
2464 if (insn
& (1 << 17))
2465 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2466 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2469 tcg_temp_free_i32(tmp2
);
2470 tcg_temp_free_i32(tmp
);
2473 tcg_temp_free_i32(tmp2
);
2474 tcg_temp_free_i32(tmp
);
2475 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2476 gen_op_iwmmxt_set_mup();
2485 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2486 (ie. an undefined instruction). */
2487 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2489 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2492 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2493 /* Multiply with Internal Accumulate Format */
2494 rd0
= (insn
>> 12) & 0xf;
2496 acc
= (insn
>> 5) & 7;
2501 tmp
= load_reg(s
, rd0
);
2502 tmp2
= load_reg(s
, rd1
);
2503 switch ((insn
>> 16) & 0xf) {
2505 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2507 case 0x8: /* MIAPH */
2508 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2510 case 0xc: /* MIABB */
2511 case 0xd: /* MIABT */
2512 case 0xe: /* MIATB */
2513 case 0xf: /* MIATT */
2514 if (insn
& (1 << 16))
2515 tcg_gen_shri_i32(tmp
, tmp
, 16);
2516 if (insn
& (1 << 17))
2517 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2518 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2523 tcg_temp_free_i32(tmp2
);
2524 tcg_temp_free_i32(tmp
);
2526 gen_op_iwmmxt_movq_wRn_M0(acc
);
2530 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2531 /* Internal Accumulator Access Format */
2532 rdhi
= (insn
>> 16) & 0xf;
2533 rdlo
= (insn
>> 12) & 0xf;
2539 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2540 iwmmxt_load_reg(cpu_V0
, acc
);
2541 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2542 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2543 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2544 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2546 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2547 iwmmxt_store_reg(cpu_V0
, acc
);
2555 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2556 #define VFP_SREG(insn, bigbit, smallbit) \
2557 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2558 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2559 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2560 reg = (((insn) >> (bigbit)) & 0x0f) \
2561 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2563 if (insn & (1 << (smallbit))) \
2565 reg = ((insn) >> (bigbit)) & 0x0f; \
2568 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2569 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2570 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2571 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2572 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2573 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2575 /* Move between integer and VFP cores. */
2576 static TCGv_i32
gen_vfp_mrs(void)
2578 TCGv_i32 tmp
= tcg_temp_new_i32();
2579 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2583 static void gen_vfp_msr(TCGv_i32 tmp
)
2585 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2586 tcg_temp_free_i32(tmp
);
2589 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2591 TCGv_i32 tmp
= tcg_temp_new_i32();
2593 tcg_gen_shri_i32(var
, var
, shift
);
2594 tcg_gen_ext8u_i32(var
, var
);
2595 tcg_gen_shli_i32(tmp
, var
, 8);
2596 tcg_gen_or_i32(var
, var
, tmp
);
2597 tcg_gen_shli_i32(tmp
, var
, 16);
2598 tcg_gen_or_i32(var
, var
, tmp
);
2599 tcg_temp_free_i32(tmp
);
2602 static void gen_neon_dup_low16(TCGv_i32 var
)
2604 TCGv_i32 tmp
= tcg_temp_new_i32();
2605 tcg_gen_ext16u_i32(var
, var
);
2606 tcg_gen_shli_i32(tmp
, var
, 16);
2607 tcg_gen_or_i32(var
, var
, tmp
);
2608 tcg_temp_free_i32(tmp
);
2611 static void gen_neon_dup_high16(TCGv_i32 var
)
2613 TCGv_i32 tmp
= tcg_temp_new_i32();
2614 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2615 tcg_gen_shri_i32(tmp
, var
, 16);
2616 tcg_gen_or_i32(var
, var
, tmp
);
2617 tcg_temp_free_i32(tmp
);
2620 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2622 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2623 TCGv_i32 tmp
= tcg_temp_new_i32();
2626 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2627 gen_neon_dup_u8(tmp
, 0);
2630 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2631 gen_neon_dup_low16(tmp
);
2634 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2636 default: /* Avoid compiler warnings. */
2642 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2645 uint32_t cc
= extract32(insn
, 20, 2);
2648 TCGv_i64 frn
, frm
, dest
;
2649 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2651 zero
= tcg_const_i64(0);
2653 frn
= tcg_temp_new_i64();
2654 frm
= tcg_temp_new_i64();
2655 dest
= tcg_temp_new_i64();
2657 zf
= tcg_temp_new_i64();
2658 nf
= tcg_temp_new_i64();
2659 vf
= tcg_temp_new_i64();
2661 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2662 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2663 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2665 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2666 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2669 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2673 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2676 case 2: /* ge: N == V -> N ^ V == 0 */
2677 tmp
= tcg_temp_new_i64();
2678 tcg_gen_xor_i64(tmp
, vf
, nf
);
2679 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2681 tcg_temp_free_i64(tmp
);
2683 case 3: /* gt: !Z && N == V */
2684 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2686 tmp
= tcg_temp_new_i64();
2687 tcg_gen_xor_i64(tmp
, vf
, nf
);
2688 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2690 tcg_temp_free_i64(tmp
);
2693 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2694 tcg_temp_free_i64(frn
);
2695 tcg_temp_free_i64(frm
);
2696 tcg_temp_free_i64(dest
);
2698 tcg_temp_free_i64(zf
);
2699 tcg_temp_free_i64(nf
);
2700 tcg_temp_free_i64(vf
);
2702 tcg_temp_free_i64(zero
);
2704 TCGv_i32 frn
, frm
, dest
;
2707 zero
= tcg_const_i32(0);
2709 frn
= tcg_temp_new_i32();
2710 frm
= tcg_temp_new_i32();
2711 dest
= tcg_temp_new_i32();
2712 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2713 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2716 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2720 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2723 case 2: /* ge: N == V -> N ^ V == 0 */
2724 tmp
= tcg_temp_new_i32();
2725 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2726 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2728 tcg_temp_free_i32(tmp
);
2730 case 3: /* gt: !Z && N == V */
2731 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2733 tmp
= tcg_temp_new_i32();
2734 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2735 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2737 tcg_temp_free_i32(tmp
);
2740 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2741 tcg_temp_free_i32(frn
);
2742 tcg_temp_free_i32(frm
);
2743 tcg_temp_free_i32(dest
);
2745 tcg_temp_free_i32(zero
);
2751 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2752 uint32_t rm
, uint32_t dp
)
2754 uint32_t vmin
= extract32(insn
, 6, 1);
2755 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2758 TCGv_i64 frn
, frm
, dest
;
2760 frn
= tcg_temp_new_i64();
2761 frm
= tcg_temp_new_i64();
2762 dest
= tcg_temp_new_i64();
2764 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2765 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2767 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2769 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2771 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2772 tcg_temp_free_i64(frn
);
2773 tcg_temp_free_i64(frm
);
2774 tcg_temp_free_i64(dest
);
2776 TCGv_i32 frn
, frm
, dest
;
2778 frn
= tcg_temp_new_i32();
2779 frm
= tcg_temp_new_i32();
2780 dest
= tcg_temp_new_i32();
2782 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2783 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2785 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2787 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2789 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2790 tcg_temp_free_i32(frn
);
2791 tcg_temp_free_i32(frm
);
2792 tcg_temp_free_i32(dest
);
2795 tcg_temp_free_ptr(fpst
);
2799 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2802 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2805 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2806 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2811 tcg_op
= tcg_temp_new_i64();
2812 tcg_res
= tcg_temp_new_i64();
2813 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2814 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2815 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2816 tcg_temp_free_i64(tcg_op
);
2817 tcg_temp_free_i64(tcg_res
);
2821 tcg_op
= tcg_temp_new_i32();
2822 tcg_res
= tcg_temp_new_i32();
2823 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2824 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2825 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2826 tcg_temp_free_i32(tcg_op
);
2827 tcg_temp_free_i32(tcg_res
);
2830 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2831 tcg_temp_free_i32(tcg_rmode
);
2833 tcg_temp_free_ptr(fpst
);
2837 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2840 bool is_signed
= extract32(insn
, 7, 1);
2841 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2842 TCGv_i32 tcg_rmode
, tcg_shift
;
2844 tcg_shift
= tcg_const_i32(0);
2846 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2847 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2850 TCGv_i64 tcg_double
, tcg_res
;
2852 /* Rd is encoded as a single precision register even when the source
2853 * is double precision.
2855 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2856 tcg_double
= tcg_temp_new_i64();
2857 tcg_res
= tcg_temp_new_i64();
2858 tcg_tmp
= tcg_temp_new_i32();
2859 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2861 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2863 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2865 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2866 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2867 tcg_temp_free_i32(tcg_tmp
);
2868 tcg_temp_free_i64(tcg_res
);
2869 tcg_temp_free_i64(tcg_double
);
2871 TCGv_i32 tcg_single
, tcg_res
;
2872 tcg_single
= tcg_temp_new_i32();
2873 tcg_res
= tcg_temp_new_i32();
2874 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2876 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2878 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2880 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2881 tcg_temp_free_i32(tcg_res
);
2882 tcg_temp_free_i32(tcg_single
);
2885 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2886 tcg_temp_free_i32(tcg_rmode
);
2888 tcg_temp_free_i32(tcg_shift
);
2890 tcg_temp_free_ptr(fpst
);
2895 /* Table for converting the most common AArch32 encoding of
2896 * rounding mode to arm_fprounding order (which matches the
2897 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2899 static const uint8_t fp_decode_rm
[] = {
2906 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2908 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2910 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2915 VFP_DREG_D(rd
, insn
);
2916 VFP_DREG_N(rn
, insn
);
2917 VFP_DREG_M(rm
, insn
);
2919 rd
= VFP_SREG_D(insn
);
2920 rn
= VFP_SREG_N(insn
);
2921 rm
= VFP_SREG_M(insn
);
2924 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2925 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2926 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2927 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2928 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2929 /* VRINTA, VRINTN, VRINTP, VRINTM */
2930 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2931 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2932 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2933 /* VCVTA, VCVTN, VCVTP, VCVTM */
2934 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2935 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
2940 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2941 (ie. an undefined instruction). */
2942 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2944 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2950 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2953 /* FIXME: this access check should not take precedence over UNDEF
2954 * for invalid encodings; we will generate incorrect syndrome information
2955 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2957 if (!s
->cpacr_fpen
) {
2958 gen_exception_insn(s
, 4, EXCP_UDEF
,
2959 syn_fp_access_trap(1, 0xe, s
->thumb
));
2963 if (!s
->vfp_enabled
) {
2964 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2965 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2967 rn
= (insn
>> 16) & 0xf;
2968 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
2969 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
2974 if (extract32(insn
, 28, 4) == 0xf) {
2975 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2976 * only used in v8 and above.
2978 return disas_vfp_v8_insn(env
, s
, insn
);
2981 dp
= ((insn
& 0xf00) == 0xb00);
2982 switch ((insn
>> 24) & 0xf) {
2984 if (insn
& (1 << 4)) {
2985 /* single register transfer */
2986 rd
= (insn
>> 12) & 0xf;
2991 VFP_DREG_N(rn
, insn
);
2994 if (insn
& 0x00c00060
2995 && !arm_feature(env
, ARM_FEATURE_NEON
))
2998 pass
= (insn
>> 21) & 1;
2999 if (insn
& (1 << 22)) {
3001 offset
= ((insn
>> 5) & 3) * 8;
3002 } else if (insn
& (1 << 5)) {
3004 offset
= (insn
& (1 << 6)) ? 16 : 0;
3009 if (insn
& ARM_CP_RW_BIT
) {
3011 tmp
= neon_load_reg(rn
, pass
);
3015 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3016 if (insn
& (1 << 23))
3022 if (insn
& (1 << 23)) {
3024 tcg_gen_shri_i32(tmp
, tmp
, 16);
3030 tcg_gen_sari_i32(tmp
, tmp
, 16);
3039 store_reg(s
, rd
, tmp
);
3042 tmp
= load_reg(s
, rd
);
3043 if (insn
& (1 << 23)) {
3046 gen_neon_dup_u8(tmp
, 0);
3047 } else if (size
== 1) {
3048 gen_neon_dup_low16(tmp
);
3050 for (n
= 0; n
<= pass
* 2; n
++) {
3051 tmp2
= tcg_temp_new_i32();
3052 tcg_gen_mov_i32(tmp2
, tmp
);
3053 neon_store_reg(rn
, n
, tmp2
);
3055 neon_store_reg(rn
, n
, tmp
);
3060 tmp2
= neon_load_reg(rn
, pass
);
3061 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3062 tcg_temp_free_i32(tmp2
);
3065 tmp2
= neon_load_reg(rn
, pass
);
3066 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3067 tcg_temp_free_i32(tmp2
);
3072 neon_store_reg(rn
, pass
, tmp
);
3076 if ((insn
& 0x6f) != 0x00)
3078 rn
= VFP_SREG_N(insn
);
3079 if (insn
& ARM_CP_RW_BIT
) {
3081 if (insn
& (1 << 21)) {
3082 /* system register */
3087 /* VFP2 allows access to FSID from userspace.
3088 VFP3 restricts all id registers to privileged
3091 && arm_feature(env
, ARM_FEATURE_VFP3
))
3093 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3098 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3100 case ARM_VFP_FPINST
:
3101 case ARM_VFP_FPINST2
:
3102 /* Not present in VFP3. */
3104 || arm_feature(env
, ARM_FEATURE_VFP3
))
3106 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3110 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3111 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3113 tmp
= tcg_temp_new_i32();
3114 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3118 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3125 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3127 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3133 gen_mov_F0_vreg(0, rn
);
3134 tmp
= gen_vfp_mrs();
3137 /* Set the 4 flag bits in the CPSR. */
3139 tcg_temp_free_i32(tmp
);
3141 store_reg(s
, rd
, tmp
);
3145 if (insn
& (1 << 21)) {
3147 /* system register */
3152 /* Writes are ignored. */
3155 tmp
= load_reg(s
, rd
);
3156 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3157 tcg_temp_free_i32(tmp
);
3163 /* TODO: VFP subarchitecture support.
3164 * For now, keep the EN bit only */
3165 tmp
= load_reg(s
, rd
);
3166 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3167 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3170 case ARM_VFP_FPINST
:
3171 case ARM_VFP_FPINST2
:
3172 tmp
= load_reg(s
, rd
);
3173 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3179 tmp
= load_reg(s
, rd
);
3181 gen_mov_vreg_F0(0, rn
);
3186 /* data processing */
3187 /* The opcode is in bits 23, 21, 20 and 6. */
3188 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3192 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3194 /* rn is register number */
3195 VFP_DREG_N(rn
, insn
);
3198 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3199 ((rn
& 0x1e) == 0x6))) {
3200 /* Integer or single/half precision destination. */
3201 rd
= VFP_SREG_D(insn
);
3203 VFP_DREG_D(rd
, insn
);
3206 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3207 ((rn
& 0x1e) == 0x4))) {
3208 /* VCVT from int or half precision is always from S reg
3209 * regardless of dp bit. VCVT with immediate frac_bits
3210 * has same format as SREG_M.
3212 rm
= VFP_SREG_M(insn
);
3214 VFP_DREG_M(rm
, insn
);
3217 rn
= VFP_SREG_N(insn
);
3218 if (op
== 15 && rn
== 15) {
3219 /* Double precision destination. */
3220 VFP_DREG_D(rd
, insn
);
3222 rd
= VFP_SREG_D(insn
);
3224 /* NB that we implicitly rely on the encoding for the frac_bits
3225 * in VCVT of fixed to float being the same as that of an SREG_M
3227 rm
= VFP_SREG_M(insn
);
3230 veclen
= s
->vec_len
;
3231 if (op
== 15 && rn
> 3)
3234 /* Shut up compiler warnings. */
3245 /* Figure out what type of vector operation this is. */
3246 if ((rd
& bank_mask
) == 0) {
3251 delta_d
= (s
->vec_stride
>> 1) + 1;
3253 delta_d
= s
->vec_stride
+ 1;
3255 if ((rm
& bank_mask
) == 0) {
3256 /* mixed scalar/vector */
3265 /* Load the initial operands. */
3270 /* Integer source */
3271 gen_mov_F0_vreg(0, rm
);
3276 gen_mov_F0_vreg(dp
, rd
);
3277 gen_mov_F1_vreg(dp
, rm
);
3281 /* Compare with zero */
3282 gen_mov_F0_vreg(dp
, rd
);
3293 /* Source and destination the same. */
3294 gen_mov_F0_vreg(dp
, rd
);
3300 /* VCVTB, VCVTT: only present with the halfprec extension
3301 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3302 * (we choose to UNDEF)
3304 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3305 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3308 if (!extract32(rn
, 1, 1)) {
3309 /* Half precision source. */
3310 gen_mov_F0_vreg(0, rm
);
3313 /* Otherwise fall through */
3315 /* One source operand. */
3316 gen_mov_F0_vreg(dp
, rm
);
3320 /* Two source operands. */
3321 gen_mov_F0_vreg(dp
, rn
);
3322 gen_mov_F1_vreg(dp
, rm
);
3326 /* Perform the calculation. */
3328 case 0: /* VMLA: fd + (fn * fm) */
3329 /* Note that order of inputs to the add matters for NaNs */
3331 gen_mov_F0_vreg(dp
, rd
);
3334 case 1: /* VMLS: fd + -(fn * fm) */
3337 gen_mov_F0_vreg(dp
, rd
);
3340 case 2: /* VNMLS: -fd + (fn * fm) */
3341 /* Note that it isn't valid to replace (-A + B) with (B - A)
3342 * or similar plausible looking simplifications
3343 * because this will give wrong results for NaNs.
3346 gen_mov_F0_vreg(dp
, rd
);
3350 case 3: /* VNMLA: -fd + -(fn * fm) */
3353 gen_mov_F0_vreg(dp
, rd
);
3357 case 4: /* mul: fn * fm */
3360 case 5: /* nmul: -(fn * fm) */
3364 case 6: /* add: fn + fm */
3367 case 7: /* sub: fn - fm */
3370 case 8: /* div: fn / fm */
3373 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3374 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3375 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3376 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3377 /* These are fused multiply-add, and must be done as one
3378 * floating point operation with no rounding between the
3379 * multiplication and addition steps.
3380 * NB that doing the negations here as separate steps is
3381 * correct : an input NaN should come out with its sign bit
3382 * flipped if it is a negated-input.
3384 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3392 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3394 frd
= tcg_temp_new_i64();
3395 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3398 gen_helper_vfp_negd(frd
, frd
);
3400 fpst
= get_fpstatus_ptr(0);
3401 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3402 cpu_F1d
, frd
, fpst
);
3403 tcg_temp_free_ptr(fpst
);
3404 tcg_temp_free_i64(frd
);
3410 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3412 frd
= tcg_temp_new_i32();
3413 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3415 gen_helper_vfp_negs(frd
, frd
);
3417 fpst
= get_fpstatus_ptr(0);
3418 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3419 cpu_F1s
, frd
, fpst
);
3420 tcg_temp_free_ptr(fpst
);
3421 tcg_temp_free_i32(frd
);
3424 case 14: /* fconst */
3425 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3428 n
= (insn
<< 12) & 0x80000000;
3429 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3436 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3443 tcg_gen_movi_i32(cpu_F0s
, n
);
3446 case 15: /* extension space */
3460 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3461 tmp
= gen_vfp_mrs();
3462 tcg_gen_ext16u_i32(tmp
, tmp
);
3464 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3467 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3470 tcg_temp_free_i32(tmp
);
3472 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3473 tmp
= gen_vfp_mrs();
3474 tcg_gen_shri_i32(tmp
, tmp
, 16);
3476 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3479 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3482 tcg_temp_free_i32(tmp
);
3484 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3485 tmp
= tcg_temp_new_i32();
3487 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3490 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3493 gen_mov_F0_vreg(0, rd
);
3494 tmp2
= gen_vfp_mrs();
3495 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3496 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3497 tcg_temp_free_i32(tmp2
);
3500 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3501 tmp
= tcg_temp_new_i32();
3503 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3506 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3509 tcg_gen_shli_i32(tmp
, tmp
, 16);
3510 gen_mov_F0_vreg(0, rd
);
3511 tmp2
= gen_vfp_mrs();
3512 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3513 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3514 tcg_temp_free_i32(tmp2
);
3526 case 11: /* cmpez */
3530 case 12: /* vrintr */
3532 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3534 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3536 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3538 tcg_temp_free_ptr(fpst
);
3541 case 13: /* vrintz */
3543 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3545 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3546 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3548 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3550 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3552 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3553 tcg_temp_free_i32(tcg_rmode
);
3554 tcg_temp_free_ptr(fpst
);
3557 case 14: /* vrintx */
3559 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3561 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3563 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3565 tcg_temp_free_ptr(fpst
);
3568 case 15: /* single<->double conversion */
3570 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3572 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3574 case 16: /* fuito */
3575 gen_vfp_uito(dp
, 0);
3577 case 17: /* fsito */
3578 gen_vfp_sito(dp
, 0);
3580 case 20: /* fshto */
3581 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3583 gen_vfp_shto(dp
, 16 - rm
, 0);
3585 case 21: /* fslto */
3586 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3588 gen_vfp_slto(dp
, 32 - rm
, 0);
3590 case 22: /* fuhto */
3591 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3593 gen_vfp_uhto(dp
, 16 - rm
, 0);
3595 case 23: /* fulto */
3596 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3598 gen_vfp_ulto(dp
, 32 - rm
, 0);
3600 case 24: /* ftoui */
3601 gen_vfp_toui(dp
, 0);
3603 case 25: /* ftouiz */
3604 gen_vfp_touiz(dp
, 0);
3606 case 26: /* ftosi */
3607 gen_vfp_tosi(dp
, 0);
3609 case 27: /* ftosiz */
3610 gen_vfp_tosiz(dp
, 0);
3612 case 28: /* ftosh */
3613 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3615 gen_vfp_tosh(dp
, 16 - rm
, 0);
3617 case 29: /* ftosl */
3618 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3620 gen_vfp_tosl(dp
, 32 - rm
, 0);
3622 case 30: /* ftouh */
3623 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3625 gen_vfp_touh(dp
, 16 - rm
, 0);
3627 case 31: /* ftoul */
3628 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3630 gen_vfp_toul(dp
, 32 - rm
, 0);
3632 default: /* undefined */
3636 default: /* undefined */
3640 /* Write back the result. */
3641 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3642 /* Comparison, do nothing. */
3643 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3644 (rn
& 0x1e) == 0x6)) {
3645 /* VCVT double to int: always integer result.
3646 * VCVT double to half precision is always a single
3649 gen_mov_vreg_F0(0, rd
);
3650 } else if (op
== 15 && rn
== 15) {
3652 gen_mov_vreg_F0(!dp
, rd
);
3654 gen_mov_vreg_F0(dp
, rd
);
3657 /* break out of the loop if we have finished */
3661 if (op
== 15 && delta_m
== 0) {
3662 /* single source one-many */
3664 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3666 gen_mov_vreg_F0(dp
, rd
);
3670 /* Setup the next operands. */
3672 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3676 /* One source operand. */
3677 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3679 gen_mov_F0_vreg(dp
, rm
);
3681 /* Two source operands. */
3682 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3684 gen_mov_F0_vreg(dp
, rn
);
3686 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3688 gen_mov_F1_vreg(dp
, rm
);
3696 if ((insn
& 0x03e00000) == 0x00400000) {
3697 /* two-register transfer */
3698 rn
= (insn
>> 16) & 0xf;
3699 rd
= (insn
>> 12) & 0xf;
3701 VFP_DREG_M(rm
, insn
);
3703 rm
= VFP_SREG_M(insn
);
3706 if (insn
& ARM_CP_RW_BIT
) {
3709 gen_mov_F0_vreg(0, rm
* 2);
3710 tmp
= gen_vfp_mrs();
3711 store_reg(s
, rd
, tmp
);
3712 gen_mov_F0_vreg(0, rm
* 2 + 1);
3713 tmp
= gen_vfp_mrs();
3714 store_reg(s
, rn
, tmp
);
3716 gen_mov_F0_vreg(0, rm
);
3717 tmp
= gen_vfp_mrs();
3718 store_reg(s
, rd
, tmp
);
3719 gen_mov_F0_vreg(0, rm
+ 1);
3720 tmp
= gen_vfp_mrs();
3721 store_reg(s
, rn
, tmp
);
3726 tmp
= load_reg(s
, rd
);
3728 gen_mov_vreg_F0(0, rm
* 2);
3729 tmp
= load_reg(s
, rn
);
3731 gen_mov_vreg_F0(0, rm
* 2 + 1);
3733 tmp
= load_reg(s
, rd
);
3735 gen_mov_vreg_F0(0, rm
);
3736 tmp
= load_reg(s
, rn
);
3738 gen_mov_vreg_F0(0, rm
+ 1);
3743 rn
= (insn
>> 16) & 0xf;
3745 VFP_DREG_D(rd
, insn
);
3747 rd
= VFP_SREG_D(insn
);
3748 if ((insn
& 0x01200000) == 0x01000000) {
3749 /* Single load/store */
3750 offset
= (insn
& 0xff) << 2;
3751 if ((insn
& (1 << 23)) == 0)
3753 if (s
->thumb
&& rn
== 15) {
3754 /* This is actually UNPREDICTABLE */
3755 addr
= tcg_temp_new_i32();
3756 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3758 addr
= load_reg(s
, rn
);
3760 tcg_gen_addi_i32(addr
, addr
, offset
);
3761 if (insn
& (1 << 20)) {
3762 gen_vfp_ld(s
, dp
, addr
);
3763 gen_mov_vreg_F0(dp
, rd
);
3765 gen_mov_F0_vreg(dp
, rd
);
3766 gen_vfp_st(s
, dp
, addr
);
3768 tcg_temp_free_i32(addr
);
3770 /* load/store multiple */
3771 int w
= insn
& (1 << 21);
3773 n
= (insn
>> 1) & 0x7f;
3777 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3778 /* P == U , W == 1 => UNDEF */
3781 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3782 /* UNPREDICTABLE cases for bad immediates: we choose to
3783 * UNDEF to avoid generating huge numbers of TCG ops
3787 if (rn
== 15 && w
) {
3788 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3792 if (s
->thumb
&& rn
== 15) {
3793 /* This is actually UNPREDICTABLE */
3794 addr
= tcg_temp_new_i32();
3795 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3797 addr
= load_reg(s
, rn
);
3799 if (insn
& (1 << 24)) /* pre-decrement */
3800 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3806 for (i
= 0; i
< n
; i
++) {
3807 if (insn
& ARM_CP_RW_BIT
) {
3809 gen_vfp_ld(s
, dp
, addr
);
3810 gen_mov_vreg_F0(dp
, rd
+ i
);
3813 gen_mov_F0_vreg(dp
, rd
+ i
);
3814 gen_vfp_st(s
, dp
, addr
);
3816 tcg_gen_addi_i32(addr
, addr
, offset
);
3820 if (insn
& (1 << 24))
3821 offset
= -offset
* n
;
3822 else if (dp
&& (insn
& 1))
3828 tcg_gen_addi_i32(addr
, addr
, offset
);
3829 store_reg(s
, rn
, addr
);
3831 tcg_temp_free_i32(addr
);
3837 /* Should never happen. */
3843 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3845 TranslationBlock
*tb
;
3848 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3850 gen_set_pc_im(s
, dest
);
3851 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3853 gen_set_pc_im(s
, dest
);
3858 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3860 if (unlikely(s
->singlestep_enabled
)) {
3861 /* An indirect jump so that we still trigger the debug exception. */
3866 gen_goto_tb(s
, 0, dest
);
3867 s
->is_jmp
= DISAS_TB_JUMP
;
3871 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3874 tcg_gen_sari_i32(t0
, t0
, 16);
3878 tcg_gen_sari_i32(t1
, t1
, 16);
3881 tcg_gen_mul_i32(t0
, t0
, t1
);
3884 /* Return the mask of PSR bits set by a MSR instruction. */
3885 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3889 if (flags
& (1 << 0))
3891 if (flags
& (1 << 1))
3893 if (flags
& (1 << 2))
3895 if (flags
& (1 << 3))
3898 /* Mask out undefined bits. */
3899 mask
&= ~CPSR_RESERVED
;
3900 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3902 if (!arm_feature(env
, ARM_FEATURE_V5
))
3903 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3904 if (!arm_feature(env
, ARM_FEATURE_V6
))
3905 mask
&= ~(CPSR_E
| CPSR_GE
);
3906 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3908 /* Mask out execution state bits. */
3911 /* Mask out privileged bits. */
3917 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3918 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3922 /* ??? This is also undefined in system mode. */
3926 tmp
= load_cpu_field(spsr
);
3927 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3928 tcg_gen_andi_i32(t0
, t0
, mask
);
3929 tcg_gen_or_i32(tmp
, tmp
, t0
);
3930 store_cpu_field(tmp
, spsr
);
3932 gen_set_cpsr(t0
, mask
);
3934 tcg_temp_free_i32(t0
);
3939 /* Returns nonzero if access to the PSR is not permitted. */
3940 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3943 tmp
= tcg_temp_new_i32();
3944 tcg_gen_movi_i32(tmp
, val
);
3945 return gen_set_psr(s
, mask
, spsr
, tmp
);
3948 /* Generate an old-style exception return. Marks pc as dead. */
3949 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3952 store_reg(s
, 15, pc
);
3953 tmp
= load_cpu_field(spsr
);
3954 gen_set_cpsr(tmp
, 0xffffffff);
3955 tcg_temp_free_i32(tmp
);
3956 s
->is_jmp
= DISAS_UPDATE
;
3959 /* Generate a v6 exception return. Marks both values as dead. */
3960 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3962 gen_set_cpsr(cpsr
, 0xffffffff);
3963 tcg_temp_free_i32(cpsr
);
3964 store_reg(s
, 15, pc
);
3965 s
->is_jmp
= DISAS_UPDATE
;
3968 static void gen_nop_hint(DisasContext
*s
, int val
)
3972 gen_set_pc_im(s
, s
->pc
);
3973 s
->is_jmp
= DISAS_WFI
;
3976 gen_set_pc_im(s
, s
->pc
);
3977 s
->is_jmp
= DISAS_WFE
;
3981 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3987 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3989 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3992 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3993 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3994 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3999 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4002 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4003 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4004 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4009 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4010 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4011 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4012 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4013 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4015 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4016 switch ((size << 1) | u) { \
4018 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4021 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4024 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4027 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4030 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4033 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4035 default: return 1; \
4038 #define GEN_NEON_INTEGER_OP(name) do { \
4039 switch ((size << 1) | u) { \
4041 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4044 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4047 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4050 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4053 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4056 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4058 default: return 1; \
4061 static TCGv_i32
neon_load_scratch(int scratch
)
4063 TCGv_i32 tmp
= tcg_temp_new_i32();
4064 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4068 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4070 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4071 tcg_temp_free_i32(var
);
4074 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4078 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4080 gen_neon_dup_high16(tmp
);
4082 gen_neon_dup_low16(tmp
);
4085 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4090 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4093 if (!q
&& size
== 2) {
4096 tmp
= tcg_const_i32(rd
);
4097 tmp2
= tcg_const_i32(rm
);
4101 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4104 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4107 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4115 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4118 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4124 tcg_temp_free_i32(tmp
);
4125 tcg_temp_free_i32(tmp2
);
4129 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4132 if (!q
&& size
== 2) {
4135 tmp
= tcg_const_i32(rd
);
4136 tmp2
= tcg_const_i32(rm
);
4140 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4143 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4146 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4154 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4157 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4163 tcg_temp_free_i32(tmp
);
4164 tcg_temp_free_i32(tmp2
);
4168 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4172 rd
= tcg_temp_new_i32();
4173 tmp
= tcg_temp_new_i32();
4175 tcg_gen_shli_i32(rd
, t0
, 8);
4176 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4177 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4178 tcg_gen_or_i32(rd
, rd
, tmp
);
4180 tcg_gen_shri_i32(t1
, t1
, 8);
4181 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4182 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4183 tcg_gen_or_i32(t1
, t1
, tmp
);
4184 tcg_gen_mov_i32(t0
, rd
);
4186 tcg_temp_free_i32(tmp
);
4187 tcg_temp_free_i32(rd
);
4190 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4194 rd
= tcg_temp_new_i32();
4195 tmp
= tcg_temp_new_i32();
4197 tcg_gen_shli_i32(rd
, t0
, 16);
4198 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4199 tcg_gen_or_i32(rd
, rd
, tmp
);
4200 tcg_gen_shri_i32(t1
, t1
, 16);
4201 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4202 tcg_gen_or_i32(t1
, t1
, tmp
);
4203 tcg_gen_mov_i32(t0
, rd
);
4205 tcg_temp_free_i32(tmp
);
4206 tcg_temp_free_i32(rd
);
4214 } neon_ls_element_type
[11] = {
4228 /* Translate a NEON load/store element instruction. Return nonzero if the
4229 instruction is invalid. */
4230 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4249 /* FIXME: this access check should not take precedence over UNDEF
4250 * for invalid encodings; we will generate incorrect syndrome information
4251 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4253 if (!s
->cpacr_fpen
) {
4254 gen_exception_insn(s
, 4, EXCP_UDEF
,
4255 syn_fp_access_trap(1, 0xe, s
->thumb
));
4259 if (!s
->vfp_enabled
)
4261 VFP_DREG_D(rd
, insn
);
4262 rn
= (insn
>> 16) & 0xf;
4264 load
= (insn
& (1 << 21)) != 0;
4265 if ((insn
& (1 << 23)) == 0) {
4266 /* Load store all elements. */
4267 op
= (insn
>> 8) & 0xf;
4268 size
= (insn
>> 6) & 3;
4271 /* Catch UNDEF cases for bad values of align field */
4274 if (((insn
>> 5) & 1) == 1) {
4279 if (((insn
>> 4) & 3) == 3) {
4286 nregs
= neon_ls_element_type
[op
].nregs
;
4287 interleave
= neon_ls_element_type
[op
].interleave
;
4288 spacing
= neon_ls_element_type
[op
].spacing
;
4289 if (size
== 3 && (interleave
| spacing
) != 1)
4291 addr
= tcg_temp_new_i32();
4292 load_reg_var(s
, addr
, rn
);
4293 stride
= (1 << size
) * interleave
;
4294 for (reg
= 0; reg
< nregs
; reg
++) {
4295 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4296 load_reg_var(s
, addr
, rn
);
4297 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4298 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4299 load_reg_var(s
, addr
, rn
);
4300 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4303 tmp64
= tcg_temp_new_i64();
4305 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4306 neon_store_reg64(tmp64
, rd
);
4308 neon_load_reg64(tmp64
, rd
);
4309 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4311 tcg_temp_free_i64(tmp64
);
4312 tcg_gen_addi_i32(addr
, addr
, stride
);
4314 for (pass
= 0; pass
< 2; pass
++) {
4317 tmp
= tcg_temp_new_i32();
4318 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4319 neon_store_reg(rd
, pass
, tmp
);
4321 tmp
= neon_load_reg(rd
, pass
);
4322 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4323 tcg_temp_free_i32(tmp
);
4325 tcg_gen_addi_i32(addr
, addr
, stride
);
4326 } else if (size
== 1) {
4328 tmp
= tcg_temp_new_i32();
4329 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4330 tcg_gen_addi_i32(addr
, addr
, stride
);
4331 tmp2
= tcg_temp_new_i32();
4332 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4333 tcg_gen_addi_i32(addr
, addr
, stride
);
4334 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4335 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4336 tcg_temp_free_i32(tmp2
);
4337 neon_store_reg(rd
, pass
, tmp
);
4339 tmp
= neon_load_reg(rd
, pass
);
4340 tmp2
= tcg_temp_new_i32();
4341 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4342 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4343 tcg_temp_free_i32(tmp
);
4344 tcg_gen_addi_i32(addr
, addr
, stride
);
4345 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4346 tcg_temp_free_i32(tmp2
);
4347 tcg_gen_addi_i32(addr
, addr
, stride
);
4349 } else /* size == 0 */ {
4351 TCGV_UNUSED_I32(tmp2
);
4352 for (n
= 0; n
< 4; n
++) {
4353 tmp
= tcg_temp_new_i32();
4354 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4355 tcg_gen_addi_i32(addr
, addr
, stride
);
4359 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4360 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4361 tcg_temp_free_i32(tmp
);
4364 neon_store_reg(rd
, pass
, tmp2
);
4366 tmp2
= neon_load_reg(rd
, pass
);
4367 for (n
= 0; n
< 4; n
++) {
4368 tmp
= tcg_temp_new_i32();
4370 tcg_gen_mov_i32(tmp
, tmp2
);
4372 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4374 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4375 tcg_temp_free_i32(tmp
);
4376 tcg_gen_addi_i32(addr
, addr
, stride
);
4378 tcg_temp_free_i32(tmp2
);
4385 tcg_temp_free_i32(addr
);
4388 size
= (insn
>> 10) & 3;
4390 /* Load single element to all lanes. */
4391 int a
= (insn
>> 4) & 1;
4395 size
= (insn
>> 6) & 3;
4396 nregs
= ((insn
>> 8) & 3) + 1;
4399 if (nregs
!= 4 || a
== 0) {
4402 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4405 if (nregs
== 1 && a
== 1 && size
== 0) {
4408 if (nregs
== 3 && a
== 1) {
4411 addr
= tcg_temp_new_i32();
4412 load_reg_var(s
, addr
, rn
);
4414 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4415 tmp
= gen_load_and_replicate(s
, addr
, size
);
4416 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4417 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4418 if (insn
& (1 << 5)) {
4419 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4420 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4422 tcg_temp_free_i32(tmp
);
4424 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4425 stride
= (insn
& (1 << 5)) ? 2 : 1;
4426 for (reg
= 0; reg
< nregs
; reg
++) {
4427 tmp
= gen_load_and_replicate(s
, addr
, size
);
4428 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4429 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4430 tcg_temp_free_i32(tmp
);
4431 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4435 tcg_temp_free_i32(addr
);
4436 stride
= (1 << size
) * nregs
;
4438 /* Single element. */
4439 int idx
= (insn
>> 4) & 0xf;
4440 pass
= (insn
>> 7) & 1;
4443 shift
= ((insn
>> 5) & 3) * 8;
4447 shift
= ((insn
>> 6) & 1) * 16;
4448 stride
= (insn
& (1 << 5)) ? 2 : 1;
4452 stride
= (insn
& (1 << 6)) ? 2 : 1;
4457 nregs
= ((insn
>> 8) & 3) + 1;
4458 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4461 if (((idx
& (1 << size
)) != 0) ||
4462 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4467 if ((idx
& 1) != 0) {
4472 if (size
== 2 && (idx
& 2) != 0) {
4477 if ((size
== 2) && ((idx
& 3) == 3)) {
4484 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4485 /* Attempts to write off the end of the register file
4486 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4487 * the neon_load_reg() would write off the end of the array.
4491 addr
= tcg_temp_new_i32();
4492 load_reg_var(s
, addr
, rn
);
4493 for (reg
= 0; reg
< nregs
; reg
++) {
4495 tmp
= tcg_temp_new_i32();
4498 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4501 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4504 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4506 default: /* Avoid compiler warnings. */
4510 tmp2
= neon_load_reg(rd
, pass
);
4511 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4512 shift
, size
? 16 : 8);
4513 tcg_temp_free_i32(tmp2
);
4515 neon_store_reg(rd
, pass
, tmp
);
4516 } else { /* Store */
4517 tmp
= neon_load_reg(rd
, pass
);
4519 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4522 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4525 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4528 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4531 tcg_temp_free_i32(tmp
);
4534 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4536 tcg_temp_free_i32(addr
);
4537 stride
= nregs
* (1 << size
);
4543 base
= load_reg(s
, rn
);
4545 tcg_gen_addi_i32(base
, base
, stride
);
4548 index
= load_reg(s
, rm
);
4549 tcg_gen_add_i32(base
, base
, index
);
4550 tcg_temp_free_i32(index
);
4552 store_reg(s
, rn
, base
);
4557 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4558 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4560 tcg_gen_and_i32(t
, t
, c
);
4561 tcg_gen_andc_i32(f
, f
, c
);
4562 tcg_gen_or_i32(dest
, t
, f
);
4565 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4568 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4569 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4570 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4575 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4578 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4579 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4580 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4585 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4588 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4589 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4590 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4595 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4598 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4599 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4600 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4605 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4611 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4612 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4617 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4618 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4625 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4626 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4631 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4632 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4639 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4643 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4644 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4645 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4650 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4651 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4652 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4656 tcg_temp_free_i32(src
);
4659 static inline void gen_neon_addl(int size
)
4662 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4663 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4664 case 2: tcg_gen_add_i64(CPU_V001
); break;
4669 static inline void gen_neon_subl(int size
)
4672 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4673 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4674 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4679 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4682 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4683 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4685 tcg_gen_neg_i64(var
, var
);
4691 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4694 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4695 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4700 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4705 switch ((size
<< 1) | u
) {
4706 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4707 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4708 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4709 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4711 tmp
= gen_muls_i64_i32(a
, b
);
4712 tcg_gen_mov_i64(dest
, tmp
);
4713 tcg_temp_free_i64(tmp
);
4716 tmp
= gen_mulu_i64_i32(a
, b
);
4717 tcg_gen_mov_i64(dest
, tmp
);
4718 tcg_temp_free_i64(tmp
);
4723 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4724 Don't forget to clean them now. */
4726 tcg_temp_free_i32(a
);
4727 tcg_temp_free_i32(b
);
4731 static void gen_neon_narrow_op(int op
, int u
, int size
,
4732 TCGv_i32 dest
, TCGv_i64 src
)
4736 gen_neon_unarrow_sats(size
, dest
, src
);
4738 gen_neon_narrow(size
, dest
, src
);
4742 gen_neon_narrow_satu(size
, dest
, src
);
4744 gen_neon_narrow_sats(size
, dest
, src
);
4749 /* Symbolic constants for op fields for Neon 3-register same-length.
4750 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4753 #define NEON_3R_VHADD 0
4754 #define NEON_3R_VQADD 1
4755 #define NEON_3R_VRHADD 2
4756 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4757 #define NEON_3R_VHSUB 4
4758 #define NEON_3R_VQSUB 5
4759 #define NEON_3R_VCGT 6
4760 #define NEON_3R_VCGE 7
4761 #define NEON_3R_VSHL 8
4762 #define NEON_3R_VQSHL 9
4763 #define NEON_3R_VRSHL 10
4764 #define NEON_3R_VQRSHL 11
4765 #define NEON_3R_VMAX 12
4766 #define NEON_3R_VMIN 13
4767 #define NEON_3R_VABD 14
4768 #define NEON_3R_VABA 15
4769 #define NEON_3R_VADD_VSUB 16
4770 #define NEON_3R_VTST_VCEQ 17
4771 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4772 #define NEON_3R_VMUL 19
4773 #define NEON_3R_VPMAX 20
4774 #define NEON_3R_VPMIN 21
4775 #define NEON_3R_VQDMULH_VQRDMULH 22
4776 #define NEON_3R_VPADD 23
4777 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4778 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4779 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4780 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4781 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4782 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4783 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4784 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4786 static const uint8_t neon_3r_sizes
[] = {
4787 [NEON_3R_VHADD
] = 0x7,
4788 [NEON_3R_VQADD
] = 0xf,
4789 [NEON_3R_VRHADD
] = 0x7,
4790 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4791 [NEON_3R_VHSUB
] = 0x7,
4792 [NEON_3R_VQSUB
] = 0xf,
4793 [NEON_3R_VCGT
] = 0x7,
4794 [NEON_3R_VCGE
] = 0x7,
4795 [NEON_3R_VSHL
] = 0xf,
4796 [NEON_3R_VQSHL
] = 0xf,
4797 [NEON_3R_VRSHL
] = 0xf,
4798 [NEON_3R_VQRSHL
] = 0xf,
4799 [NEON_3R_VMAX
] = 0x7,
4800 [NEON_3R_VMIN
] = 0x7,
4801 [NEON_3R_VABD
] = 0x7,
4802 [NEON_3R_VABA
] = 0x7,
4803 [NEON_3R_VADD_VSUB
] = 0xf,
4804 [NEON_3R_VTST_VCEQ
] = 0x7,
4805 [NEON_3R_VML
] = 0x7,
4806 [NEON_3R_VMUL
] = 0x7,
4807 [NEON_3R_VPMAX
] = 0x7,
4808 [NEON_3R_VPMIN
] = 0x7,
4809 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4810 [NEON_3R_VPADD
] = 0x7,
4811 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4812 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4813 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4814 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4815 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4816 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4817 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4818 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4821 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4822 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4825 #define NEON_2RM_VREV64 0
4826 #define NEON_2RM_VREV32 1
4827 #define NEON_2RM_VREV16 2
4828 #define NEON_2RM_VPADDL 4
4829 #define NEON_2RM_VPADDL_U 5
4830 #define NEON_2RM_AESE 6 /* Includes AESD */
4831 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4832 #define NEON_2RM_VCLS 8
4833 #define NEON_2RM_VCLZ 9
4834 #define NEON_2RM_VCNT 10
4835 #define NEON_2RM_VMVN 11
4836 #define NEON_2RM_VPADAL 12
4837 #define NEON_2RM_VPADAL_U 13
4838 #define NEON_2RM_VQABS 14
4839 #define NEON_2RM_VQNEG 15
4840 #define NEON_2RM_VCGT0 16
4841 #define NEON_2RM_VCGE0 17
4842 #define NEON_2RM_VCEQ0 18
4843 #define NEON_2RM_VCLE0 19
4844 #define NEON_2RM_VCLT0 20
4845 #define NEON_2RM_SHA1H 21
4846 #define NEON_2RM_VABS 22
4847 #define NEON_2RM_VNEG 23
4848 #define NEON_2RM_VCGT0_F 24
4849 #define NEON_2RM_VCGE0_F 25
4850 #define NEON_2RM_VCEQ0_F 26
4851 #define NEON_2RM_VCLE0_F 27
4852 #define NEON_2RM_VCLT0_F 28
4853 #define NEON_2RM_VABS_F 30
4854 #define NEON_2RM_VNEG_F 31
4855 #define NEON_2RM_VSWP 32
4856 #define NEON_2RM_VTRN 33
4857 #define NEON_2RM_VUZP 34
4858 #define NEON_2RM_VZIP 35
4859 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4860 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4861 #define NEON_2RM_VSHLL 38
4862 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4863 #define NEON_2RM_VRINTN 40
4864 #define NEON_2RM_VRINTX 41
4865 #define NEON_2RM_VRINTA 42
4866 #define NEON_2RM_VRINTZ 43
4867 #define NEON_2RM_VCVT_F16_F32 44
4868 #define NEON_2RM_VRINTM 45
4869 #define NEON_2RM_VCVT_F32_F16 46
4870 #define NEON_2RM_VRINTP 47
4871 #define NEON_2RM_VCVTAU 48
4872 #define NEON_2RM_VCVTAS 49
4873 #define NEON_2RM_VCVTNU 50
4874 #define NEON_2RM_VCVTNS 51
4875 #define NEON_2RM_VCVTPU 52
4876 #define NEON_2RM_VCVTPS 53
4877 #define NEON_2RM_VCVTMU 54
4878 #define NEON_2RM_VCVTMS 55
4879 #define NEON_2RM_VRECPE 56
4880 #define NEON_2RM_VRSQRTE 57
4881 #define NEON_2RM_VRECPE_F 58
4882 #define NEON_2RM_VRSQRTE_F 59
4883 #define NEON_2RM_VCVT_FS 60
4884 #define NEON_2RM_VCVT_FU 61
4885 #define NEON_2RM_VCVT_SF 62
4886 #define NEON_2RM_VCVT_UF 63
4888 static int neon_2rm_is_float_op(int op
)
4890 /* Return true if this neon 2reg-misc op is float-to-float */
4891 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4892 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4893 op
== NEON_2RM_VRINTM
||
4894 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4895 op
>= NEON_2RM_VRECPE_F
);
4898 /* Each entry in this array has bit n set if the insn allows
4899 * size value n (otherwise it will UNDEF). Since unallocated
4900 * op values will have no bits set they always UNDEF.
4902 static const uint8_t neon_2rm_sizes
[] = {
4903 [NEON_2RM_VREV64
] = 0x7,
4904 [NEON_2RM_VREV32
] = 0x3,
4905 [NEON_2RM_VREV16
] = 0x1,
4906 [NEON_2RM_VPADDL
] = 0x7,
4907 [NEON_2RM_VPADDL_U
] = 0x7,
4908 [NEON_2RM_AESE
] = 0x1,
4909 [NEON_2RM_AESMC
] = 0x1,
4910 [NEON_2RM_VCLS
] = 0x7,
4911 [NEON_2RM_VCLZ
] = 0x7,
4912 [NEON_2RM_VCNT
] = 0x1,
4913 [NEON_2RM_VMVN
] = 0x1,
4914 [NEON_2RM_VPADAL
] = 0x7,
4915 [NEON_2RM_VPADAL_U
] = 0x7,
4916 [NEON_2RM_VQABS
] = 0x7,
4917 [NEON_2RM_VQNEG
] = 0x7,
4918 [NEON_2RM_VCGT0
] = 0x7,
4919 [NEON_2RM_VCGE0
] = 0x7,
4920 [NEON_2RM_VCEQ0
] = 0x7,
4921 [NEON_2RM_VCLE0
] = 0x7,
4922 [NEON_2RM_VCLT0
] = 0x7,
4923 [NEON_2RM_SHA1H
] = 0x4,
4924 [NEON_2RM_VABS
] = 0x7,
4925 [NEON_2RM_VNEG
] = 0x7,
4926 [NEON_2RM_VCGT0_F
] = 0x4,
4927 [NEON_2RM_VCGE0_F
] = 0x4,
4928 [NEON_2RM_VCEQ0_F
] = 0x4,
4929 [NEON_2RM_VCLE0_F
] = 0x4,
4930 [NEON_2RM_VCLT0_F
] = 0x4,
4931 [NEON_2RM_VABS_F
] = 0x4,
4932 [NEON_2RM_VNEG_F
] = 0x4,
4933 [NEON_2RM_VSWP
] = 0x1,
4934 [NEON_2RM_VTRN
] = 0x7,
4935 [NEON_2RM_VUZP
] = 0x7,
4936 [NEON_2RM_VZIP
] = 0x7,
4937 [NEON_2RM_VMOVN
] = 0x7,
4938 [NEON_2RM_VQMOVN
] = 0x7,
4939 [NEON_2RM_VSHLL
] = 0x7,
4940 [NEON_2RM_SHA1SU1
] = 0x4,
4941 [NEON_2RM_VRINTN
] = 0x4,
4942 [NEON_2RM_VRINTX
] = 0x4,
4943 [NEON_2RM_VRINTA
] = 0x4,
4944 [NEON_2RM_VRINTZ
] = 0x4,
4945 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4946 [NEON_2RM_VRINTM
] = 0x4,
4947 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4948 [NEON_2RM_VRINTP
] = 0x4,
4949 [NEON_2RM_VCVTAU
] = 0x4,
4950 [NEON_2RM_VCVTAS
] = 0x4,
4951 [NEON_2RM_VCVTNU
] = 0x4,
4952 [NEON_2RM_VCVTNS
] = 0x4,
4953 [NEON_2RM_VCVTPU
] = 0x4,
4954 [NEON_2RM_VCVTPS
] = 0x4,
4955 [NEON_2RM_VCVTMU
] = 0x4,
4956 [NEON_2RM_VCVTMS
] = 0x4,
4957 [NEON_2RM_VRECPE
] = 0x4,
4958 [NEON_2RM_VRSQRTE
] = 0x4,
4959 [NEON_2RM_VRECPE_F
] = 0x4,
4960 [NEON_2RM_VRSQRTE_F
] = 0x4,
4961 [NEON_2RM_VCVT_FS
] = 0x4,
4962 [NEON_2RM_VCVT_FU
] = 0x4,
4963 [NEON_2RM_VCVT_SF
] = 0x4,
4964 [NEON_2RM_VCVT_UF
] = 0x4,
4967 /* Translate a NEON data processing instruction. Return nonzero if the
4968 instruction is invalid.
4969 We process data in a mixture of 32-bit and 64-bit chunks.
4970 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4972 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4984 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4987 /* FIXME: this access check should not take precedence over UNDEF
4988 * for invalid encodings; we will generate incorrect syndrome information
4989 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4991 if (!s
->cpacr_fpen
) {
4992 gen_exception_insn(s
, 4, EXCP_UDEF
,
4993 syn_fp_access_trap(1, 0xe, s
->thumb
));
4997 if (!s
->vfp_enabled
)
4999 q
= (insn
& (1 << 6)) != 0;
5000 u
= (insn
>> 24) & 1;
5001 VFP_DREG_D(rd
, insn
);
5002 VFP_DREG_N(rn
, insn
);
5003 VFP_DREG_M(rm
, insn
);
5004 size
= (insn
>> 20) & 3;
5005 if ((insn
& (1 << 23)) == 0) {
5006 /* Three register same length. */
5007 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5008 /* Catch invalid op and bad size combinations: UNDEF */
5009 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5012 /* All insns of this form UNDEF for either this condition or the
5013 * superset of cases "Q==1"; we catch the latter later.
5015 if (q
&& ((rd
| rn
| rm
) & 1)) {
5019 * The SHA-1/SHA-256 3-register instructions require special treatment
5020 * here, as their size field is overloaded as an op type selector, and
5021 * they all consume their input in a single pass.
5023 if (op
== NEON_3R_SHA
) {
5027 if (!u
) { /* SHA-1 */
5028 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5031 tmp
= tcg_const_i32(rd
);
5032 tmp2
= tcg_const_i32(rn
);
5033 tmp3
= tcg_const_i32(rm
);
5034 tmp4
= tcg_const_i32(size
);
5035 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5036 tcg_temp_free_i32(tmp4
);
5037 } else { /* SHA-256 */
5038 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5041 tmp
= tcg_const_i32(rd
);
5042 tmp2
= tcg_const_i32(rn
);
5043 tmp3
= tcg_const_i32(rm
);
5046 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5049 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5052 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5056 tcg_temp_free_i32(tmp
);
5057 tcg_temp_free_i32(tmp2
);
5058 tcg_temp_free_i32(tmp3
);
5061 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5062 /* 64-bit element instructions. */
5063 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5064 neon_load_reg64(cpu_V0
, rn
+ pass
);
5065 neon_load_reg64(cpu_V1
, rm
+ pass
);
5069 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5072 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5078 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5081 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5087 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5089 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5094 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5097 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5103 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5105 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5108 case NEON_3R_VQRSHL
:
5110 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5113 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5117 case NEON_3R_VADD_VSUB
:
5119 tcg_gen_sub_i64(CPU_V001
);
5121 tcg_gen_add_i64(CPU_V001
);
5127 neon_store_reg64(cpu_V0
, rd
+ pass
);
5136 case NEON_3R_VQRSHL
:
5139 /* Shift instruction operands are reversed. */
5154 case NEON_3R_FLOAT_ARITH
:
5155 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5157 case NEON_3R_FLOAT_MINMAX
:
5158 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5160 case NEON_3R_FLOAT_CMP
:
5162 /* no encoding for U=0 C=1x */
5166 case NEON_3R_FLOAT_ACMP
:
5171 case NEON_3R_FLOAT_MISC
:
5172 /* VMAXNM/VMINNM in ARMv8 */
5173 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5178 if (u
&& (size
!= 0)) {
5179 /* UNDEF on invalid size for polynomial subcase */
5184 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5192 if (pairwise
&& q
) {
5193 /* All the pairwise insns UNDEF if Q is set */
5197 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5202 tmp
= neon_load_reg(rn
, 0);
5203 tmp2
= neon_load_reg(rn
, 1);
5205 tmp
= neon_load_reg(rm
, 0);
5206 tmp2
= neon_load_reg(rm
, 1);
5210 tmp
= neon_load_reg(rn
, pass
);
5211 tmp2
= neon_load_reg(rm
, pass
);
5215 GEN_NEON_INTEGER_OP(hadd
);
5218 GEN_NEON_INTEGER_OP_ENV(qadd
);
5220 case NEON_3R_VRHADD
:
5221 GEN_NEON_INTEGER_OP(rhadd
);
5223 case NEON_3R_LOGIC
: /* Logic ops. */
5224 switch ((u
<< 2) | size
) {
5226 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5229 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5232 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5235 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5238 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5241 tmp3
= neon_load_reg(rd
, pass
);
5242 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5243 tcg_temp_free_i32(tmp3
);
5246 tmp3
= neon_load_reg(rd
, pass
);
5247 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5248 tcg_temp_free_i32(tmp3
);
5251 tmp3
= neon_load_reg(rd
, pass
);
5252 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5253 tcg_temp_free_i32(tmp3
);
5258 GEN_NEON_INTEGER_OP(hsub
);
5261 GEN_NEON_INTEGER_OP_ENV(qsub
);
5264 GEN_NEON_INTEGER_OP(cgt
);
5267 GEN_NEON_INTEGER_OP(cge
);
5270 GEN_NEON_INTEGER_OP(shl
);
5273 GEN_NEON_INTEGER_OP_ENV(qshl
);
5276 GEN_NEON_INTEGER_OP(rshl
);
5278 case NEON_3R_VQRSHL
:
5279 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5282 GEN_NEON_INTEGER_OP(max
);
5285 GEN_NEON_INTEGER_OP(min
);
5288 GEN_NEON_INTEGER_OP(abd
);
5291 GEN_NEON_INTEGER_OP(abd
);
5292 tcg_temp_free_i32(tmp2
);
5293 tmp2
= neon_load_reg(rd
, pass
);
5294 gen_neon_add(size
, tmp
, tmp2
);
5296 case NEON_3R_VADD_VSUB
:
5297 if (!u
) { /* VADD */
5298 gen_neon_add(size
, tmp
, tmp2
);
5301 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5302 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5303 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5308 case NEON_3R_VTST_VCEQ
:
5309 if (!u
) { /* VTST */
5311 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5312 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5313 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5318 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5319 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5320 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5325 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5327 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5328 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5329 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5332 tcg_temp_free_i32(tmp2
);
5333 tmp2
= neon_load_reg(rd
, pass
);
5335 gen_neon_rsb(size
, tmp
, tmp2
);
5337 gen_neon_add(size
, tmp
, tmp2
);
5341 if (u
) { /* polynomial */
5342 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5343 } else { /* Integer */
5345 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5346 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5347 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5353 GEN_NEON_INTEGER_OP(pmax
);
5356 GEN_NEON_INTEGER_OP(pmin
);
5358 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5359 if (!u
) { /* VQDMULH */
5362 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5365 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5369 } else { /* VQRDMULH */
5372 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5375 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5383 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5384 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5385 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5389 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5391 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5392 switch ((u
<< 2) | size
) {
5395 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5398 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5401 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5406 tcg_temp_free_ptr(fpstatus
);
5409 case NEON_3R_FLOAT_MULTIPLY
:
5411 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5412 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5414 tcg_temp_free_i32(tmp2
);
5415 tmp2
= neon_load_reg(rd
, pass
);
5417 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5419 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5422 tcg_temp_free_ptr(fpstatus
);
5425 case NEON_3R_FLOAT_CMP
:
5427 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5429 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5432 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5434 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5437 tcg_temp_free_ptr(fpstatus
);
5440 case NEON_3R_FLOAT_ACMP
:
5442 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5444 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5446 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5448 tcg_temp_free_ptr(fpstatus
);
5451 case NEON_3R_FLOAT_MINMAX
:
5453 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5455 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5457 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5459 tcg_temp_free_ptr(fpstatus
);
5462 case NEON_3R_FLOAT_MISC
:
5465 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5467 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5469 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5471 tcg_temp_free_ptr(fpstatus
);
5474 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5476 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5482 /* VFMA, VFMS: fused multiply-add */
5483 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5484 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5487 gen_helper_vfp_negs(tmp
, tmp
);
5489 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5490 tcg_temp_free_i32(tmp3
);
5491 tcg_temp_free_ptr(fpstatus
);
5497 tcg_temp_free_i32(tmp2
);
5499 /* Save the result. For elementwise operations we can put it
5500 straight into the destination register. For pairwise operations
5501 we have to be careful to avoid clobbering the source operands. */
5502 if (pairwise
&& rd
== rm
) {
5503 neon_store_scratch(pass
, tmp
);
5505 neon_store_reg(rd
, pass
, tmp
);
5509 if (pairwise
&& rd
== rm
) {
5510 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5511 tmp
= neon_load_scratch(pass
);
5512 neon_store_reg(rd
, pass
, tmp
);
5515 /* End of 3 register same size operations. */
5516 } else if (insn
& (1 << 4)) {
5517 if ((insn
& 0x00380080) != 0) {
5518 /* Two registers and shift. */
5519 op
= (insn
>> 8) & 0xf;
5520 if (insn
& (1 << 7)) {
5528 while ((insn
& (1 << (size
+ 19))) == 0)
5531 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5532 /* To avoid excessive duplication of ops we implement shift
5533 by immediate using the variable shift operations. */
5535 /* Shift by immediate:
5536 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5537 if (q
&& ((rd
| rm
) & 1)) {
5540 if (!u
&& (op
== 4 || op
== 6)) {
5543 /* Right shifts are encoded as N - shift, where N is the
5544 element size in bits. */
5546 shift
= shift
- (1 << (size
+ 3));
5554 imm
= (uint8_t) shift
;
5559 imm
= (uint16_t) shift
;
5570 for (pass
= 0; pass
< count
; pass
++) {
5572 neon_load_reg64(cpu_V0
, rm
+ pass
);
5573 tcg_gen_movi_i64(cpu_V1
, imm
);
5578 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5580 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5585 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5587 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5590 case 5: /* VSHL, VSLI */
5591 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5593 case 6: /* VQSHLU */
5594 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5599 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5602 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5607 if (op
== 1 || op
== 3) {
5609 neon_load_reg64(cpu_V1
, rd
+ pass
);
5610 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5611 } else if (op
== 4 || (op
== 5 && u
)) {
5613 neon_load_reg64(cpu_V1
, rd
+ pass
);
5615 if (shift
< -63 || shift
> 63) {
5619 mask
= 0xffffffffffffffffull
>> -shift
;
5621 mask
= 0xffffffffffffffffull
<< shift
;
5624 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5625 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5627 neon_store_reg64(cpu_V0
, rd
+ pass
);
5628 } else { /* size < 3 */
5629 /* Operands in T0 and T1. */
5630 tmp
= neon_load_reg(rm
, pass
);
5631 tmp2
= tcg_temp_new_i32();
5632 tcg_gen_movi_i32(tmp2
, imm
);
5636 GEN_NEON_INTEGER_OP(shl
);
5640 GEN_NEON_INTEGER_OP(rshl
);
5643 case 5: /* VSHL, VSLI */
5645 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5646 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5647 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5651 case 6: /* VQSHLU */
5654 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5658 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5662 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5670 GEN_NEON_INTEGER_OP_ENV(qshl
);
5673 tcg_temp_free_i32(tmp2
);
5675 if (op
== 1 || op
== 3) {
5677 tmp2
= neon_load_reg(rd
, pass
);
5678 gen_neon_add(size
, tmp
, tmp2
);
5679 tcg_temp_free_i32(tmp2
);
5680 } else if (op
== 4 || (op
== 5 && u
)) {
5685 mask
= 0xff >> -shift
;
5687 mask
= (uint8_t)(0xff << shift
);
5693 mask
= 0xffff >> -shift
;
5695 mask
= (uint16_t)(0xffff << shift
);
5699 if (shift
< -31 || shift
> 31) {
5703 mask
= 0xffffffffu
>> -shift
;
5705 mask
= 0xffffffffu
<< shift
;
5711 tmp2
= neon_load_reg(rd
, pass
);
5712 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5713 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5714 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5715 tcg_temp_free_i32(tmp2
);
5717 neon_store_reg(rd
, pass
, tmp
);
5720 } else if (op
< 10) {
5721 /* Shift by immediate and narrow:
5722 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5723 int input_unsigned
= (op
== 8) ? !u
: u
;
5727 shift
= shift
- (1 << (size
+ 3));
5730 tmp64
= tcg_const_i64(shift
);
5731 neon_load_reg64(cpu_V0
, rm
);
5732 neon_load_reg64(cpu_V1
, rm
+ 1);
5733 for (pass
= 0; pass
< 2; pass
++) {
5741 if (input_unsigned
) {
5742 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5744 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5747 if (input_unsigned
) {
5748 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5750 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5753 tmp
= tcg_temp_new_i32();
5754 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5755 neon_store_reg(rd
, pass
, tmp
);
5757 tcg_temp_free_i64(tmp64
);
5760 imm
= (uint16_t)shift
;
5764 imm
= (uint32_t)shift
;
5766 tmp2
= tcg_const_i32(imm
);
5767 tmp4
= neon_load_reg(rm
+ 1, 0);
5768 tmp5
= neon_load_reg(rm
+ 1, 1);
5769 for (pass
= 0; pass
< 2; pass
++) {
5771 tmp
= neon_load_reg(rm
, 0);
5775 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5778 tmp3
= neon_load_reg(rm
, 1);
5782 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5784 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5785 tcg_temp_free_i32(tmp
);
5786 tcg_temp_free_i32(tmp3
);
5787 tmp
= tcg_temp_new_i32();
5788 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5789 neon_store_reg(rd
, pass
, tmp
);
5791 tcg_temp_free_i32(tmp2
);
5793 } else if (op
== 10) {
5795 if (q
|| (rd
& 1)) {
5798 tmp
= neon_load_reg(rm
, 0);
5799 tmp2
= neon_load_reg(rm
, 1);
5800 for (pass
= 0; pass
< 2; pass
++) {
5804 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5807 /* The shift is less than the width of the source
5808 type, so we can just shift the whole register. */
5809 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5810 /* Widen the result of shift: we need to clear
5811 * the potential overflow bits resulting from
5812 * left bits of the narrow input appearing as
5813 * right bits of left the neighbour narrow
5815 if (size
< 2 || !u
) {
5818 imm
= (0xffu
>> (8 - shift
));
5820 } else if (size
== 1) {
5821 imm
= 0xffff >> (16 - shift
);
5824 imm
= 0xffffffff >> (32 - shift
);
5827 imm64
= imm
| (((uint64_t)imm
) << 32);
5831 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5834 neon_store_reg64(cpu_V0
, rd
+ pass
);
5836 } else if (op
>= 14) {
5837 /* VCVT fixed-point. */
5838 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5841 /* We have already masked out the must-be-1 top bit of imm6,
5842 * hence this 32-shift where the ARM ARM has 64-imm6.
5845 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5846 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5849 gen_vfp_ulto(0, shift
, 1);
5851 gen_vfp_slto(0, shift
, 1);
5854 gen_vfp_toul(0, shift
, 1);
5856 gen_vfp_tosl(0, shift
, 1);
5858 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5863 } else { /* (insn & 0x00380080) == 0 */
5865 if (q
&& (rd
& 1)) {
5869 op
= (insn
>> 8) & 0xf;
5870 /* One register and immediate. */
5871 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5872 invert
= (insn
& (1 << 5)) != 0;
5873 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5874 * We choose to not special-case this and will behave as if a
5875 * valid constant encoding of 0 had been given.
5894 imm
= (imm
<< 8) | (imm
<< 24);
5897 imm
= (imm
<< 8) | 0xff;
5900 imm
= (imm
<< 16) | 0xffff;
5903 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5911 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5912 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5918 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5919 if (op
& 1 && op
< 12) {
5920 tmp
= neon_load_reg(rd
, pass
);
5922 /* The immediate value has already been inverted, so
5924 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5926 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5930 tmp
= tcg_temp_new_i32();
5931 if (op
== 14 && invert
) {
5935 for (n
= 0; n
< 4; n
++) {
5936 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5937 val
|= 0xff << (n
* 8);
5939 tcg_gen_movi_i32(tmp
, val
);
5941 tcg_gen_movi_i32(tmp
, imm
);
5944 neon_store_reg(rd
, pass
, tmp
);
5947 } else { /* (insn & 0x00800010 == 0x00800000) */
5949 op
= (insn
>> 8) & 0xf;
5950 if ((insn
& (1 << 6)) == 0) {
5951 /* Three registers of different lengths. */
5955 /* undefreq: bit 0 : UNDEF if size == 0
5956 * bit 1 : UNDEF if size == 1
5957 * bit 2 : UNDEF if size == 2
5958 * bit 3 : UNDEF if U == 1
5959 * Note that [2:0] set implies 'always UNDEF'
5962 /* prewiden, src1_wide, src2_wide, undefreq */
5963 static const int neon_3reg_wide
[16][4] = {
5964 {1, 0, 0, 0}, /* VADDL */
5965 {1, 1, 0, 0}, /* VADDW */
5966 {1, 0, 0, 0}, /* VSUBL */
5967 {1, 1, 0, 0}, /* VSUBW */
5968 {0, 1, 1, 0}, /* VADDHN */
5969 {0, 0, 0, 0}, /* VABAL */
5970 {0, 1, 1, 0}, /* VSUBHN */
5971 {0, 0, 0, 0}, /* VABDL */
5972 {0, 0, 0, 0}, /* VMLAL */
5973 {0, 0, 0, 9}, /* VQDMLAL */
5974 {0, 0, 0, 0}, /* VMLSL */
5975 {0, 0, 0, 9}, /* VQDMLSL */
5976 {0, 0, 0, 0}, /* Integer VMULL */
5977 {0, 0, 0, 1}, /* VQDMULL */
5978 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5979 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5982 prewiden
= neon_3reg_wide
[op
][0];
5983 src1_wide
= neon_3reg_wide
[op
][1];
5984 src2_wide
= neon_3reg_wide
[op
][2];
5985 undefreq
= neon_3reg_wide
[op
][3];
5987 if ((undefreq
& (1 << size
)) ||
5988 ((undefreq
& 8) && u
)) {
5991 if ((src1_wide
&& (rn
& 1)) ||
5992 (src2_wide
&& (rm
& 1)) ||
5993 (!src2_wide
&& (rd
& 1))) {
5997 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5998 * outside the loop below as it only performs a single pass.
6000 if (op
== 14 && size
== 2) {
6001 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6003 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6006 tcg_rn
= tcg_temp_new_i64();
6007 tcg_rm
= tcg_temp_new_i64();
6008 tcg_rd
= tcg_temp_new_i64();
6009 neon_load_reg64(tcg_rn
, rn
);
6010 neon_load_reg64(tcg_rm
, rm
);
6011 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6012 neon_store_reg64(tcg_rd
, rd
);
6013 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6014 neon_store_reg64(tcg_rd
, rd
+ 1);
6015 tcg_temp_free_i64(tcg_rn
);
6016 tcg_temp_free_i64(tcg_rm
);
6017 tcg_temp_free_i64(tcg_rd
);
6021 /* Avoid overlapping operands. Wide source operands are
6022 always aligned so will never overlap with wide
6023 destinations in problematic ways. */
6024 if (rd
== rm
&& !src2_wide
) {
6025 tmp
= neon_load_reg(rm
, 1);
6026 neon_store_scratch(2, tmp
);
6027 } else if (rd
== rn
&& !src1_wide
) {
6028 tmp
= neon_load_reg(rn
, 1);
6029 neon_store_scratch(2, tmp
);
6031 TCGV_UNUSED_I32(tmp3
);
6032 for (pass
= 0; pass
< 2; pass
++) {
6034 neon_load_reg64(cpu_V0
, rn
+ pass
);
6035 TCGV_UNUSED_I32(tmp
);
6037 if (pass
== 1 && rd
== rn
) {
6038 tmp
= neon_load_scratch(2);
6040 tmp
= neon_load_reg(rn
, pass
);
6043 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6047 neon_load_reg64(cpu_V1
, rm
+ pass
);
6048 TCGV_UNUSED_I32(tmp2
);
6050 if (pass
== 1 && rd
== rm
) {
6051 tmp2
= neon_load_scratch(2);
6053 tmp2
= neon_load_reg(rm
, pass
);
6056 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6060 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6061 gen_neon_addl(size
);
6063 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6064 gen_neon_subl(size
);
6066 case 5: case 7: /* VABAL, VABDL */
6067 switch ((size
<< 1) | u
) {
6069 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6072 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6075 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6078 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6081 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6084 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6088 tcg_temp_free_i32(tmp2
);
6089 tcg_temp_free_i32(tmp
);
6091 case 8: case 9: case 10: case 11: case 12: case 13:
6092 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6093 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6095 case 14: /* Polynomial VMULL */
6096 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6097 tcg_temp_free_i32(tmp2
);
6098 tcg_temp_free_i32(tmp
);
6100 default: /* 15 is RESERVED: caught earlier */
6105 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6106 neon_store_reg64(cpu_V0
, rd
+ pass
);
6107 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6109 neon_load_reg64(cpu_V1
, rd
+ pass
);
6111 case 10: /* VMLSL */
6112 gen_neon_negl(cpu_V0
, size
);
6114 case 5: case 8: /* VABAL, VMLAL */
6115 gen_neon_addl(size
);
6117 case 9: case 11: /* VQDMLAL, VQDMLSL */
6118 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6120 gen_neon_negl(cpu_V0
, size
);
6122 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6127 neon_store_reg64(cpu_V0
, rd
+ pass
);
6128 } else if (op
== 4 || op
== 6) {
6129 /* Narrowing operation. */
6130 tmp
= tcg_temp_new_i32();
6134 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6137 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6140 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6141 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6148 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6151 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6154 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6155 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6156 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6164 neon_store_reg(rd
, 0, tmp3
);
6165 neon_store_reg(rd
, 1, tmp
);
6168 /* Write back the result. */
6169 neon_store_reg64(cpu_V0
, rd
+ pass
);
6173 /* Two registers and a scalar. NB that for ops of this form
6174 * the ARM ARM labels bit 24 as Q, but it is in our variable
6181 case 1: /* Float VMLA scalar */
6182 case 5: /* Floating point VMLS scalar */
6183 case 9: /* Floating point VMUL scalar */
6188 case 0: /* Integer VMLA scalar */
6189 case 4: /* Integer VMLS scalar */
6190 case 8: /* Integer VMUL scalar */
6191 case 12: /* VQDMULH scalar */
6192 case 13: /* VQRDMULH scalar */
6193 if (u
&& ((rd
| rn
) & 1)) {
6196 tmp
= neon_get_scalar(size
, rm
);
6197 neon_store_scratch(0, tmp
);
6198 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6199 tmp
= neon_load_scratch(0);
6200 tmp2
= neon_load_reg(rn
, pass
);
6203 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6205 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6207 } else if (op
== 13) {
6209 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6211 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6213 } else if (op
& 1) {
6214 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6215 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6216 tcg_temp_free_ptr(fpstatus
);
6219 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6220 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6221 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6225 tcg_temp_free_i32(tmp2
);
6228 tmp2
= neon_load_reg(rd
, pass
);
6231 gen_neon_add(size
, tmp
, tmp2
);
6235 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6236 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6237 tcg_temp_free_ptr(fpstatus
);
6241 gen_neon_rsb(size
, tmp
, tmp2
);
6245 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6246 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6247 tcg_temp_free_ptr(fpstatus
);
6253 tcg_temp_free_i32(tmp2
);
6255 neon_store_reg(rd
, pass
, tmp
);
6258 case 3: /* VQDMLAL scalar */
6259 case 7: /* VQDMLSL scalar */
6260 case 11: /* VQDMULL scalar */
6265 case 2: /* VMLAL sclar */
6266 case 6: /* VMLSL scalar */
6267 case 10: /* VMULL scalar */
6271 tmp2
= neon_get_scalar(size
, rm
);
6272 /* We need a copy of tmp2 because gen_neon_mull
6273 * deletes it during pass 0. */
6274 tmp4
= tcg_temp_new_i32();
6275 tcg_gen_mov_i32(tmp4
, tmp2
);
6276 tmp3
= neon_load_reg(rn
, 1);
6278 for (pass
= 0; pass
< 2; pass
++) {
6280 tmp
= neon_load_reg(rn
, 0);
6285 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6287 neon_load_reg64(cpu_V1
, rd
+ pass
);
6291 gen_neon_negl(cpu_V0
, size
);
6294 gen_neon_addl(size
);
6297 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6299 gen_neon_negl(cpu_V0
, size
);
6301 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6307 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6312 neon_store_reg64(cpu_V0
, rd
+ pass
);
6317 default: /* 14 and 15 are RESERVED */
6321 } else { /* size == 3 */
6324 imm
= (insn
>> 8) & 0xf;
6329 if (q
&& ((rd
| rn
| rm
) & 1)) {
6334 neon_load_reg64(cpu_V0
, rn
);
6336 neon_load_reg64(cpu_V1
, rn
+ 1);
6338 } else if (imm
== 8) {
6339 neon_load_reg64(cpu_V0
, rn
+ 1);
6341 neon_load_reg64(cpu_V1
, rm
);
6344 tmp64
= tcg_temp_new_i64();
6346 neon_load_reg64(cpu_V0
, rn
);
6347 neon_load_reg64(tmp64
, rn
+ 1);
6349 neon_load_reg64(cpu_V0
, rn
+ 1);
6350 neon_load_reg64(tmp64
, rm
);
6352 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6353 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6354 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6356 neon_load_reg64(cpu_V1
, rm
);
6358 neon_load_reg64(cpu_V1
, rm
+ 1);
6361 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6362 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6363 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6364 tcg_temp_free_i64(tmp64
);
6367 neon_load_reg64(cpu_V0
, rn
);
6368 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6369 neon_load_reg64(cpu_V1
, rm
);
6370 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6371 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6373 neon_store_reg64(cpu_V0
, rd
);
6375 neon_store_reg64(cpu_V1
, rd
+ 1);
6377 } else if ((insn
& (1 << 11)) == 0) {
6378 /* Two register misc. */
6379 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6380 size
= (insn
>> 18) & 3;
6381 /* UNDEF for unknown op values and bad op-size combinations */
6382 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6385 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6386 q
&& ((rm
| rd
) & 1)) {
6390 case NEON_2RM_VREV64
:
6391 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6392 tmp
= neon_load_reg(rm
, pass
* 2);
6393 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6395 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6396 case 1: gen_swap_half(tmp
); break;
6397 case 2: /* no-op */ break;
6400 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6402 neon_store_reg(rd
, pass
* 2, tmp2
);
6405 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6406 case 1: gen_swap_half(tmp2
); break;
6409 neon_store_reg(rd
, pass
* 2, tmp2
);
6413 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6414 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6415 for (pass
= 0; pass
< q
+ 1; pass
++) {
6416 tmp
= neon_load_reg(rm
, pass
* 2);
6417 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6418 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6419 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6421 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6422 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6423 case 2: tcg_gen_add_i64(CPU_V001
); break;
6426 if (op
>= NEON_2RM_VPADAL
) {
6428 neon_load_reg64(cpu_V1
, rd
+ pass
);
6429 gen_neon_addl(size
);
6431 neon_store_reg64(cpu_V0
, rd
+ pass
);
6437 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6438 tmp
= neon_load_reg(rm
, n
);
6439 tmp2
= neon_load_reg(rd
, n
+ 1);
6440 neon_store_reg(rm
, n
, tmp2
);
6441 neon_store_reg(rd
, n
+ 1, tmp
);
6448 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6453 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6457 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6458 /* also VQMOVUN; op field and mnemonics don't line up */
6462 TCGV_UNUSED_I32(tmp2
);
6463 for (pass
= 0; pass
< 2; pass
++) {
6464 neon_load_reg64(cpu_V0
, rm
+ pass
);
6465 tmp
= tcg_temp_new_i32();
6466 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6471 neon_store_reg(rd
, 0, tmp2
);
6472 neon_store_reg(rd
, 1, tmp
);
6476 case NEON_2RM_VSHLL
:
6477 if (q
|| (rd
& 1)) {
6480 tmp
= neon_load_reg(rm
, 0);
6481 tmp2
= neon_load_reg(rm
, 1);
6482 for (pass
= 0; pass
< 2; pass
++) {
6485 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6486 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6487 neon_store_reg64(cpu_V0
, rd
+ pass
);
6490 case NEON_2RM_VCVT_F16_F32
:
6491 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6495 tmp
= tcg_temp_new_i32();
6496 tmp2
= tcg_temp_new_i32();
6497 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6498 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6499 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6500 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6501 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6502 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6503 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6504 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6505 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6506 neon_store_reg(rd
, 0, tmp2
);
6507 tmp2
= tcg_temp_new_i32();
6508 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6509 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6510 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6511 neon_store_reg(rd
, 1, tmp2
);
6512 tcg_temp_free_i32(tmp
);
6514 case NEON_2RM_VCVT_F32_F16
:
6515 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6519 tmp3
= tcg_temp_new_i32();
6520 tmp
= neon_load_reg(rm
, 0);
6521 tmp2
= neon_load_reg(rm
, 1);
6522 tcg_gen_ext16u_i32(tmp3
, tmp
);
6523 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6524 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6525 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6526 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6527 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6528 tcg_temp_free_i32(tmp
);
6529 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6530 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6531 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6532 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6533 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6534 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6535 tcg_temp_free_i32(tmp2
);
6536 tcg_temp_free_i32(tmp3
);
6538 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6539 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6540 || ((rm
| rd
) & 1)) {
6543 tmp
= tcg_const_i32(rd
);
6544 tmp2
= tcg_const_i32(rm
);
6546 /* Bit 6 is the lowest opcode bit; it distinguishes between
6547 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6549 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6551 if (op
== NEON_2RM_AESE
) {
6552 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6554 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6556 tcg_temp_free_i32(tmp
);
6557 tcg_temp_free_i32(tmp2
);
6558 tcg_temp_free_i32(tmp3
);
6560 case NEON_2RM_SHA1H
:
6561 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6562 || ((rm
| rd
) & 1)) {
6565 tmp
= tcg_const_i32(rd
);
6566 tmp2
= tcg_const_i32(rm
);
6568 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6570 tcg_temp_free_i32(tmp
);
6571 tcg_temp_free_i32(tmp2
);
6573 case NEON_2RM_SHA1SU1
:
6574 if ((rm
| rd
) & 1) {
6577 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6579 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6582 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6585 tmp
= tcg_const_i32(rd
);
6586 tmp2
= tcg_const_i32(rm
);
6588 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6590 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6592 tcg_temp_free_i32(tmp
);
6593 tcg_temp_free_i32(tmp2
);
6597 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6598 if (neon_2rm_is_float_op(op
)) {
6599 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6600 neon_reg_offset(rm
, pass
));
6601 TCGV_UNUSED_I32(tmp
);
6603 tmp
= neon_load_reg(rm
, pass
);
6606 case NEON_2RM_VREV32
:
6608 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6609 case 1: gen_swap_half(tmp
); break;
6613 case NEON_2RM_VREV16
:
6618 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6619 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6620 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6626 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6627 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6628 case 2: gen_helper_clz(tmp
, tmp
); break;
6633 gen_helper_neon_cnt_u8(tmp
, tmp
);
6636 tcg_gen_not_i32(tmp
, tmp
);
6638 case NEON_2RM_VQABS
:
6641 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6644 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6647 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6652 case NEON_2RM_VQNEG
:
6655 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6658 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6661 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6666 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6667 tmp2
= tcg_const_i32(0);
6669 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6670 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6671 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6674 tcg_temp_free_i32(tmp2
);
6675 if (op
== NEON_2RM_VCLE0
) {
6676 tcg_gen_not_i32(tmp
, tmp
);
6679 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6680 tmp2
= tcg_const_i32(0);
6682 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6683 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6684 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6687 tcg_temp_free_i32(tmp2
);
6688 if (op
== NEON_2RM_VCLT0
) {
6689 tcg_gen_not_i32(tmp
, tmp
);
6692 case NEON_2RM_VCEQ0
:
6693 tmp2
= tcg_const_i32(0);
6695 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6696 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6697 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6700 tcg_temp_free_i32(tmp2
);
6704 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6705 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6706 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6711 tmp2
= tcg_const_i32(0);
6712 gen_neon_rsb(size
, tmp
, tmp2
);
6713 tcg_temp_free_i32(tmp2
);
6715 case NEON_2RM_VCGT0_F
:
6717 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6718 tmp2
= tcg_const_i32(0);
6719 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6720 tcg_temp_free_i32(tmp2
);
6721 tcg_temp_free_ptr(fpstatus
);
6724 case NEON_2RM_VCGE0_F
:
6726 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6727 tmp2
= tcg_const_i32(0);
6728 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6729 tcg_temp_free_i32(tmp2
);
6730 tcg_temp_free_ptr(fpstatus
);
6733 case NEON_2RM_VCEQ0_F
:
6735 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6736 tmp2
= tcg_const_i32(0);
6737 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6738 tcg_temp_free_i32(tmp2
);
6739 tcg_temp_free_ptr(fpstatus
);
6742 case NEON_2RM_VCLE0_F
:
6744 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6745 tmp2
= tcg_const_i32(0);
6746 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6747 tcg_temp_free_i32(tmp2
);
6748 tcg_temp_free_ptr(fpstatus
);
6751 case NEON_2RM_VCLT0_F
:
6753 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6754 tmp2
= tcg_const_i32(0);
6755 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6756 tcg_temp_free_i32(tmp2
);
6757 tcg_temp_free_ptr(fpstatus
);
6760 case NEON_2RM_VABS_F
:
6763 case NEON_2RM_VNEG_F
:
6767 tmp2
= neon_load_reg(rd
, pass
);
6768 neon_store_reg(rm
, pass
, tmp2
);
6771 tmp2
= neon_load_reg(rd
, pass
);
6773 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6774 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6777 neon_store_reg(rm
, pass
, tmp2
);
6779 case NEON_2RM_VRINTN
:
6780 case NEON_2RM_VRINTA
:
6781 case NEON_2RM_VRINTM
:
6782 case NEON_2RM_VRINTP
:
6783 case NEON_2RM_VRINTZ
:
6786 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6789 if (op
== NEON_2RM_VRINTZ
) {
6790 rmode
= FPROUNDING_ZERO
;
6792 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6795 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6796 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6798 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6799 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6801 tcg_temp_free_ptr(fpstatus
);
6802 tcg_temp_free_i32(tcg_rmode
);
6805 case NEON_2RM_VRINTX
:
6807 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6808 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6809 tcg_temp_free_ptr(fpstatus
);
6812 case NEON_2RM_VCVTAU
:
6813 case NEON_2RM_VCVTAS
:
6814 case NEON_2RM_VCVTNU
:
6815 case NEON_2RM_VCVTNS
:
6816 case NEON_2RM_VCVTPU
:
6817 case NEON_2RM_VCVTPS
:
6818 case NEON_2RM_VCVTMU
:
6819 case NEON_2RM_VCVTMS
:
6821 bool is_signed
= !extract32(insn
, 7, 1);
6822 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6823 TCGv_i32 tcg_rmode
, tcg_shift
;
6824 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6826 tcg_shift
= tcg_const_i32(0);
6827 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6828 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6832 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6835 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6839 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6841 tcg_temp_free_i32(tcg_rmode
);
6842 tcg_temp_free_i32(tcg_shift
);
6843 tcg_temp_free_ptr(fpst
);
6846 case NEON_2RM_VRECPE
:
6848 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6849 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6850 tcg_temp_free_ptr(fpstatus
);
6853 case NEON_2RM_VRSQRTE
:
6855 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6856 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6857 tcg_temp_free_ptr(fpstatus
);
6860 case NEON_2RM_VRECPE_F
:
6862 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6863 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6864 tcg_temp_free_ptr(fpstatus
);
6867 case NEON_2RM_VRSQRTE_F
:
6869 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6870 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6871 tcg_temp_free_ptr(fpstatus
);
6874 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6877 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6880 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6881 gen_vfp_tosiz(0, 1);
6883 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6884 gen_vfp_touiz(0, 1);
6887 /* Reserved op values were caught by the
6888 * neon_2rm_sizes[] check earlier.
6892 if (neon_2rm_is_float_op(op
)) {
6893 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6894 neon_reg_offset(rd
, pass
));
6896 neon_store_reg(rd
, pass
, tmp
);
6901 } else if ((insn
& (1 << 10)) == 0) {
6903 int n
= ((insn
>> 8) & 3) + 1;
6904 if ((rn
+ n
) > 32) {
6905 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6906 * helper function running off the end of the register file.
6911 if (insn
& (1 << 6)) {
6912 tmp
= neon_load_reg(rd
, 0);
6914 tmp
= tcg_temp_new_i32();
6915 tcg_gen_movi_i32(tmp
, 0);
6917 tmp2
= neon_load_reg(rm
, 0);
6918 tmp4
= tcg_const_i32(rn
);
6919 tmp5
= tcg_const_i32(n
);
6920 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6921 tcg_temp_free_i32(tmp
);
6922 if (insn
& (1 << 6)) {
6923 tmp
= neon_load_reg(rd
, 1);
6925 tmp
= tcg_temp_new_i32();
6926 tcg_gen_movi_i32(tmp
, 0);
6928 tmp3
= neon_load_reg(rm
, 1);
6929 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6930 tcg_temp_free_i32(tmp5
);
6931 tcg_temp_free_i32(tmp4
);
6932 neon_store_reg(rd
, 0, tmp2
);
6933 neon_store_reg(rd
, 1, tmp3
);
6934 tcg_temp_free_i32(tmp
);
6935 } else if ((insn
& 0x380) == 0) {
6937 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6940 if (insn
& (1 << 19)) {
6941 tmp
= neon_load_reg(rm
, 1);
6943 tmp
= neon_load_reg(rm
, 0);
6945 if (insn
& (1 << 16)) {
6946 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6947 } else if (insn
& (1 << 17)) {
6948 if ((insn
>> 18) & 1)
6949 gen_neon_dup_high16(tmp
);
6951 gen_neon_dup_low16(tmp
);
6953 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6954 tmp2
= tcg_temp_new_i32();
6955 tcg_gen_mov_i32(tmp2
, tmp
);
6956 neon_store_reg(rd
, pass
, tmp2
);
6958 tcg_temp_free_i32(tmp
);
6967 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6969 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6970 const ARMCPRegInfo
*ri
;
6972 cpnum
= (insn
>> 8) & 0xf;
6973 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6974 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6977 /* First check for coprocessor space used for actual instructions */
6981 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6982 return disas_iwmmxt_insn(env
, s
, insn
);
6983 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6984 return disas_dsp_insn(env
, s
, insn
);
6991 /* Otherwise treat as a generic register access */
6992 is64
= (insn
& (1 << 25)) == 0;
6993 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7001 opc1
= (insn
>> 4) & 0xf;
7003 rt2
= (insn
>> 16) & 0xf;
7005 crn
= (insn
>> 16) & 0xf;
7006 opc1
= (insn
>> 21) & 7;
7007 opc2
= (insn
>> 5) & 7;
7010 isread
= (insn
>> 20) & 1;
7011 rt
= (insn
>> 12) & 0xf;
7013 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7014 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7016 /* Check access permissions */
7017 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7022 /* Emit code to perform further access permissions checks at
7023 * runtime; this may result in an exception.
7029 /* Note that since we are an implementation which takes an
7030 * exception on a trapped conditional instruction only if the
7031 * instruction passes its condition code check, we can take
7032 * advantage of the clause in the ARM ARM that allows us to set
7033 * the COND field in the instruction to 0xE in all cases.
7034 * We could fish the actual condition out of the insn (ARM)
7035 * or the condexec bits (Thumb) but it isn't necessary.
7040 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7043 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7044 rt
, isread
, s
->thumb
);
7049 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7052 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7053 rt
, isread
, s
->thumb
);
7057 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7058 * so this can only happen if this is an ARMv7 or earlier CPU,
7059 * in which case the syndrome information won't actually be
7062 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7063 syndrome
= syn_uncategorized();
7067 gen_set_pc_im(s
, s
->pc
);
7068 tmpptr
= tcg_const_ptr(ri
);
7069 tcg_syn
= tcg_const_i32(syndrome
);
7070 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7071 tcg_temp_free_ptr(tmpptr
);
7072 tcg_temp_free_i32(tcg_syn
);
7075 /* Handle special cases first */
7076 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7083 gen_set_pc_im(s
, s
->pc
);
7084 s
->is_jmp
= DISAS_WFI
;
7090 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7099 if (ri
->type
& ARM_CP_CONST
) {
7100 tmp64
= tcg_const_i64(ri
->resetvalue
);
7101 } else if (ri
->readfn
) {
7103 tmp64
= tcg_temp_new_i64();
7104 tmpptr
= tcg_const_ptr(ri
);
7105 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7106 tcg_temp_free_ptr(tmpptr
);
7108 tmp64
= tcg_temp_new_i64();
7109 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7111 tmp
= tcg_temp_new_i32();
7112 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7113 store_reg(s
, rt
, tmp
);
7114 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7115 tmp
= tcg_temp_new_i32();
7116 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7117 tcg_temp_free_i64(tmp64
);
7118 store_reg(s
, rt2
, tmp
);
7121 if (ri
->type
& ARM_CP_CONST
) {
7122 tmp
= tcg_const_i32(ri
->resetvalue
);
7123 } else if (ri
->readfn
) {
7125 tmp
= tcg_temp_new_i32();
7126 tmpptr
= tcg_const_ptr(ri
);
7127 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7128 tcg_temp_free_ptr(tmpptr
);
7130 tmp
= load_cpu_offset(ri
->fieldoffset
);
7133 /* Destination register of r15 for 32 bit loads sets
7134 * the condition codes from the high 4 bits of the value
7137 tcg_temp_free_i32(tmp
);
7139 store_reg(s
, rt
, tmp
);
7144 if (ri
->type
& ARM_CP_CONST
) {
7145 /* If not forbidden by access permissions, treat as WI */
7150 TCGv_i32 tmplo
, tmphi
;
7151 TCGv_i64 tmp64
= tcg_temp_new_i64();
7152 tmplo
= load_reg(s
, rt
);
7153 tmphi
= load_reg(s
, rt2
);
7154 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7155 tcg_temp_free_i32(tmplo
);
7156 tcg_temp_free_i32(tmphi
);
7158 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7159 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7160 tcg_temp_free_ptr(tmpptr
);
7162 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7164 tcg_temp_free_i64(tmp64
);
7169 tmp
= load_reg(s
, rt
);
7170 tmpptr
= tcg_const_ptr(ri
);
7171 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7172 tcg_temp_free_ptr(tmpptr
);
7173 tcg_temp_free_i32(tmp
);
7175 TCGv_i32 tmp
= load_reg(s
, rt
);
7176 store_cpu_offset(tmp
, ri
->fieldoffset
);
7181 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7182 /* I/O operations must end the TB here (whether read or write) */
7185 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7186 /* We default to ending the TB on a coprocessor register write,
7187 * but allow this to be suppressed by the register definition
7188 * (usually only necessary to work around guest bugs).
7196 /* Unknown register; this might be a guest error or a QEMU
7197 * unimplemented feature.
7200 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7201 "64 bit system register cp:%d opc1: %d crm:%d\n",
7202 isread
? "read" : "write", cpnum
, opc1
, crm
);
7204 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7205 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7206 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7213 /* Store a 64-bit value to a register pair. Clobbers val. */
7214 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7217 tmp
= tcg_temp_new_i32();
7218 tcg_gen_trunc_i64_i32(tmp
, val
);
7219 store_reg(s
, rlow
, tmp
);
7220 tmp
= tcg_temp_new_i32();
7221 tcg_gen_shri_i64(val
, val
, 32);
7222 tcg_gen_trunc_i64_i32(tmp
, val
);
7223 store_reg(s
, rhigh
, tmp
);
7226 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7227 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7232 /* Load value and extend to 64 bits. */
7233 tmp
= tcg_temp_new_i64();
7234 tmp2
= load_reg(s
, rlow
);
7235 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7236 tcg_temp_free_i32(tmp2
);
7237 tcg_gen_add_i64(val
, val
, tmp
);
7238 tcg_temp_free_i64(tmp
);
7241 /* load and add a 64-bit value from a register pair. */
7242 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7248 /* Load 64-bit value rd:rn. */
7249 tmpl
= load_reg(s
, rlow
);
7250 tmph
= load_reg(s
, rhigh
);
7251 tmp
= tcg_temp_new_i64();
7252 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7253 tcg_temp_free_i32(tmpl
);
7254 tcg_temp_free_i32(tmph
);
7255 tcg_gen_add_i64(val
, val
, tmp
);
7256 tcg_temp_free_i64(tmp
);
7259 /* Set N and Z flags from hi|lo. */
7260 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7262 tcg_gen_mov_i32(cpu_NF
, hi
);
7263 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7266 /* Load/Store exclusive instructions are implemented by remembering
7267 the value/address loaded, and seeing if these are the same
7268 when the store is performed. This should be sufficient to implement
7269 the architecturally mandated semantics, and avoids having to monitor
7272 In system emulation mode only one CPU will be running at once, so
7273 this sequence is effectively atomic. In user emulation mode we
7274 throw an exception and handle the atomic operation elsewhere. */
7275 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7276 TCGv_i32 addr
, int size
)
7278 TCGv_i32 tmp
= tcg_temp_new_i32();
7282 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7285 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7289 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7296 TCGv_i32 tmp2
= tcg_temp_new_i32();
7297 TCGv_i32 tmp3
= tcg_temp_new_i32();
7299 tcg_gen_addi_i32(tmp2
, addr
, 4);
7300 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7301 tcg_temp_free_i32(tmp2
);
7302 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7303 store_reg(s
, rt2
, tmp3
);
7305 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7308 store_reg(s
, rt
, tmp
);
7309 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7312 static void gen_clrex(DisasContext
*s
)
7314 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7317 #ifdef CONFIG_USER_ONLY
7318 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7319 TCGv_i32 addr
, int size
)
7321 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7322 tcg_gen_movi_i32(cpu_exclusive_info
,
7323 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7324 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7327 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7328 TCGv_i32 addr
, int size
)
7331 TCGv_i64 val64
, extaddr
;
7335 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7341 fail_label
= gen_new_label();
7342 done_label
= gen_new_label();
7343 extaddr
= tcg_temp_new_i64();
7344 tcg_gen_extu_i32_i64(extaddr
, addr
);
7345 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7346 tcg_temp_free_i64(extaddr
);
7348 tmp
= tcg_temp_new_i32();
7351 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7354 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7358 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7364 val64
= tcg_temp_new_i64();
7366 TCGv_i32 tmp2
= tcg_temp_new_i32();
7367 TCGv_i32 tmp3
= tcg_temp_new_i32();
7368 tcg_gen_addi_i32(tmp2
, addr
, 4);
7369 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7370 tcg_temp_free_i32(tmp2
);
7371 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7372 tcg_temp_free_i32(tmp3
);
7374 tcg_gen_extu_i32_i64(val64
, tmp
);
7376 tcg_temp_free_i32(tmp
);
7378 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7379 tcg_temp_free_i64(val64
);
7381 tmp
= load_reg(s
, rt
);
7384 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7387 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7391 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7396 tcg_temp_free_i32(tmp
);
7398 tcg_gen_addi_i32(addr
, addr
, 4);
7399 tmp
= load_reg(s
, rt2
);
7400 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7401 tcg_temp_free_i32(tmp
);
7403 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7404 tcg_gen_br(done_label
);
7405 gen_set_label(fail_label
);
7406 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7407 gen_set_label(done_label
);
7408 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7415 * @mode: mode field from insn (which stack to store to)
7416 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7417 * @writeback: true if writeback bit set
7419 * Generate code for the SRS (Store Return State) insn.
7421 static void gen_srs(DisasContext
*s
,
7422 uint32_t mode
, uint32_t amode
, bool writeback
)
7425 TCGv_i32 addr
= tcg_temp_new_i32();
7426 TCGv_i32 tmp
= tcg_const_i32(mode
);
7427 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7428 tcg_temp_free_i32(tmp
);
7445 tcg_gen_addi_i32(addr
, addr
, offset
);
7446 tmp
= load_reg(s
, 14);
7447 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7448 tcg_temp_free_i32(tmp
);
7449 tmp
= load_cpu_field(spsr
);
7450 tcg_gen_addi_i32(addr
, addr
, 4);
7451 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7452 tcg_temp_free_i32(tmp
);
7470 tcg_gen_addi_i32(addr
, addr
, offset
);
7471 tmp
= tcg_const_i32(mode
);
7472 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7473 tcg_temp_free_i32(tmp
);
7475 tcg_temp_free_i32(addr
);
7478 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7480 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7487 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7490 /* M variants do not implement ARM mode. */
7495 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7496 * choose to UNDEF. In ARMv5 and above the space is used
7497 * for miscellaneous unconditional instructions.
7501 /* Unconditional instructions. */
7502 if (((insn
>> 25) & 7) == 1) {
7503 /* NEON Data processing. */
7504 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7507 if (disas_neon_data_insn(env
, s
, insn
))
7511 if ((insn
& 0x0f100000) == 0x04000000) {
7512 /* NEON load/store. */
7513 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7516 if (disas_neon_ls_insn(env
, s
, insn
))
7520 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7522 if (disas_vfp_insn(env
, s
, insn
)) {
7527 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7528 ((insn
& 0x0f30f010) == 0x0710f000)) {
7529 if ((insn
& (1 << 22)) == 0) {
7531 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7535 /* Otherwise PLD; v5TE+ */
7539 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7540 ((insn
& 0x0f70f010) == 0x0650f000)) {
7542 return; /* PLI; V7 */
7544 if (((insn
& 0x0f700000) == 0x04100000) ||
7545 ((insn
& 0x0f700010) == 0x06100000)) {
7546 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7549 return; /* v7MP: Unallocated memory hint: must NOP */
7552 if ((insn
& 0x0ffffdff) == 0x01010000) {
7555 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7556 /* Dynamic endianness switching not implemented. */
7557 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7561 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7562 switch ((insn
>> 4) & 0xf) {
7571 /* We don't emulate caches so these are a no-op. */
7576 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7582 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7584 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7590 rn
= (insn
>> 16) & 0xf;
7591 addr
= load_reg(s
, rn
);
7592 i
= (insn
>> 23) & 3;
7594 case 0: offset
= -4; break; /* DA */
7595 case 1: offset
= 0; break; /* IA */
7596 case 2: offset
= -8; break; /* DB */
7597 case 3: offset
= 4; break; /* IB */
7601 tcg_gen_addi_i32(addr
, addr
, offset
);
7602 /* Load PC into tmp and CPSR into tmp2. */
7603 tmp
= tcg_temp_new_i32();
7604 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7605 tcg_gen_addi_i32(addr
, addr
, 4);
7606 tmp2
= tcg_temp_new_i32();
7607 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7608 if (insn
& (1 << 21)) {
7609 /* Base writeback. */
7611 case 0: offset
= -8; break;
7612 case 1: offset
= 4; break;
7613 case 2: offset
= -4; break;
7614 case 3: offset
= 0; break;
7618 tcg_gen_addi_i32(addr
, addr
, offset
);
7619 store_reg(s
, rn
, addr
);
7621 tcg_temp_free_i32(addr
);
7623 gen_rfe(s
, tmp
, tmp2
);
7625 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7626 /* branch link and change to thumb (blx <offset>) */
7629 val
= (uint32_t)s
->pc
;
7630 tmp
= tcg_temp_new_i32();
7631 tcg_gen_movi_i32(tmp
, val
);
7632 store_reg(s
, 14, tmp
);
7633 /* Sign-extend the 24-bit offset */
7634 offset
= (((int32_t)insn
) << 8) >> 8;
7635 /* offset * 4 + bit24 * 2 + (thumb bit) */
7636 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7637 /* pipeline offset */
7639 /* protected by ARCH(5); above, near the start of uncond block */
7642 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7643 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7644 /* iWMMXt register transfer. */
7645 if (env
->cp15
.c15_cpar
& (1 << 1))
7646 if (!disas_iwmmxt_insn(env
, s
, insn
))
7649 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7650 /* Coprocessor double register transfer. */
7652 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7653 /* Additional coprocessor register transfer. */
7654 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7657 /* cps (privileged) */
7661 if (insn
& (1 << 19)) {
7662 if (insn
& (1 << 8))
7664 if (insn
& (1 << 7))
7666 if (insn
& (1 << 6))
7668 if (insn
& (1 << 18))
7671 if (insn
& (1 << 17)) {
7673 val
|= (insn
& 0x1f);
7676 gen_set_psr_im(s
, mask
, 0, val
);
7683 /* if not always execute, we generate a conditional jump to
7685 s
->condlabel
= gen_new_label();
7686 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7689 if ((insn
& 0x0f900000) == 0x03000000) {
7690 if ((insn
& (1 << 21)) == 0) {
7692 rd
= (insn
>> 12) & 0xf;
7693 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7694 if ((insn
& (1 << 22)) == 0) {
7696 tmp
= tcg_temp_new_i32();
7697 tcg_gen_movi_i32(tmp
, val
);
7700 tmp
= load_reg(s
, rd
);
7701 tcg_gen_ext16u_i32(tmp
, tmp
);
7702 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7704 store_reg(s
, rd
, tmp
);
7706 if (((insn
>> 12) & 0xf) != 0xf)
7708 if (((insn
>> 16) & 0xf) == 0) {
7709 gen_nop_hint(s
, insn
& 0xff);
7711 /* CPSR = immediate */
7713 shift
= ((insn
>> 8) & 0xf) * 2;
7715 val
= (val
>> shift
) | (val
<< (32 - shift
));
7716 i
= ((insn
& (1 << 22)) != 0);
7717 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7721 } else if ((insn
& 0x0f900000) == 0x01000000
7722 && (insn
& 0x00000090) != 0x00000090) {
7723 /* miscellaneous instructions */
7724 op1
= (insn
>> 21) & 3;
7725 sh
= (insn
>> 4) & 0xf;
7728 case 0x0: /* move program status register */
7731 tmp
= load_reg(s
, rm
);
7732 i
= ((op1
& 2) != 0);
7733 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7737 rd
= (insn
>> 12) & 0xf;
7741 tmp
= load_cpu_field(spsr
);
7743 tmp
= tcg_temp_new_i32();
7744 gen_helper_cpsr_read(tmp
, cpu_env
);
7746 store_reg(s
, rd
, tmp
);
7751 /* branch/exchange thumb (bx). */
7753 tmp
= load_reg(s
, rm
);
7755 } else if (op1
== 3) {
7758 rd
= (insn
>> 12) & 0xf;
7759 tmp
= load_reg(s
, rm
);
7760 gen_helper_clz(tmp
, tmp
);
7761 store_reg(s
, rd
, tmp
);
7769 /* Trivial implementation equivalent to bx. */
7770 tmp
= load_reg(s
, rm
);
7781 /* branch link/exchange thumb (blx) */
7782 tmp
= load_reg(s
, rm
);
7783 tmp2
= tcg_temp_new_i32();
7784 tcg_gen_movi_i32(tmp2
, s
->pc
);
7785 store_reg(s
, 14, tmp2
);
7791 uint32_t c
= extract32(insn
, 8, 4);
7793 /* Check this CPU supports ARMv8 CRC instructions.
7794 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7795 * Bits 8, 10 and 11 should be zero.
7797 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7802 rn
= extract32(insn
, 16, 4);
7803 rd
= extract32(insn
, 12, 4);
7805 tmp
= load_reg(s
, rn
);
7806 tmp2
= load_reg(s
, rm
);
7808 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7809 } else if (op1
== 1) {
7810 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7812 tmp3
= tcg_const_i32(1 << op1
);
7814 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7816 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7818 tcg_temp_free_i32(tmp2
);
7819 tcg_temp_free_i32(tmp3
);
7820 store_reg(s
, rd
, tmp
);
7823 case 0x5: /* saturating add/subtract */
7825 rd
= (insn
>> 12) & 0xf;
7826 rn
= (insn
>> 16) & 0xf;
7827 tmp
= load_reg(s
, rm
);
7828 tmp2
= load_reg(s
, rn
);
7830 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7832 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7834 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7835 tcg_temp_free_i32(tmp2
);
7836 store_reg(s
, rd
, tmp
);
7840 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7841 /* SMC instruction (op1 == 3)
7842 and undefined instructions (op1 == 0 || op1 == 2)
7849 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa32_bkpt(imm16
, false));
7852 case 0x8: /* signed multiply */
7857 rs
= (insn
>> 8) & 0xf;
7858 rn
= (insn
>> 12) & 0xf;
7859 rd
= (insn
>> 16) & 0xf;
7861 /* (32 * 16) >> 16 */
7862 tmp
= load_reg(s
, rm
);
7863 tmp2
= load_reg(s
, rs
);
7865 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7868 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7869 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7870 tmp
= tcg_temp_new_i32();
7871 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7872 tcg_temp_free_i64(tmp64
);
7873 if ((sh
& 2) == 0) {
7874 tmp2
= load_reg(s
, rn
);
7875 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7876 tcg_temp_free_i32(tmp2
);
7878 store_reg(s
, rd
, tmp
);
7881 tmp
= load_reg(s
, rm
);
7882 tmp2
= load_reg(s
, rs
);
7883 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7884 tcg_temp_free_i32(tmp2
);
7886 tmp64
= tcg_temp_new_i64();
7887 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7888 tcg_temp_free_i32(tmp
);
7889 gen_addq(s
, tmp64
, rn
, rd
);
7890 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7891 tcg_temp_free_i64(tmp64
);
7894 tmp2
= load_reg(s
, rn
);
7895 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7896 tcg_temp_free_i32(tmp2
);
7898 store_reg(s
, rd
, tmp
);
7905 } else if (((insn
& 0x0e000000) == 0 &&
7906 (insn
& 0x00000090) != 0x90) ||
7907 ((insn
& 0x0e000000) == (1 << 25))) {
7908 int set_cc
, logic_cc
, shiftop
;
7910 op1
= (insn
>> 21) & 0xf;
7911 set_cc
= (insn
>> 20) & 1;
7912 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7914 /* data processing instruction */
7915 if (insn
& (1 << 25)) {
7916 /* immediate operand */
7918 shift
= ((insn
>> 8) & 0xf) * 2;
7920 val
= (val
>> shift
) | (val
<< (32 - shift
));
7922 tmp2
= tcg_temp_new_i32();
7923 tcg_gen_movi_i32(tmp2
, val
);
7924 if (logic_cc
&& shift
) {
7925 gen_set_CF_bit31(tmp2
);
7930 tmp2
= load_reg(s
, rm
);
7931 shiftop
= (insn
>> 5) & 3;
7932 if (!(insn
& (1 << 4))) {
7933 shift
= (insn
>> 7) & 0x1f;
7934 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7936 rs
= (insn
>> 8) & 0xf;
7937 tmp
= load_reg(s
, rs
);
7938 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7941 if (op1
!= 0x0f && op1
!= 0x0d) {
7942 rn
= (insn
>> 16) & 0xf;
7943 tmp
= load_reg(s
, rn
);
7945 TCGV_UNUSED_I32(tmp
);
7947 rd
= (insn
>> 12) & 0xf;
7950 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7954 store_reg_bx(env
, s
, rd
, tmp
);
7957 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7961 store_reg_bx(env
, s
, rd
, tmp
);
7964 if (set_cc
&& rd
== 15) {
7965 /* SUBS r15, ... is used for exception return. */
7969 gen_sub_CC(tmp
, tmp
, tmp2
);
7970 gen_exception_return(s
, tmp
);
7973 gen_sub_CC(tmp
, tmp
, tmp2
);
7975 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7977 store_reg_bx(env
, s
, rd
, tmp
);
7982 gen_sub_CC(tmp
, tmp2
, tmp
);
7984 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7986 store_reg_bx(env
, s
, rd
, tmp
);
7990 gen_add_CC(tmp
, tmp
, tmp2
);
7992 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7994 store_reg_bx(env
, s
, rd
, tmp
);
7998 gen_adc_CC(tmp
, tmp
, tmp2
);
8000 gen_add_carry(tmp
, tmp
, tmp2
);
8002 store_reg_bx(env
, s
, rd
, tmp
);
8006 gen_sbc_CC(tmp
, tmp
, tmp2
);
8008 gen_sub_carry(tmp
, tmp
, tmp2
);
8010 store_reg_bx(env
, s
, rd
, tmp
);
8014 gen_sbc_CC(tmp
, tmp2
, tmp
);
8016 gen_sub_carry(tmp
, tmp2
, tmp
);
8018 store_reg_bx(env
, s
, rd
, tmp
);
8022 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8025 tcg_temp_free_i32(tmp
);
8029 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8032 tcg_temp_free_i32(tmp
);
8036 gen_sub_CC(tmp
, tmp
, tmp2
);
8038 tcg_temp_free_i32(tmp
);
8042 gen_add_CC(tmp
, tmp
, tmp2
);
8044 tcg_temp_free_i32(tmp
);
8047 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8051 store_reg_bx(env
, s
, rd
, tmp
);
8054 if (logic_cc
&& rd
== 15) {
8055 /* MOVS r15, ... is used for exception return. */
8059 gen_exception_return(s
, tmp2
);
8064 store_reg_bx(env
, s
, rd
, tmp2
);
8068 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8072 store_reg_bx(env
, s
, rd
, tmp
);
8076 tcg_gen_not_i32(tmp2
, tmp2
);
8080 store_reg_bx(env
, s
, rd
, tmp2
);
8083 if (op1
!= 0x0f && op1
!= 0x0d) {
8084 tcg_temp_free_i32(tmp2
);
8087 /* other instructions */
8088 op1
= (insn
>> 24) & 0xf;
8092 /* multiplies, extra load/stores */
8093 sh
= (insn
>> 5) & 3;
8096 rd
= (insn
>> 16) & 0xf;
8097 rn
= (insn
>> 12) & 0xf;
8098 rs
= (insn
>> 8) & 0xf;
8100 op1
= (insn
>> 20) & 0xf;
8102 case 0: case 1: case 2: case 3: case 6:
8104 tmp
= load_reg(s
, rs
);
8105 tmp2
= load_reg(s
, rm
);
8106 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8107 tcg_temp_free_i32(tmp2
);
8108 if (insn
& (1 << 22)) {
8109 /* Subtract (mls) */
8111 tmp2
= load_reg(s
, rn
);
8112 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8113 tcg_temp_free_i32(tmp2
);
8114 } else if (insn
& (1 << 21)) {
8116 tmp2
= load_reg(s
, rn
);
8117 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8118 tcg_temp_free_i32(tmp2
);
8120 if (insn
& (1 << 20))
8122 store_reg(s
, rd
, tmp
);
8125 /* 64 bit mul double accumulate (UMAAL) */
8127 tmp
= load_reg(s
, rs
);
8128 tmp2
= load_reg(s
, rm
);
8129 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8130 gen_addq_lo(s
, tmp64
, rn
);
8131 gen_addq_lo(s
, tmp64
, rd
);
8132 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8133 tcg_temp_free_i64(tmp64
);
8135 case 8: case 9: case 10: case 11:
8136 case 12: case 13: case 14: case 15:
8137 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8138 tmp
= load_reg(s
, rs
);
8139 tmp2
= load_reg(s
, rm
);
8140 if (insn
& (1 << 22)) {
8141 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8143 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8145 if (insn
& (1 << 21)) { /* mult accumulate */
8146 TCGv_i32 al
= load_reg(s
, rn
);
8147 TCGv_i32 ah
= load_reg(s
, rd
);
8148 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8149 tcg_temp_free_i32(al
);
8150 tcg_temp_free_i32(ah
);
8152 if (insn
& (1 << 20)) {
8153 gen_logicq_cc(tmp
, tmp2
);
8155 store_reg(s
, rn
, tmp
);
8156 store_reg(s
, rd
, tmp2
);
8162 rn
= (insn
>> 16) & 0xf;
8163 rd
= (insn
>> 12) & 0xf;
8164 if (insn
& (1 << 23)) {
8165 /* load/store exclusive */
8166 int op2
= (insn
>> 8) & 3;
8167 op1
= (insn
>> 21) & 0x3;
8170 case 0: /* lda/stl */
8176 case 1: /* reserved */
8178 case 2: /* ldaex/stlex */
8181 case 3: /* ldrex/strex */
8190 addr
= tcg_temp_local_new_i32();
8191 load_reg_var(s
, addr
, rn
);
8193 /* Since the emulation does not have barriers,
8194 the acquire/release semantics need no special
8197 if (insn
& (1 << 20)) {
8198 tmp
= tcg_temp_new_i32();
8201 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8204 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8207 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8212 store_reg(s
, rd
, tmp
);
8215 tmp
= load_reg(s
, rm
);
8218 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8221 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8224 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8229 tcg_temp_free_i32(tmp
);
8231 } else if (insn
& (1 << 20)) {
8234 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8236 case 1: /* ldrexd */
8237 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8239 case 2: /* ldrexb */
8240 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8242 case 3: /* ldrexh */
8243 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8252 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8254 case 1: /* strexd */
8255 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8257 case 2: /* strexb */
8258 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8260 case 3: /* strexh */
8261 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8267 tcg_temp_free_i32(addr
);
8269 /* SWP instruction */
8272 /* ??? This is not really atomic. However we know
8273 we never have multiple CPUs running in parallel,
8274 so it is good enough. */
8275 addr
= load_reg(s
, rn
);
8276 tmp
= load_reg(s
, rm
);
8277 tmp2
= tcg_temp_new_i32();
8278 if (insn
& (1 << 22)) {
8279 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8280 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8282 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8283 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8285 tcg_temp_free_i32(tmp
);
8286 tcg_temp_free_i32(addr
);
8287 store_reg(s
, rd
, tmp2
);
8293 /* Misc load/store */
8294 rn
= (insn
>> 16) & 0xf;
8295 rd
= (insn
>> 12) & 0xf;
8296 addr
= load_reg(s
, rn
);
8297 if (insn
& (1 << 24))
8298 gen_add_datah_offset(s
, insn
, 0, addr
);
8300 if (insn
& (1 << 20)) {
8302 tmp
= tcg_temp_new_i32();
8305 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8308 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8312 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8316 } else if (sh
& 2) {
8321 tmp
= load_reg(s
, rd
);
8322 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8323 tcg_temp_free_i32(tmp
);
8324 tcg_gen_addi_i32(addr
, addr
, 4);
8325 tmp
= load_reg(s
, rd
+ 1);
8326 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8327 tcg_temp_free_i32(tmp
);
8331 tmp
= tcg_temp_new_i32();
8332 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8333 store_reg(s
, rd
, tmp
);
8334 tcg_gen_addi_i32(addr
, addr
, 4);
8335 tmp
= tcg_temp_new_i32();
8336 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8340 address_offset
= -4;
8343 tmp
= load_reg(s
, rd
);
8344 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8345 tcg_temp_free_i32(tmp
);
8348 /* Perform base writeback before the loaded value to
8349 ensure correct behavior with overlapping index registers.
8350 ldrd with base writeback is is undefined if the
8351 destination and index registers overlap. */
8352 if (!(insn
& (1 << 24))) {
8353 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8354 store_reg(s
, rn
, addr
);
8355 } else if (insn
& (1 << 21)) {
8357 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8358 store_reg(s
, rn
, addr
);
8360 tcg_temp_free_i32(addr
);
8363 /* Complete the load. */
8364 store_reg(s
, rd
, tmp
);
8373 if (insn
& (1 << 4)) {
8375 /* Armv6 Media instructions. */
8377 rn
= (insn
>> 16) & 0xf;
8378 rd
= (insn
>> 12) & 0xf;
8379 rs
= (insn
>> 8) & 0xf;
8380 switch ((insn
>> 23) & 3) {
8381 case 0: /* Parallel add/subtract. */
8382 op1
= (insn
>> 20) & 7;
8383 tmp
= load_reg(s
, rn
);
8384 tmp2
= load_reg(s
, rm
);
8385 sh
= (insn
>> 5) & 7;
8386 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8388 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8389 tcg_temp_free_i32(tmp2
);
8390 store_reg(s
, rd
, tmp
);
8393 if ((insn
& 0x00700020) == 0) {
8394 /* Halfword pack. */
8395 tmp
= load_reg(s
, rn
);
8396 tmp2
= load_reg(s
, rm
);
8397 shift
= (insn
>> 7) & 0x1f;
8398 if (insn
& (1 << 6)) {
8402 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8403 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8404 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8408 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8409 tcg_gen_ext16u_i32(tmp
, tmp
);
8410 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8412 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8413 tcg_temp_free_i32(tmp2
);
8414 store_reg(s
, rd
, tmp
);
8415 } else if ((insn
& 0x00200020) == 0x00200000) {
8417 tmp
= load_reg(s
, rm
);
8418 shift
= (insn
>> 7) & 0x1f;
8419 if (insn
& (1 << 6)) {
8422 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8424 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8426 sh
= (insn
>> 16) & 0x1f;
8427 tmp2
= tcg_const_i32(sh
);
8428 if (insn
& (1 << 22))
8429 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8431 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8432 tcg_temp_free_i32(tmp2
);
8433 store_reg(s
, rd
, tmp
);
8434 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8436 tmp
= load_reg(s
, rm
);
8437 sh
= (insn
>> 16) & 0x1f;
8438 tmp2
= tcg_const_i32(sh
);
8439 if (insn
& (1 << 22))
8440 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8442 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8443 tcg_temp_free_i32(tmp2
);
8444 store_reg(s
, rd
, tmp
);
8445 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8447 tmp
= load_reg(s
, rn
);
8448 tmp2
= load_reg(s
, rm
);
8449 tmp3
= tcg_temp_new_i32();
8450 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8451 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8452 tcg_temp_free_i32(tmp3
);
8453 tcg_temp_free_i32(tmp2
);
8454 store_reg(s
, rd
, tmp
);
8455 } else if ((insn
& 0x000003e0) == 0x00000060) {
8456 tmp
= load_reg(s
, rm
);
8457 shift
= (insn
>> 10) & 3;
8458 /* ??? In many cases it's not necessary to do a
8459 rotate, a shift is sufficient. */
8461 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8462 op1
= (insn
>> 20) & 7;
8464 case 0: gen_sxtb16(tmp
); break;
8465 case 2: gen_sxtb(tmp
); break;
8466 case 3: gen_sxth(tmp
); break;
8467 case 4: gen_uxtb16(tmp
); break;
8468 case 6: gen_uxtb(tmp
); break;
8469 case 7: gen_uxth(tmp
); break;
8470 default: goto illegal_op
;
8473 tmp2
= load_reg(s
, rn
);
8474 if ((op1
& 3) == 0) {
8475 gen_add16(tmp
, tmp2
);
8477 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8478 tcg_temp_free_i32(tmp2
);
8481 store_reg(s
, rd
, tmp
);
8482 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8484 tmp
= load_reg(s
, rm
);
8485 if (insn
& (1 << 22)) {
8486 if (insn
& (1 << 7)) {
8490 gen_helper_rbit(tmp
, tmp
);
8493 if (insn
& (1 << 7))
8496 tcg_gen_bswap32_i32(tmp
, tmp
);
8498 store_reg(s
, rd
, tmp
);
8503 case 2: /* Multiplies (Type 3). */
8504 switch ((insn
>> 20) & 0x7) {
8506 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8507 /* op2 not 00x or 11x : UNDEF */
8510 /* Signed multiply most significant [accumulate].
8511 (SMMUL, SMMLA, SMMLS) */
8512 tmp
= load_reg(s
, rm
);
8513 tmp2
= load_reg(s
, rs
);
8514 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8517 tmp
= load_reg(s
, rd
);
8518 if (insn
& (1 << 6)) {
8519 tmp64
= gen_subq_msw(tmp64
, tmp
);
8521 tmp64
= gen_addq_msw(tmp64
, tmp
);
8524 if (insn
& (1 << 5)) {
8525 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8527 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8528 tmp
= tcg_temp_new_i32();
8529 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8530 tcg_temp_free_i64(tmp64
);
8531 store_reg(s
, rn
, tmp
);
8535 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8536 if (insn
& (1 << 7)) {
8539 tmp
= load_reg(s
, rm
);
8540 tmp2
= load_reg(s
, rs
);
8541 if (insn
& (1 << 5))
8542 gen_swap_half(tmp2
);
8543 gen_smul_dual(tmp
, tmp2
);
8544 if (insn
& (1 << 22)) {
8545 /* smlald, smlsld */
8548 tmp64
= tcg_temp_new_i64();
8549 tmp64_2
= tcg_temp_new_i64();
8550 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8551 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8552 tcg_temp_free_i32(tmp
);
8553 tcg_temp_free_i32(tmp2
);
8554 if (insn
& (1 << 6)) {
8555 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8557 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8559 tcg_temp_free_i64(tmp64_2
);
8560 gen_addq(s
, tmp64
, rd
, rn
);
8561 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8562 tcg_temp_free_i64(tmp64
);
8564 /* smuad, smusd, smlad, smlsd */
8565 if (insn
& (1 << 6)) {
8566 /* This subtraction cannot overflow. */
8567 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8569 /* This addition cannot overflow 32 bits;
8570 * however it may overflow considered as a
8571 * signed operation, in which case we must set
8574 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8576 tcg_temp_free_i32(tmp2
);
8579 tmp2
= load_reg(s
, rd
);
8580 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8581 tcg_temp_free_i32(tmp2
);
8583 store_reg(s
, rn
, tmp
);
8589 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8592 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8595 tmp
= load_reg(s
, rm
);
8596 tmp2
= load_reg(s
, rs
);
8597 if (insn
& (1 << 21)) {
8598 gen_helper_udiv(tmp
, tmp
, tmp2
);
8600 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8602 tcg_temp_free_i32(tmp2
);
8603 store_reg(s
, rn
, tmp
);
8610 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8612 case 0: /* Unsigned sum of absolute differences. */
8614 tmp
= load_reg(s
, rm
);
8615 tmp2
= load_reg(s
, rs
);
8616 gen_helper_usad8(tmp
, tmp
, tmp2
);
8617 tcg_temp_free_i32(tmp2
);
8619 tmp2
= load_reg(s
, rd
);
8620 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8621 tcg_temp_free_i32(tmp2
);
8623 store_reg(s
, rn
, tmp
);
8625 case 0x20: case 0x24: case 0x28: case 0x2c:
8626 /* Bitfield insert/clear. */
8628 shift
= (insn
>> 7) & 0x1f;
8629 i
= (insn
>> 16) & 0x1f;
8632 tmp
= tcg_temp_new_i32();
8633 tcg_gen_movi_i32(tmp
, 0);
8635 tmp
= load_reg(s
, rm
);
8638 tmp2
= load_reg(s
, rd
);
8639 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8640 tcg_temp_free_i32(tmp2
);
8642 store_reg(s
, rd
, tmp
);
8644 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8645 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8647 tmp
= load_reg(s
, rm
);
8648 shift
= (insn
>> 7) & 0x1f;
8649 i
= ((insn
>> 16) & 0x1f) + 1;
8654 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8656 gen_sbfx(tmp
, shift
, i
);
8659 store_reg(s
, rd
, tmp
);
8669 /* Check for undefined extension instructions
8670 * per the ARM Bible IE:
8671 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8673 sh
= (0xf << 20) | (0xf << 4);
8674 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8678 /* load/store byte/word */
8679 rn
= (insn
>> 16) & 0xf;
8680 rd
= (insn
>> 12) & 0xf;
8681 tmp2
= load_reg(s
, rn
);
8682 if ((insn
& 0x01200000) == 0x00200000) {
8686 i
= get_mem_index(s
);
8688 if (insn
& (1 << 24))
8689 gen_add_data_offset(s
, insn
, tmp2
);
8690 if (insn
& (1 << 20)) {
8692 tmp
= tcg_temp_new_i32();
8693 if (insn
& (1 << 22)) {
8694 gen_aa32_ld8u(tmp
, tmp2
, i
);
8696 gen_aa32_ld32u(tmp
, tmp2
, i
);
8700 tmp
= load_reg(s
, rd
);
8701 if (insn
& (1 << 22)) {
8702 gen_aa32_st8(tmp
, tmp2
, i
);
8704 gen_aa32_st32(tmp
, tmp2
, i
);
8706 tcg_temp_free_i32(tmp
);
8708 if (!(insn
& (1 << 24))) {
8709 gen_add_data_offset(s
, insn
, tmp2
);
8710 store_reg(s
, rn
, tmp2
);
8711 } else if (insn
& (1 << 21)) {
8712 store_reg(s
, rn
, tmp2
);
8714 tcg_temp_free_i32(tmp2
);
8716 if (insn
& (1 << 20)) {
8717 /* Complete the load. */
8718 store_reg_from_load(env
, s
, rd
, tmp
);
8724 int j
, n
, user
, loaded_base
;
8725 TCGv_i32 loaded_var
;
8726 /* load/store multiple words */
8727 /* XXX: store correct base if write back */
8729 if (insn
& (1 << 22)) {
8731 goto illegal_op
; /* only usable in supervisor mode */
8733 if ((insn
& (1 << 15)) == 0)
8736 rn
= (insn
>> 16) & 0xf;
8737 addr
= load_reg(s
, rn
);
8739 /* compute total size */
8741 TCGV_UNUSED_I32(loaded_var
);
8744 if (insn
& (1 << i
))
8747 /* XXX: test invalid n == 0 case ? */
8748 if (insn
& (1 << 23)) {
8749 if (insn
& (1 << 24)) {
8751 tcg_gen_addi_i32(addr
, addr
, 4);
8753 /* post increment */
8756 if (insn
& (1 << 24)) {
8758 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8760 /* post decrement */
8762 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8767 if (insn
& (1 << i
)) {
8768 if (insn
& (1 << 20)) {
8770 tmp
= tcg_temp_new_i32();
8771 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8773 tmp2
= tcg_const_i32(i
);
8774 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8775 tcg_temp_free_i32(tmp2
);
8776 tcg_temp_free_i32(tmp
);
8777 } else if (i
== rn
) {
8781 store_reg_from_load(env
, s
, i
, tmp
);
8786 /* special case: r15 = PC + 8 */
8787 val
= (long)s
->pc
+ 4;
8788 tmp
= tcg_temp_new_i32();
8789 tcg_gen_movi_i32(tmp
, val
);
8791 tmp
= tcg_temp_new_i32();
8792 tmp2
= tcg_const_i32(i
);
8793 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8794 tcg_temp_free_i32(tmp2
);
8796 tmp
= load_reg(s
, i
);
8798 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8799 tcg_temp_free_i32(tmp
);
8802 /* no need to add after the last transfer */
8804 tcg_gen_addi_i32(addr
, addr
, 4);
8807 if (insn
& (1 << 21)) {
8809 if (insn
& (1 << 23)) {
8810 if (insn
& (1 << 24)) {
8813 /* post increment */
8814 tcg_gen_addi_i32(addr
, addr
, 4);
8817 if (insn
& (1 << 24)) {
8820 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8822 /* post decrement */
8823 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8826 store_reg(s
, rn
, addr
);
8828 tcg_temp_free_i32(addr
);
8831 store_reg(s
, rn
, loaded_var
);
8833 if ((insn
& (1 << 22)) && !user
) {
8834 /* Restore CPSR from SPSR. */
8835 tmp
= load_cpu_field(spsr
);
8836 gen_set_cpsr(tmp
, 0xffffffff);
8837 tcg_temp_free_i32(tmp
);
8838 s
->is_jmp
= DISAS_UPDATE
;
8847 /* branch (and link) */
8848 val
= (int32_t)s
->pc
;
8849 if (insn
& (1 << 24)) {
8850 tmp
= tcg_temp_new_i32();
8851 tcg_gen_movi_i32(tmp
, val
);
8852 store_reg(s
, 14, tmp
);
8854 offset
= sextract32(insn
<< 2, 0, 26);
8862 if (((insn
>> 8) & 0xe) == 10) {
8864 if (disas_vfp_insn(env
, s
, insn
)) {
8867 } else if (disas_coproc_insn(env
, s
, insn
)) {
8874 gen_set_pc_im(s
, s
->pc
);
8875 s
->svc_imm
= extract32(insn
, 0, 24);
8876 s
->is_jmp
= DISAS_SWI
;
8880 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8886 /* Return true if this is a Thumb-2 logical op. */
8888 thumb2_logic_op(int op
)
8893 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8894 then set condition code flags based on the result of the operation.
8895 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8896 to the high bit of T1.
8897 Returns zero if the opcode is valid. */
8900 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8901 TCGv_i32 t0
, TCGv_i32 t1
)
8908 tcg_gen_and_i32(t0
, t0
, t1
);
8912 tcg_gen_andc_i32(t0
, t0
, t1
);
8916 tcg_gen_or_i32(t0
, t0
, t1
);
8920 tcg_gen_orc_i32(t0
, t0
, t1
);
8924 tcg_gen_xor_i32(t0
, t0
, t1
);
8929 gen_add_CC(t0
, t0
, t1
);
8931 tcg_gen_add_i32(t0
, t0
, t1
);
8935 gen_adc_CC(t0
, t0
, t1
);
8941 gen_sbc_CC(t0
, t0
, t1
);
8943 gen_sub_carry(t0
, t0
, t1
);
8948 gen_sub_CC(t0
, t0
, t1
);
8950 tcg_gen_sub_i32(t0
, t0
, t1
);
8954 gen_sub_CC(t0
, t1
, t0
);
8956 tcg_gen_sub_i32(t0
, t1
, t0
);
8958 default: /* 5, 6, 7, 9, 12, 15. */
8964 gen_set_CF_bit31(t1
);
8969 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8971 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8973 uint32_t insn
, imm
, shift
, offset
;
8974 uint32_t rd
, rn
, rm
, rs
;
8985 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8986 || arm_feature (env
, ARM_FEATURE_M
))) {
8987 /* Thumb-1 cores may need to treat bl and blx as a pair of
8988 16-bit instructions to get correct prefetch abort behavior. */
8990 if ((insn
& (1 << 12)) == 0) {
8992 /* Second half of blx. */
8993 offset
= ((insn
& 0x7ff) << 1);
8994 tmp
= load_reg(s
, 14);
8995 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8996 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8998 tmp2
= tcg_temp_new_i32();
8999 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9000 store_reg(s
, 14, tmp2
);
9004 if (insn
& (1 << 11)) {
9005 /* Second half of bl. */
9006 offset
= ((insn
& 0x7ff) << 1) | 1;
9007 tmp
= load_reg(s
, 14);
9008 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9010 tmp2
= tcg_temp_new_i32();
9011 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9012 store_reg(s
, 14, tmp2
);
9016 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9017 /* Instruction spans a page boundary. Implement it as two
9018 16-bit instructions in case the second half causes an
9020 offset
= ((int32_t)insn
<< 21) >> 9;
9021 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9024 /* Fall through to 32-bit decode. */
9027 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9029 insn
|= (uint32_t)insn_hw1
<< 16;
9031 if ((insn
& 0xf800e800) != 0xf000e800) {
9035 rn
= (insn
>> 16) & 0xf;
9036 rs
= (insn
>> 12) & 0xf;
9037 rd
= (insn
>> 8) & 0xf;
9039 switch ((insn
>> 25) & 0xf) {
9040 case 0: case 1: case 2: case 3:
9041 /* 16-bit instructions. Should never happen. */
9044 if (insn
& (1 << 22)) {
9045 /* Other load/store, table branch. */
9046 if (insn
& 0x01200000) {
9047 /* Load/store doubleword. */
9049 addr
= tcg_temp_new_i32();
9050 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9052 addr
= load_reg(s
, rn
);
9054 offset
= (insn
& 0xff) * 4;
9055 if ((insn
& (1 << 23)) == 0)
9057 if (insn
& (1 << 24)) {
9058 tcg_gen_addi_i32(addr
, addr
, offset
);
9061 if (insn
& (1 << 20)) {
9063 tmp
= tcg_temp_new_i32();
9064 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9065 store_reg(s
, rs
, tmp
);
9066 tcg_gen_addi_i32(addr
, addr
, 4);
9067 tmp
= tcg_temp_new_i32();
9068 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9069 store_reg(s
, rd
, tmp
);
9072 tmp
= load_reg(s
, rs
);
9073 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9074 tcg_temp_free_i32(tmp
);
9075 tcg_gen_addi_i32(addr
, addr
, 4);
9076 tmp
= load_reg(s
, rd
);
9077 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9078 tcg_temp_free_i32(tmp
);
9080 if (insn
& (1 << 21)) {
9081 /* Base writeback. */
9084 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9085 store_reg(s
, rn
, addr
);
9087 tcg_temp_free_i32(addr
);
9089 } else if ((insn
& (1 << 23)) == 0) {
9090 /* Load/store exclusive word. */
9091 addr
= tcg_temp_local_new_i32();
9092 load_reg_var(s
, addr
, rn
);
9093 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9094 if (insn
& (1 << 20)) {
9095 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9097 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9099 tcg_temp_free_i32(addr
);
9100 } else if ((insn
& (7 << 5)) == 0) {
9103 addr
= tcg_temp_new_i32();
9104 tcg_gen_movi_i32(addr
, s
->pc
);
9106 addr
= load_reg(s
, rn
);
9108 tmp
= load_reg(s
, rm
);
9109 tcg_gen_add_i32(addr
, addr
, tmp
);
9110 if (insn
& (1 << 4)) {
9112 tcg_gen_add_i32(addr
, addr
, tmp
);
9113 tcg_temp_free_i32(tmp
);
9114 tmp
= tcg_temp_new_i32();
9115 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9117 tcg_temp_free_i32(tmp
);
9118 tmp
= tcg_temp_new_i32();
9119 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9121 tcg_temp_free_i32(addr
);
9122 tcg_gen_shli_i32(tmp
, tmp
, 1);
9123 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9124 store_reg(s
, 15, tmp
);
9126 int op2
= (insn
>> 6) & 0x3;
9127 op
= (insn
>> 4) & 0x3;
9132 /* Load/store exclusive byte/halfword/doubleword */
9139 /* Load-acquire/store-release */
9145 /* Load-acquire/store-release exclusive */
9149 addr
= tcg_temp_local_new_i32();
9150 load_reg_var(s
, addr
, rn
);
9152 if (insn
& (1 << 20)) {
9153 tmp
= tcg_temp_new_i32();
9156 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9159 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9162 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9167 store_reg(s
, rs
, tmp
);
9169 tmp
= load_reg(s
, rs
);
9172 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9175 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9178 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9183 tcg_temp_free_i32(tmp
);
9185 } else if (insn
& (1 << 20)) {
9186 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9188 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9190 tcg_temp_free_i32(addr
);
9193 /* Load/store multiple, RFE, SRS. */
9194 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9195 /* RFE, SRS: not available in user mode or on M profile */
9196 if (IS_USER(s
) || IS_M(env
)) {
9199 if (insn
& (1 << 20)) {
9201 addr
= load_reg(s
, rn
);
9202 if ((insn
& (1 << 24)) == 0)
9203 tcg_gen_addi_i32(addr
, addr
, -8);
9204 /* Load PC into tmp and CPSR into tmp2. */
9205 tmp
= tcg_temp_new_i32();
9206 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9207 tcg_gen_addi_i32(addr
, addr
, 4);
9208 tmp2
= tcg_temp_new_i32();
9209 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9210 if (insn
& (1 << 21)) {
9211 /* Base writeback. */
9212 if (insn
& (1 << 24)) {
9213 tcg_gen_addi_i32(addr
, addr
, 4);
9215 tcg_gen_addi_i32(addr
, addr
, -4);
9217 store_reg(s
, rn
, addr
);
9219 tcg_temp_free_i32(addr
);
9221 gen_rfe(s
, tmp
, tmp2
);
9224 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9228 int i
, loaded_base
= 0;
9229 TCGv_i32 loaded_var
;
9230 /* Load/store multiple. */
9231 addr
= load_reg(s
, rn
);
9233 for (i
= 0; i
< 16; i
++) {
9234 if (insn
& (1 << i
))
9237 if (insn
& (1 << 24)) {
9238 tcg_gen_addi_i32(addr
, addr
, -offset
);
9241 TCGV_UNUSED_I32(loaded_var
);
9242 for (i
= 0; i
< 16; i
++) {
9243 if ((insn
& (1 << i
)) == 0)
9245 if (insn
& (1 << 20)) {
9247 tmp
= tcg_temp_new_i32();
9248 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9251 } else if (i
== rn
) {
9255 store_reg(s
, i
, tmp
);
9259 tmp
= load_reg(s
, i
);
9260 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9261 tcg_temp_free_i32(tmp
);
9263 tcg_gen_addi_i32(addr
, addr
, 4);
9266 store_reg(s
, rn
, loaded_var
);
9268 if (insn
& (1 << 21)) {
9269 /* Base register writeback. */
9270 if (insn
& (1 << 24)) {
9271 tcg_gen_addi_i32(addr
, addr
, -offset
);
9273 /* Fault if writeback register is in register list. */
9274 if (insn
& (1 << rn
))
9276 store_reg(s
, rn
, addr
);
9278 tcg_temp_free_i32(addr
);
9285 op
= (insn
>> 21) & 0xf;
9287 /* Halfword pack. */
9288 tmp
= load_reg(s
, rn
);
9289 tmp2
= load_reg(s
, rm
);
9290 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9291 if (insn
& (1 << 5)) {
9295 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9296 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9297 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9301 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9302 tcg_gen_ext16u_i32(tmp
, tmp
);
9303 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9305 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9306 tcg_temp_free_i32(tmp2
);
9307 store_reg(s
, rd
, tmp
);
9309 /* Data processing register constant shift. */
9311 tmp
= tcg_temp_new_i32();
9312 tcg_gen_movi_i32(tmp
, 0);
9314 tmp
= load_reg(s
, rn
);
9316 tmp2
= load_reg(s
, rm
);
9318 shiftop
= (insn
>> 4) & 3;
9319 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9320 conds
= (insn
& (1 << 20)) != 0;
9321 logic_cc
= (conds
&& thumb2_logic_op(op
));
9322 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9323 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9325 tcg_temp_free_i32(tmp2
);
9327 store_reg(s
, rd
, tmp
);
9329 tcg_temp_free_i32(tmp
);
9333 case 13: /* Misc data processing. */
9334 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9335 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9338 case 0: /* Register controlled shift. */
9339 tmp
= load_reg(s
, rn
);
9340 tmp2
= load_reg(s
, rm
);
9341 if ((insn
& 0x70) != 0)
9343 op
= (insn
>> 21) & 3;
9344 logic_cc
= (insn
& (1 << 20)) != 0;
9345 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9348 store_reg_bx(env
, s
, rd
, tmp
);
9350 case 1: /* Sign/zero extend. */
9351 tmp
= load_reg(s
, rm
);
9352 shift
= (insn
>> 4) & 3;
9353 /* ??? In many cases it's not necessary to do a
9354 rotate, a shift is sufficient. */
9356 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9357 op
= (insn
>> 20) & 7;
9359 case 0: gen_sxth(tmp
); break;
9360 case 1: gen_uxth(tmp
); break;
9361 case 2: gen_sxtb16(tmp
); break;
9362 case 3: gen_uxtb16(tmp
); break;
9363 case 4: gen_sxtb(tmp
); break;
9364 case 5: gen_uxtb(tmp
); break;
9365 default: goto illegal_op
;
9368 tmp2
= load_reg(s
, rn
);
9369 if ((op
>> 1) == 1) {
9370 gen_add16(tmp
, tmp2
);
9372 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9373 tcg_temp_free_i32(tmp2
);
9376 store_reg(s
, rd
, tmp
);
9378 case 2: /* SIMD add/subtract. */
9379 op
= (insn
>> 20) & 7;
9380 shift
= (insn
>> 4) & 7;
9381 if ((op
& 3) == 3 || (shift
& 3) == 3)
9383 tmp
= load_reg(s
, rn
);
9384 tmp2
= load_reg(s
, rm
);
9385 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9386 tcg_temp_free_i32(tmp2
);
9387 store_reg(s
, rd
, tmp
);
9389 case 3: /* Other data processing. */
9390 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9392 /* Saturating add/subtract. */
9393 tmp
= load_reg(s
, rn
);
9394 tmp2
= load_reg(s
, rm
);
9396 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9398 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9400 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9401 tcg_temp_free_i32(tmp2
);
9403 tmp
= load_reg(s
, rn
);
9405 case 0x0a: /* rbit */
9406 gen_helper_rbit(tmp
, tmp
);
9408 case 0x08: /* rev */
9409 tcg_gen_bswap32_i32(tmp
, tmp
);
9411 case 0x09: /* rev16 */
9414 case 0x0b: /* revsh */
9417 case 0x10: /* sel */
9418 tmp2
= load_reg(s
, rm
);
9419 tmp3
= tcg_temp_new_i32();
9420 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9421 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9422 tcg_temp_free_i32(tmp3
);
9423 tcg_temp_free_i32(tmp2
);
9425 case 0x18: /* clz */
9426 gen_helper_clz(tmp
, tmp
);
9436 uint32_t sz
= op
& 0x3;
9437 uint32_t c
= op
& 0x8;
9439 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9443 tmp2
= load_reg(s
, rm
);
9445 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9446 } else if (sz
== 1) {
9447 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9449 tmp3
= tcg_const_i32(1 << sz
);
9451 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9453 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9455 tcg_temp_free_i32(tmp2
);
9456 tcg_temp_free_i32(tmp3
);
9463 store_reg(s
, rd
, tmp
);
9465 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9466 op
= (insn
>> 4) & 0xf;
9467 tmp
= load_reg(s
, rn
);
9468 tmp2
= load_reg(s
, rm
);
9469 switch ((insn
>> 20) & 7) {
9470 case 0: /* 32 x 32 -> 32 */
9471 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9472 tcg_temp_free_i32(tmp2
);
9474 tmp2
= load_reg(s
, rs
);
9476 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9478 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9479 tcg_temp_free_i32(tmp2
);
9482 case 1: /* 16 x 16 -> 32 */
9483 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9484 tcg_temp_free_i32(tmp2
);
9486 tmp2
= load_reg(s
, rs
);
9487 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9488 tcg_temp_free_i32(tmp2
);
9491 case 2: /* Dual multiply add. */
9492 case 4: /* Dual multiply subtract. */
9494 gen_swap_half(tmp2
);
9495 gen_smul_dual(tmp
, tmp2
);
9496 if (insn
& (1 << 22)) {
9497 /* This subtraction cannot overflow. */
9498 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9500 /* This addition cannot overflow 32 bits;
9501 * however it may overflow considered as a signed
9502 * operation, in which case we must set the Q flag.
9504 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9506 tcg_temp_free_i32(tmp2
);
9509 tmp2
= load_reg(s
, rs
);
9510 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9511 tcg_temp_free_i32(tmp2
);
9514 case 3: /* 32 * 16 -> 32msb */
9516 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9519 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9520 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9521 tmp
= tcg_temp_new_i32();
9522 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9523 tcg_temp_free_i64(tmp64
);
9526 tmp2
= load_reg(s
, rs
);
9527 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9528 tcg_temp_free_i32(tmp2
);
9531 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9532 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9534 tmp
= load_reg(s
, rs
);
9535 if (insn
& (1 << 20)) {
9536 tmp64
= gen_addq_msw(tmp64
, tmp
);
9538 tmp64
= gen_subq_msw(tmp64
, tmp
);
9541 if (insn
& (1 << 4)) {
9542 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9544 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9545 tmp
= tcg_temp_new_i32();
9546 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9547 tcg_temp_free_i64(tmp64
);
9549 case 7: /* Unsigned sum of absolute differences. */
9550 gen_helper_usad8(tmp
, tmp
, tmp2
);
9551 tcg_temp_free_i32(tmp2
);
9553 tmp2
= load_reg(s
, rs
);
9554 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9555 tcg_temp_free_i32(tmp2
);
9559 store_reg(s
, rd
, tmp
);
9561 case 6: case 7: /* 64-bit multiply, Divide. */
9562 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9563 tmp
= load_reg(s
, rn
);
9564 tmp2
= load_reg(s
, rm
);
9565 if ((op
& 0x50) == 0x10) {
9567 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9571 gen_helper_udiv(tmp
, tmp
, tmp2
);
9573 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9574 tcg_temp_free_i32(tmp2
);
9575 store_reg(s
, rd
, tmp
);
9576 } else if ((op
& 0xe) == 0xc) {
9577 /* Dual multiply accumulate long. */
9579 gen_swap_half(tmp2
);
9580 gen_smul_dual(tmp
, tmp2
);
9582 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9584 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9586 tcg_temp_free_i32(tmp2
);
9588 tmp64
= tcg_temp_new_i64();
9589 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9590 tcg_temp_free_i32(tmp
);
9591 gen_addq(s
, tmp64
, rs
, rd
);
9592 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9593 tcg_temp_free_i64(tmp64
);
9596 /* Unsigned 64-bit multiply */
9597 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9601 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9602 tcg_temp_free_i32(tmp2
);
9603 tmp64
= tcg_temp_new_i64();
9604 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9605 tcg_temp_free_i32(tmp
);
9607 /* Signed 64-bit multiply */
9608 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9613 gen_addq_lo(s
, tmp64
, rs
);
9614 gen_addq_lo(s
, tmp64
, rd
);
9615 } else if (op
& 0x40) {
9616 /* 64-bit accumulate. */
9617 gen_addq(s
, tmp64
, rs
, rd
);
9619 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9620 tcg_temp_free_i64(tmp64
);
9625 case 6: case 7: case 14: case 15:
9627 if (((insn
>> 24) & 3) == 3) {
9628 /* Translate into the equivalent ARM encoding. */
9629 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9630 if (disas_neon_data_insn(env
, s
, insn
))
9632 } else if (((insn
>> 8) & 0xe) == 10) {
9633 if (disas_vfp_insn(env
, s
, insn
)) {
9637 if (insn
& (1 << 28))
9639 if (disas_coproc_insn (env
, s
, insn
))
9643 case 8: case 9: case 10: case 11:
9644 if (insn
& (1 << 15)) {
9645 /* Branches, misc control. */
9646 if (insn
& 0x5000) {
9647 /* Unconditional branch. */
9648 /* signextend(hw1[10:0]) -> offset[:12]. */
9649 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9650 /* hw1[10:0] -> offset[11:1]. */
9651 offset
|= (insn
& 0x7ff) << 1;
9652 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9653 offset[24:22] already have the same value because of the
9654 sign extension above. */
9655 offset
^= ((~insn
) & (1 << 13)) << 10;
9656 offset
^= ((~insn
) & (1 << 11)) << 11;
9658 if (insn
& (1 << 14)) {
9659 /* Branch and link. */
9660 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9664 if (insn
& (1 << 12)) {
9669 offset
&= ~(uint32_t)2;
9670 /* thumb2 bx, no need to check */
9671 gen_bx_im(s
, offset
);
9673 } else if (((insn
>> 23) & 7) == 7) {
9675 if (insn
& (1 << 13))
9678 if (insn
& (1 << 26)) {
9679 /* Secure monitor call (v6Z) */
9680 qemu_log_mask(LOG_UNIMP
,
9681 "arm: unimplemented secure monitor call\n");
9682 goto illegal_op
; /* not implemented. */
9684 op
= (insn
>> 20) & 7;
9686 case 0: /* msr cpsr. */
9688 tmp
= load_reg(s
, rn
);
9689 addr
= tcg_const_i32(insn
& 0xff);
9690 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9691 tcg_temp_free_i32(addr
);
9692 tcg_temp_free_i32(tmp
);
9697 case 1: /* msr spsr. */
9700 tmp
= load_reg(s
, rn
);
9702 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9706 case 2: /* cps, nop-hint. */
9707 if (((insn
>> 8) & 7) == 0) {
9708 gen_nop_hint(s
, insn
& 0xff);
9710 /* Implemented as NOP in user mode. */
9715 if (insn
& (1 << 10)) {
9716 if (insn
& (1 << 7))
9718 if (insn
& (1 << 6))
9720 if (insn
& (1 << 5))
9722 if (insn
& (1 << 9))
9723 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9725 if (insn
& (1 << 8)) {
9727 imm
|= (insn
& 0x1f);
9730 gen_set_psr_im(s
, offset
, 0, imm
);
9733 case 3: /* Special control operations. */
9735 op
= (insn
>> 4) & 0xf;
9743 /* These execute as NOPs. */
9750 /* Trivial implementation equivalent to bx. */
9751 tmp
= load_reg(s
, rn
);
9754 case 5: /* Exception return. */
9758 if (rn
!= 14 || rd
!= 15) {
9761 tmp
= load_reg(s
, rn
);
9762 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9763 gen_exception_return(s
, tmp
);
9765 case 6: /* mrs cpsr. */
9766 tmp
= tcg_temp_new_i32();
9768 addr
= tcg_const_i32(insn
& 0xff);
9769 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9770 tcg_temp_free_i32(addr
);
9772 gen_helper_cpsr_read(tmp
, cpu_env
);
9774 store_reg(s
, rd
, tmp
);
9776 case 7: /* mrs spsr. */
9777 /* Not accessible in user mode. */
9778 if (IS_USER(s
) || IS_M(env
))
9780 tmp
= load_cpu_field(spsr
);
9781 store_reg(s
, rd
, tmp
);
9786 /* Conditional branch. */
9787 op
= (insn
>> 22) & 0xf;
9788 /* Generate a conditional jump to next instruction. */
9789 s
->condlabel
= gen_new_label();
9790 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9793 /* offset[11:1] = insn[10:0] */
9794 offset
= (insn
& 0x7ff) << 1;
9795 /* offset[17:12] = insn[21:16]. */
9796 offset
|= (insn
& 0x003f0000) >> 4;
9797 /* offset[31:20] = insn[26]. */
9798 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9799 /* offset[18] = insn[13]. */
9800 offset
|= (insn
& (1 << 13)) << 5;
9801 /* offset[19] = insn[11]. */
9802 offset
|= (insn
& (1 << 11)) << 8;
9804 /* jump to the offset */
9805 gen_jmp(s
, s
->pc
+ offset
);
9808 /* Data processing immediate. */
9809 if (insn
& (1 << 25)) {
9810 if (insn
& (1 << 24)) {
9811 if (insn
& (1 << 20))
9813 /* Bitfield/Saturate. */
9814 op
= (insn
>> 21) & 7;
9816 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9818 tmp
= tcg_temp_new_i32();
9819 tcg_gen_movi_i32(tmp
, 0);
9821 tmp
= load_reg(s
, rn
);
9824 case 2: /* Signed bitfield extract. */
9826 if (shift
+ imm
> 32)
9829 gen_sbfx(tmp
, shift
, imm
);
9831 case 6: /* Unsigned bitfield extract. */
9833 if (shift
+ imm
> 32)
9836 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9838 case 3: /* Bitfield insert/clear. */
9841 imm
= imm
+ 1 - shift
;
9843 tmp2
= load_reg(s
, rd
);
9844 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9845 tcg_temp_free_i32(tmp2
);
9850 default: /* Saturate. */
9853 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9855 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9857 tmp2
= tcg_const_i32(imm
);
9860 if ((op
& 1) && shift
== 0)
9861 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9863 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9866 if ((op
& 1) && shift
== 0)
9867 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9869 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9871 tcg_temp_free_i32(tmp2
);
9874 store_reg(s
, rd
, tmp
);
9876 imm
= ((insn
& 0x04000000) >> 15)
9877 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9878 if (insn
& (1 << 22)) {
9879 /* 16-bit immediate. */
9880 imm
|= (insn
>> 4) & 0xf000;
9881 if (insn
& (1 << 23)) {
9883 tmp
= load_reg(s
, rd
);
9884 tcg_gen_ext16u_i32(tmp
, tmp
);
9885 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9888 tmp
= tcg_temp_new_i32();
9889 tcg_gen_movi_i32(tmp
, imm
);
9892 /* Add/sub 12-bit immediate. */
9894 offset
= s
->pc
& ~(uint32_t)3;
9895 if (insn
& (1 << 23))
9899 tmp
= tcg_temp_new_i32();
9900 tcg_gen_movi_i32(tmp
, offset
);
9902 tmp
= load_reg(s
, rn
);
9903 if (insn
& (1 << 23))
9904 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9906 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9909 store_reg(s
, rd
, tmp
);
9912 int shifter_out
= 0;
9913 /* modified 12-bit immediate. */
9914 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9915 imm
= (insn
& 0xff);
9918 /* Nothing to do. */
9920 case 1: /* 00XY00XY */
9923 case 2: /* XY00XY00 */
9927 case 3: /* XYXYXYXY */
9931 default: /* Rotated constant. */
9932 shift
= (shift
<< 1) | (imm
>> 7);
9934 imm
= imm
<< (32 - shift
);
9938 tmp2
= tcg_temp_new_i32();
9939 tcg_gen_movi_i32(tmp2
, imm
);
9940 rn
= (insn
>> 16) & 0xf;
9942 tmp
= tcg_temp_new_i32();
9943 tcg_gen_movi_i32(tmp
, 0);
9945 tmp
= load_reg(s
, rn
);
9947 op
= (insn
>> 21) & 0xf;
9948 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9949 shifter_out
, tmp
, tmp2
))
9951 tcg_temp_free_i32(tmp2
);
9952 rd
= (insn
>> 8) & 0xf;
9954 store_reg(s
, rd
, tmp
);
9956 tcg_temp_free_i32(tmp
);
9961 case 12: /* Load/store single data item. */
9966 if ((insn
& 0x01100000) == 0x01000000) {
9967 if (disas_neon_ls_insn(env
, s
, insn
))
9971 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9973 if (!(insn
& (1 << 20))) {
9977 /* Byte or halfword load space with dest == r15 : memory hints.
9978 * Catch them early so we don't emit pointless addressing code.
9979 * This space is a mix of:
9980 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9981 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9983 * unallocated hints, which must be treated as NOPs
9984 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9985 * which is easiest for the decoding logic
9986 * Some space which must UNDEF
9988 int op1
= (insn
>> 23) & 3;
9989 int op2
= (insn
>> 6) & 0x3f;
9994 /* UNPREDICTABLE, unallocated hint or
9995 * PLD/PLDW/PLI (literal)
10000 return 0; /* PLD/PLDW/PLI or unallocated hint */
10002 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10003 return 0; /* PLD/PLDW/PLI or unallocated hint */
10005 /* UNDEF space, or an UNPREDICTABLE */
10009 memidx
= get_mem_index(s
);
10011 addr
= tcg_temp_new_i32();
10013 /* s->pc has already been incremented by 4. */
10014 imm
= s
->pc
& 0xfffffffc;
10015 if (insn
& (1 << 23))
10016 imm
+= insn
& 0xfff;
10018 imm
-= insn
& 0xfff;
10019 tcg_gen_movi_i32(addr
, imm
);
10021 addr
= load_reg(s
, rn
);
10022 if (insn
& (1 << 23)) {
10023 /* Positive offset. */
10024 imm
= insn
& 0xfff;
10025 tcg_gen_addi_i32(addr
, addr
, imm
);
10028 switch ((insn
>> 8) & 0xf) {
10029 case 0x0: /* Shifted Register. */
10030 shift
= (insn
>> 4) & 0xf;
10032 tcg_temp_free_i32(addr
);
10035 tmp
= load_reg(s
, rm
);
10037 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10038 tcg_gen_add_i32(addr
, addr
, tmp
);
10039 tcg_temp_free_i32(tmp
);
10041 case 0xc: /* Negative offset. */
10042 tcg_gen_addi_i32(addr
, addr
, -imm
);
10044 case 0xe: /* User privilege. */
10045 tcg_gen_addi_i32(addr
, addr
, imm
);
10046 memidx
= MMU_USER_IDX
;
10048 case 0x9: /* Post-decrement. */
10050 /* Fall through. */
10051 case 0xb: /* Post-increment. */
10055 case 0xd: /* Pre-decrement. */
10057 /* Fall through. */
10058 case 0xf: /* Pre-increment. */
10059 tcg_gen_addi_i32(addr
, addr
, imm
);
10063 tcg_temp_free_i32(addr
);
10068 if (insn
& (1 << 20)) {
10070 tmp
= tcg_temp_new_i32();
10073 gen_aa32_ld8u(tmp
, addr
, memidx
);
10076 gen_aa32_ld8s(tmp
, addr
, memidx
);
10079 gen_aa32_ld16u(tmp
, addr
, memidx
);
10082 gen_aa32_ld16s(tmp
, addr
, memidx
);
10085 gen_aa32_ld32u(tmp
, addr
, memidx
);
10088 tcg_temp_free_i32(tmp
);
10089 tcg_temp_free_i32(addr
);
10095 store_reg(s
, rs
, tmp
);
10099 tmp
= load_reg(s
, rs
);
10102 gen_aa32_st8(tmp
, addr
, memidx
);
10105 gen_aa32_st16(tmp
, addr
, memidx
);
10108 gen_aa32_st32(tmp
, addr
, memidx
);
10111 tcg_temp_free_i32(tmp
);
10112 tcg_temp_free_i32(addr
);
10115 tcg_temp_free_i32(tmp
);
10118 tcg_gen_addi_i32(addr
, addr
, imm
);
10120 store_reg(s
, rn
, addr
);
10122 tcg_temp_free_i32(addr
);
10134 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10136 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10143 if (s
->condexec_mask
) {
10144 cond
= s
->condexec_cond
;
10145 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10146 s
->condlabel
= gen_new_label();
10147 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10152 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10155 switch (insn
>> 12) {
10159 op
= (insn
>> 11) & 3;
10162 rn
= (insn
>> 3) & 7;
10163 tmp
= load_reg(s
, rn
);
10164 if (insn
& (1 << 10)) {
10166 tmp2
= tcg_temp_new_i32();
10167 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10170 rm
= (insn
>> 6) & 7;
10171 tmp2
= load_reg(s
, rm
);
10173 if (insn
& (1 << 9)) {
10174 if (s
->condexec_mask
)
10175 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10177 gen_sub_CC(tmp
, tmp
, tmp2
);
10179 if (s
->condexec_mask
)
10180 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10182 gen_add_CC(tmp
, tmp
, tmp2
);
10184 tcg_temp_free_i32(tmp2
);
10185 store_reg(s
, rd
, tmp
);
10187 /* shift immediate */
10188 rm
= (insn
>> 3) & 7;
10189 shift
= (insn
>> 6) & 0x1f;
10190 tmp
= load_reg(s
, rm
);
10191 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10192 if (!s
->condexec_mask
)
10194 store_reg(s
, rd
, tmp
);
10198 /* arithmetic large immediate */
10199 op
= (insn
>> 11) & 3;
10200 rd
= (insn
>> 8) & 0x7;
10201 if (op
== 0) { /* mov */
10202 tmp
= tcg_temp_new_i32();
10203 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10204 if (!s
->condexec_mask
)
10206 store_reg(s
, rd
, tmp
);
10208 tmp
= load_reg(s
, rd
);
10209 tmp2
= tcg_temp_new_i32();
10210 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10213 gen_sub_CC(tmp
, tmp
, tmp2
);
10214 tcg_temp_free_i32(tmp
);
10215 tcg_temp_free_i32(tmp2
);
10218 if (s
->condexec_mask
)
10219 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10221 gen_add_CC(tmp
, tmp
, tmp2
);
10222 tcg_temp_free_i32(tmp2
);
10223 store_reg(s
, rd
, tmp
);
10226 if (s
->condexec_mask
)
10227 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10229 gen_sub_CC(tmp
, tmp
, tmp2
);
10230 tcg_temp_free_i32(tmp2
);
10231 store_reg(s
, rd
, tmp
);
10237 if (insn
& (1 << 11)) {
10238 rd
= (insn
>> 8) & 7;
10239 /* load pc-relative. Bit 1 of PC is ignored. */
10240 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10241 val
&= ~(uint32_t)2;
10242 addr
= tcg_temp_new_i32();
10243 tcg_gen_movi_i32(addr
, val
);
10244 tmp
= tcg_temp_new_i32();
10245 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10246 tcg_temp_free_i32(addr
);
10247 store_reg(s
, rd
, tmp
);
10250 if (insn
& (1 << 10)) {
10251 /* data processing extended or blx */
10252 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10253 rm
= (insn
>> 3) & 0xf;
10254 op
= (insn
>> 8) & 3;
10257 tmp
= load_reg(s
, rd
);
10258 tmp2
= load_reg(s
, rm
);
10259 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10260 tcg_temp_free_i32(tmp2
);
10261 store_reg(s
, rd
, tmp
);
10264 tmp
= load_reg(s
, rd
);
10265 tmp2
= load_reg(s
, rm
);
10266 gen_sub_CC(tmp
, tmp
, tmp2
);
10267 tcg_temp_free_i32(tmp2
);
10268 tcg_temp_free_i32(tmp
);
10270 case 2: /* mov/cpy */
10271 tmp
= load_reg(s
, rm
);
10272 store_reg(s
, rd
, tmp
);
10274 case 3:/* branch [and link] exchange thumb register */
10275 tmp
= load_reg(s
, rm
);
10276 if (insn
& (1 << 7)) {
10278 val
= (uint32_t)s
->pc
| 1;
10279 tmp2
= tcg_temp_new_i32();
10280 tcg_gen_movi_i32(tmp2
, val
);
10281 store_reg(s
, 14, tmp2
);
10283 /* already thumb, no need to check */
10290 /* data processing register */
10292 rm
= (insn
>> 3) & 7;
10293 op
= (insn
>> 6) & 0xf;
10294 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10295 /* the shift/rotate ops want the operands backwards */
10304 if (op
== 9) { /* neg */
10305 tmp
= tcg_temp_new_i32();
10306 tcg_gen_movi_i32(tmp
, 0);
10307 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10308 tmp
= load_reg(s
, rd
);
10310 TCGV_UNUSED_I32(tmp
);
10313 tmp2
= load_reg(s
, rm
);
10315 case 0x0: /* and */
10316 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10317 if (!s
->condexec_mask
)
10320 case 0x1: /* eor */
10321 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10322 if (!s
->condexec_mask
)
10325 case 0x2: /* lsl */
10326 if (s
->condexec_mask
) {
10327 gen_shl(tmp2
, tmp2
, tmp
);
10329 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10330 gen_logic_CC(tmp2
);
10333 case 0x3: /* lsr */
10334 if (s
->condexec_mask
) {
10335 gen_shr(tmp2
, tmp2
, tmp
);
10337 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10338 gen_logic_CC(tmp2
);
10341 case 0x4: /* asr */
10342 if (s
->condexec_mask
) {
10343 gen_sar(tmp2
, tmp2
, tmp
);
10345 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10346 gen_logic_CC(tmp2
);
10349 case 0x5: /* adc */
10350 if (s
->condexec_mask
) {
10351 gen_adc(tmp
, tmp2
);
10353 gen_adc_CC(tmp
, tmp
, tmp2
);
10356 case 0x6: /* sbc */
10357 if (s
->condexec_mask
) {
10358 gen_sub_carry(tmp
, tmp
, tmp2
);
10360 gen_sbc_CC(tmp
, tmp
, tmp2
);
10363 case 0x7: /* ror */
10364 if (s
->condexec_mask
) {
10365 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10366 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10368 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10369 gen_logic_CC(tmp2
);
10372 case 0x8: /* tst */
10373 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10377 case 0x9: /* neg */
10378 if (s
->condexec_mask
)
10379 tcg_gen_neg_i32(tmp
, tmp2
);
10381 gen_sub_CC(tmp
, tmp
, tmp2
);
10383 case 0xa: /* cmp */
10384 gen_sub_CC(tmp
, tmp
, tmp2
);
10387 case 0xb: /* cmn */
10388 gen_add_CC(tmp
, tmp
, tmp2
);
10391 case 0xc: /* orr */
10392 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10393 if (!s
->condexec_mask
)
10396 case 0xd: /* mul */
10397 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10398 if (!s
->condexec_mask
)
10401 case 0xe: /* bic */
10402 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10403 if (!s
->condexec_mask
)
10406 case 0xf: /* mvn */
10407 tcg_gen_not_i32(tmp2
, tmp2
);
10408 if (!s
->condexec_mask
)
10409 gen_logic_CC(tmp2
);
10416 store_reg(s
, rm
, tmp2
);
10418 tcg_temp_free_i32(tmp
);
10420 store_reg(s
, rd
, tmp
);
10421 tcg_temp_free_i32(tmp2
);
10424 tcg_temp_free_i32(tmp
);
10425 tcg_temp_free_i32(tmp2
);
10430 /* load/store register offset. */
10432 rn
= (insn
>> 3) & 7;
10433 rm
= (insn
>> 6) & 7;
10434 op
= (insn
>> 9) & 7;
10435 addr
= load_reg(s
, rn
);
10436 tmp
= load_reg(s
, rm
);
10437 tcg_gen_add_i32(addr
, addr
, tmp
);
10438 tcg_temp_free_i32(tmp
);
10440 if (op
< 3) { /* store */
10441 tmp
= load_reg(s
, rd
);
10443 tmp
= tcg_temp_new_i32();
10448 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10451 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10454 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10456 case 3: /* ldrsb */
10457 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10460 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10463 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10466 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10468 case 7: /* ldrsh */
10469 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10472 if (op
>= 3) { /* load */
10473 store_reg(s
, rd
, tmp
);
10475 tcg_temp_free_i32(tmp
);
10477 tcg_temp_free_i32(addr
);
10481 /* load/store word immediate offset */
10483 rn
= (insn
>> 3) & 7;
10484 addr
= load_reg(s
, rn
);
10485 val
= (insn
>> 4) & 0x7c;
10486 tcg_gen_addi_i32(addr
, addr
, val
);
10488 if (insn
& (1 << 11)) {
10490 tmp
= tcg_temp_new_i32();
10491 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10492 store_reg(s
, rd
, tmp
);
10495 tmp
= load_reg(s
, rd
);
10496 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10497 tcg_temp_free_i32(tmp
);
10499 tcg_temp_free_i32(addr
);
10503 /* load/store byte immediate offset */
10505 rn
= (insn
>> 3) & 7;
10506 addr
= load_reg(s
, rn
);
10507 val
= (insn
>> 6) & 0x1f;
10508 tcg_gen_addi_i32(addr
, addr
, val
);
10510 if (insn
& (1 << 11)) {
10512 tmp
= tcg_temp_new_i32();
10513 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10514 store_reg(s
, rd
, tmp
);
10517 tmp
= load_reg(s
, rd
);
10518 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10519 tcg_temp_free_i32(tmp
);
10521 tcg_temp_free_i32(addr
);
10525 /* load/store halfword immediate offset */
10527 rn
= (insn
>> 3) & 7;
10528 addr
= load_reg(s
, rn
);
10529 val
= (insn
>> 5) & 0x3e;
10530 tcg_gen_addi_i32(addr
, addr
, val
);
10532 if (insn
& (1 << 11)) {
10534 tmp
= tcg_temp_new_i32();
10535 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10536 store_reg(s
, rd
, tmp
);
10539 tmp
= load_reg(s
, rd
);
10540 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10541 tcg_temp_free_i32(tmp
);
10543 tcg_temp_free_i32(addr
);
10547 /* load/store from stack */
10548 rd
= (insn
>> 8) & 7;
10549 addr
= load_reg(s
, 13);
10550 val
= (insn
& 0xff) * 4;
10551 tcg_gen_addi_i32(addr
, addr
, val
);
10553 if (insn
& (1 << 11)) {
10555 tmp
= tcg_temp_new_i32();
10556 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10557 store_reg(s
, rd
, tmp
);
10560 tmp
= load_reg(s
, rd
);
10561 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10562 tcg_temp_free_i32(tmp
);
10564 tcg_temp_free_i32(addr
);
10568 /* add to high reg */
10569 rd
= (insn
>> 8) & 7;
10570 if (insn
& (1 << 11)) {
10572 tmp
= load_reg(s
, 13);
10574 /* PC. bit 1 is ignored. */
10575 tmp
= tcg_temp_new_i32();
10576 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10578 val
= (insn
& 0xff) * 4;
10579 tcg_gen_addi_i32(tmp
, tmp
, val
);
10580 store_reg(s
, rd
, tmp
);
10585 op
= (insn
>> 8) & 0xf;
10588 /* adjust stack pointer */
10589 tmp
= load_reg(s
, 13);
10590 val
= (insn
& 0x7f) * 4;
10591 if (insn
& (1 << 7))
10592 val
= -(int32_t)val
;
10593 tcg_gen_addi_i32(tmp
, tmp
, val
);
10594 store_reg(s
, 13, tmp
);
10597 case 2: /* sign/zero extend. */
10600 rm
= (insn
>> 3) & 7;
10601 tmp
= load_reg(s
, rm
);
10602 switch ((insn
>> 6) & 3) {
10603 case 0: gen_sxth(tmp
); break;
10604 case 1: gen_sxtb(tmp
); break;
10605 case 2: gen_uxth(tmp
); break;
10606 case 3: gen_uxtb(tmp
); break;
10608 store_reg(s
, rd
, tmp
);
10610 case 4: case 5: case 0xc: case 0xd:
10612 addr
= load_reg(s
, 13);
10613 if (insn
& (1 << 8))
10617 for (i
= 0; i
< 8; i
++) {
10618 if (insn
& (1 << i
))
10621 if ((insn
& (1 << 11)) == 0) {
10622 tcg_gen_addi_i32(addr
, addr
, -offset
);
10624 for (i
= 0; i
< 8; i
++) {
10625 if (insn
& (1 << i
)) {
10626 if (insn
& (1 << 11)) {
10628 tmp
= tcg_temp_new_i32();
10629 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10630 store_reg(s
, i
, tmp
);
10633 tmp
= load_reg(s
, i
);
10634 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10635 tcg_temp_free_i32(tmp
);
10637 /* advance to the next address. */
10638 tcg_gen_addi_i32(addr
, addr
, 4);
10641 TCGV_UNUSED_I32(tmp
);
10642 if (insn
& (1 << 8)) {
10643 if (insn
& (1 << 11)) {
10645 tmp
= tcg_temp_new_i32();
10646 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10647 /* don't set the pc until the rest of the instruction
10651 tmp
= load_reg(s
, 14);
10652 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10653 tcg_temp_free_i32(tmp
);
10655 tcg_gen_addi_i32(addr
, addr
, 4);
10657 if ((insn
& (1 << 11)) == 0) {
10658 tcg_gen_addi_i32(addr
, addr
, -offset
);
10660 /* write back the new stack pointer */
10661 store_reg(s
, 13, addr
);
10662 /* set the new PC value */
10663 if ((insn
& 0x0900) == 0x0900) {
10664 store_reg_from_load(env
, s
, 15, tmp
);
10668 case 1: case 3: case 9: case 11: /* czb */
10670 tmp
= load_reg(s
, rm
);
10671 s
->condlabel
= gen_new_label();
10673 if (insn
& (1 << 11))
10674 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10676 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10677 tcg_temp_free_i32(tmp
);
10678 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10679 val
= (uint32_t)s
->pc
+ 2;
10684 case 15: /* IT, nop-hint. */
10685 if ((insn
& 0xf) == 0) {
10686 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10690 s
->condexec_cond
= (insn
>> 4) & 0xe;
10691 s
->condexec_mask
= insn
& 0x1f;
10692 /* No actual code generated for this insn, just setup state. */
10695 case 0xe: /* bkpt */
10697 int imm8
= extract32(insn
, 0, 8);
10699 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10703 case 0xa: /* rev */
10705 rn
= (insn
>> 3) & 0x7;
10707 tmp
= load_reg(s
, rn
);
10708 switch ((insn
>> 6) & 3) {
10709 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10710 case 1: gen_rev16(tmp
); break;
10711 case 3: gen_revsh(tmp
); break;
10712 default: goto illegal_op
;
10714 store_reg(s
, rd
, tmp
);
10718 switch ((insn
>> 5) & 7) {
10722 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10723 /* Dynamic endianness switching not implemented. */
10724 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10735 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10738 addr
= tcg_const_i32(19);
10739 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10740 tcg_temp_free_i32(addr
);
10744 addr
= tcg_const_i32(16);
10745 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10746 tcg_temp_free_i32(addr
);
10748 tcg_temp_free_i32(tmp
);
10751 if (insn
& (1 << 4)) {
10752 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10756 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10771 /* load/store multiple */
10772 TCGv_i32 loaded_var
;
10773 TCGV_UNUSED_I32(loaded_var
);
10774 rn
= (insn
>> 8) & 0x7;
10775 addr
= load_reg(s
, rn
);
10776 for (i
= 0; i
< 8; i
++) {
10777 if (insn
& (1 << i
)) {
10778 if (insn
& (1 << 11)) {
10780 tmp
= tcg_temp_new_i32();
10781 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10785 store_reg(s
, i
, tmp
);
10789 tmp
= load_reg(s
, i
);
10790 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10791 tcg_temp_free_i32(tmp
);
10793 /* advance to the next address */
10794 tcg_gen_addi_i32(addr
, addr
, 4);
10797 if ((insn
& (1 << rn
)) == 0) {
10798 /* base reg not in list: base register writeback */
10799 store_reg(s
, rn
, addr
);
10801 /* base reg in list: if load, complete it now */
10802 if (insn
& (1 << 11)) {
10803 store_reg(s
, rn
, loaded_var
);
10805 tcg_temp_free_i32(addr
);
10810 /* conditional branch or swi */
10811 cond
= (insn
>> 8) & 0xf;
10817 gen_set_pc_im(s
, s
->pc
);
10818 s
->svc_imm
= extract32(insn
, 0, 8);
10819 s
->is_jmp
= DISAS_SWI
;
10822 /* generate a conditional jump to next instruction */
10823 s
->condlabel
= gen_new_label();
10824 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10827 /* jump to the offset */
10828 val
= (uint32_t)s
->pc
+ 2;
10829 offset
= ((int32_t)insn
<< 24) >> 24;
10830 val
+= offset
<< 1;
10835 if (insn
& (1 << 11)) {
10836 if (disas_thumb2_insn(env
, s
, insn
))
10840 /* unconditional branch */
10841 val
= (uint32_t)s
->pc
;
10842 offset
= ((int32_t)insn
<< 21) >> 21;
10843 val
+= (offset
<< 1) + 2;
10848 if (disas_thumb2_insn(env
, s
, insn
))
10854 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10858 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10861 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10862 basic block 'tb'. If search_pc is TRUE, also generate PC
10863 information for each intermediate instruction. */
10864 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10865 TranslationBlock
*tb
,
10868 CPUState
*cs
= CPU(cpu
);
10869 CPUARMState
*env
= &cpu
->env
;
10870 DisasContext dc1
, *dc
= &dc1
;
10872 uint16_t *gen_opc_end
;
10874 target_ulong pc_start
;
10875 target_ulong next_page_start
;
10879 /* generate intermediate code */
10881 /* The A64 decoder has its own top level loop, because it doesn't need
10882 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10884 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10885 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10893 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10895 dc
->is_jmp
= DISAS_NEXT
;
10897 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10901 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10902 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10903 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10904 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10905 #if !defined(CONFIG_USER_ONLY)
10906 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10908 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
10909 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10910 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10911 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10912 dc
->cp_regs
= cpu
->cp_regs
;
10913 dc
->current_pl
= arm_current_pl(env
);
10914 dc
->features
= env
->features
;
10916 cpu_F0s
= tcg_temp_new_i32();
10917 cpu_F1s
= tcg_temp_new_i32();
10918 cpu_F0d
= tcg_temp_new_i64();
10919 cpu_F1d
= tcg_temp_new_i64();
10922 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10923 cpu_M0
= tcg_temp_new_i64();
10924 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10927 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10928 if (max_insns
== 0)
10929 max_insns
= CF_COUNT_MASK
;
10933 tcg_clear_temp_count();
10935 /* A note on handling of the condexec (IT) bits:
10937 * We want to avoid the overhead of having to write the updated condexec
10938 * bits back to the CPUARMState for every instruction in an IT block. So:
10939 * (1) if the condexec bits are not already zero then we write
10940 * zero back into the CPUARMState now. This avoids complications trying
10941 * to do it at the end of the block. (For example if we don't do this
10942 * it's hard to identify whether we can safely skip writing condexec
10943 * at the end of the TB, which we definitely want to do for the case
10944 * where a TB doesn't do anything with the IT state at all.)
10945 * (2) if we are going to leave the TB then we call gen_set_condexec()
10946 * which will write the correct value into CPUARMState if zero is wrong.
10947 * This is done both for leaving the TB at the end, and for leaving
10948 * it because of an exception we know will happen, which is done in
10949 * gen_exception_insn(). The latter is necessary because we need to
10950 * leave the TB with the PC/IT state just prior to execution of the
10951 * instruction which caused the exception.
10952 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10953 * then the CPUARMState will be wrong and we need to reset it.
10954 * This is handled in the same way as restoration of the
10955 * PC in these situations: we will be called again with search_pc=1
10956 * and generate a mapping of the condexec bits for each PC in
10957 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10958 * this to restore the condexec bits.
10960 * Note that there are no instructions which can read the condexec
10961 * bits, and none which can write non-static values to them, so
10962 * we don't need to care about whether CPUARMState is correct in the
10966 /* Reset the conditional execution bits immediately. This avoids
10967 complications trying to do it at the end of the block. */
10968 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10970 TCGv_i32 tmp
= tcg_temp_new_i32();
10971 tcg_gen_movi_i32(tmp
, 0);
10972 store_cpu_field(tmp
, condexec_bits
);
10975 #ifdef CONFIG_USER_ONLY
10976 /* Intercept jump to the magic kernel page. */
10977 if (dc
->pc
>= 0xffff0000) {
10978 /* We always get here via a jump, so know we are not in a
10979 conditional execution block. */
10980 gen_exception_internal(EXCP_KERNEL_TRAP
);
10981 dc
->is_jmp
= DISAS_UPDATE
;
10985 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10986 /* We always get here via a jump, so know we are not in a
10987 conditional execution block. */
10988 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
10989 dc
->is_jmp
= DISAS_UPDATE
;
10994 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
10995 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
10996 if (bp
->pc
== dc
->pc
) {
10997 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
10998 /* Advance PC so that clearing the breakpoint will
10999 invalidate this TB. */
11001 goto done_generating
;
11006 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11010 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11012 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11013 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11014 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11015 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11018 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11021 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11022 tcg_gen_debug_insn_start(dc
->pc
);
11026 disas_thumb_insn(env
, dc
);
11027 if (dc
->condexec_mask
) {
11028 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11029 | ((dc
->condexec_mask
>> 4) & 1);
11030 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11031 if (dc
->condexec_mask
== 0) {
11032 dc
->condexec_cond
= 0;
11036 disas_arm_insn(env
, dc
);
11039 if (dc
->condjmp
&& !dc
->is_jmp
) {
11040 gen_set_label(dc
->condlabel
);
11044 if (tcg_check_temp_count()) {
11045 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11049 /* Translation stops when a conditional branch is encountered.
11050 * Otherwise the subsequent code could get translated several times.
11051 * Also stop translation when a page boundary is reached. This
11052 * ensures prefetch aborts occur at the right place. */
11054 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11055 !cs
->singlestep_enabled
&&
11057 dc
->pc
< next_page_start
&&
11058 num_insns
< max_insns
);
11060 if (tb
->cflags
& CF_LAST_IO
) {
11062 /* FIXME: This can theoretically happen with self-modifying
11064 cpu_abort(cs
, "IO on conditional branch instruction");
11069 /* At this stage dc->condjmp will only be set when the skipped
11070 instruction was a conditional branch or trap, and the PC has
11071 already been written. */
11072 if (unlikely(cs
->singlestep_enabled
)) {
11073 /* Make sure the pc is updated, and raise a debug exception. */
11075 gen_set_condexec(dc
);
11076 if (dc
->is_jmp
== DISAS_SWI
) {
11077 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11079 gen_exception_internal(EXCP_DEBUG
);
11081 gen_set_label(dc
->condlabel
);
11083 if (dc
->condjmp
|| !dc
->is_jmp
) {
11084 gen_set_pc_im(dc
, dc
->pc
);
11087 gen_set_condexec(dc
);
11088 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11089 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11091 /* FIXME: Single stepping a WFI insn will not halt
11093 gen_exception_internal(EXCP_DEBUG
);
11096 /* While branches must always occur at the end of an IT block,
11097 there are a few other things that can cause us to terminate
11098 the TB in the middle of an IT block:
11099 - Exception generating instructions (bkpt, swi, undefined).
11101 - Hardware watchpoints.
11102 Hardware breakpoints have already been handled and skip this code.
11104 gen_set_condexec(dc
);
11105 switch(dc
->is_jmp
) {
11107 gen_goto_tb(dc
, 1, dc
->pc
);
11112 /* indicate that the hash table must be used to find the next TB */
11113 tcg_gen_exit_tb(0);
11115 case DISAS_TB_JUMP
:
11116 /* nothing more to generate */
11119 gen_helper_wfi(cpu_env
);
11122 gen_helper_wfe(cpu_env
);
11125 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11129 gen_set_label(dc
->condlabel
);
11130 gen_set_condexec(dc
);
11131 gen_goto_tb(dc
, 1, dc
->pc
);
11137 gen_tb_end(tb
, num_insns
);
11138 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11141 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11142 qemu_log("----------------\n");
11143 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11144 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11145 dc
->thumb
| (dc
->bswap_code
<< 1));
11150 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11153 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11155 tb
->size
= dc
->pc
- pc_start
;
11156 tb
->icount
= num_insns
;
11160 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11162 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11165 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11167 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11170 static const char *cpu_mode_names
[16] = {
11171 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11172 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11175 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11178 ARMCPU
*cpu
= ARM_CPU(cs
);
11179 CPUARMState
*env
= &cpu
->env
;
11184 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11188 for(i
=0;i
<16;i
++) {
11189 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11191 cpu_fprintf(f
, "\n");
11193 cpu_fprintf(f
, " ");
11195 psr
= cpsr_read(env
);
11196 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11198 psr
& (1 << 31) ? 'N' : '-',
11199 psr
& (1 << 30) ? 'Z' : '-',
11200 psr
& (1 << 29) ? 'C' : '-',
11201 psr
& (1 << 28) ? 'V' : '-',
11202 psr
& CPSR_T
? 'T' : 'A',
11203 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11205 if (flags
& CPU_DUMP_FPU
) {
11206 int numvfpregs
= 0;
11207 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11210 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11213 for (i
= 0; i
< numvfpregs
; i
++) {
11214 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11215 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11216 i
* 2, (uint32_t)v
,
11217 i
* 2 + 1, (uint32_t)(v
>> 32),
11220 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11224 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11227 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11228 env
->condexec_bits
= 0;
11230 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11231 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];