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 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
66 static TCGv_i32 cpu_R
[16];
67 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
68 static TCGv_i64 cpu_exclusive_addr
;
69 static TCGv_i64 cpu_exclusive_val
;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test
;
72 static TCGv_i32 cpu_exclusive_info
;
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s
, cpu_F1s
;
77 static TCGv_i64 cpu_F0d
, cpu_F1d
;
79 #include "exec/gen-icount.h"
81 static const char *regnames
[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
90 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
92 for (i
= 0; i
< 16; i
++) {
93 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
94 offsetof(CPUARMState
, regs
[i
]),
97 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
98 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
99 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
100 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
102 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
103 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
104 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
108 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
109 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
110 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
113 a64_translate_init();
116 static inline TCGv_i32
load_cpu_offset(int offset
)
118 TCGv_i32 tmp
= tcg_temp_new_i32();
119 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
123 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
125 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
127 tcg_gen_st_i32(var
, cpu_env
, offset
);
128 tcg_temp_free_i32(var
);
131 #define store_cpu_field(var, name) \
132 store_cpu_offset(var, offsetof(CPUARMState, name))
134 /* Set a variable to the value of a CPU register. */
135 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
139 /* normally, since we updated PC, we need only to add one insn */
141 addr
= (long)s
->pc
+ 2;
143 addr
= (long)s
->pc
+ 4;
144 tcg_gen_movi_i32(var
, addr
);
146 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
150 /* Create a new temporary and set it to the value of a CPU register. */
151 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
153 TCGv_i32 tmp
= tcg_temp_new_i32();
154 load_reg_var(s
, tmp
, reg
);
158 /* Set a CPU register. The source must be a temporary and will be
160 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
163 tcg_gen_andi_i32(var
, var
, ~1);
164 s
->is_jmp
= DISAS_JUMP
;
166 tcg_gen_mov_i32(cpu_R
[reg
], var
);
167 tcg_temp_free_i32(var
);
170 /* Value extensions. */
171 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
172 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
173 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
174 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
176 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
177 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
180 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
182 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
183 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
184 tcg_temp_free_i32(tmp_mask
);
186 /* Set NZCV flags from the high 4 bits of var. */
187 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
189 static void gen_exception_internal(int excp
)
191 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
193 assert(excp_is_internal(excp
));
194 gen_helper_exception_internal(cpu_env
, tcg_excp
);
195 tcg_temp_free_i32(tcg_excp
);
198 static void gen_exception(int excp
, uint32_t syndrome
)
200 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
201 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
203 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
204 tcg_temp_free_i32(tcg_syn
);
205 tcg_temp_free_i32(tcg_excp
);
208 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
210 TCGv_i32 tmp1
= tcg_temp_new_i32();
211 TCGv_i32 tmp2
= tcg_temp_new_i32();
212 tcg_gen_ext16s_i32(tmp1
, a
);
213 tcg_gen_ext16s_i32(tmp2
, b
);
214 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
215 tcg_temp_free_i32(tmp2
);
216 tcg_gen_sari_i32(a
, a
, 16);
217 tcg_gen_sari_i32(b
, b
, 16);
218 tcg_gen_mul_i32(b
, b
, a
);
219 tcg_gen_mov_i32(a
, tmp1
);
220 tcg_temp_free_i32(tmp1
);
223 /* Byteswap each halfword. */
224 static void gen_rev16(TCGv_i32 var
)
226 TCGv_i32 tmp
= tcg_temp_new_i32();
227 tcg_gen_shri_i32(tmp
, var
, 8);
228 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
229 tcg_gen_shli_i32(var
, var
, 8);
230 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
231 tcg_gen_or_i32(var
, var
, tmp
);
232 tcg_temp_free_i32(tmp
);
235 /* Byteswap low halfword and sign extend. */
236 static void gen_revsh(TCGv_i32 var
)
238 tcg_gen_ext16u_i32(var
, var
);
239 tcg_gen_bswap16_i32(var
, var
);
240 tcg_gen_ext16s_i32(var
, var
);
243 /* Unsigned bitfield extract. */
244 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
247 tcg_gen_shri_i32(var
, var
, shift
);
248 tcg_gen_andi_i32(var
, var
, mask
);
251 /* Signed bitfield extract. */
252 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
257 tcg_gen_sari_i32(var
, var
, shift
);
258 if (shift
+ width
< 32) {
259 signbit
= 1u << (width
- 1);
260 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
261 tcg_gen_xori_i32(var
, var
, signbit
);
262 tcg_gen_subi_i32(var
, var
, signbit
);
266 /* Return (b << 32) + a. Mark inputs as dead */
267 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
269 TCGv_i64 tmp64
= tcg_temp_new_i64();
271 tcg_gen_extu_i32_i64(tmp64
, b
);
272 tcg_temp_free_i32(b
);
273 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
274 tcg_gen_add_i64(a
, tmp64
, a
);
276 tcg_temp_free_i64(tmp64
);
280 /* Return (b << 32) - a. Mark inputs as dead. */
281 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
283 TCGv_i64 tmp64
= tcg_temp_new_i64();
285 tcg_gen_extu_i32_i64(tmp64
, b
);
286 tcg_temp_free_i32(b
);
287 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
288 tcg_gen_sub_i64(a
, tmp64
, a
);
290 tcg_temp_free_i64(tmp64
);
294 /* 32x32->64 multiply. Marks inputs as dead. */
295 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
297 TCGv_i32 lo
= tcg_temp_new_i32();
298 TCGv_i32 hi
= tcg_temp_new_i32();
301 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
302 tcg_temp_free_i32(a
);
303 tcg_temp_free_i32(b
);
305 ret
= tcg_temp_new_i64();
306 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
307 tcg_temp_free_i32(lo
);
308 tcg_temp_free_i32(hi
);
313 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
315 TCGv_i32 lo
= tcg_temp_new_i32();
316 TCGv_i32 hi
= tcg_temp_new_i32();
319 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
320 tcg_temp_free_i32(a
);
321 tcg_temp_free_i32(b
);
323 ret
= tcg_temp_new_i64();
324 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
325 tcg_temp_free_i32(lo
);
326 tcg_temp_free_i32(hi
);
331 /* Swap low and high halfwords. */
332 static void gen_swap_half(TCGv_i32 var
)
334 TCGv_i32 tmp
= tcg_temp_new_i32();
335 tcg_gen_shri_i32(tmp
, var
, 16);
336 tcg_gen_shli_i32(var
, var
, 16);
337 tcg_gen_or_i32(var
, var
, tmp
);
338 tcg_temp_free_i32(tmp
);
341 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
342 tmp = (t0 ^ t1) & 0x8000;
345 t0 = (t0 + t1) ^ tmp;
348 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
350 TCGv_i32 tmp
= tcg_temp_new_i32();
351 tcg_gen_xor_i32(tmp
, t0
, t1
);
352 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
353 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
354 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
355 tcg_gen_add_i32(t0
, t0
, t1
);
356 tcg_gen_xor_i32(t0
, t0
, tmp
);
357 tcg_temp_free_i32(tmp
);
358 tcg_temp_free_i32(t1
);
361 /* Set CF to the top bit of var. */
362 static void gen_set_CF_bit31(TCGv_i32 var
)
364 tcg_gen_shri_i32(cpu_CF
, var
, 31);
367 /* Set N and Z flags from var. */
368 static inline void gen_logic_CC(TCGv_i32 var
)
370 tcg_gen_mov_i32(cpu_NF
, var
);
371 tcg_gen_mov_i32(cpu_ZF
, var
);
375 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
377 tcg_gen_add_i32(t0
, t0
, t1
);
378 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
381 /* dest = T0 + T1 + CF. */
382 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
384 tcg_gen_add_i32(dest
, t0
, t1
);
385 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
388 /* dest = T0 - T1 + CF - 1. */
389 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
391 tcg_gen_sub_i32(dest
, t0
, t1
);
392 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
393 tcg_gen_subi_i32(dest
, dest
, 1);
396 /* dest = T0 + T1. Compute C, N, V and Z flags */
397 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
399 TCGv_i32 tmp
= tcg_temp_new_i32();
400 tcg_gen_movi_i32(tmp
, 0);
401 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
402 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
403 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
404 tcg_gen_xor_i32(tmp
, t0
, t1
);
405 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
406 tcg_temp_free_i32(tmp
);
407 tcg_gen_mov_i32(dest
, cpu_NF
);
410 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
411 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
413 TCGv_i32 tmp
= tcg_temp_new_i32();
414 if (TCG_TARGET_HAS_add2_i32
) {
415 tcg_gen_movi_i32(tmp
, 0);
416 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
417 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
419 TCGv_i64 q0
= tcg_temp_new_i64();
420 TCGv_i64 q1
= tcg_temp_new_i64();
421 tcg_gen_extu_i32_i64(q0
, t0
);
422 tcg_gen_extu_i32_i64(q1
, t1
);
423 tcg_gen_add_i64(q0
, q0
, q1
);
424 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
425 tcg_gen_add_i64(q0
, q0
, q1
);
426 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
427 tcg_temp_free_i64(q0
);
428 tcg_temp_free_i64(q1
);
430 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
431 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
432 tcg_gen_xor_i32(tmp
, t0
, t1
);
433 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
434 tcg_temp_free_i32(tmp
);
435 tcg_gen_mov_i32(dest
, cpu_NF
);
438 /* dest = T0 - T1. Compute C, N, V and Z flags */
439 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
442 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
443 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
444 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
445 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
446 tmp
= tcg_temp_new_i32();
447 tcg_gen_xor_i32(tmp
, t0
, t1
);
448 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
449 tcg_temp_free_i32(tmp
);
450 tcg_gen_mov_i32(dest
, cpu_NF
);
453 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
454 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
456 TCGv_i32 tmp
= tcg_temp_new_i32();
457 tcg_gen_not_i32(tmp
, t1
);
458 gen_adc_CC(dest
, t0
, tmp
);
459 tcg_temp_free_i32(tmp
);
462 #define GEN_SHIFT(name) \
463 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
465 TCGv_i32 tmp1, tmp2, tmp3; \
466 tmp1 = tcg_temp_new_i32(); \
467 tcg_gen_andi_i32(tmp1, t1, 0xff); \
468 tmp2 = tcg_const_i32(0); \
469 tmp3 = tcg_const_i32(0x1f); \
470 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
471 tcg_temp_free_i32(tmp3); \
472 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
473 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
474 tcg_temp_free_i32(tmp2); \
475 tcg_temp_free_i32(tmp1); \
481 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
484 tmp1
= tcg_temp_new_i32();
485 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
486 tmp2
= tcg_const_i32(0x1f);
487 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
488 tcg_temp_free_i32(tmp2
);
489 tcg_gen_sar_i32(dest
, t0
, tmp1
);
490 tcg_temp_free_i32(tmp1
);
493 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
495 TCGv_i32 c0
= tcg_const_i32(0);
496 TCGv_i32 tmp
= tcg_temp_new_i32();
497 tcg_gen_neg_i32(tmp
, src
);
498 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
499 tcg_temp_free_i32(c0
);
500 tcg_temp_free_i32(tmp
);
503 static void shifter_out_im(TCGv_i32 var
, int shift
)
506 tcg_gen_andi_i32(cpu_CF
, var
, 1);
508 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
510 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
515 /* Shift by immediate. Includes special handling for shift == 0. */
516 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
517 int shift
, int flags
)
523 shifter_out_im(var
, 32 - shift
);
524 tcg_gen_shli_i32(var
, var
, shift
);
530 tcg_gen_shri_i32(cpu_CF
, var
, 31);
532 tcg_gen_movi_i32(var
, 0);
535 shifter_out_im(var
, shift
- 1);
536 tcg_gen_shri_i32(var
, var
, shift
);
543 shifter_out_im(var
, shift
- 1);
546 tcg_gen_sari_i32(var
, var
, shift
);
548 case 3: /* ROR/RRX */
551 shifter_out_im(var
, shift
- 1);
552 tcg_gen_rotri_i32(var
, var
, shift
); break;
554 TCGv_i32 tmp
= tcg_temp_new_i32();
555 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
557 shifter_out_im(var
, 0);
558 tcg_gen_shri_i32(var
, var
, 1);
559 tcg_gen_or_i32(var
, var
, tmp
);
560 tcg_temp_free_i32(tmp
);
565 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
566 TCGv_i32 shift
, int flags
)
570 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
571 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
572 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
573 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
578 gen_shl(var
, var
, shift
);
581 gen_shr(var
, var
, shift
);
584 gen_sar(var
, var
, shift
);
586 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
587 tcg_gen_rotr_i32(var
, var
, shift
); break;
590 tcg_temp_free_i32(shift
);
593 #define PAS_OP(pfx) \
595 case 0: gen_pas_helper(glue(pfx,add16)); break; \
596 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
597 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
598 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
599 case 4: gen_pas_helper(glue(pfx,add8)); break; \
600 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
602 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
607 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
609 tmp
= tcg_temp_new_ptr();
610 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
612 tcg_temp_free_ptr(tmp
);
615 tmp
= tcg_temp_new_ptr();
616 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
618 tcg_temp_free_ptr(tmp
);
620 #undef gen_pas_helper
621 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
634 #undef gen_pas_helper
639 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
640 #define PAS_OP(pfx) \
642 case 0: gen_pas_helper(glue(pfx,add8)); break; \
643 case 1: gen_pas_helper(glue(pfx,add16)); break; \
644 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
645 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
646 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
647 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
649 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
654 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
656 tmp
= tcg_temp_new_ptr();
657 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
659 tcg_temp_free_ptr(tmp
);
662 tmp
= tcg_temp_new_ptr();
663 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
665 tcg_temp_free_ptr(tmp
);
667 #undef gen_pas_helper
668 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
681 #undef gen_pas_helper
687 * generate a conditional branch based on ARM condition code cc.
688 * This is common between ARM and Aarch64 targets.
690 void arm_gen_test_cc(int cc
, int label
)
697 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
706 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
709 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
712 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
715 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
718 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
720 case 8: /* hi: C && !Z */
721 inv
= gen_new_label();
722 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
723 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
726 case 9: /* ls: !C || Z */
727 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
728 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
730 case 10: /* ge: N == V -> N ^ V == 0 */
731 tmp
= tcg_temp_new_i32();
732 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
733 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
734 tcg_temp_free_i32(tmp
);
736 case 11: /* lt: N != V -> N ^ V != 0 */
737 tmp
= tcg_temp_new_i32();
738 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
739 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
740 tcg_temp_free_i32(tmp
);
742 case 12: /* gt: !Z && N == V */
743 inv
= gen_new_label();
744 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
745 tmp
= tcg_temp_new_i32();
746 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
747 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
748 tcg_temp_free_i32(tmp
);
751 case 13: /* le: Z || N != V */
752 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
753 tmp
= tcg_temp_new_i32();
754 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
755 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
756 tcg_temp_free_i32(tmp
);
759 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
764 static const uint8_t table_logic_cc
[16] = {
783 /* Set PC and Thumb state from an immediate address. */
784 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
788 s
->is_jmp
= DISAS_UPDATE
;
789 if (s
->thumb
!= (addr
& 1)) {
790 tmp
= tcg_temp_new_i32();
791 tcg_gen_movi_i32(tmp
, addr
& 1);
792 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
793 tcg_temp_free_i32(tmp
);
795 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
798 /* Set PC and Thumb state from var. var is marked as dead. */
799 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
801 s
->is_jmp
= DISAS_UPDATE
;
802 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
803 tcg_gen_andi_i32(var
, var
, 1);
804 store_cpu_field(var
, thumb
);
807 /* Variant of store_reg which uses branch&exchange logic when storing
808 to r15 in ARM architecture v7 and above. The source must be a temporary
809 and will be marked as dead. */
810 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
811 int reg
, TCGv_i32 var
)
813 if (reg
== 15 && ENABLE_ARCH_7
) {
816 store_reg(s
, reg
, var
);
820 /* Variant of store_reg which uses branch&exchange logic when storing
821 * to r15 in ARM architecture v5T and above. This is used for storing
822 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
823 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
824 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
825 int reg
, TCGv_i32 var
)
827 if (reg
== 15 && ENABLE_ARCH_5
) {
830 store_reg(s
, reg
, var
);
834 /* Abstractions of "generate code to do a guest load/store for
835 * AArch32", where a vaddr is always 32 bits (and is zero
836 * extended if we're a 64 bit core) and data is also
837 * 32 bits unless specifically doing a 64 bit access.
838 * These functions work like tcg_gen_qemu_{ld,st}* except
839 * that the address argument is TCGv_i32 rather than TCGv.
841 #if TARGET_LONG_BITS == 32
843 #define DO_GEN_LD(SUFF, OPC) \
844 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
846 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
849 #define DO_GEN_ST(SUFF, OPC) \
850 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
852 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
855 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
857 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
860 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
862 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
867 #define DO_GEN_LD(SUFF, OPC) \
868 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
870 TCGv addr64 = tcg_temp_new(); \
871 tcg_gen_extu_i32_i64(addr64, addr); \
872 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
873 tcg_temp_free(addr64); \
876 #define DO_GEN_ST(SUFF, OPC) \
877 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
879 TCGv addr64 = tcg_temp_new(); \
880 tcg_gen_extu_i32_i64(addr64, addr); \
881 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
882 tcg_temp_free(addr64); \
885 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
887 TCGv addr64
= tcg_temp_new();
888 tcg_gen_extu_i32_i64(addr64
, addr
);
889 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
890 tcg_temp_free(addr64
);
893 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
895 TCGv addr64
= tcg_temp_new();
896 tcg_gen_extu_i32_i64(addr64
, addr
);
897 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
898 tcg_temp_free(addr64
);
905 DO_GEN_LD(16s
, MO_TESW
)
906 DO_GEN_LD(16u, MO_TEUW
)
907 DO_GEN_LD(32u, MO_TEUL
)
909 DO_GEN_ST(16, MO_TEUW
)
910 DO_GEN_ST(32, MO_TEUL
)
912 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
914 tcg_gen_movi_i32(cpu_R
[15], val
);
918 gen_set_condexec (DisasContext
*s
)
920 if (s
->condexec_mask
) {
921 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
922 TCGv_i32 tmp
= tcg_temp_new_i32();
923 tcg_gen_movi_i32(tmp
, val
);
924 store_cpu_field(tmp
, condexec_bits
);
928 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
931 gen_set_pc_im(s
, s
->pc
- offset
);
932 gen_exception_internal(excp
);
933 s
->is_jmp
= DISAS_JUMP
;
936 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
939 gen_set_pc_im(s
, s
->pc
- offset
);
940 gen_exception(excp
, syn
);
941 s
->is_jmp
= DISAS_JUMP
;
944 /* Force a TB lookup after an instruction that changes the CPU state. */
945 static inline void gen_lookup_tb(DisasContext
*s
)
947 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
948 s
->is_jmp
= DISAS_UPDATE
;
951 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
954 int val
, rm
, shift
, shiftop
;
957 if (!(insn
& (1 << 25))) {
960 if (!(insn
& (1 << 23)))
963 tcg_gen_addi_i32(var
, var
, val
);
967 shift
= (insn
>> 7) & 0x1f;
968 shiftop
= (insn
>> 5) & 3;
969 offset
= load_reg(s
, rm
);
970 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
971 if (!(insn
& (1 << 23)))
972 tcg_gen_sub_i32(var
, var
, offset
);
974 tcg_gen_add_i32(var
, var
, offset
);
975 tcg_temp_free_i32(offset
);
979 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
980 int extra
, TCGv_i32 var
)
985 if (insn
& (1 << 22)) {
987 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
988 if (!(insn
& (1 << 23)))
992 tcg_gen_addi_i32(var
, var
, val
);
996 tcg_gen_addi_i32(var
, var
, extra
);
998 offset
= load_reg(s
, rm
);
999 if (!(insn
& (1 << 23)))
1000 tcg_gen_sub_i32(var
, var
, offset
);
1002 tcg_gen_add_i32(var
, var
, offset
);
1003 tcg_temp_free_i32(offset
);
1007 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1009 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1012 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1014 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1016 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1020 #define VFP_OP2(name) \
1021 static inline void gen_vfp_##name(int dp) \
1023 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1025 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1027 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1029 tcg_temp_free_ptr(fpst); \
1039 static inline void gen_vfp_F1_mul(int dp
)
1041 /* Like gen_vfp_mul() but put result in F1 */
1042 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1044 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1046 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1048 tcg_temp_free_ptr(fpst
);
1051 static inline void gen_vfp_F1_neg(int dp
)
1053 /* Like gen_vfp_neg() but put result in F1 */
1055 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1057 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1061 static inline void gen_vfp_abs(int dp
)
1064 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1066 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1069 static inline void gen_vfp_neg(int dp
)
1072 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1074 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1077 static inline void gen_vfp_sqrt(int dp
)
1080 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1082 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1085 static inline void gen_vfp_cmp(int dp
)
1088 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1090 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1093 static inline void gen_vfp_cmpe(int dp
)
1096 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1098 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1101 static inline void gen_vfp_F1_ld0(int dp
)
1104 tcg_gen_movi_i64(cpu_F1d
, 0);
1106 tcg_gen_movi_i32(cpu_F1s
, 0);
1109 #define VFP_GEN_ITOF(name) \
1110 static inline void gen_vfp_##name(int dp, int neon) \
1112 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1114 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1116 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1118 tcg_temp_free_ptr(statusptr); \
1125 #define VFP_GEN_FTOI(name) \
1126 static inline void gen_vfp_##name(int dp, int neon) \
1128 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1130 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1132 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1134 tcg_temp_free_ptr(statusptr); \
1143 #define VFP_GEN_FIX(name, round) \
1144 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1146 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1147 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1149 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1152 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1155 tcg_temp_free_i32(tmp_shift); \
1156 tcg_temp_free_ptr(statusptr); \
1158 VFP_GEN_FIX(tosh
, _round_to_zero
)
1159 VFP_GEN_FIX(tosl
, _round_to_zero
)
1160 VFP_GEN_FIX(touh
, _round_to_zero
)
1161 VFP_GEN_FIX(toul
, _round_to_zero
)
1168 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1171 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1173 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1177 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1180 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1182 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1187 vfp_reg_offset (int dp
, int reg
)
1190 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1192 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1193 + offsetof(CPU_DoubleU
, l
.upper
);
1195 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1196 + offsetof(CPU_DoubleU
, l
.lower
);
1200 /* Return the offset of a 32-bit piece of a NEON register.
1201 zero is the least significant end of the register. */
1203 neon_reg_offset (int reg
, int n
)
1207 return vfp_reg_offset(0, sreg
);
1210 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1212 TCGv_i32 tmp
= tcg_temp_new_i32();
1213 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1217 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1219 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1220 tcg_temp_free_i32(var
);
1223 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1225 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1228 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1230 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1233 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1234 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1235 #define tcg_gen_st_f32 tcg_gen_st_i32
1236 #define tcg_gen_st_f64 tcg_gen_st_i64
1238 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1241 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1243 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1246 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1249 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1251 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1254 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1257 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1259 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1262 #define ARM_CP_RW_BIT (1 << 20)
1264 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1266 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1269 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1271 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1274 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1276 TCGv_i32 var
= tcg_temp_new_i32();
1277 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1281 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1283 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1284 tcg_temp_free_i32(var
);
1287 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1289 iwmmxt_store_reg(cpu_M0
, rn
);
1292 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1294 iwmmxt_load_reg(cpu_M0
, rn
);
1297 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1299 iwmmxt_load_reg(cpu_V1
, rn
);
1300 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1303 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1305 iwmmxt_load_reg(cpu_V1
, rn
);
1306 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1309 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1311 iwmmxt_load_reg(cpu_V1
, rn
);
1312 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1315 #define IWMMXT_OP(name) \
1316 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1318 iwmmxt_load_reg(cpu_V1, rn); \
1319 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1322 #define IWMMXT_OP_ENV(name) \
1323 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1325 iwmmxt_load_reg(cpu_V1, rn); \
1326 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1329 #define IWMMXT_OP_ENV_SIZE(name) \
1330 IWMMXT_OP_ENV(name##b) \
1331 IWMMXT_OP_ENV(name##w) \
1332 IWMMXT_OP_ENV(name##l)
1334 #define IWMMXT_OP_ENV1(name) \
1335 static inline void gen_op_iwmmxt_##name##_M0(void) \
1337 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1351 IWMMXT_OP_ENV_SIZE(unpackl
)
1352 IWMMXT_OP_ENV_SIZE(unpackh
)
1354 IWMMXT_OP_ENV1(unpacklub
)
1355 IWMMXT_OP_ENV1(unpackluw
)
1356 IWMMXT_OP_ENV1(unpacklul
)
1357 IWMMXT_OP_ENV1(unpackhub
)
1358 IWMMXT_OP_ENV1(unpackhuw
)
1359 IWMMXT_OP_ENV1(unpackhul
)
1360 IWMMXT_OP_ENV1(unpacklsb
)
1361 IWMMXT_OP_ENV1(unpacklsw
)
1362 IWMMXT_OP_ENV1(unpacklsl
)
1363 IWMMXT_OP_ENV1(unpackhsb
)
1364 IWMMXT_OP_ENV1(unpackhsw
)
1365 IWMMXT_OP_ENV1(unpackhsl
)
1367 IWMMXT_OP_ENV_SIZE(cmpeq
)
1368 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1369 IWMMXT_OP_ENV_SIZE(cmpgts
)
1371 IWMMXT_OP_ENV_SIZE(mins
)
1372 IWMMXT_OP_ENV_SIZE(minu
)
1373 IWMMXT_OP_ENV_SIZE(maxs
)
1374 IWMMXT_OP_ENV_SIZE(maxu
)
1376 IWMMXT_OP_ENV_SIZE(subn
)
1377 IWMMXT_OP_ENV_SIZE(addn
)
1378 IWMMXT_OP_ENV_SIZE(subu
)
1379 IWMMXT_OP_ENV_SIZE(addu
)
1380 IWMMXT_OP_ENV_SIZE(subs
)
1381 IWMMXT_OP_ENV_SIZE(adds
)
1383 IWMMXT_OP_ENV(avgb0
)
1384 IWMMXT_OP_ENV(avgb1
)
1385 IWMMXT_OP_ENV(avgw0
)
1386 IWMMXT_OP_ENV(avgw1
)
1388 IWMMXT_OP_ENV(packuw
)
1389 IWMMXT_OP_ENV(packul
)
1390 IWMMXT_OP_ENV(packuq
)
1391 IWMMXT_OP_ENV(packsw
)
1392 IWMMXT_OP_ENV(packsl
)
1393 IWMMXT_OP_ENV(packsq
)
1395 static void gen_op_iwmmxt_set_mup(void)
1398 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1399 tcg_gen_ori_i32(tmp
, tmp
, 2);
1400 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1403 static void gen_op_iwmmxt_set_cup(void)
1406 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1407 tcg_gen_ori_i32(tmp
, tmp
, 1);
1408 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1411 static void gen_op_iwmmxt_setpsr_nz(void)
1413 TCGv_i32 tmp
= tcg_temp_new_i32();
1414 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1415 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1418 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1420 iwmmxt_load_reg(cpu_V1
, rn
);
1421 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1422 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1425 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1432 rd
= (insn
>> 16) & 0xf;
1433 tmp
= load_reg(s
, rd
);
1435 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1436 if (insn
& (1 << 24)) {
1438 if (insn
& (1 << 23))
1439 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1441 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1442 tcg_gen_mov_i32(dest
, tmp
);
1443 if (insn
& (1 << 21))
1444 store_reg(s
, rd
, tmp
);
1446 tcg_temp_free_i32(tmp
);
1447 } else if (insn
& (1 << 21)) {
1449 tcg_gen_mov_i32(dest
, tmp
);
1450 if (insn
& (1 << 23))
1451 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1453 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1454 store_reg(s
, rd
, tmp
);
1455 } else if (!(insn
& (1 << 23)))
1460 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1462 int rd
= (insn
>> 0) & 0xf;
1465 if (insn
& (1 << 8)) {
1466 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1469 tmp
= iwmmxt_load_creg(rd
);
1472 tmp
= tcg_temp_new_i32();
1473 iwmmxt_load_reg(cpu_V0
, rd
);
1474 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1476 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1477 tcg_gen_mov_i32(dest
, tmp
);
1478 tcg_temp_free_i32(tmp
);
1482 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1483 (ie. an undefined instruction). */
1484 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1487 int rdhi
, rdlo
, rd0
, rd1
, i
;
1489 TCGv_i32 tmp
, tmp2
, tmp3
;
1491 if ((insn
& 0x0e000e00) == 0x0c000000) {
1492 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1494 rdlo
= (insn
>> 12) & 0xf;
1495 rdhi
= (insn
>> 16) & 0xf;
1496 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1497 iwmmxt_load_reg(cpu_V0
, wrd
);
1498 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1499 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1500 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1501 } else { /* TMCRR */
1502 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1503 iwmmxt_store_reg(cpu_V0
, wrd
);
1504 gen_op_iwmmxt_set_mup();
1509 wrd
= (insn
>> 12) & 0xf;
1510 addr
= tcg_temp_new_i32();
1511 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1512 tcg_temp_free_i32(addr
);
1515 if (insn
& ARM_CP_RW_BIT
) {
1516 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1517 tmp
= tcg_temp_new_i32();
1518 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1519 iwmmxt_store_creg(wrd
, tmp
);
1522 if (insn
& (1 << 8)) {
1523 if (insn
& (1 << 22)) { /* WLDRD */
1524 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1526 } else { /* WLDRW wRd */
1527 tmp
= tcg_temp_new_i32();
1528 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1531 tmp
= tcg_temp_new_i32();
1532 if (insn
& (1 << 22)) { /* WLDRH */
1533 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1534 } else { /* WLDRB */
1535 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1539 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1540 tcg_temp_free_i32(tmp
);
1542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1545 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1546 tmp
= iwmmxt_load_creg(wrd
);
1547 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1549 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1550 tmp
= tcg_temp_new_i32();
1551 if (insn
& (1 << 8)) {
1552 if (insn
& (1 << 22)) { /* WSTRD */
1553 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1554 } else { /* WSTRW wRd */
1555 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1556 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1559 if (insn
& (1 << 22)) { /* WSTRH */
1560 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1561 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1562 } else { /* WSTRB */
1563 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1564 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1568 tcg_temp_free_i32(tmp
);
1570 tcg_temp_free_i32(addr
);
1574 if ((insn
& 0x0f000000) != 0x0e000000)
1577 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1578 case 0x000: /* WOR */
1579 wrd
= (insn
>> 12) & 0xf;
1580 rd0
= (insn
>> 0) & 0xf;
1581 rd1
= (insn
>> 16) & 0xf;
1582 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1583 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1584 gen_op_iwmmxt_setpsr_nz();
1585 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1586 gen_op_iwmmxt_set_mup();
1587 gen_op_iwmmxt_set_cup();
1589 case 0x011: /* TMCR */
1592 rd
= (insn
>> 12) & 0xf;
1593 wrd
= (insn
>> 16) & 0xf;
1595 case ARM_IWMMXT_wCID
:
1596 case ARM_IWMMXT_wCASF
:
1598 case ARM_IWMMXT_wCon
:
1599 gen_op_iwmmxt_set_cup();
1601 case ARM_IWMMXT_wCSSF
:
1602 tmp
= iwmmxt_load_creg(wrd
);
1603 tmp2
= load_reg(s
, rd
);
1604 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1605 tcg_temp_free_i32(tmp2
);
1606 iwmmxt_store_creg(wrd
, tmp
);
1608 case ARM_IWMMXT_wCGR0
:
1609 case ARM_IWMMXT_wCGR1
:
1610 case ARM_IWMMXT_wCGR2
:
1611 case ARM_IWMMXT_wCGR3
:
1612 gen_op_iwmmxt_set_cup();
1613 tmp
= load_reg(s
, rd
);
1614 iwmmxt_store_creg(wrd
, tmp
);
1620 case 0x100: /* WXOR */
1621 wrd
= (insn
>> 12) & 0xf;
1622 rd0
= (insn
>> 0) & 0xf;
1623 rd1
= (insn
>> 16) & 0xf;
1624 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1625 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1626 gen_op_iwmmxt_setpsr_nz();
1627 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1628 gen_op_iwmmxt_set_mup();
1629 gen_op_iwmmxt_set_cup();
1631 case 0x111: /* TMRC */
1634 rd
= (insn
>> 12) & 0xf;
1635 wrd
= (insn
>> 16) & 0xf;
1636 tmp
= iwmmxt_load_creg(wrd
);
1637 store_reg(s
, rd
, tmp
);
1639 case 0x300: /* WANDN */
1640 wrd
= (insn
>> 12) & 0xf;
1641 rd0
= (insn
>> 0) & 0xf;
1642 rd1
= (insn
>> 16) & 0xf;
1643 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1644 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1645 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1646 gen_op_iwmmxt_setpsr_nz();
1647 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1648 gen_op_iwmmxt_set_mup();
1649 gen_op_iwmmxt_set_cup();
1651 case 0x200: /* WAND */
1652 wrd
= (insn
>> 12) & 0xf;
1653 rd0
= (insn
>> 0) & 0xf;
1654 rd1
= (insn
>> 16) & 0xf;
1655 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1656 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1657 gen_op_iwmmxt_setpsr_nz();
1658 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1659 gen_op_iwmmxt_set_mup();
1660 gen_op_iwmmxt_set_cup();
1662 case 0x810: case 0xa10: /* WMADD */
1663 wrd
= (insn
>> 12) & 0xf;
1664 rd0
= (insn
>> 0) & 0xf;
1665 rd1
= (insn
>> 16) & 0xf;
1666 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1667 if (insn
& (1 << 21))
1668 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1670 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1671 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1672 gen_op_iwmmxt_set_mup();
1674 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1675 wrd
= (insn
>> 12) & 0xf;
1676 rd0
= (insn
>> 16) & 0xf;
1677 rd1
= (insn
>> 0) & 0xf;
1678 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1679 switch ((insn
>> 22) & 3) {
1681 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1684 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1687 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1692 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1693 gen_op_iwmmxt_set_mup();
1694 gen_op_iwmmxt_set_cup();
1696 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1697 wrd
= (insn
>> 12) & 0xf;
1698 rd0
= (insn
>> 16) & 0xf;
1699 rd1
= (insn
>> 0) & 0xf;
1700 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1701 switch ((insn
>> 22) & 3) {
1703 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1706 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1709 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1714 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1715 gen_op_iwmmxt_set_mup();
1716 gen_op_iwmmxt_set_cup();
1718 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1719 wrd
= (insn
>> 12) & 0xf;
1720 rd0
= (insn
>> 16) & 0xf;
1721 rd1
= (insn
>> 0) & 0xf;
1722 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1723 if (insn
& (1 << 22))
1724 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1726 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1727 if (!(insn
& (1 << 20)))
1728 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1729 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1730 gen_op_iwmmxt_set_mup();
1732 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1733 wrd
= (insn
>> 12) & 0xf;
1734 rd0
= (insn
>> 16) & 0xf;
1735 rd1
= (insn
>> 0) & 0xf;
1736 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1737 if (insn
& (1 << 21)) {
1738 if (insn
& (1 << 20))
1739 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1741 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1743 if (insn
& (1 << 20))
1744 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1746 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1748 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1749 gen_op_iwmmxt_set_mup();
1751 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1752 wrd
= (insn
>> 12) & 0xf;
1753 rd0
= (insn
>> 16) & 0xf;
1754 rd1
= (insn
>> 0) & 0xf;
1755 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1756 if (insn
& (1 << 21))
1757 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1759 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1760 if (!(insn
& (1 << 20))) {
1761 iwmmxt_load_reg(cpu_V1
, wrd
);
1762 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1765 gen_op_iwmmxt_set_mup();
1767 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1768 wrd
= (insn
>> 12) & 0xf;
1769 rd0
= (insn
>> 16) & 0xf;
1770 rd1
= (insn
>> 0) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1772 switch ((insn
>> 22) & 3) {
1774 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1777 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1780 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1786 gen_op_iwmmxt_set_mup();
1787 gen_op_iwmmxt_set_cup();
1789 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1790 wrd
= (insn
>> 12) & 0xf;
1791 rd0
= (insn
>> 16) & 0xf;
1792 rd1
= (insn
>> 0) & 0xf;
1793 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1794 if (insn
& (1 << 22)) {
1795 if (insn
& (1 << 20))
1796 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1798 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1800 if (insn
& (1 << 20))
1801 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1803 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1805 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1806 gen_op_iwmmxt_set_mup();
1807 gen_op_iwmmxt_set_cup();
1809 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1810 wrd
= (insn
>> 12) & 0xf;
1811 rd0
= (insn
>> 16) & 0xf;
1812 rd1
= (insn
>> 0) & 0xf;
1813 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1814 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1815 tcg_gen_andi_i32(tmp
, tmp
, 7);
1816 iwmmxt_load_reg(cpu_V1
, rd1
);
1817 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1818 tcg_temp_free_i32(tmp
);
1819 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1820 gen_op_iwmmxt_set_mup();
1822 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1823 if (((insn
>> 6) & 3) == 3)
1825 rd
= (insn
>> 12) & 0xf;
1826 wrd
= (insn
>> 16) & 0xf;
1827 tmp
= load_reg(s
, rd
);
1828 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1829 switch ((insn
>> 6) & 3) {
1831 tmp2
= tcg_const_i32(0xff);
1832 tmp3
= tcg_const_i32((insn
& 7) << 3);
1835 tmp2
= tcg_const_i32(0xffff);
1836 tmp3
= tcg_const_i32((insn
& 3) << 4);
1839 tmp2
= tcg_const_i32(0xffffffff);
1840 tmp3
= tcg_const_i32((insn
& 1) << 5);
1843 TCGV_UNUSED_I32(tmp2
);
1844 TCGV_UNUSED_I32(tmp3
);
1846 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1847 tcg_temp_free_i32(tmp3
);
1848 tcg_temp_free_i32(tmp2
);
1849 tcg_temp_free_i32(tmp
);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1854 rd
= (insn
>> 12) & 0xf;
1855 wrd
= (insn
>> 16) & 0xf;
1856 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1858 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1859 tmp
= tcg_temp_new_i32();
1860 switch ((insn
>> 22) & 3) {
1862 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1863 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1865 tcg_gen_ext8s_i32(tmp
, tmp
);
1867 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1871 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1872 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1874 tcg_gen_ext16s_i32(tmp
, tmp
);
1876 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1880 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1881 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1884 store_reg(s
, rd
, tmp
);
1886 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1887 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1889 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1890 switch ((insn
>> 22) & 3) {
1892 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1895 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1898 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1901 tcg_gen_shli_i32(tmp
, tmp
, 28);
1903 tcg_temp_free_i32(tmp
);
1905 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1906 if (((insn
>> 6) & 3) == 3)
1908 rd
= (insn
>> 12) & 0xf;
1909 wrd
= (insn
>> 16) & 0xf;
1910 tmp
= load_reg(s
, rd
);
1911 switch ((insn
>> 6) & 3) {
1913 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1916 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1919 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1922 tcg_temp_free_i32(tmp
);
1923 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1924 gen_op_iwmmxt_set_mup();
1926 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1927 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1929 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1930 tmp2
= tcg_temp_new_i32();
1931 tcg_gen_mov_i32(tmp2
, tmp
);
1932 switch ((insn
>> 22) & 3) {
1934 for (i
= 0; i
< 7; i
++) {
1935 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1936 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1940 for (i
= 0; i
< 3; i
++) {
1941 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1942 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1946 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1947 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1951 tcg_temp_free_i32(tmp2
);
1952 tcg_temp_free_i32(tmp
);
1954 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1955 wrd
= (insn
>> 12) & 0xf;
1956 rd0
= (insn
>> 16) & 0xf;
1957 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1958 switch ((insn
>> 22) & 3) {
1960 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1963 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1966 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1971 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1972 gen_op_iwmmxt_set_mup();
1974 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1975 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1977 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1978 tmp2
= tcg_temp_new_i32();
1979 tcg_gen_mov_i32(tmp2
, tmp
);
1980 switch ((insn
>> 22) & 3) {
1982 for (i
= 0; i
< 7; i
++) {
1983 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1984 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1988 for (i
= 0; i
< 3; i
++) {
1989 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1990 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1994 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1995 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1999 tcg_temp_free_i32(tmp2
);
2000 tcg_temp_free_i32(tmp
);
2002 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2003 rd
= (insn
>> 12) & 0xf;
2004 rd0
= (insn
>> 16) & 0xf;
2005 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2007 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2008 tmp
= tcg_temp_new_i32();
2009 switch ((insn
>> 22) & 3) {
2011 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2014 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2017 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2020 store_reg(s
, rd
, tmp
);
2022 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2023 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2024 wrd
= (insn
>> 12) & 0xf;
2025 rd0
= (insn
>> 16) & 0xf;
2026 rd1
= (insn
>> 0) & 0xf;
2027 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2028 switch ((insn
>> 22) & 3) {
2030 if (insn
& (1 << 21))
2031 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2033 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2036 if (insn
& (1 << 21))
2037 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2039 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2042 if (insn
& (1 << 21))
2043 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2045 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2050 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2051 gen_op_iwmmxt_set_mup();
2052 gen_op_iwmmxt_set_cup();
2054 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2055 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2056 wrd
= (insn
>> 12) & 0xf;
2057 rd0
= (insn
>> 16) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2059 switch ((insn
>> 22) & 3) {
2061 if (insn
& (1 << 21))
2062 gen_op_iwmmxt_unpacklsb_M0();
2064 gen_op_iwmmxt_unpacklub_M0();
2067 if (insn
& (1 << 21))
2068 gen_op_iwmmxt_unpacklsw_M0();
2070 gen_op_iwmmxt_unpackluw_M0();
2073 if (insn
& (1 << 21))
2074 gen_op_iwmmxt_unpacklsl_M0();
2076 gen_op_iwmmxt_unpacklul_M0();
2081 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2082 gen_op_iwmmxt_set_mup();
2083 gen_op_iwmmxt_set_cup();
2085 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2086 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2087 wrd
= (insn
>> 12) & 0xf;
2088 rd0
= (insn
>> 16) & 0xf;
2089 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2090 switch ((insn
>> 22) & 3) {
2092 if (insn
& (1 << 21))
2093 gen_op_iwmmxt_unpackhsb_M0();
2095 gen_op_iwmmxt_unpackhub_M0();
2098 if (insn
& (1 << 21))
2099 gen_op_iwmmxt_unpackhsw_M0();
2101 gen_op_iwmmxt_unpackhuw_M0();
2104 if (insn
& (1 << 21))
2105 gen_op_iwmmxt_unpackhsl_M0();
2107 gen_op_iwmmxt_unpackhul_M0();
2112 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2113 gen_op_iwmmxt_set_mup();
2114 gen_op_iwmmxt_set_cup();
2116 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2117 case 0x214: case 0x614: case 0xa14: case 0xe14:
2118 if (((insn
>> 22) & 3) == 0)
2120 wrd
= (insn
>> 12) & 0xf;
2121 rd0
= (insn
>> 16) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2123 tmp
= tcg_temp_new_i32();
2124 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2125 tcg_temp_free_i32(tmp
);
2128 switch ((insn
>> 22) & 3) {
2130 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2133 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2139 tcg_temp_free_i32(tmp
);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2141 gen_op_iwmmxt_set_mup();
2142 gen_op_iwmmxt_set_cup();
2144 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2145 case 0x014: case 0x414: case 0x814: case 0xc14:
2146 if (((insn
>> 22) & 3) == 0)
2148 wrd
= (insn
>> 12) & 0xf;
2149 rd0
= (insn
>> 16) & 0xf;
2150 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2151 tmp
= tcg_temp_new_i32();
2152 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2153 tcg_temp_free_i32(tmp
);
2156 switch ((insn
>> 22) & 3) {
2158 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2161 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2167 tcg_temp_free_i32(tmp
);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2169 gen_op_iwmmxt_set_mup();
2170 gen_op_iwmmxt_set_cup();
2172 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2173 case 0x114: case 0x514: case 0x914: case 0xd14:
2174 if (((insn
>> 22) & 3) == 0)
2176 wrd
= (insn
>> 12) & 0xf;
2177 rd0
= (insn
>> 16) & 0xf;
2178 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2179 tmp
= tcg_temp_new_i32();
2180 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2181 tcg_temp_free_i32(tmp
);
2184 switch ((insn
>> 22) & 3) {
2186 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2189 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2192 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2195 tcg_temp_free_i32(tmp
);
2196 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2197 gen_op_iwmmxt_set_mup();
2198 gen_op_iwmmxt_set_cup();
2200 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2201 case 0x314: case 0x714: case 0xb14: case 0xf14:
2202 if (((insn
>> 22) & 3) == 0)
2204 wrd
= (insn
>> 12) & 0xf;
2205 rd0
= (insn
>> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2207 tmp
= tcg_temp_new_i32();
2208 switch ((insn
>> 22) & 3) {
2210 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2211 tcg_temp_free_i32(tmp
);
2214 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2217 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2218 tcg_temp_free_i32(tmp
);
2221 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2224 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2225 tcg_temp_free_i32(tmp
);
2228 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2231 tcg_temp_free_i32(tmp
);
2232 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2233 gen_op_iwmmxt_set_mup();
2234 gen_op_iwmmxt_set_cup();
2236 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2237 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2238 wrd
= (insn
>> 12) & 0xf;
2239 rd0
= (insn
>> 16) & 0xf;
2240 rd1
= (insn
>> 0) & 0xf;
2241 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2242 switch ((insn
>> 22) & 3) {
2244 if (insn
& (1 << 21))
2245 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2247 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2250 if (insn
& (1 << 21))
2251 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2253 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2256 if (insn
& (1 << 21))
2257 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2259 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2264 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2265 gen_op_iwmmxt_set_mup();
2267 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2268 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2269 wrd
= (insn
>> 12) & 0xf;
2270 rd0
= (insn
>> 16) & 0xf;
2271 rd1
= (insn
>> 0) & 0xf;
2272 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2273 switch ((insn
>> 22) & 3) {
2275 if (insn
& (1 << 21))
2276 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2278 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2281 if (insn
& (1 << 21))
2282 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2284 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2287 if (insn
& (1 << 21))
2288 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2290 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2295 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2296 gen_op_iwmmxt_set_mup();
2298 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2299 case 0x402: case 0x502: case 0x602: case 0x702:
2300 wrd
= (insn
>> 12) & 0xf;
2301 rd0
= (insn
>> 16) & 0xf;
2302 rd1
= (insn
>> 0) & 0xf;
2303 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2304 tmp
= tcg_const_i32((insn
>> 20) & 3);
2305 iwmmxt_load_reg(cpu_V1
, rd1
);
2306 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2307 tcg_temp_free_i32(tmp
);
2308 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2309 gen_op_iwmmxt_set_mup();
2311 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2312 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2313 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2314 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2315 wrd
= (insn
>> 12) & 0xf;
2316 rd0
= (insn
>> 16) & 0xf;
2317 rd1
= (insn
>> 0) & 0xf;
2318 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2319 switch ((insn
>> 20) & 0xf) {
2321 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2324 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2327 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2330 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2333 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2336 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2339 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2342 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2345 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2350 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2351 gen_op_iwmmxt_set_mup();
2352 gen_op_iwmmxt_set_cup();
2354 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2355 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2356 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2357 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2358 wrd
= (insn
>> 12) & 0xf;
2359 rd0
= (insn
>> 16) & 0xf;
2360 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2361 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2362 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2363 tcg_temp_free_i32(tmp
);
2364 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2365 gen_op_iwmmxt_set_mup();
2366 gen_op_iwmmxt_set_cup();
2368 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2369 case 0x418: case 0x518: case 0x618: case 0x718:
2370 case 0x818: case 0x918: case 0xa18: case 0xb18:
2371 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2372 wrd
= (insn
>> 12) & 0xf;
2373 rd0
= (insn
>> 16) & 0xf;
2374 rd1
= (insn
>> 0) & 0xf;
2375 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2376 switch ((insn
>> 20) & 0xf) {
2378 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2381 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2384 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2387 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2390 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2393 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2396 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2399 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2402 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2407 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2408 gen_op_iwmmxt_set_mup();
2409 gen_op_iwmmxt_set_cup();
2411 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2412 case 0x408: case 0x508: case 0x608: case 0x708:
2413 case 0x808: case 0x908: case 0xa08: case 0xb08:
2414 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2415 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2417 wrd
= (insn
>> 12) & 0xf;
2418 rd0
= (insn
>> 16) & 0xf;
2419 rd1
= (insn
>> 0) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2421 switch ((insn
>> 22) & 3) {
2423 if (insn
& (1 << 21))
2424 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2426 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2429 if (insn
& (1 << 21))
2430 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2432 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2435 if (insn
& (1 << 21))
2436 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2438 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2441 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2442 gen_op_iwmmxt_set_mup();
2443 gen_op_iwmmxt_set_cup();
2445 case 0x201: case 0x203: case 0x205: case 0x207:
2446 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2447 case 0x211: case 0x213: case 0x215: case 0x217:
2448 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2449 wrd
= (insn
>> 5) & 0xf;
2450 rd0
= (insn
>> 12) & 0xf;
2451 rd1
= (insn
>> 0) & 0xf;
2452 if (rd0
== 0xf || rd1
== 0xf)
2454 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2455 tmp
= load_reg(s
, rd0
);
2456 tmp2
= load_reg(s
, rd1
);
2457 switch ((insn
>> 16) & 0xf) {
2458 case 0x0: /* TMIA */
2459 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2461 case 0x8: /* TMIAPH */
2462 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2464 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2465 if (insn
& (1 << 16))
2466 tcg_gen_shri_i32(tmp
, tmp
, 16);
2467 if (insn
& (1 << 17))
2468 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2469 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2472 tcg_temp_free_i32(tmp2
);
2473 tcg_temp_free_i32(tmp
);
2476 tcg_temp_free_i32(tmp2
);
2477 tcg_temp_free_i32(tmp
);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2479 gen_op_iwmmxt_set_mup();
2488 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2489 (ie. an undefined instruction). */
2490 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2492 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2495 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2496 /* Multiply with Internal Accumulate Format */
2497 rd0
= (insn
>> 12) & 0xf;
2499 acc
= (insn
>> 5) & 7;
2504 tmp
= load_reg(s
, rd0
);
2505 tmp2
= load_reg(s
, rd1
);
2506 switch ((insn
>> 16) & 0xf) {
2508 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2510 case 0x8: /* MIAPH */
2511 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2513 case 0xc: /* MIABB */
2514 case 0xd: /* MIABT */
2515 case 0xe: /* MIATB */
2516 case 0xf: /* MIATT */
2517 if (insn
& (1 << 16))
2518 tcg_gen_shri_i32(tmp
, tmp
, 16);
2519 if (insn
& (1 << 17))
2520 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2521 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2526 tcg_temp_free_i32(tmp2
);
2527 tcg_temp_free_i32(tmp
);
2529 gen_op_iwmmxt_movq_wRn_M0(acc
);
2533 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2534 /* Internal Accumulator Access Format */
2535 rdhi
= (insn
>> 16) & 0xf;
2536 rdlo
= (insn
>> 12) & 0xf;
2542 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2543 iwmmxt_load_reg(cpu_V0
, acc
);
2544 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2545 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2546 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2547 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2549 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2550 iwmmxt_store_reg(cpu_V0
, acc
);
2558 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2559 #define VFP_SREG(insn, bigbit, smallbit) \
2560 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2561 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2562 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2563 reg = (((insn) >> (bigbit)) & 0x0f) \
2564 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2566 if (insn & (1 << (smallbit))) \
2568 reg = ((insn) >> (bigbit)) & 0x0f; \
2571 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2572 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2573 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2574 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2575 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2576 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2578 /* Move between integer and VFP cores. */
2579 static TCGv_i32
gen_vfp_mrs(void)
2581 TCGv_i32 tmp
= tcg_temp_new_i32();
2582 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2586 static void gen_vfp_msr(TCGv_i32 tmp
)
2588 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2589 tcg_temp_free_i32(tmp
);
2592 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2594 TCGv_i32 tmp
= tcg_temp_new_i32();
2596 tcg_gen_shri_i32(var
, var
, shift
);
2597 tcg_gen_ext8u_i32(var
, var
);
2598 tcg_gen_shli_i32(tmp
, var
, 8);
2599 tcg_gen_or_i32(var
, var
, tmp
);
2600 tcg_gen_shli_i32(tmp
, var
, 16);
2601 tcg_gen_or_i32(var
, var
, tmp
);
2602 tcg_temp_free_i32(tmp
);
2605 static void gen_neon_dup_low16(TCGv_i32 var
)
2607 TCGv_i32 tmp
= tcg_temp_new_i32();
2608 tcg_gen_ext16u_i32(var
, var
);
2609 tcg_gen_shli_i32(tmp
, var
, 16);
2610 tcg_gen_or_i32(var
, var
, tmp
);
2611 tcg_temp_free_i32(tmp
);
2614 static void gen_neon_dup_high16(TCGv_i32 var
)
2616 TCGv_i32 tmp
= tcg_temp_new_i32();
2617 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2618 tcg_gen_shri_i32(tmp
, var
, 16);
2619 tcg_gen_or_i32(var
, var
, tmp
);
2620 tcg_temp_free_i32(tmp
);
2623 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2625 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2626 TCGv_i32 tmp
= tcg_temp_new_i32();
2629 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2630 gen_neon_dup_u8(tmp
, 0);
2633 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2634 gen_neon_dup_low16(tmp
);
2637 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2639 default: /* Avoid compiler warnings. */
2645 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2648 uint32_t cc
= extract32(insn
, 20, 2);
2651 TCGv_i64 frn
, frm
, dest
;
2652 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2654 zero
= tcg_const_i64(0);
2656 frn
= tcg_temp_new_i64();
2657 frm
= tcg_temp_new_i64();
2658 dest
= tcg_temp_new_i64();
2660 zf
= tcg_temp_new_i64();
2661 nf
= tcg_temp_new_i64();
2662 vf
= tcg_temp_new_i64();
2664 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2665 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2666 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2668 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2669 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2672 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2676 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2679 case 2: /* ge: N == V -> N ^ V == 0 */
2680 tmp
= tcg_temp_new_i64();
2681 tcg_gen_xor_i64(tmp
, vf
, nf
);
2682 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2684 tcg_temp_free_i64(tmp
);
2686 case 3: /* gt: !Z && N == V */
2687 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2689 tmp
= tcg_temp_new_i64();
2690 tcg_gen_xor_i64(tmp
, vf
, nf
);
2691 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2693 tcg_temp_free_i64(tmp
);
2696 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2697 tcg_temp_free_i64(frn
);
2698 tcg_temp_free_i64(frm
);
2699 tcg_temp_free_i64(dest
);
2701 tcg_temp_free_i64(zf
);
2702 tcg_temp_free_i64(nf
);
2703 tcg_temp_free_i64(vf
);
2705 tcg_temp_free_i64(zero
);
2707 TCGv_i32 frn
, frm
, dest
;
2710 zero
= tcg_const_i32(0);
2712 frn
= tcg_temp_new_i32();
2713 frm
= tcg_temp_new_i32();
2714 dest
= tcg_temp_new_i32();
2715 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2716 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2719 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2723 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2726 case 2: /* ge: N == V -> N ^ V == 0 */
2727 tmp
= tcg_temp_new_i32();
2728 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2729 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2731 tcg_temp_free_i32(tmp
);
2733 case 3: /* gt: !Z && N == V */
2734 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2736 tmp
= tcg_temp_new_i32();
2737 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2738 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2740 tcg_temp_free_i32(tmp
);
2743 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2744 tcg_temp_free_i32(frn
);
2745 tcg_temp_free_i32(frm
);
2746 tcg_temp_free_i32(dest
);
2748 tcg_temp_free_i32(zero
);
2754 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2755 uint32_t rm
, uint32_t dp
)
2757 uint32_t vmin
= extract32(insn
, 6, 1);
2758 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2761 TCGv_i64 frn
, frm
, dest
;
2763 frn
= tcg_temp_new_i64();
2764 frm
= tcg_temp_new_i64();
2765 dest
= tcg_temp_new_i64();
2767 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2768 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2770 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2772 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2774 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2775 tcg_temp_free_i64(frn
);
2776 tcg_temp_free_i64(frm
);
2777 tcg_temp_free_i64(dest
);
2779 TCGv_i32 frn
, frm
, dest
;
2781 frn
= tcg_temp_new_i32();
2782 frm
= tcg_temp_new_i32();
2783 dest
= tcg_temp_new_i32();
2785 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2786 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2788 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2790 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2792 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2793 tcg_temp_free_i32(frn
);
2794 tcg_temp_free_i32(frm
);
2795 tcg_temp_free_i32(dest
);
2798 tcg_temp_free_ptr(fpst
);
2802 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2805 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2808 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2809 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2814 tcg_op
= tcg_temp_new_i64();
2815 tcg_res
= tcg_temp_new_i64();
2816 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2817 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2818 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2819 tcg_temp_free_i64(tcg_op
);
2820 tcg_temp_free_i64(tcg_res
);
2824 tcg_op
= tcg_temp_new_i32();
2825 tcg_res
= tcg_temp_new_i32();
2826 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2827 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2828 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2829 tcg_temp_free_i32(tcg_op
);
2830 tcg_temp_free_i32(tcg_res
);
2833 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2834 tcg_temp_free_i32(tcg_rmode
);
2836 tcg_temp_free_ptr(fpst
);
2840 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2843 bool is_signed
= extract32(insn
, 7, 1);
2844 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2845 TCGv_i32 tcg_rmode
, tcg_shift
;
2847 tcg_shift
= tcg_const_i32(0);
2849 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2850 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2853 TCGv_i64 tcg_double
, tcg_res
;
2855 /* Rd is encoded as a single precision register even when the source
2856 * is double precision.
2858 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2859 tcg_double
= tcg_temp_new_i64();
2860 tcg_res
= tcg_temp_new_i64();
2861 tcg_tmp
= tcg_temp_new_i32();
2862 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2864 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2866 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2868 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2869 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2870 tcg_temp_free_i32(tcg_tmp
);
2871 tcg_temp_free_i64(tcg_res
);
2872 tcg_temp_free_i64(tcg_double
);
2874 TCGv_i32 tcg_single
, tcg_res
;
2875 tcg_single
= tcg_temp_new_i32();
2876 tcg_res
= tcg_temp_new_i32();
2877 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2879 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2881 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2883 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2884 tcg_temp_free_i32(tcg_res
);
2885 tcg_temp_free_i32(tcg_single
);
2888 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2889 tcg_temp_free_i32(tcg_rmode
);
2891 tcg_temp_free_i32(tcg_shift
);
2893 tcg_temp_free_ptr(fpst
);
2898 /* Table for converting the most common AArch32 encoding of
2899 * rounding mode to arm_fprounding order (which matches the
2900 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2902 static const uint8_t fp_decode_rm
[] = {
2909 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2911 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2913 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2918 VFP_DREG_D(rd
, insn
);
2919 VFP_DREG_N(rn
, insn
);
2920 VFP_DREG_M(rm
, insn
);
2922 rd
= VFP_SREG_D(insn
);
2923 rn
= VFP_SREG_N(insn
);
2924 rm
= VFP_SREG_M(insn
);
2927 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2928 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2929 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2930 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2931 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2932 /* VRINTA, VRINTN, VRINTP, VRINTM */
2933 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2934 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2935 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2936 /* VCVTA, VCVTN, VCVTP, VCVTM */
2937 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2938 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
2943 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2944 (ie. an undefined instruction). */
2945 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2947 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2953 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2956 /* FIXME: this access check should not take precedence over UNDEF
2957 * for invalid encodings; we will generate incorrect syndrome information
2958 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2960 if (!s
->cpacr_fpen
) {
2961 gen_exception_insn(s
, 4, EXCP_UDEF
,
2962 syn_fp_access_trap(1, 0xe, s
->thumb
));
2966 if (!s
->vfp_enabled
) {
2967 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2968 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2970 rn
= (insn
>> 16) & 0xf;
2971 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
2972 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
2977 if (extract32(insn
, 28, 4) == 0xf) {
2978 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2979 * only used in v8 and above.
2981 return disas_vfp_v8_insn(env
, s
, insn
);
2984 dp
= ((insn
& 0xf00) == 0xb00);
2985 switch ((insn
>> 24) & 0xf) {
2987 if (insn
& (1 << 4)) {
2988 /* single register transfer */
2989 rd
= (insn
>> 12) & 0xf;
2994 VFP_DREG_N(rn
, insn
);
2997 if (insn
& 0x00c00060
2998 && !arm_feature(env
, ARM_FEATURE_NEON
))
3001 pass
= (insn
>> 21) & 1;
3002 if (insn
& (1 << 22)) {
3004 offset
= ((insn
>> 5) & 3) * 8;
3005 } else if (insn
& (1 << 5)) {
3007 offset
= (insn
& (1 << 6)) ? 16 : 0;
3012 if (insn
& ARM_CP_RW_BIT
) {
3014 tmp
= neon_load_reg(rn
, pass
);
3018 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3019 if (insn
& (1 << 23))
3025 if (insn
& (1 << 23)) {
3027 tcg_gen_shri_i32(tmp
, tmp
, 16);
3033 tcg_gen_sari_i32(tmp
, tmp
, 16);
3042 store_reg(s
, rd
, tmp
);
3045 tmp
= load_reg(s
, rd
);
3046 if (insn
& (1 << 23)) {
3049 gen_neon_dup_u8(tmp
, 0);
3050 } else if (size
== 1) {
3051 gen_neon_dup_low16(tmp
);
3053 for (n
= 0; n
<= pass
* 2; n
++) {
3054 tmp2
= tcg_temp_new_i32();
3055 tcg_gen_mov_i32(tmp2
, tmp
);
3056 neon_store_reg(rn
, n
, tmp2
);
3058 neon_store_reg(rn
, n
, tmp
);
3063 tmp2
= neon_load_reg(rn
, pass
);
3064 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3065 tcg_temp_free_i32(tmp2
);
3068 tmp2
= neon_load_reg(rn
, pass
);
3069 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3070 tcg_temp_free_i32(tmp2
);
3075 neon_store_reg(rn
, pass
, tmp
);
3079 if ((insn
& 0x6f) != 0x00)
3081 rn
= VFP_SREG_N(insn
);
3082 if (insn
& ARM_CP_RW_BIT
) {
3084 if (insn
& (1 << 21)) {
3085 /* system register */
3090 /* VFP2 allows access to FSID from userspace.
3091 VFP3 restricts all id registers to privileged
3094 && arm_feature(env
, ARM_FEATURE_VFP3
))
3096 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3101 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3103 case ARM_VFP_FPINST
:
3104 case ARM_VFP_FPINST2
:
3105 /* Not present in VFP3. */
3107 || arm_feature(env
, ARM_FEATURE_VFP3
))
3109 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3113 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3114 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3116 tmp
= tcg_temp_new_i32();
3117 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3121 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3128 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3130 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3136 gen_mov_F0_vreg(0, rn
);
3137 tmp
= gen_vfp_mrs();
3140 /* Set the 4 flag bits in the CPSR. */
3142 tcg_temp_free_i32(tmp
);
3144 store_reg(s
, rd
, tmp
);
3148 if (insn
& (1 << 21)) {
3150 /* system register */
3155 /* Writes are ignored. */
3158 tmp
= load_reg(s
, rd
);
3159 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3160 tcg_temp_free_i32(tmp
);
3166 /* TODO: VFP subarchitecture support.
3167 * For now, keep the EN bit only */
3168 tmp
= load_reg(s
, rd
);
3169 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3170 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3173 case ARM_VFP_FPINST
:
3174 case ARM_VFP_FPINST2
:
3175 tmp
= load_reg(s
, rd
);
3176 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3182 tmp
= load_reg(s
, rd
);
3184 gen_mov_vreg_F0(0, rn
);
3189 /* data processing */
3190 /* The opcode is in bits 23, 21, 20 and 6. */
3191 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3195 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3197 /* rn is register number */
3198 VFP_DREG_N(rn
, insn
);
3201 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3202 ((rn
& 0x1e) == 0x6))) {
3203 /* Integer or single/half precision destination. */
3204 rd
= VFP_SREG_D(insn
);
3206 VFP_DREG_D(rd
, insn
);
3209 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3210 ((rn
& 0x1e) == 0x4))) {
3211 /* VCVT from int or half precision is always from S reg
3212 * regardless of dp bit. VCVT with immediate frac_bits
3213 * has same format as SREG_M.
3215 rm
= VFP_SREG_M(insn
);
3217 VFP_DREG_M(rm
, insn
);
3220 rn
= VFP_SREG_N(insn
);
3221 if (op
== 15 && rn
== 15) {
3222 /* Double precision destination. */
3223 VFP_DREG_D(rd
, insn
);
3225 rd
= VFP_SREG_D(insn
);
3227 /* NB that we implicitly rely on the encoding for the frac_bits
3228 * in VCVT of fixed to float being the same as that of an SREG_M
3230 rm
= VFP_SREG_M(insn
);
3233 veclen
= s
->vec_len
;
3234 if (op
== 15 && rn
> 3)
3237 /* Shut up compiler warnings. */
3248 /* Figure out what type of vector operation this is. */
3249 if ((rd
& bank_mask
) == 0) {
3254 delta_d
= (s
->vec_stride
>> 1) + 1;
3256 delta_d
= s
->vec_stride
+ 1;
3258 if ((rm
& bank_mask
) == 0) {
3259 /* mixed scalar/vector */
3268 /* Load the initial operands. */
3273 /* Integer source */
3274 gen_mov_F0_vreg(0, rm
);
3279 gen_mov_F0_vreg(dp
, rd
);
3280 gen_mov_F1_vreg(dp
, rm
);
3284 /* Compare with zero */
3285 gen_mov_F0_vreg(dp
, rd
);
3296 /* Source and destination the same. */
3297 gen_mov_F0_vreg(dp
, rd
);
3303 /* VCVTB, VCVTT: only present with the halfprec extension
3304 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3305 * (we choose to UNDEF)
3307 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3308 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3311 if (!extract32(rn
, 1, 1)) {
3312 /* Half precision source. */
3313 gen_mov_F0_vreg(0, rm
);
3316 /* Otherwise fall through */
3318 /* One source operand. */
3319 gen_mov_F0_vreg(dp
, rm
);
3323 /* Two source operands. */
3324 gen_mov_F0_vreg(dp
, rn
);
3325 gen_mov_F1_vreg(dp
, rm
);
3329 /* Perform the calculation. */
3331 case 0: /* VMLA: fd + (fn * fm) */
3332 /* Note that order of inputs to the add matters for NaNs */
3334 gen_mov_F0_vreg(dp
, rd
);
3337 case 1: /* VMLS: fd + -(fn * fm) */
3340 gen_mov_F0_vreg(dp
, rd
);
3343 case 2: /* VNMLS: -fd + (fn * fm) */
3344 /* Note that it isn't valid to replace (-A + B) with (B - A)
3345 * or similar plausible looking simplifications
3346 * because this will give wrong results for NaNs.
3349 gen_mov_F0_vreg(dp
, rd
);
3353 case 3: /* VNMLA: -fd + -(fn * fm) */
3356 gen_mov_F0_vreg(dp
, rd
);
3360 case 4: /* mul: fn * fm */
3363 case 5: /* nmul: -(fn * fm) */
3367 case 6: /* add: fn + fm */
3370 case 7: /* sub: fn - fm */
3373 case 8: /* div: fn / fm */
3376 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3377 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3378 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3379 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3380 /* These are fused multiply-add, and must be done as one
3381 * floating point operation with no rounding between the
3382 * multiplication and addition steps.
3383 * NB that doing the negations here as separate steps is
3384 * correct : an input NaN should come out with its sign bit
3385 * flipped if it is a negated-input.
3387 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3395 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3397 frd
= tcg_temp_new_i64();
3398 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3401 gen_helper_vfp_negd(frd
, frd
);
3403 fpst
= get_fpstatus_ptr(0);
3404 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3405 cpu_F1d
, frd
, fpst
);
3406 tcg_temp_free_ptr(fpst
);
3407 tcg_temp_free_i64(frd
);
3413 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3415 frd
= tcg_temp_new_i32();
3416 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3418 gen_helper_vfp_negs(frd
, frd
);
3420 fpst
= get_fpstatus_ptr(0);
3421 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3422 cpu_F1s
, frd
, fpst
);
3423 tcg_temp_free_ptr(fpst
);
3424 tcg_temp_free_i32(frd
);
3427 case 14: /* fconst */
3428 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3431 n
= (insn
<< 12) & 0x80000000;
3432 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3439 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3446 tcg_gen_movi_i32(cpu_F0s
, n
);
3449 case 15: /* extension space */
3463 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3464 tmp
= gen_vfp_mrs();
3465 tcg_gen_ext16u_i32(tmp
, tmp
);
3467 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3470 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3473 tcg_temp_free_i32(tmp
);
3475 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3476 tmp
= gen_vfp_mrs();
3477 tcg_gen_shri_i32(tmp
, tmp
, 16);
3479 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3482 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3485 tcg_temp_free_i32(tmp
);
3487 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3488 tmp
= tcg_temp_new_i32();
3490 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3493 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3496 gen_mov_F0_vreg(0, rd
);
3497 tmp2
= gen_vfp_mrs();
3498 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3499 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3500 tcg_temp_free_i32(tmp2
);
3503 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3504 tmp
= tcg_temp_new_i32();
3506 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3509 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3512 tcg_gen_shli_i32(tmp
, tmp
, 16);
3513 gen_mov_F0_vreg(0, rd
);
3514 tmp2
= gen_vfp_mrs();
3515 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3516 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3517 tcg_temp_free_i32(tmp2
);
3529 case 11: /* cmpez */
3533 case 12: /* vrintr */
3535 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3537 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3539 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3541 tcg_temp_free_ptr(fpst
);
3544 case 13: /* vrintz */
3546 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3548 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3549 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3551 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3553 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3555 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3556 tcg_temp_free_i32(tcg_rmode
);
3557 tcg_temp_free_ptr(fpst
);
3560 case 14: /* vrintx */
3562 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3564 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3566 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3568 tcg_temp_free_ptr(fpst
);
3571 case 15: /* single<->double conversion */
3573 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3575 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3577 case 16: /* fuito */
3578 gen_vfp_uito(dp
, 0);
3580 case 17: /* fsito */
3581 gen_vfp_sito(dp
, 0);
3583 case 20: /* fshto */
3584 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3586 gen_vfp_shto(dp
, 16 - rm
, 0);
3588 case 21: /* fslto */
3589 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3591 gen_vfp_slto(dp
, 32 - rm
, 0);
3593 case 22: /* fuhto */
3594 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3596 gen_vfp_uhto(dp
, 16 - rm
, 0);
3598 case 23: /* fulto */
3599 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3601 gen_vfp_ulto(dp
, 32 - rm
, 0);
3603 case 24: /* ftoui */
3604 gen_vfp_toui(dp
, 0);
3606 case 25: /* ftouiz */
3607 gen_vfp_touiz(dp
, 0);
3609 case 26: /* ftosi */
3610 gen_vfp_tosi(dp
, 0);
3612 case 27: /* ftosiz */
3613 gen_vfp_tosiz(dp
, 0);
3615 case 28: /* ftosh */
3616 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3618 gen_vfp_tosh(dp
, 16 - rm
, 0);
3620 case 29: /* ftosl */
3621 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3623 gen_vfp_tosl(dp
, 32 - rm
, 0);
3625 case 30: /* ftouh */
3626 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3628 gen_vfp_touh(dp
, 16 - rm
, 0);
3630 case 31: /* ftoul */
3631 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3633 gen_vfp_toul(dp
, 32 - rm
, 0);
3635 default: /* undefined */
3639 default: /* undefined */
3643 /* Write back the result. */
3644 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3645 /* Comparison, do nothing. */
3646 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3647 (rn
& 0x1e) == 0x6)) {
3648 /* VCVT double to int: always integer result.
3649 * VCVT double to half precision is always a single
3652 gen_mov_vreg_F0(0, rd
);
3653 } else if (op
== 15 && rn
== 15) {
3655 gen_mov_vreg_F0(!dp
, rd
);
3657 gen_mov_vreg_F0(dp
, rd
);
3660 /* break out of the loop if we have finished */
3664 if (op
== 15 && delta_m
== 0) {
3665 /* single source one-many */
3667 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3669 gen_mov_vreg_F0(dp
, rd
);
3673 /* Setup the next operands. */
3675 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3679 /* One source operand. */
3680 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3682 gen_mov_F0_vreg(dp
, rm
);
3684 /* Two source operands. */
3685 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3687 gen_mov_F0_vreg(dp
, rn
);
3689 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3691 gen_mov_F1_vreg(dp
, rm
);
3699 if ((insn
& 0x03e00000) == 0x00400000) {
3700 /* two-register transfer */
3701 rn
= (insn
>> 16) & 0xf;
3702 rd
= (insn
>> 12) & 0xf;
3704 VFP_DREG_M(rm
, insn
);
3706 rm
= VFP_SREG_M(insn
);
3709 if (insn
& ARM_CP_RW_BIT
) {
3712 gen_mov_F0_vreg(0, rm
* 2);
3713 tmp
= gen_vfp_mrs();
3714 store_reg(s
, rd
, tmp
);
3715 gen_mov_F0_vreg(0, rm
* 2 + 1);
3716 tmp
= gen_vfp_mrs();
3717 store_reg(s
, rn
, tmp
);
3719 gen_mov_F0_vreg(0, rm
);
3720 tmp
= gen_vfp_mrs();
3721 store_reg(s
, rd
, tmp
);
3722 gen_mov_F0_vreg(0, rm
+ 1);
3723 tmp
= gen_vfp_mrs();
3724 store_reg(s
, rn
, tmp
);
3729 tmp
= load_reg(s
, rd
);
3731 gen_mov_vreg_F0(0, rm
* 2);
3732 tmp
= load_reg(s
, rn
);
3734 gen_mov_vreg_F0(0, rm
* 2 + 1);
3736 tmp
= load_reg(s
, rd
);
3738 gen_mov_vreg_F0(0, rm
);
3739 tmp
= load_reg(s
, rn
);
3741 gen_mov_vreg_F0(0, rm
+ 1);
3746 rn
= (insn
>> 16) & 0xf;
3748 VFP_DREG_D(rd
, insn
);
3750 rd
= VFP_SREG_D(insn
);
3751 if ((insn
& 0x01200000) == 0x01000000) {
3752 /* Single load/store */
3753 offset
= (insn
& 0xff) << 2;
3754 if ((insn
& (1 << 23)) == 0)
3756 if (s
->thumb
&& rn
== 15) {
3757 /* This is actually UNPREDICTABLE */
3758 addr
= tcg_temp_new_i32();
3759 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3761 addr
= load_reg(s
, rn
);
3763 tcg_gen_addi_i32(addr
, addr
, offset
);
3764 if (insn
& (1 << 20)) {
3765 gen_vfp_ld(s
, dp
, addr
);
3766 gen_mov_vreg_F0(dp
, rd
);
3768 gen_mov_F0_vreg(dp
, rd
);
3769 gen_vfp_st(s
, dp
, addr
);
3771 tcg_temp_free_i32(addr
);
3773 /* load/store multiple */
3774 int w
= insn
& (1 << 21);
3776 n
= (insn
>> 1) & 0x7f;
3780 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3781 /* P == U , W == 1 => UNDEF */
3784 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3785 /* UNPREDICTABLE cases for bad immediates: we choose to
3786 * UNDEF to avoid generating huge numbers of TCG ops
3790 if (rn
== 15 && w
) {
3791 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3795 if (s
->thumb
&& rn
== 15) {
3796 /* This is actually UNPREDICTABLE */
3797 addr
= tcg_temp_new_i32();
3798 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3800 addr
= load_reg(s
, rn
);
3802 if (insn
& (1 << 24)) /* pre-decrement */
3803 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3809 for (i
= 0; i
< n
; i
++) {
3810 if (insn
& ARM_CP_RW_BIT
) {
3812 gen_vfp_ld(s
, dp
, addr
);
3813 gen_mov_vreg_F0(dp
, rd
+ i
);
3816 gen_mov_F0_vreg(dp
, rd
+ i
);
3817 gen_vfp_st(s
, dp
, addr
);
3819 tcg_gen_addi_i32(addr
, addr
, offset
);
3823 if (insn
& (1 << 24))
3824 offset
= -offset
* n
;
3825 else if (dp
&& (insn
& 1))
3831 tcg_gen_addi_i32(addr
, addr
, offset
);
3832 store_reg(s
, rn
, addr
);
3834 tcg_temp_free_i32(addr
);
3840 /* Should never happen. */
3846 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3848 TranslationBlock
*tb
;
3851 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3853 gen_set_pc_im(s
, dest
);
3854 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3856 gen_set_pc_im(s
, dest
);
3861 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3863 if (unlikely(s
->singlestep_enabled
)) {
3864 /* An indirect jump so that we still trigger the debug exception. */
3869 gen_goto_tb(s
, 0, dest
);
3870 s
->is_jmp
= DISAS_TB_JUMP
;
3874 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3877 tcg_gen_sari_i32(t0
, t0
, 16);
3881 tcg_gen_sari_i32(t1
, t1
, 16);
3884 tcg_gen_mul_i32(t0
, t0
, t1
);
3887 /* Return the mask of PSR bits set by a MSR instruction. */
3888 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3892 if (flags
& (1 << 0))
3894 if (flags
& (1 << 1))
3896 if (flags
& (1 << 2))
3898 if (flags
& (1 << 3))
3901 /* Mask out undefined bits. */
3902 mask
&= ~CPSR_RESERVED
;
3903 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3905 if (!arm_feature(env
, ARM_FEATURE_V5
))
3906 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3907 if (!arm_feature(env
, ARM_FEATURE_V6
))
3908 mask
&= ~(CPSR_E
| CPSR_GE
);
3909 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3911 /* Mask out execution state bits. */
3914 /* Mask out privileged bits. */
3920 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3921 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3925 /* ??? This is also undefined in system mode. */
3929 tmp
= load_cpu_field(spsr
);
3930 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3931 tcg_gen_andi_i32(t0
, t0
, mask
);
3932 tcg_gen_or_i32(tmp
, tmp
, t0
);
3933 store_cpu_field(tmp
, spsr
);
3935 gen_set_cpsr(t0
, mask
);
3937 tcg_temp_free_i32(t0
);
3942 /* Returns nonzero if access to the PSR is not permitted. */
3943 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3946 tmp
= tcg_temp_new_i32();
3947 tcg_gen_movi_i32(tmp
, val
);
3948 return gen_set_psr(s
, mask
, spsr
, tmp
);
3951 /* Generate an old-style exception return. Marks pc as dead. */
3952 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3955 store_reg(s
, 15, pc
);
3956 tmp
= load_cpu_field(spsr
);
3957 gen_set_cpsr(tmp
, 0xffffffff);
3958 tcg_temp_free_i32(tmp
);
3959 s
->is_jmp
= DISAS_UPDATE
;
3962 /* Generate a v6 exception return. Marks both values as dead. */
3963 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3965 gen_set_cpsr(cpsr
, 0xffffffff);
3966 tcg_temp_free_i32(cpsr
);
3967 store_reg(s
, 15, pc
);
3968 s
->is_jmp
= DISAS_UPDATE
;
3971 static void gen_nop_hint(DisasContext
*s
, int val
)
3975 gen_set_pc_im(s
, s
->pc
);
3976 s
->is_jmp
= DISAS_WFI
;
3979 gen_set_pc_im(s
, s
->pc
);
3980 s
->is_jmp
= DISAS_WFE
;
3984 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3990 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3992 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3995 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3996 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3997 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4002 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4005 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4006 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4007 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4012 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4013 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4014 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4015 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4016 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4018 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4019 switch ((size << 1) | u) { \
4021 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4024 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4027 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4030 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4033 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4036 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4038 default: return 1; \
4041 #define GEN_NEON_INTEGER_OP(name) do { \
4042 switch ((size << 1) | u) { \
4044 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4047 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4050 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4053 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4056 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4059 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4061 default: return 1; \
4064 static TCGv_i32
neon_load_scratch(int scratch
)
4066 TCGv_i32 tmp
= tcg_temp_new_i32();
4067 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4071 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4073 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4074 tcg_temp_free_i32(var
);
4077 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4081 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4083 gen_neon_dup_high16(tmp
);
4085 gen_neon_dup_low16(tmp
);
4088 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4093 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4096 if (!q
&& size
== 2) {
4099 tmp
= tcg_const_i32(rd
);
4100 tmp2
= tcg_const_i32(rm
);
4104 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4107 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4110 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4118 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4121 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4127 tcg_temp_free_i32(tmp
);
4128 tcg_temp_free_i32(tmp2
);
4132 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4135 if (!q
&& size
== 2) {
4138 tmp
= tcg_const_i32(rd
);
4139 tmp2
= tcg_const_i32(rm
);
4143 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4146 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4149 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4157 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4160 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4166 tcg_temp_free_i32(tmp
);
4167 tcg_temp_free_i32(tmp2
);
4171 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4175 rd
= tcg_temp_new_i32();
4176 tmp
= tcg_temp_new_i32();
4178 tcg_gen_shli_i32(rd
, t0
, 8);
4179 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4180 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4181 tcg_gen_or_i32(rd
, rd
, tmp
);
4183 tcg_gen_shri_i32(t1
, t1
, 8);
4184 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4185 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4186 tcg_gen_or_i32(t1
, t1
, tmp
);
4187 tcg_gen_mov_i32(t0
, rd
);
4189 tcg_temp_free_i32(tmp
);
4190 tcg_temp_free_i32(rd
);
4193 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4197 rd
= tcg_temp_new_i32();
4198 tmp
= tcg_temp_new_i32();
4200 tcg_gen_shli_i32(rd
, t0
, 16);
4201 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4202 tcg_gen_or_i32(rd
, rd
, tmp
);
4203 tcg_gen_shri_i32(t1
, t1
, 16);
4204 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4205 tcg_gen_or_i32(t1
, t1
, tmp
);
4206 tcg_gen_mov_i32(t0
, rd
);
4208 tcg_temp_free_i32(tmp
);
4209 tcg_temp_free_i32(rd
);
4217 } neon_ls_element_type
[11] = {
4231 /* Translate a NEON load/store element instruction. Return nonzero if the
4232 instruction is invalid. */
4233 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4252 /* FIXME: this access check should not take precedence over UNDEF
4253 * for invalid encodings; we will generate incorrect syndrome information
4254 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4256 if (!s
->cpacr_fpen
) {
4257 gen_exception_insn(s
, 4, EXCP_UDEF
,
4258 syn_fp_access_trap(1, 0xe, s
->thumb
));
4262 if (!s
->vfp_enabled
)
4264 VFP_DREG_D(rd
, insn
);
4265 rn
= (insn
>> 16) & 0xf;
4267 load
= (insn
& (1 << 21)) != 0;
4268 if ((insn
& (1 << 23)) == 0) {
4269 /* Load store all elements. */
4270 op
= (insn
>> 8) & 0xf;
4271 size
= (insn
>> 6) & 3;
4274 /* Catch UNDEF cases for bad values of align field */
4277 if (((insn
>> 5) & 1) == 1) {
4282 if (((insn
>> 4) & 3) == 3) {
4289 nregs
= neon_ls_element_type
[op
].nregs
;
4290 interleave
= neon_ls_element_type
[op
].interleave
;
4291 spacing
= neon_ls_element_type
[op
].spacing
;
4292 if (size
== 3 && (interleave
| spacing
) != 1)
4294 addr
= tcg_temp_new_i32();
4295 load_reg_var(s
, addr
, rn
);
4296 stride
= (1 << size
) * interleave
;
4297 for (reg
= 0; reg
< nregs
; reg
++) {
4298 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4299 load_reg_var(s
, addr
, rn
);
4300 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4301 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4302 load_reg_var(s
, addr
, rn
);
4303 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4306 tmp64
= tcg_temp_new_i64();
4308 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4309 neon_store_reg64(tmp64
, rd
);
4311 neon_load_reg64(tmp64
, rd
);
4312 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4314 tcg_temp_free_i64(tmp64
);
4315 tcg_gen_addi_i32(addr
, addr
, stride
);
4317 for (pass
= 0; pass
< 2; pass
++) {
4320 tmp
= tcg_temp_new_i32();
4321 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4322 neon_store_reg(rd
, pass
, tmp
);
4324 tmp
= neon_load_reg(rd
, pass
);
4325 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4326 tcg_temp_free_i32(tmp
);
4328 tcg_gen_addi_i32(addr
, addr
, stride
);
4329 } else if (size
== 1) {
4331 tmp
= tcg_temp_new_i32();
4332 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4333 tcg_gen_addi_i32(addr
, addr
, stride
);
4334 tmp2
= tcg_temp_new_i32();
4335 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4336 tcg_gen_addi_i32(addr
, addr
, stride
);
4337 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4338 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4339 tcg_temp_free_i32(tmp2
);
4340 neon_store_reg(rd
, pass
, tmp
);
4342 tmp
= neon_load_reg(rd
, pass
);
4343 tmp2
= tcg_temp_new_i32();
4344 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4345 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4346 tcg_temp_free_i32(tmp
);
4347 tcg_gen_addi_i32(addr
, addr
, stride
);
4348 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4349 tcg_temp_free_i32(tmp2
);
4350 tcg_gen_addi_i32(addr
, addr
, stride
);
4352 } else /* size == 0 */ {
4354 TCGV_UNUSED_I32(tmp2
);
4355 for (n
= 0; n
< 4; n
++) {
4356 tmp
= tcg_temp_new_i32();
4357 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4358 tcg_gen_addi_i32(addr
, addr
, stride
);
4362 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4363 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4364 tcg_temp_free_i32(tmp
);
4367 neon_store_reg(rd
, pass
, tmp2
);
4369 tmp2
= neon_load_reg(rd
, pass
);
4370 for (n
= 0; n
< 4; n
++) {
4371 tmp
= tcg_temp_new_i32();
4373 tcg_gen_mov_i32(tmp
, tmp2
);
4375 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4377 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4378 tcg_temp_free_i32(tmp
);
4379 tcg_gen_addi_i32(addr
, addr
, stride
);
4381 tcg_temp_free_i32(tmp2
);
4388 tcg_temp_free_i32(addr
);
4391 size
= (insn
>> 10) & 3;
4393 /* Load single element to all lanes. */
4394 int a
= (insn
>> 4) & 1;
4398 size
= (insn
>> 6) & 3;
4399 nregs
= ((insn
>> 8) & 3) + 1;
4402 if (nregs
!= 4 || a
== 0) {
4405 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4408 if (nregs
== 1 && a
== 1 && size
== 0) {
4411 if (nregs
== 3 && a
== 1) {
4414 addr
= tcg_temp_new_i32();
4415 load_reg_var(s
, addr
, rn
);
4417 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4418 tmp
= gen_load_and_replicate(s
, addr
, size
);
4419 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4420 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4421 if (insn
& (1 << 5)) {
4422 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4423 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4425 tcg_temp_free_i32(tmp
);
4427 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4428 stride
= (insn
& (1 << 5)) ? 2 : 1;
4429 for (reg
= 0; reg
< nregs
; reg
++) {
4430 tmp
= gen_load_and_replicate(s
, addr
, size
);
4431 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4432 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4433 tcg_temp_free_i32(tmp
);
4434 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4438 tcg_temp_free_i32(addr
);
4439 stride
= (1 << size
) * nregs
;
4441 /* Single element. */
4442 int idx
= (insn
>> 4) & 0xf;
4443 pass
= (insn
>> 7) & 1;
4446 shift
= ((insn
>> 5) & 3) * 8;
4450 shift
= ((insn
>> 6) & 1) * 16;
4451 stride
= (insn
& (1 << 5)) ? 2 : 1;
4455 stride
= (insn
& (1 << 6)) ? 2 : 1;
4460 nregs
= ((insn
>> 8) & 3) + 1;
4461 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4464 if (((idx
& (1 << size
)) != 0) ||
4465 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4470 if ((idx
& 1) != 0) {
4475 if (size
== 2 && (idx
& 2) != 0) {
4480 if ((size
== 2) && ((idx
& 3) == 3)) {
4487 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4488 /* Attempts to write off the end of the register file
4489 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4490 * the neon_load_reg() would write off the end of the array.
4494 addr
= tcg_temp_new_i32();
4495 load_reg_var(s
, addr
, rn
);
4496 for (reg
= 0; reg
< nregs
; reg
++) {
4498 tmp
= tcg_temp_new_i32();
4501 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4504 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4507 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4509 default: /* Avoid compiler warnings. */
4513 tmp2
= neon_load_reg(rd
, pass
);
4514 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4515 shift
, size
? 16 : 8);
4516 tcg_temp_free_i32(tmp2
);
4518 neon_store_reg(rd
, pass
, tmp
);
4519 } else { /* Store */
4520 tmp
= neon_load_reg(rd
, pass
);
4522 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4525 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4528 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4531 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4534 tcg_temp_free_i32(tmp
);
4537 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4539 tcg_temp_free_i32(addr
);
4540 stride
= nregs
* (1 << size
);
4546 base
= load_reg(s
, rn
);
4548 tcg_gen_addi_i32(base
, base
, stride
);
4551 index
= load_reg(s
, rm
);
4552 tcg_gen_add_i32(base
, base
, index
);
4553 tcg_temp_free_i32(index
);
4555 store_reg(s
, rn
, base
);
4560 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4561 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4563 tcg_gen_and_i32(t
, t
, c
);
4564 tcg_gen_andc_i32(f
, f
, c
);
4565 tcg_gen_or_i32(dest
, t
, f
);
4568 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4571 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4572 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4573 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4578 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4581 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4582 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4583 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4588 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4591 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4592 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4593 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4598 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4601 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4602 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4603 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4608 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4614 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4615 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4620 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4621 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4628 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4629 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4634 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4635 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4642 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4646 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4647 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4648 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4653 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4654 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4655 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4659 tcg_temp_free_i32(src
);
4662 static inline void gen_neon_addl(int size
)
4665 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4666 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4667 case 2: tcg_gen_add_i64(CPU_V001
); break;
4672 static inline void gen_neon_subl(int size
)
4675 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4676 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4677 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4682 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4685 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4686 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4688 tcg_gen_neg_i64(var
, var
);
4694 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4697 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4698 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4703 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4708 switch ((size
<< 1) | u
) {
4709 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4710 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4711 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4712 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4714 tmp
= gen_muls_i64_i32(a
, b
);
4715 tcg_gen_mov_i64(dest
, tmp
);
4716 tcg_temp_free_i64(tmp
);
4719 tmp
= gen_mulu_i64_i32(a
, b
);
4720 tcg_gen_mov_i64(dest
, tmp
);
4721 tcg_temp_free_i64(tmp
);
4726 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4727 Don't forget to clean them now. */
4729 tcg_temp_free_i32(a
);
4730 tcg_temp_free_i32(b
);
4734 static void gen_neon_narrow_op(int op
, int u
, int size
,
4735 TCGv_i32 dest
, TCGv_i64 src
)
4739 gen_neon_unarrow_sats(size
, dest
, src
);
4741 gen_neon_narrow(size
, dest
, src
);
4745 gen_neon_narrow_satu(size
, dest
, src
);
4747 gen_neon_narrow_sats(size
, dest
, src
);
4752 /* Symbolic constants for op fields for Neon 3-register same-length.
4753 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4756 #define NEON_3R_VHADD 0
4757 #define NEON_3R_VQADD 1
4758 #define NEON_3R_VRHADD 2
4759 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4760 #define NEON_3R_VHSUB 4
4761 #define NEON_3R_VQSUB 5
4762 #define NEON_3R_VCGT 6
4763 #define NEON_3R_VCGE 7
4764 #define NEON_3R_VSHL 8
4765 #define NEON_3R_VQSHL 9
4766 #define NEON_3R_VRSHL 10
4767 #define NEON_3R_VQRSHL 11
4768 #define NEON_3R_VMAX 12
4769 #define NEON_3R_VMIN 13
4770 #define NEON_3R_VABD 14
4771 #define NEON_3R_VABA 15
4772 #define NEON_3R_VADD_VSUB 16
4773 #define NEON_3R_VTST_VCEQ 17
4774 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4775 #define NEON_3R_VMUL 19
4776 #define NEON_3R_VPMAX 20
4777 #define NEON_3R_VPMIN 21
4778 #define NEON_3R_VQDMULH_VQRDMULH 22
4779 #define NEON_3R_VPADD 23
4780 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4781 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4782 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4783 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4784 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4785 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4786 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4787 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4789 static const uint8_t neon_3r_sizes
[] = {
4790 [NEON_3R_VHADD
] = 0x7,
4791 [NEON_3R_VQADD
] = 0xf,
4792 [NEON_3R_VRHADD
] = 0x7,
4793 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4794 [NEON_3R_VHSUB
] = 0x7,
4795 [NEON_3R_VQSUB
] = 0xf,
4796 [NEON_3R_VCGT
] = 0x7,
4797 [NEON_3R_VCGE
] = 0x7,
4798 [NEON_3R_VSHL
] = 0xf,
4799 [NEON_3R_VQSHL
] = 0xf,
4800 [NEON_3R_VRSHL
] = 0xf,
4801 [NEON_3R_VQRSHL
] = 0xf,
4802 [NEON_3R_VMAX
] = 0x7,
4803 [NEON_3R_VMIN
] = 0x7,
4804 [NEON_3R_VABD
] = 0x7,
4805 [NEON_3R_VABA
] = 0x7,
4806 [NEON_3R_VADD_VSUB
] = 0xf,
4807 [NEON_3R_VTST_VCEQ
] = 0x7,
4808 [NEON_3R_VML
] = 0x7,
4809 [NEON_3R_VMUL
] = 0x7,
4810 [NEON_3R_VPMAX
] = 0x7,
4811 [NEON_3R_VPMIN
] = 0x7,
4812 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4813 [NEON_3R_VPADD
] = 0x7,
4814 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4815 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4816 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4817 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4818 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4819 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4820 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4821 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4824 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4825 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4828 #define NEON_2RM_VREV64 0
4829 #define NEON_2RM_VREV32 1
4830 #define NEON_2RM_VREV16 2
4831 #define NEON_2RM_VPADDL 4
4832 #define NEON_2RM_VPADDL_U 5
4833 #define NEON_2RM_AESE 6 /* Includes AESD */
4834 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4835 #define NEON_2RM_VCLS 8
4836 #define NEON_2RM_VCLZ 9
4837 #define NEON_2RM_VCNT 10
4838 #define NEON_2RM_VMVN 11
4839 #define NEON_2RM_VPADAL 12
4840 #define NEON_2RM_VPADAL_U 13
4841 #define NEON_2RM_VQABS 14
4842 #define NEON_2RM_VQNEG 15
4843 #define NEON_2RM_VCGT0 16
4844 #define NEON_2RM_VCGE0 17
4845 #define NEON_2RM_VCEQ0 18
4846 #define NEON_2RM_VCLE0 19
4847 #define NEON_2RM_VCLT0 20
4848 #define NEON_2RM_SHA1H 21
4849 #define NEON_2RM_VABS 22
4850 #define NEON_2RM_VNEG 23
4851 #define NEON_2RM_VCGT0_F 24
4852 #define NEON_2RM_VCGE0_F 25
4853 #define NEON_2RM_VCEQ0_F 26
4854 #define NEON_2RM_VCLE0_F 27
4855 #define NEON_2RM_VCLT0_F 28
4856 #define NEON_2RM_VABS_F 30
4857 #define NEON_2RM_VNEG_F 31
4858 #define NEON_2RM_VSWP 32
4859 #define NEON_2RM_VTRN 33
4860 #define NEON_2RM_VUZP 34
4861 #define NEON_2RM_VZIP 35
4862 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4863 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4864 #define NEON_2RM_VSHLL 38
4865 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4866 #define NEON_2RM_VRINTN 40
4867 #define NEON_2RM_VRINTX 41
4868 #define NEON_2RM_VRINTA 42
4869 #define NEON_2RM_VRINTZ 43
4870 #define NEON_2RM_VCVT_F16_F32 44
4871 #define NEON_2RM_VRINTM 45
4872 #define NEON_2RM_VCVT_F32_F16 46
4873 #define NEON_2RM_VRINTP 47
4874 #define NEON_2RM_VCVTAU 48
4875 #define NEON_2RM_VCVTAS 49
4876 #define NEON_2RM_VCVTNU 50
4877 #define NEON_2RM_VCVTNS 51
4878 #define NEON_2RM_VCVTPU 52
4879 #define NEON_2RM_VCVTPS 53
4880 #define NEON_2RM_VCVTMU 54
4881 #define NEON_2RM_VCVTMS 55
4882 #define NEON_2RM_VRECPE 56
4883 #define NEON_2RM_VRSQRTE 57
4884 #define NEON_2RM_VRECPE_F 58
4885 #define NEON_2RM_VRSQRTE_F 59
4886 #define NEON_2RM_VCVT_FS 60
4887 #define NEON_2RM_VCVT_FU 61
4888 #define NEON_2RM_VCVT_SF 62
4889 #define NEON_2RM_VCVT_UF 63
4891 static int neon_2rm_is_float_op(int op
)
4893 /* Return true if this neon 2reg-misc op is float-to-float */
4894 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4895 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4896 op
== NEON_2RM_VRINTM
||
4897 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4898 op
>= NEON_2RM_VRECPE_F
);
4901 /* Each entry in this array has bit n set if the insn allows
4902 * size value n (otherwise it will UNDEF). Since unallocated
4903 * op values will have no bits set they always UNDEF.
4905 static const uint8_t neon_2rm_sizes
[] = {
4906 [NEON_2RM_VREV64
] = 0x7,
4907 [NEON_2RM_VREV32
] = 0x3,
4908 [NEON_2RM_VREV16
] = 0x1,
4909 [NEON_2RM_VPADDL
] = 0x7,
4910 [NEON_2RM_VPADDL_U
] = 0x7,
4911 [NEON_2RM_AESE
] = 0x1,
4912 [NEON_2RM_AESMC
] = 0x1,
4913 [NEON_2RM_VCLS
] = 0x7,
4914 [NEON_2RM_VCLZ
] = 0x7,
4915 [NEON_2RM_VCNT
] = 0x1,
4916 [NEON_2RM_VMVN
] = 0x1,
4917 [NEON_2RM_VPADAL
] = 0x7,
4918 [NEON_2RM_VPADAL_U
] = 0x7,
4919 [NEON_2RM_VQABS
] = 0x7,
4920 [NEON_2RM_VQNEG
] = 0x7,
4921 [NEON_2RM_VCGT0
] = 0x7,
4922 [NEON_2RM_VCGE0
] = 0x7,
4923 [NEON_2RM_VCEQ0
] = 0x7,
4924 [NEON_2RM_VCLE0
] = 0x7,
4925 [NEON_2RM_VCLT0
] = 0x7,
4926 [NEON_2RM_SHA1H
] = 0x4,
4927 [NEON_2RM_VABS
] = 0x7,
4928 [NEON_2RM_VNEG
] = 0x7,
4929 [NEON_2RM_VCGT0_F
] = 0x4,
4930 [NEON_2RM_VCGE0_F
] = 0x4,
4931 [NEON_2RM_VCEQ0_F
] = 0x4,
4932 [NEON_2RM_VCLE0_F
] = 0x4,
4933 [NEON_2RM_VCLT0_F
] = 0x4,
4934 [NEON_2RM_VABS_F
] = 0x4,
4935 [NEON_2RM_VNEG_F
] = 0x4,
4936 [NEON_2RM_VSWP
] = 0x1,
4937 [NEON_2RM_VTRN
] = 0x7,
4938 [NEON_2RM_VUZP
] = 0x7,
4939 [NEON_2RM_VZIP
] = 0x7,
4940 [NEON_2RM_VMOVN
] = 0x7,
4941 [NEON_2RM_VQMOVN
] = 0x7,
4942 [NEON_2RM_VSHLL
] = 0x7,
4943 [NEON_2RM_SHA1SU1
] = 0x4,
4944 [NEON_2RM_VRINTN
] = 0x4,
4945 [NEON_2RM_VRINTX
] = 0x4,
4946 [NEON_2RM_VRINTA
] = 0x4,
4947 [NEON_2RM_VRINTZ
] = 0x4,
4948 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4949 [NEON_2RM_VRINTM
] = 0x4,
4950 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4951 [NEON_2RM_VRINTP
] = 0x4,
4952 [NEON_2RM_VCVTAU
] = 0x4,
4953 [NEON_2RM_VCVTAS
] = 0x4,
4954 [NEON_2RM_VCVTNU
] = 0x4,
4955 [NEON_2RM_VCVTNS
] = 0x4,
4956 [NEON_2RM_VCVTPU
] = 0x4,
4957 [NEON_2RM_VCVTPS
] = 0x4,
4958 [NEON_2RM_VCVTMU
] = 0x4,
4959 [NEON_2RM_VCVTMS
] = 0x4,
4960 [NEON_2RM_VRECPE
] = 0x4,
4961 [NEON_2RM_VRSQRTE
] = 0x4,
4962 [NEON_2RM_VRECPE_F
] = 0x4,
4963 [NEON_2RM_VRSQRTE_F
] = 0x4,
4964 [NEON_2RM_VCVT_FS
] = 0x4,
4965 [NEON_2RM_VCVT_FU
] = 0x4,
4966 [NEON_2RM_VCVT_SF
] = 0x4,
4967 [NEON_2RM_VCVT_UF
] = 0x4,
4970 /* Translate a NEON data processing instruction. Return nonzero if the
4971 instruction is invalid.
4972 We process data in a mixture of 32-bit and 64-bit chunks.
4973 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4975 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4987 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4990 /* FIXME: this access check should not take precedence over UNDEF
4991 * for invalid encodings; we will generate incorrect syndrome information
4992 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4994 if (!s
->cpacr_fpen
) {
4995 gen_exception_insn(s
, 4, EXCP_UDEF
,
4996 syn_fp_access_trap(1, 0xe, s
->thumb
));
5000 if (!s
->vfp_enabled
)
5002 q
= (insn
& (1 << 6)) != 0;
5003 u
= (insn
>> 24) & 1;
5004 VFP_DREG_D(rd
, insn
);
5005 VFP_DREG_N(rn
, insn
);
5006 VFP_DREG_M(rm
, insn
);
5007 size
= (insn
>> 20) & 3;
5008 if ((insn
& (1 << 23)) == 0) {
5009 /* Three register same length. */
5010 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5011 /* Catch invalid op and bad size combinations: UNDEF */
5012 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5015 /* All insns of this form UNDEF for either this condition or the
5016 * superset of cases "Q==1"; we catch the latter later.
5018 if (q
&& ((rd
| rn
| rm
) & 1)) {
5022 * The SHA-1/SHA-256 3-register instructions require special treatment
5023 * here, as their size field is overloaded as an op type selector, and
5024 * they all consume their input in a single pass.
5026 if (op
== NEON_3R_SHA
) {
5030 if (!u
) { /* SHA-1 */
5031 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5034 tmp
= tcg_const_i32(rd
);
5035 tmp2
= tcg_const_i32(rn
);
5036 tmp3
= tcg_const_i32(rm
);
5037 tmp4
= tcg_const_i32(size
);
5038 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5039 tcg_temp_free_i32(tmp4
);
5040 } else { /* SHA-256 */
5041 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5044 tmp
= tcg_const_i32(rd
);
5045 tmp2
= tcg_const_i32(rn
);
5046 tmp3
= tcg_const_i32(rm
);
5049 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5052 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5055 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5059 tcg_temp_free_i32(tmp
);
5060 tcg_temp_free_i32(tmp2
);
5061 tcg_temp_free_i32(tmp3
);
5064 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5065 /* 64-bit element instructions. */
5066 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5067 neon_load_reg64(cpu_V0
, rn
+ pass
);
5068 neon_load_reg64(cpu_V1
, rm
+ pass
);
5072 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5075 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5081 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5084 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5090 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5092 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5097 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5100 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5106 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5108 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5111 case NEON_3R_VQRSHL
:
5113 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5116 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5120 case NEON_3R_VADD_VSUB
:
5122 tcg_gen_sub_i64(CPU_V001
);
5124 tcg_gen_add_i64(CPU_V001
);
5130 neon_store_reg64(cpu_V0
, rd
+ pass
);
5139 case NEON_3R_VQRSHL
:
5142 /* Shift instruction operands are reversed. */
5157 case NEON_3R_FLOAT_ARITH
:
5158 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5160 case NEON_3R_FLOAT_MINMAX
:
5161 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5163 case NEON_3R_FLOAT_CMP
:
5165 /* no encoding for U=0 C=1x */
5169 case NEON_3R_FLOAT_ACMP
:
5174 case NEON_3R_FLOAT_MISC
:
5175 /* VMAXNM/VMINNM in ARMv8 */
5176 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5181 if (u
&& (size
!= 0)) {
5182 /* UNDEF on invalid size for polynomial subcase */
5187 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5195 if (pairwise
&& q
) {
5196 /* All the pairwise insns UNDEF if Q is set */
5200 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5205 tmp
= neon_load_reg(rn
, 0);
5206 tmp2
= neon_load_reg(rn
, 1);
5208 tmp
= neon_load_reg(rm
, 0);
5209 tmp2
= neon_load_reg(rm
, 1);
5213 tmp
= neon_load_reg(rn
, pass
);
5214 tmp2
= neon_load_reg(rm
, pass
);
5218 GEN_NEON_INTEGER_OP(hadd
);
5221 GEN_NEON_INTEGER_OP_ENV(qadd
);
5223 case NEON_3R_VRHADD
:
5224 GEN_NEON_INTEGER_OP(rhadd
);
5226 case NEON_3R_LOGIC
: /* Logic ops. */
5227 switch ((u
<< 2) | size
) {
5229 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5232 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5235 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5238 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5241 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5244 tmp3
= neon_load_reg(rd
, pass
);
5245 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5246 tcg_temp_free_i32(tmp3
);
5249 tmp3
= neon_load_reg(rd
, pass
);
5250 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5251 tcg_temp_free_i32(tmp3
);
5254 tmp3
= neon_load_reg(rd
, pass
);
5255 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5256 tcg_temp_free_i32(tmp3
);
5261 GEN_NEON_INTEGER_OP(hsub
);
5264 GEN_NEON_INTEGER_OP_ENV(qsub
);
5267 GEN_NEON_INTEGER_OP(cgt
);
5270 GEN_NEON_INTEGER_OP(cge
);
5273 GEN_NEON_INTEGER_OP(shl
);
5276 GEN_NEON_INTEGER_OP_ENV(qshl
);
5279 GEN_NEON_INTEGER_OP(rshl
);
5281 case NEON_3R_VQRSHL
:
5282 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5285 GEN_NEON_INTEGER_OP(max
);
5288 GEN_NEON_INTEGER_OP(min
);
5291 GEN_NEON_INTEGER_OP(abd
);
5294 GEN_NEON_INTEGER_OP(abd
);
5295 tcg_temp_free_i32(tmp2
);
5296 tmp2
= neon_load_reg(rd
, pass
);
5297 gen_neon_add(size
, tmp
, tmp2
);
5299 case NEON_3R_VADD_VSUB
:
5300 if (!u
) { /* VADD */
5301 gen_neon_add(size
, tmp
, tmp2
);
5304 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5305 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5306 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5311 case NEON_3R_VTST_VCEQ
:
5312 if (!u
) { /* VTST */
5314 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5315 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5316 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5321 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5322 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5323 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5328 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5330 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5331 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5332 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5335 tcg_temp_free_i32(tmp2
);
5336 tmp2
= neon_load_reg(rd
, pass
);
5338 gen_neon_rsb(size
, tmp
, tmp2
);
5340 gen_neon_add(size
, tmp
, tmp2
);
5344 if (u
) { /* polynomial */
5345 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5346 } else { /* Integer */
5348 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5349 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5350 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5356 GEN_NEON_INTEGER_OP(pmax
);
5359 GEN_NEON_INTEGER_OP(pmin
);
5361 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5362 if (!u
) { /* VQDMULH */
5365 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5368 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5372 } else { /* VQRDMULH */
5375 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5378 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5386 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5387 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5388 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5392 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5394 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5395 switch ((u
<< 2) | size
) {
5398 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5401 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5404 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5409 tcg_temp_free_ptr(fpstatus
);
5412 case NEON_3R_FLOAT_MULTIPLY
:
5414 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5415 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5417 tcg_temp_free_i32(tmp2
);
5418 tmp2
= neon_load_reg(rd
, pass
);
5420 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5422 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5425 tcg_temp_free_ptr(fpstatus
);
5428 case NEON_3R_FLOAT_CMP
:
5430 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5432 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5435 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5437 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5440 tcg_temp_free_ptr(fpstatus
);
5443 case NEON_3R_FLOAT_ACMP
:
5445 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5447 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5449 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5451 tcg_temp_free_ptr(fpstatus
);
5454 case NEON_3R_FLOAT_MINMAX
:
5456 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5458 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5460 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5462 tcg_temp_free_ptr(fpstatus
);
5465 case NEON_3R_FLOAT_MISC
:
5468 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5470 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5472 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5474 tcg_temp_free_ptr(fpstatus
);
5477 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5479 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5485 /* VFMA, VFMS: fused multiply-add */
5486 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5487 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5490 gen_helper_vfp_negs(tmp
, tmp
);
5492 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5493 tcg_temp_free_i32(tmp3
);
5494 tcg_temp_free_ptr(fpstatus
);
5500 tcg_temp_free_i32(tmp2
);
5502 /* Save the result. For elementwise operations we can put it
5503 straight into the destination register. For pairwise operations
5504 we have to be careful to avoid clobbering the source operands. */
5505 if (pairwise
&& rd
== rm
) {
5506 neon_store_scratch(pass
, tmp
);
5508 neon_store_reg(rd
, pass
, tmp
);
5512 if (pairwise
&& rd
== rm
) {
5513 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5514 tmp
= neon_load_scratch(pass
);
5515 neon_store_reg(rd
, pass
, tmp
);
5518 /* End of 3 register same size operations. */
5519 } else if (insn
& (1 << 4)) {
5520 if ((insn
& 0x00380080) != 0) {
5521 /* Two registers and shift. */
5522 op
= (insn
>> 8) & 0xf;
5523 if (insn
& (1 << 7)) {
5531 while ((insn
& (1 << (size
+ 19))) == 0)
5534 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5535 /* To avoid excessive duplication of ops we implement shift
5536 by immediate using the variable shift operations. */
5538 /* Shift by immediate:
5539 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5540 if (q
&& ((rd
| rm
) & 1)) {
5543 if (!u
&& (op
== 4 || op
== 6)) {
5546 /* Right shifts are encoded as N - shift, where N is the
5547 element size in bits. */
5549 shift
= shift
- (1 << (size
+ 3));
5557 imm
= (uint8_t) shift
;
5562 imm
= (uint16_t) shift
;
5573 for (pass
= 0; pass
< count
; pass
++) {
5575 neon_load_reg64(cpu_V0
, rm
+ pass
);
5576 tcg_gen_movi_i64(cpu_V1
, imm
);
5581 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5583 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5588 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5590 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5593 case 5: /* VSHL, VSLI */
5594 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5596 case 6: /* VQSHLU */
5597 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5602 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5605 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5610 if (op
== 1 || op
== 3) {
5612 neon_load_reg64(cpu_V1
, rd
+ pass
);
5613 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5614 } else if (op
== 4 || (op
== 5 && u
)) {
5616 neon_load_reg64(cpu_V1
, rd
+ pass
);
5618 if (shift
< -63 || shift
> 63) {
5622 mask
= 0xffffffffffffffffull
>> -shift
;
5624 mask
= 0xffffffffffffffffull
<< shift
;
5627 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5628 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5630 neon_store_reg64(cpu_V0
, rd
+ pass
);
5631 } else { /* size < 3 */
5632 /* Operands in T0 and T1. */
5633 tmp
= neon_load_reg(rm
, pass
);
5634 tmp2
= tcg_temp_new_i32();
5635 tcg_gen_movi_i32(tmp2
, imm
);
5639 GEN_NEON_INTEGER_OP(shl
);
5643 GEN_NEON_INTEGER_OP(rshl
);
5646 case 5: /* VSHL, VSLI */
5648 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5649 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5650 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5654 case 6: /* VQSHLU */
5657 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5661 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5665 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5673 GEN_NEON_INTEGER_OP_ENV(qshl
);
5676 tcg_temp_free_i32(tmp2
);
5678 if (op
== 1 || op
== 3) {
5680 tmp2
= neon_load_reg(rd
, pass
);
5681 gen_neon_add(size
, tmp
, tmp2
);
5682 tcg_temp_free_i32(tmp2
);
5683 } else if (op
== 4 || (op
== 5 && u
)) {
5688 mask
= 0xff >> -shift
;
5690 mask
= (uint8_t)(0xff << shift
);
5696 mask
= 0xffff >> -shift
;
5698 mask
= (uint16_t)(0xffff << shift
);
5702 if (shift
< -31 || shift
> 31) {
5706 mask
= 0xffffffffu
>> -shift
;
5708 mask
= 0xffffffffu
<< shift
;
5714 tmp2
= neon_load_reg(rd
, pass
);
5715 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5716 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5717 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5718 tcg_temp_free_i32(tmp2
);
5720 neon_store_reg(rd
, pass
, tmp
);
5723 } else if (op
< 10) {
5724 /* Shift by immediate and narrow:
5725 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5726 int input_unsigned
= (op
== 8) ? !u
: u
;
5730 shift
= shift
- (1 << (size
+ 3));
5733 tmp64
= tcg_const_i64(shift
);
5734 neon_load_reg64(cpu_V0
, rm
);
5735 neon_load_reg64(cpu_V1
, rm
+ 1);
5736 for (pass
= 0; pass
< 2; pass
++) {
5744 if (input_unsigned
) {
5745 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5747 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5750 if (input_unsigned
) {
5751 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5753 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5756 tmp
= tcg_temp_new_i32();
5757 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5758 neon_store_reg(rd
, pass
, tmp
);
5760 tcg_temp_free_i64(tmp64
);
5763 imm
= (uint16_t)shift
;
5767 imm
= (uint32_t)shift
;
5769 tmp2
= tcg_const_i32(imm
);
5770 tmp4
= neon_load_reg(rm
+ 1, 0);
5771 tmp5
= neon_load_reg(rm
+ 1, 1);
5772 for (pass
= 0; pass
< 2; pass
++) {
5774 tmp
= neon_load_reg(rm
, 0);
5778 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5781 tmp3
= neon_load_reg(rm
, 1);
5785 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5787 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5788 tcg_temp_free_i32(tmp
);
5789 tcg_temp_free_i32(tmp3
);
5790 tmp
= tcg_temp_new_i32();
5791 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5792 neon_store_reg(rd
, pass
, tmp
);
5794 tcg_temp_free_i32(tmp2
);
5796 } else if (op
== 10) {
5798 if (q
|| (rd
& 1)) {
5801 tmp
= neon_load_reg(rm
, 0);
5802 tmp2
= neon_load_reg(rm
, 1);
5803 for (pass
= 0; pass
< 2; pass
++) {
5807 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5810 /* The shift is less than the width of the source
5811 type, so we can just shift the whole register. */
5812 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5813 /* Widen the result of shift: we need to clear
5814 * the potential overflow bits resulting from
5815 * left bits of the narrow input appearing as
5816 * right bits of left the neighbour narrow
5818 if (size
< 2 || !u
) {
5821 imm
= (0xffu
>> (8 - shift
));
5823 } else if (size
== 1) {
5824 imm
= 0xffff >> (16 - shift
);
5827 imm
= 0xffffffff >> (32 - shift
);
5830 imm64
= imm
| (((uint64_t)imm
) << 32);
5834 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5837 neon_store_reg64(cpu_V0
, rd
+ pass
);
5839 } else if (op
>= 14) {
5840 /* VCVT fixed-point. */
5841 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5844 /* We have already masked out the must-be-1 top bit of imm6,
5845 * hence this 32-shift where the ARM ARM has 64-imm6.
5848 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5849 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5852 gen_vfp_ulto(0, shift
, 1);
5854 gen_vfp_slto(0, shift
, 1);
5857 gen_vfp_toul(0, shift
, 1);
5859 gen_vfp_tosl(0, shift
, 1);
5861 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5866 } else { /* (insn & 0x00380080) == 0 */
5868 if (q
&& (rd
& 1)) {
5872 op
= (insn
>> 8) & 0xf;
5873 /* One register and immediate. */
5874 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5875 invert
= (insn
& (1 << 5)) != 0;
5876 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5877 * We choose to not special-case this and will behave as if a
5878 * valid constant encoding of 0 had been given.
5897 imm
= (imm
<< 8) | (imm
<< 24);
5900 imm
= (imm
<< 8) | 0xff;
5903 imm
= (imm
<< 16) | 0xffff;
5906 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5914 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5915 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5921 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5922 if (op
& 1 && op
< 12) {
5923 tmp
= neon_load_reg(rd
, pass
);
5925 /* The immediate value has already been inverted, so
5927 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5929 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5933 tmp
= tcg_temp_new_i32();
5934 if (op
== 14 && invert
) {
5938 for (n
= 0; n
< 4; n
++) {
5939 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5940 val
|= 0xff << (n
* 8);
5942 tcg_gen_movi_i32(tmp
, val
);
5944 tcg_gen_movi_i32(tmp
, imm
);
5947 neon_store_reg(rd
, pass
, tmp
);
5950 } else { /* (insn & 0x00800010 == 0x00800000) */
5952 op
= (insn
>> 8) & 0xf;
5953 if ((insn
& (1 << 6)) == 0) {
5954 /* Three registers of different lengths. */
5958 /* undefreq: bit 0 : UNDEF if size == 0
5959 * bit 1 : UNDEF if size == 1
5960 * bit 2 : UNDEF if size == 2
5961 * bit 3 : UNDEF if U == 1
5962 * Note that [2:0] set implies 'always UNDEF'
5965 /* prewiden, src1_wide, src2_wide, undefreq */
5966 static const int neon_3reg_wide
[16][4] = {
5967 {1, 0, 0, 0}, /* VADDL */
5968 {1, 1, 0, 0}, /* VADDW */
5969 {1, 0, 0, 0}, /* VSUBL */
5970 {1, 1, 0, 0}, /* VSUBW */
5971 {0, 1, 1, 0}, /* VADDHN */
5972 {0, 0, 0, 0}, /* VABAL */
5973 {0, 1, 1, 0}, /* VSUBHN */
5974 {0, 0, 0, 0}, /* VABDL */
5975 {0, 0, 0, 0}, /* VMLAL */
5976 {0, 0, 0, 9}, /* VQDMLAL */
5977 {0, 0, 0, 0}, /* VMLSL */
5978 {0, 0, 0, 9}, /* VQDMLSL */
5979 {0, 0, 0, 0}, /* Integer VMULL */
5980 {0, 0, 0, 1}, /* VQDMULL */
5981 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5982 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5985 prewiden
= neon_3reg_wide
[op
][0];
5986 src1_wide
= neon_3reg_wide
[op
][1];
5987 src2_wide
= neon_3reg_wide
[op
][2];
5988 undefreq
= neon_3reg_wide
[op
][3];
5990 if ((undefreq
& (1 << size
)) ||
5991 ((undefreq
& 8) && u
)) {
5994 if ((src1_wide
&& (rn
& 1)) ||
5995 (src2_wide
&& (rm
& 1)) ||
5996 (!src2_wide
&& (rd
& 1))) {
6000 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6001 * outside the loop below as it only performs a single pass.
6003 if (op
== 14 && size
== 2) {
6004 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6006 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6009 tcg_rn
= tcg_temp_new_i64();
6010 tcg_rm
= tcg_temp_new_i64();
6011 tcg_rd
= tcg_temp_new_i64();
6012 neon_load_reg64(tcg_rn
, rn
);
6013 neon_load_reg64(tcg_rm
, rm
);
6014 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6015 neon_store_reg64(tcg_rd
, rd
);
6016 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6017 neon_store_reg64(tcg_rd
, rd
+ 1);
6018 tcg_temp_free_i64(tcg_rn
);
6019 tcg_temp_free_i64(tcg_rm
);
6020 tcg_temp_free_i64(tcg_rd
);
6024 /* Avoid overlapping operands. Wide source operands are
6025 always aligned so will never overlap with wide
6026 destinations in problematic ways. */
6027 if (rd
== rm
&& !src2_wide
) {
6028 tmp
= neon_load_reg(rm
, 1);
6029 neon_store_scratch(2, tmp
);
6030 } else if (rd
== rn
&& !src1_wide
) {
6031 tmp
= neon_load_reg(rn
, 1);
6032 neon_store_scratch(2, tmp
);
6034 TCGV_UNUSED_I32(tmp3
);
6035 for (pass
= 0; pass
< 2; pass
++) {
6037 neon_load_reg64(cpu_V0
, rn
+ pass
);
6038 TCGV_UNUSED_I32(tmp
);
6040 if (pass
== 1 && rd
== rn
) {
6041 tmp
= neon_load_scratch(2);
6043 tmp
= neon_load_reg(rn
, pass
);
6046 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6050 neon_load_reg64(cpu_V1
, rm
+ pass
);
6051 TCGV_UNUSED_I32(tmp2
);
6053 if (pass
== 1 && rd
== rm
) {
6054 tmp2
= neon_load_scratch(2);
6056 tmp2
= neon_load_reg(rm
, pass
);
6059 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6063 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6064 gen_neon_addl(size
);
6066 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6067 gen_neon_subl(size
);
6069 case 5: case 7: /* VABAL, VABDL */
6070 switch ((size
<< 1) | u
) {
6072 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6075 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6078 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6081 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6084 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6087 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6091 tcg_temp_free_i32(tmp2
);
6092 tcg_temp_free_i32(tmp
);
6094 case 8: case 9: case 10: case 11: case 12: case 13:
6095 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6096 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6098 case 14: /* Polynomial VMULL */
6099 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6100 tcg_temp_free_i32(tmp2
);
6101 tcg_temp_free_i32(tmp
);
6103 default: /* 15 is RESERVED: caught earlier */
6108 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6109 neon_store_reg64(cpu_V0
, rd
+ pass
);
6110 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6112 neon_load_reg64(cpu_V1
, rd
+ pass
);
6114 case 10: /* VMLSL */
6115 gen_neon_negl(cpu_V0
, size
);
6117 case 5: case 8: /* VABAL, VMLAL */
6118 gen_neon_addl(size
);
6120 case 9: case 11: /* VQDMLAL, VQDMLSL */
6121 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6123 gen_neon_negl(cpu_V0
, size
);
6125 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6130 neon_store_reg64(cpu_V0
, rd
+ pass
);
6131 } else if (op
== 4 || op
== 6) {
6132 /* Narrowing operation. */
6133 tmp
= tcg_temp_new_i32();
6137 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6140 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6143 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6144 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6151 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6154 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6157 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6158 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6159 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6167 neon_store_reg(rd
, 0, tmp3
);
6168 neon_store_reg(rd
, 1, tmp
);
6171 /* Write back the result. */
6172 neon_store_reg64(cpu_V0
, rd
+ pass
);
6176 /* Two registers and a scalar. NB that for ops of this form
6177 * the ARM ARM labels bit 24 as Q, but it is in our variable
6184 case 1: /* Float VMLA scalar */
6185 case 5: /* Floating point VMLS scalar */
6186 case 9: /* Floating point VMUL scalar */
6191 case 0: /* Integer VMLA scalar */
6192 case 4: /* Integer VMLS scalar */
6193 case 8: /* Integer VMUL scalar */
6194 case 12: /* VQDMULH scalar */
6195 case 13: /* VQRDMULH scalar */
6196 if (u
&& ((rd
| rn
) & 1)) {
6199 tmp
= neon_get_scalar(size
, rm
);
6200 neon_store_scratch(0, tmp
);
6201 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6202 tmp
= neon_load_scratch(0);
6203 tmp2
= neon_load_reg(rn
, pass
);
6206 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6208 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6210 } else if (op
== 13) {
6212 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6214 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6216 } else if (op
& 1) {
6217 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6218 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6219 tcg_temp_free_ptr(fpstatus
);
6222 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6223 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6224 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6228 tcg_temp_free_i32(tmp2
);
6231 tmp2
= neon_load_reg(rd
, pass
);
6234 gen_neon_add(size
, tmp
, tmp2
);
6238 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6239 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6240 tcg_temp_free_ptr(fpstatus
);
6244 gen_neon_rsb(size
, tmp
, tmp2
);
6248 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6249 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6250 tcg_temp_free_ptr(fpstatus
);
6256 tcg_temp_free_i32(tmp2
);
6258 neon_store_reg(rd
, pass
, tmp
);
6261 case 3: /* VQDMLAL scalar */
6262 case 7: /* VQDMLSL scalar */
6263 case 11: /* VQDMULL scalar */
6268 case 2: /* VMLAL sclar */
6269 case 6: /* VMLSL scalar */
6270 case 10: /* VMULL scalar */
6274 tmp2
= neon_get_scalar(size
, rm
);
6275 /* We need a copy of tmp2 because gen_neon_mull
6276 * deletes it during pass 0. */
6277 tmp4
= tcg_temp_new_i32();
6278 tcg_gen_mov_i32(tmp4
, tmp2
);
6279 tmp3
= neon_load_reg(rn
, 1);
6281 for (pass
= 0; pass
< 2; pass
++) {
6283 tmp
= neon_load_reg(rn
, 0);
6288 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6290 neon_load_reg64(cpu_V1
, rd
+ pass
);
6294 gen_neon_negl(cpu_V0
, size
);
6297 gen_neon_addl(size
);
6300 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6302 gen_neon_negl(cpu_V0
, size
);
6304 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6310 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6315 neon_store_reg64(cpu_V0
, rd
+ pass
);
6320 default: /* 14 and 15 are RESERVED */
6324 } else { /* size == 3 */
6327 imm
= (insn
>> 8) & 0xf;
6332 if (q
&& ((rd
| rn
| rm
) & 1)) {
6337 neon_load_reg64(cpu_V0
, rn
);
6339 neon_load_reg64(cpu_V1
, rn
+ 1);
6341 } else if (imm
== 8) {
6342 neon_load_reg64(cpu_V0
, rn
+ 1);
6344 neon_load_reg64(cpu_V1
, rm
);
6347 tmp64
= tcg_temp_new_i64();
6349 neon_load_reg64(cpu_V0
, rn
);
6350 neon_load_reg64(tmp64
, rn
+ 1);
6352 neon_load_reg64(cpu_V0
, rn
+ 1);
6353 neon_load_reg64(tmp64
, rm
);
6355 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6356 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6357 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6359 neon_load_reg64(cpu_V1
, rm
);
6361 neon_load_reg64(cpu_V1
, rm
+ 1);
6364 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6365 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6366 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6367 tcg_temp_free_i64(tmp64
);
6370 neon_load_reg64(cpu_V0
, rn
);
6371 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6372 neon_load_reg64(cpu_V1
, rm
);
6373 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6374 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6376 neon_store_reg64(cpu_V0
, rd
);
6378 neon_store_reg64(cpu_V1
, rd
+ 1);
6380 } else if ((insn
& (1 << 11)) == 0) {
6381 /* Two register misc. */
6382 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6383 size
= (insn
>> 18) & 3;
6384 /* UNDEF for unknown op values and bad op-size combinations */
6385 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6388 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6389 q
&& ((rm
| rd
) & 1)) {
6393 case NEON_2RM_VREV64
:
6394 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6395 tmp
= neon_load_reg(rm
, pass
* 2);
6396 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6398 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6399 case 1: gen_swap_half(tmp
); break;
6400 case 2: /* no-op */ break;
6403 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6405 neon_store_reg(rd
, pass
* 2, tmp2
);
6408 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6409 case 1: gen_swap_half(tmp2
); break;
6412 neon_store_reg(rd
, pass
* 2, tmp2
);
6416 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6417 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6418 for (pass
= 0; pass
< q
+ 1; pass
++) {
6419 tmp
= neon_load_reg(rm
, pass
* 2);
6420 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6421 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6422 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6424 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6425 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6426 case 2: tcg_gen_add_i64(CPU_V001
); break;
6429 if (op
>= NEON_2RM_VPADAL
) {
6431 neon_load_reg64(cpu_V1
, rd
+ pass
);
6432 gen_neon_addl(size
);
6434 neon_store_reg64(cpu_V0
, rd
+ pass
);
6440 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6441 tmp
= neon_load_reg(rm
, n
);
6442 tmp2
= neon_load_reg(rd
, n
+ 1);
6443 neon_store_reg(rm
, n
, tmp2
);
6444 neon_store_reg(rd
, n
+ 1, tmp
);
6451 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6456 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6460 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6461 /* also VQMOVUN; op field and mnemonics don't line up */
6465 TCGV_UNUSED_I32(tmp2
);
6466 for (pass
= 0; pass
< 2; pass
++) {
6467 neon_load_reg64(cpu_V0
, rm
+ pass
);
6468 tmp
= tcg_temp_new_i32();
6469 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6474 neon_store_reg(rd
, 0, tmp2
);
6475 neon_store_reg(rd
, 1, tmp
);
6479 case NEON_2RM_VSHLL
:
6480 if (q
|| (rd
& 1)) {
6483 tmp
= neon_load_reg(rm
, 0);
6484 tmp2
= neon_load_reg(rm
, 1);
6485 for (pass
= 0; pass
< 2; pass
++) {
6488 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6489 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6490 neon_store_reg64(cpu_V0
, rd
+ pass
);
6493 case NEON_2RM_VCVT_F16_F32
:
6494 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6498 tmp
= tcg_temp_new_i32();
6499 tmp2
= tcg_temp_new_i32();
6500 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6501 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6502 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6503 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6504 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6505 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6506 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6507 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6508 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6509 neon_store_reg(rd
, 0, tmp2
);
6510 tmp2
= tcg_temp_new_i32();
6511 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6512 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6513 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6514 neon_store_reg(rd
, 1, tmp2
);
6515 tcg_temp_free_i32(tmp
);
6517 case NEON_2RM_VCVT_F32_F16
:
6518 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6522 tmp3
= tcg_temp_new_i32();
6523 tmp
= neon_load_reg(rm
, 0);
6524 tmp2
= neon_load_reg(rm
, 1);
6525 tcg_gen_ext16u_i32(tmp3
, tmp
);
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
, 0));
6528 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6529 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6530 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6531 tcg_temp_free_i32(tmp
);
6532 tcg_gen_ext16u_i32(tmp3
, tmp2
);
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
, 2));
6535 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6536 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6537 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6538 tcg_temp_free_i32(tmp2
);
6539 tcg_temp_free_i32(tmp3
);
6541 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6542 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6543 || ((rm
| rd
) & 1)) {
6546 tmp
= tcg_const_i32(rd
);
6547 tmp2
= tcg_const_i32(rm
);
6549 /* Bit 6 is the lowest opcode bit; it distinguishes between
6550 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6552 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6554 if (op
== NEON_2RM_AESE
) {
6555 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6557 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6559 tcg_temp_free_i32(tmp
);
6560 tcg_temp_free_i32(tmp2
);
6561 tcg_temp_free_i32(tmp3
);
6563 case NEON_2RM_SHA1H
:
6564 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6565 || ((rm
| rd
) & 1)) {
6568 tmp
= tcg_const_i32(rd
);
6569 tmp2
= tcg_const_i32(rm
);
6571 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6573 tcg_temp_free_i32(tmp
);
6574 tcg_temp_free_i32(tmp2
);
6576 case NEON_2RM_SHA1SU1
:
6577 if ((rm
| rd
) & 1) {
6580 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6582 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6585 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6588 tmp
= tcg_const_i32(rd
);
6589 tmp2
= tcg_const_i32(rm
);
6591 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6593 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6595 tcg_temp_free_i32(tmp
);
6596 tcg_temp_free_i32(tmp2
);
6600 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6601 if (neon_2rm_is_float_op(op
)) {
6602 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6603 neon_reg_offset(rm
, pass
));
6604 TCGV_UNUSED_I32(tmp
);
6606 tmp
= neon_load_reg(rm
, pass
);
6609 case NEON_2RM_VREV32
:
6611 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6612 case 1: gen_swap_half(tmp
); break;
6616 case NEON_2RM_VREV16
:
6621 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6622 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6623 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6629 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6630 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6631 case 2: gen_helper_clz(tmp
, tmp
); break;
6636 gen_helper_neon_cnt_u8(tmp
, tmp
);
6639 tcg_gen_not_i32(tmp
, tmp
);
6641 case NEON_2RM_VQABS
:
6644 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6647 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6650 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6655 case NEON_2RM_VQNEG
:
6658 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6661 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6664 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6669 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6670 tmp2
= tcg_const_i32(0);
6672 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6673 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6674 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6677 tcg_temp_free_i32(tmp2
);
6678 if (op
== NEON_2RM_VCLE0
) {
6679 tcg_gen_not_i32(tmp
, tmp
);
6682 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6683 tmp2
= tcg_const_i32(0);
6685 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6686 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6687 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6690 tcg_temp_free_i32(tmp2
);
6691 if (op
== NEON_2RM_VCLT0
) {
6692 tcg_gen_not_i32(tmp
, tmp
);
6695 case NEON_2RM_VCEQ0
:
6696 tmp2
= tcg_const_i32(0);
6698 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6699 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6700 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6703 tcg_temp_free_i32(tmp2
);
6707 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6708 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6709 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6714 tmp2
= tcg_const_i32(0);
6715 gen_neon_rsb(size
, tmp
, tmp2
);
6716 tcg_temp_free_i32(tmp2
);
6718 case NEON_2RM_VCGT0_F
:
6720 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6721 tmp2
= tcg_const_i32(0);
6722 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6723 tcg_temp_free_i32(tmp2
);
6724 tcg_temp_free_ptr(fpstatus
);
6727 case NEON_2RM_VCGE0_F
:
6729 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6730 tmp2
= tcg_const_i32(0);
6731 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6732 tcg_temp_free_i32(tmp2
);
6733 tcg_temp_free_ptr(fpstatus
);
6736 case NEON_2RM_VCEQ0_F
:
6738 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6739 tmp2
= tcg_const_i32(0);
6740 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6741 tcg_temp_free_i32(tmp2
);
6742 tcg_temp_free_ptr(fpstatus
);
6745 case NEON_2RM_VCLE0_F
:
6747 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6748 tmp2
= tcg_const_i32(0);
6749 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6750 tcg_temp_free_i32(tmp2
);
6751 tcg_temp_free_ptr(fpstatus
);
6754 case NEON_2RM_VCLT0_F
:
6756 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6757 tmp2
= tcg_const_i32(0);
6758 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6759 tcg_temp_free_i32(tmp2
);
6760 tcg_temp_free_ptr(fpstatus
);
6763 case NEON_2RM_VABS_F
:
6766 case NEON_2RM_VNEG_F
:
6770 tmp2
= neon_load_reg(rd
, pass
);
6771 neon_store_reg(rm
, pass
, tmp2
);
6774 tmp2
= neon_load_reg(rd
, pass
);
6776 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6777 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6780 neon_store_reg(rm
, pass
, tmp2
);
6782 case NEON_2RM_VRINTN
:
6783 case NEON_2RM_VRINTA
:
6784 case NEON_2RM_VRINTM
:
6785 case NEON_2RM_VRINTP
:
6786 case NEON_2RM_VRINTZ
:
6789 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6792 if (op
== NEON_2RM_VRINTZ
) {
6793 rmode
= FPROUNDING_ZERO
;
6795 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6798 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6799 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6801 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6802 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6804 tcg_temp_free_ptr(fpstatus
);
6805 tcg_temp_free_i32(tcg_rmode
);
6808 case NEON_2RM_VRINTX
:
6810 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6811 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6812 tcg_temp_free_ptr(fpstatus
);
6815 case NEON_2RM_VCVTAU
:
6816 case NEON_2RM_VCVTAS
:
6817 case NEON_2RM_VCVTNU
:
6818 case NEON_2RM_VCVTNS
:
6819 case NEON_2RM_VCVTPU
:
6820 case NEON_2RM_VCVTPS
:
6821 case NEON_2RM_VCVTMU
:
6822 case NEON_2RM_VCVTMS
:
6824 bool is_signed
= !extract32(insn
, 7, 1);
6825 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6826 TCGv_i32 tcg_rmode
, tcg_shift
;
6827 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6829 tcg_shift
= tcg_const_i32(0);
6830 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6831 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6835 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6838 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6842 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6844 tcg_temp_free_i32(tcg_rmode
);
6845 tcg_temp_free_i32(tcg_shift
);
6846 tcg_temp_free_ptr(fpst
);
6849 case NEON_2RM_VRECPE
:
6851 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6852 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6853 tcg_temp_free_ptr(fpstatus
);
6856 case NEON_2RM_VRSQRTE
:
6858 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6859 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6860 tcg_temp_free_ptr(fpstatus
);
6863 case NEON_2RM_VRECPE_F
:
6865 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6866 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6867 tcg_temp_free_ptr(fpstatus
);
6870 case NEON_2RM_VRSQRTE_F
:
6872 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6873 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6874 tcg_temp_free_ptr(fpstatus
);
6877 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6880 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6883 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6884 gen_vfp_tosiz(0, 1);
6886 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6887 gen_vfp_touiz(0, 1);
6890 /* Reserved op values were caught by the
6891 * neon_2rm_sizes[] check earlier.
6895 if (neon_2rm_is_float_op(op
)) {
6896 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6897 neon_reg_offset(rd
, pass
));
6899 neon_store_reg(rd
, pass
, tmp
);
6904 } else if ((insn
& (1 << 10)) == 0) {
6906 int n
= ((insn
>> 8) & 3) + 1;
6907 if ((rn
+ n
) > 32) {
6908 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6909 * helper function running off the end of the register file.
6914 if (insn
& (1 << 6)) {
6915 tmp
= neon_load_reg(rd
, 0);
6917 tmp
= tcg_temp_new_i32();
6918 tcg_gen_movi_i32(tmp
, 0);
6920 tmp2
= neon_load_reg(rm
, 0);
6921 tmp4
= tcg_const_i32(rn
);
6922 tmp5
= tcg_const_i32(n
);
6923 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6924 tcg_temp_free_i32(tmp
);
6925 if (insn
& (1 << 6)) {
6926 tmp
= neon_load_reg(rd
, 1);
6928 tmp
= tcg_temp_new_i32();
6929 tcg_gen_movi_i32(tmp
, 0);
6931 tmp3
= neon_load_reg(rm
, 1);
6932 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6933 tcg_temp_free_i32(tmp5
);
6934 tcg_temp_free_i32(tmp4
);
6935 neon_store_reg(rd
, 0, tmp2
);
6936 neon_store_reg(rd
, 1, tmp3
);
6937 tcg_temp_free_i32(tmp
);
6938 } else if ((insn
& 0x380) == 0) {
6940 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6943 if (insn
& (1 << 19)) {
6944 tmp
= neon_load_reg(rm
, 1);
6946 tmp
= neon_load_reg(rm
, 0);
6948 if (insn
& (1 << 16)) {
6949 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6950 } else if (insn
& (1 << 17)) {
6951 if ((insn
>> 18) & 1)
6952 gen_neon_dup_high16(tmp
);
6954 gen_neon_dup_low16(tmp
);
6956 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6957 tmp2
= tcg_temp_new_i32();
6958 tcg_gen_mov_i32(tmp2
, tmp
);
6959 neon_store_reg(rd
, pass
, tmp2
);
6961 tcg_temp_free_i32(tmp
);
6970 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6972 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6973 const ARMCPRegInfo
*ri
;
6975 cpnum
= (insn
>> 8) & 0xf;
6976 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6977 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6980 /* First check for coprocessor space used for actual instructions */
6984 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6985 return disas_iwmmxt_insn(env
, s
, insn
);
6986 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6987 return disas_dsp_insn(env
, s
, insn
);
6994 /* Otherwise treat as a generic register access */
6995 is64
= (insn
& (1 << 25)) == 0;
6996 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7004 opc1
= (insn
>> 4) & 0xf;
7006 rt2
= (insn
>> 16) & 0xf;
7008 crn
= (insn
>> 16) & 0xf;
7009 opc1
= (insn
>> 21) & 7;
7010 opc2
= (insn
>> 5) & 7;
7013 isread
= (insn
>> 20) & 1;
7014 rt
= (insn
>> 12) & 0xf;
7016 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7017 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7019 /* Check access permissions */
7020 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
7025 /* Emit code to perform further access permissions checks at
7026 * runtime; this may result in an exception.
7032 /* Note that since we are an implementation which takes an
7033 * exception on a trapped conditional instruction only if the
7034 * instruction passes its condition code check, we can take
7035 * advantage of the clause in the ARM ARM that allows us to set
7036 * the COND field in the instruction to 0xE in all cases.
7037 * We could fish the actual condition out of the insn (ARM)
7038 * or the condexec bits (Thumb) but it isn't necessary.
7043 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7046 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7047 rt
, isread
, s
->thumb
);
7052 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7055 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7056 rt
, isread
, s
->thumb
);
7060 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7061 * so this can only happen if this is an ARMv7 or earlier CPU,
7062 * in which case the syndrome information won't actually be
7065 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7066 syndrome
= syn_uncategorized();
7070 gen_set_pc_im(s
, s
->pc
);
7071 tmpptr
= tcg_const_ptr(ri
);
7072 tcg_syn
= tcg_const_i32(syndrome
);
7073 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7074 tcg_temp_free_ptr(tmpptr
);
7075 tcg_temp_free_i32(tcg_syn
);
7078 /* Handle special cases first */
7079 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7086 gen_set_pc_im(s
, s
->pc
);
7087 s
->is_jmp
= DISAS_WFI
;
7093 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7102 if (ri
->type
& ARM_CP_CONST
) {
7103 tmp64
= tcg_const_i64(ri
->resetvalue
);
7104 } else if (ri
->readfn
) {
7106 tmp64
= tcg_temp_new_i64();
7107 tmpptr
= tcg_const_ptr(ri
);
7108 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7109 tcg_temp_free_ptr(tmpptr
);
7111 tmp64
= tcg_temp_new_i64();
7112 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7114 tmp
= tcg_temp_new_i32();
7115 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7116 store_reg(s
, rt
, tmp
);
7117 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7118 tmp
= tcg_temp_new_i32();
7119 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7120 tcg_temp_free_i64(tmp64
);
7121 store_reg(s
, rt2
, tmp
);
7124 if (ri
->type
& ARM_CP_CONST
) {
7125 tmp
= tcg_const_i32(ri
->resetvalue
);
7126 } else if (ri
->readfn
) {
7128 tmp
= tcg_temp_new_i32();
7129 tmpptr
= tcg_const_ptr(ri
);
7130 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7131 tcg_temp_free_ptr(tmpptr
);
7133 tmp
= load_cpu_offset(ri
->fieldoffset
);
7136 /* Destination register of r15 for 32 bit loads sets
7137 * the condition codes from the high 4 bits of the value
7140 tcg_temp_free_i32(tmp
);
7142 store_reg(s
, rt
, tmp
);
7147 if (ri
->type
& ARM_CP_CONST
) {
7148 /* If not forbidden by access permissions, treat as WI */
7153 TCGv_i32 tmplo
, tmphi
;
7154 TCGv_i64 tmp64
= tcg_temp_new_i64();
7155 tmplo
= load_reg(s
, rt
);
7156 tmphi
= load_reg(s
, rt2
);
7157 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7158 tcg_temp_free_i32(tmplo
);
7159 tcg_temp_free_i32(tmphi
);
7161 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7162 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7163 tcg_temp_free_ptr(tmpptr
);
7165 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7167 tcg_temp_free_i64(tmp64
);
7172 tmp
= load_reg(s
, rt
);
7173 tmpptr
= tcg_const_ptr(ri
);
7174 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7175 tcg_temp_free_ptr(tmpptr
);
7176 tcg_temp_free_i32(tmp
);
7178 TCGv_i32 tmp
= load_reg(s
, rt
);
7179 store_cpu_offset(tmp
, ri
->fieldoffset
);
7184 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7185 /* I/O operations must end the TB here (whether read or write) */
7188 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7189 /* We default to ending the TB on a coprocessor register write,
7190 * but allow this to be suppressed by the register definition
7191 * (usually only necessary to work around guest bugs).
7199 /* Unknown register; this might be a guest error or a QEMU
7200 * unimplemented feature.
7203 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7204 "64 bit system register cp:%d opc1: %d crm:%d\n",
7205 isread
? "read" : "write", cpnum
, opc1
, crm
);
7207 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7208 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7209 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7216 /* Store a 64-bit value to a register pair. Clobbers val. */
7217 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7220 tmp
= tcg_temp_new_i32();
7221 tcg_gen_trunc_i64_i32(tmp
, val
);
7222 store_reg(s
, rlow
, tmp
);
7223 tmp
= tcg_temp_new_i32();
7224 tcg_gen_shri_i64(val
, val
, 32);
7225 tcg_gen_trunc_i64_i32(tmp
, val
);
7226 store_reg(s
, rhigh
, tmp
);
7229 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7230 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7235 /* Load value and extend to 64 bits. */
7236 tmp
= tcg_temp_new_i64();
7237 tmp2
= load_reg(s
, rlow
);
7238 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7239 tcg_temp_free_i32(tmp2
);
7240 tcg_gen_add_i64(val
, val
, tmp
);
7241 tcg_temp_free_i64(tmp
);
7244 /* load and add a 64-bit value from a register pair. */
7245 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7251 /* Load 64-bit value rd:rn. */
7252 tmpl
= load_reg(s
, rlow
);
7253 tmph
= load_reg(s
, rhigh
);
7254 tmp
= tcg_temp_new_i64();
7255 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7256 tcg_temp_free_i32(tmpl
);
7257 tcg_temp_free_i32(tmph
);
7258 tcg_gen_add_i64(val
, val
, tmp
);
7259 tcg_temp_free_i64(tmp
);
7262 /* Set N and Z flags from hi|lo. */
7263 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7265 tcg_gen_mov_i32(cpu_NF
, hi
);
7266 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7269 /* Load/Store exclusive instructions are implemented by remembering
7270 the value/address loaded, and seeing if these are the same
7271 when the store is performed. This should be sufficient to implement
7272 the architecturally mandated semantics, and avoids having to monitor
7275 In system emulation mode only one CPU will be running at once, so
7276 this sequence is effectively atomic. In user emulation mode we
7277 throw an exception and handle the atomic operation elsewhere. */
7278 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7279 TCGv_i32 addr
, int size
)
7281 TCGv_i32 tmp
= tcg_temp_new_i32();
7285 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7288 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7292 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7299 TCGv_i32 tmp2
= tcg_temp_new_i32();
7300 TCGv_i32 tmp3
= tcg_temp_new_i32();
7302 tcg_gen_addi_i32(tmp2
, addr
, 4);
7303 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7304 tcg_temp_free_i32(tmp2
);
7305 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7306 store_reg(s
, rt2
, tmp3
);
7308 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7311 store_reg(s
, rt
, tmp
);
7312 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7315 static void gen_clrex(DisasContext
*s
)
7317 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7320 #ifdef CONFIG_USER_ONLY
7321 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7322 TCGv_i32 addr
, int size
)
7324 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7325 tcg_gen_movi_i32(cpu_exclusive_info
,
7326 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7327 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7330 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7331 TCGv_i32 addr
, int size
)
7334 TCGv_i64 val64
, extaddr
;
7338 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7344 fail_label
= gen_new_label();
7345 done_label
= gen_new_label();
7346 extaddr
= tcg_temp_new_i64();
7347 tcg_gen_extu_i32_i64(extaddr
, addr
);
7348 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7349 tcg_temp_free_i64(extaddr
);
7351 tmp
= tcg_temp_new_i32();
7354 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7357 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7361 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7367 val64
= tcg_temp_new_i64();
7369 TCGv_i32 tmp2
= tcg_temp_new_i32();
7370 TCGv_i32 tmp3
= tcg_temp_new_i32();
7371 tcg_gen_addi_i32(tmp2
, addr
, 4);
7372 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7373 tcg_temp_free_i32(tmp2
);
7374 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7375 tcg_temp_free_i32(tmp3
);
7377 tcg_gen_extu_i32_i64(val64
, tmp
);
7379 tcg_temp_free_i32(tmp
);
7381 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7382 tcg_temp_free_i64(val64
);
7384 tmp
= load_reg(s
, rt
);
7387 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7390 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7394 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7399 tcg_temp_free_i32(tmp
);
7401 tcg_gen_addi_i32(addr
, addr
, 4);
7402 tmp
= load_reg(s
, rt2
);
7403 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7404 tcg_temp_free_i32(tmp
);
7406 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7407 tcg_gen_br(done_label
);
7408 gen_set_label(fail_label
);
7409 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7410 gen_set_label(done_label
);
7411 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7418 * @mode: mode field from insn (which stack to store to)
7419 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7420 * @writeback: true if writeback bit set
7422 * Generate code for the SRS (Store Return State) insn.
7424 static void gen_srs(DisasContext
*s
,
7425 uint32_t mode
, uint32_t amode
, bool writeback
)
7428 TCGv_i32 addr
= tcg_temp_new_i32();
7429 TCGv_i32 tmp
= tcg_const_i32(mode
);
7430 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7431 tcg_temp_free_i32(tmp
);
7448 tcg_gen_addi_i32(addr
, addr
, offset
);
7449 tmp
= load_reg(s
, 14);
7450 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7451 tcg_temp_free_i32(tmp
);
7452 tmp
= load_cpu_field(spsr
);
7453 tcg_gen_addi_i32(addr
, addr
, 4);
7454 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7455 tcg_temp_free_i32(tmp
);
7473 tcg_gen_addi_i32(addr
, addr
, offset
);
7474 tmp
= tcg_const_i32(mode
);
7475 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7476 tcg_temp_free_i32(tmp
);
7478 tcg_temp_free_i32(addr
);
7481 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7483 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7490 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7493 /* M variants do not implement ARM mode. */
7498 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7499 * choose to UNDEF. In ARMv5 and above the space is used
7500 * for miscellaneous unconditional instructions.
7504 /* Unconditional instructions. */
7505 if (((insn
>> 25) & 7) == 1) {
7506 /* NEON Data processing. */
7507 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7510 if (disas_neon_data_insn(env
, s
, insn
))
7514 if ((insn
& 0x0f100000) == 0x04000000) {
7515 /* NEON load/store. */
7516 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7519 if (disas_neon_ls_insn(env
, s
, insn
))
7523 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7525 if (disas_vfp_insn(env
, s
, insn
)) {
7530 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7531 ((insn
& 0x0f30f010) == 0x0710f000)) {
7532 if ((insn
& (1 << 22)) == 0) {
7534 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7538 /* Otherwise PLD; v5TE+ */
7542 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7543 ((insn
& 0x0f70f010) == 0x0650f000)) {
7545 return; /* PLI; V7 */
7547 if (((insn
& 0x0f700000) == 0x04100000) ||
7548 ((insn
& 0x0f700010) == 0x06100000)) {
7549 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7552 return; /* v7MP: Unallocated memory hint: must NOP */
7555 if ((insn
& 0x0ffffdff) == 0x01010000) {
7558 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7559 /* Dynamic endianness switching not implemented. */
7560 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7564 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7565 switch ((insn
>> 4) & 0xf) {
7574 /* We don't emulate caches so these are a no-op. */
7579 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7585 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7587 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7593 rn
= (insn
>> 16) & 0xf;
7594 addr
= load_reg(s
, rn
);
7595 i
= (insn
>> 23) & 3;
7597 case 0: offset
= -4; break; /* DA */
7598 case 1: offset
= 0; break; /* IA */
7599 case 2: offset
= -8; break; /* DB */
7600 case 3: offset
= 4; break; /* IB */
7604 tcg_gen_addi_i32(addr
, addr
, offset
);
7605 /* Load PC into tmp and CPSR into tmp2. */
7606 tmp
= tcg_temp_new_i32();
7607 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7608 tcg_gen_addi_i32(addr
, addr
, 4);
7609 tmp2
= tcg_temp_new_i32();
7610 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7611 if (insn
& (1 << 21)) {
7612 /* Base writeback. */
7614 case 0: offset
= -8; break;
7615 case 1: offset
= 4; break;
7616 case 2: offset
= -4; break;
7617 case 3: offset
= 0; break;
7621 tcg_gen_addi_i32(addr
, addr
, offset
);
7622 store_reg(s
, rn
, addr
);
7624 tcg_temp_free_i32(addr
);
7626 gen_rfe(s
, tmp
, tmp2
);
7628 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7629 /* branch link and change to thumb (blx <offset>) */
7632 val
= (uint32_t)s
->pc
;
7633 tmp
= tcg_temp_new_i32();
7634 tcg_gen_movi_i32(tmp
, val
);
7635 store_reg(s
, 14, tmp
);
7636 /* Sign-extend the 24-bit offset */
7637 offset
= (((int32_t)insn
) << 8) >> 8;
7638 /* offset * 4 + bit24 * 2 + (thumb bit) */
7639 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7640 /* pipeline offset */
7642 /* protected by ARCH(5); above, near the start of uncond block */
7645 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7646 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7647 /* iWMMXt register transfer. */
7648 if (env
->cp15
.c15_cpar
& (1 << 1))
7649 if (!disas_iwmmxt_insn(env
, s
, insn
))
7652 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7653 /* Coprocessor double register transfer. */
7655 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7656 /* Additional coprocessor register transfer. */
7657 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7660 /* cps (privileged) */
7664 if (insn
& (1 << 19)) {
7665 if (insn
& (1 << 8))
7667 if (insn
& (1 << 7))
7669 if (insn
& (1 << 6))
7671 if (insn
& (1 << 18))
7674 if (insn
& (1 << 17)) {
7676 val
|= (insn
& 0x1f);
7679 gen_set_psr_im(s
, mask
, 0, val
);
7686 /* if not always execute, we generate a conditional jump to
7688 s
->condlabel
= gen_new_label();
7689 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7692 if ((insn
& 0x0f900000) == 0x03000000) {
7693 if ((insn
& (1 << 21)) == 0) {
7695 rd
= (insn
>> 12) & 0xf;
7696 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7697 if ((insn
& (1 << 22)) == 0) {
7699 tmp
= tcg_temp_new_i32();
7700 tcg_gen_movi_i32(tmp
, val
);
7703 tmp
= load_reg(s
, rd
);
7704 tcg_gen_ext16u_i32(tmp
, tmp
);
7705 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7707 store_reg(s
, rd
, tmp
);
7709 if (((insn
>> 12) & 0xf) != 0xf)
7711 if (((insn
>> 16) & 0xf) == 0) {
7712 gen_nop_hint(s
, insn
& 0xff);
7714 /* CPSR = immediate */
7716 shift
= ((insn
>> 8) & 0xf) * 2;
7718 val
= (val
>> shift
) | (val
<< (32 - shift
));
7719 i
= ((insn
& (1 << 22)) != 0);
7720 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7724 } else if ((insn
& 0x0f900000) == 0x01000000
7725 && (insn
& 0x00000090) != 0x00000090) {
7726 /* miscellaneous instructions */
7727 op1
= (insn
>> 21) & 3;
7728 sh
= (insn
>> 4) & 0xf;
7731 case 0x0: /* move program status register */
7734 tmp
= load_reg(s
, rm
);
7735 i
= ((op1
& 2) != 0);
7736 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7740 rd
= (insn
>> 12) & 0xf;
7744 tmp
= load_cpu_field(spsr
);
7746 tmp
= tcg_temp_new_i32();
7747 gen_helper_cpsr_read(tmp
, cpu_env
);
7749 store_reg(s
, rd
, tmp
);
7754 /* branch/exchange thumb (bx). */
7756 tmp
= load_reg(s
, rm
);
7758 } else if (op1
== 3) {
7761 rd
= (insn
>> 12) & 0xf;
7762 tmp
= load_reg(s
, rm
);
7763 gen_helper_clz(tmp
, tmp
);
7764 store_reg(s
, rd
, tmp
);
7772 /* Trivial implementation equivalent to bx. */
7773 tmp
= load_reg(s
, rm
);
7784 /* branch link/exchange thumb (blx) */
7785 tmp
= load_reg(s
, rm
);
7786 tmp2
= tcg_temp_new_i32();
7787 tcg_gen_movi_i32(tmp2
, s
->pc
);
7788 store_reg(s
, 14, tmp2
);
7794 uint32_t c
= extract32(insn
, 8, 4);
7796 /* Check this CPU supports ARMv8 CRC instructions.
7797 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7798 * Bits 8, 10 and 11 should be zero.
7800 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7805 rn
= extract32(insn
, 16, 4);
7806 rd
= extract32(insn
, 12, 4);
7808 tmp
= load_reg(s
, rn
);
7809 tmp2
= load_reg(s
, rm
);
7811 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7812 } else if (op1
== 1) {
7813 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7815 tmp3
= tcg_const_i32(1 << op1
);
7817 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7819 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7821 tcg_temp_free_i32(tmp2
);
7822 tcg_temp_free_i32(tmp3
);
7823 store_reg(s
, rd
, tmp
);
7826 case 0x5: /* saturating add/subtract */
7828 rd
= (insn
>> 12) & 0xf;
7829 rn
= (insn
>> 16) & 0xf;
7830 tmp
= load_reg(s
, rm
);
7831 tmp2
= load_reg(s
, rn
);
7833 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7835 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7837 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7838 tcg_temp_free_i32(tmp2
);
7839 store_reg(s
, rd
, tmp
);
7843 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7844 /* SMC instruction (op1 == 3)
7845 and undefined instructions (op1 == 0 || op1 == 2)
7852 gen_exception_insn(s
, 4, EXCP_BKPT
, syn_aa32_bkpt(imm16
, false));
7855 case 0x8: /* signed multiply */
7860 rs
= (insn
>> 8) & 0xf;
7861 rn
= (insn
>> 12) & 0xf;
7862 rd
= (insn
>> 16) & 0xf;
7864 /* (32 * 16) >> 16 */
7865 tmp
= load_reg(s
, rm
);
7866 tmp2
= load_reg(s
, rs
);
7868 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7871 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7872 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7873 tmp
= tcg_temp_new_i32();
7874 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7875 tcg_temp_free_i64(tmp64
);
7876 if ((sh
& 2) == 0) {
7877 tmp2
= load_reg(s
, rn
);
7878 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7879 tcg_temp_free_i32(tmp2
);
7881 store_reg(s
, rd
, tmp
);
7884 tmp
= load_reg(s
, rm
);
7885 tmp2
= load_reg(s
, rs
);
7886 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7887 tcg_temp_free_i32(tmp2
);
7889 tmp64
= tcg_temp_new_i64();
7890 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7891 tcg_temp_free_i32(tmp
);
7892 gen_addq(s
, tmp64
, rn
, rd
);
7893 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7894 tcg_temp_free_i64(tmp64
);
7897 tmp2
= load_reg(s
, rn
);
7898 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7899 tcg_temp_free_i32(tmp2
);
7901 store_reg(s
, rd
, tmp
);
7908 } else if (((insn
& 0x0e000000) == 0 &&
7909 (insn
& 0x00000090) != 0x90) ||
7910 ((insn
& 0x0e000000) == (1 << 25))) {
7911 int set_cc
, logic_cc
, shiftop
;
7913 op1
= (insn
>> 21) & 0xf;
7914 set_cc
= (insn
>> 20) & 1;
7915 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7917 /* data processing instruction */
7918 if (insn
& (1 << 25)) {
7919 /* immediate operand */
7921 shift
= ((insn
>> 8) & 0xf) * 2;
7923 val
= (val
>> shift
) | (val
<< (32 - shift
));
7925 tmp2
= tcg_temp_new_i32();
7926 tcg_gen_movi_i32(tmp2
, val
);
7927 if (logic_cc
&& shift
) {
7928 gen_set_CF_bit31(tmp2
);
7933 tmp2
= load_reg(s
, rm
);
7934 shiftop
= (insn
>> 5) & 3;
7935 if (!(insn
& (1 << 4))) {
7936 shift
= (insn
>> 7) & 0x1f;
7937 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7939 rs
= (insn
>> 8) & 0xf;
7940 tmp
= load_reg(s
, rs
);
7941 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7944 if (op1
!= 0x0f && op1
!= 0x0d) {
7945 rn
= (insn
>> 16) & 0xf;
7946 tmp
= load_reg(s
, rn
);
7948 TCGV_UNUSED_I32(tmp
);
7950 rd
= (insn
>> 12) & 0xf;
7953 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7957 store_reg_bx(env
, s
, rd
, tmp
);
7960 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7964 store_reg_bx(env
, s
, rd
, tmp
);
7967 if (set_cc
&& rd
== 15) {
7968 /* SUBS r15, ... is used for exception return. */
7972 gen_sub_CC(tmp
, tmp
, tmp2
);
7973 gen_exception_return(s
, tmp
);
7976 gen_sub_CC(tmp
, tmp
, tmp2
);
7978 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7980 store_reg_bx(env
, s
, rd
, tmp
);
7985 gen_sub_CC(tmp
, tmp2
, tmp
);
7987 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7989 store_reg_bx(env
, s
, rd
, tmp
);
7993 gen_add_CC(tmp
, tmp
, tmp2
);
7995 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7997 store_reg_bx(env
, s
, rd
, tmp
);
8001 gen_adc_CC(tmp
, tmp
, tmp2
);
8003 gen_add_carry(tmp
, tmp
, tmp2
);
8005 store_reg_bx(env
, s
, rd
, tmp
);
8009 gen_sbc_CC(tmp
, tmp
, tmp2
);
8011 gen_sub_carry(tmp
, tmp
, tmp2
);
8013 store_reg_bx(env
, s
, rd
, tmp
);
8017 gen_sbc_CC(tmp
, tmp2
, tmp
);
8019 gen_sub_carry(tmp
, tmp2
, tmp
);
8021 store_reg_bx(env
, s
, rd
, tmp
);
8025 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8028 tcg_temp_free_i32(tmp
);
8032 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8035 tcg_temp_free_i32(tmp
);
8039 gen_sub_CC(tmp
, tmp
, tmp2
);
8041 tcg_temp_free_i32(tmp
);
8045 gen_add_CC(tmp
, tmp
, tmp2
);
8047 tcg_temp_free_i32(tmp
);
8050 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8054 store_reg_bx(env
, s
, rd
, tmp
);
8057 if (logic_cc
&& rd
== 15) {
8058 /* MOVS r15, ... is used for exception return. */
8062 gen_exception_return(s
, tmp2
);
8067 store_reg_bx(env
, s
, rd
, tmp2
);
8071 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8075 store_reg_bx(env
, s
, rd
, tmp
);
8079 tcg_gen_not_i32(tmp2
, tmp2
);
8083 store_reg_bx(env
, s
, rd
, tmp2
);
8086 if (op1
!= 0x0f && op1
!= 0x0d) {
8087 tcg_temp_free_i32(tmp2
);
8090 /* other instructions */
8091 op1
= (insn
>> 24) & 0xf;
8095 /* multiplies, extra load/stores */
8096 sh
= (insn
>> 5) & 3;
8099 rd
= (insn
>> 16) & 0xf;
8100 rn
= (insn
>> 12) & 0xf;
8101 rs
= (insn
>> 8) & 0xf;
8103 op1
= (insn
>> 20) & 0xf;
8105 case 0: case 1: case 2: case 3: case 6:
8107 tmp
= load_reg(s
, rs
);
8108 tmp2
= load_reg(s
, rm
);
8109 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8110 tcg_temp_free_i32(tmp2
);
8111 if (insn
& (1 << 22)) {
8112 /* Subtract (mls) */
8114 tmp2
= load_reg(s
, rn
);
8115 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8116 tcg_temp_free_i32(tmp2
);
8117 } else if (insn
& (1 << 21)) {
8119 tmp2
= load_reg(s
, rn
);
8120 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8121 tcg_temp_free_i32(tmp2
);
8123 if (insn
& (1 << 20))
8125 store_reg(s
, rd
, tmp
);
8128 /* 64 bit mul double accumulate (UMAAL) */
8130 tmp
= load_reg(s
, rs
);
8131 tmp2
= load_reg(s
, rm
);
8132 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8133 gen_addq_lo(s
, tmp64
, rn
);
8134 gen_addq_lo(s
, tmp64
, rd
);
8135 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8136 tcg_temp_free_i64(tmp64
);
8138 case 8: case 9: case 10: case 11:
8139 case 12: case 13: case 14: case 15:
8140 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8141 tmp
= load_reg(s
, rs
);
8142 tmp2
= load_reg(s
, rm
);
8143 if (insn
& (1 << 22)) {
8144 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8146 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8148 if (insn
& (1 << 21)) { /* mult accumulate */
8149 TCGv_i32 al
= load_reg(s
, rn
);
8150 TCGv_i32 ah
= load_reg(s
, rd
);
8151 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8152 tcg_temp_free_i32(al
);
8153 tcg_temp_free_i32(ah
);
8155 if (insn
& (1 << 20)) {
8156 gen_logicq_cc(tmp
, tmp2
);
8158 store_reg(s
, rn
, tmp
);
8159 store_reg(s
, rd
, tmp2
);
8165 rn
= (insn
>> 16) & 0xf;
8166 rd
= (insn
>> 12) & 0xf;
8167 if (insn
& (1 << 23)) {
8168 /* load/store exclusive */
8169 int op2
= (insn
>> 8) & 3;
8170 op1
= (insn
>> 21) & 0x3;
8173 case 0: /* lda/stl */
8179 case 1: /* reserved */
8181 case 2: /* ldaex/stlex */
8184 case 3: /* ldrex/strex */
8193 addr
= tcg_temp_local_new_i32();
8194 load_reg_var(s
, addr
, rn
);
8196 /* Since the emulation does not have barriers,
8197 the acquire/release semantics need no special
8200 if (insn
& (1 << 20)) {
8201 tmp
= tcg_temp_new_i32();
8204 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8207 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8210 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8215 store_reg(s
, rd
, tmp
);
8218 tmp
= load_reg(s
, rm
);
8221 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8224 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8227 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8232 tcg_temp_free_i32(tmp
);
8234 } else if (insn
& (1 << 20)) {
8237 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8239 case 1: /* ldrexd */
8240 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8242 case 2: /* ldrexb */
8243 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8245 case 3: /* ldrexh */
8246 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8255 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8257 case 1: /* strexd */
8258 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8260 case 2: /* strexb */
8261 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8263 case 3: /* strexh */
8264 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8270 tcg_temp_free_i32(addr
);
8272 /* SWP instruction */
8275 /* ??? This is not really atomic. However we know
8276 we never have multiple CPUs running in parallel,
8277 so it is good enough. */
8278 addr
= load_reg(s
, rn
);
8279 tmp
= load_reg(s
, rm
);
8280 tmp2
= tcg_temp_new_i32();
8281 if (insn
& (1 << 22)) {
8282 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8283 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8285 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8286 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8288 tcg_temp_free_i32(tmp
);
8289 tcg_temp_free_i32(addr
);
8290 store_reg(s
, rd
, tmp2
);
8296 /* Misc load/store */
8297 rn
= (insn
>> 16) & 0xf;
8298 rd
= (insn
>> 12) & 0xf;
8299 addr
= load_reg(s
, rn
);
8300 if (insn
& (1 << 24))
8301 gen_add_datah_offset(s
, insn
, 0, addr
);
8303 if (insn
& (1 << 20)) {
8305 tmp
= tcg_temp_new_i32();
8308 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8311 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8315 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8319 } else if (sh
& 2) {
8324 tmp
= load_reg(s
, rd
);
8325 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8326 tcg_temp_free_i32(tmp
);
8327 tcg_gen_addi_i32(addr
, addr
, 4);
8328 tmp
= load_reg(s
, rd
+ 1);
8329 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8330 tcg_temp_free_i32(tmp
);
8334 tmp
= tcg_temp_new_i32();
8335 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8336 store_reg(s
, rd
, tmp
);
8337 tcg_gen_addi_i32(addr
, addr
, 4);
8338 tmp
= tcg_temp_new_i32();
8339 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8343 address_offset
= -4;
8346 tmp
= load_reg(s
, rd
);
8347 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8348 tcg_temp_free_i32(tmp
);
8351 /* Perform base writeback before the loaded value to
8352 ensure correct behavior with overlapping index registers.
8353 ldrd with base writeback is is undefined if the
8354 destination and index registers overlap. */
8355 if (!(insn
& (1 << 24))) {
8356 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8357 store_reg(s
, rn
, addr
);
8358 } else if (insn
& (1 << 21)) {
8360 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8361 store_reg(s
, rn
, addr
);
8363 tcg_temp_free_i32(addr
);
8366 /* Complete the load. */
8367 store_reg(s
, rd
, tmp
);
8376 if (insn
& (1 << 4)) {
8378 /* Armv6 Media instructions. */
8380 rn
= (insn
>> 16) & 0xf;
8381 rd
= (insn
>> 12) & 0xf;
8382 rs
= (insn
>> 8) & 0xf;
8383 switch ((insn
>> 23) & 3) {
8384 case 0: /* Parallel add/subtract. */
8385 op1
= (insn
>> 20) & 7;
8386 tmp
= load_reg(s
, rn
);
8387 tmp2
= load_reg(s
, rm
);
8388 sh
= (insn
>> 5) & 7;
8389 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8391 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8392 tcg_temp_free_i32(tmp2
);
8393 store_reg(s
, rd
, tmp
);
8396 if ((insn
& 0x00700020) == 0) {
8397 /* Halfword pack. */
8398 tmp
= load_reg(s
, rn
);
8399 tmp2
= load_reg(s
, rm
);
8400 shift
= (insn
>> 7) & 0x1f;
8401 if (insn
& (1 << 6)) {
8405 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8406 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8407 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8411 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8412 tcg_gen_ext16u_i32(tmp
, tmp
);
8413 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8415 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8416 tcg_temp_free_i32(tmp2
);
8417 store_reg(s
, rd
, tmp
);
8418 } else if ((insn
& 0x00200020) == 0x00200000) {
8420 tmp
= load_reg(s
, rm
);
8421 shift
= (insn
>> 7) & 0x1f;
8422 if (insn
& (1 << 6)) {
8425 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8427 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8429 sh
= (insn
>> 16) & 0x1f;
8430 tmp2
= tcg_const_i32(sh
);
8431 if (insn
& (1 << 22))
8432 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8434 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8435 tcg_temp_free_i32(tmp2
);
8436 store_reg(s
, rd
, tmp
);
8437 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8439 tmp
= load_reg(s
, rm
);
8440 sh
= (insn
>> 16) & 0x1f;
8441 tmp2
= tcg_const_i32(sh
);
8442 if (insn
& (1 << 22))
8443 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8445 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8446 tcg_temp_free_i32(tmp2
);
8447 store_reg(s
, rd
, tmp
);
8448 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8450 tmp
= load_reg(s
, rn
);
8451 tmp2
= load_reg(s
, rm
);
8452 tmp3
= tcg_temp_new_i32();
8453 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8454 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8455 tcg_temp_free_i32(tmp3
);
8456 tcg_temp_free_i32(tmp2
);
8457 store_reg(s
, rd
, tmp
);
8458 } else if ((insn
& 0x000003e0) == 0x00000060) {
8459 tmp
= load_reg(s
, rm
);
8460 shift
= (insn
>> 10) & 3;
8461 /* ??? In many cases it's not necessary to do a
8462 rotate, a shift is sufficient. */
8464 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8465 op1
= (insn
>> 20) & 7;
8467 case 0: gen_sxtb16(tmp
); break;
8468 case 2: gen_sxtb(tmp
); break;
8469 case 3: gen_sxth(tmp
); break;
8470 case 4: gen_uxtb16(tmp
); break;
8471 case 6: gen_uxtb(tmp
); break;
8472 case 7: gen_uxth(tmp
); break;
8473 default: goto illegal_op
;
8476 tmp2
= load_reg(s
, rn
);
8477 if ((op1
& 3) == 0) {
8478 gen_add16(tmp
, tmp2
);
8480 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8481 tcg_temp_free_i32(tmp2
);
8484 store_reg(s
, rd
, tmp
);
8485 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8487 tmp
= load_reg(s
, rm
);
8488 if (insn
& (1 << 22)) {
8489 if (insn
& (1 << 7)) {
8493 gen_helper_rbit(tmp
, tmp
);
8496 if (insn
& (1 << 7))
8499 tcg_gen_bswap32_i32(tmp
, tmp
);
8501 store_reg(s
, rd
, tmp
);
8506 case 2: /* Multiplies (Type 3). */
8507 switch ((insn
>> 20) & 0x7) {
8509 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8510 /* op2 not 00x or 11x : UNDEF */
8513 /* Signed multiply most significant [accumulate].
8514 (SMMUL, SMMLA, SMMLS) */
8515 tmp
= load_reg(s
, rm
);
8516 tmp2
= load_reg(s
, rs
);
8517 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8520 tmp
= load_reg(s
, rd
);
8521 if (insn
& (1 << 6)) {
8522 tmp64
= gen_subq_msw(tmp64
, tmp
);
8524 tmp64
= gen_addq_msw(tmp64
, tmp
);
8527 if (insn
& (1 << 5)) {
8528 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8530 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8531 tmp
= tcg_temp_new_i32();
8532 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8533 tcg_temp_free_i64(tmp64
);
8534 store_reg(s
, rn
, tmp
);
8538 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8539 if (insn
& (1 << 7)) {
8542 tmp
= load_reg(s
, rm
);
8543 tmp2
= load_reg(s
, rs
);
8544 if (insn
& (1 << 5))
8545 gen_swap_half(tmp2
);
8546 gen_smul_dual(tmp
, tmp2
);
8547 if (insn
& (1 << 22)) {
8548 /* smlald, smlsld */
8551 tmp64
= tcg_temp_new_i64();
8552 tmp64_2
= tcg_temp_new_i64();
8553 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8554 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8555 tcg_temp_free_i32(tmp
);
8556 tcg_temp_free_i32(tmp2
);
8557 if (insn
& (1 << 6)) {
8558 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8560 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8562 tcg_temp_free_i64(tmp64_2
);
8563 gen_addq(s
, tmp64
, rd
, rn
);
8564 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8565 tcg_temp_free_i64(tmp64
);
8567 /* smuad, smusd, smlad, smlsd */
8568 if (insn
& (1 << 6)) {
8569 /* This subtraction cannot overflow. */
8570 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8572 /* This addition cannot overflow 32 bits;
8573 * however it may overflow considered as a
8574 * signed operation, in which case we must set
8577 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8579 tcg_temp_free_i32(tmp2
);
8582 tmp2
= load_reg(s
, rd
);
8583 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8584 tcg_temp_free_i32(tmp2
);
8586 store_reg(s
, rn
, tmp
);
8592 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8595 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8598 tmp
= load_reg(s
, rm
);
8599 tmp2
= load_reg(s
, rs
);
8600 if (insn
& (1 << 21)) {
8601 gen_helper_udiv(tmp
, tmp
, tmp2
);
8603 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8605 tcg_temp_free_i32(tmp2
);
8606 store_reg(s
, rn
, tmp
);
8613 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8615 case 0: /* Unsigned sum of absolute differences. */
8617 tmp
= load_reg(s
, rm
);
8618 tmp2
= load_reg(s
, rs
);
8619 gen_helper_usad8(tmp
, tmp
, tmp2
);
8620 tcg_temp_free_i32(tmp2
);
8622 tmp2
= load_reg(s
, rd
);
8623 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8624 tcg_temp_free_i32(tmp2
);
8626 store_reg(s
, rn
, tmp
);
8628 case 0x20: case 0x24: case 0x28: case 0x2c:
8629 /* Bitfield insert/clear. */
8631 shift
= (insn
>> 7) & 0x1f;
8632 i
= (insn
>> 16) & 0x1f;
8635 tmp
= tcg_temp_new_i32();
8636 tcg_gen_movi_i32(tmp
, 0);
8638 tmp
= load_reg(s
, rm
);
8641 tmp2
= load_reg(s
, rd
);
8642 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8643 tcg_temp_free_i32(tmp2
);
8645 store_reg(s
, rd
, tmp
);
8647 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8648 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8650 tmp
= load_reg(s
, rm
);
8651 shift
= (insn
>> 7) & 0x1f;
8652 i
= ((insn
>> 16) & 0x1f) + 1;
8657 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8659 gen_sbfx(tmp
, shift
, i
);
8662 store_reg(s
, rd
, tmp
);
8672 /* Check for undefined extension instructions
8673 * per the ARM Bible IE:
8674 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8676 sh
= (0xf << 20) | (0xf << 4);
8677 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8681 /* load/store byte/word */
8682 rn
= (insn
>> 16) & 0xf;
8683 rd
= (insn
>> 12) & 0xf;
8684 tmp2
= load_reg(s
, rn
);
8685 if ((insn
& 0x01200000) == 0x00200000) {
8689 i
= get_mem_index(s
);
8691 if (insn
& (1 << 24))
8692 gen_add_data_offset(s
, insn
, tmp2
);
8693 if (insn
& (1 << 20)) {
8695 tmp
= tcg_temp_new_i32();
8696 if (insn
& (1 << 22)) {
8697 gen_aa32_ld8u(tmp
, tmp2
, i
);
8699 gen_aa32_ld32u(tmp
, tmp2
, i
);
8703 tmp
= load_reg(s
, rd
);
8704 if (insn
& (1 << 22)) {
8705 gen_aa32_st8(tmp
, tmp2
, i
);
8707 gen_aa32_st32(tmp
, tmp2
, i
);
8709 tcg_temp_free_i32(tmp
);
8711 if (!(insn
& (1 << 24))) {
8712 gen_add_data_offset(s
, insn
, tmp2
);
8713 store_reg(s
, rn
, tmp2
);
8714 } else if (insn
& (1 << 21)) {
8715 store_reg(s
, rn
, tmp2
);
8717 tcg_temp_free_i32(tmp2
);
8719 if (insn
& (1 << 20)) {
8720 /* Complete the load. */
8721 store_reg_from_load(env
, s
, rd
, tmp
);
8727 int j
, n
, user
, loaded_base
;
8728 TCGv_i32 loaded_var
;
8729 /* load/store multiple words */
8730 /* XXX: store correct base if write back */
8732 if (insn
& (1 << 22)) {
8734 goto illegal_op
; /* only usable in supervisor mode */
8736 if ((insn
& (1 << 15)) == 0)
8739 rn
= (insn
>> 16) & 0xf;
8740 addr
= load_reg(s
, rn
);
8742 /* compute total size */
8744 TCGV_UNUSED_I32(loaded_var
);
8747 if (insn
& (1 << i
))
8750 /* XXX: test invalid n == 0 case ? */
8751 if (insn
& (1 << 23)) {
8752 if (insn
& (1 << 24)) {
8754 tcg_gen_addi_i32(addr
, addr
, 4);
8756 /* post increment */
8759 if (insn
& (1 << 24)) {
8761 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8763 /* post decrement */
8765 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8770 if (insn
& (1 << i
)) {
8771 if (insn
& (1 << 20)) {
8773 tmp
= tcg_temp_new_i32();
8774 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8776 tmp2
= tcg_const_i32(i
);
8777 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8778 tcg_temp_free_i32(tmp2
);
8779 tcg_temp_free_i32(tmp
);
8780 } else if (i
== rn
) {
8784 store_reg_from_load(env
, s
, i
, tmp
);
8789 /* special case: r15 = PC + 8 */
8790 val
= (long)s
->pc
+ 4;
8791 tmp
= tcg_temp_new_i32();
8792 tcg_gen_movi_i32(tmp
, val
);
8794 tmp
= tcg_temp_new_i32();
8795 tmp2
= tcg_const_i32(i
);
8796 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8797 tcg_temp_free_i32(tmp2
);
8799 tmp
= load_reg(s
, i
);
8801 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8802 tcg_temp_free_i32(tmp
);
8805 /* no need to add after the last transfer */
8807 tcg_gen_addi_i32(addr
, addr
, 4);
8810 if (insn
& (1 << 21)) {
8812 if (insn
& (1 << 23)) {
8813 if (insn
& (1 << 24)) {
8816 /* post increment */
8817 tcg_gen_addi_i32(addr
, addr
, 4);
8820 if (insn
& (1 << 24)) {
8823 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8825 /* post decrement */
8826 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8829 store_reg(s
, rn
, addr
);
8831 tcg_temp_free_i32(addr
);
8834 store_reg(s
, rn
, loaded_var
);
8836 if ((insn
& (1 << 22)) && !user
) {
8837 /* Restore CPSR from SPSR. */
8838 tmp
= load_cpu_field(spsr
);
8839 gen_set_cpsr(tmp
, 0xffffffff);
8840 tcg_temp_free_i32(tmp
);
8841 s
->is_jmp
= DISAS_UPDATE
;
8850 /* branch (and link) */
8851 val
= (int32_t)s
->pc
;
8852 if (insn
& (1 << 24)) {
8853 tmp
= tcg_temp_new_i32();
8854 tcg_gen_movi_i32(tmp
, val
);
8855 store_reg(s
, 14, tmp
);
8857 offset
= sextract32(insn
<< 2, 0, 26);
8865 if (((insn
>> 8) & 0xe) == 10) {
8867 if (disas_vfp_insn(env
, s
, insn
)) {
8870 } else if (disas_coproc_insn(env
, s
, insn
)) {
8877 gen_set_pc_im(s
, s
->pc
);
8878 s
->svc_imm
= extract32(insn
, 0, 24);
8879 s
->is_jmp
= DISAS_SWI
;
8883 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8889 /* Return true if this is a Thumb-2 logical op. */
8891 thumb2_logic_op(int op
)
8896 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8897 then set condition code flags based on the result of the operation.
8898 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8899 to the high bit of T1.
8900 Returns zero if the opcode is valid. */
8903 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8904 TCGv_i32 t0
, TCGv_i32 t1
)
8911 tcg_gen_and_i32(t0
, t0
, t1
);
8915 tcg_gen_andc_i32(t0
, t0
, t1
);
8919 tcg_gen_or_i32(t0
, t0
, t1
);
8923 tcg_gen_orc_i32(t0
, t0
, t1
);
8927 tcg_gen_xor_i32(t0
, t0
, t1
);
8932 gen_add_CC(t0
, t0
, t1
);
8934 tcg_gen_add_i32(t0
, t0
, t1
);
8938 gen_adc_CC(t0
, t0
, t1
);
8944 gen_sbc_CC(t0
, t0
, t1
);
8946 gen_sub_carry(t0
, t0
, t1
);
8951 gen_sub_CC(t0
, t0
, t1
);
8953 tcg_gen_sub_i32(t0
, t0
, t1
);
8957 gen_sub_CC(t0
, t1
, t0
);
8959 tcg_gen_sub_i32(t0
, t1
, t0
);
8961 default: /* 5, 6, 7, 9, 12, 15. */
8967 gen_set_CF_bit31(t1
);
8972 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8974 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8976 uint32_t insn
, imm
, shift
, offset
;
8977 uint32_t rd
, rn
, rm
, rs
;
8988 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8989 || arm_feature (env
, ARM_FEATURE_M
))) {
8990 /* Thumb-1 cores may need to treat bl and blx as a pair of
8991 16-bit instructions to get correct prefetch abort behavior. */
8993 if ((insn
& (1 << 12)) == 0) {
8995 /* Second half of blx. */
8996 offset
= ((insn
& 0x7ff) << 1);
8997 tmp
= load_reg(s
, 14);
8998 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8999 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9001 tmp2
= tcg_temp_new_i32();
9002 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9003 store_reg(s
, 14, tmp2
);
9007 if (insn
& (1 << 11)) {
9008 /* Second half of bl. */
9009 offset
= ((insn
& 0x7ff) << 1) | 1;
9010 tmp
= load_reg(s
, 14);
9011 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9013 tmp2
= tcg_temp_new_i32();
9014 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9015 store_reg(s
, 14, tmp2
);
9019 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9020 /* Instruction spans a page boundary. Implement it as two
9021 16-bit instructions in case the second half causes an
9023 offset
= ((int32_t)insn
<< 21) >> 9;
9024 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9027 /* Fall through to 32-bit decode. */
9030 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9032 insn
|= (uint32_t)insn_hw1
<< 16;
9034 if ((insn
& 0xf800e800) != 0xf000e800) {
9038 rn
= (insn
>> 16) & 0xf;
9039 rs
= (insn
>> 12) & 0xf;
9040 rd
= (insn
>> 8) & 0xf;
9042 switch ((insn
>> 25) & 0xf) {
9043 case 0: case 1: case 2: case 3:
9044 /* 16-bit instructions. Should never happen. */
9047 if (insn
& (1 << 22)) {
9048 /* Other load/store, table branch. */
9049 if (insn
& 0x01200000) {
9050 /* Load/store doubleword. */
9052 addr
= tcg_temp_new_i32();
9053 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9055 addr
= load_reg(s
, rn
);
9057 offset
= (insn
& 0xff) * 4;
9058 if ((insn
& (1 << 23)) == 0)
9060 if (insn
& (1 << 24)) {
9061 tcg_gen_addi_i32(addr
, addr
, offset
);
9064 if (insn
& (1 << 20)) {
9066 tmp
= tcg_temp_new_i32();
9067 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9068 store_reg(s
, rs
, tmp
);
9069 tcg_gen_addi_i32(addr
, addr
, 4);
9070 tmp
= tcg_temp_new_i32();
9071 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9072 store_reg(s
, rd
, tmp
);
9075 tmp
= load_reg(s
, rs
);
9076 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9077 tcg_temp_free_i32(tmp
);
9078 tcg_gen_addi_i32(addr
, addr
, 4);
9079 tmp
= load_reg(s
, rd
);
9080 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9081 tcg_temp_free_i32(tmp
);
9083 if (insn
& (1 << 21)) {
9084 /* Base writeback. */
9087 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9088 store_reg(s
, rn
, addr
);
9090 tcg_temp_free_i32(addr
);
9092 } else if ((insn
& (1 << 23)) == 0) {
9093 /* Load/store exclusive word. */
9094 addr
= tcg_temp_local_new_i32();
9095 load_reg_var(s
, addr
, rn
);
9096 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9097 if (insn
& (1 << 20)) {
9098 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9100 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9102 tcg_temp_free_i32(addr
);
9103 } else if ((insn
& (7 << 5)) == 0) {
9106 addr
= tcg_temp_new_i32();
9107 tcg_gen_movi_i32(addr
, s
->pc
);
9109 addr
= load_reg(s
, rn
);
9111 tmp
= load_reg(s
, rm
);
9112 tcg_gen_add_i32(addr
, addr
, tmp
);
9113 if (insn
& (1 << 4)) {
9115 tcg_gen_add_i32(addr
, addr
, tmp
);
9116 tcg_temp_free_i32(tmp
);
9117 tmp
= tcg_temp_new_i32();
9118 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9120 tcg_temp_free_i32(tmp
);
9121 tmp
= tcg_temp_new_i32();
9122 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9124 tcg_temp_free_i32(addr
);
9125 tcg_gen_shli_i32(tmp
, tmp
, 1);
9126 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9127 store_reg(s
, 15, tmp
);
9129 int op2
= (insn
>> 6) & 0x3;
9130 op
= (insn
>> 4) & 0x3;
9135 /* Load/store exclusive byte/halfword/doubleword */
9142 /* Load-acquire/store-release */
9148 /* Load-acquire/store-release exclusive */
9152 addr
= tcg_temp_local_new_i32();
9153 load_reg_var(s
, addr
, rn
);
9155 if (insn
& (1 << 20)) {
9156 tmp
= tcg_temp_new_i32();
9159 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9162 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9165 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9170 store_reg(s
, rs
, tmp
);
9172 tmp
= load_reg(s
, rs
);
9175 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9178 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9181 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9186 tcg_temp_free_i32(tmp
);
9188 } else if (insn
& (1 << 20)) {
9189 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9191 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9193 tcg_temp_free_i32(addr
);
9196 /* Load/store multiple, RFE, SRS. */
9197 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9198 /* RFE, SRS: not available in user mode or on M profile */
9199 if (IS_USER(s
) || IS_M(env
)) {
9202 if (insn
& (1 << 20)) {
9204 addr
= load_reg(s
, rn
);
9205 if ((insn
& (1 << 24)) == 0)
9206 tcg_gen_addi_i32(addr
, addr
, -8);
9207 /* Load PC into tmp and CPSR into tmp2. */
9208 tmp
= tcg_temp_new_i32();
9209 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9210 tcg_gen_addi_i32(addr
, addr
, 4);
9211 tmp2
= tcg_temp_new_i32();
9212 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9213 if (insn
& (1 << 21)) {
9214 /* Base writeback. */
9215 if (insn
& (1 << 24)) {
9216 tcg_gen_addi_i32(addr
, addr
, 4);
9218 tcg_gen_addi_i32(addr
, addr
, -4);
9220 store_reg(s
, rn
, addr
);
9222 tcg_temp_free_i32(addr
);
9224 gen_rfe(s
, tmp
, tmp2
);
9227 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9231 int i
, loaded_base
= 0;
9232 TCGv_i32 loaded_var
;
9233 /* Load/store multiple. */
9234 addr
= load_reg(s
, rn
);
9236 for (i
= 0; i
< 16; i
++) {
9237 if (insn
& (1 << i
))
9240 if (insn
& (1 << 24)) {
9241 tcg_gen_addi_i32(addr
, addr
, -offset
);
9244 TCGV_UNUSED_I32(loaded_var
);
9245 for (i
= 0; i
< 16; i
++) {
9246 if ((insn
& (1 << i
)) == 0)
9248 if (insn
& (1 << 20)) {
9250 tmp
= tcg_temp_new_i32();
9251 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9254 } else if (i
== rn
) {
9258 store_reg(s
, i
, tmp
);
9262 tmp
= load_reg(s
, i
);
9263 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9264 tcg_temp_free_i32(tmp
);
9266 tcg_gen_addi_i32(addr
, addr
, 4);
9269 store_reg(s
, rn
, loaded_var
);
9271 if (insn
& (1 << 21)) {
9272 /* Base register writeback. */
9273 if (insn
& (1 << 24)) {
9274 tcg_gen_addi_i32(addr
, addr
, -offset
);
9276 /* Fault if writeback register is in register list. */
9277 if (insn
& (1 << rn
))
9279 store_reg(s
, rn
, addr
);
9281 tcg_temp_free_i32(addr
);
9288 op
= (insn
>> 21) & 0xf;
9290 /* Halfword pack. */
9291 tmp
= load_reg(s
, rn
);
9292 tmp2
= load_reg(s
, rm
);
9293 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9294 if (insn
& (1 << 5)) {
9298 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9299 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9300 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9304 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9305 tcg_gen_ext16u_i32(tmp
, tmp
);
9306 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9308 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9309 tcg_temp_free_i32(tmp2
);
9310 store_reg(s
, rd
, tmp
);
9312 /* Data processing register constant shift. */
9314 tmp
= tcg_temp_new_i32();
9315 tcg_gen_movi_i32(tmp
, 0);
9317 tmp
= load_reg(s
, rn
);
9319 tmp2
= load_reg(s
, rm
);
9321 shiftop
= (insn
>> 4) & 3;
9322 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9323 conds
= (insn
& (1 << 20)) != 0;
9324 logic_cc
= (conds
&& thumb2_logic_op(op
));
9325 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9326 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9328 tcg_temp_free_i32(tmp2
);
9330 store_reg(s
, rd
, tmp
);
9332 tcg_temp_free_i32(tmp
);
9336 case 13: /* Misc data processing. */
9337 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9338 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9341 case 0: /* Register controlled shift. */
9342 tmp
= load_reg(s
, rn
);
9343 tmp2
= load_reg(s
, rm
);
9344 if ((insn
& 0x70) != 0)
9346 op
= (insn
>> 21) & 3;
9347 logic_cc
= (insn
& (1 << 20)) != 0;
9348 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9351 store_reg_bx(env
, s
, rd
, tmp
);
9353 case 1: /* Sign/zero extend. */
9354 tmp
= load_reg(s
, rm
);
9355 shift
= (insn
>> 4) & 3;
9356 /* ??? In many cases it's not necessary to do a
9357 rotate, a shift is sufficient. */
9359 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9360 op
= (insn
>> 20) & 7;
9362 case 0: gen_sxth(tmp
); break;
9363 case 1: gen_uxth(tmp
); break;
9364 case 2: gen_sxtb16(tmp
); break;
9365 case 3: gen_uxtb16(tmp
); break;
9366 case 4: gen_sxtb(tmp
); break;
9367 case 5: gen_uxtb(tmp
); break;
9368 default: goto illegal_op
;
9371 tmp2
= load_reg(s
, rn
);
9372 if ((op
>> 1) == 1) {
9373 gen_add16(tmp
, tmp2
);
9375 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9376 tcg_temp_free_i32(tmp2
);
9379 store_reg(s
, rd
, tmp
);
9381 case 2: /* SIMD add/subtract. */
9382 op
= (insn
>> 20) & 7;
9383 shift
= (insn
>> 4) & 7;
9384 if ((op
& 3) == 3 || (shift
& 3) == 3)
9386 tmp
= load_reg(s
, rn
);
9387 tmp2
= load_reg(s
, rm
);
9388 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9389 tcg_temp_free_i32(tmp2
);
9390 store_reg(s
, rd
, tmp
);
9392 case 3: /* Other data processing. */
9393 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9395 /* Saturating add/subtract. */
9396 tmp
= load_reg(s
, rn
);
9397 tmp2
= load_reg(s
, rm
);
9399 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9401 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9403 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9404 tcg_temp_free_i32(tmp2
);
9406 tmp
= load_reg(s
, rn
);
9408 case 0x0a: /* rbit */
9409 gen_helper_rbit(tmp
, tmp
);
9411 case 0x08: /* rev */
9412 tcg_gen_bswap32_i32(tmp
, tmp
);
9414 case 0x09: /* rev16 */
9417 case 0x0b: /* revsh */
9420 case 0x10: /* sel */
9421 tmp2
= load_reg(s
, rm
);
9422 tmp3
= tcg_temp_new_i32();
9423 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9424 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9425 tcg_temp_free_i32(tmp3
);
9426 tcg_temp_free_i32(tmp2
);
9428 case 0x18: /* clz */
9429 gen_helper_clz(tmp
, tmp
);
9439 uint32_t sz
= op
& 0x3;
9440 uint32_t c
= op
& 0x8;
9442 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9446 tmp2
= load_reg(s
, rm
);
9448 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9449 } else if (sz
== 1) {
9450 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9452 tmp3
= tcg_const_i32(1 << sz
);
9454 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9456 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9458 tcg_temp_free_i32(tmp2
);
9459 tcg_temp_free_i32(tmp3
);
9466 store_reg(s
, rd
, tmp
);
9468 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9469 op
= (insn
>> 4) & 0xf;
9470 tmp
= load_reg(s
, rn
);
9471 tmp2
= load_reg(s
, rm
);
9472 switch ((insn
>> 20) & 7) {
9473 case 0: /* 32 x 32 -> 32 */
9474 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9475 tcg_temp_free_i32(tmp2
);
9477 tmp2
= load_reg(s
, rs
);
9479 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9481 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9482 tcg_temp_free_i32(tmp2
);
9485 case 1: /* 16 x 16 -> 32 */
9486 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9487 tcg_temp_free_i32(tmp2
);
9489 tmp2
= load_reg(s
, rs
);
9490 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9491 tcg_temp_free_i32(tmp2
);
9494 case 2: /* Dual multiply add. */
9495 case 4: /* Dual multiply subtract. */
9497 gen_swap_half(tmp2
);
9498 gen_smul_dual(tmp
, tmp2
);
9499 if (insn
& (1 << 22)) {
9500 /* This subtraction cannot overflow. */
9501 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9503 /* This addition cannot overflow 32 bits;
9504 * however it may overflow considered as a signed
9505 * operation, in which case we must set the Q flag.
9507 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9509 tcg_temp_free_i32(tmp2
);
9512 tmp2
= load_reg(s
, rs
);
9513 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9514 tcg_temp_free_i32(tmp2
);
9517 case 3: /* 32 * 16 -> 32msb */
9519 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9522 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9523 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9524 tmp
= tcg_temp_new_i32();
9525 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9526 tcg_temp_free_i64(tmp64
);
9529 tmp2
= load_reg(s
, rs
);
9530 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9531 tcg_temp_free_i32(tmp2
);
9534 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9535 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9537 tmp
= load_reg(s
, rs
);
9538 if (insn
& (1 << 20)) {
9539 tmp64
= gen_addq_msw(tmp64
, tmp
);
9541 tmp64
= gen_subq_msw(tmp64
, tmp
);
9544 if (insn
& (1 << 4)) {
9545 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9547 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9548 tmp
= tcg_temp_new_i32();
9549 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9550 tcg_temp_free_i64(tmp64
);
9552 case 7: /* Unsigned sum of absolute differences. */
9553 gen_helper_usad8(tmp
, tmp
, tmp2
);
9554 tcg_temp_free_i32(tmp2
);
9556 tmp2
= load_reg(s
, rs
);
9557 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9558 tcg_temp_free_i32(tmp2
);
9562 store_reg(s
, rd
, tmp
);
9564 case 6: case 7: /* 64-bit multiply, Divide. */
9565 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9566 tmp
= load_reg(s
, rn
);
9567 tmp2
= load_reg(s
, rm
);
9568 if ((op
& 0x50) == 0x10) {
9570 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9574 gen_helper_udiv(tmp
, tmp
, tmp2
);
9576 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9577 tcg_temp_free_i32(tmp2
);
9578 store_reg(s
, rd
, tmp
);
9579 } else if ((op
& 0xe) == 0xc) {
9580 /* Dual multiply accumulate long. */
9582 gen_swap_half(tmp2
);
9583 gen_smul_dual(tmp
, tmp2
);
9585 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9587 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9589 tcg_temp_free_i32(tmp2
);
9591 tmp64
= tcg_temp_new_i64();
9592 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9593 tcg_temp_free_i32(tmp
);
9594 gen_addq(s
, tmp64
, rs
, rd
);
9595 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9596 tcg_temp_free_i64(tmp64
);
9599 /* Unsigned 64-bit multiply */
9600 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9604 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9605 tcg_temp_free_i32(tmp2
);
9606 tmp64
= tcg_temp_new_i64();
9607 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9608 tcg_temp_free_i32(tmp
);
9610 /* Signed 64-bit multiply */
9611 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9616 gen_addq_lo(s
, tmp64
, rs
);
9617 gen_addq_lo(s
, tmp64
, rd
);
9618 } else if (op
& 0x40) {
9619 /* 64-bit accumulate. */
9620 gen_addq(s
, tmp64
, rs
, rd
);
9622 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9623 tcg_temp_free_i64(tmp64
);
9628 case 6: case 7: case 14: case 15:
9630 if (((insn
>> 24) & 3) == 3) {
9631 /* Translate into the equivalent ARM encoding. */
9632 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9633 if (disas_neon_data_insn(env
, s
, insn
))
9635 } else if (((insn
>> 8) & 0xe) == 10) {
9636 if (disas_vfp_insn(env
, s
, insn
)) {
9640 if (insn
& (1 << 28))
9642 if (disas_coproc_insn (env
, s
, insn
))
9646 case 8: case 9: case 10: case 11:
9647 if (insn
& (1 << 15)) {
9648 /* Branches, misc control. */
9649 if (insn
& 0x5000) {
9650 /* Unconditional branch. */
9651 /* signextend(hw1[10:0]) -> offset[:12]. */
9652 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9653 /* hw1[10:0] -> offset[11:1]. */
9654 offset
|= (insn
& 0x7ff) << 1;
9655 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9656 offset[24:22] already have the same value because of the
9657 sign extension above. */
9658 offset
^= ((~insn
) & (1 << 13)) << 10;
9659 offset
^= ((~insn
) & (1 << 11)) << 11;
9661 if (insn
& (1 << 14)) {
9662 /* Branch and link. */
9663 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9667 if (insn
& (1 << 12)) {
9672 offset
&= ~(uint32_t)2;
9673 /* thumb2 bx, no need to check */
9674 gen_bx_im(s
, offset
);
9676 } else if (((insn
>> 23) & 7) == 7) {
9678 if (insn
& (1 << 13))
9681 if (insn
& (1 << 26)) {
9682 /* Secure monitor call (v6Z) */
9683 qemu_log_mask(LOG_UNIMP
,
9684 "arm: unimplemented secure monitor call\n");
9685 goto illegal_op
; /* not implemented. */
9687 op
= (insn
>> 20) & 7;
9689 case 0: /* msr cpsr. */
9691 tmp
= load_reg(s
, rn
);
9692 addr
= tcg_const_i32(insn
& 0xff);
9693 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9694 tcg_temp_free_i32(addr
);
9695 tcg_temp_free_i32(tmp
);
9700 case 1: /* msr spsr. */
9703 tmp
= load_reg(s
, rn
);
9705 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9709 case 2: /* cps, nop-hint. */
9710 if (((insn
>> 8) & 7) == 0) {
9711 gen_nop_hint(s
, insn
& 0xff);
9713 /* Implemented as NOP in user mode. */
9718 if (insn
& (1 << 10)) {
9719 if (insn
& (1 << 7))
9721 if (insn
& (1 << 6))
9723 if (insn
& (1 << 5))
9725 if (insn
& (1 << 9))
9726 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9728 if (insn
& (1 << 8)) {
9730 imm
|= (insn
& 0x1f);
9733 gen_set_psr_im(s
, offset
, 0, imm
);
9736 case 3: /* Special control operations. */
9738 op
= (insn
>> 4) & 0xf;
9746 /* These execute as NOPs. */
9753 /* Trivial implementation equivalent to bx. */
9754 tmp
= load_reg(s
, rn
);
9757 case 5: /* Exception return. */
9761 if (rn
!= 14 || rd
!= 15) {
9764 tmp
= load_reg(s
, rn
);
9765 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9766 gen_exception_return(s
, tmp
);
9768 case 6: /* mrs cpsr. */
9769 tmp
= tcg_temp_new_i32();
9771 addr
= tcg_const_i32(insn
& 0xff);
9772 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9773 tcg_temp_free_i32(addr
);
9775 gen_helper_cpsr_read(tmp
, cpu_env
);
9777 store_reg(s
, rd
, tmp
);
9779 case 7: /* mrs spsr. */
9780 /* Not accessible in user mode. */
9781 if (IS_USER(s
) || IS_M(env
))
9783 tmp
= load_cpu_field(spsr
);
9784 store_reg(s
, rd
, tmp
);
9789 /* Conditional branch. */
9790 op
= (insn
>> 22) & 0xf;
9791 /* Generate a conditional jump to next instruction. */
9792 s
->condlabel
= gen_new_label();
9793 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9796 /* offset[11:1] = insn[10:0] */
9797 offset
= (insn
& 0x7ff) << 1;
9798 /* offset[17:12] = insn[21:16]. */
9799 offset
|= (insn
& 0x003f0000) >> 4;
9800 /* offset[31:20] = insn[26]. */
9801 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9802 /* offset[18] = insn[13]. */
9803 offset
|= (insn
& (1 << 13)) << 5;
9804 /* offset[19] = insn[11]. */
9805 offset
|= (insn
& (1 << 11)) << 8;
9807 /* jump to the offset */
9808 gen_jmp(s
, s
->pc
+ offset
);
9811 /* Data processing immediate. */
9812 if (insn
& (1 << 25)) {
9813 if (insn
& (1 << 24)) {
9814 if (insn
& (1 << 20))
9816 /* Bitfield/Saturate. */
9817 op
= (insn
>> 21) & 7;
9819 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9821 tmp
= tcg_temp_new_i32();
9822 tcg_gen_movi_i32(tmp
, 0);
9824 tmp
= load_reg(s
, rn
);
9827 case 2: /* Signed bitfield extract. */
9829 if (shift
+ imm
> 32)
9832 gen_sbfx(tmp
, shift
, imm
);
9834 case 6: /* Unsigned bitfield extract. */
9836 if (shift
+ imm
> 32)
9839 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9841 case 3: /* Bitfield insert/clear. */
9844 imm
= imm
+ 1 - shift
;
9846 tmp2
= load_reg(s
, rd
);
9847 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9848 tcg_temp_free_i32(tmp2
);
9853 default: /* Saturate. */
9856 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9858 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9860 tmp2
= tcg_const_i32(imm
);
9863 if ((op
& 1) && shift
== 0)
9864 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9866 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9869 if ((op
& 1) && shift
== 0)
9870 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9872 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9874 tcg_temp_free_i32(tmp2
);
9877 store_reg(s
, rd
, tmp
);
9879 imm
= ((insn
& 0x04000000) >> 15)
9880 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9881 if (insn
& (1 << 22)) {
9882 /* 16-bit immediate. */
9883 imm
|= (insn
>> 4) & 0xf000;
9884 if (insn
& (1 << 23)) {
9886 tmp
= load_reg(s
, rd
);
9887 tcg_gen_ext16u_i32(tmp
, tmp
);
9888 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9891 tmp
= tcg_temp_new_i32();
9892 tcg_gen_movi_i32(tmp
, imm
);
9895 /* Add/sub 12-bit immediate. */
9897 offset
= s
->pc
& ~(uint32_t)3;
9898 if (insn
& (1 << 23))
9902 tmp
= tcg_temp_new_i32();
9903 tcg_gen_movi_i32(tmp
, offset
);
9905 tmp
= load_reg(s
, rn
);
9906 if (insn
& (1 << 23))
9907 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9909 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9912 store_reg(s
, rd
, tmp
);
9915 int shifter_out
= 0;
9916 /* modified 12-bit immediate. */
9917 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9918 imm
= (insn
& 0xff);
9921 /* Nothing to do. */
9923 case 1: /* 00XY00XY */
9926 case 2: /* XY00XY00 */
9930 case 3: /* XYXYXYXY */
9934 default: /* Rotated constant. */
9935 shift
= (shift
<< 1) | (imm
>> 7);
9937 imm
= imm
<< (32 - shift
);
9941 tmp2
= tcg_temp_new_i32();
9942 tcg_gen_movi_i32(tmp2
, imm
);
9943 rn
= (insn
>> 16) & 0xf;
9945 tmp
= tcg_temp_new_i32();
9946 tcg_gen_movi_i32(tmp
, 0);
9948 tmp
= load_reg(s
, rn
);
9950 op
= (insn
>> 21) & 0xf;
9951 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9952 shifter_out
, tmp
, tmp2
))
9954 tcg_temp_free_i32(tmp2
);
9955 rd
= (insn
>> 8) & 0xf;
9957 store_reg(s
, rd
, tmp
);
9959 tcg_temp_free_i32(tmp
);
9964 case 12: /* Load/store single data item. */
9969 if ((insn
& 0x01100000) == 0x01000000) {
9970 if (disas_neon_ls_insn(env
, s
, insn
))
9974 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9976 if (!(insn
& (1 << 20))) {
9980 /* Byte or halfword load space with dest == r15 : memory hints.
9981 * Catch them early so we don't emit pointless addressing code.
9982 * This space is a mix of:
9983 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9984 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9986 * unallocated hints, which must be treated as NOPs
9987 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9988 * which is easiest for the decoding logic
9989 * Some space which must UNDEF
9991 int op1
= (insn
>> 23) & 3;
9992 int op2
= (insn
>> 6) & 0x3f;
9997 /* UNPREDICTABLE, unallocated hint or
9998 * PLD/PLDW/PLI (literal)
10003 return 0; /* PLD/PLDW/PLI or unallocated hint */
10005 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10006 return 0; /* PLD/PLDW/PLI or unallocated hint */
10008 /* UNDEF space, or an UNPREDICTABLE */
10012 memidx
= get_mem_index(s
);
10014 addr
= tcg_temp_new_i32();
10016 /* s->pc has already been incremented by 4. */
10017 imm
= s
->pc
& 0xfffffffc;
10018 if (insn
& (1 << 23))
10019 imm
+= insn
& 0xfff;
10021 imm
-= insn
& 0xfff;
10022 tcg_gen_movi_i32(addr
, imm
);
10024 addr
= load_reg(s
, rn
);
10025 if (insn
& (1 << 23)) {
10026 /* Positive offset. */
10027 imm
= insn
& 0xfff;
10028 tcg_gen_addi_i32(addr
, addr
, imm
);
10031 switch ((insn
>> 8) & 0xf) {
10032 case 0x0: /* Shifted Register. */
10033 shift
= (insn
>> 4) & 0xf;
10035 tcg_temp_free_i32(addr
);
10038 tmp
= load_reg(s
, rm
);
10040 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10041 tcg_gen_add_i32(addr
, addr
, tmp
);
10042 tcg_temp_free_i32(tmp
);
10044 case 0xc: /* Negative offset. */
10045 tcg_gen_addi_i32(addr
, addr
, -imm
);
10047 case 0xe: /* User privilege. */
10048 tcg_gen_addi_i32(addr
, addr
, imm
);
10049 memidx
= MMU_USER_IDX
;
10051 case 0x9: /* Post-decrement. */
10053 /* Fall through. */
10054 case 0xb: /* Post-increment. */
10058 case 0xd: /* Pre-decrement. */
10060 /* Fall through. */
10061 case 0xf: /* Pre-increment. */
10062 tcg_gen_addi_i32(addr
, addr
, imm
);
10066 tcg_temp_free_i32(addr
);
10071 if (insn
& (1 << 20)) {
10073 tmp
= tcg_temp_new_i32();
10076 gen_aa32_ld8u(tmp
, addr
, memidx
);
10079 gen_aa32_ld8s(tmp
, addr
, memidx
);
10082 gen_aa32_ld16u(tmp
, addr
, memidx
);
10085 gen_aa32_ld16s(tmp
, addr
, memidx
);
10088 gen_aa32_ld32u(tmp
, addr
, memidx
);
10091 tcg_temp_free_i32(tmp
);
10092 tcg_temp_free_i32(addr
);
10098 store_reg(s
, rs
, tmp
);
10102 tmp
= load_reg(s
, rs
);
10105 gen_aa32_st8(tmp
, addr
, memidx
);
10108 gen_aa32_st16(tmp
, addr
, memidx
);
10111 gen_aa32_st32(tmp
, addr
, memidx
);
10114 tcg_temp_free_i32(tmp
);
10115 tcg_temp_free_i32(addr
);
10118 tcg_temp_free_i32(tmp
);
10121 tcg_gen_addi_i32(addr
, addr
, imm
);
10123 store_reg(s
, rn
, addr
);
10125 tcg_temp_free_i32(addr
);
10137 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10139 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10146 if (s
->condexec_mask
) {
10147 cond
= s
->condexec_cond
;
10148 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10149 s
->condlabel
= gen_new_label();
10150 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10155 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10158 switch (insn
>> 12) {
10162 op
= (insn
>> 11) & 3;
10165 rn
= (insn
>> 3) & 7;
10166 tmp
= load_reg(s
, rn
);
10167 if (insn
& (1 << 10)) {
10169 tmp2
= tcg_temp_new_i32();
10170 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10173 rm
= (insn
>> 6) & 7;
10174 tmp2
= load_reg(s
, rm
);
10176 if (insn
& (1 << 9)) {
10177 if (s
->condexec_mask
)
10178 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10180 gen_sub_CC(tmp
, tmp
, tmp2
);
10182 if (s
->condexec_mask
)
10183 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10185 gen_add_CC(tmp
, tmp
, tmp2
);
10187 tcg_temp_free_i32(tmp2
);
10188 store_reg(s
, rd
, tmp
);
10190 /* shift immediate */
10191 rm
= (insn
>> 3) & 7;
10192 shift
= (insn
>> 6) & 0x1f;
10193 tmp
= load_reg(s
, rm
);
10194 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10195 if (!s
->condexec_mask
)
10197 store_reg(s
, rd
, tmp
);
10201 /* arithmetic large immediate */
10202 op
= (insn
>> 11) & 3;
10203 rd
= (insn
>> 8) & 0x7;
10204 if (op
== 0) { /* mov */
10205 tmp
= tcg_temp_new_i32();
10206 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10207 if (!s
->condexec_mask
)
10209 store_reg(s
, rd
, tmp
);
10211 tmp
= load_reg(s
, rd
);
10212 tmp2
= tcg_temp_new_i32();
10213 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10216 gen_sub_CC(tmp
, tmp
, tmp2
);
10217 tcg_temp_free_i32(tmp
);
10218 tcg_temp_free_i32(tmp2
);
10221 if (s
->condexec_mask
)
10222 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10224 gen_add_CC(tmp
, tmp
, tmp2
);
10225 tcg_temp_free_i32(tmp2
);
10226 store_reg(s
, rd
, tmp
);
10229 if (s
->condexec_mask
)
10230 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10232 gen_sub_CC(tmp
, tmp
, tmp2
);
10233 tcg_temp_free_i32(tmp2
);
10234 store_reg(s
, rd
, tmp
);
10240 if (insn
& (1 << 11)) {
10241 rd
= (insn
>> 8) & 7;
10242 /* load pc-relative. Bit 1 of PC is ignored. */
10243 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10244 val
&= ~(uint32_t)2;
10245 addr
= tcg_temp_new_i32();
10246 tcg_gen_movi_i32(addr
, val
);
10247 tmp
= tcg_temp_new_i32();
10248 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10249 tcg_temp_free_i32(addr
);
10250 store_reg(s
, rd
, tmp
);
10253 if (insn
& (1 << 10)) {
10254 /* data processing extended or blx */
10255 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10256 rm
= (insn
>> 3) & 0xf;
10257 op
= (insn
>> 8) & 3;
10260 tmp
= load_reg(s
, rd
);
10261 tmp2
= load_reg(s
, rm
);
10262 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10263 tcg_temp_free_i32(tmp2
);
10264 store_reg(s
, rd
, tmp
);
10267 tmp
= load_reg(s
, rd
);
10268 tmp2
= load_reg(s
, rm
);
10269 gen_sub_CC(tmp
, tmp
, tmp2
);
10270 tcg_temp_free_i32(tmp2
);
10271 tcg_temp_free_i32(tmp
);
10273 case 2: /* mov/cpy */
10274 tmp
= load_reg(s
, rm
);
10275 store_reg(s
, rd
, tmp
);
10277 case 3:/* branch [and link] exchange thumb register */
10278 tmp
= load_reg(s
, rm
);
10279 if (insn
& (1 << 7)) {
10281 val
= (uint32_t)s
->pc
| 1;
10282 tmp2
= tcg_temp_new_i32();
10283 tcg_gen_movi_i32(tmp2
, val
);
10284 store_reg(s
, 14, tmp2
);
10286 /* already thumb, no need to check */
10293 /* data processing register */
10295 rm
= (insn
>> 3) & 7;
10296 op
= (insn
>> 6) & 0xf;
10297 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10298 /* the shift/rotate ops want the operands backwards */
10307 if (op
== 9) { /* neg */
10308 tmp
= tcg_temp_new_i32();
10309 tcg_gen_movi_i32(tmp
, 0);
10310 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10311 tmp
= load_reg(s
, rd
);
10313 TCGV_UNUSED_I32(tmp
);
10316 tmp2
= load_reg(s
, rm
);
10318 case 0x0: /* and */
10319 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10320 if (!s
->condexec_mask
)
10323 case 0x1: /* eor */
10324 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10325 if (!s
->condexec_mask
)
10328 case 0x2: /* lsl */
10329 if (s
->condexec_mask
) {
10330 gen_shl(tmp2
, tmp2
, tmp
);
10332 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10333 gen_logic_CC(tmp2
);
10336 case 0x3: /* lsr */
10337 if (s
->condexec_mask
) {
10338 gen_shr(tmp2
, tmp2
, tmp
);
10340 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10341 gen_logic_CC(tmp2
);
10344 case 0x4: /* asr */
10345 if (s
->condexec_mask
) {
10346 gen_sar(tmp2
, tmp2
, tmp
);
10348 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10349 gen_logic_CC(tmp2
);
10352 case 0x5: /* adc */
10353 if (s
->condexec_mask
) {
10354 gen_adc(tmp
, tmp2
);
10356 gen_adc_CC(tmp
, tmp
, tmp2
);
10359 case 0x6: /* sbc */
10360 if (s
->condexec_mask
) {
10361 gen_sub_carry(tmp
, tmp
, tmp2
);
10363 gen_sbc_CC(tmp
, tmp
, tmp2
);
10366 case 0x7: /* ror */
10367 if (s
->condexec_mask
) {
10368 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10369 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10371 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10372 gen_logic_CC(tmp2
);
10375 case 0x8: /* tst */
10376 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10380 case 0x9: /* neg */
10381 if (s
->condexec_mask
)
10382 tcg_gen_neg_i32(tmp
, tmp2
);
10384 gen_sub_CC(tmp
, tmp
, tmp2
);
10386 case 0xa: /* cmp */
10387 gen_sub_CC(tmp
, tmp
, tmp2
);
10390 case 0xb: /* cmn */
10391 gen_add_CC(tmp
, tmp
, tmp2
);
10394 case 0xc: /* orr */
10395 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10396 if (!s
->condexec_mask
)
10399 case 0xd: /* mul */
10400 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10401 if (!s
->condexec_mask
)
10404 case 0xe: /* bic */
10405 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10406 if (!s
->condexec_mask
)
10409 case 0xf: /* mvn */
10410 tcg_gen_not_i32(tmp2
, tmp2
);
10411 if (!s
->condexec_mask
)
10412 gen_logic_CC(tmp2
);
10419 store_reg(s
, rm
, tmp2
);
10421 tcg_temp_free_i32(tmp
);
10423 store_reg(s
, rd
, tmp
);
10424 tcg_temp_free_i32(tmp2
);
10427 tcg_temp_free_i32(tmp
);
10428 tcg_temp_free_i32(tmp2
);
10433 /* load/store register offset. */
10435 rn
= (insn
>> 3) & 7;
10436 rm
= (insn
>> 6) & 7;
10437 op
= (insn
>> 9) & 7;
10438 addr
= load_reg(s
, rn
);
10439 tmp
= load_reg(s
, rm
);
10440 tcg_gen_add_i32(addr
, addr
, tmp
);
10441 tcg_temp_free_i32(tmp
);
10443 if (op
< 3) { /* store */
10444 tmp
= load_reg(s
, rd
);
10446 tmp
= tcg_temp_new_i32();
10451 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10454 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10457 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10459 case 3: /* ldrsb */
10460 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10463 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10466 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10469 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10471 case 7: /* ldrsh */
10472 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10475 if (op
>= 3) { /* load */
10476 store_reg(s
, rd
, tmp
);
10478 tcg_temp_free_i32(tmp
);
10480 tcg_temp_free_i32(addr
);
10484 /* load/store word immediate offset */
10486 rn
= (insn
>> 3) & 7;
10487 addr
= load_reg(s
, rn
);
10488 val
= (insn
>> 4) & 0x7c;
10489 tcg_gen_addi_i32(addr
, addr
, val
);
10491 if (insn
& (1 << 11)) {
10493 tmp
= tcg_temp_new_i32();
10494 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10495 store_reg(s
, rd
, tmp
);
10498 tmp
= load_reg(s
, rd
);
10499 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10500 tcg_temp_free_i32(tmp
);
10502 tcg_temp_free_i32(addr
);
10506 /* load/store byte immediate offset */
10508 rn
= (insn
>> 3) & 7;
10509 addr
= load_reg(s
, rn
);
10510 val
= (insn
>> 6) & 0x1f;
10511 tcg_gen_addi_i32(addr
, addr
, val
);
10513 if (insn
& (1 << 11)) {
10515 tmp
= tcg_temp_new_i32();
10516 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10517 store_reg(s
, rd
, tmp
);
10520 tmp
= load_reg(s
, rd
);
10521 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10522 tcg_temp_free_i32(tmp
);
10524 tcg_temp_free_i32(addr
);
10528 /* load/store halfword immediate offset */
10530 rn
= (insn
>> 3) & 7;
10531 addr
= load_reg(s
, rn
);
10532 val
= (insn
>> 5) & 0x3e;
10533 tcg_gen_addi_i32(addr
, addr
, val
);
10535 if (insn
& (1 << 11)) {
10537 tmp
= tcg_temp_new_i32();
10538 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10539 store_reg(s
, rd
, tmp
);
10542 tmp
= load_reg(s
, rd
);
10543 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10544 tcg_temp_free_i32(tmp
);
10546 tcg_temp_free_i32(addr
);
10550 /* load/store from stack */
10551 rd
= (insn
>> 8) & 7;
10552 addr
= load_reg(s
, 13);
10553 val
= (insn
& 0xff) * 4;
10554 tcg_gen_addi_i32(addr
, addr
, val
);
10556 if (insn
& (1 << 11)) {
10558 tmp
= tcg_temp_new_i32();
10559 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10560 store_reg(s
, rd
, tmp
);
10563 tmp
= load_reg(s
, rd
);
10564 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10565 tcg_temp_free_i32(tmp
);
10567 tcg_temp_free_i32(addr
);
10571 /* add to high reg */
10572 rd
= (insn
>> 8) & 7;
10573 if (insn
& (1 << 11)) {
10575 tmp
= load_reg(s
, 13);
10577 /* PC. bit 1 is ignored. */
10578 tmp
= tcg_temp_new_i32();
10579 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10581 val
= (insn
& 0xff) * 4;
10582 tcg_gen_addi_i32(tmp
, tmp
, val
);
10583 store_reg(s
, rd
, tmp
);
10588 op
= (insn
>> 8) & 0xf;
10591 /* adjust stack pointer */
10592 tmp
= load_reg(s
, 13);
10593 val
= (insn
& 0x7f) * 4;
10594 if (insn
& (1 << 7))
10595 val
= -(int32_t)val
;
10596 tcg_gen_addi_i32(tmp
, tmp
, val
);
10597 store_reg(s
, 13, tmp
);
10600 case 2: /* sign/zero extend. */
10603 rm
= (insn
>> 3) & 7;
10604 tmp
= load_reg(s
, rm
);
10605 switch ((insn
>> 6) & 3) {
10606 case 0: gen_sxth(tmp
); break;
10607 case 1: gen_sxtb(tmp
); break;
10608 case 2: gen_uxth(tmp
); break;
10609 case 3: gen_uxtb(tmp
); break;
10611 store_reg(s
, rd
, tmp
);
10613 case 4: case 5: case 0xc: case 0xd:
10615 addr
= load_reg(s
, 13);
10616 if (insn
& (1 << 8))
10620 for (i
= 0; i
< 8; i
++) {
10621 if (insn
& (1 << i
))
10624 if ((insn
& (1 << 11)) == 0) {
10625 tcg_gen_addi_i32(addr
, addr
, -offset
);
10627 for (i
= 0; i
< 8; i
++) {
10628 if (insn
& (1 << i
)) {
10629 if (insn
& (1 << 11)) {
10631 tmp
= tcg_temp_new_i32();
10632 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10633 store_reg(s
, i
, tmp
);
10636 tmp
= load_reg(s
, i
);
10637 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10638 tcg_temp_free_i32(tmp
);
10640 /* advance to the next address. */
10641 tcg_gen_addi_i32(addr
, addr
, 4);
10644 TCGV_UNUSED_I32(tmp
);
10645 if (insn
& (1 << 8)) {
10646 if (insn
& (1 << 11)) {
10648 tmp
= tcg_temp_new_i32();
10649 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10650 /* don't set the pc until the rest of the instruction
10654 tmp
= load_reg(s
, 14);
10655 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10656 tcg_temp_free_i32(tmp
);
10658 tcg_gen_addi_i32(addr
, addr
, 4);
10660 if ((insn
& (1 << 11)) == 0) {
10661 tcg_gen_addi_i32(addr
, addr
, -offset
);
10663 /* write back the new stack pointer */
10664 store_reg(s
, 13, addr
);
10665 /* set the new PC value */
10666 if ((insn
& 0x0900) == 0x0900) {
10667 store_reg_from_load(env
, s
, 15, tmp
);
10671 case 1: case 3: case 9: case 11: /* czb */
10673 tmp
= load_reg(s
, rm
);
10674 s
->condlabel
= gen_new_label();
10676 if (insn
& (1 << 11))
10677 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10679 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10680 tcg_temp_free_i32(tmp
);
10681 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10682 val
= (uint32_t)s
->pc
+ 2;
10687 case 15: /* IT, nop-hint. */
10688 if ((insn
& 0xf) == 0) {
10689 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10693 s
->condexec_cond
= (insn
>> 4) & 0xe;
10694 s
->condexec_mask
= insn
& 0x1f;
10695 /* No actual code generated for this insn, just setup state. */
10698 case 0xe: /* bkpt */
10700 int imm8
= extract32(insn
, 0, 8);
10702 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10706 case 0xa: /* rev */
10708 rn
= (insn
>> 3) & 0x7;
10710 tmp
= load_reg(s
, rn
);
10711 switch ((insn
>> 6) & 3) {
10712 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10713 case 1: gen_rev16(tmp
); break;
10714 case 3: gen_revsh(tmp
); break;
10715 default: goto illegal_op
;
10717 store_reg(s
, rd
, tmp
);
10721 switch ((insn
>> 5) & 7) {
10725 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10726 /* Dynamic endianness switching not implemented. */
10727 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10738 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10741 addr
= tcg_const_i32(19);
10742 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10743 tcg_temp_free_i32(addr
);
10747 addr
= tcg_const_i32(16);
10748 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10749 tcg_temp_free_i32(addr
);
10751 tcg_temp_free_i32(tmp
);
10754 if (insn
& (1 << 4)) {
10755 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10759 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10774 /* load/store multiple */
10775 TCGv_i32 loaded_var
;
10776 TCGV_UNUSED_I32(loaded_var
);
10777 rn
= (insn
>> 8) & 0x7;
10778 addr
= load_reg(s
, rn
);
10779 for (i
= 0; i
< 8; i
++) {
10780 if (insn
& (1 << i
)) {
10781 if (insn
& (1 << 11)) {
10783 tmp
= tcg_temp_new_i32();
10784 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10788 store_reg(s
, i
, tmp
);
10792 tmp
= load_reg(s
, i
);
10793 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10794 tcg_temp_free_i32(tmp
);
10796 /* advance to the next address */
10797 tcg_gen_addi_i32(addr
, addr
, 4);
10800 if ((insn
& (1 << rn
)) == 0) {
10801 /* base reg not in list: base register writeback */
10802 store_reg(s
, rn
, addr
);
10804 /* base reg in list: if load, complete it now */
10805 if (insn
& (1 << 11)) {
10806 store_reg(s
, rn
, loaded_var
);
10808 tcg_temp_free_i32(addr
);
10813 /* conditional branch or swi */
10814 cond
= (insn
>> 8) & 0xf;
10820 gen_set_pc_im(s
, s
->pc
);
10821 s
->svc_imm
= extract32(insn
, 0, 8);
10822 s
->is_jmp
= DISAS_SWI
;
10825 /* generate a conditional jump to next instruction */
10826 s
->condlabel
= gen_new_label();
10827 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10830 /* jump to the offset */
10831 val
= (uint32_t)s
->pc
+ 2;
10832 offset
= ((int32_t)insn
<< 24) >> 24;
10833 val
+= offset
<< 1;
10838 if (insn
& (1 << 11)) {
10839 if (disas_thumb2_insn(env
, s
, insn
))
10843 /* unconditional branch */
10844 val
= (uint32_t)s
->pc
;
10845 offset
= ((int32_t)insn
<< 21) >> 21;
10846 val
+= (offset
<< 1) + 2;
10851 if (disas_thumb2_insn(env
, s
, insn
))
10857 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10861 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10864 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10865 basic block 'tb'. If search_pc is TRUE, also generate PC
10866 information for each intermediate instruction. */
10867 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10868 TranslationBlock
*tb
,
10871 CPUState
*cs
= CPU(cpu
);
10872 CPUARMState
*env
= &cpu
->env
;
10873 DisasContext dc1
, *dc
= &dc1
;
10875 uint16_t *gen_opc_end
;
10877 target_ulong pc_start
;
10878 target_ulong next_page_start
;
10882 /* generate intermediate code */
10884 /* The A64 decoder has its own top level loop, because it doesn't need
10885 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10887 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10888 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10896 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10898 dc
->is_jmp
= DISAS_NEXT
;
10900 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10904 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10905 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10906 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10907 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10908 #if !defined(CONFIG_USER_ONLY)
10909 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10911 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
10912 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10913 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10914 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10915 dc
->cp_regs
= cpu
->cp_regs
;
10916 dc
->current_pl
= arm_current_pl(env
);
10917 dc
->features
= env
->features
;
10919 cpu_F0s
= tcg_temp_new_i32();
10920 cpu_F1s
= tcg_temp_new_i32();
10921 cpu_F0d
= tcg_temp_new_i64();
10922 cpu_F1d
= tcg_temp_new_i64();
10925 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10926 cpu_M0
= tcg_temp_new_i64();
10927 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10930 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10931 if (max_insns
== 0)
10932 max_insns
= CF_COUNT_MASK
;
10936 tcg_clear_temp_count();
10938 /* A note on handling of the condexec (IT) bits:
10940 * We want to avoid the overhead of having to write the updated condexec
10941 * bits back to the CPUARMState for every instruction in an IT block. So:
10942 * (1) if the condexec bits are not already zero then we write
10943 * zero back into the CPUARMState now. This avoids complications trying
10944 * to do it at the end of the block. (For example if we don't do this
10945 * it's hard to identify whether we can safely skip writing condexec
10946 * at the end of the TB, which we definitely want to do for the case
10947 * where a TB doesn't do anything with the IT state at all.)
10948 * (2) if we are going to leave the TB then we call gen_set_condexec()
10949 * which will write the correct value into CPUARMState if zero is wrong.
10950 * This is done both for leaving the TB at the end, and for leaving
10951 * it because of an exception we know will happen, which is done in
10952 * gen_exception_insn(). The latter is necessary because we need to
10953 * leave the TB with the PC/IT state just prior to execution of the
10954 * instruction which caused the exception.
10955 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10956 * then the CPUARMState will be wrong and we need to reset it.
10957 * This is handled in the same way as restoration of the
10958 * PC in these situations: we will be called again with search_pc=1
10959 * and generate a mapping of the condexec bits for each PC in
10960 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10961 * this to restore the condexec bits.
10963 * Note that there are no instructions which can read the condexec
10964 * bits, and none which can write non-static values to them, so
10965 * we don't need to care about whether CPUARMState is correct in the
10969 /* Reset the conditional execution bits immediately. This avoids
10970 complications trying to do it at the end of the block. */
10971 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10973 TCGv_i32 tmp
= tcg_temp_new_i32();
10974 tcg_gen_movi_i32(tmp
, 0);
10975 store_cpu_field(tmp
, condexec_bits
);
10978 #ifdef CONFIG_USER_ONLY
10979 /* Intercept jump to the magic kernel page. */
10980 if (dc
->pc
>= 0xffff0000) {
10981 /* We always get here via a jump, so know we are not in a
10982 conditional execution block. */
10983 gen_exception_internal(EXCP_KERNEL_TRAP
);
10984 dc
->is_jmp
= DISAS_UPDATE
;
10988 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10989 /* We always get here via a jump, so know we are not in a
10990 conditional execution block. */
10991 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
10992 dc
->is_jmp
= DISAS_UPDATE
;
10997 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
10998 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
10999 if (bp
->pc
== dc
->pc
) {
11000 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11001 /* Advance PC so that clearing the breakpoint will
11002 invalidate this TB. */
11004 goto done_generating
;
11009 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11013 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11015 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11016 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11017 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11018 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11021 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11024 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11025 tcg_gen_debug_insn_start(dc
->pc
);
11029 disas_thumb_insn(env
, dc
);
11030 if (dc
->condexec_mask
) {
11031 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11032 | ((dc
->condexec_mask
>> 4) & 1);
11033 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11034 if (dc
->condexec_mask
== 0) {
11035 dc
->condexec_cond
= 0;
11039 disas_arm_insn(env
, dc
);
11042 if (dc
->condjmp
&& !dc
->is_jmp
) {
11043 gen_set_label(dc
->condlabel
);
11047 if (tcg_check_temp_count()) {
11048 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11052 /* Translation stops when a conditional branch is encountered.
11053 * Otherwise the subsequent code could get translated several times.
11054 * Also stop translation when a page boundary is reached. This
11055 * ensures prefetch aborts occur at the right place. */
11057 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11058 !cs
->singlestep_enabled
&&
11060 dc
->pc
< next_page_start
&&
11061 num_insns
< max_insns
);
11063 if (tb
->cflags
& CF_LAST_IO
) {
11065 /* FIXME: This can theoretically happen with self-modifying
11067 cpu_abort(cs
, "IO on conditional branch instruction");
11072 /* At this stage dc->condjmp will only be set when the skipped
11073 instruction was a conditional branch or trap, and the PC has
11074 already been written. */
11075 if (unlikely(cs
->singlestep_enabled
)) {
11076 /* Make sure the pc is updated, and raise a debug exception. */
11078 gen_set_condexec(dc
);
11079 if (dc
->is_jmp
== DISAS_SWI
) {
11080 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11082 gen_exception_internal(EXCP_DEBUG
);
11084 gen_set_label(dc
->condlabel
);
11086 if (dc
->condjmp
|| !dc
->is_jmp
) {
11087 gen_set_pc_im(dc
, dc
->pc
);
11090 gen_set_condexec(dc
);
11091 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11092 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11094 /* FIXME: Single stepping a WFI insn will not halt
11096 gen_exception_internal(EXCP_DEBUG
);
11099 /* While branches must always occur at the end of an IT block,
11100 there are a few other things that can cause us to terminate
11101 the TB in the middle of an IT block:
11102 - Exception generating instructions (bkpt, swi, undefined).
11104 - Hardware watchpoints.
11105 Hardware breakpoints have already been handled and skip this code.
11107 gen_set_condexec(dc
);
11108 switch(dc
->is_jmp
) {
11110 gen_goto_tb(dc
, 1, dc
->pc
);
11115 /* indicate that the hash table must be used to find the next TB */
11116 tcg_gen_exit_tb(0);
11118 case DISAS_TB_JUMP
:
11119 /* nothing more to generate */
11122 gen_helper_wfi(cpu_env
);
11125 gen_helper_wfe(cpu_env
);
11128 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11132 gen_set_label(dc
->condlabel
);
11133 gen_set_condexec(dc
);
11134 gen_goto_tb(dc
, 1, dc
->pc
);
11140 gen_tb_end(tb
, num_insns
);
11141 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11144 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11145 qemu_log("----------------\n");
11146 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11147 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11148 dc
->thumb
| (dc
->bswap_code
<< 1));
11153 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11156 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11158 tb
->size
= dc
->pc
- pc_start
;
11159 tb
->icount
= num_insns
;
11163 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11165 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11168 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11170 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11173 static const char *cpu_mode_names
[16] = {
11174 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11175 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11178 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11181 ARMCPU
*cpu
= ARM_CPU(cs
);
11182 CPUARMState
*env
= &cpu
->env
;
11187 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11191 for(i
=0;i
<16;i
++) {
11192 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11194 cpu_fprintf(f
, "\n");
11196 cpu_fprintf(f
, " ");
11198 psr
= cpsr_read(env
);
11199 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11201 psr
& (1 << 31) ? 'N' : '-',
11202 psr
& (1 << 30) ? 'Z' : '-',
11203 psr
& (1 << 29) ? 'C' : '-',
11204 psr
& (1 << 28) ? 'V' : '-',
11205 psr
& CPSR_T
? 'T' : 'A',
11206 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11208 if (flags
& CPU_DUMP_FPU
) {
11209 int numvfpregs
= 0;
11210 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11213 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11216 for (i
= 0; i
< numvfpregs
; i
++) {
11217 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11218 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11219 i
* 2, (uint32_t)v
,
11220 i
* 2 + 1, (uint32_t)(v
>> 32),
11223 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11227 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11230 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11231 env
->condexec_bits
= 0;
11233 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11234 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];