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)
59 /* These instructions trap after executing, so defer them until after the
60 conditional execution state has been updated. */
64 static TCGv_ptr cpu_env
;
65 /* We reuse the same 64-bit temporaries for efficiency. */
66 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
67 static TCGv_i32 cpu_R
[16];
68 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
69 static TCGv_i32 cpu_exclusive_addr
;
70 static TCGv_i32 cpu_exclusive_val
;
71 static TCGv_i32 cpu_exclusive_high
;
72 #ifdef CONFIG_USER_ONLY
73 static TCGv_i32 cpu_exclusive_test
;
74 static TCGv_i32 cpu_exclusive_info
;
77 /* FIXME: These should be removed. */
78 static TCGv_i32 cpu_F0s
, cpu_F1s
;
79 static TCGv_i64 cpu_F0d
, cpu_F1d
;
81 #include "exec/gen-icount.h"
83 static const char *regnames
[] =
84 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
87 /* initialize TCG globals. */
88 void arm_translate_init(void)
92 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
94 for (i
= 0; i
< 16; i
++) {
95 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
96 offsetof(CPUARMState
, regs
[i
]),
99 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
100 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
101 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
102 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
104 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
106 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
107 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
108 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
109 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
110 #ifdef CONFIG_USER_ONLY
111 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
112 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
113 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
114 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
121 static inline TCGv_i32
load_cpu_offset(int offset
)
123 TCGv_i32 tmp
= tcg_temp_new_i32();
124 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
128 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
130 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
132 tcg_gen_st_i32(var
, cpu_env
, offset
);
133 tcg_temp_free_i32(var
);
136 #define store_cpu_field(var, name) \
137 store_cpu_offset(var, offsetof(CPUARMState, name))
139 /* Set a variable to the value of a CPU register. */
140 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
144 /* normally, since we updated PC, we need only to add one insn */
146 addr
= (long)s
->pc
+ 2;
148 addr
= (long)s
->pc
+ 4;
149 tcg_gen_movi_i32(var
, addr
);
151 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
155 /* Create a new temporary and set it to the value of a CPU register. */
156 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
158 TCGv_i32 tmp
= tcg_temp_new_i32();
159 load_reg_var(s
, tmp
, reg
);
163 /* Set a CPU register. The source must be a temporary and will be
165 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
168 tcg_gen_andi_i32(var
, var
, ~1);
169 s
->is_jmp
= DISAS_JUMP
;
171 tcg_gen_mov_i32(cpu_R
[reg
], var
);
172 tcg_temp_free_i32(var
);
175 /* Value extensions. */
176 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
177 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
178 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
179 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
181 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
182 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
185 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
187 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
188 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
189 tcg_temp_free_i32(tmp_mask
);
191 /* Set NZCV flags from the high 4 bits of var. */
192 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
194 static void gen_exception(int excp
)
196 TCGv_i32 tmp
= tcg_temp_new_i32();
197 tcg_gen_movi_i32(tmp
, excp
);
198 gen_helper_exception(cpu_env
, tmp
);
199 tcg_temp_free_i32(tmp
);
202 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
204 TCGv_i32 tmp1
= tcg_temp_new_i32();
205 TCGv_i32 tmp2
= tcg_temp_new_i32();
206 tcg_gen_ext16s_i32(tmp1
, a
);
207 tcg_gen_ext16s_i32(tmp2
, b
);
208 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
209 tcg_temp_free_i32(tmp2
);
210 tcg_gen_sari_i32(a
, a
, 16);
211 tcg_gen_sari_i32(b
, b
, 16);
212 tcg_gen_mul_i32(b
, b
, a
);
213 tcg_gen_mov_i32(a
, tmp1
);
214 tcg_temp_free_i32(tmp1
);
217 /* Byteswap each halfword. */
218 static void gen_rev16(TCGv_i32 var
)
220 TCGv_i32 tmp
= tcg_temp_new_i32();
221 tcg_gen_shri_i32(tmp
, var
, 8);
222 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
223 tcg_gen_shli_i32(var
, var
, 8);
224 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
225 tcg_gen_or_i32(var
, var
, tmp
);
226 tcg_temp_free_i32(tmp
);
229 /* Byteswap low halfword and sign extend. */
230 static void gen_revsh(TCGv_i32 var
)
232 tcg_gen_ext16u_i32(var
, var
);
233 tcg_gen_bswap16_i32(var
, var
);
234 tcg_gen_ext16s_i32(var
, var
);
237 /* Unsigned bitfield extract. */
238 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
241 tcg_gen_shri_i32(var
, var
, shift
);
242 tcg_gen_andi_i32(var
, var
, mask
);
245 /* Signed bitfield extract. */
246 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
251 tcg_gen_sari_i32(var
, var
, shift
);
252 if (shift
+ width
< 32) {
253 signbit
= 1u << (width
- 1);
254 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
255 tcg_gen_xori_i32(var
, var
, signbit
);
256 tcg_gen_subi_i32(var
, var
, signbit
);
260 /* Return (b << 32) + a. Mark inputs as dead */
261 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
263 TCGv_i64 tmp64
= tcg_temp_new_i64();
265 tcg_gen_extu_i32_i64(tmp64
, b
);
266 tcg_temp_free_i32(b
);
267 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
268 tcg_gen_add_i64(a
, tmp64
, a
);
270 tcg_temp_free_i64(tmp64
);
274 /* Return (b << 32) - a. Mark inputs as dead. */
275 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
277 TCGv_i64 tmp64
= tcg_temp_new_i64();
279 tcg_gen_extu_i32_i64(tmp64
, b
);
280 tcg_temp_free_i32(b
);
281 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
282 tcg_gen_sub_i64(a
, tmp64
, a
);
284 tcg_temp_free_i64(tmp64
);
288 /* 32x32->64 multiply. Marks inputs as dead. */
289 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
291 TCGv_i32 lo
= tcg_temp_new_i32();
292 TCGv_i32 hi
= tcg_temp_new_i32();
295 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
296 tcg_temp_free_i32(a
);
297 tcg_temp_free_i32(b
);
299 ret
= tcg_temp_new_i64();
300 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
301 tcg_temp_free_i32(lo
);
302 tcg_temp_free_i32(hi
);
307 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
309 TCGv_i32 lo
= tcg_temp_new_i32();
310 TCGv_i32 hi
= tcg_temp_new_i32();
313 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
314 tcg_temp_free_i32(a
);
315 tcg_temp_free_i32(b
);
317 ret
= tcg_temp_new_i64();
318 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
319 tcg_temp_free_i32(lo
);
320 tcg_temp_free_i32(hi
);
325 /* Swap low and high halfwords. */
326 static void gen_swap_half(TCGv_i32 var
)
328 TCGv_i32 tmp
= tcg_temp_new_i32();
329 tcg_gen_shri_i32(tmp
, var
, 16);
330 tcg_gen_shli_i32(var
, var
, 16);
331 tcg_gen_or_i32(var
, var
, tmp
);
332 tcg_temp_free_i32(tmp
);
335 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
336 tmp = (t0 ^ t1) & 0x8000;
339 t0 = (t0 + t1) ^ tmp;
342 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
344 TCGv_i32 tmp
= tcg_temp_new_i32();
345 tcg_gen_xor_i32(tmp
, t0
, t1
);
346 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
347 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
348 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
349 tcg_gen_add_i32(t0
, t0
, t1
);
350 tcg_gen_xor_i32(t0
, t0
, tmp
);
351 tcg_temp_free_i32(tmp
);
352 tcg_temp_free_i32(t1
);
355 /* Set CF to the top bit of var. */
356 static void gen_set_CF_bit31(TCGv_i32 var
)
358 tcg_gen_shri_i32(cpu_CF
, var
, 31);
361 /* Set N and Z flags from var. */
362 static inline void gen_logic_CC(TCGv_i32 var
)
364 tcg_gen_mov_i32(cpu_NF
, var
);
365 tcg_gen_mov_i32(cpu_ZF
, var
);
369 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
371 tcg_gen_add_i32(t0
, t0
, t1
);
372 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
375 /* dest = T0 + T1 + CF. */
376 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
378 tcg_gen_add_i32(dest
, t0
, t1
);
379 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
382 /* dest = T0 - T1 + CF - 1. */
383 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
385 tcg_gen_sub_i32(dest
, t0
, t1
);
386 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
387 tcg_gen_subi_i32(dest
, dest
, 1);
390 /* dest = T0 + T1. Compute C, N, V and Z flags */
391 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
393 TCGv_i32 tmp
= tcg_temp_new_i32();
394 tcg_gen_movi_i32(tmp
, 0);
395 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
396 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
397 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
398 tcg_gen_xor_i32(tmp
, t0
, t1
);
399 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
400 tcg_temp_free_i32(tmp
);
401 tcg_gen_mov_i32(dest
, cpu_NF
);
404 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
405 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
407 TCGv_i32 tmp
= tcg_temp_new_i32();
408 if (TCG_TARGET_HAS_add2_i32
) {
409 tcg_gen_movi_i32(tmp
, 0);
410 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
411 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
413 TCGv_i64 q0
= tcg_temp_new_i64();
414 TCGv_i64 q1
= tcg_temp_new_i64();
415 tcg_gen_extu_i32_i64(q0
, t0
);
416 tcg_gen_extu_i32_i64(q1
, t1
);
417 tcg_gen_add_i64(q0
, q0
, q1
);
418 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
419 tcg_gen_add_i64(q0
, q0
, q1
);
420 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
421 tcg_temp_free_i64(q0
);
422 tcg_temp_free_i64(q1
);
424 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
425 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
426 tcg_gen_xor_i32(tmp
, t0
, t1
);
427 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
428 tcg_temp_free_i32(tmp
);
429 tcg_gen_mov_i32(dest
, cpu_NF
);
432 /* dest = T0 - T1. Compute C, N, V and Z flags */
433 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
436 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
437 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
438 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
439 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
440 tmp
= tcg_temp_new_i32();
441 tcg_gen_xor_i32(tmp
, t0
, t1
);
442 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
443 tcg_temp_free_i32(tmp
);
444 tcg_gen_mov_i32(dest
, cpu_NF
);
447 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
448 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
450 TCGv_i32 tmp
= tcg_temp_new_i32();
451 tcg_gen_not_i32(tmp
, t1
);
452 gen_adc_CC(dest
, t0
, tmp
);
453 tcg_temp_free_i32(tmp
);
456 #define GEN_SHIFT(name) \
457 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
459 TCGv_i32 tmp1, tmp2, tmp3; \
460 tmp1 = tcg_temp_new_i32(); \
461 tcg_gen_andi_i32(tmp1, t1, 0xff); \
462 tmp2 = tcg_const_i32(0); \
463 tmp3 = tcg_const_i32(0x1f); \
464 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
465 tcg_temp_free_i32(tmp3); \
466 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
467 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
468 tcg_temp_free_i32(tmp2); \
469 tcg_temp_free_i32(tmp1); \
475 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
478 tmp1
= tcg_temp_new_i32();
479 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
480 tmp2
= tcg_const_i32(0x1f);
481 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
482 tcg_temp_free_i32(tmp2
);
483 tcg_gen_sar_i32(dest
, t0
, tmp1
);
484 tcg_temp_free_i32(tmp1
);
487 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
489 TCGv_i32 c0
= tcg_const_i32(0);
490 TCGv_i32 tmp
= tcg_temp_new_i32();
491 tcg_gen_neg_i32(tmp
, src
);
492 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
493 tcg_temp_free_i32(c0
);
494 tcg_temp_free_i32(tmp
);
497 static void shifter_out_im(TCGv_i32 var
, int shift
)
500 tcg_gen_andi_i32(cpu_CF
, var
, 1);
502 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
504 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
509 /* Shift by immediate. Includes special handling for shift == 0. */
510 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
511 int shift
, int flags
)
517 shifter_out_im(var
, 32 - shift
);
518 tcg_gen_shli_i32(var
, var
, shift
);
524 tcg_gen_shri_i32(cpu_CF
, var
, 31);
526 tcg_gen_movi_i32(var
, 0);
529 shifter_out_im(var
, shift
- 1);
530 tcg_gen_shri_i32(var
, var
, shift
);
537 shifter_out_im(var
, shift
- 1);
540 tcg_gen_sari_i32(var
, var
, shift
);
542 case 3: /* ROR/RRX */
545 shifter_out_im(var
, shift
- 1);
546 tcg_gen_rotri_i32(var
, var
, shift
); break;
548 TCGv_i32 tmp
= tcg_temp_new_i32();
549 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
551 shifter_out_im(var
, 0);
552 tcg_gen_shri_i32(var
, var
, 1);
553 tcg_gen_or_i32(var
, var
, tmp
);
554 tcg_temp_free_i32(tmp
);
559 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
560 TCGv_i32 shift
, int flags
)
564 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
565 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
566 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
567 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
572 gen_shl(var
, var
, shift
);
575 gen_shr(var
, var
, shift
);
578 gen_sar(var
, var
, shift
);
580 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
581 tcg_gen_rotr_i32(var
, var
, shift
); break;
584 tcg_temp_free_i32(shift
);
587 #define PAS_OP(pfx) \
589 case 0: gen_pas_helper(glue(pfx,add16)); break; \
590 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
591 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
592 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
593 case 4: gen_pas_helper(glue(pfx,add8)); break; \
594 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
596 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
601 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
603 tmp
= tcg_temp_new_ptr();
604 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
606 tcg_temp_free_ptr(tmp
);
609 tmp
= tcg_temp_new_ptr();
610 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
612 tcg_temp_free_ptr(tmp
);
614 #undef gen_pas_helper
615 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
628 #undef gen_pas_helper
633 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
634 #define PAS_OP(pfx) \
636 case 0: gen_pas_helper(glue(pfx,add8)); break; \
637 case 1: gen_pas_helper(glue(pfx,add16)); break; \
638 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
639 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
640 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
641 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
643 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
648 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
650 tmp
= tcg_temp_new_ptr();
651 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
653 tcg_temp_free_ptr(tmp
);
656 tmp
= tcg_temp_new_ptr();
657 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
659 tcg_temp_free_ptr(tmp
);
661 #undef gen_pas_helper
662 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
675 #undef gen_pas_helper
680 static void gen_test_cc(int cc
, int label
)
687 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
690 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
693 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
696 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
699 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
702 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
705 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
708 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
710 case 8: /* hi: C && !Z */
711 inv
= gen_new_label();
712 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
713 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
716 case 9: /* ls: !C || Z */
717 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
718 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
720 case 10: /* ge: N == V -> N ^ V == 0 */
721 tmp
= tcg_temp_new_i32();
722 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
723 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
724 tcg_temp_free_i32(tmp
);
726 case 11: /* lt: N != V -> N ^ V != 0 */
727 tmp
= tcg_temp_new_i32();
728 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
729 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
730 tcg_temp_free_i32(tmp
);
732 case 12: /* gt: !Z && N == V */
733 inv
= gen_new_label();
734 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
735 tmp
= tcg_temp_new_i32();
736 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
737 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
738 tcg_temp_free_i32(tmp
);
741 case 13: /* le: Z || N != V */
742 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
743 tmp
= tcg_temp_new_i32();
744 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
745 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
746 tcg_temp_free_i32(tmp
);
749 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
754 static const uint8_t table_logic_cc
[16] = {
773 /* Set PC and Thumb state from an immediate address. */
774 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
778 s
->is_jmp
= DISAS_UPDATE
;
779 if (s
->thumb
!= (addr
& 1)) {
780 tmp
= tcg_temp_new_i32();
781 tcg_gen_movi_i32(tmp
, addr
& 1);
782 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
783 tcg_temp_free_i32(tmp
);
785 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
788 /* Set PC and Thumb state from var. var is marked as dead. */
789 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
791 s
->is_jmp
= DISAS_UPDATE
;
792 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
793 tcg_gen_andi_i32(var
, var
, 1);
794 store_cpu_field(var
, thumb
);
797 /* Variant of store_reg which uses branch&exchange logic when storing
798 to r15 in ARM architecture v7 and above. The source must be a temporary
799 and will be marked as dead. */
800 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
801 int reg
, TCGv_i32 var
)
803 if (reg
== 15 && ENABLE_ARCH_7
) {
806 store_reg(s
, reg
, var
);
810 /* Variant of store_reg which uses branch&exchange logic when storing
811 * to r15 in ARM architecture v5T and above. This is used for storing
812 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
813 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
814 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
815 int reg
, TCGv_i32 var
)
817 if (reg
== 15 && ENABLE_ARCH_5
) {
820 store_reg(s
, reg
, var
);
824 /* Abstractions of "generate code to do a guest load/store for
825 * AArch32", where a vaddr is always 32 bits (and is zero
826 * extended if we're a 64 bit core) and data is also
827 * 32 bits unless specifically doing a 64 bit access.
828 * These functions work like tcg_gen_qemu_{ld,st}* except
829 * that their arguments are TCGv_i32 rather than TCGv.
831 #if TARGET_LONG_BITS == 32
833 #define DO_GEN_LD(OP) \
834 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
836 tcg_gen_qemu_##OP(val, addr, index); \
839 #define DO_GEN_ST(OP) \
840 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
842 tcg_gen_qemu_##OP(val, addr, index); \
845 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
847 tcg_gen_qemu_ld64(val
, addr
, index
);
850 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
852 tcg_gen_qemu_st64(val
, addr
, index
);
857 #define DO_GEN_LD(OP) \
858 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
860 TCGv addr64 = tcg_temp_new(); \
861 TCGv val64 = tcg_temp_new(); \
862 tcg_gen_extu_i32_i64(addr64, addr); \
863 tcg_gen_qemu_##OP(val64, addr64, index); \
864 tcg_temp_free(addr64); \
865 tcg_gen_trunc_i64_i32(val, val64); \
866 tcg_temp_free(val64); \
869 #define DO_GEN_ST(OP) \
870 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
872 TCGv addr64 = tcg_temp_new(); \
873 TCGv val64 = tcg_temp_new(); \
874 tcg_gen_extu_i32_i64(addr64, addr); \
875 tcg_gen_extu_i32_i64(val64, val); \
876 tcg_gen_qemu_##OP(val64, addr64, index); \
877 tcg_temp_free(addr64); \
878 tcg_temp_free(val64); \
881 static inline void gen_aa32_ld64(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_ld64(val
, addr64
, index
);
886 tcg_temp_free(addr64
);
889 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
891 TCGv addr64
= tcg_temp_new();
892 tcg_gen_extu_i32_i64(addr64
, addr
);
893 tcg_gen_qemu_st64(val
, addr64
, index
);
894 tcg_temp_free(addr64
);
908 static inline void gen_set_pc_im(uint32_t val
)
910 tcg_gen_movi_i32(cpu_R
[15], val
);
913 /* Force a TB lookup after an instruction that changes the CPU state. */
914 static inline void gen_lookup_tb(DisasContext
*s
)
916 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
917 s
->is_jmp
= DISAS_UPDATE
;
920 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
923 int val
, rm
, shift
, shiftop
;
926 if (!(insn
& (1 << 25))) {
929 if (!(insn
& (1 << 23)))
932 tcg_gen_addi_i32(var
, var
, val
);
936 shift
= (insn
>> 7) & 0x1f;
937 shiftop
= (insn
>> 5) & 3;
938 offset
= load_reg(s
, rm
);
939 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
940 if (!(insn
& (1 << 23)))
941 tcg_gen_sub_i32(var
, var
, offset
);
943 tcg_gen_add_i32(var
, var
, offset
);
944 tcg_temp_free_i32(offset
);
948 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
949 int extra
, TCGv_i32 var
)
954 if (insn
& (1 << 22)) {
956 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
957 if (!(insn
& (1 << 23)))
961 tcg_gen_addi_i32(var
, var
, val
);
965 tcg_gen_addi_i32(var
, var
, extra
);
967 offset
= load_reg(s
, rm
);
968 if (!(insn
& (1 << 23)))
969 tcg_gen_sub_i32(var
, var
, offset
);
971 tcg_gen_add_i32(var
, var
, offset
);
972 tcg_temp_free_i32(offset
);
976 static TCGv_ptr
get_fpstatus_ptr(int neon
)
978 TCGv_ptr statusptr
= tcg_temp_new_ptr();
981 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
983 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
985 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
989 #define VFP_OP2(name) \
990 static inline void gen_vfp_##name(int dp) \
992 TCGv_ptr fpst = get_fpstatus_ptr(0); \
994 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
996 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
998 tcg_temp_free_ptr(fpst); \
1008 static inline void gen_vfp_F1_mul(int dp
)
1010 /* Like gen_vfp_mul() but put result in F1 */
1011 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1013 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1015 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1017 tcg_temp_free_ptr(fpst
);
1020 static inline void gen_vfp_F1_neg(int dp
)
1022 /* Like gen_vfp_neg() but put result in F1 */
1024 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1026 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1030 static inline void gen_vfp_abs(int dp
)
1033 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1035 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1038 static inline void gen_vfp_neg(int dp
)
1041 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1043 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1046 static inline void gen_vfp_sqrt(int dp
)
1049 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1051 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1054 static inline void gen_vfp_cmp(int dp
)
1057 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1059 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1062 static inline void gen_vfp_cmpe(int dp
)
1065 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1067 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1070 static inline void gen_vfp_F1_ld0(int dp
)
1073 tcg_gen_movi_i64(cpu_F1d
, 0);
1075 tcg_gen_movi_i32(cpu_F1s
, 0);
1078 #define VFP_GEN_ITOF(name) \
1079 static inline void gen_vfp_##name(int dp, int neon) \
1081 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1083 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1085 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1087 tcg_temp_free_ptr(statusptr); \
1094 #define VFP_GEN_FTOI(name) \
1095 static inline void gen_vfp_##name(int dp, int neon) \
1097 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1099 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1101 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1103 tcg_temp_free_ptr(statusptr); \
1112 #define VFP_GEN_FIX(name) \
1113 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1115 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1116 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1118 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1120 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1122 tcg_temp_free_i32(tmp_shift); \
1123 tcg_temp_free_ptr(statusptr); \
1135 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1138 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1140 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1144 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1147 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1149 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1154 vfp_reg_offset (int dp
, int reg
)
1157 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1159 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1160 + offsetof(CPU_DoubleU
, l
.upper
);
1162 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1163 + offsetof(CPU_DoubleU
, l
.lower
);
1167 /* Return the offset of a 32-bit piece of a NEON register.
1168 zero is the least significant end of the register. */
1170 neon_reg_offset (int reg
, int n
)
1174 return vfp_reg_offset(0, sreg
);
1177 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1179 TCGv_i32 tmp
= tcg_temp_new_i32();
1180 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1184 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1186 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1187 tcg_temp_free_i32(var
);
1190 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1192 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1195 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1197 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1200 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1201 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1202 #define tcg_gen_st_f32 tcg_gen_st_i32
1203 #define tcg_gen_st_f64 tcg_gen_st_i64
1205 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1208 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1210 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1213 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1216 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1218 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1221 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1224 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1226 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1229 #define ARM_CP_RW_BIT (1 << 20)
1231 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1233 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1236 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1238 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1241 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1243 TCGv_i32 var
= tcg_temp_new_i32();
1244 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1248 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1250 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1251 tcg_temp_free_i32(var
);
1254 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1256 iwmmxt_store_reg(cpu_M0
, rn
);
1259 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1261 iwmmxt_load_reg(cpu_M0
, rn
);
1264 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1266 iwmmxt_load_reg(cpu_V1
, rn
);
1267 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1270 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1272 iwmmxt_load_reg(cpu_V1
, rn
);
1273 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1276 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1278 iwmmxt_load_reg(cpu_V1
, rn
);
1279 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1282 #define IWMMXT_OP(name) \
1283 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1285 iwmmxt_load_reg(cpu_V1, rn); \
1286 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1289 #define IWMMXT_OP_ENV(name) \
1290 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1292 iwmmxt_load_reg(cpu_V1, rn); \
1293 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1296 #define IWMMXT_OP_ENV_SIZE(name) \
1297 IWMMXT_OP_ENV(name##b) \
1298 IWMMXT_OP_ENV(name##w) \
1299 IWMMXT_OP_ENV(name##l)
1301 #define IWMMXT_OP_ENV1(name) \
1302 static inline void gen_op_iwmmxt_##name##_M0(void) \
1304 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1318 IWMMXT_OP_ENV_SIZE(unpackl
)
1319 IWMMXT_OP_ENV_SIZE(unpackh
)
1321 IWMMXT_OP_ENV1(unpacklub
)
1322 IWMMXT_OP_ENV1(unpackluw
)
1323 IWMMXT_OP_ENV1(unpacklul
)
1324 IWMMXT_OP_ENV1(unpackhub
)
1325 IWMMXT_OP_ENV1(unpackhuw
)
1326 IWMMXT_OP_ENV1(unpackhul
)
1327 IWMMXT_OP_ENV1(unpacklsb
)
1328 IWMMXT_OP_ENV1(unpacklsw
)
1329 IWMMXT_OP_ENV1(unpacklsl
)
1330 IWMMXT_OP_ENV1(unpackhsb
)
1331 IWMMXT_OP_ENV1(unpackhsw
)
1332 IWMMXT_OP_ENV1(unpackhsl
)
1334 IWMMXT_OP_ENV_SIZE(cmpeq
)
1335 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1336 IWMMXT_OP_ENV_SIZE(cmpgts
)
1338 IWMMXT_OP_ENV_SIZE(mins
)
1339 IWMMXT_OP_ENV_SIZE(minu
)
1340 IWMMXT_OP_ENV_SIZE(maxs
)
1341 IWMMXT_OP_ENV_SIZE(maxu
)
1343 IWMMXT_OP_ENV_SIZE(subn
)
1344 IWMMXT_OP_ENV_SIZE(addn
)
1345 IWMMXT_OP_ENV_SIZE(subu
)
1346 IWMMXT_OP_ENV_SIZE(addu
)
1347 IWMMXT_OP_ENV_SIZE(subs
)
1348 IWMMXT_OP_ENV_SIZE(adds
)
1350 IWMMXT_OP_ENV(avgb0
)
1351 IWMMXT_OP_ENV(avgb1
)
1352 IWMMXT_OP_ENV(avgw0
)
1353 IWMMXT_OP_ENV(avgw1
)
1357 IWMMXT_OP_ENV(packuw
)
1358 IWMMXT_OP_ENV(packul
)
1359 IWMMXT_OP_ENV(packuq
)
1360 IWMMXT_OP_ENV(packsw
)
1361 IWMMXT_OP_ENV(packsl
)
1362 IWMMXT_OP_ENV(packsq
)
1364 static void gen_op_iwmmxt_set_mup(void)
1367 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1368 tcg_gen_ori_i32(tmp
, tmp
, 2);
1369 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1372 static void gen_op_iwmmxt_set_cup(void)
1375 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1376 tcg_gen_ori_i32(tmp
, tmp
, 1);
1377 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1380 static void gen_op_iwmmxt_setpsr_nz(void)
1382 TCGv_i32 tmp
= tcg_temp_new_i32();
1383 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1384 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1387 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1389 iwmmxt_load_reg(cpu_V1
, rn
);
1390 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1391 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1394 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1401 rd
= (insn
>> 16) & 0xf;
1402 tmp
= load_reg(s
, rd
);
1404 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1405 if (insn
& (1 << 24)) {
1407 if (insn
& (1 << 23))
1408 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1410 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1411 tcg_gen_mov_i32(dest
, tmp
);
1412 if (insn
& (1 << 21))
1413 store_reg(s
, rd
, tmp
);
1415 tcg_temp_free_i32(tmp
);
1416 } else if (insn
& (1 << 21)) {
1418 tcg_gen_mov_i32(dest
, tmp
);
1419 if (insn
& (1 << 23))
1420 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1422 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1423 store_reg(s
, rd
, tmp
);
1424 } else if (!(insn
& (1 << 23)))
1429 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1431 int rd
= (insn
>> 0) & 0xf;
1434 if (insn
& (1 << 8)) {
1435 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1438 tmp
= iwmmxt_load_creg(rd
);
1441 tmp
= tcg_temp_new_i32();
1442 iwmmxt_load_reg(cpu_V0
, rd
);
1443 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1445 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1446 tcg_gen_mov_i32(dest
, tmp
);
1447 tcg_temp_free_i32(tmp
);
1451 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1452 (ie. an undefined instruction). */
1453 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1456 int rdhi
, rdlo
, rd0
, rd1
, i
;
1458 TCGv_i32 tmp
, tmp2
, tmp3
;
1460 if ((insn
& 0x0e000e00) == 0x0c000000) {
1461 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1463 rdlo
= (insn
>> 12) & 0xf;
1464 rdhi
= (insn
>> 16) & 0xf;
1465 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1466 iwmmxt_load_reg(cpu_V0
, wrd
);
1467 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1468 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1469 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1470 } else { /* TMCRR */
1471 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1472 iwmmxt_store_reg(cpu_V0
, wrd
);
1473 gen_op_iwmmxt_set_mup();
1478 wrd
= (insn
>> 12) & 0xf;
1479 addr
= tcg_temp_new_i32();
1480 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1481 tcg_temp_free_i32(addr
);
1484 if (insn
& ARM_CP_RW_BIT
) {
1485 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1486 tmp
= tcg_temp_new_i32();
1487 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1488 iwmmxt_store_creg(wrd
, tmp
);
1491 if (insn
& (1 << 8)) {
1492 if (insn
& (1 << 22)) { /* WLDRD */
1493 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1495 } else { /* WLDRW wRd */
1496 tmp
= tcg_temp_new_i32();
1497 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1500 tmp
= tcg_temp_new_i32();
1501 if (insn
& (1 << 22)) { /* WLDRH */
1502 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1503 } else { /* WLDRB */
1504 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1508 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1509 tcg_temp_free_i32(tmp
);
1511 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1514 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1515 tmp
= iwmmxt_load_creg(wrd
);
1516 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1518 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1519 tmp
= tcg_temp_new_i32();
1520 if (insn
& (1 << 8)) {
1521 if (insn
& (1 << 22)) { /* WSTRD */
1522 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1523 } else { /* WSTRW wRd */
1524 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1525 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1528 if (insn
& (1 << 22)) { /* WSTRH */
1529 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1530 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1531 } else { /* WSTRB */
1532 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1533 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1537 tcg_temp_free_i32(tmp
);
1539 tcg_temp_free_i32(addr
);
1543 if ((insn
& 0x0f000000) != 0x0e000000)
1546 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1547 case 0x000: /* WOR */
1548 wrd
= (insn
>> 12) & 0xf;
1549 rd0
= (insn
>> 0) & 0xf;
1550 rd1
= (insn
>> 16) & 0xf;
1551 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1552 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1553 gen_op_iwmmxt_setpsr_nz();
1554 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1555 gen_op_iwmmxt_set_mup();
1556 gen_op_iwmmxt_set_cup();
1558 case 0x011: /* TMCR */
1561 rd
= (insn
>> 12) & 0xf;
1562 wrd
= (insn
>> 16) & 0xf;
1564 case ARM_IWMMXT_wCID
:
1565 case ARM_IWMMXT_wCASF
:
1567 case ARM_IWMMXT_wCon
:
1568 gen_op_iwmmxt_set_cup();
1570 case ARM_IWMMXT_wCSSF
:
1571 tmp
= iwmmxt_load_creg(wrd
);
1572 tmp2
= load_reg(s
, rd
);
1573 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1574 tcg_temp_free_i32(tmp2
);
1575 iwmmxt_store_creg(wrd
, tmp
);
1577 case ARM_IWMMXT_wCGR0
:
1578 case ARM_IWMMXT_wCGR1
:
1579 case ARM_IWMMXT_wCGR2
:
1580 case ARM_IWMMXT_wCGR3
:
1581 gen_op_iwmmxt_set_cup();
1582 tmp
= load_reg(s
, rd
);
1583 iwmmxt_store_creg(wrd
, tmp
);
1589 case 0x100: /* WXOR */
1590 wrd
= (insn
>> 12) & 0xf;
1591 rd0
= (insn
>> 0) & 0xf;
1592 rd1
= (insn
>> 16) & 0xf;
1593 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1594 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1595 gen_op_iwmmxt_setpsr_nz();
1596 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1597 gen_op_iwmmxt_set_mup();
1598 gen_op_iwmmxt_set_cup();
1600 case 0x111: /* TMRC */
1603 rd
= (insn
>> 12) & 0xf;
1604 wrd
= (insn
>> 16) & 0xf;
1605 tmp
= iwmmxt_load_creg(wrd
);
1606 store_reg(s
, rd
, tmp
);
1608 case 0x300: /* WANDN */
1609 wrd
= (insn
>> 12) & 0xf;
1610 rd0
= (insn
>> 0) & 0xf;
1611 rd1
= (insn
>> 16) & 0xf;
1612 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1613 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1614 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1615 gen_op_iwmmxt_setpsr_nz();
1616 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1617 gen_op_iwmmxt_set_mup();
1618 gen_op_iwmmxt_set_cup();
1620 case 0x200: /* WAND */
1621 wrd
= (insn
>> 12) & 0xf;
1622 rd0
= (insn
>> 0) & 0xf;
1623 rd1
= (insn
>> 16) & 0xf;
1624 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1625 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1626 gen_op_iwmmxt_setpsr_nz();
1627 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1628 gen_op_iwmmxt_set_mup();
1629 gen_op_iwmmxt_set_cup();
1631 case 0x810: case 0xa10: /* WMADD */
1632 wrd
= (insn
>> 12) & 0xf;
1633 rd0
= (insn
>> 0) & 0xf;
1634 rd1
= (insn
>> 16) & 0xf;
1635 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1636 if (insn
& (1 << 21))
1637 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1639 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1640 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1641 gen_op_iwmmxt_set_mup();
1643 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1644 wrd
= (insn
>> 12) & 0xf;
1645 rd0
= (insn
>> 16) & 0xf;
1646 rd1
= (insn
>> 0) & 0xf;
1647 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1648 switch ((insn
>> 22) & 3) {
1650 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1653 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1656 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1661 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1662 gen_op_iwmmxt_set_mup();
1663 gen_op_iwmmxt_set_cup();
1665 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1666 wrd
= (insn
>> 12) & 0xf;
1667 rd0
= (insn
>> 16) & 0xf;
1668 rd1
= (insn
>> 0) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1670 switch ((insn
>> 22) & 3) {
1672 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1675 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1678 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1683 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1684 gen_op_iwmmxt_set_mup();
1685 gen_op_iwmmxt_set_cup();
1687 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1688 wrd
= (insn
>> 12) & 0xf;
1689 rd0
= (insn
>> 16) & 0xf;
1690 rd1
= (insn
>> 0) & 0xf;
1691 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1692 if (insn
& (1 << 22))
1693 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1695 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1696 if (!(insn
& (1 << 20)))
1697 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1698 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1699 gen_op_iwmmxt_set_mup();
1701 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1702 wrd
= (insn
>> 12) & 0xf;
1703 rd0
= (insn
>> 16) & 0xf;
1704 rd1
= (insn
>> 0) & 0xf;
1705 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1706 if (insn
& (1 << 21)) {
1707 if (insn
& (1 << 20))
1708 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1710 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1712 if (insn
& (1 << 20))
1713 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1715 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1717 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1718 gen_op_iwmmxt_set_mup();
1720 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1721 wrd
= (insn
>> 12) & 0xf;
1722 rd0
= (insn
>> 16) & 0xf;
1723 rd1
= (insn
>> 0) & 0xf;
1724 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1725 if (insn
& (1 << 21))
1726 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1728 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1729 if (!(insn
& (1 << 20))) {
1730 iwmmxt_load_reg(cpu_V1
, wrd
);
1731 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 gen_op_iwmmxt_set_mup();
1736 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1737 wrd
= (insn
>> 12) & 0xf;
1738 rd0
= (insn
>> 16) & 0xf;
1739 rd1
= (insn
>> 0) & 0xf;
1740 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1741 switch ((insn
>> 22) & 3) {
1743 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1746 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1749 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1754 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1755 gen_op_iwmmxt_set_mup();
1756 gen_op_iwmmxt_set_cup();
1758 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1759 wrd
= (insn
>> 12) & 0xf;
1760 rd0
= (insn
>> 16) & 0xf;
1761 rd1
= (insn
>> 0) & 0xf;
1762 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1763 if (insn
& (1 << 22)) {
1764 if (insn
& (1 << 20))
1765 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1767 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1769 if (insn
& (1 << 20))
1770 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1772 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1774 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1775 gen_op_iwmmxt_set_mup();
1776 gen_op_iwmmxt_set_cup();
1778 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1779 wrd
= (insn
>> 12) & 0xf;
1780 rd0
= (insn
>> 16) & 0xf;
1781 rd1
= (insn
>> 0) & 0xf;
1782 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1783 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1784 tcg_gen_andi_i32(tmp
, tmp
, 7);
1785 iwmmxt_load_reg(cpu_V1
, rd1
);
1786 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1787 tcg_temp_free_i32(tmp
);
1788 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1789 gen_op_iwmmxt_set_mup();
1791 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1792 if (((insn
>> 6) & 3) == 3)
1794 rd
= (insn
>> 12) & 0xf;
1795 wrd
= (insn
>> 16) & 0xf;
1796 tmp
= load_reg(s
, rd
);
1797 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1798 switch ((insn
>> 6) & 3) {
1800 tmp2
= tcg_const_i32(0xff);
1801 tmp3
= tcg_const_i32((insn
& 7) << 3);
1804 tmp2
= tcg_const_i32(0xffff);
1805 tmp3
= tcg_const_i32((insn
& 3) << 4);
1808 tmp2
= tcg_const_i32(0xffffffff);
1809 tmp3
= tcg_const_i32((insn
& 1) << 5);
1812 TCGV_UNUSED_I32(tmp2
);
1813 TCGV_UNUSED_I32(tmp3
);
1815 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1816 tcg_temp_free_i32(tmp3
);
1817 tcg_temp_free_i32(tmp2
);
1818 tcg_temp_free_i32(tmp
);
1819 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1820 gen_op_iwmmxt_set_mup();
1822 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1823 rd
= (insn
>> 12) & 0xf;
1824 wrd
= (insn
>> 16) & 0xf;
1825 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1827 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1828 tmp
= tcg_temp_new_i32();
1829 switch ((insn
>> 22) & 3) {
1831 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1832 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1834 tcg_gen_ext8s_i32(tmp
, tmp
);
1836 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1840 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1841 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1843 tcg_gen_ext16s_i32(tmp
, tmp
);
1845 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1849 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1850 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1853 store_reg(s
, rd
, tmp
);
1855 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1856 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1858 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1859 switch ((insn
>> 22) & 3) {
1861 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1864 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1867 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1870 tcg_gen_shli_i32(tmp
, tmp
, 28);
1872 tcg_temp_free_i32(tmp
);
1874 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1875 if (((insn
>> 6) & 3) == 3)
1877 rd
= (insn
>> 12) & 0xf;
1878 wrd
= (insn
>> 16) & 0xf;
1879 tmp
= load_reg(s
, rd
);
1880 switch ((insn
>> 6) & 3) {
1882 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1885 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1888 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1891 tcg_temp_free_i32(tmp
);
1892 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1893 gen_op_iwmmxt_set_mup();
1895 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1896 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1898 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1899 tmp2
= tcg_temp_new_i32();
1900 tcg_gen_mov_i32(tmp2
, tmp
);
1901 switch ((insn
>> 22) & 3) {
1903 for (i
= 0; i
< 7; i
++) {
1904 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1905 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1909 for (i
= 0; i
< 3; i
++) {
1910 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1911 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1915 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1916 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1920 tcg_temp_free_i32(tmp2
);
1921 tcg_temp_free_i32(tmp
);
1923 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1924 wrd
= (insn
>> 12) & 0xf;
1925 rd0
= (insn
>> 16) & 0xf;
1926 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1927 switch ((insn
>> 22) & 3) {
1929 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1932 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1935 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1940 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1941 gen_op_iwmmxt_set_mup();
1943 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1944 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1946 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1947 tmp2
= tcg_temp_new_i32();
1948 tcg_gen_mov_i32(tmp2
, tmp
);
1949 switch ((insn
>> 22) & 3) {
1951 for (i
= 0; i
< 7; i
++) {
1952 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1953 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1957 for (i
= 0; i
< 3; i
++) {
1958 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1959 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1963 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1964 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1968 tcg_temp_free_i32(tmp2
);
1969 tcg_temp_free_i32(tmp
);
1971 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1972 rd
= (insn
>> 12) & 0xf;
1973 rd0
= (insn
>> 16) & 0xf;
1974 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1976 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1977 tmp
= tcg_temp_new_i32();
1978 switch ((insn
>> 22) & 3) {
1980 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1983 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1986 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1989 store_reg(s
, rd
, tmp
);
1991 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1992 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1993 wrd
= (insn
>> 12) & 0xf;
1994 rd0
= (insn
>> 16) & 0xf;
1995 rd1
= (insn
>> 0) & 0xf;
1996 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1997 switch ((insn
>> 22) & 3) {
1999 if (insn
& (1 << 21))
2000 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2002 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2005 if (insn
& (1 << 21))
2006 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2008 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2011 if (insn
& (1 << 21))
2012 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2014 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2019 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2020 gen_op_iwmmxt_set_mup();
2021 gen_op_iwmmxt_set_cup();
2023 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2024 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2025 wrd
= (insn
>> 12) & 0xf;
2026 rd0
= (insn
>> 16) & 0xf;
2027 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2028 switch ((insn
>> 22) & 3) {
2030 if (insn
& (1 << 21))
2031 gen_op_iwmmxt_unpacklsb_M0();
2033 gen_op_iwmmxt_unpacklub_M0();
2036 if (insn
& (1 << 21))
2037 gen_op_iwmmxt_unpacklsw_M0();
2039 gen_op_iwmmxt_unpackluw_M0();
2042 if (insn
& (1 << 21))
2043 gen_op_iwmmxt_unpacklsl_M0();
2045 gen_op_iwmmxt_unpacklul_M0();
2050 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2051 gen_op_iwmmxt_set_mup();
2052 gen_op_iwmmxt_set_cup();
2054 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2055 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2056 wrd
= (insn
>> 12) & 0xf;
2057 rd0
= (insn
>> 16) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2059 switch ((insn
>> 22) & 3) {
2061 if (insn
& (1 << 21))
2062 gen_op_iwmmxt_unpackhsb_M0();
2064 gen_op_iwmmxt_unpackhub_M0();
2067 if (insn
& (1 << 21))
2068 gen_op_iwmmxt_unpackhsw_M0();
2070 gen_op_iwmmxt_unpackhuw_M0();
2073 if (insn
& (1 << 21))
2074 gen_op_iwmmxt_unpackhsl_M0();
2076 gen_op_iwmmxt_unpackhul_M0();
2081 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2082 gen_op_iwmmxt_set_mup();
2083 gen_op_iwmmxt_set_cup();
2085 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2086 case 0x214: case 0x614: case 0xa14: case 0xe14:
2087 if (((insn
>> 22) & 3) == 0)
2089 wrd
= (insn
>> 12) & 0xf;
2090 rd0
= (insn
>> 16) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2092 tmp
= tcg_temp_new_i32();
2093 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2094 tcg_temp_free_i32(tmp
);
2097 switch ((insn
>> 22) & 3) {
2099 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2102 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2105 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 tcg_temp_free_i32(tmp
);
2109 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2110 gen_op_iwmmxt_set_mup();
2111 gen_op_iwmmxt_set_cup();
2113 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2114 case 0x014: case 0x414: case 0x814: case 0xc14:
2115 if (((insn
>> 22) & 3) == 0)
2117 wrd
= (insn
>> 12) & 0xf;
2118 rd0
= (insn
>> 16) & 0xf;
2119 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2120 tmp
= tcg_temp_new_i32();
2121 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2122 tcg_temp_free_i32(tmp
);
2125 switch ((insn
>> 22) & 3) {
2127 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2130 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2133 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 tcg_temp_free_i32(tmp
);
2137 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2138 gen_op_iwmmxt_set_mup();
2139 gen_op_iwmmxt_set_cup();
2141 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2142 case 0x114: case 0x514: case 0x914: case 0xd14:
2143 if (((insn
>> 22) & 3) == 0)
2145 wrd
= (insn
>> 12) & 0xf;
2146 rd0
= (insn
>> 16) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 tmp
= tcg_temp_new_i32();
2149 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2150 tcg_temp_free_i32(tmp
);
2153 switch ((insn
>> 22) & 3) {
2155 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2158 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2161 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 tcg_temp_free_i32(tmp
);
2165 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2166 gen_op_iwmmxt_set_mup();
2167 gen_op_iwmmxt_set_cup();
2169 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2170 case 0x314: case 0x714: case 0xb14: case 0xf14:
2171 if (((insn
>> 22) & 3) == 0)
2173 wrd
= (insn
>> 12) & 0xf;
2174 rd0
= (insn
>> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2176 tmp
= tcg_temp_new_i32();
2177 switch ((insn
>> 22) & 3) {
2179 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2180 tcg_temp_free_i32(tmp
);
2183 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2186 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2187 tcg_temp_free_i32(tmp
);
2190 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2193 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2194 tcg_temp_free_i32(tmp
);
2197 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2200 tcg_temp_free_i32(tmp
);
2201 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2202 gen_op_iwmmxt_set_mup();
2203 gen_op_iwmmxt_set_cup();
2205 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2206 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2207 wrd
= (insn
>> 12) & 0xf;
2208 rd0
= (insn
>> 16) & 0xf;
2209 rd1
= (insn
>> 0) & 0xf;
2210 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2211 switch ((insn
>> 22) & 3) {
2213 if (insn
& (1 << 21))
2214 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2216 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2219 if (insn
& (1 << 21))
2220 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2222 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2225 if (insn
& (1 << 21))
2226 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2228 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2233 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2234 gen_op_iwmmxt_set_mup();
2236 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2237 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2238 wrd
= (insn
>> 12) & 0xf;
2239 rd0
= (insn
>> 16) & 0xf;
2240 rd1
= (insn
>> 0) & 0xf;
2241 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2242 switch ((insn
>> 22) & 3) {
2244 if (insn
& (1 << 21))
2245 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2247 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2250 if (insn
& (1 << 21))
2251 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2253 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2256 if (insn
& (1 << 21))
2257 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2259 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2264 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2265 gen_op_iwmmxt_set_mup();
2267 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2268 case 0x402: case 0x502: case 0x602: case 0x702:
2269 wrd
= (insn
>> 12) & 0xf;
2270 rd0
= (insn
>> 16) & 0xf;
2271 rd1
= (insn
>> 0) & 0xf;
2272 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2273 tmp
= tcg_const_i32((insn
>> 20) & 3);
2274 iwmmxt_load_reg(cpu_V1
, rd1
);
2275 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2276 tcg_temp_free_i32(tmp
);
2277 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2278 gen_op_iwmmxt_set_mup();
2280 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2281 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2282 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2283 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2284 wrd
= (insn
>> 12) & 0xf;
2285 rd0
= (insn
>> 16) & 0xf;
2286 rd1
= (insn
>> 0) & 0xf;
2287 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2288 switch ((insn
>> 20) & 0xf) {
2290 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2293 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2296 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2299 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2302 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2308 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2311 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2314 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2319 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2320 gen_op_iwmmxt_set_mup();
2321 gen_op_iwmmxt_set_cup();
2323 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2324 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2325 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2326 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2327 wrd
= (insn
>> 12) & 0xf;
2328 rd0
= (insn
>> 16) & 0xf;
2329 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2330 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2331 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2332 tcg_temp_free_i32(tmp
);
2333 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2334 gen_op_iwmmxt_set_mup();
2335 gen_op_iwmmxt_set_cup();
2337 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2338 case 0x418: case 0x518: case 0x618: case 0x718:
2339 case 0x818: case 0x918: case 0xa18: case 0xb18:
2340 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2341 wrd
= (insn
>> 12) & 0xf;
2342 rd0
= (insn
>> 16) & 0xf;
2343 rd1
= (insn
>> 0) & 0xf;
2344 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2345 switch ((insn
>> 20) & 0xf) {
2347 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2350 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2353 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2356 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2359 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2362 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2365 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2368 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2371 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2376 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2377 gen_op_iwmmxt_set_mup();
2378 gen_op_iwmmxt_set_cup();
2380 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2381 case 0x408: case 0x508: case 0x608: case 0x708:
2382 case 0x808: case 0x908: case 0xa08: case 0xb08:
2383 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2384 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2386 wrd
= (insn
>> 12) & 0xf;
2387 rd0
= (insn
>> 16) & 0xf;
2388 rd1
= (insn
>> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2390 switch ((insn
>> 22) & 3) {
2392 if (insn
& (1 << 21))
2393 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2395 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2398 if (insn
& (1 << 21))
2399 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2401 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2404 if (insn
& (1 << 21))
2405 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2407 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2410 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2411 gen_op_iwmmxt_set_mup();
2412 gen_op_iwmmxt_set_cup();
2414 case 0x201: case 0x203: case 0x205: case 0x207:
2415 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2416 case 0x211: case 0x213: case 0x215: case 0x217:
2417 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2418 wrd
= (insn
>> 5) & 0xf;
2419 rd0
= (insn
>> 12) & 0xf;
2420 rd1
= (insn
>> 0) & 0xf;
2421 if (rd0
== 0xf || rd1
== 0xf)
2423 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2424 tmp
= load_reg(s
, rd0
);
2425 tmp2
= load_reg(s
, rd1
);
2426 switch ((insn
>> 16) & 0xf) {
2427 case 0x0: /* TMIA */
2428 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2430 case 0x8: /* TMIAPH */
2431 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2433 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2434 if (insn
& (1 << 16))
2435 tcg_gen_shri_i32(tmp
, tmp
, 16);
2436 if (insn
& (1 << 17))
2437 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2438 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2441 tcg_temp_free_i32(tmp2
);
2442 tcg_temp_free_i32(tmp
);
2445 tcg_temp_free_i32(tmp2
);
2446 tcg_temp_free_i32(tmp
);
2447 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2448 gen_op_iwmmxt_set_mup();
2457 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2458 (ie. an undefined instruction). */
2459 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2461 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2464 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2465 /* Multiply with Internal Accumulate Format */
2466 rd0
= (insn
>> 12) & 0xf;
2468 acc
= (insn
>> 5) & 7;
2473 tmp
= load_reg(s
, rd0
);
2474 tmp2
= load_reg(s
, rd1
);
2475 switch ((insn
>> 16) & 0xf) {
2477 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2479 case 0x8: /* MIAPH */
2480 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2482 case 0xc: /* MIABB */
2483 case 0xd: /* MIABT */
2484 case 0xe: /* MIATB */
2485 case 0xf: /* MIATT */
2486 if (insn
& (1 << 16))
2487 tcg_gen_shri_i32(tmp
, tmp
, 16);
2488 if (insn
& (1 << 17))
2489 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2490 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2495 tcg_temp_free_i32(tmp2
);
2496 tcg_temp_free_i32(tmp
);
2498 gen_op_iwmmxt_movq_wRn_M0(acc
);
2502 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2503 /* Internal Accumulator Access Format */
2504 rdhi
= (insn
>> 16) & 0xf;
2505 rdlo
= (insn
>> 12) & 0xf;
2511 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2512 iwmmxt_load_reg(cpu_V0
, acc
);
2513 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2514 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2515 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2516 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2518 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2519 iwmmxt_store_reg(cpu_V0
, acc
);
2527 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2528 #define VFP_SREG(insn, bigbit, smallbit) \
2529 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2530 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2531 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2532 reg = (((insn) >> (bigbit)) & 0x0f) \
2533 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2535 if (insn & (1 << (smallbit))) \
2537 reg = ((insn) >> (bigbit)) & 0x0f; \
2540 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2541 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2542 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2543 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2544 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2545 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2547 /* Move between integer and VFP cores. */
2548 static TCGv_i32
gen_vfp_mrs(void)
2550 TCGv_i32 tmp
= tcg_temp_new_i32();
2551 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2555 static void gen_vfp_msr(TCGv_i32 tmp
)
2557 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2558 tcg_temp_free_i32(tmp
);
2561 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2563 TCGv_i32 tmp
= tcg_temp_new_i32();
2565 tcg_gen_shri_i32(var
, var
, shift
);
2566 tcg_gen_ext8u_i32(var
, var
);
2567 tcg_gen_shli_i32(tmp
, var
, 8);
2568 tcg_gen_or_i32(var
, var
, tmp
);
2569 tcg_gen_shli_i32(tmp
, var
, 16);
2570 tcg_gen_or_i32(var
, var
, tmp
);
2571 tcg_temp_free_i32(tmp
);
2574 static void gen_neon_dup_low16(TCGv_i32 var
)
2576 TCGv_i32 tmp
= tcg_temp_new_i32();
2577 tcg_gen_ext16u_i32(var
, var
);
2578 tcg_gen_shli_i32(tmp
, var
, 16);
2579 tcg_gen_or_i32(var
, var
, tmp
);
2580 tcg_temp_free_i32(tmp
);
2583 static void gen_neon_dup_high16(TCGv_i32 var
)
2585 TCGv_i32 tmp
= tcg_temp_new_i32();
2586 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2587 tcg_gen_shri_i32(tmp
, var
, 16);
2588 tcg_gen_or_i32(var
, var
, tmp
);
2589 tcg_temp_free_i32(tmp
);
2592 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2594 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2595 TCGv_i32 tmp
= tcg_temp_new_i32();
2598 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2599 gen_neon_dup_u8(tmp
, 0);
2602 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2603 gen_neon_dup_low16(tmp
);
2606 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2608 default: /* Avoid compiler warnings. */
2614 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2615 (ie. an undefined instruction). */
2616 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2618 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2624 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2627 if (!s
->vfp_enabled
) {
2628 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2629 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2631 rn
= (insn
>> 16) & 0xf;
2632 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2633 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2636 dp
= ((insn
& 0xf00) == 0xb00);
2637 switch ((insn
>> 24) & 0xf) {
2639 if (insn
& (1 << 4)) {
2640 /* single register transfer */
2641 rd
= (insn
>> 12) & 0xf;
2646 VFP_DREG_N(rn
, insn
);
2649 if (insn
& 0x00c00060
2650 && !arm_feature(env
, ARM_FEATURE_NEON
))
2653 pass
= (insn
>> 21) & 1;
2654 if (insn
& (1 << 22)) {
2656 offset
= ((insn
>> 5) & 3) * 8;
2657 } else if (insn
& (1 << 5)) {
2659 offset
= (insn
& (1 << 6)) ? 16 : 0;
2664 if (insn
& ARM_CP_RW_BIT
) {
2666 tmp
= neon_load_reg(rn
, pass
);
2670 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2671 if (insn
& (1 << 23))
2677 if (insn
& (1 << 23)) {
2679 tcg_gen_shri_i32(tmp
, tmp
, 16);
2685 tcg_gen_sari_i32(tmp
, tmp
, 16);
2694 store_reg(s
, rd
, tmp
);
2697 tmp
= load_reg(s
, rd
);
2698 if (insn
& (1 << 23)) {
2701 gen_neon_dup_u8(tmp
, 0);
2702 } else if (size
== 1) {
2703 gen_neon_dup_low16(tmp
);
2705 for (n
= 0; n
<= pass
* 2; n
++) {
2706 tmp2
= tcg_temp_new_i32();
2707 tcg_gen_mov_i32(tmp2
, tmp
);
2708 neon_store_reg(rn
, n
, tmp2
);
2710 neon_store_reg(rn
, n
, tmp
);
2715 tmp2
= neon_load_reg(rn
, pass
);
2716 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2717 tcg_temp_free_i32(tmp2
);
2720 tmp2
= neon_load_reg(rn
, pass
);
2721 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2722 tcg_temp_free_i32(tmp2
);
2727 neon_store_reg(rn
, pass
, tmp
);
2731 if ((insn
& 0x6f) != 0x00)
2733 rn
= VFP_SREG_N(insn
);
2734 if (insn
& ARM_CP_RW_BIT
) {
2736 if (insn
& (1 << 21)) {
2737 /* system register */
2742 /* VFP2 allows access to FSID from userspace.
2743 VFP3 restricts all id registers to privileged
2746 && arm_feature(env
, ARM_FEATURE_VFP3
))
2748 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2753 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2755 case ARM_VFP_FPINST
:
2756 case ARM_VFP_FPINST2
:
2757 /* Not present in VFP3. */
2759 || arm_feature(env
, ARM_FEATURE_VFP3
))
2761 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2765 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2766 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2768 tmp
= tcg_temp_new_i32();
2769 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2775 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2777 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2783 gen_mov_F0_vreg(0, rn
);
2784 tmp
= gen_vfp_mrs();
2787 /* Set the 4 flag bits in the CPSR. */
2789 tcg_temp_free_i32(tmp
);
2791 store_reg(s
, rd
, tmp
);
2795 if (insn
& (1 << 21)) {
2797 /* system register */
2802 /* Writes are ignored. */
2805 tmp
= load_reg(s
, rd
);
2806 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2807 tcg_temp_free_i32(tmp
);
2813 /* TODO: VFP subarchitecture support.
2814 * For now, keep the EN bit only */
2815 tmp
= load_reg(s
, rd
);
2816 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2817 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2820 case ARM_VFP_FPINST
:
2821 case ARM_VFP_FPINST2
:
2822 tmp
= load_reg(s
, rd
);
2823 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2829 tmp
= load_reg(s
, rd
);
2831 gen_mov_vreg_F0(0, rn
);
2836 /* data processing */
2837 /* The opcode is in bits 23, 21, 20 and 6. */
2838 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2842 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2844 /* rn is register number */
2845 VFP_DREG_N(rn
, insn
);
2848 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2849 /* Integer or single precision destination. */
2850 rd
= VFP_SREG_D(insn
);
2852 VFP_DREG_D(rd
, insn
);
2855 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2856 /* VCVT from int is always from S reg regardless of dp bit.
2857 * VCVT with immediate frac_bits has same format as SREG_M
2859 rm
= VFP_SREG_M(insn
);
2861 VFP_DREG_M(rm
, insn
);
2864 rn
= VFP_SREG_N(insn
);
2865 if (op
== 15 && rn
== 15) {
2866 /* Double precision destination. */
2867 VFP_DREG_D(rd
, insn
);
2869 rd
= VFP_SREG_D(insn
);
2871 /* NB that we implicitly rely on the encoding for the frac_bits
2872 * in VCVT of fixed to float being the same as that of an SREG_M
2874 rm
= VFP_SREG_M(insn
);
2877 veclen
= s
->vec_len
;
2878 if (op
== 15 && rn
> 3)
2881 /* Shut up compiler warnings. */
2892 /* Figure out what type of vector operation this is. */
2893 if ((rd
& bank_mask
) == 0) {
2898 delta_d
= (s
->vec_stride
>> 1) + 1;
2900 delta_d
= s
->vec_stride
+ 1;
2902 if ((rm
& bank_mask
) == 0) {
2903 /* mixed scalar/vector */
2912 /* Load the initial operands. */
2917 /* Integer source */
2918 gen_mov_F0_vreg(0, rm
);
2923 gen_mov_F0_vreg(dp
, rd
);
2924 gen_mov_F1_vreg(dp
, rm
);
2928 /* Compare with zero */
2929 gen_mov_F0_vreg(dp
, rd
);
2940 /* Source and destination the same. */
2941 gen_mov_F0_vreg(dp
, rd
);
2947 /* VCVTB, VCVTT: only present with the halfprec extension,
2948 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2950 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2953 /* Otherwise fall through */
2955 /* One source operand. */
2956 gen_mov_F0_vreg(dp
, rm
);
2960 /* Two source operands. */
2961 gen_mov_F0_vreg(dp
, rn
);
2962 gen_mov_F1_vreg(dp
, rm
);
2966 /* Perform the calculation. */
2968 case 0: /* VMLA: fd + (fn * fm) */
2969 /* Note that order of inputs to the add matters for NaNs */
2971 gen_mov_F0_vreg(dp
, rd
);
2974 case 1: /* VMLS: fd + -(fn * fm) */
2977 gen_mov_F0_vreg(dp
, rd
);
2980 case 2: /* VNMLS: -fd + (fn * fm) */
2981 /* Note that it isn't valid to replace (-A + B) with (B - A)
2982 * or similar plausible looking simplifications
2983 * because this will give wrong results for NaNs.
2986 gen_mov_F0_vreg(dp
, rd
);
2990 case 3: /* VNMLA: -fd + -(fn * fm) */
2993 gen_mov_F0_vreg(dp
, rd
);
2997 case 4: /* mul: fn * fm */
3000 case 5: /* nmul: -(fn * fm) */
3004 case 6: /* add: fn + fm */
3007 case 7: /* sub: fn - fm */
3010 case 8: /* div: fn / fm */
3013 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3014 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3015 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3016 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3017 /* These are fused multiply-add, and must be done as one
3018 * floating point operation with no rounding between the
3019 * multiplication and addition steps.
3020 * NB that doing the negations here as separate steps is
3021 * correct : an input NaN should come out with its sign bit
3022 * flipped if it is a negated-input.
3024 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3032 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3034 frd
= tcg_temp_new_i64();
3035 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3038 gen_helper_vfp_negd(frd
, frd
);
3040 fpst
= get_fpstatus_ptr(0);
3041 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3042 cpu_F1d
, frd
, fpst
);
3043 tcg_temp_free_ptr(fpst
);
3044 tcg_temp_free_i64(frd
);
3050 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3052 frd
= tcg_temp_new_i32();
3053 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3055 gen_helper_vfp_negs(frd
, frd
);
3057 fpst
= get_fpstatus_ptr(0);
3058 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3059 cpu_F1s
, frd
, fpst
);
3060 tcg_temp_free_ptr(fpst
);
3061 tcg_temp_free_i32(frd
);
3064 case 14: /* fconst */
3065 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3068 n
= (insn
<< 12) & 0x80000000;
3069 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3076 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3083 tcg_gen_movi_i32(cpu_F0s
, n
);
3086 case 15: /* extension space */
3100 case 4: /* vcvtb.f32.f16 */
3101 tmp
= gen_vfp_mrs();
3102 tcg_gen_ext16u_i32(tmp
, tmp
);
3103 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3104 tcg_temp_free_i32(tmp
);
3106 case 5: /* vcvtt.f32.f16 */
3107 tmp
= gen_vfp_mrs();
3108 tcg_gen_shri_i32(tmp
, tmp
, 16);
3109 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3110 tcg_temp_free_i32(tmp
);
3112 case 6: /* vcvtb.f16.f32 */
3113 tmp
= tcg_temp_new_i32();
3114 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3115 gen_mov_F0_vreg(0, rd
);
3116 tmp2
= gen_vfp_mrs();
3117 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3118 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3119 tcg_temp_free_i32(tmp2
);
3122 case 7: /* vcvtt.f16.f32 */
3123 tmp
= tcg_temp_new_i32();
3124 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3125 tcg_gen_shli_i32(tmp
, tmp
, 16);
3126 gen_mov_F0_vreg(0, rd
);
3127 tmp2
= gen_vfp_mrs();
3128 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3129 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3130 tcg_temp_free_i32(tmp2
);
3142 case 11: /* cmpez */
3146 case 15: /* single<->double conversion */
3148 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3150 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3152 case 16: /* fuito */
3153 gen_vfp_uito(dp
, 0);
3155 case 17: /* fsito */
3156 gen_vfp_sito(dp
, 0);
3158 case 20: /* fshto */
3159 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3161 gen_vfp_shto(dp
, 16 - rm
, 0);
3163 case 21: /* fslto */
3164 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3166 gen_vfp_slto(dp
, 32 - rm
, 0);
3168 case 22: /* fuhto */
3169 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3171 gen_vfp_uhto(dp
, 16 - rm
, 0);
3173 case 23: /* fulto */
3174 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3176 gen_vfp_ulto(dp
, 32 - rm
, 0);
3178 case 24: /* ftoui */
3179 gen_vfp_toui(dp
, 0);
3181 case 25: /* ftouiz */
3182 gen_vfp_touiz(dp
, 0);
3184 case 26: /* ftosi */
3185 gen_vfp_tosi(dp
, 0);
3187 case 27: /* ftosiz */
3188 gen_vfp_tosiz(dp
, 0);
3190 case 28: /* ftosh */
3191 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3193 gen_vfp_tosh(dp
, 16 - rm
, 0);
3195 case 29: /* ftosl */
3196 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3198 gen_vfp_tosl(dp
, 32 - rm
, 0);
3200 case 30: /* ftouh */
3201 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3203 gen_vfp_touh(dp
, 16 - rm
, 0);
3205 case 31: /* ftoul */
3206 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3208 gen_vfp_toul(dp
, 32 - rm
, 0);
3210 default: /* undefined */
3214 default: /* undefined */
3218 /* Write back the result. */
3219 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3220 ; /* Comparison, do nothing. */
3221 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3222 /* VCVT double to int: always integer result. */
3223 gen_mov_vreg_F0(0, rd
);
3224 else if (op
== 15 && rn
== 15)
3226 gen_mov_vreg_F0(!dp
, rd
);
3228 gen_mov_vreg_F0(dp
, rd
);
3230 /* break out of the loop if we have finished */
3234 if (op
== 15 && delta_m
== 0) {
3235 /* single source one-many */
3237 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3239 gen_mov_vreg_F0(dp
, rd
);
3243 /* Setup the next operands. */
3245 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3249 /* One source operand. */
3250 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3252 gen_mov_F0_vreg(dp
, rm
);
3254 /* Two source operands. */
3255 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3257 gen_mov_F0_vreg(dp
, rn
);
3259 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3261 gen_mov_F1_vreg(dp
, rm
);
3269 if ((insn
& 0x03e00000) == 0x00400000) {
3270 /* two-register transfer */
3271 rn
= (insn
>> 16) & 0xf;
3272 rd
= (insn
>> 12) & 0xf;
3274 VFP_DREG_M(rm
, insn
);
3276 rm
= VFP_SREG_M(insn
);
3279 if (insn
& ARM_CP_RW_BIT
) {
3282 gen_mov_F0_vreg(0, rm
* 2);
3283 tmp
= gen_vfp_mrs();
3284 store_reg(s
, rd
, tmp
);
3285 gen_mov_F0_vreg(0, rm
* 2 + 1);
3286 tmp
= gen_vfp_mrs();
3287 store_reg(s
, rn
, tmp
);
3289 gen_mov_F0_vreg(0, rm
);
3290 tmp
= gen_vfp_mrs();
3291 store_reg(s
, rd
, tmp
);
3292 gen_mov_F0_vreg(0, rm
+ 1);
3293 tmp
= gen_vfp_mrs();
3294 store_reg(s
, rn
, tmp
);
3299 tmp
= load_reg(s
, rd
);
3301 gen_mov_vreg_F0(0, rm
* 2);
3302 tmp
= load_reg(s
, rn
);
3304 gen_mov_vreg_F0(0, rm
* 2 + 1);
3306 tmp
= load_reg(s
, rd
);
3308 gen_mov_vreg_F0(0, rm
);
3309 tmp
= load_reg(s
, rn
);
3311 gen_mov_vreg_F0(0, rm
+ 1);
3316 rn
= (insn
>> 16) & 0xf;
3318 VFP_DREG_D(rd
, insn
);
3320 rd
= VFP_SREG_D(insn
);
3321 if ((insn
& 0x01200000) == 0x01000000) {
3322 /* Single load/store */
3323 offset
= (insn
& 0xff) << 2;
3324 if ((insn
& (1 << 23)) == 0)
3326 if (s
->thumb
&& rn
== 15) {
3327 /* This is actually UNPREDICTABLE */
3328 addr
= tcg_temp_new_i32();
3329 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3331 addr
= load_reg(s
, rn
);
3333 tcg_gen_addi_i32(addr
, addr
, offset
);
3334 if (insn
& (1 << 20)) {
3335 gen_vfp_ld(s
, dp
, addr
);
3336 gen_mov_vreg_F0(dp
, rd
);
3338 gen_mov_F0_vreg(dp
, rd
);
3339 gen_vfp_st(s
, dp
, addr
);
3341 tcg_temp_free_i32(addr
);
3343 /* load/store multiple */
3344 int w
= insn
& (1 << 21);
3346 n
= (insn
>> 1) & 0x7f;
3350 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3351 /* P == U , W == 1 => UNDEF */
3354 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3355 /* UNPREDICTABLE cases for bad immediates: we choose to
3356 * UNDEF to avoid generating huge numbers of TCG ops
3360 if (rn
== 15 && w
) {
3361 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3365 if (s
->thumb
&& rn
== 15) {
3366 /* This is actually UNPREDICTABLE */
3367 addr
= tcg_temp_new_i32();
3368 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3370 addr
= load_reg(s
, rn
);
3372 if (insn
& (1 << 24)) /* pre-decrement */
3373 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3379 for (i
= 0; i
< n
; i
++) {
3380 if (insn
& ARM_CP_RW_BIT
) {
3382 gen_vfp_ld(s
, dp
, addr
);
3383 gen_mov_vreg_F0(dp
, rd
+ i
);
3386 gen_mov_F0_vreg(dp
, rd
+ i
);
3387 gen_vfp_st(s
, dp
, addr
);
3389 tcg_gen_addi_i32(addr
, addr
, offset
);
3393 if (insn
& (1 << 24))
3394 offset
= -offset
* n
;
3395 else if (dp
&& (insn
& 1))
3401 tcg_gen_addi_i32(addr
, addr
, offset
);
3402 store_reg(s
, rn
, addr
);
3404 tcg_temp_free_i32(addr
);
3410 /* Should never happen. */
3416 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3418 TranslationBlock
*tb
;
3421 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3423 gen_set_pc_im(dest
);
3424 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3426 gen_set_pc_im(dest
);
3431 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3433 if (unlikely(s
->singlestep_enabled
)) {
3434 /* An indirect jump so that we still trigger the debug exception. */
3439 gen_goto_tb(s
, 0, dest
);
3440 s
->is_jmp
= DISAS_TB_JUMP
;
3444 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3447 tcg_gen_sari_i32(t0
, t0
, 16);
3451 tcg_gen_sari_i32(t1
, t1
, 16);
3454 tcg_gen_mul_i32(t0
, t0
, t1
);
3457 /* Return the mask of PSR bits set by a MSR instruction. */
3458 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3462 if (flags
& (1 << 0))
3464 if (flags
& (1 << 1))
3466 if (flags
& (1 << 2))
3468 if (flags
& (1 << 3))
3471 /* Mask out undefined bits. */
3472 mask
&= ~CPSR_RESERVED
;
3473 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3475 if (!arm_feature(env
, ARM_FEATURE_V5
))
3476 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3477 if (!arm_feature(env
, ARM_FEATURE_V6
))
3478 mask
&= ~(CPSR_E
| CPSR_GE
);
3479 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3481 /* Mask out execution state bits. */
3484 /* Mask out privileged bits. */
3490 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3491 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3495 /* ??? This is also undefined in system mode. */
3499 tmp
= load_cpu_field(spsr
);
3500 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3501 tcg_gen_andi_i32(t0
, t0
, mask
);
3502 tcg_gen_or_i32(tmp
, tmp
, t0
);
3503 store_cpu_field(tmp
, spsr
);
3505 gen_set_cpsr(t0
, mask
);
3507 tcg_temp_free_i32(t0
);
3512 /* Returns nonzero if access to the PSR is not permitted. */
3513 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3516 tmp
= tcg_temp_new_i32();
3517 tcg_gen_movi_i32(tmp
, val
);
3518 return gen_set_psr(s
, mask
, spsr
, tmp
);
3521 /* Generate an old-style exception return. Marks pc as dead. */
3522 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3525 store_reg(s
, 15, pc
);
3526 tmp
= load_cpu_field(spsr
);
3527 gen_set_cpsr(tmp
, 0xffffffff);
3528 tcg_temp_free_i32(tmp
);
3529 s
->is_jmp
= DISAS_UPDATE
;
3532 /* Generate a v6 exception return. Marks both values as dead. */
3533 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3535 gen_set_cpsr(cpsr
, 0xffffffff);
3536 tcg_temp_free_i32(cpsr
);
3537 store_reg(s
, 15, pc
);
3538 s
->is_jmp
= DISAS_UPDATE
;
3542 gen_set_condexec (DisasContext
*s
)
3544 if (s
->condexec_mask
) {
3545 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3546 TCGv_i32 tmp
= tcg_temp_new_i32();
3547 tcg_gen_movi_i32(tmp
, val
);
3548 store_cpu_field(tmp
, condexec_bits
);
3552 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3554 gen_set_condexec(s
);
3555 gen_set_pc_im(s
->pc
- offset
);
3556 gen_exception(excp
);
3557 s
->is_jmp
= DISAS_JUMP
;
3560 static void gen_nop_hint(DisasContext
*s
, int val
)
3564 gen_set_pc_im(s
->pc
);
3565 s
->is_jmp
= DISAS_WFI
;
3570 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3576 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3578 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3581 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3582 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3583 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3588 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3591 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3592 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3593 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3598 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3599 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3600 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3601 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3602 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3604 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3605 switch ((size << 1) | u) { \
3607 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3610 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3613 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3616 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3619 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3622 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3624 default: return 1; \
3627 #define GEN_NEON_INTEGER_OP(name) do { \
3628 switch ((size << 1) | u) { \
3630 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3633 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3636 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3639 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3642 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3645 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3647 default: return 1; \
3650 static TCGv_i32
neon_load_scratch(int scratch
)
3652 TCGv_i32 tmp
= tcg_temp_new_i32();
3653 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3657 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3659 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3660 tcg_temp_free_i32(var
);
3663 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3667 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3669 gen_neon_dup_high16(tmp
);
3671 gen_neon_dup_low16(tmp
);
3674 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3679 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3682 if (!q
&& size
== 2) {
3685 tmp
= tcg_const_i32(rd
);
3686 tmp2
= tcg_const_i32(rm
);
3690 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3693 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3696 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3704 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3707 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3713 tcg_temp_free_i32(tmp
);
3714 tcg_temp_free_i32(tmp2
);
3718 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3721 if (!q
&& size
== 2) {
3724 tmp
= tcg_const_i32(rd
);
3725 tmp2
= tcg_const_i32(rm
);
3729 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3732 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3735 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3743 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3746 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3752 tcg_temp_free_i32(tmp
);
3753 tcg_temp_free_i32(tmp2
);
3757 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3761 rd
= tcg_temp_new_i32();
3762 tmp
= tcg_temp_new_i32();
3764 tcg_gen_shli_i32(rd
, t0
, 8);
3765 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3766 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3767 tcg_gen_or_i32(rd
, rd
, tmp
);
3769 tcg_gen_shri_i32(t1
, t1
, 8);
3770 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3771 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3772 tcg_gen_or_i32(t1
, t1
, tmp
);
3773 tcg_gen_mov_i32(t0
, rd
);
3775 tcg_temp_free_i32(tmp
);
3776 tcg_temp_free_i32(rd
);
3779 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3783 rd
= tcg_temp_new_i32();
3784 tmp
= tcg_temp_new_i32();
3786 tcg_gen_shli_i32(rd
, t0
, 16);
3787 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3788 tcg_gen_or_i32(rd
, rd
, tmp
);
3789 tcg_gen_shri_i32(t1
, t1
, 16);
3790 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3791 tcg_gen_or_i32(t1
, t1
, tmp
);
3792 tcg_gen_mov_i32(t0
, rd
);
3794 tcg_temp_free_i32(tmp
);
3795 tcg_temp_free_i32(rd
);
3803 } neon_ls_element_type
[11] = {
3817 /* Translate a NEON load/store element instruction. Return nonzero if the
3818 instruction is invalid. */
3819 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3838 if (!s
->vfp_enabled
)
3840 VFP_DREG_D(rd
, insn
);
3841 rn
= (insn
>> 16) & 0xf;
3843 load
= (insn
& (1 << 21)) != 0;
3844 if ((insn
& (1 << 23)) == 0) {
3845 /* Load store all elements. */
3846 op
= (insn
>> 8) & 0xf;
3847 size
= (insn
>> 6) & 3;
3850 /* Catch UNDEF cases for bad values of align field */
3853 if (((insn
>> 5) & 1) == 1) {
3858 if (((insn
>> 4) & 3) == 3) {
3865 nregs
= neon_ls_element_type
[op
].nregs
;
3866 interleave
= neon_ls_element_type
[op
].interleave
;
3867 spacing
= neon_ls_element_type
[op
].spacing
;
3868 if (size
== 3 && (interleave
| spacing
) != 1)
3870 addr
= tcg_temp_new_i32();
3871 load_reg_var(s
, addr
, rn
);
3872 stride
= (1 << size
) * interleave
;
3873 for (reg
= 0; reg
< nregs
; reg
++) {
3874 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3875 load_reg_var(s
, addr
, rn
);
3876 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3877 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3878 load_reg_var(s
, addr
, rn
);
3879 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3882 tmp64
= tcg_temp_new_i64();
3884 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
3885 neon_store_reg64(tmp64
, rd
);
3887 neon_load_reg64(tmp64
, rd
);
3888 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
3890 tcg_temp_free_i64(tmp64
);
3891 tcg_gen_addi_i32(addr
, addr
, stride
);
3893 for (pass
= 0; pass
< 2; pass
++) {
3896 tmp
= tcg_temp_new_i32();
3897 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
3898 neon_store_reg(rd
, pass
, tmp
);
3900 tmp
= neon_load_reg(rd
, pass
);
3901 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
3902 tcg_temp_free_i32(tmp
);
3904 tcg_gen_addi_i32(addr
, addr
, stride
);
3905 } else if (size
== 1) {
3907 tmp
= tcg_temp_new_i32();
3908 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
3909 tcg_gen_addi_i32(addr
, addr
, stride
);
3910 tmp2
= tcg_temp_new_i32();
3911 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
3912 tcg_gen_addi_i32(addr
, addr
, stride
);
3913 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3914 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3915 tcg_temp_free_i32(tmp2
);
3916 neon_store_reg(rd
, pass
, tmp
);
3918 tmp
= neon_load_reg(rd
, pass
);
3919 tmp2
= tcg_temp_new_i32();
3920 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3921 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
3922 tcg_temp_free_i32(tmp
);
3923 tcg_gen_addi_i32(addr
, addr
, stride
);
3924 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
3925 tcg_temp_free_i32(tmp2
);
3926 tcg_gen_addi_i32(addr
, addr
, stride
);
3928 } else /* size == 0 */ {
3930 TCGV_UNUSED_I32(tmp2
);
3931 for (n
= 0; n
< 4; n
++) {
3932 tmp
= tcg_temp_new_i32();
3933 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
3934 tcg_gen_addi_i32(addr
, addr
, stride
);
3938 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3939 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3940 tcg_temp_free_i32(tmp
);
3943 neon_store_reg(rd
, pass
, tmp2
);
3945 tmp2
= neon_load_reg(rd
, pass
);
3946 for (n
= 0; n
< 4; n
++) {
3947 tmp
= tcg_temp_new_i32();
3949 tcg_gen_mov_i32(tmp
, tmp2
);
3951 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3953 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
3954 tcg_temp_free_i32(tmp
);
3955 tcg_gen_addi_i32(addr
, addr
, stride
);
3957 tcg_temp_free_i32(tmp2
);
3964 tcg_temp_free_i32(addr
);
3967 size
= (insn
>> 10) & 3;
3969 /* Load single element to all lanes. */
3970 int a
= (insn
>> 4) & 1;
3974 size
= (insn
>> 6) & 3;
3975 nregs
= ((insn
>> 8) & 3) + 1;
3978 if (nregs
!= 4 || a
== 0) {
3981 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3984 if (nregs
== 1 && a
== 1 && size
== 0) {
3987 if (nregs
== 3 && a
== 1) {
3990 addr
= tcg_temp_new_i32();
3991 load_reg_var(s
, addr
, rn
);
3993 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3994 tmp
= gen_load_and_replicate(s
, addr
, size
);
3995 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3996 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3997 if (insn
& (1 << 5)) {
3998 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3999 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4001 tcg_temp_free_i32(tmp
);
4003 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4004 stride
= (insn
& (1 << 5)) ? 2 : 1;
4005 for (reg
= 0; reg
< nregs
; reg
++) {
4006 tmp
= gen_load_and_replicate(s
, addr
, size
);
4007 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4008 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4009 tcg_temp_free_i32(tmp
);
4010 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4014 tcg_temp_free_i32(addr
);
4015 stride
= (1 << size
) * nregs
;
4017 /* Single element. */
4018 int idx
= (insn
>> 4) & 0xf;
4019 pass
= (insn
>> 7) & 1;
4022 shift
= ((insn
>> 5) & 3) * 8;
4026 shift
= ((insn
>> 6) & 1) * 16;
4027 stride
= (insn
& (1 << 5)) ? 2 : 1;
4031 stride
= (insn
& (1 << 6)) ? 2 : 1;
4036 nregs
= ((insn
>> 8) & 3) + 1;
4037 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4040 if (((idx
& (1 << size
)) != 0) ||
4041 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4046 if ((idx
& 1) != 0) {
4051 if (size
== 2 && (idx
& 2) != 0) {
4056 if ((size
== 2) && ((idx
& 3) == 3)) {
4063 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4064 /* Attempts to write off the end of the register file
4065 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4066 * the neon_load_reg() would write off the end of the array.
4070 addr
= tcg_temp_new_i32();
4071 load_reg_var(s
, addr
, rn
);
4072 for (reg
= 0; reg
< nregs
; reg
++) {
4074 tmp
= tcg_temp_new_i32();
4077 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4080 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4083 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4085 default: /* Avoid compiler warnings. */
4089 tmp2
= neon_load_reg(rd
, pass
);
4090 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4091 shift
, size
? 16 : 8);
4092 tcg_temp_free_i32(tmp2
);
4094 neon_store_reg(rd
, pass
, tmp
);
4095 } else { /* Store */
4096 tmp
= neon_load_reg(rd
, pass
);
4098 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4101 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4104 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4107 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4110 tcg_temp_free_i32(tmp
);
4113 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4115 tcg_temp_free_i32(addr
);
4116 stride
= nregs
* (1 << size
);
4122 base
= load_reg(s
, rn
);
4124 tcg_gen_addi_i32(base
, base
, stride
);
4127 index
= load_reg(s
, rm
);
4128 tcg_gen_add_i32(base
, base
, index
);
4129 tcg_temp_free_i32(index
);
4131 store_reg(s
, rn
, base
);
4136 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4137 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4139 tcg_gen_and_i32(t
, t
, c
);
4140 tcg_gen_andc_i32(f
, f
, c
);
4141 tcg_gen_or_i32(dest
, t
, f
);
4144 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4147 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4148 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4149 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4154 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4157 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4158 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4159 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4164 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4167 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4168 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4169 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4174 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4177 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4178 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4179 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4184 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4190 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4191 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4196 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4197 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4204 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4205 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4210 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4211 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4218 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4222 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4223 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4224 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4229 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4230 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4231 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4235 tcg_temp_free_i32(src
);
4238 static inline void gen_neon_addl(int size
)
4241 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4242 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4243 case 2: tcg_gen_add_i64(CPU_V001
); break;
4248 static inline void gen_neon_subl(int size
)
4251 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4252 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4253 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4258 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4261 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4262 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4264 tcg_gen_neg_i64(var
, var
);
4270 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4273 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4274 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4279 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4284 switch ((size
<< 1) | u
) {
4285 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4286 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4287 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4288 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4290 tmp
= gen_muls_i64_i32(a
, b
);
4291 tcg_gen_mov_i64(dest
, tmp
);
4292 tcg_temp_free_i64(tmp
);
4295 tmp
= gen_mulu_i64_i32(a
, b
);
4296 tcg_gen_mov_i64(dest
, tmp
);
4297 tcg_temp_free_i64(tmp
);
4302 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4303 Don't forget to clean them now. */
4305 tcg_temp_free_i32(a
);
4306 tcg_temp_free_i32(b
);
4310 static void gen_neon_narrow_op(int op
, int u
, int size
,
4311 TCGv_i32 dest
, TCGv_i64 src
)
4315 gen_neon_unarrow_sats(size
, dest
, src
);
4317 gen_neon_narrow(size
, dest
, src
);
4321 gen_neon_narrow_satu(size
, dest
, src
);
4323 gen_neon_narrow_sats(size
, dest
, src
);
4328 /* Symbolic constants for op fields for Neon 3-register same-length.
4329 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4332 #define NEON_3R_VHADD 0
4333 #define NEON_3R_VQADD 1
4334 #define NEON_3R_VRHADD 2
4335 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4336 #define NEON_3R_VHSUB 4
4337 #define NEON_3R_VQSUB 5
4338 #define NEON_3R_VCGT 6
4339 #define NEON_3R_VCGE 7
4340 #define NEON_3R_VSHL 8
4341 #define NEON_3R_VQSHL 9
4342 #define NEON_3R_VRSHL 10
4343 #define NEON_3R_VQRSHL 11
4344 #define NEON_3R_VMAX 12
4345 #define NEON_3R_VMIN 13
4346 #define NEON_3R_VABD 14
4347 #define NEON_3R_VABA 15
4348 #define NEON_3R_VADD_VSUB 16
4349 #define NEON_3R_VTST_VCEQ 17
4350 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4351 #define NEON_3R_VMUL 19
4352 #define NEON_3R_VPMAX 20
4353 #define NEON_3R_VPMIN 21
4354 #define NEON_3R_VQDMULH_VQRDMULH 22
4355 #define NEON_3R_VPADD 23
4356 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4357 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4358 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4359 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4360 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4361 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4362 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4364 static const uint8_t neon_3r_sizes
[] = {
4365 [NEON_3R_VHADD
] = 0x7,
4366 [NEON_3R_VQADD
] = 0xf,
4367 [NEON_3R_VRHADD
] = 0x7,
4368 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4369 [NEON_3R_VHSUB
] = 0x7,
4370 [NEON_3R_VQSUB
] = 0xf,
4371 [NEON_3R_VCGT
] = 0x7,
4372 [NEON_3R_VCGE
] = 0x7,
4373 [NEON_3R_VSHL
] = 0xf,
4374 [NEON_3R_VQSHL
] = 0xf,
4375 [NEON_3R_VRSHL
] = 0xf,
4376 [NEON_3R_VQRSHL
] = 0xf,
4377 [NEON_3R_VMAX
] = 0x7,
4378 [NEON_3R_VMIN
] = 0x7,
4379 [NEON_3R_VABD
] = 0x7,
4380 [NEON_3R_VABA
] = 0x7,
4381 [NEON_3R_VADD_VSUB
] = 0xf,
4382 [NEON_3R_VTST_VCEQ
] = 0x7,
4383 [NEON_3R_VML
] = 0x7,
4384 [NEON_3R_VMUL
] = 0x7,
4385 [NEON_3R_VPMAX
] = 0x7,
4386 [NEON_3R_VPMIN
] = 0x7,
4387 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4388 [NEON_3R_VPADD
] = 0x7,
4389 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4390 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4391 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4392 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4393 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4394 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4395 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4398 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4399 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4402 #define NEON_2RM_VREV64 0
4403 #define NEON_2RM_VREV32 1
4404 #define NEON_2RM_VREV16 2
4405 #define NEON_2RM_VPADDL 4
4406 #define NEON_2RM_VPADDL_U 5
4407 #define NEON_2RM_VCLS 8
4408 #define NEON_2RM_VCLZ 9
4409 #define NEON_2RM_VCNT 10
4410 #define NEON_2RM_VMVN 11
4411 #define NEON_2RM_VPADAL 12
4412 #define NEON_2RM_VPADAL_U 13
4413 #define NEON_2RM_VQABS 14
4414 #define NEON_2RM_VQNEG 15
4415 #define NEON_2RM_VCGT0 16
4416 #define NEON_2RM_VCGE0 17
4417 #define NEON_2RM_VCEQ0 18
4418 #define NEON_2RM_VCLE0 19
4419 #define NEON_2RM_VCLT0 20
4420 #define NEON_2RM_VABS 22
4421 #define NEON_2RM_VNEG 23
4422 #define NEON_2RM_VCGT0_F 24
4423 #define NEON_2RM_VCGE0_F 25
4424 #define NEON_2RM_VCEQ0_F 26
4425 #define NEON_2RM_VCLE0_F 27
4426 #define NEON_2RM_VCLT0_F 28
4427 #define NEON_2RM_VABS_F 30
4428 #define NEON_2RM_VNEG_F 31
4429 #define NEON_2RM_VSWP 32
4430 #define NEON_2RM_VTRN 33
4431 #define NEON_2RM_VUZP 34
4432 #define NEON_2RM_VZIP 35
4433 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4434 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4435 #define NEON_2RM_VSHLL 38
4436 #define NEON_2RM_VCVT_F16_F32 44
4437 #define NEON_2RM_VCVT_F32_F16 46
4438 #define NEON_2RM_VRECPE 56
4439 #define NEON_2RM_VRSQRTE 57
4440 #define NEON_2RM_VRECPE_F 58
4441 #define NEON_2RM_VRSQRTE_F 59
4442 #define NEON_2RM_VCVT_FS 60
4443 #define NEON_2RM_VCVT_FU 61
4444 #define NEON_2RM_VCVT_SF 62
4445 #define NEON_2RM_VCVT_UF 63
4447 static int neon_2rm_is_float_op(int op
)
4449 /* Return true if this neon 2reg-misc op is float-to-float */
4450 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4451 op
>= NEON_2RM_VRECPE_F
);
4454 /* Each entry in this array has bit n set if the insn allows
4455 * size value n (otherwise it will UNDEF). Since unallocated
4456 * op values will have no bits set they always UNDEF.
4458 static const uint8_t neon_2rm_sizes
[] = {
4459 [NEON_2RM_VREV64
] = 0x7,
4460 [NEON_2RM_VREV32
] = 0x3,
4461 [NEON_2RM_VREV16
] = 0x1,
4462 [NEON_2RM_VPADDL
] = 0x7,
4463 [NEON_2RM_VPADDL_U
] = 0x7,
4464 [NEON_2RM_VCLS
] = 0x7,
4465 [NEON_2RM_VCLZ
] = 0x7,
4466 [NEON_2RM_VCNT
] = 0x1,
4467 [NEON_2RM_VMVN
] = 0x1,
4468 [NEON_2RM_VPADAL
] = 0x7,
4469 [NEON_2RM_VPADAL_U
] = 0x7,
4470 [NEON_2RM_VQABS
] = 0x7,
4471 [NEON_2RM_VQNEG
] = 0x7,
4472 [NEON_2RM_VCGT0
] = 0x7,
4473 [NEON_2RM_VCGE0
] = 0x7,
4474 [NEON_2RM_VCEQ0
] = 0x7,
4475 [NEON_2RM_VCLE0
] = 0x7,
4476 [NEON_2RM_VCLT0
] = 0x7,
4477 [NEON_2RM_VABS
] = 0x7,
4478 [NEON_2RM_VNEG
] = 0x7,
4479 [NEON_2RM_VCGT0_F
] = 0x4,
4480 [NEON_2RM_VCGE0_F
] = 0x4,
4481 [NEON_2RM_VCEQ0_F
] = 0x4,
4482 [NEON_2RM_VCLE0_F
] = 0x4,
4483 [NEON_2RM_VCLT0_F
] = 0x4,
4484 [NEON_2RM_VABS_F
] = 0x4,
4485 [NEON_2RM_VNEG_F
] = 0x4,
4486 [NEON_2RM_VSWP
] = 0x1,
4487 [NEON_2RM_VTRN
] = 0x7,
4488 [NEON_2RM_VUZP
] = 0x7,
4489 [NEON_2RM_VZIP
] = 0x7,
4490 [NEON_2RM_VMOVN
] = 0x7,
4491 [NEON_2RM_VQMOVN
] = 0x7,
4492 [NEON_2RM_VSHLL
] = 0x7,
4493 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4494 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4495 [NEON_2RM_VRECPE
] = 0x4,
4496 [NEON_2RM_VRSQRTE
] = 0x4,
4497 [NEON_2RM_VRECPE_F
] = 0x4,
4498 [NEON_2RM_VRSQRTE_F
] = 0x4,
4499 [NEON_2RM_VCVT_FS
] = 0x4,
4500 [NEON_2RM_VCVT_FU
] = 0x4,
4501 [NEON_2RM_VCVT_SF
] = 0x4,
4502 [NEON_2RM_VCVT_UF
] = 0x4,
4505 /* Translate a NEON data processing instruction. Return nonzero if the
4506 instruction is invalid.
4507 We process data in a mixture of 32-bit and 64-bit chunks.
4508 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4510 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4522 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4525 if (!s
->vfp_enabled
)
4527 q
= (insn
& (1 << 6)) != 0;
4528 u
= (insn
>> 24) & 1;
4529 VFP_DREG_D(rd
, insn
);
4530 VFP_DREG_N(rn
, insn
);
4531 VFP_DREG_M(rm
, insn
);
4532 size
= (insn
>> 20) & 3;
4533 if ((insn
& (1 << 23)) == 0) {
4534 /* Three register same length. */
4535 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4536 /* Catch invalid op and bad size combinations: UNDEF */
4537 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4540 /* All insns of this form UNDEF for either this condition or the
4541 * superset of cases "Q==1"; we catch the latter later.
4543 if (q
&& ((rd
| rn
| rm
) & 1)) {
4546 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4547 /* 64-bit element instructions. */
4548 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4549 neon_load_reg64(cpu_V0
, rn
+ pass
);
4550 neon_load_reg64(cpu_V1
, rm
+ pass
);
4554 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4557 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4563 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4566 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4572 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4574 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4579 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4582 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4588 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4590 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4593 case NEON_3R_VQRSHL
:
4595 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4598 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4602 case NEON_3R_VADD_VSUB
:
4604 tcg_gen_sub_i64(CPU_V001
);
4606 tcg_gen_add_i64(CPU_V001
);
4612 neon_store_reg64(cpu_V0
, rd
+ pass
);
4621 case NEON_3R_VQRSHL
:
4624 /* Shift instruction operands are reversed. */
4639 case NEON_3R_FLOAT_ARITH
:
4640 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4642 case NEON_3R_FLOAT_MINMAX
:
4643 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4645 case NEON_3R_FLOAT_CMP
:
4647 /* no encoding for U=0 C=1x */
4651 case NEON_3R_FLOAT_ACMP
:
4656 case NEON_3R_VRECPS_VRSQRTS
:
4662 if (u
&& (size
!= 0)) {
4663 /* UNDEF on invalid size for polynomial subcase */
4668 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4676 if (pairwise
&& q
) {
4677 /* All the pairwise insns UNDEF if Q is set */
4681 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4686 tmp
= neon_load_reg(rn
, 0);
4687 tmp2
= neon_load_reg(rn
, 1);
4689 tmp
= neon_load_reg(rm
, 0);
4690 tmp2
= neon_load_reg(rm
, 1);
4694 tmp
= neon_load_reg(rn
, pass
);
4695 tmp2
= neon_load_reg(rm
, pass
);
4699 GEN_NEON_INTEGER_OP(hadd
);
4702 GEN_NEON_INTEGER_OP_ENV(qadd
);
4704 case NEON_3R_VRHADD
:
4705 GEN_NEON_INTEGER_OP(rhadd
);
4707 case NEON_3R_LOGIC
: /* Logic ops. */
4708 switch ((u
<< 2) | size
) {
4710 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4713 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4716 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4719 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4722 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4725 tmp3
= neon_load_reg(rd
, pass
);
4726 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4727 tcg_temp_free_i32(tmp3
);
4730 tmp3
= neon_load_reg(rd
, pass
);
4731 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4732 tcg_temp_free_i32(tmp3
);
4735 tmp3
= neon_load_reg(rd
, pass
);
4736 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4737 tcg_temp_free_i32(tmp3
);
4742 GEN_NEON_INTEGER_OP(hsub
);
4745 GEN_NEON_INTEGER_OP_ENV(qsub
);
4748 GEN_NEON_INTEGER_OP(cgt
);
4751 GEN_NEON_INTEGER_OP(cge
);
4754 GEN_NEON_INTEGER_OP(shl
);
4757 GEN_NEON_INTEGER_OP_ENV(qshl
);
4760 GEN_NEON_INTEGER_OP(rshl
);
4762 case NEON_3R_VQRSHL
:
4763 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4766 GEN_NEON_INTEGER_OP(max
);
4769 GEN_NEON_INTEGER_OP(min
);
4772 GEN_NEON_INTEGER_OP(abd
);
4775 GEN_NEON_INTEGER_OP(abd
);
4776 tcg_temp_free_i32(tmp2
);
4777 tmp2
= neon_load_reg(rd
, pass
);
4778 gen_neon_add(size
, tmp
, tmp2
);
4780 case NEON_3R_VADD_VSUB
:
4781 if (!u
) { /* VADD */
4782 gen_neon_add(size
, tmp
, tmp2
);
4785 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4786 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4787 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4792 case NEON_3R_VTST_VCEQ
:
4793 if (!u
) { /* VTST */
4795 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4796 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4797 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4802 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4803 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4804 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4809 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4811 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4812 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4813 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4816 tcg_temp_free_i32(tmp2
);
4817 tmp2
= neon_load_reg(rd
, pass
);
4819 gen_neon_rsb(size
, tmp
, tmp2
);
4821 gen_neon_add(size
, tmp
, tmp2
);
4825 if (u
) { /* polynomial */
4826 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4827 } else { /* Integer */
4829 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4830 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4831 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4837 GEN_NEON_INTEGER_OP(pmax
);
4840 GEN_NEON_INTEGER_OP(pmin
);
4842 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4843 if (!u
) { /* VQDMULH */
4846 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4849 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4853 } else { /* VQRDMULH */
4856 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4859 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4867 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4868 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4869 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4873 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4875 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4876 switch ((u
<< 2) | size
) {
4879 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4882 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4885 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4890 tcg_temp_free_ptr(fpstatus
);
4893 case NEON_3R_FLOAT_MULTIPLY
:
4895 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4896 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4898 tcg_temp_free_i32(tmp2
);
4899 tmp2
= neon_load_reg(rd
, pass
);
4901 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4903 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4906 tcg_temp_free_ptr(fpstatus
);
4909 case NEON_3R_FLOAT_CMP
:
4911 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4913 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4916 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4918 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4921 tcg_temp_free_ptr(fpstatus
);
4924 case NEON_3R_FLOAT_ACMP
:
4926 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4928 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4930 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4932 tcg_temp_free_ptr(fpstatus
);
4935 case NEON_3R_FLOAT_MINMAX
:
4937 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4939 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4941 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4943 tcg_temp_free_ptr(fpstatus
);
4946 case NEON_3R_VRECPS_VRSQRTS
:
4948 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4950 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4954 /* VFMA, VFMS: fused multiply-add */
4955 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4956 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4959 gen_helper_vfp_negs(tmp
, tmp
);
4961 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4962 tcg_temp_free_i32(tmp3
);
4963 tcg_temp_free_ptr(fpstatus
);
4969 tcg_temp_free_i32(tmp2
);
4971 /* Save the result. For elementwise operations we can put it
4972 straight into the destination register. For pairwise operations
4973 we have to be careful to avoid clobbering the source operands. */
4974 if (pairwise
&& rd
== rm
) {
4975 neon_store_scratch(pass
, tmp
);
4977 neon_store_reg(rd
, pass
, tmp
);
4981 if (pairwise
&& rd
== rm
) {
4982 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4983 tmp
= neon_load_scratch(pass
);
4984 neon_store_reg(rd
, pass
, tmp
);
4987 /* End of 3 register same size operations. */
4988 } else if (insn
& (1 << 4)) {
4989 if ((insn
& 0x00380080) != 0) {
4990 /* Two registers and shift. */
4991 op
= (insn
>> 8) & 0xf;
4992 if (insn
& (1 << 7)) {
5000 while ((insn
& (1 << (size
+ 19))) == 0)
5003 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5004 /* To avoid excessive duplication of ops we implement shift
5005 by immediate using the variable shift operations. */
5007 /* Shift by immediate:
5008 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5009 if (q
&& ((rd
| rm
) & 1)) {
5012 if (!u
&& (op
== 4 || op
== 6)) {
5015 /* Right shifts are encoded as N - shift, where N is the
5016 element size in bits. */
5018 shift
= shift
- (1 << (size
+ 3));
5026 imm
= (uint8_t) shift
;
5031 imm
= (uint16_t) shift
;
5042 for (pass
= 0; pass
< count
; pass
++) {
5044 neon_load_reg64(cpu_V0
, rm
+ pass
);
5045 tcg_gen_movi_i64(cpu_V1
, imm
);
5050 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5052 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5057 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5059 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5062 case 5: /* VSHL, VSLI */
5063 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5065 case 6: /* VQSHLU */
5066 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5071 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5074 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5079 if (op
== 1 || op
== 3) {
5081 neon_load_reg64(cpu_V1
, rd
+ pass
);
5082 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5083 } else if (op
== 4 || (op
== 5 && u
)) {
5085 neon_load_reg64(cpu_V1
, rd
+ pass
);
5087 if (shift
< -63 || shift
> 63) {
5091 mask
= 0xffffffffffffffffull
>> -shift
;
5093 mask
= 0xffffffffffffffffull
<< shift
;
5096 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5097 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5099 neon_store_reg64(cpu_V0
, rd
+ pass
);
5100 } else { /* size < 3 */
5101 /* Operands in T0 and T1. */
5102 tmp
= neon_load_reg(rm
, pass
);
5103 tmp2
= tcg_temp_new_i32();
5104 tcg_gen_movi_i32(tmp2
, imm
);
5108 GEN_NEON_INTEGER_OP(shl
);
5112 GEN_NEON_INTEGER_OP(rshl
);
5115 case 5: /* VSHL, VSLI */
5117 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5118 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5119 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5123 case 6: /* VQSHLU */
5126 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5130 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5134 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5142 GEN_NEON_INTEGER_OP_ENV(qshl
);
5145 tcg_temp_free_i32(tmp2
);
5147 if (op
== 1 || op
== 3) {
5149 tmp2
= neon_load_reg(rd
, pass
);
5150 gen_neon_add(size
, tmp
, tmp2
);
5151 tcg_temp_free_i32(tmp2
);
5152 } else if (op
== 4 || (op
== 5 && u
)) {
5157 mask
= 0xff >> -shift
;
5159 mask
= (uint8_t)(0xff << shift
);
5165 mask
= 0xffff >> -shift
;
5167 mask
= (uint16_t)(0xffff << shift
);
5171 if (shift
< -31 || shift
> 31) {
5175 mask
= 0xffffffffu
>> -shift
;
5177 mask
= 0xffffffffu
<< shift
;
5183 tmp2
= neon_load_reg(rd
, pass
);
5184 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5185 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5186 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5187 tcg_temp_free_i32(tmp2
);
5189 neon_store_reg(rd
, pass
, tmp
);
5192 } else if (op
< 10) {
5193 /* Shift by immediate and narrow:
5194 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5195 int input_unsigned
= (op
== 8) ? !u
: u
;
5199 shift
= shift
- (1 << (size
+ 3));
5202 tmp64
= tcg_const_i64(shift
);
5203 neon_load_reg64(cpu_V0
, rm
);
5204 neon_load_reg64(cpu_V1
, rm
+ 1);
5205 for (pass
= 0; pass
< 2; pass
++) {
5213 if (input_unsigned
) {
5214 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5216 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5219 if (input_unsigned
) {
5220 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5222 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5225 tmp
= tcg_temp_new_i32();
5226 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5227 neon_store_reg(rd
, pass
, tmp
);
5229 tcg_temp_free_i64(tmp64
);
5232 imm
= (uint16_t)shift
;
5236 imm
= (uint32_t)shift
;
5238 tmp2
= tcg_const_i32(imm
);
5239 tmp4
= neon_load_reg(rm
+ 1, 0);
5240 tmp5
= neon_load_reg(rm
+ 1, 1);
5241 for (pass
= 0; pass
< 2; pass
++) {
5243 tmp
= neon_load_reg(rm
, 0);
5247 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5250 tmp3
= neon_load_reg(rm
, 1);
5254 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5256 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5257 tcg_temp_free_i32(tmp
);
5258 tcg_temp_free_i32(tmp3
);
5259 tmp
= tcg_temp_new_i32();
5260 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5261 neon_store_reg(rd
, pass
, tmp
);
5263 tcg_temp_free_i32(tmp2
);
5265 } else if (op
== 10) {
5267 if (q
|| (rd
& 1)) {
5270 tmp
= neon_load_reg(rm
, 0);
5271 tmp2
= neon_load_reg(rm
, 1);
5272 for (pass
= 0; pass
< 2; pass
++) {
5276 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5279 /* The shift is less than the width of the source
5280 type, so we can just shift the whole register. */
5281 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5282 /* Widen the result of shift: we need to clear
5283 * the potential overflow bits resulting from
5284 * left bits of the narrow input appearing as
5285 * right bits of left the neighbour narrow
5287 if (size
< 2 || !u
) {
5290 imm
= (0xffu
>> (8 - shift
));
5292 } else if (size
== 1) {
5293 imm
= 0xffff >> (16 - shift
);
5296 imm
= 0xffffffff >> (32 - shift
);
5299 imm64
= imm
| (((uint64_t)imm
) << 32);
5303 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5306 neon_store_reg64(cpu_V0
, rd
+ pass
);
5308 } else if (op
>= 14) {
5309 /* VCVT fixed-point. */
5310 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5313 /* We have already masked out the must-be-1 top bit of imm6,
5314 * hence this 32-shift where the ARM ARM has 64-imm6.
5317 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5318 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5321 gen_vfp_ulto(0, shift
, 1);
5323 gen_vfp_slto(0, shift
, 1);
5326 gen_vfp_toul(0, shift
, 1);
5328 gen_vfp_tosl(0, shift
, 1);
5330 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5335 } else { /* (insn & 0x00380080) == 0 */
5337 if (q
&& (rd
& 1)) {
5341 op
= (insn
>> 8) & 0xf;
5342 /* One register and immediate. */
5343 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5344 invert
= (insn
& (1 << 5)) != 0;
5345 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5346 * We choose to not special-case this and will behave as if a
5347 * valid constant encoding of 0 had been given.
5366 imm
= (imm
<< 8) | (imm
<< 24);
5369 imm
= (imm
<< 8) | 0xff;
5372 imm
= (imm
<< 16) | 0xffff;
5375 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5383 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5384 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5390 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5391 if (op
& 1 && op
< 12) {
5392 tmp
= neon_load_reg(rd
, pass
);
5394 /* The immediate value has already been inverted, so
5396 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5398 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5402 tmp
= tcg_temp_new_i32();
5403 if (op
== 14 && invert
) {
5407 for (n
= 0; n
< 4; n
++) {
5408 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5409 val
|= 0xff << (n
* 8);
5411 tcg_gen_movi_i32(tmp
, val
);
5413 tcg_gen_movi_i32(tmp
, imm
);
5416 neon_store_reg(rd
, pass
, tmp
);
5419 } else { /* (insn & 0x00800010 == 0x00800000) */
5421 op
= (insn
>> 8) & 0xf;
5422 if ((insn
& (1 << 6)) == 0) {
5423 /* Three registers of different lengths. */
5427 /* undefreq: bit 0 : UNDEF if size != 0
5428 * bit 1 : UNDEF if size == 0
5429 * bit 2 : UNDEF if U == 1
5430 * Note that [1:0] set implies 'always UNDEF'
5433 /* prewiden, src1_wide, src2_wide, undefreq */
5434 static const int neon_3reg_wide
[16][4] = {
5435 {1, 0, 0, 0}, /* VADDL */
5436 {1, 1, 0, 0}, /* VADDW */
5437 {1, 0, 0, 0}, /* VSUBL */
5438 {1, 1, 0, 0}, /* VSUBW */
5439 {0, 1, 1, 0}, /* VADDHN */
5440 {0, 0, 0, 0}, /* VABAL */
5441 {0, 1, 1, 0}, /* VSUBHN */
5442 {0, 0, 0, 0}, /* VABDL */
5443 {0, 0, 0, 0}, /* VMLAL */
5444 {0, 0, 0, 6}, /* VQDMLAL */
5445 {0, 0, 0, 0}, /* VMLSL */
5446 {0, 0, 0, 6}, /* VQDMLSL */
5447 {0, 0, 0, 0}, /* Integer VMULL */
5448 {0, 0, 0, 2}, /* VQDMULL */
5449 {0, 0, 0, 5}, /* Polynomial VMULL */
5450 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5453 prewiden
= neon_3reg_wide
[op
][0];
5454 src1_wide
= neon_3reg_wide
[op
][1];
5455 src2_wide
= neon_3reg_wide
[op
][2];
5456 undefreq
= neon_3reg_wide
[op
][3];
5458 if (((undefreq
& 1) && (size
!= 0)) ||
5459 ((undefreq
& 2) && (size
== 0)) ||
5460 ((undefreq
& 4) && u
)) {
5463 if ((src1_wide
&& (rn
& 1)) ||
5464 (src2_wide
&& (rm
& 1)) ||
5465 (!src2_wide
&& (rd
& 1))) {
5469 /* Avoid overlapping operands. Wide source operands are
5470 always aligned so will never overlap with wide
5471 destinations in problematic ways. */
5472 if (rd
== rm
&& !src2_wide
) {
5473 tmp
= neon_load_reg(rm
, 1);
5474 neon_store_scratch(2, tmp
);
5475 } else if (rd
== rn
&& !src1_wide
) {
5476 tmp
= neon_load_reg(rn
, 1);
5477 neon_store_scratch(2, tmp
);
5479 TCGV_UNUSED_I32(tmp3
);
5480 for (pass
= 0; pass
< 2; pass
++) {
5482 neon_load_reg64(cpu_V0
, rn
+ pass
);
5483 TCGV_UNUSED_I32(tmp
);
5485 if (pass
== 1 && rd
== rn
) {
5486 tmp
= neon_load_scratch(2);
5488 tmp
= neon_load_reg(rn
, pass
);
5491 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5495 neon_load_reg64(cpu_V1
, rm
+ pass
);
5496 TCGV_UNUSED_I32(tmp2
);
5498 if (pass
== 1 && rd
== rm
) {
5499 tmp2
= neon_load_scratch(2);
5501 tmp2
= neon_load_reg(rm
, pass
);
5504 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5508 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5509 gen_neon_addl(size
);
5511 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5512 gen_neon_subl(size
);
5514 case 5: case 7: /* VABAL, VABDL */
5515 switch ((size
<< 1) | u
) {
5517 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5520 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5523 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5526 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5529 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5532 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5536 tcg_temp_free_i32(tmp2
);
5537 tcg_temp_free_i32(tmp
);
5539 case 8: case 9: case 10: case 11: case 12: case 13:
5540 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5541 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5543 case 14: /* Polynomial VMULL */
5544 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5545 tcg_temp_free_i32(tmp2
);
5546 tcg_temp_free_i32(tmp
);
5548 default: /* 15 is RESERVED: caught earlier */
5553 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5554 neon_store_reg64(cpu_V0
, rd
+ pass
);
5555 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5557 neon_load_reg64(cpu_V1
, rd
+ pass
);
5559 case 10: /* VMLSL */
5560 gen_neon_negl(cpu_V0
, size
);
5562 case 5: case 8: /* VABAL, VMLAL */
5563 gen_neon_addl(size
);
5565 case 9: case 11: /* VQDMLAL, VQDMLSL */
5566 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5568 gen_neon_negl(cpu_V0
, size
);
5570 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5575 neon_store_reg64(cpu_V0
, rd
+ pass
);
5576 } else if (op
== 4 || op
== 6) {
5577 /* Narrowing operation. */
5578 tmp
= tcg_temp_new_i32();
5582 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5585 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5588 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5589 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5596 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5599 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5602 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5603 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5604 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5612 neon_store_reg(rd
, 0, tmp3
);
5613 neon_store_reg(rd
, 1, tmp
);
5616 /* Write back the result. */
5617 neon_store_reg64(cpu_V0
, rd
+ pass
);
5621 /* Two registers and a scalar. NB that for ops of this form
5622 * the ARM ARM labels bit 24 as Q, but it is in our variable
5629 case 1: /* Float VMLA scalar */
5630 case 5: /* Floating point VMLS scalar */
5631 case 9: /* Floating point VMUL scalar */
5636 case 0: /* Integer VMLA scalar */
5637 case 4: /* Integer VMLS scalar */
5638 case 8: /* Integer VMUL scalar */
5639 case 12: /* VQDMULH scalar */
5640 case 13: /* VQRDMULH scalar */
5641 if (u
&& ((rd
| rn
) & 1)) {
5644 tmp
= neon_get_scalar(size
, rm
);
5645 neon_store_scratch(0, tmp
);
5646 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5647 tmp
= neon_load_scratch(0);
5648 tmp2
= neon_load_reg(rn
, pass
);
5651 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5653 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5655 } else if (op
== 13) {
5657 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5659 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5661 } else if (op
& 1) {
5662 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5663 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5664 tcg_temp_free_ptr(fpstatus
);
5667 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5668 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5669 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5673 tcg_temp_free_i32(tmp2
);
5676 tmp2
= neon_load_reg(rd
, pass
);
5679 gen_neon_add(size
, tmp
, tmp2
);
5683 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5684 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5685 tcg_temp_free_ptr(fpstatus
);
5689 gen_neon_rsb(size
, tmp
, tmp2
);
5693 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5694 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5695 tcg_temp_free_ptr(fpstatus
);
5701 tcg_temp_free_i32(tmp2
);
5703 neon_store_reg(rd
, pass
, tmp
);
5706 case 3: /* VQDMLAL scalar */
5707 case 7: /* VQDMLSL scalar */
5708 case 11: /* VQDMULL scalar */
5713 case 2: /* VMLAL sclar */
5714 case 6: /* VMLSL scalar */
5715 case 10: /* VMULL scalar */
5719 tmp2
= neon_get_scalar(size
, rm
);
5720 /* We need a copy of tmp2 because gen_neon_mull
5721 * deletes it during pass 0. */
5722 tmp4
= tcg_temp_new_i32();
5723 tcg_gen_mov_i32(tmp4
, tmp2
);
5724 tmp3
= neon_load_reg(rn
, 1);
5726 for (pass
= 0; pass
< 2; pass
++) {
5728 tmp
= neon_load_reg(rn
, 0);
5733 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5735 neon_load_reg64(cpu_V1
, rd
+ pass
);
5739 gen_neon_negl(cpu_V0
, size
);
5742 gen_neon_addl(size
);
5745 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5747 gen_neon_negl(cpu_V0
, size
);
5749 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5755 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5760 neon_store_reg64(cpu_V0
, rd
+ pass
);
5765 default: /* 14 and 15 are RESERVED */
5769 } else { /* size == 3 */
5772 imm
= (insn
>> 8) & 0xf;
5777 if (q
&& ((rd
| rn
| rm
) & 1)) {
5782 neon_load_reg64(cpu_V0
, rn
);
5784 neon_load_reg64(cpu_V1
, rn
+ 1);
5786 } else if (imm
== 8) {
5787 neon_load_reg64(cpu_V0
, rn
+ 1);
5789 neon_load_reg64(cpu_V1
, rm
);
5792 tmp64
= tcg_temp_new_i64();
5794 neon_load_reg64(cpu_V0
, rn
);
5795 neon_load_reg64(tmp64
, rn
+ 1);
5797 neon_load_reg64(cpu_V0
, rn
+ 1);
5798 neon_load_reg64(tmp64
, rm
);
5800 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5801 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5802 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5804 neon_load_reg64(cpu_V1
, rm
);
5806 neon_load_reg64(cpu_V1
, rm
+ 1);
5809 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5810 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5811 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5812 tcg_temp_free_i64(tmp64
);
5815 neon_load_reg64(cpu_V0
, rn
);
5816 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5817 neon_load_reg64(cpu_V1
, rm
);
5818 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5819 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5821 neon_store_reg64(cpu_V0
, rd
);
5823 neon_store_reg64(cpu_V1
, rd
+ 1);
5825 } else if ((insn
& (1 << 11)) == 0) {
5826 /* Two register misc. */
5827 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5828 size
= (insn
>> 18) & 3;
5829 /* UNDEF for unknown op values and bad op-size combinations */
5830 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5833 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5834 q
&& ((rm
| rd
) & 1)) {
5838 case NEON_2RM_VREV64
:
5839 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5840 tmp
= neon_load_reg(rm
, pass
* 2);
5841 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5843 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5844 case 1: gen_swap_half(tmp
); break;
5845 case 2: /* no-op */ break;
5848 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5850 neon_store_reg(rd
, pass
* 2, tmp2
);
5853 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5854 case 1: gen_swap_half(tmp2
); break;
5857 neon_store_reg(rd
, pass
* 2, tmp2
);
5861 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5862 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5863 for (pass
= 0; pass
< q
+ 1; pass
++) {
5864 tmp
= neon_load_reg(rm
, pass
* 2);
5865 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5866 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5867 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5869 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5870 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5871 case 2: tcg_gen_add_i64(CPU_V001
); break;
5874 if (op
>= NEON_2RM_VPADAL
) {
5876 neon_load_reg64(cpu_V1
, rd
+ pass
);
5877 gen_neon_addl(size
);
5879 neon_store_reg64(cpu_V0
, rd
+ pass
);
5885 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5886 tmp
= neon_load_reg(rm
, n
);
5887 tmp2
= neon_load_reg(rd
, n
+ 1);
5888 neon_store_reg(rm
, n
, tmp2
);
5889 neon_store_reg(rd
, n
+ 1, tmp
);
5896 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5901 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5905 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5906 /* also VQMOVUN; op field and mnemonics don't line up */
5910 TCGV_UNUSED_I32(tmp2
);
5911 for (pass
= 0; pass
< 2; pass
++) {
5912 neon_load_reg64(cpu_V0
, rm
+ pass
);
5913 tmp
= tcg_temp_new_i32();
5914 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5919 neon_store_reg(rd
, 0, tmp2
);
5920 neon_store_reg(rd
, 1, tmp
);
5924 case NEON_2RM_VSHLL
:
5925 if (q
|| (rd
& 1)) {
5928 tmp
= neon_load_reg(rm
, 0);
5929 tmp2
= neon_load_reg(rm
, 1);
5930 for (pass
= 0; pass
< 2; pass
++) {
5933 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5934 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5935 neon_store_reg64(cpu_V0
, rd
+ pass
);
5938 case NEON_2RM_VCVT_F16_F32
:
5939 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5943 tmp
= tcg_temp_new_i32();
5944 tmp2
= tcg_temp_new_i32();
5945 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5946 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5947 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5948 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5949 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5950 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5951 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5952 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5953 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5954 neon_store_reg(rd
, 0, tmp2
);
5955 tmp2
= tcg_temp_new_i32();
5956 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5957 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5958 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5959 neon_store_reg(rd
, 1, tmp2
);
5960 tcg_temp_free_i32(tmp
);
5962 case NEON_2RM_VCVT_F32_F16
:
5963 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5967 tmp3
= tcg_temp_new_i32();
5968 tmp
= neon_load_reg(rm
, 0);
5969 tmp2
= neon_load_reg(rm
, 1);
5970 tcg_gen_ext16u_i32(tmp3
, tmp
);
5971 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5972 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5973 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5974 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5975 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5976 tcg_temp_free_i32(tmp
);
5977 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5978 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5979 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5980 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5981 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5982 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5983 tcg_temp_free_i32(tmp2
);
5984 tcg_temp_free_i32(tmp3
);
5988 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5989 if (neon_2rm_is_float_op(op
)) {
5990 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5991 neon_reg_offset(rm
, pass
));
5992 TCGV_UNUSED_I32(tmp
);
5994 tmp
= neon_load_reg(rm
, pass
);
5997 case NEON_2RM_VREV32
:
5999 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6000 case 1: gen_swap_half(tmp
); break;
6004 case NEON_2RM_VREV16
:
6009 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6010 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6011 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6017 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6018 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6019 case 2: gen_helper_clz(tmp
, tmp
); break;
6024 gen_helper_neon_cnt_u8(tmp
, tmp
);
6027 tcg_gen_not_i32(tmp
, tmp
);
6029 case NEON_2RM_VQABS
:
6032 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6035 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6038 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6043 case NEON_2RM_VQNEG
:
6046 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6049 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6052 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6057 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6058 tmp2
= tcg_const_i32(0);
6060 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6061 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6062 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6065 tcg_temp_free_i32(tmp2
);
6066 if (op
== NEON_2RM_VCLE0
) {
6067 tcg_gen_not_i32(tmp
, tmp
);
6070 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6071 tmp2
= tcg_const_i32(0);
6073 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6074 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6075 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6078 tcg_temp_free_i32(tmp2
);
6079 if (op
== NEON_2RM_VCLT0
) {
6080 tcg_gen_not_i32(tmp
, tmp
);
6083 case NEON_2RM_VCEQ0
:
6084 tmp2
= tcg_const_i32(0);
6086 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6087 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6088 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6091 tcg_temp_free_i32(tmp2
);
6095 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6096 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6097 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6102 tmp2
= tcg_const_i32(0);
6103 gen_neon_rsb(size
, tmp
, tmp2
);
6104 tcg_temp_free_i32(tmp2
);
6106 case NEON_2RM_VCGT0_F
:
6108 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6109 tmp2
= tcg_const_i32(0);
6110 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6111 tcg_temp_free_i32(tmp2
);
6112 tcg_temp_free_ptr(fpstatus
);
6115 case NEON_2RM_VCGE0_F
:
6117 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6118 tmp2
= tcg_const_i32(0);
6119 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6120 tcg_temp_free_i32(tmp2
);
6121 tcg_temp_free_ptr(fpstatus
);
6124 case NEON_2RM_VCEQ0_F
:
6126 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6127 tmp2
= tcg_const_i32(0);
6128 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6129 tcg_temp_free_i32(tmp2
);
6130 tcg_temp_free_ptr(fpstatus
);
6133 case NEON_2RM_VCLE0_F
:
6135 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6136 tmp2
= tcg_const_i32(0);
6137 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6138 tcg_temp_free_i32(tmp2
);
6139 tcg_temp_free_ptr(fpstatus
);
6142 case NEON_2RM_VCLT0_F
:
6144 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6145 tmp2
= tcg_const_i32(0);
6146 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6147 tcg_temp_free_i32(tmp2
);
6148 tcg_temp_free_ptr(fpstatus
);
6151 case NEON_2RM_VABS_F
:
6154 case NEON_2RM_VNEG_F
:
6158 tmp2
= neon_load_reg(rd
, pass
);
6159 neon_store_reg(rm
, pass
, tmp2
);
6162 tmp2
= neon_load_reg(rd
, pass
);
6164 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6165 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6168 neon_store_reg(rm
, pass
, tmp2
);
6170 case NEON_2RM_VRECPE
:
6171 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6173 case NEON_2RM_VRSQRTE
:
6174 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6176 case NEON_2RM_VRECPE_F
:
6177 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6179 case NEON_2RM_VRSQRTE_F
:
6180 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6182 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6185 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6188 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6189 gen_vfp_tosiz(0, 1);
6191 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6192 gen_vfp_touiz(0, 1);
6195 /* Reserved op values were caught by the
6196 * neon_2rm_sizes[] check earlier.
6200 if (neon_2rm_is_float_op(op
)) {
6201 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6202 neon_reg_offset(rd
, pass
));
6204 neon_store_reg(rd
, pass
, tmp
);
6209 } else if ((insn
& (1 << 10)) == 0) {
6211 int n
= ((insn
>> 8) & 3) + 1;
6212 if ((rn
+ n
) > 32) {
6213 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6214 * helper function running off the end of the register file.
6219 if (insn
& (1 << 6)) {
6220 tmp
= neon_load_reg(rd
, 0);
6222 tmp
= tcg_temp_new_i32();
6223 tcg_gen_movi_i32(tmp
, 0);
6225 tmp2
= neon_load_reg(rm
, 0);
6226 tmp4
= tcg_const_i32(rn
);
6227 tmp5
= tcg_const_i32(n
);
6228 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6229 tcg_temp_free_i32(tmp
);
6230 if (insn
& (1 << 6)) {
6231 tmp
= neon_load_reg(rd
, 1);
6233 tmp
= tcg_temp_new_i32();
6234 tcg_gen_movi_i32(tmp
, 0);
6236 tmp3
= neon_load_reg(rm
, 1);
6237 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6238 tcg_temp_free_i32(tmp5
);
6239 tcg_temp_free_i32(tmp4
);
6240 neon_store_reg(rd
, 0, tmp2
);
6241 neon_store_reg(rd
, 1, tmp3
);
6242 tcg_temp_free_i32(tmp
);
6243 } else if ((insn
& 0x380) == 0) {
6245 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6248 if (insn
& (1 << 19)) {
6249 tmp
= neon_load_reg(rm
, 1);
6251 tmp
= neon_load_reg(rm
, 0);
6253 if (insn
& (1 << 16)) {
6254 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6255 } else if (insn
& (1 << 17)) {
6256 if ((insn
>> 18) & 1)
6257 gen_neon_dup_high16(tmp
);
6259 gen_neon_dup_low16(tmp
);
6261 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6262 tmp2
= tcg_temp_new_i32();
6263 tcg_gen_mov_i32(tmp2
, tmp
);
6264 neon_store_reg(rd
, pass
, tmp2
);
6266 tcg_temp_free_i32(tmp
);
6275 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6277 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6278 const ARMCPRegInfo
*ri
;
6279 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6281 cpnum
= (insn
>> 8) & 0xf;
6282 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6283 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6286 /* First check for coprocessor space used for actual instructions */
6290 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6291 return disas_iwmmxt_insn(env
, s
, insn
);
6292 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6293 return disas_dsp_insn(env
, s
, insn
);
6298 return disas_vfp_insn (env
, s
, insn
);
6303 /* Otherwise treat as a generic register access */
6304 is64
= (insn
& (1 << 25)) == 0;
6305 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6313 opc1
= (insn
>> 4) & 0xf;
6315 rt2
= (insn
>> 16) & 0xf;
6317 crn
= (insn
>> 16) & 0xf;
6318 opc1
= (insn
>> 21) & 7;
6319 opc2
= (insn
>> 5) & 7;
6322 isread
= (insn
>> 20) & 1;
6323 rt
= (insn
>> 12) & 0xf;
6325 ri
= get_arm_cp_reginfo(cpu
,
6326 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6328 /* Check access permissions */
6329 if (!cp_access_ok(env
, ri
, isread
)) {
6333 /* Handle special cases first */
6334 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6341 gen_set_pc_im(s
->pc
);
6342 s
->is_jmp
= DISAS_WFI
;
6348 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6357 if (ri
->type
& ARM_CP_CONST
) {
6358 tmp64
= tcg_const_i64(ri
->resetvalue
);
6359 } else if (ri
->readfn
) {
6361 gen_set_pc_im(s
->pc
);
6362 tmp64
= tcg_temp_new_i64();
6363 tmpptr
= tcg_const_ptr(ri
);
6364 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6365 tcg_temp_free_ptr(tmpptr
);
6367 tmp64
= tcg_temp_new_i64();
6368 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6370 tmp
= tcg_temp_new_i32();
6371 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6372 store_reg(s
, rt
, tmp
);
6373 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6374 tmp
= tcg_temp_new_i32();
6375 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6376 tcg_temp_free_i64(tmp64
);
6377 store_reg(s
, rt2
, tmp
);
6380 if (ri
->type
& ARM_CP_CONST
) {
6381 tmp
= tcg_const_i32(ri
->resetvalue
);
6382 } else if (ri
->readfn
) {
6384 gen_set_pc_im(s
->pc
);
6385 tmp
= tcg_temp_new_i32();
6386 tmpptr
= tcg_const_ptr(ri
);
6387 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6388 tcg_temp_free_ptr(tmpptr
);
6390 tmp
= load_cpu_offset(ri
->fieldoffset
);
6393 /* Destination register of r15 for 32 bit loads sets
6394 * the condition codes from the high 4 bits of the value
6397 tcg_temp_free_i32(tmp
);
6399 store_reg(s
, rt
, tmp
);
6404 if (ri
->type
& ARM_CP_CONST
) {
6405 /* If not forbidden by access permissions, treat as WI */
6410 TCGv_i32 tmplo
, tmphi
;
6411 TCGv_i64 tmp64
= tcg_temp_new_i64();
6412 tmplo
= load_reg(s
, rt
);
6413 tmphi
= load_reg(s
, rt2
);
6414 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6415 tcg_temp_free_i32(tmplo
);
6416 tcg_temp_free_i32(tmphi
);
6418 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6419 gen_set_pc_im(s
->pc
);
6420 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6421 tcg_temp_free_ptr(tmpptr
);
6423 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6425 tcg_temp_free_i64(tmp64
);
6430 gen_set_pc_im(s
->pc
);
6431 tmp
= load_reg(s
, rt
);
6432 tmpptr
= tcg_const_ptr(ri
);
6433 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6434 tcg_temp_free_ptr(tmpptr
);
6435 tcg_temp_free_i32(tmp
);
6437 TCGv_i32 tmp
= load_reg(s
, rt
);
6438 store_cpu_offset(tmp
, ri
->fieldoffset
);
6443 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6444 /* I/O operations must end the TB here (whether read or write) */
6447 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6448 /* We default to ending the TB on a coprocessor register write,
6449 * but allow this to be suppressed by the register definition
6450 * (usually only necessary to work around guest bugs).
6462 /* Store a 64-bit value to a register pair. Clobbers val. */
6463 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6466 tmp
= tcg_temp_new_i32();
6467 tcg_gen_trunc_i64_i32(tmp
, val
);
6468 store_reg(s
, rlow
, tmp
);
6469 tmp
= tcg_temp_new_i32();
6470 tcg_gen_shri_i64(val
, val
, 32);
6471 tcg_gen_trunc_i64_i32(tmp
, val
);
6472 store_reg(s
, rhigh
, tmp
);
6475 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6476 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6481 /* Load value and extend to 64 bits. */
6482 tmp
= tcg_temp_new_i64();
6483 tmp2
= load_reg(s
, rlow
);
6484 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6485 tcg_temp_free_i32(tmp2
);
6486 tcg_gen_add_i64(val
, val
, tmp
);
6487 tcg_temp_free_i64(tmp
);
6490 /* load and add a 64-bit value from a register pair. */
6491 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6497 /* Load 64-bit value rd:rn. */
6498 tmpl
= load_reg(s
, rlow
);
6499 tmph
= load_reg(s
, rhigh
);
6500 tmp
= tcg_temp_new_i64();
6501 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6502 tcg_temp_free_i32(tmpl
);
6503 tcg_temp_free_i32(tmph
);
6504 tcg_gen_add_i64(val
, val
, tmp
);
6505 tcg_temp_free_i64(tmp
);
6508 /* Set N and Z flags from hi|lo. */
6509 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6511 tcg_gen_mov_i32(cpu_NF
, hi
);
6512 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6515 /* Load/Store exclusive instructions are implemented by remembering
6516 the value/address loaded, and seeing if these are the same
6517 when the store is performed. This should be sufficient to implement
6518 the architecturally mandated semantics, and avoids having to monitor
6521 In system emulation mode only one CPU will be running at once, so
6522 this sequence is effectively atomic. In user emulation mode we
6523 throw an exception and handle the atomic operation elsewhere. */
6524 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6525 TCGv_i32 addr
, int size
)
6527 TCGv_i32 tmp
= tcg_temp_new_i32();
6531 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6534 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6538 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6543 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6544 store_reg(s
, rt
, tmp
);
6546 TCGv_i32 tmp2
= tcg_temp_new_i32();
6547 tcg_gen_addi_i32(tmp2
, addr
, 4);
6548 tmp
= tcg_temp_new_i32();
6549 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6550 tcg_temp_free_i32(tmp2
);
6551 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6552 store_reg(s
, rt2
, tmp
);
6554 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6557 static void gen_clrex(DisasContext
*s
)
6559 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6562 #ifdef CONFIG_USER_ONLY
6563 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6564 TCGv_i32 addr
, int size
)
6566 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6567 tcg_gen_movi_i32(cpu_exclusive_info
,
6568 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6569 gen_exception_insn(s
, 4, EXCP_STREX
);
6572 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6573 TCGv_i32 addr
, int size
)
6579 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6585 fail_label
= gen_new_label();
6586 done_label
= gen_new_label();
6587 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6588 tmp
= tcg_temp_new_i32();
6591 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6594 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6598 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6603 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6604 tcg_temp_free_i32(tmp
);
6606 TCGv_i32 tmp2
= tcg_temp_new_i32();
6607 tcg_gen_addi_i32(tmp2
, addr
, 4);
6608 tmp
= tcg_temp_new_i32();
6609 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6610 tcg_temp_free_i32(tmp2
);
6611 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6612 tcg_temp_free_i32(tmp
);
6614 tmp
= load_reg(s
, rt
);
6617 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
6620 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
6624 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6629 tcg_temp_free_i32(tmp
);
6631 tcg_gen_addi_i32(addr
, addr
, 4);
6632 tmp
= load_reg(s
, rt2
);
6633 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6634 tcg_temp_free_i32(tmp
);
6636 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6637 tcg_gen_br(done_label
);
6638 gen_set_label(fail_label
);
6639 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6640 gen_set_label(done_label
);
6641 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6648 * @mode: mode field from insn (which stack to store to)
6649 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6650 * @writeback: true if writeback bit set
6652 * Generate code for the SRS (Store Return State) insn.
6654 static void gen_srs(DisasContext
*s
,
6655 uint32_t mode
, uint32_t amode
, bool writeback
)
6658 TCGv_i32 addr
= tcg_temp_new_i32();
6659 TCGv_i32 tmp
= tcg_const_i32(mode
);
6660 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6661 tcg_temp_free_i32(tmp
);
6678 tcg_gen_addi_i32(addr
, addr
, offset
);
6679 tmp
= load_reg(s
, 14);
6680 gen_aa32_st32(tmp
, addr
, 0);
6681 tcg_temp_free_i32(tmp
);
6682 tmp
= load_cpu_field(spsr
);
6683 tcg_gen_addi_i32(addr
, addr
, 4);
6684 gen_aa32_st32(tmp
, addr
, 0);
6685 tcg_temp_free_i32(tmp
);
6703 tcg_gen_addi_i32(addr
, addr
, offset
);
6704 tmp
= tcg_const_i32(mode
);
6705 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6706 tcg_temp_free_i32(tmp
);
6708 tcg_temp_free_i32(addr
);
6711 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6713 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6720 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6723 /* M variants do not implement ARM mode. */
6728 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6729 * choose to UNDEF. In ARMv5 and above the space is used
6730 * for miscellaneous unconditional instructions.
6734 /* Unconditional instructions. */
6735 if (((insn
>> 25) & 7) == 1) {
6736 /* NEON Data processing. */
6737 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6740 if (disas_neon_data_insn(env
, s
, insn
))
6744 if ((insn
& 0x0f100000) == 0x04000000) {
6745 /* NEON load/store. */
6746 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6749 if (disas_neon_ls_insn(env
, s
, insn
))
6753 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6754 ((insn
& 0x0f30f010) == 0x0710f000)) {
6755 if ((insn
& (1 << 22)) == 0) {
6757 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6761 /* Otherwise PLD; v5TE+ */
6765 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6766 ((insn
& 0x0f70f010) == 0x0650f000)) {
6768 return; /* PLI; V7 */
6770 if (((insn
& 0x0f700000) == 0x04100000) ||
6771 ((insn
& 0x0f700010) == 0x06100000)) {
6772 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6775 return; /* v7MP: Unallocated memory hint: must NOP */
6778 if ((insn
& 0x0ffffdff) == 0x01010000) {
6781 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6782 /* Dynamic endianness switching not implemented. */
6783 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
6787 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6788 switch ((insn
>> 4) & 0xf) {
6797 /* We don't emulate caches so these are a no-op. */
6802 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6808 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
6810 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6816 rn
= (insn
>> 16) & 0xf;
6817 addr
= load_reg(s
, rn
);
6818 i
= (insn
>> 23) & 3;
6820 case 0: offset
= -4; break; /* DA */
6821 case 1: offset
= 0; break; /* IA */
6822 case 2: offset
= -8; break; /* DB */
6823 case 3: offset
= 4; break; /* IB */
6827 tcg_gen_addi_i32(addr
, addr
, offset
);
6828 /* Load PC into tmp and CPSR into tmp2. */
6829 tmp
= tcg_temp_new_i32();
6830 gen_aa32_ld32u(tmp
, addr
, 0);
6831 tcg_gen_addi_i32(addr
, addr
, 4);
6832 tmp2
= tcg_temp_new_i32();
6833 gen_aa32_ld32u(tmp2
, addr
, 0);
6834 if (insn
& (1 << 21)) {
6835 /* Base writeback. */
6837 case 0: offset
= -8; break;
6838 case 1: offset
= 4; break;
6839 case 2: offset
= -4; break;
6840 case 3: offset
= 0; break;
6844 tcg_gen_addi_i32(addr
, addr
, offset
);
6845 store_reg(s
, rn
, addr
);
6847 tcg_temp_free_i32(addr
);
6849 gen_rfe(s
, tmp
, tmp2
);
6851 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6852 /* branch link and change to thumb (blx <offset>) */
6855 val
= (uint32_t)s
->pc
;
6856 tmp
= tcg_temp_new_i32();
6857 tcg_gen_movi_i32(tmp
, val
);
6858 store_reg(s
, 14, tmp
);
6859 /* Sign-extend the 24-bit offset */
6860 offset
= (((int32_t)insn
) << 8) >> 8;
6861 /* offset * 4 + bit24 * 2 + (thumb bit) */
6862 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6863 /* pipeline offset */
6865 /* protected by ARCH(5); above, near the start of uncond block */
6868 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6869 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6870 /* iWMMXt register transfer. */
6871 if (env
->cp15
.c15_cpar
& (1 << 1))
6872 if (!disas_iwmmxt_insn(env
, s
, insn
))
6875 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6876 /* Coprocessor double register transfer. */
6878 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6879 /* Additional coprocessor register transfer. */
6880 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6883 /* cps (privileged) */
6887 if (insn
& (1 << 19)) {
6888 if (insn
& (1 << 8))
6890 if (insn
& (1 << 7))
6892 if (insn
& (1 << 6))
6894 if (insn
& (1 << 18))
6897 if (insn
& (1 << 17)) {
6899 val
|= (insn
& 0x1f);
6902 gen_set_psr_im(s
, mask
, 0, val
);
6909 /* if not always execute, we generate a conditional jump to
6911 s
->condlabel
= gen_new_label();
6912 gen_test_cc(cond
^ 1, s
->condlabel
);
6915 if ((insn
& 0x0f900000) == 0x03000000) {
6916 if ((insn
& (1 << 21)) == 0) {
6918 rd
= (insn
>> 12) & 0xf;
6919 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6920 if ((insn
& (1 << 22)) == 0) {
6922 tmp
= tcg_temp_new_i32();
6923 tcg_gen_movi_i32(tmp
, val
);
6926 tmp
= load_reg(s
, rd
);
6927 tcg_gen_ext16u_i32(tmp
, tmp
);
6928 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6930 store_reg(s
, rd
, tmp
);
6932 if (((insn
>> 12) & 0xf) != 0xf)
6934 if (((insn
>> 16) & 0xf) == 0) {
6935 gen_nop_hint(s
, insn
& 0xff);
6937 /* CPSR = immediate */
6939 shift
= ((insn
>> 8) & 0xf) * 2;
6941 val
= (val
>> shift
) | (val
<< (32 - shift
));
6942 i
= ((insn
& (1 << 22)) != 0);
6943 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6947 } else if ((insn
& 0x0f900000) == 0x01000000
6948 && (insn
& 0x00000090) != 0x00000090) {
6949 /* miscellaneous instructions */
6950 op1
= (insn
>> 21) & 3;
6951 sh
= (insn
>> 4) & 0xf;
6954 case 0x0: /* move program status register */
6957 tmp
= load_reg(s
, rm
);
6958 i
= ((op1
& 2) != 0);
6959 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6963 rd
= (insn
>> 12) & 0xf;
6967 tmp
= load_cpu_field(spsr
);
6969 tmp
= tcg_temp_new_i32();
6970 gen_helper_cpsr_read(tmp
, cpu_env
);
6972 store_reg(s
, rd
, tmp
);
6977 /* branch/exchange thumb (bx). */
6979 tmp
= load_reg(s
, rm
);
6981 } else if (op1
== 3) {
6984 rd
= (insn
>> 12) & 0xf;
6985 tmp
= load_reg(s
, rm
);
6986 gen_helper_clz(tmp
, tmp
);
6987 store_reg(s
, rd
, tmp
);
6995 /* Trivial implementation equivalent to bx. */
6996 tmp
= load_reg(s
, rm
);
7007 /* branch link/exchange thumb (blx) */
7008 tmp
= load_reg(s
, rm
);
7009 tmp2
= tcg_temp_new_i32();
7010 tcg_gen_movi_i32(tmp2
, s
->pc
);
7011 store_reg(s
, 14, tmp2
);
7014 case 0x5: /* saturating add/subtract */
7016 rd
= (insn
>> 12) & 0xf;
7017 rn
= (insn
>> 16) & 0xf;
7018 tmp
= load_reg(s
, rm
);
7019 tmp2
= load_reg(s
, rn
);
7021 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7023 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7025 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7026 tcg_temp_free_i32(tmp2
);
7027 store_reg(s
, rd
, tmp
);
7030 /* SMC instruction (op1 == 3)
7031 and undefined instructions (op1 == 0 || op1 == 2)
7038 gen_exception_insn(s
, 4, EXCP_BKPT
);
7040 case 0x8: /* signed multiply */
7045 rs
= (insn
>> 8) & 0xf;
7046 rn
= (insn
>> 12) & 0xf;
7047 rd
= (insn
>> 16) & 0xf;
7049 /* (32 * 16) >> 16 */
7050 tmp
= load_reg(s
, rm
);
7051 tmp2
= load_reg(s
, rs
);
7053 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7056 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7057 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7058 tmp
= tcg_temp_new_i32();
7059 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7060 tcg_temp_free_i64(tmp64
);
7061 if ((sh
& 2) == 0) {
7062 tmp2
= load_reg(s
, rn
);
7063 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7064 tcg_temp_free_i32(tmp2
);
7066 store_reg(s
, rd
, tmp
);
7069 tmp
= load_reg(s
, rm
);
7070 tmp2
= load_reg(s
, rs
);
7071 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7072 tcg_temp_free_i32(tmp2
);
7074 tmp64
= tcg_temp_new_i64();
7075 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7076 tcg_temp_free_i32(tmp
);
7077 gen_addq(s
, tmp64
, rn
, rd
);
7078 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7079 tcg_temp_free_i64(tmp64
);
7082 tmp2
= load_reg(s
, rn
);
7083 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7084 tcg_temp_free_i32(tmp2
);
7086 store_reg(s
, rd
, tmp
);
7093 } else if (((insn
& 0x0e000000) == 0 &&
7094 (insn
& 0x00000090) != 0x90) ||
7095 ((insn
& 0x0e000000) == (1 << 25))) {
7096 int set_cc
, logic_cc
, shiftop
;
7098 op1
= (insn
>> 21) & 0xf;
7099 set_cc
= (insn
>> 20) & 1;
7100 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7102 /* data processing instruction */
7103 if (insn
& (1 << 25)) {
7104 /* immediate operand */
7106 shift
= ((insn
>> 8) & 0xf) * 2;
7108 val
= (val
>> shift
) | (val
<< (32 - shift
));
7110 tmp2
= tcg_temp_new_i32();
7111 tcg_gen_movi_i32(tmp2
, val
);
7112 if (logic_cc
&& shift
) {
7113 gen_set_CF_bit31(tmp2
);
7118 tmp2
= load_reg(s
, rm
);
7119 shiftop
= (insn
>> 5) & 3;
7120 if (!(insn
& (1 << 4))) {
7121 shift
= (insn
>> 7) & 0x1f;
7122 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7124 rs
= (insn
>> 8) & 0xf;
7125 tmp
= load_reg(s
, rs
);
7126 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7129 if (op1
!= 0x0f && op1
!= 0x0d) {
7130 rn
= (insn
>> 16) & 0xf;
7131 tmp
= load_reg(s
, rn
);
7133 TCGV_UNUSED_I32(tmp
);
7135 rd
= (insn
>> 12) & 0xf;
7138 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7142 store_reg_bx(env
, s
, rd
, tmp
);
7145 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7149 store_reg_bx(env
, s
, rd
, tmp
);
7152 if (set_cc
&& rd
== 15) {
7153 /* SUBS r15, ... is used for exception return. */
7157 gen_sub_CC(tmp
, tmp
, tmp2
);
7158 gen_exception_return(s
, tmp
);
7161 gen_sub_CC(tmp
, tmp
, tmp2
);
7163 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7165 store_reg_bx(env
, s
, rd
, tmp
);
7170 gen_sub_CC(tmp
, tmp2
, tmp
);
7172 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7174 store_reg_bx(env
, s
, rd
, tmp
);
7178 gen_add_CC(tmp
, tmp
, tmp2
);
7180 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7182 store_reg_bx(env
, s
, rd
, tmp
);
7186 gen_adc_CC(tmp
, tmp
, tmp2
);
7188 gen_add_carry(tmp
, tmp
, tmp2
);
7190 store_reg_bx(env
, s
, rd
, tmp
);
7194 gen_sbc_CC(tmp
, tmp
, tmp2
);
7196 gen_sub_carry(tmp
, tmp
, tmp2
);
7198 store_reg_bx(env
, s
, rd
, tmp
);
7202 gen_sbc_CC(tmp
, tmp2
, tmp
);
7204 gen_sub_carry(tmp
, tmp2
, tmp
);
7206 store_reg_bx(env
, s
, rd
, tmp
);
7210 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7213 tcg_temp_free_i32(tmp
);
7217 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7220 tcg_temp_free_i32(tmp
);
7224 gen_sub_CC(tmp
, tmp
, tmp2
);
7226 tcg_temp_free_i32(tmp
);
7230 gen_add_CC(tmp
, tmp
, tmp2
);
7232 tcg_temp_free_i32(tmp
);
7235 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7239 store_reg_bx(env
, s
, rd
, tmp
);
7242 if (logic_cc
&& rd
== 15) {
7243 /* MOVS r15, ... is used for exception return. */
7247 gen_exception_return(s
, tmp2
);
7252 store_reg_bx(env
, s
, rd
, tmp2
);
7256 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7260 store_reg_bx(env
, s
, rd
, tmp
);
7264 tcg_gen_not_i32(tmp2
, tmp2
);
7268 store_reg_bx(env
, s
, rd
, tmp2
);
7271 if (op1
!= 0x0f && op1
!= 0x0d) {
7272 tcg_temp_free_i32(tmp2
);
7275 /* other instructions */
7276 op1
= (insn
>> 24) & 0xf;
7280 /* multiplies, extra load/stores */
7281 sh
= (insn
>> 5) & 3;
7284 rd
= (insn
>> 16) & 0xf;
7285 rn
= (insn
>> 12) & 0xf;
7286 rs
= (insn
>> 8) & 0xf;
7288 op1
= (insn
>> 20) & 0xf;
7290 case 0: case 1: case 2: case 3: case 6:
7292 tmp
= load_reg(s
, rs
);
7293 tmp2
= load_reg(s
, rm
);
7294 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7295 tcg_temp_free_i32(tmp2
);
7296 if (insn
& (1 << 22)) {
7297 /* Subtract (mls) */
7299 tmp2
= load_reg(s
, rn
);
7300 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7301 tcg_temp_free_i32(tmp2
);
7302 } else if (insn
& (1 << 21)) {
7304 tmp2
= load_reg(s
, rn
);
7305 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7306 tcg_temp_free_i32(tmp2
);
7308 if (insn
& (1 << 20))
7310 store_reg(s
, rd
, tmp
);
7313 /* 64 bit mul double accumulate (UMAAL) */
7315 tmp
= load_reg(s
, rs
);
7316 tmp2
= load_reg(s
, rm
);
7317 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7318 gen_addq_lo(s
, tmp64
, rn
);
7319 gen_addq_lo(s
, tmp64
, rd
);
7320 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7321 tcg_temp_free_i64(tmp64
);
7323 case 8: case 9: case 10: case 11:
7324 case 12: case 13: case 14: case 15:
7325 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7326 tmp
= load_reg(s
, rs
);
7327 tmp2
= load_reg(s
, rm
);
7328 if (insn
& (1 << 22)) {
7329 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7331 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7333 if (insn
& (1 << 21)) { /* mult accumulate */
7334 TCGv_i32 al
= load_reg(s
, rn
);
7335 TCGv_i32 ah
= load_reg(s
, rd
);
7336 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7337 tcg_temp_free_i32(al
);
7338 tcg_temp_free_i32(ah
);
7340 if (insn
& (1 << 20)) {
7341 gen_logicq_cc(tmp
, tmp2
);
7343 store_reg(s
, rn
, tmp
);
7344 store_reg(s
, rd
, tmp2
);
7350 rn
= (insn
>> 16) & 0xf;
7351 rd
= (insn
>> 12) & 0xf;
7352 if (insn
& (1 << 23)) {
7353 /* load/store exclusive */
7354 int op2
= (insn
>> 8) & 3;
7355 op1
= (insn
>> 21) & 0x3;
7358 case 0: /* lda/stl */
7364 case 1: /* reserved */
7366 case 2: /* ldaex/stlex */
7369 case 3: /* ldrex/strex */
7378 addr
= tcg_temp_local_new_i32();
7379 load_reg_var(s
, addr
, rn
);
7381 /* Since the emulation does not have barriers,
7382 the acquire/release semantics need no special
7385 if (insn
& (1 << 20)) {
7386 tmp
= tcg_temp_new_i32();
7389 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7392 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7395 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7400 store_reg(s
, rd
, tmp
);
7403 tmp
= load_reg(s
, rm
);
7406 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7409 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7412 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7417 tcg_temp_free_i32(tmp
);
7419 } else if (insn
& (1 << 20)) {
7422 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7424 case 1: /* ldrexd */
7425 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7427 case 2: /* ldrexb */
7428 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7430 case 3: /* ldrexh */
7431 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7440 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7442 case 1: /* strexd */
7443 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7445 case 2: /* strexb */
7446 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7448 case 3: /* strexh */
7449 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7455 tcg_temp_free_i32(addr
);
7457 /* SWP instruction */
7460 /* ??? This is not really atomic. However we know
7461 we never have multiple CPUs running in parallel,
7462 so it is good enough. */
7463 addr
= load_reg(s
, rn
);
7464 tmp
= load_reg(s
, rm
);
7465 tmp2
= tcg_temp_new_i32();
7466 if (insn
& (1 << 22)) {
7467 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7468 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7470 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7471 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7473 tcg_temp_free_i32(tmp
);
7474 tcg_temp_free_i32(addr
);
7475 store_reg(s
, rd
, tmp2
);
7481 /* Misc load/store */
7482 rn
= (insn
>> 16) & 0xf;
7483 rd
= (insn
>> 12) & 0xf;
7484 addr
= load_reg(s
, rn
);
7485 if (insn
& (1 << 24))
7486 gen_add_datah_offset(s
, insn
, 0, addr
);
7488 if (insn
& (1 << 20)) {
7490 tmp
= tcg_temp_new_i32();
7493 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7496 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7500 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7504 } else if (sh
& 2) {
7509 tmp
= load_reg(s
, rd
);
7510 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7511 tcg_temp_free_i32(tmp
);
7512 tcg_gen_addi_i32(addr
, addr
, 4);
7513 tmp
= load_reg(s
, rd
+ 1);
7514 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7515 tcg_temp_free_i32(tmp
);
7519 tmp
= tcg_temp_new_i32();
7520 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7521 store_reg(s
, rd
, tmp
);
7522 tcg_gen_addi_i32(addr
, addr
, 4);
7523 tmp
= tcg_temp_new_i32();
7524 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7528 address_offset
= -4;
7531 tmp
= load_reg(s
, rd
);
7532 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7533 tcg_temp_free_i32(tmp
);
7536 /* Perform base writeback before the loaded value to
7537 ensure correct behavior with overlapping index registers.
7538 ldrd with base writeback is is undefined if the
7539 destination and index registers overlap. */
7540 if (!(insn
& (1 << 24))) {
7541 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7542 store_reg(s
, rn
, addr
);
7543 } else if (insn
& (1 << 21)) {
7545 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7546 store_reg(s
, rn
, addr
);
7548 tcg_temp_free_i32(addr
);
7551 /* Complete the load. */
7552 store_reg(s
, rd
, tmp
);
7561 if (insn
& (1 << 4)) {
7563 /* Armv6 Media instructions. */
7565 rn
= (insn
>> 16) & 0xf;
7566 rd
= (insn
>> 12) & 0xf;
7567 rs
= (insn
>> 8) & 0xf;
7568 switch ((insn
>> 23) & 3) {
7569 case 0: /* Parallel add/subtract. */
7570 op1
= (insn
>> 20) & 7;
7571 tmp
= load_reg(s
, rn
);
7572 tmp2
= load_reg(s
, rm
);
7573 sh
= (insn
>> 5) & 7;
7574 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7576 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7577 tcg_temp_free_i32(tmp2
);
7578 store_reg(s
, rd
, tmp
);
7581 if ((insn
& 0x00700020) == 0) {
7582 /* Halfword pack. */
7583 tmp
= load_reg(s
, rn
);
7584 tmp2
= load_reg(s
, rm
);
7585 shift
= (insn
>> 7) & 0x1f;
7586 if (insn
& (1 << 6)) {
7590 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7591 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7592 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7596 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7597 tcg_gen_ext16u_i32(tmp
, tmp
);
7598 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7600 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7601 tcg_temp_free_i32(tmp2
);
7602 store_reg(s
, rd
, tmp
);
7603 } else if ((insn
& 0x00200020) == 0x00200000) {
7605 tmp
= load_reg(s
, rm
);
7606 shift
= (insn
>> 7) & 0x1f;
7607 if (insn
& (1 << 6)) {
7610 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7612 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7614 sh
= (insn
>> 16) & 0x1f;
7615 tmp2
= tcg_const_i32(sh
);
7616 if (insn
& (1 << 22))
7617 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7619 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7620 tcg_temp_free_i32(tmp2
);
7621 store_reg(s
, rd
, tmp
);
7622 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7624 tmp
= load_reg(s
, rm
);
7625 sh
= (insn
>> 16) & 0x1f;
7626 tmp2
= tcg_const_i32(sh
);
7627 if (insn
& (1 << 22))
7628 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7630 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7631 tcg_temp_free_i32(tmp2
);
7632 store_reg(s
, rd
, tmp
);
7633 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7635 tmp
= load_reg(s
, rn
);
7636 tmp2
= load_reg(s
, rm
);
7637 tmp3
= tcg_temp_new_i32();
7638 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7639 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7640 tcg_temp_free_i32(tmp3
);
7641 tcg_temp_free_i32(tmp2
);
7642 store_reg(s
, rd
, tmp
);
7643 } else if ((insn
& 0x000003e0) == 0x00000060) {
7644 tmp
= load_reg(s
, rm
);
7645 shift
= (insn
>> 10) & 3;
7646 /* ??? In many cases it's not necessary to do a
7647 rotate, a shift is sufficient. */
7649 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7650 op1
= (insn
>> 20) & 7;
7652 case 0: gen_sxtb16(tmp
); break;
7653 case 2: gen_sxtb(tmp
); break;
7654 case 3: gen_sxth(tmp
); break;
7655 case 4: gen_uxtb16(tmp
); break;
7656 case 6: gen_uxtb(tmp
); break;
7657 case 7: gen_uxth(tmp
); break;
7658 default: goto illegal_op
;
7661 tmp2
= load_reg(s
, rn
);
7662 if ((op1
& 3) == 0) {
7663 gen_add16(tmp
, tmp2
);
7665 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7666 tcg_temp_free_i32(tmp2
);
7669 store_reg(s
, rd
, tmp
);
7670 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7672 tmp
= load_reg(s
, rm
);
7673 if (insn
& (1 << 22)) {
7674 if (insn
& (1 << 7)) {
7678 gen_helper_rbit(tmp
, tmp
);
7681 if (insn
& (1 << 7))
7684 tcg_gen_bswap32_i32(tmp
, tmp
);
7686 store_reg(s
, rd
, tmp
);
7691 case 2: /* Multiplies (Type 3). */
7692 switch ((insn
>> 20) & 0x7) {
7694 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7695 /* op2 not 00x or 11x : UNDEF */
7698 /* Signed multiply most significant [accumulate].
7699 (SMMUL, SMMLA, SMMLS) */
7700 tmp
= load_reg(s
, rm
);
7701 tmp2
= load_reg(s
, rs
);
7702 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7705 tmp
= load_reg(s
, rd
);
7706 if (insn
& (1 << 6)) {
7707 tmp64
= gen_subq_msw(tmp64
, tmp
);
7709 tmp64
= gen_addq_msw(tmp64
, tmp
);
7712 if (insn
& (1 << 5)) {
7713 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7715 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7716 tmp
= tcg_temp_new_i32();
7717 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7718 tcg_temp_free_i64(tmp64
);
7719 store_reg(s
, rn
, tmp
);
7723 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7724 if (insn
& (1 << 7)) {
7727 tmp
= load_reg(s
, rm
);
7728 tmp2
= load_reg(s
, rs
);
7729 if (insn
& (1 << 5))
7730 gen_swap_half(tmp2
);
7731 gen_smul_dual(tmp
, tmp2
);
7732 if (insn
& (1 << 6)) {
7733 /* This subtraction cannot overflow. */
7734 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7736 /* This addition cannot overflow 32 bits;
7737 * however it may overflow considered as a signed
7738 * operation, in which case we must set the Q flag.
7740 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7742 tcg_temp_free_i32(tmp2
);
7743 if (insn
& (1 << 22)) {
7744 /* smlald, smlsld */
7745 tmp64
= tcg_temp_new_i64();
7746 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7747 tcg_temp_free_i32(tmp
);
7748 gen_addq(s
, tmp64
, rd
, rn
);
7749 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7750 tcg_temp_free_i64(tmp64
);
7752 /* smuad, smusd, smlad, smlsd */
7755 tmp2
= load_reg(s
, rd
);
7756 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7757 tcg_temp_free_i32(tmp2
);
7759 store_reg(s
, rn
, tmp
);
7765 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7768 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7771 tmp
= load_reg(s
, rm
);
7772 tmp2
= load_reg(s
, rs
);
7773 if (insn
& (1 << 21)) {
7774 gen_helper_udiv(tmp
, tmp
, tmp2
);
7776 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7778 tcg_temp_free_i32(tmp2
);
7779 store_reg(s
, rn
, tmp
);
7786 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7788 case 0: /* Unsigned sum of absolute differences. */
7790 tmp
= load_reg(s
, rm
);
7791 tmp2
= load_reg(s
, rs
);
7792 gen_helper_usad8(tmp
, tmp
, tmp2
);
7793 tcg_temp_free_i32(tmp2
);
7795 tmp2
= load_reg(s
, rd
);
7796 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7797 tcg_temp_free_i32(tmp2
);
7799 store_reg(s
, rn
, tmp
);
7801 case 0x20: case 0x24: case 0x28: case 0x2c:
7802 /* Bitfield insert/clear. */
7804 shift
= (insn
>> 7) & 0x1f;
7805 i
= (insn
>> 16) & 0x1f;
7808 tmp
= tcg_temp_new_i32();
7809 tcg_gen_movi_i32(tmp
, 0);
7811 tmp
= load_reg(s
, rm
);
7814 tmp2
= load_reg(s
, rd
);
7815 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7816 tcg_temp_free_i32(tmp2
);
7818 store_reg(s
, rd
, tmp
);
7820 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7821 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7823 tmp
= load_reg(s
, rm
);
7824 shift
= (insn
>> 7) & 0x1f;
7825 i
= ((insn
>> 16) & 0x1f) + 1;
7830 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7832 gen_sbfx(tmp
, shift
, i
);
7835 store_reg(s
, rd
, tmp
);
7845 /* Check for undefined extension instructions
7846 * per the ARM Bible IE:
7847 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7849 sh
= (0xf << 20) | (0xf << 4);
7850 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7854 /* load/store byte/word */
7855 rn
= (insn
>> 16) & 0xf;
7856 rd
= (insn
>> 12) & 0xf;
7857 tmp2
= load_reg(s
, rn
);
7858 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7859 if (insn
& (1 << 24))
7860 gen_add_data_offset(s
, insn
, tmp2
);
7861 if (insn
& (1 << 20)) {
7863 tmp
= tcg_temp_new_i32();
7864 if (insn
& (1 << 22)) {
7865 gen_aa32_ld8u(tmp
, tmp2
, i
);
7867 gen_aa32_ld32u(tmp
, tmp2
, i
);
7871 tmp
= load_reg(s
, rd
);
7872 if (insn
& (1 << 22)) {
7873 gen_aa32_st8(tmp
, tmp2
, i
);
7875 gen_aa32_st32(tmp
, tmp2
, i
);
7877 tcg_temp_free_i32(tmp
);
7879 if (!(insn
& (1 << 24))) {
7880 gen_add_data_offset(s
, insn
, tmp2
);
7881 store_reg(s
, rn
, tmp2
);
7882 } else if (insn
& (1 << 21)) {
7883 store_reg(s
, rn
, tmp2
);
7885 tcg_temp_free_i32(tmp2
);
7887 if (insn
& (1 << 20)) {
7888 /* Complete the load. */
7889 store_reg_from_load(env
, s
, rd
, tmp
);
7895 int j
, n
, user
, loaded_base
;
7896 TCGv_i32 loaded_var
;
7897 /* load/store multiple words */
7898 /* XXX: store correct base if write back */
7900 if (insn
& (1 << 22)) {
7902 goto illegal_op
; /* only usable in supervisor mode */
7904 if ((insn
& (1 << 15)) == 0)
7907 rn
= (insn
>> 16) & 0xf;
7908 addr
= load_reg(s
, rn
);
7910 /* compute total size */
7912 TCGV_UNUSED_I32(loaded_var
);
7915 if (insn
& (1 << i
))
7918 /* XXX: test invalid n == 0 case ? */
7919 if (insn
& (1 << 23)) {
7920 if (insn
& (1 << 24)) {
7922 tcg_gen_addi_i32(addr
, addr
, 4);
7924 /* post increment */
7927 if (insn
& (1 << 24)) {
7929 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7931 /* post decrement */
7933 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7938 if (insn
& (1 << i
)) {
7939 if (insn
& (1 << 20)) {
7941 tmp
= tcg_temp_new_i32();
7942 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7944 tmp2
= tcg_const_i32(i
);
7945 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7946 tcg_temp_free_i32(tmp2
);
7947 tcg_temp_free_i32(tmp
);
7948 } else if (i
== rn
) {
7952 store_reg_from_load(env
, s
, i
, tmp
);
7957 /* special case: r15 = PC + 8 */
7958 val
= (long)s
->pc
+ 4;
7959 tmp
= tcg_temp_new_i32();
7960 tcg_gen_movi_i32(tmp
, val
);
7962 tmp
= tcg_temp_new_i32();
7963 tmp2
= tcg_const_i32(i
);
7964 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7965 tcg_temp_free_i32(tmp2
);
7967 tmp
= load_reg(s
, i
);
7969 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7970 tcg_temp_free_i32(tmp
);
7973 /* no need to add after the last transfer */
7975 tcg_gen_addi_i32(addr
, addr
, 4);
7978 if (insn
& (1 << 21)) {
7980 if (insn
& (1 << 23)) {
7981 if (insn
& (1 << 24)) {
7984 /* post increment */
7985 tcg_gen_addi_i32(addr
, addr
, 4);
7988 if (insn
& (1 << 24)) {
7991 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7993 /* post decrement */
7994 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7997 store_reg(s
, rn
, addr
);
7999 tcg_temp_free_i32(addr
);
8002 store_reg(s
, rn
, loaded_var
);
8004 if ((insn
& (1 << 22)) && !user
) {
8005 /* Restore CPSR from SPSR. */
8006 tmp
= load_cpu_field(spsr
);
8007 gen_set_cpsr(tmp
, 0xffffffff);
8008 tcg_temp_free_i32(tmp
);
8009 s
->is_jmp
= DISAS_UPDATE
;
8018 /* branch (and link) */
8019 val
= (int32_t)s
->pc
;
8020 if (insn
& (1 << 24)) {
8021 tmp
= tcg_temp_new_i32();
8022 tcg_gen_movi_i32(tmp
, val
);
8023 store_reg(s
, 14, tmp
);
8025 offset
= sextract32(insn
<< 2, 0, 26);
8034 if (disas_coproc_insn(env
, s
, insn
))
8039 gen_set_pc_im(s
->pc
);
8040 s
->is_jmp
= DISAS_SWI
;
8044 gen_exception_insn(s
, 4, EXCP_UDEF
);
8050 /* Return true if this is a Thumb-2 logical op. */
8052 thumb2_logic_op(int op
)
8057 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8058 then set condition code flags based on the result of the operation.
8059 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8060 to the high bit of T1.
8061 Returns zero if the opcode is valid. */
8064 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8065 TCGv_i32 t0
, TCGv_i32 t1
)
8072 tcg_gen_and_i32(t0
, t0
, t1
);
8076 tcg_gen_andc_i32(t0
, t0
, t1
);
8080 tcg_gen_or_i32(t0
, t0
, t1
);
8084 tcg_gen_orc_i32(t0
, t0
, t1
);
8088 tcg_gen_xor_i32(t0
, t0
, t1
);
8093 gen_add_CC(t0
, t0
, t1
);
8095 tcg_gen_add_i32(t0
, t0
, t1
);
8099 gen_adc_CC(t0
, t0
, t1
);
8105 gen_sbc_CC(t0
, t0
, t1
);
8107 gen_sub_carry(t0
, t0
, t1
);
8112 gen_sub_CC(t0
, t0
, t1
);
8114 tcg_gen_sub_i32(t0
, t0
, t1
);
8118 gen_sub_CC(t0
, t1
, t0
);
8120 tcg_gen_sub_i32(t0
, t1
, t0
);
8122 default: /* 5, 6, 7, 9, 12, 15. */
8128 gen_set_CF_bit31(t1
);
8133 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8135 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8137 uint32_t insn
, imm
, shift
, offset
;
8138 uint32_t rd
, rn
, rm
, rs
;
8149 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8150 || arm_feature (env
, ARM_FEATURE_M
))) {
8151 /* Thumb-1 cores may need to treat bl and blx as a pair of
8152 16-bit instructions to get correct prefetch abort behavior. */
8154 if ((insn
& (1 << 12)) == 0) {
8156 /* Second half of blx. */
8157 offset
= ((insn
& 0x7ff) << 1);
8158 tmp
= load_reg(s
, 14);
8159 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8160 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8162 tmp2
= tcg_temp_new_i32();
8163 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8164 store_reg(s
, 14, tmp2
);
8168 if (insn
& (1 << 11)) {
8169 /* Second half of bl. */
8170 offset
= ((insn
& 0x7ff) << 1) | 1;
8171 tmp
= load_reg(s
, 14);
8172 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8174 tmp2
= tcg_temp_new_i32();
8175 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8176 store_reg(s
, 14, tmp2
);
8180 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8181 /* Instruction spans a page boundary. Implement it as two
8182 16-bit instructions in case the second half causes an
8184 offset
= ((int32_t)insn
<< 21) >> 9;
8185 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8188 /* Fall through to 32-bit decode. */
8191 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8193 insn
|= (uint32_t)insn_hw1
<< 16;
8195 if ((insn
& 0xf800e800) != 0xf000e800) {
8199 rn
= (insn
>> 16) & 0xf;
8200 rs
= (insn
>> 12) & 0xf;
8201 rd
= (insn
>> 8) & 0xf;
8203 switch ((insn
>> 25) & 0xf) {
8204 case 0: case 1: case 2: case 3:
8205 /* 16-bit instructions. Should never happen. */
8208 if (insn
& (1 << 22)) {
8209 /* Other load/store, table branch. */
8210 if (insn
& 0x01200000) {
8211 /* Load/store doubleword. */
8213 addr
= tcg_temp_new_i32();
8214 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8216 addr
= load_reg(s
, rn
);
8218 offset
= (insn
& 0xff) * 4;
8219 if ((insn
& (1 << 23)) == 0)
8221 if (insn
& (1 << 24)) {
8222 tcg_gen_addi_i32(addr
, addr
, offset
);
8225 if (insn
& (1 << 20)) {
8227 tmp
= tcg_temp_new_i32();
8228 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8229 store_reg(s
, rs
, tmp
);
8230 tcg_gen_addi_i32(addr
, addr
, 4);
8231 tmp
= tcg_temp_new_i32();
8232 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8233 store_reg(s
, rd
, tmp
);
8236 tmp
= load_reg(s
, rs
);
8237 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8238 tcg_temp_free_i32(tmp
);
8239 tcg_gen_addi_i32(addr
, addr
, 4);
8240 tmp
= load_reg(s
, rd
);
8241 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8242 tcg_temp_free_i32(tmp
);
8244 if (insn
& (1 << 21)) {
8245 /* Base writeback. */
8248 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8249 store_reg(s
, rn
, addr
);
8251 tcg_temp_free_i32(addr
);
8253 } else if ((insn
& (1 << 23)) == 0) {
8254 /* Load/store exclusive word. */
8255 addr
= tcg_temp_local_new_i32();
8256 load_reg_var(s
, addr
, rn
);
8257 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8258 if (insn
& (1 << 20)) {
8259 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8261 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8263 tcg_temp_free_i32(addr
);
8264 } else if ((insn
& (7 << 5)) == 0) {
8267 addr
= tcg_temp_new_i32();
8268 tcg_gen_movi_i32(addr
, s
->pc
);
8270 addr
= load_reg(s
, rn
);
8272 tmp
= load_reg(s
, rm
);
8273 tcg_gen_add_i32(addr
, addr
, tmp
);
8274 if (insn
& (1 << 4)) {
8276 tcg_gen_add_i32(addr
, addr
, tmp
);
8277 tcg_temp_free_i32(tmp
);
8278 tmp
= tcg_temp_new_i32();
8279 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8281 tcg_temp_free_i32(tmp
);
8282 tmp
= tcg_temp_new_i32();
8283 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8285 tcg_temp_free_i32(addr
);
8286 tcg_gen_shli_i32(tmp
, tmp
, 1);
8287 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8288 store_reg(s
, 15, tmp
);
8290 int op2
= (insn
>> 6) & 0x3;
8291 op
= (insn
>> 4) & 0x3;
8296 /* Load/store exclusive byte/halfword/doubleword */
8303 /* Load-acquire/store-release */
8309 /* Load-acquire/store-release exclusive */
8313 addr
= tcg_temp_local_new_i32();
8314 load_reg_var(s
, addr
, rn
);
8316 if (insn
& (1 << 20)) {
8317 tmp
= tcg_temp_new_i32();
8320 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8323 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8326 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8331 store_reg(s
, rs
, tmp
);
8333 tmp
= load_reg(s
, rs
);
8336 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8339 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8342 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8347 tcg_temp_free_i32(tmp
);
8349 } else if (insn
& (1 << 20)) {
8350 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8352 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8354 tcg_temp_free_i32(addr
);
8357 /* Load/store multiple, RFE, SRS. */
8358 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8359 /* RFE, SRS: not available in user mode or on M profile */
8360 if (IS_USER(s
) || IS_M(env
)) {
8363 if (insn
& (1 << 20)) {
8365 addr
= load_reg(s
, rn
);
8366 if ((insn
& (1 << 24)) == 0)
8367 tcg_gen_addi_i32(addr
, addr
, -8);
8368 /* Load PC into tmp and CPSR into tmp2. */
8369 tmp
= tcg_temp_new_i32();
8370 gen_aa32_ld32u(tmp
, addr
, 0);
8371 tcg_gen_addi_i32(addr
, addr
, 4);
8372 tmp2
= tcg_temp_new_i32();
8373 gen_aa32_ld32u(tmp2
, addr
, 0);
8374 if (insn
& (1 << 21)) {
8375 /* Base writeback. */
8376 if (insn
& (1 << 24)) {
8377 tcg_gen_addi_i32(addr
, addr
, 4);
8379 tcg_gen_addi_i32(addr
, addr
, -4);
8381 store_reg(s
, rn
, addr
);
8383 tcg_temp_free_i32(addr
);
8385 gen_rfe(s
, tmp
, tmp2
);
8388 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8392 int i
, loaded_base
= 0;
8393 TCGv_i32 loaded_var
;
8394 /* Load/store multiple. */
8395 addr
= load_reg(s
, rn
);
8397 for (i
= 0; i
< 16; i
++) {
8398 if (insn
& (1 << i
))
8401 if (insn
& (1 << 24)) {
8402 tcg_gen_addi_i32(addr
, addr
, -offset
);
8405 TCGV_UNUSED_I32(loaded_var
);
8406 for (i
= 0; i
< 16; i
++) {
8407 if ((insn
& (1 << i
)) == 0)
8409 if (insn
& (1 << 20)) {
8411 tmp
= tcg_temp_new_i32();
8412 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8415 } else if (i
== rn
) {
8419 store_reg(s
, i
, tmp
);
8423 tmp
= load_reg(s
, i
);
8424 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8425 tcg_temp_free_i32(tmp
);
8427 tcg_gen_addi_i32(addr
, addr
, 4);
8430 store_reg(s
, rn
, loaded_var
);
8432 if (insn
& (1 << 21)) {
8433 /* Base register writeback. */
8434 if (insn
& (1 << 24)) {
8435 tcg_gen_addi_i32(addr
, addr
, -offset
);
8437 /* Fault if writeback register is in register list. */
8438 if (insn
& (1 << rn
))
8440 store_reg(s
, rn
, addr
);
8442 tcg_temp_free_i32(addr
);
8449 op
= (insn
>> 21) & 0xf;
8451 /* Halfword pack. */
8452 tmp
= load_reg(s
, rn
);
8453 tmp2
= load_reg(s
, rm
);
8454 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8455 if (insn
& (1 << 5)) {
8459 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8460 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8461 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8465 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8466 tcg_gen_ext16u_i32(tmp
, tmp
);
8467 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8469 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8470 tcg_temp_free_i32(tmp2
);
8471 store_reg(s
, rd
, tmp
);
8473 /* Data processing register constant shift. */
8475 tmp
= tcg_temp_new_i32();
8476 tcg_gen_movi_i32(tmp
, 0);
8478 tmp
= load_reg(s
, rn
);
8480 tmp2
= load_reg(s
, rm
);
8482 shiftop
= (insn
>> 4) & 3;
8483 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8484 conds
= (insn
& (1 << 20)) != 0;
8485 logic_cc
= (conds
&& thumb2_logic_op(op
));
8486 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8487 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8489 tcg_temp_free_i32(tmp2
);
8491 store_reg(s
, rd
, tmp
);
8493 tcg_temp_free_i32(tmp
);
8497 case 13: /* Misc data processing. */
8498 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8499 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8502 case 0: /* Register controlled shift. */
8503 tmp
= load_reg(s
, rn
);
8504 tmp2
= load_reg(s
, rm
);
8505 if ((insn
& 0x70) != 0)
8507 op
= (insn
>> 21) & 3;
8508 logic_cc
= (insn
& (1 << 20)) != 0;
8509 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8512 store_reg_bx(env
, s
, rd
, tmp
);
8514 case 1: /* Sign/zero extend. */
8515 tmp
= load_reg(s
, rm
);
8516 shift
= (insn
>> 4) & 3;
8517 /* ??? In many cases it's not necessary to do a
8518 rotate, a shift is sufficient. */
8520 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8521 op
= (insn
>> 20) & 7;
8523 case 0: gen_sxth(tmp
); break;
8524 case 1: gen_uxth(tmp
); break;
8525 case 2: gen_sxtb16(tmp
); break;
8526 case 3: gen_uxtb16(tmp
); break;
8527 case 4: gen_sxtb(tmp
); break;
8528 case 5: gen_uxtb(tmp
); break;
8529 default: goto illegal_op
;
8532 tmp2
= load_reg(s
, rn
);
8533 if ((op
>> 1) == 1) {
8534 gen_add16(tmp
, tmp2
);
8536 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8537 tcg_temp_free_i32(tmp2
);
8540 store_reg(s
, rd
, tmp
);
8542 case 2: /* SIMD add/subtract. */
8543 op
= (insn
>> 20) & 7;
8544 shift
= (insn
>> 4) & 7;
8545 if ((op
& 3) == 3 || (shift
& 3) == 3)
8547 tmp
= load_reg(s
, rn
);
8548 tmp2
= load_reg(s
, rm
);
8549 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8550 tcg_temp_free_i32(tmp2
);
8551 store_reg(s
, rd
, tmp
);
8553 case 3: /* Other data processing. */
8554 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8556 /* Saturating add/subtract. */
8557 tmp
= load_reg(s
, rn
);
8558 tmp2
= load_reg(s
, rm
);
8560 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8562 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8564 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8565 tcg_temp_free_i32(tmp2
);
8567 tmp
= load_reg(s
, rn
);
8569 case 0x0a: /* rbit */
8570 gen_helper_rbit(tmp
, tmp
);
8572 case 0x08: /* rev */
8573 tcg_gen_bswap32_i32(tmp
, tmp
);
8575 case 0x09: /* rev16 */
8578 case 0x0b: /* revsh */
8581 case 0x10: /* sel */
8582 tmp2
= load_reg(s
, rm
);
8583 tmp3
= tcg_temp_new_i32();
8584 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8585 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8586 tcg_temp_free_i32(tmp3
);
8587 tcg_temp_free_i32(tmp2
);
8589 case 0x18: /* clz */
8590 gen_helper_clz(tmp
, tmp
);
8596 store_reg(s
, rd
, tmp
);
8598 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8599 op
= (insn
>> 4) & 0xf;
8600 tmp
= load_reg(s
, rn
);
8601 tmp2
= load_reg(s
, rm
);
8602 switch ((insn
>> 20) & 7) {
8603 case 0: /* 32 x 32 -> 32 */
8604 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8605 tcg_temp_free_i32(tmp2
);
8607 tmp2
= load_reg(s
, rs
);
8609 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8611 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8612 tcg_temp_free_i32(tmp2
);
8615 case 1: /* 16 x 16 -> 32 */
8616 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8617 tcg_temp_free_i32(tmp2
);
8619 tmp2
= load_reg(s
, rs
);
8620 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8621 tcg_temp_free_i32(tmp2
);
8624 case 2: /* Dual multiply add. */
8625 case 4: /* Dual multiply subtract. */
8627 gen_swap_half(tmp2
);
8628 gen_smul_dual(tmp
, tmp2
);
8629 if (insn
& (1 << 22)) {
8630 /* This subtraction cannot overflow. */
8631 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8633 /* This addition cannot overflow 32 bits;
8634 * however it may overflow considered as a signed
8635 * operation, in which case we must set the Q flag.
8637 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8639 tcg_temp_free_i32(tmp2
);
8642 tmp2
= load_reg(s
, rs
);
8643 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8644 tcg_temp_free_i32(tmp2
);
8647 case 3: /* 32 * 16 -> 32msb */
8649 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8652 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8653 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8654 tmp
= tcg_temp_new_i32();
8655 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8656 tcg_temp_free_i64(tmp64
);
8659 tmp2
= load_reg(s
, rs
);
8660 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8661 tcg_temp_free_i32(tmp2
);
8664 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8665 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8667 tmp
= load_reg(s
, rs
);
8668 if (insn
& (1 << 20)) {
8669 tmp64
= gen_addq_msw(tmp64
, tmp
);
8671 tmp64
= gen_subq_msw(tmp64
, tmp
);
8674 if (insn
& (1 << 4)) {
8675 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8677 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8678 tmp
= tcg_temp_new_i32();
8679 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8680 tcg_temp_free_i64(tmp64
);
8682 case 7: /* Unsigned sum of absolute differences. */
8683 gen_helper_usad8(tmp
, tmp
, tmp2
);
8684 tcg_temp_free_i32(tmp2
);
8686 tmp2
= load_reg(s
, rs
);
8687 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8688 tcg_temp_free_i32(tmp2
);
8692 store_reg(s
, rd
, tmp
);
8694 case 6: case 7: /* 64-bit multiply, Divide. */
8695 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8696 tmp
= load_reg(s
, rn
);
8697 tmp2
= load_reg(s
, rm
);
8698 if ((op
& 0x50) == 0x10) {
8700 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8704 gen_helper_udiv(tmp
, tmp
, tmp2
);
8706 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8707 tcg_temp_free_i32(tmp2
);
8708 store_reg(s
, rd
, tmp
);
8709 } else if ((op
& 0xe) == 0xc) {
8710 /* Dual multiply accumulate long. */
8712 gen_swap_half(tmp2
);
8713 gen_smul_dual(tmp
, tmp2
);
8715 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8717 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8719 tcg_temp_free_i32(tmp2
);
8721 tmp64
= tcg_temp_new_i64();
8722 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8723 tcg_temp_free_i32(tmp
);
8724 gen_addq(s
, tmp64
, rs
, rd
);
8725 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8726 tcg_temp_free_i64(tmp64
);
8729 /* Unsigned 64-bit multiply */
8730 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8734 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8735 tcg_temp_free_i32(tmp2
);
8736 tmp64
= tcg_temp_new_i64();
8737 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8738 tcg_temp_free_i32(tmp
);
8740 /* Signed 64-bit multiply */
8741 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8746 gen_addq_lo(s
, tmp64
, rs
);
8747 gen_addq_lo(s
, tmp64
, rd
);
8748 } else if (op
& 0x40) {
8749 /* 64-bit accumulate. */
8750 gen_addq(s
, tmp64
, rs
, rd
);
8752 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8753 tcg_temp_free_i64(tmp64
);
8758 case 6: case 7: case 14: case 15:
8760 if (((insn
>> 24) & 3) == 3) {
8761 /* Translate into the equivalent ARM encoding. */
8762 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8763 if (disas_neon_data_insn(env
, s
, insn
))
8766 if (insn
& (1 << 28))
8768 if (disas_coproc_insn (env
, s
, insn
))
8772 case 8: case 9: case 10: case 11:
8773 if (insn
& (1 << 15)) {
8774 /* Branches, misc control. */
8775 if (insn
& 0x5000) {
8776 /* Unconditional branch. */
8777 /* signextend(hw1[10:0]) -> offset[:12]. */
8778 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8779 /* hw1[10:0] -> offset[11:1]. */
8780 offset
|= (insn
& 0x7ff) << 1;
8781 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8782 offset[24:22] already have the same value because of the
8783 sign extension above. */
8784 offset
^= ((~insn
) & (1 << 13)) << 10;
8785 offset
^= ((~insn
) & (1 << 11)) << 11;
8787 if (insn
& (1 << 14)) {
8788 /* Branch and link. */
8789 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8793 if (insn
& (1 << 12)) {
8798 offset
&= ~(uint32_t)2;
8799 /* thumb2 bx, no need to check */
8800 gen_bx_im(s
, offset
);
8802 } else if (((insn
>> 23) & 7) == 7) {
8804 if (insn
& (1 << 13))
8807 if (insn
& (1 << 26)) {
8808 /* Secure monitor call (v6Z) */
8809 qemu_log_mask(LOG_UNIMP
,
8810 "arm: unimplemented secure monitor call\n");
8811 goto illegal_op
; /* not implemented. */
8813 op
= (insn
>> 20) & 7;
8815 case 0: /* msr cpsr. */
8817 tmp
= load_reg(s
, rn
);
8818 addr
= tcg_const_i32(insn
& 0xff);
8819 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8820 tcg_temp_free_i32(addr
);
8821 tcg_temp_free_i32(tmp
);
8826 case 1: /* msr spsr. */
8829 tmp
= load_reg(s
, rn
);
8831 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8835 case 2: /* cps, nop-hint. */
8836 if (((insn
>> 8) & 7) == 0) {
8837 gen_nop_hint(s
, insn
& 0xff);
8839 /* Implemented as NOP in user mode. */
8844 if (insn
& (1 << 10)) {
8845 if (insn
& (1 << 7))
8847 if (insn
& (1 << 6))
8849 if (insn
& (1 << 5))
8851 if (insn
& (1 << 9))
8852 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8854 if (insn
& (1 << 8)) {
8856 imm
|= (insn
& 0x1f);
8859 gen_set_psr_im(s
, offset
, 0, imm
);
8862 case 3: /* Special control operations. */
8864 op
= (insn
>> 4) & 0xf;
8872 /* These execute as NOPs. */
8879 /* Trivial implementation equivalent to bx. */
8880 tmp
= load_reg(s
, rn
);
8883 case 5: /* Exception return. */
8887 if (rn
!= 14 || rd
!= 15) {
8890 tmp
= load_reg(s
, rn
);
8891 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8892 gen_exception_return(s
, tmp
);
8894 case 6: /* mrs cpsr. */
8895 tmp
= tcg_temp_new_i32();
8897 addr
= tcg_const_i32(insn
& 0xff);
8898 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8899 tcg_temp_free_i32(addr
);
8901 gen_helper_cpsr_read(tmp
, cpu_env
);
8903 store_reg(s
, rd
, tmp
);
8905 case 7: /* mrs spsr. */
8906 /* Not accessible in user mode. */
8907 if (IS_USER(s
) || IS_M(env
))
8909 tmp
= load_cpu_field(spsr
);
8910 store_reg(s
, rd
, tmp
);
8915 /* Conditional branch. */
8916 op
= (insn
>> 22) & 0xf;
8917 /* Generate a conditional jump to next instruction. */
8918 s
->condlabel
= gen_new_label();
8919 gen_test_cc(op
^ 1, s
->condlabel
);
8922 /* offset[11:1] = insn[10:0] */
8923 offset
= (insn
& 0x7ff) << 1;
8924 /* offset[17:12] = insn[21:16]. */
8925 offset
|= (insn
& 0x003f0000) >> 4;
8926 /* offset[31:20] = insn[26]. */
8927 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8928 /* offset[18] = insn[13]. */
8929 offset
|= (insn
& (1 << 13)) << 5;
8930 /* offset[19] = insn[11]. */
8931 offset
|= (insn
& (1 << 11)) << 8;
8933 /* jump to the offset */
8934 gen_jmp(s
, s
->pc
+ offset
);
8937 /* Data processing immediate. */
8938 if (insn
& (1 << 25)) {
8939 if (insn
& (1 << 24)) {
8940 if (insn
& (1 << 20))
8942 /* Bitfield/Saturate. */
8943 op
= (insn
>> 21) & 7;
8945 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8947 tmp
= tcg_temp_new_i32();
8948 tcg_gen_movi_i32(tmp
, 0);
8950 tmp
= load_reg(s
, rn
);
8953 case 2: /* Signed bitfield extract. */
8955 if (shift
+ imm
> 32)
8958 gen_sbfx(tmp
, shift
, imm
);
8960 case 6: /* Unsigned bitfield extract. */
8962 if (shift
+ imm
> 32)
8965 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8967 case 3: /* Bitfield insert/clear. */
8970 imm
= imm
+ 1 - shift
;
8972 tmp2
= load_reg(s
, rd
);
8973 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8974 tcg_temp_free_i32(tmp2
);
8979 default: /* Saturate. */
8982 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8984 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8986 tmp2
= tcg_const_i32(imm
);
8989 if ((op
& 1) && shift
== 0)
8990 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8992 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8995 if ((op
& 1) && shift
== 0)
8996 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8998 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9000 tcg_temp_free_i32(tmp2
);
9003 store_reg(s
, rd
, tmp
);
9005 imm
= ((insn
& 0x04000000) >> 15)
9006 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9007 if (insn
& (1 << 22)) {
9008 /* 16-bit immediate. */
9009 imm
|= (insn
>> 4) & 0xf000;
9010 if (insn
& (1 << 23)) {
9012 tmp
= load_reg(s
, rd
);
9013 tcg_gen_ext16u_i32(tmp
, tmp
);
9014 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9017 tmp
= tcg_temp_new_i32();
9018 tcg_gen_movi_i32(tmp
, imm
);
9021 /* Add/sub 12-bit immediate. */
9023 offset
= s
->pc
& ~(uint32_t)3;
9024 if (insn
& (1 << 23))
9028 tmp
= tcg_temp_new_i32();
9029 tcg_gen_movi_i32(tmp
, offset
);
9031 tmp
= load_reg(s
, rn
);
9032 if (insn
& (1 << 23))
9033 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9035 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9038 store_reg(s
, rd
, tmp
);
9041 int shifter_out
= 0;
9042 /* modified 12-bit immediate. */
9043 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9044 imm
= (insn
& 0xff);
9047 /* Nothing to do. */
9049 case 1: /* 00XY00XY */
9052 case 2: /* XY00XY00 */
9056 case 3: /* XYXYXYXY */
9060 default: /* Rotated constant. */
9061 shift
= (shift
<< 1) | (imm
>> 7);
9063 imm
= imm
<< (32 - shift
);
9067 tmp2
= tcg_temp_new_i32();
9068 tcg_gen_movi_i32(tmp2
, imm
);
9069 rn
= (insn
>> 16) & 0xf;
9071 tmp
= tcg_temp_new_i32();
9072 tcg_gen_movi_i32(tmp
, 0);
9074 tmp
= load_reg(s
, rn
);
9076 op
= (insn
>> 21) & 0xf;
9077 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9078 shifter_out
, tmp
, tmp2
))
9080 tcg_temp_free_i32(tmp2
);
9081 rd
= (insn
>> 8) & 0xf;
9083 store_reg(s
, rd
, tmp
);
9085 tcg_temp_free_i32(tmp
);
9090 case 12: /* Load/store single data item. */
9095 if ((insn
& 0x01100000) == 0x01000000) {
9096 if (disas_neon_ls_insn(env
, s
, insn
))
9100 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9102 if (!(insn
& (1 << 20))) {
9106 /* Byte or halfword load space with dest == r15 : memory hints.
9107 * Catch them early so we don't emit pointless addressing code.
9108 * This space is a mix of:
9109 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9110 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9112 * unallocated hints, which must be treated as NOPs
9113 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9114 * which is easiest for the decoding logic
9115 * Some space which must UNDEF
9117 int op1
= (insn
>> 23) & 3;
9118 int op2
= (insn
>> 6) & 0x3f;
9123 /* UNPREDICTABLE, unallocated hint or
9124 * PLD/PLDW/PLI (literal)
9129 return 0; /* PLD/PLDW/PLI or unallocated hint */
9131 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9132 return 0; /* PLD/PLDW/PLI or unallocated hint */
9134 /* UNDEF space, or an UNPREDICTABLE */
9140 addr
= tcg_temp_new_i32();
9142 /* s->pc has already been incremented by 4. */
9143 imm
= s
->pc
& 0xfffffffc;
9144 if (insn
& (1 << 23))
9145 imm
+= insn
& 0xfff;
9147 imm
-= insn
& 0xfff;
9148 tcg_gen_movi_i32(addr
, imm
);
9150 addr
= load_reg(s
, rn
);
9151 if (insn
& (1 << 23)) {
9152 /* Positive offset. */
9154 tcg_gen_addi_i32(addr
, addr
, imm
);
9157 switch ((insn
>> 8) & 0xf) {
9158 case 0x0: /* Shifted Register. */
9159 shift
= (insn
>> 4) & 0xf;
9161 tcg_temp_free_i32(addr
);
9164 tmp
= load_reg(s
, rm
);
9166 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9167 tcg_gen_add_i32(addr
, addr
, tmp
);
9168 tcg_temp_free_i32(tmp
);
9170 case 0xc: /* Negative offset. */
9171 tcg_gen_addi_i32(addr
, addr
, -imm
);
9173 case 0xe: /* User privilege. */
9174 tcg_gen_addi_i32(addr
, addr
, imm
);
9177 case 0x9: /* Post-decrement. */
9180 case 0xb: /* Post-increment. */
9184 case 0xd: /* Pre-decrement. */
9187 case 0xf: /* Pre-increment. */
9188 tcg_gen_addi_i32(addr
, addr
, imm
);
9192 tcg_temp_free_i32(addr
);
9197 if (insn
& (1 << 20)) {
9199 tmp
= tcg_temp_new_i32();
9202 gen_aa32_ld8u(tmp
, addr
, user
);
9205 gen_aa32_ld8s(tmp
, addr
, user
);
9208 gen_aa32_ld16u(tmp
, addr
, user
);
9211 gen_aa32_ld16s(tmp
, addr
, user
);
9214 gen_aa32_ld32u(tmp
, addr
, user
);
9217 tcg_temp_free_i32(tmp
);
9218 tcg_temp_free_i32(addr
);
9224 store_reg(s
, rs
, tmp
);
9228 tmp
= load_reg(s
, rs
);
9231 gen_aa32_st8(tmp
, addr
, user
);
9234 gen_aa32_st16(tmp
, addr
, user
);
9237 gen_aa32_st32(tmp
, addr
, user
);
9240 tcg_temp_free_i32(tmp
);
9241 tcg_temp_free_i32(addr
);
9244 tcg_temp_free_i32(tmp
);
9247 tcg_gen_addi_i32(addr
, addr
, imm
);
9249 store_reg(s
, rn
, addr
);
9251 tcg_temp_free_i32(addr
);
9263 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9265 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9272 if (s
->condexec_mask
) {
9273 cond
= s
->condexec_cond
;
9274 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9275 s
->condlabel
= gen_new_label();
9276 gen_test_cc(cond
^ 1, s
->condlabel
);
9281 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9284 switch (insn
>> 12) {
9288 op
= (insn
>> 11) & 3;
9291 rn
= (insn
>> 3) & 7;
9292 tmp
= load_reg(s
, rn
);
9293 if (insn
& (1 << 10)) {
9295 tmp2
= tcg_temp_new_i32();
9296 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9299 rm
= (insn
>> 6) & 7;
9300 tmp2
= load_reg(s
, rm
);
9302 if (insn
& (1 << 9)) {
9303 if (s
->condexec_mask
)
9304 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9306 gen_sub_CC(tmp
, tmp
, tmp2
);
9308 if (s
->condexec_mask
)
9309 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9311 gen_add_CC(tmp
, tmp
, tmp2
);
9313 tcg_temp_free_i32(tmp2
);
9314 store_reg(s
, rd
, tmp
);
9316 /* shift immediate */
9317 rm
= (insn
>> 3) & 7;
9318 shift
= (insn
>> 6) & 0x1f;
9319 tmp
= load_reg(s
, rm
);
9320 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9321 if (!s
->condexec_mask
)
9323 store_reg(s
, rd
, tmp
);
9327 /* arithmetic large immediate */
9328 op
= (insn
>> 11) & 3;
9329 rd
= (insn
>> 8) & 0x7;
9330 if (op
== 0) { /* mov */
9331 tmp
= tcg_temp_new_i32();
9332 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9333 if (!s
->condexec_mask
)
9335 store_reg(s
, rd
, tmp
);
9337 tmp
= load_reg(s
, rd
);
9338 tmp2
= tcg_temp_new_i32();
9339 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9342 gen_sub_CC(tmp
, tmp
, tmp2
);
9343 tcg_temp_free_i32(tmp
);
9344 tcg_temp_free_i32(tmp2
);
9347 if (s
->condexec_mask
)
9348 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9350 gen_add_CC(tmp
, tmp
, tmp2
);
9351 tcg_temp_free_i32(tmp2
);
9352 store_reg(s
, rd
, tmp
);
9355 if (s
->condexec_mask
)
9356 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9358 gen_sub_CC(tmp
, tmp
, tmp2
);
9359 tcg_temp_free_i32(tmp2
);
9360 store_reg(s
, rd
, tmp
);
9366 if (insn
& (1 << 11)) {
9367 rd
= (insn
>> 8) & 7;
9368 /* load pc-relative. Bit 1 of PC is ignored. */
9369 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9370 val
&= ~(uint32_t)2;
9371 addr
= tcg_temp_new_i32();
9372 tcg_gen_movi_i32(addr
, val
);
9373 tmp
= tcg_temp_new_i32();
9374 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9375 tcg_temp_free_i32(addr
);
9376 store_reg(s
, rd
, tmp
);
9379 if (insn
& (1 << 10)) {
9380 /* data processing extended or blx */
9381 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9382 rm
= (insn
>> 3) & 0xf;
9383 op
= (insn
>> 8) & 3;
9386 tmp
= load_reg(s
, rd
);
9387 tmp2
= load_reg(s
, rm
);
9388 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9389 tcg_temp_free_i32(tmp2
);
9390 store_reg(s
, rd
, tmp
);
9393 tmp
= load_reg(s
, rd
);
9394 tmp2
= load_reg(s
, rm
);
9395 gen_sub_CC(tmp
, tmp
, tmp2
);
9396 tcg_temp_free_i32(tmp2
);
9397 tcg_temp_free_i32(tmp
);
9399 case 2: /* mov/cpy */
9400 tmp
= load_reg(s
, rm
);
9401 store_reg(s
, rd
, tmp
);
9403 case 3:/* branch [and link] exchange thumb register */
9404 tmp
= load_reg(s
, rm
);
9405 if (insn
& (1 << 7)) {
9407 val
= (uint32_t)s
->pc
| 1;
9408 tmp2
= tcg_temp_new_i32();
9409 tcg_gen_movi_i32(tmp2
, val
);
9410 store_reg(s
, 14, tmp2
);
9412 /* already thumb, no need to check */
9419 /* data processing register */
9421 rm
= (insn
>> 3) & 7;
9422 op
= (insn
>> 6) & 0xf;
9423 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9424 /* the shift/rotate ops want the operands backwards */
9433 if (op
== 9) { /* neg */
9434 tmp
= tcg_temp_new_i32();
9435 tcg_gen_movi_i32(tmp
, 0);
9436 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9437 tmp
= load_reg(s
, rd
);
9439 TCGV_UNUSED_I32(tmp
);
9442 tmp2
= load_reg(s
, rm
);
9445 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9446 if (!s
->condexec_mask
)
9450 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9451 if (!s
->condexec_mask
)
9455 if (s
->condexec_mask
) {
9456 gen_shl(tmp2
, tmp2
, tmp
);
9458 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9463 if (s
->condexec_mask
) {
9464 gen_shr(tmp2
, tmp2
, tmp
);
9466 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9471 if (s
->condexec_mask
) {
9472 gen_sar(tmp2
, tmp2
, tmp
);
9474 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9479 if (s
->condexec_mask
) {
9482 gen_adc_CC(tmp
, tmp
, tmp2
);
9486 if (s
->condexec_mask
) {
9487 gen_sub_carry(tmp
, tmp
, tmp2
);
9489 gen_sbc_CC(tmp
, tmp
, tmp2
);
9493 if (s
->condexec_mask
) {
9494 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9495 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9497 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9502 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9507 if (s
->condexec_mask
)
9508 tcg_gen_neg_i32(tmp
, tmp2
);
9510 gen_sub_CC(tmp
, tmp
, tmp2
);
9513 gen_sub_CC(tmp
, tmp
, tmp2
);
9517 gen_add_CC(tmp
, tmp
, tmp2
);
9521 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9522 if (!s
->condexec_mask
)
9526 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9527 if (!s
->condexec_mask
)
9531 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9532 if (!s
->condexec_mask
)
9536 tcg_gen_not_i32(tmp2
, tmp2
);
9537 if (!s
->condexec_mask
)
9545 store_reg(s
, rm
, tmp2
);
9547 tcg_temp_free_i32(tmp
);
9549 store_reg(s
, rd
, tmp
);
9550 tcg_temp_free_i32(tmp2
);
9553 tcg_temp_free_i32(tmp
);
9554 tcg_temp_free_i32(tmp2
);
9559 /* load/store register offset. */
9561 rn
= (insn
>> 3) & 7;
9562 rm
= (insn
>> 6) & 7;
9563 op
= (insn
>> 9) & 7;
9564 addr
= load_reg(s
, rn
);
9565 tmp
= load_reg(s
, rm
);
9566 tcg_gen_add_i32(addr
, addr
, tmp
);
9567 tcg_temp_free_i32(tmp
);
9569 if (op
< 3) { /* store */
9570 tmp
= load_reg(s
, rd
);
9572 tmp
= tcg_temp_new_i32();
9577 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9580 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9583 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9586 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
9589 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9592 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9595 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9598 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
9601 if (op
>= 3) { /* load */
9602 store_reg(s
, rd
, tmp
);
9604 tcg_temp_free_i32(tmp
);
9606 tcg_temp_free_i32(addr
);
9610 /* load/store word immediate offset */
9612 rn
= (insn
>> 3) & 7;
9613 addr
= load_reg(s
, rn
);
9614 val
= (insn
>> 4) & 0x7c;
9615 tcg_gen_addi_i32(addr
, addr
, val
);
9617 if (insn
& (1 << 11)) {
9619 tmp
= tcg_temp_new_i32();
9620 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9621 store_reg(s
, rd
, tmp
);
9624 tmp
= load_reg(s
, rd
);
9625 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9626 tcg_temp_free_i32(tmp
);
9628 tcg_temp_free_i32(addr
);
9632 /* load/store byte immediate offset */
9634 rn
= (insn
>> 3) & 7;
9635 addr
= load_reg(s
, rn
);
9636 val
= (insn
>> 6) & 0x1f;
9637 tcg_gen_addi_i32(addr
, addr
, val
);
9639 if (insn
& (1 << 11)) {
9641 tmp
= tcg_temp_new_i32();
9642 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9643 store_reg(s
, rd
, tmp
);
9646 tmp
= load_reg(s
, rd
);
9647 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9648 tcg_temp_free_i32(tmp
);
9650 tcg_temp_free_i32(addr
);
9654 /* load/store halfword immediate offset */
9656 rn
= (insn
>> 3) & 7;
9657 addr
= load_reg(s
, rn
);
9658 val
= (insn
>> 5) & 0x3e;
9659 tcg_gen_addi_i32(addr
, addr
, val
);
9661 if (insn
& (1 << 11)) {
9663 tmp
= tcg_temp_new_i32();
9664 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9665 store_reg(s
, rd
, tmp
);
9668 tmp
= load_reg(s
, rd
);
9669 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9670 tcg_temp_free_i32(tmp
);
9672 tcg_temp_free_i32(addr
);
9676 /* load/store from stack */
9677 rd
= (insn
>> 8) & 7;
9678 addr
= load_reg(s
, 13);
9679 val
= (insn
& 0xff) * 4;
9680 tcg_gen_addi_i32(addr
, addr
, val
);
9682 if (insn
& (1 << 11)) {
9684 tmp
= tcg_temp_new_i32();
9685 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9686 store_reg(s
, rd
, tmp
);
9689 tmp
= load_reg(s
, rd
);
9690 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9691 tcg_temp_free_i32(tmp
);
9693 tcg_temp_free_i32(addr
);
9697 /* add to high reg */
9698 rd
= (insn
>> 8) & 7;
9699 if (insn
& (1 << 11)) {
9701 tmp
= load_reg(s
, 13);
9703 /* PC. bit 1 is ignored. */
9704 tmp
= tcg_temp_new_i32();
9705 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9707 val
= (insn
& 0xff) * 4;
9708 tcg_gen_addi_i32(tmp
, tmp
, val
);
9709 store_reg(s
, rd
, tmp
);
9714 op
= (insn
>> 8) & 0xf;
9717 /* adjust stack pointer */
9718 tmp
= load_reg(s
, 13);
9719 val
= (insn
& 0x7f) * 4;
9720 if (insn
& (1 << 7))
9721 val
= -(int32_t)val
;
9722 tcg_gen_addi_i32(tmp
, tmp
, val
);
9723 store_reg(s
, 13, tmp
);
9726 case 2: /* sign/zero extend. */
9729 rm
= (insn
>> 3) & 7;
9730 tmp
= load_reg(s
, rm
);
9731 switch ((insn
>> 6) & 3) {
9732 case 0: gen_sxth(tmp
); break;
9733 case 1: gen_sxtb(tmp
); break;
9734 case 2: gen_uxth(tmp
); break;
9735 case 3: gen_uxtb(tmp
); break;
9737 store_reg(s
, rd
, tmp
);
9739 case 4: case 5: case 0xc: case 0xd:
9741 addr
= load_reg(s
, 13);
9742 if (insn
& (1 << 8))
9746 for (i
= 0; i
< 8; i
++) {
9747 if (insn
& (1 << i
))
9750 if ((insn
& (1 << 11)) == 0) {
9751 tcg_gen_addi_i32(addr
, addr
, -offset
);
9753 for (i
= 0; i
< 8; i
++) {
9754 if (insn
& (1 << i
)) {
9755 if (insn
& (1 << 11)) {
9757 tmp
= tcg_temp_new_i32();
9758 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9759 store_reg(s
, i
, tmp
);
9762 tmp
= load_reg(s
, i
);
9763 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9764 tcg_temp_free_i32(tmp
);
9766 /* advance to the next address. */
9767 tcg_gen_addi_i32(addr
, addr
, 4);
9770 TCGV_UNUSED_I32(tmp
);
9771 if (insn
& (1 << 8)) {
9772 if (insn
& (1 << 11)) {
9774 tmp
= tcg_temp_new_i32();
9775 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9776 /* don't set the pc until the rest of the instruction
9780 tmp
= load_reg(s
, 14);
9781 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9782 tcg_temp_free_i32(tmp
);
9784 tcg_gen_addi_i32(addr
, addr
, 4);
9786 if ((insn
& (1 << 11)) == 0) {
9787 tcg_gen_addi_i32(addr
, addr
, -offset
);
9789 /* write back the new stack pointer */
9790 store_reg(s
, 13, addr
);
9791 /* set the new PC value */
9792 if ((insn
& 0x0900) == 0x0900) {
9793 store_reg_from_load(env
, s
, 15, tmp
);
9797 case 1: case 3: case 9: case 11: /* czb */
9799 tmp
= load_reg(s
, rm
);
9800 s
->condlabel
= gen_new_label();
9802 if (insn
& (1 << 11))
9803 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9805 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9806 tcg_temp_free_i32(tmp
);
9807 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9808 val
= (uint32_t)s
->pc
+ 2;
9813 case 15: /* IT, nop-hint. */
9814 if ((insn
& 0xf) == 0) {
9815 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9819 s
->condexec_cond
= (insn
>> 4) & 0xe;
9820 s
->condexec_mask
= insn
& 0x1f;
9821 /* No actual code generated for this insn, just setup state. */
9824 case 0xe: /* bkpt */
9826 gen_exception_insn(s
, 2, EXCP_BKPT
);
9831 rn
= (insn
>> 3) & 0x7;
9833 tmp
= load_reg(s
, rn
);
9834 switch ((insn
>> 6) & 3) {
9835 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9836 case 1: gen_rev16(tmp
); break;
9837 case 3: gen_revsh(tmp
); break;
9838 default: goto illegal_op
;
9840 store_reg(s
, rd
, tmp
);
9844 switch ((insn
>> 5) & 7) {
9848 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9849 /* Dynamic endianness switching not implemented. */
9850 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
9861 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9864 addr
= tcg_const_i32(19);
9865 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9866 tcg_temp_free_i32(addr
);
9870 addr
= tcg_const_i32(16);
9871 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9872 tcg_temp_free_i32(addr
);
9874 tcg_temp_free_i32(tmp
);
9877 if (insn
& (1 << 4)) {
9878 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9882 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9897 /* load/store multiple */
9898 TCGv_i32 loaded_var
;
9899 TCGV_UNUSED_I32(loaded_var
);
9900 rn
= (insn
>> 8) & 0x7;
9901 addr
= load_reg(s
, rn
);
9902 for (i
= 0; i
< 8; i
++) {
9903 if (insn
& (1 << i
)) {
9904 if (insn
& (1 << 11)) {
9906 tmp
= tcg_temp_new_i32();
9907 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9911 store_reg(s
, i
, tmp
);
9915 tmp
= load_reg(s
, i
);
9916 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9917 tcg_temp_free_i32(tmp
);
9919 /* advance to the next address */
9920 tcg_gen_addi_i32(addr
, addr
, 4);
9923 if ((insn
& (1 << rn
)) == 0) {
9924 /* base reg not in list: base register writeback */
9925 store_reg(s
, rn
, addr
);
9927 /* base reg in list: if load, complete it now */
9928 if (insn
& (1 << 11)) {
9929 store_reg(s
, rn
, loaded_var
);
9931 tcg_temp_free_i32(addr
);
9936 /* conditional branch or swi */
9937 cond
= (insn
>> 8) & 0xf;
9943 gen_set_pc_im(s
->pc
);
9944 s
->is_jmp
= DISAS_SWI
;
9947 /* generate a conditional jump to next instruction */
9948 s
->condlabel
= gen_new_label();
9949 gen_test_cc(cond
^ 1, s
->condlabel
);
9952 /* jump to the offset */
9953 val
= (uint32_t)s
->pc
+ 2;
9954 offset
= ((int32_t)insn
<< 24) >> 24;
9960 if (insn
& (1 << 11)) {
9961 if (disas_thumb2_insn(env
, s
, insn
))
9965 /* unconditional branch */
9966 val
= (uint32_t)s
->pc
;
9967 offset
= ((int32_t)insn
<< 21) >> 21;
9968 val
+= (offset
<< 1) + 2;
9973 if (disas_thumb2_insn(env
, s
, insn
))
9979 gen_exception_insn(s
, 4, EXCP_UDEF
);
9983 gen_exception_insn(s
, 2, EXCP_UDEF
);
9986 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9987 basic block 'tb'. If search_pc is TRUE, also generate PC
9988 information for each intermediate instruction. */
9989 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
9990 TranslationBlock
*tb
,
9993 CPUState
*cs
= CPU(cpu
);
9994 CPUARMState
*env
= &cpu
->env
;
9995 DisasContext dc1
, *dc
= &dc1
;
9997 uint16_t *gen_opc_end
;
9999 target_ulong pc_start
;
10000 uint32_t next_page_start
;
10004 /* generate intermediate code */
10009 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10011 dc
->is_jmp
= DISAS_NEXT
;
10013 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10015 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10016 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10017 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10018 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10019 #if !defined(CONFIG_USER_ONLY)
10020 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10022 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10023 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10024 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10025 cpu_F0s
= tcg_temp_new_i32();
10026 cpu_F1s
= tcg_temp_new_i32();
10027 cpu_F0d
= tcg_temp_new_i64();
10028 cpu_F1d
= tcg_temp_new_i64();
10031 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10032 cpu_M0
= tcg_temp_new_i64();
10033 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10036 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10037 if (max_insns
== 0)
10038 max_insns
= CF_COUNT_MASK
;
10042 tcg_clear_temp_count();
10044 /* A note on handling of the condexec (IT) bits:
10046 * We want to avoid the overhead of having to write the updated condexec
10047 * bits back to the CPUARMState for every instruction in an IT block. So:
10048 * (1) if the condexec bits are not already zero then we write
10049 * zero back into the CPUARMState now. This avoids complications trying
10050 * to do it at the end of the block. (For example if we don't do this
10051 * it's hard to identify whether we can safely skip writing condexec
10052 * at the end of the TB, which we definitely want to do for the case
10053 * where a TB doesn't do anything with the IT state at all.)
10054 * (2) if we are going to leave the TB then we call gen_set_condexec()
10055 * which will write the correct value into CPUARMState if zero is wrong.
10056 * This is done both for leaving the TB at the end, and for leaving
10057 * it because of an exception we know will happen, which is done in
10058 * gen_exception_insn(). The latter is necessary because we need to
10059 * leave the TB with the PC/IT state just prior to execution of the
10060 * instruction which caused the exception.
10061 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10062 * then the CPUARMState will be wrong and we need to reset it.
10063 * This is handled in the same way as restoration of the
10064 * PC in these situations: we will be called again with search_pc=1
10065 * and generate a mapping of the condexec bits for each PC in
10066 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10067 * this to restore the condexec bits.
10069 * Note that there are no instructions which can read the condexec
10070 * bits, and none which can write non-static values to them, so
10071 * we don't need to care about whether CPUARMState is correct in the
10075 /* Reset the conditional execution bits immediately. This avoids
10076 complications trying to do it at the end of the block. */
10077 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10079 TCGv_i32 tmp
= tcg_temp_new_i32();
10080 tcg_gen_movi_i32(tmp
, 0);
10081 store_cpu_field(tmp
, condexec_bits
);
10084 #ifdef CONFIG_USER_ONLY
10085 /* Intercept jump to the magic kernel page. */
10086 if (dc
->pc
>= 0xffff0000) {
10087 /* We always get here via a jump, so know we are not in a
10088 conditional execution block. */
10089 gen_exception(EXCP_KERNEL_TRAP
);
10090 dc
->is_jmp
= DISAS_UPDATE
;
10094 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10095 /* We always get here via a jump, so know we are not in a
10096 conditional execution block. */
10097 gen_exception(EXCP_EXCEPTION_EXIT
);
10098 dc
->is_jmp
= DISAS_UPDATE
;
10103 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10104 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10105 if (bp
->pc
== dc
->pc
) {
10106 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10107 /* Advance PC so that clearing the breakpoint will
10108 invalidate this TB. */
10110 goto done_generating
;
10115 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10119 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10121 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10122 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10123 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10124 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10127 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10130 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10131 tcg_gen_debug_insn_start(dc
->pc
);
10135 disas_thumb_insn(env
, dc
);
10136 if (dc
->condexec_mask
) {
10137 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10138 | ((dc
->condexec_mask
>> 4) & 1);
10139 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10140 if (dc
->condexec_mask
== 0) {
10141 dc
->condexec_cond
= 0;
10145 disas_arm_insn(env
, dc
);
10148 if (dc
->condjmp
&& !dc
->is_jmp
) {
10149 gen_set_label(dc
->condlabel
);
10153 if (tcg_check_temp_count()) {
10154 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
10157 /* Translation stops when a conditional branch is encountered.
10158 * Otherwise the subsequent code could get translated several times.
10159 * Also stop translation when a page boundary is reached. This
10160 * ensures prefetch aborts occur at the right place. */
10162 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10163 !cs
->singlestep_enabled
&&
10165 dc
->pc
< next_page_start
&&
10166 num_insns
< max_insns
);
10168 if (tb
->cflags
& CF_LAST_IO
) {
10170 /* FIXME: This can theoretically happen with self-modifying
10172 cpu_abort(env
, "IO on conditional branch instruction");
10177 /* At this stage dc->condjmp will only be set when the skipped
10178 instruction was a conditional branch or trap, and the PC has
10179 already been written. */
10180 if (unlikely(cs
->singlestep_enabled
)) {
10181 /* Make sure the pc is updated, and raise a debug exception. */
10183 gen_set_condexec(dc
);
10184 if (dc
->is_jmp
== DISAS_SWI
) {
10185 gen_exception(EXCP_SWI
);
10187 gen_exception(EXCP_DEBUG
);
10189 gen_set_label(dc
->condlabel
);
10191 if (dc
->condjmp
|| !dc
->is_jmp
) {
10192 gen_set_pc_im(dc
->pc
);
10195 gen_set_condexec(dc
);
10196 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10197 gen_exception(EXCP_SWI
);
10199 /* FIXME: Single stepping a WFI insn will not halt
10201 gen_exception(EXCP_DEBUG
);
10204 /* While branches must always occur at the end of an IT block,
10205 there are a few other things that can cause us to terminate
10206 the TB in the middle of an IT block:
10207 - Exception generating instructions (bkpt, swi, undefined).
10209 - Hardware watchpoints.
10210 Hardware breakpoints have already been handled and skip this code.
10212 gen_set_condexec(dc
);
10213 switch(dc
->is_jmp
) {
10215 gen_goto_tb(dc
, 1, dc
->pc
);
10220 /* indicate that the hash table must be used to find the next TB */
10221 tcg_gen_exit_tb(0);
10223 case DISAS_TB_JUMP
:
10224 /* nothing more to generate */
10227 gen_helper_wfi(cpu_env
);
10230 gen_exception(EXCP_SWI
);
10234 gen_set_label(dc
->condlabel
);
10235 gen_set_condexec(dc
);
10236 gen_goto_tb(dc
, 1, dc
->pc
);
10242 gen_tb_end(tb
, num_insns
);
10243 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10246 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10247 qemu_log("----------------\n");
10248 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10249 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10250 dc
->thumb
| (dc
->bswap_code
<< 1));
10255 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10258 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10260 tb
->size
= dc
->pc
- pc_start
;
10261 tb
->icount
= num_insns
;
10265 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10267 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10270 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10272 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10275 static const char *cpu_mode_names
[16] = {
10276 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10277 "???", "???", "???", "und", "???", "???", "???", "sys"
10280 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10283 ARMCPU
*cpu
= ARM_CPU(cs
);
10284 CPUARMState
*env
= &cpu
->env
;
10288 for(i
=0;i
<16;i
++) {
10289 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10291 cpu_fprintf(f
, "\n");
10293 cpu_fprintf(f
, " ");
10295 psr
= cpsr_read(env
);
10296 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10298 psr
& (1 << 31) ? 'N' : '-',
10299 psr
& (1 << 30) ? 'Z' : '-',
10300 psr
& (1 << 29) ? 'C' : '-',
10301 psr
& (1 << 28) ? 'V' : '-',
10302 psr
& CPSR_T
? 'T' : 'A',
10303 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10305 if (flags
& CPU_DUMP_FPU
) {
10306 int numvfpregs
= 0;
10307 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10310 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10313 for (i
= 0; i
< numvfpregs
; i
++) {
10314 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10315 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10316 i
* 2, (uint32_t)v
,
10317 i
* 2 + 1, (uint32_t)(v
>> 32),
10320 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10324 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10326 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10327 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];