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. */
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");
117 a64_translate_init();
123 static inline TCGv_i32
load_cpu_offset(int offset
)
125 TCGv_i32 tmp
= tcg_temp_new_i32();
126 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
130 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
132 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
134 tcg_gen_st_i32(var
, cpu_env
, offset
);
135 tcg_temp_free_i32(var
);
138 #define store_cpu_field(var, name) \
139 store_cpu_offset(var, offsetof(CPUARMState, name))
141 /* Set a variable to the value of a CPU register. */
142 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
146 /* normally, since we updated PC, we need only to add one insn */
148 addr
= (long)s
->pc
+ 2;
150 addr
= (long)s
->pc
+ 4;
151 tcg_gen_movi_i32(var
, addr
);
153 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
157 /* Create a new temporary and set it to the value of a CPU register. */
158 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
160 TCGv_i32 tmp
= tcg_temp_new_i32();
161 load_reg_var(s
, tmp
, reg
);
165 /* Set a CPU register. The source must be a temporary and will be
167 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
170 tcg_gen_andi_i32(var
, var
, ~1);
171 s
->is_jmp
= DISAS_JUMP
;
173 tcg_gen_mov_i32(cpu_R
[reg
], var
);
174 tcg_temp_free_i32(var
);
177 /* Value extensions. */
178 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
179 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
180 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
181 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
183 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
184 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
187 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
189 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
190 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
191 tcg_temp_free_i32(tmp_mask
);
193 /* Set NZCV flags from the high 4 bits of var. */
194 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
196 static void gen_exception(int excp
)
198 TCGv_i32 tmp
= tcg_temp_new_i32();
199 tcg_gen_movi_i32(tmp
, excp
);
200 gen_helper_exception(cpu_env
, tmp
);
201 tcg_temp_free_i32(tmp
);
204 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
206 TCGv_i32 tmp1
= tcg_temp_new_i32();
207 TCGv_i32 tmp2
= tcg_temp_new_i32();
208 tcg_gen_ext16s_i32(tmp1
, a
);
209 tcg_gen_ext16s_i32(tmp2
, b
);
210 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
211 tcg_temp_free_i32(tmp2
);
212 tcg_gen_sari_i32(a
, a
, 16);
213 tcg_gen_sari_i32(b
, b
, 16);
214 tcg_gen_mul_i32(b
, b
, a
);
215 tcg_gen_mov_i32(a
, tmp1
);
216 tcg_temp_free_i32(tmp1
);
219 /* Byteswap each halfword. */
220 static void gen_rev16(TCGv_i32 var
)
222 TCGv_i32 tmp
= tcg_temp_new_i32();
223 tcg_gen_shri_i32(tmp
, var
, 8);
224 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
225 tcg_gen_shli_i32(var
, var
, 8);
226 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
227 tcg_gen_or_i32(var
, var
, tmp
);
228 tcg_temp_free_i32(tmp
);
231 /* Byteswap low halfword and sign extend. */
232 static void gen_revsh(TCGv_i32 var
)
234 tcg_gen_ext16u_i32(var
, var
);
235 tcg_gen_bswap16_i32(var
, var
);
236 tcg_gen_ext16s_i32(var
, var
);
239 /* Unsigned bitfield extract. */
240 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
243 tcg_gen_shri_i32(var
, var
, shift
);
244 tcg_gen_andi_i32(var
, var
, mask
);
247 /* Signed bitfield extract. */
248 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
253 tcg_gen_sari_i32(var
, var
, shift
);
254 if (shift
+ width
< 32) {
255 signbit
= 1u << (width
- 1);
256 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
257 tcg_gen_xori_i32(var
, var
, signbit
);
258 tcg_gen_subi_i32(var
, var
, signbit
);
262 /* Return (b << 32) + a. Mark inputs as dead */
263 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
265 TCGv_i64 tmp64
= tcg_temp_new_i64();
267 tcg_gen_extu_i32_i64(tmp64
, b
);
268 tcg_temp_free_i32(b
);
269 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
270 tcg_gen_add_i64(a
, tmp64
, a
);
272 tcg_temp_free_i64(tmp64
);
276 /* Return (b << 32) - a. Mark inputs as dead. */
277 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
279 TCGv_i64 tmp64
= tcg_temp_new_i64();
281 tcg_gen_extu_i32_i64(tmp64
, b
);
282 tcg_temp_free_i32(b
);
283 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
284 tcg_gen_sub_i64(a
, tmp64
, a
);
286 tcg_temp_free_i64(tmp64
);
290 /* 32x32->64 multiply. Marks inputs as dead. */
291 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
293 TCGv_i32 lo
= tcg_temp_new_i32();
294 TCGv_i32 hi
= tcg_temp_new_i32();
297 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
298 tcg_temp_free_i32(a
);
299 tcg_temp_free_i32(b
);
301 ret
= tcg_temp_new_i64();
302 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
303 tcg_temp_free_i32(lo
);
304 tcg_temp_free_i32(hi
);
309 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
311 TCGv_i32 lo
= tcg_temp_new_i32();
312 TCGv_i32 hi
= tcg_temp_new_i32();
315 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
316 tcg_temp_free_i32(a
);
317 tcg_temp_free_i32(b
);
319 ret
= tcg_temp_new_i64();
320 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
321 tcg_temp_free_i32(lo
);
322 tcg_temp_free_i32(hi
);
327 /* Swap low and high halfwords. */
328 static void gen_swap_half(TCGv_i32 var
)
330 TCGv_i32 tmp
= tcg_temp_new_i32();
331 tcg_gen_shri_i32(tmp
, var
, 16);
332 tcg_gen_shli_i32(var
, var
, 16);
333 tcg_gen_or_i32(var
, var
, tmp
);
334 tcg_temp_free_i32(tmp
);
337 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
338 tmp = (t0 ^ t1) & 0x8000;
341 t0 = (t0 + t1) ^ tmp;
344 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
346 TCGv_i32 tmp
= tcg_temp_new_i32();
347 tcg_gen_xor_i32(tmp
, t0
, t1
);
348 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
349 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
350 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
351 tcg_gen_add_i32(t0
, t0
, t1
);
352 tcg_gen_xor_i32(t0
, t0
, tmp
);
353 tcg_temp_free_i32(tmp
);
354 tcg_temp_free_i32(t1
);
357 /* Set CF to the top bit of var. */
358 static void gen_set_CF_bit31(TCGv_i32 var
)
360 tcg_gen_shri_i32(cpu_CF
, var
, 31);
363 /* Set N and Z flags from var. */
364 static inline void gen_logic_CC(TCGv_i32 var
)
366 tcg_gen_mov_i32(cpu_NF
, var
);
367 tcg_gen_mov_i32(cpu_ZF
, var
);
371 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
373 tcg_gen_add_i32(t0
, t0
, t1
);
374 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
377 /* dest = T0 + T1 + CF. */
378 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
380 tcg_gen_add_i32(dest
, t0
, t1
);
381 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
384 /* dest = T0 - T1 + CF - 1. */
385 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
387 tcg_gen_sub_i32(dest
, t0
, t1
);
388 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
389 tcg_gen_subi_i32(dest
, dest
, 1);
392 /* dest = T0 + T1. Compute C, N, V and Z flags */
393 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
395 TCGv_i32 tmp
= tcg_temp_new_i32();
396 tcg_gen_movi_i32(tmp
, 0);
397 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
398 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
399 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
400 tcg_gen_xor_i32(tmp
, t0
, t1
);
401 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
402 tcg_temp_free_i32(tmp
);
403 tcg_gen_mov_i32(dest
, cpu_NF
);
406 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
407 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
409 TCGv_i32 tmp
= tcg_temp_new_i32();
410 if (TCG_TARGET_HAS_add2_i32
) {
411 tcg_gen_movi_i32(tmp
, 0);
412 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
413 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
415 TCGv_i64 q0
= tcg_temp_new_i64();
416 TCGv_i64 q1
= tcg_temp_new_i64();
417 tcg_gen_extu_i32_i64(q0
, t0
);
418 tcg_gen_extu_i32_i64(q1
, t1
);
419 tcg_gen_add_i64(q0
, q0
, q1
);
420 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
421 tcg_gen_add_i64(q0
, q0
, q1
);
422 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
423 tcg_temp_free_i64(q0
);
424 tcg_temp_free_i64(q1
);
426 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
427 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
428 tcg_gen_xor_i32(tmp
, t0
, t1
);
429 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
430 tcg_temp_free_i32(tmp
);
431 tcg_gen_mov_i32(dest
, cpu_NF
);
434 /* dest = T0 - T1. Compute C, N, V and Z flags */
435 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
438 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
439 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
440 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
441 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
442 tmp
= tcg_temp_new_i32();
443 tcg_gen_xor_i32(tmp
, t0
, t1
);
444 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
445 tcg_temp_free_i32(tmp
);
446 tcg_gen_mov_i32(dest
, cpu_NF
);
449 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
450 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
452 TCGv_i32 tmp
= tcg_temp_new_i32();
453 tcg_gen_not_i32(tmp
, t1
);
454 gen_adc_CC(dest
, t0
, tmp
);
455 tcg_temp_free_i32(tmp
);
458 #define GEN_SHIFT(name) \
459 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
461 TCGv_i32 tmp1, tmp2, tmp3; \
462 tmp1 = tcg_temp_new_i32(); \
463 tcg_gen_andi_i32(tmp1, t1, 0xff); \
464 tmp2 = tcg_const_i32(0); \
465 tmp3 = tcg_const_i32(0x1f); \
466 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
467 tcg_temp_free_i32(tmp3); \
468 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
469 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
470 tcg_temp_free_i32(tmp2); \
471 tcg_temp_free_i32(tmp1); \
477 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
480 tmp1
= tcg_temp_new_i32();
481 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
482 tmp2
= tcg_const_i32(0x1f);
483 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
484 tcg_temp_free_i32(tmp2
);
485 tcg_gen_sar_i32(dest
, t0
, tmp1
);
486 tcg_temp_free_i32(tmp1
);
489 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
491 TCGv_i32 c0
= tcg_const_i32(0);
492 TCGv_i32 tmp
= tcg_temp_new_i32();
493 tcg_gen_neg_i32(tmp
, src
);
494 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
495 tcg_temp_free_i32(c0
);
496 tcg_temp_free_i32(tmp
);
499 static void shifter_out_im(TCGv_i32 var
, int shift
)
502 tcg_gen_andi_i32(cpu_CF
, var
, 1);
504 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
506 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
511 /* Shift by immediate. Includes special handling for shift == 0. */
512 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
513 int shift
, int flags
)
519 shifter_out_im(var
, 32 - shift
);
520 tcg_gen_shli_i32(var
, var
, shift
);
526 tcg_gen_shri_i32(cpu_CF
, var
, 31);
528 tcg_gen_movi_i32(var
, 0);
531 shifter_out_im(var
, shift
- 1);
532 tcg_gen_shri_i32(var
, var
, shift
);
539 shifter_out_im(var
, shift
- 1);
542 tcg_gen_sari_i32(var
, var
, shift
);
544 case 3: /* ROR/RRX */
547 shifter_out_im(var
, shift
- 1);
548 tcg_gen_rotri_i32(var
, var
, shift
); break;
550 TCGv_i32 tmp
= tcg_temp_new_i32();
551 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
553 shifter_out_im(var
, 0);
554 tcg_gen_shri_i32(var
, var
, 1);
555 tcg_gen_or_i32(var
, var
, tmp
);
556 tcg_temp_free_i32(tmp
);
561 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
562 TCGv_i32 shift
, int flags
)
566 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
567 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
568 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
569 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
574 gen_shl(var
, var
, shift
);
577 gen_shr(var
, var
, shift
);
580 gen_sar(var
, var
, shift
);
582 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
583 tcg_gen_rotr_i32(var
, var
, shift
); break;
586 tcg_temp_free_i32(shift
);
589 #define PAS_OP(pfx) \
591 case 0: gen_pas_helper(glue(pfx,add16)); break; \
592 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
593 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
594 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
595 case 4: gen_pas_helper(glue(pfx,add8)); break; \
596 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
598 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
603 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
605 tmp
= tcg_temp_new_ptr();
606 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
608 tcg_temp_free_ptr(tmp
);
611 tmp
= tcg_temp_new_ptr();
612 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
614 tcg_temp_free_ptr(tmp
);
616 #undef gen_pas_helper
617 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
630 #undef gen_pas_helper
635 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
636 #define PAS_OP(pfx) \
638 case 0: gen_pas_helper(glue(pfx,add8)); break; \
639 case 1: gen_pas_helper(glue(pfx,add16)); break; \
640 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
641 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
642 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
643 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
645 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
650 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
652 tmp
= tcg_temp_new_ptr();
653 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
655 tcg_temp_free_ptr(tmp
);
658 tmp
= tcg_temp_new_ptr();
659 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
661 tcg_temp_free_ptr(tmp
);
663 #undef gen_pas_helper
664 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
677 #undef gen_pas_helper
682 static void gen_test_cc(int cc
, int label
)
689 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
692 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
695 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
698 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
701 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
704 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
707 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
710 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
712 case 8: /* hi: C && !Z */
713 inv
= gen_new_label();
714 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
715 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
718 case 9: /* ls: !C || Z */
719 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
720 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
722 case 10: /* ge: N == V -> N ^ V == 0 */
723 tmp
= tcg_temp_new_i32();
724 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
725 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
726 tcg_temp_free_i32(tmp
);
728 case 11: /* lt: N != V -> N ^ V != 0 */
729 tmp
= tcg_temp_new_i32();
730 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
731 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
732 tcg_temp_free_i32(tmp
);
734 case 12: /* gt: !Z && N == V */
735 inv
= gen_new_label();
736 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
737 tmp
= tcg_temp_new_i32();
738 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
739 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
740 tcg_temp_free_i32(tmp
);
743 case 13: /* le: Z || N != V */
744 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
745 tmp
= tcg_temp_new_i32();
746 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
747 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
748 tcg_temp_free_i32(tmp
);
751 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
756 static const uint8_t table_logic_cc
[16] = {
775 /* Set PC and Thumb state from an immediate address. */
776 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
780 s
->is_jmp
= DISAS_UPDATE
;
781 if (s
->thumb
!= (addr
& 1)) {
782 tmp
= tcg_temp_new_i32();
783 tcg_gen_movi_i32(tmp
, addr
& 1);
784 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
785 tcg_temp_free_i32(tmp
);
787 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
790 /* Set PC and Thumb state from var. var is marked as dead. */
791 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
793 s
->is_jmp
= DISAS_UPDATE
;
794 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
795 tcg_gen_andi_i32(var
, var
, 1);
796 store_cpu_field(var
, thumb
);
799 /* Variant of store_reg which uses branch&exchange logic when storing
800 to r15 in ARM architecture v7 and above. The source must be a temporary
801 and will be marked as dead. */
802 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
803 int reg
, TCGv_i32 var
)
805 if (reg
== 15 && ENABLE_ARCH_7
) {
808 store_reg(s
, reg
, var
);
812 /* Variant of store_reg which uses branch&exchange logic when storing
813 * to r15 in ARM architecture v5T and above. This is used for storing
814 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
815 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
816 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
817 int reg
, TCGv_i32 var
)
819 if (reg
== 15 && ENABLE_ARCH_5
) {
822 store_reg(s
, reg
, var
);
826 /* Abstractions of "generate code to do a guest load/store for
827 * AArch32", where a vaddr is always 32 bits (and is zero
828 * extended if we're a 64 bit core) and data is also
829 * 32 bits unless specifically doing a 64 bit access.
830 * These functions work like tcg_gen_qemu_{ld,st}* except
831 * that their arguments are TCGv_i32 rather than TCGv.
833 #if TARGET_LONG_BITS == 32
835 #define DO_GEN_LD(OP) \
836 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
838 tcg_gen_qemu_##OP(val, addr, index); \
841 #define DO_GEN_ST(OP) \
842 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
844 tcg_gen_qemu_##OP(val, addr, index); \
847 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
849 tcg_gen_qemu_ld64(val
, addr
, index
);
852 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
854 tcg_gen_qemu_st64(val
, addr
, index
);
859 #define DO_GEN_LD(OP) \
860 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
862 TCGv addr64 = tcg_temp_new(); \
863 TCGv val64 = tcg_temp_new(); \
864 tcg_gen_extu_i32_i64(addr64, addr); \
865 tcg_gen_qemu_##OP(val64, addr64, index); \
866 tcg_temp_free(addr64); \
867 tcg_gen_trunc_i64_i32(val, val64); \
868 tcg_temp_free(val64); \
871 #define DO_GEN_ST(OP) \
872 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
874 TCGv addr64 = tcg_temp_new(); \
875 TCGv val64 = tcg_temp_new(); \
876 tcg_gen_extu_i32_i64(addr64, addr); \
877 tcg_gen_extu_i32_i64(val64, val); \
878 tcg_gen_qemu_##OP(val64, addr64, index); \
879 tcg_temp_free(addr64); \
880 tcg_temp_free(val64); \
883 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
885 TCGv addr64
= tcg_temp_new();
886 tcg_gen_extu_i32_i64(addr64
, addr
);
887 tcg_gen_qemu_ld64(val
, addr64
, index
);
888 tcg_temp_free(addr64
);
891 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
893 TCGv addr64
= tcg_temp_new();
894 tcg_gen_extu_i32_i64(addr64
, addr
);
895 tcg_gen_qemu_st64(val
, addr64
, index
);
896 tcg_temp_free(addr64
);
910 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
913 gen_a64_set_pc_im(val
);
915 tcg_gen_movi_i32(cpu_R
[15], val
);
919 /* Force a TB lookup after an instruction that changes the CPU state. */
920 static inline void gen_lookup_tb(DisasContext
*s
)
922 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
923 s
->is_jmp
= DISAS_UPDATE
;
926 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
929 int val
, rm
, shift
, shiftop
;
932 if (!(insn
& (1 << 25))) {
935 if (!(insn
& (1 << 23)))
938 tcg_gen_addi_i32(var
, var
, val
);
942 shift
= (insn
>> 7) & 0x1f;
943 shiftop
= (insn
>> 5) & 3;
944 offset
= load_reg(s
, rm
);
945 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
946 if (!(insn
& (1 << 23)))
947 tcg_gen_sub_i32(var
, var
, offset
);
949 tcg_gen_add_i32(var
, var
, offset
);
950 tcg_temp_free_i32(offset
);
954 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
955 int extra
, TCGv_i32 var
)
960 if (insn
& (1 << 22)) {
962 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
963 if (!(insn
& (1 << 23)))
967 tcg_gen_addi_i32(var
, var
, val
);
971 tcg_gen_addi_i32(var
, var
, extra
);
973 offset
= load_reg(s
, rm
);
974 if (!(insn
& (1 << 23)))
975 tcg_gen_sub_i32(var
, var
, offset
);
977 tcg_gen_add_i32(var
, var
, offset
);
978 tcg_temp_free_i32(offset
);
982 static TCGv_ptr
get_fpstatus_ptr(int neon
)
984 TCGv_ptr statusptr
= tcg_temp_new_ptr();
987 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
989 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
991 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
995 #define VFP_OP2(name) \
996 static inline void gen_vfp_##name(int dp) \
998 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1000 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1002 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1004 tcg_temp_free_ptr(fpst); \
1014 static inline void gen_vfp_F1_mul(int dp
)
1016 /* Like gen_vfp_mul() but put result in F1 */
1017 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1019 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1021 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1023 tcg_temp_free_ptr(fpst
);
1026 static inline void gen_vfp_F1_neg(int dp
)
1028 /* Like gen_vfp_neg() but put result in F1 */
1030 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1032 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1036 static inline void gen_vfp_abs(int dp
)
1039 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1041 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1044 static inline void gen_vfp_neg(int dp
)
1047 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1049 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1052 static inline void gen_vfp_sqrt(int dp
)
1055 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1057 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1060 static inline void gen_vfp_cmp(int dp
)
1063 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1065 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1068 static inline void gen_vfp_cmpe(int dp
)
1071 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1073 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1076 static inline void gen_vfp_F1_ld0(int dp
)
1079 tcg_gen_movi_i64(cpu_F1d
, 0);
1081 tcg_gen_movi_i32(cpu_F1s
, 0);
1084 #define VFP_GEN_ITOF(name) \
1085 static inline void gen_vfp_##name(int dp, int neon) \
1087 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1089 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1091 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1093 tcg_temp_free_ptr(statusptr); \
1100 #define VFP_GEN_FTOI(name) \
1101 static inline void gen_vfp_##name(int dp, int neon) \
1103 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1105 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1107 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1109 tcg_temp_free_ptr(statusptr); \
1118 #define VFP_GEN_FIX(name) \
1119 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1121 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1122 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1124 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1126 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1128 tcg_temp_free_i32(tmp_shift); \
1129 tcg_temp_free_ptr(statusptr); \
1141 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1144 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1146 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1150 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1153 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1155 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1160 vfp_reg_offset (int dp
, int reg
)
1163 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1165 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1166 + offsetof(CPU_DoubleU
, l
.upper
);
1168 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1169 + offsetof(CPU_DoubleU
, l
.lower
);
1173 /* Return the offset of a 32-bit piece of a NEON register.
1174 zero is the least significant end of the register. */
1176 neon_reg_offset (int reg
, int n
)
1180 return vfp_reg_offset(0, sreg
);
1183 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1185 TCGv_i32 tmp
= tcg_temp_new_i32();
1186 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1190 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1192 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1193 tcg_temp_free_i32(var
);
1196 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1198 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1201 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1203 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1206 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1207 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1208 #define tcg_gen_st_f32 tcg_gen_st_i32
1209 #define tcg_gen_st_f64 tcg_gen_st_i64
1211 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1214 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1216 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1219 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1222 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1224 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1227 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1230 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1232 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1235 #define ARM_CP_RW_BIT (1 << 20)
1237 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1239 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1242 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1244 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1247 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1249 TCGv_i32 var
= tcg_temp_new_i32();
1250 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1254 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1256 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1257 tcg_temp_free_i32(var
);
1260 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1262 iwmmxt_store_reg(cpu_M0
, rn
);
1265 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1267 iwmmxt_load_reg(cpu_M0
, rn
);
1270 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1272 iwmmxt_load_reg(cpu_V1
, rn
);
1273 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1276 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1278 iwmmxt_load_reg(cpu_V1
, rn
);
1279 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1282 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1284 iwmmxt_load_reg(cpu_V1
, rn
);
1285 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1288 #define IWMMXT_OP(name) \
1289 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1291 iwmmxt_load_reg(cpu_V1, rn); \
1292 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1295 #define IWMMXT_OP_ENV(name) \
1296 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1298 iwmmxt_load_reg(cpu_V1, rn); \
1299 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1302 #define IWMMXT_OP_ENV_SIZE(name) \
1303 IWMMXT_OP_ENV(name##b) \
1304 IWMMXT_OP_ENV(name##w) \
1305 IWMMXT_OP_ENV(name##l)
1307 #define IWMMXT_OP_ENV1(name) \
1308 static inline void gen_op_iwmmxt_##name##_M0(void) \
1310 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1324 IWMMXT_OP_ENV_SIZE(unpackl
)
1325 IWMMXT_OP_ENV_SIZE(unpackh
)
1327 IWMMXT_OP_ENV1(unpacklub
)
1328 IWMMXT_OP_ENV1(unpackluw
)
1329 IWMMXT_OP_ENV1(unpacklul
)
1330 IWMMXT_OP_ENV1(unpackhub
)
1331 IWMMXT_OP_ENV1(unpackhuw
)
1332 IWMMXT_OP_ENV1(unpackhul
)
1333 IWMMXT_OP_ENV1(unpacklsb
)
1334 IWMMXT_OP_ENV1(unpacklsw
)
1335 IWMMXT_OP_ENV1(unpacklsl
)
1336 IWMMXT_OP_ENV1(unpackhsb
)
1337 IWMMXT_OP_ENV1(unpackhsw
)
1338 IWMMXT_OP_ENV1(unpackhsl
)
1340 IWMMXT_OP_ENV_SIZE(cmpeq
)
1341 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1342 IWMMXT_OP_ENV_SIZE(cmpgts
)
1344 IWMMXT_OP_ENV_SIZE(mins
)
1345 IWMMXT_OP_ENV_SIZE(minu
)
1346 IWMMXT_OP_ENV_SIZE(maxs
)
1347 IWMMXT_OP_ENV_SIZE(maxu
)
1349 IWMMXT_OP_ENV_SIZE(subn
)
1350 IWMMXT_OP_ENV_SIZE(addn
)
1351 IWMMXT_OP_ENV_SIZE(subu
)
1352 IWMMXT_OP_ENV_SIZE(addu
)
1353 IWMMXT_OP_ENV_SIZE(subs
)
1354 IWMMXT_OP_ENV_SIZE(adds
)
1356 IWMMXT_OP_ENV(avgb0
)
1357 IWMMXT_OP_ENV(avgb1
)
1358 IWMMXT_OP_ENV(avgw0
)
1359 IWMMXT_OP_ENV(avgw1
)
1363 IWMMXT_OP_ENV(packuw
)
1364 IWMMXT_OP_ENV(packul
)
1365 IWMMXT_OP_ENV(packuq
)
1366 IWMMXT_OP_ENV(packsw
)
1367 IWMMXT_OP_ENV(packsl
)
1368 IWMMXT_OP_ENV(packsq
)
1370 static void gen_op_iwmmxt_set_mup(void)
1373 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1374 tcg_gen_ori_i32(tmp
, tmp
, 2);
1375 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1378 static void gen_op_iwmmxt_set_cup(void)
1381 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1382 tcg_gen_ori_i32(tmp
, tmp
, 1);
1383 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1386 static void gen_op_iwmmxt_setpsr_nz(void)
1388 TCGv_i32 tmp
= tcg_temp_new_i32();
1389 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1390 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1393 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1395 iwmmxt_load_reg(cpu_V1
, rn
);
1396 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1397 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1400 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1407 rd
= (insn
>> 16) & 0xf;
1408 tmp
= load_reg(s
, rd
);
1410 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1411 if (insn
& (1 << 24)) {
1413 if (insn
& (1 << 23))
1414 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1416 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1417 tcg_gen_mov_i32(dest
, tmp
);
1418 if (insn
& (1 << 21))
1419 store_reg(s
, rd
, tmp
);
1421 tcg_temp_free_i32(tmp
);
1422 } else if (insn
& (1 << 21)) {
1424 tcg_gen_mov_i32(dest
, tmp
);
1425 if (insn
& (1 << 23))
1426 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1428 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1429 store_reg(s
, rd
, tmp
);
1430 } else if (!(insn
& (1 << 23)))
1435 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1437 int rd
= (insn
>> 0) & 0xf;
1440 if (insn
& (1 << 8)) {
1441 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1444 tmp
= iwmmxt_load_creg(rd
);
1447 tmp
= tcg_temp_new_i32();
1448 iwmmxt_load_reg(cpu_V0
, rd
);
1449 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1451 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1452 tcg_gen_mov_i32(dest
, tmp
);
1453 tcg_temp_free_i32(tmp
);
1457 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1458 (ie. an undefined instruction). */
1459 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1462 int rdhi
, rdlo
, rd0
, rd1
, i
;
1464 TCGv_i32 tmp
, tmp2
, tmp3
;
1466 if ((insn
& 0x0e000e00) == 0x0c000000) {
1467 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1469 rdlo
= (insn
>> 12) & 0xf;
1470 rdhi
= (insn
>> 16) & 0xf;
1471 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1472 iwmmxt_load_reg(cpu_V0
, wrd
);
1473 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1474 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1475 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1476 } else { /* TMCRR */
1477 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1478 iwmmxt_store_reg(cpu_V0
, wrd
);
1479 gen_op_iwmmxt_set_mup();
1484 wrd
= (insn
>> 12) & 0xf;
1485 addr
= tcg_temp_new_i32();
1486 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1487 tcg_temp_free_i32(addr
);
1490 if (insn
& ARM_CP_RW_BIT
) {
1491 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1492 tmp
= tcg_temp_new_i32();
1493 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1494 iwmmxt_store_creg(wrd
, tmp
);
1497 if (insn
& (1 << 8)) {
1498 if (insn
& (1 << 22)) { /* WLDRD */
1499 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1501 } else { /* WLDRW wRd */
1502 tmp
= tcg_temp_new_i32();
1503 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1506 tmp
= tcg_temp_new_i32();
1507 if (insn
& (1 << 22)) { /* WLDRH */
1508 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1509 } else { /* WLDRB */
1510 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1514 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1515 tcg_temp_free_i32(tmp
);
1517 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1520 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1521 tmp
= iwmmxt_load_creg(wrd
);
1522 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1524 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1525 tmp
= tcg_temp_new_i32();
1526 if (insn
& (1 << 8)) {
1527 if (insn
& (1 << 22)) { /* WSTRD */
1528 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1529 } else { /* WSTRW wRd */
1530 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1531 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1534 if (insn
& (1 << 22)) { /* WSTRH */
1535 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1536 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1537 } else { /* WSTRB */
1538 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1539 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1543 tcg_temp_free_i32(tmp
);
1545 tcg_temp_free_i32(addr
);
1549 if ((insn
& 0x0f000000) != 0x0e000000)
1552 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1553 case 0x000: /* WOR */
1554 wrd
= (insn
>> 12) & 0xf;
1555 rd0
= (insn
>> 0) & 0xf;
1556 rd1
= (insn
>> 16) & 0xf;
1557 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1558 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1559 gen_op_iwmmxt_setpsr_nz();
1560 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1561 gen_op_iwmmxt_set_mup();
1562 gen_op_iwmmxt_set_cup();
1564 case 0x011: /* TMCR */
1567 rd
= (insn
>> 12) & 0xf;
1568 wrd
= (insn
>> 16) & 0xf;
1570 case ARM_IWMMXT_wCID
:
1571 case ARM_IWMMXT_wCASF
:
1573 case ARM_IWMMXT_wCon
:
1574 gen_op_iwmmxt_set_cup();
1576 case ARM_IWMMXT_wCSSF
:
1577 tmp
= iwmmxt_load_creg(wrd
);
1578 tmp2
= load_reg(s
, rd
);
1579 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1580 tcg_temp_free_i32(tmp2
);
1581 iwmmxt_store_creg(wrd
, tmp
);
1583 case ARM_IWMMXT_wCGR0
:
1584 case ARM_IWMMXT_wCGR1
:
1585 case ARM_IWMMXT_wCGR2
:
1586 case ARM_IWMMXT_wCGR3
:
1587 gen_op_iwmmxt_set_cup();
1588 tmp
= load_reg(s
, rd
);
1589 iwmmxt_store_creg(wrd
, tmp
);
1595 case 0x100: /* WXOR */
1596 wrd
= (insn
>> 12) & 0xf;
1597 rd0
= (insn
>> 0) & 0xf;
1598 rd1
= (insn
>> 16) & 0xf;
1599 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1600 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1601 gen_op_iwmmxt_setpsr_nz();
1602 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1603 gen_op_iwmmxt_set_mup();
1604 gen_op_iwmmxt_set_cup();
1606 case 0x111: /* TMRC */
1609 rd
= (insn
>> 12) & 0xf;
1610 wrd
= (insn
>> 16) & 0xf;
1611 tmp
= iwmmxt_load_creg(wrd
);
1612 store_reg(s
, rd
, tmp
);
1614 case 0x300: /* WANDN */
1615 wrd
= (insn
>> 12) & 0xf;
1616 rd0
= (insn
>> 0) & 0xf;
1617 rd1
= (insn
>> 16) & 0xf;
1618 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1619 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1620 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1621 gen_op_iwmmxt_setpsr_nz();
1622 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1623 gen_op_iwmmxt_set_mup();
1624 gen_op_iwmmxt_set_cup();
1626 case 0x200: /* WAND */
1627 wrd
= (insn
>> 12) & 0xf;
1628 rd0
= (insn
>> 0) & 0xf;
1629 rd1
= (insn
>> 16) & 0xf;
1630 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1631 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1632 gen_op_iwmmxt_setpsr_nz();
1633 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1634 gen_op_iwmmxt_set_mup();
1635 gen_op_iwmmxt_set_cup();
1637 case 0x810: case 0xa10: /* WMADD */
1638 wrd
= (insn
>> 12) & 0xf;
1639 rd0
= (insn
>> 0) & 0xf;
1640 rd1
= (insn
>> 16) & 0xf;
1641 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1642 if (insn
& (1 << 21))
1643 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1645 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1646 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1647 gen_op_iwmmxt_set_mup();
1649 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1650 wrd
= (insn
>> 12) & 0xf;
1651 rd0
= (insn
>> 16) & 0xf;
1652 rd1
= (insn
>> 0) & 0xf;
1653 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1654 switch ((insn
>> 22) & 3) {
1656 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1659 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1662 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1667 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1668 gen_op_iwmmxt_set_mup();
1669 gen_op_iwmmxt_set_cup();
1671 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1672 wrd
= (insn
>> 12) & 0xf;
1673 rd0
= (insn
>> 16) & 0xf;
1674 rd1
= (insn
>> 0) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1676 switch ((insn
>> 22) & 3) {
1678 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1681 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1684 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1691 gen_op_iwmmxt_set_cup();
1693 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1694 wrd
= (insn
>> 12) & 0xf;
1695 rd0
= (insn
>> 16) & 0xf;
1696 rd1
= (insn
>> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1698 if (insn
& (1 << 22))
1699 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1701 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1702 if (!(insn
& (1 << 20)))
1703 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1704 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1705 gen_op_iwmmxt_set_mup();
1707 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1708 wrd
= (insn
>> 12) & 0xf;
1709 rd0
= (insn
>> 16) & 0xf;
1710 rd1
= (insn
>> 0) & 0xf;
1711 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1712 if (insn
& (1 << 21)) {
1713 if (insn
& (1 << 20))
1714 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1716 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1718 if (insn
& (1 << 20))
1719 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1721 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1723 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1724 gen_op_iwmmxt_set_mup();
1726 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1727 wrd
= (insn
>> 12) & 0xf;
1728 rd0
= (insn
>> 16) & 0xf;
1729 rd1
= (insn
>> 0) & 0xf;
1730 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1731 if (insn
& (1 << 21))
1732 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1734 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1735 if (!(insn
& (1 << 20))) {
1736 iwmmxt_load_reg(cpu_V1
, wrd
);
1737 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1739 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1740 gen_op_iwmmxt_set_mup();
1742 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1743 wrd
= (insn
>> 12) & 0xf;
1744 rd0
= (insn
>> 16) & 0xf;
1745 rd1
= (insn
>> 0) & 0xf;
1746 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1747 switch ((insn
>> 22) & 3) {
1749 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1752 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1755 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1760 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1761 gen_op_iwmmxt_set_mup();
1762 gen_op_iwmmxt_set_cup();
1764 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1765 wrd
= (insn
>> 12) & 0xf;
1766 rd0
= (insn
>> 16) & 0xf;
1767 rd1
= (insn
>> 0) & 0xf;
1768 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1769 if (insn
& (1 << 22)) {
1770 if (insn
& (1 << 20))
1771 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1773 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1775 if (insn
& (1 << 20))
1776 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1778 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1781 gen_op_iwmmxt_set_mup();
1782 gen_op_iwmmxt_set_cup();
1784 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1785 wrd
= (insn
>> 12) & 0xf;
1786 rd0
= (insn
>> 16) & 0xf;
1787 rd1
= (insn
>> 0) & 0xf;
1788 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1789 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1790 tcg_gen_andi_i32(tmp
, tmp
, 7);
1791 iwmmxt_load_reg(cpu_V1
, rd1
);
1792 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1793 tcg_temp_free_i32(tmp
);
1794 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1795 gen_op_iwmmxt_set_mup();
1797 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1798 if (((insn
>> 6) & 3) == 3)
1800 rd
= (insn
>> 12) & 0xf;
1801 wrd
= (insn
>> 16) & 0xf;
1802 tmp
= load_reg(s
, rd
);
1803 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1804 switch ((insn
>> 6) & 3) {
1806 tmp2
= tcg_const_i32(0xff);
1807 tmp3
= tcg_const_i32((insn
& 7) << 3);
1810 tmp2
= tcg_const_i32(0xffff);
1811 tmp3
= tcg_const_i32((insn
& 3) << 4);
1814 tmp2
= tcg_const_i32(0xffffffff);
1815 tmp3
= tcg_const_i32((insn
& 1) << 5);
1818 TCGV_UNUSED_I32(tmp2
);
1819 TCGV_UNUSED_I32(tmp3
);
1821 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1822 tcg_temp_free_i32(tmp3
);
1823 tcg_temp_free_i32(tmp2
);
1824 tcg_temp_free_i32(tmp
);
1825 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1826 gen_op_iwmmxt_set_mup();
1828 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1829 rd
= (insn
>> 12) & 0xf;
1830 wrd
= (insn
>> 16) & 0xf;
1831 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1833 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1834 tmp
= tcg_temp_new_i32();
1835 switch ((insn
>> 22) & 3) {
1837 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1838 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1840 tcg_gen_ext8s_i32(tmp
, tmp
);
1842 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1846 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1847 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1849 tcg_gen_ext16s_i32(tmp
, tmp
);
1851 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1855 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1856 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1859 store_reg(s
, rd
, tmp
);
1861 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1862 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1864 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1865 switch ((insn
>> 22) & 3) {
1867 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1870 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1873 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1876 tcg_gen_shli_i32(tmp
, tmp
, 28);
1878 tcg_temp_free_i32(tmp
);
1880 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1881 if (((insn
>> 6) & 3) == 3)
1883 rd
= (insn
>> 12) & 0xf;
1884 wrd
= (insn
>> 16) & 0xf;
1885 tmp
= load_reg(s
, rd
);
1886 switch ((insn
>> 6) & 3) {
1888 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1891 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1894 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1897 tcg_temp_free_i32(tmp
);
1898 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1899 gen_op_iwmmxt_set_mup();
1901 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1902 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1904 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1905 tmp2
= tcg_temp_new_i32();
1906 tcg_gen_mov_i32(tmp2
, tmp
);
1907 switch ((insn
>> 22) & 3) {
1909 for (i
= 0; i
< 7; i
++) {
1910 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1911 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1915 for (i
= 0; i
< 3; i
++) {
1916 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1917 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1921 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1922 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1926 tcg_temp_free_i32(tmp2
);
1927 tcg_temp_free_i32(tmp
);
1929 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1930 wrd
= (insn
>> 12) & 0xf;
1931 rd0
= (insn
>> 16) & 0xf;
1932 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1933 switch ((insn
>> 22) & 3) {
1935 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1938 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1941 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1946 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1947 gen_op_iwmmxt_set_mup();
1949 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1950 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1952 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1953 tmp2
= tcg_temp_new_i32();
1954 tcg_gen_mov_i32(tmp2
, tmp
);
1955 switch ((insn
>> 22) & 3) {
1957 for (i
= 0; i
< 7; i
++) {
1958 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1959 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1963 for (i
= 0; i
< 3; i
++) {
1964 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1965 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1969 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1970 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1974 tcg_temp_free_i32(tmp2
);
1975 tcg_temp_free_i32(tmp
);
1977 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1978 rd
= (insn
>> 12) & 0xf;
1979 rd0
= (insn
>> 16) & 0xf;
1980 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1982 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1983 tmp
= tcg_temp_new_i32();
1984 switch ((insn
>> 22) & 3) {
1986 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1989 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1992 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1995 store_reg(s
, rd
, tmp
);
1997 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1998 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 rd1
= (insn
>> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2003 switch ((insn
>> 22) & 3) {
2005 if (insn
& (1 << 21))
2006 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2008 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2011 if (insn
& (1 << 21))
2012 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2014 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2017 if (insn
& (1 << 21))
2018 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2020 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2025 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2026 gen_op_iwmmxt_set_mup();
2027 gen_op_iwmmxt_set_cup();
2029 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2030 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2031 wrd
= (insn
>> 12) & 0xf;
2032 rd0
= (insn
>> 16) & 0xf;
2033 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2034 switch ((insn
>> 22) & 3) {
2036 if (insn
& (1 << 21))
2037 gen_op_iwmmxt_unpacklsb_M0();
2039 gen_op_iwmmxt_unpacklub_M0();
2042 if (insn
& (1 << 21))
2043 gen_op_iwmmxt_unpacklsw_M0();
2045 gen_op_iwmmxt_unpackluw_M0();
2048 if (insn
& (1 << 21))
2049 gen_op_iwmmxt_unpacklsl_M0();
2051 gen_op_iwmmxt_unpacklul_M0();
2056 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2057 gen_op_iwmmxt_set_mup();
2058 gen_op_iwmmxt_set_cup();
2060 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2061 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2062 wrd
= (insn
>> 12) & 0xf;
2063 rd0
= (insn
>> 16) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2065 switch ((insn
>> 22) & 3) {
2067 if (insn
& (1 << 21))
2068 gen_op_iwmmxt_unpackhsb_M0();
2070 gen_op_iwmmxt_unpackhub_M0();
2073 if (insn
& (1 << 21))
2074 gen_op_iwmmxt_unpackhsw_M0();
2076 gen_op_iwmmxt_unpackhuw_M0();
2079 if (insn
& (1 << 21))
2080 gen_op_iwmmxt_unpackhsl_M0();
2082 gen_op_iwmmxt_unpackhul_M0();
2087 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2091 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2092 case 0x214: case 0x614: case 0xa14: case 0xe14:
2093 if (((insn
>> 22) & 3) == 0)
2095 wrd
= (insn
>> 12) & 0xf;
2096 rd0
= (insn
>> 16) & 0xf;
2097 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2098 tmp
= tcg_temp_new_i32();
2099 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2100 tcg_temp_free_i32(tmp
);
2103 switch ((insn
>> 22) & 3) {
2105 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2111 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2114 tcg_temp_free_i32(tmp
);
2115 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2116 gen_op_iwmmxt_set_mup();
2117 gen_op_iwmmxt_set_cup();
2119 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2120 case 0x014: case 0x414: case 0x814: case 0xc14:
2121 if (((insn
>> 22) & 3) == 0)
2123 wrd
= (insn
>> 12) & 0xf;
2124 rd0
= (insn
>> 16) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2126 tmp
= tcg_temp_new_i32();
2127 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2128 tcg_temp_free_i32(tmp
);
2131 switch ((insn
>> 22) & 3) {
2133 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2139 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2142 tcg_temp_free_i32(tmp
);
2143 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2144 gen_op_iwmmxt_set_mup();
2145 gen_op_iwmmxt_set_cup();
2147 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2148 case 0x114: case 0x514: case 0x914: case 0xd14:
2149 if (((insn
>> 22) & 3) == 0)
2151 wrd
= (insn
>> 12) & 0xf;
2152 rd0
= (insn
>> 16) & 0xf;
2153 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2154 tmp
= tcg_temp_new_i32();
2155 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2156 tcg_temp_free_i32(tmp
);
2159 switch ((insn
>> 22) & 3) {
2161 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2167 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2170 tcg_temp_free_i32(tmp
);
2171 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2172 gen_op_iwmmxt_set_mup();
2173 gen_op_iwmmxt_set_cup();
2175 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2176 case 0x314: case 0x714: case 0xb14: case 0xf14:
2177 if (((insn
>> 22) & 3) == 0)
2179 wrd
= (insn
>> 12) & 0xf;
2180 rd0
= (insn
>> 16) & 0xf;
2181 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2182 tmp
= tcg_temp_new_i32();
2183 switch ((insn
>> 22) & 3) {
2185 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2186 tcg_temp_free_i32(tmp
);
2189 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2192 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2193 tcg_temp_free_i32(tmp
);
2196 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2199 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2200 tcg_temp_free_i32(tmp
);
2203 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2206 tcg_temp_free_i32(tmp
);
2207 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2208 gen_op_iwmmxt_set_mup();
2209 gen_op_iwmmxt_set_cup();
2211 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2212 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2213 wrd
= (insn
>> 12) & 0xf;
2214 rd0
= (insn
>> 16) & 0xf;
2215 rd1
= (insn
>> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2217 switch ((insn
>> 22) & 3) {
2219 if (insn
& (1 << 21))
2220 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2222 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2225 if (insn
& (1 << 21))
2226 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2228 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2231 if (insn
& (1 << 21))
2232 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2234 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2239 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2240 gen_op_iwmmxt_set_mup();
2242 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2243 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2244 wrd
= (insn
>> 12) & 0xf;
2245 rd0
= (insn
>> 16) & 0xf;
2246 rd1
= (insn
>> 0) & 0xf;
2247 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2248 switch ((insn
>> 22) & 3) {
2250 if (insn
& (1 << 21))
2251 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2253 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2256 if (insn
& (1 << 21))
2257 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2259 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2262 if (insn
& (1 << 21))
2263 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2265 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2270 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2271 gen_op_iwmmxt_set_mup();
2273 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2274 case 0x402: case 0x502: case 0x602: case 0x702:
2275 wrd
= (insn
>> 12) & 0xf;
2276 rd0
= (insn
>> 16) & 0xf;
2277 rd1
= (insn
>> 0) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2279 tmp
= tcg_const_i32((insn
>> 20) & 3);
2280 iwmmxt_load_reg(cpu_V1
, rd1
);
2281 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2282 tcg_temp_free_i32(tmp
);
2283 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2284 gen_op_iwmmxt_set_mup();
2286 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2287 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2288 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2289 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2290 wrd
= (insn
>> 12) & 0xf;
2291 rd0
= (insn
>> 16) & 0xf;
2292 rd1
= (insn
>> 0) & 0xf;
2293 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2294 switch ((insn
>> 20) & 0xf) {
2296 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2299 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2302 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2305 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2308 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2311 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2314 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2317 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2320 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2329 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2330 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2331 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2332 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2333 wrd
= (insn
>> 12) & 0xf;
2334 rd0
= (insn
>> 16) & 0xf;
2335 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2336 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2337 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2338 tcg_temp_free_i32(tmp
);
2339 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2340 gen_op_iwmmxt_set_mup();
2341 gen_op_iwmmxt_set_cup();
2343 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2344 case 0x418: case 0x518: case 0x618: case 0x718:
2345 case 0x818: case 0x918: case 0xa18: case 0xb18:
2346 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2347 wrd
= (insn
>> 12) & 0xf;
2348 rd0
= (insn
>> 16) & 0xf;
2349 rd1
= (insn
>> 0) & 0xf;
2350 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2351 switch ((insn
>> 20) & 0xf) {
2353 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2356 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2359 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2362 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2365 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2368 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2371 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2374 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2377 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2382 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2383 gen_op_iwmmxt_set_mup();
2384 gen_op_iwmmxt_set_cup();
2386 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2387 case 0x408: case 0x508: case 0x608: case 0x708:
2388 case 0x808: case 0x908: case 0xa08: case 0xb08:
2389 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2390 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2392 wrd
= (insn
>> 12) & 0xf;
2393 rd0
= (insn
>> 16) & 0xf;
2394 rd1
= (insn
>> 0) & 0xf;
2395 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2396 switch ((insn
>> 22) & 3) {
2398 if (insn
& (1 << 21))
2399 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2401 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2404 if (insn
& (1 << 21))
2405 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2407 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2410 if (insn
& (1 << 21))
2411 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2413 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2416 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2417 gen_op_iwmmxt_set_mup();
2418 gen_op_iwmmxt_set_cup();
2420 case 0x201: case 0x203: case 0x205: case 0x207:
2421 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2422 case 0x211: case 0x213: case 0x215: case 0x217:
2423 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2424 wrd
= (insn
>> 5) & 0xf;
2425 rd0
= (insn
>> 12) & 0xf;
2426 rd1
= (insn
>> 0) & 0xf;
2427 if (rd0
== 0xf || rd1
== 0xf)
2429 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2430 tmp
= load_reg(s
, rd0
);
2431 tmp2
= load_reg(s
, rd1
);
2432 switch ((insn
>> 16) & 0xf) {
2433 case 0x0: /* TMIA */
2434 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2436 case 0x8: /* TMIAPH */
2437 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2439 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2440 if (insn
& (1 << 16))
2441 tcg_gen_shri_i32(tmp
, tmp
, 16);
2442 if (insn
& (1 << 17))
2443 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2444 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2447 tcg_temp_free_i32(tmp2
);
2448 tcg_temp_free_i32(tmp
);
2451 tcg_temp_free_i32(tmp2
);
2452 tcg_temp_free_i32(tmp
);
2453 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2454 gen_op_iwmmxt_set_mup();
2463 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2464 (ie. an undefined instruction). */
2465 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2467 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2470 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2471 /* Multiply with Internal Accumulate Format */
2472 rd0
= (insn
>> 12) & 0xf;
2474 acc
= (insn
>> 5) & 7;
2479 tmp
= load_reg(s
, rd0
);
2480 tmp2
= load_reg(s
, rd1
);
2481 switch ((insn
>> 16) & 0xf) {
2483 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2485 case 0x8: /* MIAPH */
2486 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2488 case 0xc: /* MIABB */
2489 case 0xd: /* MIABT */
2490 case 0xe: /* MIATB */
2491 case 0xf: /* MIATT */
2492 if (insn
& (1 << 16))
2493 tcg_gen_shri_i32(tmp
, tmp
, 16);
2494 if (insn
& (1 << 17))
2495 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2496 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2501 tcg_temp_free_i32(tmp2
);
2502 tcg_temp_free_i32(tmp
);
2504 gen_op_iwmmxt_movq_wRn_M0(acc
);
2508 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2509 /* Internal Accumulator Access Format */
2510 rdhi
= (insn
>> 16) & 0xf;
2511 rdlo
= (insn
>> 12) & 0xf;
2517 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2518 iwmmxt_load_reg(cpu_V0
, acc
);
2519 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2520 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2521 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2522 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2524 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2525 iwmmxt_store_reg(cpu_V0
, acc
);
2533 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2534 #define VFP_SREG(insn, bigbit, smallbit) \
2535 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2536 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2537 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2538 reg = (((insn) >> (bigbit)) & 0x0f) \
2539 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2541 if (insn & (1 << (smallbit))) \
2543 reg = ((insn) >> (bigbit)) & 0x0f; \
2546 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2547 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2548 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2549 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2550 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2551 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2553 /* Move between integer and VFP cores. */
2554 static TCGv_i32
gen_vfp_mrs(void)
2556 TCGv_i32 tmp
= tcg_temp_new_i32();
2557 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2561 static void gen_vfp_msr(TCGv_i32 tmp
)
2563 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2564 tcg_temp_free_i32(tmp
);
2567 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2569 TCGv_i32 tmp
= tcg_temp_new_i32();
2571 tcg_gen_shri_i32(var
, var
, shift
);
2572 tcg_gen_ext8u_i32(var
, var
);
2573 tcg_gen_shli_i32(tmp
, var
, 8);
2574 tcg_gen_or_i32(var
, var
, tmp
);
2575 tcg_gen_shli_i32(tmp
, var
, 16);
2576 tcg_gen_or_i32(var
, var
, tmp
);
2577 tcg_temp_free_i32(tmp
);
2580 static void gen_neon_dup_low16(TCGv_i32 var
)
2582 TCGv_i32 tmp
= tcg_temp_new_i32();
2583 tcg_gen_ext16u_i32(var
, var
);
2584 tcg_gen_shli_i32(tmp
, var
, 16);
2585 tcg_gen_or_i32(var
, var
, tmp
);
2586 tcg_temp_free_i32(tmp
);
2589 static void gen_neon_dup_high16(TCGv_i32 var
)
2591 TCGv_i32 tmp
= tcg_temp_new_i32();
2592 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2593 tcg_gen_shri_i32(tmp
, var
, 16);
2594 tcg_gen_or_i32(var
, var
, tmp
);
2595 tcg_temp_free_i32(tmp
);
2598 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2600 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2601 TCGv_i32 tmp
= tcg_temp_new_i32();
2604 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2605 gen_neon_dup_u8(tmp
, 0);
2608 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2609 gen_neon_dup_low16(tmp
);
2612 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2614 default: /* Avoid compiler warnings. */
2620 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2621 (ie. an undefined instruction). */
2622 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2624 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2630 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2633 if (!s
->vfp_enabled
) {
2634 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2635 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2637 rn
= (insn
>> 16) & 0xf;
2638 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2639 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2642 dp
= ((insn
& 0xf00) == 0xb00);
2643 switch ((insn
>> 24) & 0xf) {
2645 if (insn
& (1 << 4)) {
2646 /* single register transfer */
2647 rd
= (insn
>> 12) & 0xf;
2652 VFP_DREG_N(rn
, insn
);
2655 if (insn
& 0x00c00060
2656 && !arm_feature(env
, ARM_FEATURE_NEON
))
2659 pass
= (insn
>> 21) & 1;
2660 if (insn
& (1 << 22)) {
2662 offset
= ((insn
>> 5) & 3) * 8;
2663 } else if (insn
& (1 << 5)) {
2665 offset
= (insn
& (1 << 6)) ? 16 : 0;
2670 if (insn
& ARM_CP_RW_BIT
) {
2672 tmp
= neon_load_reg(rn
, pass
);
2676 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2677 if (insn
& (1 << 23))
2683 if (insn
& (1 << 23)) {
2685 tcg_gen_shri_i32(tmp
, tmp
, 16);
2691 tcg_gen_sari_i32(tmp
, tmp
, 16);
2700 store_reg(s
, rd
, tmp
);
2703 tmp
= load_reg(s
, rd
);
2704 if (insn
& (1 << 23)) {
2707 gen_neon_dup_u8(tmp
, 0);
2708 } else if (size
== 1) {
2709 gen_neon_dup_low16(tmp
);
2711 for (n
= 0; n
<= pass
* 2; n
++) {
2712 tmp2
= tcg_temp_new_i32();
2713 tcg_gen_mov_i32(tmp2
, tmp
);
2714 neon_store_reg(rn
, n
, tmp2
);
2716 neon_store_reg(rn
, n
, tmp
);
2721 tmp2
= neon_load_reg(rn
, pass
);
2722 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2723 tcg_temp_free_i32(tmp2
);
2726 tmp2
= neon_load_reg(rn
, pass
);
2727 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2728 tcg_temp_free_i32(tmp2
);
2733 neon_store_reg(rn
, pass
, tmp
);
2737 if ((insn
& 0x6f) != 0x00)
2739 rn
= VFP_SREG_N(insn
);
2740 if (insn
& ARM_CP_RW_BIT
) {
2742 if (insn
& (1 << 21)) {
2743 /* system register */
2748 /* VFP2 allows access to FSID from userspace.
2749 VFP3 restricts all id registers to privileged
2752 && arm_feature(env
, ARM_FEATURE_VFP3
))
2754 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2759 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2761 case ARM_VFP_FPINST
:
2762 case ARM_VFP_FPINST2
:
2763 /* Not present in VFP3. */
2765 || arm_feature(env
, ARM_FEATURE_VFP3
))
2767 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2771 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2772 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2774 tmp
= tcg_temp_new_i32();
2775 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2781 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2783 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2789 gen_mov_F0_vreg(0, rn
);
2790 tmp
= gen_vfp_mrs();
2793 /* Set the 4 flag bits in the CPSR. */
2795 tcg_temp_free_i32(tmp
);
2797 store_reg(s
, rd
, tmp
);
2801 if (insn
& (1 << 21)) {
2803 /* system register */
2808 /* Writes are ignored. */
2811 tmp
= load_reg(s
, rd
);
2812 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2813 tcg_temp_free_i32(tmp
);
2819 /* TODO: VFP subarchitecture support.
2820 * For now, keep the EN bit only */
2821 tmp
= load_reg(s
, rd
);
2822 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2823 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2826 case ARM_VFP_FPINST
:
2827 case ARM_VFP_FPINST2
:
2828 tmp
= load_reg(s
, rd
);
2829 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2835 tmp
= load_reg(s
, rd
);
2837 gen_mov_vreg_F0(0, rn
);
2842 /* data processing */
2843 /* The opcode is in bits 23, 21, 20 and 6. */
2844 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2848 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2850 /* rn is register number */
2851 VFP_DREG_N(rn
, insn
);
2854 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2855 /* Integer or single precision destination. */
2856 rd
= VFP_SREG_D(insn
);
2858 VFP_DREG_D(rd
, insn
);
2861 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2862 /* VCVT from int is always from S reg regardless of dp bit.
2863 * VCVT with immediate frac_bits has same format as SREG_M
2865 rm
= VFP_SREG_M(insn
);
2867 VFP_DREG_M(rm
, insn
);
2870 rn
= VFP_SREG_N(insn
);
2871 if (op
== 15 && rn
== 15) {
2872 /* Double precision destination. */
2873 VFP_DREG_D(rd
, insn
);
2875 rd
= VFP_SREG_D(insn
);
2877 /* NB that we implicitly rely on the encoding for the frac_bits
2878 * in VCVT of fixed to float being the same as that of an SREG_M
2880 rm
= VFP_SREG_M(insn
);
2883 veclen
= s
->vec_len
;
2884 if (op
== 15 && rn
> 3)
2887 /* Shut up compiler warnings. */
2898 /* Figure out what type of vector operation this is. */
2899 if ((rd
& bank_mask
) == 0) {
2904 delta_d
= (s
->vec_stride
>> 1) + 1;
2906 delta_d
= s
->vec_stride
+ 1;
2908 if ((rm
& bank_mask
) == 0) {
2909 /* mixed scalar/vector */
2918 /* Load the initial operands. */
2923 /* Integer source */
2924 gen_mov_F0_vreg(0, rm
);
2929 gen_mov_F0_vreg(dp
, rd
);
2930 gen_mov_F1_vreg(dp
, rm
);
2934 /* Compare with zero */
2935 gen_mov_F0_vreg(dp
, rd
);
2946 /* Source and destination the same. */
2947 gen_mov_F0_vreg(dp
, rd
);
2953 /* VCVTB, VCVTT: only present with the halfprec extension,
2954 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2956 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2959 /* Otherwise fall through */
2961 /* One source operand. */
2962 gen_mov_F0_vreg(dp
, rm
);
2966 /* Two source operands. */
2967 gen_mov_F0_vreg(dp
, rn
);
2968 gen_mov_F1_vreg(dp
, rm
);
2972 /* Perform the calculation. */
2974 case 0: /* VMLA: fd + (fn * fm) */
2975 /* Note that order of inputs to the add matters for NaNs */
2977 gen_mov_F0_vreg(dp
, rd
);
2980 case 1: /* VMLS: fd + -(fn * fm) */
2983 gen_mov_F0_vreg(dp
, rd
);
2986 case 2: /* VNMLS: -fd + (fn * fm) */
2987 /* Note that it isn't valid to replace (-A + B) with (B - A)
2988 * or similar plausible looking simplifications
2989 * because this will give wrong results for NaNs.
2992 gen_mov_F0_vreg(dp
, rd
);
2996 case 3: /* VNMLA: -fd + -(fn * fm) */
2999 gen_mov_F0_vreg(dp
, rd
);
3003 case 4: /* mul: fn * fm */
3006 case 5: /* nmul: -(fn * fm) */
3010 case 6: /* add: fn + fm */
3013 case 7: /* sub: fn - fm */
3016 case 8: /* div: fn / fm */
3019 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3020 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3021 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3022 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3023 /* These are fused multiply-add, and must be done as one
3024 * floating point operation with no rounding between the
3025 * multiplication and addition steps.
3026 * NB that doing the negations here as separate steps is
3027 * correct : an input NaN should come out with its sign bit
3028 * flipped if it is a negated-input.
3030 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3038 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3040 frd
= tcg_temp_new_i64();
3041 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3044 gen_helper_vfp_negd(frd
, frd
);
3046 fpst
= get_fpstatus_ptr(0);
3047 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3048 cpu_F1d
, frd
, fpst
);
3049 tcg_temp_free_ptr(fpst
);
3050 tcg_temp_free_i64(frd
);
3056 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3058 frd
= tcg_temp_new_i32();
3059 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3061 gen_helper_vfp_negs(frd
, frd
);
3063 fpst
= get_fpstatus_ptr(0);
3064 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3065 cpu_F1s
, frd
, fpst
);
3066 tcg_temp_free_ptr(fpst
);
3067 tcg_temp_free_i32(frd
);
3070 case 14: /* fconst */
3071 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3074 n
= (insn
<< 12) & 0x80000000;
3075 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3082 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3089 tcg_gen_movi_i32(cpu_F0s
, n
);
3092 case 15: /* extension space */
3106 case 4: /* vcvtb.f32.f16 */
3107 tmp
= gen_vfp_mrs();
3108 tcg_gen_ext16u_i32(tmp
, tmp
);
3109 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3110 tcg_temp_free_i32(tmp
);
3112 case 5: /* vcvtt.f32.f16 */
3113 tmp
= gen_vfp_mrs();
3114 tcg_gen_shri_i32(tmp
, tmp
, 16);
3115 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3116 tcg_temp_free_i32(tmp
);
3118 case 6: /* vcvtb.f16.f32 */
3119 tmp
= tcg_temp_new_i32();
3120 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3121 gen_mov_F0_vreg(0, rd
);
3122 tmp2
= gen_vfp_mrs();
3123 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3124 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3125 tcg_temp_free_i32(tmp2
);
3128 case 7: /* vcvtt.f16.f32 */
3129 tmp
= tcg_temp_new_i32();
3130 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3131 tcg_gen_shli_i32(tmp
, tmp
, 16);
3132 gen_mov_F0_vreg(0, rd
);
3133 tmp2
= gen_vfp_mrs();
3134 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3135 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3136 tcg_temp_free_i32(tmp2
);
3148 case 11: /* cmpez */
3152 case 15: /* single<->double conversion */
3154 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3156 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3158 case 16: /* fuito */
3159 gen_vfp_uito(dp
, 0);
3161 case 17: /* fsito */
3162 gen_vfp_sito(dp
, 0);
3164 case 20: /* fshto */
3165 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3167 gen_vfp_shto(dp
, 16 - rm
, 0);
3169 case 21: /* fslto */
3170 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3172 gen_vfp_slto(dp
, 32 - rm
, 0);
3174 case 22: /* fuhto */
3175 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3177 gen_vfp_uhto(dp
, 16 - rm
, 0);
3179 case 23: /* fulto */
3180 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3182 gen_vfp_ulto(dp
, 32 - rm
, 0);
3184 case 24: /* ftoui */
3185 gen_vfp_toui(dp
, 0);
3187 case 25: /* ftouiz */
3188 gen_vfp_touiz(dp
, 0);
3190 case 26: /* ftosi */
3191 gen_vfp_tosi(dp
, 0);
3193 case 27: /* ftosiz */
3194 gen_vfp_tosiz(dp
, 0);
3196 case 28: /* ftosh */
3197 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3199 gen_vfp_tosh(dp
, 16 - rm
, 0);
3201 case 29: /* ftosl */
3202 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3204 gen_vfp_tosl(dp
, 32 - rm
, 0);
3206 case 30: /* ftouh */
3207 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3209 gen_vfp_touh(dp
, 16 - rm
, 0);
3211 case 31: /* ftoul */
3212 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3214 gen_vfp_toul(dp
, 32 - rm
, 0);
3216 default: /* undefined */
3220 default: /* undefined */
3224 /* Write back the result. */
3225 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3226 ; /* Comparison, do nothing. */
3227 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3228 /* VCVT double to int: always integer result. */
3229 gen_mov_vreg_F0(0, rd
);
3230 else if (op
== 15 && rn
== 15)
3232 gen_mov_vreg_F0(!dp
, rd
);
3234 gen_mov_vreg_F0(dp
, rd
);
3236 /* break out of the loop if we have finished */
3240 if (op
== 15 && delta_m
== 0) {
3241 /* single source one-many */
3243 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3245 gen_mov_vreg_F0(dp
, rd
);
3249 /* Setup the next operands. */
3251 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3255 /* One source operand. */
3256 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3258 gen_mov_F0_vreg(dp
, rm
);
3260 /* Two source operands. */
3261 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3263 gen_mov_F0_vreg(dp
, rn
);
3265 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3267 gen_mov_F1_vreg(dp
, rm
);
3275 if ((insn
& 0x03e00000) == 0x00400000) {
3276 /* two-register transfer */
3277 rn
= (insn
>> 16) & 0xf;
3278 rd
= (insn
>> 12) & 0xf;
3280 VFP_DREG_M(rm
, insn
);
3282 rm
= VFP_SREG_M(insn
);
3285 if (insn
& ARM_CP_RW_BIT
) {
3288 gen_mov_F0_vreg(0, rm
* 2);
3289 tmp
= gen_vfp_mrs();
3290 store_reg(s
, rd
, tmp
);
3291 gen_mov_F0_vreg(0, rm
* 2 + 1);
3292 tmp
= gen_vfp_mrs();
3293 store_reg(s
, rn
, tmp
);
3295 gen_mov_F0_vreg(0, rm
);
3296 tmp
= gen_vfp_mrs();
3297 store_reg(s
, rd
, tmp
);
3298 gen_mov_F0_vreg(0, rm
+ 1);
3299 tmp
= gen_vfp_mrs();
3300 store_reg(s
, rn
, tmp
);
3305 tmp
= load_reg(s
, rd
);
3307 gen_mov_vreg_F0(0, rm
* 2);
3308 tmp
= load_reg(s
, rn
);
3310 gen_mov_vreg_F0(0, rm
* 2 + 1);
3312 tmp
= load_reg(s
, rd
);
3314 gen_mov_vreg_F0(0, rm
);
3315 tmp
= load_reg(s
, rn
);
3317 gen_mov_vreg_F0(0, rm
+ 1);
3322 rn
= (insn
>> 16) & 0xf;
3324 VFP_DREG_D(rd
, insn
);
3326 rd
= VFP_SREG_D(insn
);
3327 if ((insn
& 0x01200000) == 0x01000000) {
3328 /* Single load/store */
3329 offset
= (insn
& 0xff) << 2;
3330 if ((insn
& (1 << 23)) == 0)
3332 if (s
->thumb
&& rn
== 15) {
3333 /* This is actually UNPREDICTABLE */
3334 addr
= tcg_temp_new_i32();
3335 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3337 addr
= load_reg(s
, rn
);
3339 tcg_gen_addi_i32(addr
, addr
, offset
);
3340 if (insn
& (1 << 20)) {
3341 gen_vfp_ld(s
, dp
, addr
);
3342 gen_mov_vreg_F0(dp
, rd
);
3344 gen_mov_F0_vreg(dp
, rd
);
3345 gen_vfp_st(s
, dp
, addr
);
3347 tcg_temp_free_i32(addr
);
3349 /* load/store multiple */
3350 int w
= insn
& (1 << 21);
3352 n
= (insn
>> 1) & 0x7f;
3356 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3357 /* P == U , W == 1 => UNDEF */
3360 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3361 /* UNPREDICTABLE cases for bad immediates: we choose to
3362 * UNDEF to avoid generating huge numbers of TCG ops
3366 if (rn
== 15 && w
) {
3367 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3371 if (s
->thumb
&& rn
== 15) {
3372 /* This is actually UNPREDICTABLE */
3373 addr
= tcg_temp_new_i32();
3374 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3376 addr
= load_reg(s
, rn
);
3378 if (insn
& (1 << 24)) /* pre-decrement */
3379 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3385 for (i
= 0; i
< n
; i
++) {
3386 if (insn
& ARM_CP_RW_BIT
) {
3388 gen_vfp_ld(s
, dp
, addr
);
3389 gen_mov_vreg_F0(dp
, rd
+ i
);
3392 gen_mov_F0_vreg(dp
, rd
+ i
);
3393 gen_vfp_st(s
, dp
, addr
);
3395 tcg_gen_addi_i32(addr
, addr
, offset
);
3399 if (insn
& (1 << 24))
3400 offset
= -offset
* n
;
3401 else if (dp
&& (insn
& 1))
3407 tcg_gen_addi_i32(addr
, addr
, offset
);
3408 store_reg(s
, rn
, addr
);
3410 tcg_temp_free_i32(addr
);
3416 /* Should never happen. */
3422 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3424 TranslationBlock
*tb
;
3427 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3429 gen_set_pc_im(s
, dest
);
3430 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3432 gen_set_pc_im(s
, dest
);
3437 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3439 if (unlikely(s
->singlestep_enabled
)) {
3440 /* An indirect jump so that we still trigger the debug exception. */
3445 gen_goto_tb(s
, 0, dest
);
3446 s
->is_jmp
= DISAS_TB_JUMP
;
3450 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3453 tcg_gen_sari_i32(t0
, t0
, 16);
3457 tcg_gen_sari_i32(t1
, t1
, 16);
3460 tcg_gen_mul_i32(t0
, t0
, t1
);
3463 /* Return the mask of PSR bits set by a MSR instruction. */
3464 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3468 if (flags
& (1 << 0))
3470 if (flags
& (1 << 1))
3472 if (flags
& (1 << 2))
3474 if (flags
& (1 << 3))
3477 /* Mask out undefined bits. */
3478 mask
&= ~CPSR_RESERVED
;
3479 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3481 if (!arm_feature(env
, ARM_FEATURE_V5
))
3482 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3483 if (!arm_feature(env
, ARM_FEATURE_V6
))
3484 mask
&= ~(CPSR_E
| CPSR_GE
);
3485 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3487 /* Mask out execution state bits. */
3490 /* Mask out privileged bits. */
3496 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3497 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3501 /* ??? This is also undefined in system mode. */
3505 tmp
= load_cpu_field(spsr
);
3506 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3507 tcg_gen_andi_i32(t0
, t0
, mask
);
3508 tcg_gen_or_i32(tmp
, tmp
, t0
);
3509 store_cpu_field(tmp
, spsr
);
3511 gen_set_cpsr(t0
, mask
);
3513 tcg_temp_free_i32(t0
);
3518 /* Returns nonzero if access to the PSR is not permitted. */
3519 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3522 tmp
= tcg_temp_new_i32();
3523 tcg_gen_movi_i32(tmp
, val
);
3524 return gen_set_psr(s
, mask
, spsr
, tmp
);
3527 /* Generate an old-style exception return. Marks pc as dead. */
3528 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3531 store_reg(s
, 15, pc
);
3532 tmp
= load_cpu_field(spsr
);
3533 gen_set_cpsr(tmp
, 0xffffffff);
3534 tcg_temp_free_i32(tmp
);
3535 s
->is_jmp
= DISAS_UPDATE
;
3538 /* Generate a v6 exception return. Marks both values as dead. */
3539 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3541 gen_set_cpsr(cpsr
, 0xffffffff);
3542 tcg_temp_free_i32(cpsr
);
3543 store_reg(s
, 15, pc
);
3544 s
->is_jmp
= DISAS_UPDATE
;
3548 gen_set_condexec (DisasContext
*s
)
3550 if (s
->condexec_mask
) {
3551 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3552 TCGv_i32 tmp
= tcg_temp_new_i32();
3553 tcg_gen_movi_i32(tmp
, val
);
3554 store_cpu_field(tmp
, condexec_bits
);
3558 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3560 gen_set_condexec(s
);
3561 gen_set_pc_im(s
, s
->pc
- offset
);
3562 gen_exception(excp
);
3563 s
->is_jmp
= DISAS_JUMP
;
3566 static void gen_nop_hint(DisasContext
*s
, int val
)
3570 gen_set_pc_im(s
, s
->pc
);
3571 s
->is_jmp
= DISAS_WFI
;
3576 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3582 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3584 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3587 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3588 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3589 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3594 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3597 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3598 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3599 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3604 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3605 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3606 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3607 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3608 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3610 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3611 switch ((size << 1) | u) { \
3613 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3616 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3619 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3622 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3625 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3628 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3630 default: return 1; \
3633 #define GEN_NEON_INTEGER_OP(name) do { \
3634 switch ((size << 1) | u) { \
3636 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3639 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3642 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3645 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3648 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3651 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3653 default: return 1; \
3656 static TCGv_i32
neon_load_scratch(int scratch
)
3658 TCGv_i32 tmp
= tcg_temp_new_i32();
3659 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3663 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3665 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3666 tcg_temp_free_i32(var
);
3669 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3673 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3675 gen_neon_dup_high16(tmp
);
3677 gen_neon_dup_low16(tmp
);
3680 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3685 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3688 if (!q
&& size
== 2) {
3691 tmp
= tcg_const_i32(rd
);
3692 tmp2
= tcg_const_i32(rm
);
3696 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3699 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3702 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3710 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3713 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3719 tcg_temp_free_i32(tmp
);
3720 tcg_temp_free_i32(tmp2
);
3724 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3727 if (!q
&& size
== 2) {
3730 tmp
= tcg_const_i32(rd
);
3731 tmp2
= tcg_const_i32(rm
);
3735 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3738 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3741 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3749 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3752 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3758 tcg_temp_free_i32(tmp
);
3759 tcg_temp_free_i32(tmp2
);
3763 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3767 rd
= tcg_temp_new_i32();
3768 tmp
= tcg_temp_new_i32();
3770 tcg_gen_shli_i32(rd
, t0
, 8);
3771 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3772 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3773 tcg_gen_or_i32(rd
, rd
, tmp
);
3775 tcg_gen_shri_i32(t1
, t1
, 8);
3776 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3777 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3778 tcg_gen_or_i32(t1
, t1
, tmp
);
3779 tcg_gen_mov_i32(t0
, rd
);
3781 tcg_temp_free_i32(tmp
);
3782 tcg_temp_free_i32(rd
);
3785 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3789 rd
= tcg_temp_new_i32();
3790 tmp
= tcg_temp_new_i32();
3792 tcg_gen_shli_i32(rd
, t0
, 16);
3793 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3794 tcg_gen_or_i32(rd
, rd
, tmp
);
3795 tcg_gen_shri_i32(t1
, t1
, 16);
3796 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3797 tcg_gen_or_i32(t1
, t1
, tmp
);
3798 tcg_gen_mov_i32(t0
, rd
);
3800 tcg_temp_free_i32(tmp
);
3801 tcg_temp_free_i32(rd
);
3809 } neon_ls_element_type
[11] = {
3823 /* Translate a NEON load/store element instruction. Return nonzero if the
3824 instruction is invalid. */
3825 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3844 if (!s
->vfp_enabled
)
3846 VFP_DREG_D(rd
, insn
);
3847 rn
= (insn
>> 16) & 0xf;
3849 load
= (insn
& (1 << 21)) != 0;
3850 if ((insn
& (1 << 23)) == 0) {
3851 /* Load store all elements. */
3852 op
= (insn
>> 8) & 0xf;
3853 size
= (insn
>> 6) & 3;
3856 /* Catch UNDEF cases for bad values of align field */
3859 if (((insn
>> 5) & 1) == 1) {
3864 if (((insn
>> 4) & 3) == 3) {
3871 nregs
= neon_ls_element_type
[op
].nregs
;
3872 interleave
= neon_ls_element_type
[op
].interleave
;
3873 spacing
= neon_ls_element_type
[op
].spacing
;
3874 if (size
== 3 && (interleave
| spacing
) != 1)
3876 addr
= tcg_temp_new_i32();
3877 load_reg_var(s
, addr
, rn
);
3878 stride
= (1 << size
) * interleave
;
3879 for (reg
= 0; reg
< nregs
; reg
++) {
3880 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3881 load_reg_var(s
, addr
, rn
);
3882 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3883 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3884 load_reg_var(s
, addr
, rn
);
3885 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3888 tmp64
= tcg_temp_new_i64();
3890 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
3891 neon_store_reg64(tmp64
, rd
);
3893 neon_load_reg64(tmp64
, rd
);
3894 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
3896 tcg_temp_free_i64(tmp64
);
3897 tcg_gen_addi_i32(addr
, addr
, stride
);
3899 for (pass
= 0; pass
< 2; pass
++) {
3902 tmp
= tcg_temp_new_i32();
3903 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
3904 neon_store_reg(rd
, pass
, tmp
);
3906 tmp
= neon_load_reg(rd
, pass
);
3907 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
3908 tcg_temp_free_i32(tmp
);
3910 tcg_gen_addi_i32(addr
, addr
, stride
);
3911 } else if (size
== 1) {
3913 tmp
= tcg_temp_new_i32();
3914 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
3915 tcg_gen_addi_i32(addr
, addr
, stride
);
3916 tmp2
= tcg_temp_new_i32();
3917 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
3918 tcg_gen_addi_i32(addr
, addr
, stride
);
3919 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3920 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3921 tcg_temp_free_i32(tmp2
);
3922 neon_store_reg(rd
, pass
, tmp
);
3924 tmp
= neon_load_reg(rd
, pass
);
3925 tmp2
= tcg_temp_new_i32();
3926 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3927 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
3928 tcg_temp_free_i32(tmp
);
3929 tcg_gen_addi_i32(addr
, addr
, stride
);
3930 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
3931 tcg_temp_free_i32(tmp2
);
3932 tcg_gen_addi_i32(addr
, addr
, stride
);
3934 } else /* size == 0 */ {
3936 TCGV_UNUSED_I32(tmp2
);
3937 for (n
= 0; n
< 4; n
++) {
3938 tmp
= tcg_temp_new_i32();
3939 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
3940 tcg_gen_addi_i32(addr
, addr
, stride
);
3944 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3945 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3946 tcg_temp_free_i32(tmp
);
3949 neon_store_reg(rd
, pass
, tmp2
);
3951 tmp2
= neon_load_reg(rd
, pass
);
3952 for (n
= 0; n
< 4; n
++) {
3953 tmp
= tcg_temp_new_i32();
3955 tcg_gen_mov_i32(tmp
, tmp2
);
3957 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3959 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
3960 tcg_temp_free_i32(tmp
);
3961 tcg_gen_addi_i32(addr
, addr
, stride
);
3963 tcg_temp_free_i32(tmp2
);
3970 tcg_temp_free_i32(addr
);
3973 size
= (insn
>> 10) & 3;
3975 /* Load single element to all lanes. */
3976 int a
= (insn
>> 4) & 1;
3980 size
= (insn
>> 6) & 3;
3981 nregs
= ((insn
>> 8) & 3) + 1;
3984 if (nregs
!= 4 || a
== 0) {
3987 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3990 if (nregs
== 1 && a
== 1 && size
== 0) {
3993 if (nregs
== 3 && a
== 1) {
3996 addr
= tcg_temp_new_i32();
3997 load_reg_var(s
, addr
, rn
);
3999 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4000 tmp
= gen_load_and_replicate(s
, addr
, size
);
4001 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4002 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4003 if (insn
& (1 << 5)) {
4004 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4005 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4007 tcg_temp_free_i32(tmp
);
4009 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4010 stride
= (insn
& (1 << 5)) ? 2 : 1;
4011 for (reg
= 0; reg
< nregs
; reg
++) {
4012 tmp
= gen_load_and_replicate(s
, addr
, size
);
4013 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4014 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4015 tcg_temp_free_i32(tmp
);
4016 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4020 tcg_temp_free_i32(addr
);
4021 stride
= (1 << size
) * nregs
;
4023 /* Single element. */
4024 int idx
= (insn
>> 4) & 0xf;
4025 pass
= (insn
>> 7) & 1;
4028 shift
= ((insn
>> 5) & 3) * 8;
4032 shift
= ((insn
>> 6) & 1) * 16;
4033 stride
= (insn
& (1 << 5)) ? 2 : 1;
4037 stride
= (insn
& (1 << 6)) ? 2 : 1;
4042 nregs
= ((insn
>> 8) & 3) + 1;
4043 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4046 if (((idx
& (1 << size
)) != 0) ||
4047 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4052 if ((idx
& 1) != 0) {
4057 if (size
== 2 && (idx
& 2) != 0) {
4062 if ((size
== 2) && ((idx
& 3) == 3)) {
4069 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4070 /* Attempts to write off the end of the register file
4071 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4072 * the neon_load_reg() would write off the end of the array.
4076 addr
= tcg_temp_new_i32();
4077 load_reg_var(s
, addr
, rn
);
4078 for (reg
= 0; reg
< nregs
; reg
++) {
4080 tmp
= tcg_temp_new_i32();
4083 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4086 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4089 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4091 default: /* Avoid compiler warnings. */
4095 tmp2
= neon_load_reg(rd
, pass
);
4096 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4097 shift
, size
? 16 : 8);
4098 tcg_temp_free_i32(tmp2
);
4100 neon_store_reg(rd
, pass
, tmp
);
4101 } else { /* Store */
4102 tmp
= neon_load_reg(rd
, pass
);
4104 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4107 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4110 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4113 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4116 tcg_temp_free_i32(tmp
);
4119 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4121 tcg_temp_free_i32(addr
);
4122 stride
= nregs
* (1 << size
);
4128 base
= load_reg(s
, rn
);
4130 tcg_gen_addi_i32(base
, base
, stride
);
4133 index
= load_reg(s
, rm
);
4134 tcg_gen_add_i32(base
, base
, index
);
4135 tcg_temp_free_i32(index
);
4137 store_reg(s
, rn
, base
);
4142 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4143 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4145 tcg_gen_and_i32(t
, t
, c
);
4146 tcg_gen_andc_i32(f
, f
, c
);
4147 tcg_gen_or_i32(dest
, t
, f
);
4150 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4153 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4154 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4155 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4160 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4163 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4164 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4165 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4170 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4173 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4174 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4175 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4180 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4183 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4184 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4185 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4190 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4196 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4197 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4202 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4203 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4210 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4211 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4216 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4217 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4224 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4228 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4229 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4230 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4235 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4236 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4237 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4241 tcg_temp_free_i32(src
);
4244 static inline void gen_neon_addl(int size
)
4247 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4248 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4249 case 2: tcg_gen_add_i64(CPU_V001
); break;
4254 static inline void gen_neon_subl(int size
)
4257 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4258 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4259 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4264 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4267 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4268 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4270 tcg_gen_neg_i64(var
, var
);
4276 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4279 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4280 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4285 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4290 switch ((size
<< 1) | u
) {
4291 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4292 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4293 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4294 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4296 tmp
= gen_muls_i64_i32(a
, b
);
4297 tcg_gen_mov_i64(dest
, tmp
);
4298 tcg_temp_free_i64(tmp
);
4301 tmp
= gen_mulu_i64_i32(a
, b
);
4302 tcg_gen_mov_i64(dest
, tmp
);
4303 tcg_temp_free_i64(tmp
);
4308 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4309 Don't forget to clean them now. */
4311 tcg_temp_free_i32(a
);
4312 tcg_temp_free_i32(b
);
4316 static void gen_neon_narrow_op(int op
, int u
, int size
,
4317 TCGv_i32 dest
, TCGv_i64 src
)
4321 gen_neon_unarrow_sats(size
, dest
, src
);
4323 gen_neon_narrow(size
, dest
, src
);
4327 gen_neon_narrow_satu(size
, dest
, src
);
4329 gen_neon_narrow_sats(size
, dest
, src
);
4334 /* Symbolic constants for op fields for Neon 3-register same-length.
4335 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4338 #define NEON_3R_VHADD 0
4339 #define NEON_3R_VQADD 1
4340 #define NEON_3R_VRHADD 2
4341 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4342 #define NEON_3R_VHSUB 4
4343 #define NEON_3R_VQSUB 5
4344 #define NEON_3R_VCGT 6
4345 #define NEON_3R_VCGE 7
4346 #define NEON_3R_VSHL 8
4347 #define NEON_3R_VQSHL 9
4348 #define NEON_3R_VRSHL 10
4349 #define NEON_3R_VQRSHL 11
4350 #define NEON_3R_VMAX 12
4351 #define NEON_3R_VMIN 13
4352 #define NEON_3R_VABD 14
4353 #define NEON_3R_VABA 15
4354 #define NEON_3R_VADD_VSUB 16
4355 #define NEON_3R_VTST_VCEQ 17
4356 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4357 #define NEON_3R_VMUL 19
4358 #define NEON_3R_VPMAX 20
4359 #define NEON_3R_VPMIN 21
4360 #define NEON_3R_VQDMULH_VQRDMULH 22
4361 #define NEON_3R_VPADD 23
4362 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4363 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4364 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4365 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4366 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4367 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4368 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4370 static const uint8_t neon_3r_sizes
[] = {
4371 [NEON_3R_VHADD
] = 0x7,
4372 [NEON_3R_VQADD
] = 0xf,
4373 [NEON_3R_VRHADD
] = 0x7,
4374 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4375 [NEON_3R_VHSUB
] = 0x7,
4376 [NEON_3R_VQSUB
] = 0xf,
4377 [NEON_3R_VCGT
] = 0x7,
4378 [NEON_3R_VCGE
] = 0x7,
4379 [NEON_3R_VSHL
] = 0xf,
4380 [NEON_3R_VQSHL
] = 0xf,
4381 [NEON_3R_VRSHL
] = 0xf,
4382 [NEON_3R_VQRSHL
] = 0xf,
4383 [NEON_3R_VMAX
] = 0x7,
4384 [NEON_3R_VMIN
] = 0x7,
4385 [NEON_3R_VABD
] = 0x7,
4386 [NEON_3R_VABA
] = 0x7,
4387 [NEON_3R_VADD_VSUB
] = 0xf,
4388 [NEON_3R_VTST_VCEQ
] = 0x7,
4389 [NEON_3R_VML
] = 0x7,
4390 [NEON_3R_VMUL
] = 0x7,
4391 [NEON_3R_VPMAX
] = 0x7,
4392 [NEON_3R_VPMIN
] = 0x7,
4393 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4394 [NEON_3R_VPADD
] = 0x7,
4395 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4396 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4397 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4398 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4399 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4400 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4401 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4404 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4405 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4408 #define NEON_2RM_VREV64 0
4409 #define NEON_2RM_VREV32 1
4410 #define NEON_2RM_VREV16 2
4411 #define NEON_2RM_VPADDL 4
4412 #define NEON_2RM_VPADDL_U 5
4413 #define NEON_2RM_VCLS 8
4414 #define NEON_2RM_VCLZ 9
4415 #define NEON_2RM_VCNT 10
4416 #define NEON_2RM_VMVN 11
4417 #define NEON_2RM_VPADAL 12
4418 #define NEON_2RM_VPADAL_U 13
4419 #define NEON_2RM_VQABS 14
4420 #define NEON_2RM_VQNEG 15
4421 #define NEON_2RM_VCGT0 16
4422 #define NEON_2RM_VCGE0 17
4423 #define NEON_2RM_VCEQ0 18
4424 #define NEON_2RM_VCLE0 19
4425 #define NEON_2RM_VCLT0 20
4426 #define NEON_2RM_VABS 22
4427 #define NEON_2RM_VNEG 23
4428 #define NEON_2RM_VCGT0_F 24
4429 #define NEON_2RM_VCGE0_F 25
4430 #define NEON_2RM_VCEQ0_F 26
4431 #define NEON_2RM_VCLE0_F 27
4432 #define NEON_2RM_VCLT0_F 28
4433 #define NEON_2RM_VABS_F 30
4434 #define NEON_2RM_VNEG_F 31
4435 #define NEON_2RM_VSWP 32
4436 #define NEON_2RM_VTRN 33
4437 #define NEON_2RM_VUZP 34
4438 #define NEON_2RM_VZIP 35
4439 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4440 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4441 #define NEON_2RM_VSHLL 38
4442 #define NEON_2RM_VCVT_F16_F32 44
4443 #define NEON_2RM_VCVT_F32_F16 46
4444 #define NEON_2RM_VRECPE 56
4445 #define NEON_2RM_VRSQRTE 57
4446 #define NEON_2RM_VRECPE_F 58
4447 #define NEON_2RM_VRSQRTE_F 59
4448 #define NEON_2RM_VCVT_FS 60
4449 #define NEON_2RM_VCVT_FU 61
4450 #define NEON_2RM_VCVT_SF 62
4451 #define NEON_2RM_VCVT_UF 63
4453 static int neon_2rm_is_float_op(int op
)
4455 /* Return true if this neon 2reg-misc op is float-to-float */
4456 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4457 op
>= NEON_2RM_VRECPE_F
);
4460 /* Each entry in this array has bit n set if the insn allows
4461 * size value n (otherwise it will UNDEF). Since unallocated
4462 * op values will have no bits set they always UNDEF.
4464 static const uint8_t neon_2rm_sizes
[] = {
4465 [NEON_2RM_VREV64
] = 0x7,
4466 [NEON_2RM_VREV32
] = 0x3,
4467 [NEON_2RM_VREV16
] = 0x1,
4468 [NEON_2RM_VPADDL
] = 0x7,
4469 [NEON_2RM_VPADDL_U
] = 0x7,
4470 [NEON_2RM_VCLS
] = 0x7,
4471 [NEON_2RM_VCLZ
] = 0x7,
4472 [NEON_2RM_VCNT
] = 0x1,
4473 [NEON_2RM_VMVN
] = 0x1,
4474 [NEON_2RM_VPADAL
] = 0x7,
4475 [NEON_2RM_VPADAL_U
] = 0x7,
4476 [NEON_2RM_VQABS
] = 0x7,
4477 [NEON_2RM_VQNEG
] = 0x7,
4478 [NEON_2RM_VCGT0
] = 0x7,
4479 [NEON_2RM_VCGE0
] = 0x7,
4480 [NEON_2RM_VCEQ0
] = 0x7,
4481 [NEON_2RM_VCLE0
] = 0x7,
4482 [NEON_2RM_VCLT0
] = 0x7,
4483 [NEON_2RM_VABS
] = 0x7,
4484 [NEON_2RM_VNEG
] = 0x7,
4485 [NEON_2RM_VCGT0_F
] = 0x4,
4486 [NEON_2RM_VCGE0_F
] = 0x4,
4487 [NEON_2RM_VCEQ0_F
] = 0x4,
4488 [NEON_2RM_VCLE0_F
] = 0x4,
4489 [NEON_2RM_VCLT0_F
] = 0x4,
4490 [NEON_2RM_VABS_F
] = 0x4,
4491 [NEON_2RM_VNEG_F
] = 0x4,
4492 [NEON_2RM_VSWP
] = 0x1,
4493 [NEON_2RM_VTRN
] = 0x7,
4494 [NEON_2RM_VUZP
] = 0x7,
4495 [NEON_2RM_VZIP
] = 0x7,
4496 [NEON_2RM_VMOVN
] = 0x7,
4497 [NEON_2RM_VQMOVN
] = 0x7,
4498 [NEON_2RM_VSHLL
] = 0x7,
4499 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4500 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4501 [NEON_2RM_VRECPE
] = 0x4,
4502 [NEON_2RM_VRSQRTE
] = 0x4,
4503 [NEON_2RM_VRECPE_F
] = 0x4,
4504 [NEON_2RM_VRSQRTE_F
] = 0x4,
4505 [NEON_2RM_VCVT_FS
] = 0x4,
4506 [NEON_2RM_VCVT_FU
] = 0x4,
4507 [NEON_2RM_VCVT_SF
] = 0x4,
4508 [NEON_2RM_VCVT_UF
] = 0x4,
4511 /* Translate a NEON data processing instruction. Return nonzero if the
4512 instruction is invalid.
4513 We process data in a mixture of 32-bit and 64-bit chunks.
4514 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4516 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4528 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4531 if (!s
->vfp_enabled
)
4533 q
= (insn
& (1 << 6)) != 0;
4534 u
= (insn
>> 24) & 1;
4535 VFP_DREG_D(rd
, insn
);
4536 VFP_DREG_N(rn
, insn
);
4537 VFP_DREG_M(rm
, insn
);
4538 size
= (insn
>> 20) & 3;
4539 if ((insn
& (1 << 23)) == 0) {
4540 /* Three register same length. */
4541 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4542 /* Catch invalid op and bad size combinations: UNDEF */
4543 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4546 /* All insns of this form UNDEF for either this condition or the
4547 * superset of cases "Q==1"; we catch the latter later.
4549 if (q
&& ((rd
| rn
| rm
) & 1)) {
4552 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4553 /* 64-bit element instructions. */
4554 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4555 neon_load_reg64(cpu_V0
, rn
+ pass
);
4556 neon_load_reg64(cpu_V1
, rm
+ pass
);
4560 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4563 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4569 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4572 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4578 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4580 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4585 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4588 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4594 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4596 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4599 case NEON_3R_VQRSHL
:
4601 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4604 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4608 case NEON_3R_VADD_VSUB
:
4610 tcg_gen_sub_i64(CPU_V001
);
4612 tcg_gen_add_i64(CPU_V001
);
4618 neon_store_reg64(cpu_V0
, rd
+ pass
);
4627 case NEON_3R_VQRSHL
:
4630 /* Shift instruction operands are reversed. */
4645 case NEON_3R_FLOAT_ARITH
:
4646 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4648 case NEON_3R_FLOAT_MINMAX
:
4649 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4651 case NEON_3R_FLOAT_CMP
:
4653 /* no encoding for U=0 C=1x */
4657 case NEON_3R_FLOAT_ACMP
:
4662 case NEON_3R_VRECPS_VRSQRTS
:
4668 if (u
&& (size
!= 0)) {
4669 /* UNDEF on invalid size for polynomial subcase */
4674 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4682 if (pairwise
&& q
) {
4683 /* All the pairwise insns UNDEF if Q is set */
4687 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4692 tmp
= neon_load_reg(rn
, 0);
4693 tmp2
= neon_load_reg(rn
, 1);
4695 tmp
= neon_load_reg(rm
, 0);
4696 tmp2
= neon_load_reg(rm
, 1);
4700 tmp
= neon_load_reg(rn
, pass
);
4701 tmp2
= neon_load_reg(rm
, pass
);
4705 GEN_NEON_INTEGER_OP(hadd
);
4708 GEN_NEON_INTEGER_OP_ENV(qadd
);
4710 case NEON_3R_VRHADD
:
4711 GEN_NEON_INTEGER_OP(rhadd
);
4713 case NEON_3R_LOGIC
: /* Logic ops. */
4714 switch ((u
<< 2) | size
) {
4716 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4719 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4722 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4725 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4728 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4731 tmp3
= neon_load_reg(rd
, pass
);
4732 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4733 tcg_temp_free_i32(tmp3
);
4736 tmp3
= neon_load_reg(rd
, pass
);
4737 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4738 tcg_temp_free_i32(tmp3
);
4741 tmp3
= neon_load_reg(rd
, pass
);
4742 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4743 tcg_temp_free_i32(tmp3
);
4748 GEN_NEON_INTEGER_OP(hsub
);
4751 GEN_NEON_INTEGER_OP_ENV(qsub
);
4754 GEN_NEON_INTEGER_OP(cgt
);
4757 GEN_NEON_INTEGER_OP(cge
);
4760 GEN_NEON_INTEGER_OP(shl
);
4763 GEN_NEON_INTEGER_OP_ENV(qshl
);
4766 GEN_NEON_INTEGER_OP(rshl
);
4768 case NEON_3R_VQRSHL
:
4769 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4772 GEN_NEON_INTEGER_OP(max
);
4775 GEN_NEON_INTEGER_OP(min
);
4778 GEN_NEON_INTEGER_OP(abd
);
4781 GEN_NEON_INTEGER_OP(abd
);
4782 tcg_temp_free_i32(tmp2
);
4783 tmp2
= neon_load_reg(rd
, pass
);
4784 gen_neon_add(size
, tmp
, tmp2
);
4786 case NEON_3R_VADD_VSUB
:
4787 if (!u
) { /* VADD */
4788 gen_neon_add(size
, tmp
, tmp2
);
4791 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4792 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4793 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4798 case NEON_3R_VTST_VCEQ
:
4799 if (!u
) { /* VTST */
4801 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4802 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4803 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4808 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4809 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4810 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4815 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4817 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4818 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4819 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4822 tcg_temp_free_i32(tmp2
);
4823 tmp2
= neon_load_reg(rd
, pass
);
4825 gen_neon_rsb(size
, tmp
, tmp2
);
4827 gen_neon_add(size
, tmp
, tmp2
);
4831 if (u
) { /* polynomial */
4832 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4833 } else { /* Integer */
4835 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4836 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4837 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4843 GEN_NEON_INTEGER_OP(pmax
);
4846 GEN_NEON_INTEGER_OP(pmin
);
4848 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4849 if (!u
) { /* VQDMULH */
4852 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4855 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4859 } else { /* VQRDMULH */
4862 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4865 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4873 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4874 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4875 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4879 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4881 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4882 switch ((u
<< 2) | size
) {
4885 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4888 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4891 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4896 tcg_temp_free_ptr(fpstatus
);
4899 case NEON_3R_FLOAT_MULTIPLY
:
4901 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4902 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4904 tcg_temp_free_i32(tmp2
);
4905 tmp2
= neon_load_reg(rd
, pass
);
4907 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4909 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4912 tcg_temp_free_ptr(fpstatus
);
4915 case NEON_3R_FLOAT_CMP
:
4917 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4919 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4922 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4924 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4927 tcg_temp_free_ptr(fpstatus
);
4930 case NEON_3R_FLOAT_ACMP
:
4932 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4934 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4936 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4938 tcg_temp_free_ptr(fpstatus
);
4941 case NEON_3R_FLOAT_MINMAX
:
4943 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4945 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4947 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4949 tcg_temp_free_ptr(fpstatus
);
4952 case NEON_3R_VRECPS_VRSQRTS
:
4954 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4956 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4960 /* VFMA, VFMS: fused multiply-add */
4961 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4962 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4965 gen_helper_vfp_negs(tmp
, tmp
);
4967 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4968 tcg_temp_free_i32(tmp3
);
4969 tcg_temp_free_ptr(fpstatus
);
4975 tcg_temp_free_i32(tmp2
);
4977 /* Save the result. For elementwise operations we can put it
4978 straight into the destination register. For pairwise operations
4979 we have to be careful to avoid clobbering the source operands. */
4980 if (pairwise
&& rd
== rm
) {
4981 neon_store_scratch(pass
, tmp
);
4983 neon_store_reg(rd
, pass
, tmp
);
4987 if (pairwise
&& rd
== rm
) {
4988 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4989 tmp
= neon_load_scratch(pass
);
4990 neon_store_reg(rd
, pass
, tmp
);
4993 /* End of 3 register same size operations. */
4994 } else if (insn
& (1 << 4)) {
4995 if ((insn
& 0x00380080) != 0) {
4996 /* Two registers and shift. */
4997 op
= (insn
>> 8) & 0xf;
4998 if (insn
& (1 << 7)) {
5006 while ((insn
& (1 << (size
+ 19))) == 0)
5009 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5010 /* To avoid excessive duplication of ops we implement shift
5011 by immediate using the variable shift operations. */
5013 /* Shift by immediate:
5014 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5015 if (q
&& ((rd
| rm
) & 1)) {
5018 if (!u
&& (op
== 4 || op
== 6)) {
5021 /* Right shifts are encoded as N - shift, where N is the
5022 element size in bits. */
5024 shift
= shift
- (1 << (size
+ 3));
5032 imm
= (uint8_t) shift
;
5037 imm
= (uint16_t) shift
;
5048 for (pass
= 0; pass
< count
; pass
++) {
5050 neon_load_reg64(cpu_V0
, rm
+ pass
);
5051 tcg_gen_movi_i64(cpu_V1
, imm
);
5056 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5058 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5063 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5065 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5068 case 5: /* VSHL, VSLI */
5069 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5071 case 6: /* VQSHLU */
5072 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5077 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5080 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5085 if (op
== 1 || op
== 3) {
5087 neon_load_reg64(cpu_V1
, rd
+ pass
);
5088 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5089 } else if (op
== 4 || (op
== 5 && u
)) {
5091 neon_load_reg64(cpu_V1
, rd
+ pass
);
5093 if (shift
< -63 || shift
> 63) {
5097 mask
= 0xffffffffffffffffull
>> -shift
;
5099 mask
= 0xffffffffffffffffull
<< shift
;
5102 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5103 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5105 neon_store_reg64(cpu_V0
, rd
+ pass
);
5106 } else { /* size < 3 */
5107 /* Operands in T0 and T1. */
5108 tmp
= neon_load_reg(rm
, pass
);
5109 tmp2
= tcg_temp_new_i32();
5110 tcg_gen_movi_i32(tmp2
, imm
);
5114 GEN_NEON_INTEGER_OP(shl
);
5118 GEN_NEON_INTEGER_OP(rshl
);
5121 case 5: /* VSHL, VSLI */
5123 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5124 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5125 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5129 case 6: /* VQSHLU */
5132 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5136 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5140 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5148 GEN_NEON_INTEGER_OP_ENV(qshl
);
5151 tcg_temp_free_i32(tmp2
);
5153 if (op
== 1 || op
== 3) {
5155 tmp2
= neon_load_reg(rd
, pass
);
5156 gen_neon_add(size
, tmp
, tmp2
);
5157 tcg_temp_free_i32(tmp2
);
5158 } else if (op
== 4 || (op
== 5 && u
)) {
5163 mask
= 0xff >> -shift
;
5165 mask
= (uint8_t)(0xff << shift
);
5171 mask
= 0xffff >> -shift
;
5173 mask
= (uint16_t)(0xffff << shift
);
5177 if (shift
< -31 || shift
> 31) {
5181 mask
= 0xffffffffu
>> -shift
;
5183 mask
= 0xffffffffu
<< shift
;
5189 tmp2
= neon_load_reg(rd
, pass
);
5190 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5191 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5192 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5193 tcg_temp_free_i32(tmp2
);
5195 neon_store_reg(rd
, pass
, tmp
);
5198 } else if (op
< 10) {
5199 /* Shift by immediate and narrow:
5200 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5201 int input_unsigned
= (op
== 8) ? !u
: u
;
5205 shift
= shift
- (1 << (size
+ 3));
5208 tmp64
= tcg_const_i64(shift
);
5209 neon_load_reg64(cpu_V0
, rm
);
5210 neon_load_reg64(cpu_V1
, rm
+ 1);
5211 for (pass
= 0; pass
< 2; pass
++) {
5219 if (input_unsigned
) {
5220 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5222 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5225 if (input_unsigned
) {
5226 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5228 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5231 tmp
= tcg_temp_new_i32();
5232 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5233 neon_store_reg(rd
, pass
, tmp
);
5235 tcg_temp_free_i64(tmp64
);
5238 imm
= (uint16_t)shift
;
5242 imm
= (uint32_t)shift
;
5244 tmp2
= tcg_const_i32(imm
);
5245 tmp4
= neon_load_reg(rm
+ 1, 0);
5246 tmp5
= neon_load_reg(rm
+ 1, 1);
5247 for (pass
= 0; pass
< 2; pass
++) {
5249 tmp
= neon_load_reg(rm
, 0);
5253 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5256 tmp3
= neon_load_reg(rm
, 1);
5260 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5262 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5263 tcg_temp_free_i32(tmp
);
5264 tcg_temp_free_i32(tmp3
);
5265 tmp
= tcg_temp_new_i32();
5266 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5267 neon_store_reg(rd
, pass
, tmp
);
5269 tcg_temp_free_i32(tmp2
);
5271 } else if (op
== 10) {
5273 if (q
|| (rd
& 1)) {
5276 tmp
= neon_load_reg(rm
, 0);
5277 tmp2
= neon_load_reg(rm
, 1);
5278 for (pass
= 0; pass
< 2; pass
++) {
5282 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5285 /* The shift is less than the width of the source
5286 type, so we can just shift the whole register. */
5287 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5288 /* Widen the result of shift: we need to clear
5289 * the potential overflow bits resulting from
5290 * left bits of the narrow input appearing as
5291 * right bits of left the neighbour narrow
5293 if (size
< 2 || !u
) {
5296 imm
= (0xffu
>> (8 - shift
));
5298 } else if (size
== 1) {
5299 imm
= 0xffff >> (16 - shift
);
5302 imm
= 0xffffffff >> (32 - shift
);
5305 imm64
= imm
| (((uint64_t)imm
) << 32);
5309 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5312 neon_store_reg64(cpu_V0
, rd
+ pass
);
5314 } else if (op
>= 14) {
5315 /* VCVT fixed-point. */
5316 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5319 /* We have already masked out the must-be-1 top bit of imm6,
5320 * hence this 32-shift where the ARM ARM has 64-imm6.
5323 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5324 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5327 gen_vfp_ulto(0, shift
, 1);
5329 gen_vfp_slto(0, shift
, 1);
5332 gen_vfp_toul(0, shift
, 1);
5334 gen_vfp_tosl(0, shift
, 1);
5336 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5341 } else { /* (insn & 0x00380080) == 0 */
5343 if (q
&& (rd
& 1)) {
5347 op
= (insn
>> 8) & 0xf;
5348 /* One register and immediate. */
5349 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5350 invert
= (insn
& (1 << 5)) != 0;
5351 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5352 * We choose to not special-case this and will behave as if a
5353 * valid constant encoding of 0 had been given.
5372 imm
= (imm
<< 8) | (imm
<< 24);
5375 imm
= (imm
<< 8) | 0xff;
5378 imm
= (imm
<< 16) | 0xffff;
5381 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5389 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5390 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5396 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5397 if (op
& 1 && op
< 12) {
5398 tmp
= neon_load_reg(rd
, pass
);
5400 /* The immediate value has already been inverted, so
5402 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5404 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5408 tmp
= tcg_temp_new_i32();
5409 if (op
== 14 && invert
) {
5413 for (n
= 0; n
< 4; n
++) {
5414 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5415 val
|= 0xff << (n
* 8);
5417 tcg_gen_movi_i32(tmp
, val
);
5419 tcg_gen_movi_i32(tmp
, imm
);
5422 neon_store_reg(rd
, pass
, tmp
);
5425 } else { /* (insn & 0x00800010 == 0x00800000) */
5427 op
= (insn
>> 8) & 0xf;
5428 if ((insn
& (1 << 6)) == 0) {
5429 /* Three registers of different lengths. */
5433 /* undefreq: bit 0 : UNDEF if size != 0
5434 * bit 1 : UNDEF if size == 0
5435 * bit 2 : UNDEF if U == 1
5436 * Note that [1:0] set implies 'always UNDEF'
5439 /* prewiden, src1_wide, src2_wide, undefreq */
5440 static const int neon_3reg_wide
[16][4] = {
5441 {1, 0, 0, 0}, /* VADDL */
5442 {1, 1, 0, 0}, /* VADDW */
5443 {1, 0, 0, 0}, /* VSUBL */
5444 {1, 1, 0, 0}, /* VSUBW */
5445 {0, 1, 1, 0}, /* VADDHN */
5446 {0, 0, 0, 0}, /* VABAL */
5447 {0, 1, 1, 0}, /* VSUBHN */
5448 {0, 0, 0, 0}, /* VABDL */
5449 {0, 0, 0, 0}, /* VMLAL */
5450 {0, 0, 0, 6}, /* VQDMLAL */
5451 {0, 0, 0, 0}, /* VMLSL */
5452 {0, 0, 0, 6}, /* VQDMLSL */
5453 {0, 0, 0, 0}, /* Integer VMULL */
5454 {0, 0, 0, 2}, /* VQDMULL */
5455 {0, 0, 0, 5}, /* Polynomial VMULL */
5456 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5459 prewiden
= neon_3reg_wide
[op
][0];
5460 src1_wide
= neon_3reg_wide
[op
][1];
5461 src2_wide
= neon_3reg_wide
[op
][2];
5462 undefreq
= neon_3reg_wide
[op
][3];
5464 if (((undefreq
& 1) && (size
!= 0)) ||
5465 ((undefreq
& 2) && (size
== 0)) ||
5466 ((undefreq
& 4) && u
)) {
5469 if ((src1_wide
&& (rn
& 1)) ||
5470 (src2_wide
&& (rm
& 1)) ||
5471 (!src2_wide
&& (rd
& 1))) {
5475 /* Avoid overlapping operands. Wide source operands are
5476 always aligned so will never overlap with wide
5477 destinations in problematic ways. */
5478 if (rd
== rm
&& !src2_wide
) {
5479 tmp
= neon_load_reg(rm
, 1);
5480 neon_store_scratch(2, tmp
);
5481 } else if (rd
== rn
&& !src1_wide
) {
5482 tmp
= neon_load_reg(rn
, 1);
5483 neon_store_scratch(2, tmp
);
5485 TCGV_UNUSED_I32(tmp3
);
5486 for (pass
= 0; pass
< 2; pass
++) {
5488 neon_load_reg64(cpu_V0
, rn
+ pass
);
5489 TCGV_UNUSED_I32(tmp
);
5491 if (pass
== 1 && rd
== rn
) {
5492 tmp
= neon_load_scratch(2);
5494 tmp
= neon_load_reg(rn
, pass
);
5497 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5501 neon_load_reg64(cpu_V1
, rm
+ pass
);
5502 TCGV_UNUSED_I32(tmp2
);
5504 if (pass
== 1 && rd
== rm
) {
5505 tmp2
= neon_load_scratch(2);
5507 tmp2
= neon_load_reg(rm
, pass
);
5510 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5514 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5515 gen_neon_addl(size
);
5517 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5518 gen_neon_subl(size
);
5520 case 5: case 7: /* VABAL, VABDL */
5521 switch ((size
<< 1) | u
) {
5523 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5526 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5529 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5532 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5535 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5538 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5542 tcg_temp_free_i32(tmp2
);
5543 tcg_temp_free_i32(tmp
);
5545 case 8: case 9: case 10: case 11: case 12: case 13:
5546 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5547 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5549 case 14: /* Polynomial VMULL */
5550 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5551 tcg_temp_free_i32(tmp2
);
5552 tcg_temp_free_i32(tmp
);
5554 default: /* 15 is RESERVED: caught earlier */
5559 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5560 neon_store_reg64(cpu_V0
, rd
+ pass
);
5561 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5563 neon_load_reg64(cpu_V1
, rd
+ pass
);
5565 case 10: /* VMLSL */
5566 gen_neon_negl(cpu_V0
, size
);
5568 case 5: case 8: /* VABAL, VMLAL */
5569 gen_neon_addl(size
);
5571 case 9: case 11: /* VQDMLAL, VQDMLSL */
5572 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5574 gen_neon_negl(cpu_V0
, size
);
5576 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5581 neon_store_reg64(cpu_V0
, rd
+ pass
);
5582 } else if (op
== 4 || op
== 6) {
5583 /* Narrowing operation. */
5584 tmp
= tcg_temp_new_i32();
5588 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5591 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5594 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5595 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5602 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5605 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5608 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5609 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5610 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5618 neon_store_reg(rd
, 0, tmp3
);
5619 neon_store_reg(rd
, 1, tmp
);
5622 /* Write back the result. */
5623 neon_store_reg64(cpu_V0
, rd
+ pass
);
5627 /* Two registers and a scalar. NB that for ops of this form
5628 * the ARM ARM labels bit 24 as Q, but it is in our variable
5635 case 1: /* Float VMLA scalar */
5636 case 5: /* Floating point VMLS scalar */
5637 case 9: /* Floating point VMUL scalar */
5642 case 0: /* Integer VMLA scalar */
5643 case 4: /* Integer VMLS scalar */
5644 case 8: /* Integer VMUL scalar */
5645 case 12: /* VQDMULH scalar */
5646 case 13: /* VQRDMULH scalar */
5647 if (u
&& ((rd
| rn
) & 1)) {
5650 tmp
= neon_get_scalar(size
, rm
);
5651 neon_store_scratch(0, tmp
);
5652 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5653 tmp
= neon_load_scratch(0);
5654 tmp2
= neon_load_reg(rn
, pass
);
5657 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5659 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5661 } else if (op
== 13) {
5663 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5665 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5667 } else if (op
& 1) {
5668 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5669 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5670 tcg_temp_free_ptr(fpstatus
);
5673 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5674 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5675 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5679 tcg_temp_free_i32(tmp2
);
5682 tmp2
= neon_load_reg(rd
, pass
);
5685 gen_neon_add(size
, tmp
, tmp2
);
5689 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5690 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5691 tcg_temp_free_ptr(fpstatus
);
5695 gen_neon_rsb(size
, tmp
, tmp2
);
5699 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5700 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5701 tcg_temp_free_ptr(fpstatus
);
5707 tcg_temp_free_i32(tmp2
);
5709 neon_store_reg(rd
, pass
, tmp
);
5712 case 3: /* VQDMLAL scalar */
5713 case 7: /* VQDMLSL scalar */
5714 case 11: /* VQDMULL scalar */
5719 case 2: /* VMLAL sclar */
5720 case 6: /* VMLSL scalar */
5721 case 10: /* VMULL scalar */
5725 tmp2
= neon_get_scalar(size
, rm
);
5726 /* We need a copy of tmp2 because gen_neon_mull
5727 * deletes it during pass 0. */
5728 tmp4
= tcg_temp_new_i32();
5729 tcg_gen_mov_i32(tmp4
, tmp2
);
5730 tmp3
= neon_load_reg(rn
, 1);
5732 for (pass
= 0; pass
< 2; pass
++) {
5734 tmp
= neon_load_reg(rn
, 0);
5739 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5741 neon_load_reg64(cpu_V1
, rd
+ pass
);
5745 gen_neon_negl(cpu_V0
, size
);
5748 gen_neon_addl(size
);
5751 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5753 gen_neon_negl(cpu_V0
, size
);
5755 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5761 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5766 neon_store_reg64(cpu_V0
, rd
+ pass
);
5771 default: /* 14 and 15 are RESERVED */
5775 } else { /* size == 3 */
5778 imm
= (insn
>> 8) & 0xf;
5783 if (q
&& ((rd
| rn
| rm
) & 1)) {
5788 neon_load_reg64(cpu_V0
, rn
);
5790 neon_load_reg64(cpu_V1
, rn
+ 1);
5792 } else if (imm
== 8) {
5793 neon_load_reg64(cpu_V0
, rn
+ 1);
5795 neon_load_reg64(cpu_V1
, rm
);
5798 tmp64
= tcg_temp_new_i64();
5800 neon_load_reg64(cpu_V0
, rn
);
5801 neon_load_reg64(tmp64
, rn
+ 1);
5803 neon_load_reg64(cpu_V0
, rn
+ 1);
5804 neon_load_reg64(tmp64
, rm
);
5806 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5807 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5808 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5810 neon_load_reg64(cpu_V1
, rm
);
5812 neon_load_reg64(cpu_V1
, rm
+ 1);
5815 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5816 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5817 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5818 tcg_temp_free_i64(tmp64
);
5821 neon_load_reg64(cpu_V0
, rn
);
5822 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5823 neon_load_reg64(cpu_V1
, rm
);
5824 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5825 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5827 neon_store_reg64(cpu_V0
, rd
);
5829 neon_store_reg64(cpu_V1
, rd
+ 1);
5831 } else if ((insn
& (1 << 11)) == 0) {
5832 /* Two register misc. */
5833 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5834 size
= (insn
>> 18) & 3;
5835 /* UNDEF for unknown op values and bad op-size combinations */
5836 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5839 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5840 q
&& ((rm
| rd
) & 1)) {
5844 case NEON_2RM_VREV64
:
5845 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5846 tmp
= neon_load_reg(rm
, pass
* 2);
5847 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5849 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5850 case 1: gen_swap_half(tmp
); break;
5851 case 2: /* no-op */ break;
5854 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5856 neon_store_reg(rd
, pass
* 2, tmp2
);
5859 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5860 case 1: gen_swap_half(tmp2
); break;
5863 neon_store_reg(rd
, pass
* 2, tmp2
);
5867 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5868 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5869 for (pass
= 0; pass
< q
+ 1; pass
++) {
5870 tmp
= neon_load_reg(rm
, pass
* 2);
5871 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5872 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5873 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5875 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5876 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5877 case 2: tcg_gen_add_i64(CPU_V001
); break;
5880 if (op
>= NEON_2RM_VPADAL
) {
5882 neon_load_reg64(cpu_V1
, rd
+ pass
);
5883 gen_neon_addl(size
);
5885 neon_store_reg64(cpu_V0
, rd
+ pass
);
5891 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5892 tmp
= neon_load_reg(rm
, n
);
5893 tmp2
= neon_load_reg(rd
, n
+ 1);
5894 neon_store_reg(rm
, n
, tmp2
);
5895 neon_store_reg(rd
, n
+ 1, tmp
);
5902 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5907 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5911 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5912 /* also VQMOVUN; op field and mnemonics don't line up */
5916 TCGV_UNUSED_I32(tmp2
);
5917 for (pass
= 0; pass
< 2; pass
++) {
5918 neon_load_reg64(cpu_V0
, rm
+ pass
);
5919 tmp
= tcg_temp_new_i32();
5920 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5925 neon_store_reg(rd
, 0, tmp2
);
5926 neon_store_reg(rd
, 1, tmp
);
5930 case NEON_2RM_VSHLL
:
5931 if (q
|| (rd
& 1)) {
5934 tmp
= neon_load_reg(rm
, 0);
5935 tmp2
= neon_load_reg(rm
, 1);
5936 for (pass
= 0; pass
< 2; pass
++) {
5939 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5940 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5941 neon_store_reg64(cpu_V0
, rd
+ pass
);
5944 case NEON_2RM_VCVT_F16_F32
:
5945 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5949 tmp
= tcg_temp_new_i32();
5950 tmp2
= tcg_temp_new_i32();
5951 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
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
, 1));
5954 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5955 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5956 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5957 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5958 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5959 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5960 neon_store_reg(rd
, 0, tmp2
);
5961 tmp2
= tcg_temp_new_i32();
5962 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5963 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5964 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5965 neon_store_reg(rd
, 1, tmp2
);
5966 tcg_temp_free_i32(tmp
);
5968 case NEON_2RM_VCVT_F32_F16
:
5969 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5973 tmp3
= tcg_temp_new_i32();
5974 tmp
= neon_load_reg(rm
, 0);
5975 tmp2
= neon_load_reg(rm
, 1);
5976 tcg_gen_ext16u_i32(tmp3
, tmp
);
5977 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5978 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5979 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5980 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5981 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5982 tcg_temp_free_i32(tmp
);
5983 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5984 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5985 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5986 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5987 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5988 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5989 tcg_temp_free_i32(tmp2
);
5990 tcg_temp_free_i32(tmp3
);
5994 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5995 if (neon_2rm_is_float_op(op
)) {
5996 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5997 neon_reg_offset(rm
, pass
));
5998 TCGV_UNUSED_I32(tmp
);
6000 tmp
= neon_load_reg(rm
, pass
);
6003 case NEON_2RM_VREV32
:
6005 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6006 case 1: gen_swap_half(tmp
); break;
6010 case NEON_2RM_VREV16
:
6015 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6016 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6017 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6023 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6024 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6025 case 2: gen_helper_clz(tmp
, tmp
); break;
6030 gen_helper_neon_cnt_u8(tmp
, tmp
);
6033 tcg_gen_not_i32(tmp
, tmp
);
6035 case NEON_2RM_VQABS
:
6038 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6041 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6044 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6049 case NEON_2RM_VQNEG
:
6052 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6055 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6058 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6063 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6064 tmp2
= tcg_const_i32(0);
6066 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6067 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6068 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6071 tcg_temp_free_i32(tmp2
);
6072 if (op
== NEON_2RM_VCLE0
) {
6073 tcg_gen_not_i32(tmp
, tmp
);
6076 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6077 tmp2
= tcg_const_i32(0);
6079 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6080 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6081 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6084 tcg_temp_free_i32(tmp2
);
6085 if (op
== NEON_2RM_VCLT0
) {
6086 tcg_gen_not_i32(tmp
, tmp
);
6089 case NEON_2RM_VCEQ0
:
6090 tmp2
= tcg_const_i32(0);
6092 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6093 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6094 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6097 tcg_temp_free_i32(tmp2
);
6101 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6102 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6103 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6108 tmp2
= tcg_const_i32(0);
6109 gen_neon_rsb(size
, tmp
, tmp2
);
6110 tcg_temp_free_i32(tmp2
);
6112 case NEON_2RM_VCGT0_F
:
6114 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6115 tmp2
= tcg_const_i32(0);
6116 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6117 tcg_temp_free_i32(tmp2
);
6118 tcg_temp_free_ptr(fpstatus
);
6121 case NEON_2RM_VCGE0_F
:
6123 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6124 tmp2
= tcg_const_i32(0);
6125 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6126 tcg_temp_free_i32(tmp2
);
6127 tcg_temp_free_ptr(fpstatus
);
6130 case NEON_2RM_VCEQ0_F
:
6132 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6133 tmp2
= tcg_const_i32(0);
6134 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6135 tcg_temp_free_i32(tmp2
);
6136 tcg_temp_free_ptr(fpstatus
);
6139 case NEON_2RM_VCLE0_F
:
6141 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6142 tmp2
= tcg_const_i32(0);
6143 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6144 tcg_temp_free_i32(tmp2
);
6145 tcg_temp_free_ptr(fpstatus
);
6148 case NEON_2RM_VCLT0_F
:
6150 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6151 tmp2
= tcg_const_i32(0);
6152 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6153 tcg_temp_free_i32(tmp2
);
6154 tcg_temp_free_ptr(fpstatus
);
6157 case NEON_2RM_VABS_F
:
6160 case NEON_2RM_VNEG_F
:
6164 tmp2
= neon_load_reg(rd
, pass
);
6165 neon_store_reg(rm
, pass
, tmp2
);
6168 tmp2
= neon_load_reg(rd
, pass
);
6170 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6171 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6174 neon_store_reg(rm
, pass
, tmp2
);
6176 case NEON_2RM_VRECPE
:
6177 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6179 case NEON_2RM_VRSQRTE
:
6180 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6182 case NEON_2RM_VRECPE_F
:
6183 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6185 case NEON_2RM_VRSQRTE_F
:
6186 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6188 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6191 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6194 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6195 gen_vfp_tosiz(0, 1);
6197 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6198 gen_vfp_touiz(0, 1);
6201 /* Reserved op values were caught by the
6202 * neon_2rm_sizes[] check earlier.
6206 if (neon_2rm_is_float_op(op
)) {
6207 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6208 neon_reg_offset(rd
, pass
));
6210 neon_store_reg(rd
, pass
, tmp
);
6215 } else if ((insn
& (1 << 10)) == 0) {
6217 int n
= ((insn
>> 8) & 3) + 1;
6218 if ((rn
+ n
) > 32) {
6219 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6220 * helper function running off the end of the register file.
6225 if (insn
& (1 << 6)) {
6226 tmp
= neon_load_reg(rd
, 0);
6228 tmp
= tcg_temp_new_i32();
6229 tcg_gen_movi_i32(tmp
, 0);
6231 tmp2
= neon_load_reg(rm
, 0);
6232 tmp4
= tcg_const_i32(rn
);
6233 tmp5
= tcg_const_i32(n
);
6234 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6235 tcg_temp_free_i32(tmp
);
6236 if (insn
& (1 << 6)) {
6237 tmp
= neon_load_reg(rd
, 1);
6239 tmp
= tcg_temp_new_i32();
6240 tcg_gen_movi_i32(tmp
, 0);
6242 tmp3
= neon_load_reg(rm
, 1);
6243 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6244 tcg_temp_free_i32(tmp5
);
6245 tcg_temp_free_i32(tmp4
);
6246 neon_store_reg(rd
, 0, tmp2
);
6247 neon_store_reg(rd
, 1, tmp3
);
6248 tcg_temp_free_i32(tmp
);
6249 } else if ((insn
& 0x380) == 0) {
6251 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6254 if (insn
& (1 << 19)) {
6255 tmp
= neon_load_reg(rm
, 1);
6257 tmp
= neon_load_reg(rm
, 0);
6259 if (insn
& (1 << 16)) {
6260 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6261 } else if (insn
& (1 << 17)) {
6262 if ((insn
>> 18) & 1)
6263 gen_neon_dup_high16(tmp
);
6265 gen_neon_dup_low16(tmp
);
6267 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6268 tmp2
= tcg_temp_new_i32();
6269 tcg_gen_mov_i32(tmp2
, tmp
);
6270 neon_store_reg(rd
, pass
, tmp2
);
6272 tcg_temp_free_i32(tmp
);
6281 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6283 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6284 const ARMCPRegInfo
*ri
;
6285 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6287 cpnum
= (insn
>> 8) & 0xf;
6288 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6289 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6292 /* First check for coprocessor space used for actual instructions */
6296 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6297 return disas_iwmmxt_insn(env
, s
, insn
);
6298 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6299 return disas_dsp_insn(env
, s
, insn
);
6304 return disas_vfp_insn (env
, s
, insn
);
6309 /* Otherwise treat as a generic register access */
6310 is64
= (insn
& (1 << 25)) == 0;
6311 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6319 opc1
= (insn
>> 4) & 0xf;
6321 rt2
= (insn
>> 16) & 0xf;
6323 crn
= (insn
>> 16) & 0xf;
6324 opc1
= (insn
>> 21) & 7;
6325 opc2
= (insn
>> 5) & 7;
6328 isread
= (insn
>> 20) & 1;
6329 rt
= (insn
>> 12) & 0xf;
6331 ri
= get_arm_cp_reginfo(cpu
,
6332 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6334 /* Check access permissions */
6335 if (!cp_access_ok(env
, ri
, isread
)) {
6339 /* Handle special cases first */
6340 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6347 gen_set_pc_im(s
, s
->pc
);
6348 s
->is_jmp
= DISAS_WFI
;
6354 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6363 if (ri
->type
& ARM_CP_CONST
) {
6364 tmp64
= tcg_const_i64(ri
->resetvalue
);
6365 } else if (ri
->readfn
) {
6367 gen_set_pc_im(s
, s
->pc
);
6368 tmp64
= tcg_temp_new_i64();
6369 tmpptr
= tcg_const_ptr(ri
);
6370 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6371 tcg_temp_free_ptr(tmpptr
);
6373 tmp64
= tcg_temp_new_i64();
6374 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6376 tmp
= tcg_temp_new_i32();
6377 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6378 store_reg(s
, rt
, tmp
);
6379 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6380 tmp
= tcg_temp_new_i32();
6381 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6382 tcg_temp_free_i64(tmp64
);
6383 store_reg(s
, rt2
, tmp
);
6386 if (ri
->type
& ARM_CP_CONST
) {
6387 tmp
= tcg_const_i32(ri
->resetvalue
);
6388 } else if (ri
->readfn
) {
6390 gen_set_pc_im(s
, s
->pc
);
6391 tmp
= tcg_temp_new_i32();
6392 tmpptr
= tcg_const_ptr(ri
);
6393 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6394 tcg_temp_free_ptr(tmpptr
);
6396 tmp
= load_cpu_offset(ri
->fieldoffset
);
6399 /* Destination register of r15 for 32 bit loads sets
6400 * the condition codes from the high 4 bits of the value
6403 tcg_temp_free_i32(tmp
);
6405 store_reg(s
, rt
, tmp
);
6410 if (ri
->type
& ARM_CP_CONST
) {
6411 /* If not forbidden by access permissions, treat as WI */
6416 TCGv_i32 tmplo
, tmphi
;
6417 TCGv_i64 tmp64
= tcg_temp_new_i64();
6418 tmplo
= load_reg(s
, rt
);
6419 tmphi
= load_reg(s
, rt2
);
6420 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6421 tcg_temp_free_i32(tmplo
);
6422 tcg_temp_free_i32(tmphi
);
6424 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6425 gen_set_pc_im(s
, s
->pc
);
6426 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6427 tcg_temp_free_ptr(tmpptr
);
6429 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6431 tcg_temp_free_i64(tmp64
);
6436 gen_set_pc_im(s
, s
->pc
);
6437 tmp
= load_reg(s
, rt
);
6438 tmpptr
= tcg_const_ptr(ri
);
6439 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6440 tcg_temp_free_ptr(tmpptr
);
6441 tcg_temp_free_i32(tmp
);
6443 TCGv_i32 tmp
= load_reg(s
, rt
);
6444 store_cpu_offset(tmp
, ri
->fieldoffset
);
6449 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6450 /* I/O operations must end the TB here (whether read or write) */
6453 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6454 /* We default to ending the TB on a coprocessor register write,
6455 * but allow this to be suppressed by the register definition
6456 * (usually only necessary to work around guest bugs).
6468 /* Store a 64-bit value to a register pair. Clobbers val. */
6469 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6472 tmp
= tcg_temp_new_i32();
6473 tcg_gen_trunc_i64_i32(tmp
, val
);
6474 store_reg(s
, rlow
, tmp
);
6475 tmp
= tcg_temp_new_i32();
6476 tcg_gen_shri_i64(val
, val
, 32);
6477 tcg_gen_trunc_i64_i32(tmp
, val
);
6478 store_reg(s
, rhigh
, tmp
);
6481 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6482 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6487 /* Load value and extend to 64 bits. */
6488 tmp
= tcg_temp_new_i64();
6489 tmp2
= load_reg(s
, rlow
);
6490 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6491 tcg_temp_free_i32(tmp2
);
6492 tcg_gen_add_i64(val
, val
, tmp
);
6493 tcg_temp_free_i64(tmp
);
6496 /* load and add a 64-bit value from a register pair. */
6497 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6503 /* Load 64-bit value rd:rn. */
6504 tmpl
= load_reg(s
, rlow
);
6505 tmph
= load_reg(s
, rhigh
);
6506 tmp
= tcg_temp_new_i64();
6507 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6508 tcg_temp_free_i32(tmpl
);
6509 tcg_temp_free_i32(tmph
);
6510 tcg_gen_add_i64(val
, val
, tmp
);
6511 tcg_temp_free_i64(tmp
);
6514 /* Set N and Z flags from hi|lo. */
6515 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6517 tcg_gen_mov_i32(cpu_NF
, hi
);
6518 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6521 /* Load/Store exclusive instructions are implemented by remembering
6522 the value/address loaded, and seeing if these are the same
6523 when the store is performed. This should be sufficient to implement
6524 the architecturally mandated semantics, and avoids having to monitor
6527 In system emulation mode only one CPU will be running at once, so
6528 this sequence is effectively atomic. In user emulation mode we
6529 throw an exception and handle the atomic operation elsewhere. */
6530 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6531 TCGv_i32 addr
, int size
)
6533 TCGv_i32 tmp
= tcg_temp_new_i32();
6537 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6540 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6544 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6549 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6550 store_reg(s
, rt
, tmp
);
6552 TCGv_i32 tmp2
= tcg_temp_new_i32();
6553 tcg_gen_addi_i32(tmp2
, addr
, 4);
6554 tmp
= tcg_temp_new_i32();
6555 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6556 tcg_temp_free_i32(tmp2
);
6557 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6558 store_reg(s
, rt2
, tmp
);
6560 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6563 static void gen_clrex(DisasContext
*s
)
6565 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6568 #ifdef CONFIG_USER_ONLY
6569 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6570 TCGv_i32 addr
, int size
)
6572 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6573 tcg_gen_movi_i32(cpu_exclusive_info
,
6574 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6575 gen_exception_insn(s
, 4, EXCP_STREX
);
6578 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6579 TCGv_i32 addr
, int size
)
6585 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6591 fail_label
= gen_new_label();
6592 done_label
= gen_new_label();
6593 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6594 tmp
= tcg_temp_new_i32();
6597 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6600 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6604 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6609 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6610 tcg_temp_free_i32(tmp
);
6612 TCGv_i32 tmp2
= tcg_temp_new_i32();
6613 tcg_gen_addi_i32(tmp2
, addr
, 4);
6614 tmp
= tcg_temp_new_i32();
6615 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6616 tcg_temp_free_i32(tmp2
);
6617 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6618 tcg_temp_free_i32(tmp
);
6620 tmp
= load_reg(s
, rt
);
6623 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
6626 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
6630 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6635 tcg_temp_free_i32(tmp
);
6637 tcg_gen_addi_i32(addr
, addr
, 4);
6638 tmp
= load_reg(s
, rt2
);
6639 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6640 tcg_temp_free_i32(tmp
);
6642 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6643 tcg_gen_br(done_label
);
6644 gen_set_label(fail_label
);
6645 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6646 gen_set_label(done_label
);
6647 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6654 * @mode: mode field from insn (which stack to store to)
6655 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6656 * @writeback: true if writeback bit set
6658 * Generate code for the SRS (Store Return State) insn.
6660 static void gen_srs(DisasContext
*s
,
6661 uint32_t mode
, uint32_t amode
, bool writeback
)
6664 TCGv_i32 addr
= tcg_temp_new_i32();
6665 TCGv_i32 tmp
= tcg_const_i32(mode
);
6666 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6667 tcg_temp_free_i32(tmp
);
6684 tcg_gen_addi_i32(addr
, addr
, offset
);
6685 tmp
= load_reg(s
, 14);
6686 gen_aa32_st32(tmp
, addr
, 0);
6687 tcg_temp_free_i32(tmp
);
6688 tmp
= load_cpu_field(spsr
);
6689 tcg_gen_addi_i32(addr
, addr
, 4);
6690 gen_aa32_st32(tmp
, addr
, 0);
6691 tcg_temp_free_i32(tmp
);
6709 tcg_gen_addi_i32(addr
, addr
, offset
);
6710 tmp
= tcg_const_i32(mode
);
6711 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6712 tcg_temp_free_i32(tmp
);
6714 tcg_temp_free_i32(addr
);
6717 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6719 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6726 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6729 /* M variants do not implement ARM mode. */
6734 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6735 * choose to UNDEF. In ARMv5 and above the space is used
6736 * for miscellaneous unconditional instructions.
6740 /* Unconditional instructions. */
6741 if (((insn
>> 25) & 7) == 1) {
6742 /* NEON Data processing. */
6743 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6746 if (disas_neon_data_insn(env
, s
, insn
))
6750 if ((insn
& 0x0f100000) == 0x04000000) {
6751 /* NEON load/store. */
6752 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6755 if (disas_neon_ls_insn(env
, s
, insn
))
6759 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6760 ((insn
& 0x0f30f010) == 0x0710f000)) {
6761 if ((insn
& (1 << 22)) == 0) {
6763 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6767 /* Otherwise PLD; v5TE+ */
6771 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6772 ((insn
& 0x0f70f010) == 0x0650f000)) {
6774 return; /* PLI; V7 */
6776 if (((insn
& 0x0f700000) == 0x04100000) ||
6777 ((insn
& 0x0f700010) == 0x06100000)) {
6778 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6781 return; /* v7MP: Unallocated memory hint: must NOP */
6784 if ((insn
& 0x0ffffdff) == 0x01010000) {
6787 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6788 /* Dynamic endianness switching not implemented. */
6789 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
6793 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6794 switch ((insn
>> 4) & 0xf) {
6803 /* We don't emulate caches so these are a no-op. */
6808 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6814 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
6816 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6822 rn
= (insn
>> 16) & 0xf;
6823 addr
= load_reg(s
, rn
);
6824 i
= (insn
>> 23) & 3;
6826 case 0: offset
= -4; break; /* DA */
6827 case 1: offset
= 0; break; /* IA */
6828 case 2: offset
= -8; break; /* DB */
6829 case 3: offset
= 4; break; /* IB */
6833 tcg_gen_addi_i32(addr
, addr
, offset
);
6834 /* Load PC into tmp and CPSR into tmp2. */
6835 tmp
= tcg_temp_new_i32();
6836 gen_aa32_ld32u(tmp
, addr
, 0);
6837 tcg_gen_addi_i32(addr
, addr
, 4);
6838 tmp2
= tcg_temp_new_i32();
6839 gen_aa32_ld32u(tmp2
, addr
, 0);
6840 if (insn
& (1 << 21)) {
6841 /* Base writeback. */
6843 case 0: offset
= -8; break;
6844 case 1: offset
= 4; break;
6845 case 2: offset
= -4; break;
6846 case 3: offset
= 0; break;
6850 tcg_gen_addi_i32(addr
, addr
, offset
);
6851 store_reg(s
, rn
, addr
);
6853 tcg_temp_free_i32(addr
);
6855 gen_rfe(s
, tmp
, tmp2
);
6857 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6858 /* branch link and change to thumb (blx <offset>) */
6861 val
= (uint32_t)s
->pc
;
6862 tmp
= tcg_temp_new_i32();
6863 tcg_gen_movi_i32(tmp
, val
);
6864 store_reg(s
, 14, tmp
);
6865 /* Sign-extend the 24-bit offset */
6866 offset
= (((int32_t)insn
) << 8) >> 8;
6867 /* offset * 4 + bit24 * 2 + (thumb bit) */
6868 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6869 /* pipeline offset */
6871 /* protected by ARCH(5); above, near the start of uncond block */
6874 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6875 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6876 /* iWMMXt register transfer. */
6877 if (env
->cp15
.c15_cpar
& (1 << 1))
6878 if (!disas_iwmmxt_insn(env
, s
, insn
))
6881 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6882 /* Coprocessor double register transfer. */
6884 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6885 /* Additional coprocessor register transfer. */
6886 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6889 /* cps (privileged) */
6893 if (insn
& (1 << 19)) {
6894 if (insn
& (1 << 8))
6896 if (insn
& (1 << 7))
6898 if (insn
& (1 << 6))
6900 if (insn
& (1 << 18))
6903 if (insn
& (1 << 17)) {
6905 val
|= (insn
& 0x1f);
6908 gen_set_psr_im(s
, mask
, 0, val
);
6915 /* if not always execute, we generate a conditional jump to
6917 s
->condlabel
= gen_new_label();
6918 gen_test_cc(cond
^ 1, s
->condlabel
);
6921 if ((insn
& 0x0f900000) == 0x03000000) {
6922 if ((insn
& (1 << 21)) == 0) {
6924 rd
= (insn
>> 12) & 0xf;
6925 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6926 if ((insn
& (1 << 22)) == 0) {
6928 tmp
= tcg_temp_new_i32();
6929 tcg_gen_movi_i32(tmp
, val
);
6932 tmp
= load_reg(s
, rd
);
6933 tcg_gen_ext16u_i32(tmp
, tmp
);
6934 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6936 store_reg(s
, rd
, tmp
);
6938 if (((insn
>> 12) & 0xf) != 0xf)
6940 if (((insn
>> 16) & 0xf) == 0) {
6941 gen_nop_hint(s
, insn
& 0xff);
6943 /* CPSR = immediate */
6945 shift
= ((insn
>> 8) & 0xf) * 2;
6947 val
= (val
>> shift
) | (val
<< (32 - shift
));
6948 i
= ((insn
& (1 << 22)) != 0);
6949 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6953 } else if ((insn
& 0x0f900000) == 0x01000000
6954 && (insn
& 0x00000090) != 0x00000090) {
6955 /* miscellaneous instructions */
6956 op1
= (insn
>> 21) & 3;
6957 sh
= (insn
>> 4) & 0xf;
6960 case 0x0: /* move program status register */
6963 tmp
= load_reg(s
, rm
);
6964 i
= ((op1
& 2) != 0);
6965 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6969 rd
= (insn
>> 12) & 0xf;
6973 tmp
= load_cpu_field(spsr
);
6975 tmp
= tcg_temp_new_i32();
6976 gen_helper_cpsr_read(tmp
, cpu_env
);
6978 store_reg(s
, rd
, tmp
);
6983 /* branch/exchange thumb (bx). */
6985 tmp
= load_reg(s
, rm
);
6987 } else if (op1
== 3) {
6990 rd
= (insn
>> 12) & 0xf;
6991 tmp
= load_reg(s
, rm
);
6992 gen_helper_clz(tmp
, tmp
);
6993 store_reg(s
, rd
, tmp
);
7001 /* Trivial implementation equivalent to bx. */
7002 tmp
= load_reg(s
, rm
);
7013 /* branch link/exchange thumb (blx) */
7014 tmp
= load_reg(s
, rm
);
7015 tmp2
= tcg_temp_new_i32();
7016 tcg_gen_movi_i32(tmp2
, s
->pc
);
7017 store_reg(s
, 14, tmp2
);
7020 case 0x5: /* saturating add/subtract */
7022 rd
= (insn
>> 12) & 0xf;
7023 rn
= (insn
>> 16) & 0xf;
7024 tmp
= load_reg(s
, rm
);
7025 tmp2
= load_reg(s
, rn
);
7027 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7029 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7031 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7032 tcg_temp_free_i32(tmp2
);
7033 store_reg(s
, rd
, tmp
);
7036 /* SMC instruction (op1 == 3)
7037 and undefined instructions (op1 == 0 || op1 == 2)
7044 gen_exception_insn(s
, 4, EXCP_BKPT
);
7046 case 0x8: /* signed multiply */
7051 rs
= (insn
>> 8) & 0xf;
7052 rn
= (insn
>> 12) & 0xf;
7053 rd
= (insn
>> 16) & 0xf;
7055 /* (32 * 16) >> 16 */
7056 tmp
= load_reg(s
, rm
);
7057 tmp2
= load_reg(s
, rs
);
7059 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7062 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7063 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7064 tmp
= tcg_temp_new_i32();
7065 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7066 tcg_temp_free_i64(tmp64
);
7067 if ((sh
& 2) == 0) {
7068 tmp2
= load_reg(s
, rn
);
7069 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7070 tcg_temp_free_i32(tmp2
);
7072 store_reg(s
, rd
, tmp
);
7075 tmp
= load_reg(s
, rm
);
7076 tmp2
= load_reg(s
, rs
);
7077 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7078 tcg_temp_free_i32(tmp2
);
7080 tmp64
= tcg_temp_new_i64();
7081 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7082 tcg_temp_free_i32(tmp
);
7083 gen_addq(s
, tmp64
, rn
, rd
);
7084 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7085 tcg_temp_free_i64(tmp64
);
7088 tmp2
= load_reg(s
, rn
);
7089 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7090 tcg_temp_free_i32(tmp2
);
7092 store_reg(s
, rd
, tmp
);
7099 } else if (((insn
& 0x0e000000) == 0 &&
7100 (insn
& 0x00000090) != 0x90) ||
7101 ((insn
& 0x0e000000) == (1 << 25))) {
7102 int set_cc
, logic_cc
, shiftop
;
7104 op1
= (insn
>> 21) & 0xf;
7105 set_cc
= (insn
>> 20) & 1;
7106 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7108 /* data processing instruction */
7109 if (insn
& (1 << 25)) {
7110 /* immediate operand */
7112 shift
= ((insn
>> 8) & 0xf) * 2;
7114 val
= (val
>> shift
) | (val
<< (32 - shift
));
7116 tmp2
= tcg_temp_new_i32();
7117 tcg_gen_movi_i32(tmp2
, val
);
7118 if (logic_cc
&& shift
) {
7119 gen_set_CF_bit31(tmp2
);
7124 tmp2
= load_reg(s
, rm
);
7125 shiftop
= (insn
>> 5) & 3;
7126 if (!(insn
& (1 << 4))) {
7127 shift
= (insn
>> 7) & 0x1f;
7128 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7130 rs
= (insn
>> 8) & 0xf;
7131 tmp
= load_reg(s
, rs
);
7132 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7135 if (op1
!= 0x0f && op1
!= 0x0d) {
7136 rn
= (insn
>> 16) & 0xf;
7137 tmp
= load_reg(s
, rn
);
7139 TCGV_UNUSED_I32(tmp
);
7141 rd
= (insn
>> 12) & 0xf;
7144 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7148 store_reg_bx(env
, s
, rd
, tmp
);
7151 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7155 store_reg_bx(env
, s
, rd
, tmp
);
7158 if (set_cc
&& rd
== 15) {
7159 /* SUBS r15, ... is used for exception return. */
7163 gen_sub_CC(tmp
, tmp
, tmp2
);
7164 gen_exception_return(s
, tmp
);
7167 gen_sub_CC(tmp
, tmp
, tmp2
);
7169 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7171 store_reg_bx(env
, s
, rd
, tmp
);
7176 gen_sub_CC(tmp
, tmp2
, tmp
);
7178 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7180 store_reg_bx(env
, s
, rd
, tmp
);
7184 gen_add_CC(tmp
, tmp
, tmp2
);
7186 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7188 store_reg_bx(env
, s
, rd
, tmp
);
7192 gen_adc_CC(tmp
, tmp
, tmp2
);
7194 gen_add_carry(tmp
, tmp
, tmp2
);
7196 store_reg_bx(env
, s
, rd
, tmp
);
7200 gen_sbc_CC(tmp
, tmp
, tmp2
);
7202 gen_sub_carry(tmp
, tmp
, tmp2
);
7204 store_reg_bx(env
, s
, rd
, tmp
);
7208 gen_sbc_CC(tmp
, tmp2
, tmp
);
7210 gen_sub_carry(tmp
, tmp2
, tmp
);
7212 store_reg_bx(env
, s
, rd
, tmp
);
7216 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7219 tcg_temp_free_i32(tmp
);
7223 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7226 tcg_temp_free_i32(tmp
);
7230 gen_sub_CC(tmp
, tmp
, tmp2
);
7232 tcg_temp_free_i32(tmp
);
7236 gen_add_CC(tmp
, tmp
, tmp2
);
7238 tcg_temp_free_i32(tmp
);
7241 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7245 store_reg_bx(env
, s
, rd
, tmp
);
7248 if (logic_cc
&& rd
== 15) {
7249 /* MOVS r15, ... is used for exception return. */
7253 gen_exception_return(s
, tmp2
);
7258 store_reg_bx(env
, s
, rd
, tmp2
);
7262 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7266 store_reg_bx(env
, s
, rd
, tmp
);
7270 tcg_gen_not_i32(tmp2
, tmp2
);
7274 store_reg_bx(env
, s
, rd
, tmp2
);
7277 if (op1
!= 0x0f && op1
!= 0x0d) {
7278 tcg_temp_free_i32(tmp2
);
7281 /* other instructions */
7282 op1
= (insn
>> 24) & 0xf;
7286 /* multiplies, extra load/stores */
7287 sh
= (insn
>> 5) & 3;
7290 rd
= (insn
>> 16) & 0xf;
7291 rn
= (insn
>> 12) & 0xf;
7292 rs
= (insn
>> 8) & 0xf;
7294 op1
= (insn
>> 20) & 0xf;
7296 case 0: case 1: case 2: case 3: case 6:
7298 tmp
= load_reg(s
, rs
);
7299 tmp2
= load_reg(s
, rm
);
7300 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7301 tcg_temp_free_i32(tmp2
);
7302 if (insn
& (1 << 22)) {
7303 /* Subtract (mls) */
7305 tmp2
= load_reg(s
, rn
);
7306 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7307 tcg_temp_free_i32(tmp2
);
7308 } else if (insn
& (1 << 21)) {
7310 tmp2
= load_reg(s
, rn
);
7311 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7312 tcg_temp_free_i32(tmp2
);
7314 if (insn
& (1 << 20))
7316 store_reg(s
, rd
, tmp
);
7319 /* 64 bit mul double accumulate (UMAAL) */
7321 tmp
= load_reg(s
, rs
);
7322 tmp2
= load_reg(s
, rm
);
7323 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7324 gen_addq_lo(s
, tmp64
, rn
);
7325 gen_addq_lo(s
, tmp64
, rd
);
7326 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7327 tcg_temp_free_i64(tmp64
);
7329 case 8: case 9: case 10: case 11:
7330 case 12: case 13: case 14: case 15:
7331 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7332 tmp
= load_reg(s
, rs
);
7333 tmp2
= load_reg(s
, rm
);
7334 if (insn
& (1 << 22)) {
7335 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7337 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7339 if (insn
& (1 << 21)) { /* mult accumulate */
7340 TCGv_i32 al
= load_reg(s
, rn
);
7341 TCGv_i32 ah
= load_reg(s
, rd
);
7342 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7343 tcg_temp_free_i32(al
);
7344 tcg_temp_free_i32(ah
);
7346 if (insn
& (1 << 20)) {
7347 gen_logicq_cc(tmp
, tmp2
);
7349 store_reg(s
, rn
, tmp
);
7350 store_reg(s
, rd
, tmp2
);
7356 rn
= (insn
>> 16) & 0xf;
7357 rd
= (insn
>> 12) & 0xf;
7358 if (insn
& (1 << 23)) {
7359 /* load/store exclusive */
7360 int op2
= (insn
>> 8) & 3;
7361 op1
= (insn
>> 21) & 0x3;
7364 case 0: /* lda/stl */
7370 case 1: /* reserved */
7372 case 2: /* ldaex/stlex */
7375 case 3: /* ldrex/strex */
7384 addr
= tcg_temp_local_new_i32();
7385 load_reg_var(s
, addr
, rn
);
7387 /* Since the emulation does not have barriers,
7388 the acquire/release semantics need no special
7391 if (insn
& (1 << 20)) {
7392 tmp
= tcg_temp_new_i32();
7395 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7398 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7401 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7406 store_reg(s
, rd
, tmp
);
7409 tmp
= load_reg(s
, rm
);
7412 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7415 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7418 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7423 tcg_temp_free_i32(tmp
);
7425 } else if (insn
& (1 << 20)) {
7428 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7430 case 1: /* ldrexd */
7431 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7433 case 2: /* ldrexb */
7434 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7436 case 3: /* ldrexh */
7437 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7446 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7448 case 1: /* strexd */
7449 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7451 case 2: /* strexb */
7452 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7454 case 3: /* strexh */
7455 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7461 tcg_temp_free_i32(addr
);
7463 /* SWP instruction */
7466 /* ??? This is not really atomic. However we know
7467 we never have multiple CPUs running in parallel,
7468 so it is good enough. */
7469 addr
= load_reg(s
, rn
);
7470 tmp
= load_reg(s
, rm
);
7471 tmp2
= tcg_temp_new_i32();
7472 if (insn
& (1 << 22)) {
7473 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7474 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7476 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7477 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7479 tcg_temp_free_i32(tmp
);
7480 tcg_temp_free_i32(addr
);
7481 store_reg(s
, rd
, tmp2
);
7487 /* Misc load/store */
7488 rn
= (insn
>> 16) & 0xf;
7489 rd
= (insn
>> 12) & 0xf;
7490 addr
= load_reg(s
, rn
);
7491 if (insn
& (1 << 24))
7492 gen_add_datah_offset(s
, insn
, 0, addr
);
7494 if (insn
& (1 << 20)) {
7496 tmp
= tcg_temp_new_i32();
7499 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7502 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7506 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7510 } else if (sh
& 2) {
7515 tmp
= load_reg(s
, rd
);
7516 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7517 tcg_temp_free_i32(tmp
);
7518 tcg_gen_addi_i32(addr
, addr
, 4);
7519 tmp
= load_reg(s
, rd
+ 1);
7520 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7521 tcg_temp_free_i32(tmp
);
7525 tmp
= tcg_temp_new_i32();
7526 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7527 store_reg(s
, rd
, tmp
);
7528 tcg_gen_addi_i32(addr
, addr
, 4);
7529 tmp
= tcg_temp_new_i32();
7530 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7534 address_offset
= -4;
7537 tmp
= load_reg(s
, rd
);
7538 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7539 tcg_temp_free_i32(tmp
);
7542 /* Perform base writeback before the loaded value to
7543 ensure correct behavior with overlapping index registers.
7544 ldrd with base writeback is is undefined if the
7545 destination and index registers overlap. */
7546 if (!(insn
& (1 << 24))) {
7547 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7548 store_reg(s
, rn
, addr
);
7549 } else if (insn
& (1 << 21)) {
7551 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7552 store_reg(s
, rn
, addr
);
7554 tcg_temp_free_i32(addr
);
7557 /* Complete the load. */
7558 store_reg(s
, rd
, tmp
);
7567 if (insn
& (1 << 4)) {
7569 /* Armv6 Media instructions. */
7571 rn
= (insn
>> 16) & 0xf;
7572 rd
= (insn
>> 12) & 0xf;
7573 rs
= (insn
>> 8) & 0xf;
7574 switch ((insn
>> 23) & 3) {
7575 case 0: /* Parallel add/subtract. */
7576 op1
= (insn
>> 20) & 7;
7577 tmp
= load_reg(s
, rn
);
7578 tmp2
= load_reg(s
, rm
);
7579 sh
= (insn
>> 5) & 7;
7580 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7582 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7583 tcg_temp_free_i32(tmp2
);
7584 store_reg(s
, rd
, tmp
);
7587 if ((insn
& 0x00700020) == 0) {
7588 /* Halfword pack. */
7589 tmp
= load_reg(s
, rn
);
7590 tmp2
= load_reg(s
, rm
);
7591 shift
= (insn
>> 7) & 0x1f;
7592 if (insn
& (1 << 6)) {
7596 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7597 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7598 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7602 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7603 tcg_gen_ext16u_i32(tmp
, tmp
);
7604 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7606 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7607 tcg_temp_free_i32(tmp2
);
7608 store_reg(s
, rd
, tmp
);
7609 } else if ((insn
& 0x00200020) == 0x00200000) {
7611 tmp
= load_reg(s
, rm
);
7612 shift
= (insn
>> 7) & 0x1f;
7613 if (insn
& (1 << 6)) {
7616 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7618 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7620 sh
= (insn
>> 16) & 0x1f;
7621 tmp2
= tcg_const_i32(sh
);
7622 if (insn
& (1 << 22))
7623 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7625 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7626 tcg_temp_free_i32(tmp2
);
7627 store_reg(s
, rd
, tmp
);
7628 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7630 tmp
= load_reg(s
, rm
);
7631 sh
= (insn
>> 16) & 0x1f;
7632 tmp2
= tcg_const_i32(sh
);
7633 if (insn
& (1 << 22))
7634 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7636 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7637 tcg_temp_free_i32(tmp2
);
7638 store_reg(s
, rd
, tmp
);
7639 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7641 tmp
= load_reg(s
, rn
);
7642 tmp2
= load_reg(s
, rm
);
7643 tmp3
= tcg_temp_new_i32();
7644 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7645 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7646 tcg_temp_free_i32(tmp3
);
7647 tcg_temp_free_i32(tmp2
);
7648 store_reg(s
, rd
, tmp
);
7649 } else if ((insn
& 0x000003e0) == 0x00000060) {
7650 tmp
= load_reg(s
, rm
);
7651 shift
= (insn
>> 10) & 3;
7652 /* ??? In many cases it's not necessary to do a
7653 rotate, a shift is sufficient. */
7655 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7656 op1
= (insn
>> 20) & 7;
7658 case 0: gen_sxtb16(tmp
); break;
7659 case 2: gen_sxtb(tmp
); break;
7660 case 3: gen_sxth(tmp
); break;
7661 case 4: gen_uxtb16(tmp
); break;
7662 case 6: gen_uxtb(tmp
); break;
7663 case 7: gen_uxth(tmp
); break;
7664 default: goto illegal_op
;
7667 tmp2
= load_reg(s
, rn
);
7668 if ((op1
& 3) == 0) {
7669 gen_add16(tmp
, tmp2
);
7671 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7672 tcg_temp_free_i32(tmp2
);
7675 store_reg(s
, rd
, tmp
);
7676 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7678 tmp
= load_reg(s
, rm
);
7679 if (insn
& (1 << 22)) {
7680 if (insn
& (1 << 7)) {
7684 gen_helper_rbit(tmp
, tmp
);
7687 if (insn
& (1 << 7))
7690 tcg_gen_bswap32_i32(tmp
, tmp
);
7692 store_reg(s
, rd
, tmp
);
7697 case 2: /* Multiplies (Type 3). */
7698 switch ((insn
>> 20) & 0x7) {
7700 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7701 /* op2 not 00x or 11x : UNDEF */
7704 /* Signed multiply most significant [accumulate].
7705 (SMMUL, SMMLA, SMMLS) */
7706 tmp
= load_reg(s
, rm
);
7707 tmp2
= load_reg(s
, rs
);
7708 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7711 tmp
= load_reg(s
, rd
);
7712 if (insn
& (1 << 6)) {
7713 tmp64
= gen_subq_msw(tmp64
, tmp
);
7715 tmp64
= gen_addq_msw(tmp64
, tmp
);
7718 if (insn
& (1 << 5)) {
7719 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7721 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7722 tmp
= tcg_temp_new_i32();
7723 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7724 tcg_temp_free_i64(tmp64
);
7725 store_reg(s
, rn
, tmp
);
7729 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7730 if (insn
& (1 << 7)) {
7733 tmp
= load_reg(s
, rm
);
7734 tmp2
= load_reg(s
, rs
);
7735 if (insn
& (1 << 5))
7736 gen_swap_half(tmp2
);
7737 gen_smul_dual(tmp
, tmp2
);
7738 if (insn
& (1 << 6)) {
7739 /* This subtraction cannot overflow. */
7740 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7742 /* This addition cannot overflow 32 bits;
7743 * however it may overflow considered as a signed
7744 * operation, in which case we must set the Q flag.
7746 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7748 tcg_temp_free_i32(tmp2
);
7749 if (insn
& (1 << 22)) {
7750 /* smlald, smlsld */
7751 tmp64
= tcg_temp_new_i64();
7752 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7753 tcg_temp_free_i32(tmp
);
7754 gen_addq(s
, tmp64
, rd
, rn
);
7755 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7756 tcg_temp_free_i64(tmp64
);
7758 /* smuad, smusd, smlad, smlsd */
7761 tmp2
= load_reg(s
, rd
);
7762 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7763 tcg_temp_free_i32(tmp2
);
7765 store_reg(s
, rn
, tmp
);
7771 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7774 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7777 tmp
= load_reg(s
, rm
);
7778 tmp2
= load_reg(s
, rs
);
7779 if (insn
& (1 << 21)) {
7780 gen_helper_udiv(tmp
, tmp
, tmp2
);
7782 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7784 tcg_temp_free_i32(tmp2
);
7785 store_reg(s
, rn
, tmp
);
7792 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7794 case 0: /* Unsigned sum of absolute differences. */
7796 tmp
= load_reg(s
, rm
);
7797 tmp2
= load_reg(s
, rs
);
7798 gen_helper_usad8(tmp
, tmp
, tmp2
);
7799 tcg_temp_free_i32(tmp2
);
7801 tmp2
= load_reg(s
, rd
);
7802 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7803 tcg_temp_free_i32(tmp2
);
7805 store_reg(s
, rn
, tmp
);
7807 case 0x20: case 0x24: case 0x28: case 0x2c:
7808 /* Bitfield insert/clear. */
7810 shift
= (insn
>> 7) & 0x1f;
7811 i
= (insn
>> 16) & 0x1f;
7814 tmp
= tcg_temp_new_i32();
7815 tcg_gen_movi_i32(tmp
, 0);
7817 tmp
= load_reg(s
, rm
);
7820 tmp2
= load_reg(s
, rd
);
7821 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7822 tcg_temp_free_i32(tmp2
);
7824 store_reg(s
, rd
, tmp
);
7826 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7827 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7829 tmp
= load_reg(s
, rm
);
7830 shift
= (insn
>> 7) & 0x1f;
7831 i
= ((insn
>> 16) & 0x1f) + 1;
7836 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7838 gen_sbfx(tmp
, shift
, i
);
7841 store_reg(s
, rd
, tmp
);
7851 /* Check for undefined extension instructions
7852 * per the ARM Bible IE:
7853 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7855 sh
= (0xf << 20) | (0xf << 4);
7856 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7860 /* load/store byte/word */
7861 rn
= (insn
>> 16) & 0xf;
7862 rd
= (insn
>> 12) & 0xf;
7863 tmp2
= load_reg(s
, rn
);
7864 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7865 if (insn
& (1 << 24))
7866 gen_add_data_offset(s
, insn
, tmp2
);
7867 if (insn
& (1 << 20)) {
7869 tmp
= tcg_temp_new_i32();
7870 if (insn
& (1 << 22)) {
7871 gen_aa32_ld8u(tmp
, tmp2
, i
);
7873 gen_aa32_ld32u(tmp
, tmp2
, i
);
7877 tmp
= load_reg(s
, rd
);
7878 if (insn
& (1 << 22)) {
7879 gen_aa32_st8(tmp
, tmp2
, i
);
7881 gen_aa32_st32(tmp
, tmp2
, i
);
7883 tcg_temp_free_i32(tmp
);
7885 if (!(insn
& (1 << 24))) {
7886 gen_add_data_offset(s
, insn
, tmp2
);
7887 store_reg(s
, rn
, tmp2
);
7888 } else if (insn
& (1 << 21)) {
7889 store_reg(s
, rn
, tmp2
);
7891 tcg_temp_free_i32(tmp2
);
7893 if (insn
& (1 << 20)) {
7894 /* Complete the load. */
7895 store_reg_from_load(env
, s
, rd
, tmp
);
7901 int j
, n
, user
, loaded_base
;
7902 TCGv_i32 loaded_var
;
7903 /* load/store multiple words */
7904 /* XXX: store correct base if write back */
7906 if (insn
& (1 << 22)) {
7908 goto illegal_op
; /* only usable in supervisor mode */
7910 if ((insn
& (1 << 15)) == 0)
7913 rn
= (insn
>> 16) & 0xf;
7914 addr
= load_reg(s
, rn
);
7916 /* compute total size */
7918 TCGV_UNUSED_I32(loaded_var
);
7921 if (insn
& (1 << i
))
7924 /* XXX: test invalid n == 0 case ? */
7925 if (insn
& (1 << 23)) {
7926 if (insn
& (1 << 24)) {
7928 tcg_gen_addi_i32(addr
, addr
, 4);
7930 /* post increment */
7933 if (insn
& (1 << 24)) {
7935 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7937 /* post decrement */
7939 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7944 if (insn
& (1 << i
)) {
7945 if (insn
& (1 << 20)) {
7947 tmp
= tcg_temp_new_i32();
7948 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7950 tmp2
= tcg_const_i32(i
);
7951 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7952 tcg_temp_free_i32(tmp2
);
7953 tcg_temp_free_i32(tmp
);
7954 } else if (i
== rn
) {
7958 store_reg_from_load(env
, s
, i
, tmp
);
7963 /* special case: r15 = PC + 8 */
7964 val
= (long)s
->pc
+ 4;
7965 tmp
= tcg_temp_new_i32();
7966 tcg_gen_movi_i32(tmp
, val
);
7968 tmp
= tcg_temp_new_i32();
7969 tmp2
= tcg_const_i32(i
);
7970 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7971 tcg_temp_free_i32(tmp2
);
7973 tmp
= load_reg(s
, i
);
7975 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7976 tcg_temp_free_i32(tmp
);
7979 /* no need to add after the last transfer */
7981 tcg_gen_addi_i32(addr
, addr
, 4);
7984 if (insn
& (1 << 21)) {
7986 if (insn
& (1 << 23)) {
7987 if (insn
& (1 << 24)) {
7990 /* post increment */
7991 tcg_gen_addi_i32(addr
, addr
, 4);
7994 if (insn
& (1 << 24)) {
7997 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7999 /* post decrement */
8000 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8003 store_reg(s
, rn
, addr
);
8005 tcg_temp_free_i32(addr
);
8008 store_reg(s
, rn
, loaded_var
);
8010 if ((insn
& (1 << 22)) && !user
) {
8011 /* Restore CPSR from SPSR. */
8012 tmp
= load_cpu_field(spsr
);
8013 gen_set_cpsr(tmp
, 0xffffffff);
8014 tcg_temp_free_i32(tmp
);
8015 s
->is_jmp
= DISAS_UPDATE
;
8024 /* branch (and link) */
8025 val
= (int32_t)s
->pc
;
8026 if (insn
& (1 << 24)) {
8027 tmp
= tcg_temp_new_i32();
8028 tcg_gen_movi_i32(tmp
, val
);
8029 store_reg(s
, 14, tmp
);
8031 offset
= sextract32(insn
<< 2, 0, 26);
8040 if (disas_coproc_insn(env
, s
, insn
))
8045 gen_set_pc_im(s
, s
->pc
);
8046 s
->is_jmp
= DISAS_SWI
;
8050 gen_exception_insn(s
, 4, EXCP_UDEF
);
8056 /* Return true if this is a Thumb-2 logical op. */
8058 thumb2_logic_op(int op
)
8063 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8064 then set condition code flags based on the result of the operation.
8065 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8066 to the high bit of T1.
8067 Returns zero if the opcode is valid. */
8070 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8071 TCGv_i32 t0
, TCGv_i32 t1
)
8078 tcg_gen_and_i32(t0
, t0
, t1
);
8082 tcg_gen_andc_i32(t0
, t0
, t1
);
8086 tcg_gen_or_i32(t0
, t0
, t1
);
8090 tcg_gen_orc_i32(t0
, t0
, t1
);
8094 tcg_gen_xor_i32(t0
, t0
, t1
);
8099 gen_add_CC(t0
, t0
, t1
);
8101 tcg_gen_add_i32(t0
, t0
, t1
);
8105 gen_adc_CC(t0
, t0
, t1
);
8111 gen_sbc_CC(t0
, t0
, t1
);
8113 gen_sub_carry(t0
, t0
, t1
);
8118 gen_sub_CC(t0
, t0
, t1
);
8120 tcg_gen_sub_i32(t0
, t0
, t1
);
8124 gen_sub_CC(t0
, t1
, t0
);
8126 tcg_gen_sub_i32(t0
, t1
, t0
);
8128 default: /* 5, 6, 7, 9, 12, 15. */
8134 gen_set_CF_bit31(t1
);
8139 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8141 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8143 uint32_t insn
, imm
, shift
, offset
;
8144 uint32_t rd
, rn
, rm
, rs
;
8155 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8156 || arm_feature (env
, ARM_FEATURE_M
))) {
8157 /* Thumb-1 cores may need to treat bl and blx as a pair of
8158 16-bit instructions to get correct prefetch abort behavior. */
8160 if ((insn
& (1 << 12)) == 0) {
8162 /* Second half of blx. */
8163 offset
= ((insn
& 0x7ff) << 1);
8164 tmp
= load_reg(s
, 14);
8165 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8166 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8168 tmp2
= tcg_temp_new_i32();
8169 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8170 store_reg(s
, 14, tmp2
);
8174 if (insn
& (1 << 11)) {
8175 /* Second half of bl. */
8176 offset
= ((insn
& 0x7ff) << 1) | 1;
8177 tmp
= load_reg(s
, 14);
8178 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8180 tmp2
= tcg_temp_new_i32();
8181 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8182 store_reg(s
, 14, tmp2
);
8186 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8187 /* Instruction spans a page boundary. Implement it as two
8188 16-bit instructions in case the second half causes an
8190 offset
= ((int32_t)insn
<< 21) >> 9;
8191 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8194 /* Fall through to 32-bit decode. */
8197 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8199 insn
|= (uint32_t)insn_hw1
<< 16;
8201 if ((insn
& 0xf800e800) != 0xf000e800) {
8205 rn
= (insn
>> 16) & 0xf;
8206 rs
= (insn
>> 12) & 0xf;
8207 rd
= (insn
>> 8) & 0xf;
8209 switch ((insn
>> 25) & 0xf) {
8210 case 0: case 1: case 2: case 3:
8211 /* 16-bit instructions. Should never happen. */
8214 if (insn
& (1 << 22)) {
8215 /* Other load/store, table branch. */
8216 if (insn
& 0x01200000) {
8217 /* Load/store doubleword. */
8219 addr
= tcg_temp_new_i32();
8220 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8222 addr
= load_reg(s
, rn
);
8224 offset
= (insn
& 0xff) * 4;
8225 if ((insn
& (1 << 23)) == 0)
8227 if (insn
& (1 << 24)) {
8228 tcg_gen_addi_i32(addr
, addr
, offset
);
8231 if (insn
& (1 << 20)) {
8233 tmp
= tcg_temp_new_i32();
8234 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8235 store_reg(s
, rs
, tmp
);
8236 tcg_gen_addi_i32(addr
, addr
, 4);
8237 tmp
= tcg_temp_new_i32();
8238 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8239 store_reg(s
, rd
, tmp
);
8242 tmp
= load_reg(s
, rs
);
8243 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8244 tcg_temp_free_i32(tmp
);
8245 tcg_gen_addi_i32(addr
, addr
, 4);
8246 tmp
= load_reg(s
, rd
);
8247 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8248 tcg_temp_free_i32(tmp
);
8250 if (insn
& (1 << 21)) {
8251 /* Base writeback. */
8254 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8255 store_reg(s
, rn
, addr
);
8257 tcg_temp_free_i32(addr
);
8259 } else if ((insn
& (1 << 23)) == 0) {
8260 /* Load/store exclusive word. */
8261 addr
= tcg_temp_local_new_i32();
8262 load_reg_var(s
, addr
, rn
);
8263 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8264 if (insn
& (1 << 20)) {
8265 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8267 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8269 tcg_temp_free_i32(addr
);
8270 } else if ((insn
& (7 << 5)) == 0) {
8273 addr
= tcg_temp_new_i32();
8274 tcg_gen_movi_i32(addr
, s
->pc
);
8276 addr
= load_reg(s
, rn
);
8278 tmp
= load_reg(s
, rm
);
8279 tcg_gen_add_i32(addr
, addr
, tmp
);
8280 if (insn
& (1 << 4)) {
8282 tcg_gen_add_i32(addr
, addr
, tmp
);
8283 tcg_temp_free_i32(tmp
);
8284 tmp
= tcg_temp_new_i32();
8285 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8287 tcg_temp_free_i32(tmp
);
8288 tmp
= tcg_temp_new_i32();
8289 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8291 tcg_temp_free_i32(addr
);
8292 tcg_gen_shli_i32(tmp
, tmp
, 1);
8293 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8294 store_reg(s
, 15, tmp
);
8296 int op2
= (insn
>> 6) & 0x3;
8297 op
= (insn
>> 4) & 0x3;
8302 /* Load/store exclusive byte/halfword/doubleword */
8309 /* Load-acquire/store-release */
8315 /* Load-acquire/store-release exclusive */
8319 addr
= tcg_temp_local_new_i32();
8320 load_reg_var(s
, addr
, rn
);
8322 if (insn
& (1 << 20)) {
8323 tmp
= tcg_temp_new_i32();
8326 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8329 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8332 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8337 store_reg(s
, rs
, tmp
);
8339 tmp
= load_reg(s
, rs
);
8342 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8345 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8348 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8353 tcg_temp_free_i32(tmp
);
8355 } else if (insn
& (1 << 20)) {
8356 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8358 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8360 tcg_temp_free_i32(addr
);
8363 /* Load/store multiple, RFE, SRS. */
8364 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8365 /* RFE, SRS: not available in user mode or on M profile */
8366 if (IS_USER(s
) || IS_M(env
)) {
8369 if (insn
& (1 << 20)) {
8371 addr
= load_reg(s
, rn
);
8372 if ((insn
& (1 << 24)) == 0)
8373 tcg_gen_addi_i32(addr
, addr
, -8);
8374 /* Load PC into tmp and CPSR into tmp2. */
8375 tmp
= tcg_temp_new_i32();
8376 gen_aa32_ld32u(tmp
, addr
, 0);
8377 tcg_gen_addi_i32(addr
, addr
, 4);
8378 tmp2
= tcg_temp_new_i32();
8379 gen_aa32_ld32u(tmp2
, addr
, 0);
8380 if (insn
& (1 << 21)) {
8381 /* Base writeback. */
8382 if (insn
& (1 << 24)) {
8383 tcg_gen_addi_i32(addr
, addr
, 4);
8385 tcg_gen_addi_i32(addr
, addr
, -4);
8387 store_reg(s
, rn
, addr
);
8389 tcg_temp_free_i32(addr
);
8391 gen_rfe(s
, tmp
, tmp2
);
8394 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8398 int i
, loaded_base
= 0;
8399 TCGv_i32 loaded_var
;
8400 /* Load/store multiple. */
8401 addr
= load_reg(s
, rn
);
8403 for (i
= 0; i
< 16; i
++) {
8404 if (insn
& (1 << i
))
8407 if (insn
& (1 << 24)) {
8408 tcg_gen_addi_i32(addr
, addr
, -offset
);
8411 TCGV_UNUSED_I32(loaded_var
);
8412 for (i
= 0; i
< 16; i
++) {
8413 if ((insn
& (1 << i
)) == 0)
8415 if (insn
& (1 << 20)) {
8417 tmp
= tcg_temp_new_i32();
8418 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8421 } else if (i
== rn
) {
8425 store_reg(s
, i
, tmp
);
8429 tmp
= load_reg(s
, i
);
8430 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8431 tcg_temp_free_i32(tmp
);
8433 tcg_gen_addi_i32(addr
, addr
, 4);
8436 store_reg(s
, rn
, loaded_var
);
8438 if (insn
& (1 << 21)) {
8439 /* Base register writeback. */
8440 if (insn
& (1 << 24)) {
8441 tcg_gen_addi_i32(addr
, addr
, -offset
);
8443 /* Fault if writeback register is in register list. */
8444 if (insn
& (1 << rn
))
8446 store_reg(s
, rn
, addr
);
8448 tcg_temp_free_i32(addr
);
8455 op
= (insn
>> 21) & 0xf;
8457 /* Halfword pack. */
8458 tmp
= load_reg(s
, rn
);
8459 tmp2
= load_reg(s
, rm
);
8460 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8461 if (insn
& (1 << 5)) {
8465 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8466 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8467 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8471 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8472 tcg_gen_ext16u_i32(tmp
, tmp
);
8473 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8475 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8476 tcg_temp_free_i32(tmp2
);
8477 store_reg(s
, rd
, tmp
);
8479 /* Data processing register constant shift. */
8481 tmp
= tcg_temp_new_i32();
8482 tcg_gen_movi_i32(tmp
, 0);
8484 tmp
= load_reg(s
, rn
);
8486 tmp2
= load_reg(s
, rm
);
8488 shiftop
= (insn
>> 4) & 3;
8489 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8490 conds
= (insn
& (1 << 20)) != 0;
8491 logic_cc
= (conds
&& thumb2_logic_op(op
));
8492 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8493 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8495 tcg_temp_free_i32(tmp2
);
8497 store_reg(s
, rd
, tmp
);
8499 tcg_temp_free_i32(tmp
);
8503 case 13: /* Misc data processing. */
8504 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8505 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8508 case 0: /* Register controlled shift. */
8509 tmp
= load_reg(s
, rn
);
8510 tmp2
= load_reg(s
, rm
);
8511 if ((insn
& 0x70) != 0)
8513 op
= (insn
>> 21) & 3;
8514 logic_cc
= (insn
& (1 << 20)) != 0;
8515 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8518 store_reg_bx(env
, s
, rd
, tmp
);
8520 case 1: /* Sign/zero extend. */
8521 tmp
= load_reg(s
, rm
);
8522 shift
= (insn
>> 4) & 3;
8523 /* ??? In many cases it's not necessary to do a
8524 rotate, a shift is sufficient. */
8526 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8527 op
= (insn
>> 20) & 7;
8529 case 0: gen_sxth(tmp
); break;
8530 case 1: gen_uxth(tmp
); break;
8531 case 2: gen_sxtb16(tmp
); break;
8532 case 3: gen_uxtb16(tmp
); break;
8533 case 4: gen_sxtb(tmp
); break;
8534 case 5: gen_uxtb(tmp
); break;
8535 default: goto illegal_op
;
8538 tmp2
= load_reg(s
, rn
);
8539 if ((op
>> 1) == 1) {
8540 gen_add16(tmp
, tmp2
);
8542 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8543 tcg_temp_free_i32(tmp2
);
8546 store_reg(s
, rd
, tmp
);
8548 case 2: /* SIMD add/subtract. */
8549 op
= (insn
>> 20) & 7;
8550 shift
= (insn
>> 4) & 7;
8551 if ((op
& 3) == 3 || (shift
& 3) == 3)
8553 tmp
= load_reg(s
, rn
);
8554 tmp2
= load_reg(s
, rm
);
8555 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8556 tcg_temp_free_i32(tmp2
);
8557 store_reg(s
, rd
, tmp
);
8559 case 3: /* Other data processing. */
8560 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8562 /* Saturating add/subtract. */
8563 tmp
= load_reg(s
, rn
);
8564 tmp2
= load_reg(s
, rm
);
8566 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8568 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8570 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8571 tcg_temp_free_i32(tmp2
);
8573 tmp
= load_reg(s
, rn
);
8575 case 0x0a: /* rbit */
8576 gen_helper_rbit(tmp
, tmp
);
8578 case 0x08: /* rev */
8579 tcg_gen_bswap32_i32(tmp
, tmp
);
8581 case 0x09: /* rev16 */
8584 case 0x0b: /* revsh */
8587 case 0x10: /* sel */
8588 tmp2
= load_reg(s
, rm
);
8589 tmp3
= tcg_temp_new_i32();
8590 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8591 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8592 tcg_temp_free_i32(tmp3
);
8593 tcg_temp_free_i32(tmp2
);
8595 case 0x18: /* clz */
8596 gen_helper_clz(tmp
, tmp
);
8602 store_reg(s
, rd
, tmp
);
8604 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8605 op
= (insn
>> 4) & 0xf;
8606 tmp
= load_reg(s
, rn
);
8607 tmp2
= load_reg(s
, rm
);
8608 switch ((insn
>> 20) & 7) {
8609 case 0: /* 32 x 32 -> 32 */
8610 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8611 tcg_temp_free_i32(tmp2
);
8613 tmp2
= load_reg(s
, rs
);
8615 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8617 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8618 tcg_temp_free_i32(tmp2
);
8621 case 1: /* 16 x 16 -> 32 */
8622 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8623 tcg_temp_free_i32(tmp2
);
8625 tmp2
= load_reg(s
, rs
);
8626 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8627 tcg_temp_free_i32(tmp2
);
8630 case 2: /* Dual multiply add. */
8631 case 4: /* Dual multiply subtract. */
8633 gen_swap_half(tmp2
);
8634 gen_smul_dual(tmp
, tmp2
);
8635 if (insn
& (1 << 22)) {
8636 /* This subtraction cannot overflow. */
8637 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8639 /* This addition cannot overflow 32 bits;
8640 * however it may overflow considered as a signed
8641 * operation, in which case we must set the Q flag.
8643 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8645 tcg_temp_free_i32(tmp2
);
8648 tmp2
= load_reg(s
, rs
);
8649 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8650 tcg_temp_free_i32(tmp2
);
8653 case 3: /* 32 * 16 -> 32msb */
8655 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8658 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8659 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8660 tmp
= tcg_temp_new_i32();
8661 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8662 tcg_temp_free_i64(tmp64
);
8665 tmp2
= load_reg(s
, rs
);
8666 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8667 tcg_temp_free_i32(tmp2
);
8670 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8671 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8673 tmp
= load_reg(s
, rs
);
8674 if (insn
& (1 << 20)) {
8675 tmp64
= gen_addq_msw(tmp64
, tmp
);
8677 tmp64
= gen_subq_msw(tmp64
, tmp
);
8680 if (insn
& (1 << 4)) {
8681 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8683 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8684 tmp
= tcg_temp_new_i32();
8685 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8686 tcg_temp_free_i64(tmp64
);
8688 case 7: /* Unsigned sum of absolute differences. */
8689 gen_helper_usad8(tmp
, tmp
, tmp2
);
8690 tcg_temp_free_i32(tmp2
);
8692 tmp2
= load_reg(s
, rs
);
8693 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8694 tcg_temp_free_i32(tmp2
);
8698 store_reg(s
, rd
, tmp
);
8700 case 6: case 7: /* 64-bit multiply, Divide. */
8701 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8702 tmp
= load_reg(s
, rn
);
8703 tmp2
= load_reg(s
, rm
);
8704 if ((op
& 0x50) == 0x10) {
8706 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8710 gen_helper_udiv(tmp
, tmp
, tmp2
);
8712 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8713 tcg_temp_free_i32(tmp2
);
8714 store_reg(s
, rd
, tmp
);
8715 } else if ((op
& 0xe) == 0xc) {
8716 /* Dual multiply accumulate long. */
8718 gen_swap_half(tmp2
);
8719 gen_smul_dual(tmp
, tmp2
);
8721 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8723 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8725 tcg_temp_free_i32(tmp2
);
8727 tmp64
= tcg_temp_new_i64();
8728 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8729 tcg_temp_free_i32(tmp
);
8730 gen_addq(s
, tmp64
, rs
, rd
);
8731 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8732 tcg_temp_free_i64(tmp64
);
8735 /* Unsigned 64-bit multiply */
8736 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8740 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8741 tcg_temp_free_i32(tmp2
);
8742 tmp64
= tcg_temp_new_i64();
8743 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8744 tcg_temp_free_i32(tmp
);
8746 /* Signed 64-bit multiply */
8747 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8752 gen_addq_lo(s
, tmp64
, rs
);
8753 gen_addq_lo(s
, tmp64
, rd
);
8754 } else if (op
& 0x40) {
8755 /* 64-bit accumulate. */
8756 gen_addq(s
, tmp64
, rs
, rd
);
8758 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8759 tcg_temp_free_i64(tmp64
);
8764 case 6: case 7: case 14: case 15:
8766 if (((insn
>> 24) & 3) == 3) {
8767 /* Translate into the equivalent ARM encoding. */
8768 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8769 if (disas_neon_data_insn(env
, s
, insn
))
8772 if (insn
& (1 << 28))
8774 if (disas_coproc_insn (env
, s
, insn
))
8778 case 8: case 9: case 10: case 11:
8779 if (insn
& (1 << 15)) {
8780 /* Branches, misc control. */
8781 if (insn
& 0x5000) {
8782 /* Unconditional branch. */
8783 /* signextend(hw1[10:0]) -> offset[:12]. */
8784 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8785 /* hw1[10:0] -> offset[11:1]. */
8786 offset
|= (insn
& 0x7ff) << 1;
8787 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8788 offset[24:22] already have the same value because of the
8789 sign extension above. */
8790 offset
^= ((~insn
) & (1 << 13)) << 10;
8791 offset
^= ((~insn
) & (1 << 11)) << 11;
8793 if (insn
& (1 << 14)) {
8794 /* Branch and link. */
8795 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8799 if (insn
& (1 << 12)) {
8804 offset
&= ~(uint32_t)2;
8805 /* thumb2 bx, no need to check */
8806 gen_bx_im(s
, offset
);
8808 } else if (((insn
>> 23) & 7) == 7) {
8810 if (insn
& (1 << 13))
8813 if (insn
& (1 << 26)) {
8814 /* Secure monitor call (v6Z) */
8815 qemu_log_mask(LOG_UNIMP
,
8816 "arm: unimplemented secure monitor call\n");
8817 goto illegal_op
; /* not implemented. */
8819 op
= (insn
>> 20) & 7;
8821 case 0: /* msr cpsr. */
8823 tmp
= load_reg(s
, rn
);
8824 addr
= tcg_const_i32(insn
& 0xff);
8825 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8826 tcg_temp_free_i32(addr
);
8827 tcg_temp_free_i32(tmp
);
8832 case 1: /* msr spsr. */
8835 tmp
= load_reg(s
, rn
);
8837 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8841 case 2: /* cps, nop-hint. */
8842 if (((insn
>> 8) & 7) == 0) {
8843 gen_nop_hint(s
, insn
& 0xff);
8845 /* Implemented as NOP in user mode. */
8850 if (insn
& (1 << 10)) {
8851 if (insn
& (1 << 7))
8853 if (insn
& (1 << 6))
8855 if (insn
& (1 << 5))
8857 if (insn
& (1 << 9))
8858 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8860 if (insn
& (1 << 8)) {
8862 imm
|= (insn
& 0x1f);
8865 gen_set_psr_im(s
, offset
, 0, imm
);
8868 case 3: /* Special control operations. */
8870 op
= (insn
>> 4) & 0xf;
8878 /* These execute as NOPs. */
8885 /* Trivial implementation equivalent to bx. */
8886 tmp
= load_reg(s
, rn
);
8889 case 5: /* Exception return. */
8893 if (rn
!= 14 || rd
!= 15) {
8896 tmp
= load_reg(s
, rn
);
8897 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8898 gen_exception_return(s
, tmp
);
8900 case 6: /* mrs cpsr. */
8901 tmp
= tcg_temp_new_i32();
8903 addr
= tcg_const_i32(insn
& 0xff);
8904 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8905 tcg_temp_free_i32(addr
);
8907 gen_helper_cpsr_read(tmp
, cpu_env
);
8909 store_reg(s
, rd
, tmp
);
8911 case 7: /* mrs spsr. */
8912 /* Not accessible in user mode. */
8913 if (IS_USER(s
) || IS_M(env
))
8915 tmp
= load_cpu_field(spsr
);
8916 store_reg(s
, rd
, tmp
);
8921 /* Conditional branch. */
8922 op
= (insn
>> 22) & 0xf;
8923 /* Generate a conditional jump to next instruction. */
8924 s
->condlabel
= gen_new_label();
8925 gen_test_cc(op
^ 1, s
->condlabel
);
8928 /* offset[11:1] = insn[10:0] */
8929 offset
= (insn
& 0x7ff) << 1;
8930 /* offset[17:12] = insn[21:16]. */
8931 offset
|= (insn
& 0x003f0000) >> 4;
8932 /* offset[31:20] = insn[26]. */
8933 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8934 /* offset[18] = insn[13]. */
8935 offset
|= (insn
& (1 << 13)) << 5;
8936 /* offset[19] = insn[11]. */
8937 offset
|= (insn
& (1 << 11)) << 8;
8939 /* jump to the offset */
8940 gen_jmp(s
, s
->pc
+ offset
);
8943 /* Data processing immediate. */
8944 if (insn
& (1 << 25)) {
8945 if (insn
& (1 << 24)) {
8946 if (insn
& (1 << 20))
8948 /* Bitfield/Saturate. */
8949 op
= (insn
>> 21) & 7;
8951 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8953 tmp
= tcg_temp_new_i32();
8954 tcg_gen_movi_i32(tmp
, 0);
8956 tmp
= load_reg(s
, rn
);
8959 case 2: /* Signed bitfield extract. */
8961 if (shift
+ imm
> 32)
8964 gen_sbfx(tmp
, shift
, imm
);
8966 case 6: /* Unsigned bitfield extract. */
8968 if (shift
+ imm
> 32)
8971 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8973 case 3: /* Bitfield insert/clear. */
8976 imm
= imm
+ 1 - shift
;
8978 tmp2
= load_reg(s
, rd
);
8979 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8980 tcg_temp_free_i32(tmp2
);
8985 default: /* Saturate. */
8988 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8990 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8992 tmp2
= tcg_const_i32(imm
);
8995 if ((op
& 1) && shift
== 0)
8996 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8998 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9001 if ((op
& 1) && shift
== 0)
9002 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9004 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9006 tcg_temp_free_i32(tmp2
);
9009 store_reg(s
, rd
, tmp
);
9011 imm
= ((insn
& 0x04000000) >> 15)
9012 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9013 if (insn
& (1 << 22)) {
9014 /* 16-bit immediate. */
9015 imm
|= (insn
>> 4) & 0xf000;
9016 if (insn
& (1 << 23)) {
9018 tmp
= load_reg(s
, rd
);
9019 tcg_gen_ext16u_i32(tmp
, tmp
);
9020 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9023 tmp
= tcg_temp_new_i32();
9024 tcg_gen_movi_i32(tmp
, imm
);
9027 /* Add/sub 12-bit immediate. */
9029 offset
= s
->pc
& ~(uint32_t)3;
9030 if (insn
& (1 << 23))
9034 tmp
= tcg_temp_new_i32();
9035 tcg_gen_movi_i32(tmp
, offset
);
9037 tmp
= load_reg(s
, rn
);
9038 if (insn
& (1 << 23))
9039 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9041 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9044 store_reg(s
, rd
, tmp
);
9047 int shifter_out
= 0;
9048 /* modified 12-bit immediate. */
9049 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9050 imm
= (insn
& 0xff);
9053 /* Nothing to do. */
9055 case 1: /* 00XY00XY */
9058 case 2: /* XY00XY00 */
9062 case 3: /* XYXYXYXY */
9066 default: /* Rotated constant. */
9067 shift
= (shift
<< 1) | (imm
>> 7);
9069 imm
= imm
<< (32 - shift
);
9073 tmp2
= tcg_temp_new_i32();
9074 tcg_gen_movi_i32(tmp2
, imm
);
9075 rn
= (insn
>> 16) & 0xf;
9077 tmp
= tcg_temp_new_i32();
9078 tcg_gen_movi_i32(tmp
, 0);
9080 tmp
= load_reg(s
, rn
);
9082 op
= (insn
>> 21) & 0xf;
9083 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9084 shifter_out
, tmp
, tmp2
))
9086 tcg_temp_free_i32(tmp2
);
9087 rd
= (insn
>> 8) & 0xf;
9089 store_reg(s
, rd
, tmp
);
9091 tcg_temp_free_i32(tmp
);
9096 case 12: /* Load/store single data item. */
9101 if ((insn
& 0x01100000) == 0x01000000) {
9102 if (disas_neon_ls_insn(env
, s
, insn
))
9106 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9108 if (!(insn
& (1 << 20))) {
9112 /* Byte or halfword load space with dest == r15 : memory hints.
9113 * Catch them early so we don't emit pointless addressing code.
9114 * This space is a mix of:
9115 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9116 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9118 * unallocated hints, which must be treated as NOPs
9119 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9120 * which is easiest for the decoding logic
9121 * Some space which must UNDEF
9123 int op1
= (insn
>> 23) & 3;
9124 int op2
= (insn
>> 6) & 0x3f;
9129 /* UNPREDICTABLE, unallocated hint or
9130 * PLD/PLDW/PLI (literal)
9135 return 0; /* PLD/PLDW/PLI or unallocated hint */
9137 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9138 return 0; /* PLD/PLDW/PLI or unallocated hint */
9140 /* UNDEF space, or an UNPREDICTABLE */
9146 addr
= tcg_temp_new_i32();
9148 /* s->pc has already been incremented by 4. */
9149 imm
= s
->pc
& 0xfffffffc;
9150 if (insn
& (1 << 23))
9151 imm
+= insn
& 0xfff;
9153 imm
-= insn
& 0xfff;
9154 tcg_gen_movi_i32(addr
, imm
);
9156 addr
= load_reg(s
, rn
);
9157 if (insn
& (1 << 23)) {
9158 /* Positive offset. */
9160 tcg_gen_addi_i32(addr
, addr
, imm
);
9163 switch ((insn
>> 8) & 0xf) {
9164 case 0x0: /* Shifted Register. */
9165 shift
= (insn
>> 4) & 0xf;
9167 tcg_temp_free_i32(addr
);
9170 tmp
= load_reg(s
, rm
);
9172 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9173 tcg_gen_add_i32(addr
, addr
, tmp
);
9174 tcg_temp_free_i32(tmp
);
9176 case 0xc: /* Negative offset. */
9177 tcg_gen_addi_i32(addr
, addr
, -imm
);
9179 case 0xe: /* User privilege. */
9180 tcg_gen_addi_i32(addr
, addr
, imm
);
9183 case 0x9: /* Post-decrement. */
9186 case 0xb: /* Post-increment. */
9190 case 0xd: /* Pre-decrement. */
9193 case 0xf: /* Pre-increment. */
9194 tcg_gen_addi_i32(addr
, addr
, imm
);
9198 tcg_temp_free_i32(addr
);
9203 if (insn
& (1 << 20)) {
9205 tmp
= tcg_temp_new_i32();
9208 gen_aa32_ld8u(tmp
, addr
, user
);
9211 gen_aa32_ld8s(tmp
, addr
, user
);
9214 gen_aa32_ld16u(tmp
, addr
, user
);
9217 gen_aa32_ld16s(tmp
, addr
, user
);
9220 gen_aa32_ld32u(tmp
, addr
, user
);
9223 tcg_temp_free_i32(tmp
);
9224 tcg_temp_free_i32(addr
);
9230 store_reg(s
, rs
, tmp
);
9234 tmp
= load_reg(s
, rs
);
9237 gen_aa32_st8(tmp
, addr
, user
);
9240 gen_aa32_st16(tmp
, addr
, user
);
9243 gen_aa32_st32(tmp
, addr
, user
);
9246 tcg_temp_free_i32(tmp
);
9247 tcg_temp_free_i32(addr
);
9250 tcg_temp_free_i32(tmp
);
9253 tcg_gen_addi_i32(addr
, addr
, imm
);
9255 store_reg(s
, rn
, addr
);
9257 tcg_temp_free_i32(addr
);
9269 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9271 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9278 if (s
->condexec_mask
) {
9279 cond
= s
->condexec_cond
;
9280 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9281 s
->condlabel
= gen_new_label();
9282 gen_test_cc(cond
^ 1, s
->condlabel
);
9287 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9290 switch (insn
>> 12) {
9294 op
= (insn
>> 11) & 3;
9297 rn
= (insn
>> 3) & 7;
9298 tmp
= load_reg(s
, rn
);
9299 if (insn
& (1 << 10)) {
9301 tmp2
= tcg_temp_new_i32();
9302 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9305 rm
= (insn
>> 6) & 7;
9306 tmp2
= load_reg(s
, rm
);
9308 if (insn
& (1 << 9)) {
9309 if (s
->condexec_mask
)
9310 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9312 gen_sub_CC(tmp
, tmp
, tmp2
);
9314 if (s
->condexec_mask
)
9315 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9317 gen_add_CC(tmp
, tmp
, tmp2
);
9319 tcg_temp_free_i32(tmp2
);
9320 store_reg(s
, rd
, tmp
);
9322 /* shift immediate */
9323 rm
= (insn
>> 3) & 7;
9324 shift
= (insn
>> 6) & 0x1f;
9325 tmp
= load_reg(s
, rm
);
9326 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9327 if (!s
->condexec_mask
)
9329 store_reg(s
, rd
, tmp
);
9333 /* arithmetic large immediate */
9334 op
= (insn
>> 11) & 3;
9335 rd
= (insn
>> 8) & 0x7;
9336 if (op
== 0) { /* mov */
9337 tmp
= tcg_temp_new_i32();
9338 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9339 if (!s
->condexec_mask
)
9341 store_reg(s
, rd
, tmp
);
9343 tmp
= load_reg(s
, rd
);
9344 tmp2
= tcg_temp_new_i32();
9345 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9348 gen_sub_CC(tmp
, tmp
, tmp2
);
9349 tcg_temp_free_i32(tmp
);
9350 tcg_temp_free_i32(tmp2
);
9353 if (s
->condexec_mask
)
9354 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9356 gen_add_CC(tmp
, tmp
, tmp2
);
9357 tcg_temp_free_i32(tmp2
);
9358 store_reg(s
, rd
, tmp
);
9361 if (s
->condexec_mask
)
9362 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9364 gen_sub_CC(tmp
, tmp
, tmp2
);
9365 tcg_temp_free_i32(tmp2
);
9366 store_reg(s
, rd
, tmp
);
9372 if (insn
& (1 << 11)) {
9373 rd
= (insn
>> 8) & 7;
9374 /* load pc-relative. Bit 1 of PC is ignored. */
9375 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9376 val
&= ~(uint32_t)2;
9377 addr
= tcg_temp_new_i32();
9378 tcg_gen_movi_i32(addr
, val
);
9379 tmp
= tcg_temp_new_i32();
9380 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9381 tcg_temp_free_i32(addr
);
9382 store_reg(s
, rd
, tmp
);
9385 if (insn
& (1 << 10)) {
9386 /* data processing extended or blx */
9387 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9388 rm
= (insn
>> 3) & 0xf;
9389 op
= (insn
>> 8) & 3;
9392 tmp
= load_reg(s
, rd
);
9393 tmp2
= load_reg(s
, rm
);
9394 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9395 tcg_temp_free_i32(tmp2
);
9396 store_reg(s
, rd
, tmp
);
9399 tmp
= load_reg(s
, rd
);
9400 tmp2
= load_reg(s
, rm
);
9401 gen_sub_CC(tmp
, tmp
, tmp2
);
9402 tcg_temp_free_i32(tmp2
);
9403 tcg_temp_free_i32(tmp
);
9405 case 2: /* mov/cpy */
9406 tmp
= load_reg(s
, rm
);
9407 store_reg(s
, rd
, tmp
);
9409 case 3:/* branch [and link] exchange thumb register */
9410 tmp
= load_reg(s
, rm
);
9411 if (insn
& (1 << 7)) {
9413 val
= (uint32_t)s
->pc
| 1;
9414 tmp2
= tcg_temp_new_i32();
9415 tcg_gen_movi_i32(tmp2
, val
);
9416 store_reg(s
, 14, tmp2
);
9418 /* already thumb, no need to check */
9425 /* data processing register */
9427 rm
= (insn
>> 3) & 7;
9428 op
= (insn
>> 6) & 0xf;
9429 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9430 /* the shift/rotate ops want the operands backwards */
9439 if (op
== 9) { /* neg */
9440 tmp
= tcg_temp_new_i32();
9441 tcg_gen_movi_i32(tmp
, 0);
9442 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9443 tmp
= load_reg(s
, rd
);
9445 TCGV_UNUSED_I32(tmp
);
9448 tmp2
= load_reg(s
, rm
);
9451 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9452 if (!s
->condexec_mask
)
9456 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9457 if (!s
->condexec_mask
)
9461 if (s
->condexec_mask
) {
9462 gen_shl(tmp2
, tmp2
, tmp
);
9464 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9469 if (s
->condexec_mask
) {
9470 gen_shr(tmp2
, tmp2
, tmp
);
9472 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9477 if (s
->condexec_mask
) {
9478 gen_sar(tmp2
, tmp2
, tmp
);
9480 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9485 if (s
->condexec_mask
) {
9488 gen_adc_CC(tmp
, tmp
, tmp2
);
9492 if (s
->condexec_mask
) {
9493 gen_sub_carry(tmp
, tmp
, tmp2
);
9495 gen_sbc_CC(tmp
, tmp
, tmp2
);
9499 if (s
->condexec_mask
) {
9500 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9501 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9503 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9508 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9513 if (s
->condexec_mask
)
9514 tcg_gen_neg_i32(tmp
, tmp2
);
9516 gen_sub_CC(tmp
, tmp
, tmp2
);
9519 gen_sub_CC(tmp
, tmp
, tmp2
);
9523 gen_add_CC(tmp
, tmp
, tmp2
);
9527 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9528 if (!s
->condexec_mask
)
9532 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9533 if (!s
->condexec_mask
)
9537 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9538 if (!s
->condexec_mask
)
9542 tcg_gen_not_i32(tmp2
, tmp2
);
9543 if (!s
->condexec_mask
)
9551 store_reg(s
, rm
, tmp2
);
9553 tcg_temp_free_i32(tmp
);
9555 store_reg(s
, rd
, tmp
);
9556 tcg_temp_free_i32(tmp2
);
9559 tcg_temp_free_i32(tmp
);
9560 tcg_temp_free_i32(tmp2
);
9565 /* load/store register offset. */
9567 rn
= (insn
>> 3) & 7;
9568 rm
= (insn
>> 6) & 7;
9569 op
= (insn
>> 9) & 7;
9570 addr
= load_reg(s
, rn
);
9571 tmp
= load_reg(s
, rm
);
9572 tcg_gen_add_i32(addr
, addr
, tmp
);
9573 tcg_temp_free_i32(tmp
);
9575 if (op
< 3) { /* store */
9576 tmp
= load_reg(s
, rd
);
9578 tmp
= tcg_temp_new_i32();
9583 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9586 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9589 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9592 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
9595 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9598 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9601 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9604 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
9607 if (op
>= 3) { /* load */
9608 store_reg(s
, rd
, tmp
);
9610 tcg_temp_free_i32(tmp
);
9612 tcg_temp_free_i32(addr
);
9616 /* load/store word immediate offset */
9618 rn
= (insn
>> 3) & 7;
9619 addr
= load_reg(s
, rn
);
9620 val
= (insn
>> 4) & 0x7c;
9621 tcg_gen_addi_i32(addr
, addr
, val
);
9623 if (insn
& (1 << 11)) {
9625 tmp
= tcg_temp_new_i32();
9626 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9627 store_reg(s
, rd
, tmp
);
9630 tmp
= load_reg(s
, rd
);
9631 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9632 tcg_temp_free_i32(tmp
);
9634 tcg_temp_free_i32(addr
);
9638 /* load/store byte immediate offset */
9640 rn
= (insn
>> 3) & 7;
9641 addr
= load_reg(s
, rn
);
9642 val
= (insn
>> 6) & 0x1f;
9643 tcg_gen_addi_i32(addr
, addr
, val
);
9645 if (insn
& (1 << 11)) {
9647 tmp
= tcg_temp_new_i32();
9648 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9649 store_reg(s
, rd
, tmp
);
9652 tmp
= load_reg(s
, rd
);
9653 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9654 tcg_temp_free_i32(tmp
);
9656 tcg_temp_free_i32(addr
);
9660 /* load/store halfword immediate offset */
9662 rn
= (insn
>> 3) & 7;
9663 addr
= load_reg(s
, rn
);
9664 val
= (insn
>> 5) & 0x3e;
9665 tcg_gen_addi_i32(addr
, addr
, val
);
9667 if (insn
& (1 << 11)) {
9669 tmp
= tcg_temp_new_i32();
9670 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9671 store_reg(s
, rd
, tmp
);
9674 tmp
= load_reg(s
, rd
);
9675 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9676 tcg_temp_free_i32(tmp
);
9678 tcg_temp_free_i32(addr
);
9682 /* load/store from stack */
9683 rd
= (insn
>> 8) & 7;
9684 addr
= load_reg(s
, 13);
9685 val
= (insn
& 0xff) * 4;
9686 tcg_gen_addi_i32(addr
, addr
, val
);
9688 if (insn
& (1 << 11)) {
9690 tmp
= tcg_temp_new_i32();
9691 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9692 store_reg(s
, rd
, tmp
);
9695 tmp
= load_reg(s
, rd
);
9696 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9697 tcg_temp_free_i32(tmp
);
9699 tcg_temp_free_i32(addr
);
9703 /* add to high reg */
9704 rd
= (insn
>> 8) & 7;
9705 if (insn
& (1 << 11)) {
9707 tmp
= load_reg(s
, 13);
9709 /* PC. bit 1 is ignored. */
9710 tmp
= tcg_temp_new_i32();
9711 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9713 val
= (insn
& 0xff) * 4;
9714 tcg_gen_addi_i32(tmp
, tmp
, val
);
9715 store_reg(s
, rd
, tmp
);
9720 op
= (insn
>> 8) & 0xf;
9723 /* adjust stack pointer */
9724 tmp
= load_reg(s
, 13);
9725 val
= (insn
& 0x7f) * 4;
9726 if (insn
& (1 << 7))
9727 val
= -(int32_t)val
;
9728 tcg_gen_addi_i32(tmp
, tmp
, val
);
9729 store_reg(s
, 13, tmp
);
9732 case 2: /* sign/zero extend. */
9735 rm
= (insn
>> 3) & 7;
9736 tmp
= load_reg(s
, rm
);
9737 switch ((insn
>> 6) & 3) {
9738 case 0: gen_sxth(tmp
); break;
9739 case 1: gen_sxtb(tmp
); break;
9740 case 2: gen_uxth(tmp
); break;
9741 case 3: gen_uxtb(tmp
); break;
9743 store_reg(s
, rd
, tmp
);
9745 case 4: case 5: case 0xc: case 0xd:
9747 addr
= load_reg(s
, 13);
9748 if (insn
& (1 << 8))
9752 for (i
= 0; i
< 8; i
++) {
9753 if (insn
& (1 << i
))
9756 if ((insn
& (1 << 11)) == 0) {
9757 tcg_gen_addi_i32(addr
, addr
, -offset
);
9759 for (i
= 0; i
< 8; i
++) {
9760 if (insn
& (1 << i
)) {
9761 if (insn
& (1 << 11)) {
9763 tmp
= tcg_temp_new_i32();
9764 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9765 store_reg(s
, i
, tmp
);
9768 tmp
= load_reg(s
, i
);
9769 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9770 tcg_temp_free_i32(tmp
);
9772 /* advance to the next address. */
9773 tcg_gen_addi_i32(addr
, addr
, 4);
9776 TCGV_UNUSED_I32(tmp
);
9777 if (insn
& (1 << 8)) {
9778 if (insn
& (1 << 11)) {
9780 tmp
= tcg_temp_new_i32();
9781 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9782 /* don't set the pc until the rest of the instruction
9786 tmp
= load_reg(s
, 14);
9787 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9788 tcg_temp_free_i32(tmp
);
9790 tcg_gen_addi_i32(addr
, addr
, 4);
9792 if ((insn
& (1 << 11)) == 0) {
9793 tcg_gen_addi_i32(addr
, addr
, -offset
);
9795 /* write back the new stack pointer */
9796 store_reg(s
, 13, addr
);
9797 /* set the new PC value */
9798 if ((insn
& 0x0900) == 0x0900) {
9799 store_reg_from_load(env
, s
, 15, tmp
);
9803 case 1: case 3: case 9: case 11: /* czb */
9805 tmp
= load_reg(s
, rm
);
9806 s
->condlabel
= gen_new_label();
9808 if (insn
& (1 << 11))
9809 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9811 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9812 tcg_temp_free_i32(tmp
);
9813 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9814 val
= (uint32_t)s
->pc
+ 2;
9819 case 15: /* IT, nop-hint. */
9820 if ((insn
& 0xf) == 0) {
9821 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9825 s
->condexec_cond
= (insn
>> 4) & 0xe;
9826 s
->condexec_mask
= insn
& 0x1f;
9827 /* No actual code generated for this insn, just setup state. */
9830 case 0xe: /* bkpt */
9832 gen_exception_insn(s
, 2, EXCP_BKPT
);
9837 rn
= (insn
>> 3) & 0x7;
9839 tmp
= load_reg(s
, rn
);
9840 switch ((insn
>> 6) & 3) {
9841 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9842 case 1: gen_rev16(tmp
); break;
9843 case 3: gen_revsh(tmp
); break;
9844 default: goto illegal_op
;
9846 store_reg(s
, rd
, tmp
);
9850 switch ((insn
>> 5) & 7) {
9854 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9855 /* Dynamic endianness switching not implemented. */
9856 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
9867 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9870 addr
= tcg_const_i32(19);
9871 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9872 tcg_temp_free_i32(addr
);
9876 addr
= tcg_const_i32(16);
9877 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9878 tcg_temp_free_i32(addr
);
9880 tcg_temp_free_i32(tmp
);
9883 if (insn
& (1 << 4)) {
9884 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9888 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9903 /* load/store multiple */
9904 TCGv_i32 loaded_var
;
9905 TCGV_UNUSED_I32(loaded_var
);
9906 rn
= (insn
>> 8) & 0x7;
9907 addr
= load_reg(s
, rn
);
9908 for (i
= 0; i
< 8; i
++) {
9909 if (insn
& (1 << i
)) {
9910 if (insn
& (1 << 11)) {
9912 tmp
= tcg_temp_new_i32();
9913 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9917 store_reg(s
, i
, tmp
);
9921 tmp
= load_reg(s
, i
);
9922 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9923 tcg_temp_free_i32(tmp
);
9925 /* advance to the next address */
9926 tcg_gen_addi_i32(addr
, addr
, 4);
9929 if ((insn
& (1 << rn
)) == 0) {
9930 /* base reg not in list: base register writeback */
9931 store_reg(s
, rn
, addr
);
9933 /* base reg in list: if load, complete it now */
9934 if (insn
& (1 << 11)) {
9935 store_reg(s
, rn
, loaded_var
);
9937 tcg_temp_free_i32(addr
);
9942 /* conditional branch or swi */
9943 cond
= (insn
>> 8) & 0xf;
9949 gen_set_pc_im(s
, s
->pc
);
9950 s
->is_jmp
= DISAS_SWI
;
9953 /* generate a conditional jump to next instruction */
9954 s
->condlabel
= gen_new_label();
9955 gen_test_cc(cond
^ 1, s
->condlabel
);
9958 /* jump to the offset */
9959 val
= (uint32_t)s
->pc
+ 2;
9960 offset
= ((int32_t)insn
<< 24) >> 24;
9966 if (insn
& (1 << 11)) {
9967 if (disas_thumb2_insn(env
, s
, insn
))
9971 /* unconditional branch */
9972 val
= (uint32_t)s
->pc
;
9973 offset
= ((int32_t)insn
<< 21) >> 21;
9974 val
+= (offset
<< 1) + 2;
9979 if (disas_thumb2_insn(env
, s
, insn
))
9985 gen_exception_insn(s
, 4, EXCP_UDEF
);
9989 gen_exception_insn(s
, 2, EXCP_UDEF
);
9992 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9993 basic block 'tb'. If search_pc is TRUE, also generate PC
9994 information for each intermediate instruction. */
9995 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
9996 TranslationBlock
*tb
,
9999 CPUState
*cs
= CPU(cpu
);
10000 CPUARMState
*env
= &cpu
->env
;
10001 DisasContext dc1
, *dc
= &dc1
;
10003 uint16_t *gen_opc_end
;
10005 target_ulong pc_start
;
10006 target_ulong next_page_start
;
10010 /* generate intermediate code */
10015 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10017 dc
->is_jmp
= DISAS_NEXT
;
10019 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10022 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10025 dc
->bswap_code
= 0;
10026 dc
->condexec_mask
= 0;
10027 dc
->condexec_cond
= 0;
10028 #if !defined(CONFIG_USER_ONLY)
10031 dc
->vfp_enabled
= 0;
10033 dc
->vec_stride
= 0;
10036 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10037 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10038 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10039 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10040 #if !defined(CONFIG_USER_ONLY)
10041 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10043 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10044 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10045 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10047 cpu_F0s
= tcg_temp_new_i32();
10048 cpu_F1s
= tcg_temp_new_i32();
10049 cpu_F0d
= tcg_temp_new_i64();
10050 cpu_F1d
= tcg_temp_new_i64();
10053 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10054 cpu_M0
= tcg_temp_new_i64();
10055 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10058 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10059 if (max_insns
== 0)
10060 max_insns
= CF_COUNT_MASK
;
10064 tcg_clear_temp_count();
10066 /* A note on handling of the condexec (IT) bits:
10068 * We want to avoid the overhead of having to write the updated condexec
10069 * bits back to the CPUARMState for every instruction in an IT block. So:
10070 * (1) if the condexec bits are not already zero then we write
10071 * zero back into the CPUARMState now. This avoids complications trying
10072 * to do it at the end of the block. (For example if we don't do this
10073 * it's hard to identify whether we can safely skip writing condexec
10074 * at the end of the TB, which we definitely want to do for the case
10075 * where a TB doesn't do anything with the IT state at all.)
10076 * (2) if we are going to leave the TB then we call gen_set_condexec()
10077 * which will write the correct value into CPUARMState if zero is wrong.
10078 * This is done both for leaving the TB at the end, and for leaving
10079 * it because of an exception we know will happen, which is done in
10080 * gen_exception_insn(). The latter is necessary because we need to
10081 * leave the TB with the PC/IT state just prior to execution of the
10082 * instruction which caused the exception.
10083 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10084 * then the CPUARMState will be wrong and we need to reset it.
10085 * This is handled in the same way as restoration of the
10086 * PC in these situations: we will be called again with search_pc=1
10087 * and generate a mapping of the condexec bits for each PC in
10088 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10089 * this to restore the condexec bits.
10091 * Note that there are no instructions which can read the condexec
10092 * bits, and none which can write non-static values to them, so
10093 * we don't need to care about whether CPUARMState is correct in the
10097 /* Reset the conditional execution bits immediately. This avoids
10098 complications trying to do it at the end of the block. */
10099 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10101 TCGv_i32 tmp
= tcg_temp_new_i32();
10102 tcg_gen_movi_i32(tmp
, 0);
10103 store_cpu_field(tmp
, condexec_bits
);
10106 #ifdef CONFIG_USER_ONLY
10107 /* Intercept jump to the magic kernel page. */
10108 if (!dc
->aarch64
&& dc
->pc
>= 0xffff0000) {
10109 /* We always get here via a jump, so know we are not in a
10110 conditional execution block. */
10111 gen_exception(EXCP_KERNEL_TRAP
);
10112 dc
->is_jmp
= DISAS_UPDATE
;
10116 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10117 /* We always get here via a jump, so know we are not in a
10118 conditional execution block. */
10119 gen_exception(EXCP_EXCEPTION_EXIT
);
10120 dc
->is_jmp
= DISAS_UPDATE
;
10125 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10126 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10127 if (bp
->pc
== dc
->pc
) {
10128 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10129 /* Advance PC so that clearing the breakpoint will
10130 invalidate this TB. */
10132 goto done_generating
;
10137 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10141 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10143 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10144 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10145 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10146 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10149 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10152 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10153 tcg_gen_debug_insn_start(dc
->pc
);
10157 disas_a64_insn(env
, dc
);
10158 } else if (dc
->thumb
) {
10159 disas_thumb_insn(env
, dc
);
10160 if (dc
->condexec_mask
) {
10161 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10162 | ((dc
->condexec_mask
>> 4) & 1);
10163 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10164 if (dc
->condexec_mask
== 0) {
10165 dc
->condexec_cond
= 0;
10169 disas_arm_insn(env
, dc
);
10172 if (dc
->condjmp
&& !dc
->is_jmp
) {
10173 gen_set_label(dc
->condlabel
);
10177 if (tcg_check_temp_count()) {
10178 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10182 /* Translation stops when a conditional branch is encountered.
10183 * Otherwise the subsequent code could get translated several times.
10184 * Also stop translation when a page boundary is reached. This
10185 * ensures prefetch aborts occur at the right place. */
10187 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10188 !cs
->singlestep_enabled
&&
10190 dc
->pc
< next_page_start
&&
10191 num_insns
< max_insns
);
10193 if (tb
->cflags
& CF_LAST_IO
) {
10195 /* FIXME: This can theoretically happen with self-modifying
10197 cpu_abort(env
, "IO on conditional branch instruction");
10202 /* At this stage dc->condjmp will only be set when the skipped
10203 instruction was a conditional branch or trap, and the PC has
10204 already been written. */
10205 if (unlikely(cs
->singlestep_enabled
)) {
10206 /* Make sure the pc is updated, and raise a debug exception. */
10208 gen_set_condexec(dc
);
10209 if (dc
->is_jmp
== DISAS_SWI
) {
10210 gen_exception(EXCP_SWI
);
10212 gen_exception(EXCP_DEBUG
);
10214 gen_set_label(dc
->condlabel
);
10216 if (dc
->condjmp
|| !dc
->is_jmp
) {
10217 gen_set_pc_im(dc
, dc
->pc
);
10220 gen_set_condexec(dc
);
10221 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10222 gen_exception(EXCP_SWI
);
10224 /* FIXME: Single stepping a WFI insn will not halt
10226 gen_exception(EXCP_DEBUG
);
10229 /* While branches must always occur at the end of an IT block,
10230 there are a few other things that can cause us to terminate
10231 the TB in the middle of an IT block:
10232 - Exception generating instructions (bkpt, swi, undefined).
10234 - Hardware watchpoints.
10235 Hardware breakpoints have already been handled and skip this code.
10237 gen_set_condexec(dc
);
10238 switch(dc
->is_jmp
) {
10240 gen_goto_tb(dc
, 1, dc
->pc
);
10245 /* indicate that the hash table must be used to find the next TB */
10246 tcg_gen_exit_tb(0);
10248 case DISAS_TB_JUMP
:
10249 /* nothing more to generate */
10252 gen_helper_wfi(cpu_env
);
10255 gen_exception(EXCP_SWI
);
10259 gen_set_label(dc
->condlabel
);
10260 gen_set_condexec(dc
);
10261 gen_goto_tb(dc
, 1, dc
->pc
);
10267 gen_tb_end(tb
, num_insns
);
10268 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10271 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10272 qemu_log("----------------\n");
10273 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10274 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10275 dc
->thumb
| (dc
->bswap_code
<< 1));
10280 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10283 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10285 tb
->size
= dc
->pc
- pc_start
;
10286 tb
->icount
= num_insns
;
10290 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10292 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10295 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10297 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10300 static const char *cpu_mode_names
[16] = {
10301 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10302 "???", "???", "???", "und", "???", "???", "???", "sys"
10305 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10308 ARMCPU
*cpu
= ARM_CPU(cs
);
10309 CPUARMState
*env
= &cpu
->env
;
10313 for(i
=0;i
<16;i
++) {
10314 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10316 cpu_fprintf(f
, "\n");
10318 cpu_fprintf(f
, " ");
10320 psr
= cpsr_read(env
);
10321 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10323 psr
& (1 << 31) ? 'N' : '-',
10324 psr
& (1 << 30) ? 'Z' : '-',
10325 psr
& (1 << 29) ? 'C' : '-',
10326 psr
& (1 << 28) ? 'V' : '-',
10327 psr
& CPSR_T
? 'T' : 'A',
10328 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10330 if (flags
& CPU_DUMP_FPU
) {
10331 int numvfpregs
= 0;
10332 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10335 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10338 for (i
= 0; i
< numvfpregs
; i
++) {
10339 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10340 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10341 i
* 2, (uint32_t)v
,
10342 i
* 2 + 1, (uint32_t)(v
>> 32),
10345 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10349 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10352 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10354 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10356 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];