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/>.
22 #include "qemu-common.h"
24 #include "internals.h"
25 #include "disas/disas.h"
28 #include "qemu/bitops.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
62 static TCGv_i32 cpu_R
[16];
63 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
64 static TCGv_i64 cpu_exclusive_addr
;
65 static TCGv_i64 cpu_exclusive_val
;
66 #ifdef CONFIG_USER_ONLY
67 static TCGv_i64 cpu_exclusive_test
;
68 static TCGv_i32 cpu_exclusive_info
;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s
, cpu_F1s
;
73 static TCGv_i64 cpu_F0d
, cpu_F1d
;
75 #include "exec/gen-icount.h"
77 static const char *regnames
[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
106 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
109 a64_translate_init();
112 static inline TCGv_i32
load_cpu_offset(int offset
)
114 TCGv_i32 tmp
= tcg_temp_new_i32();
115 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
119 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
123 tcg_gen_st_i32(var
, cpu_env
, offset
);
124 tcg_temp_free_i32(var
);
127 #define store_cpu_field(var, name) \
128 store_cpu_offset(var, offsetof(CPUARMState, name))
130 /* Set a variable to the value of a CPU register. */
131 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
135 /* normally, since we updated PC, we need only to add one insn */
137 addr
= (long)s
->pc
+ 2;
139 addr
= (long)s
->pc
+ 4;
140 tcg_gen_movi_i32(var
, addr
);
142 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
146 /* Create a new temporary and set it to the value of a CPU register. */
147 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
149 TCGv_i32 tmp
= tcg_temp_new_i32();
150 load_reg_var(s
, tmp
, reg
);
154 /* Set a CPU register. The source must be a temporary and will be
156 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
159 tcg_gen_andi_i32(var
, var
, ~1);
160 s
->is_jmp
= DISAS_JUMP
;
162 tcg_gen_mov_i32(cpu_R
[reg
], var
);
163 tcg_temp_free_i32(var
);
166 /* Value extensions. */
167 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
172 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
176 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
178 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
179 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
180 tcg_temp_free_i32(tmp_mask
);
182 /* Set NZCV flags from the high 4 bits of var. */
183 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
185 static void gen_exception_internal(int excp
)
187 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
189 assert(excp_is_internal(excp
));
190 gen_helper_exception_internal(cpu_env
, tcg_excp
);
191 tcg_temp_free_i32(tcg_excp
);
194 static void gen_exception(int excp
, uint32_t syndrome
)
196 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
197 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
199 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
200 tcg_temp_free_i32(tcg_syn
);
201 tcg_temp_free_i32(tcg_excp
);
204 static void gen_ss_advance(DisasContext
*s
)
206 /* If the singlestep state is Active-not-pending, advance to
211 gen_helper_clear_pstate_ss(cpu_env
);
215 static void gen_step_complete_exception(DisasContext
*s
)
217 /* We just completed step of an insn. Move from Active-not-pending
218 * to Active-pending, and then also take the swstep exception.
219 * This corresponds to making the (IMPDEF) choice to prioritize
220 * swstep exceptions over asynchronous exceptions taken to an exception
221 * level where debug is disabled. This choice has the advantage that
222 * we do not need to maintain internal state corresponding to the
223 * ISV/EX syndrome bits between completion of the step and generation
224 * of the exception, and our syndrome information is always correct.
227 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
));
228 s
->is_jmp
= DISAS_EXC
;
231 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
233 TCGv_i32 tmp1
= tcg_temp_new_i32();
234 TCGv_i32 tmp2
= tcg_temp_new_i32();
235 tcg_gen_ext16s_i32(tmp1
, a
);
236 tcg_gen_ext16s_i32(tmp2
, b
);
237 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
238 tcg_temp_free_i32(tmp2
);
239 tcg_gen_sari_i32(a
, a
, 16);
240 tcg_gen_sari_i32(b
, b
, 16);
241 tcg_gen_mul_i32(b
, b
, a
);
242 tcg_gen_mov_i32(a
, tmp1
);
243 tcg_temp_free_i32(tmp1
);
246 /* Byteswap each halfword. */
247 static void gen_rev16(TCGv_i32 var
)
249 TCGv_i32 tmp
= tcg_temp_new_i32();
250 tcg_gen_shri_i32(tmp
, var
, 8);
251 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
252 tcg_gen_shli_i32(var
, var
, 8);
253 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
254 tcg_gen_or_i32(var
, var
, tmp
);
255 tcg_temp_free_i32(tmp
);
258 /* Byteswap low halfword and sign extend. */
259 static void gen_revsh(TCGv_i32 var
)
261 tcg_gen_ext16u_i32(var
, var
);
262 tcg_gen_bswap16_i32(var
, var
);
263 tcg_gen_ext16s_i32(var
, var
);
266 /* Unsigned bitfield extract. */
267 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
270 tcg_gen_shri_i32(var
, var
, shift
);
271 tcg_gen_andi_i32(var
, var
, mask
);
274 /* Signed bitfield extract. */
275 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
280 tcg_gen_sari_i32(var
, var
, shift
);
281 if (shift
+ width
< 32) {
282 signbit
= 1u << (width
- 1);
283 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
284 tcg_gen_xori_i32(var
, var
, signbit
);
285 tcg_gen_subi_i32(var
, var
, signbit
);
289 /* Return (b << 32) + a. Mark inputs as dead */
290 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
292 TCGv_i64 tmp64
= tcg_temp_new_i64();
294 tcg_gen_extu_i32_i64(tmp64
, b
);
295 tcg_temp_free_i32(b
);
296 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
297 tcg_gen_add_i64(a
, tmp64
, a
);
299 tcg_temp_free_i64(tmp64
);
303 /* Return (b << 32) - a. Mark inputs as dead. */
304 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
306 TCGv_i64 tmp64
= tcg_temp_new_i64();
308 tcg_gen_extu_i32_i64(tmp64
, b
);
309 tcg_temp_free_i32(b
);
310 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
311 tcg_gen_sub_i64(a
, tmp64
, a
);
313 tcg_temp_free_i64(tmp64
);
317 /* 32x32->64 multiply. Marks inputs as dead. */
318 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
320 TCGv_i32 lo
= tcg_temp_new_i32();
321 TCGv_i32 hi
= tcg_temp_new_i32();
324 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
325 tcg_temp_free_i32(a
);
326 tcg_temp_free_i32(b
);
328 ret
= tcg_temp_new_i64();
329 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
330 tcg_temp_free_i32(lo
);
331 tcg_temp_free_i32(hi
);
336 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
338 TCGv_i32 lo
= tcg_temp_new_i32();
339 TCGv_i32 hi
= tcg_temp_new_i32();
342 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
343 tcg_temp_free_i32(a
);
344 tcg_temp_free_i32(b
);
346 ret
= tcg_temp_new_i64();
347 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
348 tcg_temp_free_i32(lo
);
349 tcg_temp_free_i32(hi
);
354 /* Swap low and high halfwords. */
355 static void gen_swap_half(TCGv_i32 var
)
357 TCGv_i32 tmp
= tcg_temp_new_i32();
358 tcg_gen_shri_i32(tmp
, var
, 16);
359 tcg_gen_shli_i32(var
, var
, 16);
360 tcg_gen_or_i32(var
, var
, tmp
);
361 tcg_temp_free_i32(tmp
);
364 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
365 tmp = (t0 ^ t1) & 0x8000;
368 t0 = (t0 + t1) ^ tmp;
371 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
373 TCGv_i32 tmp
= tcg_temp_new_i32();
374 tcg_gen_xor_i32(tmp
, t0
, t1
);
375 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
376 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
377 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
378 tcg_gen_add_i32(t0
, t0
, t1
);
379 tcg_gen_xor_i32(t0
, t0
, tmp
);
380 tcg_temp_free_i32(tmp
);
381 tcg_temp_free_i32(t1
);
384 /* Set CF to the top bit of var. */
385 static void gen_set_CF_bit31(TCGv_i32 var
)
387 tcg_gen_shri_i32(cpu_CF
, var
, 31);
390 /* Set N and Z flags from var. */
391 static inline void gen_logic_CC(TCGv_i32 var
)
393 tcg_gen_mov_i32(cpu_NF
, var
);
394 tcg_gen_mov_i32(cpu_ZF
, var
);
398 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
400 tcg_gen_add_i32(t0
, t0
, t1
);
401 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
404 /* dest = T0 + T1 + CF. */
405 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
407 tcg_gen_add_i32(dest
, t0
, t1
);
408 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
411 /* dest = T0 - T1 + CF - 1. */
412 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
414 tcg_gen_sub_i32(dest
, t0
, t1
);
415 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
416 tcg_gen_subi_i32(dest
, dest
, 1);
419 /* dest = T0 + T1. Compute C, N, V and Z flags */
420 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
422 TCGv_i32 tmp
= tcg_temp_new_i32();
423 tcg_gen_movi_i32(tmp
, 0);
424 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
425 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
426 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
427 tcg_gen_xor_i32(tmp
, t0
, t1
);
428 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
429 tcg_temp_free_i32(tmp
);
430 tcg_gen_mov_i32(dest
, cpu_NF
);
433 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
434 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
436 TCGv_i32 tmp
= tcg_temp_new_i32();
437 if (TCG_TARGET_HAS_add2_i32
) {
438 tcg_gen_movi_i32(tmp
, 0);
439 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
440 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
442 TCGv_i64 q0
= tcg_temp_new_i64();
443 TCGv_i64 q1
= tcg_temp_new_i64();
444 tcg_gen_extu_i32_i64(q0
, t0
);
445 tcg_gen_extu_i32_i64(q1
, t1
);
446 tcg_gen_add_i64(q0
, q0
, q1
);
447 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
448 tcg_gen_add_i64(q0
, q0
, q1
);
449 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
450 tcg_temp_free_i64(q0
);
451 tcg_temp_free_i64(q1
);
453 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
454 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
455 tcg_gen_xor_i32(tmp
, t0
, t1
);
456 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
457 tcg_temp_free_i32(tmp
);
458 tcg_gen_mov_i32(dest
, cpu_NF
);
461 /* dest = T0 - T1. Compute C, N, V and Z flags */
462 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
465 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
466 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
467 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
468 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
469 tmp
= tcg_temp_new_i32();
470 tcg_gen_xor_i32(tmp
, t0
, t1
);
471 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
472 tcg_temp_free_i32(tmp
);
473 tcg_gen_mov_i32(dest
, cpu_NF
);
476 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
477 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
479 TCGv_i32 tmp
= tcg_temp_new_i32();
480 tcg_gen_not_i32(tmp
, t1
);
481 gen_adc_CC(dest
, t0
, tmp
);
482 tcg_temp_free_i32(tmp
);
485 #define GEN_SHIFT(name) \
486 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
488 TCGv_i32 tmp1, tmp2, tmp3; \
489 tmp1 = tcg_temp_new_i32(); \
490 tcg_gen_andi_i32(tmp1, t1, 0xff); \
491 tmp2 = tcg_const_i32(0); \
492 tmp3 = tcg_const_i32(0x1f); \
493 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
494 tcg_temp_free_i32(tmp3); \
495 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
496 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
497 tcg_temp_free_i32(tmp2); \
498 tcg_temp_free_i32(tmp1); \
504 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
507 tmp1
= tcg_temp_new_i32();
508 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
509 tmp2
= tcg_const_i32(0x1f);
510 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
511 tcg_temp_free_i32(tmp2
);
512 tcg_gen_sar_i32(dest
, t0
, tmp1
);
513 tcg_temp_free_i32(tmp1
);
516 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
518 TCGv_i32 c0
= tcg_const_i32(0);
519 TCGv_i32 tmp
= tcg_temp_new_i32();
520 tcg_gen_neg_i32(tmp
, src
);
521 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
522 tcg_temp_free_i32(c0
);
523 tcg_temp_free_i32(tmp
);
526 static void shifter_out_im(TCGv_i32 var
, int shift
)
529 tcg_gen_andi_i32(cpu_CF
, var
, 1);
531 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
533 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
538 /* Shift by immediate. Includes special handling for shift == 0. */
539 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
540 int shift
, int flags
)
546 shifter_out_im(var
, 32 - shift
);
547 tcg_gen_shli_i32(var
, var
, shift
);
553 tcg_gen_shri_i32(cpu_CF
, var
, 31);
555 tcg_gen_movi_i32(var
, 0);
558 shifter_out_im(var
, shift
- 1);
559 tcg_gen_shri_i32(var
, var
, shift
);
566 shifter_out_im(var
, shift
- 1);
569 tcg_gen_sari_i32(var
, var
, shift
);
571 case 3: /* ROR/RRX */
574 shifter_out_im(var
, shift
- 1);
575 tcg_gen_rotri_i32(var
, var
, shift
); break;
577 TCGv_i32 tmp
= tcg_temp_new_i32();
578 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
580 shifter_out_im(var
, 0);
581 tcg_gen_shri_i32(var
, var
, 1);
582 tcg_gen_or_i32(var
, var
, tmp
);
583 tcg_temp_free_i32(tmp
);
588 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
589 TCGv_i32 shift
, int flags
)
593 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
594 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
595 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
596 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
601 gen_shl(var
, var
, shift
);
604 gen_shr(var
, var
, shift
);
607 gen_sar(var
, var
, shift
);
609 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
610 tcg_gen_rotr_i32(var
, var
, shift
); break;
613 tcg_temp_free_i32(shift
);
616 #define PAS_OP(pfx) \
618 case 0: gen_pas_helper(glue(pfx,add16)); break; \
619 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
620 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
621 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
622 case 4: gen_pas_helper(glue(pfx,add8)); break; \
623 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
625 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
630 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
632 tmp
= tcg_temp_new_ptr();
633 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
635 tcg_temp_free_ptr(tmp
);
638 tmp
= tcg_temp_new_ptr();
639 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
641 tcg_temp_free_ptr(tmp
);
643 #undef gen_pas_helper
644 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
657 #undef gen_pas_helper
662 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
663 #define PAS_OP(pfx) \
665 case 0: gen_pas_helper(glue(pfx,add8)); break; \
666 case 1: gen_pas_helper(glue(pfx,add16)); break; \
667 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
668 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
669 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
670 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
672 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
677 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
679 tmp
= tcg_temp_new_ptr();
680 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
682 tcg_temp_free_ptr(tmp
);
685 tmp
= tcg_temp_new_ptr();
686 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
688 tcg_temp_free_ptr(tmp
);
690 #undef gen_pas_helper
691 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
704 #undef gen_pas_helper
710 * generate a conditional branch based on ARM condition code cc.
711 * This is common between ARM and Aarch64 targets.
713 void arm_gen_test_cc(int cc
, int label
)
720 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
723 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
726 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
729 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
732 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
735 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
738 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
741 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
743 case 8: /* hi: C && !Z */
744 inv
= gen_new_label();
745 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
746 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
749 case 9: /* ls: !C || Z */
750 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
751 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
753 case 10: /* ge: N == V -> N ^ V == 0 */
754 tmp
= tcg_temp_new_i32();
755 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
756 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
757 tcg_temp_free_i32(tmp
);
759 case 11: /* lt: N != V -> N ^ V != 0 */
760 tmp
= tcg_temp_new_i32();
761 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
762 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
763 tcg_temp_free_i32(tmp
);
765 case 12: /* gt: !Z && N == V */
766 inv
= gen_new_label();
767 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
768 tmp
= tcg_temp_new_i32();
769 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
770 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
771 tcg_temp_free_i32(tmp
);
774 case 13: /* le: Z || N != V */
775 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
776 tmp
= tcg_temp_new_i32();
777 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
778 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
779 tcg_temp_free_i32(tmp
);
782 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
787 static const uint8_t table_logic_cc
[16] = {
806 /* Set PC and Thumb state from an immediate address. */
807 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
811 s
->is_jmp
= DISAS_UPDATE
;
812 if (s
->thumb
!= (addr
& 1)) {
813 tmp
= tcg_temp_new_i32();
814 tcg_gen_movi_i32(tmp
, addr
& 1);
815 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
816 tcg_temp_free_i32(tmp
);
818 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
821 /* Set PC and Thumb state from var. var is marked as dead. */
822 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
824 s
->is_jmp
= DISAS_UPDATE
;
825 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
826 tcg_gen_andi_i32(var
, var
, 1);
827 store_cpu_field(var
, thumb
);
830 /* Variant of store_reg which uses branch&exchange logic when storing
831 to r15 in ARM architecture v7 and above. The source must be a temporary
832 and will be marked as dead. */
833 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
834 int reg
, TCGv_i32 var
)
836 if (reg
== 15 && ENABLE_ARCH_7
) {
839 store_reg(s
, reg
, var
);
843 /* Variant of store_reg which uses branch&exchange logic when storing
844 * to r15 in ARM architecture v5T and above. This is used for storing
845 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
846 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
847 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
848 int reg
, TCGv_i32 var
)
850 if (reg
== 15 && ENABLE_ARCH_5
) {
853 store_reg(s
, reg
, var
);
857 /* Abstractions of "generate code to do a guest load/store for
858 * AArch32", where a vaddr is always 32 bits (and is zero
859 * extended if we're a 64 bit core) and data is also
860 * 32 bits unless specifically doing a 64 bit access.
861 * These functions work like tcg_gen_qemu_{ld,st}* except
862 * that the address argument is TCGv_i32 rather than TCGv.
864 #if TARGET_LONG_BITS == 32
866 #define DO_GEN_LD(SUFF, OPC) \
867 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
869 TCGMemOp opc = (OPC) | s->mo_endianness; \
870 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
873 #define DO_GEN_ST(SUFF, OPC) \
874 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
876 TCGMemOp opc = (OPC) | s->mo_endianness; \
877 tcg_gen_qemu_st_i32(val, addr, index, opc); \
880 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 addr
, int index
)
882 TCGMemOp opc
= MO_Q
| s
->mo_endianness
;
883 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
886 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 addr
, int index
)
888 TCGMemOp opc
= MO_Q
| s
->mo_endianness
;
889 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
894 #define DO_GEN_LD(SUFF, OPC) \
895 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
897 TCGMemOp opc = (OPC) | s->mo_endianness; \
898 TCGv addr64 = tcg_temp_new(); \
899 tcg_gen_extu_i32_i64(addr64, addr); \
900 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
901 tcg_temp_free(addr64); \
904 #define DO_GEN_ST(SUFF, OPC) \
905 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
907 TCGMemOp opc = (OPC) | s->mo_endianness; \
908 TCGv addr64 = tcg_temp_new(); \
909 tcg_gen_extu_i32_i64(addr64, addr); \
910 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
911 tcg_temp_free(addr64); \
914 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 addr
, int index
)
916 TCGMemOp opc
= MO_Q
| s
->mo_endianness
;
917 TCGv addr64
= tcg_temp_new();
918 tcg_gen_extu_i32_i64(addr64
, addr
);
919 tcg_gen_qemu_ld_i64(val
, addr64
, index
, opc
);
920 tcg_temp_free(addr64
);
923 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 addr
, int index
)
925 TCGMemOp opc
= MO_Q
| s
->mo_endianness
;
926 TCGv addr64
= tcg_temp_new();
927 tcg_gen_extu_i32_i64(addr64
, addr
);
928 tcg_gen_qemu_st_i64(val
, addr64
, index
, opc
);
929 tcg_temp_free(addr64
);
936 DO_GEN_LD(16s
, MO_SW
)
937 DO_GEN_LD(16u, MO_UW
)
938 DO_GEN_LD(32u, MO_UL
)
943 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
945 tcg_gen_movi_i32(cpu_R
[15], val
);
948 static inline void gen_hvc(DisasContext
*s
, int imm16
)
950 /* The pre HVC helper handles cases when HVC gets trapped
951 * as an undefined insn by runtime configuration (ie before
952 * the insn really executes).
954 gen_set_pc_im(s
, s
->pc
- 4);
955 gen_helper_pre_hvc(cpu_env
);
956 /* Otherwise we will treat this as a real exception which
957 * happens after execution of the insn. (The distinction matters
958 * for the PC value reported to the exception handler and also
959 * for single stepping.)
962 gen_set_pc_im(s
, s
->pc
);
963 s
->is_jmp
= DISAS_HVC
;
966 static inline void gen_smc(DisasContext
*s
)
968 /* As with HVC, we may take an exception either before or after
973 gen_set_pc_im(s
, s
->pc
- 4);
974 tmp
= tcg_const_i32(syn_aa32_smc());
975 gen_helper_pre_smc(cpu_env
, tmp
);
976 tcg_temp_free_i32(tmp
);
977 gen_set_pc_im(s
, s
->pc
);
978 s
->is_jmp
= DISAS_SMC
;
982 gen_set_condexec (DisasContext
*s
)
984 if (s
->condexec_mask
) {
985 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
986 TCGv_i32 tmp
= tcg_temp_new_i32();
987 tcg_gen_movi_i32(tmp
, val
);
988 store_cpu_field(tmp
, condexec_bits
);
992 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
995 gen_set_pc_im(s
, s
->pc
- offset
);
996 gen_exception_internal(excp
);
997 s
->is_jmp
= DISAS_JUMP
;
1000 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
1002 gen_set_condexec(s
);
1003 gen_set_pc_im(s
, s
->pc
- offset
);
1004 gen_exception(excp
, syn
);
1005 s
->is_jmp
= DISAS_JUMP
;
1008 /* Force a TB lookup after an instruction that changes the CPU state. */
1009 static inline void gen_lookup_tb(DisasContext
*s
)
1011 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1012 s
->is_jmp
= DISAS_UPDATE
;
1015 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1018 int val
, rm
, shift
, shiftop
;
1021 if (!(insn
& (1 << 25))) {
1024 if (!(insn
& (1 << 23)))
1027 tcg_gen_addi_i32(var
, var
, val
);
1029 /* shift/register */
1031 shift
= (insn
>> 7) & 0x1f;
1032 shiftop
= (insn
>> 5) & 3;
1033 offset
= load_reg(s
, rm
);
1034 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1035 if (!(insn
& (1 << 23)))
1036 tcg_gen_sub_i32(var
, var
, offset
);
1038 tcg_gen_add_i32(var
, var
, offset
);
1039 tcg_temp_free_i32(offset
);
1043 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1044 int extra
, TCGv_i32 var
)
1049 if (insn
& (1 << 22)) {
1051 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1052 if (!(insn
& (1 << 23)))
1056 tcg_gen_addi_i32(var
, var
, val
);
1060 tcg_gen_addi_i32(var
, var
, extra
);
1062 offset
= load_reg(s
, rm
);
1063 if (!(insn
& (1 << 23)))
1064 tcg_gen_sub_i32(var
, var
, offset
);
1066 tcg_gen_add_i32(var
, var
, offset
);
1067 tcg_temp_free_i32(offset
);
1071 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1073 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1076 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1078 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1080 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1084 #define VFP_OP2(name) \
1085 static inline void gen_vfp_##name(int dp) \
1087 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1089 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1091 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1093 tcg_temp_free_ptr(fpst); \
1103 static inline void gen_vfp_F1_mul(int dp
)
1105 /* Like gen_vfp_mul() but put result in F1 */
1106 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1108 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1110 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1112 tcg_temp_free_ptr(fpst
);
1115 static inline void gen_vfp_F1_neg(int dp
)
1117 /* Like gen_vfp_neg() but put result in F1 */
1119 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1121 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1125 static inline void gen_vfp_abs(int dp
)
1128 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1130 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1133 static inline void gen_vfp_neg(int dp
)
1136 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1138 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1141 static inline void gen_vfp_sqrt(int dp
)
1144 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1146 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1149 static inline void gen_vfp_cmp(int dp
)
1152 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1154 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1157 static inline void gen_vfp_cmpe(int dp
)
1160 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1162 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1165 static inline void gen_vfp_F1_ld0(int dp
)
1168 tcg_gen_movi_i64(cpu_F1d
, 0);
1170 tcg_gen_movi_i32(cpu_F1s
, 0);
1173 #define VFP_GEN_ITOF(name) \
1174 static inline void gen_vfp_##name(int dp, int neon) \
1176 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1178 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1180 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1182 tcg_temp_free_ptr(statusptr); \
1189 #define VFP_GEN_FTOI(name) \
1190 static inline void gen_vfp_##name(int dp, int neon) \
1192 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1194 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1196 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1198 tcg_temp_free_ptr(statusptr); \
1207 #define VFP_GEN_FIX(name, round) \
1208 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1210 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1211 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1213 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1216 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1219 tcg_temp_free_i32(tmp_shift); \
1220 tcg_temp_free_ptr(statusptr); \
1222 VFP_GEN_FIX(tosh
, _round_to_zero
)
1223 VFP_GEN_FIX(tosl
, _round_to_zero
)
1224 VFP_GEN_FIX(touh
, _round_to_zero
)
1225 VFP_GEN_FIX(toul
, _round_to_zero
)
1232 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1235 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1237 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1241 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1244 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1246 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1251 vfp_reg_offset (int dp
, int reg
)
1254 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1256 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1257 + offsetof(CPU_DoubleU
, l
.upper
);
1259 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1260 + offsetof(CPU_DoubleU
, l
.lower
);
1264 /* Return the offset of a 32-bit piece of a NEON register.
1265 zero is the least significant end of the register. */
1267 neon_reg_offset (int reg
, int n
)
1271 return vfp_reg_offset(0, sreg
);
1274 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1276 TCGv_i32 tmp
= tcg_temp_new_i32();
1277 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1281 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1283 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1284 tcg_temp_free_i32(var
);
1287 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1289 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1292 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1294 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1297 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1298 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1299 #define tcg_gen_st_f32 tcg_gen_st_i32
1300 #define tcg_gen_st_f64 tcg_gen_st_i64
1302 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1305 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1307 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1310 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1313 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1315 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1318 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1321 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1323 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1326 #define ARM_CP_RW_BIT (1 << 20)
1328 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1330 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1333 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1335 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1338 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1340 TCGv_i32 var
= tcg_temp_new_i32();
1341 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1345 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1347 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1348 tcg_temp_free_i32(var
);
1351 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1353 iwmmxt_store_reg(cpu_M0
, rn
);
1356 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1358 iwmmxt_load_reg(cpu_M0
, rn
);
1361 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1363 iwmmxt_load_reg(cpu_V1
, rn
);
1364 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1367 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1369 iwmmxt_load_reg(cpu_V1
, rn
);
1370 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1373 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1375 iwmmxt_load_reg(cpu_V1
, rn
);
1376 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1379 #define IWMMXT_OP(name) \
1380 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1382 iwmmxt_load_reg(cpu_V1, rn); \
1383 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1386 #define IWMMXT_OP_ENV(name) \
1387 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1389 iwmmxt_load_reg(cpu_V1, rn); \
1390 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1393 #define IWMMXT_OP_ENV_SIZE(name) \
1394 IWMMXT_OP_ENV(name##b) \
1395 IWMMXT_OP_ENV(name##w) \
1396 IWMMXT_OP_ENV(name##l)
1398 #define IWMMXT_OP_ENV1(name) \
1399 static inline void gen_op_iwmmxt_##name##_M0(void) \
1401 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1415 IWMMXT_OP_ENV_SIZE(unpackl
)
1416 IWMMXT_OP_ENV_SIZE(unpackh
)
1418 IWMMXT_OP_ENV1(unpacklub
)
1419 IWMMXT_OP_ENV1(unpackluw
)
1420 IWMMXT_OP_ENV1(unpacklul
)
1421 IWMMXT_OP_ENV1(unpackhub
)
1422 IWMMXT_OP_ENV1(unpackhuw
)
1423 IWMMXT_OP_ENV1(unpackhul
)
1424 IWMMXT_OP_ENV1(unpacklsb
)
1425 IWMMXT_OP_ENV1(unpacklsw
)
1426 IWMMXT_OP_ENV1(unpacklsl
)
1427 IWMMXT_OP_ENV1(unpackhsb
)
1428 IWMMXT_OP_ENV1(unpackhsw
)
1429 IWMMXT_OP_ENV1(unpackhsl
)
1431 IWMMXT_OP_ENV_SIZE(cmpeq
)
1432 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1433 IWMMXT_OP_ENV_SIZE(cmpgts
)
1435 IWMMXT_OP_ENV_SIZE(mins
)
1436 IWMMXT_OP_ENV_SIZE(minu
)
1437 IWMMXT_OP_ENV_SIZE(maxs
)
1438 IWMMXT_OP_ENV_SIZE(maxu
)
1440 IWMMXT_OP_ENV_SIZE(subn
)
1441 IWMMXT_OP_ENV_SIZE(addn
)
1442 IWMMXT_OP_ENV_SIZE(subu
)
1443 IWMMXT_OP_ENV_SIZE(addu
)
1444 IWMMXT_OP_ENV_SIZE(subs
)
1445 IWMMXT_OP_ENV_SIZE(adds
)
1447 IWMMXT_OP_ENV(avgb0
)
1448 IWMMXT_OP_ENV(avgb1
)
1449 IWMMXT_OP_ENV(avgw0
)
1450 IWMMXT_OP_ENV(avgw1
)
1452 IWMMXT_OP_ENV(packuw
)
1453 IWMMXT_OP_ENV(packul
)
1454 IWMMXT_OP_ENV(packuq
)
1455 IWMMXT_OP_ENV(packsw
)
1456 IWMMXT_OP_ENV(packsl
)
1457 IWMMXT_OP_ENV(packsq
)
1459 static void gen_op_iwmmxt_set_mup(void)
1462 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1463 tcg_gen_ori_i32(tmp
, tmp
, 2);
1464 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1467 static void gen_op_iwmmxt_set_cup(void)
1470 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1471 tcg_gen_ori_i32(tmp
, tmp
, 1);
1472 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1475 static void gen_op_iwmmxt_setpsr_nz(void)
1477 TCGv_i32 tmp
= tcg_temp_new_i32();
1478 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1479 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1482 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1484 iwmmxt_load_reg(cpu_V1
, rn
);
1485 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1486 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1489 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1496 rd
= (insn
>> 16) & 0xf;
1497 tmp
= load_reg(s
, rd
);
1499 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1500 if (insn
& (1 << 24)) {
1502 if (insn
& (1 << 23))
1503 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1505 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1506 tcg_gen_mov_i32(dest
, tmp
);
1507 if (insn
& (1 << 21))
1508 store_reg(s
, rd
, tmp
);
1510 tcg_temp_free_i32(tmp
);
1511 } else if (insn
& (1 << 21)) {
1513 tcg_gen_mov_i32(dest
, tmp
);
1514 if (insn
& (1 << 23))
1515 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1517 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1518 store_reg(s
, rd
, tmp
);
1519 } else if (!(insn
& (1 << 23)))
1524 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1526 int rd
= (insn
>> 0) & 0xf;
1529 if (insn
& (1 << 8)) {
1530 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1533 tmp
= iwmmxt_load_creg(rd
);
1536 tmp
= tcg_temp_new_i32();
1537 iwmmxt_load_reg(cpu_V0
, rd
);
1538 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1540 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1541 tcg_gen_mov_i32(dest
, tmp
);
1542 tcg_temp_free_i32(tmp
);
1546 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1547 (ie. an undefined instruction). */
1548 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1551 int rdhi
, rdlo
, rd0
, rd1
, i
;
1553 TCGv_i32 tmp
, tmp2
, tmp3
;
1555 if ((insn
& 0x0e000e00) == 0x0c000000) {
1556 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1558 rdlo
= (insn
>> 12) & 0xf;
1559 rdhi
= (insn
>> 16) & 0xf;
1560 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1561 iwmmxt_load_reg(cpu_V0
, wrd
);
1562 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1563 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1564 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1565 } else { /* TMCRR */
1566 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1567 iwmmxt_store_reg(cpu_V0
, wrd
);
1568 gen_op_iwmmxt_set_mup();
1573 wrd
= (insn
>> 12) & 0xf;
1574 addr
= tcg_temp_new_i32();
1575 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1576 tcg_temp_free_i32(addr
);
1579 if (insn
& ARM_CP_RW_BIT
) {
1580 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1581 tmp
= tcg_temp_new_i32();
1582 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1583 iwmmxt_store_creg(wrd
, tmp
);
1586 if (insn
& (1 << 8)) {
1587 if (insn
& (1 << 22)) { /* WLDRD */
1588 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1590 } else { /* WLDRW wRd */
1591 tmp
= tcg_temp_new_i32();
1592 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1595 tmp
= tcg_temp_new_i32();
1596 if (insn
& (1 << 22)) { /* WLDRH */
1597 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1598 } else { /* WLDRB */
1599 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1603 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1604 tcg_temp_free_i32(tmp
);
1606 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1609 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1610 tmp
= iwmmxt_load_creg(wrd
);
1611 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1613 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1614 tmp
= tcg_temp_new_i32();
1615 if (insn
& (1 << 8)) {
1616 if (insn
& (1 << 22)) { /* WSTRD */
1617 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1618 } else { /* WSTRW wRd */
1619 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1620 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1623 if (insn
& (1 << 22)) { /* WSTRH */
1624 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1625 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1626 } else { /* WSTRB */
1627 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1628 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1632 tcg_temp_free_i32(tmp
);
1634 tcg_temp_free_i32(addr
);
1638 if ((insn
& 0x0f000000) != 0x0e000000)
1641 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1642 case 0x000: /* WOR */
1643 wrd
= (insn
>> 12) & 0xf;
1644 rd0
= (insn
>> 0) & 0xf;
1645 rd1
= (insn
>> 16) & 0xf;
1646 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1647 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1648 gen_op_iwmmxt_setpsr_nz();
1649 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1650 gen_op_iwmmxt_set_mup();
1651 gen_op_iwmmxt_set_cup();
1653 case 0x011: /* TMCR */
1656 rd
= (insn
>> 12) & 0xf;
1657 wrd
= (insn
>> 16) & 0xf;
1659 case ARM_IWMMXT_wCID
:
1660 case ARM_IWMMXT_wCASF
:
1662 case ARM_IWMMXT_wCon
:
1663 gen_op_iwmmxt_set_cup();
1665 case ARM_IWMMXT_wCSSF
:
1666 tmp
= iwmmxt_load_creg(wrd
);
1667 tmp2
= load_reg(s
, rd
);
1668 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1669 tcg_temp_free_i32(tmp2
);
1670 iwmmxt_store_creg(wrd
, tmp
);
1672 case ARM_IWMMXT_wCGR0
:
1673 case ARM_IWMMXT_wCGR1
:
1674 case ARM_IWMMXT_wCGR2
:
1675 case ARM_IWMMXT_wCGR3
:
1676 gen_op_iwmmxt_set_cup();
1677 tmp
= load_reg(s
, rd
);
1678 iwmmxt_store_creg(wrd
, tmp
);
1684 case 0x100: /* WXOR */
1685 wrd
= (insn
>> 12) & 0xf;
1686 rd0
= (insn
>> 0) & 0xf;
1687 rd1
= (insn
>> 16) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1689 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1690 gen_op_iwmmxt_setpsr_nz();
1691 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1692 gen_op_iwmmxt_set_mup();
1693 gen_op_iwmmxt_set_cup();
1695 case 0x111: /* TMRC */
1698 rd
= (insn
>> 12) & 0xf;
1699 wrd
= (insn
>> 16) & 0xf;
1700 tmp
= iwmmxt_load_creg(wrd
);
1701 store_reg(s
, rd
, tmp
);
1703 case 0x300: /* WANDN */
1704 wrd
= (insn
>> 12) & 0xf;
1705 rd0
= (insn
>> 0) & 0xf;
1706 rd1
= (insn
>> 16) & 0xf;
1707 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1708 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1709 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1710 gen_op_iwmmxt_setpsr_nz();
1711 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1712 gen_op_iwmmxt_set_mup();
1713 gen_op_iwmmxt_set_cup();
1715 case 0x200: /* WAND */
1716 wrd
= (insn
>> 12) & 0xf;
1717 rd0
= (insn
>> 0) & 0xf;
1718 rd1
= (insn
>> 16) & 0xf;
1719 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1720 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1721 gen_op_iwmmxt_setpsr_nz();
1722 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1723 gen_op_iwmmxt_set_mup();
1724 gen_op_iwmmxt_set_cup();
1726 case 0x810: case 0xa10: /* WMADD */
1727 wrd
= (insn
>> 12) & 0xf;
1728 rd0
= (insn
>> 0) & 0xf;
1729 rd1
= (insn
>> 16) & 0xf;
1730 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1731 if (insn
& (1 << 21))
1732 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1734 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1735 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1736 gen_op_iwmmxt_set_mup();
1738 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1739 wrd
= (insn
>> 12) & 0xf;
1740 rd0
= (insn
>> 16) & 0xf;
1741 rd1
= (insn
>> 0) & 0xf;
1742 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1743 switch ((insn
>> 22) & 3) {
1745 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1748 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1751 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1756 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1757 gen_op_iwmmxt_set_mup();
1758 gen_op_iwmmxt_set_cup();
1760 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1761 wrd
= (insn
>> 12) & 0xf;
1762 rd0
= (insn
>> 16) & 0xf;
1763 rd1
= (insn
>> 0) & 0xf;
1764 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1765 switch ((insn
>> 22) & 3) {
1767 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1770 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1773 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1778 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1782 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1783 wrd
= (insn
>> 12) & 0xf;
1784 rd0
= (insn
>> 16) & 0xf;
1785 rd1
= (insn
>> 0) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1787 if (insn
& (1 << 22))
1788 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1790 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1791 if (!(insn
& (1 << 20)))
1792 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1793 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1794 gen_op_iwmmxt_set_mup();
1796 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1797 wrd
= (insn
>> 12) & 0xf;
1798 rd0
= (insn
>> 16) & 0xf;
1799 rd1
= (insn
>> 0) & 0xf;
1800 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1801 if (insn
& (1 << 21)) {
1802 if (insn
& (1 << 20))
1803 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1805 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1807 if (insn
& (1 << 20))
1808 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1810 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1812 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1813 gen_op_iwmmxt_set_mup();
1815 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1816 wrd
= (insn
>> 12) & 0xf;
1817 rd0
= (insn
>> 16) & 0xf;
1818 rd1
= (insn
>> 0) & 0xf;
1819 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1820 if (insn
& (1 << 21))
1821 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1823 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1824 if (!(insn
& (1 << 20))) {
1825 iwmmxt_load_reg(cpu_V1
, wrd
);
1826 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1828 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1829 gen_op_iwmmxt_set_mup();
1831 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1832 wrd
= (insn
>> 12) & 0xf;
1833 rd0
= (insn
>> 16) & 0xf;
1834 rd1
= (insn
>> 0) & 0xf;
1835 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1836 switch ((insn
>> 22) & 3) {
1838 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1841 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1844 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1849 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1850 gen_op_iwmmxt_set_mup();
1851 gen_op_iwmmxt_set_cup();
1853 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1854 wrd
= (insn
>> 12) & 0xf;
1855 rd0
= (insn
>> 16) & 0xf;
1856 rd1
= (insn
>> 0) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1858 if (insn
& (1 << 22)) {
1859 if (insn
& (1 << 20))
1860 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1862 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1864 if (insn
& (1 << 20))
1865 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1867 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1869 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1870 gen_op_iwmmxt_set_mup();
1871 gen_op_iwmmxt_set_cup();
1873 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1874 wrd
= (insn
>> 12) & 0xf;
1875 rd0
= (insn
>> 16) & 0xf;
1876 rd1
= (insn
>> 0) & 0xf;
1877 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1878 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1879 tcg_gen_andi_i32(tmp
, tmp
, 7);
1880 iwmmxt_load_reg(cpu_V1
, rd1
);
1881 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1882 tcg_temp_free_i32(tmp
);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1884 gen_op_iwmmxt_set_mup();
1886 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1887 if (((insn
>> 6) & 3) == 3)
1889 rd
= (insn
>> 12) & 0xf;
1890 wrd
= (insn
>> 16) & 0xf;
1891 tmp
= load_reg(s
, rd
);
1892 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1893 switch ((insn
>> 6) & 3) {
1895 tmp2
= tcg_const_i32(0xff);
1896 tmp3
= tcg_const_i32((insn
& 7) << 3);
1899 tmp2
= tcg_const_i32(0xffff);
1900 tmp3
= tcg_const_i32((insn
& 3) << 4);
1903 tmp2
= tcg_const_i32(0xffffffff);
1904 tmp3
= tcg_const_i32((insn
& 1) << 5);
1907 TCGV_UNUSED_I32(tmp2
);
1908 TCGV_UNUSED_I32(tmp3
);
1910 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1911 tcg_temp_free_i32(tmp3
);
1912 tcg_temp_free_i32(tmp2
);
1913 tcg_temp_free_i32(tmp
);
1914 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1915 gen_op_iwmmxt_set_mup();
1917 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1918 rd
= (insn
>> 12) & 0xf;
1919 wrd
= (insn
>> 16) & 0xf;
1920 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1922 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1923 tmp
= tcg_temp_new_i32();
1924 switch ((insn
>> 22) & 3) {
1926 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1927 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1929 tcg_gen_ext8s_i32(tmp
, tmp
);
1931 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1935 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1936 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1938 tcg_gen_ext16s_i32(tmp
, tmp
);
1940 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1944 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1945 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1948 store_reg(s
, rd
, tmp
);
1950 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1951 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1953 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1954 switch ((insn
>> 22) & 3) {
1956 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1959 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1962 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1965 tcg_gen_shli_i32(tmp
, tmp
, 28);
1967 tcg_temp_free_i32(tmp
);
1969 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1970 if (((insn
>> 6) & 3) == 3)
1972 rd
= (insn
>> 12) & 0xf;
1973 wrd
= (insn
>> 16) & 0xf;
1974 tmp
= load_reg(s
, rd
);
1975 switch ((insn
>> 6) & 3) {
1977 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1980 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1983 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1986 tcg_temp_free_i32(tmp
);
1987 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1988 gen_op_iwmmxt_set_mup();
1990 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1991 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1993 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1994 tmp2
= tcg_temp_new_i32();
1995 tcg_gen_mov_i32(tmp2
, tmp
);
1996 switch ((insn
>> 22) & 3) {
1998 for (i
= 0; i
< 7; i
++) {
1999 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2000 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2004 for (i
= 0; i
< 3; i
++) {
2005 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2006 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2010 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2011 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2015 tcg_temp_free_i32(tmp2
);
2016 tcg_temp_free_i32(tmp
);
2018 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2019 wrd
= (insn
>> 12) & 0xf;
2020 rd0
= (insn
>> 16) & 0xf;
2021 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2022 switch ((insn
>> 22) & 3) {
2024 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2027 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2030 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2035 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2036 gen_op_iwmmxt_set_mup();
2038 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2039 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2041 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2042 tmp2
= tcg_temp_new_i32();
2043 tcg_gen_mov_i32(tmp2
, tmp
);
2044 switch ((insn
>> 22) & 3) {
2046 for (i
= 0; i
< 7; i
++) {
2047 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2048 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2052 for (i
= 0; i
< 3; i
++) {
2053 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2054 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2058 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2059 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2063 tcg_temp_free_i32(tmp2
);
2064 tcg_temp_free_i32(tmp
);
2066 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2067 rd
= (insn
>> 12) & 0xf;
2068 rd0
= (insn
>> 16) & 0xf;
2069 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2071 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2072 tmp
= tcg_temp_new_i32();
2073 switch ((insn
>> 22) & 3) {
2075 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2078 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2081 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2084 store_reg(s
, rd
, tmp
);
2086 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2087 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2088 wrd
= (insn
>> 12) & 0xf;
2089 rd0
= (insn
>> 16) & 0xf;
2090 rd1
= (insn
>> 0) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2092 switch ((insn
>> 22) & 3) {
2094 if (insn
& (1 << 21))
2095 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2097 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2100 if (insn
& (1 << 21))
2101 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2103 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2106 if (insn
& (1 << 21))
2107 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2109 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2114 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2115 gen_op_iwmmxt_set_mup();
2116 gen_op_iwmmxt_set_cup();
2118 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2119 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2120 wrd
= (insn
>> 12) & 0xf;
2121 rd0
= (insn
>> 16) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2123 switch ((insn
>> 22) & 3) {
2125 if (insn
& (1 << 21))
2126 gen_op_iwmmxt_unpacklsb_M0();
2128 gen_op_iwmmxt_unpacklub_M0();
2131 if (insn
& (1 << 21))
2132 gen_op_iwmmxt_unpacklsw_M0();
2134 gen_op_iwmmxt_unpackluw_M0();
2137 if (insn
& (1 << 21))
2138 gen_op_iwmmxt_unpacklsl_M0();
2140 gen_op_iwmmxt_unpacklul_M0();
2145 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2146 gen_op_iwmmxt_set_mup();
2147 gen_op_iwmmxt_set_cup();
2149 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2150 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2151 wrd
= (insn
>> 12) & 0xf;
2152 rd0
= (insn
>> 16) & 0xf;
2153 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2154 switch ((insn
>> 22) & 3) {
2156 if (insn
& (1 << 21))
2157 gen_op_iwmmxt_unpackhsb_M0();
2159 gen_op_iwmmxt_unpackhub_M0();
2162 if (insn
& (1 << 21))
2163 gen_op_iwmmxt_unpackhsw_M0();
2165 gen_op_iwmmxt_unpackhuw_M0();
2168 if (insn
& (1 << 21))
2169 gen_op_iwmmxt_unpackhsl_M0();
2171 gen_op_iwmmxt_unpackhul_M0();
2176 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2177 gen_op_iwmmxt_set_mup();
2178 gen_op_iwmmxt_set_cup();
2180 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2181 case 0x214: case 0x614: case 0xa14: case 0xe14:
2182 if (((insn
>> 22) & 3) == 0)
2184 wrd
= (insn
>> 12) & 0xf;
2185 rd0
= (insn
>> 16) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2187 tmp
= tcg_temp_new_i32();
2188 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2189 tcg_temp_free_i32(tmp
);
2192 switch ((insn
>> 22) & 3) {
2194 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2197 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2200 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2203 tcg_temp_free_i32(tmp
);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2205 gen_op_iwmmxt_set_mup();
2206 gen_op_iwmmxt_set_cup();
2208 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2209 case 0x014: case 0x414: case 0x814: case 0xc14:
2210 if (((insn
>> 22) & 3) == 0)
2212 wrd
= (insn
>> 12) & 0xf;
2213 rd0
= (insn
>> 16) & 0xf;
2214 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2215 tmp
= tcg_temp_new_i32();
2216 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2217 tcg_temp_free_i32(tmp
);
2220 switch ((insn
>> 22) & 3) {
2222 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2225 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2228 gen_helper_iwmmxt_sraq(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 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2237 case 0x114: case 0x514: case 0x914: case 0xd14:
2238 if (((insn
>> 22) & 3) == 0)
2240 wrd
= (insn
>> 12) & 0xf;
2241 rd0
= (insn
>> 16) & 0xf;
2242 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2243 tmp
= tcg_temp_new_i32();
2244 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2245 tcg_temp_free_i32(tmp
);
2248 switch ((insn
>> 22) & 3) {
2250 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2256 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2259 tcg_temp_free_i32(tmp
);
2260 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2261 gen_op_iwmmxt_set_mup();
2262 gen_op_iwmmxt_set_cup();
2264 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2265 case 0x314: case 0x714: case 0xb14: case 0xf14:
2266 if (((insn
>> 22) & 3) == 0)
2268 wrd
= (insn
>> 12) & 0xf;
2269 rd0
= (insn
>> 16) & 0xf;
2270 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2271 tmp
= tcg_temp_new_i32();
2272 switch ((insn
>> 22) & 3) {
2274 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2275 tcg_temp_free_i32(tmp
);
2278 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2282 tcg_temp_free_i32(tmp
);
2285 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2288 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2289 tcg_temp_free_i32(tmp
);
2292 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2295 tcg_temp_free_i32(tmp
);
2296 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2297 gen_op_iwmmxt_set_mup();
2298 gen_op_iwmmxt_set_cup();
2300 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2301 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2302 wrd
= (insn
>> 12) & 0xf;
2303 rd0
= (insn
>> 16) & 0xf;
2304 rd1
= (insn
>> 0) & 0xf;
2305 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2306 switch ((insn
>> 22) & 3) {
2308 if (insn
& (1 << 21))
2309 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2311 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2314 if (insn
& (1 << 21))
2315 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2317 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2320 if (insn
& (1 << 21))
2321 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2323 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2328 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2329 gen_op_iwmmxt_set_mup();
2331 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2332 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2333 wrd
= (insn
>> 12) & 0xf;
2334 rd0
= (insn
>> 16) & 0xf;
2335 rd1
= (insn
>> 0) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2337 switch ((insn
>> 22) & 3) {
2339 if (insn
& (1 << 21))
2340 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2342 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2345 if (insn
& (1 << 21))
2346 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2348 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2351 if (insn
& (1 << 21))
2352 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2354 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2359 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2360 gen_op_iwmmxt_set_mup();
2362 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2363 case 0x402: case 0x502: case 0x602: case 0x702:
2364 wrd
= (insn
>> 12) & 0xf;
2365 rd0
= (insn
>> 16) & 0xf;
2366 rd1
= (insn
>> 0) & 0xf;
2367 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2368 tmp
= tcg_const_i32((insn
>> 20) & 3);
2369 iwmmxt_load_reg(cpu_V1
, rd1
);
2370 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2371 tcg_temp_free_i32(tmp
);
2372 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2373 gen_op_iwmmxt_set_mup();
2375 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2376 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2377 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2378 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2379 wrd
= (insn
>> 12) & 0xf;
2380 rd0
= (insn
>> 16) & 0xf;
2381 rd1
= (insn
>> 0) & 0xf;
2382 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2383 switch ((insn
>> 20) & 0xf) {
2385 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2388 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2391 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2394 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2397 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2400 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2403 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2406 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2409 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2414 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2415 gen_op_iwmmxt_set_mup();
2416 gen_op_iwmmxt_set_cup();
2418 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2419 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2420 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2421 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2422 wrd
= (insn
>> 12) & 0xf;
2423 rd0
= (insn
>> 16) & 0xf;
2424 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2425 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2426 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2427 tcg_temp_free_i32(tmp
);
2428 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2429 gen_op_iwmmxt_set_mup();
2430 gen_op_iwmmxt_set_cup();
2432 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2433 case 0x418: case 0x518: case 0x618: case 0x718:
2434 case 0x818: case 0x918: case 0xa18: case 0xb18:
2435 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2436 wrd
= (insn
>> 12) & 0xf;
2437 rd0
= (insn
>> 16) & 0xf;
2438 rd1
= (insn
>> 0) & 0xf;
2439 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2440 switch ((insn
>> 20) & 0xf) {
2442 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2445 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2448 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2451 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2454 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2457 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2460 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2463 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2466 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2471 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2472 gen_op_iwmmxt_set_mup();
2473 gen_op_iwmmxt_set_cup();
2475 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2476 case 0x408: case 0x508: case 0x608: case 0x708:
2477 case 0x808: case 0x908: case 0xa08: case 0xb08:
2478 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2479 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2481 wrd
= (insn
>> 12) & 0xf;
2482 rd0
= (insn
>> 16) & 0xf;
2483 rd1
= (insn
>> 0) & 0xf;
2484 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2485 switch ((insn
>> 22) & 3) {
2487 if (insn
& (1 << 21))
2488 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2490 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2493 if (insn
& (1 << 21))
2494 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2496 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2499 if (insn
& (1 << 21))
2500 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2502 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2505 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2506 gen_op_iwmmxt_set_mup();
2507 gen_op_iwmmxt_set_cup();
2509 case 0x201: case 0x203: case 0x205: case 0x207:
2510 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2511 case 0x211: case 0x213: case 0x215: case 0x217:
2512 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2513 wrd
= (insn
>> 5) & 0xf;
2514 rd0
= (insn
>> 12) & 0xf;
2515 rd1
= (insn
>> 0) & 0xf;
2516 if (rd0
== 0xf || rd1
== 0xf)
2518 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2519 tmp
= load_reg(s
, rd0
);
2520 tmp2
= load_reg(s
, rd1
);
2521 switch ((insn
>> 16) & 0xf) {
2522 case 0x0: /* TMIA */
2523 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2525 case 0x8: /* TMIAPH */
2526 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2528 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2529 if (insn
& (1 << 16))
2530 tcg_gen_shri_i32(tmp
, tmp
, 16);
2531 if (insn
& (1 << 17))
2532 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2533 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2536 tcg_temp_free_i32(tmp2
);
2537 tcg_temp_free_i32(tmp
);
2540 tcg_temp_free_i32(tmp2
);
2541 tcg_temp_free_i32(tmp
);
2542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2543 gen_op_iwmmxt_set_mup();
2552 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2553 (ie. an undefined instruction). */
2554 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2556 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2559 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2560 /* Multiply with Internal Accumulate Format */
2561 rd0
= (insn
>> 12) & 0xf;
2563 acc
= (insn
>> 5) & 7;
2568 tmp
= load_reg(s
, rd0
);
2569 tmp2
= load_reg(s
, rd1
);
2570 switch ((insn
>> 16) & 0xf) {
2572 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2574 case 0x8: /* MIAPH */
2575 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2577 case 0xc: /* MIABB */
2578 case 0xd: /* MIABT */
2579 case 0xe: /* MIATB */
2580 case 0xf: /* MIATT */
2581 if (insn
& (1 << 16))
2582 tcg_gen_shri_i32(tmp
, tmp
, 16);
2583 if (insn
& (1 << 17))
2584 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2585 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2590 tcg_temp_free_i32(tmp2
);
2591 tcg_temp_free_i32(tmp
);
2593 gen_op_iwmmxt_movq_wRn_M0(acc
);
2597 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2598 /* Internal Accumulator Access Format */
2599 rdhi
= (insn
>> 16) & 0xf;
2600 rdlo
= (insn
>> 12) & 0xf;
2606 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2607 iwmmxt_load_reg(cpu_V0
, acc
);
2608 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2609 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2610 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2611 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2613 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2614 iwmmxt_store_reg(cpu_V0
, acc
);
2622 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2623 #define VFP_SREG(insn, bigbit, smallbit) \
2624 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2625 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2626 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2627 reg = (((insn) >> (bigbit)) & 0x0f) \
2628 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2630 if (insn & (1 << (smallbit))) \
2632 reg = ((insn) >> (bigbit)) & 0x0f; \
2635 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2636 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2637 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2638 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2639 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2640 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2642 /* Move between integer and VFP cores. */
2643 static TCGv_i32
gen_vfp_mrs(void)
2645 TCGv_i32 tmp
= tcg_temp_new_i32();
2646 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2650 static void gen_vfp_msr(TCGv_i32 tmp
)
2652 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2653 tcg_temp_free_i32(tmp
);
2656 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2658 TCGv_i32 tmp
= tcg_temp_new_i32();
2660 tcg_gen_shri_i32(var
, var
, shift
);
2661 tcg_gen_ext8u_i32(var
, var
);
2662 tcg_gen_shli_i32(tmp
, var
, 8);
2663 tcg_gen_or_i32(var
, var
, tmp
);
2664 tcg_gen_shli_i32(tmp
, var
, 16);
2665 tcg_gen_or_i32(var
, var
, tmp
);
2666 tcg_temp_free_i32(tmp
);
2669 static void gen_neon_dup_low16(TCGv_i32 var
)
2671 TCGv_i32 tmp
= tcg_temp_new_i32();
2672 tcg_gen_ext16u_i32(var
, var
);
2673 tcg_gen_shli_i32(tmp
, var
, 16);
2674 tcg_gen_or_i32(var
, var
, tmp
);
2675 tcg_temp_free_i32(tmp
);
2678 static void gen_neon_dup_high16(TCGv_i32 var
)
2680 TCGv_i32 tmp
= tcg_temp_new_i32();
2681 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2682 tcg_gen_shri_i32(tmp
, var
, 16);
2683 tcg_gen_or_i32(var
, var
, tmp
);
2684 tcg_temp_free_i32(tmp
);
2687 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2689 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2690 TCGv_i32 tmp
= tcg_temp_new_i32();
2693 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2694 gen_neon_dup_u8(tmp
, 0);
2697 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2698 gen_neon_dup_low16(tmp
);
2701 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2703 default: /* Avoid compiler warnings. */
2709 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2712 uint32_t cc
= extract32(insn
, 20, 2);
2715 TCGv_i64 frn
, frm
, dest
;
2716 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2718 zero
= tcg_const_i64(0);
2720 frn
= tcg_temp_new_i64();
2721 frm
= tcg_temp_new_i64();
2722 dest
= tcg_temp_new_i64();
2724 zf
= tcg_temp_new_i64();
2725 nf
= tcg_temp_new_i64();
2726 vf
= tcg_temp_new_i64();
2728 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2729 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2730 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2732 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2733 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2736 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2740 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2743 case 2: /* ge: N == V -> N ^ V == 0 */
2744 tmp
= tcg_temp_new_i64();
2745 tcg_gen_xor_i64(tmp
, vf
, nf
);
2746 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2748 tcg_temp_free_i64(tmp
);
2750 case 3: /* gt: !Z && N == V */
2751 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2753 tmp
= tcg_temp_new_i64();
2754 tcg_gen_xor_i64(tmp
, vf
, nf
);
2755 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2757 tcg_temp_free_i64(tmp
);
2760 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2761 tcg_temp_free_i64(frn
);
2762 tcg_temp_free_i64(frm
);
2763 tcg_temp_free_i64(dest
);
2765 tcg_temp_free_i64(zf
);
2766 tcg_temp_free_i64(nf
);
2767 tcg_temp_free_i64(vf
);
2769 tcg_temp_free_i64(zero
);
2771 TCGv_i32 frn
, frm
, dest
;
2774 zero
= tcg_const_i32(0);
2776 frn
= tcg_temp_new_i32();
2777 frm
= tcg_temp_new_i32();
2778 dest
= tcg_temp_new_i32();
2779 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2780 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2783 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2787 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2790 case 2: /* ge: N == V -> N ^ V == 0 */
2791 tmp
= tcg_temp_new_i32();
2792 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2793 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2795 tcg_temp_free_i32(tmp
);
2797 case 3: /* gt: !Z && N == V */
2798 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2800 tmp
= tcg_temp_new_i32();
2801 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2802 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2804 tcg_temp_free_i32(tmp
);
2807 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2808 tcg_temp_free_i32(frn
);
2809 tcg_temp_free_i32(frm
);
2810 tcg_temp_free_i32(dest
);
2812 tcg_temp_free_i32(zero
);
2818 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2819 uint32_t rm
, uint32_t dp
)
2821 uint32_t vmin
= extract32(insn
, 6, 1);
2822 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2825 TCGv_i64 frn
, frm
, dest
;
2827 frn
= tcg_temp_new_i64();
2828 frm
= tcg_temp_new_i64();
2829 dest
= tcg_temp_new_i64();
2831 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2832 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2834 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2836 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2838 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2839 tcg_temp_free_i64(frn
);
2840 tcg_temp_free_i64(frm
);
2841 tcg_temp_free_i64(dest
);
2843 TCGv_i32 frn
, frm
, dest
;
2845 frn
= tcg_temp_new_i32();
2846 frm
= tcg_temp_new_i32();
2847 dest
= tcg_temp_new_i32();
2849 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2850 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2852 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2854 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2856 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2857 tcg_temp_free_i32(frn
);
2858 tcg_temp_free_i32(frm
);
2859 tcg_temp_free_i32(dest
);
2862 tcg_temp_free_ptr(fpst
);
2866 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2869 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2872 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2873 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2878 tcg_op
= tcg_temp_new_i64();
2879 tcg_res
= tcg_temp_new_i64();
2880 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2881 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2882 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2883 tcg_temp_free_i64(tcg_op
);
2884 tcg_temp_free_i64(tcg_res
);
2888 tcg_op
= tcg_temp_new_i32();
2889 tcg_res
= tcg_temp_new_i32();
2890 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2891 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2892 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2893 tcg_temp_free_i32(tcg_op
);
2894 tcg_temp_free_i32(tcg_res
);
2897 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2898 tcg_temp_free_i32(tcg_rmode
);
2900 tcg_temp_free_ptr(fpst
);
2904 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2907 bool is_signed
= extract32(insn
, 7, 1);
2908 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2909 TCGv_i32 tcg_rmode
, tcg_shift
;
2911 tcg_shift
= tcg_const_i32(0);
2913 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2914 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2917 TCGv_i64 tcg_double
, tcg_res
;
2919 /* Rd is encoded as a single precision register even when the source
2920 * is double precision.
2922 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2923 tcg_double
= tcg_temp_new_i64();
2924 tcg_res
= tcg_temp_new_i64();
2925 tcg_tmp
= tcg_temp_new_i32();
2926 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2928 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2930 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2932 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2933 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2934 tcg_temp_free_i32(tcg_tmp
);
2935 tcg_temp_free_i64(tcg_res
);
2936 tcg_temp_free_i64(tcg_double
);
2938 TCGv_i32 tcg_single
, tcg_res
;
2939 tcg_single
= tcg_temp_new_i32();
2940 tcg_res
= tcg_temp_new_i32();
2941 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2943 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2945 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2947 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2948 tcg_temp_free_i32(tcg_res
);
2949 tcg_temp_free_i32(tcg_single
);
2952 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2953 tcg_temp_free_i32(tcg_rmode
);
2955 tcg_temp_free_i32(tcg_shift
);
2957 tcg_temp_free_ptr(fpst
);
2962 /* Table for converting the most common AArch32 encoding of
2963 * rounding mode to arm_fprounding order (which matches the
2964 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2966 static const uint8_t fp_decode_rm
[] = {
2973 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2975 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2977 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2982 VFP_DREG_D(rd
, insn
);
2983 VFP_DREG_N(rn
, insn
);
2984 VFP_DREG_M(rm
, insn
);
2986 rd
= VFP_SREG_D(insn
);
2987 rn
= VFP_SREG_N(insn
);
2988 rm
= VFP_SREG_M(insn
);
2991 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2992 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2993 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2994 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2995 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2996 /* VRINTA, VRINTN, VRINTP, VRINTM */
2997 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2998 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2999 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3000 /* VCVTA, VCVTN, VCVTP, VCVTM */
3001 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3002 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3007 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3008 (ie. an undefined instruction). */
3009 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3011 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3017 if (!arm_feature(env
, ARM_FEATURE_VFP
))
3020 /* FIXME: this access check should not take precedence over UNDEF
3021 * for invalid encodings; we will generate incorrect syndrome information
3022 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3024 if (!s
->cpacr_fpen
) {
3025 gen_exception_insn(s
, 4, EXCP_UDEF
,
3026 syn_fp_access_trap(1, 0xe, s
->thumb
));
3030 if (!s
->vfp_enabled
) {
3031 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3032 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3034 rn
= (insn
>> 16) & 0xf;
3035 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3036 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3041 if (extract32(insn
, 28, 4) == 0xf) {
3042 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3043 * only used in v8 and above.
3045 return disas_vfp_v8_insn(env
, s
, insn
);
3048 dp
= ((insn
& 0xf00) == 0xb00);
3049 switch ((insn
>> 24) & 0xf) {
3051 if (insn
& (1 << 4)) {
3052 /* single register transfer */
3053 rd
= (insn
>> 12) & 0xf;
3058 VFP_DREG_N(rn
, insn
);
3061 if (insn
& 0x00c00060
3062 && !arm_feature(env
, ARM_FEATURE_NEON
))
3065 pass
= (insn
>> 21) & 1;
3066 if (insn
& (1 << 22)) {
3068 offset
= ((insn
>> 5) & 3) * 8;
3069 } else if (insn
& (1 << 5)) {
3071 offset
= (insn
& (1 << 6)) ? 16 : 0;
3076 if (insn
& ARM_CP_RW_BIT
) {
3078 tmp
= neon_load_reg(rn
, pass
);
3082 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3083 if (insn
& (1 << 23))
3089 if (insn
& (1 << 23)) {
3091 tcg_gen_shri_i32(tmp
, tmp
, 16);
3097 tcg_gen_sari_i32(tmp
, tmp
, 16);
3106 store_reg(s
, rd
, tmp
);
3109 tmp
= load_reg(s
, rd
);
3110 if (insn
& (1 << 23)) {
3113 gen_neon_dup_u8(tmp
, 0);
3114 } else if (size
== 1) {
3115 gen_neon_dup_low16(tmp
);
3117 for (n
= 0; n
<= pass
* 2; n
++) {
3118 tmp2
= tcg_temp_new_i32();
3119 tcg_gen_mov_i32(tmp2
, tmp
);
3120 neon_store_reg(rn
, n
, tmp2
);
3122 neon_store_reg(rn
, n
, tmp
);
3127 tmp2
= neon_load_reg(rn
, pass
);
3128 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3129 tcg_temp_free_i32(tmp2
);
3132 tmp2
= neon_load_reg(rn
, pass
);
3133 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3134 tcg_temp_free_i32(tmp2
);
3139 neon_store_reg(rn
, pass
, tmp
);
3143 if ((insn
& 0x6f) != 0x00)
3145 rn
= VFP_SREG_N(insn
);
3146 if (insn
& ARM_CP_RW_BIT
) {
3148 if (insn
& (1 << 21)) {
3149 /* system register */
3154 /* VFP2 allows access to FSID from userspace.
3155 VFP3 restricts all id registers to privileged
3158 && arm_feature(env
, ARM_FEATURE_VFP3
))
3160 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3165 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3167 case ARM_VFP_FPINST
:
3168 case ARM_VFP_FPINST2
:
3169 /* Not present in VFP3. */
3171 || arm_feature(env
, ARM_FEATURE_VFP3
))
3173 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3177 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3178 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3180 tmp
= tcg_temp_new_i32();
3181 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3185 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
3192 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3194 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3200 gen_mov_F0_vreg(0, rn
);
3201 tmp
= gen_vfp_mrs();
3204 /* Set the 4 flag bits in the CPSR. */
3206 tcg_temp_free_i32(tmp
);
3208 store_reg(s
, rd
, tmp
);
3212 if (insn
& (1 << 21)) {
3214 /* system register */
3219 /* Writes are ignored. */
3222 tmp
= load_reg(s
, rd
);
3223 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3224 tcg_temp_free_i32(tmp
);
3230 /* TODO: VFP subarchitecture support.
3231 * For now, keep the EN bit only */
3232 tmp
= load_reg(s
, rd
);
3233 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3234 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3237 case ARM_VFP_FPINST
:
3238 case ARM_VFP_FPINST2
:
3242 tmp
= load_reg(s
, rd
);
3243 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3249 tmp
= load_reg(s
, rd
);
3251 gen_mov_vreg_F0(0, rn
);
3256 /* data processing */
3257 /* The opcode is in bits 23, 21, 20 and 6. */
3258 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3262 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3264 /* rn is register number */
3265 VFP_DREG_N(rn
, insn
);
3268 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3269 ((rn
& 0x1e) == 0x6))) {
3270 /* Integer or single/half precision destination. */
3271 rd
= VFP_SREG_D(insn
);
3273 VFP_DREG_D(rd
, insn
);
3276 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3277 ((rn
& 0x1e) == 0x4))) {
3278 /* VCVT from int or half precision is always from S reg
3279 * regardless of dp bit. VCVT with immediate frac_bits
3280 * has same format as SREG_M.
3282 rm
= VFP_SREG_M(insn
);
3284 VFP_DREG_M(rm
, insn
);
3287 rn
= VFP_SREG_N(insn
);
3288 if (op
== 15 && rn
== 15) {
3289 /* Double precision destination. */
3290 VFP_DREG_D(rd
, insn
);
3292 rd
= VFP_SREG_D(insn
);
3294 /* NB that we implicitly rely on the encoding for the frac_bits
3295 * in VCVT of fixed to float being the same as that of an SREG_M
3297 rm
= VFP_SREG_M(insn
);
3300 veclen
= s
->vec_len
;
3301 if (op
== 15 && rn
> 3)
3304 /* Shut up compiler warnings. */
3315 /* Figure out what type of vector operation this is. */
3316 if ((rd
& bank_mask
) == 0) {
3321 delta_d
= (s
->vec_stride
>> 1) + 1;
3323 delta_d
= s
->vec_stride
+ 1;
3325 if ((rm
& bank_mask
) == 0) {
3326 /* mixed scalar/vector */
3335 /* Load the initial operands. */
3340 /* Integer source */
3341 gen_mov_F0_vreg(0, rm
);
3346 gen_mov_F0_vreg(dp
, rd
);
3347 gen_mov_F1_vreg(dp
, rm
);
3351 /* Compare with zero */
3352 gen_mov_F0_vreg(dp
, rd
);
3363 /* Source and destination the same. */
3364 gen_mov_F0_vreg(dp
, rd
);
3370 /* VCVTB, VCVTT: only present with the halfprec extension
3371 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3372 * (we choose to UNDEF)
3374 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3375 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3378 if (!extract32(rn
, 1, 1)) {
3379 /* Half precision source. */
3380 gen_mov_F0_vreg(0, rm
);
3383 /* Otherwise fall through */
3385 /* One source operand. */
3386 gen_mov_F0_vreg(dp
, rm
);
3390 /* Two source operands. */
3391 gen_mov_F0_vreg(dp
, rn
);
3392 gen_mov_F1_vreg(dp
, rm
);
3396 /* Perform the calculation. */
3398 case 0: /* VMLA: fd + (fn * fm) */
3399 /* Note that order of inputs to the add matters for NaNs */
3401 gen_mov_F0_vreg(dp
, rd
);
3404 case 1: /* VMLS: fd + -(fn * fm) */
3407 gen_mov_F0_vreg(dp
, rd
);
3410 case 2: /* VNMLS: -fd + (fn * fm) */
3411 /* Note that it isn't valid to replace (-A + B) with (B - A)
3412 * or similar plausible looking simplifications
3413 * because this will give wrong results for NaNs.
3416 gen_mov_F0_vreg(dp
, rd
);
3420 case 3: /* VNMLA: -fd + -(fn * fm) */
3423 gen_mov_F0_vreg(dp
, rd
);
3427 case 4: /* mul: fn * fm */
3430 case 5: /* nmul: -(fn * fm) */
3434 case 6: /* add: fn + fm */
3437 case 7: /* sub: fn - fm */
3440 case 8: /* div: fn / fm */
3443 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3444 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3445 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3446 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3447 /* These are fused multiply-add, and must be done as one
3448 * floating point operation with no rounding between the
3449 * multiplication and addition steps.
3450 * NB that doing the negations here as separate steps is
3451 * correct : an input NaN should come out with its sign bit
3452 * flipped if it is a negated-input.
3454 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3462 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3464 frd
= tcg_temp_new_i64();
3465 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3468 gen_helper_vfp_negd(frd
, frd
);
3470 fpst
= get_fpstatus_ptr(0);
3471 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3472 cpu_F1d
, frd
, fpst
);
3473 tcg_temp_free_ptr(fpst
);
3474 tcg_temp_free_i64(frd
);
3480 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3482 frd
= tcg_temp_new_i32();
3483 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3485 gen_helper_vfp_negs(frd
, frd
);
3487 fpst
= get_fpstatus_ptr(0);
3488 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3489 cpu_F1s
, frd
, fpst
);
3490 tcg_temp_free_ptr(fpst
);
3491 tcg_temp_free_i32(frd
);
3494 case 14: /* fconst */
3495 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3498 n
= (insn
<< 12) & 0x80000000;
3499 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3506 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3513 tcg_gen_movi_i32(cpu_F0s
, n
);
3516 case 15: /* extension space */
3530 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3531 tmp
= gen_vfp_mrs();
3532 tcg_gen_ext16u_i32(tmp
, tmp
);
3534 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3537 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3540 tcg_temp_free_i32(tmp
);
3542 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3543 tmp
= gen_vfp_mrs();
3544 tcg_gen_shri_i32(tmp
, tmp
, 16);
3546 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3549 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3552 tcg_temp_free_i32(tmp
);
3554 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3555 tmp
= tcg_temp_new_i32();
3557 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3560 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3563 gen_mov_F0_vreg(0, rd
);
3564 tmp2
= gen_vfp_mrs();
3565 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3566 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3567 tcg_temp_free_i32(tmp2
);
3570 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3571 tmp
= tcg_temp_new_i32();
3573 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3576 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3579 tcg_gen_shli_i32(tmp
, tmp
, 16);
3580 gen_mov_F0_vreg(0, rd
);
3581 tmp2
= gen_vfp_mrs();
3582 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3583 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3584 tcg_temp_free_i32(tmp2
);
3596 case 11: /* cmpez */
3600 case 12: /* vrintr */
3602 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3604 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3606 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3608 tcg_temp_free_ptr(fpst
);
3611 case 13: /* vrintz */
3613 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3615 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3616 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3618 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3620 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3622 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3623 tcg_temp_free_i32(tcg_rmode
);
3624 tcg_temp_free_ptr(fpst
);
3627 case 14: /* vrintx */
3629 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3631 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3633 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3635 tcg_temp_free_ptr(fpst
);
3638 case 15: /* single<->double conversion */
3640 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3642 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3644 case 16: /* fuito */
3645 gen_vfp_uito(dp
, 0);
3647 case 17: /* fsito */
3648 gen_vfp_sito(dp
, 0);
3650 case 20: /* fshto */
3651 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3653 gen_vfp_shto(dp
, 16 - rm
, 0);
3655 case 21: /* fslto */
3656 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3658 gen_vfp_slto(dp
, 32 - rm
, 0);
3660 case 22: /* fuhto */
3661 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3663 gen_vfp_uhto(dp
, 16 - rm
, 0);
3665 case 23: /* fulto */
3666 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3668 gen_vfp_ulto(dp
, 32 - rm
, 0);
3670 case 24: /* ftoui */
3671 gen_vfp_toui(dp
, 0);
3673 case 25: /* ftouiz */
3674 gen_vfp_touiz(dp
, 0);
3676 case 26: /* ftosi */
3677 gen_vfp_tosi(dp
, 0);
3679 case 27: /* ftosiz */
3680 gen_vfp_tosiz(dp
, 0);
3682 case 28: /* ftosh */
3683 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3685 gen_vfp_tosh(dp
, 16 - rm
, 0);
3687 case 29: /* ftosl */
3688 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3690 gen_vfp_tosl(dp
, 32 - rm
, 0);
3692 case 30: /* ftouh */
3693 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3695 gen_vfp_touh(dp
, 16 - rm
, 0);
3697 case 31: /* ftoul */
3698 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3700 gen_vfp_toul(dp
, 32 - rm
, 0);
3702 default: /* undefined */
3706 default: /* undefined */
3710 /* Write back the result. */
3711 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3712 /* Comparison, do nothing. */
3713 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3714 (rn
& 0x1e) == 0x6)) {
3715 /* VCVT double to int: always integer result.
3716 * VCVT double to half precision is always a single
3719 gen_mov_vreg_F0(0, rd
);
3720 } else if (op
== 15 && rn
== 15) {
3722 gen_mov_vreg_F0(!dp
, rd
);
3724 gen_mov_vreg_F0(dp
, rd
);
3727 /* break out of the loop if we have finished */
3731 if (op
== 15 && delta_m
== 0) {
3732 /* single source one-many */
3734 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3736 gen_mov_vreg_F0(dp
, rd
);
3740 /* Setup the next operands. */
3742 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3746 /* One source operand. */
3747 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3749 gen_mov_F0_vreg(dp
, rm
);
3751 /* Two source operands. */
3752 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3754 gen_mov_F0_vreg(dp
, rn
);
3756 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3758 gen_mov_F1_vreg(dp
, rm
);
3766 if ((insn
& 0x03e00000) == 0x00400000) {
3767 /* two-register transfer */
3768 rn
= (insn
>> 16) & 0xf;
3769 rd
= (insn
>> 12) & 0xf;
3771 VFP_DREG_M(rm
, insn
);
3773 rm
= VFP_SREG_M(insn
);
3776 if (insn
& ARM_CP_RW_BIT
) {
3779 gen_mov_F0_vreg(0, rm
* 2);
3780 tmp
= gen_vfp_mrs();
3781 store_reg(s
, rd
, tmp
);
3782 gen_mov_F0_vreg(0, rm
* 2 + 1);
3783 tmp
= gen_vfp_mrs();
3784 store_reg(s
, rn
, tmp
);
3786 gen_mov_F0_vreg(0, rm
);
3787 tmp
= gen_vfp_mrs();
3788 store_reg(s
, rd
, tmp
);
3789 gen_mov_F0_vreg(0, rm
+ 1);
3790 tmp
= gen_vfp_mrs();
3791 store_reg(s
, rn
, tmp
);
3796 tmp
= load_reg(s
, rd
);
3798 gen_mov_vreg_F0(0, rm
* 2);
3799 tmp
= load_reg(s
, rn
);
3801 gen_mov_vreg_F0(0, rm
* 2 + 1);
3803 tmp
= load_reg(s
, rd
);
3805 gen_mov_vreg_F0(0, rm
);
3806 tmp
= load_reg(s
, rn
);
3808 gen_mov_vreg_F0(0, rm
+ 1);
3813 rn
= (insn
>> 16) & 0xf;
3815 VFP_DREG_D(rd
, insn
);
3817 rd
= VFP_SREG_D(insn
);
3818 if ((insn
& 0x01200000) == 0x01000000) {
3819 /* Single load/store */
3820 offset
= (insn
& 0xff) << 2;
3821 if ((insn
& (1 << 23)) == 0)
3823 if (s
->thumb
&& rn
== 15) {
3824 /* This is actually UNPREDICTABLE */
3825 addr
= tcg_temp_new_i32();
3826 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3828 addr
= load_reg(s
, rn
);
3830 tcg_gen_addi_i32(addr
, addr
, offset
);
3831 if (insn
& (1 << 20)) {
3832 gen_vfp_ld(s
, dp
, addr
);
3833 gen_mov_vreg_F0(dp
, rd
);
3835 gen_mov_F0_vreg(dp
, rd
);
3836 gen_vfp_st(s
, dp
, addr
);
3838 tcg_temp_free_i32(addr
);
3840 /* load/store multiple */
3841 int w
= insn
& (1 << 21);
3843 n
= (insn
>> 1) & 0x7f;
3847 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3848 /* P == U , W == 1 => UNDEF */
3851 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3852 /* UNPREDICTABLE cases for bad immediates: we choose to
3853 * UNDEF to avoid generating huge numbers of TCG ops
3857 if (rn
== 15 && w
) {
3858 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3862 if (s
->thumb
&& rn
== 15) {
3863 /* This is actually UNPREDICTABLE */
3864 addr
= tcg_temp_new_i32();
3865 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3867 addr
= load_reg(s
, rn
);
3869 if (insn
& (1 << 24)) /* pre-decrement */
3870 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3876 for (i
= 0; i
< n
; i
++) {
3877 if (insn
& ARM_CP_RW_BIT
) {
3879 gen_vfp_ld(s
, dp
, addr
);
3880 gen_mov_vreg_F0(dp
, rd
+ i
);
3883 gen_mov_F0_vreg(dp
, rd
+ i
);
3884 gen_vfp_st(s
, dp
, addr
);
3886 tcg_gen_addi_i32(addr
, addr
, offset
);
3890 if (insn
& (1 << 24))
3891 offset
= -offset
* n
;
3892 else if (dp
&& (insn
& 1))
3898 tcg_gen_addi_i32(addr
, addr
, offset
);
3899 store_reg(s
, rn
, addr
);
3901 tcg_temp_free_i32(addr
);
3907 /* Should never happen. */
3913 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3915 TranslationBlock
*tb
;
3918 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3920 gen_set_pc_im(s
, dest
);
3921 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3923 gen_set_pc_im(s
, dest
);
3928 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3930 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3931 /* An indirect jump so that we still trigger the debug exception. */
3936 gen_goto_tb(s
, 0, dest
);
3937 s
->is_jmp
= DISAS_TB_JUMP
;
3941 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3944 tcg_gen_sari_i32(t0
, t0
, 16);
3948 tcg_gen_sari_i32(t1
, t1
, 16);
3951 tcg_gen_mul_i32(t0
, t0
, t1
);
3954 /* Return the mask of PSR bits set by a MSR instruction. */
3955 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3959 if (flags
& (1 << 0))
3961 if (flags
& (1 << 1))
3963 if (flags
& (1 << 2))
3965 if (flags
& (1 << 3))
3968 /* Mask out undefined bits. */
3969 mask
&= ~CPSR_RESERVED
;
3970 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3972 if (!arm_feature(env
, ARM_FEATURE_V5
))
3973 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3974 if (!arm_feature(env
, ARM_FEATURE_V6
))
3975 mask
&= ~(CPSR_E
| CPSR_GE
);
3976 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3978 /* Mask out execution state and reserved bits. */
3980 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3982 /* Mask out privileged bits. */
3988 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3989 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3993 /* ??? This is also undefined in system mode. */
3997 tmp
= load_cpu_field(spsr
);
3998 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3999 tcg_gen_andi_i32(t0
, t0
, mask
);
4000 tcg_gen_or_i32(tmp
, tmp
, t0
);
4001 store_cpu_field(tmp
, spsr
);
4003 gen_set_cpsr(t0
, mask
);
4005 tcg_temp_free_i32(t0
);
4010 /* Returns nonzero if access to the PSR is not permitted. */
4011 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4014 tmp
= tcg_temp_new_i32();
4015 tcg_gen_movi_i32(tmp
, val
);
4016 return gen_set_psr(s
, mask
, spsr
, tmp
);
4019 /* Generate an old-style exception return. Marks pc as dead. */
4020 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4023 store_reg(s
, 15, pc
);
4024 tmp
= load_cpu_field(spsr
);
4025 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4026 tcg_temp_free_i32(tmp
);
4027 s
->is_jmp
= DISAS_UPDATE
;
4030 /* Generate a v6 exception return. Marks both values as dead. */
4031 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4033 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4034 tcg_temp_free_i32(cpsr
);
4035 store_reg(s
, 15, pc
);
4036 s
->is_jmp
= DISAS_UPDATE
;
4039 static void gen_nop_hint(DisasContext
*s
, int val
)
4043 gen_set_pc_im(s
, s
->pc
);
4044 s
->is_jmp
= DISAS_WFI
;
4047 gen_set_pc_im(s
, s
->pc
);
4048 s
->is_jmp
= DISAS_WFE
;
4052 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4058 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4060 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4063 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4064 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4065 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4070 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4073 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4074 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4075 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4080 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4081 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4082 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4083 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4084 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4086 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4087 switch ((size << 1) | u) { \
4089 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4092 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4095 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4098 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4101 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4104 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4106 default: return 1; \
4109 #define GEN_NEON_INTEGER_OP(name) do { \
4110 switch ((size << 1) | u) { \
4112 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4115 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4118 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4121 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4124 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4127 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4129 default: return 1; \
4132 static TCGv_i32
neon_load_scratch(int scratch
)
4134 TCGv_i32 tmp
= tcg_temp_new_i32();
4135 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4139 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4141 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4142 tcg_temp_free_i32(var
);
4145 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4149 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4151 gen_neon_dup_high16(tmp
);
4153 gen_neon_dup_low16(tmp
);
4156 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4161 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4164 if (!q
&& size
== 2) {
4167 tmp
= tcg_const_i32(rd
);
4168 tmp2
= tcg_const_i32(rm
);
4172 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4175 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4178 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4186 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4189 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4195 tcg_temp_free_i32(tmp
);
4196 tcg_temp_free_i32(tmp2
);
4200 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4203 if (!q
&& size
== 2) {
4206 tmp
= tcg_const_i32(rd
);
4207 tmp2
= tcg_const_i32(rm
);
4211 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4214 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4217 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4225 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4228 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4234 tcg_temp_free_i32(tmp
);
4235 tcg_temp_free_i32(tmp2
);
4239 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4243 rd
= tcg_temp_new_i32();
4244 tmp
= tcg_temp_new_i32();
4246 tcg_gen_shli_i32(rd
, t0
, 8);
4247 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4248 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4249 tcg_gen_or_i32(rd
, rd
, tmp
);
4251 tcg_gen_shri_i32(t1
, t1
, 8);
4252 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4253 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4254 tcg_gen_or_i32(t1
, t1
, tmp
);
4255 tcg_gen_mov_i32(t0
, rd
);
4257 tcg_temp_free_i32(tmp
);
4258 tcg_temp_free_i32(rd
);
4261 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4265 rd
= tcg_temp_new_i32();
4266 tmp
= tcg_temp_new_i32();
4268 tcg_gen_shli_i32(rd
, t0
, 16);
4269 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4270 tcg_gen_or_i32(rd
, rd
, tmp
);
4271 tcg_gen_shri_i32(t1
, t1
, 16);
4272 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4273 tcg_gen_or_i32(t1
, t1
, tmp
);
4274 tcg_gen_mov_i32(t0
, rd
);
4276 tcg_temp_free_i32(tmp
);
4277 tcg_temp_free_i32(rd
);
4285 } neon_ls_element_type
[11] = {
4299 /* Translate a NEON load/store element instruction. Return nonzero if the
4300 instruction is invalid. */
4301 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4320 /* FIXME: this access check should not take precedence over UNDEF
4321 * for invalid encodings; we will generate incorrect syndrome information
4322 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4324 if (!s
->cpacr_fpen
) {
4325 gen_exception_insn(s
, 4, EXCP_UDEF
,
4326 syn_fp_access_trap(1, 0xe, s
->thumb
));
4330 if (!s
->vfp_enabled
)
4332 VFP_DREG_D(rd
, insn
);
4333 rn
= (insn
>> 16) & 0xf;
4335 load
= (insn
& (1 << 21)) != 0;
4336 if ((insn
& (1 << 23)) == 0) {
4337 /* Load store all elements. */
4338 op
= (insn
>> 8) & 0xf;
4339 size
= (insn
>> 6) & 3;
4342 /* Catch UNDEF cases for bad values of align field */
4345 if (((insn
>> 5) & 1) == 1) {
4350 if (((insn
>> 4) & 3) == 3) {
4357 nregs
= neon_ls_element_type
[op
].nregs
;
4358 interleave
= neon_ls_element_type
[op
].interleave
;
4359 spacing
= neon_ls_element_type
[op
].spacing
;
4360 if (size
== 3 && (interleave
| spacing
) != 1)
4362 addr
= tcg_temp_new_i32();
4363 load_reg_var(s
, addr
, rn
);
4364 stride
= (1 << size
) * interleave
;
4365 for (reg
= 0; reg
< nregs
; reg
++) {
4366 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4367 load_reg_var(s
, addr
, rn
);
4368 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4369 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4370 load_reg_var(s
, addr
, rn
);
4371 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4374 tmp64
= tcg_temp_new_i64();
4376 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4377 neon_store_reg64(tmp64
, rd
);
4379 neon_load_reg64(tmp64
, rd
);
4380 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4382 tcg_temp_free_i64(tmp64
);
4383 tcg_gen_addi_i32(addr
, addr
, stride
);
4385 for (pass
= 0; pass
< 2; pass
++) {
4388 tmp
= tcg_temp_new_i32();
4389 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4390 neon_store_reg(rd
, pass
, tmp
);
4392 tmp
= neon_load_reg(rd
, pass
);
4393 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4394 tcg_temp_free_i32(tmp
);
4396 tcg_gen_addi_i32(addr
, addr
, stride
);
4397 } else if (size
== 1) {
4399 tmp
= tcg_temp_new_i32();
4400 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4401 tcg_gen_addi_i32(addr
, addr
, stride
);
4402 tmp2
= tcg_temp_new_i32();
4403 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4404 tcg_gen_addi_i32(addr
, addr
, stride
);
4405 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4406 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4407 tcg_temp_free_i32(tmp2
);
4408 neon_store_reg(rd
, pass
, tmp
);
4410 tmp
= neon_load_reg(rd
, pass
);
4411 tmp2
= tcg_temp_new_i32();
4412 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4413 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4414 tcg_temp_free_i32(tmp
);
4415 tcg_gen_addi_i32(addr
, addr
, stride
);
4416 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4417 tcg_temp_free_i32(tmp2
);
4418 tcg_gen_addi_i32(addr
, addr
, stride
);
4420 } else /* size == 0 */ {
4422 TCGV_UNUSED_I32(tmp2
);
4423 for (n
= 0; n
< 4; n
++) {
4424 tmp
= tcg_temp_new_i32();
4425 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4426 tcg_gen_addi_i32(addr
, addr
, stride
);
4430 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4431 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4432 tcg_temp_free_i32(tmp
);
4435 neon_store_reg(rd
, pass
, tmp2
);
4437 tmp2
= neon_load_reg(rd
, pass
);
4438 for (n
= 0; n
< 4; n
++) {
4439 tmp
= tcg_temp_new_i32();
4441 tcg_gen_mov_i32(tmp
, tmp2
);
4443 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4445 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4446 tcg_temp_free_i32(tmp
);
4447 tcg_gen_addi_i32(addr
, addr
, stride
);
4449 tcg_temp_free_i32(tmp2
);
4456 tcg_temp_free_i32(addr
);
4459 size
= (insn
>> 10) & 3;
4461 /* Load single element to all lanes. */
4462 int a
= (insn
>> 4) & 1;
4466 size
= (insn
>> 6) & 3;
4467 nregs
= ((insn
>> 8) & 3) + 1;
4470 if (nregs
!= 4 || a
== 0) {
4473 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4476 if (nregs
== 1 && a
== 1 && size
== 0) {
4479 if (nregs
== 3 && a
== 1) {
4482 addr
= tcg_temp_new_i32();
4483 load_reg_var(s
, addr
, rn
);
4485 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4486 tmp
= gen_load_and_replicate(s
, addr
, size
);
4487 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4488 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4489 if (insn
& (1 << 5)) {
4490 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4491 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4493 tcg_temp_free_i32(tmp
);
4495 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4496 stride
= (insn
& (1 << 5)) ? 2 : 1;
4497 for (reg
= 0; reg
< nregs
; reg
++) {
4498 tmp
= gen_load_and_replicate(s
, addr
, size
);
4499 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4500 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4501 tcg_temp_free_i32(tmp
);
4502 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4506 tcg_temp_free_i32(addr
);
4507 stride
= (1 << size
) * nregs
;
4509 /* Single element. */
4510 int idx
= (insn
>> 4) & 0xf;
4511 pass
= (insn
>> 7) & 1;
4514 shift
= ((insn
>> 5) & 3) * 8;
4518 shift
= ((insn
>> 6) & 1) * 16;
4519 stride
= (insn
& (1 << 5)) ? 2 : 1;
4523 stride
= (insn
& (1 << 6)) ? 2 : 1;
4528 nregs
= ((insn
>> 8) & 3) + 1;
4529 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4532 if (((idx
& (1 << size
)) != 0) ||
4533 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4538 if ((idx
& 1) != 0) {
4543 if (size
== 2 && (idx
& 2) != 0) {
4548 if ((size
== 2) && ((idx
& 3) == 3)) {
4555 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4556 /* Attempts to write off the end of the register file
4557 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4558 * the neon_load_reg() would write off the end of the array.
4562 addr
= tcg_temp_new_i32();
4563 load_reg_var(s
, addr
, rn
);
4564 for (reg
= 0; reg
< nregs
; reg
++) {
4566 tmp
= tcg_temp_new_i32();
4569 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4572 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4575 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4577 default: /* Avoid compiler warnings. */
4581 tmp2
= neon_load_reg(rd
, pass
);
4582 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4583 shift
, size
? 16 : 8);
4584 tcg_temp_free_i32(tmp2
);
4586 neon_store_reg(rd
, pass
, tmp
);
4587 } else { /* Store */
4588 tmp
= neon_load_reg(rd
, pass
);
4590 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4593 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4596 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4599 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4602 tcg_temp_free_i32(tmp
);
4605 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4607 tcg_temp_free_i32(addr
);
4608 stride
= nregs
* (1 << size
);
4614 base
= load_reg(s
, rn
);
4616 tcg_gen_addi_i32(base
, base
, stride
);
4619 index
= load_reg(s
, rm
);
4620 tcg_gen_add_i32(base
, base
, index
);
4621 tcg_temp_free_i32(index
);
4623 store_reg(s
, rn
, base
);
4628 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4629 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4631 tcg_gen_and_i32(t
, t
, c
);
4632 tcg_gen_andc_i32(f
, f
, c
);
4633 tcg_gen_or_i32(dest
, t
, f
);
4636 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4639 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4640 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4641 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4646 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4649 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4650 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4651 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4656 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4659 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4660 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4661 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4666 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4669 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4670 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4671 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4676 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4682 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4683 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4688 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4689 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4696 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4697 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4702 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4703 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4710 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4714 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4715 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4716 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4721 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4722 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4723 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4727 tcg_temp_free_i32(src
);
4730 static inline void gen_neon_addl(int size
)
4733 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4734 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4735 case 2: tcg_gen_add_i64(CPU_V001
); break;
4740 static inline void gen_neon_subl(int size
)
4743 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4744 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4745 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4750 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4753 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4754 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4756 tcg_gen_neg_i64(var
, var
);
4762 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4765 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4766 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4771 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4776 switch ((size
<< 1) | u
) {
4777 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4778 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4779 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4780 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4782 tmp
= gen_muls_i64_i32(a
, b
);
4783 tcg_gen_mov_i64(dest
, tmp
);
4784 tcg_temp_free_i64(tmp
);
4787 tmp
= gen_mulu_i64_i32(a
, b
);
4788 tcg_gen_mov_i64(dest
, tmp
);
4789 tcg_temp_free_i64(tmp
);
4794 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4795 Don't forget to clean them now. */
4797 tcg_temp_free_i32(a
);
4798 tcg_temp_free_i32(b
);
4802 static void gen_neon_narrow_op(int op
, int u
, int size
,
4803 TCGv_i32 dest
, TCGv_i64 src
)
4807 gen_neon_unarrow_sats(size
, dest
, src
);
4809 gen_neon_narrow(size
, dest
, src
);
4813 gen_neon_narrow_satu(size
, dest
, src
);
4815 gen_neon_narrow_sats(size
, dest
, src
);
4820 /* Symbolic constants for op fields for Neon 3-register same-length.
4821 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4824 #define NEON_3R_VHADD 0
4825 #define NEON_3R_VQADD 1
4826 #define NEON_3R_VRHADD 2
4827 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4828 #define NEON_3R_VHSUB 4
4829 #define NEON_3R_VQSUB 5
4830 #define NEON_3R_VCGT 6
4831 #define NEON_3R_VCGE 7
4832 #define NEON_3R_VSHL 8
4833 #define NEON_3R_VQSHL 9
4834 #define NEON_3R_VRSHL 10
4835 #define NEON_3R_VQRSHL 11
4836 #define NEON_3R_VMAX 12
4837 #define NEON_3R_VMIN 13
4838 #define NEON_3R_VABD 14
4839 #define NEON_3R_VABA 15
4840 #define NEON_3R_VADD_VSUB 16
4841 #define NEON_3R_VTST_VCEQ 17
4842 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4843 #define NEON_3R_VMUL 19
4844 #define NEON_3R_VPMAX 20
4845 #define NEON_3R_VPMIN 21
4846 #define NEON_3R_VQDMULH_VQRDMULH 22
4847 #define NEON_3R_VPADD 23
4848 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4849 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4850 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4851 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4852 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4853 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4854 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4855 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4857 static const uint8_t neon_3r_sizes
[] = {
4858 [NEON_3R_VHADD
] = 0x7,
4859 [NEON_3R_VQADD
] = 0xf,
4860 [NEON_3R_VRHADD
] = 0x7,
4861 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4862 [NEON_3R_VHSUB
] = 0x7,
4863 [NEON_3R_VQSUB
] = 0xf,
4864 [NEON_3R_VCGT
] = 0x7,
4865 [NEON_3R_VCGE
] = 0x7,
4866 [NEON_3R_VSHL
] = 0xf,
4867 [NEON_3R_VQSHL
] = 0xf,
4868 [NEON_3R_VRSHL
] = 0xf,
4869 [NEON_3R_VQRSHL
] = 0xf,
4870 [NEON_3R_VMAX
] = 0x7,
4871 [NEON_3R_VMIN
] = 0x7,
4872 [NEON_3R_VABD
] = 0x7,
4873 [NEON_3R_VABA
] = 0x7,
4874 [NEON_3R_VADD_VSUB
] = 0xf,
4875 [NEON_3R_VTST_VCEQ
] = 0x7,
4876 [NEON_3R_VML
] = 0x7,
4877 [NEON_3R_VMUL
] = 0x7,
4878 [NEON_3R_VPMAX
] = 0x7,
4879 [NEON_3R_VPMIN
] = 0x7,
4880 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4881 [NEON_3R_VPADD
] = 0x7,
4882 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4883 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4884 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4885 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4886 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4887 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4888 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4889 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4892 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4893 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4896 #define NEON_2RM_VREV64 0
4897 #define NEON_2RM_VREV32 1
4898 #define NEON_2RM_VREV16 2
4899 #define NEON_2RM_VPADDL 4
4900 #define NEON_2RM_VPADDL_U 5
4901 #define NEON_2RM_AESE 6 /* Includes AESD */
4902 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4903 #define NEON_2RM_VCLS 8
4904 #define NEON_2RM_VCLZ 9
4905 #define NEON_2RM_VCNT 10
4906 #define NEON_2RM_VMVN 11
4907 #define NEON_2RM_VPADAL 12
4908 #define NEON_2RM_VPADAL_U 13
4909 #define NEON_2RM_VQABS 14
4910 #define NEON_2RM_VQNEG 15
4911 #define NEON_2RM_VCGT0 16
4912 #define NEON_2RM_VCGE0 17
4913 #define NEON_2RM_VCEQ0 18
4914 #define NEON_2RM_VCLE0 19
4915 #define NEON_2RM_VCLT0 20
4916 #define NEON_2RM_SHA1H 21
4917 #define NEON_2RM_VABS 22
4918 #define NEON_2RM_VNEG 23
4919 #define NEON_2RM_VCGT0_F 24
4920 #define NEON_2RM_VCGE0_F 25
4921 #define NEON_2RM_VCEQ0_F 26
4922 #define NEON_2RM_VCLE0_F 27
4923 #define NEON_2RM_VCLT0_F 28
4924 #define NEON_2RM_VABS_F 30
4925 #define NEON_2RM_VNEG_F 31
4926 #define NEON_2RM_VSWP 32
4927 #define NEON_2RM_VTRN 33
4928 #define NEON_2RM_VUZP 34
4929 #define NEON_2RM_VZIP 35
4930 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4931 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4932 #define NEON_2RM_VSHLL 38
4933 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4934 #define NEON_2RM_VRINTN 40
4935 #define NEON_2RM_VRINTX 41
4936 #define NEON_2RM_VRINTA 42
4937 #define NEON_2RM_VRINTZ 43
4938 #define NEON_2RM_VCVT_F16_F32 44
4939 #define NEON_2RM_VRINTM 45
4940 #define NEON_2RM_VCVT_F32_F16 46
4941 #define NEON_2RM_VRINTP 47
4942 #define NEON_2RM_VCVTAU 48
4943 #define NEON_2RM_VCVTAS 49
4944 #define NEON_2RM_VCVTNU 50
4945 #define NEON_2RM_VCVTNS 51
4946 #define NEON_2RM_VCVTPU 52
4947 #define NEON_2RM_VCVTPS 53
4948 #define NEON_2RM_VCVTMU 54
4949 #define NEON_2RM_VCVTMS 55
4950 #define NEON_2RM_VRECPE 56
4951 #define NEON_2RM_VRSQRTE 57
4952 #define NEON_2RM_VRECPE_F 58
4953 #define NEON_2RM_VRSQRTE_F 59
4954 #define NEON_2RM_VCVT_FS 60
4955 #define NEON_2RM_VCVT_FU 61
4956 #define NEON_2RM_VCVT_SF 62
4957 #define NEON_2RM_VCVT_UF 63
4959 static int neon_2rm_is_float_op(int op
)
4961 /* Return true if this neon 2reg-misc op is float-to-float */
4962 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4963 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4964 op
== NEON_2RM_VRINTM
||
4965 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4966 op
>= NEON_2RM_VRECPE_F
);
4969 /* Each entry in this array has bit n set if the insn allows
4970 * size value n (otherwise it will UNDEF). Since unallocated
4971 * op values will have no bits set they always UNDEF.
4973 static const uint8_t neon_2rm_sizes
[] = {
4974 [NEON_2RM_VREV64
] = 0x7,
4975 [NEON_2RM_VREV32
] = 0x3,
4976 [NEON_2RM_VREV16
] = 0x1,
4977 [NEON_2RM_VPADDL
] = 0x7,
4978 [NEON_2RM_VPADDL_U
] = 0x7,
4979 [NEON_2RM_AESE
] = 0x1,
4980 [NEON_2RM_AESMC
] = 0x1,
4981 [NEON_2RM_VCLS
] = 0x7,
4982 [NEON_2RM_VCLZ
] = 0x7,
4983 [NEON_2RM_VCNT
] = 0x1,
4984 [NEON_2RM_VMVN
] = 0x1,
4985 [NEON_2RM_VPADAL
] = 0x7,
4986 [NEON_2RM_VPADAL_U
] = 0x7,
4987 [NEON_2RM_VQABS
] = 0x7,
4988 [NEON_2RM_VQNEG
] = 0x7,
4989 [NEON_2RM_VCGT0
] = 0x7,
4990 [NEON_2RM_VCGE0
] = 0x7,
4991 [NEON_2RM_VCEQ0
] = 0x7,
4992 [NEON_2RM_VCLE0
] = 0x7,
4993 [NEON_2RM_VCLT0
] = 0x7,
4994 [NEON_2RM_SHA1H
] = 0x4,
4995 [NEON_2RM_VABS
] = 0x7,
4996 [NEON_2RM_VNEG
] = 0x7,
4997 [NEON_2RM_VCGT0_F
] = 0x4,
4998 [NEON_2RM_VCGE0_F
] = 0x4,
4999 [NEON_2RM_VCEQ0_F
] = 0x4,
5000 [NEON_2RM_VCLE0_F
] = 0x4,
5001 [NEON_2RM_VCLT0_F
] = 0x4,
5002 [NEON_2RM_VABS_F
] = 0x4,
5003 [NEON_2RM_VNEG_F
] = 0x4,
5004 [NEON_2RM_VSWP
] = 0x1,
5005 [NEON_2RM_VTRN
] = 0x7,
5006 [NEON_2RM_VUZP
] = 0x7,
5007 [NEON_2RM_VZIP
] = 0x7,
5008 [NEON_2RM_VMOVN
] = 0x7,
5009 [NEON_2RM_VQMOVN
] = 0x7,
5010 [NEON_2RM_VSHLL
] = 0x7,
5011 [NEON_2RM_SHA1SU1
] = 0x4,
5012 [NEON_2RM_VRINTN
] = 0x4,
5013 [NEON_2RM_VRINTX
] = 0x4,
5014 [NEON_2RM_VRINTA
] = 0x4,
5015 [NEON_2RM_VRINTZ
] = 0x4,
5016 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5017 [NEON_2RM_VRINTM
] = 0x4,
5018 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5019 [NEON_2RM_VRINTP
] = 0x4,
5020 [NEON_2RM_VCVTAU
] = 0x4,
5021 [NEON_2RM_VCVTAS
] = 0x4,
5022 [NEON_2RM_VCVTNU
] = 0x4,
5023 [NEON_2RM_VCVTNS
] = 0x4,
5024 [NEON_2RM_VCVTPU
] = 0x4,
5025 [NEON_2RM_VCVTPS
] = 0x4,
5026 [NEON_2RM_VCVTMU
] = 0x4,
5027 [NEON_2RM_VCVTMS
] = 0x4,
5028 [NEON_2RM_VRECPE
] = 0x4,
5029 [NEON_2RM_VRSQRTE
] = 0x4,
5030 [NEON_2RM_VRECPE_F
] = 0x4,
5031 [NEON_2RM_VRSQRTE_F
] = 0x4,
5032 [NEON_2RM_VCVT_FS
] = 0x4,
5033 [NEON_2RM_VCVT_FU
] = 0x4,
5034 [NEON_2RM_VCVT_SF
] = 0x4,
5035 [NEON_2RM_VCVT_UF
] = 0x4,
5038 /* Translate a NEON data processing instruction. Return nonzero if the
5039 instruction is invalid.
5040 We process data in a mixture of 32-bit and 64-bit chunks.
5041 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5043 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
5055 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5058 /* FIXME: this access check should not take precedence over UNDEF
5059 * for invalid encodings; we will generate incorrect syndrome information
5060 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5062 if (!s
->cpacr_fpen
) {
5063 gen_exception_insn(s
, 4, EXCP_UDEF
,
5064 syn_fp_access_trap(1, 0xe, s
->thumb
));
5068 if (!s
->vfp_enabled
)
5070 q
= (insn
& (1 << 6)) != 0;
5071 u
= (insn
>> 24) & 1;
5072 VFP_DREG_D(rd
, insn
);
5073 VFP_DREG_N(rn
, insn
);
5074 VFP_DREG_M(rm
, insn
);
5075 size
= (insn
>> 20) & 3;
5076 if ((insn
& (1 << 23)) == 0) {
5077 /* Three register same length. */
5078 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5079 /* Catch invalid op and bad size combinations: UNDEF */
5080 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5083 /* All insns of this form UNDEF for either this condition or the
5084 * superset of cases "Q==1"; we catch the latter later.
5086 if (q
&& ((rd
| rn
| rm
) & 1)) {
5090 * The SHA-1/SHA-256 3-register instructions require special treatment
5091 * here, as their size field is overloaded as an op type selector, and
5092 * they all consume their input in a single pass.
5094 if (op
== NEON_3R_SHA
) {
5098 if (!u
) { /* SHA-1 */
5099 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
5102 tmp
= tcg_const_i32(rd
);
5103 tmp2
= tcg_const_i32(rn
);
5104 tmp3
= tcg_const_i32(rm
);
5105 tmp4
= tcg_const_i32(size
);
5106 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5107 tcg_temp_free_i32(tmp4
);
5108 } else { /* SHA-256 */
5109 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5112 tmp
= tcg_const_i32(rd
);
5113 tmp2
= tcg_const_i32(rn
);
5114 tmp3
= tcg_const_i32(rm
);
5117 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5120 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5123 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5127 tcg_temp_free_i32(tmp
);
5128 tcg_temp_free_i32(tmp2
);
5129 tcg_temp_free_i32(tmp3
);
5132 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5133 /* 64-bit element instructions. */
5134 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5135 neon_load_reg64(cpu_V0
, rn
+ pass
);
5136 neon_load_reg64(cpu_V1
, rm
+ pass
);
5140 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5143 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5149 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5152 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5158 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5160 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5165 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5168 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5174 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5176 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5179 case NEON_3R_VQRSHL
:
5181 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5184 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5188 case NEON_3R_VADD_VSUB
:
5190 tcg_gen_sub_i64(CPU_V001
);
5192 tcg_gen_add_i64(CPU_V001
);
5198 neon_store_reg64(cpu_V0
, rd
+ pass
);
5207 case NEON_3R_VQRSHL
:
5210 /* Shift instruction operands are reversed. */
5225 case NEON_3R_FLOAT_ARITH
:
5226 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5228 case NEON_3R_FLOAT_MINMAX
:
5229 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5231 case NEON_3R_FLOAT_CMP
:
5233 /* no encoding for U=0 C=1x */
5237 case NEON_3R_FLOAT_ACMP
:
5242 case NEON_3R_FLOAT_MISC
:
5243 /* VMAXNM/VMINNM in ARMv8 */
5244 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5249 if (u
&& (size
!= 0)) {
5250 /* UNDEF on invalid size for polynomial subcase */
5255 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5263 if (pairwise
&& q
) {
5264 /* All the pairwise insns UNDEF if Q is set */
5268 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5273 tmp
= neon_load_reg(rn
, 0);
5274 tmp2
= neon_load_reg(rn
, 1);
5276 tmp
= neon_load_reg(rm
, 0);
5277 tmp2
= neon_load_reg(rm
, 1);
5281 tmp
= neon_load_reg(rn
, pass
);
5282 tmp2
= neon_load_reg(rm
, pass
);
5286 GEN_NEON_INTEGER_OP(hadd
);
5289 GEN_NEON_INTEGER_OP_ENV(qadd
);
5291 case NEON_3R_VRHADD
:
5292 GEN_NEON_INTEGER_OP(rhadd
);
5294 case NEON_3R_LOGIC
: /* Logic ops. */
5295 switch ((u
<< 2) | size
) {
5297 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5300 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5303 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5306 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5309 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5312 tmp3
= neon_load_reg(rd
, pass
);
5313 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5314 tcg_temp_free_i32(tmp3
);
5317 tmp3
= neon_load_reg(rd
, pass
);
5318 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5319 tcg_temp_free_i32(tmp3
);
5322 tmp3
= neon_load_reg(rd
, pass
);
5323 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5324 tcg_temp_free_i32(tmp3
);
5329 GEN_NEON_INTEGER_OP(hsub
);
5332 GEN_NEON_INTEGER_OP_ENV(qsub
);
5335 GEN_NEON_INTEGER_OP(cgt
);
5338 GEN_NEON_INTEGER_OP(cge
);
5341 GEN_NEON_INTEGER_OP(shl
);
5344 GEN_NEON_INTEGER_OP_ENV(qshl
);
5347 GEN_NEON_INTEGER_OP(rshl
);
5349 case NEON_3R_VQRSHL
:
5350 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5353 GEN_NEON_INTEGER_OP(max
);
5356 GEN_NEON_INTEGER_OP(min
);
5359 GEN_NEON_INTEGER_OP(abd
);
5362 GEN_NEON_INTEGER_OP(abd
);
5363 tcg_temp_free_i32(tmp2
);
5364 tmp2
= neon_load_reg(rd
, pass
);
5365 gen_neon_add(size
, tmp
, tmp2
);
5367 case NEON_3R_VADD_VSUB
:
5368 if (!u
) { /* VADD */
5369 gen_neon_add(size
, tmp
, tmp2
);
5372 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5373 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5374 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5379 case NEON_3R_VTST_VCEQ
:
5380 if (!u
) { /* VTST */
5382 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5383 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5384 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5389 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5390 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5391 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5396 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5398 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5399 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5400 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5403 tcg_temp_free_i32(tmp2
);
5404 tmp2
= neon_load_reg(rd
, pass
);
5406 gen_neon_rsb(size
, tmp
, tmp2
);
5408 gen_neon_add(size
, tmp
, tmp2
);
5412 if (u
) { /* polynomial */
5413 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5414 } else { /* Integer */
5416 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5417 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5418 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5424 GEN_NEON_INTEGER_OP(pmax
);
5427 GEN_NEON_INTEGER_OP(pmin
);
5429 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5430 if (!u
) { /* VQDMULH */
5433 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5436 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5440 } else { /* VQRDMULH */
5443 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5446 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5454 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5455 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5456 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5460 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5462 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5463 switch ((u
<< 2) | size
) {
5466 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5469 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5472 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5477 tcg_temp_free_ptr(fpstatus
);
5480 case NEON_3R_FLOAT_MULTIPLY
:
5482 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5483 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5485 tcg_temp_free_i32(tmp2
);
5486 tmp2
= neon_load_reg(rd
, pass
);
5488 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5490 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5493 tcg_temp_free_ptr(fpstatus
);
5496 case NEON_3R_FLOAT_CMP
:
5498 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5500 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5503 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5505 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5508 tcg_temp_free_ptr(fpstatus
);
5511 case NEON_3R_FLOAT_ACMP
:
5513 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5515 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5517 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5519 tcg_temp_free_ptr(fpstatus
);
5522 case NEON_3R_FLOAT_MINMAX
:
5524 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5526 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5528 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5530 tcg_temp_free_ptr(fpstatus
);
5533 case NEON_3R_FLOAT_MISC
:
5536 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5538 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5540 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5542 tcg_temp_free_ptr(fpstatus
);
5545 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5547 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5553 /* VFMA, VFMS: fused multiply-add */
5554 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5555 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5558 gen_helper_vfp_negs(tmp
, tmp
);
5560 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5561 tcg_temp_free_i32(tmp3
);
5562 tcg_temp_free_ptr(fpstatus
);
5568 tcg_temp_free_i32(tmp2
);
5570 /* Save the result. For elementwise operations we can put it
5571 straight into the destination register. For pairwise operations
5572 we have to be careful to avoid clobbering the source operands. */
5573 if (pairwise
&& rd
== rm
) {
5574 neon_store_scratch(pass
, tmp
);
5576 neon_store_reg(rd
, pass
, tmp
);
5580 if (pairwise
&& rd
== rm
) {
5581 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5582 tmp
= neon_load_scratch(pass
);
5583 neon_store_reg(rd
, pass
, tmp
);
5586 /* End of 3 register same size operations. */
5587 } else if (insn
& (1 << 4)) {
5588 if ((insn
& 0x00380080) != 0) {
5589 /* Two registers and shift. */
5590 op
= (insn
>> 8) & 0xf;
5591 if (insn
& (1 << 7)) {
5599 while ((insn
& (1 << (size
+ 19))) == 0)
5602 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5603 /* To avoid excessive duplication of ops we implement shift
5604 by immediate using the variable shift operations. */
5606 /* Shift by immediate:
5607 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5608 if (q
&& ((rd
| rm
) & 1)) {
5611 if (!u
&& (op
== 4 || op
== 6)) {
5614 /* Right shifts are encoded as N - shift, where N is the
5615 element size in bits. */
5617 shift
= shift
- (1 << (size
+ 3));
5625 imm
= (uint8_t) shift
;
5630 imm
= (uint16_t) shift
;
5641 for (pass
= 0; pass
< count
; pass
++) {
5643 neon_load_reg64(cpu_V0
, rm
+ pass
);
5644 tcg_gen_movi_i64(cpu_V1
, imm
);
5649 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5651 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5656 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5658 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5661 case 5: /* VSHL, VSLI */
5662 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5664 case 6: /* VQSHLU */
5665 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5670 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5673 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5678 if (op
== 1 || op
== 3) {
5680 neon_load_reg64(cpu_V1
, rd
+ pass
);
5681 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5682 } else if (op
== 4 || (op
== 5 && u
)) {
5684 neon_load_reg64(cpu_V1
, rd
+ pass
);
5686 if (shift
< -63 || shift
> 63) {
5690 mask
= 0xffffffffffffffffull
>> -shift
;
5692 mask
= 0xffffffffffffffffull
<< shift
;
5695 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5696 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5698 neon_store_reg64(cpu_V0
, rd
+ pass
);
5699 } else { /* size < 3 */
5700 /* Operands in T0 and T1. */
5701 tmp
= neon_load_reg(rm
, pass
);
5702 tmp2
= tcg_temp_new_i32();
5703 tcg_gen_movi_i32(tmp2
, imm
);
5707 GEN_NEON_INTEGER_OP(shl
);
5711 GEN_NEON_INTEGER_OP(rshl
);
5714 case 5: /* VSHL, VSLI */
5716 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5717 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5718 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5722 case 6: /* VQSHLU */
5725 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5729 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5733 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5741 GEN_NEON_INTEGER_OP_ENV(qshl
);
5744 tcg_temp_free_i32(tmp2
);
5746 if (op
== 1 || op
== 3) {
5748 tmp2
= neon_load_reg(rd
, pass
);
5749 gen_neon_add(size
, tmp
, tmp2
);
5750 tcg_temp_free_i32(tmp2
);
5751 } else if (op
== 4 || (op
== 5 && u
)) {
5756 mask
= 0xff >> -shift
;
5758 mask
= (uint8_t)(0xff << shift
);
5764 mask
= 0xffff >> -shift
;
5766 mask
= (uint16_t)(0xffff << shift
);
5770 if (shift
< -31 || shift
> 31) {
5774 mask
= 0xffffffffu
>> -shift
;
5776 mask
= 0xffffffffu
<< shift
;
5782 tmp2
= neon_load_reg(rd
, pass
);
5783 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5784 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5785 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5786 tcg_temp_free_i32(tmp2
);
5788 neon_store_reg(rd
, pass
, tmp
);
5791 } else if (op
< 10) {
5792 /* Shift by immediate and narrow:
5793 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5794 int input_unsigned
= (op
== 8) ? !u
: u
;
5798 shift
= shift
- (1 << (size
+ 3));
5801 tmp64
= tcg_const_i64(shift
);
5802 neon_load_reg64(cpu_V0
, rm
);
5803 neon_load_reg64(cpu_V1
, rm
+ 1);
5804 for (pass
= 0; pass
< 2; pass
++) {
5812 if (input_unsigned
) {
5813 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5815 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5818 if (input_unsigned
) {
5819 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5821 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5824 tmp
= tcg_temp_new_i32();
5825 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5826 neon_store_reg(rd
, pass
, tmp
);
5828 tcg_temp_free_i64(tmp64
);
5831 imm
= (uint16_t)shift
;
5835 imm
= (uint32_t)shift
;
5837 tmp2
= tcg_const_i32(imm
);
5838 tmp4
= neon_load_reg(rm
+ 1, 0);
5839 tmp5
= neon_load_reg(rm
+ 1, 1);
5840 for (pass
= 0; pass
< 2; pass
++) {
5842 tmp
= neon_load_reg(rm
, 0);
5846 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5849 tmp3
= neon_load_reg(rm
, 1);
5853 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5855 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5856 tcg_temp_free_i32(tmp
);
5857 tcg_temp_free_i32(tmp3
);
5858 tmp
= tcg_temp_new_i32();
5859 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5860 neon_store_reg(rd
, pass
, tmp
);
5862 tcg_temp_free_i32(tmp2
);
5864 } else if (op
== 10) {
5866 if (q
|| (rd
& 1)) {
5869 tmp
= neon_load_reg(rm
, 0);
5870 tmp2
= neon_load_reg(rm
, 1);
5871 for (pass
= 0; pass
< 2; pass
++) {
5875 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5878 /* The shift is less than the width of the source
5879 type, so we can just shift the whole register. */
5880 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5881 /* Widen the result of shift: we need to clear
5882 * the potential overflow bits resulting from
5883 * left bits of the narrow input appearing as
5884 * right bits of left the neighbour narrow
5886 if (size
< 2 || !u
) {
5889 imm
= (0xffu
>> (8 - shift
));
5891 } else if (size
== 1) {
5892 imm
= 0xffff >> (16 - shift
);
5895 imm
= 0xffffffff >> (32 - shift
);
5898 imm64
= imm
| (((uint64_t)imm
) << 32);
5902 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5905 neon_store_reg64(cpu_V0
, rd
+ pass
);
5907 } else if (op
>= 14) {
5908 /* VCVT fixed-point. */
5909 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5912 /* We have already masked out the must-be-1 top bit of imm6,
5913 * hence this 32-shift where the ARM ARM has 64-imm6.
5916 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5917 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5920 gen_vfp_ulto(0, shift
, 1);
5922 gen_vfp_slto(0, shift
, 1);
5925 gen_vfp_toul(0, shift
, 1);
5927 gen_vfp_tosl(0, shift
, 1);
5929 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5934 } else { /* (insn & 0x00380080) == 0 */
5936 if (q
&& (rd
& 1)) {
5940 op
= (insn
>> 8) & 0xf;
5941 /* One register and immediate. */
5942 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5943 invert
= (insn
& (1 << 5)) != 0;
5944 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5945 * We choose to not special-case this and will behave as if a
5946 * valid constant encoding of 0 had been given.
5965 imm
= (imm
<< 8) | (imm
<< 24);
5968 imm
= (imm
<< 8) | 0xff;
5971 imm
= (imm
<< 16) | 0xffff;
5974 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5982 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5983 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5989 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5990 if (op
& 1 && op
< 12) {
5991 tmp
= neon_load_reg(rd
, pass
);
5993 /* The immediate value has already been inverted, so
5995 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5997 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6001 tmp
= tcg_temp_new_i32();
6002 if (op
== 14 && invert
) {
6006 for (n
= 0; n
< 4; n
++) {
6007 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6008 val
|= 0xff << (n
* 8);
6010 tcg_gen_movi_i32(tmp
, val
);
6012 tcg_gen_movi_i32(tmp
, imm
);
6015 neon_store_reg(rd
, pass
, tmp
);
6018 } else { /* (insn & 0x00800010 == 0x00800000) */
6020 op
= (insn
>> 8) & 0xf;
6021 if ((insn
& (1 << 6)) == 0) {
6022 /* Three registers of different lengths. */
6026 /* undefreq: bit 0 : UNDEF if size == 0
6027 * bit 1 : UNDEF if size == 1
6028 * bit 2 : UNDEF if size == 2
6029 * bit 3 : UNDEF if U == 1
6030 * Note that [2:0] set implies 'always UNDEF'
6033 /* prewiden, src1_wide, src2_wide, undefreq */
6034 static const int neon_3reg_wide
[16][4] = {
6035 {1, 0, 0, 0}, /* VADDL */
6036 {1, 1, 0, 0}, /* VADDW */
6037 {1, 0, 0, 0}, /* VSUBL */
6038 {1, 1, 0, 0}, /* VSUBW */
6039 {0, 1, 1, 0}, /* VADDHN */
6040 {0, 0, 0, 0}, /* VABAL */
6041 {0, 1, 1, 0}, /* VSUBHN */
6042 {0, 0, 0, 0}, /* VABDL */
6043 {0, 0, 0, 0}, /* VMLAL */
6044 {0, 0, 0, 9}, /* VQDMLAL */
6045 {0, 0, 0, 0}, /* VMLSL */
6046 {0, 0, 0, 9}, /* VQDMLSL */
6047 {0, 0, 0, 0}, /* Integer VMULL */
6048 {0, 0, 0, 1}, /* VQDMULL */
6049 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6050 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6053 prewiden
= neon_3reg_wide
[op
][0];
6054 src1_wide
= neon_3reg_wide
[op
][1];
6055 src2_wide
= neon_3reg_wide
[op
][2];
6056 undefreq
= neon_3reg_wide
[op
][3];
6058 if ((undefreq
& (1 << size
)) ||
6059 ((undefreq
& 8) && u
)) {
6062 if ((src1_wide
&& (rn
& 1)) ||
6063 (src2_wide
&& (rm
& 1)) ||
6064 (!src2_wide
&& (rd
& 1))) {
6068 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6069 * outside the loop below as it only performs a single pass.
6071 if (op
== 14 && size
== 2) {
6072 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6074 if (!arm_feature(env
, ARM_FEATURE_V8_PMULL
)) {
6077 tcg_rn
= tcg_temp_new_i64();
6078 tcg_rm
= tcg_temp_new_i64();
6079 tcg_rd
= tcg_temp_new_i64();
6080 neon_load_reg64(tcg_rn
, rn
);
6081 neon_load_reg64(tcg_rm
, rm
);
6082 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6083 neon_store_reg64(tcg_rd
, rd
);
6084 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6085 neon_store_reg64(tcg_rd
, rd
+ 1);
6086 tcg_temp_free_i64(tcg_rn
);
6087 tcg_temp_free_i64(tcg_rm
);
6088 tcg_temp_free_i64(tcg_rd
);
6092 /* Avoid overlapping operands. Wide source operands are
6093 always aligned so will never overlap with wide
6094 destinations in problematic ways. */
6095 if (rd
== rm
&& !src2_wide
) {
6096 tmp
= neon_load_reg(rm
, 1);
6097 neon_store_scratch(2, tmp
);
6098 } else if (rd
== rn
&& !src1_wide
) {
6099 tmp
= neon_load_reg(rn
, 1);
6100 neon_store_scratch(2, tmp
);
6102 TCGV_UNUSED_I32(tmp3
);
6103 for (pass
= 0; pass
< 2; pass
++) {
6105 neon_load_reg64(cpu_V0
, rn
+ pass
);
6106 TCGV_UNUSED_I32(tmp
);
6108 if (pass
== 1 && rd
== rn
) {
6109 tmp
= neon_load_scratch(2);
6111 tmp
= neon_load_reg(rn
, pass
);
6114 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6118 neon_load_reg64(cpu_V1
, rm
+ pass
);
6119 TCGV_UNUSED_I32(tmp2
);
6121 if (pass
== 1 && rd
== rm
) {
6122 tmp2
= neon_load_scratch(2);
6124 tmp2
= neon_load_reg(rm
, pass
);
6127 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6131 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6132 gen_neon_addl(size
);
6134 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6135 gen_neon_subl(size
);
6137 case 5: case 7: /* VABAL, VABDL */
6138 switch ((size
<< 1) | u
) {
6140 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6143 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6146 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6149 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6152 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6155 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6159 tcg_temp_free_i32(tmp2
);
6160 tcg_temp_free_i32(tmp
);
6162 case 8: case 9: case 10: case 11: case 12: case 13:
6163 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6164 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6166 case 14: /* Polynomial VMULL */
6167 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6168 tcg_temp_free_i32(tmp2
);
6169 tcg_temp_free_i32(tmp
);
6171 default: /* 15 is RESERVED: caught earlier */
6176 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6177 neon_store_reg64(cpu_V0
, rd
+ pass
);
6178 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6180 neon_load_reg64(cpu_V1
, rd
+ pass
);
6182 case 10: /* VMLSL */
6183 gen_neon_negl(cpu_V0
, size
);
6185 case 5: case 8: /* VABAL, VMLAL */
6186 gen_neon_addl(size
);
6188 case 9: case 11: /* VQDMLAL, VQDMLSL */
6189 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6191 gen_neon_negl(cpu_V0
, size
);
6193 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6198 neon_store_reg64(cpu_V0
, rd
+ pass
);
6199 } else if (op
== 4 || op
== 6) {
6200 /* Narrowing operation. */
6201 tmp
= tcg_temp_new_i32();
6205 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6208 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6211 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6212 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6219 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6222 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6225 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6226 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6227 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6235 neon_store_reg(rd
, 0, tmp3
);
6236 neon_store_reg(rd
, 1, tmp
);
6239 /* Write back the result. */
6240 neon_store_reg64(cpu_V0
, rd
+ pass
);
6244 /* Two registers and a scalar. NB that for ops of this form
6245 * the ARM ARM labels bit 24 as Q, but it is in our variable
6252 case 1: /* Float VMLA scalar */
6253 case 5: /* Floating point VMLS scalar */
6254 case 9: /* Floating point VMUL scalar */
6259 case 0: /* Integer VMLA scalar */
6260 case 4: /* Integer VMLS scalar */
6261 case 8: /* Integer VMUL scalar */
6262 case 12: /* VQDMULH scalar */
6263 case 13: /* VQRDMULH scalar */
6264 if (u
&& ((rd
| rn
) & 1)) {
6267 tmp
= neon_get_scalar(size
, rm
);
6268 neon_store_scratch(0, tmp
);
6269 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6270 tmp
= neon_load_scratch(0);
6271 tmp2
= neon_load_reg(rn
, pass
);
6274 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6276 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6278 } else if (op
== 13) {
6280 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6282 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6284 } else if (op
& 1) {
6285 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6286 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6287 tcg_temp_free_ptr(fpstatus
);
6290 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6291 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6292 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6296 tcg_temp_free_i32(tmp2
);
6299 tmp2
= neon_load_reg(rd
, pass
);
6302 gen_neon_add(size
, tmp
, tmp2
);
6306 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6307 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6308 tcg_temp_free_ptr(fpstatus
);
6312 gen_neon_rsb(size
, tmp
, tmp2
);
6316 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6317 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6318 tcg_temp_free_ptr(fpstatus
);
6324 tcg_temp_free_i32(tmp2
);
6326 neon_store_reg(rd
, pass
, tmp
);
6329 case 3: /* VQDMLAL scalar */
6330 case 7: /* VQDMLSL scalar */
6331 case 11: /* VQDMULL scalar */
6336 case 2: /* VMLAL sclar */
6337 case 6: /* VMLSL scalar */
6338 case 10: /* VMULL scalar */
6342 tmp2
= neon_get_scalar(size
, rm
);
6343 /* We need a copy of tmp2 because gen_neon_mull
6344 * deletes it during pass 0. */
6345 tmp4
= tcg_temp_new_i32();
6346 tcg_gen_mov_i32(tmp4
, tmp2
);
6347 tmp3
= neon_load_reg(rn
, 1);
6349 for (pass
= 0; pass
< 2; pass
++) {
6351 tmp
= neon_load_reg(rn
, 0);
6356 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6358 neon_load_reg64(cpu_V1
, rd
+ pass
);
6362 gen_neon_negl(cpu_V0
, size
);
6365 gen_neon_addl(size
);
6368 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6370 gen_neon_negl(cpu_V0
, size
);
6372 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6378 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6383 neon_store_reg64(cpu_V0
, rd
+ pass
);
6388 default: /* 14 and 15 are RESERVED */
6392 } else { /* size == 3 */
6395 imm
= (insn
>> 8) & 0xf;
6400 if (q
&& ((rd
| rn
| rm
) & 1)) {
6405 neon_load_reg64(cpu_V0
, rn
);
6407 neon_load_reg64(cpu_V1
, rn
+ 1);
6409 } else if (imm
== 8) {
6410 neon_load_reg64(cpu_V0
, rn
+ 1);
6412 neon_load_reg64(cpu_V1
, rm
);
6415 tmp64
= tcg_temp_new_i64();
6417 neon_load_reg64(cpu_V0
, rn
);
6418 neon_load_reg64(tmp64
, rn
+ 1);
6420 neon_load_reg64(cpu_V0
, rn
+ 1);
6421 neon_load_reg64(tmp64
, rm
);
6423 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6424 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6425 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6427 neon_load_reg64(cpu_V1
, rm
);
6429 neon_load_reg64(cpu_V1
, rm
+ 1);
6432 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6433 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6434 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6435 tcg_temp_free_i64(tmp64
);
6438 neon_load_reg64(cpu_V0
, rn
);
6439 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6440 neon_load_reg64(cpu_V1
, rm
);
6441 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6442 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6444 neon_store_reg64(cpu_V0
, rd
);
6446 neon_store_reg64(cpu_V1
, rd
+ 1);
6448 } else if ((insn
& (1 << 11)) == 0) {
6449 /* Two register misc. */
6450 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6451 size
= (insn
>> 18) & 3;
6452 /* UNDEF for unknown op values and bad op-size combinations */
6453 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6456 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6457 q
&& ((rm
| rd
) & 1)) {
6461 case NEON_2RM_VREV64
:
6462 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6463 tmp
= neon_load_reg(rm
, pass
* 2);
6464 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6466 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6467 case 1: gen_swap_half(tmp
); break;
6468 case 2: /* no-op */ break;
6471 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6473 neon_store_reg(rd
, pass
* 2, tmp2
);
6476 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6477 case 1: gen_swap_half(tmp2
); break;
6480 neon_store_reg(rd
, pass
* 2, tmp2
);
6484 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6485 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6486 for (pass
= 0; pass
< q
+ 1; pass
++) {
6487 tmp
= neon_load_reg(rm
, pass
* 2);
6488 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6489 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6490 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6492 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6493 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6494 case 2: tcg_gen_add_i64(CPU_V001
); break;
6497 if (op
>= NEON_2RM_VPADAL
) {
6499 neon_load_reg64(cpu_V1
, rd
+ pass
);
6500 gen_neon_addl(size
);
6502 neon_store_reg64(cpu_V0
, rd
+ pass
);
6508 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6509 tmp
= neon_load_reg(rm
, n
);
6510 tmp2
= neon_load_reg(rd
, n
+ 1);
6511 neon_store_reg(rm
, n
, tmp2
);
6512 neon_store_reg(rd
, n
+ 1, tmp
);
6519 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6524 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6528 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6529 /* also VQMOVUN; op field and mnemonics don't line up */
6533 TCGV_UNUSED_I32(tmp2
);
6534 for (pass
= 0; pass
< 2; pass
++) {
6535 neon_load_reg64(cpu_V0
, rm
+ pass
);
6536 tmp
= tcg_temp_new_i32();
6537 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6542 neon_store_reg(rd
, 0, tmp2
);
6543 neon_store_reg(rd
, 1, tmp
);
6547 case NEON_2RM_VSHLL
:
6548 if (q
|| (rd
& 1)) {
6551 tmp
= neon_load_reg(rm
, 0);
6552 tmp2
= neon_load_reg(rm
, 1);
6553 for (pass
= 0; pass
< 2; pass
++) {
6556 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6557 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6558 neon_store_reg64(cpu_V0
, rd
+ pass
);
6561 case NEON_2RM_VCVT_F16_F32
:
6562 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6566 tmp
= tcg_temp_new_i32();
6567 tmp2
= tcg_temp_new_i32();
6568 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6569 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6570 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6571 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6572 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6573 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6574 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6575 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6576 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6577 neon_store_reg(rd
, 0, tmp2
);
6578 tmp2
= tcg_temp_new_i32();
6579 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6580 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6581 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6582 neon_store_reg(rd
, 1, tmp2
);
6583 tcg_temp_free_i32(tmp
);
6585 case NEON_2RM_VCVT_F32_F16
:
6586 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6590 tmp3
= tcg_temp_new_i32();
6591 tmp
= neon_load_reg(rm
, 0);
6592 tmp2
= neon_load_reg(rm
, 1);
6593 tcg_gen_ext16u_i32(tmp3
, tmp
);
6594 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6595 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6596 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6597 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6598 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6599 tcg_temp_free_i32(tmp
);
6600 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6601 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6602 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6603 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6604 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6605 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6606 tcg_temp_free_i32(tmp2
);
6607 tcg_temp_free_i32(tmp3
);
6609 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6610 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6611 || ((rm
| rd
) & 1)) {
6614 tmp
= tcg_const_i32(rd
);
6615 tmp2
= tcg_const_i32(rm
);
6617 /* Bit 6 is the lowest opcode bit; it distinguishes between
6618 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6620 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6622 if (op
== NEON_2RM_AESE
) {
6623 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6625 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6627 tcg_temp_free_i32(tmp
);
6628 tcg_temp_free_i32(tmp2
);
6629 tcg_temp_free_i32(tmp3
);
6631 case NEON_2RM_SHA1H
:
6632 if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)
6633 || ((rm
| rd
) & 1)) {
6636 tmp
= tcg_const_i32(rd
);
6637 tmp2
= tcg_const_i32(rm
);
6639 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6641 tcg_temp_free_i32(tmp
);
6642 tcg_temp_free_i32(tmp2
);
6644 case NEON_2RM_SHA1SU1
:
6645 if ((rm
| rd
) & 1) {
6648 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6650 if (!arm_feature(env
, ARM_FEATURE_V8_SHA256
)) {
6653 } else if (!arm_feature(env
, ARM_FEATURE_V8_SHA1
)) {
6656 tmp
= tcg_const_i32(rd
);
6657 tmp2
= tcg_const_i32(rm
);
6659 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6661 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6663 tcg_temp_free_i32(tmp
);
6664 tcg_temp_free_i32(tmp2
);
6668 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6669 if (neon_2rm_is_float_op(op
)) {
6670 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6671 neon_reg_offset(rm
, pass
));
6672 TCGV_UNUSED_I32(tmp
);
6674 tmp
= neon_load_reg(rm
, pass
);
6677 case NEON_2RM_VREV32
:
6679 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6680 case 1: gen_swap_half(tmp
); break;
6684 case NEON_2RM_VREV16
:
6689 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6690 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6691 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6697 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6698 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6699 case 2: gen_helper_clz(tmp
, tmp
); break;
6704 gen_helper_neon_cnt_u8(tmp
, tmp
);
6707 tcg_gen_not_i32(tmp
, tmp
);
6709 case NEON_2RM_VQABS
:
6712 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6715 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6718 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6723 case NEON_2RM_VQNEG
:
6726 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6729 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6732 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6737 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6738 tmp2
= tcg_const_i32(0);
6740 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6741 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6742 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6745 tcg_temp_free_i32(tmp2
);
6746 if (op
== NEON_2RM_VCLE0
) {
6747 tcg_gen_not_i32(tmp
, tmp
);
6750 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6751 tmp2
= tcg_const_i32(0);
6753 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6754 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6755 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6758 tcg_temp_free_i32(tmp2
);
6759 if (op
== NEON_2RM_VCLT0
) {
6760 tcg_gen_not_i32(tmp
, tmp
);
6763 case NEON_2RM_VCEQ0
:
6764 tmp2
= tcg_const_i32(0);
6766 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6767 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6768 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6771 tcg_temp_free_i32(tmp2
);
6775 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6776 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6777 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6782 tmp2
= tcg_const_i32(0);
6783 gen_neon_rsb(size
, tmp
, tmp2
);
6784 tcg_temp_free_i32(tmp2
);
6786 case NEON_2RM_VCGT0_F
:
6788 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6789 tmp2
= tcg_const_i32(0);
6790 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6791 tcg_temp_free_i32(tmp2
);
6792 tcg_temp_free_ptr(fpstatus
);
6795 case NEON_2RM_VCGE0_F
:
6797 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6798 tmp2
= tcg_const_i32(0);
6799 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6800 tcg_temp_free_i32(tmp2
);
6801 tcg_temp_free_ptr(fpstatus
);
6804 case NEON_2RM_VCEQ0_F
:
6806 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6807 tmp2
= tcg_const_i32(0);
6808 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6809 tcg_temp_free_i32(tmp2
);
6810 tcg_temp_free_ptr(fpstatus
);
6813 case NEON_2RM_VCLE0_F
:
6815 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6816 tmp2
= tcg_const_i32(0);
6817 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6818 tcg_temp_free_i32(tmp2
);
6819 tcg_temp_free_ptr(fpstatus
);
6822 case NEON_2RM_VCLT0_F
:
6824 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6825 tmp2
= tcg_const_i32(0);
6826 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6827 tcg_temp_free_i32(tmp2
);
6828 tcg_temp_free_ptr(fpstatus
);
6831 case NEON_2RM_VABS_F
:
6834 case NEON_2RM_VNEG_F
:
6838 tmp2
= neon_load_reg(rd
, pass
);
6839 neon_store_reg(rm
, pass
, tmp2
);
6842 tmp2
= neon_load_reg(rd
, pass
);
6844 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6845 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6848 neon_store_reg(rm
, pass
, tmp2
);
6850 case NEON_2RM_VRINTN
:
6851 case NEON_2RM_VRINTA
:
6852 case NEON_2RM_VRINTM
:
6853 case NEON_2RM_VRINTP
:
6854 case NEON_2RM_VRINTZ
:
6857 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6860 if (op
== NEON_2RM_VRINTZ
) {
6861 rmode
= FPROUNDING_ZERO
;
6863 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6866 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6867 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6869 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6870 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6872 tcg_temp_free_ptr(fpstatus
);
6873 tcg_temp_free_i32(tcg_rmode
);
6876 case NEON_2RM_VRINTX
:
6878 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6879 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6880 tcg_temp_free_ptr(fpstatus
);
6883 case NEON_2RM_VCVTAU
:
6884 case NEON_2RM_VCVTAS
:
6885 case NEON_2RM_VCVTNU
:
6886 case NEON_2RM_VCVTNS
:
6887 case NEON_2RM_VCVTPU
:
6888 case NEON_2RM_VCVTPS
:
6889 case NEON_2RM_VCVTMU
:
6890 case NEON_2RM_VCVTMS
:
6892 bool is_signed
= !extract32(insn
, 7, 1);
6893 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6894 TCGv_i32 tcg_rmode
, tcg_shift
;
6895 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6897 tcg_shift
= tcg_const_i32(0);
6898 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6899 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6903 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6906 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6910 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6912 tcg_temp_free_i32(tcg_rmode
);
6913 tcg_temp_free_i32(tcg_shift
);
6914 tcg_temp_free_ptr(fpst
);
6917 case NEON_2RM_VRECPE
:
6919 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6920 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6921 tcg_temp_free_ptr(fpstatus
);
6924 case NEON_2RM_VRSQRTE
:
6926 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6927 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6928 tcg_temp_free_ptr(fpstatus
);
6931 case NEON_2RM_VRECPE_F
:
6933 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6934 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6935 tcg_temp_free_ptr(fpstatus
);
6938 case NEON_2RM_VRSQRTE_F
:
6940 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6941 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6942 tcg_temp_free_ptr(fpstatus
);
6945 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6948 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6951 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6952 gen_vfp_tosiz(0, 1);
6954 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6955 gen_vfp_touiz(0, 1);
6958 /* Reserved op values were caught by the
6959 * neon_2rm_sizes[] check earlier.
6963 if (neon_2rm_is_float_op(op
)) {
6964 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6965 neon_reg_offset(rd
, pass
));
6967 neon_store_reg(rd
, pass
, tmp
);
6972 } else if ((insn
& (1 << 10)) == 0) {
6974 int n
= ((insn
>> 8) & 3) + 1;
6975 if ((rn
+ n
) > 32) {
6976 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6977 * helper function running off the end of the register file.
6982 if (insn
& (1 << 6)) {
6983 tmp
= neon_load_reg(rd
, 0);
6985 tmp
= tcg_temp_new_i32();
6986 tcg_gen_movi_i32(tmp
, 0);
6988 tmp2
= neon_load_reg(rm
, 0);
6989 tmp4
= tcg_const_i32(rn
);
6990 tmp5
= tcg_const_i32(n
);
6991 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6992 tcg_temp_free_i32(tmp
);
6993 if (insn
& (1 << 6)) {
6994 tmp
= neon_load_reg(rd
, 1);
6996 tmp
= tcg_temp_new_i32();
6997 tcg_gen_movi_i32(tmp
, 0);
6999 tmp3
= neon_load_reg(rm
, 1);
7000 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7001 tcg_temp_free_i32(tmp5
);
7002 tcg_temp_free_i32(tmp4
);
7003 neon_store_reg(rd
, 0, tmp2
);
7004 neon_store_reg(rd
, 1, tmp3
);
7005 tcg_temp_free_i32(tmp
);
7006 } else if ((insn
& 0x380) == 0) {
7008 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7011 if (insn
& (1 << 19)) {
7012 tmp
= neon_load_reg(rm
, 1);
7014 tmp
= neon_load_reg(rm
, 0);
7016 if (insn
& (1 << 16)) {
7017 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7018 } else if (insn
& (1 << 17)) {
7019 if ((insn
>> 18) & 1)
7020 gen_neon_dup_high16(tmp
);
7022 gen_neon_dup_low16(tmp
);
7024 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7025 tmp2
= tcg_temp_new_i32();
7026 tcg_gen_mov_i32(tmp2
, tmp
);
7027 neon_store_reg(rd
, pass
, tmp2
);
7029 tcg_temp_free_i32(tmp
);
7038 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
7040 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7041 const ARMCPRegInfo
*ri
;
7043 cpnum
= (insn
>> 8) & 0xf;
7045 /* First check for coprocessor space used for XScale/iwMMXt insns */
7046 if (arm_feature(env
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7047 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7050 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7051 return disas_iwmmxt_insn(env
, s
, insn
);
7052 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
7053 return disas_dsp_insn(env
, s
, insn
);
7058 /* Otherwise treat as a generic register access */
7059 is64
= (insn
& (1 << 25)) == 0;
7060 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7068 opc1
= (insn
>> 4) & 0xf;
7070 rt2
= (insn
>> 16) & 0xf;
7072 crn
= (insn
>> 16) & 0xf;
7073 opc1
= (insn
>> 21) & 7;
7074 opc2
= (insn
>> 5) & 7;
7077 isread
= (insn
>> 20) & 1;
7078 rt
= (insn
>> 12) & 0xf;
7080 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7081 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
7083 /* Check access permissions */
7084 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7089 (arm_feature(env
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7090 /* Emit code to perform further access permissions checks at
7091 * runtime; this may result in an exception.
7092 * Note that on XScale all cp0..c13 registers do an access check
7093 * call in order to handle c15_cpar.
7099 /* Note that since we are an implementation which takes an
7100 * exception on a trapped conditional instruction only if the
7101 * instruction passes its condition code check, we can take
7102 * advantage of the clause in the ARM ARM that allows us to set
7103 * the COND field in the instruction to 0xE in all cases.
7104 * We could fish the actual condition out of the insn (ARM)
7105 * or the condexec bits (Thumb) but it isn't necessary.
7110 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7113 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7114 rt
, isread
, s
->thumb
);
7119 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7122 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7123 rt
, isread
, s
->thumb
);
7127 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7128 * so this can only happen if this is an ARMv7 or earlier CPU,
7129 * in which case the syndrome information won't actually be
7132 assert(!arm_feature(env
, ARM_FEATURE_V8
));
7133 syndrome
= syn_uncategorized();
7137 gen_set_pc_im(s
, s
->pc
);
7138 tmpptr
= tcg_const_ptr(ri
);
7139 tcg_syn
= tcg_const_i32(syndrome
);
7140 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7141 tcg_temp_free_ptr(tmpptr
);
7142 tcg_temp_free_i32(tcg_syn
);
7145 /* Handle special cases first */
7146 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7153 gen_set_pc_im(s
, s
->pc
);
7154 s
->is_jmp
= DISAS_WFI
;
7160 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7169 if (ri
->type
& ARM_CP_CONST
) {
7170 tmp64
= tcg_const_i64(ri
->resetvalue
);
7171 } else if (ri
->readfn
) {
7173 tmp64
= tcg_temp_new_i64();
7174 tmpptr
= tcg_const_ptr(ri
);
7175 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7176 tcg_temp_free_ptr(tmpptr
);
7178 tmp64
= tcg_temp_new_i64();
7179 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7181 tmp
= tcg_temp_new_i32();
7182 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7183 store_reg(s
, rt
, tmp
);
7184 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7185 tmp
= tcg_temp_new_i32();
7186 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7187 tcg_temp_free_i64(tmp64
);
7188 store_reg(s
, rt2
, tmp
);
7191 if (ri
->type
& ARM_CP_CONST
) {
7192 tmp
= tcg_const_i32(ri
->resetvalue
);
7193 } else if (ri
->readfn
) {
7195 tmp
= tcg_temp_new_i32();
7196 tmpptr
= tcg_const_ptr(ri
);
7197 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7198 tcg_temp_free_ptr(tmpptr
);
7200 tmp
= load_cpu_offset(ri
->fieldoffset
);
7203 /* Destination register of r15 for 32 bit loads sets
7204 * the condition codes from the high 4 bits of the value
7207 tcg_temp_free_i32(tmp
);
7209 store_reg(s
, rt
, tmp
);
7214 if (ri
->type
& ARM_CP_CONST
) {
7215 /* If not forbidden by access permissions, treat as WI */
7220 TCGv_i32 tmplo
, tmphi
;
7221 TCGv_i64 tmp64
= tcg_temp_new_i64();
7222 tmplo
= load_reg(s
, rt
);
7223 tmphi
= load_reg(s
, rt2
);
7224 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7225 tcg_temp_free_i32(tmplo
);
7226 tcg_temp_free_i32(tmphi
);
7228 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7229 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7230 tcg_temp_free_ptr(tmpptr
);
7232 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7234 tcg_temp_free_i64(tmp64
);
7239 tmp
= load_reg(s
, rt
);
7240 tmpptr
= tcg_const_ptr(ri
);
7241 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7242 tcg_temp_free_ptr(tmpptr
);
7243 tcg_temp_free_i32(tmp
);
7245 TCGv_i32 tmp
= load_reg(s
, rt
);
7246 store_cpu_offset(tmp
, ri
->fieldoffset
);
7251 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
7252 /* I/O operations must end the TB here (whether read or write) */
7255 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7256 /* We default to ending the TB on a coprocessor register write,
7257 * but allow this to be suppressed by the register definition
7258 * (usually only necessary to work around guest bugs).
7266 /* Unknown register; this might be a guest error or a QEMU
7267 * unimplemented feature.
7270 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7271 "64 bit system register cp:%d opc1: %d crm:%d\n",
7272 isread
? "read" : "write", cpnum
, opc1
, crm
);
7274 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7275 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7276 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7283 /* Store a 64-bit value to a register pair. Clobbers val. */
7284 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7287 tmp
= tcg_temp_new_i32();
7288 tcg_gen_trunc_i64_i32(tmp
, val
);
7289 store_reg(s
, rlow
, tmp
);
7290 tmp
= tcg_temp_new_i32();
7291 tcg_gen_shri_i64(val
, val
, 32);
7292 tcg_gen_trunc_i64_i32(tmp
, val
);
7293 store_reg(s
, rhigh
, tmp
);
7296 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7297 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7302 /* Load value and extend to 64 bits. */
7303 tmp
= tcg_temp_new_i64();
7304 tmp2
= load_reg(s
, rlow
);
7305 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7306 tcg_temp_free_i32(tmp2
);
7307 tcg_gen_add_i64(val
, val
, tmp
);
7308 tcg_temp_free_i64(tmp
);
7311 /* load and add a 64-bit value from a register pair. */
7312 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7318 /* Load 64-bit value rd:rn. */
7319 tmpl
= load_reg(s
, rlow
);
7320 tmph
= load_reg(s
, rhigh
);
7321 tmp
= tcg_temp_new_i64();
7322 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7323 tcg_temp_free_i32(tmpl
);
7324 tcg_temp_free_i32(tmph
);
7325 tcg_gen_add_i64(val
, val
, tmp
);
7326 tcg_temp_free_i64(tmp
);
7329 /* Set N and Z flags from hi|lo. */
7330 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7332 tcg_gen_mov_i32(cpu_NF
, hi
);
7333 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7336 /* Load/Store exclusive instructions are implemented by remembering
7337 the value/address loaded, and seeing if these are the same
7338 when the store is performed. This should be sufficient to implement
7339 the architecturally mandated semantics, and avoids having to monitor
7342 In system emulation mode only one CPU will be running at once, so
7343 this sequence is effectively atomic. In user emulation mode we
7344 throw an exception and handle the atomic operation elsewhere. */
7345 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7346 TCGv_i32 addr
, int size
)
7348 TCGv_i32 tmp
= tcg_temp_new_i32();
7354 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7357 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7361 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7368 TCGv_i32 tmp2
= tcg_temp_new_i32();
7369 TCGv_i32 tmp3
= tcg_temp_new_i32();
7371 tcg_gen_addi_i32(tmp2
, addr
, 4);
7372 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7373 tcg_temp_free_i32(tmp2
);
7374 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7375 store_reg(s
, rt2
, tmp3
);
7377 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7380 store_reg(s
, rt
, tmp
);
7381 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7384 static void gen_clrex(DisasContext
*s
)
7386 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7389 #ifdef CONFIG_USER_ONLY
7390 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7391 TCGv_i32 addr
, int size
)
7393 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7394 tcg_gen_movi_i32(cpu_exclusive_info
,
7395 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7396 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7399 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7400 TCGv_i32 addr
, int size
)
7403 TCGv_i64 val64
, extaddr
;
7407 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7413 fail_label
= gen_new_label();
7414 done_label
= gen_new_label();
7415 extaddr
= tcg_temp_new_i64();
7416 tcg_gen_extu_i32_i64(extaddr
, addr
);
7417 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7418 tcg_temp_free_i64(extaddr
);
7420 tmp
= tcg_temp_new_i32();
7423 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7426 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7430 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7436 val64
= tcg_temp_new_i64();
7438 TCGv_i32 tmp2
= tcg_temp_new_i32();
7439 TCGv_i32 tmp3
= tcg_temp_new_i32();
7440 tcg_gen_addi_i32(tmp2
, addr
, 4);
7441 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7442 tcg_temp_free_i32(tmp2
);
7443 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7444 tcg_temp_free_i32(tmp3
);
7446 tcg_gen_extu_i32_i64(val64
, tmp
);
7448 tcg_temp_free_i32(tmp
);
7450 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7451 tcg_temp_free_i64(val64
);
7453 tmp
= load_reg(s
, rt
);
7456 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7459 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7463 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7468 tcg_temp_free_i32(tmp
);
7470 tcg_gen_addi_i32(addr
, addr
, 4);
7471 tmp
= load_reg(s
, rt2
);
7472 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7473 tcg_temp_free_i32(tmp
);
7475 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7476 tcg_gen_br(done_label
);
7477 gen_set_label(fail_label
);
7478 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7479 gen_set_label(done_label
);
7480 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7487 * @mode: mode field from insn (which stack to store to)
7488 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7489 * @writeback: true if writeback bit set
7491 * Generate code for the SRS (Store Return State) insn.
7493 static void gen_srs(DisasContext
*s
,
7494 uint32_t mode
, uint32_t amode
, bool writeback
)
7497 TCGv_i32 addr
= tcg_temp_new_i32();
7498 TCGv_i32 tmp
= tcg_const_i32(mode
);
7499 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7500 tcg_temp_free_i32(tmp
);
7517 tcg_gen_addi_i32(addr
, addr
, offset
);
7518 tmp
= load_reg(s
, 14);
7519 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7520 tcg_temp_free_i32(tmp
);
7521 tmp
= load_cpu_field(spsr
);
7522 tcg_gen_addi_i32(addr
, addr
, 4);
7523 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7524 tcg_temp_free_i32(tmp
);
7542 tcg_gen_addi_i32(addr
, addr
, offset
);
7543 tmp
= tcg_const_i32(mode
);
7544 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7545 tcg_temp_free_i32(tmp
);
7547 tcg_temp_free_i32(addr
);
7550 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7552 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7559 insn
= arm_ldl_code(env
, s
->pc
, s
->sctlr_b
);
7562 /* M variants do not implement ARM mode. */
7567 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7568 * choose to UNDEF. In ARMv5 and above the space is used
7569 * for miscellaneous unconditional instructions.
7573 /* Unconditional instructions. */
7574 if (((insn
>> 25) & 7) == 1) {
7575 /* NEON Data processing. */
7576 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7579 if (disas_neon_data_insn(env
, s
, insn
))
7583 if ((insn
& 0x0f100000) == 0x04000000) {
7584 /* NEON load/store. */
7585 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7588 if (disas_neon_ls_insn(env
, s
, insn
))
7592 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7594 if (disas_vfp_insn(env
, s
, insn
)) {
7599 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7600 ((insn
& 0x0f30f010) == 0x0710f000)) {
7601 if ((insn
& (1 << 22)) == 0) {
7603 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7607 /* Otherwise PLD; v5TE+ */
7611 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7612 ((insn
& 0x0f70f010) == 0x0650f000)) {
7614 return; /* PLI; V7 */
7616 if (((insn
& 0x0f700000) == 0x04100000) ||
7617 ((insn
& 0x0f700010) == 0x06100000)) {
7618 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7621 return; /* v7MP: Unallocated memory hint: must NOP */
7624 if ((insn
& 0x0ffffdff) == 0x01010000) {
7627 if (((insn
>> 9) & 1) != s
->cpsr_e
) {
7628 /* Dynamic endianness switching not implemented. */
7629 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7633 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7634 switch ((insn
>> 4) & 0xf) {
7643 /* We don't emulate caches so these are a no-op. */
7648 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7654 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7656 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7662 rn
= (insn
>> 16) & 0xf;
7663 addr
= load_reg(s
, rn
);
7664 i
= (insn
>> 23) & 3;
7666 case 0: offset
= -4; break; /* DA */
7667 case 1: offset
= 0; break; /* IA */
7668 case 2: offset
= -8; break; /* DB */
7669 case 3: offset
= 4; break; /* IB */
7673 tcg_gen_addi_i32(addr
, addr
, offset
);
7674 /* Load PC into tmp and CPSR into tmp2. */
7675 tmp
= tcg_temp_new_i32();
7676 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7677 tcg_gen_addi_i32(addr
, addr
, 4);
7678 tmp2
= tcg_temp_new_i32();
7679 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
7680 if (insn
& (1 << 21)) {
7681 /* Base writeback. */
7683 case 0: offset
= -8; break;
7684 case 1: offset
= 4; break;
7685 case 2: offset
= -4; break;
7686 case 3: offset
= 0; break;
7690 tcg_gen_addi_i32(addr
, addr
, offset
);
7691 store_reg(s
, rn
, addr
);
7693 tcg_temp_free_i32(addr
);
7695 gen_rfe(s
, tmp
, tmp2
);
7697 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7698 /* branch link and change to thumb (blx <offset>) */
7701 val
= (uint32_t)s
->pc
;
7702 tmp
= tcg_temp_new_i32();
7703 tcg_gen_movi_i32(tmp
, val
);
7704 store_reg(s
, 14, tmp
);
7705 /* Sign-extend the 24-bit offset */
7706 offset
= (((int32_t)insn
) << 8) >> 8;
7707 /* offset * 4 + bit24 * 2 + (thumb bit) */
7708 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7709 /* pipeline offset */
7711 /* protected by ARCH(5); above, near the start of uncond block */
7714 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7715 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7716 /* iWMMXt register transfer. */
7717 if (extract32(s
->c15_cpar
, 1, 1)) {
7718 if (!disas_iwmmxt_insn(env
, s
, insn
)) {
7723 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7724 /* Coprocessor double register transfer. */
7726 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7727 /* Additional coprocessor register transfer. */
7728 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7731 /* cps (privileged) */
7735 if (insn
& (1 << 19)) {
7736 if (insn
& (1 << 8))
7738 if (insn
& (1 << 7))
7740 if (insn
& (1 << 6))
7742 if (insn
& (1 << 18))
7745 if (insn
& (1 << 17)) {
7747 val
|= (insn
& 0x1f);
7750 gen_set_psr_im(s
, mask
, 0, val
);
7757 /* if not always execute, we generate a conditional jump to
7759 s
->condlabel
= gen_new_label();
7760 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7763 if ((insn
& 0x0f900000) == 0x03000000) {
7764 if ((insn
& (1 << 21)) == 0) {
7766 rd
= (insn
>> 12) & 0xf;
7767 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7768 if ((insn
& (1 << 22)) == 0) {
7770 tmp
= tcg_temp_new_i32();
7771 tcg_gen_movi_i32(tmp
, val
);
7774 tmp
= load_reg(s
, rd
);
7775 tcg_gen_ext16u_i32(tmp
, tmp
);
7776 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7778 store_reg(s
, rd
, tmp
);
7780 if (((insn
>> 12) & 0xf) != 0xf)
7782 if (((insn
>> 16) & 0xf) == 0) {
7783 gen_nop_hint(s
, insn
& 0xff);
7785 /* CPSR = immediate */
7787 shift
= ((insn
>> 8) & 0xf) * 2;
7789 val
= (val
>> shift
) | (val
<< (32 - shift
));
7790 i
= ((insn
& (1 << 22)) != 0);
7791 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7795 } else if ((insn
& 0x0f900000) == 0x01000000
7796 && (insn
& 0x00000090) != 0x00000090) {
7797 /* miscellaneous instructions */
7798 op1
= (insn
>> 21) & 3;
7799 sh
= (insn
>> 4) & 0xf;
7802 case 0x0: /* move program status register */
7805 tmp
= load_reg(s
, rm
);
7806 i
= ((op1
& 2) != 0);
7807 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7811 rd
= (insn
>> 12) & 0xf;
7815 tmp
= load_cpu_field(spsr
);
7817 tmp
= tcg_temp_new_i32();
7818 gen_helper_cpsr_read(tmp
, cpu_env
);
7820 store_reg(s
, rd
, tmp
);
7825 /* branch/exchange thumb (bx). */
7827 tmp
= load_reg(s
, rm
);
7829 } else if (op1
== 3) {
7832 rd
= (insn
>> 12) & 0xf;
7833 tmp
= load_reg(s
, rm
);
7834 gen_helper_clz(tmp
, tmp
);
7835 store_reg(s
, rd
, tmp
);
7843 /* Trivial implementation equivalent to bx. */
7844 tmp
= load_reg(s
, rm
);
7855 /* branch link/exchange thumb (blx) */
7856 tmp
= load_reg(s
, rm
);
7857 tmp2
= tcg_temp_new_i32();
7858 tcg_gen_movi_i32(tmp2
, s
->pc
);
7859 store_reg(s
, 14, tmp2
);
7865 uint32_t c
= extract32(insn
, 8, 4);
7867 /* Check this CPU supports ARMv8 CRC instructions.
7868 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7869 * Bits 8, 10 and 11 should be zero.
7871 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7876 rn
= extract32(insn
, 16, 4);
7877 rd
= extract32(insn
, 12, 4);
7879 tmp
= load_reg(s
, rn
);
7880 tmp2
= load_reg(s
, rm
);
7882 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7883 } else if (op1
== 1) {
7884 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7886 tmp3
= tcg_const_i32(1 << op1
);
7888 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7890 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7892 tcg_temp_free_i32(tmp2
);
7893 tcg_temp_free_i32(tmp3
);
7894 store_reg(s
, rd
, tmp
);
7897 case 0x5: /* saturating add/subtract */
7899 rd
= (insn
>> 12) & 0xf;
7900 rn
= (insn
>> 16) & 0xf;
7901 tmp
= load_reg(s
, rm
);
7902 tmp2
= load_reg(s
, rn
);
7904 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7906 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7908 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7909 tcg_temp_free_i32(tmp2
);
7910 store_reg(s
, rd
, tmp
);
7914 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7919 gen_exception_insn(s
, 4, EXCP_BKPT
,
7920 syn_aa32_bkpt(imm16
, false));
7923 /* Hypervisor call (v7) */
7931 /* Secure monitor call (v6+) */
7943 case 0x8: /* signed multiply */
7948 rs
= (insn
>> 8) & 0xf;
7949 rn
= (insn
>> 12) & 0xf;
7950 rd
= (insn
>> 16) & 0xf;
7952 /* (32 * 16) >> 16 */
7953 tmp
= load_reg(s
, rm
);
7954 tmp2
= load_reg(s
, rs
);
7956 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7959 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7960 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7961 tmp
= tcg_temp_new_i32();
7962 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7963 tcg_temp_free_i64(tmp64
);
7964 if ((sh
& 2) == 0) {
7965 tmp2
= load_reg(s
, rn
);
7966 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7967 tcg_temp_free_i32(tmp2
);
7969 store_reg(s
, rd
, tmp
);
7972 tmp
= load_reg(s
, rm
);
7973 tmp2
= load_reg(s
, rs
);
7974 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7975 tcg_temp_free_i32(tmp2
);
7977 tmp64
= tcg_temp_new_i64();
7978 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7979 tcg_temp_free_i32(tmp
);
7980 gen_addq(s
, tmp64
, rn
, rd
);
7981 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7982 tcg_temp_free_i64(tmp64
);
7985 tmp2
= load_reg(s
, rn
);
7986 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7987 tcg_temp_free_i32(tmp2
);
7989 store_reg(s
, rd
, tmp
);
7996 } else if (((insn
& 0x0e000000) == 0 &&
7997 (insn
& 0x00000090) != 0x90) ||
7998 ((insn
& 0x0e000000) == (1 << 25))) {
7999 int set_cc
, logic_cc
, shiftop
;
8001 op1
= (insn
>> 21) & 0xf;
8002 set_cc
= (insn
>> 20) & 1;
8003 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8005 /* data processing instruction */
8006 if (insn
& (1 << 25)) {
8007 /* immediate operand */
8009 shift
= ((insn
>> 8) & 0xf) * 2;
8011 val
= (val
>> shift
) | (val
<< (32 - shift
));
8013 tmp2
= tcg_temp_new_i32();
8014 tcg_gen_movi_i32(tmp2
, val
);
8015 if (logic_cc
&& shift
) {
8016 gen_set_CF_bit31(tmp2
);
8021 tmp2
= load_reg(s
, rm
);
8022 shiftop
= (insn
>> 5) & 3;
8023 if (!(insn
& (1 << 4))) {
8024 shift
= (insn
>> 7) & 0x1f;
8025 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8027 rs
= (insn
>> 8) & 0xf;
8028 tmp
= load_reg(s
, rs
);
8029 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8032 if (op1
!= 0x0f && op1
!= 0x0d) {
8033 rn
= (insn
>> 16) & 0xf;
8034 tmp
= load_reg(s
, rn
);
8036 TCGV_UNUSED_I32(tmp
);
8038 rd
= (insn
>> 12) & 0xf;
8041 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8045 store_reg_bx(env
, s
, rd
, tmp
);
8048 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8052 store_reg_bx(env
, s
, rd
, tmp
);
8055 if (set_cc
&& rd
== 15) {
8056 /* SUBS r15, ... is used for exception return. */
8060 gen_sub_CC(tmp
, tmp
, tmp2
);
8061 gen_exception_return(s
, tmp
);
8064 gen_sub_CC(tmp
, tmp
, tmp2
);
8066 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8068 store_reg_bx(env
, s
, rd
, tmp
);
8073 gen_sub_CC(tmp
, tmp2
, tmp
);
8075 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8077 store_reg_bx(env
, s
, rd
, tmp
);
8081 gen_add_CC(tmp
, tmp
, tmp2
);
8083 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8085 store_reg_bx(env
, s
, rd
, tmp
);
8089 gen_adc_CC(tmp
, tmp
, tmp2
);
8091 gen_add_carry(tmp
, tmp
, tmp2
);
8093 store_reg_bx(env
, s
, rd
, tmp
);
8097 gen_sbc_CC(tmp
, tmp
, tmp2
);
8099 gen_sub_carry(tmp
, tmp
, tmp2
);
8101 store_reg_bx(env
, s
, rd
, tmp
);
8105 gen_sbc_CC(tmp
, tmp2
, tmp
);
8107 gen_sub_carry(tmp
, tmp2
, tmp
);
8109 store_reg_bx(env
, s
, rd
, tmp
);
8113 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8116 tcg_temp_free_i32(tmp
);
8120 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8123 tcg_temp_free_i32(tmp
);
8127 gen_sub_CC(tmp
, tmp
, tmp2
);
8129 tcg_temp_free_i32(tmp
);
8133 gen_add_CC(tmp
, tmp
, tmp2
);
8135 tcg_temp_free_i32(tmp
);
8138 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8142 store_reg_bx(env
, s
, rd
, tmp
);
8145 if (logic_cc
&& rd
== 15) {
8146 /* MOVS r15, ... is used for exception return. */
8150 gen_exception_return(s
, tmp2
);
8155 store_reg_bx(env
, s
, rd
, tmp2
);
8159 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8163 store_reg_bx(env
, s
, rd
, tmp
);
8167 tcg_gen_not_i32(tmp2
, tmp2
);
8171 store_reg_bx(env
, s
, rd
, tmp2
);
8174 if (op1
!= 0x0f && op1
!= 0x0d) {
8175 tcg_temp_free_i32(tmp2
);
8178 /* other instructions */
8179 op1
= (insn
>> 24) & 0xf;
8183 /* multiplies, extra load/stores */
8184 sh
= (insn
>> 5) & 3;
8187 rd
= (insn
>> 16) & 0xf;
8188 rn
= (insn
>> 12) & 0xf;
8189 rs
= (insn
>> 8) & 0xf;
8191 op1
= (insn
>> 20) & 0xf;
8193 case 0: case 1: case 2: case 3: case 6:
8195 tmp
= load_reg(s
, rs
);
8196 tmp2
= load_reg(s
, rm
);
8197 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8198 tcg_temp_free_i32(tmp2
);
8199 if (insn
& (1 << 22)) {
8200 /* Subtract (mls) */
8202 tmp2
= load_reg(s
, rn
);
8203 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8204 tcg_temp_free_i32(tmp2
);
8205 } else if (insn
& (1 << 21)) {
8207 tmp2
= load_reg(s
, rn
);
8208 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8209 tcg_temp_free_i32(tmp2
);
8211 if (insn
& (1 << 20))
8213 store_reg(s
, rd
, tmp
);
8216 /* 64 bit mul double accumulate (UMAAL) */
8218 tmp
= load_reg(s
, rs
);
8219 tmp2
= load_reg(s
, rm
);
8220 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8221 gen_addq_lo(s
, tmp64
, rn
);
8222 gen_addq_lo(s
, tmp64
, rd
);
8223 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8224 tcg_temp_free_i64(tmp64
);
8226 case 8: case 9: case 10: case 11:
8227 case 12: case 13: case 14: case 15:
8228 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8229 tmp
= load_reg(s
, rs
);
8230 tmp2
= load_reg(s
, rm
);
8231 if (insn
& (1 << 22)) {
8232 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8234 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8236 if (insn
& (1 << 21)) { /* mult accumulate */
8237 TCGv_i32 al
= load_reg(s
, rn
);
8238 TCGv_i32 ah
= load_reg(s
, rd
);
8239 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8240 tcg_temp_free_i32(al
);
8241 tcg_temp_free_i32(ah
);
8243 if (insn
& (1 << 20)) {
8244 gen_logicq_cc(tmp
, tmp2
);
8246 store_reg(s
, rn
, tmp
);
8247 store_reg(s
, rd
, tmp2
);
8253 rn
= (insn
>> 16) & 0xf;
8254 rd
= (insn
>> 12) & 0xf;
8255 if (insn
& (1 << 23)) {
8256 /* load/store exclusive */
8257 int op2
= (insn
>> 8) & 3;
8258 op1
= (insn
>> 21) & 0x3;
8261 case 0: /* lda/stl */
8267 case 1: /* reserved */
8269 case 2: /* ldaex/stlex */
8272 case 3: /* ldrex/strex */
8281 addr
= tcg_temp_local_new_i32();
8282 load_reg_var(s
, addr
, rn
);
8284 /* Since the emulation does not have barriers,
8285 the acquire/release semantics need no special
8288 if (insn
& (1 << 20)) {
8289 tmp
= tcg_temp_new_i32();
8292 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8295 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
8298 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8303 store_reg(s
, rd
, tmp
);
8306 tmp
= load_reg(s
, rm
);
8309 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8312 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8315 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8320 tcg_temp_free_i32(tmp
);
8322 } else if (insn
& (1 << 20)) {
8325 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8327 case 1: /* ldrexd */
8328 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8330 case 2: /* ldrexb */
8331 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8333 case 3: /* ldrexh */
8334 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8343 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8345 case 1: /* strexd */
8346 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8348 case 2: /* strexb */
8349 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8351 case 3: /* strexh */
8352 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8358 tcg_temp_free_i32(addr
);
8360 /* SWP instruction */
8363 /* ??? This is not really atomic. However we know
8364 we never have multiple CPUs running in parallel,
8365 so it is good enough. */
8366 addr
= load_reg(s
, rn
);
8367 tmp
= load_reg(s
, rm
);
8368 tmp2
= tcg_temp_new_i32();
8369 if (insn
& (1 << 22)) {
8370 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8371 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8373 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8374 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8376 tcg_temp_free_i32(tmp
);
8377 tcg_temp_free_i32(addr
);
8378 store_reg(s
, rd
, tmp2
);
8384 /* Misc load/store */
8385 rn
= (insn
>> 16) & 0xf;
8386 rd
= (insn
>> 12) & 0xf;
8387 addr
= load_reg(s
, rn
);
8388 if (insn
& (1 << 24))
8389 gen_add_datah_offset(s
, insn
, 0, addr
);
8391 if (insn
& (1 << 20)) {
8393 tmp
= tcg_temp_new_i32();
8396 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8399 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8403 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8407 } else if (sh
& 2) {
8412 tmp
= load_reg(s
, rd
);
8413 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8414 tcg_temp_free_i32(tmp
);
8415 tcg_gen_addi_i32(addr
, addr
, 4);
8416 tmp
= load_reg(s
, rd
+ 1);
8417 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8418 tcg_temp_free_i32(tmp
);
8422 tmp
= tcg_temp_new_i32();
8423 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8424 store_reg(s
, rd
, tmp
);
8425 tcg_gen_addi_i32(addr
, addr
, 4);
8426 tmp
= tcg_temp_new_i32();
8427 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8431 address_offset
= -4;
8434 tmp
= load_reg(s
, rd
);
8435 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8436 tcg_temp_free_i32(tmp
);
8439 /* Perform base writeback before the loaded value to
8440 ensure correct behavior with overlapping index registers.
8441 ldrd with base writeback is is undefined if the
8442 destination and index registers overlap. */
8443 if (!(insn
& (1 << 24))) {
8444 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8445 store_reg(s
, rn
, addr
);
8446 } else if (insn
& (1 << 21)) {
8448 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8449 store_reg(s
, rn
, addr
);
8451 tcg_temp_free_i32(addr
);
8454 /* Complete the load. */
8455 store_reg(s
, rd
, tmp
);
8464 if (insn
& (1 << 4)) {
8466 /* Armv6 Media instructions. */
8468 rn
= (insn
>> 16) & 0xf;
8469 rd
= (insn
>> 12) & 0xf;
8470 rs
= (insn
>> 8) & 0xf;
8471 switch ((insn
>> 23) & 3) {
8472 case 0: /* Parallel add/subtract. */
8473 op1
= (insn
>> 20) & 7;
8474 tmp
= load_reg(s
, rn
);
8475 tmp2
= load_reg(s
, rm
);
8476 sh
= (insn
>> 5) & 7;
8477 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8479 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8480 tcg_temp_free_i32(tmp2
);
8481 store_reg(s
, rd
, tmp
);
8484 if ((insn
& 0x00700020) == 0) {
8485 /* Halfword pack. */
8486 tmp
= load_reg(s
, rn
);
8487 tmp2
= load_reg(s
, rm
);
8488 shift
= (insn
>> 7) & 0x1f;
8489 if (insn
& (1 << 6)) {
8493 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8494 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8495 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8499 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8500 tcg_gen_ext16u_i32(tmp
, tmp
);
8501 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8503 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8504 tcg_temp_free_i32(tmp2
);
8505 store_reg(s
, rd
, tmp
);
8506 } else if ((insn
& 0x00200020) == 0x00200000) {
8508 tmp
= load_reg(s
, rm
);
8509 shift
= (insn
>> 7) & 0x1f;
8510 if (insn
& (1 << 6)) {
8513 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8515 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8517 sh
= (insn
>> 16) & 0x1f;
8518 tmp2
= tcg_const_i32(sh
);
8519 if (insn
& (1 << 22))
8520 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8522 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8523 tcg_temp_free_i32(tmp2
);
8524 store_reg(s
, rd
, tmp
);
8525 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8527 tmp
= load_reg(s
, rm
);
8528 sh
= (insn
>> 16) & 0x1f;
8529 tmp2
= tcg_const_i32(sh
);
8530 if (insn
& (1 << 22))
8531 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8533 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8534 tcg_temp_free_i32(tmp2
);
8535 store_reg(s
, rd
, tmp
);
8536 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8538 tmp
= load_reg(s
, rn
);
8539 tmp2
= load_reg(s
, rm
);
8540 tmp3
= tcg_temp_new_i32();
8541 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8542 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8543 tcg_temp_free_i32(tmp3
);
8544 tcg_temp_free_i32(tmp2
);
8545 store_reg(s
, rd
, tmp
);
8546 } else if ((insn
& 0x000003e0) == 0x00000060) {
8547 tmp
= load_reg(s
, rm
);
8548 shift
= (insn
>> 10) & 3;
8549 /* ??? In many cases it's not necessary to do a
8550 rotate, a shift is sufficient. */
8552 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8553 op1
= (insn
>> 20) & 7;
8555 case 0: gen_sxtb16(tmp
); break;
8556 case 2: gen_sxtb(tmp
); break;
8557 case 3: gen_sxth(tmp
); break;
8558 case 4: gen_uxtb16(tmp
); break;
8559 case 6: gen_uxtb(tmp
); break;
8560 case 7: gen_uxth(tmp
); break;
8561 default: goto illegal_op
;
8564 tmp2
= load_reg(s
, rn
);
8565 if ((op1
& 3) == 0) {
8566 gen_add16(tmp
, tmp2
);
8568 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8569 tcg_temp_free_i32(tmp2
);
8572 store_reg(s
, rd
, tmp
);
8573 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8575 tmp
= load_reg(s
, rm
);
8576 if (insn
& (1 << 22)) {
8577 if (insn
& (1 << 7)) {
8581 gen_helper_rbit(tmp
, tmp
);
8584 if (insn
& (1 << 7))
8587 tcg_gen_bswap32_i32(tmp
, tmp
);
8589 store_reg(s
, rd
, tmp
);
8594 case 2: /* Multiplies (Type 3). */
8595 switch ((insn
>> 20) & 0x7) {
8597 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8598 /* op2 not 00x or 11x : UNDEF */
8601 /* Signed multiply most significant [accumulate].
8602 (SMMUL, SMMLA, SMMLS) */
8603 tmp
= load_reg(s
, rm
);
8604 tmp2
= load_reg(s
, rs
);
8605 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8608 tmp
= load_reg(s
, rd
);
8609 if (insn
& (1 << 6)) {
8610 tmp64
= gen_subq_msw(tmp64
, tmp
);
8612 tmp64
= gen_addq_msw(tmp64
, tmp
);
8615 if (insn
& (1 << 5)) {
8616 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8618 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8619 tmp
= tcg_temp_new_i32();
8620 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8621 tcg_temp_free_i64(tmp64
);
8622 store_reg(s
, rn
, tmp
);
8626 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8627 if (insn
& (1 << 7)) {
8630 tmp
= load_reg(s
, rm
);
8631 tmp2
= load_reg(s
, rs
);
8632 if (insn
& (1 << 5))
8633 gen_swap_half(tmp2
);
8634 gen_smul_dual(tmp
, tmp2
);
8635 if (insn
& (1 << 22)) {
8636 /* smlald, smlsld */
8639 tmp64
= tcg_temp_new_i64();
8640 tmp64_2
= tcg_temp_new_i64();
8641 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8642 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8643 tcg_temp_free_i32(tmp
);
8644 tcg_temp_free_i32(tmp2
);
8645 if (insn
& (1 << 6)) {
8646 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8648 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8650 tcg_temp_free_i64(tmp64_2
);
8651 gen_addq(s
, tmp64
, rd
, rn
);
8652 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8653 tcg_temp_free_i64(tmp64
);
8655 /* smuad, smusd, smlad, smlsd */
8656 if (insn
& (1 << 6)) {
8657 /* This subtraction cannot overflow. */
8658 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8660 /* This addition cannot overflow 32 bits;
8661 * however it may overflow considered as a
8662 * signed operation, in which case we must set
8665 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8667 tcg_temp_free_i32(tmp2
);
8670 tmp2
= load_reg(s
, rd
);
8671 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8672 tcg_temp_free_i32(tmp2
);
8674 store_reg(s
, rn
, tmp
);
8680 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8683 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8686 tmp
= load_reg(s
, rm
);
8687 tmp2
= load_reg(s
, rs
);
8688 if (insn
& (1 << 21)) {
8689 gen_helper_udiv(tmp
, tmp
, tmp2
);
8691 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8693 tcg_temp_free_i32(tmp2
);
8694 store_reg(s
, rn
, tmp
);
8701 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8703 case 0: /* Unsigned sum of absolute differences. */
8705 tmp
= load_reg(s
, rm
);
8706 tmp2
= load_reg(s
, rs
);
8707 gen_helper_usad8(tmp
, tmp
, tmp2
);
8708 tcg_temp_free_i32(tmp2
);
8710 tmp2
= load_reg(s
, rd
);
8711 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8712 tcg_temp_free_i32(tmp2
);
8714 store_reg(s
, rn
, tmp
);
8716 case 0x20: case 0x24: case 0x28: case 0x2c:
8717 /* Bitfield insert/clear. */
8719 shift
= (insn
>> 7) & 0x1f;
8720 i
= (insn
>> 16) & 0x1f;
8723 tmp
= tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp
, 0);
8726 tmp
= load_reg(s
, rm
);
8729 tmp2
= load_reg(s
, rd
);
8730 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8731 tcg_temp_free_i32(tmp2
);
8733 store_reg(s
, rd
, tmp
);
8735 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8736 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8738 tmp
= load_reg(s
, rm
);
8739 shift
= (insn
>> 7) & 0x1f;
8740 i
= ((insn
>> 16) & 0x1f) + 1;
8745 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8747 gen_sbfx(tmp
, shift
, i
);
8750 store_reg(s
, rd
, tmp
);
8760 /* Check for undefined extension instructions
8761 * per the ARM Bible IE:
8762 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8764 sh
= (0xf << 20) | (0xf << 4);
8765 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8769 /* load/store byte/word */
8770 rn
= (insn
>> 16) & 0xf;
8771 rd
= (insn
>> 12) & 0xf;
8772 tmp2
= load_reg(s
, rn
);
8773 if ((insn
& 0x01200000) == 0x00200000) {
8777 i
= get_mem_index(s
);
8779 if (insn
& (1 << 24))
8780 gen_add_data_offset(s
, insn
, tmp2
);
8781 if (insn
& (1 << 20)) {
8783 tmp
= tcg_temp_new_i32();
8784 if (insn
& (1 << 22)) {
8785 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
8787 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
8791 tmp
= load_reg(s
, rd
);
8792 if (insn
& (1 << 22)) {
8793 gen_aa32_st8(s
, tmp
, tmp2
, i
);
8795 gen_aa32_st32(s
, tmp
, tmp2
, i
);
8797 tcg_temp_free_i32(tmp
);
8799 if (!(insn
& (1 << 24))) {
8800 gen_add_data_offset(s
, insn
, tmp2
);
8801 store_reg(s
, rn
, tmp2
);
8802 } else if (insn
& (1 << 21)) {
8803 store_reg(s
, rn
, tmp2
);
8805 tcg_temp_free_i32(tmp2
);
8807 if (insn
& (1 << 20)) {
8808 /* Complete the load. */
8809 store_reg_from_load(env
, s
, rd
, tmp
);
8815 int j
, n
, user
, loaded_base
;
8816 TCGv_i32 loaded_var
;
8817 /* load/store multiple words */
8818 /* XXX: store correct base if write back */
8820 if (insn
& (1 << 22)) {
8822 goto illegal_op
; /* only usable in supervisor mode */
8824 if ((insn
& (1 << 15)) == 0)
8827 rn
= (insn
>> 16) & 0xf;
8828 addr
= load_reg(s
, rn
);
8830 /* compute total size */
8832 TCGV_UNUSED_I32(loaded_var
);
8835 if (insn
& (1 << i
))
8838 /* XXX: test invalid n == 0 case ? */
8839 if (insn
& (1 << 23)) {
8840 if (insn
& (1 << 24)) {
8842 tcg_gen_addi_i32(addr
, addr
, 4);
8844 /* post increment */
8847 if (insn
& (1 << 24)) {
8849 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8851 /* post decrement */
8853 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8858 if (insn
& (1 << i
)) {
8859 if (insn
& (1 << 20)) {
8861 tmp
= tcg_temp_new_i32();
8862 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8864 tmp2
= tcg_const_i32(i
);
8865 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8866 tcg_temp_free_i32(tmp2
);
8867 tcg_temp_free_i32(tmp
);
8868 } else if (i
== rn
) {
8872 store_reg_from_load(env
, s
, i
, tmp
);
8877 /* special case: r15 = PC + 8 */
8878 val
= (long)s
->pc
+ 4;
8879 tmp
= tcg_temp_new_i32();
8880 tcg_gen_movi_i32(tmp
, val
);
8882 tmp
= tcg_temp_new_i32();
8883 tmp2
= tcg_const_i32(i
);
8884 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8885 tcg_temp_free_i32(tmp2
);
8887 tmp
= load_reg(s
, i
);
8889 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8890 tcg_temp_free_i32(tmp
);
8893 /* no need to add after the last transfer */
8895 tcg_gen_addi_i32(addr
, addr
, 4);
8898 if (insn
& (1 << 21)) {
8900 if (insn
& (1 << 23)) {
8901 if (insn
& (1 << 24)) {
8904 /* post increment */
8905 tcg_gen_addi_i32(addr
, addr
, 4);
8908 if (insn
& (1 << 24)) {
8911 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8913 /* post decrement */
8914 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8917 store_reg(s
, rn
, addr
);
8919 tcg_temp_free_i32(addr
);
8922 store_reg(s
, rn
, loaded_var
);
8924 if ((insn
& (1 << 22)) && !user
) {
8925 /* Restore CPSR from SPSR. */
8926 tmp
= load_cpu_field(spsr
);
8927 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8928 tcg_temp_free_i32(tmp
);
8929 s
->is_jmp
= DISAS_UPDATE
;
8938 /* branch (and link) */
8939 val
= (int32_t)s
->pc
;
8940 if (insn
& (1 << 24)) {
8941 tmp
= tcg_temp_new_i32();
8942 tcg_gen_movi_i32(tmp
, val
);
8943 store_reg(s
, 14, tmp
);
8945 offset
= sextract32(insn
<< 2, 0, 26);
8953 if (((insn
>> 8) & 0xe) == 10) {
8955 if (disas_vfp_insn(env
, s
, insn
)) {
8958 } else if (disas_coproc_insn(env
, s
, insn
)) {
8965 gen_set_pc_im(s
, s
->pc
);
8966 s
->svc_imm
= extract32(insn
, 0, 24);
8967 s
->is_jmp
= DISAS_SWI
;
8971 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
8977 /* Return true if this is a Thumb-2 logical op. */
8979 thumb2_logic_op(int op
)
8984 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8985 then set condition code flags based on the result of the operation.
8986 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8987 to the high bit of T1.
8988 Returns zero if the opcode is valid. */
8991 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8992 TCGv_i32 t0
, TCGv_i32 t1
)
8999 tcg_gen_and_i32(t0
, t0
, t1
);
9003 tcg_gen_andc_i32(t0
, t0
, t1
);
9007 tcg_gen_or_i32(t0
, t0
, t1
);
9011 tcg_gen_orc_i32(t0
, t0
, t1
);
9015 tcg_gen_xor_i32(t0
, t0
, t1
);
9020 gen_add_CC(t0
, t0
, t1
);
9022 tcg_gen_add_i32(t0
, t0
, t1
);
9026 gen_adc_CC(t0
, t0
, t1
);
9032 gen_sbc_CC(t0
, t0
, t1
);
9034 gen_sub_carry(t0
, t0
, t1
);
9039 gen_sub_CC(t0
, t0
, t1
);
9041 tcg_gen_sub_i32(t0
, t0
, t1
);
9045 gen_sub_CC(t0
, t1
, t0
);
9047 tcg_gen_sub_i32(t0
, t1
, t0
);
9049 default: /* 5, 6, 7, 9, 12, 15. */
9055 gen_set_CF_bit31(t1
);
9060 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9062 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9064 uint32_t insn
, imm
, shift
, offset
;
9065 uint32_t rd
, rn
, rm
, rs
;
9076 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
9077 || arm_feature (env
, ARM_FEATURE_M
))) {
9078 /* Thumb-1 cores may need to treat bl and blx as a pair of
9079 16-bit instructions to get correct prefetch abort behavior. */
9081 if ((insn
& (1 << 12)) == 0) {
9083 /* Second half of blx. */
9084 offset
= ((insn
& 0x7ff) << 1);
9085 tmp
= load_reg(s
, 14);
9086 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9087 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9089 tmp2
= tcg_temp_new_i32();
9090 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9091 store_reg(s
, 14, tmp2
);
9095 if (insn
& (1 << 11)) {
9096 /* Second half of bl. */
9097 offset
= ((insn
& 0x7ff) << 1) | 1;
9098 tmp
= load_reg(s
, 14);
9099 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9101 tmp2
= tcg_temp_new_i32();
9102 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9103 store_reg(s
, 14, tmp2
);
9107 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9108 /* Instruction spans a page boundary. Implement it as two
9109 16-bit instructions in case the second half causes an
9111 offset
= ((int32_t)insn
<< 21) >> 9;
9112 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9115 /* Fall through to 32-bit decode. */
9118 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9120 insn
|= (uint32_t)insn_hw1
<< 16;
9122 if ((insn
& 0xf800e800) != 0xf000e800) {
9126 rn
= (insn
>> 16) & 0xf;
9127 rs
= (insn
>> 12) & 0xf;
9128 rd
= (insn
>> 8) & 0xf;
9130 switch ((insn
>> 25) & 0xf) {
9131 case 0: case 1: case 2: case 3:
9132 /* 16-bit instructions. Should never happen. */
9135 if (insn
& (1 << 22)) {
9136 /* Other load/store, table branch. */
9137 if (insn
& 0x01200000) {
9138 ARCH(5); /* Load/store doubleword. */
9140 addr
= tcg_temp_new_i32();
9141 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9143 addr
= load_reg(s
, rn
);
9145 offset
= (insn
& 0xff) * 4;
9146 if ((insn
& (1 << 23)) == 0)
9148 if (insn
& (1 << 24)) {
9149 tcg_gen_addi_i32(addr
, addr
, offset
);
9152 if (insn
& (1 << 20)) {
9154 tmp
= tcg_temp_new_i32();
9155 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9156 store_reg(s
, rs
, tmp
);
9157 tcg_gen_addi_i32(addr
, addr
, 4);
9158 tmp
= tcg_temp_new_i32();
9159 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9160 store_reg(s
, rd
, tmp
);
9163 tmp
= load_reg(s
, rs
);
9164 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9165 tcg_temp_free_i32(tmp
);
9166 tcg_gen_addi_i32(addr
, addr
, 4);
9167 tmp
= load_reg(s
, rd
);
9168 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9169 tcg_temp_free_i32(tmp
);
9171 if (insn
& (1 << 21)) {
9172 /* Base writeback. */
9175 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9176 store_reg(s
, rn
, addr
);
9178 tcg_temp_free_i32(addr
);
9180 } else if ((insn
& (1 << 23)) == 0) {
9181 /* Load/store exclusive word. */
9182 addr
= tcg_temp_local_new_i32();
9183 load_reg_var(s
, addr
, rn
);
9184 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9185 if (insn
& (1 << 20)) {
9186 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9188 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9190 tcg_temp_free_i32(addr
);
9191 } else if ((insn
& (7 << 5)) == 0) {
9194 addr
= tcg_temp_new_i32();
9195 tcg_gen_movi_i32(addr
, s
->pc
);
9197 addr
= load_reg(s
, rn
);
9199 tmp
= load_reg(s
, rm
);
9200 tcg_gen_add_i32(addr
, addr
, tmp
);
9201 if (insn
& (1 << 4)) {
9203 tcg_gen_add_i32(addr
, addr
, tmp
);
9204 tcg_temp_free_i32(tmp
);
9205 tmp
= tcg_temp_new_i32();
9206 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9208 tcg_temp_free_i32(tmp
);
9209 tmp
= tcg_temp_new_i32();
9210 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9212 tcg_temp_free_i32(addr
);
9213 tcg_gen_shli_i32(tmp
, tmp
, 1);
9214 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9215 store_reg(s
, 15, tmp
);
9217 int op2
= (insn
>> 6) & 0x3;
9218 op
= (insn
>> 4) & 0x3;
9223 /* Load/store exclusive byte/halfword/doubleword */
9230 /* Load-acquire/store-release */
9236 /* Load-acquire/store-release exclusive */
9240 addr
= tcg_temp_local_new_i32();
9241 load_reg_var(s
, addr
, rn
);
9243 if (insn
& (1 << 20)) {
9244 tmp
= tcg_temp_new_i32();
9247 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9250 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9253 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9258 store_reg(s
, rs
, tmp
);
9260 tmp
= load_reg(s
, rs
);
9263 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9266 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9269 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9274 tcg_temp_free_i32(tmp
);
9276 } else if (insn
& (1 << 20)) {
9277 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9279 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9281 tcg_temp_free_i32(addr
);
9284 /* Load/store multiple, RFE, SRS. */
9285 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9286 /* RFE, SRS: not available in user mode or on M profile */
9287 if (IS_USER(s
) || IS_M(env
)) {
9290 if (insn
& (1 << 20)) {
9292 addr
= load_reg(s
, rn
);
9293 if ((insn
& (1 << 24)) == 0)
9294 tcg_gen_addi_i32(addr
, addr
, -8);
9295 /* Load PC into tmp and CPSR into tmp2. */
9296 tmp
= tcg_temp_new_i32();
9297 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9298 tcg_gen_addi_i32(addr
, addr
, 4);
9299 tmp2
= tcg_temp_new_i32();
9300 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9301 if (insn
& (1 << 21)) {
9302 /* Base writeback. */
9303 if (insn
& (1 << 24)) {
9304 tcg_gen_addi_i32(addr
, addr
, 4);
9306 tcg_gen_addi_i32(addr
, addr
, -4);
9308 store_reg(s
, rn
, addr
);
9310 tcg_temp_free_i32(addr
);
9312 gen_rfe(s
, tmp
, tmp2
);
9315 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9319 int i
, loaded_base
= 0;
9320 TCGv_i32 loaded_var
;
9321 /* Load/store multiple. */
9322 addr
= load_reg(s
, rn
);
9324 for (i
= 0; i
< 16; i
++) {
9325 if (insn
& (1 << i
))
9328 if (insn
& (1 << 24)) {
9329 tcg_gen_addi_i32(addr
, addr
, -offset
);
9332 TCGV_UNUSED_I32(loaded_var
);
9333 for (i
= 0; i
< 16; i
++) {
9334 if ((insn
& (1 << i
)) == 0)
9336 if (insn
& (1 << 20)) {
9338 tmp
= tcg_temp_new_i32();
9339 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9342 } else if (i
== rn
) {
9346 store_reg(s
, i
, tmp
);
9350 tmp
= load_reg(s
, i
);
9351 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9352 tcg_temp_free_i32(tmp
);
9354 tcg_gen_addi_i32(addr
, addr
, 4);
9357 store_reg(s
, rn
, loaded_var
);
9359 if (insn
& (1 << 21)) {
9360 /* Base register writeback. */
9361 if (insn
& (1 << 24)) {
9362 tcg_gen_addi_i32(addr
, addr
, -offset
);
9364 /* Fault if writeback register is in register list. */
9365 if (insn
& (1 << rn
))
9367 store_reg(s
, rn
, addr
);
9369 tcg_temp_free_i32(addr
);
9376 op
= (insn
>> 21) & 0xf;
9378 /* Halfword pack. */
9379 tmp
= load_reg(s
, rn
);
9380 tmp2
= load_reg(s
, rm
);
9381 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9382 if (insn
& (1 << 5)) {
9386 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9387 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9388 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9392 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9393 tcg_gen_ext16u_i32(tmp
, tmp
);
9394 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9396 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9397 tcg_temp_free_i32(tmp2
);
9398 store_reg(s
, rd
, tmp
);
9400 /* Data processing register constant shift. */
9402 tmp
= tcg_temp_new_i32();
9403 tcg_gen_movi_i32(tmp
, 0);
9405 tmp
= load_reg(s
, rn
);
9407 tmp2
= load_reg(s
, rm
);
9409 shiftop
= (insn
>> 4) & 3;
9410 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9411 conds
= (insn
& (1 << 20)) != 0;
9412 logic_cc
= (conds
&& thumb2_logic_op(op
));
9413 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9414 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9416 tcg_temp_free_i32(tmp2
);
9418 store_reg(s
, rd
, tmp
);
9420 tcg_temp_free_i32(tmp
);
9424 case 13: /* Misc data processing. */
9425 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9426 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9429 case 0: /* Register controlled shift. */
9430 tmp
= load_reg(s
, rn
);
9431 tmp2
= load_reg(s
, rm
);
9432 if ((insn
& 0x70) != 0)
9434 op
= (insn
>> 21) & 3;
9435 logic_cc
= (insn
& (1 << 20)) != 0;
9436 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9439 store_reg_bx(env
, s
, rd
, tmp
);
9441 case 1: /* Sign/zero extend. */
9442 tmp
= load_reg(s
, rm
);
9443 shift
= (insn
>> 4) & 3;
9444 /* ??? In many cases it's not necessary to do a
9445 rotate, a shift is sufficient. */
9447 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9448 op
= (insn
>> 20) & 7;
9450 case 0: gen_sxth(tmp
); break;
9451 case 1: gen_uxth(tmp
); break;
9452 case 2: gen_sxtb16(tmp
); break;
9453 case 3: gen_uxtb16(tmp
); break;
9454 case 4: gen_sxtb(tmp
); break;
9455 case 5: gen_uxtb(tmp
); break;
9456 default: goto illegal_op
;
9459 tmp2
= load_reg(s
, rn
);
9460 if ((op
>> 1) == 1) {
9461 gen_add16(tmp
, tmp2
);
9463 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9464 tcg_temp_free_i32(tmp2
);
9467 store_reg(s
, rd
, tmp
);
9469 case 2: /* SIMD add/subtract. */
9470 op
= (insn
>> 20) & 7;
9471 shift
= (insn
>> 4) & 7;
9472 if ((op
& 3) == 3 || (shift
& 3) == 3)
9474 tmp
= load_reg(s
, rn
);
9475 tmp2
= load_reg(s
, rm
);
9476 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9477 tcg_temp_free_i32(tmp2
);
9478 store_reg(s
, rd
, tmp
);
9480 case 3: /* Other data processing. */
9481 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9483 /* Saturating add/subtract. */
9484 tmp
= load_reg(s
, rn
);
9485 tmp2
= load_reg(s
, rm
);
9487 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9489 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9491 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9492 tcg_temp_free_i32(tmp2
);
9494 tmp
= load_reg(s
, rn
);
9496 case 0x0a: /* rbit */
9497 gen_helper_rbit(tmp
, tmp
);
9499 case 0x08: /* rev */
9500 tcg_gen_bswap32_i32(tmp
, tmp
);
9502 case 0x09: /* rev16 */
9505 case 0x0b: /* revsh */
9508 case 0x10: /* sel */
9509 tmp2
= load_reg(s
, rm
);
9510 tmp3
= tcg_temp_new_i32();
9511 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9512 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9513 tcg_temp_free_i32(tmp3
);
9514 tcg_temp_free_i32(tmp2
);
9516 case 0x18: /* clz */
9517 gen_helper_clz(tmp
, tmp
);
9527 uint32_t sz
= op
& 0x3;
9528 uint32_t c
= op
& 0x8;
9530 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9534 tmp2
= load_reg(s
, rm
);
9536 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9537 } else if (sz
== 1) {
9538 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9540 tmp3
= tcg_const_i32(1 << sz
);
9542 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9544 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9546 tcg_temp_free_i32(tmp2
);
9547 tcg_temp_free_i32(tmp3
);
9554 store_reg(s
, rd
, tmp
);
9556 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9557 op
= (insn
>> 4) & 0xf;
9558 tmp
= load_reg(s
, rn
);
9559 tmp2
= load_reg(s
, rm
);
9560 switch ((insn
>> 20) & 7) {
9561 case 0: /* 32 x 32 -> 32 */
9562 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9563 tcg_temp_free_i32(tmp2
);
9565 tmp2
= load_reg(s
, rs
);
9567 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9569 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9570 tcg_temp_free_i32(tmp2
);
9573 case 1: /* 16 x 16 -> 32 */
9574 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9575 tcg_temp_free_i32(tmp2
);
9577 tmp2
= load_reg(s
, rs
);
9578 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9579 tcg_temp_free_i32(tmp2
);
9582 case 2: /* Dual multiply add. */
9583 case 4: /* Dual multiply subtract. */
9585 gen_swap_half(tmp2
);
9586 gen_smul_dual(tmp
, tmp2
);
9587 if (insn
& (1 << 22)) {
9588 /* This subtraction cannot overflow. */
9589 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9591 /* This addition cannot overflow 32 bits;
9592 * however it may overflow considered as a signed
9593 * operation, in which case we must set the Q flag.
9595 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9597 tcg_temp_free_i32(tmp2
);
9600 tmp2
= load_reg(s
, rs
);
9601 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9602 tcg_temp_free_i32(tmp2
);
9605 case 3: /* 32 * 16 -> 32msb */
9607 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9610 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9611 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9612 tmp
= tcg_temp_new_i32();
9613 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9614 tcg_temp_free_i64(tmp64
);
9617 tmp2
= load_reg(s
, rs
);
9618 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9619 tcg_temp_free_i32(tmp2
);
9622 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9623 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9625 tmp
= load_reg(s
, rs
);
9626 if (insn
& (1 << 20)) {
9627 tmp64
= gen_addq_msw(tmp64
, tmp
);
9629 tmp64
= gen_subq_msw(tmp64
, tmp
);
9632 if (insn
& (1 << 4)) {
9633 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9635 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9636 tmp
= tcg_temp_new_i32();
9637 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9638 tcg_temp_free_i64(tmp64
);
9640 case 7: /* Unsigned sum of absolute differences. */
9641 gen_helper_usad8(tmp
, tmp
, tmp2
);
9642 tcg_temp_free_i32(tmp2
);
9644 tmp2
= load_reg(s
, rs
);
9645 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9646 tcg_temp_free_i32(tmp2
);
9650 store_reg(s
, rd
, tmp
);
9652 case 6: case 7: /* 64-bit multiply, Divide. */
9653 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9654 tmp
= load_reg(s
, rn
);
9655 tmp2
= load_reg(s
, rm
);
9656 if ((op
& 0x50) == 0x10) {
9658 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9662 gen_helper_udiv(tmp
, tmp
, tmp2
);
9664 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9665 tcg_temp_free_i32(tmp2
);
9666 store_reg(s
, rd
, tmp
);
9667 } else if ((op
& 0xe) == 0xc) {
9668 /* Dual multiply accumulate long. */
9670 gen_swap_half(tmp2
);
9671 gen_smul_dual(tmp
, tmp2
);
9673 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9675 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9677 tcg_temp_free_i32(tmp2
);
9679 tmp64
= tcg_temp_new_i64();
9680 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9681 tcg_temp_free_i32(tmp
);
9682 gen_addq(s
, tmp64
, rs
, rd
);
9683 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9684 tcg_temp_free_i64(tmp64
);
9687 /* Unsigned 64-bit multiply */
9688 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9692 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9693 tcg_temp_free_i32(tmp2
);
9694 tmp64
= tcg_temp_new_i64();
9695 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9696 tcg_temp_free_i32(tmp
);
9698 /* Signed 64-bit multiply */
9699 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9704 gen_addq_lo(s
, tmp64
, rs
);
9705 gen_addq_lo(s
, tmp64
, rd
);
9706 } else if (op
& 0x40) {
9707 /* 64-bit accumulate. */
9708 gen_addq(s
, tmp64
, rs
, rd
);
9710 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9711 tcg_temp_free_i64(tmp64
);
9716 case 6: case 7: case 14: case 15:
9718 if (((insn
>> 24) & 3) == 3) {
9719 /* Translate into the equivalent ARM encoding. */
9720 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9721 if (disas_neon_data_insn(env
, s
, insn
))
9723 } else if (((insn
>> 8) & 0xe) == 10) {
9724 if (disas_vfp_insn(env
, s
, insn
)) {
9728 if (insn
& (1 << 28))
9730 if (disas_coproc_insn (env
, s
, insn
))
9734 case 8: case 9: case 10: case 11:
9735 if (insn
& (1 << 15)) {
9736 /* Branches, misc control. */
9737 if (insn
& 0x5000) {
9738 /* Unconditional branch. */
9739 /* signextend(hw1[10:0]) -> offset[:12]. */
9740 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9741 /* hw1[10:0] -> offset[11:1]. */
9742 offset
|= (insn
& 0x7ff) << 1;
9743 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9744 offset[24:22] already have the same value because of the
9745 sign extension above. */
9746 offset
^= ((~insn
) & (1 << 13)) << 10;
9747 offset
^= ((~insn
) & (1 << 11)) << 11;
9749 if (insn
& (1 << 14)) {
9750 /* Branch and link. */
9751 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9755 if (insn
& (1 << 12)) {
9760 offset
&= ~(uint32_t)2;
9761 /* thumb2 bx, no need to check */
9762 gen_bx_im(s
, offset
);
9764 } else if (((insn
>> 23) & 7) == 7) {
9766 if (insn
& (1 << 13))
9769 if (insn
& (1 << 26)) {
9770 if (!(insn
& (1 << 20))) {
9771 /* Hypervisor call (v7) */
9772 int imm16
= extract32(insn
, 16, 4) << 12
9773 | extract32(insn
, 0, 12);
9780 /* Secure monitor call (v6+) */
9788 op
= (insn
>> 20) & 7;
9790 case 0: /* msr cpsr. */
9792 tmp
= load_reg(s
, rn
);
9793 addr
= tcg_const_i32(insn
& 0xff);
9794 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9795 tcg_temp_free_i32(addr
);
9796 tcg_temp_free_i32(tmp
);
9801 case 1: /* msr spsr. */
9804 tmp
= load_reg(s
, rn
);
9806 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9810 case 2: /* cps, nop-hint. */
9811 if (((insn
>> 8) & 7) == 0) {
9812 gen_nop_hint(s
, insn
& 0xff);
9814 /* Implemented as NOP in user mode. */
9819 if (insn
& (1 << 10)) {
9820 if (insn
& (1 << 7))
9822 if (insn
& (1 << 6))
9824 if (insn
& (1 << 5))
9826 if (insn
& (1 << 9))
9827 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9829 if (insn
& (1 << 8)) {
9831 imm
|= (insn
& 0x1f);
9834 gen_set_psr_im(s
, offset
, 0, imm
);
9837 case 3: /* Special control operations. */
9839 op
= (insn
>> 4) & 0xf;
9847 /* These execute as NOPs. */
9854 /* Trivial implementation equivalent to bx. */
9855 tmp
= load_reg(s
, rn
);
9858 case 5: /* Exception return. */
9862 if (rn
!= 14 || rd
!= 15) {
9865 tmp
= load_reg(s
, rn
);
9866 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9867 gen_exception_return(s
, tmp
);
9869 case 6: /* mrs cpsr. */
9870 tmp
= tcg_temp_new_i32();
9872 addr
= tcg_const_i32(insn
& 0xff);
9873 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9874 tcg_temp_free_i32(addr
);
9876 gen_helper_cpsr_read(tmp
, cpu_env
);
9878 store_reg(s
, rd
, tmp
);
9880 case 7: /* mrs spsr. */
9881 /* Not accessible in user mode. */
9882 if (IS_USER(s
) || IS_M(env
))
9884 tmp
= load_cpu_field(spsr
);
9885 store_reg(s
, rd
, tmp
);
9890 /* Conditional branch. */
9891 op
= (insn
>> 22) & 0xf;
9892 /* Generate a conditional jump to next instruction. */
9893 s
->condlabel
= gen_new_label();
9894 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9897 /* offset[11:1] = insn[10:0] */
9898 offset
= (insn
& 0x7ff) << 1;
9899 /* offset[17:12] = insn[21:16]. */
9900 offset
|= (insn
& 0x003f0000) >> 4;
9901 /* offset[31:20] = insn[26]. */
9902 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9903 /* offset[18] = insn[13]. */
9904 offset
|= (insn
& (1 << 13)) << 5;
9905 /* offset[19] = insn[11]. */
9906 offset
|= (insn
& (1 << 11)) << 8;
9908 /* jump to the offset */
9909 gen_jmp(s
, s
->pc
+ offset
);
9912 /* Data processing immediate. */
9913 if (insn
& (1 << 25)) {
9914 if (insn
& (1 << 24)) {
9915 if (insn
& (1 << 20))
9917 /* Bitfield/Saturate. */
9918 op
= (insn
>> 21) & 7;
9920 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9922 tmp
= tcg_temp_new_i32();
9923 tcg_gen_movi_i32(tmp
, 0);
9925 tmp
= load_reg(s
, rn
);
9928 case 2: /* Signed bitfield extract. */
9930 if (shift
+ imm
> 32)
9933 gen_sbfx(tmp
, shift
, imm
);
9935 case 6: /* Unsigned bitfield extract. */
9937 if (shift
+ imm
> 32)
9940 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9942 case 3: /* Bitfield insert/clear. */
9945 imm
= imm
+ 1 - shift
;
9947 tmp2
= load_reg(s
, rd
);
9948 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9949 tcg_temp_free_i32(tmp2
);
9954 default: /* Saturate. */
9957 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9959 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9961 tmp2
= tcg_const_i32(imm
);
9964 if ((op
& 1) && shift
== 0)
9965 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9967 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9970 if ((op
& 1) && shift
== 0)
9971 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9973 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9975 tcg_temp_free_i32(tmp2
);
9978 store_reg(s
, rd
, tmp
);
9980 imm
= ((insn
& 0x04000000) >> 15)
9981 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9982 if (insn
& (1 << 22)) {
9983 /* 16-bit immediate. */
9984 imm
|= (insn
>> 4) & 0xf000;
9985 if (insn
& (1 << 23)) {
9987 tmp
= load_reg(s
, rd
);
9988 tcg_gen_ext16u_i32(tmp
, tmp
);
9989 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9992 tmp
= tcg_temp_new_i32();
9993 tcg_gen_movi_i32(tmp
, imm
);
9996 /* Add/sub 12-bit immediate. */
9998 offset
= s
->pc
& ~(uint32_t)3;
9999 if (insn
& (1 << 23))
10003 tmp
= tcg_temp_new_i32();
10004 tcg_gen_movi_i32(tmp
, offset
);
10006 tmp
= load_reg(s
, rn
);
10007 if (insn
& (1 << 23))
10008 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10010 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10013 store_reg(s
, rd
, tmp
);
10016 int shifter_out
= 0;
10017 /* modified 12-bit immediate. */
10018 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10019 imm
= (insn
& 0xff);
10022 /* Nothing to do. */
10024 case 1: /* 00XY00XY */
10027 case 2: /* XY00XY00 */
10031 case 3: /* XYXYXYXY */
10035 default: /* Rotated constant. */
10036 shift
= (shift
<< 1) | (imm
>> 7);
10038 imm
= imm
<< (32 - shift
);
10042 tmp2
= tcg_temp_new_i32();
10043 tcg_gen_movi_i32(tmp2
, imm
);
10044 rn
= (insn
>> 16) & 0xf;
10046 tmp
= tcg_temp_new_i32();
10047 tcg_gen_movi_i32(tmp
, 0);
10049 tmp
= load_reg(s
, rn
);
10051 op
= (insn
>> 21) & 0xf;
10052 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10053 shifter_out
, tmp
, tmp2
))
10055 tcg_temp_free_i32(tmp2
);
10056 rd
= (insn
>> 8) & 0xf;
10058 store_reg(s
, rd
, tmp
);
10060 tcg_temp_free_i32(tmp
);
10065 case 12: /* Load/store single data item. */
10070 if ((insn
& 0x01100000) == 0x01000000) {
10071 if (disas_neon_ls_insn(env
, s
, insn
))
10075 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10077 if (!(insn
& (1 << 20))) {
10081 /* Byte or halfword load space with dest == r15 : memory hints.
10082 * Catch them early so we don't emit pointless addressing code.
10083 * This space is a mix of:
10084 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10085 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10087 * unallocated hints, which must be treated as NOPs
10088 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10089 * which is easiest for the decoding logic
10090 * Some space which must UNDEF
10092 int op1
= (insn
>> 23) & 3;
10093 int op2
= (insn
>> 6) & 0x3f;
10098 /* UNPREDICTABLE, unallocated hint or
10099 * PLD/PLDW/PLI (literal)
10104 return 0; /* PLD/PLDW/PLI or unallocated hint */
10106 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10107 return 0; /* PLD/PLDW/PLI or unallocated hint */
10109 /* UNDEF space, or an UNPREDICTABLE */
10113 memidx
= get_mem_index(s
);
10115 addr
= tcg_temp_new_i32();
10117 /* s->pc has already been incremented by 4. */
10118 imm
= s
->pc
& 0xfffffffc;
10119 if (insn
& (1 << 23))
10120 imm
+= insn
& 0xfff;
10122 imm
-= insn
& 0xfff;
10123 tcg_gen_movi_i32(addr
, imm
);
10125 addr
= load_reg(s
, rn
);
10126 if (insn
& (1 << 23)) {
10127 /* Positive offset. */
10128 imm
= insn
& 0xfff;
10129 tcg_gen_addi_i32(addr
, addr
, imm
);
10132 switch ((insn
>> 8) & 0xf) {
10133 case 0x0: /* Shifted Register. */
10134 shift
= (insn
>> 4) & 0xf;
10136 tcg_temp_free_i32(addr
);
10139 tmp
= load_reg(s
, rm
);
10141 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10142 tcg_gen_add_i32(addr
, addr
, tmp
);
10143 tcg_temp_free_i32(tmp
);
10145 case 0xc: /* Negative offset. */
10146 tcg_gen_addi_i32(addr
, addr
, -imm
);
10148 case 0xe: /* User privilege. */
10149 tcg_gen_addi_i32(addr
, addr
, imm
);
10150 memidx
= MMU_USER_IDX
;
10152 case 0x9: /* Post-decrement. */
10154 /* Fall through. */
10155 case 0xb: /* Post-increment. */
10159 case 0xd: /* Pre-decrement. */
10161 /* Fall through. */
10162 case 0xf: /* Pre-increment. */
10163 tcg_gen_addi_i32(addr
, addr
, imm
);
10167 tcg_temp_free_i32(addr
);
10172 if (insn
& (1 << 20)) {
10174 tmp
= tcg_temp_new_i32();
10177 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10180 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10183 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10186 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10189 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10192 tcg_temp_free_i32(tmp
);
10193 tcg_temp_free_i32(addr
);
10199 store_reg(s
, rs
, tmp
);
10203 tmp
= load_reg(s
, rs
);
10206 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10209 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10212 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10215 tcg_temp_free_i32(tmp
);
10216 tcg_temp_free_i32(addr
);
10219 tcg_temp_free_i32(tmp
);
10222 tcg_gen_addi_i32(addr
, addr
, imm
);
10224 store_reg(s
, rn
, addr
);
10226 tcg_temp_free_i32(addr
);
10238 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10240 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10247 if (s
->condexec_mask
) {
10248 cond
= s
->condexec_cond
;
10249 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10250 s
->condlabel
= gen_new_label();
10251 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10256 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10259 switch (insn
>> 12) {
10263 op
= (insn
>> 11) & 3;
10266 rn
= (insn
>> 3) & 7;
10267 tmp
= load_reg(s
, rn
);
10268 if (insn
& (1 << 10)) {
10270 tmp2
= tcg_temp_new_i32();
10271 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10274 rm
= (insn
>> 6) & 7;
10275 tmp2
= load_reg(s
, rm
);
10277 if (insn
& (1 << 9)) {
10278 if (s
->condexec_mask
)
10279 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10281 gen_sub_CC(tmp
, tmp
, tmp2
);
10283 if (s
->condexec_mask
)
10284 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10286 gen_add_CC(tmp
, tmp
, tmp2
);
10288 tcg_temp_free_i32(tmp2
);
10289 store_reg(s
, rd
, tmp
);
10291 /* shift immediate */
10292 rm
= (insn
>> 3) & 7;
10293 shift
= (insn
>> 6) & 0x1f;
10294 tmp
= load_reg(s
, rm
);
10295 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10296 if (!s
->condexec_mask
)
10298 store_reg(s
, rd
, tmp
);
10302 /* arithmetic large immediate */
10303 op
= (insn
>> 11) & 3;
10304 rd
= (insn
>> 8) & 0x7;
10305 if (op
== 0) { /* mov */
10306 tmp
= tcg_temp_new_i32();
10307 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10308 if (!s
->condexec_mask
)
10310 store_reg(s
, rd
, tmp
);
10312 tmp
= load_reg(s
, rd
);
10313 tmp2
= tcg_temp_new_i32();
10314 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10317 gen_sub_CC(tmp
, tmp
, tmp2
);
10318 tcg_temp_free_i32(tmp
);
10319 tcg_temp_free_i32(tmp2
);
10322 if (s
->condexec_mask
)
10323 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10325 gen_add_CC(tmp
, tmp
, tmp2
);
10326 tcg_temp_free_i32(tmp2
);
10327 store_reg(s
, rd
, tmp
);
10330 if (s
->condexec_mask
)
10331 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10333 gen_sub_CC(tmp
, tmp
, tmp2
);
10334 tcg_temp_free_i32(tmp2
);
10335 store_reg(s
, rd
, tmp
);
10341 if (insn
& (1 << 11)) {
10342 rd
= (insn
>> 8) & 7;
10343 /* load pc-relative. Bit 1 of PC is ignored. */
10344 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10345 val
&= ~(uint32_t)2;
10346 addr
= tcg_temp_new_i32();
10347 tcg_gen_movi_i32(addr
, val
);
10348 tmp
= tcg_temp_new_i32();
10349 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10350 tcg_temp_free_i32(addr
);
10351 store_reg(s
, rd
, tmp
);
10354 if (insn
& (1 << 10)) {
10355 /* data processing extended or blx */
10356 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10357 rm
= (insn
>> 3) & 0xf;
10358 op
= (insn
>> 8) & 3;
10361 tmp
= load_reg(s
, rd
);
10362 tmp2
= load_reg(s
, rm
);
10363 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10364 tcg_temp_free_i32(tmp2
);
10365 store_reg(s
, rd
, tmp
);
10368 tmp
= load_reg(s
, rd
);
10369 tmp2
= load_reg(s
, rm
);
10370 gen_sub_CC(tmp
, tmp
, tmp2
);
10371 tcg_temp_free_i32(tmp2
);
10372 tcg_temp_free_i32(tmp
);
10374 case 2: /* mov/cpy */
10375 tmp
= load_reg(s
, rm
);
10376 store_reg(s
, rd
, tmp
);
10378 case 3:/* branch [and link] exchange thumb register */
10379 tmp
= load_reg(s
, rm
);
10380 if (insn
& (1 << 7)) {
10382 val
= (uint32_t)s
->pc
| 1;
10383 tmp2
= tcg_temp_new_i32();
10384 tcg_gen_movi_i32(tmp2
, val
);
10385 store_reg(s
, 14, tmp2
);
10387 /* already thumb, no need to check */
10394 /* data processing register */
10396 rm
= (insn
>> 3) & 7;
10397 op
= (insn
>> 6) & 0xf;
10398 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10399 /* the shift/rotate ops want the operands backwards */
10408 if (op
== 9) { /* neg */
10409 tmp
= tcg_temp_new_i32();
10410 tcg_gen_movi_i32(tmp
, 0);
10411 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10412 tmp
= load_reg(s
, rd
);
10414 TCGV_UNUSED_I32(tmp
);
10417 tmp2
= load_reg(s
, rm
);
10419 case 0x0: /* and */
10420 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10421 if (!s
->condexec_mask
)
10424 case 0x1: /* eor */
10425 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10426 if (!s
->condexec_mask
)
10429 case 0x2: /* lsl */
10430 if (s
->condexec_mask
) {
10431 gen_shl(tmp2
, tmp2
, tmp
);
10433 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10434 gen_logic_CC(tmp2
);
10437 case 0x3: /* lsr */
10438 if (s
->condexec_mask
) {
10439 gen_shr(tmp2
, tmp2
, tmp
);
10441 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10442 gen_logic_CC(tmp2
);
10445 case 0x4: /* asr */
10446 if (s
->condexec_mask
) {
10447 gen_sar(tmp2
, tmp2
, tmp
);
10449 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10450 gen_logic_CC(tmp2
);
10453 case 0x5: /* adc */
10454 if (s
->condexec_mask
) {
10455 gen_adc(tmp
, tmp2
);
10457 gen_adc_CC(tmp
, tmp
, tmp2
);
10460 case 0x6: /* sbc */
10461 if (s
->condexec_mask
) {
10462 gen_sub_carry(tmp
, tmp
, tmp2
);
10464 gen_sbc_CC(tmp
, tmp
, tmp2
);
10467 case 0x7: /* ror */
10468 if (s
->condexec_mask
) {
10469 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10470 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10472 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10473 gen_logic_CC(tmp2
);
10476 case 0x8: /* tst */
10477 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10481 case 0x9: /* neg */
10482 if (s
->condexec_mask
)
10483 tcg_gen_neg_i32(tmp
, tmp2
);
10485 gen_sub_CC(tmp
, tmp
, tmp2
);
10487 case 0xa: /* cmp */
10488 gen_sub_CC(tmp
, tmp
, tmp2
);
10491 case 0xb: /* cmn */
10492 gen_add_CC(tmp
, tmp
, tmp2
);
10495 case 0xc: /* orr */
10496 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10497 if (!s
->condexec_mask
)
10500 case 0xd: /* mul */
10501 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10502 if (!s
->condexec_mask
)
10505 case 0xe: /* bic */
10506 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10507 if (!s
->condexec_mask
)
10510 case 0xf: /* mvn */
10511 tcg_gen_not_i32(tmp2
, tmp2
);
10512 if (!s
->condexec_mask
)
10513 gen_logic_CC(tmp2
);
10520 store_reg(s
, rm
, tmp2
);
10522 tcg_temp_free_i32(tmp
);
10524 store_reg(s
, rd
, tmp
);
10525 tcg_temp_free_i32(tmp2
);
10528 tcg_temp_free_i32(tmp
);
10529 tcg_temp_free_i32(tmp2
);
10534 /* load/store register offset. */
10536 rn
= (insn
>> 3) & 7;
10537 rm
= (insn
>> 6) & 7;
10538 op
= (insn
>> 9) & 7;
10539 addr
= load_reg(s
, rn
);
10540 tmp
= load_reg(s
, rm
);
10541 tcg_gen_add_i32(addr
, addr
, tmp
);
10542 tcg_temp_free_i32(tmp
);
10544 if (op
< 3) { /* store */
10545 tmp
= load_reg(s
, rd
);
10547 tmp
= tcg_temp_new_i32();
10552 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10555 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
10558 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
10560 case 3: /* ldrsb */
10561 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
10564 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10567 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10570 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10572 case 7: /* ldrsh */
10573 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
10576 if (op
>= 3) { /* load */
10577 store_reg(s
, rd
, tmp
);
10579 tcg_temp_free_i32(tmp
);
10581 tcg_temp_free_i32(addr
);
10585 /* load/store word immediate offset */
10587 rn
= (insn
>> 3) & 7;
10588 addr
= load_reg(s
, rn
);
10589 val
= (insn
>> 4) & 0x7c;
10590 tcg_gen_addi_i32(addr
, addr
, val
);
10592 if (insn
& (1 << 11)) {
10594 tmp
= tcg_temp_new_i32();
10595 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10596 store_reg(s
, rd
, tmp
);
10599 tmp
= load_reg(s
, rd
);
10600 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10601 tcg_temp_free_i32(tmp
);
10603 tcg_temp_free_i32(addr
);
10607 /* load/store byte immediate offset */
10609 rn
= (insn
>> 3) & 7;
10610 addr
= load_reg(s
, rn
);
10611 val
= (insn
>> 6) & 0x1f;
10612 tcg_gen_addi_i32(addr
, addr
, val
);
10614 if (insn
& (1 << 11)) {
10616 tmp
= tcg_temp_new_i32();
10617 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10618 store_reg(s
, rd
, tmp
);
10621 tmp
= load_reg(s
, rd
);
10622 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
10623 tcg_temp_free_i32(tmp
);
10625 tcg_temp_free_i32(addr
);
10629 /* load/store halfword immediate offset */
10631 rn
= (insn
>> 3) & 7;
10632 addr
= load_reg(s
, rn
);
10633 val
= (insn
>> 5) & 0x3e;
10634 tcg_gen_addi_i32(addr
, addr
, val
);
10636 if (insn
& (1 << 11)) {
10638 tmp
= tcg_temp_new_i32();
10639 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10640 store_reg(s
, rd
, tmp
);
10643 tmp
= load_reg(s
, rd
);
10644 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
10645 tcg_temp_free_i32(tmp
);
10647 tcg_temp_free_i32(addr
);
10651 /* load/store from stack */
10652 rd
= (insn
>> 8) & 7;
10653 addr
= load_reg(s
, 13);
10654 val
= (insn
& 0xff) * 4;
10655 tcg_gen_addi_i32(addr
, addr
, val
);
10657 if (insn
& (1 << 11)) {
10659 tmp
= tcg_temp_new_i32();
10660 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10661 store_reg(s
, rd
, tmp
);
10664 tmp
= load_reg(s
, rd
);
10665 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10666 tcg_temp_free_i32(tmp
);
10668 tcg_temp_free_i32(addr
);
10672 /* add to high reg */
10673 rd
= (insn
>> 8) & 7;
10674 if (insn
& (1 << 11)) {
10676 tmp
= load_reg(s
, 13);
10678 /* PC. bit 1 is ignored. */
10679 tmp
= tcg_temp_new_i32();
10680 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10682 val
= (insn
& 0xff) * 4;
10683 tcg_gen_addi_i32(tmp
, tmp
, val
);
10684 store_reg(s
, rd
, tmp
);
10689 op
= (insn
>> 8) & 0xf;
10692 /* adjust stack pointer */
10693 tmp
= load_reg(s
, 13);
10694 val
= (insn
& 0x7f) * 4;
10695 if (insn
& (1 << 7))
10696 val
= -(int32_t)val
;
10697 tcg_gen_addi_i32(tmp
, tmp
, val
);
10698 store_reg(s
, 13, tmp
);
10701 case 2: /* sign/zero extend. */
10704 rm
= (insn
>> 3) & 7;
10705 tmp
= load_reg(s
, rm
);
10706 switch ((insn
>> 6) & 3) {
10707 case 0: gen_sxth(tmp
); break;
10708 case 1: gen_sxtb(tmp
); break;
10709 case 2: gen_uxth(tmp
); break;
10710 case 3: gen_uxtb(tmp
); break;
10712 store_reg(s
, rd
, tmp
);
10714 case 4: case 5: case 0xc: case 0xd:
10716 addr
= load_reg(s
, 13);
10717 if (insn
& (1 << 8))
10721 for (i
= 0; i
< 8; i
++) {
10722 if (insn
& (1 << i
))
10725 if ((insn
& (1 << 11)) == 0) {
10726 tcg_gen_addi_i32(addr
, addr
, -offset
);
10728 for (i
= 0; i
< 8; i
++) {
10729 if (insn
& (1 << i
)) {
10730 if (insn
& (1 << 11)) {
10732 tmp
= tcg_temp_new_i32();
10733 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10734 store_reg(s
, i
, tmp
);
10737 tmp
= load_reg(s
, i
);
10738 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10739 tcg_temp_free_i32(tmp
);
10741 /* advance to the next address. */
10742 tcg_gen_addi_i32(addr
, addr
, 4);
10745 TCGV_UNUSED_I32(tmp
);
10746 if (insn
& (1 << 8)) {
10747 if (insn
& (1 << 11)) {
10749 tmp
= tcg_temp_new_i32();
10750 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10751 /* don't set the pc until the rest of the instruction
10755 tmp
= load_reg(s
, 14);
10756 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10757 tcg_temp_free_i32(tmp
);
10759 tcg_gen_addi_i32(addr
, addr
, 4);
10761 if ((insn
& (1 << 11)) == 0) {
10762 tcg_gen_addi_i32(addr
, addr
, -offset
);
10764 /* write back the new stack pointer */
10765 store_reg(s
, 13, addr
);
10766 /* set the new PC value */
10767 if ((insn
& 0x0900) == 0x0900) {
10768 store_reg_from_load(env
, s
, 15, tmp
);
10772 case 1: case 3: case 9: case 11: /* czb */
10774 tmp
= load_reg(s
, rm
);
10775 s
->condlabel
= gen_new_label();
10777 if (insn
& (1 << 11))
10778 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10780 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10781 tcg_temp_free_i32(tmp
);
10782 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10783 val
= (uint32_t)s
->pc
+ 2;
10788 case 15: /* IT, nop-hint. */
10789 if ((insn
& 0xf) == 0) {
10790 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10794 s
->condexec_cond
= (insn
>> 4) & 0xe;
10795 s
->condexec_mask
= insn
& 0x1f;
10796 /* No actual code generated for this insn, just setup state. */
10799 case 0xe: /* bkpt */
10801 int imm8
= extract32(insn
, 0, 8);
10803 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10807 case 0xa: /* rev */
10809 rn
= (insn
>> 3) & 0x7;
10811 tmp
= load_reg(s
, rn
);
10812 switch ((insn
>> 6) & 3) {
10813 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10814 case 1: gen_rev16(tmp
); break;
10815 case 3: gen_revsh(tmp
); break;
10816 default: goto illegal_op
;
10818 store_reg(s
, rd
, tmp
);
10822 switch ((insn
>> 5) & 7) {
10826 if (((insn
>> 3) & 1) != s
->cpsr_e
) {
10827 /* Dynamic endianness switching not implemented. */
10828 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10839 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10842 addr
= tcg_const_i32(19);
10843 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10844 tcg_temp_free_i32(addr
);
10848 addr
= tcg_const_i32(16);
10849 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10850 tcg_temp_free_i32(addr
);
10852 tcg_temp_free_i32(tmp
);
10855 if (insn
& (1 << 4)) {
10856 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10860 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10875 /* load/store multiple */
10876 TCGv_i32 loaded_var
;
10877 TCGV_UNUSED_I32(loaded_var
);
10878 rn
= (insn
>> 8) & 0x7;
10879 addr
= load_reg(s
, rn
);
10880 for (i
= 0; i
< 8; i
++) {
10881 if (insn
& (1 << i
)) {
10882 if (insn
& (1 << 11)) {
10884 tmp
= tcg_temp_new_i32();
10885 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10889 store_reg(s
, i
, tmp
);
10893 tmp
= load_reg(s
, i
);
10894 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10895 tcg_temp_free_i32(tmp
);
10897 /* advance to the next address */
10898 tcg_gen_addi_i32(addr
, addr
, 4);
10901 if ((insn
& (1 << rn
)) == 0) {
10902 /* base reg not in list: base register writeback */
10903 store_reg(s
, rn
, addr
);
10905 /* base reg in list: if load, complete it now */
10906 if (insn
& (1 << 11)) {
10907 store_reg(s
, rn
, loaded_var
);
10909 tcg_temp_free_i32(addr
);
10914 /* conditional branch or swi */
10915 cond
= (insn
>> 8) & 0xf;
10921 gen_set_pc_im(s
, s
->pc
);
10922 s
->svc_imm
= extract32(insn
, 0, 8);
10923 s
->is_jmp
= DISAS_SWI
;
10926 /* generate a conditional jump to next instruction */
10927 s
->condlabel
= gen_new_label();
10928 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10931 /* jump to the offset */
10932 val
= (uint32_t)s
->pc
+ 2;
10933 offset
= ((int32_t)insn
<< 24) >> 24;
10934 val
+= offset
<< 1;
10939 if (insn
& (1 << 11)) {
10940 if (disas_thumb2_insn(env
, s
, insn
))
10944 /* unconditional branch */
10945 val
= (uint32_t)s
->pc
;
10946 offset
= ((int32_t)insn
<< 21) >> 21;
10947 val
+= (offset
<< 1) + 2;
10952 if (disas_thumb2_insn(env
, s
, insn
))
10958 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
10962 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
10965 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10966 basic block 'tb'. If search_pc is TRUE, also generate PC
10967 information for each intermediate instruction. */
10968 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10969 TranslationBlock
*tb
,
10972 CPUState
*cs
= CPU(cpu
);
10973 CPUARMState
*env
= &cpu
->env
;
10974 DisasContext dc1
, *dc
= &dc1
;
10976 uint16_t *gen_opc_end
;
10978 target_ulong pc_start
;
10979 target_ulong next_page_start
;
10983 /* generate intermediate code */
10985 /* The A64 decoder has its own top level loop, because it doesn't need
10986 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10988 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10989 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10997 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10999 dc
->is_jmp
= DISAS_NEXT
;
11001 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11005 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11006 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11007 dc
->cpsr_e
= ARM_TBFLAG_CPSR_E(tb
->flags
);
11008 dc
->mo_endianness
= arm_tbflag_is_data_be(tb
->flags
) ? MO_BE
: MO_LE
;
11009 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11010 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11011 #if !defined(CONFIG_USER_ONLY)
11012 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
11014 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
11015 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11016 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11017 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11018 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11019 dc
->cp_regs
= cpu
->cp_regs
;
11020 dc
->current_el
= arm_current_el(env
);
11021 dc
->features
= env
->features
;
11023 /* Single step state. The code-generation logic here is:
11025 * generate code with no special handling for single-stepping (except
11026 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11027 * this happens anyway because those changes are all system register or
11029 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11030 * emit code for one insn
11031 * emit code to clear PSTATE.SS
11032 * emit code to generate software step exception for completed step
11033 * end TB (as usual for having generated an exception)
11034 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11035 * emit code to generate a software step exception
11038 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11039 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11040 dc
->is_ldex
= false;
11041 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11043 cpu_F0s
= tcg_temp_new_i32();
11044 cpu_F1s
= tcg_temp_new_i32();
11045 cpu_F0d
= tcg_temp_new_i64();
11046 cpu_F1d
= tcg_temp_new_i64();
11049 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11050 cpu_M0
= tcg_temp_new_i64();
11051 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11054 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11055 if (max_insns
== 0)
11056 max_insns
= CF_COUNT_MASK
;
11060 tcg_clear_temp_count();
11062 /* A note on handling of the condexec (IT) bits:
11064 * We want to avoid the overhead of having to write the updated condexec
11065 * bits back to the CPUARMState for every instruction in an IT block. So:
11066 * (1) if the condexec bits are not already zero then we write
11067 * zero back into the CPUARMState now. This avoids complications trying
11068 * to do it at the end of the block. (For example if we don't do this
11069 * it's hard to identify whether we can safely skip writing condexec
11070 * at the end of the TB, which we definitely want to do for the case
11071 * where a TB doesn't do anything with the IT state at all.)
11072 * (2) if we are going to leave the TB then we call gen_set_condexec()
11073 * which will write the correct value into CPUARMState if zero is wrong.
11074 * This is done both for leaving the TB at the end, and for leaving
11075 * it because of an exception we know will happen, which is done in
11076 * gen_exception_insn(). The latter is necessary because we need to
11077 * leave the TB with the PC/IT state just prior to execution of the
11078 * instruction which caused the exception.
11079 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11080 * then the CPUARMState will be wrong and we need to reset it.
11081 * This is handled in the same way as restoration of the
11082 * PC in these situations: we will be called again with search_pc=1
11083 * and generate a mapping of the condexec bits for each PC in
11084 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11085 * this to restore the condexec bits.
11087 * Note that there are no instructions which can read the condexec
11088 * bits, and none which can write non-static values to them, so
11089 * we don't need to care about whether CPUARMState is correct in the
11093 /* Reset the conditional execution bits immediately. This avoids
11094 complications trying to do it at the end of the block. */
11095 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11097 TCGv_i32 tmp
= tcg_temp_new_i32();
11098 tcg_gen_movi_i32(tmp
, 0);
11099 store_cpu_field(tmp
, condexec_bits
);
11102 #ifdef CONFIG_USER_ONLY
11103 /* Intercept jump to the magic kernel page. */
11104 if (dc
->pc
>= 0xffff0000) {
11105 /* We always get here via a jump, so know we are not in a
11106 conditional execution block. */
11107 gen_exception_internal(EXCP_KERNEL_TRAP
);
11108 dc
->is_jmp
= DISAS_UPDATE
;
11112 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
11113 /* We always get here via a jump, so know we are not in a
11114 conditional execution block. */
11115 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11116 dc
->is_jmp
= DISAS_UPDATE
;
11121 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11122 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11123 if (bp
->pc
== dc
->pc
) {
11124 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11125 /* Advance PC so that clearing the breakpoint will
11126 invalidate this TB. */
11128 goto done_generating
;
11133 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11137 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11139 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11140 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11141 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11142 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11145 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11148 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11149 tcg_gen_debug_insn_start(dc
->pc
);
11152 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11153 /* Singlestep state is Active-pending.
11154 * If we're in this state at the start of a TB then either
11155 * a) we just took an exception to an EL which is being debugged
11156 * and this is the first insn in the exception handler
11157 * b) debug exceptions were masked and we just unmasked them
11158 * without changing EL (eg by clearing PSTATE.D)
11159 * In either case we're going to take a swstep exception in the
11160 * "did not step an insn" case, and so the syndrome ISV and EX
11161 * bits should be zero.
11163 assert(num_insns
== 0);
11164 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11165 goto done_generating
;
11169 disas_thumb_insn(env
, dc
);
11170 if (dc
->condexec_mask
) {
11171 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11172 | ((dc
->condexec_mask
>> 4) & 1);
11173 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11174 if (dc
->condexec_mask
== 0) {
11175 dc
->condexec_cond
= 0;
11179 disas_arm_insn(env
, dc
);
11182 if (dc
->condjmp
&& !dc
->is_jmp
) {
11183 gen_set_label(dc
->condlabel
);
11187 if (tcg_check_temp_count()) {
11188 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11192 /* Translation stops when a conditional branch is encountered.
11193 * Otherwise the subsequent code could get translated several times.
11194 * Also stop translation when a page boundary is reached. This
11195 * ensures prefetch aborts occur at the right place. */
11197 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
11198 !cs
->singlestep_enabled
&&
11201 dc
->pc
< next_page_start
&&
11202 num_insns
< max_insns
);
11204 if (tb
->cflags
& CF_LAST_IO
) {
11206 /* FIXME: This can theoretically happen with self-modifying
11208 cpu_abort(cs
, "IO on conditional branch instruction");
11213 /* At this stage dc->condjmp will only be set when the skipped
11214 instruction was a conditional branch or trap, and the PC has
11215 already been written. */
11216 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11217 /* Make sure the pc is updated, and raise a debug exception. */
11219 gen_set_condexec(dc
);
11220 if (dc
->is_jmp
== DISAS_SWI
) {
11221 gen_ss_advance(dc
);
11222 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11223 } else if (dc
->is_jmp
== DISAS_HVC
) {
11224 gen_ss_advance(dc
);
11225 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11226 } else if (dc
->is_jmp
== DISAS_SMC
) {
11227 gen_ss_advance(dc
);
11228 gen_exception(EXCP_SMC
, syn_aa32_smc());
11229 } else if (dc
->ss_active
) {
11230 gen_step_complete_exception(dc
);
11232 gen_exception_internal(EXCP_DEBUG
);
11234 gen_set_label(dc
->condlabel
);
11236 if (dc
->condjmp
|| !dc
->is_jmp
) {
11237 gen_set_pc_im(dc
, dc
->pc
);
11240 gen_set_condexec(dc
);
11241 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11242 gen_ss_advance(dc
);
11243 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11244 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11245 gen_ss_advance(dc
);
11246 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11247 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11248 gen_ss_advance(dc
);
11249 gen_exception(EXCP_SMC
, syn_aa32_smc());
11250 } else if (dc
->ss_active
) {
11251 gen_step_complete_exception(dc
);
11253 /* FIXME: Single stepping a WFI insn will not halt
11255 gen_exception_internal(EXCP_DEBUG
);
11258 /* While branches must always occur at the end of an IT block,
11259 there are a few other things that can cause us to terminate
11260 the TB in the middle of an IT block:
11261 - Exception generating instructions (bkpt, swi, undefined).
11263 - Hardware watchpoints.
11264 Hardware breakpoints have already been handled and skip this code.
11266 gen_set_condexec(dc
);
11267 switch(dc
->is_jmp
) {
11269 gen_goto_tb(dc
, 1, dc
->pc
);
11274 /* indicate that the hash table must be used to find the next TB */
11275 tcg_gen_exit_tb(0);
11277 case DISAS_TB_JUMP
:
11278 /* nothing more to generate */
11281 gen_helper_wfi(cpu_env
);
11284 gen_helper_wfe(cpu_env
);
11287 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11290 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11293 gen_exception(EXCP_SMC
, syn_aa32_smc());
11297 gen_set_label(dc
->condlabel
);
11298 gen_set_condexec(dc
);
11299 gen_goto_tb(dc
, 1, dc
->pc
);
11305 gen_tb_end(tb
, num_insns
);
11306 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
11309 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11310 qemu_log("----------------\n");
11311 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11312 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11313 dc
->thumb
| (dc
->sctlr_b
<< 1));
11318 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
11321 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11323 tb
->size
= dc
->pc
- pc_start
;
11324 tb
->icount
= num_insns
;
11328 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11330 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11333 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11335 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11338 static const char *cpu_mode_names
[16] = {
11339 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11340 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11343 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11346 ARMCPU
*cpu
= ARM_CPU(cs
);
11347 CPUARMState
*env
= &cpu
->env
;
11352 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11356 for(i
=0;i
<16;i
++) {
11357 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11359 cpu_fprintf(f
, "\n");
11361 cpu_fprintf(f
, " ");
11363 psr
= cpsr_read(env
);
11364 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11366 psr
& (1 << 31) ? 'N' : '-',
11367 psr
& (1 << 30) ? 'Z' : '-',
11368 psr
& (1 << 29) ? 'C' : '-',
11369 psr
& (1 << 28) ? 'V' : '-',
11370 psr
& CPSR_T
? 'T' : 'A',
11371 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11373 if (flags
& CPU_DUMP_FPU
) {
11374 int numvfpregs
= 0;
11375 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11378 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11381 for (i
= 0; i
< numvfpregs
; i
++) {
11382 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11383 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11384 i
* 2, (uint32_t)v
,
11385 i
* 2 + 1, (uint32_t)(v
>> 32),
11388 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11392 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11395 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11396 env
->condexec_bits
= 0;
11398 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11399 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];