4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "disas/disas.h"
31 #include "qemu/bitops.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_i32 cpu_exclusive_addr
;
65 static TCGv_i32 cpu_exclusive_val
;
66 static TCGv_i32 cpu_exclusive_high
;
67 #ifdef CONFIG_USER_ONLY
68 static TCGv_i32 cpu_exclusive_test
;
69 static TCGv_i32 cpu_exclusive_info
;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s
, cpu_F1s
;
74 static TCGv_i64 cpu_F0d
, cpu_F1d
;
76 #include "exec/gen-icount.h"
78 static const char *regnames
[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
103 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
104 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
105 #ifdef CONFIG_USER_ONLY
106 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
107 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
108 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
109 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
112 a64_translate_init();
115 static inline TCGv_i32
load_cpu_offset(int offset
)
117 TCGv_i32 tmp
= tcg_temp_new_i32();
118 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
122 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
124 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
126 tcg_gen_st_i32(var
, cpu_env
, offset
);
127 tcg_temp_free_i32(var
);
130 #define store_cpu_field(var, name) \
131 store_cpu_offset(var, offsetof(CPUARMState, name))
133 /* Set a variable to the value of a CPU register. */
134 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
138 /* normally, since we updated PC, we need only to add one insn */
140 addr
= (long)s
->pc
+ 2;
142 addr
= (long)s
->pc
+ 4;
143 tcg_gen_movi_i32(var
, addr
);
145 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
149 /* Create a new temporary and set it to the value of a CPU register. */
150 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
152 TCGv_i32 tmp
= tcg_temp_new_i32();
153 load_reg_var(s
, tmp
, reg
);
157 /* Set a CPU register. The source must be a temporary and will be
159 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
162 tcg_gen_andi_i32(var
, var
, ~1);
163 s
->is_jmp
= DISAS_JUMP
;
165 tcg_gen_mov_i32(cpu_R
[reg
], var
);
166 tcg_temp_free_i32(var
);
169 /* Value extensions. */
170 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
171 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
172 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
173 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
175 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
176 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
179 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
181 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
182 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
183 tcg_temp_free_i32(tmp_mask
);
185 /* Set NZCV flags from the high 4 bits of var. */
186 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
188 static void gen_exception(int excp
)
190 TCGv_i32 tmp
= tcg_temp_new_i32();
191 tcg_gen_movi_i32(tmp
, excp
);
192 gen_helper_exception(cpu_env
, tmp
);
193 tcg_temp_free_i32(tmp
);
196 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
198 TCGv_i32 tmp1
= tcg_temp_new_i32();
199 TCGv_i32 tmp2
= tcg_temp_new_i32();
200 tcg_gen_ext16s_i32(tmp1
, a
);
201 tcg_gen_ext16s_i32(tmp2
, b
);
202 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
203 tcg_temp_free_i32(tmp2
);
204 tcg_gen_sari_i32(a
, a
, 16);
205 tcg_gen_sari_i32(b
, b
, 16);
206 tcg_gen_mul_i32(b
, b
, a
);
207 tcg_gen_mov_i32(a
, tmp1
);
208 tcg_temp_free_i32(tmp1
);
211 /* Byteswap each halfword. */
212 static void gen_rev16(TCGv_i32 var
)
214 TCGv_i32 tmp
= tcg_temp_new_i32();
215 tcg_gen_shri_i32(tmp
, var
, 8);
216 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
217 tcg_gen_shli_i32(var
, var
, 8);
218 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
219 tcg_gen_or_i32(var
, var
, tmp
);
220 tcg_temp_free_i32(tmp
);
223 /* Byteswap low halfword and sign extend. */
224 static void gen_revsh(TCGv_i32 var
)
226 tcg_gen_ext16u_i32(var
, var
);
227 tcg_gen_bswap16_i32(var
, var
);
228 tcg_gen_ext16s_i32(var
, var
);
231 /* Unsigned bitfield extract. */
232 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
235 tcg_gen_shri_i32(var
, var
, shift
);
236 tcg_gen_andi_i32(var
, var
, mask
);
239 /* Signed bitfield extract. */
240 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
245 tcg_gen_sari_i32(var
, var
, shift
);
246 if (shift
+ width
< 32) {
247 signbit
= 1u << (width
- 1);
248 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
249 tcg_gen_xori_i32(var
, var
, signbit
);
250 tcg_gen_subi_i32(var
, var
, signbit
);
254 /* Return (b << 32) + a. Mark inputs as dead */
255 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
257 TCGv_i64 tmp64
= tcg_temp_new_i64();
259 tcg_gen_extu_i32_i64(tmp64
, b
);
260 tcg_temp_free_i32(b
);
261 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
262 tcg_gen_add_i64(a
, tmp64
, a
);
264 tcg_temp_free_i64(tmp64
);
268 /* Return (b << 32) - a. Mark inputs as dead. */
269 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
271 TCGv_i64 tmp64
= tcg_temp_new_i64();
273 tcg_gen_extu_i32_i64(tmp64
, b
);
274 tcg_temp_free_i32(b
);
275 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
276 tcg_gen_sub_i64(a
, tmp64
, a
);
278 tcg_temp_free_i64(tmp64
);
282 /* 32x32->64 multiply. Marks inputs as dead. */
283 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
285 TCGv_i32 lo
= tcg_temp_new_i32();
286 TCGv_i32 hi
= tcg_temp_new_i32();
289 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
290 tcg_temp_free_i32(a
);
291 tcg_temp_free_i32(b
);
293 ret
= tcg_temp_new_i64();
294 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
295 tcg_temp_free_i32(lo
);
296 tcg_temp_free_i32(hi
);
301 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
303 TCGv_i32 lo
= tcg_temp_new_i32();
304 TCGv_i32 hi
= tcg_temp_new_i32();
307 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
308 tcg_temp_free_i32(a
);
309 tcg_temp_free_i32(b
);
311 ret
= tcg_temp_new_i64();
312 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
313 tcg_temp_free_i32(lo
);
314 tcg_temp_free_i32(hi
);
319 /* Swap low and high halfwords. */
320 static void gen_swap_half(TCGv_i32 var
)
322 TCGv_i32 tmp
= tcg_temp_new_i32();
323 tcg_gen_shri_i32(tmp
, var
, 16);
324 tcg_gen_shli_i32(var
, var
, 16);
325 tcg_gen_or_i32(var
, var
, tmp
);
326 tcg_temp_free_i32(tmp
);
329 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
330 tmp = (t0 ^ t1) & 0x8000;
333 t0 = (t0 + t1) ^ tmp;
336 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
338 TCGv_i32 tmp
= tcg_temp_new_i32();
339 tcg_gen_xor_i32(tmp
, t0
, t1
);
340 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
341 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
342 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
343 tcg_gen_add_i32(t0
, t0
, t1
);
344 tcg_gen_xor_i32(t0
, t0
, tmp
);
345 tcg_temp_free_i32(tmp
);
346 tcg_temp_free_i32(t1
);
349 /* Set CF to the top bit of var. */
350 static void gen_set_CF_bit31(TCGv_i32 var
)
352 tcg_gen_shri_i32(cpu_CF
, var
, 31);
355 /* Set N and Z flags from var. */
356 static inline void gen_logic_CC(TCGv_i32 var
)
358 tcg_gen_mov_i32(cpu_NF
, var
);
359 tcg_gen_mov_i32(cpu_ZF
, var
);
363 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
365 tcg_gen_add_i32(t0
, t0
, t1
);
366 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
369 /* dest = T0 + T1 + CF. */
370 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
372 tcg_gen_add_i32(dest
, t0
, t1
);
373 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
376 /* dest = T0 - T1 + CF - 1. */
377 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
379 tcg_gen_sub_i32(dest
, t0
, t1
);
380 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
381 tcg_gen_subi_i32(dest
, dest
, 1);
384 /* dest = T0 + T1. Compute C, N, V and Z flags */
385 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
387 TCGv_i32 tmp
= tcg_temp_new_i32();
388 tcg_gen_movi_i32(tmp
, 0);
389 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
390 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
391 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
392 tcg_gen_xor_i32(tmp
, t0
, t1
);
393 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
394 tcg_temp_free_i32(tmp
);
395 tcg_gen_mov_i32(dest
, cpu_NF
);
398 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
399 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
401 TCGv_i32 tmp
= tcg_temp_new_i32();
402 if (TCG_TARGET_HAS_add2_i32
) {
403 tcg_gen_movi_i32(tmp
, 0);
404 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
405 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
407 TCGv_i64 q0
= tcg_temp_new_i64();
408 TCGv_i64 q1
= tcg_temp_new_i64();
409 tcg_gen_extu_i32_i64(q0
, t0
);
410 tcg_gen_extu_i32_i64(q1
, t1
);
411 tcg_gen_add_i64(q0
, q0
, q1
);
412 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
413 tcg_gen_add_i64(q0
, q0
, q1
);
414 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
415 tcg_temp_free_i64(q0
);
416 tcg_temp_free_i64(q1
);
418 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
419 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
420 tcg_gen_xor_i32(tmp
, t0
, t1
);
421 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
422 tcg_temp_free_i32(tmp
);
423 tcg_gen_mov_i32(dest
, cpu_NF
);
426 /* dest = T0 - T1. Compute C, N, V and Z flags */
427 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
430 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
431 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
432 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
433 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
434 tmp
= tcg_temp_new_i32();
435 tcg_gen_xor_i32(tmp
, t0
, t1
);
436 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
437 tcg_temp_free_i32(tmp
);
438 tcg_gen_mov_i32(dest
, cpu_NF
);
441 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
442 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
444 TCGv_i32 tmp
= tcg_temp_new_i32();
445 tcg_gen_not_i32(tmp
, t1
);
446 gen_adc_CC(dest
, t0
, tmp
);
447 tcg_temp_free_i32(tmp
);
450 #define GEN_SHIFT(name) \
451 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
453 TCGv_i32 tmp1, tmp2, tmp3; \
454 tmp1 = tcg_temp_new_i32(); \
455 tcg_gen_andi_i32(tmp1, t1, 0xff); \
456 tmp2 = tcg_const_i32(0); \
457 tmp3 = tcg_const_i32(0x1f); \
458 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
459 tcg_temp_free_i32(tmp3); \
460 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
461 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
462 tcg_temp_free_i32(tmp2); \
463 tcg_temp_free_i32(tmp1); \
469 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
472 tmp1
= tcg_temp_new_i32();
473 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
474 tmp2
= tcg_const_i32(0x1f);
475 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
476 tcg_temp_free_i32(tmp2
);
477 tcg_gen_sar_i32(dest
, t0
, tmp1
);
478 tcg_temp_free_i32(tmp1
);
481 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
483 TCGv_i32 c0
= tcg_const_i32(0);
484 TCGv_i32 tmp
= tcg_temp_new_i32();
485 tcg_gen_neg_i32(tmp
, src
);
486 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
487 tcg_temp_free_i32(c0
);
488 tcg_temp_free_i32(tmp
);
491 static void shifter_out_im(TCGv_i32 var
, int shift
)
494 tcg_gen_andi_i32(cpu_CF
, var
, 1);
496 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
498 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
503 /* Shift by immediate. Includes special handling for shift == 0. */
504 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
505 int shift
, int flags
)
511 shifter_out_im(var
, 32 - shift
);
512 tcg_gen_shli_i32(var
, var
, shift
);
518 tcg_gen_shri_i32(cpu_CF
, var
, 31);
520 tcg_gen_movi_i32(var
, 0);
523 shifter_out_im(var
, shift
- 1);
524 tcg_gen_shri_i32(var
, var
, shift
);
531 shifter_out_im(var
, shift
- 1);
534 tcg_gen_sari_i32(var
, var
, shift
);
536 case 3: /* ROR/RRX */
539 shifter_out_im(var
, shift
- 1);
540 tcg_gen_rotri_i32(var
, var
, shift
); break;
542 TCGv_i32 tmp
= tcg_temp_new_i32();
543 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
545 shifter_out_im(var
, 0);
546 tcg_gen_shri_i32(var
, var
, 1);
547 tcg_gen_or_i32(var
, var
, tmp
);
548 tcg_temp_free_i32(tmp
);
553 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
554 TCGv_i32 shift
, int flags
)
558 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
559 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
560 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
561 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
566 gen_shl(var
, var
, shift
);
569 gen_shr(var
, var
, shift
);
572 gen_sar(var
, var
, shift
);
574 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
575 tcg_gen_rotr_i32(var
, var
, shift
); break;
578 tcg_temp_free_i32(shift
);
581 #define PAS_OP(pfx) \
583 case 0: gen_pas_helper(glue(pfx,add16)); break; \
584 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
585 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
586 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
587 case 4: gen_pas_helper(glue(pfx,add8)); break; \
588 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
590 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
595 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
597 tmp
= tcg_temp_new_ptr();
598 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
600 tcg_temp_free_ptr(tmp
);
603 tmp
= tcg_temp_new_ptr();
604 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
606 tcg_temp_free_ptr(tmp
);
608 #undef gen_pas_helper
609 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
622 #undef gen_pas_helper
627 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
628 #define PAS_OP(pfx) \
630 case 0: gen_pas_helper(glue(pfx,add8)); break; \
631 case 1: gen_pas_helper(glue(pfx,add16)); break; \
632 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
633 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
634 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
635 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
637 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
642 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
644 tmp
= tcg_temp_new_ptr();
645 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
647 tcg_temp_free_ptr(tmp
);
650 tmp
= tcg_temp_new_ptr();
651 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
653 tcg_temp_free_ptr(tmp
);
655 #undef gen_pas_helper
656 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
669 #undef gen_pas_helper
675 * generate a conditional branch based on ARM condition code cc.
676 * This is common between ARM and Aarch64 targets.
678 void arm_gen_test_cc(int cc
, int label
)
685 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
688 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
691 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
694 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
697 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
706 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
708 case 8: /* hi: C && !Z */
709 inv
= gen_new_label();
710 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
711 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
714 case 9: /* ls: !C || Z */
715 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
716 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
718 case 10: /* ge: N == V -> N ^ V == 0 */
719 tmp
= tcg_temp_new_i32();
720 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
721 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
722 tcg_temp_free_i32(tmp
);
724 case 11: /* lt: N != V -> N ^ V != 0 */
725 tmp
= tcg_temp_new_i32();
726 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
727 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
728 tcg_temp_free_i32(tmp
);
730 case 12: /* gt: !Z && N == V */
731 inv
= gen_new_label();
732 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
733 tmp
= tcg_temp_new_i32();
734 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
735 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
736 tcg_temp_free_i32(tmp
);
739 case 13: /* le: Z || N != V */
740 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
741 tmp
= tcg_temp_new_i32();
742 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
743 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
744 tcg_temp_free_i32(tmp
);
747 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
752 static const uint8_t table_logic_cc
[16] = {
771 /* Set PC and Thumb state from an immediate address. */
772 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
776 s
->is_jmp
= DISAS_UPDATE
;
777 if (s
->thumb
!= (addr
& 1)) {
778 tmp
= tcg_temp_new_i32();
779 tcg_gen_movi_i32(tmp
, addr
& 1);
780 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
781 tcg_temp_free_i32(tmp
);
783 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
786 /* Set PC and Thumb state from var. var is marked as dead. */
787 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
789 s
->is_jmp
= DISAS_UPDATE
;
790 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
791 tcg_gen_andi_i32(var
, var
, 1);
792 store_cpu_field(var
, thumb
);
795 /* Variant of store_reg which uses branch&exchange logic when storing
796 to r15 in ARM architecture v7 and above. The source must be a temporary
797 and will be marked as dead. */
798 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
799 int reg
, TCGv_i32 var
)
801 if (reg
== 15 && ENABLE_ARCH_7
) {
804 store_reg(s
, reg
, var
);
808 /* Variant of store_reg which uses branch&exchange logic when storing
809 * to r15 in ARM architecture v5T and above. This is used for storing
810 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
811 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
812 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
813 int reg
, TCGv_i32 var
)
815 if (reg
== 15 && ENABLE_ARCH_5
) {
818 store_reg(s
, reg
, var
);
822 /* Abstractions of "generate code to do a guest load/store for
823 * AArch32", where a vaddr is always 32 bits (and is zero
824 * extended if we're a 64 bit core) and data is also
825 * 32 bits unless specifically doing a 64 bit access.
826 * These functions work like tcg_gen_qemu_{ld,st}* except
827 * that the address argument is TCGv_i32 rather than TCGv.
829 #if TARGET_LONG_BITS == 32
831 #define DO_GEN_LD(SUFF, OPC) \
832 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
834 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
837 #define DO_GEN_ST(SUFF, OPC) \
838 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
840 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
843 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
845 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
848 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
850 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
855 #define DO_GEN_LD(SUFF, OPC) \
856 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
858 TCGv addr64 = tcg_temp_new(); \
859 tcg_gen_extu_i32_i64(addr64, addr); \
860 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
861 tcg_temp_free(addr64); \
864 #define DO_GEN_ST(SUFF, OPC) \
865 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
867 TCGv addr64 = tcg_temp_new(); \
868 tcg_gen_extu_i32_i64(addr64, addr); \
869 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
870 tcg_temp_free(addr64); \
873 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
875 TCGv addr64
= tcg_temp_new();
876 tcg_gen_extu_i32_i64(addr64
, addr
);
877 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
878 tcg_temp_free(addr64
);
881 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
883 TCGv addr64
= tcg_temp_new();
884 tcg_gen_extu_i32_i64(addr64
, addr
);
885 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
886 tcg_temp_free(addr64
);
893 DO_GEN_LD(16s
, MO_TESW
)
894 DO_GEN_LD(16u, MO_TEUW
)
895 DO_GEN_LD(32u, MO_TEUL
)
897 DO_GEN_ST(16, MO_TEUW
)
898 DO_GEN_ST(32, MO_TEUL
)
900 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
902 tcg_gen_movi_i32(cpu_R
[15], val
);
905 /* Force a TB lookup after an instruction that changes the CPU state. */
906 static inline void gen_lookup_tb(DisasContext
*s
)
908 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
909 s
->is_jmp
= DISAS_UPDATE
;
912 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
915 int val
, rm
, shift
, shiftop
;
918 if (!(insn
& (1 << 25))) {
921 if (!(insn
& (1 << 23)))
924 tcg_gen_addi_i32(var
, var
, val
);
928 shift
= (insn
>> 7) & 0x1f;
929 shiftop
= (insn
>> 5) & 3;
930 offset
= load_reg(s
, rm
);
931 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
932 if (!(insn
& (1 << 23)))
933 tcg_gen_sub_i32(var
, var
, offset
);
935 tcg_gen_add_i32(var
, var
, offset
);
936 tcg_temp_free_i32(offset
);
940 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
941 int extra
, TCGv_i32 var
)
946 if (insn
& (1 << 22)) {
948 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
949 if (!(insn
& (1 << 23)))
953 tcg_gen_addi_i32(var
, var
, val
);
957 tcg_gen_addi_i32(var
, var
, extra
);
959 offset
= load_reg(s
, rm
);
960 if (!(insn
& (1 << 23)))
961 tcg_gen_sub_i32(var
, var
, offset
);
963 tcg_gen_add_i32(var
, var
, offset
);
964 tcg_temp_free_i32(offset
);
968 static TCGv_ptr
get_fpstatus_ptr(int neon
)
970 TCGv_ptr statusptr
= tcg_temp_new_ptr();
973 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
975 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
977 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
981 #define VFP_OP2(name) \
982 static inline void gen_vfp_##name(int dp) \
984 TCGv_ptr fpst = get_fpstatus_ptr(0); \
986 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
988 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
990 tcg_temp_free_ptr(fpst); \
1000 static inline void gen_vfp_F1_mul(int dp
)
1002 /* Like gen_vfp_mul() but put result in F1 */
1003 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1005 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1007 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1009 tcg_temp_free_ptr(fpst
);
1012 static inline void gen_vfp_F1_neg(int dp
)
1014 /* Like gen_vfp_neg() but put result in F1 */
1016 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1018 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1022 static inline void gen_vfp_abs(int dp
)
1025 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1027 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1030 static inline void gen_vfp_neg(int dp
)
1033 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1035 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1038 static inline void gen_vfp_sqrt(int dp
)
1041 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1043 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1046 static inline void gen_vfp_cmp(int dp
)
1049 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1051 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1054 static inline void gen_vfp_cmpe(int dp
)
1057 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1059 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1062 static inline void gen_vfp_F1_ld0(int dp
)
1065 tcg_gen_movi_i64(cpu_F1d
, 0);
1067 tcg_gen_movi_i32(cpu_F1s
, 0);
1070 #define VFP_GEN_ITOF(name) \
1071 static inline void gen_vfp_##name(int dp, int neon) \
1073 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1075 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1077 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1079 tcg_temp_free_ptr(statusptr); \
1086 #define VFP_GEN_FTOI(name) \
1087 static inline void gen_vfp_##name(int dp, int neon) \
1089 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1091 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1093 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1095 tcg_temp_free_ptr(statusptr); \
1104 #define VFP_GEN_FIX(name) \
1105 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1107 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1108 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1110 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1112 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1114 tcg_temp_free_i32(tmp_shift); \
1115 tcg_temp_free_ptr(statusptr); \
1127 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1130 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1132 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1136 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1139 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1141 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1146 vfp_reg_offset (int dp
, int reg
)
1149 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1151 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1152 + offsetof(CPU_DoubleU
, l
.upper
);
1154 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1155 + offsetof(CPU_DoubleU
, l
.lower
);
1159 /* Return the offset of a 32-bit piece of a NEON register.
1160 zero is the least significant end of the register. */
1162 neon_reg_offset (int reg
, int n
)
1166 return vfp_reg_offset(0, sreg
);
1169 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1171 TCGv_i32 tmp
= tcg_temp_new_i32();
1172 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1176 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1178 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1179 tcg_temp_free_i32(var
);
1182 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1184 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1187 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1189 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1192 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1193 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1194 #define tcg_gen_st_f32 tcg_gen_st_i32
1195 #define tcg_gen_st_f64 tcg_gen_st_i64
1197 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1200 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1202 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1205 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1208 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1210 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1213 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1216 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1218 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1221 #define ARM_CP_RW_BIT (1 << 20)
1223 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1225 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1228 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1230 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1233 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1235 TCGv_i32 var
= tcg_temp_new_i32();
1236 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1240 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1242 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1243 tcg_temp_free_i32(var
);
1246 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1248 iwmmxt_store_reg(cpu_M0
, rn
);
1251 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1253 iwmmxt_load_reg(cpu_M0
, rn
);
1256 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1258 iwmmxt_load_reg(cpu_V1
, rn
);
1259 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1262 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1264 iwmmxt_load_reg(cpu_V1
, rn
);
1265 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1268 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1270 iwmmxt_load_reg(cpu_V1
, rn
);
1271 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1274 #define IWMMXT_OP(name) \
1275 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1277 iwmmxt_load_reg(cpu_V1, rn); \
1278 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1281 #define IWMMXT_OP_ENV(name) \
1282 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1284 iwmmxt_load_reg(cpu_V1, rn); \
1285 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1288 #define IWMMXT_OP_ENV_SIZE(name) \
1289 IWMMXT_OP_ENV(name##b) \
1290 IWMMXT_OP_ENV(name##w) \
1291 IWMMXT_OP_ENV(name##l)
1293 #define IWMMXT_OP_ENV1(name) \
1294 static inline void gen_op_iwmmxt_##name##_M0(void) \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1310 IWMMXT_OP_ENV_SIZE(unpackl
)
1311 IWMMXT_OP_ENV_SIZE(unpackh
)
1313 IWMMXT_OP_ENV1(unpacklub
)
1314 IWMMXT_OP_ENV1(unpackluw
)
1315 IWMMXT_OP_ENV1(unpacklul
)
1316 IWMMXT_OP_ENV1(unpackhub
)
1317 IWMMXT_OP_ENV1(unpackhuw
)
1318 IWMMXT_OP_ENV1(unpackhul
)
1319 IWMMXT_OP_ENV1(unpacklsb
)
1320 IWMMXT_OP_ENV1(unpacklsw
)
1321 IWMMXT_OP_ENV1(unpacklsl
)
1322 IWMMXT_OP_ENV1(unpackhsb
)
1323 IWMMXT_OP_ENV1(unpackhsw
)
1324 IWMMXT_OP_ENV1(unpackhsl
)
1326 IWMMXT_OP_ENV_SIZE(cmpeq
)
1327 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1328 IWMMXT_OP_ENV_SIZE(cmpgts
)
1330 IWMMXT_OP_ENV_SIZE(mins
)
1331 IWMMXT_OP_ENV_SIZE(minu
)
1332 IWMMXT_OP_ENV_SIZE(maxs
)
1333 IWMMXT_OP_ENV_SIZE(maxu
)
1335 IWMMXT_OP_ENV_SIZE(subn
)
1336 IWMMXT_OP_ENV_SIZE(addn
)
1337 IWMMXT_OP_ENV_SIZE(subu
)
1338 IWMMXT_OP_ENV_SIZE(addu
)
1339 IWMMXT_OP_ENV_SIZE(subs
)
1340 IWMMXT_OP_ENV_SIZE(adds
)
1342 IWMMXT_OP_ENV(avgb0
)
1343 IWMMXT_OP_ENV(avgb1
)
1344 IWMMXT_OP_ENV(avgw0
)
1345 IWMMXT_OP_ENV(avgw1
)
1349 IWMMXT_OP_ENV(packuw
)
1350 IWMMXT_OP_ENV(packul
)
1351 IWMMXT_OP_ENV(packuq
)
1352 IWMMXT_OP_ENV(packsw
)
1353 IWMMXT_OP_ENV(packsl
)
1354 IWMMXT_OP_ENV(packsq
)
1356 static void gen_op_iwmmxt_set_mup(void)
1359 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1360 tcg_gen_ori_i32(tmp
, tmp
, 2);
1361 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1364 static void gen_op_iwmmxt_set_cup(void)
1367 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1368 tcg_gen_ori_i32(tmp
, tmp
, 1);
1369 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1372 static void gen_op_iwmmxt_setpsr_nz(void)
1374 TCGv_i32 tmp
= tcg_temp_new_i32();
1375 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1376 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1379 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1381 iwmmxt_load_reg(cpu_V1
, rn
);
1382 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1383 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1386 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1393 rd
= (insn
>> 16) & 0xf;
1394 tmp
= load_reg(s
, rd
);
1396 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1397 if (insn
& (1 << 24)) {
1399 if (insn
& (1 << 23))
1400 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1402 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1403 tcg_gen_mov_i32(dest
, tmp
);
1404 if (insn
& (1 << 21))
1405 store_reg(s
, rd
, tmp
);
1407 tcg_temp_free_i32(tmp
);
1408 } else if (insn
& (1 << 21)) {
1410 tcg_gen_mov_i32(dest
, tmp
);
1411 if (insn
& (1 << 23))
1412 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1414 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1415 store_reg(s
, rd
, tmp
);
1416 } else if (!(insn
& (1 << 23)))
1421 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1423 int rd
= (insn
>> 0) & 0xf;
1426 if (insn
& (1 << 8)) {
1427 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1430 tmp
= iwmmxt_load_creg(rd
);
1433 tmp
= tcg_temp_new_i32();
1434 iwmmxt_load_reg(cpu_V0
, rd
);
1435 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1437 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1438 tcg_gen_mov_i32(dest
, tmp
);
1439 tcg_temp_free_i32(tmp
);
1443 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1444 (ie. an undefined instruction). */
1445 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1448 int rdhi
, rdlo
, rd0
, rd1
, i
;
1450 TCGv_i32 tmp
, tmp2
, tmp3
;
1452 if ((insn
& 0x0e000e00) == 0x0c000000) {
1453 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1455 rdlo
= (insn
>> 12) & 0xf;
1456 rdhi
= (insn
>> 16) & 0xf;
1457 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1458 iwmmxt_load_reg(cpu_V0
, wrd
);
1459 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1460 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1461 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1462 } else { /* TMCRR */
1463 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1464 iwmmxt_store_reg(cpu_V0
, wrd
);
1465 gen_op_iwmmxt_set_mup();
1470 wrd
= (insn
>> 12) & 0xf;
1471 addr
= tcg_temp_new_i32();
1472 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1473 tcg_temp_free_i32(addr
);
1476 if (insn
& ARM_CP_RW_BIT
) {
1477 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1478 tmp
= tcg_temp_new_i32();
1479 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1480 iwmmxt_store_creg(wrd
, tmp
);
1483 if (insn
& (1 << 8)) {
1484 if (insn
& (1 << 22)) { /* WLDRD */
1485 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1487 } else { /* WLDRW wRd */
1488 tmp
= tcg_temp_new_i32();
1489 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1492 tmp
= tcg_temp_new_i32();
1493 if (insn
& (1 << 22)) { /* WLDRH */
1494 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1495 } else { /* WLDRB */
1496 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1500 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1501 tcg_temp_free_i32(tmp
);
1503 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1506 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1507 tmp
= iwmmxt_load_creg(wrd
);
1508 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1510 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1511 tmp
= tcg_temp_new_i32();
1512 if (insn
& (1 << 8)) {
1513 if (insn
& (1 << 22)) { /* WSTRD */
1514 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1515 } else { /* WSTRW wRd */
1516 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1517 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1520 if (insn
& (1 << 22)) { /* WSTRH */
1521 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1522 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1523 } else { /* WSTRB */
1524 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1525 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1529 tcg_temp_free_i32(tmp
);
1531 tcg_temp_free_i32(addr
);
1535 if ((insn
& 0x0f000000) != 0x0e000000)
1538 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1539 case 0x000: /* WOR */
1540 wrd
= (insn
>> 12) & 0xf;
1541 rd0
= (insn
>> 0) & 0xf;
1542 rd1
= (insn
>> 16) & 0xf;
1543 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1544 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1545 gen_op_iwmmxt_setpsr_nz();
1546 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1547 gen_op_iwmmxt_set_mup();
1548 gen_op_iwmmxt_set_cup();
1550 case 0x011: /* TMCR */
1553 rd
= (insn
>> 12) & 0xf;
1554 wrd
= (insn
>> 16) & 0xf;
1556 case ARM_IWMMXT_wCID
:
1557 case ARM_IWMMXT_wCASF
:
1559 case ARM_IWMMXT_wCon
:
1560 gen_op_iwmmxt_set_cup();
1562 case ARM_IWMMXT_wCSSF
:
1563 tmp
= iwmmxt_load_creg(wrd
);
1564 tmp2
= load_reg(s
, rd
);
1565 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1566 tcg_temp_free_i32(tmp2
);
1567 iwmmxt_store_creg(wrd
, tmp
);
1569 case ARM_IWMMXT_wCGR0
:
1570 case ARM_IWMMXT_wCGR1
:
1571 case ARM_IWMMXT_wCGR2
:
1572 case ARM_IWMMXT_wCGR3
:
1573 gen_op_iwmmxt_set_cup();
1574 tmp
= load_reg(s
, rd
);
1575 iwmmxt_store_creg(wrd
, tmp
);
1581 case 0x100: /* WXOR */
1582 wrd
= (insn
>> 12) & 0xf;
1583 rd0
= (insn
>> 0) & 0xf;
1584 rd1
= (insn
>> 16) & 0xf;
1585 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1586 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1587 gen_op_iwmmxt_setpsr_nz();
1588 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1589 gen_op_iwmmxt_set_mup();
1590 gen_op_iwmmxt_set_cup();
1592 case 0x111: /* TMRC */
1595 rd
= (insn
>> 12) & 0xf;
1596 wrd
= (insn
>> 16) & 0xf;
1597 tmp
= iwmmxt_load_creg(wrd
);
1598 store_reg(s
, rd
, tmp
);
1600 case 0x300: /* WANDN */
1601 wrd
= (insn
>> 12) & 0xf;
1602 rd0
= (insn
>> 0) & 0xf;
1603 rd1
= (insn
>> 16) & 0xf;
1604 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1605 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1606 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1607 gen_op_iwmmxt_setpsr_nz();
1608 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1609 gen_op_iwmmxt_set_mup();
1610 gen_op_iwmmxt_set_cup();
1612 case 0x200: /* WAND */
1613 wrd
= (insn
>> 12) & 0xf;
1614 rd0
= (insn
>> 0) & 0xf;
1615 rd1
= (insn
>> 16) & 0xf;
1616 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1617 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1618 gen_op_iwmmxt_setpsr_nz();
1619 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1620 gen_op_iwmmxt_set_mup();
1621 gen_op_iwmmxt_set_cup();
1623 case 0x810: case 0xa10: /* WMADD */
1624 wrd
= (insn
>> 12) & 0xf;
1625 rd0
= (insn
>> 0) & 0xf;
1626 rd1
= (insn
>> 16) & 0xf;
1627 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1628 if (insn
& (1 << 21))
1629 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1631 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1632 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1633 gen_op_iwmmxt_set_mup();
1635 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1636 wrd
= (insn
>> 12) & 0xf;
1637 rd0
= (insn
>> 16) & 0xf;
1638 rd1
= (insn
>> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1640 switch ((insn
>> 22) & 3) {
1642 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1645 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1648 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1653 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1654 gen_op_iwmmxt_set_mup();
1655 gen_op_iwmmxt_set_cup();
1657 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1658 wrd
= (insn
>> 12) & 0xf;
1659 rd0
= (insn
>> 16) & 0xf;
1660 rd1
= (insn
>> 0) & 0xf;
1661 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1662 switch ((insn
>> 22) & 3) {
1664 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1667 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1670 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1675 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1676 gen_op_iwmmxt_set_mup();
1677 gen_op_iwmmxt_set_cup();
1679 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1680 wrd
= (insn
>> 12) & 0xf;
1681 rd0
= (insn
>> 16) & 0xf;
1682 rd1
= (insn
>> 0) & 0xf;
1683 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1684 if (insn
& (1 << 22))
1685 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1687 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1688 if (!(insn
& (1 << 20)))
1689 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1690 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1691 gen_op_iwmmxt_set_mup();
1693 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1694 wrd
= (insn
>> 12) & 0xf;
1695 rd0
= (insn
>> 16) & 0xf;
1696 rd1
= (insn
>> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1698 if (insn
& (1 << 21)) {
1699 if (insn
& (1 << 20))
1700 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1702 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1704 if (insn
& (1 << 20))
1705 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1707 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1709 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1710 gen_op_iwmmxt_set_mup();
1712 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1713 wrd
= (insn
>> 12) & 0xf;
1714 rd0
= (insn
>> 16) & 0xf;
1715 rd1
= (insn
>> 0) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1717 if (insn
& (1 << 21))
1718 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1720 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1721 if (!(insn
& (1 << 20))) {
1722 iwmmxt_load_reg(cpu_V1
, wrd
);
1723 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1726 gen_op_iwmmxt_set_mup();
1728 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1729 wrd
= (insn
>> 12) & 0xf;
1730 rd0
= (insn
>> 16) & 0xf;
1731 rd1
= (insn
>> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1733 switch ((insn
>> 22) & 3) {
1735 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1738 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1741 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1746 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1750 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1751 wrd
= (insn
>> 12) & 0xf;
1752 rd0
= (insn
>> 16) & 0xf;
1753 rd1
= (insn
>> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1755 if (insn
& (1 << 22)) {
1756 if (insn
& (1 << 20))
1757 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1759 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1761 if (insn
& (1 << 20))
1762 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1764 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1767 gen_op_iwmmxt_set_mup();
1768 gen_op_iwmmxt_set_cup();
1770 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1771 wrd
= (insn
>> 12) & 0xf;
1772 rd0
= (insn
>> 16) & 0xf;
1773 rd1
= (insn
>> 0) & 0xf;
1774 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1775 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1776 tcg_gen_andi_i32(tmp
, tmp
, 7);
1777 iwmmxt_load_reg(cpu_V1
, rd1
);
1778 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1779 tcg_temp_free_i32(tmp
);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1781 gen_op_iwmmxt_set_mup();
1783 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1784 if (((insn
>> 6) & 3) == 3)
1786 rd
= (insn
>> 12) & 0xf;
1787 wrd
= (insn
>> 16) & 0xf;
1788 tmp
= load_reg(s
, rd
);
1789 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1790 switch ((insn
>> 6) & 3) {
1792 tmp2
= tcg_const_i32(0xff);
1793 tmp3
= tcg_const_i32((insn
& 7) << 3);
1796 tmp2
= tcg_const_i32(0xffff);
1797 tmp3
= tcg_const_i32((insn
& 3) << 4);
1800 tmp2
= tcg_const_i32(0xffffffff);
1801 tmp3
= tcg_const_i32((insn
& 1) << 5);
1804 TCGV_UNUSED_I32(tmp2
);
1805 TCGV_UNUSED_I32(tmp3
);
1807 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1808 tcg_temp_free_i32(tmp3
);
1809 tcg_temp_free_i32(tmp2
);
1810 tcg_temp_free_i32(tmp
);
1811 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1812 gen_op_iwmmxt_set_mup();
1814 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1815 rd
= (insn
>> 12) & 0xf;
1816 wrd
= (insn
>> 16) & 0xf;
1817 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1819 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1820 tmp
= tcg_temp_new_i32();
1821 switch ((insn
>> 22) & 3) {
1823 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1824 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1826 tcg_gen_ext8s_i32(tmp
, tmp
);
1828 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1832 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1833 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1835 tcg_gen_ext16s_i32(tmp
, tmp
);
1837 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1841 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1842 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1845 store_reg(s
, rd
, tmp
);
1847 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1848 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1850 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1851 switch ((insn
>> 22) & 3) {
1853 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1856 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1859 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1862 tcg_gen_shli_i32(tmp
, tmp
, 28);
1864 tcg_temp_free_i32(tmp
);
1866 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1867 if (((insn
>> 6) & 3) == 3)
1869 rd
= (insn
>> 12) & 0xf;
1870 wrd
= (insn
>> 16) & 0xf;
1871 tmp
= load_reg(s
, rd
);
1872 switch ((insn
>> 6) & 3) {
1874 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1877 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1880 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1883 tcg_temp_free_i32(tmp
);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1885 gen_op_iwmmxt_set_mup();
1887 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1888 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1890 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1891 tmp2
= tcg_temp_new_i32();
1892 tcg_gen_mov_i32(tmp2
, tmp
);
1893 switch ((insn
>> 22) & 3) {
1895 for (i
= 0; i
< 7; i
++) {
1896 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1897 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1901 for (i
= 0; i
< 3; i
++) {
1902 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1903 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1907 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1908 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1912 tcg_temp_free_i32(tmp2
);
1913 tcg_temp_free_i32(tmp
);
1915 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1916 wrd
= (insn
>> 12) & 0xf;
1917 rd0
= (insn
>> 16) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1919 switch ((insn
>> 22) & 3) {
1921 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1924 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1927 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1932 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1933 gen_op_iwmmxt_set_mup();
1935 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1936 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1938 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1939 tmp2
= tcg_temp_new_i32();
1940 tcg_gen_mov_i32(tmp2
, tmp
);
1941 switch ((insn
>> 22) & 3) {
1943 for (i
= 0; i
< 7; i
++) {
1944 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1945 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1949 for (i
= 0; i
< 3; i
++) {
1950 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1951 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1955 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1956 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1960 tcg_temp_free_i32(tmp2
);
1961 tcg_temp_free_i32(tmp
);
1963 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1964 rd
= (insn
>> 12) & 0xf;
1965 rd0
= (insn
>> 16) & 0xf;
1966 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1968 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1969 tmp
= tcg_temp_new_i32();
1970 switch ((insn
>> 22) & 3) {
1972 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1975 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1978 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1981 store_reg(s
, rd
, tmp
);
1983 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1984 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1985 wrd
= (insn
>> 12) & 0xf;
1986 rd0
= (insn
>> 16) & 0xf;
1987 rd1
= (insn
>> 0) & 0xf;
1988 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1989 switch ((insn
>> 22) & 3) {
1991 if (insn
& (1 << 21))
1992 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1994 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1997 if (insn
& (1 << 21))
1998 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2000 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2003 if (insn
& (1 << 21))
2004 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2006 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2011 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2012 gen_op_iwmmxt_set_mup();
2013 gen_op_iwmmxt_set_cup();
2015 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2016 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2017 wrd
= (insn
>> 12) & 0xf;
2018 rd0
= (insn
>> 16) & 0xf;
2019 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2020 switch ((insn
>> 22) & 3) {
2022 if (insn
& (1 << 21))
2023 gen_op_iwmmxt_unpacklsb_M0();
2025 gen_op_iwmmxt_unpacklub_M0();
2028 if (insn
& (1 << 21))
2029 gen_op_iwmmxt_unpacklsw_M0();
2031 gen_op_iwmmxt_unpackluw_M0();
2034 if (insn
& (1 << 21))
2035 gen_op_iwmmxt_unpacklsl_M0();
2037 gen_op_iwmmxt_unpacklul_M0();
2042 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2043 gen_op_iwmmxt_set_mup();
2044 gen_op_iwmmxt_set_cup();
2046 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2047 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2048 wrd
= (insn
>> 12) & 0xf;
2049 rd0
= (insn
>> 16) & 0xf;
2050 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2051 switch ((insn
>> 22) & 3) {
2053 if (insn
& (1 << 21))
2054 gen_op_iwmmxt_unpackhsb_M0();
2056 gen_op_iwmmxt_unpackhub_M0();
2059 if (insn
& (1 << 21))
2060 gen_op_iwmmxt_unpackhsw_M0();
2062 gen_op_iwmmxt_unpackhuw_M0();
2065 if (insn
& (1 << 21))
2066 gen_op_iwmmxt_unpackhsl_M0();
2068 gen_op_iwmmxt_unpackhul_M0();
2073 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2074 gen_op_iwmmxt_set_mup();
2075 gen_op_iwmmxt_set_cup();
2077 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2078 case 0x214: case 0x614: case 0xa14: case 0xe14:
2079 if (((insn
>> 22) & 3) == 0)
2081 wrd
= (insn
>> 12) & 0xf;
2082 rd0
= (insn
>> 16) & 0xf;
2083 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2084 tmp
= tcg_temp_new_i32();
2085 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2086 tcg_temp_free_i32(tmp
);
2089 switch ((insn
>> 22) & 3) {
2091 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2094 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2097 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2100 tcg_temp_free_i32(tmp
);
2101 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2102 gen_op_iwmmxt_set_mup();
2103 gen_op_iwmmxt_set_cup();
2105 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2106 case 0x014: case 0x414: case 0x814: case 0xc14:
2107 if (((insn
>> 22) & 3) == 0)
2109 wrd
= (insn
>> 12) & 0xf;
2110 rd0
= (insn
>> 16) & 0xf;
2111 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2112 tmp
= tcg_temp_new_i32();
2113 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2114 tcg_temp_free_i32(tmp
);
2117 switch ((insn
>> 22) & 3) {
2119 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2122 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2125 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2128 tcg_temp_free_i32(tmp
);
2129 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2130 gen_op_iwmmxt_set_mup();
2131 gen_op_iwmmxt_set_cup();
2133 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2134 case 0x114: case 0x514: case 0x914: case 0xd14:
2135 if (((insn
>> 22) & 3) == 0)
2137 wrd
= (insn
>> 12) & 0xf;
2138 rd0
= (insn
>> 16) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2140 tmp
= tcg_temp_new_i32();
2141 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2142 tcg_temp_free_i32(tmp
);
2145 switch ((insn
>> 22) & 3) {
2147 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2150 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2153 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2156 tcg_temp_free_i32(tmp
);
2157 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2158 gen_op_iwmmxt_set_mup();
2159 gen_op_iwmmxt_set_cup();
2161 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2162 case 0x314: case 0x714: case 0xb14: case 0xf14:
2163 if (((insn
>> 22) & 3) == 0)
2165 wrd
= (insn
>> 12) & 0xf;
2166 rd0
= (insn
>> 16) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2168 tmp
= tcg_temp_new_i32();
2169 switch ((insn
>> 22) & 3) {
2171 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2172 tcg_temp_free_i32(tmp
);
2175 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2178 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2179 tcg_temp_free_i32(tmp
);
2182 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2185 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2186 tcg_temp_free_i32(tmp
);
2189 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2192 tcg_temp_free_i32(tmp
);
2193 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2194 gen_op_iwmmxt_set_mup();
2195 gen_op_iwmmxt_set_cup();
2197 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2198 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2199 wrd
= (insn
>> 12) & 0xf;
2200 rd0
= (insn
>> 16) & 0xf;
2201 rd1
= (insn
>> 0) & 0xf;
2202 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2203 switch ((insn
>> 22) & 3) {
2205 if (insn
& (1 << 21))
2206 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2208 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2211 if (insn
& (1 << 21))
2212 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2214 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2217 if (insn
& (1 << 21))
2218 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2220 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2226 gen_op_iwmmxt_set_mup();
2228 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2229 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2230 wrd
= (insn
>> 12) & 0xf;
2231 rd0
= (insn
>> 16) & 0xf;
2232 rd1
= (insn
>> 0) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2234 switch ((insn
>> 22) & 3) {
2236 if (insn
& (1 << 21))
2237 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2239 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2242 if (insn
& (1 << 21))
2243 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2245 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2248 if (insn
& (1 << 21))
2249 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2251 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2256 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2257 gen_op_iwmmxt_set_mup();
2259 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2260 case 0x402: case 0x502: case 0x602: case 0x702:
2261 wrd
= (insn
>> 12) & 0xf;
2262 rd0
= (insn
>> 16) & 0xf;
2263 rd1
= (insn
>> 0) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2265 tmp
= tcg_const_i32((insn
>> 20) & 3);
2266 iwmmxt_load_reg(cpu_V1
, rd1
);
2267 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2268 tcg_temp_free_i32(tmp
);
2269 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2270 gen_op_iwmmxt_set_mup();
2272 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2273 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2274 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2275 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2276 wrd
= (insn
>> 12) & 0xf;
2277 rd0
= (insn
>> 16) & 0xf;
2278 rd1
= (insn
>> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2280 switch ((insn
>> 20) & 0xf) {
2282 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2285 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2288 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2291 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2294 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2297 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2300 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2303 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2306 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2312 gen_op_iwmmxt_set_mup();
2313 gen_op_iwmmxt_set_cup();
2315 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2316 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2317 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2318 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2319 wrd
= (insn
>> 12) & 0xf;
2320 rd0
= (insn
>> 16) & 0xf;
2321 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2322 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2323 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2324 tcg_temp_free_i32(tmp
);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2329 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2330 case 0x418: case 0x518: case 0x618: case 0x718:
2331 case 0x818: case 0x918: case 0xa18: case 0xb18:
2332 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
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
>> 20) & 0xf) {
2339 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2342 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2345 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2348 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2351 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2354 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2357 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2360 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2363 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2368 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2369 gen_op_iwmmxt_set_mup();
2370 gen_op_iwmmxt_set_cup();
2372 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2373 case 0x408: case 0x508: case 0x608: case 0x708:
2374 case 0x808: case 0x908: case 0xa08: case 0xb08:
2375 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2376 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2378 wrd
= (insn
>> 12) & 0xf;
2379 rd0
= (insn
>> 16) & 0xf;
2380 rd1
= (insn
>> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2382 switch ((insn
>> 22) & 3) {
2384 if (insn
& (1 << 21))
2385 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2387 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2390 if (insn
& (1 << 21))
2391 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2393 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2396 if (insn
& (1 << 21))
2397 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2399 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2402 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2403 gen_op_iwmmxt_set_mup();
2404 gen_op_iwmmxt_set_cup();
2406 case 0x201: case 0x203: case 0x205: case 0x207:
2407 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2408 case 0x211: case 0x213: case 0x215: case 0x217:
2409 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2410 wrd
= (insn
>> 5) & 0xf;
2411 rd0
= (insn
>> 12) & 0xf;
2412 rd1
= (insn
>> 0) & 0xf;
2413 if (rd0
== 0xf || rd1
== 0xf)
2415 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2416 tmp
= load_reg(s
, rd0
);
2417 tmp2
= load_reg(s
, rd1
);
2418 switch ((insn
>> 16) & 0xf) {
2419 case 0x0: /* TMIA */
2420 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2422 case 0x8: /* TMIAPH */
2423 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2425 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2426 if (insn
& (1 << 16))
2427 tcg_gen_shri_i32(tmp
, tmp
, 16);
2428 if (insn
& (1 << 17))
2429 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2430 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2433 tcg_temp_free_i32(tmp2
);
2434 tcg_temp_free_i32(tmp
);
2437 tcg_temp_free_i32(tmp2
);
2438 tcg_temp_free_i32(tmp
);
2439 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2440 gen_op_iwmmxt_set_mup();
2449 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2450 (ie. an undefined instruction). */
2451 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2453 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2456 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2457 /* Multiply with Internal Accumulate Format */
2458 rd0
= (insn
>> 12) & 0xf;
2460 acc
= (insn
>> 5) & 7;
2465 tmp
= load_reg(s
, rd0
);
2466 tmp2
= load_reg(s
, rd1
);
2467 switch ((insn
>> 16) & 0xf) {
2469 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2471 case 0x8: /* MIAPH */
2472 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2474 case 0xc: /* MIABB */
2475 case 0xd: /* MIABT */
2476 case 0xe: /* MIATB */
2477 case 0xf: /* MIATT */
2478 if (insn
& (1 << 16))
2479 tcg_gen_shri_i32(tmp
, tmp
, 16);
2480 if (insn
& (1 << 17))
2481 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2482 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2487 tcg_temp_free_i32(tmp2
);
2488 tcg_temp_free_i32(tmp
);
2490 gen_op_iwmmxt_movq_wRn_M0(acc
);
2494 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2495 /* Internal Accumulator Access Format */
2496 rdhi
= (insn
>> 16) & 0xf;
2497 rdlo
= (insn
>> 12) & 0xf;
2503 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2504 iwmmxt_load_reg(cpu_V0
, acc
);
2505 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2506 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2507 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2508 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2510 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2511 iwmmxt_store_reg(cpu_V0
, acc
);
2519 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2520 #define VFP_SREG(insn, bigbit, smallbit) \
2521 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2522 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2523 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2524 reg = (((insn) >> (bigbit)) & 0x0f) \
2525 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2527 if (insn & (1 << (smallbit))) \
2529 reg = ((insn) >> (bigbit)) & 0x0f; \
2532 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2533 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2534 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2535 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2536 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2537 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2539 /* Move between integer and VFP cores. */
2540 static TCGv_i32
gen_vfp_mrs(void)
2542 TCGv_i32 tmp
= tcg_temp_new_i32();
2543 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2547 static void gen_vfp_msr(TCGv_i32 tmp
)
2549 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2550 tcg_temp_free_i32(tmp
);
2553 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2555 TCGv_i32 tmp
= tcg_temp_new_i32();
2557 tcg_gen_shri_i32(var
, var
, shift
);
2558 tcg_gen_ext8u_i32(var
, var
);
2559 tcg_gen_shli_i32(tmp
, var
, 8);
2560 tcg_gen_or_i32(var
, var
, tmp
);
2561 tcg_gen_shli_i32(tmp
, var
, 16);
2562 tcg_gen_or_i32(var
, var
, tmp
);
2563 tcg_temp_free_i32(tmp
);
2566 static void gen_neon_dup_low16(TCGv_i32 var
)
2568 TCGv_i32 tmp
= tcg_temp_new_i32();
2569 tcg_gen_ext16u_i32(var
, var
);
2570 tcg_gen_shli_i32(tmp
, var
, 16);
2571 tcg_gen_or_i32(var
, var
, tmp
);
2572 tcg_temp_free_i32(tmp
);
2575 static void gen_neon_dup_high16(TCGv_i32 var
)
2577 TCGv_i32 tmp
= tcg_temp_new_i32();
2578 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2579 tcg_gen_shri_i32(tmp
, var
, 16);
2580 tcg_gen_or_i32(var
, var
, tmp
);
2581 tcg_temp_free_i32(tmp
);
2584 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2586 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2587 TCGv_i32 tmp
= tcg_temp_new_i32();
2590 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2591 gen_neon_dup_u8(tmp
, 0);
2594 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2595 gen_neon_dup_low16(tmp
);
2598 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2600 default: /* Avoid compiler warnings. */
2606 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2609 uint32_t cc
= extract32(insn
, 20, 2);
2612 TCGv_i64 frn
, frm
, dest
;
2613 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2615 zero
= tcg_const_i64(0);
2617 frn
= tcg_temp_new_i64();
2618 frm
= tcg_temp_new_i64();
2619 dest
= tcg_temp_new_i64();
2621 zf
= tcg_temp_new_i64();
2622 nf
= tcg_temp_new_i64();
2623 vf
= tcg_temp_new_i64();
2625 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2626 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2627 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2629 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2630 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2633 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2637 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2640 case 2: /* ge: N == V -> N ^ V == 0 */
2641 tmp
= tcg_temp_new_i64();
2642 tcg_gen_xor_i64(tmp
, vf
, nf
);
2643 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2645 tcg_temp_free_i64(tmp
);
2647 case 3: /* gt: !Z && N == V */
2648 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2650 tmp
= tcg_temp_new_i64();
2651 tcg_gen_xor_i64(tmp
, vf
, nf
);
2652 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2654 tcg_temp_free_i64(tmp
);
2657 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2658 tcg_temp_free_i64(frn
);
2659 tcg_temp_free_i64(frm
);
2660 tcg_temp_free_i64(dest
);
2662 tcg_temp_free_i64(zf
);
2663 tcg_temp_free_i64(nf
);
2664 tcg_temp_free_i64(vf
);
2666 tcg_temp_free_i64(zero
);
2668 TCGv_i32 frn
, frm
, dest
;
2671 zero
= tcg_const_i32(0);
2673 frn
= tcg_temp_new_i32();
2674 frm
= tcg_temp_new_i32();
2675 dest
= tcg_temp_new_i32();
2676 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2677 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2680 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2684 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2687 case 2: /* ge: N == V -> N ^ V == 0 */
2688 tmp
= tcg_temp_new_i32();
2689 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2690 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2692 tcg_temp_free_i32(tmp
);
2694 case 3: /* gt: !Z && N == V */
2695 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2697 tmp
= tcg_temp_new_i32();
2698 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2699 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2701 tcg_temp_free_i32(tmp
);
2704 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2705 tcg_temp_free_i32(frn
);
2706 tcg_temp_free_i32(frm
);
2707 tcg_temp_free_i32(dest
);
2709 tcg_temp_free_i32(zero
);
2715 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2716 uint32_t rm
, uint32_t dp
)
2718 uint32_t vmin
= extract32(insn
, 6, 1);
2719 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2722 TCGv_i64 frn
, frm
, dest
;
2724 frn
= tcg_temp_new_i64();
2725 frm
= tcg_temp_new_i64();
2726 dest
= tcg_temp_new_i64();
2728 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2729 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2731 gen_helper_vfp_minnmd(dest
, frn
, frm
, fpst
);
2733 gen_helper_vfp_maxnmd(dest
, frn
, frm
, fpst
);
2735 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2736 tcg_temp_free_i64(frn
);
2737 tcg_temp_free_i64(frm
);
2738 tcg_temp_free_i64(dest
);
2740 TCGv_i32 frn
, frm
, dest
;
2742 frn
= tcg_temp_new_i32();
2743 frm
= tcg_temp_new_i32();
2744 dest
= tcg_temp_new_i32();
2746 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2747 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2749 gen_helper_vfp_minnms(dest
, frn
, frm
, fpst
);
2751 gen_helper_vfp_maxnms(dest
, frn
, frm
, fpst
);
2753 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2754 tcg_temp_free_i32(frn
);
2755 tcg_temp_free_i32(frm
);
2756 tcg_temp_free_i32(dest
);
2759 tcg_temp_free_ptr(fpst
);
2763 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2765 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2767 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2772 VFP_DREG_D(rd
, insn
);
2773 VFP_DREG_N(rn
, insn
);
2774 VFP_DREG_M(rm
, insn
);
2776 rd
= VFP_SREG_D(insn
);
2777 rn
= VFP_SREG_N(insn
);
2778 rm
= VFP_SREG_M(insn
);
2781 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2782 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2783 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2784 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2789 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2790 (ie. an undefined instruction). */
2791 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2793 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2799 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2802 if (!s
->vfp_enabled
) {
2803 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2804 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2806 rn
= (insn
>> 16) & 0xf;
2807 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2808 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2812 if (extract32(insn
, 28, 4) == 0xf) {
2813 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2814 * only used in v8 and above.
2816 return disas_vfp_v8_insn(env
, s
, insn
);
2819 dp
= ((insn
& 0xf00) == 0xb00);
2820 switch ((insn
>> 24) & 0xf) {
2822 if (insn
& (1 << 4)) {
2823 /* single register transfer */
2824 rd
= (insn
>> 12) & 0xf;
2829 VFP_DREG_N(rn
, insn
);
2832 if (insn
& 0x00c00060
2833 && !arm_feature(env
, ARM_FEATURE_NEON
))
2836 pass
= (insn
>> 21) & 1;
2837 if (insn
& (1 << 22)) {
2839 offset
= ((insn
>> 5) & 3) * 8;
2840 } else if (insn
& (1 << 5)) {
2842 offset
= (insn
& (1 << 6)) ? 16 : 0;
2847 if (insn
& ARM_CP_RW_BIT
) {
2849 tmp
= neon_load_reg(rn
, pass
);
2853 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2854 if (insn
& (1 << 23))
2860 if (insn
& (1 << 23)) {
2862 tcg_gen_shri_i32(tmp
, tmp
, 16);
2868 tcg_gen_sari_i32(tmp
, tmp
, 16);
2877 store_reg(s
, rd
, tmp
);
2880 tmp
= load_reg(s
, rd
);
2881 if (insn
& (1 << 23)) {
2884 gen_neon_dup_u8(tmp
, 0);
2885 } else if (size
== 1) {
2886 gen_neon_dup_low16(tmp
);
2888 for (n
= 0; n
<= pass
* 2; n
++) {
2889 tmp2
= tcg_temp_new_i32();
2890 tcg_gen_mov_i32(tmp2
, tmp
);
2891 neon_store_reg(rn
, n
, tmp2
);
2893 neon_store_reg(rn
, n
, tmp
);
2898 tmp2
= neon_load_reg(rn
, pass
);
2899 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2900 tcg_temp_free_i32(tmp2
);
2903 tmp2
= neon_load_reg(rn
, pass
);
2904 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2905 tcg_temp_free_i32(tmp2
);
2910 neon_store_reg(rn
, pass
, tmp
);
2914 if ((insn
& 0x6f) != 0x00)
2916 rn
= VFP_SREG_N(insn
);
2917 if (insn
& ARM_CP_RW_BIT
) {
2919 if (insn
& (1 << 21)) {
2920 /* system register */
2925 /* VFP2 allows access to FSID from userspace.
2926 VFP3 restricts all id registers to privileged
2929 && arm_feature(env
, ARM_FEATURE_VFP3
))
2931 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2936 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2938 case ARM_VFP_FPINST
:
2939 case ARM_VFP_FPINST2
:
2940 /* Not present in VFP3. */
2942 || arm_feature(env
, ARM_FEATURE_VFP3
))
2944 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2948 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2949 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2951 tmp
= tcg_temp_new_i32();
2952 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2958 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2960 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2966 gen_mov_F0_vreg(0, rn
);
2967 tmp
= gen_vfp_mrs();
2970 /* Set the 4 flag bits in the CPSR. */
2972 tcg_temp_free_i32(tmp
);
2974 store_reg(s
, rd
, tmp
);
2978 if (insn
& (1 << 21)) {
2980 /* system register */
2985 /* Writes are ignored. */
2988 tmp
= load_reg(s
, rd
);
2989 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2990 tcg_temp_free_i32(tmp
);
2996 /* TODO: VFP subarchitecture support.
2997 * For now, keep the EN bit only */
2998 tmp
= load_reg(s
, rd
);
2999 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3000 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3003 case ARM_VFP_FPINST
:
3004 case ARM_VFP_FPINST2
:
3005 tmp
= load_reg(s
, rd
);
3006 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3012 tmp
= load_reg(s
, rd
);
3014 gen_mov_vreg_F0(0, rn
);
3019 /* data processing */
3020 /* The opcode is in bits 23, 21, 20 and 6. */
3021 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3025 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3027 /* rn is register number */
3028 VFP_DREG_N(rn
, insn
);
3031 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
3032 /* Integer or single precision destination. */
3033 rd
= VFP_SREG_D(insn
);
3035 VFP_DREG_D(rd
, insn
);
3038 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
3039 /* VCVT from int is always from S reg regardless of dp bit.
3040 * VCVT with immediate frac_bits has same format as SREG_M
3042 rm
= VFP_SREG_M(insn
);
3044 VFP_DREG_M(rm
, insn
);
3047 rn
= VFP_SREG_N(insn
);
3048 if (op
== 15 && rn
== 15) {
3049 /* Double precision destination. */
3050 VFP_DREG_D(rd
, insn
);
3052 rd
= VFP_SREG_D(insn
);
3054 /* NB that we implicitly rely on the encoding for the frac_bits
3055 * in VCVT of fixed to float being the same as that of an SREG_M
3057 rm
= VFP_SREG_M(insn
);
3060 veclen
= s
->vec_len
;
3061 if (op
== 15 && rn
> 3)
3064 /* Shut up compiler warnings. */
3075 /* Figure out what type of vector operation this is. */
3076 if ((rd
& bank_mask
) == 0) {
3081 delta_d
= (s
->vec_stride
>> 1) + 1;
3083 delta_d
= s
->vec_stride
+ 1;
3085 if ((rm
& bank_mask
) == 0) {
3086 /* mixed scalar/vector */
3095 /* Load the initial operands. */
3100 /* Integer source */
3101 gen_mov_F0_vreg(0, rm
);
3106 gen_mov_F0_vreg(dp
, rd
);
3107 gen_mov_F1_vreg(dp
, rm
);
3111 /* Compare with zero */
3112 gen_mov_F0_vreg(dp
, rd
);
3123 /* Source and destination the same. */
3124 gen_mov_F0_vreg(dp
, rd
);
3130 /* VCVTB, VCVTT: only present with the halfprec extension,
3131 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3133 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3136 /* Otherwise fall through */
3138 /* One source operand. */
3139 gen_mov_F0_vreg(dp
, rm
);
3143 /* Two source operands. */
3144 gen_mov_F0_vreg(dp
, rn
);
3145 gen_mov_F1_vreg(dp
, rm
);
3149 /* Perform the calculation. */
3151 case 0: /* VMLA: fd + (fn * fm) */
3152 /* Note that order of inputs to the add matters for NaNs */
3154 gen_mov_F0_vreg(dp
, rd
);
3157 case 1: /* VMLS: fd + -(fn * fm) */
3160 gen_mov_F0_vreg(dp
, rd
);
3163 case 2: /* VNMLS: -fd + (fn * fm) */
3164 /* Note that it isn't valid to replace (-A + B) with (B - A)
3165 * or similar plausible looking simplifications
3166 * because this will give wrong results for NaNs.
3169 gen_mov_F0_vreg(dp
, rd
);
3173 case 3: /* VNMLA: -fd + -(fn * fm) */
3176 gen_mov_F0_vreg(dp
, rd
);
3180 case 4: /* mul: fn * fm */
3183 case 5: /* nmul: -(fn * fm) */
3187 case 6: /* add: fn + fm */
3190 case 7: /* sub: fn - fm */
3193 case 8: /* div: fn / fm */
3196 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3197 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3198 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3199 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3200 /* These are fused multiply-add, and must be done as one
3201 * floating point operation with no rounding between the
3202 * multiplication and addition steps.
3203 * NB that doing the negations here as separate steps is
3204 * correct : an input NaN should come out with its sign bit
3205 * flipped if it is a negated-input.
3207 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3215 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3217 frd
= tcg_temp_new_i64();
3218 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3221 gen_helper_vfp_negd(frd
, frd
);
3223 fpst
= get_fpstatus_ptr(0);
3224 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3225 cpu_F1d
, frd
, fpst
);
3226 tcg_temp_free_ptr(fpst
);
3227 tcg_temp_free_i64(frd
);
3233 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3235 frd
= tcg_temp_new_i32();
3236 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3238 gen_helper_vfp_negs(frd
, frd
);
3240 fpst
= get_fpstatus_ptr(0);
3241 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3242 cpu_F1s
, frd
, fpst
);
3243 tcg_temp_free_ptr(fpst
);
3244 tcg_temp_free_i32(frd
);
3247 case 14: /* fconst */
3248 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3251 n
= (insn
<< 12) & 0x80000000;
3252 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3259 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3266 tcg_gen_movi_i32(cpu_F0s
, n
);
3269 case 15: /* extension space */
3283 case 4: /* vcvtb.f32.f16 */
3284 tmp
= gen_vfp_mrs();
3285 tcg_gen_ext16u_i32(tmp
, tmp
);
3286 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3287 tcg_temp_free_i32(tmp
);
3289 case 5: /* vcvtt.f32.f16 */
3290 tmp
= gen_vfp_mrs();
3291 tcg_gen_shri_i32(tmp
, tmp
, 16);
3292 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3293 tcg_temp_free_i32(tmp
);
3295 case 6: /* vcvtb.f16.f32 */
3296 tmp
= tcg_temp_new_i32();
3297 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3298 gen_mov_F0_vreg(0, rd
);
3299 tmp2
= gen_vfp_mrs();
3300 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3301 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3302 tcg_temp_free_i32(tmp2
);
3305 case 7: /* vcvtt.f16.f32 */
3306 tmp
= tcg_temp_new_i32();
3307 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3308 tcg_gen_shli_i32(tmp
, tmp
, 16);
3309 gen_mov_F0_vreg(0, rd
);
3310 tmp2
= gen_vfp_mrs();
3311 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3312 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3313 tcg_temp_free_i32(tmp2
);
3325 case 11: /* cmpez */
3329 case 15: /* single<->double conversion */
3331 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3333 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3335 case 16: /* fuito */
3336 gen_vfp_uito(dp
, 0);
3338 case 17: /* fsito */
3339 gen_vfp_sito(dp
, 0);
3341 case 20: /* fshto */
3342 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3344 gen_vfp_shto(dp
, 16 - rm
, 0);
3346 case 21: /* fslto */
3347 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3349 gen_vfp_slto(dp
, 32 - rm
, 0);
3351 case 22: /* fuhto */
3352 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3354 gen_vfp_uhto(dp
, 16 - rm
, 0);
3356 case 23: /* fulto */
3357 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3359 gen_vfp_ulto(dp
, 32 - rm
, 0);
3361 case 24: /* ftoui */
3362 gen_vfp_toui(dp
, 0);
3364 case 25: /* ftouiz */
3365 gen_vfp_touiz(dp
, 0);
3367 case 26: /* ftosi */
3368 gen_vfp_tosi(dp
, 0);
3370 case 27: /* ftosiz */
3371 gen_vfp_tosiz(dp
, 0);
3373 case 28: /* ftosh */
3374 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3376 gen_vfp_tosh(dp
, 16 - rm
, 0);
3378 case 29: /* ftosl */
3379 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3381 gen_vfp_tosl(dp
, 32 - rm
, 0);
3383 case 30: /* ftouh */
3384 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3386 gen_vfp_touh(dp
, 16 - rm
, 0);
3388 case 31: /* ftoul */
3389 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3391 gen_vfp_toul(dp
, 32 - rm
, 0);
3393 default: /* undefined */
3397 default: /* undefined */
3401 /* Write back the result. */
3402 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3403 ; /* Comparison, do nothing. */
3404 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3405 /* VCVT double to int: always integer result. */
3406 gen_mov_vreg_F0(0, rd
);
3407 else if (op
== 15 && rn
== 15)
3409 gen_mov_vreg_F0(!dp
, rd
);
3411 gen_mov_vreg_F0(dp
, rd
);
3413 /* break out of the loop if we have finished */
3417 if (op
== 15 && delta_m
== 0) {
3418 /* single source one-many */
3420 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3422 gen_mov_vreg_F0(dp
, rd
);
3426 /* Setup the next operands. */
3428 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3432 /* One source operand. */
3433 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3435 gen_mov_F0_vreg(dp
, rm
);
3437 /* Two source operands. */
3438 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3440 gen_mov_F0_vreg(dp
, rn
);
3442 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3444 gen_mov_F1_vreg(dp
, rm
);
3452 if ((insn
& 0x03e00000) == 0x00400000) {
3453 /* two-register transfer */
3454 rn
= (insn
>> 16) & 0xf;
3455 rd
= (insn
>> 12) & 0xf;
3457 VFP_DREG_M(rm
, insn
);
3459 rm
= VFP_SREG_M(insn
);
3462 if (insn
& ARM_CP_RW_BIT
) {
3465 gen_mov_F0_vreg(0, rm
* 2);
3466 tmp
= gen_vfp_mrs();
3467 store_reg(s
, rd
, tmp
);
3468 gen_mov_F0_vreg(0, rm
* 2 + 1);
3469 tmp
= gen_vfp_mrs();
3470 store_reg(s
, rn
, tmp
);
3472 gen_mov_F0_vreg(0, rm
);
3473 tmp
= gen_vfp_mrs();
3474 store_reg(s
, rd
, tmp
);
3475 gen_mov_F0_vreg(0, rm
+ 1);
3476 tmp
= gen_vfp_mrs();
3477 store_reg(s
, rn
, tmp
);
3482 tmp
= load_reg(s
, rd
);
3484 gen_mov_vreg_F0(0, rm
* 2);
3485 tmp
= load_reg(s
, rn
);
3487 gen_mov_vreg_F0(0, rm
* 2 + 1);
3489 tmp
= load_reg(s
, rd
);
3491 gen_mov_vreg_F0(0, rm
);
3492 tmp
= load_reg(s
, rn
);
3494 gen_mov_vreg_F0(0, rm
+ 1);
3499 rn
= (insn
>> 16) & 0xf;
3501 VFP_DREG_D(rd
, insn
);
3503 rd
= VFP_SREG_D(insn
);
3504 if ((insn
& 0x01200000) == 0x01000000) {
3505 /* Single load/store */
3506 offset
= (insn
& 0xff) << 2;
3507 if ((insn
& (1 << 23)) == 0)
3509 if (s
->thumb
&& rn
== 15) {
3510 /* This is actually UNPREDICTABLE */
3511 addr
= tcg_temp_new_i32();
3512 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3514 addr
= load_reg(s
, rn
);
3516 tcg_gen_addi_i32(addr
, addr
, offset
);
3517 if (insn
& (1 << 20)) {
3518 gen_vfp_ld(s
, dp
, addr
);
3519 gen_mov_vreg_F0(dp
, rd
);
3521 gen_mov_F0_vreg(dp
, rd
);
3522 gen_vfp_st(s
, dp
, addr
);
3524 tcg_temp_free_i32(addr
);
3526 /* load/store multiple */
3527 int w
= insn
& (1 << 21);
3529 n
= (insn
>> 1) & 0x7f;
3533 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3534 /* P == U , W == 1 => UNDEF */
3537 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3538 /* UNPREDICTABLE cases for bad immediates: we choose to
3539 * UNDEF to avoid generating huge numbers of TCG ops
3543 if (rn
== 15 && w
) {
3544 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3548 if (s
->thumb
&& rn
== 15) {
3549 /* This is actually UNPREDICTABLE */
3550 addr
= tcg_temp_new_i32();
3551 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3553 addr
= load_reg(s
, rn
);
3555 if (insn
& (1 << 24)) /* pre-decrement */
3556 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3562 for (i
= 0; i
< n
; i
++) {
3563 if (insn
& ARM_CP_RW_BIT
) {
3565 gen_vfp_ld(s
, dp
, addr
);
3566 gen_mov_vreg_F0(dp
, rd
+ i
);
3569 gen_mov_F0_vreg(dp
, rd
+ i
);
3570 gen_vfp_st(s
, dp
, addr
);
3572 tcg_gen_addi_i32(addr
, addr
, offset
);
3576 if (insn
& (1 << 24))
3577 offset
= -offset
* n
;
3578 else if (dp
&& (insn
& 1))
3584 tcg_gen_addi_i32(addr
, addr
, offset
);
3585 store_reg(s
, rn
, addr
);
3587 tcg_temp_free_i32(addr
);
3593 /* Should never happen. */
3599 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3601 TranslationBlock
*tb
;
3604 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3606 gen_set_pc_im(s
, dest
);
3607 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3609 gen_set_pc_im(s
, dest
);
3614 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3616 if (unlikely(s
->singlestep_enabled
)) {
3617 /* An indirect jump so that we still trigger the debug exception. */
3622 gen_goto_tb(s
, 0, dest
);
3623 s
->is_jmp
= DISAS_TB_JUMP
;
3627 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3630 tcg_gen_sari_i32(t0
, t0
, 16);
3634 tcg_gen_sari_i32(t1
, t1
, 16);
3637 tcg_gen_mul_i32(t0
, t0
, t1
);
3640 /* Return the mask of PSR bits set by a MSR instruction. */
3641 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3645 if (flags
& (1 << 0))
3647 if (flags
& (1 << 1))
3649 if (flags
& (1 << 2))
3651 if (flags
& (1 << 3))
3654 /* Mask out undefined bits. */
3655 mask
&= ~CPSR_RESERVED
;
3656 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3658 if (!arm_feature(env
, ARM_FEATURE_V5
))
3659 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3660 if (!arm_feature(env
, ARM_FEATURE_V6
))
3661 mask
&= ~(CPSR_E
| CPSR_GE
);
3662 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3664 /* Mask out execution state bits. */
3667 /* Mask out privileged bits. */
3673 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3674 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3678 /* ??? This is also undefined in system mode. */
3682 tmp
= load_cpu_field(spsr
);
3683 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3684 tcg_gen_andi_i32(t0
, t0
, mask
);
3685 tcg_gen_or_i32(tmp
, tmp
, t0
);
3686 store_cpu_field(tmp
, spsr
);
3688 gen_set_cpsr(t0
, mask
);
3690 tcg_temp_free_i32(t0
);
3695 /* Returns nonzero if access to the PSR is not permitted. */
3696 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3699 tmp
= tcg_temp_new_i32();
3700 tcg_gen_movi_i32(tmp
, val
);
3701 return gen_set_psr(s
, mask
, spsr
, tmp
);
3704 /* Generate an old-style exception return. Marks pc as dead. */
3705 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3708 store_reg(s
, 15, pc
);
3709 tmp
= load_cpu_field(spsr
);
3710 gen_set_cpsr(tmp
, 0xffffffff);
3711 tcg_temp_free_i32(tmp
);
3712 s
->is_jmp
= DISAS_UPDATE
;
3715 /* Generate a v6 exception return. Marks both values as dead. */
3716 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3718 gen_set_cpsr(cpsr
, 0xffffffff);
3719 tcg_temp_free_i32(cpsr
);
3720 store_reg(s
, 15, pc
);
3721 s
->is_jmp
= DISAS_UPDATE
;
3725 gen_set_condexec (DisasContext
*s
)
3727 if (s
->condexec_mask
) {
3728 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3729 TCGv_i32 tmp
= tcg_temp_new_i32();
3730 tcg_gen_movi_i32(tmp
, val
);
3731 store_cpu_field(tmp
, condexec_bits
);
3735 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3737 gen_set_condexec(s
);
3738 gen_set_pc_im(s
, s
->pc
- offset
);
3739 gen_exception(excp
);
3740 s
->is_jmp
= DISAS_JUMP
;
3743 static void gen_nop_hint(DisasContext
*s
, int val
)
3747 gen_set_pc_im(s
, s
->pc
);
3748 s
->is_jmp
= DISAS_WFI
;
3753 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3759 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3761 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3764 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3765 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3766 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3771 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3774 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3775 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3776 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3781 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3782 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3783 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3784 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3785 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3787 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3788 switch ((size << 1) | u) { \
3790 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3793 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3796 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3799 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3802 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3805 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3807 default: return 1; \
3810 #define GEN_NEON_INTEGER_OP(name) do { \
3811 switch ((size << 1) | u) { \
3813 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3816 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3819 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3822 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3825 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3828 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3830 default: return 1; \
3833 static TCGv_i32
neon_load_scratch(int scratch
)
3835 TCGv_i32 tmp
= tcg_temp_new_i32();
3836 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3840 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3842 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3843 tcg_temp_free_i32(var
);
3846 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3850 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3852 gen_neon_dup_high16(tmp
);
3854 gen_neon_dup_low16(tmp
);
3857 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3862 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3865 if (!q
&& size
== 2) {
3868 tmp
= tcg_const_i32(rd
);
3869 tmp2
= tcg_const_i32(rm
);
3873 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3876 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3879 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3887 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3890 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3896 tcg_temp_free_i32(tmp
);
3897 tcg_temp_free_i32(tmp2
);
3901 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3904 if (!q
&& size
== 2) {
3907 tmp
= tcg_const_i32(rd
);
3908 tmp2
= tcg_const_i32(rm
);
3912 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3915 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3918 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3926 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3929 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3935 tcg_temp_free_i32(tmp
);
3936 tcg_temp_free_i32(tmp2
);
3940 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3944 rd
= tcg_temp_new_i32();
3945 tmp
= tcg_temp_new_i32();
3947 tcg_gen_shli_i32(rd
, t0
, 8);
3948 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3949 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3950 tcg_gen_or_i32(rd
, rd
, tmp
);
3952 tcg_gen_shri_i32(t1
, t1
, 8);
3953 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3954 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3955 tcg_gen_or_i32(t1
, t1
, tmp
);
3956 tcg_gen_mov_i32(t0
, rd
);
3958 tcg_temp_free_i32(tmp
);
3959 tcg_temp_free_i32(rd
);
3962 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3966 rd
= tcg_temp_new_i32();
3967 tmp
= tcg_temp_new_i32();
3969 tcg_gen_shli_i32(rd
, t0
, 16);
3970 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3971 tcg_gen_or_i32(rd
, rd
, tmp
);
3972 tcg_gen_shri_i32(t1
, t1
, 16);
3973 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3974 tcg_gen_or_i32(t1
, t1
, tmp
);
3975 tcg_gen_mov_i32(t0
, rd
);
3977 tcg_temp_free_i32(tmp
);
3978 tcg_temp_free_i32(rd
);
3986 } neon_ls_element_type
[11] = {
4000 /* Translate a NEON load/store element instruction. Return nonzero if the
4001 instruction is invalid. */
4002 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4021 if (!s
->vfp_enabled
)
4023 VFP_DREG_D(rd
, insn
);
4024 rn
= (insn
>> 16) & 0xf;
4026 load
= (insn
& (1 << 21)) != 0;
4027 if ((insn
& (1 << 23)) == 0) {
4028 /* Load store all elements. */
4029 op
= (insn
>> 8) & 0xf;
4030 size
= (insn
>> 6) & 3;
4033 /* Catch UNDEF cases for bad values of align field */
4036 if (((insn
>> 5) & 1) == 1) {
4041 if (((insn
>> 4) & 3) == 3) {
4048 nregs
= neon_ls_element_type
[op
].nregs
;
4049 interleave
= neon_ls_element_type
[op
].interleave
;
4050 spacing
= neon_ls_element_type
[op
].spacing
;
4051 if (size
== 3 && (interleave
| spacing
) != 1)
4053 addr
= tcg_temp_new_i32();
4054 load_reg_var(s
, addr
, rn
);
4055 stride
= (1 << size
) * interleave
;
4056 for (reg
= 0; reg
< nregs
; reg
++) {
4057 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4058 load_reg_var(s
, addr
, rn
);
4059 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4060 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4061 load_reg_var(s
, addr
, rn
);
4062 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4065 tmp64
= tcg_temp_new_i64();
4067 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
4068 neon_store_reg64(tmp64
, rd
);
4070 neon_load_reg64(tmp64
, rd
);
4071 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
4073 tcg_temp_free_i64(tmp64
);
4074 tcg_gen_addi_i32(addr
, addr
, stride
);
4076 for (pass
= 0; pass
< 2; pass
++) {
4079 tmp
= tcg_temp_new_i32();
4080 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4081 neon_store_reg(rd
, pass
, tmp
);
4083 tmp
= neon_load_reg(rd
, pass
);
4084 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4085 tcg_temp_free_i32(tmp
);
4087 tcg_gen_addi_i32(addr
, addr
, stride
);
4088 } else if (size
== 1) {
4090 tmp
= tcg_temp_new_i32();
4091 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4092 tcg_gen_addi_i32(addr
, addr
, stride
);
4093 tmp2
= tcg_temp_new_i32();
4094 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
4095 tcg_gen_addi_i32(addr
, addr
, stride
);
4096 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4097 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4098 tcg_temp_free_i32(tmp2
);
4099 neon_store_reg(rd
, pass
, tmp
);
4101 tmp
= neon_load_reg(rd
, pass
);
4102 tmp2
= tcg_temp_new_i32();
4103 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4104 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4105 tcg_temp_free_i32(tmp
);
4106 tcg_gen_addi_i32(addr
, addr
, stride
);
4107 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
4108 tcg_temp_free_i32(tmp2
);
4109 tcg_gen_addi_i32(addr
, addr
, stride
);
4111 } else /* size == 0 */ {
4113 TCGV_UNUSED_I32(tmp2
);
4114 for (n
= 0; n
< 4; n
++) {
4115 tmp
= tcg_temp_new_i32();
4116 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4117 tcg_gen_addi_i32(addr
, addr
, stride
);
4121 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4122 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4123 tcg_temp_free_i32(tmp
);
4126 neon_store_reg(rd
, pass
, tmp2
);
4128 tmp2
= neon_load_reg(rd
, pass
);
4129 for (n
= 0; n
< 4; n
++) {
4130 tmp
= tcg_temp_new_i32();
4132 tcg_gen_mov_i32(tmp
, tmp2
);
4134 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4136 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4137 tcg_temp_free_i32(tmp
);
4138 tcg_gen_addi_i32(addr
, addr
, stride
);
4140 tcg_temp_free_i32(tmp2
);
4147 tcg_temp_free_i32(addr
);
4150 size
= (insn
>> 10) & 3;
4152 /* Load single element to all lanes. */
4153 int a
= (insn
>> 4) & 1;
4157 size
= (insn
>> 6) & 3;
4158 nregs
= ((insn
>> 8) & 3) + 1;
4161 if (nregs
!= 4 || a
== 0) {
4164 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4167 if (nregs
== 1 && a
== 1 && size
== 0) {
4170 if (nregs
== 3 && a
== 1) {
4173 addr
= tcg_temp_new_i32();
4174 load_reg_var(s
, addr
, rn
);
4176 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4177 tmp
= gen_load_and_replicate(s
, addr
, size
);
4178 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4179 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4180 if (insn
& (1 << 5)) {
4181 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4182 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4184 tcg_temp_free_i32(tmp
);
4186 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4187 stride
= (insn
& (1 << 5)) ? 2 : 1;
4188 for (reg
= 0; reg
< nregs
; reg
++) {
4189 tmp
= gen_load_and_replicate(s
, addr
, size
);
4190 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4191 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4192 tcg_temp_free_i32(tmp
);
4193 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4197 tcg_temp_free_i32(addr
);
4198 stride
= (1 << size
) * nregs
;
4200 /* Single element. */
4201 int idx
= (insn
>> 4) & 0xf;
4202 pass
= (insn
>> 7) & 1;
4205 shift
= ((insn
>> 5) & 3) * 8;
4209 shift
= ((insn
>> 6) & 1) * 16;
4210 stride
= (insn
& (1 << 5)) ? 2 : 1;
4214 stride
= (insn
& (1 << 6)) ? 2 : 1;
4219 nregs
= ((insn
>> 8) & 3) + 1;
4220 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4223 if (((idx
& (1 << size
)) != 0) ||
4224 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4229 if ((idx
& 1) != 0) {
4234 if (size
== 2 && (idx
& 2) != 0) {
4239 if ((size
== 2) && ((idx
& 3) == 3)) {
4246 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4247 /* Attempts to write off the end of the register file
4248 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4249 * the neon_load_reg() would write off the end of the array.
4253 addr
= tcg_temp_new_i32();
4254 load_reg_var(s
, addr
, rn
);
4255 for (reg
= 0; reg
< nregs
; reg
++) {
4257 tmp
= tcg_temp_new_i32();
4260 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4263 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4266 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4268 default: /* Avoid compiler warnings. */
4272 tmp2
= neon_load_reg(rd
, pass
);
4273 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4274 shift
, size
? 16 : 8);
4275 tcg_temp_free_i32(tmp2
);
4277 neon_store_reg(rd
, pass
, tmp
);
4278 } else { /* Store */
4279 tmp
= neon_load_reg(rd
, pass
);
4281 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4284 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4287 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4290 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4293 tcg_temp_free_i32(tmp
);
4296 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4298 tcg_temp_free_i32(addr
);
4299 stride
= nregs
* (1 << size
);
4305 base
= load_reg(s
, rn
);
4307 tcg_gen_addi_i32(base
, base
, stride
);
4310 index
= load_reg(s
, rm
);
4311 tcg_gen_add_i32(base
, base
, index
);
4312 tcg_temp_free_i32(index
);
4314 store_reg(s
, rn
, base
);
4319 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4320 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4322 tcg_gen_and_i32(t
, t
, c
);
4323 tcg_gen_andc_i32(f
, f
, c
);
4324 tcg_gen_or_i32(dest
, t
, f
);
4327 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4330 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4331 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4332 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4337 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4340 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4341 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4342 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4347 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4350 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4351 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4352 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4357 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4360 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4361 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4362 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4367 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4373 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4374 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4379 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4380 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4387 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4388 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4393 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4394 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4401 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4405 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4406 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4407 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4412 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4413 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4414 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4418 tcg_temp_free_i32(src
);
4421 static inline void gen_neon_addl(int size
)
4424 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4425 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4426 case 2: tcg_gen_add_i64(CPU_V001
); break;
4431 static inline void gen_neon_subl(int size
)
4434 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4435 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4436 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4441 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4444 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4445 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4447 tcg_gen_neg_i64(var
, var
);
4453 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4456 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4457 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4462 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4467 switch ((size
<< 1) | u
) {
4468 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4469 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4470 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4471 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4473 tmp
= gen_muls_i64_i32(a
, b
);
4474 tcg_gen_mov_i64(dest
, tmp
);
4475 tcg_temp_free_i64(tmp
);
4478 tmp
= gen_mulu_i64_i32(a
, b
);
4479 tcg_gen_mov_i64(dest
, tmp
);
4480 tcg_temp_free_i64(tmp
);
4485 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4486 Don't forget to clean them now. */
4488 tcg_temp_free_i32(a
);
4489 tcg_temp_free_i32(b
);
4493 static void gen_neon_narrow_op(int op
, int u
, int size
,
4494 TCGv_i32 dest
, TCGv_i64 src
)
4498 gen_neon_unarrow_sats(size
, dest
, src
);
4500 gen_neon_narrow(size
, dest
, src
);
4504 gen_neon_narrow_satu(size
, dest
, src
);
4506 gen_neon_narrow_sats(size
, dest
, src
);
4511 /* Symbolic constants for op fields for Neon 3-register same-length.
4512 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4515 #define NEON_3R_VHADD 0
4516 #define NEON_3R_VQADD 1
4517 #define NEON_3R_VRHADD 2
4518 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4519 #define NEON_3R_VHSUB 4
4520 #define NEON_3R_VQSUB 5
4521 #define NEON_3R_VCGT 6
4522 #define NEON_3R_VCGE 7
4523 #define NEON_3R_VSHL 8
4524 #define NEON_3R_VQSHL 9
4525 #define NEON_3R_VRSHL 10
4526 #define NEON_3R_VQRSHL 11
4527 #define NEON_3R_VMAX 12
4528 #define NEON_3R_VMIN 13
4529 #define NEON_3R_VABD 14
4530 #define NEON_3R_VABA 15
4531 #define NEON_3R_VADD_VSUB 16
4532 #define NEON_3R_VTST_VCEQ 17
4533 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4534 #define NEON_3R_VMUL 19
4535 #define NEON_3R_VPMAX 20
4536 #define NEON_3R_VPMIN 21
4537 #define NEON_3R_VQDMULH_VQRDMULH 22
4538 #define NEON_3R_VPADD 23
4539 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4540 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4541 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4542 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4543 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4544 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4545 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4547 static const uint8_t neon_3r_sizes
[] = {
4548 [NEON_3R_VHADD
] = 0x7,
4549 [NEON_3R_VQADD
] = 0xf,
4550 [NEON_3R_VRHADD
] = 0x7,
4551 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4552 [NEON_3R_VHSUB
] = 0x7,
4553 [NEON_3R_VQSUB
] = 0xf,
4554 [NEON_3R_VCGT
] = 0x7,
4555 [NEON_3R_VCGE
] = 0x7,
4556 [NEON_3R_VSHL
] = 0xf,
4557 [NEON_3R_VQSHL
] = 0xf,
4558 [NEON_3R_VRSHL
] = 0xf,
4559 [NEON_3R_VQRSHL
] = 0xf,
4560 [NEON_3R_VMAX
] = 0x7,
4561 [NEON_3R_VMIN
] = 0x7,
4562 [NEON_3R_VABD
] = 0x7,
4563 [NEON_3R_VABA
] = 0x7,
4564 [NEON_3R_VADD_VSUB
] = 0xf,
4565 [NEON_3R_VTST_VCEQ
] = 0x7,
4566 [NEON_3R_VML
] = 0x7,
4567 [NEON_3R_VMUL
] = 0x7,
4568 [NEON_3R_VPMAX
] = 0x7,
4569 [NEON_3R_VPMIN
] = 0x7,
4570 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4571 [NEON_3R_VPADD
] = 0x7,
4572 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4573 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4574 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4575 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4576 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4577 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4578 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4581 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4582 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4585 #define NEON_2RM_VREV64 0
4586 #define NEON_2RM_VREV32 1
4587 #define NEON_2RM_VREV16 2
4588 #define NEON_2RM_VPADDL 4
4589 #define NEON_2RM_VPADDL_U 5
4590 #define NEON_2RM_AESE 6 /* Includes AESD */
4591 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4592 #define NEON_2RM_VCLS 8
4593 #define NEON_2RM_VCLZ 9
4594 #define NEON_2RM_VCNT 10
4595 #define NEON_2RM_VMVN 11
4596 #define NEON_2RM_VPADAL 12
4597 #define NEON_2RM_VPADAL_U 13
4598 #define NEON_2RM_VQABS 14
4599 #define NEON_2RM_VQNEG 15
4600 #define NEON_2RM_VCGT0 16
4601 #define NEON_2RM_VCGE0 17
4602 #define NEON_2RM_VCEQ0 18
4603 #define NEON_2RM_VCLE0 19
4604 #define NEON_2RM_VCLT0 20
4605 #define NEON_2RM_VABS 22
4606 #define NEON_2RM_VNEG 23
4607 #define NEON_2RM_VCGT0_F 24
4608 #define NEON_2RM_VCGE0_F 25
4609 #define NEON_2RM_VCEQ0_F 26
4610 #define NEON_2RM_VCLE0_F 27
4611 #define NEON_2RM_VCLT0_F 28
4612 #define NEON_2RM_VABS_F 30
4613 #define NEON_2RM_VNEG_F 31
4614 #define NEON_2RM_VSWP 32
4615 #define NEON_2RM_VTRN 33
4616 #define NEON_2RM_VUZP 34
4617 #define NEON_2RM_VZIP 35
4618 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4619 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4620 #define NEON_2RM_VSHLL 38
4621 #define NEON_2RM_VCVT_F16_F32 44
4622 #define NEON_2RM_VCVT_F32_F16 46
4623 #define NEON_2RM_VRECPE 56
4624 #define NEON_2RM_VRSQRTE 57
4625 #define NEON_2RM_VRECPE_F 58
4626 #define NEON_2RM_VRSQRTE_F 59
4627 #define NEON_2RM_VCVT_FS 60
4628 #define NEON_2RM_VCVT_FU 61
4629 #define NEON_2RM_VCVT_SF 62
4630 #define NEON_2RM_VCVT_UF 63
4632 static int neon_2rm_is_float_op(int op
)
4634 /* Return true if this neon 2reg-misc op is float-to-float */
4635 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4636 op
>= NEON_2RM_VRECPE_F
);
4639 /* Each entry in this array has bit n set if the insn allows
4640 * size value n (otherwise it will UNDEF). Since unallocated
4641 * op values will have no bits set they always UNDEF.
4643 static const uint8_t neon_2rm_sizes
[] = {
4644 [NEON_2RM_VREV64
] = 0x7,
4645 [NEON_2RM_VREV32
] = 0x3,
4646 [NEON_2RM_VREV16
] = 0x1,
4647 [NEON_2RM_VPADDL
] = 0x7,
4648 [NEON_2RM_VPADDL_U
] = 0x7,
4649 [NEON_2RM_AESE
] = 0x1,
4650 [NEON_2RM_AESMC
] = 0x1,
4651 [NEON_2RM_VCLS
] = 0x7,
4652 [NEON_2RM_VCLZ
] = 0x7,
4653 [NEON_2RM_VCNT
] = 0x1,
4654 [NEON_2RM_VMVN
] = 0x1,
4655 [NEON_2RM_VPADAL
] = 0x7,
4656 [NEON_2RM_VPADAL_U
] = 0x7,
4657 [NEON_2RM_VQABS
] = 0x7,
4658 [NEON_2RM_VQNEG
] = 0x7,
4659 [NEON_2RM_VCGT0
] = 0x7,
4660 [NEON_2RM_VCGE0
] = 0x7,
4661 [NEON_2RM_VCEQ0
] = 0x7,
4662 [NEON_2RM_VCLE0
] = 0x7,
4663 [NEON_2RM_VCLT0
] = 0x7,
4664 [NEON_2RM_VABS
] = 0x7,
4665 [NEON_2RM_VNEG
] = 0x7,
4666 [NEON_2RM_VCGT0_F
] = 0x4,
4667 [NEON_2RM_VCGE0_F
] = 0x4,
4668 [NEON_2RM_VCEQ0_F
] = 0x4,
4669 [NEON_2RM_VCLE0_F
] = 0x4,
4670 [NEON_2RM_VCLT0_F
] = 0x4,
4671 [NEON_2RM_VABS_F
] = 0x4,
4672 [NEON_2RM_VNEG_F
] = 0x4,
4673 [NEON_2RM_VSWP
] = 0x1,
4674 [NEON_2RM_VTRN
] = 0x7,
4675 [NEON_2RM_VUZP
] = 0x7,
4676 [NEON_2RM_VZIP
] = 0x7,
4677 [NEON_2RM_VMOVN
] = 0x7,
4678 [NEON_2RM_VQMOVN
] = 0x7,
4679 [NEON_2RM_VSHLL
] = 0x7,
4680 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4681 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4682 [NEON_2RM_VRECPE
] = 0x4,
4683 [NEON_2RM_VRSQRTE
] = 0x4,
4684 [NEON_2RM_VRECPE_F
] = 0x4,
4685 [NEON_2RM_VRSQRTE_F
] = 0x4,
4686 [NEON_2RM_VCVT_FS
] = 0x4,
4687 [NEON_2RM_VCVT_FU
] = 0x4,
4688 [NEON_2RM_VCVT_SF
] = 0x4,
4689 [NEON_2RM_VCVT_UF
] = 0x4,
4692 /* Translate a NEON data processing instruction. Return nonzero if the
4693 instruction is invalid.
4694 We process data in a mixture of 32-bit and 64-bit chunks.
4695 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4697 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4709 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4712 if (!s
->vfp_enabled
)
4714 q
= (insn
& (1 << 6)) != 0;
4715 u
= (insn
>> 24) & 1;
4716 VFP_DREG_D(rd
, insn
);
4717 VFP_DREG_N(rn
, insn
);
4718 VFP_DREG_M(rm
, insn
);
4719 size
= (insn
>> 20) & 3;
4720 if ((insn
& (1 << 23)) == 0) {
4721 /* Three register same length. */
4722 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4723 /* Catch invalid op and bad size combinations: UNDEF */
4724 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4727 /* All insns of this form UNDEF for either this condition or the
4728 * superset of cases "Q==1"; we catch the latter later.
4730 if (q
&& ((rd
| rn
| rm
) & 1)) {
4733 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4734 /* 64-bit element instructions. */
4735 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4736 neon_load_reg64(cpu_V0
, rn
+ pass
);
4737 neon_load_reg64(cpu_V1
, rm
+ pass
);
4741 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4744 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4750 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4753 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4759 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4761 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4766 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4769 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4775 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4777 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4780 case NEON_3R_VQRSHL
:
4782 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4785 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4789 case NEON_3R_VADD_VSUB
:
4791 tcg_gen_sub_i64(CPU_V001
);
4793 tcg_gen_add_i64(CPU_V001
);
4799 neon_store_reg64(cpu_V0
, rd
+ pass
);
4808 case NEON_3R_VQRSHL
:
4811 /* Shift instruction operands are reversed. */
4826 case NEON_3R_FLOAT_ARITH
:
4827 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4829 case NEON_3R_FLOAT_MINMAX
:
4830 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4832 case NEON_3R_FLOAT_CMP
:
4834 /* no encoding for U=0 C=1x */
4838 case NEON_3R_FLOAT_ACMP
:
4843 case NEON_3R_FLOAT_MISC
:
4844 /* VMAXNM/VMINNM in ARMv8 */
4845 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
4850 if (u
&& (size
!= 0)) {
4851 /* UNDEF on invalid size for polynomial subcase */
4856 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4864 if (pairwise
&& q
) {
4865 /* All the pairwise insns UNDEF if Q is set */
4869 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4874 tmp
= neon_load_reg(rn
, 0);
4875 tmp2
= neon_load_reg(rn
, 1);
4877 tmp
= neon_load_reg(rm
, 0);
4878 tmp2
= neon_load_reg(rm
, 1);
4882 tmp
= neon_load_reg(rn
, pass
);
4883 tmp2
= neon_load_reg(rm
, pass
);
4887 GEN_NEON_INTEGER_OP(hadd
);
4890 GEN_NEON_INTEGER_OP_ENV(qadd
);
4892 case NEON_3R_VRHADD
:
4893 GEN_NEON_INTEGER_OP(rhadd
);
4895 case NEON_3R_LOGIC
: /* Logic ops. */
4896 switch ((u
<< 2) | size
) {
4898 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4901 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4904 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4907 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4910 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4913 tmp3
= neon_load_reg(rd
, pass
);
4914 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4915 tcg_temp_free_i32(tmp3
);
4918 tmp3
= neon_load_reg(rd
, pass
);
4919 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4920 tcg_temp_free_i32(tmp3
);
4923 tmp3
= neon_load_reg(rd
, pass
);
4924 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4925 tcg_temp_free_i32(tmp3
);
4930 GEN_NEON_INTEGER_OP(hsub
);
4933 GEN_NEON_INTEGER_OP_ENV(qsub
);
4936 GEN_NEON_INTEGER_OP(cgt
);
4939 GEN_NEON_INTEGER_OP(cge
);
4942 GEN_NEON_INTEGER_OP(shl
);
4945 GEN_NEON_INTEGER_OP_ENV(qshl
);
4948 GEN_NEON_INTEGER_OP(rshl
);
4950 case NEON_3R_VQRSHL
:
4951 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4954 GEN_NEON_INTEGER_OP(max
);
4957 GEN_NEON_INTEGER_OP(min
);
4960 GEN_NEON_INTEGER_OP(abd
);
4963 GEN_NEON_INTEGER_OP(abd
);
4964 tcg_temp_free_i32(tmp2
);
4965 tmp2
= neon_load_reg(rd
, pass
);
4966 gen_neon_add(size
, tmp
, tmp2
);
4968 case NEON_3R_VADD_VSUB
:
4969 if (!u
) { /* VADD */
4970 gen_neon_add(size
, tmp
, tmp2
);
4973 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4974 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4975 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4980 case NEON_3R_VTST_VCEQ
:
4981 if (!u
) { /* VTST */
4983 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4984 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4985 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4990 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4991 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4992 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4997 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4999 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5000 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5001 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5004 tcg_temp_free_i32(tmp2
);
5005 tmp2
= neon_load_reg(rd
, pass
);
5007 gen_neon_rsb(size
, tmp
, tmp2
);
5009 gen_neon_add(size
, tmp
, tmp2
);
5013 if (u
) { /* polynomial */
5014 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5015 } else { /* Integer */
5017 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5018 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5019 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5025 GEN_NEON_INTEGER_OP(pmax
);
5028 GEN_NEON_INTEGER_OP(pmin
);
5030 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5031 if (!u
) { /* VQDMULH */
5034 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5037 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5041 } else { /* VQRDMULH */
5044 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5047 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5055 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5056 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5057 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5061 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5063 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5064 switch ((u
<< 2) | size
) {
5067 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5070 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5073 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5078 tcg_temp_free_ptr(fpstatus
);
5081 case NEON_3R_FLOAT_MULTIPLY
:
5083 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5084 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5086 tcg_temp_free_i32(tmp2
);
5087 tmp2
= neon_load_reg(rd
, pass
);
5089 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5091 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5094 tcg_temp_free_ptr(fpstatus
);
5097 case NEON_3R_FLOAT_CMP
:
5099 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5101 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5104 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5106 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5109 tcg_temp_free_ptr(fpstatus
);
5112 case NEON_3R_FLOAT_ACMP
:
5114 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5116 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5118 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5120 tcg_temp_free_ptr(fpstatus
);
5123 case NEON_3R_FLOAT_MINMAX
:
5125 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5127 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
5129 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
5131 tcg_temp_free_ptr(fpstatus
);
5134 case NEON_3R_FLOAT_MISC
:
5137 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5139 gen_helper_vfp_maxnms(tmp
, tmp
, tmp2
, fpstatus
);
5141 gen_helper_vfp_minnms(tmp
, tmp
, tmp2
, fpstatus
);
5143 tcg_temp_free_ptr(fpstatus
);
5146 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5148 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5154 /* VFMA, VFMS: fused multiply-add */
5155 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5156 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5159 gen_helper_vfp_negs(tmp
, tmp
);
5161 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5162 tcg_temp_free_i32(tmp3
);
5163 tcg_temp_free_ptr(fpstatus
);
5169 tcg_temp_free_i32(tmp2
);
5171 /* Save the result. For elementwise operations we can put it
5172 straight into the destination register. For pairwise operations
5173 we have to be careful to avoid clobbering the source operands. */
5174 if (pairwise
&& rd
== rm
) {
5175 neon_store_scratch(pass
, tmp
);
5177 neon_store_reg(rd
, pass
, tmp
);
5181 if (pairwise
&& rd
== rm
) {
5182 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5183 tmp
= neon_load_scratch(pass
);
5184 neon_store_reg(rd
, pass
, tmp
);
5187 /* End of 3 register same size operations. */
5188 } else if (insn
& (1 << 4)) {
5189 if ((insn
& 0x00380080) != 0) {
5190 /* Two registers and shift. */
5191 op
= (insn
>> 8) & 0xf;
5192 if (insn
& (1 << 7)) {
5200 while ((insn
& (1 << (size
+ 19))) == 0)
5203 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5204 /* To avoid excessive duplication of ops we implement shift
5205 by immediate using the variable shift operations. */
5207 /* Shift by immediate:
5208 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5209 if (q
&& ((rd
| rm
) & 1)) {
5212 if (!u
&& (op
== 4 || op
== 6)) {
5215 /* Right shifts are encoded as N - shift, where N is the
5216 element size in bits. */
5218 shift
= shift
- (1 << (size
+ 3));
5226 imm
= (uint8_t) shift
;
5231 imm
= (uint16_t) shift
;
5242 for (pass
= 0; pass
< count
; pass
++) {
5244 neon_load_reg64(cpu_V0
, rm
+ pass
);
5245 tcg_gen_movi_i64(cpu_V1
, imm
);
5250 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5252 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5257 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5259 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5262 case 5: /* VSHL, VSLI */
5263 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5265 case 6: /* VQSHLU */
5266 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5271 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5274 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5279 if (op
== 1 || op
== 3) {
5281 neon_load_reg64(cpu_V1
, rd
+ pass
);
5282 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5283 } else if (op
== 4 || (op
== 5 && u
)) {
5285 neon_load_reg64(cpu_V1
, rd
+ pass
);
5287 if (shift
< -63 || shift
> 63) {
5291 mask
= 0xffffffffffffffffull
>> -shift
;
5293 mask
= 0xffffffffffffffffull
<< shift
;
5296 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5297 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5299 neon_store_reg64(cpu_V0
, rd
+ pass
);
5300 } else { /* size < 3 */
5301 /* Operands in T0 and T1. */
5302 tmp
= neon_load_reg(rm
, pass
);
5303 tmp2
= tcg_temp_new_i32();
5304 tcg_gen_movi_i32(tmp2
, imm
);
5308 GEN_NEON_INTEGER_OP(shl
);
5312 GEN_NEON_INTEGER_OP(rshl
);
5315 case 5: /* VSHL, VSLI */
5317 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5318 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5319 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5323 case 6: /* VQSHLU */
5326 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5330 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5334 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5342 GEN_NEON_INTEGER_OP_ENV(qshl
);
5345 tcg_temp_free_i32(tmp2
);
5347 if (op
== 1 || op
== 3) {
5349 tmp2
= neon_load_reg(rd
, pass
);
5350 gen_neon_add(size
, tmp
, tmp2
);
5351 tcg_temp_free_i32(tmp2
);
5352 } else if (op
== 4 || (op
== 5 && u
)) {
5357 mask
= 0xff >> -shift
;
5359 mask
= (uint8_t)(0xff << shift
);
5365 mask
= 0xffff >> -shift
;
5367 mask
= (uint16_t)(0xffff << shift
);
5371 if (shift
< -31 || shift
> 31) {
5375 mask
= 0xffffffffu
>> -shift
;
5377 mask
= 0xffffffffu
<< shift
;
5383 tmp2
= neon_load_reg(rd
, pass
);
5384 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5385 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5386 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5387 tcg_temp_free_i32(tmp2
);
5389 neon_store_reg(rd
, pass
, tmp
);
5392 } else if (op
< 10) {
5393 /* Shift by immediate and narrow:
5394 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5395 int input_unsigned
= (op
== 8) ? !u
: u
;
5399 shift
= shift
- (1 << (size
+ 3));
5402 tmp64
= tcg_const_i64(shift
);
5403 neon_load_reg64(cpu_V0
, rm
);
5404 neon_load_reg64(cpu_V1
, rm
+ 1);
5405 for (pass
= 0; pass
< 2; pass
++) {
5413 if (input_unsigned
) {
5414 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5416 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5419 if (input_unsigned
) {
5420 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5422 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5425 tmp
= tcg_temp_new_i32();
5426 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5427 neon_store_reg(rd
, pass
, tmp
);
5429 tcg_temp_free_i64(tmp64
);
5432 imm
= (uint16_t)shift
;
5436 imm
= (uint32_t)shift
;
5438 tmp2
= tcg_const_i32(imm
);
5439 tmp4
= neon_load_reg(rm
+ 1, 0);
5440 tmp5
= neon_load_reg(rm
+ 1, 1);
5441 for (pass
= 0; pass
< 2; pass
++) {
5443 tmp
= neon_load_reg(rm
, 0);
5447 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5450 tmp3
= neon_load_reg(rm
, 1);
5454 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5456 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5457 tcg_temp_free_i32(tmp
);
5458 tcg_temp_free_i32(tmp3
);
5459 tmp
= tcg_temp_new_i32();
5460 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5461 neon_store_reg(rd
, pass
, tmp
);
5463 tcg_temp_free_i32(tmp2
);
5465 } else if (op
== 10) {
5467 if (q
|| (rd
& 1)) {
5470 tmp
= neon_load_reg(rm
, 0);
5471 tmp2
= neon_load_reg(rm
, 1);
5472 for (pass
= 0; pass
< 2; pass
++) {
5476 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5479 /* The shift is less than the width of the source
5480 type, so we can just shift the whole register. */
5481 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5482 /* Widen the result of shift: we need to clear
5483 * the potential overflow bits resulting from
5484 * left bits of the narrow input appearing as
5485 * right bits of left the neighbour narrow
5487 if (size
< 2 || !u
) {
5490 imm
= (0xffu
>> (8 - shift
));
5492 } else if (size
== 1) {
5493 imm
= 0xffff >> (16 - shift
);
5496 imm
= 0xffffffff >> (32 - shift
);
5499 imm64
= imm
| (((uint64_t)imm
) << 32);
5503 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5506 neon_store_reg64(cpu_V0
, rd
+ pass
);
5508 } else if (op
>= 14) {
5509 /* VCVT fixed-point. */
5510 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5513 /* We have already masked out the must-be-1 top bit of imm6,
5514 * hence this 32-shift where the ARM ARM has 64-imm6.
5517 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5518 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5521 gen_vfp_ulto(0, shift
, 1);
5523 gen_vfp_slto(0, shift
, 1);
5526 gen_vfp_toul(0, shift
, 1);
5528 gen_vfp_tosl(0, shift
, 1);
5530 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5535 } else { /* (insn & 0x00380080) == 0 */
5537 if (q
&& (rd
& 1)) {
5541 op
= (insn
>> 8) & 0xf;
5542 /* One register and immediate. */
5543 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5544 invert
= (insn
& (1 << 5)) != 0;
5545 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5546 * We choose to not special-case this and will behave as if a
5547 * valid constant encoding of 0 had been given.
5566 imm
= (imm
<< 8) | (imm
<< 24);
5569 imm
= (imm
<< 8) | 0xff;
5572 imm
= (imm
<< 16) | 0xffff;
5575 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5583 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5584 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5590 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5591 if (op
& 1 && op
< 12) {
5592 tmp
= neon_load_reg(rd
, pass
);
5594 /* The immediate value has already been inverted, so
5596 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5598 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5602 tmp
= tcg_temp_new_i32();
5603 if (op
== 14 && invert
) {
5607 for (n
= 0; n
< 4; n
++) {
5608 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5609 val
|= 0xff << (n
* 8);
5611 tcg_gen_movi_i32(tmp
, val
);
5613 tcg_gen_movi_i32(tmp
, imm
);
5616 neon_store_reg(rd
, pass
, tmp
);
5619 } else { /* (insn & 0x00800010 == 0x00800000) */
5621 op
= (insn
>> 8) & 0xf;
5622 if ((insn
& (1 << 6)) == 0) {
5623 /* Three registers of different lengths. */
5627 /* undefreq: bit 0 : UNDEF if size != 0
5628 * bit 1 : UNDEF if size == 0
5629 * bit 2 : UNDEF if U == 1
5630 * Note that [1:0] set implies 'always UNDEF'
5633 /* prewiden, src1_wide, src2_wide, undefreq */
5634 static const int neon_3reg_wide
[16][4] = {
5635 {1, 0, 0, 0}, /* VADDL */
5636 {1, 1, 0, 0}, /* VADDW */
5637 {1, 0, 0, 0}, /* VSUBL */
5638 {1, 1, 0, 0}, /* VSUBW */
5639 {0, 1, 1, 0}, /* VADDHN */
5640 {0, 0, 0, 0}, /* VABAL */
5641 {0, 1, 1, 0}, /* VSUBHN */
5642 {0, 0, 0, 0}, /* VABDL */
5643 {0, 0, 0, 0}, /* VMLAL */
5644 {0, 0, 0, 6}, /* VQDMLAL */
5645 {0, 0, 0, 0}, /* VMLSL */
5646 {0, 0, 0, 6}, /* VQDMLSL */
5647 {0, 0, 0, 0}, /* Integer VMULL */
5648 {0, 0, 0, 2}, /* VQDMULL */
5649 {0, 0, 0, 5}, /* Polynomial VMULL */
5650 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5653 prewiden
= neon_3reg_wide
[op
][0];
5654 src1_wide
= neon_3reg_wide
[op
][1];
5655 src2_wide
= neon_3reg_wide
[op
][2];
5656 undefreq
= neon_3reg_wide
[op
][3];
5658 if (((undefreq
& 1) && (size
!= 0)) ||
5659 ((undefreq
& 2) && (size
== 0)) ||
5660 ((undefreq
& 4) && u
)) {
5663 if ((src1_wide
&& (rn
& 1)) ||
5664 (src2_wide
&& (rm
& 1)) ||
5665 (!src2_wide
&& (rd
& 1))) {
5669 /* Avoid overlapping operands. Wide source operands are
5670 always aligned so will never overlap with wide
5671 destinations in problematic ways. */
5672 if (rd
== rm
&& !src2_wide
) {
5673 tmp
= neon_load_reg(rm
, 1);
5674 neon_store_scratch(2, tmp
);
5675 } else if (rd
== rn
&& !src1_wide
) {
5676 tmp
= neon_load_reg(rn
, 1);
5677 neon_store_scratch(2, tmp
);
5679 TCGV_UNUSED_I32(tmp3
);
5680 for (pass
= 0; pass
< 2; pass
++) {
5682 neon_load_reg64(cpu_V0
, rn
+ pass
);
5683 TCGV_UNUSED_I32(tmp
);
5685 if (pass
== 1 && rd
== rn
) {
5686 tmp
= neon_load_scratch(2);
5688 tmp
= neon_load_reg(rn
, pass
);
5691 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5695 neon_load_reg64(cpu_V1
, rm
+ pass
);
5696 TCGV_UNUSED_I32(tmp2
);
5698 if (pass
== 1 && rd
== rm
) {
5699 tmp2
= neon_load_scratch(2);
5701 tmp2
= neon_load_reg(rm
, pass
);
5704 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5708 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5709 gen_neon_addl(size
);
5711 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5712 gen_neon_subl(size
);
5714 case 5: case 7: /* VABAL, VABDL */
5715 switch ((size
<< 1) | u
) {
5717 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5720 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5723 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5726 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5729 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5732 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5736 tcg_temp_free_i32(tmp2
);
5737 tcg_temp_free_i32(tmp
);
5739 case 8: case 9: case 10: case 11: case 12: case 13:
5740 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5741 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5743 case 14: /* Polynomial VMULL */
5744 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5745 tcg_temp_free_i32(tmp2
);
5746 tcg_temp_free_i32(tmp
);
5748 default: /* 15 is RESERVED: caught earlier */
5753 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5754 neon_store_reg64(cpu_V0
, rd
+ pass
);
5755 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5757 neon_load_reg64(cpu_V1
, rd
+ pass
);
5759 case 10: /* VMLSL */
5760 gen_neon_negl(cpu_V0
, size
);
5762 case 5: case 8: /* VABAL, VMLAL */
5763 gen_neon_addl(size
);
5765 case 9: case 11: /* VQDMLAL, VQDMLSL */
5766 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5768 gen_neon_negl(cpu_V0
, size
);
5770 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5775 neon_store_reg64(cpu_V0
, rd
+ pass
);
5776 } else if (op
== 4 || op
== 6) {
5777 /* Narrowing operation. */
5778 tmp
= tcg_temp_new_i32();
5782 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5785 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5788 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5789 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5796 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5799 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5802 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5803 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5804 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5812 neon_store_reg(rd
, 0, tmp3
);
5813 neon_store_reg(rd
, 1, tmp
);
5816 /* Write back the result. */
5817 neon_store_reg64(cpu_V0
, rd
+ pass
);
5821 /* Two registers and a scalar. NB that for ops of this form
5822 * the ARM ARM labels bit 24 as Q, but it is in our variable
5829 case 1: /* Float VMLA scalar */
5830 case 5: /* Floating point VMLS scalar */
5831 case 9: /* Floating point VMUL scalar */
5836 case 0: /* Integer VMLA scalar */
5837 case 4: /* Integer VMLS scalar */
5838 case 8: /* Integer VMUL scalar */
5839 case 12: /* VQDMULH scalar */
5840 case 13: /* VQRDMULH scalar */
5841 if (u
&& ((rd
| rn
) & 1)) {
5844 tmp
= neon_get_scalar(size
, rm
);
5845 neon_store_scratch(0, tmp
);
5846 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5847 tmp
= neon_load_scratch(0);
5848 tmp2
= neon_load_reg(rn
, pass
);
5851 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5853 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5855 } else if (op
== 13) {
5857 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5859 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5861 } else if (op
& 1) {
5862 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5863 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5864 tcg_temp_free_ptr(fpstatus
);
5867 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5868 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5869 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5873 tcg_temp_free_i32(tmp2
);
5876 tmp2
= neon_load_reg(rd
, pass
);
5879 gen_neon_add(size
, tmp
, tmp2
);
5883 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5884 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5885 tcg_temp_free_ptr(fpstatus
);
5889 gen_neon_rsb(size
, tmp
, tmp2
);
5893 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5894 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5895 tcg_temp_free_ptr(fpstatus
);
5901 tcg_temp_free_i32(tmp2
);
5903 neon_store_reg(rd
, pass
, tmp
);
5906 case 3: /* VQDMLAL scalar */
5907 case 7: /* VQDMLSL scalar */
5908 case 11: /* VQDMULL scalar */
5913 case 2: /* VMLAL sclar */
5914 case 6: /* VMLSL scalar */
5915 case 10: /* VMULL scalar */
5919 tmp2
= neon_get_scalar(size
, rm
);
5920 /* We need a copy of tmp2 because gen_neon_mull
5921 * deletes it during pass 0. */
5922 tmp4
= tcg_temp_new_i32();
5923 tcg_gen_mov_i32(tmp4
, tmp2
);
5924 tmp3
= neon_load_reg(rn
, 1);
5926 for (pass
= 0; pass
< 2; pass
++) {
5928 tmp
= neon_load_reg(rn
, 0);
5933 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5935 neon_load_reg64(cpu_V1
, rd
+ pass
);
5939 gen_neon_negl(cpu_V0
, size
);
5942 gen_neon_addl(size
);
5945 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5947 gen_neon_negl(cpu_V0
, size
);
5949 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5955 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5960 neon_store_reg64(cpu_V0
, rd
+ pass
);
5965 default: /* 14 and 15 are RESERVED */
5969 } else { /* size == 3 */
5972 imm
= (insn
>> 8) & 0xf;
5977 if (q
&& ((rd
| rn
| rm
) & 1)) {
5982 neon_load_reg64(cpu_V0
, rn
);
5984 neon_load_reg64(cpu_V1
, rn
+ 1);
5986 } else if (imm
== 8) {
5987 neon_load_reg64(cpu_V0
, rn
+ 1);
5989 neon_load_reg64(cpu_V1
, rm
);
5992 tmp64
= tcg_temp_new_i64();
5994 neon_load_reg64(cpu_V0
, rn
);
5995 neon_load_reg64(tmp64
, rn
+ 1);
5997 neon_load_reg64(cpu_V0
, rn
+ 1);
5998 neon_load_reg64(tmp64
, rm
);
6000 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6001 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6002 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6004 neon_load_reg64(cpu_V1
, rm
);
6006 neon_load_reg64(cpu_V1
, rm
+ 1);
6009 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6010 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6011 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6012 tcg_temp_free_i64(tmp64
);
6015 neon_load_reg64(cpu_V0
, rn
);
6016 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6017 neon_load_reg64(cpu_V1
, rm
);
6018 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6019 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6021 neon_store_reg64(cpu_V0
, rd
);
6023 neon_store_reg64(cpu_V1
, rd
+ 1);
6025 } else if ((insn
& (1 << 11)) == 0) {
6026 /* Two register misc. */
6027 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6028 size
= (insn
>> 18) & 3;
6029 /* UNDEF for unknown op values and bad op-size combinations */
6030 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6033 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6034 q
&& ((rm
| rd
) & 1)) {
6038 case NEON_2RM_VREV64
:
6039 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6040 tmp
= neon_load_reg(rm
, pass
* 2);
6041 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6043 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6044 case 1: gen_swap_half(tmp
); break;
6045 case 2: /* no-op */ break;
6048 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6050 neon_store_reg(rd
, pass
* 2, tmp2
);
6053 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6054 case 1: gen_swap_half(tmp2
); break;
6057 neon_store_reg(rd
, pass
* 2, tmp2
);
6061 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6062 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6063 for (pass
= 0; pass
< q
+ 1; pass
++) {
6064 tmp
= neon_load_reg(rm
, pass
* 2);
6065 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6066 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6067 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6069 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6070 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6071 case 2: tcg_gen_add_i64(CPU_V001
); break;
6074 if (op
>= NEON_2RM_VPADAL
) {
6076 neon_load_reg64(cpu_V1
, rd
+ pass
);
6077 gen_neon_addl(size
);
6079 neon_store_reg64(cpu_V0
, rd
+ pass
);
6085 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6086 tmp
= neon_load_reg(rm
, n
);
6087 tmp2
= neon_load_reg(rd
, n
+ 1);
6088 neon_store_reg(rm
, n
, tmp2
);
6089 neon_store_reg(rd
, n
+ 1, tmp
);
6096 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6101 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6105 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6106 /* also VQMOVUN; op field and mnemonics don't line up */
6110 TCGV_UNUSED_I32(tmp2
);
6111 for (pass
= 0; pass
< 2; pass
++) {
6112 neon_load_reg64(cpu_V0
, rm
+ pass
);
6113 tmp
= tcg_temp_new_i32();
6114 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6119 neon_store_reg(rd
, 0, tmp2
);
6120 neon_store_reg(rd
, 1, tmp
);
6124 case NEON_2RM_VSHLL
:
6125 if (q
|| (rd
& 1)) {
6128 tmp
= neon_load_reg(rm
, 0);
6129 tmp2
= neon_load_reg(rm
, 1);
6130 for (pass
= 0; pass
< 2; pass
++) {
6133 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6134 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6135 neon_store_reg64(cpu_V0
, rd
+ pass
);
6138 case NEON_2RM_VCVT_F16_F32
:
6139 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6143 tmp
= tcg_temp_new_i32();
6144 tmp2
= tcg_temp_new_i32();
6145 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6146 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6147 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6148 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6149 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6150 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6151 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6152 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6153 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6154 neon_store_reg(rd
, 0, tmp2
);
6155 tmp2
= tcg_temp_new_i32();
6156 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6157 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6158 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6159 neon_store_reg(rd
, 1, tmp2
);
6160 tcg_temp_free_i32(tmp
);
6162 case NEON_2RM_VCVT_F32_F16
:
6163 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6167 tmp3
= tcg_temp_new_i32();
6168 tmp
= neon_load_reg(rm
, 0);
6169 tmp2
= neon_load_reg(rm
, 1);
6170 tcg_gen_ext16u_i32(tmp3
, tmp
);
6171 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6172 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6173 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6174 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6175 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6176 tcg_temp_free_i32(tmp
);
6177 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6178 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6179 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6180 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6181 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6182 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6183 tcg_temp_free_i32(tmp2
);
6184 tcg_temp_free_i32(tmp3
);
6186 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6187 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6188 || ((rm
| rd
) & 1)) {
6191 tmp
= tcg_const_i32(rd
);
6192 tmp2
= tcg_const_i32(rm
);
6194 /* Bit 6 is the lowest opcode bit; it distinguishes between
6195 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6197 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6199 if (op
== NEON_2RM_AESE
) {
6200 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6202 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6204 tcg_temp_free_i32(tmp
);
6205 tcg_temp_free_i32(tmp2
);
6206 tcg_temp_free_i32(tmp3
);
6210 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6211 if (neon_2rm_is_float_op(op
)) {
6212 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6213 neon_reg_offset(rm
, pass
));
6214 TCGV_UNUSED_I32(tmp
);
6216 tmp
= neon_load_reg(rm
, pass
);
6219 case NEON_2RM_VREV32
:
6221 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6222 case 1: gen_swap_half(tmp
); break;
6226 case NEON_2RM_VREV16
:
6231 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6232 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6233 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6239 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6240 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6241 case 2: gen_helper_clz(tmp
, tmp
); break;
6246 gen_helper_neon_cnt_u8(tmp
, tmp
);
6249 tcg_gen_not_i32(tmp
, tmp
);
6251 case NEON_2RM_VQABS
:
6254 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6257 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6260 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6265 case NEON_2RM_VQNEG
:
6268 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6271 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6274 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6279 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6280 tmp2
= tcg_const_i32(0);
6282 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6283 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6284 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6287 tcg_temp_free_i32(tmp2
);
6288 if (op
== NEON_2RM_VCLE0
) {
6289 tcg_gen_not_i32(tmp
, tmp
);
6292 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6293 tmp2
= tcg_const_i32(0);
6295 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6296 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6297 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6300 tcg_temp_free_i32(tmp2
);
6301 if (op
== NEON_2RM_VCLT0
) {
6302 tcg_gen_not_i32(tmp
, tmp
);
6305 case NEON_2RM_VCEQ0
:
6306 tmp2
= tcg_const_i32(0);
6308 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6309 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6310 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6313 tcg_temp_free_i32(tmp2
);
6317 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6318 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6319 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6324 tmp2
= tcg_const_i32(0);
6325 gen_neon_rsb(size
, tmp
, tmp2
);
6326 tcg_temp_free_i32(tmp2
);
6328 case NEON_2RM_VCGT0_F
:
6330 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6331 tmp2
= tcg_const_i32(0);
6332 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6333 tcg_temp_free_i32(tmp2
);
6334 tcg_temp_free_ptr(fpstatus
);
6337 case NEON_2RM_VCGE0_F
:
6339 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6340 tmp2
= tcg_const_i32(0);
6341 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6342 tcg_temp_free_i32(tmp2
);
6343 tcg_temp_free_ptr(fpstatus
);
6346 case NEON_2RM_VCEQ0_F
:
6348 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6349 tmp2
= tcg_const_i32(0);
6350 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6351 tcg_temp_free_i32(tmp2
);
6352 tcg_temp_free_ptr(fpstatus
);
6355 case NEON_2RM_VCLE0_F
:
6357 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6358 tmp2
= tcg_const_i32(0);
6359 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6360 tcg_temp_free_i32(tmp2
);
6361 tcg_temp_free_ptr(fpstatus
);
6364 case NEON_2RM_VCLT0_F
:
6366 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6367 tmp2
= tcg_const_i32(0);
6368 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6369 tcg_temp_free_i32(tmp2
);
6370 tcg_temp_free_ptr(fpstatus
);
6373 case NEON_2RM_VABS_F
:
6376 case NEON_2RM_VNEG_F
:
6380 tmp2
= neon_load_reg(rd
, pass
);
6381 neon_store_reg(rm
, pass
, tmp2
);
6384 tmp2
= neon_load_reg(rd
, pass
);
6386 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6387 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6390 neon_store_reg(rm
, pass
, tmp2
);
6392 case NEON_2RM_VRECPE
:
6393 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6395 case NEON_2RM_VRSQRTE
:
6396 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6398 case NEON_2RM_VRECPE_F
:
6399 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6401 case NEON_2RM_VRSQRTE_F
:
6402 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6404 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6407 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6410 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6411 gen_vfp_tosiz(0, 1);
6413 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6414 gen_vfp_touiz(0, 1);
6417 /* Reserved op values were caught by the
6418 * neon_2rm_sizes[] check earlier.
6422 if (neon_2rm_is_float_op(op
)) {
6423 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6424 neon_reg_offset(rd
, pass
));
6426 neon_store_reg(rd
, pass
, tmp
);
6431 } else if ((insn
& (1 << 10)) == 0) {
6433 int n
= ((insn
>> 8) & 3) + 1;
6434 if ((rn
+ n
) > 32) {
6435 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6436 * helper function running off the end of the register file.
6441 if (insn
& (1 << 6)) {
6442 tmp
= neon_load_reg(rd
, 0);
6444 tmp
= tcg_temp_new_i32();
6445 tcg_gen_movi_i32(tmp
, 0);
6447 tmp2
= neon_load_reg(rm
, 0);
6448 tmp4
= tcg_const_i32(rn
);
6449 tmp5
= tcg_const_i32(n
);
6450 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6451 tcg_temp_free_i32(tmp
);
6452 if (insn
& (1 << 6)) {
6453 tmp
= neon_load_reg(rd
, 1);
6455 tmp
= tcg_temp_new_i32();
6456 tcg_gen_movi_i32(tmp
, 0);
6458 tmp3
= neon_load_reg(rm
, 1);
6459 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6460 tcg_temp_free_i32(tmp5
);
6461 tcg_temp_free_i32(tmp4
);
6462 neon_store_reg(rd
, 0, tmp2
);
6463 neon_store_reg(rd
, 1, tmp3
);
6464 tcg_temp_free_i32(tmp
);
6465 } else if ((insn
& 0x380) == 0) {
6467 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6470 if (insn
& (1 << 19)) {
6471 tmp
= neon_load_reg(rm
, 1);
6473 tmp
= neon_load_reg(rm
, 0);
6475 if (insn
& (1 << 16)) {
6476 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6477 } else if (insn
& (1 << 17)) {
6478 if ((insn
>> 18) & 1)
6479 gen_neon_dup_high16(tmp
);
6481 gen_neon_dup_low16(tmp
);
6483 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6484 tmp2
= tcg_temp_new_i32();
6485 tcg_gen_mov_i32(tmp2
, tmp
);
6486 neon_store_reg(rd
, pass
, tmp2
);
6488 tcg_temp_free_i32(tmp
);
6497 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6499 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6500 const ARMCPRegInfo
*ri
;
6501 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6503 cpnum
= (insn
>> 8) & 0xf;
6504 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6505 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6508 /* First check for coprocessor space used for actual instructions */
6512 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6513 return disas_iwmmxt_insn(env
, s
, insn
);
6514 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6515 return disas_dsp_insn(env
, s
, insn
);
6522 /* Otherwise treat as a generic register access */
6523 is64
= (insn
& (1 << 25)) == 0;
6524 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6532 opc1
= (insn
>> 4) & 0xf;
6534 rt2
= (insn
>> 16) & 0xf;
6536 crn
= (insn
>> 16) & 0xf;
6537 opc1
= (insn
>> 21) & 7;
6538 opc2
= (insn
>> 5) & 7;
6541 isread
= (insn
>> 20) & 1;
6542 rt
= (insn
>> 12) & 0xf;
6544 ri
= get_arm_cp_reginfo(cpu
,
6545 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6547 /* Check access permissions */
6548 if (!cp_access_ok(env
, ri
, isread
)) {
6552 /* Handle special cases first */
6553 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6560 gen_set_pc_im(s
, s
->pc
);
6561 s
->is_jmp
= DISAS_WFI
;
6567 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6576 if (ri
->type
& ARM_CP_CONST
) {
6577 tmp64
= tcg_const_i64(ri
->resetvalue
);
6578 } else if (ri
->readfn
) {
6580 gen_set_pc_im(s
, s
->pc
);
6581 tmp64
= tcg_temp_new_i64();
6582 tmpptr
= tcg_const_ptr(ri
);
6583 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6584 tcg_temp_free_ptr(tmpptr
);
6586 tmp64
= tcg_temp_new_i64();
6587 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6589 tmp
= tcg_temp_new_i32();
6590 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6591 store_reg(s
, rt
, tmp
);
6592 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6593 tmp
= tcg_temp_new_i32();
6594 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6595 tcg_temp_free_i64(tmp64
);
6596 store_reg(s
, rt2
, tmp
);
6599 if (ri
->type
& ARM_CP_CONST
) {
6600 tmp
= tcg_const_i32(ri
->resetvalue
);
6601 } else if (ri
->readfn
) {
6603 gen_set_pc_im(s
, s
->pc
);
6604 tmp
= tcg_temp_new_i32();
6605 tmpptr
= tcg_const_ptr(ri
);
6606 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6607 tcg_temp_free_ptr(tmpptr
);
6609 tmp
= load_cpu_offset(ri
->fieldoffset
);
6612 /* Destination register of r15 for 32 bit loads sets
6613 * the condition codes from the high 4 bits of the value
6616 tcg_temp_free_i32(tmp
);
6618 store_reg(s
, rt
, tmp
);
6623 if (ri
->type
& ARM_CP_CONST
) {
6624 /* If not forbidden by access permissions, treat as WI */
6629 TCGv_i32 tmplo
, tmphi
;
6630 TCGv_i64 tmp64
= tcg_temp_new_i64();
6631 tmplo
= load_reg(s
, rt
);
6632 tmphi
= load_reg(s
, rt2
);
6633 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6634 tcg_temp_free_i32(tmplo
);
6635 tcg_temp_free_i32(tmphi
);
6637 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6638 gen_set_pc_im(s
, s
->pc
);
6639 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6640 tcg_temp_free_ptr(tmpptr
);
6642 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6644 tcg_temp_free_i64(tmp64
);
6649 gen_set_pc_im(s
, s
->pc
);
6650 tmp
= load_reg(s
, rt
);
6651 tmpptr
= tcg_const_ptr(ri
);
6652 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6653 tcg_temp_free_ptr(tmpptr
);
6654 tcg_temp_free_i32(tmp
);
6656 TCGv_i32 tmp
= load_reg(s
, rt
);
6657 store_cpu_offset(tmp
, ri
->fieldoffset
);
6662 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6663 /* I/O operations must end the TB here (whether read or write) */
6666 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6667 /* We default to ending the TB on a coprocessor register write,
6668 * but allow this to be suppressed by the register definition
6669 * (usually only necessary to work around guest bugs).
6681 /* Store a 64-bit value to a register pair. Clobbers val. */
6682 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6685 tmp
= tcg_temp_new_i32();
6686 tcg_gen_trunc_i64_i32(tmp
, val
);
6687 store_reg(s
, rlow
, tmp
);
6688 tmp
= tcg_temp_new_i32();
6689 tcg_gen_shri_i64(val
, val
, 32);
6690 tcg_gen_trunc_i64_i32(tmp
, val
);
6691 store_reg(s
, rhigh
, tmp
);
6694 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6695 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6700 /* Load value and extend to 64 bits. */
6701 tmp
= tcg_temp_new_i64();
6702 tmp2
= load_reg(s
, rlow
);
6703 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6704 tcg_temp_free_i32(tmp2
);
6705 tcg_gen_add_i64(val
, val
, tmp
);
6706 tcg_temp_free_i64(tmp
);
6709 /* load and add a 64-bit value from a register pair. */
6710 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6716 /* Load 64-bit value rd:rn. */
6717 tmpl
= load_reg(s
, rlow
);
6718 tmph
= load_reg(s
, rhigh
);
6719 tmp
= tcg_temp_new_i64();
6720 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6721 tcg_temp_free_i32(tmpl
);
6722 tcg_temp_free_i32(tmph
);
6723 tcg_gen_add_i64(val
, val
, tmp
);
6724 tcg_temp_free_i64(tmp
);
6727 /* Set N and Z flags from hi|lo. */
6728 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6730 tcg_gen_mov_i32(cpu_NF
, hi
);
6731 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6734 /* Load/Store exclusive instructions are implemented by remembering
6735 the value/address loaded, and seeing if these are the same
6736 when the store is performed. This should be sufficient to implement
6737 the architecturally mandated semantics, and avoids having to monitor
6740 In system emulation mode only one CPU will be running at once, so
6741 this sequence is effectively atomic. In user emulation mode we
6742 throw an exception and handle the atomic operation elsewhere. */
6743 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6744 TCGv_i32 addr
, int size
)
6746 TCGv_i32 tmp
= tcg_temp_new_i32();
6750 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6753 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6757 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6762 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6763 store_reg(s
, rt
, tmp
);
6765 TCGv_i32 tmp2
= tcg_temp_new_i32();
6766 tcg_gen_addi_i32(tmp2
, addr
, 4);
6767 tmp
= tcg_temp_new_i32();
6768 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6769 tcg_temp_free_i32(tmp2
);
6770 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6771 store_reg(s
, rt2
, tmp
);
6773 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6776 static void gen_clrex(DisasContext
*s
)
6778 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6781 #ifdef CONFIG_USER_ONLY
6782 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6783 TCGv_i32 addr
, int size
)
6785 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6786 tcg_gen_movi_i32(cpu_exclusive_info
,
6787 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6788 gen_exception_insn(s
, 4, EXCP_STREX
);
6791 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6792 TCGv_i32 addr
, int size
)
6798 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6804 fail_label
= gen_new_label();
6805 done_label
= gen_new_label();
6806 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6807 tmp
= tcg_temp_new_i32();
6810 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6813 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6817 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6822 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6823 tcg_temp_free_i32(tmp
);
6825 TCGv_i32 tmp2
= tcg_temp_new_i32();
6826 tcg_gen_addi_i32(tmp2
, addr
, 4);
6827 tmp
= tcg_temp_new_i32();
6828 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6829 tcg_temp_free_i32(tmp2
);
6830 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6831 tcg_temp_free_i32(tmp
);
6833 tmp
= load_reg(s
, rt
);
6836 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
6839 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
6843 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6848 tcg_temp_free_i32(tmp
);
6850 tcg_gen_addi_i32(addr
, addr
, 4);
6851 tmp
= load_reg(s
, rt2
);
6852 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6853 tcg_temp_free_i32(tmp
);
6855 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6856 tcg_gen_br(done_label
);
6857 gen_set_label(fail_label
);
6858 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6859 gen_set_label(done_label
);
6860 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6867 * @mode: mode field from insn (which stack to store to)
6868 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6869 * @writeback: true if writeback bit set
6871 * Generate code for the SRS (Store Return State) insn.
6873 static void gen_srs(DisasContext
*s
,
6874 uint32_t mode
, uint32_t amode
, bool writeback
)
6877 TCGv_i32 addr
= tcg_temp_new_i32();
6878 TCGv_i32 tmp
= tcg_const_i32(mode
);
6879 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6880 tcg_temp_free_i32(tmp
);
6897 tcg_gen_addi_i32(addr
, addr
, offset
);
6898 tmp
= load_reg(s
, 14);
6899 gen_aa32_st32(tmp
, addr
, 0);
6900 tcg_temp_free_i32(tmp
);
6901 tmp
= load_cpu_field(spsr
);
6902 tcg_gen_addi_i32(addr
, addr
, 4);
6903 gen_aa32_st32(tmp
, addr
, 0);
6904 tcg_temp_free_i32(tmp
);
6922 tcg_gen_addi_i32(addr
, addr
, offset
);
6923 tmp
= tcg_const_i32(mode
);
6924 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6925 tcg_temp_free_i32(tmp
);
6927 tcg_temp_free_i32(addr
);
6930 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6932 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6939 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6942 /* M variants do not implement ARM mode. */
6947 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6948 * choose to UNDEF. In ARMv5 and above the space is used
6949 * for miscellaneous unconditional instructions.
6953 /* Unconditional instructions. */
6954 if (((insn
>> 25) & 7) == 1) {
6955 /* NEON Data processing. */
6956 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6959 if (disas_neon_data_insn(env
, s
, insn
))
6963 if ((insn
& 0x0f100000) == 0x04000000) {
6964 /* NEON load/store. */
6965 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6968 if (disas_neon_ls_insn(env
, s
, insn
))
6972 if ((insn
& 0x0f000e10) == 0x0e000a00) {
6974 if (disas_vfp_insn(env
, s
, insn
)) {
6979 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6980 ((insn
& 0x0f30f010) == 0x0710f000)) {
6981 if ((insn
& (1 << 22)) == 0) {
6983 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6987 /* Otherwise PLD; v5TE+ */
6991 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6992 ((insn
& 0x0f70f010) == 0x0650f000)) {
6994 return; /* PLI; V7 */
6996 if (((insn
& 0x0f700000) == 0x04100000) ||
6997 ((insn
& 0x0f700010) == 0x06100000)) {
6998 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7001 return; /* v7MP: Unallocated memory hint: must NOP */
7004 if ((insn
& 0x0ffffdff) == 0x01010000) {
7007 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7008 /* Dynamic endianness switching not implemented. */
7009 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7013 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7014 switch ((insn
>> 4) & 0xf) {
7023 /* We don't emulate caches so these are a no-op. */
7028 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7034 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7036 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7042 rn
= (insn
>> 16) & 0xf;
7043 addr
= load_reg(s
, rn
);
7044 i
= (insn
>> 23) & 3;
7046 case 0: offset
= -4; break; /* DA */
7047 case 1: offset
= 0; break; /* IA */
7048 case 2: offset
= -8; break; /* DB */
7049 case 3: offset
= 4; break; /* IB */
7053 tcg_gen_addi_i32(addr
, addr
, offset
);
7054 /* Load PC into tmp and CPSR into tmp2. */
7055 tmp
= tcg_temp_new_i32();
7056 gen_aa32_ld32u(tmp
, addr
, 0);
7057 tcg_gen_addi_i32(addr
, addr
, 4);
7058 tmp2
= tcg_temp_new_i32();
7059 gen_aa32_ld32u(tmp2
, addr
, 0);
7060 if (insn
& (1 << 21)) {
7061 /* Base writeback. */
7063 case 0: offset
= -8; break;
7064 case 1: offset
= 4; break;
7065 case 2: offset
= -4; break;
7066 case 3: offset
= 0; break;
7070 tcg_gen_addi_i32(addr
, addr
, offset
);
7071 store_reg(s
, rn
, addr
);
7073 tcg_temp_free_i32(addr
);
7075 gen_rfe(s
, tmp
, tmp2
);
7077 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7078 /* branch link and change to thumb (blx <offset>) */
7081 val
= (uint32_t)s
->pc
;
7082 tmp
= tcg_temp_new_i32();
7083 tcg_gen_movi_i32(tmp
, val
);
7084 store_reg(s
, 14, tmp
);
7085 /* Sign-extend the 24-bit offset */
7086 offset
= (((int32_t)insn
) << 8) >> 8;
7087 /* offset * 4 + bit24 * 2 + (thumb bit) */
7088 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7089 /* pipeline offset */
7091 /* protected by ARCH(5); above, near the start of uncond block */
7094 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7095 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7096 /* iWMMXt register transfer. */
7097 if (env
->cp15
.c15_cpar
& (1 << 1))
7098 if (!disas_iwmmxt_insn(env
, s
, insn
))
7101 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7102 /* Coprocessor double register transfer. */
7104 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7105 /* Additional coprocessor register transfer. */
7106 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7109 /* cps (privileged) */
7113 if (insn
& (1 << 19)) {
7114 if (insn
& (1 << 8))
7116 if (insn
& (1 << 7))
7118 if (insn
& (1 << 6))
7120 if (insn
& (1 << 18))
7123 if (insn
& (1 << 17)) {
7125 val
|= (insn
& 0x1f);
7128 gen_set_psr_im(s
, mask
, 0, val
);
7135 /* if not always execute, we generate a conditional jump to
7137 s
->condlabel
= gen_new_label();
7138 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7141 if ((insn
& 0x0f900000) == 0x03000000) {
7142 if ((insn
& (1 << 21)) == 0) {
7144 rd
= (insn
>> 12) & 0xf;
7145 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7146 if ((insn
& (1 << 22)) == 0) {
7148 tmp
= tcg_temp_new_i32();
7149 tcg_gen_movi_i32(tmp
, val
);
7152 tmp
= load_reg(s
, rd
);
7153 tcg_gen_ext16u_i32(tmp
, tmp
);
7154 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7156 store_reg(s
, rd
, tmp
);
7158 if (((insn
>> 12) & 0xf) != 0xf)
7160 if (((insn
>> 16) & 0xf) == 0) {
7161 gen_nop_hint(s
, insn
& 0xff);
7163 /* CPSR = immediate */
7165 shift
= ((insn
>> 8) & 0xf) * 2;
7167 val
= (val
>> shift
) | (val
<< (32 - shift
));
7168 i
= ((insn
& (1 << 22)) != 0);
7169 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7173 } else if ((insn
& 0x0f900000) == 0x01000000
7174 && (insn
& 0x00000090) != 0x00000090) {
7175 /* miscellaneous instructions */
7176 op1
= (insn
>> 21) & 3;
7177 sh
= (insn
>> 4) & 0xf;
7180 case 0x0: /* move program status register */
7183 tmp
= load_reg(s
, rm
);
7184 i
= ((op1
& 2) != 0);
7185 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7189 rd
= (insn
>> 12) & 0xf;
7193 tmp
= load_cpu_field(spsr
);
7195 tmp
= tcg_temp_new_i32();
7196 gen_helper_cpsr_read(tmp
, cpu_env
);
7198 store_reg(s
, rd
, tmp
);
7203 /* branch/exchange thumb (bx). */
7205 tmp
= load_reg(s
, rm
);
7207 } else if (op1
== 3) {
7210 rd
= (insn
>> 12) & 0xf;
7211 tmp
= load_reg(s
, rm
);
7212 gen_helper_clz(tmp
, tmp
);
7213 store_reg(s
, rd
, tmp
);
7221 /* Trivial implementation equivalent to bx. */
7222 tmp
= load_reg(s
, rm
);
7233 /* branch link/exchange thumb (blx) */
7234 tmp
= load_reg(s
, rm
);
7235 tmp2
= tcg_temp_new_i32();
7236 tcg_gen_movi_i32(tmp2
, s
->pc
);
7237 store_reg(s
, 14, tmp2
);
7240 case 0x5: /* saturating add/subtract */
7242 rd
= (insn
>> 12) & 0xf;
7243 rn
= (insn
>> 16) & 0xf;
7244 tmp
= load_reg(s
, rm
);
7245 tmp2
= load_reg(s
, rn
);
7247 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7249 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7251 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7252 tcg_temp_free_i32(tmp2
);
7253 store_reg(s
, rd
, tmp
);
7256 /* SMC instruction (op1 == 3)
7257 and undefined instructions (op1 == 0 || op1 == 2)
7264 gen_exception_insn(s
, 4, EXCP_BKPT
);
7266 case 0x8: /* signed multiply */
7271 rs
= (insn
>> 8) & 0xf;
7272 rn
= (insn
>> 12) & 0xf;
7273 rd
= (insn
>> 16) & 0xf;
7275 /* (32 * 16) >> 16 */
7276 tmp
= load_reg(s
, rm
);
7277 tmp2
= load_reg(s
, rs
);
7279 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7282 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7283 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7284 tmp
= tcg_temp_new_i32();
7285 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7286 tcg_temp_free_i64(tmp64
);
7287 if ((sh
& 2) == 0) {
7288 tmp2
= load_reg(s
, rn
);
7289 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7290 tcg_temp_free_i32(tmp2
);
7292 store_reg(s
, rd
, tmp
);
7295 tmp
= load_reg(s
, rm
);
7296 tmp2
= load_reg(s
, rs
);
7297 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7298 tcg_temp_free_i32(tmp2
);
7300 tmp64
= tcg_temp_new_i64();
7301 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7302 tcg_temp_free_i32(tmp
);
7303 gen_addq(s
, tmp64
, rn
, rd
);
7304 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7305 tcg_temp_free_i64(tmp64
);
7308 tmp2
= load_reg(s
, rn
);
7309 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7310 tcg_temp_free_i32(tmp2
);
7312 store_reg(s
, rd
, tmp
);
7319 } else if (((insn
& 0x0e000000) == 0 &&
7320 (insn
& 0x00000090) != 0x90) ||
7321 ((insn
& 0x0e000000) == (1 << 25))) {
7322 int set_cc
, logic_cc
, shiftop
;
7324 op1
= (insn
>> 21) & 0xf;
7325 set_cc
= (insn
>> 20) & 1;
7326 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7328 /* data processing instruction */
7329 if (insn
& (1 << 25)) {
7330 /* immediate operand */
7332 shift
= ((insn
>> 8) & 0xf) * 2;
7334 val
= (val
>> shift
) | (val
<< (32 - shift
));
7336 tmp2
= tcg_temp_new_i32();
7337 tcg_gen_movi_i32(tmp2
, val
);
7338 if (logic_cc
&& shift
) {
7339 gen_set_CF_bit31(tmp2
);
7344 tmp2
= load_reg(s
, rm
);
7345 shiftop
= (insn
>> 5) & 3;
7346 if (!(insn
& (1 << 4))) {
7347 shift
= (insn
>> 7) & 0x1f;
7348 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7350 rs
= (insn
>> 8) & 0xf;
7351 tmp
= load_reg(s
, rs
);
7352 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7355 if (op1
!= 0x0f && op1
!= 0x0d) {
7356 rn
= (insn
>> 16) & 0xf;
7357 tmp
= load_reg(s
, rn
);
7359 TCGV_UNUSED_I32(tmp
);
7361 rd
= (insn
>> 12) & 0xf;
7364 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7368 store_reg_bx(env
, s
, rd
, tmp
);
7371 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7375 store_reg_bx(env
, s
, rd
, tmp
);
7378 if (set_cc
&& rd
== 15) {
7379 /* SUBS r15, ... is used for exception return. */
7383 gen_sub_CC(tmp
, tmp
, tmp2
);
7384 gen_exception_return(s
, tmp
);
7387 gen_sub_CC(tmp
, tmp
, tmp2
);
7389 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7391 store_reg_bx(env
, s
, rd
, tmp
);
7396 gen_sub_CC(tmp
, tmp2
, tmp
);
7398 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7400 store_reg_bx(env
, s
, rd
, tmp
);
7404 gen_add_CC(tmp
, tmp
, tmp2
);
7406 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7408 store_reg_bx(env
, s
, rd
, tmp
);
7412 gen_adc_CC(tmp
, tmp
, tmp2
);
7414 gen_add_carry(tmp
, tmp
, tmp2
);
7416 store_reg_bx(env
, s
, rd
, tmp
);
7420 gen_sbc_CC(tmp
, tmp
, tmp2
);
7422 gen_sub_carry(tmp
, tmp
, tmp2
);
7424 store_reg_bx(env
, s
, rd
, tmp
);
7428 gen_sbc_CC(tmp
, tmp2
, tmp
);
7430 gen_sub_carry(tmp
, tmp2
, tmp
);
7432 store_reg_bx(env
, s
, rd
, tmp
);
7436 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7439 tcg_temp_free_i32(tmp
);
7443 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7446 tcg_temp_free_i32(tmp
);
7450 gen_sub_CC(tmp
, tmp
, tmp2
);
7452 tcg_temp_free_i32(tmp
);
7456 gen_add_CC(tmp
, tmp
, tmp2
);
7458 tcg_temp_free_i32(tmp
);
7461 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7465 store_reg_bx(env
, s
, rd
, tmp
);
7468 if (logic_cc
&& rd
== 15) {
7469 /* MOVS r15, ... is used for exception return. */
7473 gen_exception_return(s
, tmp2
);
7478 store_reg_bx(env
, s
, rd
, tmp2
);
7482 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7486 store_reg_bx(env
, s
, rd
, tmp
);
7490 tcg_gen_not_i32(tmp2
, tmp2
);
7494 store_reg_bx(env
, s
, rd
, tmp2
);
7497 if (op1
!= 0x0f && op1
!= 0x0d) {
7498 tcg_temp_free_i32(tmp2
);
7501 /* other instructions */
7502 op1
= (insn
>> 24) & 0xf;
7506 /* multiplies, extra load/stores */
7507 sh
= (insn
>> 5) & 3;
7510 rd
= (insn
>> 16) & 0xf;
7511 rn
= (insn
>> 12) & 0xf;
7512 rs
= (insn
>> 8) & 0xf;
7514 op1
= (insn
>> 20) & 0xf;
7516 case 0: case 1: case 2: case 3: case 6:
7518 tmp
= load_reg(s
, rs
);
7519 tmp2
= load_reg(s
, rm
);
7520 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7521 tcg_temp_free_i32(tmp2
);
7522 if (insn
& (1 << 22)) {
7523 /* Subtract (mls) */
7525 tmp2
= load_reg(s
, rn
);
7526 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7527 tcg_temp_free_i32(tmp2
);
7528 } else if (insn
& (1 << 21)) {
7530 tmp2
= load_reg(s
, rn
);
7531 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7532 tcg_temp_free_i32(tmp2
);
7534 if (insn
& (1 << 20))
7536 store_reg(s
, rd
, tmp
);
7539 /* 64 bit mul double accumulate (UMAAL) */
7541 tmp
= load_reg(s
, rs
);
7542 tmp2
= load_reg(s
, rm
);
7543 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7544 gen_addq_lo(s
, tmp64
, rn
);
7545 gen_addq_lo(s
, tmp64
, rd
);
7546 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7547 tcg_temp_free_i64(tmp64
);
7549 case 8: case 9: case 10: case 11:
7550 case 12: case 13: case 14: case 15:
7551 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7552 tmp
= load_reg(s
, rs
);
7553 tmp2
= load_reg(s
, rm
);
7554 if (insn
& (1 << 22)) {
7555 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7557 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7559 if (insn
& (1 << 21)) { /* mult accumulate */
7560 TCGv_i32 al
= load_reg(s
, rn
);
7561 TCGv_i32 ah
= load_reg(s
, rd
);
7562 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7563 tcg_temp_free_i32(al
);
7564 tcg_temp_free_i32(ah
);
7566 if (insn
& (1 << 20)) {
7567 gen_logicq_cc(tmp
, tmp2
);
7569 store_reg(s
, rn
, tmp
);
7570 store_reg(s
, rd
, tmp2
);
7576 rn
= (insn
>> 16) & 0xf;
7577 rd
= (insn
>> 12) & 0xf;
7578 if (insn
& (1 << 23)) {
7579 /* load/store exclusive */
7580 int op2
= (insn
>> 8) & 3;
7581 op1
= (insn
>> 21) & 0x3;
7584 case 0: /* lda/stl */
7590 case 1: /* reserved */
7592 case 2: /* ldaex/stlex */
7595 case 3: /* ldrex/strex */
7604 addr
= tcg_temp_local_new_i32();
7605 load_reg_var(s
, addr
, rn
);
7607 /* Since the emulation does not have barriers,
7608 the acquire/release semantics need no special
7611 if (insn
& (1 << 20)) {
7612 tmp
= tcg_temp_new_i32();
7615 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7618 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7621 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7626 store_reg(s
, rd
, tmp
);
7629 tmp
= load_reg(s
, rm
);
7632 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7635 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7638 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7643 tcg_temp_free_i32(tmp
);
7645 } else if (insn
& (1 << 20)) {
7648 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7650 case 1: /* ldrexd */
7651 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7653 case 2: /* ldrexb */
7654 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7656 case 3: /* ldrexh */
7657 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7666 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7668 case 1: /* strexd */
7669 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7671 case 2: /* strexb */
7672 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7674 case 3: /* strexh */
7675 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7681 tcg_temp_free_i32(addr
);
7683 /* SWP instruction */
7686 /* ??? This is not really atomic. However we know
7687 we never have multiple CPUs running in parallel,
7688 so it is good enough. */
7689 addr
= load_reg(s
, rn
);
7690 tmp
= load_reg(s
, rm
);
7691 tmp2
= tcg_temp_new_i32();
7692 if (insn
& (1 << 22)) {
7693 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7694 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7696 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7697 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7699 tcg_temp_free_i32(tmp
);
7700 tcg_temp_free_i32(addr
);
7701 store_reg(s
, rd
, tmp2
);
7707 /* Misc load/store */
7708 rn
= (insn
>> 16) & 0xf;
7709 rd
= (insn
>> 12) & 0xf;
7710 addr
= load_reg(s
, rn
);
7711 if (insn
& (1 << 24))
7712 gen_add_datah_offset(s
, insn
, 0, addr
);
7714 if (insn
& (1 << 20)) {
7716 tmp
= tcg_temp_new_i32();
7719 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7722 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7726 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7730 } else if (sh
& 2) {
7735 tmp
= load_reg(s
, rd
);
7736 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7737 tcg_temp_free_i32(tmp
);
7738 tcg_gen_addi_i32(addr
, addr
, 4);
7739 tmp
= load_reg(s
, rd
+ 1);
7740 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7741 tcg_temp_free_i32(tmp
);
7745 tmp
= tcg_temp_new_i32();
7746 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7747 store_reg(s
, rd
, tmp
);
7748 tcg_gen_addi_i32(addr
, addr
, 4);
7749 tmp
= tcg_temp_new_i32();
7750 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7754 address_offset
= -4;
7757 tmp
= load_reg(s
, rd
);
7758 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7759 tcg_temp_free_i32(tmp
);
7762 /* Perform base writeback before the loaded value to
7763 ensure correct behavior with overlapping index registers.
7764 ldrd with base writeback is is undefined if the
7765 destination and index registers overlap. */
7766 if (!(insn
& (1 << 24))) {
7767 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7768 store_reg(s
, rn
, addr
);
7769 } else if (insn
& (1 << 21)) {
7771 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7772 store_reg(s
, rn
, addr
);
7774 tcg_temp_free_i32(addr
);
7777 /* Complete the load. */
7778 store_reg(s
, rd
, tmp
);
7787 if (insn
& (1 << 4)) {
7789 /* Armv6 Media instructions. */
7791 rn
= (insn
>> 16) & 0xf;
7792 rd
= (insn
>> 12) & 0xf;
7793 rs
= (insn
>> 8) & 0xf;
7794 switch ((insn
>> 23) & 3) {
7795 case 0: /* Parallel add/subtract. */
7796 op1
= (insn
>> 20) & 7;
7797 tmp
= load_reg(s
, rn
);
7798 tmp2
= load_reg(s
, rm
);
7799 sh
= (insn
>> 5) & 7;
7800 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7802 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7803 tcg_temp_free_i32(tmp2
);
7804 store_reg(s
, rd
, tmp
);
7807 if ((insn
& 0x00700020) == 0) {
7808 /* Halfword pack. */
7809 tmp
= load_reg(s
, rn
);
7810 tmp2
= load_reg(s
, rm
);
7811 shift
= (insn
>> 7) & 0x1f;
7812 if (insn
& (1 << 6)) {
7816 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7817 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7818 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7822 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7823 tcg_gen_ext16u_i32(tmp
, tmp
);
7824 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7826 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7827 tcg_temp_free_i32(tmp2
);
7828 store_reg(s
, rd
, tmp
);
7829 } else if ((insn
& 0x00200020) == 0x00200000) {
7831 tmp
= load_reg(s
, rm
);
7832 shift
= (insn
>> 7) & 0x1f;
7833 if (insn
& (1 << 6)) {
7836 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7838 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7840 sh
= (insn
>> 16) & 0x1f;
7841 tmp2
= tcg_const_i32(sh
);
7842 if (insn
& (1 << 22))
7843 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7845 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7846 tcg_temp_free_i32(tmp2
);
7847 store_reg(s
, rd
, tmp
);
7848 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7850 tmp
= load_reg(s
, rm
);
7851 sh
= (insn
>> 16) & 0x1f;
7852 tmp2
= tcg_const_i32(sh
);
7853 if (insn
& (1 << 22))
7854 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7856 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7857 tcg_temp_free_i32(tmp2
);
7858 store_reg(s
, rd
, tmp
);
7859 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7861 tmp
= load_reg(s
, rn
);
7862 tmp2
= load_reg(s
, rm
);
7863 tmp3
= tcg_temp_new_i32();
7864 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7865 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7866 tcg_temp_free_i32(tmp3
);
7867 tcg_temp_free_i32(tmp2
);
7868 store_reg(s
, rd
, tmp
);
7869 } else if ((insn
& 0x000003e0) == 0x00000060) {
7870 tmp
= load_reg(s
, rm
);
7871 shift
= (insn
>> 10) & 3;
7872 /* ??? In many cases it's not necessary to do a
7873 rotate, a shift is sufficient. */
7875 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7876 op1
= (insn
>> 20) & 7;
7878 case 0: gen_sxtb16(tmp
); break;
7879 case 2: gen_sxtb(tmp
); break;
7880 case 3: gen_sxth(tmp
); break;
7881 case 4: gen_uxtb16(tmp
); break;
7882 case 6: gen_uxtb(tmp
); break;
7883 case 7: gen_uxth(tmp
); break;
7884 default: goto illegal_op
;
7887 tmp2
= load_reg(s
, rn
);
7888 if ((op1
& 3) == 0) {
7889 gen_add16(tmp
, tmp2
);
7891 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7892 tcg_temp_free_i32(tmp2
);
7895 store_reg(s
, rd
, tmp
);
7896 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7898 tmp
= load_reg(s
, rm
);
7899 if (insn
& (1 << 22)) {
7900 if (insn
& (1 << 7)) {
7904 gen_helper_rbit(tmp
, tmp
);
7907 if (insn
& (1 << 7))
7910 tcg_gen_bswap32_i32(tmp
, tmp
);
7912 store_reg(s
, rd
, tmp
);
7917 case 2: /* Multiplies (Type 3). */
7918 switch ((insn
>> 20) & 0x7) {
7920 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7921 /* op2 not 00x or 11x : UNDEF */
7924 /* Signed multiply most significant [accumulate].
7925 (SMMUL, SMMLA, SMMLS) */
7926 tmp
= load_reg(s
, rm
);
7927 tmp2
= load_reg(s
, rs
);
7928 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7931 tmp
= load_reg(s
, rd
);
7932 if (insn
& (1 << 6)) {
7933 tmp64
= gen_subq_msw(tmp64
, tmp
);
7935 tmp64
= gen_addq_msw(tmp64
, tmp
);
7938 if (insn
& (1 << 5)) {
7939 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7941 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7942 tmp
= tcg_temp_new_i32();
7943 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7944 tcg_temp_free_i64(tmp64
);
7945 store_reg(s
, rn
, tmp
);
7949 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7950 if (insn
& (1 << 7)) {
7953 tmp
= load_reg(s
, rm
);
7954 tmp2
= load_reg(s
, rs
);
7955 if (insn
& (1 << 5))
7956 gen_swap_half(tmp2
);
7957 gen_smul_dual(tmp
, tmp2
);
7958 if (insn
& (1 << 6)) {
7959 /* This subtraction cannot overflow. */
7960 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7962 /* This addition cannot overflow 32 bits;
7963 * however it may overflow considered as a signed
7964 * operation, in which case we must set the Q flag.
7966 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7968 tcg_temp_free_i32(tmp2
);
7969 if (insn
& (1 << 22)) {
7970 /* smlald, smlsld */
7971 tmp64
= tcg_temp_new_i64();
7972 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7973 tcg_temp_free_i32(tmp
);
7974 gen_addq(s
, tmp64
, rd
, rn
);
7975 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7976 tcg_temp_free_i64(tmp64
);
7978 /* smuad, smusd, smlad, smlsd */
7981 tmp2
= load_reg(s
, rd
);
7982 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7983 tcg_temp_free_i32(tmp2
);
7985 store_reg(s
, rn
, tmp
);
7991 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7994 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7997 tmp
= load_reg(s
, rm
);
7998 tmp2
= load_reg(s
, rs
);
7999 if (insn
& (1 << 21)) {
8000 gen_helper_udiv(tmp
, tmp
, tmp2
);
8002 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8004 tcg_temp_free_i32(tmp2
);
8005 store_reg(s
, rn
, tmp
);
8012 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8014 case 0: /* Unsigned sum of absolute differences. */
8016 tmp
= load_reg(s
, rm
);
8017 tmp2
= load_reg(s
, rs
);
8018 gen_helper_usad8(tmp
, tmp
, tmp2
);
8019 tcg_temp_free_i32(tmp2
);
8021 tmp2
= load_reg(s
, rd
);
8022 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8023 tcg_temp_free_i32(tmp2
);
8025 store_reg(s
, rn
, tmp
);
8027 case 0x20: case 0x24: case 0x28: case 0x2c:
8028 /* Bitfield insert/clear. */
8030 shift
= (insn
>> 7) & 0x1f;
8031 i
= (insn
>> 16) & 0x1f;
8034 tmp
= tcg_temp_new_i32();
8035 tcg_gen_movi_i32(tmp
, 0);
8037 tmp
= load_reg(s
, rm
);
8040 tmp2
= load_reg(s
, rd
);
8041 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8042 tcg_temp_free_i32(tmp2
);
8044 store_reg(s
, rd
, tmp
);
8046 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8047 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8049 tmp
= load_reg(s
, rm
);
8050 shift
= (insn
>> 7) & 0x1f;
8051 i
= ((insn
>> 16) & 0x1f) + 1;
8056 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8058 gen_sbfx(tmp
, shift
, i
);
8061 store_reg(s
, rd
, tmp
);
8071 /* Check for undefined extension instructions
8072 * per the ARM Bible IE:
8073 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8075 sh
= (0xf << 20) | (0xf << 4);
8076 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8080 /* load/store byte/word */
8081 rn
= (insn
>> 16) & 0xf;
8082 rd
= (insn
>> 12) & 0xf;
8083 tmp2
= load_reg(s
, rn
);
8084 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
8085 if (insn
& (1 << 24))
8086 gen_add_data_offset(s
, insn
, tmp2
);
8087 if (insn
& (1 << 20)) {
8089 tmp
= tcg_temp_new_i32();
8090 if (insn
& (1 << 22)) {
8091 gen_aa32_ld8u(tmp
, tmp2
, i
);
8093 gen_aa32_ld32u(tmp
, tmp2
, i
);
8097 tmp
= load_reg(s
, rd
);
8098 if (insn
& (1 << 22)) {
8099 gen_aa32_st8(tmp
, tmp2
, i
);
8101 gen_aa32_st32(tmp
, tmp2
, i
);
8103 tcg_temp_free_i32(tmp
);
8105 if (!(insn
& (1 << 24))) {
8106 gen_add_data_offset(s
, insn
, tmp2
);
8107 store_reg(s
, rn
, tmp2
);
8108 } else if (insn
& (1 << 21)) {
8109 store_reg(s
, rn
, tmp2
);
8111 tcg_temp_free_i32(tmp2
);
8113 if (insn
& (1 << 20)) {
8114 /* Complete the load. */
8115 store_reg_from_load(env
, s
, rd
, tmp
);
8121 int j
, n
, user
, loaded_base
;
8122 TCGv_i32 loaded_var
;
8123 /* load/store multiple words */
8124 /* XXX: store correct base if write back */
8126 if (insn
& (1 << 22)) {
8128 goto illegal_op
; /* only usable in supervisor mode */
8130 if ((insn
& (1 << 15)) == 0)
8133 rn
= (insn
>> 16) & 0xf;
8134 addr
= load_reg(s
, rn
);
8136 /* compute total size */
8138 TCGV_UNUSED_I32(loaded_var
);
8141 if (insn
& (1 << i
))
8144 /* XXX: test invalid n == 0 case ? */
8145 if (insn
& (1 << 23)) {
8146 if (insn
& (1 << 24)) {
8148 tcg_gen_addi_i32(addr
, addr
, 4);
8150 /* post increment */
8153 if (insn
& (1 << 24)) {
8155 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8157 /* post decrement */
8159 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8164 if (insn
& (1 << i
)) {
8165 if (insn
& (1 << 20)) {
8167 tmp
= tcg_temp_new_i32();
8168 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8170 tmp2
= tcg_const_i32(i
);
8171 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8172 tcg_temp_free_i32(tmp2
);
8173 tcg_temp_free_i32(tmp
);
8174 } else if (i
== rn
) {
8178 store_reg_from_load(env
, s
, i
, tmp
);
8183 /* special case: r15 = PC + 8 */
8184 val
= (long)s
->pc
+ 4;
8185 tmp
= tcg_temp_new_i32();
8186 tcg_gen_movi_i32(tmp
, val
);
8188 tmp
= tcg_temp_new_i32();
8189 tmp2
= tcg_const_i32(i
);
8190 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8191 tcg_temp_free_i32(tmp2
);
8193 tmp
= load_reg(s
, i
);
8195 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8196 tcg_temp_free_i32(tmp
);
8199 /* no need to add after the last transfer */
8201 tcg_gen_addi_i32(addr
, addr
, 4);
8204 if (insn
& (1 << 21)) {
8206 if (insn
& (1 << 23)) {
8207 if (insn
& (1 << 24)) {
8210 /* post increment */
8211 tcg_gen_addi_i32(addr
, addr
, 4);
8214 if (insn
& (1 << 24)) {
8217 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8219 /* post decrement */
8220 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8223 store_reg(s
, rn
, addr
);
8225 tcg_temp_free_i32(addr
);
8228 store_reg(s
, rn
, loaded_var
);
8230 if ((insn
& (1 << 22)) && !user
) {
8231 /* Restore CPSR from SPSR. */
8232 tmp
= load_cpu_field(spsr
);
8233 gen_set_cpsr(tmp
, 0xffffffff);
8234 tcg_temp_free_i32(tmp
);
8235 s
->is_jmp
= DISAS_UPDATE
;
8244 /* branch (and link) */
8245 val
= (int32_t)s
->pc
;
8246 if (insn
& (1 << 24)) {
8247 tmp
= tcg_temp_new_i32();
8248 tcg_gen_movi_i32(tmp
, val
);
8249 store_reg(s
, 14, tmp
);
8251 offset
= sextract32(insn
<< 2, 0, 26);
8259 if (((insn
>> 8) & 0xe) == 10) {
8261 if (disas_vfp_insn(env
, s
, insn
)) {
8264 } else if (disas_coproc_insn(env
, s
, insn
)) {
8271 gen_set_pc_im(s
, s
->pc
);
8272 s
->is_jmp
= DISAS_SWI
;
8276 gen_exception_insn(s
, 4, EXCP_UDEF
);
8282 /* Return true if this is a Thumb-2 logical op. */
8284 thumb2_logic_op(int op
)
8289 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8290 then set condition code flags based on the result of the operation.
8291 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8292 to the high bit of T1.
8293 Returns zero if the opcode is valid. */
8296 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8297 TCGv_i32 t0
, TCGv_i32 t1
)
8304 tcg_gen_and_i32(t0
, t0
, t1
);
8308 tcg_gen_andc_i32(t0
, t0
, t1
);
8312 tcg_gen_or_i32(t0
, t0
, t1
);
8316 tcg_gen_orc_i32(t0
, t0
, t1
);
8320 tcg_gen_xor_i32(t0
, t0
, t1
);
8325 gen_add_CC(t0
, t0
, t1
);
8327 tcg_gen_add_i32(t0
, t0
, t1
);
8331 gen_adc_CC(t0
, t0
, t1
);
8337 gen_sbc_CC(t0
, t0
, t1
);
8339 gen_sub_carry(t0
, t0
, t1
);
8344 gen_sub_CC(t0
, t0
, t1
);
8346 tcg_gen_sub_i32(t0
, t0
, t1
);
8350 gen_sub_CC(t0
, t1
, t0
);
8352 tcg_gen_sub_i32(t0
, t1
, t0
);
8354 default: /* 5, 6, 7, 9, 12, 15. */
8360 gen_set_CF_bit31(t1
);
8365 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8367 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8369 uint32_t insn
, imm
, shift
, offset
;
8370 uint32_t rd
, rn
, rm
, rs
;
8381 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8382 || arm_feature (env
, ARM_FEATURE_M
))) {
8383 /* Thumb-1 cores may need to treat bl and blx as a pair of
8384 16-bit instructions to get correct prefetch abort behavior. */
8386 if ((insn
& (1 << 12)) == 0) {
8388 /* Second half of blx. */
8389 offset
= ((insn
& 0x7ff) << 1);
8390 tmp
= load_reg(s
, 14);
8391 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8392 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8394 tmp2
= tcg_temp_new_i32();
8395 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8396 store_reg(s
, 14, tmp2
);
8400 if (insn
& (1 << 11)) {
8401 /* Second half of bl. */
8402 offset
= ((insn
& 0x7ff) << 1) | 1;
8403 tmp
= load_reg(s
, 14);
8404 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8406 tmp2
= tcg_temp_new_i32();
8407 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8408 store_reg(s
, 14, tmp2
);
8412 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8413 /* Instruction spans a page boundary. Implement it as two
8414 16-bit instructions in case the second half causes an
8416 offset
= ((int32_t)insn
<< 21) >> 9;
8417 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8420 /* Fall through to 32-bit decode. */
8423 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8425 insn
|= (uint32_t)insn_hw1
<< 16;
8427 if ((insn
& 0xf800e800) != 0xf000e800) {
8431 rn
= (insn
>> 16) & 0xf;
8432 rs
= (insn
>> 12) & 0xf;
8433 rd
= (insn
>> 8) & 0xf;
8435 switch ((insn
>> 25) & 0xf) {
8436 case 0: case 1: case 2: case 3:
8437 /* 16-bit instructions. Should never happen. */
8440 if (insn
& (1 << 22)) {
8441 /* Other load/store, table branch. */
8442 if (insn
& 0x01200000) {
8443 /* Load/store doubleword. */
8445 addr
= tcg_temp_new_i32();
8446 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8448 addr
= load_reg(s
, rn
);
8450 offset
= (insn
& 0xff) * 4;
8451 if ((insn
& (1 << 23)) == 0)
8453 if (insn
& (1 << 24)) {
8454 tcg_gen_addi_i32(addr
, addr
, offset
);
8457 if (insn
& (1 << 20)) {
8459 tmp
= tcg_temp_new_i32();
8460 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8461 store_reg(s
, rs
, tmp
);
8462 tcg_gen_addi_i32(addr
, addr
, 4);
8463 tmp
= tcg_temp_new_i32();
8464 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8465 store_reg(s
, rd
, tmp
);
8468 tmp
= load_reg(s
, rs
);
8469 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8470 tcg_temp_free_i32(tmp
);
8471 tcg_gen_addi_i32(addr
, addr
, 4);
8472 tmp
= load_reg(s
, rd
);
8473 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8474 tcg_temp_free_i32(tmp
);
8476 if (insn
& (1 << 21)) {
8477 /* Base writeback. */
8480 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8481 store_reg(s
, rn
, addr
);
8483 tcg_temp_free_i32(addr
);
8485 } else if ((insn
& (1 << 23)) == 0) {
8486 /* Load/store exclusive word. */
8487 addr
= tcg_temp_local_new_i32();
8488 load_reg_var(s
, addr
, rn
);
8489 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8490 if (insn
& (1 << 20)) {
8491 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8493 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8495 tcg_temp_free_i32(addr
);
8496 } else if ((insn
& (7 << 5)) == 0) {
8499 addr
= tcg_temp_new_i32();
8500 tcg_gen_movi_i32(addr
, s
->pc
);
8502 addr
= load_reg(s
, rn
);
8504 tmp
= load_reg(s
, rm
);
8505 tcg_gen_add_i32(addr
, addr
, tmp
);
8506 if (insn
& (1 << 4)) {
8508 tcg_gen_add_i32(addr
, addr
, tmp
);
8509 tcg_temp_free_i32(tmp
);
8510 tmp
= tcg_temp_new_i32();
8511 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8513 tcg_temp_free_i32(tmp
);
8514 tmp
= tcg_temp_new_i32();
8515 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8517 tcg_temp_free_i32(addr
);
8518 tcg_gen_shli_i32(tmp
, tmp
, 1);
8519 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8520 store_reg(s
, 15, tmp
);
8522 int op2
= (insn
>> 6) & 0x3;
8523 op
= (insn
>> 4) & 0x3;
8528 /* Load/store exclusive byte/halfword/doubleword */
8535 /* Load-acquire/store-release */
8541 /* Load-acquire/store-release exclusive */
8545 addr
= tcg_temp_local_new_i32();
8546 load_reg_var(s
, addr
, rn
);
8548 if (insn
& (1 << 20)) {
8549 tmp
= tcg_temp_new_i32();
8552 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8555 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8558 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8563 store_reg(s
, rs
, tmp
);
8565 tmp
= load_reg(s
, rs
);
8568 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8571 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8574 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8579 tcg_temp_free_i32(tmp
);
8581 } else if (insn
& (1 << 20)) {
8582 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8584 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8586 tcg_temp_free_i32(addr
);
8589 /* Load/store multiple, RFE, SRS. */
8590 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8591 /* RFE, SRS: not available in user mode or on M profile */
8592 if (IS_USER(s
) || IS_M(env
)) {
8595 if (insn
& (1 << 20)) {
8597 addr
= load_reg(s
, rn
);
8598 if ((insn
& (1 << 24)) == 0)
8599 tcg_gen_addi_i32(addr
, addr
, -8);
8600 /* Load PC into tmp and CPSR into tmp2. */
8601 tmp
= tcg_temp_new_i32();
8602 gen_aa32_ld32u(tmp
, addr
, 0);
8603 tcg_gen_addi_i32(addr
, addr
, 4);
8604 tmp2
= tcg_temp_new_i32();
8605 gen_aa32_ld32u(tmp2
, addr
, 0);
8606 if (insn
& (1 << 21)) {
8607 /* Base writeback. */
8608 if (insn
& (1 << 24)) {
8609 tcg_gen_addi_i32(addr
, addr
, 4);
8611 tcg_gen_addi_i32(addr
, addr
, -4);
8613 store_reg(s
, rn
, addr
);
8615 tcg_temp_free_i32(addr
);
8617 gen_rfe(s
, tmp
, tmp2
);
8620 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8624 int i
, loaded_base
= 0;
8625 TCGv_i32 loaded_var
;
8626 /* Load/store multiple. */
8627 addr
= load_reg(s
, rn
);
8629 for (i
= 0; i
< 16; i
++) {
8630 if (insn
& (1 << i
))
8633 if (insn
& (1 << 24)) {
8634 tcg_gen_addi_i32(addr
, addr
, -offset
);
8637 TCGV_UNUSED_I32(loaded_var
);
8638 for (i
= 0; i
< 16; i
++) {
8639 if ((insn
& (1 << i
)) == 0)
8641 if (insn
& (1 << 20)) {
8643 tmp
= tcg_temp_new_i32();
8644 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8647 } else if (i
== rn
) {
8651 store_reg(s
, i
, tmp
);
8655 tmp
= load_reg(s
, i
);
8656 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8657 tcg_temp_free_i32(tmp
);
8659 tcg_gen_addi_i32(addr
, addr
, 4);
8662 store_reg(s
, rn
, loaded_var
);
8664 if (insn
& (1 << 21)) {
8665 /* Base register writeback. */
8666 if (insn
& (1 << 24)) {
8667 tcg_gen_addi_i32(addr
, addr
, -offset
);
8669 /* Fault if writeback register is in register list. */
8670 if (insn
& (1 << rn
))
8672 store_reg(s
, rn
, addr
);
8674 tcg_temp_free_i32(addr
);
8681 op
= (insn
>> 21) & 0xf;
8683 /* Halfword pack. */
8684 tmp
= load_reg(s
, rn
);
8685 tmp2
= load_reg(s
, rm
);
8686 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8687 if (insn
& (1 << 5)) {
8691 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8692 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8693 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8697 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8698 tcg_gen_ext16u_i32(tmp
, tmp
);
8699 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8701 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8702 tcg_temp_free_i32(tmp2
);
8703 store_reg(s
, rd
, tmp
);
8705 /* Data processing register constant shift. */
8707 tmp
= tcg_temp_new_i32();
8708 tcg_gen_movi_i32(tmp
, 0);
8710 tmp
= load_reg(s
, rn
);
8712 tmp2
= load_reg(s
, rm
);
8714 shiftop
= (insn
>> 4) & 3;
8715 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8716 conds
= (insn
& (1 << 20)) != 0;
8717 logic_cc
= (conds
&& thumb2_logic_op(op
));
8718 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8719 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8721 tcg_temp_free_i32(tmp2
);
8723 store_reg(s
, rd
, tmp
);
8725 tcg_temp_free_i32(tmp
);
8729 case 13: /* Misc data processing. */
8730 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8731 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8734 case 0: /* Register controlled shift. */
8735 tmp
= load_reg(s
, rn
);
8736 tmp2
= load_reg(s
, rm
);
8737 if ((insn
& 0x70) != 0)
8739 op
= (insn
>> 21) & 3;
8740 logic_cc
= (insn
& (1 << 20)) != 0;
8741 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8744 store_reg_bx(env
, s
, rd
, tmp
);
8746 case 1: /* Sign/zero extend. */
8747 tmp
= load_reg(s
, rm
);
8748 shift
= (insn
>> 4) & 3;
8749 /* ??? In many cases it's not necessary to do a
8750 rotate, a shift is sufficient. */
8752 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8753 op
= (insn
>> 20) & 7;
8755 case 0: gen_sxth(tmp
); break;
8756 case 1: gen_uxth(tmp
); break;
8757 case 2: gen_sxtb16(tmp
); break;
8758 case 3: gen_uxtb16(tmp
); break;
8759 case 4: gen_sxtb(tmp
); break;
8760 case 5: gen_uxtb(tmp
); break;
8761 default: goto illegal_op
;
8764 tmp2
= load_reg(s
, rn
);
8765 if ((op
>> 1) == 1) {
8766 gen_add16(tmp
, tmp2
);
8768 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8769 tcg_temp_free_i32(tmp2
);
8772 store_reg(s
, rd
, tmp
);
8774 case 2: /* SIMD add/subtract. */
8775 op
= (insn
>> 20) & 7;
8776 shift
= (insn
>> 4) & 7;
8777 if ((op
& 3) == 3 || (shift
& 3) == 3)
8779 tmp
= load_reg(s
, rn
);
8780 tmp2
= load_reg(s
, rm
);
8781 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8782 tcg_temp_free_i32(tmp2
);
8783 store_reg(s
, rd
, tmp
);
8785 case 3: /* Other data processing. */
8786 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8788 /* Saturating add/subtract. */
8789 tmp
= load_reg(s
, rn
);
8790 tmp2
= load_reg(s
, rm
);
8792 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8794 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8796 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8797 tcg_temp_free_i32(tmp2
);
8799 tmp
= load_reg(s
, rn
);
8801 case 0x0a: /* rbit */
8802 gen_helper_rbit(tmp
, tmp
);
8804 case 0x08: /* rev */
8805 tcg_gen_bswap32_i32(tmp
, tmp
);
8807 case 0x09: /* rev16 */
8810 case 0x0b: /* revsh */
8813 case 0x10: /* sel */
8814 tmp2
= load_reg(s
, rm
);
8815 tmp3
= tcg_temp_new_i32();
8816 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8817 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8818 tcg_temp_free_i32(tmp3
);
8819 tcg_temp_free_i32(tmp2
);
8821 case 0x18: /* clz */
8822 gen_helper_clz(tmp
, tmp
);
8828 store_reg(s
, rd
, tmp
);
8830 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8831 op
= (insn
>> 4) & 0xf;
8832 tmp
= load_reg(s
, rn
);
8833 tmp2
= load_reg(s
, rm
);
8834 switch ((insn
>> 20) & 7) {
8835 case 0: /* 32 x 32 -> 32 */
8836 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8837 tcg_temp_free_i32(tmp2
);
8839 tmp2
= load_reg(s
, rs
);
8841 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8843 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8844 tcg_temp_free_i32(tmp2
);
8847 case 1: /* 16 x 16 -> 32 */
8848 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8849 tcg_temp_free_i32(tmp2
);
8851 tmp2
= load_reg(s
, rs
);
8852 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8853 tcg_temp_free_i32(tmp2
);
8856 case 2: /* Dual multiply add. */
8857 case 4: /* Dual multiply subtract. */
8859 gen_swap_half(tmp2
);
8860 gen_smul_dual(tmp
, tmp2
);
8861 if (insn
& (1 << 22)) {
8862 /* This subtraction cannot overflow. */
8863 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8865 /* This addition cannot overflow 32 bits;
8866 * however it may overflow considered as a signed
8867 * operation, in which case we must set the Q flag.
8869 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8871 tcg_temp_free_i32(tmp2
);
8874 tmp2
= load_reg(s
, rs
);
8875 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8876 tcg_temp_free_i32(tmp2
);
8879 case 3: /* 32 * 16 -> 32msb */
8881 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8884 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8885 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8886 tmp
= tcg_temp_new_i32();
8887 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8888 tcg_temp_free_i64(tmp64
);
8891 tmp2
= load_reg(s
, rs
);
8892 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8893 tcg_temp_free_i32(tmp2
);
8896 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8897 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8899 tmp
= load_reg(s
, rs
);
8900 if (insn
& (1 << 20)) {
8901 tmp64
= gen_addq_msw(tmp64
, tmp
);
8903 tmp64
= gen_subq_msw(tmp64
, tmp
);
8906 if (insn
& (1 << 4)) {
8907 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8909 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8910 tmp
= tcg_temp_new_i32();
8911 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8912 tcg_temp_free_i64(tmp64
);
8914 case 7: /* Unsigned sum of absolute differences. */
8915 gen_helper_usad8(tmp
, tmp
, tmp2
);
8916 tcg_temp_free_i32(tmp2
);
8918 tmp2
= load_reg(s
, rs
);
8919 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8920 tcg_temp_free_i32(tmp2
);
8924 store_reg(s
, rd
, tmp
);
8926 case 6: case 7: /* 64-bit multiply, Divide. */
8927 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8928 tmp
= load_reg(s
, rn
);
8929 tmp2
= load_reg(s
, rm
);
8930 if ((op
& 0x50) == 0x10) {
8932 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8936 gen_helper_udiv(tmp
, tmp
, tmp2
);
8938 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8939 tcg_temp_free_i32(tmp2
);
8940 store_reg(s
, rd
, tmp
);
8941 } else if ((op
& 0xe) == 0xc) {
8942 /* Dual multiply accumulate long. */
8944 gen_swap_half(tmp2
);
8945 gen_smul_dual(tmp
, tmp2
);
8947 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8949 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8951 tcg_temp_free_i32(tmp2
);
8953 tmp64
= tcg_temp_new_i64();
8954 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8955 tcg_temp_free_i32(tmp
);
8956 gen_addq(s
, tmp64
, rs
, rd
);
8957 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8958 tcg_temp_free_i64(tmp64
);
8961 /* Unsigned 64-bit multiply */
8962 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8966 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8967 tcg_temp_free_i32(tmp2
);
8968 tmp64
= tcg_temp_new_i64();
8969 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8970 tcg_temp_free_i32(tmp
);
8972 /* Signed 64-bit multiply */
8973 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8978 gen_addq_lo(s
, tmp64
, rs
);
8979 gen_addq_lo(s
, tmp64
, rd
);
8980 } else if (op
& 0x40) {
8981 /* 64-bit accumulate. */
8982 gen_addq(s
, tmp64
, rs
, rd
);
8984 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8985 tcg_temp_free_i64(tmp64
);
8990 case 6: case 7: case 14: case 15:
8992 if (((insn
>> 24) & 3) == 3) {
8993 /* Translate into the equivalent ARM encoding. */
8994 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8995 if (disas_neon_data_insn(env
, s
, insn
))
8997 } else if (((insn
>> 8) & 0xe) == 10) {
8998 if (disas_vfp_insn(env
, s
, insn
)) {
9002 if (insn
& (1 << 28))
9004 if (disas_coproc_insn (env
, s
, insn
))
9008 case 8: case 9: case 10: case 11:
9009 if (insn
& (1 << 15)) {
9010 /* Branches, misc control. */
9011 if (insn
& 0x5000) {
9012 /* Unconditional branch. */
9013 /* signextend(hw1[10:0]) -> offset[:12]. */
9014 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9015 /* hw1[10:0] -> offset[11:1]. */
9016 offset
|= (insn
& 0x7ff) << 1;
9017 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9018 offset[24:22] already have the same value because of the
9019 sign extension above. */
9020 offset
^= ((~insn
) & (1 << 13)) << 10;
9021 offset
^= ((~insn
) & (1 << 11)) << 11;
9023 if (insn
& (1 << 14)) {
9024 /* Branch and link. */
9025 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9029 if (insn
& (1 << 12)) {
9034 offset
&= ~(uint32_t)2;
9035 /* thumb2 bx, no need to check */
9036 gen_bx_im(s
, offset
);
9038 } else if (((insn
>> 23) & 7) == 7) {
9040 if (insn
& (1 << 13))
9043 if (insn
& (1 << 26)) {
9044 /* Secure monitor call (v6Z) */
9045 qemu_log_mask(LOG_UNIMP
,
9046 "arm: unimplemented secure monitor call\n");
9047 goto illegal_op
; /* not implemented. */
9049 op
= (insn
>> 20) & 7;
9051 case 0: /* msr cpsr. */
9053 tmp
= load_reg(s
, rn
);
9054 addr
= tcg_const_i32(insn
& 0xff);
9055 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9056 tcg_temp_free_i32(addr
);
9057 tcg_temp_free_i32(tmp
);
9062 case 1: /* msr spsr. */
9065 tmp
= load_reg(s
, rn
);
9067 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9071 case 2: /* cps, nop-hint. */
9072 if (((insn
>> 8) & 7) == 0) {
9073 gen_nop_hint(s
, insn
& 0xff);
9075 /* Implemented as NOP in user mode. */
9080 if (insn
& (1 << 10)) {
9081 if (insn
& (1 << 7))
9083 if (insn
& (1 << 6))
9085 if (insn
& (1 << 5))
9087 if (insn
& (1 << 9))
9088 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9090 if (insn
& (1 << 8)) {
9092 imm
|= (insn
& 0x1f);
9095 gen_set_psr_im(s
, offset
, 0, imm
);
9098 case 3: /* Special control operations. */
9100 op
= (insn
>> 4) & 0xf;
9108 /* These execute as NOPs. */
9115 /* Trivial implementation equivalent to bx. */
9116 tmp
= load_reg(s
, rn
);
9119 case 5: /* Exception return. */
9123 if (rn
!= 14 || rd
!= 15) {
9126 tmp
= load_reg(s
, rn
);
9127 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9128 gen_exception_return(s
, tmp
);
9130 case 6: /* mrs cpsr. */
9131 tmp
= tcg_temp_new_i32();
9133 addr
= tcg_const_i32(insn
& 0xff);
9134 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9135 tcg_temp_free_i32(addr
);
9137 gen_helper_cpsr_read(tmp
, cpu_env
);
9139 store_reg(s
, rd
, tmp
);
9141 case 7: /* mrs spsr. */
9142 /* Not accessible in user mode. */
9143 if (IS_USER(s
) || IS_M(env
))
9145 tmp
= load_cpu_field(spsr
);
9146 store_reg(s
, rd
, tmp
);
9151 /* Conditional branch. */
9152 op
= (insn
>> 22) & 0xf;
9153 /* Generate a conditional jump to next instruction. */
9154 s
->condlabel
= gen_new_label();
9155 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9158 /* offset[11:1] = insn[10:0] */
9159 offset
= (insn
& 0x7ff) << 1;
9160 /* offset[17:12] = insn[21:16]. */
9161 offset
|= (insn
& 0x003f0000) >> 4;
9162 /* offset[31:20] = insn[26]. */
9163 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9164 /* offset[18] = insn[13]. */
9165 offset
|= (insn
& (1 << 13)) << 5;
9166 /* offset[19] = insn[11]. */
9167 offset
|= (insn
& (1 << 11)) << 8;
9169 /* jump to the offset */
9170 gen_jmp(s
, s
->pc
+ offset
);
9173 /* Data processing immediate. */
9174 if (insn
& (1 << 25)) {
9175 if (insn
& (1 << 24)) {
9176 if (insn
& (1 << 20))
9178 /* Bitfield/Saturate. */
9179 op
= (insn
>> 21) & 7;
9181 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9183 tmp
= tcg_temp_new_i32();
9184 tcg_gen_movi_i32(tmp
, 0);
9186 tmp
= load_reg(s
, rn
);
9189 case 2: /* Signed bitfield extract. */
9191 if (shift
+ imm
> 32)
9194 gen_sbfx(tmp
, shift
, imm
);
9196 case 6: /* Unsigned bitfield extract. */
9198 if (shift
+ imm
> 32)
9201 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9203 case 3: /* Bitfield insert/clear. */
9206 imm
= imm
+ 1 - shift
;
9208 tmp2
= load_reg(s
, rd
);
9209 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9210 tcg_temp_free_i32(tmp2
);
9215 default: /* Saturate. */
9218 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9220 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9222 tmp2
= tcg_const_i32(imm
);
9225 if ((op
& 1) && shift
== 0)
9226 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9228 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9231 if ((op
& 1) && shift
== 0)
9232 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9234 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9236 tcg_temp_free_i32(tmp2
);
9239 store_reg(s
, rd
, tmp
);
9241 imm
= ((insn
& 0x04000000) >> 15)
9242 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9243 if (insn
& (1 << 22)) {
9244 /* 16-bit immediate. */
9245 imm
|= (insn
>> 4) & 0xf000;
9246 if (insn
& (1 << 23)) {
9248 tmp
= load_reg(s
, rd
);
9249 tcg_gen_ext16u_i32(tmp
, tmp
);
9250 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9253 tmp
= tcg_temp_new_i32();
9254 tcg_gen_movi_i32(tmp
, imm
);
9257 /* Add/sub 12-bit immediate. */
9259 offset
= s
->pc
& ~(uint32_t)3;
9260 if (insn
& (1 << 23))
9264 tmp
= tcg_temp_new_i32();
9265 tcg_gen_movi_i32(tmp
, offset
);
9267 tmp
= load_reg(s
, rn
);
9268 if (insn
& (1 << 23))
9269 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9271 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9274 store_reg(s
, rd
, tmp
);
9277 int shifter_out
= 0;
9278 /* modified 12-bit immediate. */
9279 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9280 imm
= (insn
& 0xff);
9283 /* Nothing to do. */
9285 case 1: /* 00XY00XY */
9288 case 2: /* XY00XY00 */
9292 case 3: /* XYXYXYXY */
9296 default: /* Rotated constant. */
9297 shift
= (shift
<< 1) | (imm
>> 7);
9299 imm
= imm
<< (32 - shift
);
9303 tmp2
= tcg_temp_new_i32();
9304 tcg_gen_movi_i32(tmp2
, imm
);
9305 rn
= (insn
>> 16) & 0xf;
9307 tmp
= tcg_temp_new_i32();
9308 tcg_gen_movi_i32(tmp
, 0);
9310 tmp
= load_reg(s
, rn
);
9312 op
= (insn
>> 21) & 0xf;
9313 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9314 shifter_out
, tmp
, tmp2
))
9316 tcg_temp_free_i32(tmp2
);
9317 rd
= (insn
>> 8) & 0xf;
9319 store_reg(s
, rd
, tmp
);
9321 tcg_temp_free_i32(tmp
);
9326 case 12: /* Load/store single data item. */
9331 if ((insn
& 0x01100000) == 0x01000000) {
9332 if (disas_neon_ls_insn(env
, s
, insn
))
9336 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9338 if (!(insn
& (1 << 20))) {
9342 /* Byte or halfword load space with dest == r15 : memory hints.
9343 * Catch them early so we don't emit pointless addressing code.
9344 * This space is a mix of:
9345 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9346 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9348 * unallocated hints, which must be treated as NOPs
9349 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9350 * which is easiest for the decoding logic
9351 * Some space which must UNDEF
9353 int op1
= (insn
>> 23) & 3;
9354 int op2
= (insn
>> 6) & 0x3f;
9359 /* UNPREDICTABLE, unallocated hint or
9360 * PLD/PLDW/PLI (literal)
9365 return 0; /* PLD/PLDW/PLI or unallocated hint */
9367 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9368 return 0; /* PLD/PLDW/PLI or unallocated hint */
9370 /* UNDEF space, or an UNPREDICTABLE */
9376 addr
= tcg_temp_new_i32();
9378 /* s->pc has already been incremented by 4. */
9379 imm
= s
->pc
& 0xfffffffc;
9380 if (insn
& (1 << 23))
9381 imm
+= insn
& 0xfff;
9383 imm
-= insn
& 0xfff;
9384 tcg_gen_movi_i32(addr
, imm
);
9386 addr
= load_reg(s
, rn
);
9387 if (insn
& (1 << 23)) {
9388 /* Positive offset. */
9390 tcg_gen_addi_i32(addr
, addr
, imm
);
9393 switch ((insn
>> 8) & 0xf) {
9394 case 0x0: /* Shifted Register. */
9395 shift
= (insn
>> 4) & 0xf;
9397 tcg_temp_free_i32(addr
);
9400 tmp
= load_reg(s
, rm
);
9402 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9403 tcg_gen_add_i32(addr
, addr
, tmp
);
9404 tcg_temp_free_i32(tmp
);
9406 case 0xc: /* Negative offset. */
9407 tcg_gen_addi_i32(addr
, addr
, -imm
);
9409 case 0xe: /* User privilege. */
9410 tcg_gen_addi_i32(addr
, addr
, imm
);
9413 case 0x9: /* Post-decrement. */
9416 case 0xb: /* Post-increment. */
9420 case 0xd: /* Pre-decrement. */
9423 case 0xf: /* Pre-increment. */
9424 tcg_gen_addi_i32(addr
, addr
, imm
);
9428 tcg_temp_free_i32(addr
);
9433 if (insn
& (1 << 20)) {
9435 tmp
= tcg_temp_new_i32();
9438 gen_aa32_ld8u(tmp
, addr
, user
);
9441 gen_aa32_ld8s(tmp
, addr
, user
);
9444 gen_aa32_ld16u(tmp
, addr
, user
);
9447 gen_aa32_ld16s(tmp
, addr
, user
);
9450 gen_aa32_ld32u(tmp
, addr
, user
);
9453 tcg_temp_free_i32(tmp
);
9454 tcg_temp_free_i32(addr
);
9460 store_reg(s
, rs
, tmp
);
9464 tmp
= load_reg(s
, rs
);
9467 gen_aa32_st8(tmp
, addr
, user
);
9470 gen_aa32_st16(tmp
, addr
, user
);
9473 gen_aa32_st32(tmp
, addr
, user
);
9476 tcg_temp_free_i32(tmp
);
9477 tcg_temp_free_i32(addr
);
9480 tcg_temp_free_i32(tmp
);
9483 tcg_gen_addi_i32(addr
, addr
, imm
);
9485 store_reg(s
, rn
, addr
);
9487 tcg_temp_free_i32(addr
);
9499 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9501 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9508 if (s
->condexec_mask
) {
9509 cond
= s
->condexec_cond
;
9510 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9511 s
->condlabel
= gen_new_label();
9512 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
9517 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9520 switch (insn
>> 12) {
9524 op
= (insn
>> 11) & 3;
9527 rn
= (insn
>> 3) & 7;
9528 tmp
= load_reg(s
, rn
);
9529 if (insn
& (1 << 10)) {
9531 tmp2
= tcg_temp_new_i32();
9532 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9535 rm
= (insn
>> 6) & 7;
9536 tmp2
= load_reg(s
, rm
);
9538 if (insn
& (1 << 9)) {
9539 if (s
->condexec_mask
)
9540 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9542 gen_sub_CC(tmp
, tmp
, tmp2
);
9544 if (s
->condexec_mask
)
9545 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9547 gen_add_CC(tmp
, tmp
, tmp2
);
9549 tcg_temp_free_i32(tmp2
);
9550 store_reg(s
, rd
, tmp
);
9552 /* shift immediate */
9553 rm
= (insn
>> 3) & 7;
9554 shift
= (insn
>> 6) & 0x1f;
9555 tmp
= load_reg(s
, rm
);
9556 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9557 if (!s
->condexec_mask
)
9559 store_reg(s
, rd
, tmp
);
9563 /* arithmetic large immediate */
9564 op
= (insn
>> 11) & 3;
9565 rd
= (insn
>> 8) & 0x7;
9566 if (op
== 0) { /* mov */
9567 tmp
= tcg_temp_new_i32();
9568 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9569 if (!s
->condexec_mask
)
9571 store_reg(s
, rd
, tmp
);
9573 tmp
= load_reg(s
, rd
);
9574 tmp2
= tcg_temp_new_i32();
9575 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9578 gen_sub_CC(tmp
, tmp
, tmp2
);
9579 tcg_temp_free_i32(tmp
);
9580 tcg_temp_free_i32(tmp2
);
9583 if (s
->condexec_mask
)
9584 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9586 gen_add_CC(tmp
, tmp
, tmp2
);
9587 tcg_temp_free_i32(tmp2
);
9588 store_reg(s
, rd
, tmp
);
9591 if (s
->condexec_mask
)
9592 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9594 gen_sub_CC(tmp
, tmp
, tmp2
);
9595 tcg_temp_free_i32(tmp2
);
9596 store_reg(s
, rd
, tmp
);
9602 if (insn
& (1 << 11)) {
9603 rd
= (insn
>> 8) & 7;
9604 /* load pc-relative. Bit 1 of PC is ignored. */
9605 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9606 val
&= ~(uint32_t)2;
9607 addr
= tcg_temp_new_i32();
9608 tcg_gen_movi_i32(addr
, val
);
9609 tmp
= tcg_temp_new_i32();
9610 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9611 tcg_temp_free_i32(addr
);
9612 store_reg(s
, rd
, tmp
);
9615 if (insn
& (1 << 10)) {
9616 /* data processing extended or blx */
9617 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9618 rm
= (insn
>> 3) & 0xf;
9619 op
= (insn
>> 8) & 3;
9622 tmp
= load_reg(s
, rd
);
9623 tmp2
= load_reg(s
, rm
);
9624 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9625 tcg_temp_free_i32(tmp2
);
9626 store_reg(s
, rd
, tmp
);
9629 tmp
= load_reg(s
, rd
);
9630 tmp2
= load_reg(s
, rm
);
9631 gen_sub_CC(tmp
, tmp
, tmp2
);
9632 tcg_temp_free_i32(tmp2
);
9633 tcg_temp_free_i32(tmp
);
9635 case 2: /* mov/cpy */
9636 tmp
= load_reg(s
, rm
);
9637 store_reg(s
, rd
, tmp
);
9639 case 3:/* branch [and link] exchange thumb register */
9640 tmp
= load_reg(s
, rm
);
9641 if (insn
& (1 << 7)) {
9643 val
= (uint32_t)s
->pc
| 1;
9644 tmp2
= tcg_temp_new_i32();
9645 tcg_gen_movi_i32(tmp2
, val
);
9646 store_reg(s
, 14, tmp2
);
9648 /* already thumb, no need to check */
9655 /* data processing register */
9657 rm
= (insn
>> 3) & 7;
9658 op
= (insn
>> 6) & 0xf;
9659 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9660 /* the shift/rotate ops want the operands backwards */
9669 if (op
== 9) { /* neg */
9670 tmp
= tcg_temp_new_i32();
9671 tcg_gen_movi_i32(tmp
, 0);
9672 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9673 tmp
= load_reg(s
, rd
);
9675 TCGV_UNUSED_I32(tmp
);
9678 tmp2
= load_reg(s
, rm
);
9681 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9682 if (!s
->condexec_mask
)
9686 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9687 if (!s
->condexec_mask
)
9691 if (s
->condexec_mask
) {
9692 gen_shl(tmp2
, tmp2
, tmp
);
9694 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9699 if (s
->condexec_mask
) {
9700 gen_shr(tmp2
, tmp2
, tmp
);
9702 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9707 if (s
->condexec_mask
) {
9708 gen_sar(tmp2
, tmp2
, tmp
);
9710 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9715 if (s
->condexec_mask
) {
9718 gen_adc_CC(tmp
, tmp
, tmp2
);
9722 if (s
->condexec_mask
) {
9723 gen_sub_carry(tmp
, tmp
, tmp2
);
9725 gen_sbc_CC(tmp
, tmp
, tmp2
);
9729 if (s
->condexec_mask
) {
9730 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9731 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9733 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9738 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9743 if (s
->condexec_mask
)
9744 tcg_gen_neg_i32(tmp
, tmp2
);
9746 gen_sub_CC(tmp
, tmp
, tmp2
);
9749 gen_sub_CC(tmp
, tmp
, tmp2
);
9753 gen_add_CC(tmp
, tmp
, tmp2
);
9757 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9758 if (!s
->condexec_mask
)
9762 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9763 if (!s
->condexec_mask
)
9767 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9768 if (!s
->condexec_mask
)
9772 tcg_gen_not_i32(tmp2
, tmp2
);
9773 if (!s
->condexec_mask
)
9781 store_reg(s
, rm
, tmp2
);
9783 tcg_temp_free_i32(tmp
);
9785 store_reg(s
, rd
, tmp
);
9786 tcg_temp_free_i32(tmp2
);
9789 tcg_temp_free_i32(tmp
);
9790 tcg_temp_free_i32(tmp2
);
9795 /* load/store register offset. */
9797 rn
= (insn
>> 3) & 7;
9798 rm
= (insn
>> 6) & 7;
9799 op
= (insn
>> 9) & 7;
9800 addr
= load_reg(s
, rn
);
9801 tmp
= load_reg(s
, rm
);
9802 tcg_gen_add_i32(addr
, addr
, tmp
);
9803 tcg_temp_free_i32(tmp
);
9805 if (op
< 3) { /* store */
9806 tmp
= load_reg(s
, rd
);
9808 tmp
= tcg_temp_new_i32();
9813 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9816 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9819 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9822 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
9825 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9828 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9831 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9834 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
9837 if (op
>= 3) { /* load */
9838 store_reg(s
, rd
, tmp
);
9840 tcg_temp_free_i32(tmp
);
9842 tcg_temp_free_i32(addr
);
9846 /* load/store word immediate offset */
9848 rn
= (insn
>> 3) & 7;
9849 addr
= load_reg(s
, rn
);
9850 val
= (insn
>> 4) & 0x7c;
9851 tcg_gen_addi_i32(addr
, addr
, val
);
9853 if (insn
& (1 << 11)) {
9855 tmp
= tcg_temp_new_i32();
9856 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9857 store_reg(s
, rd
, tmp
);
9860 tmp
= load_reg(s
, rd
);
9861 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9862 tcg_temp_free_i32(tmp
);
9864 tcg_temp_free_i32(addr
);
9868 /* load/store byte immediate offset */
9870 rn
= (insn
>> 3) & 7;
9871 addr
= load_reg(s
, rn
);
9872 val
= (insn
>> 6) & 0x1f;
9873 tcg_gen_addi_i32(addr
, addr
, val
);
9875 if (insn
& (1 << 11)) {
9877 tmp
= tcg_temp_new_i32();
9878 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9879 store_reg(s
, rd
, tmp
);
9882 tmp
= load_reg(s
, rd
);
9883 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9884 tcg_temp_free_i32(tmp
);
9886 tcg_temp_free_i32(addr
);
9890 /* load/store halfword immediate offset */
9892 rn
= (insn
>> 3) & 7;
9893 addr
= load_reg(s
, rn
);
9894 val
= (insn
>> 5) & 0x3e;
9895 tcg_gen_addi_i32(addr
, addr
, val
);
9897 if (insn
& (1 << 11)) {
9899 tmp
= tcg_temp_new_i32();
9900 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9901 store_reg(s
, rd
, tmp
);
9904 tmp
= load_reg(s
, rd
);
9905 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9906 tcg_temp_free_i32(tmp
);
9908 tcg_temp_free_i32(addr
);
9912 /* load/store from stack */
9913 rd
= (insn
>> 8) & 7;
9914 addr
= load_reg(s
, 13);
9915 val
= (insn
& 0xff) * 4;
9916 tcg_gen_addi_i32(addr
, addr
, val
);
9918 if (insn
& (1 << 11)) {
9920 tmp
= tcg_temp_new_i32();
9921 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9922 store_reg(s
, rd
, tmp
);
9925 tmp
= load_reg(s
, rd
);
9926 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9927 tcg_temp_free_i32(tmp
);
9929 tcg_temp_free_i32(addr
);
9933 /* add to high reg */
9934 rd
= (insn
>> 8) & 7;
9935 if (insn
& (1 << 11)) {
9937 tmp
= load_reg(s
, 13);
9939 /* PC. bit 1 is ignored. */
9940 tmp
= tcg_temp_new_i32();
9941 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9943 val
= (insn
& 0xff) * 4;
9944 tcg_gen_addi_i32(tmp
, tmp
, val
);
9945 store_reg(s
, rd
, tmp
);
9950 op
= (insn
>> 8) & 0xf;
9953 /* adjust stack pointer */
9954 tmp
= load_reg(s
, 13);
9955 val
= (insn
& 0x7f) * 4;
9956 if (insn
& (1 << 7))
9957 val
= -(int32_t)val
;
9958 tcg_gen_addi_i32(tmp
, tmp
, val
);
9959 store_reg(s
, 13, tmp
);
9962 case 2: /* sign/zero extend. */
9965 rm
= (insn
>> 3) & 7;
9966 tmp
= load_reg(s
, rm
);
9967 switch ((insn
>> 6) & 3) {
9968 case 0: gen_sxth(tmp
); break;
9969 case 1: gen_sxtb(tmp
); break;
9970 case 2: gen_uxth(tmp
); break;
9971 case 3: gen_uxtb(tmp
); break;
9973 store_reg(s
, rd
, tmp
);
9975 case 4: case 5: case 0xc: case 0xd:
9977 addr
= load_reg(s
, 13);
9978 if (insn
& (1 << 8))
9982 for (i
= 0; i
< 8; i
++) {
9983 if (insn
& (1 << i
))
9986 if ((insn
& (1 << 11)) == 0) {
9987 tcg_gen_addi_i32(addr
, addr
, -offset
);
9989 for (i
= 0; i
< 8; i
++) {
9990 if (insn
& (1 << i
)) {
9991 if (insn
& (1 << 11)) {
9993 tmp
= tcg_temp_new_i32();
9994 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9995 store_reg(s
, i
, tmp
);
9998 tmp
= load_reg(s
, i
);
9999 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10000 tcg_temp_free_i32(tmp
);
10002 /* advance to the next address. */
10003 tcg_gen_addi_i32(addr
, addr
, 4);
10006 TCGV_UNUSED_I32(tmp
);
10007 if (insn
& (1 << 8)) {
10008 if (insn
& (1 << 11)) {
10010 tmp
= tcg_temp_new_i32();
10011 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10012 /* don't set the pc until the rest of the instruction
10016 tmp
= load_reg(s
, 14);
10017 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10018 tcg_temp_free_i32(tmp
);
10020 tcg_gen_addi_i32(addr
, addr
, 4);
10022 if ((insn
& (1 << 11)) == 0) {
10023 tcg_gen_addi_i32(addr
, addr
, -offset
);
10025 /* write back the new stack pointer */
10026 store_reg(s
, 13, addr
);
10027 /* set the new PC value */
10028 if ((insn
& 0x0900) == 0x0900) {
10029 store_reg_from_load(env
, s
, 15, tmp
);
10033 case 1: case 3: case 9: case 11: /* czb */
10035 tmp
= load_reg(s
, rm
);
10036 s
->condlabel
= gen_new_label();
10038 if (insn
& (1 << 11))
10039 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10041 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10042 tcg_temp_free_i32(tmp
);
10043 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10044 val
= (uint32_t)s
->pc
+ 2;
10049 case 15: /* IT, nop-hint. */
10050 if ((insn
& 0xf) == 0) {
10051 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10055 s
->condexec_cond
= (insn
>> 4) & 0xe;
10056 s
->condexec_mask
= insn
& 0x1f;
10057 /* No actual code generated for this insn, just setup state. */
10060 case 0xe: /* bkpt */
10062 gen_exception_insn(s
, 2, EXCP_BKPT
);
10065 case 0xa: /* rev */
10067 rn
= (insn
>> 3) & 0x7;
10069 tmp
= load_reg(s
, rn
);
10070 switch ((insn
>> 6) & 3) {
10071 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10072 case 1: gen_rev16(tmp
); break;
10073 case 3: gen_revsh(tmp
); break;
10074 default: goto illegal_op
;
10076 store_reg(s
, rd
, tmp
);
10080 switch ((insn
>> 5) & 7) {
10084 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10085 /* Dynamic endianness switching not implemented. */
10086 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10097 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10100 addr
= tcg_const_i32(19);
10101 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10102 tcg_temp_free_i32(addr
);
10106 addr
= tcg_const_i32(16);
10107 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10108 tcg_temp_free_i32(addr
);
10110 tcg_temp_free_i32(tmp
);
10113 if (insn
& (1 << 4)) {
10114 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10118 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10133 /* load/store multiple */
10134 TCGv_i32 loaded_var
;
10135 TCGV_UNUSED_I32(loaded_var
);
10136 rn
= (insn
>> 8) & 0x7;
10137 addr
= load_reg(s
, rn
);
10138 for (i
= 0; i
< 8; i
++) {
10139 if (insn
& (1 << i
)) {
10140 if (insn
& (1 << 11)) {
10142 tmp
= tcg_temp_new_i32();
10143 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10147 store_reg(s
, i
, tmp
);
10151 tmp
= load_reg(s
, i
);
10152 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10153 tcg_temp_free_i32(tmp
);
10155 /* advance to the next address */
10156 tcg_gen_addi_i32(addr
, addr
, 4);
10159 if ((insn
& (1 << rn
)) == 0) {
10160 /* base reg not in list: base register writeback */
10161 store_reg(s
, rn
, addr
);
10163 /* base reg in list: if load, complete it now */
10164 if (insn
& (1 << 11)) {
10165 store_reg(s
, rn
, loaded_var
);
10167 tcg_temp_free_i32(addr
);
10172 /* conditional branch or swi */
10173 cond
= (insn
>> 8) & 0xf;
10179 gen_set_pc_im(s
, s
->pc
);
10180 s
->is_jmp
= DISAS_SWI
;
10183 /* generate a conditional jump to next instruction */
10184 s
->condlabel
= gen_new_label();
10185 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10188 /* jump to the offset */
10189 val
= (uint32_t)s
->pc
+ 2;
10190 offset
= ((int32_t)insn
<< 24) >> 24;
10191 val
+= offset
<< 1;
10196 if (insn
& (1 << 11)) {
10197 if (disas_thumb2_insn(env
, s
, insn
))
10201 /* unconditional branch */
10202 val
= (uint32_t)s
->pc
;
10203 offset
= ((int32_t)insn
<< 21) >> 21;
10204 val
+= (offset
<< 1) + 2;
10209 if (disas_thumb2_insn(env
, s
, insn
))
10215 gen_exception_insn(s
, 4, EXCP_UDEF
);
10219 gen_exception_insn(s
, 2, EXCP_UDEF
);
10222 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10223 basic block 'tb'. If search_pc is TRUE, also generate PC
10224 information for each intermediate instruction. */
10225 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10226 TranslationBlock
*tb
,
10229 CPUState
*cs
= CPU(cpu
);
10230 CPUARMState
*env
= &cpu
->env
;
10231 DisasContext dc1
, *dc
= &dc1
;
10233 uint16_t *gen_opc_end
;
10235 target_ulong pc_start
;
10236 target_ulong next_page_start
;
10240 /* generate intermediate code */
10242 /* The A64 decoder has its own top level loop, because it doesn't need
10243 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10245 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10246 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10254 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10256 dc
->is_jmp
= DISAS_NEXT
;
10258 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10262 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10263 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10264 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10265 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10266 #if !defined(CONFIG_USER_ONLY)
10267 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10269 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10270 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10271 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10273 cpu_F0s
= tcg_temp_new_i32();
10274 cpu_F1s
= tcg_temp_new_i32();
10275 cpu_F0d
= tcg_temp_new_i64();
10276 cpu_F1d
= tcg_temp_new_i64();
10279 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10280 cpu_M0
= tcg_temp_new_i64();
10281 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10284 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10285 if (max_insns
== 0)
10286 max_insns
= CF_COUNT_MASK
;
10290 tcg_clear_temp_count();
10292 /* A note on handling of the condexec (IT) bits:
10294 * We want to avoid the overhead of having to write the updated condexec
10295 * bits back to the CPUARMState for every instruction in an IT block. So:
10296 * (1) if the condexec bits are not already zero then we write
10297 * zero back into the CPUARMState now. This avoids complications trying
10298 * to do it at the end of the block. (For example if we don't do this
10299 * it's hard to identify whether we can safely skip writing condexec
10300 * at the end of the TB, which we definitely want to do for the case
10301 * where a TB doesn't do anything with the IT state at all.)
10302 * (2) if we are going to leave the TB then we call gen_set_condexec()
10303 * which will write the correct value into CPUARMState if zero is wrong.
10304 * This is done both for leaving the TB at the end, and for leaving
10305 * it because of an exception we know will happen, which is done in
10306 * gen_exception_insn(). The latter is necessary because we need to
10307 * leave the TB with the PC/IT state just prior to execution of the
10308 * instruction which caused the exception.
10309 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10310 * then the CPUARMState will be wrong and we need to reset it.
10311 * This is handled in the same way as restoration of the
10312 * PC in these situations: we will be called again with search_pc=1
10313 * and generate a mapping of the condexec bits for each PC in
10314 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10315 * this to restore the condexec bits.
10317 * Note that there are no instructions which can read the condexec
10318 * bits, and none which can write non-static values to them, so
10319 * we don't need to care about whether CPUARMState is correct in the
10323 /* Reset the conditional execution bits immediately. This avoids
10324 complications trying to do it at the end of the block. */
10325 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10327 TCGv_i32 tmp
= tcg_temp_new_i32();
10328 tcg_gen_movi_i32(tmp
, 0);
10329 store_cpu_field(tmp
, condexec_bits
);
10332 #ifdef CONFIG_USER_ONLY
10333 /* Intercept jump to the magic kernel page. */
10334 if (dc
->pc
>= 0xffff0000) {
10335 /* We always get here via a jump, so know we are not in a
10336 conditional execution block. */
10337 gen_exception(EXCP_KERNEL_TRAP
);
10338 dc
->is_jmp
= DISAS_UPDATE
;
10342 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10343 /* We always get here via a jump, so know we are not in a
10344 conditional execution block. */
10345 gen_exception(EXCP_EXCEPTION_EXIT
);
10346 dc
->is_jmp
= DISAS_UPDATE
;
10351 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10352 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10353 if (bp
->pc
== dc
->pc
) {
10354 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10355 /* Advance PC so that clearing the breakpoint will
10356 invalidate this TB. */
10358 goto done_generating
;
10363 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10367 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10369 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10370 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10371 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10372 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10375 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10378 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10379 tcg_gen_debug_insn_start(dc
->pc
);
10383 disas_thumb_insn(env
, dc
);
10384 if (dc
->condexec_mask
) {
10385 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10386 | ((dc
->condexec_mask
>> 4) & 1);
10387 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10388 if (dc
->condexec_mask
== 0) {
10389 dc
->condexec_cond
= 0;
10393 disas_arm_insn(env
, dc
);
10396 if (dc
->condjmp
&& !dc
->is_jmp
) {
10397 gen_set_label(dc
->condlabel
);
10401 if (tcg_check_temp_count()) {
10402 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10406 /* Translation stops when a conditional branch is encountered.
10407 * Otherwise the subsequent code could get translated several times.
10408 * Also stop translation when a page boundary is reached. This
10409 * ensures prefetch aborts occur at the right place. */
10411 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10412 !cs
->singlestep_enabled
&&
10414 dc
->pc
< next_page_start
&&
10415 num_insns
< max_insns
);
10417 if (tb
->cflags
& CF_LAST_IO
) {
10419 /* FIXME: This can theoretically happen with self-modifying
10421 cpu_abort(env
, "IO on conditional branch instruction");
10426 /* At this stage dc->condjmp will only be set when the skipped
10427 instruction was a conditional branch or trap, and the PC has
10428 already been written. */
10429 if (unlikely(cs
->singlestep_enabled
)) {
10430 /* Make sure the pc is updated, and raise a debug exception. */
10432 gen_set_condexec(dc
);
10433 if (dc
->is_jmp
== DISAS_SWI
) {
10434 gen_exception(EXCP_SWI
);
10436 gen_exception(EXCP_DEBUG
);
10438 gen_set_label(dc
->condlabel
);
10440 if (dc
->condjmp
|| !dc
->is_jmp
) {
10441 gen_set_pc_im(dc
, dc
->pc
);
10444 gen_set_condexec(dc
);
10445 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10446 gen_exception(EXCP_SWI
);
10448 /* FIXME: Single stepping a WFI insn will not halt
10450 gen_exception(EXCP_DEBUG
);
10453 /* While branches must always occur at the end of an IT block,
10454 there are a few other things that can cause us to terminate
10455 the TB in the middle of an IT block:
10456 - Exception generating instructions (bkpt, swi, undefined).
10458 - Hardware watchpoints.
10459 Hardware breakpoints have already been handled and skip this code.
10461 gen_set_condexec(dc
);
10462 switch(dc
->is_jmp
) {
10464 gen_goto_tb(dc
, 1, dc
->pc
);
10469 /* indicate that the hash table must be used to find the next TB */
10470 tcg_gen_exit_tb(0);
10472 case DISAS_TB_JUMP
:
10473 /* nothing more to generate */
10476 gen_helper_wfi(cpu_env
);
10479 gen_exception(EXCP_SWI
);
10483 gen_set_label(dc
->condlabel
);
10484 gen_set_condexec(dc
);
10485 gen_goto_tb(dc
, 1, dc
->pc
);
10491 gen_tb_end(tb
, num_insns
);
10492 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10495 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10496 qemu_log("----------------\n");
10497 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10498 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10499 dc
->thumb
| (dc
->bswap_code
<< 1));
10504 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10507 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10509 tb
->size
= dc
->pc
- pc_start
;
10510 tb
->icount
= num_insns
;
10514 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10516 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10519 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10521 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10524 static const char *cpu_mode_names
[16] = {
10525 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10526 "???", "???", "???", "und", "???", "???", "???", "sys"
10529 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10532 ARMCPU
*cpu
= ARM_CPU(cs
);
10533 CPUARMState
*env
= &cpu
->env
;
10537 for(i
=0;i
<16;i
++) {
10538 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10540 cpu_fprintf(f
, "\n");
10542 cpu_fprintf(f
, " ");
10544 psr
= cpsr_read(env
);
10545 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10547 psr
& (1 << 31) ? 'N' : '-',
10548 psr
& (1 << 30) ? 'Z' : '-',
10549 psr
& (1 << 29) ? 'C' : '-',
10550 psr
& (1 << 28) ? 'V' : '-',
10551 psr
& CPSR_T
? 'T' : 'A',
10552 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10554 if (flags
& CPU_DUMP_FPU
) {
10555 int numvfpregs
= 0;
10556 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10559 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10562 for (i
= 0; i
< numvfpregs
; i
++) {
10563 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10564 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10565 i
* 2, (uint32_t)v
,
10566 i
* 2 + 1, (uint32_t)(v
>> 32),
10569 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10573 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10576 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10577 env
->condexec_bits
= 0;
10579 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10580 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];