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();
120 static inline TCGv_i32
load_cpu_offset(int offset
)
122 TCGv_i32 tmp
= tcg_temp_new_i32();
123 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
127 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
129 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
131 tcg_gen_st_i32(var
, cpu_env
, offset
);
132 tcg_temp_free_i32(var
);
135 #define store_cpu_field(var, name) \
136 store_cpu_offset(var, offsetof(CPUARMState, name))
138 /* Set a variable to the value of a CPU register. */
139 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
143 /* normally, since we updated PC, we need only to add one insn */
145 addr
= (long)s
->pc
+ 2;
147 addr
= (long)s
->pc
+ 4;
148 tcg_gen_movi_i32(var
, addr
);
150 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
154 /* Create a new temporary and set it to the value of a CPU register. */
155 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
157 TCGv_i32 tmp
= tcg_temp_new_i32();
158 load_reg_var(s
, tmp
, reg
);
162 /* Set a CPU register. The source must be a temporary and will be
164 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
167 tcg_gen_andi_i32(var
, var
, ~1);
168 s
->is_jmp
= DISAS_JUMP
;
170 tcg_gen_mov_i32(cpu_R
[reg
], var
);
171 tcg_temp_free_i32(var
);
174 /* Value extensions. */
175 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
176 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
177 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
178 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
180 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
181 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
184 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
186 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
187 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
188 tcg_temp_free_i32(tmp_mask
);
190 /* Set NZCV flags from the high 4 bits of var. */
191 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
193 static void gen_exception(int excp
)
195 TCGv_i32 tmp
= tcg_temp_new_i32();
196 tcg_gen_movi_i32(tmp
, excp
);
197 gen_helper_exception(cpu_env
, tmp
);
198 tcg_temp_free_i32(tmp
);
201 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
203 TCGv_i32 tmp1
= tcg_temp_new_i32();
204 TCGv_i32 tmp2
= tcg_temp_new_i32();
205 tcg_gen_ext16s_i32(tmp1
, a
);
206 tcg_gen_ext16s_i32(tmp2
, b
);
207 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
208 tcg_temp_free_i32(tmp2
);
209 tcg_gen_sari_i32(a
, a
, 16);
210 tcg_gen_sari_i32(b
, b
, 16);
211 tcg_gen_mul_i32(b
, b
, a
);
212 tcg_gen_mov_i32(a
, tmp1
);
213 tcg_temp_free_i32(tmp1
);
216 /* Byteswap each halfword. */
217 static void gen_rev16(TCGv_i32 var
)
219 TCGv_i32 tmp
= tcg_temp_new_i32();
220 tcg_gen_shri_i32(tmp
, var
, 8);
221 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
222 tcg_gen_shli_i32(var
, var
, 8);
223 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
224 tcg_gen_or_i32(var
, var
, tmp
);
225 tcg_temp_free_i32(tmp
);
228 /* Byteswap low halfword and sign extend. */
229 static void gen_revsh(TCGv_i32 var
)
231 tcg_gen_ext16u_i32(var
, var
);
232 tcg_gen_bswap16_i32(var
, var
);
233 tcg_gen_ext16s_i32(var
, var
);
236 /* Unsigned bitfield extract. */
237 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
240 tcg_gen_shri_i32(var
, var
, shift
);
241 tcg_gen_andi_i32(var
, var
, mask
);
244 /* Signed bitfield extract. */
245 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
250 tcg_gen_sari_i32(var
, var
, shift
);
251 if (shift
+ width
< 32) {
252 signbit
= 1u << (width
- 1);
253 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
254 tcg_gen_xori_i32(var
, var
, signbit
);
255 tcg_gen_subi_i32(var
, var
, signbit
);
259 /* Return (b << 32) + a. Mark inputs as dead */
260 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
262 TCGv_i64 tmp64
= tcg_temp_new_i64();
264 tcg_gen_extu_i32_i64(tmp64
, b
);
265 tcg_temp_free_i32(b
);
266 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
267 tcg_gen_add_i64(a
, tmp64
, a
);
269 tcg_temp_free_i64(tmp64
);
273 /* Return (b << 32) - a. Mark inputs as dead. */
274 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
276 TCGv_i64 tmp64
= tcg_temp_new_i64();
278 tcg_gen_extu_i32_i64(tmp64
, b
);
279 tcg_temp_free_i32(b
);
280 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
281 tcg_gen_sub_i64(a
, tmp64
, a
);
283 tcg_temp_free_i64(tmp64
);
287 /* 32x32->64 multiply. Marks inputs as dead. */
288 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
290 TCGv_i32 lo
= tcg_temp_new_i32();
291 TCGv_i32 hi
= tcg_temp_new_i32();
294 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
295 tcg_temp_free_i32(a
);
296 tcg_temp_free_i32(b
);
298 ret
= tcg_temp_new_i64();
299 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
300 tcg_temp_free_i32(lo
);
301 tcg_temp_free_i32(hi
);
306 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
308 TCGv_i32 lo
= tcg_temp_new_i32();
309 TCGv_i32 hi
= tcg_temp_new_i32();
312 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
313 tcg_temp_free_i32(a
);
314 tcg_temp_free_i32(b
);
316 ret
= tcg_temp_new_i64();
317 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
318 tcg_temp_free_i32(lo
);
319 tcg_temp_free_i32(hi
);
324 /* Swap low and high halfwords. */
325 static void gen_swap_half(TCGv_i32 var
)
327 TCGv_i32 tmp
= tcg_temp_new_i32();
328 tcg_gen_shri_i32(tmp
, var
, 16);
329 tcg_gen_shli_i32(var
, var
, 16);
330 tcg_gen_or_i32(var
, var
, tmp
);
331 tcg_temp_free_i32(tmp
);
334 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
335 tmp = (t0 ^ t1) & 0x8000;
338 t0 = (t0 + t1) ^ tmp;
341 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
343 TCGv_i32 tmp
= tcg_temp_new_i32();
344 tcg_gen_xor_i32(tmp
, t0
, t1
);
345 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
346 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
347 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
348 tcg_gen_add_i32(t0
, t0
, t1
);
349 tcg_gen_xor_i32(t0
, t0
, tmp
);
350 tcg_temp_free_i32(tmp
);
351 tcg_temp_free_i32(t1
);
354 /* Set CF to the top bit of var. */
355 static void gen_set_CF_bit31(TCGv_i32 var
)
357 tcg_gen_shri_i32(cpu_CF
, var
, 31);
360 /* Set N and Z flags from var. */
361 static inline void gen_logic_CC(TCGv_i32 var
)
363 tcg_gen_mov_i32(cpu_NF
, var
);
364 tcg_gen_mov_i32(cpu_ZF
, var
);
368 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
370 tcg_gen_add_i32(t0
, t0
, t1
);
371 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
374 /* dest = T0 + T1 + CF. */
375 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
377 tcg_gen_add_i32(dest
, t0
, t1
);
378 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
381 /* dest = T0 - T1 + CF - 1. */
382 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
384 tcg_gen_sub_i32(dest
, t0
, t1
);
385 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
386 tcg_gen_subi_i32(dest
, dest
, 1);
389 /* dest = T0 + T1. Compute C, N, V and Z flags */
390 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
392 TCGv_i32 tmp
= tcg_temp_new_i32();
393 tcg_gen_movi_i32(tmp
, 0);
394 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
395 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
396 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
397 tcg_gen_xor_i32(tmp
, t0
, t1
);
398 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
399 tcg_temp_free_i32(tmp
);
400 tcg_gen_mov_i32(dest
, cpu_NF
);
403 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
404 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
406 TCGv_i32 tmp
= tcg_temp_new_i32();
407 if (TCG_TARGET_HAS_add2_i32
) {
408 tcg_gen_movi_i32(tmp
, 0);
409 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
410 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
412 TCGv_i64 q0
= tcg_temp_new_i64();
413 TCGv_i64 q1
= tcg_temp_new_i64();
414 tcg_gen_extu_i32_i64(q0
, t0
);
415 tcg_gen_extu_i32_i64(q1
, t1
);
416 tcg_gen_add_i64(q0
, q0
, q1
);
417 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
418 tcg_gen_add_i64(q0
, q0
, q1
);
419 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
420 tcg_temp_free_i64(q0
);
421 tcg_temp_free_i64(q1
);
423 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
424 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
425 tcg_gen_xor_i32(tmp
, t0
, t1
);
426 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
427 tcg_temp_free_i32(tmp
);
428 tcg_gen_mov_i32(dest
, cpu_NF
);
431 /* dest = T0 - T1. Compute C, N, V and Z flags */
432 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
435 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
436 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
437 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
438 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
439 tmp
= tcg_temp_new_i32();
440 tcg_gen_xor_i32(tmp
, t0
, t1
);
441 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
442 tcg_temp_free_i32(tmp
);
443 tcg_gen_mov_i32(dest
, cpu_NF
);
446 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
447 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
449 TCGv_i32 tmp
= tcg_temp_new_i32();
450 tcg_gen_not_i32(tmp
, t1
);
451 gen_adc_CC(dest
, t0
, tmp
);
452 tcg_temp_free_i32(tmp
);
455 #define GEN_SHIFT(name) \
456 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
458 TCGv_i32 tmp1, tmp2, tmp3; \
459 tmp1 = tcg_temp_new_i32(); \
460 tcg_gen_andi_i32(tmp1, t1, 0xff); \
461 tmp2 = tcg_const_i32(0); \
462 tmp3 = tcg_const_i32(0x1f); \
463 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
464 tcg_temp_free_i32(tmp3); \
465 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
466 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
467 tcg_temp_free_i32(tmp2); \
468 tcg_temp_free_i32(tmp1); \
474 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
477 tmp1
= tcg_temp_new_i32();
478 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
479 tmp2
= tcg_const_i32(0x1f);
480 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
481 tcg_temp_free_i32(tmp2
);
482 tcg_gen_sar_i32(dest
, t0
, tmp1
);
483 tcg_temp_free_i32(tmp1
);
486 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
488 TCGv_i32 c0
= tcg_const_i32(0);
489 TCGv_i32 tmp
= tcg_temp_new_i32();
490 tcg_gen_neg_i32(tmp
, src
);
491 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
492 tcg_temp_free_i32(c0
);
493 tcg_temp_free_i32(tmp
);
496 static void shifter_out_im(TCGv_i32 var
, int shift
)
499 tcg_gen_andi_i32(cpu_CF
, var
, 1);
501 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
503 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
508 /* Shift by immediate. Includes special handling for shift == 0. */
509 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
510 int shift
, int flags
)
516 shifter_out_im(var
, 32 - shift
);
517 tcg_gen_shli_i32(var
, var
, shift
);
523 tcg_gen_shri_i32(cpu_CF
, var
, 31);
525 tcg_gen_movi_i32(var
, 0);
528 shifter_out_im(var
, shift
- 1);
529 tcg_gen_shri_i32(var
, var
, shift
);
536 shifter_out_im(var
, shift
- 1);
539 tcg_gen_sari_i32(var
, var
, shift
);
541 case 3: /* ROR/RRX */
544 shifter_out_im(var
, shift
- 1);
545 tcg_gen_rotri_i32(var
, var
, shift
); break;
547 TCGv_i32 tmp
= tcg_temp_new_i32();
548 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
550 shifter_out_im(var
, 0);
551 tcg_gen_shri_i32(var
, var
, 1);
552 tcg_gen_or_i32(var
, var
, tmp
);
553 tcg_temp_free_i32(tmp
);
558 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
559 TCGv_i32 shift
, int flags
)
563 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
564 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
565 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
566 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
571 gen_shl(var
, var
, shift
);
574 gen_shr(var
, var
, shift
);
577 gen_sar(var
, var
, shift
);
579 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
580 tcg_gen_rotr_i32(var
, var
, shift
); break;
583 tcg_temp_free_i32(shift
);
586 #define PAS_OP(pfx) \
588 case 0: gen_pas_helper(glue(pfx,add16)); break; \
589 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
590 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
591 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
592 case 4: gen_pas_helper(glue(pfx,add8)); break; \
593 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
595 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
600 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
602 tmp
= tcg_temp_new_ptr();
603 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
605 tcg_temp_free_ptr(tmp
);
608 tmp
= tcg_temp_new_ptr();
609 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
611 tcg_temp_free_ptr(tmp
);
613 #undef gen_pas_helper
614 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
627 #undef gen_pas_helper
632 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
633 #define PAS_OP(pfx) \
635 case 0: gen_pas_helper(glue(pfx,add8)); break; \
636 case 1: gen_pas_helper(glue(pfx,add16)); break; \
637 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
638 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
639 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
640 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
642 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
647 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
649 tmp
= tcg_temp_new_ptr();
650 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
652 tcg_temp_free_ptr(tmp
);
655 tmp
= tcg_temp_new_ptr();
656 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
658 tcg_temp_free_ptr(tmp
);
660 #undef gen_pas_helper
661 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
674 #undef gen_pas_helper
679 static void gen_test_cc(int cc
, int label
)
686 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
689 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
692 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
695 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
698 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
701 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
704 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
707 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
709 case 8: /* hi: C && !Z */
710 inv
= gen_new_label();
711 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
712 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
715 case 9: /* ls: !C || Z */
716 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
717 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
719 case 10: /* ge: N == V -> N ^ V == 0 */
720 tmp
= tcg_temp_new_i32();
721 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
722 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
723 tcg_temp_free_i32(tmp
);
725 case 11: /* lt: N != V -> N ^ V != 0 */
726 tmp
= tcg_temp_new_i32();
727 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
728 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
729 tcg_temp_free_i32(tmp
);
731 case 12: /* gt: !Z && N == V */
732 inv
= gen_new_label();
733 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
734 tmp
= tcg_temp_new_i32();
735 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
736 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
737 tcg_temp_free_i32(tmp
);
740 case 13: /* le: Z || N != V */
741 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
742 tmp
= tcg_temp_new_i32();
743 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
744 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
745 tcg_temp_free_i32(tmp
);
748 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
753 static const uint8_t table_logic_cc
[16] = {
772 /* Set PC and Thumb state from an immediate address. */
773 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
777 s
->is_jmp
= DISAS_UPDATE
;
778 if (s
->thumb
!= (addr
& 1)) {
779 tmp
= tcg_temp_new_i32();
780 tcg_gen_movi_i32(tmp
, addr
& 1);
781 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
782 tcg_temp_free_i32(tmp
);
784 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
787 /* Set PC and Thumb state from var. var is marked as dead. */
788 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
790 s
->is_jmp
= DISAS_UPDATE
;
791 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
792 tcg_gen_andi_i32(var
, var
, 1);
793 store_cpu_field(var
, thumb
);
796 /* Variant of store_reg which uses branch&exchange logic when storing
797 to r15 in ARM architecture v7 and above. The source must be a temporary
798 and will be marked as dead. */
799 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
800 int reg
, TCGv_i32 var
)
802 if (reg
== 15 && ENABLE_ARCH_7
) {
805 store_reg(s
, reg
, var
);
809 /* Variant of store_reg which uses branch&exchange logic when storing
810 * to r15 in ARM architecture v5T and above. This is used for storing
811 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
812 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
813 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
814 int reg
, TCGv_i32 var
)
816 if (reg
== 15 && ENABLE_ARCH_5
) {
819 store_reg(s
, reg
, var
);
823 /* Abstractions of "generate code to do a guest load/store for
824 * AArch32", where a vaddr is always 32 bits (and is zero
825 * extended if we're a 64 bit core) and data is also
826 * 32 bits unless specifically doing a 64 bit access.
827 * These functions work like tcg_gen_qemu_{ld,st}* except
828 * that their arguments are TCGv_i32 rather than TCGv.
830 #if TARGET_LONG_BITS == 32
832 #define DO_GEN_LD(OP) \
833 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
835 tcg_gen_qemu_##OP(val, addr, index); \
838 #define DO_GEN_ST(OP) \
839 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
841 tcg_gen_qemu_##OP(val, addr, index); \
844 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
846 tcg_gen_qemu_ld64(val
, addr
, index
);
849 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
851 tcg_gen_qemu_st64(val
, addr
, index
);
856 #define DO_GEN_LD(OP) \
857 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
859 TCGv addr64 = tcg_temp_new(); \
860 TCGv val64 = tcg_temp_new(); \
861 tcg_gen_extu_i32_i64(addr64, addr); \
862 tcg_gen_qemu_##OP(val64, addr64, index); \
863 tcg_temp_free(addr64); \
864 tcg_gen_trunc_i64_i32(val, val64); \
865 tcg_temp_free(val64); \
868 #define DO_GEN_ST(OP) \
869 static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
871 TCGv addr64 = tcg_temp_new(); \
872 TCGv val64 = tcg_temp_new(); \
873 tcg_gen_extu_i32_i64(addr64, addr); \
874 tcg_gen_extu_i32_i64(val64, val); \
875 tcg_gen_qemu_##OP(val64, addr64, index); \
876 tcg_temp_free(addr64); \
877 tcg_temp_free(val64); \
880 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
882 TCGv addr64
= tcg_temp_new();
883 tcg_gen_extu_i32_i64(addr64
, addr
);
884 tcg_gen_qemu_ld64(val
, addr64
, index
);
885 tcg_temp_free(addr64
);
888 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
890 TCGv addr64
= tcg_temp_new();
891 tcg_gen_extu_i32_i64(addr64
, addr
);
892 tcg_gen_qemu_st64(val
, addr64
, index
);
893 tcg_temp_free(addr64
);
907 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
910 gen_a64_set_pc_im(val
);
912 tcg_gen_movi_i32(cpu_R
[15], val
);
916 /* Force a TB lookup after an instruction that changes the CPU state. */
917 static inline void gen_lookup_tb(DisasContext
*s
)
919 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
920 s
->is_jmp
= DISAS_UPDATE
;
923 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
926 int val
, rm
, shift
, shiftop
;
929 if (!(insn
& (1 << 25))) {
932 if (!(insn
& (1 << 23)))
935 tcg_gen_addi_i32(var
, var
, val
);
939 shift
= (insn
>> 7) & 0x1f;
940 shiftop
= (insn
>> 5) & 3;
941 offset
= load_reg(s
, rm
);
942 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
943 if (!(insn
& (1 << 23)))
944 tcg_gen_sub_i32(var
, var
, offset
);
946 tcg_gen_add_i32(var
, var
, offset
);
947 tcg_temp_free_i32(offset
);
951 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
952 int extra
, TCGv_i32 var
)
957 if (insn
& (1 << 22)) {
959 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
960 if (!(insn
& (1 << 23)))
964 tcg_gen_addi_i32(var
, var
, val
);
968 tcg_gen_addi_i32(var
, var
, extra
);
970 offset
= load_reg(s
, rm
);
971 if (!(insn
& (1 << 23)))
972 tcg_gen_sub_i32(var
, var
, offset
);
974 tcg_gen_add_i32(var
, var
, offset
);
975 tcg_temp_free_i32(offset
);
979 static TCGv_ptr
get_fpstatus_ptr(int neon
)
981 TCGv_ptr statusptr
= tcg_temp_new_ptr();
984 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
986 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
988 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
992 #define VFP_OP2(name) \
993 static inline void gen_vfp_##name(int dp) \
995 TCGv_ptr fpst = get_fpstatus_ptr(0); \
997 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
999 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1001 tcg_temp_free_ptr(fpst); \
1011 static inline void gen_vfp_F1_mul(int dp
)
1013 /* Like gen_vfp_mul() but put result in F1 */
1014 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1016 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1018 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1020 tcg_temp_free_ptr(fpst
);
1023 static inline void gen_vfp_F1_neg(int dp
)
1025 /* Like gen_vfp_neg() but put result in F1 */
1027 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1029 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1033 static inline void gen_vfp_abs(int dp
)
1036 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1038 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1041 static inline void gen_vfp_neg(int dp
)
1044 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1046 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1049 static inline void gen_vfp_sqrt(int dp
)
1052 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1054 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1057 static inline void gen_vfp_cmp(int dp
)
1060 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1062 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1065 static inline void gen_vfp_cmpe(int dp
)
1068 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1070 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1073 static inline void gen_vfp_F1_ld0(int dp
)
1076 tcg_gen_movi_i64(cpu_F1d
, 0);
1078 tcg_gen_movi_i32(cpu_F1s
, 0);
1081 #define VFP_GEN_ITOF(name) \
1082 static inline void gen_vfp_##name(int dp, int neon) \
1084 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1086 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1088 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1090 tcg_temp_free_ptr(statusptr); \
1097 #define VFP_GEN_FTOI(name) \
1098 static inline void gen_vfp_##name(int dp, int neon) \
1100 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1102 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1104 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1106 tcg_temp_free_ptr(statusptr); \
1115 #define VFP_GEN_FIX(name) \
1116 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1118 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1119 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1121 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1123 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1125 tcg_temp_free_i32(tmp_shift); \
1126 tcg_temp_free_ptr(statusptr); \
1138 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1141 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1143 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1147 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1150 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1152 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1157 vfp_reg_offset (int dp
, int reg
)
1160 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1162 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1163 + offsetof(CPU_DoubleU
, l
.upper
);
1165 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1166 + offsetof(CPU_DoubleU
, l
.lower
);
1170 /* Return the offset of a 32-bit piece of a NEON register.
1171 zero is the least significant end of the register. */
1173 neon_reg_offset (int reg
, int n
)
1177 return vfp_reg_offset(0, sreg
);
1180 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1182 TCGv_i32 tmp
= tcg_temp_new_i32();
1183 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1187 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1189 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1190 tcg_temp_free_i32(var
);
1193 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1195 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1198 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1200 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1203 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1204 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1205 #define tcg_gen_st_f32 tcg_gen_st_i32
1206 #define tcg_gen_st_f64 tcg_gen_st_i64
1208 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1211 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1213 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1216 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1219 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1221 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1224 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1227 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1229 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1232 #define ARM_CP_RW_BIT (1 << 20)
1234 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1236 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1239 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1241 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1244 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1246 TCGv_i32 var
= tcg_temp_new_i32();
1247 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1251 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1253 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1254 tcg_temp_free_i32(var
);
1257 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1259 iwmmxt_store_reg(cpu_M0
, rn
);
1262 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1264 iwmmxt_load_reg(cpu_M0
, rn
);
1267 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1269 iwmmxt_load_reg(cpu_V1
, rn
);
1270 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1273 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1275 iwmmxt_load_reg(cpu_V1
, rn
);
1276 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1279 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1281 iwmmxt_load_reg(cpu_V1
, rn
);
1282 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1285 #define IWMMXT_OP(name) \
1286 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1288 iwmmxt_load_reg(cpu_V1, rn); \
1289 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1292 #define IWMMXT_OP_ENV(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295 iwmmxt_load_reg(cpu_V1, rn); \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1299 #define IWMMXT_OP_ENV_SIZE(name) \
1300 IWMMXT_OP_ENV(name##b) \
1301 IWMMXT_OP_ENV(name##w) \
1302 IWMMXT_OP_ENV(name##l)
1304 #define IWMMXT_OP_ENV1(name) \
1305 static inline void gen_op_iwmmxt_##name##_M0(void) \
1307 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1321 IWMMXT_OP_ENV_SIZE(unpackl
)
1322 IWMMXT_OP_ENV_SIZE(unpackh
)
1324 IWMMXT_OP_ENV1(unpacklub
)
1325 IWMMXT_OP_ENV1(unpackluw
)
1326 IWMMXT_OP_ENV1(unpacklul
)
1327 IWMMXT_OP_ENV1(unpackhub
)
1328 IWMMXT_OP_ENV1(unpackhuw
)
1329 IWMMXT_OP_ENV1(unpackhul
)
1330 IWMMXT_OP_ENV1(unpacklsb
)
1331 IWMMXT_OP_ENV1(unpacklsw
)
1332 IWMMXT_OP_ENV1(unpacklsl
)
1333 IWMMXT_OP_ENV1(unpackhsb
)
1334 IWMMXT_OP_ENV1(unpackhsw
)
1335 IWMMXT_OP_ENV1(unpackhsl
)
1337 IWMMXT_OP_ENV_SIZE(cmpeq
)
1338 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1339 IWMMXT_OP_ENV_SIZE(cmpgts
)
1341 IWMMXT_OP_ENV_SIZE(mins
)
1342 IWMMXT_OP_ENV_SIZE(minu
)
1343 IWMMXT_OP_ENV_SIZE(maxs
)
1344 IWMMXT_OP_ENV_SIZE(maxu
)
1346 IWMMXT_OP_ENV_SIZE(subn
)
1347 IWMMXT_OP_ENV_SIZE(addn
)
1348 IWMMXT_OP_ENV_SIZE(subu
)
1349 IWMMXT_OP_ENV_SIZE(addu
)
1350 IWMMXT_OP_ENV_SIZE(subs
)
1351 IWMMXT_OP_ENV_SIZE(adds
)
1353 IWMMXT_OP_ENV(avgb0
)
1354 IWMMXT_OP_ENV(avgb1
)
1355 IWMMXT_OP_ENV(avgw0
)
1356 IWMMXT_OP_ENV(avgw1
)
1360 IWMMXT_OP_ENV(packuw
)
1361 IWMMXT_OP_ENV(packul
)
1362 IWMMXT_OP_ENV(packuq
)
1363 IWMMXT_OP_ENV(packsw
)
1364 IWMMXT_OP_ENV(packsl
)
1365 IWMMXT_OP_ENV(packsq
)
1367 static void gen_op_iwmmxt_set_mup(void)
1370 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1371 tcg_gen_ori_i32(tmp
, tmp
, 2);
1372 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1375 static void gen_op_iwmmxt_set_cup(void)
1378 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1379 tcg_gen_ori_i32(tmp
, tmp
, 1);
1380 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1383 static void gen_op_iwmmxt_setpsr_nz(void)
1385 TCGv_i32 tmp
= tcg_temp_new_i32();
1386 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1387 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1390 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1392 iwmmxt_load_reg(cpu_V1
, rn
);
1393 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1394 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1397 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1404 rd
= (insn
>> 16) & 0xf;
1405 tmp
= load_reg(s
, rd
);
1407 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1408 if (insn
& (1 << 24)) {
1410 if (insn
& (1 << 23))
1411 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1413 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1414 tcg_gen_mov_i32(dest
, tmp
);
1415 if (insn
& (1 << 21))
1416 store_reg(s
, rd
, tmp
);
1418 tcg_temp_free_i32(tmp
);
1419 } else if (insn
& (1 << 21)) {
1421 tcg_gen_mov_i32(dest
, tmp
);
1422 if (insn
& (1 << 23))
1423 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1425 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1426 store_reg(s
, rd
, tmp
);
1427 } else if (!(insn
& (1 << 23)))
1432 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1434 int rd
= (insn
>> 0) & 0xf;
1437 if (insn
& (1 << 8)) {
1438 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1441 tmp
= iwmmxt_load_creg(rd
);
1444 tmp
= tcg_temp_new_i32();
1445 iwmmxt_load_reg(cpu_V0
, rd
);
1446 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1448 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1449 tcg_gen_mov_i32(dest
, tmp
);
1450 tcg_temp_free_i32(tmp
);
1454 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1455 (ie. an undefined instruction). */
1456 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1459 int rdhi
, rdlo
, rd0
, rd1
, i
;
1461 TCGv_i32 tmp
, tmp2
, tmp3
;
1463 if ((insn
& 0x0e000e00) == 0x0c000000) {
1464 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1466 rdlo
= (insn
>> 12) & 0xf;
1467 rdhi
= (insn
>> 16) & 0xf;
1468 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1469 iwmmxt_load_reg(cpu_V0
, wrd
);
1470 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1471 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1472 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1473 } else { /* TMCRR */
1474 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1475 iwmmxt_store_reg(cpu_V0
, wrd
);
1476 gen_op_iwmmxt_set_mup();
1481 wrd
= (insn
>> 12) & 0xf;
1482 addr
= tcg_temp_new_i32();
1483 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1484 tcg_temp_free_i32(addr
);
1487 if (insn
& ARM_CP_RW_BIT
) {
1488 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1489 tmp
= tcg_temp_new_i32();
1490 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1491 iwmmxt_store_creg(wrd
, tmp
);
1494 if (insn
& (1 << 8)) {
1495 if (insn
& (1 << 22)) { /* WLDRD */
1496 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1498 } else { /* WLDRW wRd */
1499 tmp
= tcg_temp_new_i32();
1500 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1503 tmp
= tcg_temp_new_i32();
1504 if (insn
& (1 << 22)) { /* WLDRH */
1505 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1506 } else { /* WLDRB */
1507 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1511 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1512 tcg_temp_free_i32(tmp
);
1514 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1517 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1518 tmp
= iwmmxt_load_creg(wrd
);
1519 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1521 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1522 tmp
= tcg_temp_new_i32();
1523 if (insn
& (1 << 8)) {
1524 if (insn
& (1 << 22)) { /* WSTRD */
1525 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1526 } else { /* WSTRW wRd */
1527 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1528 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1531 if (insn
& (1 << 22)) { /* WSTRH */
1532 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1533 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1534 } else { /* WSTRB */
1535 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1536 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1540 tcg_temp_free_i32(tmp
);
1542 tcg_temp_free_i32(addr
);
1546 if ((insn
& 0x0f000000) != 0x0e000000)
1549 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1550 case 0x000: /* WOR */
1551 wrd
= (insn
>> 12) & 0xf;
1552 rd0
= (insn
>> 0) & 0xf;
1553 rd1
= (insn
>> 16) & 0xf;
1554 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1555 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1556 gen_op_iwmmxt_setpsr_nz();
1557 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1558 gen_op_iwmmxt_set_mup();
1559 gen_op_iwmmxt_set_cup();
1561 case 0x011: /* TMCR */
1564 rd
= (insn
>> 12) & 0xf;
1565 wrd
= (insn
>> 16) & 0xf;
1567 case ARM_IWMMXT_wCID
:
1568 case ARM_IWMMXT_wCASF
:
1570 case ARM_IWMMXT_wCon
:
1571 gen_op_iwmmxt_set_cup();
1573 case ARM_IWMMXT_wCSSF
:
1574 tmp
= iwmmxt_load_creg(wrd
);
1575 tmp2
= load_reg(s
, rd
);
1576 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1577 tcg_temp_free_i32(tmp2
);
1578 iwmmxt_store_creg(wrd
, tmp
);
1580 case ARM_IWMMXT_wCGR0
:
1581 case ARM_IWMMXT_wCGR1
:
1582 case ARM_IWMMXT_wCGR2
:
1583 case ARM_IWMMXT_wCGR3
:
1584 gen_op_iwmmxt_set_cup();
1585 tmp
= load_reg(s
, rd
);
1586 iwmmxt_store_creg(wrd
, tmp
);
1592 case 0x100: /* WXOR */
1593 wrd
= (insn
>> 12) & 0xf;
1594 rd0
= (insn
>> 0) & 0xf;
1595 rd1
= (insn
>> 16) & 0xf;
1596 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1597 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1598 gen_op_iwmmxt_setpsr_nz();
1599 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1600 gen_op_iwmmxt_set_mup();
1601 gen_op_iwmmxt_set_cup();
1603 case 0x111: /* TMRC */
1606 rd
= (insn
>> 12) & 0xf;
1607 wrd
= (insn
>> 16) & 0xf;
1608 tmp
= iwmmxt_load_creg(wrd
);
1609 store_reg(s
, rd
, tmp
);
1611 case 0x300: /* WANDN */
1612 wrd
= (insn
>> 12) & 0xf;
1613 rd0
= (insn
>> 0) & 0xf;
1614 rd1
= (insn
>> 16) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1616 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1617 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1618 gen_op_iwmmxt_setpsr_nz();
1619 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1620 gen_op_iwmmxt_set_mup();
1621 gen_op_iwmmxt_set_cup();
1623 case 0x200: /* WAND */
1624 wrd
= (insn
>> 12) & 0xf;
1625 rd0
= (insn
>> 0) & 0xf;
1626 rd1
= (insn
>> 16) & 0xf;
1627 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1628 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1629 gen_op_iwmmxt_setpsr_nz();
1630 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1631 gen_op_iwmmxt_set_mup();
1632 gen_op_iwmmxt_set_cup();
1634 case 0x810: case 0xa10: /* WMADD */
1635 wrd
= (insn
>> 12) & 0xf;
1636 rd0
= (insn
>> 0) & 0xf;
1637 rd1
= (insn
>> 16) & 0xf;
1638 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1639 if (insn
& (1 << 21))
1640 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1642 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1643 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1644 gen_op_iwmmxt_set_mup();
1646 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1647 wrd
= (insn
>> 12) & 0xf;
1648 rd0
= (insn
>> 16) & 0xf;
1649 rd1
= (insn
>> 0) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1651 switch ((insn
>> 22) & 3) {
1653 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1656 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1659 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1664 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1665 gen_op_iwmmxt_set_mup();
1666 gen_op_iwmmxt_set_cup();
1668 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1669 wrd
= (insn
>> 12) & 0xf;
1670 rd0
= (insn
>> 16) & 0xf;
1671 rd1
= (insn
>> 0) & 0xf;
1672 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1673 switch ((insn
>> 22) & 3) {
1675 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1678 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1681 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1686 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1687 gen_op_iwmmxt_set_mup();
1688 gen_op_iwmmxt_set_cup();
1690 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1691 wrd
= (insn
>> 12) & 0xf;
1692 rd0
= (insn
>> 16) & 0xf;
1693 rd1
= (insn
>> 0) & 0xf;
1694 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1695 if (insn
& (1 << 22))
1696 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1698 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1699 if (!(insn
& (1 << 20)))
1700 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1701 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1702 gen_op_iwmmxt_set_mup();
1704 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1705 wrd
= (insn
>> 12) & 0xf;
1706 rd0
= (insn
>> 16) & 0xf;
1707 rd1
= (insn
>> 0) & 0xf;
1708 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1709 if (insn
& (1 << 21)) {
1710 if (insn
& (1 << 20))
1711 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1713 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1715 if (insn
& (1 << 20))
1716 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1718 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1720 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1721 gen_op_iwmmxt_set_mup();
1723 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1724 wrd
= (insn
>> 12) & 0xf;
1725 rd0
= (insn
>> 16) & 0xf;
1726 rd1
= (insn
>> 0) & 0xf;
1727 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1728 if (insn
& (1 << 21))
1729 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1731 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1732 if (!(insn
& (1 << 20))) {
1733 iwmmxt_load_reg(cpu_V1
, wrd
);
1734 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1736 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1737 gen_op_iwmmxt_set_mup();
1739 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1740 wrd
= (insn
>> 12) & 0xf;
1741 rd0
= (insn
>> 16) & 0xf;
1742 rd1
= (insn
>> 0) & 0xf;
1743 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1744 switch ((insn
>> 22) & 3) {
1746 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1749 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1752 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1757 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1758 gen_op_iwmmxt_set_mup();
1759 gen_op_iwmmxt_set_cup();
1761 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1762 wrd
= (insn
>> 12) & 0xf;
1763 rd0
= (insn
>> 16) & 0xf;
1764 rd1
= (insn
>> 0) & 0xf;
1765 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1766 if (insn
& (1 << 22)) {
1767 if (insn
& (1 << 20))
1768 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1770 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1772 if (insn
& (1 << 20))
1773 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1775 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1777 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1778 gen_op_iwmmxt_set_mup();
1779 gen_op_iwmmxt_set_cup();
1781 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1782 wrd
= (insn
>> 12) & 0xf;
1783 rd0
= (insn
>> 16) & 0xf;
1784 rd1
= (insn
>> 0) & 0xf;
1785 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1786 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1787 tcg_gen_andi_i32(tmp
, tmp
, 7);
1788 iwmmxt_load_reg(cpu_V1
, rd1
);
1789 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1790 tcg_temp_free_i32(tmp
);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1792 gen_op_iwmmxt_set_mup();
1794 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1795 if (((insn
>> 6) & 3) == 3)
1797 rd
= (insn
>> 12) & 0xf;
1798 wrd
= (insn
>> 16) & 0xf;
1799 tmp
= load_reg(s
, rd
);
1800 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1801 switch ((insn
>> 6) & 3) {
1803 tmp2
= tcg_const_i32(0xff);
1804 tmp3
= tcg_const_i32((insn
& 7) << 3);
1807 tmp2
= tcg_const_i32(0xffff);
1808 tmp3
= tcg_const_i32((insn
& 3) << 4);
1811 tmp2
= tcg_const_i32(0xffffffff);
1812 tmp3
= tcg_const_i32((insn
& 1) << 5);
1815 TCGV_UNUSED_I32(tmp2
);
1816 TCGV_UNUSED_I32(tmp3
);
1818 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1819 tcg_temp_free_i32(tmp3
);
1820 tcg_temp_free_i32(tmp2
);
1821 tcg_temp_free_i32(tmp
);
1822 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1823 gen_op_iwmmxt_set_mup();
1825 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1826 rd
= (insn
>> 12) & 0xf;
1827 wrd
= (insn
>> 16) & 0xf;
1828 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1830 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1831 tmp
= tcg_temp_new_i32();
1832 switch ((insn
>> 22) & 3) {
1834 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1835 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1837 tcg_gen_ext8s_i32(tmp
, tmp
);
1839 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1843 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1844 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1846 tcg_gen_ext16s_i32(tmp
, tmp
);
1848 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1852 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1853 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1856 store_reg(s
, rd
, tmp
);
1858 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1859 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1861 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1862 switch ((insn
>> 22) & 3) {
1864 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1867 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1870 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1873 tcg_gen_shli_i32(tmp
, tmp
, 28);
1875 tcg_temp_free_i32(tmp
);
1877 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1878 if (((insn
>> 6) & 3) == 3)
1880 rd
= (insn
>> 12) & 0xf;
1881 wrd
= (insn
>> 16) & 0xf;
1882 tmp
= load_reg(s
, rd
);
1883 switch ((insn
>> 6) & 3) {
1885 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1888 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1891 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1894 tcg_temp_free_i32(tmp
);
1895 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1896 gen_op_iwmmxt_set_mup();
1898 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1899 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1901 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1902 tmp2
= tcg_temp_new_i32();
1903 tcg_gen_mov_i32(tmp2
, tmp
);
1904 switch ((insn
>> 22) & 3) {
1906 for (i
= 0; i
< 7; i
++) {
1907 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1908 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1912 for (i
= 0; i
< 3; i
++) {
1913 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1914 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1918 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1919 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1923 tcg_temp_free_i32(tmp2
);
1924 tcg_temp_free_i32(tmp
);
1926 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1927 wrd
= (insn
>> 12) & 0xf;
1928 rd0
= (insn
>> 16) & 0xf;
1929 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1930 switch ((insn
>> 22) & 3) {
1932 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1935 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1938 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1943 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1944 gen_op_iwmmxt_set_mup();
1946 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1947 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1949 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1950 tmp2
= tcg_temp_new_i32();
1951 tcg_gen_mov_i32(tmp2
, tmp
);
1952 switch ((insn
>> 22) & 3) {
1954 for (i
= 0; i
< 7; i
++) {
1955 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1956 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1960 for (i
= 0; i
< 3; i
++) {
1961 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1962 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1966 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1967 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1971 tcg_temp_free_i32(tmp2
);
1972 tcg_temp_free_i32(tmp
);
1974 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1975 rd
= (insn
>> 12) & 0xf;
1976 rd0
= (insn
>> 16) & 0xf;
1977 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1979 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1980 tmp
= tcg_temp_new_i32();
1981 switch ((insn
>> 22) & 3) {
1983 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1986 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1989 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1992 store_reg(s
, rd
, tmp
);
1994 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1995 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1996 wrd
= (insn
>> 12) & 0xf;
1997 rd0
= (insn
>> 16) & 0xf;
1998 rd1
= (insn
>> 0) & 0xf;
1999 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2000 switch ((insn
>> 22) & 3) {
2002 if (insn
& (1 << 21))
2003 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2005 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2008 if (insn
& (1 << 21))
2009 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2011 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2014 if (insn
& (1 << 21))
2015 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2017 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2022 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2023 gen_op_iwmmxt_set_mup();
2024 gen_op_iwmmxt_set_cup();
2026 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2027 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2028 wrd
= (insn
>> 12) & 0xf;
2029 rd0
= (insn
>> 16) & 0xf;
2030 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2031 switch ((insn
>> 22) & 3) {
2033 if (insn
& (1 << 21))
2034 gen_op_iwmmxt_unpacklsb_M0();
2036 gen_op_iwmmxt_unpacklub_M0();
2039 if (insn
& (1 << 21))
2040 gen_op_iwmmxt_unpacklsw_M0();
2042 gen_op_iwmmxt_unpackluw_M0();
2045 if (insn
& (1 << 21))
2046 gen_op_iwmmxt_unpacklsl_M0();
2048 gen_op_iwmmxt_unpacklul_M0();
2053 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2054 gen_op_iwmmxt_set_mup();
2055 gen_op_iwmmxt_set_cup();
2057 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2058 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2059 wrd
= (insn
>> 12) & 0xf;
2060 rd0
= (insn
>> 16) & 0xf;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2062 switch ((insn
>> 22) & 3) {
2064 if (insn
& (1 << 21))
2065 gen_op_iwmmxt_unpackhsb_M0();
2067 gen_op_iwmmxt_unpackhub_M0();
2070 if (insn
& (1 << 21))
2071 gen_op_iwmmxt_unpackhsw_M0();
2073 gen_op_iwmmxt_unpackhuw_M0();
2076 if (insn
& (1 << 21))
2077 gen_op_iwmmxt_unpackhsl_M0();
2079 gen_op_iwmmxt_unpackhul_M0();
2084 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2085 gen_op_iwmmxt_set_mup();
2086 gen_op_iwmmxt_set_cup();
2088 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2089 case 0x214: case 0x614: case 0xa14: case 0xe14:
2090 if (((insn
>> 22) & 3) == 0)
2092 wrd
= (insn
>> 12) & 0xf;
2093 rd0
= (insn
>> 16) & 0xf;
2094 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2095 tmp
= tcg_temp_new_i32();
2096 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2097 tcg_temp_free_i32(tmp
);
2100 switch ((insn
>> 22) & 3) {
2102 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2105 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2111 tcg_temp_free_i32(tmp
);
2112 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2113 gen_op_iwmmxt_set_mup();
2114 gen_op_iwmmxt_set_cup();
2116 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2117 case 0x014: case 0x414: case 0x814: case 0xc14:
2118 if (((insn
>> 22) & 3) == 0)
2120 wrd
= (insn
>> 12) & 0xf;
2121 rd0
= (insn
>> 16) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2123 tmp
= tcg_temp_new_i32();
2124 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2125 tcg_temp_free_i32(tmp
);
2128 switch ((insn
>> 22) & 3) {
2130 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2133 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2139 tcg_temp_free_i32(tmp
);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2141 gen_op_iwmmxt_set_mup();
2142 gen_op_iwmmxt_set_cup();
2144 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2145 case 0x114: case 0x514: case 0x914: case 0xd14:
2146 if (((insn
>> 22) & 3) == 0)
2148 wrd
= (insn
>> 12) & 0xf;
2149 rd0
= (insn
>> 16) & 0xf;
2150 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2151 tmp
= tcg_temp_new_i32();
2152 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2153 tcg_temp_free_i32(tmp
);
2156 switch ((insn
>> 22) & 3) {
2158 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2161 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2167 tcg_temp_free_i32(tmp
);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2169 gen_op_iwmmxt_set_mup();
2170 gen_op_iwmmxt_set_cup();
2172 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2173 case 0x314: case 0x714: case 0xb14: case 0xf14:
2174 if (((insn
>> 22) & 3) == 0)
2176 wrd
= (insn
>> 12) & 0xf;
2177 rd0
= (insn
>> 16) & 0xf;
2178 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2179 tmp
= tcg_temp_new_i32();
2180 switch ((insn
>> 22) & 3) {
2182 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2183 tcg_temp_free_i32(tmp
);
2186 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2189 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2190 tcg_temp_free_i32(tmp
);
2193 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2196 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2197 tcg_temp_free_i32(tmp
);
2200 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2203 tcg_temp_free_i32(tmp
);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2205 gen_op_iwmmxt_set_mup();
2206 gen_op_iwmmxt_set_cup();
2208 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2209 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2210 wrd
= (insn
>> 12) & 0xf;
2211 rd0
= (insn
>> 16) & 0xf;
2212 rd1
= (insn
>> 0) & 0xf;
2213 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2214 switch ((insn
>> 22) & 3) {
2216 if (insn
& (1 << 21))
2217 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2219 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2222 if (insn
& (1 << 21))
2223 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2225 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2228 if (insn
& (1 << 21))
2229 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2231 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2236 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2237 gen_op_iwmmxt_set_mup();
2239 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2240 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2241 wrd
= (insn
>> 12) & 0xf;
2242 rd0
= (insn
>> 16) & 0xf;
2243 rd1
= (insn
>> 0) & 0xf;
2244 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2245 switch ((insn
>> 22) & 3) {
2247 if (insn
& (1 << 21))
2248 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2250 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2253 if (insn
& (1 << 21))
2254 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2256 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2259 if (insn
& (1 << 21))
2260 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2262 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2267 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2268 gen_op_iwmmxt_set_mup();
2270 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2271 case 0x402: case 0x502: case 0x602: case 0x702:
2272 wrd
= (insn
>> 12) & 0xf;
2273 rd0
= (insn
>> 16) & 0xf;
2274 rd1
= (insn
>> 0) & 0xf;
2275 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2276 tmp
= tcg_const_i32((insn
>> 20) & 3);
2277 iwmmxt_load_reg(cpu_V1
, rd1
);
2278 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2279 tcg_temp_free_i32(tmp
);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2281 gen_op_iwmmxt_set_mup();
2283 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2284 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2285 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2286 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2287 wrd
= (insn
>> 12) & 0xf;
2288 rd0
= (insn
>> 16) & 0xf;
2289 rd1
= (insn
>> 0) & 0xf;
2290 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2291 switch ((insn
>> 20) & 0xf) {
2293 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2296 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2299 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2302 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2308 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2311 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2314 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2317 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2322 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2323 gen_op_iwmmxt_set_mup();
2324 gen_op_iwmmxt_set_cup();
2326 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2327 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2328 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2329 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2330 wrd
= (insn
>> 12) & 0xf;
2331 rd0
= (insn
>> 16) & 0xf;
2332 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2333 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2334 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2335 tcg_temp_free_i32(tmp
);
2336 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2337 gen_op_iwmmxt_set_mup();
2338 gen_op_iwmmxt_set_cup();
2340 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2341 case 0x418: case 0x518: case 0x618: case 0x718:
2342 case 0x818: case 0x918: case 0xa18: case 0xb18:
2343 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2344 wrd
= (insn
>> 12) & 0xf;
2345 rd0
= (insn
>> 16) & 0xf;
2346 rd1
= (insn
>> 0) & 0xf;
2347 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2348 switch ((insn
>> 20) & 0xf) {
2350 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2353 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2356 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2359 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2362 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2365 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2368 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2371 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2374 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2379 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2380 gen_op_iwmmxt_set_mup();
2381 gen_op_iwmmxt_set_cup();
2383 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2384 case 0x408: case 0x508: case 0x608: case 0x708:
2385 case 0x808: case 0x908: case 0xa08: case 0xb08:
2386 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2387 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2389 wrd
= (insn
>> 12) & 0xf;
2390 rd0
= (insn
>> 16) & 0xf;
2391 rd1
= (insn
>> 0) & 0xf;
2392 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2393 switch ((insn
>> 22) & 3) {
2395 if (insn
& (1 << 21))
2396 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2398 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2401 if (insn
& (1 << 21))
2402 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2404 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2407 if (insn
& (1 << 21))
2408 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2410 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2413 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2414 gen_op_iwmmxt_set_mup();
2415 gen_op_iwmmxt_set_cup();
2417 case 0x201: case 0x203: case 0x205: case 0x207:
2418 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2419 case 0x211: case 0x213: case 0x215: case 0x217:
2420 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2421 wrd
= (insn
>> 5) & 0xf;
2422 rd0
= (insn
>> 12) & 0xf;
2423 rd1
= (insn
>> 0) & 0xf;
2424 if (rd0
== 0xf || rd1
== 0xf)
2426 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2427 tmp
= load_reg(s
, rd0
);
2428 tmp2
= load_reg(s
, rd1
);
2429 switch ((insn
>> 16) & 0xf) {
2430 case 0x0: /* TMIA */
2431 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2433 case 0x8: /* TMIAPH */
2434 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2436 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2437 if (insn
& (1 << 16))
2438 tcg_gen_shri_i32(tmp
, tmp
, 16);
2439 if (insn
& (1 << 17))
2440 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2441 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2444 tcg_temp_free_i32(tmp2
);
2445 tcg_temp_free_i32(tmp
);
2448 tcg_temp_free_i32(tmp2
);
2449 tcg_temp_free_i32(tmp
);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2451 gen_op_iwmmxt_set_mup();
2460 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2461 (ie. an undefined instruction). */
2462 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2464 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2467 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2468 /* Multiply with Internal Accumulate Format */
2469 rd0
= (insn
>> 12) & 0xf;
2471 acc
= (insn
>> 5) & 7;
2476 tmp
= load_reg(s
, rd0
);
2477 tmp2
= load_reg(s
, rd1
);
2478 switch ((insn
>> 16) & 0xf) {
2480 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2482 case 0x8: /* MIAPH */
2483 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2485 case 0xc: /* MIABB */
2486 case 0xd: /* MIABT */
2487 case 0xe: /* MIATB */
2488 case 0xf: /* MIATT */
2489 if (insn
& (1 << 16))
2490 tcg_gen_shri_i32(tmp
, tmp
, 16);
2491 if (insn
& (1 << 17))
2492 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2493 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2498 tcg_temp_free_i32(tmp2
);
2499 tcg_temp_free_i32(tmp
);
2501 gen_op_iwmmxt_movq_wRn_M0(acc
);
2505 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2506 /* Internal Accumulator Access Format */
2507 rdhi
= (insn
>> 16) & 0xf;
2508 rdlo
= (insn
>> 12) & 0xf;
2514 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2515 iwmmxt_load_reg(cpu_V0
, acc
);
2516 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2517 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2518 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2519 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2521 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2522 iwmmxt_store_reg(cpu_V0
, acc
);
2530 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2531 #define VFP_SREG(insn, bigbit, smallbit) \
2532 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2533 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2534 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2535 reg = (((insn) >> (bigbit)) & 0x0f) \
2536 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2538 if (insn & (1 << (smallbit))) \
2540 reg = ((insn) >> (bigbit)) & 0x0f; \
2543 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2544 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2545 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2546 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2547 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2548 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2550 /* Move between integer and VFP cores. */
2551 static TCGv_i32
gen_vfp_mrs(void)
2553 TCGv_i32 tmp
= tcg_temp_new_i32();
2554 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2558 static void gen_vfp_msr(TCGv_i32 tmp
)
2560 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2561 tcg_temp_free_i32(tmp
);
2564 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2566 TCGv_i32 tmp
= tcg_temp_new_i32();
2568 tcg_gen_shri_i32(var
, var
, shift
);
2569 tcg_gen_ext8u_i32(var
, var
);
2570 tcg_gen_shli_i32(tmp
, var
, 8);
2571 tcg_gen_or_i32(var
, var
, tmp
);
2572 tcg_gen_shli_i32(tmp
, var
, 16);
2573 tcg_gen_or_i32(var
, var
, tmp
);
2574 tcg_temp_free_i32(tmp
);
2577 static void gen_neon_dup_low16(TCGv_i32 var
)
2579 TCGv_i32 tmp
= tcg_temp_new_i32();
2580 tcg_gen_ext16u_i32(var
, var
);
2581 tcg_gen_shli_i32(tmp
, var
, 16);
2582 tcg_gen_or_i32(var
, var
, tmp
);
2583 tcg_temp_free_i32(tmp
);
2586 static void gen_neon_dup_high16(TCGv_i32 var
)
2588 TCGv_i32 tmp
= tcg_temp_new_i32();
2589 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2590 tcg_gen_shri_i32(tmp
, var
, 16);
2591 tcg_gen_or_i32(var
, var
, tmp
);
2592 tcg_temp_free_i32(tmp
);
2595 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2597 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2598 TCGv_i32 tmp
= tcg_temp_new_i32();
2601 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2602 gen_neon_dup_u8(tmp
, 0);
2605 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2606 gen_neon_dup_low16(tmp
);
2609 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2611 default: /* Avoid compiler warnings. */
2617 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2618 (ie. an undefined instruction). */
2619 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2621 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2627 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2630 if (!s
->vfp_enabled
) {
2631 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2632 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2634 rn
= (insn
>> 16) & 0xf;
2635 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2636 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2639 dp
= ((insn
& 0xf00) == 0xb00);
2640 switch ((insn
>> 24) & 0xf) {
2642 if (insn
& (1 << 4)) {
2643 /* single register transfer */
2644 rd
= (insn
>> 12) & 0xf;
2649 VFP_DREG_N(rn
, insn
);
2652 if (insn
& 0x00c00060
2653 && !arm_feature(env
, ARM_FEATURE_NEON
))
2656 pass
= (insn
>> 21) & 1;
2657 if (insn
& (1 << 22)) {
2659 offset
= ((insn
>> 5) & 3) * 8;
2660 } else if (insn
& (1 << 5)) {
2662 offset
= (insn
& (1 << 6)) ? 16 : 0;
2667 if (insn
& ARM_CP_RW_BIT
) {
2669 tmp
= neon_load_reg(rn
, pass
);
2673 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2674 if (insn
& (1 << 23))
2680 if (insn
& (1 << 23)) {
2682 tcg_gen_shri_i32(tmp
, tmp
, 16);
2688 tcg_gen_sari_i32(tmp
, tmp
, 16);
2697 store_reg(s
, rd
, tmp
);
2700 tmp
= load_reg(s
, rd
);
2701 if (insn
& (1 << 23)) {
2704 gen_neon_dup_u8(tmp
, 0);
2705 } else if (size
== 1) {
2706 gen_neon_dup_low16(tmp
);
2708 for (n
= 0; n
<= pass
* 2; n
++) {
2709 tmp2
= tcg_temp_new_i32();
2710 tcg_gen_mov_i32(tmp2
, tmp
);
2711 neon_store_reg(rn
, n
, tmp2
);
2713 neon_store_reg(rn
, n
, tmp
);
2718 tmp2
= neon_load_reg(rn
, pass
);
2719 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2720 tcg_temp_free_i32(tmp2
);
2723 tmp2
= neon_load_reg(rn
, pass
);
2724 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2725 tcg_temp_free_i32(tmp2
);
2730 neon_store_reg(rn
, pass
, tmp
);
2734 if ((insn
& 0x6f) != 0x00)
2736 rn
= VFP_SREG_N(insn
);
2737 if (insn
& ARM_CP_RW_BIT
) {
2739 if (insn
& (1 << 21)) {
2740 /* system register */
2745 /* VFP2 allows access to FSID from userspace.
2746 VFP3 restricts all id registers to privileged
2749 && arm_feature(env
, ARM_FEATURE_VFP3
))
2751 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2756 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2758 case ARM_VFP_FPINST
:
2759 case ARM_VFP_FPINST2
:
2760 /* Not present in VFP3. */
2762 || arm_feature(env
, ARM_FEATURE_VFP3
))
2764 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2768 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2769 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2771 tmp
= tcg_temp_new_i32();
2772 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2778 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2780 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2786 gen_mov_F0_vreg(0, rn
);
2787 tmp
= gen_vfp_mrs();
2790 /* Set the 4 flag bits in the CPSR. */
2792 tcg_temp_free_i32(tmp
);
2794 store_reg(s
, rd
, tmp
);
2798 if (insn
& (1 << 21)) {
2800 /* system register */
2805 /* Writes are ignored. */
2808 tmp
= load_reg(s
, rd
);
2809 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2810 tcg_temp_free_i32(tmp
);
2816 /* TODO: VFP subarchitecture support.
2817 * For now, keep the EN bit only */
2818 tmp
= load_reg(s
, rd
);
2819 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2820 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2823 case ARM_VFP_FPINST
:
2824 case ARM_VFP_FPINST2
:
2825 tmp
= load_reg(s
, rd
);
2826 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2832 tmp
= load_reg(s
, rd
);
2834 gen_mov_vreg_F0(0, rn
);
2839 /* data processing */
2840 /* The opcode is in bits 23, 21, 20 and 6. */
2841 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2845 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2847 /* rn is register number */
2848 VFP_DREG_N(rn
, insn
);
2851 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2852 /* Integer or single precision destination. */
2853 rd
= VFP_SREG_D(insn
);
2855 VFP_DREG_D(rd
, insn
);
2858 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2859 /* VCVT from int is always from S reg regardless of dp bit.
2860 * VCVT with immediate frac_bits has same format as SREG_M
2862 rm
= VFP_SREG_M(insn
);
2864 VFP_DREG_M(rm
, insn
);
2867 rn
= VFP_SREG_N(insn
);
2868 if (op
== 15 && rn
== 15) {
2869 /* Double precision destination. */
2870 VFP_DREG_D(rd
, insn
);
2872 rd
= VFP_SREG_D(insn
);
2874 /* NB that we implicitly rely on the encoding for the frac_bits
2875 * in VCVT of fixed to float being the same as that of an SREG_M
2877 rm
= VFP_SREG_M(insn
);
2880 veclen
= s
->vec_len
;
2881 if (op
== 15 && rn
> 3)
2884 /* Shut up compiler warnings. */
2895 /* Figure out what type of vector operation this is. */
2896 if ((rd
& bank_mask
) == 0) {
2901 delta_d
= (s
->vec_stride
>> 1) + 1;
2903 delta_d
= s
->vec_stride
+ 1;
2905 if ((rm
& bank_mask
) == 0) {
2906 /* mixed scalar/vector */
2915 /* Load the initial operands. */
2920 /* Integer source */
2921 gen_mov_F0_vreg(0, rm
);
2926 gen_mov_F0_vreg(dp
, rd
);
2927 gen_mov_F1_vreg(dp
, rm
);
2931 /* Compare with zero */
2932 gen_mov_F0_vreg(dp
, rd
);
2943 /* Source and destination the same. */
2944 gen_mov_F0_vreg(dp
, rd
);
2950 /* VCVTB, VCVTT: only present with the halfprec extension,
2951 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2953 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2956 /* Otherwise fall through */
2958 /* One source operand. */
2959 gen_mov_F0_vreg(dp
, rm
);
2963 /* Two source operands. */
2964 gen_mov_F0_vreg(dp
, rn
);
2965 gen_mov_F1_vreg(dp
, rm
);
2969 /* Perform the calculation. */
2971 case 0: /* VMLA: fd + (fn * fm) */
2972 /* Note that order of inputs to the add matters for NaNs */
2974 gen_mov_F0_vreg(dp
, rd
);
2977 case 1: /* VMLS: fd + -(fn * fm) */
2980 gen_mov_F0_vreg(dp
, rd
);
2983 case 2: /* VNMLS: -fd + (fn * fm) */
2984 /* Note that it isn't valid to replace (-A + B) with (B - A)
2985 * or similar plausible looking simplifications
2986 * because this will give wrong results for NaNs.
2989 gen_mov_F0_vreg(dp
, rd
);
2993 case 3: /* VNMLA: -fd + -(fn * fm) */
2996 gen_mov_F0_vreg(dp
, rd
);
3000 case 4: /* mul: fn * fm */
3003 case 5: /* nmul: -(fn * fm) */
3007 case 6: /* add: fn + fm */
3010 case 7: /* sub: fn - fm */
3013 case 8: /* div: fn / fm */
3016 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3017 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3018 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3019 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3020 /* These are fused multiply-add, and must be done as one
3021 * floating point operation with no rounding between the
3022 * multiplication and addition steps.
3023 * NB that doing the negations here as separate steps is
3024 * correct : an input NaN should come out with its sign bit
3025 * flipped if it is a negated-input.
3027 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3035 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3037 frd
= tcg_temp_new_i64();
3038 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3041 gen_helper_vfp_negd(frd
, frd
);
3043 fpst
= get_fpstatus_ptr(0);
3044 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3045 cpu_F1d
, frd
, fpst
);
3046 tcg_temp_free_ptr(fpst
);
3047 tcg_temp_free_i64(frd
);
3053 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3055 frd
= tcg_temp_new_i32();
3056 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3058 gen_helper_vfp_negs(frd
, frd
);
3060 fpst
= get_fpstatus_ptr(0);
3061 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3062 cpu_F1s
, frd
, fpst
);
3063 tcg_temp_free_ptr(fpst
);
3064 tcg_temp_free_i32(frd
);
3067 case 14: /* fconst */
3068 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3071 n
= (insn
<< 12) & 0x80000000;
3072 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3079 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3086 tcg_gen_movi_i32(cpu_F0s
, n
);
3089 case 15: /* extension space */
3103 case 4: /* vcvtb.f32.f16 */
3104 tmp
= gen_vfp_mrs();
3105 tcg_gen_ext16u_i32(tmp
, tmp
);
3106 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3107 tcg_temp_free_i32(tmp
);
3109 case 5: /* vcvtt.f32.f16 */
3110 tmp
= gen_vfp_mrs();
3111 tcg_gen_shri_i32(tmp
, tmp
, 16);
3112 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3113 tcg_temp_free_i32(tmp
);
3115 case 6: /* vcvtb.f16.f32 */
3116 tmp
= tcg_temp_new_i32();
3117 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3118 gen_mov_F0_vreg(0, rd
);
3119 tmp2
= gen_vfp_mrs();
3120 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3121 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3122 tcg_temp_free_i32(tmp2
);
3125 case 7: /* vcvtt.f16.f32 */
3126 tmp
= tcg_temp_new_i32();
3127 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3128 tcg_gen_shli_i32(tmp
, tmp
, 16);
3129 gen_mov_F0_vreg(0, rd
);
3130 tmp2
= gen_vfp_mrs();
3131 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3132 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3133 tcg_temp_free_i32(tmp2
);
3145 case 11: /* cmpez */
3149 case 15: /* single<->double conversion */
3151 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3153 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3155 case 16: /* fuito */
3156 gen_vfp_uito(dp
, 0);
3158 case 17: /* fsito */
3159 gen_vfp_sito(dp
, 0);
3161 case 20: /* fshto */
3162 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3164 gen_vfp_shto(dp
, 16 - rm
, 0);
3166 case 21: /* fslto */
3167 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3169 gen_vfp_slto(dp
, 32 - rm
, 0);
3171 case 22: /* fuhto */
3172 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3174 gen_vfp_uhto(dp
, 16 - rm
, 0);
3176 case 23: /* fulto */
3177 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3179 gen_vfp_ulto(dp
, 32 - rm
, 0);
3181 case 24: /* ftoui */
3182 gen_vfp_toui(dp
, 0);
3184 case 25: /* ftouiz */
3185 gen_vfp_touiz(dp
, 0);
3187 case 26: /* ftosi */
3188 gen_vfp_tosi(dp
, 0);
3190 case 27: /* ftosiz */
3191 gen_vfp_tosiz(dp
, 0);
3193 case 28: /* ftosh */
3194 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3196 gen_vfp_tosh(dp
, 16 - rm
, 0);
3198 case 29: /* ftosl */
3199 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3201 gen_vfp_tosl(dp
, 32 - rm
, 0);
3203 case 30: /* ftouh */
3204 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3206 gen_vfp_touh(dp
, 16 - rm
, 0);
3208 case 31: /* ftoul */
3209 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3211 gen_vfp_toul(dp
, 32 - rm
, 0);
3213 default: /* undefined */
3217 default: /* undefined */
3221 /* Write back the result. */
3222 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3223 ; /* Comparison, do nothing. */
3224 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3225 /* VCVT double to int: always integer result. */
3226 gen_mov_vreg_F0(0, rd
);
3227 else if (op
== 15 && rn
== 15)
3229 gen_mov_vreg_F0(!dp
, rd
);
3231 gen_mov_vreg_F0(dp
, rd
);
3233 /* break out of the loop if we have finished */
3237 if (op
== 15 && delta_m
== 0) {
3238 /* single source one-many */
3240 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3242 gen_mov_vreg_F0(dp
, rd
);
3246 /* Setup the next operands. */
3248 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3252 /* One source operand. */
3253 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3255 gen_mov_F0_vreg(dp
, rm
);
3257 /* Two source operands. */
3258 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3260 gen_mov_F0_vreg(dp
, rn
);
3262 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3264 gen_mov_F1_vreg(dp
, rm
);
3272 if ((insn
& 0x03e00000) == 0x00400000) {
3273 /* two-register transfer */
3274 rn
= (insn
>> 16) & 0xf;
3275 rd
= (insn
>> 12) & 0xf;
3277 VFP_DREG_M(rm
, insn
);
3279 rm
= VFP_SREG_M(insn
);
3282 if (insn
& ARM_CP_RW_BIT
) {
3285 gen_mov_F0_vreg(0, rm
* 2);
3286 tmp
= gen_vfp_mrs();
3287 store_reg(s
, rd
, tmp
);
3288 gen_mov_F0_vreg(0, rm
* 2 + 1);
3289 tmp
= gen_vfp_mrs();
3290 store_reg(s
, rn
, tmp
);
3292 gen_mov_F0_vreg(0, rm
);
3293 tmp
= gen_vfp_mrs();
3294 store_reg(s
, rd
, tmp
);
3295 gen_mov_F0_vreg(0, rm
+ 1);
3296 tmp
= gen_vfp_mrs();
3297 store_reg(s
, rn
, tmp
);
3302 tmp
= load_reg(s
, rd
);
3304 gen_mov_vreg_F0(0, rm
* 2);
3305 tmp
= load_reg(s
, rn
);
3307 gen_mov_vreg_F0(0, rm
* 2 + 1);
3309 tmp
= load_reg(s
, rd
);
3311 gen_mov_vreg_F0(0, rm
);
3312 tmp
= load_reg(s
, rn
);
3314 gen_mov_vreg_F0(0, rm
+ 1);
3319 rn
= (insn
>> 16) & 0xf;
3321 VFP_DREG_D(rd
, insn
);
3323 rd
= VFP_SREG_D(insn
);
3324 if ((insn
& 0x01200000) == 0x01000000) {
3325 /* Single load/store */
3326 offset
= (insn
& 0xff) << 2;
3327 if ((insn
& (1 << 23)) == 0)
3329 if (s
->thumb
&& rn
== 15) {
3330 /* This is actually UNPREDICTABLE */
3331 addr
= tcg_temp_new_i32();
3332 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3334 addr
= load_reg(s
, rn
);
3336 tcg_gen_addi_i32(addr
, addr
, offset
);
3337 if (insn
& (1 << 20)) {
3338 gen_vfp_ld(s
, dp
, addr
);
3339 gen_mov_vreg_F0(dp
, rd
);
3341 gen_mov_F0_vreg(dp
, rd
);
3342 gen_vfp_st(s
, dp
, addr
);
3344 tcg_temp_free_i32(addr
);
3346 /* load/store multiple */
3347 int w
= insn
& (1 << 21);
3349 n
= (insn
>> 1) & 0x7f;
3353 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3354 /* P == U , W == 1 => UNDEF */
3357 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3358 /* UNPREDICTABLE cases for bad immediates: we choose to
3359 * UNDEF to avoid generating huge numbers of TCG ops
3363 if (rn
== 15 && w
) {
3364 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3368 if (s
->thumb
&& rn
== 15) {
3369 /* This is actually UNPREDICTABLE */
3370 addr
= tcg_temp_new_i32();
3371 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3373 addr
= load_reg(s
, rn
);
3375 if (insn
& (1 << 24)) /* pre-decrement */
3376 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3382 for (i
= 0; i
< n
; i
++) {
3383 if (insn
& ARM_CP_RW_BIT
) {
3385 gen_vfp_ld(s
, dp
, addr
);
3386 gen_mov_vreg_F0(dp
, rd
+ i
);
3389 gen_mov_F0_vreg(dp
, rd
+ i
);
3390 gen_vfp_st(s
, dp
, addr
);
3392 tcg_gen_addi_i32(addr
, addr
, offset
);
3396 if (insn
& (1 << 24))
3397 offset
= -offset
* n
;
3398 else if (dp
&& (insn
& 1))
3404 tcg_gen_addi_i32(addr
, addr
, offset
);
3405 store_reg(s
, rn
, addr
);
3407 tcg_temp_free_i32(addr
);
3413 /* Should never happen. */
3419 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3421 TranslationBlock
*tb
;
3424 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3426 gen_set_pc_im(s
, dest
);
3427 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3429 gen_set_pc_im(s
, dest
);
3434 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3436 if (unlikely(s
->singlestep_enabled
)) {
3437 /* An indirect jump so that we still trigger the debug exception. */
3442 gen_goto_tb(s
, 0, dest
);
3443 s
->is_jmp
= DISAS_TB_JUMP
;
3447 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3450 tcg_gen_sari_i32(t0
, t0
, 16);
3454 tcg_gen_sari_i32(t1
, t1
, 16);
3457 tcg_gen_mul_i32(t0
, t0
, t1
);
3460 /* Return the mask of PSR bits set by a MSR instruction. */
3461 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3465 if (flags
& (1 << 0))
3467 if (flags
& (1 << 1))
3469 if (flags
& (1 << 2))
3471 if (flags
& (1 << 3))
3474 /* Mask out undefined bits. */
3475 mask
&= ~CPSR_RESERVED
;
3476 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3478 if (!arm_feature(env
, ARM_FEATURE_V5
))
3479 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3480 if (!arm_feature(env
, ARM_FEATURE_V6
))
3481 mask
&= ~(CPSR_E
| CPSR_GE
);
3482 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3484 /* Mask out execution state bits. */
3487 /* Mask out privileged bits. */
3493 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3494 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3498 /* ??? This is also undefined in system mode. */
3502 tmp
= load_cpu_field(spsr
);
3503 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3504 tcg_gen_andi_i32(t0
, t0
, mask
);
3505 tcg_gen_or_i32(tmp
, tmp
, t0
);
3506 store_cpu_field(tmp
, spsr
);
3508 gen_set_cpsr(t0
, mask
);
3510 tcg_temp_free_i32(t0
);
3515 /* Returns nonzero if access to the PSR is not permitted. */
3516 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3519 tmp
= tcg_temp_new_i32();
3520 tcg_gen_movi_i32(tmp
, val
);
3521 return gen_set_psr(s
, mask
, spsr
, tmp
);
3524 /* Generate an old-style exception return. Marks pc as dead. */
3525 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3528 store_reg(s
, 15, pc
);
3529 tmp
= load_cpu_field(spsr
);
3530 gen_set_cpsr(tmp
, 0xffffffff);
3531 tcg_temp_free_i32(tmp
);
3532 s
->is_jmp
= DISAS_UPDATE
;
3535 /* Generate a v6 exception return. Marks both values as dead. */
3536 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3538 gen_set_cpsr(cpsr
, 0xffffffff);
3539 tcg_temp_free_i32(cpsr
);
3540 store_reg(s
, 15, pc
);
3541 s
->is_jmp
= DISAS_UPDATE
;
3545 gen_set_condexec (DisasContext
*s
)
3547 if (s
->condexec_mask
) {
3548 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3549 TCGv_i32 tmp
= tcg_temp_new_i32();
3550 tcg_gen_movi_i32(tmp
, val
);
3551 store_cpu_field(tmp
, condexec_bits
);
3555 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3557 gen_set_condexec(s
);
3558 gen_set_pc_im(s
, s
->pc
- offset
);
3559 gen_exception(excp
);
3560 s
->is_jmp
= DISAS_JUMP
;
3563 static void gen_nop_hint(DisasContext
*s
, int val
)
3567 gen_set_pc_im(s
, s
->pc
);
3568 s
->is_jmp
= DISAS_WFI
;
3573 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3579 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3581 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3584 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3585 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3586 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3591 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3594 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3595 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3596 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3601 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3602 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3603 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3604 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3605 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3607 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3608 switch ((size << 1) | u) { \
3610 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3613 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3616 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3619 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3622 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3625 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3627 default: return 1; \
3630 #define GEN_NEON_INTEGER_OP(name) do { \
3631 switch ((size << 1) | u) { \
3633 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3636 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3639 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3642 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3645 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3648 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3650 default: return 1; \
3653 static TCGv_i32
neon_load_scratch(int scratch
)
3655 TCGv_i32 tmp
= tcg_temp_new_i32();
3656 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3660 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3662 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3663 tcg_temp_free_i32(var
);
3666 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3670 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3672 gen_neon_dup_high16(tmp
);
3674 gen_neon_dup_low16(tmp
);
3677 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3682 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3685 if (!q
&& size
== 2) {
3688 tmp
= tcg_const_i32(rd
);
3689 tmp2
= tcg_const_i32(rm
);
3693 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3696 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3699 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3707 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3710 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3716 tcg_temp_free_i32(tmp
);
3717 tcg_temp_free_i32(tmp2
);
3721 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3724 if (!q
&& size
== 2) {
3727 tmp
= tcg_const_i32(rd
);
3728 tmp2
= tcg_const_i32(rm
);
3732 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3735 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3738 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3746 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3749 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3755 tcg_temp_free_i32(tmp
);
3756 tcg_temp_free_i32(tmp2
);
3760 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3764 rd
= tcg_temp_new_i32();
3765 tmp
= tcg_temp_new_i32();
3767 tcg_gen_shli_i32(rd
, t0
, 8);
3768 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3769 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3770 tcg_gen_or_i32(rd
, rd
, tmp
);
3772 tcg_gen_shri_i32(t1
, t1
, 8);
3773 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3774 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3775 tcg_gen_or_i32(t1
, t1
, tmp
);
3776 tcg_gen_mov_i32(t0
, rd
);
3778 tcg_temp_free_i32(tmp
);
3779 tcg_temp_free_i32(rd
);
3782 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3786 rd
= tcg_temp_new_i32();
3787 tmp
= tcg_temp_new_i32();
3789 tcg_gen_shli_i32(rd
, t0
, 16);
3790 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3791 tcg_gen_or_i32(rd
, rd
, tmp
);
3792 tcg_gen_shri_i32(t1
, t1
, 16);
3793 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3794 tcg_gen_or_i32(t1
, t1
, tmp
);
3795 tcg_gen_mov_i32(t0
, rd
);
3797 tcg_temp_free_i32(tmp
);
3798 tcg_temp_free_i32(rd
);
3806 } neon_ls_element_type
[11] = {
3820 /* Translate a NEON load/store element instruction. Return nonzero if the
3821 instruction is invalid. */
3822 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3841 if (!s
->vfp_enabled
)
3843 VFP_DREG_D(rd
, insn
);
3844 rn
= (insn
>> 16) & 0xf;
3846 load
= (insn
& (1 << 21)) != 0;
3847 if ((insn
& (1 << 23)) == 0) {
3848 /* Load store all elements. */
3849 op
= (insn
>> 8) & 0xf;
3850 size
= (insn
>> 6) & 3;
3853 /* Catch UNDEF cases for bad values of align field */
3856 if (((insn
>> 5) & 1) == 1) {
3861 if (((insn
>> 4) & 3) == 3) {
3868 nregs
= neon_ls_element_type
[op
].nregs
;
3869 interleave
= neon_ls_element_type
[op
].interleave
;
3870 spacing
= neon_ls_element_type
[op
].spacing
;
3871 if (size
== 3 && (interleave
| spacing
) != 1)
3873 addr
= tcg_temp_new_i32();
3874 load_reg_var(s
, addr
, rn
);
3875 stride
= (1 << size
) * interleave
;
3876 for (reg
= 0; reg
< nregs
; reg
++) {
3877 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3878 load_reg_var(s
, addr
, rn
);
3879 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3880 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3881 load_reg_var(s
, addr
, rn
);
3882 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3885 tmp64
= tcg_temp_new_i64();
3887 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
3888 neon_store_reg64(tmp64
, rd
);
3890 neon_load_reg64(tmp64
, rd
);
3891 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
3893 tcg_temp_free_i64(tmp64
);
3894 tcg_gen_addi_i32(addr
, addr
, stride
);
3896 for (pass
= 0; pass
< 2; pass
++) {
3899 tmp
= tcg_temp_new_i32();
3900 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
3901 neon_store_reg(rd
, pass
, tmp
);
3903 tmp
= neon_load_reg(rd
, pass
);
3904 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
3905 tcg_temp_free_i32(tmp
);
3907 tcg_gen_addi_i32(addr
, addr
, stride
);
3908 } else if (size
== 1) {
3910 tmp
= tcg_temp_new_i32();
3911 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
3912 tcg_gen_addi_i32(addr
, addr
, stride
);
3913 tmp2
= tcg_temp_new_i32();
3914 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
3915 tcg_gen_addi_i32(addr
, addr
, stride
);
3916 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3917 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3918 tcg_temp_free_i32(tmp2
);
3919 neon_store_reg(rd
, pass
, tmp
);
3921 tmp
= neon_load_reg(rd
, pass
);
3922 tmp2
= tcg_temp_new_i32();
3923 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3924 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
3925 tcg_temp_free_i32(tmp
);
3926 tcg_gen_addi_i32(addr
, addr
, stride
);
3927 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
3928 tcg_temp_free_i32(tmp2
);
3929 tcg_gen_addi_i32(addr
, addr
, stride
);
3931 } else /* size == 0 */ {
3933 TCGV_UNUSED_I32(tmp2
);
3934 for (n
= 0; n
< 4; n
++) {
3935 tmp
= tcg_temp_new_i32();
3936 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
3937 tcg_gen_addi_i32(addr
, addr
, stride
);
3941 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3942 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3943 tcg_temp_free_i32(tmp
);
3946 neon_store_reg(rd
, pass
, tmp2
);
3948 tmp2
= neon_load_reg(rd
, pass
);
3949 for (n
= 0; n
< 4; n
++) {
3950 tmp
= tcg_temp_new_i32();
3952 tcg_gen_mov_i32(tmp
, tmp2
);
3954 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3956 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
3957 tcg_temp_free_i32(tmp
);
3958 tcg_gen_addi_i32(addr
, addr
, stride
);
3960 tcg_temp_free_i32(tmp2
);
3967 tcg_temp_free_i32(addr
);
3970 size
= (insn
>> 10) & 3;
3972 /* Load single element to all lanes. */
3973 int a
= (insn
>> 4) & 1;
3977 size
= (insn
>> 6) & 3;
3978 nregs
= ((insn
>> 8) & 3) + 1;
3981 if (nregs
!= 4 || a
== 0) {
3984 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3987 if (nregs
== 1 && a
== 1 && size
== 0) {
3990 if (nregs
== 3 && a
== 1) {
3993 addr
= tcg_temp_new_i32();
3994 load_reg_var(s
, addr
, rn
);
3996 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3997 tmp
= gen_load_and_replicate(s
, addr
, size
);
3998 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3999 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4000 if (insn
& (1 << 5)) {
4001 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4002 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4004 tcg_temp_free_i32(tmp
);
4006 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4007 stride
= (insn
& (1 << 5)) ? 2 : 1;
4008 for (reg
= 0; reg
< nregs
; reg
++) {
4009 tmp
= gen_load_and_replicate(s
, addr
, size
);
4010 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4011 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4012 tcg_temp_free_i32(tmp
);
4013 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4017 tcg_temp_free_i32(addr
);
4018 stride
= (1 << size
) * nregs
;
4020 /* Single element. */
4021 int idx
= (insn
>> 4) & 0xf;
4022 pass
= (insn
>> 7) & 1;
4025 shift
= ((insn
>> 5) & 3) * 8;
4029 shift
= ((insn
>> 6) & 1) * 16;
4030 stride
= (insn
& (1 << 5)) ? 2 : 1;
4034 stride
= (insn
& (1 << 6)) ? 2 : 1;
4039 nregs
= ((insn
>> 8) & 3) + 1;
4040 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4043 if (((idx
& (1 << size
)) != 0) ||
4044 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4049 if ((idx
& 1) != 0) {
4054 if (size
== 2 && (idx
& 2) != 0) {
4059 if ((size
== 2) && ((idx
& 3) == 3)) {
4066 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4067 /* Attempts to write off the end of the register file
4068 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4069 * the neon_load_reg() would write off the end of the array.
4073 addr
= tcg_temp_new_i32();
4074 load_reg_var(s
, addr
, rn
);
4075 for (reg
= 0; reg
< nregs
; reg
++) {
4077 tmp
= tcg_temp_new_i32();
4080 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4083 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4086 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4088 default: /* Avoid compiler warnings. */
4092 tmp2
= neon_load_reg(rd
, pass
);
4093 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4094 shift
, size
? 16 : 8);
4095 tcg_temp_free_i32(tmp2
);
4097 neon_store_reg(rd
, pass
, tmp
);
4098 } else { /* Store */
4099 tmp
= neon_load_reg(rd
, pass
);
4101 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4104 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4107 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4110 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4113 tcg_temp_free_i32(tmp
);
4116 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4118 tcg_temp_free_i32(addr
);
4119 stride
= nregs
* (1 << size
);
4125 base
= load_reg(s
, rn
);
4127 tcg_gen_addi_i32(base
, base
, stride
);
4130 index
= load_reg(s
, rm
);
4131 tcg_gen_add_i32(base
, base
, index
);
4132 tcg_temp_free_i32(index
);
4134 store_reg(s
, rn
, base
);
4139 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4140 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4142 tcg_gen_and_i32(t
, t
, c
);
4143 tcg_gen_andc_i32(f
, f
, c
);
4144 tcg_gen_or_i32(dest
, t
, f
);
4147 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4150 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4151 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4152 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4157 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4160 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4161 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4162 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4167 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4170 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4171 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4172 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4177 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4180 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4181 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4182 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4187 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4193 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4194 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4199 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4200 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4207 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4208 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4213 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4214 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4221 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4225 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4226 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4227 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4232 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4233 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4234 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4238 tcg_temp_free_i32(src
);
4241 static inline void gen_neon_addl(int size
)
4244 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4245 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4246 case 2: tcg_gen_add_i64(CPU_V001
); break;
4251 static inline void gen_neon_subl(int size
)
4254 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4255 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4256 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4261 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4264 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4265 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4267 tcg_gen_neg_i64(var
, var
);
4273 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4276 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4277 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4282 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4287 switch ((size
<< 1) | u
) {
4288 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4289 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4290 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4291 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4293 tmp
= gen_muls_i64_i32(a
, b
);
4294 tcg_gen_mov_i64(dest
, tmp
);
4295 tcg_temp_free_i64(tmp
);
4298 tmp
= gen_mulu_i64_i32(a
, b
);
4299 tcg_gen_mov_i64(dest
, tmp
);
4300 tcg_temp_free_i64(tmp
);
4305 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4306 Don't forget to clean them now. */
4308 tcg_temp_free_i32(a
);
4309 tcg_temp_free_i32(b
);
4313 static void gen_neon_narrow_op(int op
, int u
, int size
,
4314 TCGv_i32 dest
, TCGv_i64 src
)
4318 gen_neon_unarrow_sats(size
, dest
, src
);
4320 gen_neon_narrow(size
, dest
, src
);
4324 gen_neon_narrow_satu(size
, dest
, src
);
4326 gen_neon_narrow_sats(size
, dest
, src
);
4331 /* Symbolic constants for op fields for Neon 3-register same-length.
4332 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4335 #define NEON_3R_VHADD 0
4336 #define NEON_3R_VQADD 1
4337 #define NEON_3R_VRHADD 2
4338 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4339 #define NEON_3R_VHSUB 4
4340 #define NEON_3R_VQSUB 5
4341 #define NEON_3R_VCGT 6
4342 #define NEON_3R_VCGE 7
4343 #define NEON_3R_VSHL 8
4344 #define NEON_3R_VQSHL 9
4345 #define NEON_3R_VRSHL 10
4346 #define NEON_3R_VQRSHL 11
4347 #define NEON_3R_VMAX 12
4348 #define NEON_3R_VMIN 13
4349 #define NEON_3R_VABD 14
4350 #define NEON_3R_VABA 15
4351 #define NEON_3R_VADD_VSUB 16
4352 #define NEON_3R_VTST_VCEQ 17
4353 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4354 #define NEON_3R_VMUL 19
4355 #define NEON_3R_VPMAX 20
4356 #define NEON_3R_VPMIN 21
4357 #define NEON_3R_VQDMULH_VQRDMULH 22
4358 #define NEON_3R_VPADD 23
4359 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4360 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4361 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4362 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4363 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4364 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4365 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4367 static const uint8_t neon_3r_sizes
[] = {
4368 [NEON_3R_VHADD
] = 0x7,
4369 [NEON_3R_VQADD
] = 0xf,
4370 [NEON_3R_VRHADD
] = 0x7,
4371 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4372 [NEON_3R_VHSUB
] = 0x7,
4373 [NEON_3R_VQSUB
] = 0xf,
4374 [NEON_3R_VCGT
] = 0x7,
4375 [NEON_3R_VCGE
] = 0x7,
4376 [NEON_3R_VSHL
] = 0xf,
4377 [NEON_3R_VQSHL
] = 0xf,
4378 [NEON_3R_VRSHL
] = 0xf,
4379 [NEON_3R_VQRSHL
] = 0xf,
4380 [NEON_3R_VMAX
] = 0x7,
4381 [NEON_3R_VMIN
] = 0x7,
4382 [NEON_3R_VABD
] = 0x7,
4383 [NEON_3R_VABA
] = 0x7,
4384 [NEON_3R_VADD_VSUB
] = 0xf,
4385 [NEON_3R_VTST_VCEQ
] = 0x7,
4386 [NEON_3R_VML
] = 0x7,
4387 [NEON_3R_VMUL
] = 0x7,
4388 [NEON_3R_VPMAX
] = 0x7,
4389 [NEON_3R_VPMIN
] = 0x7,
4390 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4391 [NEON_3R_VPADD
] = 0x7,
4392 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4393 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4394 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4395 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4396 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4397 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4398 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4401 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4402 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4405 #define NEON_2RM_VREV64 0
4406 #define NEON_2RM_VREV32 1
4407 #define NEON_2RM_VREV16 2
4408 #define NEON_2RM_VPADDL 4
4409 #define NEON_2RM_VPADDL_U 5
4410 #define NEON_2RM_VCLS 8
4411 #define NEON_2RM_VCLZ 9
4412 #define NEON_2RM_VCNT 10
4413 #define NEON_2RM_VMVN 11
4414 #define NEON_2RM_VPADAL 12
4415 #define NEON_2RM_VPADAL_U 13
4416 #define NEON_2RM_VQABS 14
4417 #define NEON_2RM_VQNEG 15
4418 #define NEON_2RM_VCGT0 16
4419 #define NEON_2RM_VCGE0 17
4420 #define NEON_2RM_VCEQ0 18
4421 #define NEON_2RM_VCLE0 19
4422 #define NEON_2RM_VCLT0 20
4423 #define NEON_2RM_VABS 22
4424 #define NEON_2RM_VNEG 23
4425 #define NEON_2RM_VCGT0_F 24
4426 #define NEON_2RM_VCGE0_F 25
4427 #define NEON_2RM_VCEQ0_F 26
4428 #define NEON_2RM_VCLE0_F 27
4429 #define NEON_2RM_VCLT0_F 28
4430 #define NEON_2RM_VABS_F 30
4431 #define NEON_2RM_VNEG_F 31
4432 #define NEON_2RM_VSWP 32
4433 #define NEON_2RM_VTRN 33
4434 #define NEON_2RM_VUZP 34
4435 #define NEON_2RM_VZIP 35
4436 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4437 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4438 #define NEON_2RM_VSHLL 38
4439 #define NEON_2RM_VCVT_F16_F32 44
4440 #define NEON_2RM_VCVT_F32_F16 46
4441 #define NEON_2RM_VRECPE 56
4442 #define NEON_2RM_VRSQRTE 57
4443 #define NEON_2RM_VRECPE_F 58
4444 #define NEON_2RM_VRSQRTE_F 59
4445 #define NEON_2RM_VCVT_FS 60
4446 #define NEON_2RM_VCVT_FU 61
4447 #define NEON_2RM_VCVT_SF 62
4448 #define NEON_2RM_VCVT_UF 63
4450 static int neon_2rm_is_float_op(int op
)
4452 /* Return true if this neon 2reg-misc op is float-to-float */
4453 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4454 op
>= NEON_2RM_VRECPE_F
);
4457 /* Each entry in this array has bit n set if the insn allows
4458 * size value n (otherwise it will UNDEF). Since unallocated
4459 * op values will have no bits set they always UNDEF.
4461 static const uint8_t neon_2rm_sizes
[] = {
4462 [NEON_2RM_VREV64
] = 0x7,
4463 [NEON_2RM_VREV32
] = 0x3,
4464 [NEON_2RM_VREV16
] = 0x1,
4465 [NEON_2RM_VPADDL
] = 0x7,
4466 [NEON_2RM_VPADDL_U
] = 0x7,
4467 [NEON_2RM_VCLS
] = 0x7,
4468 [NEON_2RM_VCLZ
] = 0x7,
4469 [NEON_2RM_VCNT
] = 0x1,
4470 [NEON_2RM_VMVN
] = 0x1,
4471 [NEON_2RM_VPADAL
] = 0x7,
4472 [NEON_2RM_VPADAL_U
] = 0x7,
4473 [NEON_2RM_VQABS
] = 0x7,
4474 [NEON_2RM_VQNEG
] = 0x7,
4475 [NEON_2RM_VCGT0
] = 0x7,
4476 [NEON_2RM_VCGE0
] = 0x7,
4477 [NEON_2RM_VCEQ0
] = 0x7,
4478 [NEON_2RM_VCLE0
] = 0x7,
4479 [NEON_2RM_VCLT0
] = 0x7,
4480 [NEON_2RM_VABS
] = 0x7,
4481 [NEON_2RM_VNEG
] = 0x7,
4482 [NEON_2RM_VCGT0_F
] = 0x4,
4483 [NEON_2RM_VCGE0_F
] = 0x4,
4484 [NEON_2RM_VCEQ0_F
] = 0x4,
4485 [NEON_2RM_VCLE0_F
] = 0x4,
4486 [NEON_2RM_VCLT0_F
] = 0x4,
4487 [NEON_2RM_VABS_F
] = 0x4,
4488 [NEON_2RM_VNEG_F
] = 0x4,
4489 [NEON_2RM_VSWP
] = 0x1,
4490 [NEON_2RM_VTRN
] = 0x7,
4491 [NEON_2RM_VUZP
] = 0x7,
4492 [NEON_2RM_VZIP
] = 0x7,
4493 [NEON_2RM_VMOVN
] = 0x7,
4494 [NEON_2RM_VQMOVN
] = 0x7,
4495 [NEON_2RM_VSHLL
] = 0x7,
4496 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4497 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4498 [NEON_2RM_VRECPE
] = 0x4,
4499 [NEON_2RM_VRSQRTE
] = 0x4,
4500 [NEON_2RM_VRECPE_F
] = 0x4,
4501 [NEON_2RM_VRSQRTE_F
] = 0x4,
4502 [NEON_2RM_VCVT_FS
] = 0x4,
4503 [NEON_2RM_VCVT_FU
] = 0x4,
4504 [NEON_2RM_VCVT_SF
] = 0x4,
4505 [NEON_2RM_VCVT_UF
] = 0x4,
4508 /* Translate a NEON data processing instruction. Return nonzero if the
4509 instruction is invalid.
4510 We process data in a mixture of 32-bit and 64-bit chunks.
4511 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4513 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4525 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4528 if (!s
->vfp_enabled
)
4530 q
= (insn
& (1 << 6)) != 0;
4531 u
= (insn
>> 24) & 1;
4532 VFP_DREG_D(rd
, insn
);
4533 VFP_DREG_N(rn
, insn
);
4534 VFP_DREG_M(rm
, insn
);
4535 size
= (insn
>> 20) & 3;
4536 if ((insn
& (1 << 23)) == 0) {
4537 /* Three register same length. */
4538 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4539 /* Catch invalid op and bad size combinations: UNDEF */
4540 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4543 /* All insns of this form UNDEF for either this condition or the
4544 * superset of cases "Q==1"; we catch the latter later.
4546 if (q
&& ((rd
| rn
| rm
) & 1)) {
4549 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4550 /* 64-bit element instructions. */
4551 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4552 neon_load_reg64(cpu_V0
, rn
+ pass
);
4553 neon_load_reg64(cpu_V1
, rm
+ pass
);
4557 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4560 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4566 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4569 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4575 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4577 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4582 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4585 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4591 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4593 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4596 case NEON_3R_VQRSHL
:
4598 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4601 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4605 case NEON_3R_VADD_VSUB
:
4607 tcg_gen_sub_i64(CPU_V001
);
4609 tcg_gen_add_i64(CPU_V001
);
4615 neon_store_reg64(cpu_V0
, rd
+ pass
);
4624 case NEON_3R_VQRSHL
:
4627 /* Shift instruction operands are reversed. */
4642 case NEON_3R_FLOAT_ARITH
:
4643 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4645 case NEON_3R_FLOAT_MINMAX
:
4646 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4648 case NEON_3R_FLOAT_CMP
:
4650 /* no encoding for U=0 C=1x */
4654 case NEON_3R_FLOAT_ACMP
:
4659 case NEON_3R_VRECPS_VRSQRTS
:
4665 if (u
&& (size
!= 0)) {
4666 /* UNDEF on invalid size for polynomial subcase */
4671 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4679 if (pairwise
&& q
) {
4680 /* All the pairwise insns UNDEF if Q is set */
4684 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4689 tmp
= neon_load_reg(rn
, 0);
4690 tmp2
= neon_load_reg(rn
, 1);
4692 tmp
= neon_load_reg(rm
, 0);
4693 tmp2
= neon_load_reg(rm
, 1);
4697 tmp
= neon_load_reg(rn
, pass
);
4698 tmp2
= neon_load_reg(rm
, pass
);
4702 GEN_NEON_INTEGER_OP(hadd
);
4705 GEN_NEON_INTEGER_OP_ENV(qadd
);
4707 case NEON_3R_VRHADD
:
4708 GEN_NEON_INTEGER_OP(rhadd
);
4710 case NEON_3R_LOGIC
: /* Logic ops. */
4711 switch ((u
<< 2) | size
) {
4713 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4716 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4719 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4722 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4725 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4728 tmp3
= neon_load_reg(rd
, pass
);
4729 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4730 tcg_temp_free_i32(tmp3
);
4733 tmp3
= neon_load_reg(rd
, pass
);
4734 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4735 tcg_temp_free_i32(tmp3
);
4738 tmp3
= neon_load_reg(rd
, pass
);
4739 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4740 tcg_temp_free_i32(tmp3
);
4745 GEN_NEON_INTEGER_OP(hsub
);
4748 GEN_NEON_INTEGER_OP_ENV(qsub
);
4751 GEN_NEON_INTEGER_OP(cgt
);
4754 GEN_NEON_INTEGER_OP(cge
);
4757 GEN_NEON_INTEGER_OP(shl
);
4760 GEN_NEON_INTEGER_OP_ENV(qshl
);
4763 GEN_NEON_INTEGER_OP(rshl
);
4765 case NEON_3R_VQRSHL
:
4766 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4769 GEN_NEON_INTEGER_OP(max
);
4772 GEN_NEON_INTEGER_OP(min
);
4775 GEN_NEON_INTEGER_OP(abd
);
4778 GEN_NEON_INTEGER_OP(abd
);
4779 tcg_temp_free_i32(tmp2
);
4780 tmp2
= neon_load_reg(rd
, pass
);
4781 gen_neon_add(size
, tmp
, tmp2
);
4783 case NEON_3R_VADD_VSUB
:
4784 if (!u
) { /* VADD */
4785 gen_neon_add(size
, tmp
, tmp2
);
4788 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4789 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4790 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4795 case NEON_3R_VTST_VCEQ
:
4796 if (!u
) { /* VTST */
4798 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4799 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4800 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4805 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4806 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4807 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4812 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4814 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4815 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4816 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4819 tcg_temp_free_i32(tmp2
);
4820 tmp2
= neon_load_reg(rd
, pass
);
4822 gen_neon_rsb(size
, tmp
, tmp2
);
4824 gen_neon_add(size
, tmp
, tmp2
);
4828 if (u
) { /* polynomial */
4829 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4830 } else { /* Integer */
4832 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4833 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4834 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4840 GEN_NEON_INTEGER_OP(pmax
);
4843 GEN_NEON_INTEGER_OP(pmin
);
4845 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4846 if (!u
) { /* VQDMULH */
4849 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4852 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4856 } else { /* VQRDMULH */
4859 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4862 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4870 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4871 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4872 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4876 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4878 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4879 switch ((u
<< 2) | size
) {
4882 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4885 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4888 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4893 tcg_temp_free_ptr(fpstatus
);
4896 case NEON_3R_FLOAT_MULTIPLY
:
4898 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4899 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4901 tcg_temp_free_i32(tmp2
);
4902 tmp2
= neon_load_reg(rd
, pass
);
4904 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4906 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4909 tcg_temp_free_ptr(fpstatus
);
4912 case NEON_3R_FLOAT_CMP
:
4914 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4916 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4919 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4921 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4924 tcg_temp_free_ptr(fpstatus
);
4927 case NEON_3R_FLOAT_ACMP
:
4929 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4931 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4933 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4935 tcg_temp_free_ptr(fpstatus
);
4938 case NEON_3R_FLOAT_MINMAX
:
4940 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4942 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4944 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4946 tcg_temp_free_ptr(fpstatus
);
4949 case NEON_3R_VRECPS_VRSQRTS
:
4951 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4953 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4957 /* VFMA, VFMS: fused multiply-add */
4958 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4959 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4962 gen_helper_vfp_negs(tmp
, tmp
);
4964 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4965 tcg_temp_free_i32(tmp3
);
4966 tcg_temp_free_ptr(fpstatus
);
4972 tcg_temp_free_i32(tmp2
);
4974 /* Save the result. For elementwise operations we can put it
4975 straight into the destination register. For pairwise operations
4976 we have to be careful to avoid clobbering the source operands. */
4977 if (pairwise
&& rd
== rm
) {
4978 neon_store_scratch(pass
, tmp
);
4980 neon_store_reg(rd
, pass
, tmp
);
4984 if (pairwise
&& rd
== rm
) {
4985 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4986 tmp
= neon_load_scratch(pass
);
4987 neon_store_reg(rd
, pass
, tmp
);
4990 /* End of 3 register same size operations. */
4991 } else if (insn
& (1 << 4)) {
4992 if ((insn
& 0x00380080) != 0) {
4993 /* Two registers and shift. */
4994 op
= (insn
>> 8) & 0xf;
4995 if (insn
& (1 << 7)) {
5003 while ((insn
& (1 << (size
+ 19))) == 0)
5006 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5007 /* To avoid excessive duplication of ops we implement shift
5008 by immediate using the variable shift operations. */
5010 /* Shift by immediate:
5011 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5012 if (q
&& ((rd
| rm
) & 1)) {
5015 if (!u
&& (op
== 4 || op
== 6)) {
5018 /* Right shifts are encoded as N - shift, where N is the
5019 element size in bits. */
5021 shift
= shift
- (1 << (size
+ 3));
5029 imm
= (uint8_t) shift
;
5034 imm
= (uint16_t) shift
;
5045 for (pass
= 0; pass
< count
; pass
++) {
5047 neon_load_reg64(cpu_V0
, rm
+ pass
);
5048 tcg_gen_movi_i64(cpu_V1
, imm
);
5053 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5055 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5060 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5062 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5065 case 5: /* VSHL, VSLI */
5066 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5068 case 6: /* VQSHLU */
5069 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5074 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5077 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5082 if (op
== 1 || op
== 3) {
5084 neon_load_reg64(cpu_V1
, rd
+ pass
);
5085 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5086 } else if (op
== 4 || (op
== 5 && u
)) {
5088 neon_load_reg64(cpu_V1
, rd
+ pass
);
5090 if (shift
< -63 || shift
> 63) {
5094 mask
= 0xffffffffffffffffull
>> -shift
;
5096 mask
= 0xffffffffffffffffull
<< shift
;
5099 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5100 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5102 neon_store_reg64(cpu_V0
, rd
+ pass
);
5103 } else { /* size < 3 */
5104 /* Operands in T0 and T1. */
5105 tmp
= neon_load_reg(rm
, pass
);
5106 tmp2
= tcg_temp_new_i32();
5107 tcg_gen_movi_i32(tmp2
, imm
);
5111 GEN_NEON_INTEGER_OP(shl
);
5115 GEN_NEON_INTEGER_OP(rshl
);
5118 case 5: /* VSHL, VSLI */
5120 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5121 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5122 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5126 case 6: /* VQSHLU */
5129 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5133 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5137 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5145 GEN_NEON_INTEGER_OP_ENV(qshl
);
5148 tcg_temp_free_i32(tmp2
);
5150 if (op
== 1 || op
== 3) {
5152 tmp2
= neon_load_reg(rd
, pass
);
5153 gen_neon_add(size
, tmp
, tmp2
);
5154 tcg_temp_free_i32(tmp2
);
5155 } else if (op
== 4 || (op
== 5 && u
)) {
5160 mask
= 0xff >> -shift
;
5162 mask
= (uint8_t)(0xff << shift
);
5168 mask
= 0xffff >> -shift
;
5170 mask
= (uint16_t)(0xffff << shift
);
5174 if (shift
< -31 || shift
> 31) {
5178 mask
= 0xffffffffu
>> -shift
;
5180 mask
= 0xffffffffu
<< shift
;
5186 tmp2
= neon_load_reg(rd
, pass
);
5187 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5188 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5189 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5190 tcg_temp_free_i32(tmp2
);
5192 neon_store_reg(rd
, pass
, tmp
);
5195 } else if (op
< 10) {
5196 /* Shift by immediate and narrow:
5197 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5198 int input_unsigned
= (op
== 8) ? !u
: u
;
5202 shift
= shift
- (1 << (size
+ 3));
5205 tmp64
= tcg_const_i64(shift
);
5206 neon_load_reg64(cpu_V0
, rm
);
5207 neon_load_reg64(cpu_V1
, rm
+ 1);
5208 for (pass
= 0; pass
< 2; pass
++) {
5216 if (input_unsigned
) {
5217 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5219 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5222 if (input_unsigned
) {
5223 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5225 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5228 tmp
= tcg_temp_new_i32();
5229 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5230 neon_store_reg(rd
, pass
, tmp
);
5232 tcg_temp_free_i64(tmp64
);
5235 imm
= (uint16_t)shift
;
5239 imm
= (uint32_t)shift
;
5241 tmp2
= tcg_const_i32(imm
);
5242 tmp4
= neon_load_reg(rm
+ 1, 0);
5243 tmp5
= neon_load_reg(rm
+ 1, 1);
5244 for (pass
= 0; pass
< 2; pass
++) {
5246 tmp
= neon_load_reg(rm
, 0);
5250 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5253 tmp3
= neon_load_reg(rm
, 1);
5257 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5259 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5260 tcg_temp_free_i32(tmp
);
5261 tcg_temp_free_i32(tmp3
);
5262 tmp
= tcg_temp_new_i32();
5263 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5264 neon_store_reg(rd
, pass
, tmp
);
5266 tcg_temp_free_i32(tmp2
);
5268 } else if (op
== 10) {
5270 if (q
|| (rd
& 1)) {
5273 tmp
= neon_load_reg(rm
, 0);
5274 tmp2
= neon_load_reg(rm
, 1);
5275 for (pass
= 0; pass
< 2; pass
++) {
5279 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5282 /* The shift is less than the width of the source
5283 type, so we can just shift the whole register. */
5284 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5285 /* Widen the result of shift: we need to clear
5286 * the potential overflow bits resulting from
5287 * left bits of the narrow input appearing as
5288 * right bits of left the neighbour narrow
5290 if (size
< 2 || !u
) {
5293 imm
= (0xffu
>> (8 - shift
));
5295 } else if (size
== 1) {
5296 imm
= 0xffff >> (16 - shift
);
5299 imm
= 0xffffffff >> (32 - shift
);
5302 imm64
= imm
| (((uint64_t)imm
) << 32);
5306 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5309 neon_store_reg64(cpu_V0
, rd
+ pass
);
5311 } else if (op
>= 14) {
5312 /* VCVT fixed-point. */
5313 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5316 /* We have already masked out the must-be-1 top bit of imm6,
5317 * hence this 32-shift where the ARM ARM has 64-imm6.
5320 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5321 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5324 gen_vfp_ulto(0, shift
, 1);
5326 gen_vfp_slto(0, shift
, 1);
5329 gen_vfp_toul(0, shift
, 1);
5331 gen_vfp_tosl(0, shift
, 1);
5333 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5338 } else { /* (insn & 0x00380080) == 0 */
5340 if (q
&& (rd
& 1)) {
5344 op
= (insn
>> 8) & 0xf;
5345 /* One register and immediate. */
5346 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5347 invert
= (insn
& (1 << 5)) != 0;
5348 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5349 * We choose to not special-case this and will behave as if a
5350 * valid constant encoding of 0 had been given.
5369 imm
= (imm
<< 8) | (imm
<< 24);
5372 imm
= (imm
<< 8) | 0xff;
5375 imm
= (imm
<< 16) | 0xffff;
5378 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5386 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5387 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5393 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5394 if (op
& 1 && op
< 12) {
5395 tmp
= neon_load_reg(rd
, pass
);
5397 /* The immediate value has already been inverted, so
5399 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5401 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5405 tmp
= tcg_temp_new_i32();
5406 if (op
== 14 && invert
) {
5410 for (n
= 0; n
< 4; n
++) {
5411 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5412 val
|= 0xff << (n
* 8);
5414 tcg_gen_movi_i32(tmp
, val
);
5416 tcg_gen_movi_i32(tmp
, imm
);
5419 neon_store_reg(rd
, pass
, tmp
);
5422 } else { /* (insn & 0x00800010 == 0x00800000) */
5424 op
= (insn
>> 8) & 0xf;
5425 if ((insn
& (1 << 6)) == 0) {
5426 /* Three registers of different lengths. */
5430 /* undefreq: bit 0 : UNDEF if size != 0
5431 * bit 1 : UNDEF if size == 0
5432 * bit 2 : UNDEF if U == 1
5433 * Note that [1:0] set implies 'always UNDEF'
5436 /* prewiden, src1_wide, src2_wide, undefreq */
5437 static const int neon_3reg_wide
[16][4] = {
5438 {1, 0, 0, 0}, /* VADDL */
5439 {1, 1, 0, 0}, /* VADDW */
5440 {1, 0, 0, 0}, /* VSUBL */
5441 {1, 1, 0, 0}, /* VSUBW */
5442 {0, 1, 1, 0}, /* VADDHN */
5443 {0, 0, 0, 0}, /* VABAL */
5444 {0, 1, 1, 0}, /* VSUBHN */
5445 {0, 0, 0, 0}, /* VABDL */
5446 {0, 0, 0, 0}, /* VMLAL */
5447 {0, 0, 0, 6}, /* VQDMLAL */
5448 {0, 0, 0, 0}, /* VMLSL */
5449 {0, 0, 0, 6}, /* VQDMLSL */
5450 {0, 0, 0, 0}, /* Integer VMULL */
5451 {0, 0, 0, 2}, /* VQDMULL */
5452 {0, 0, 0, 5}, /* Polynomial VMULL */
5453 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5456 prewiden
= neon_3reg_wide
[op
][0];
5457 src1_wide
= neon_3reg_wide
[op
][1];
5458 src2_wide
= neon_3reg_wide
[op
][2];
5459 undefreq
= neon_3reg_wide
[op
][3];
5461 if (((undefreq
& 1) && (size
!= 0)) ||
5462 ((undefreq
& 2) && (size
== 0)) ||
5463 ((undefreq
& 4) && u
)) {
5466 if ((src1_wide
&& (rn
& 1)) ||
5467 (src2_wide
&& (rm
& 1)) ||
5468 (!src2_wide
&& (rd
& 1))) {
5472 /* Avoid overlapping operands. Wide source operands are
5473 always aligned so will never overlap with wide
5474 destinations in problematic ways. */
5475 if (rd
== rm
&& !src2_wide
) {
5476 tmp
= neon_load_reg(rm
, 1);
5477 neon_store_scratch(2, tmp
);
5478 } else if (rd
== rn
&& !src1_wide
) {
5479 tmp
= neon_load_reg(rn
, 1);
5480 neon_store_scratch(2, tmp
);
5482 TCGV_UNUSED_I32(tmp3
);
5483 for (pass
= 0; pass
< 2; pass
++) {
5485 neon_load_reg64(cpu_V0
, rn
+ pass
);
5486 TCGV_UNUSED_I32(tmp
);
5488 if (pass
== 1 && rd
== rn
) {
5489 tmp
= neon_load_scratch(2);
5491 tmp
= neon_load_reg(rn
, pass
);
5494 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5498 neon_load_reg64(cpu_V1
, rm
+ pass
);
5499 TCGV_UNUSED_I32(tmp2
);
5501 if (pass
== 1 && rd
== rm
) {
5502 tmp2
= neon_load_scratch(2);
5504 tmp2
= neon_load_reg(rm
, pass
);
5507 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5511 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5512 gen_neon_addl(size
);
5514 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5515 gen_neon_subl(size
);
5517 case 5: case 7: /* VABAL, VABDL */
5518 switch ((size
<< 1) | u
) {
5520 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5523 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5526 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5529 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5532 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5535 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5539 tcg_temp_free_i32(tmp2
);
5540 tcg_temp_free_i32(tmp
);
5542 case 8: case 9: case 10: case 11: case 12: case 13:
5543 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5544 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5546 case 14: /* Polynomial VMULL */
5547 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5548 tcg_temp_free_i32(tmp2
);
5549 tcg_temp_free_i32(tmp
);
5551 default: /* 15 is RESERVED: caught earlier */
5556 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5557 neon_store_reg64(cpu_V0
, rd
+ pass
);
5558 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5560 neon_load_reg64(cpu_V1
, rd
+ pass
);
5562 case 10: /* VMLSL */
5563 gen_neon_negl(cpu_V0
, size
);
5565 case 5: case 8: /* VABAL, VMLAL */
5566 gen_neon_addl(size
);
5568 case 9: case 11: /* VQDMLAL, VQDMLSL */
5569 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5571 gen_neon_negl(cpu_V0
, size
);
5573 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5578 neon_store_reg64(cpu_V0
, rd
+ pass
);
5579 } else if (op
== 4 || op
== 6) {
5580 /* Narrowing operation. */
5581 tmp
= tcg_temp_new_i32();
5585 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5588 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5591 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5592 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5599 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5602 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5605 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5606 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5607 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5615 neon_store_reg(rd
, 0, tmp3
);
5616 neon_store_reg(rd
, 1, tmp
);
5619 /* Write back the result. */
5620 neon_store_reg64(cpu_V0
, rd
+ pass
);
5624 /* Two registers and a scalar. NB that for ops of this form
5625 * the ARM ARM labels bit 24 as Q, but it is in our variable
5632 case 1: /* Float VMLA scalar */
5633 case 5: /* Floating point VMLS scalar */
5634 case 9: /* Floating point VMUL scalar */
5639 case 0: /* Integer VMLA scalar */
5640 case 4: /* Integer VMLS scalar */
5641 case 8: /* Integer VMUL scalar */
5642 case 12: /* VQDMULH scalar */
5643 case 13: /* VQRDMULH scalar */
5644 if (u
&& ((rd
| rn
) & 1)) {
5647 tmp
= neon_get_scalar(size
, rm
);
5648 neon_store_scratch(0, tmp
);
5649 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5650 tmp
= neon_load_scratch(0);
5651 tmp2
= neon_load_reg(rn
, pass
);
5654 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5656 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5658 } else if (op
== 13) {
5660 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5662 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5664 } else if (op
& 1) {
5665 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5666 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5667 tcg_temp_free_ptr(fpstatus
);
5670 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5671 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5672 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5676 tcg_temp_free_i32(tmp2
);
5679 tmp2
= neon_load_reg(rd
, pass
);
5682 gen_neon_add(size
, tmp
, tmp2
);
5686 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5687 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5688 tcg_temp_free_ptr(fpstatus
);
5692 gen_neon_rsb(size
, tmp
, tmp2
);
5696 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5697 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5698 tcg_temp_free_ptr(fpstatus
);
5704 tcg_temp_free_i32(tmp2
);
5706 neon_store_reg(rd
, pass
, tmp
);
5709 case 3: /* VQDMLAL scalar */
5710 case 7: /* VQDMLSL scalar */
5711 case 11: /* VQDMULL scalar */
5716 case 2: /* VMLAL sclar */
5717 case 6: /* VMLSL scalar */
5718 case 10: /* VMULL scalar */
5722 tmp2
= neon_get_scalar(size
, rm
);
5723 /* We need a copy of tmp2 because gen_neon_mull
5724 * deletes it during pass 0. */
5725 tmp4
= tcg_temp_new_i32();
5726 tcg_gen_mov_i32(tmp4
, tmp2
);
5727 tmp3
= neon_load_reg(rn
, 1);
5729 for (pass
= 0; pass
< 2; pass
++) {
5731 tmp
= neon_load_reg(rn
, 0);
5736 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5738 neon_load_reg64(cpu_V1
, rd
+ pass
);
5742 gen_neon_negl(cpu_V0
, size
);
5745 gen_neon_addl(size
);
5748 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5750 gen_neon_negl(cpu_V0
, size
);
5752 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5758 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5763 neon_store_reg64(cpu_V0
, rd
+ pass
);
5768 default: /* 14 and 15 are RESERVED */
5772 } else { /* size == 3 */
5775 imm
= (insn
>> 8) & 0xf;
5780 if (q
&& ((rd
| rn
| rm
) & 1)) {
5785 neon_load_reg64(cpu_V0
, rn
);
5787 neon_load_reg64(cpu_V1
, rn
+ 1);
5789 } else if (imm
== 8) {
5790 neon_load_reg64(cpu_V0
, rn
+ 1);
5792 neon_load_reg64(cpu_V1
, rm
);
5795 tmp64
= tcg_temp_new_i64();
5797 neon_load_reg64(cpu_V0
, rn
);
5798 neon_load_reg64(tmp64
, rn
+ 1);
5800 neon_load_reg64(cpu_V0
, rn
+ 1);
5801 neon_load_reg64(tmp64
, rm
);
5803 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5804 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5805 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5807 neon_load_reg64(cpu_V1
, rm
);
5809 neon_load_reg64(cpu_V1
, rm
+ 1);
5812 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5813 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5814 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5815 tcg_temp_free_i64(tmp64
);
5818 neon_load_reg64(cpu_V0
, rn
);
5819 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5820 neon_load_reg64(cpu_V1
, rm
);
5821 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5822 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5824 neon_store_reg64(cpu_V0
, rd
);
5826 neon_store_reg64(cpu_V1
, rd
+ 1);
5828 } else if ((insn
& (1 << 11)) == 0) {
5829 /* Two register misc. */
5830 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5831 size
= (insn
>> 18) & 3;
5832 /* UNDEF for unknown op values and bad op-size combinations */
5833 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5836 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5837 q
&& ((rm
| rd
) & 1)) {
5841 case NEON_2RM_VREV64
:
5842 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5843 tmp
= neon_load_reg(rm
, pass
* 2);
5844 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5846 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5847 case 1: gen_swap_half(tmp
); break;
5848 case 2: /* no-op */ break;
5851 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5853 neon_store_reg(rd
, pass
* 2, tmp2
);
5856 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5857 case 1: gen_swap_half(tmp2
); break;
5860 neon_store_reg(rd
, pass
* 2, tmp2
);
5864 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5865 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5866 for (pass
= 0; pass
< q
+ 1; pass
++) {
5867 tmp
= neon_load_reg(rm
, pass
* 2);
5868 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5869 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5870 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5872 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5873 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5874 case 2: tcg_gen_add_i64(CPU_V001
); break;
5877 if (op
>= NEON_2RM_VPADAL
) {
5879 neon_load_reg64(cpu_V1
, rd
+ pass
);
5880 gen_neon_addl(size
);
5882 neon_store_reg64(cpu_V0
, rd
+ pass
);
5888 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5889 tmp
= neon_load_reg(rm
, n
);
5890 tmp2
= neon_load_reg(rd
, n
+ 1);
5891 neon_store_reg(rm
, n
, tmp2
);
5892 neon_store_reg(rd
, n
+ 1, tmp
);
5899 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5904 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5908 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5909 /* also VQMOVUN; op field and mnemonics don't line up */
5913 TCGV_UNUSED_I32(tmp2
);
5914 for (pass
= 0; pass
< 2; pass
++) {
5915 neon_load_reg64(cpu_V0
, rm
+ pass
);
5916 tmp
= tcg_temp_new_i32();
5917 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5922 neon_store_reg(rd
, 0, tmp2
);
5923 neon_store_reg(rd
, 1, tmp
);
5927 case NEON_2RM_VSHLL
:
5928 if (q
|| (rd
& 1)) {
5931 tmp
= neon_load_reg(rm
, 0);
5932 tmp2
= neon_load_reg(rm
, 1);
5933 for (pass
= 0; pass
< 2; pass
++) {
5936 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5937 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5938 neon_store_reg64(cpu_V0
, rd
+ pass
);
5941 case NEON_2RM_VCVT_F16_F32
:
5942 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5946 tmp
= tcg_temp_new_i32();
5947 tmp2
= tcg_temp_new_i32();
5948 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5949 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5950 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5951 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5952 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5953 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5954 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5955 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5956 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5957 neon_store_reg(rd
, 0, tmp2
);
5958 tmp2
= tcg_temp_new_i32();
5959 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5960 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5961 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5962 neon_store_reg(rd
, 1, tmp2
);
5963 tcg_temp_free_i32(tmp
);
5965 case NEON_2RM_VCVT_F32_F16
:
5966 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5970 tmp3
= tcg_temp_new_i32();
5971 tmp
= neon_load_reg(rm
, 0);
5972 tmp2
= neon_load_reg(rm
, 1);
5973 tcg_gen_ext16u_i32(tmp3
, tmp
);
5974 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5975 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5976 tcg_gen_shri_i32(tmp3
, tmp
, 16);
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
, 1));
5979 tcg_temp_free_i32(tmp
);
5980 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5981 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5982 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5983 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
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
, 3));
5986 tcg_temp_free_i32(tmp2
);
5987 tcg_temp_free_i32(tmp3
);
5991 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5992 if (neon_2rm_is_float_op(op
)) {
5993 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5994 neon_reg_offset(rm
, pass
));
5995 TCGV_UNUSED_I32(tmp
);
5997 tmp
= neon_load_reg(rm
, pass
);
6000 case NEON_2RM_VREV32
:
6002 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6003 case 1: gen_swap_half(tmp
); break;
6007 case NEON_2RM_VREV16
:
6012 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6013 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6014 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6020 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6021 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6022 case 2: gen_helper_clz(tmp
, tmp
); break;
6027 gen_helper_neon_cnt_u8(tmp
, tmp
);
6030 tcg_gen_not_i32(tmp
, tmp
);
6032 case NEON_2RM_VQABS
:
6035 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6038 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6041 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6046 case NEON_2RM_VQNEG
:
6049 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6052 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6055 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6060 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6061 tmp2
= tcg_const_i32(0);
6063 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6064 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6065 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6068 tcg_temp_free_i32(tmp2
);
6069 if (op
== NEON_2RM_VCLE0
) {
6070 tcg_gen_not_i32(tmp
, tmp
);
6073 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6074 tmp2
= tcg_const_i32(0);
6076 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6077 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6078 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6081 tcg_temp_free_i32(tmp2
);
6082 if (op
== NEON_2RM_VCLT0
) {
6083 tcg_gen_not_i32(tmp
, tmp
);
6086 case NEON_2RM_VCEQ0
:
6087 tmp2
= tcg_const_i32(0);
6089 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6090 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6091 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6094 tcg_temp_free_i32(tmp2
);
6098 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6099 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6100 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6105 tmp2
= tcg_const_i32(0);
6106 gen_neon_rsb(size
, tmp
, tmp2
);
6107 tcg_temp_free_i32(tmp2
);
6109 case NEON_2RM_VCGT0_F
:
6111 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6112 tmp2
= tcg_const_i32(0);
6113 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6114 tcg_temp_free_i32(tmp2
);
6115 tcg_temp_free_ptr(fpstatus
);
6118 case NEON_2RM_VCGE0_F
:
6120 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6121 tmp2
= tcg_const_i32(0);
6122 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6123 tcg_temp_free_i32(tmp2
);
6124 tcg_temp_free_ptr(fpstatus
);
6127 case NEON_2RM_VCEQ0_F
:
6129 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6130 tmp2
= tcg_const_i32(0);
6131 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6132 tcg_temp_free_i32(tmp2
);
6133 tcg_temp_free_ptr(fpstatus
);
6136 case NEON_2RM_VCLE0_F
:
6138 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6139 tmp2
= tcg_const_i32(0);
6140 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6141 tcg_temp_free_i32(tmp2
);
6142 tcg_temp_free_ptr(fpstatus
);
6145 case NEON_2RM_VCLT0_F
:
6147 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6148 tmp2
= tcg_const_i32(0);
6149 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6150 tcg_temp_free_i32(tmp2
);
6151 tcg_temp_free_ptr(fpstatus
);
6154 case NEON_2RM_VABS_F
:
6157 case NEON_2RM_VNEG_F
:
6161 tmp2
= neon_load_reg(rd
, pass
);
6162 neon_store_reg(rm
, pass
, tmp2
);
6165 tmp2
= neon_load_reg(rd
, pass
);
6167 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6168 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6171 neon_store_reg(rm
, pass
, tmp2
);
6173 case NEON_2RM_VRECPE
:
6174 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6176 case NEON_2RM_VRSQRTE
:
6177 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6179 case NEON_2RM_VRECPE_F
:
6180 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6182 case NEON_2RM_VRSQRTE_F
:
6183 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6185 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6188 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6191 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6192 gen_vfp_tosiz(0, 1);
6194 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6195 gen_vfp_touiz(0, 1);
6198 /* Reserved op values were caught by the
6199 * neon_2rm_sizes[] check earlier.
6203 if (neon_2rm_is_float_op(op
)) {
6204 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6205 neon_reg_offset(rd
, pass
));
6207 neon_store_reg(rd
, pass
, tmp
);
6212 } else if ((insn
& (1 << 10)) == 0) {
6214 int n
= ((insn
>> 8) & 3) + 1;
6215 if ((rn
+ n
) > 32) {
6216 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6217 * helper function running off the end of the register file.
6222 if (insn
& (1 << 6)) {
6223 tmp
= neon_load_reg(rd
, 0);
6225 tmp
= tcg_temp_new_i32();
6226 tcg_gen_movi_i32(tmp
, 0);
6228 tmp2
= neon_load_reg(rm
, 0);
6229 tmp4
= tcg_const_i32(rn
);
6230 tmp5
= tcg_const_i32(n
);
6231 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6232 tcg_temp_free_i32(tmp
);
6233 if (insn
& (1 << 6)) {
6234 tmp
= neon_load_reg(rd
, 1);
6236 tmp
= tcg_temp_new_i32();
6237 tcg_gen_movi_i32(tmp
, 0);
6239 tmp3
= neon_load_reg(rm
, 1);
6240 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6241 tcg_temp_free_i32(tmp5
);
6242 tcg_temp_free_i32(tmp4
);
6243 neon_store_reg(rd
, 0, tmp2
);
6244 neon_store_reg(rd
, 1, tmp3
);
6245 tcg_temp_free_i32(tmp
);
6246 } else if ((insn
& 0x380) == 0) {
6248 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6251 if (insn
& (1 << 19)) {
6252 tmp
= neon_load_reg(rm
, 1);
6254 tmp
= neon_load_reg(rm
, 0);
6256 if (insn
& (1 << 16)) {
6257 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6258 } else if (insn
& (1 << 17)) {
6259 if ((insn
>> 18) & 1)
6260 gen_neon_dup_high16(tmp
);
6262 gen_neon_dup_low16(tmp
);
6264 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6265 tmp2
= tcg_temp_new_i32();
6266 tcg_gen_mov_i32(tmp2
, tmp
);
6267 neon_store_reg(rd
, pass
, tmp2
);
6269 tcg_temp_free_i32(tmp
);
6278 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6280 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6281 const ARMCPRegInfo
*ri
;
6282 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6284 cpnum
= (insn
>> 8) & 0xf;
6285 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6286 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6289 /* First check for coprocessor space used for actual instructions */
6293 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6294 return disas_iwmmxt_insn(env
, s
, insn
);
6295 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6296 return disas_dsp_insn(env
, s
, insn
);
6301 return disas_vfp_insn (env
, s
, insn
);
6306 /* Otherwise treat as a generic register access */
6307 is64
= (insn
& (1 << 25)) == 0;
6308 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6316 opc1
= (insn
>> 4) & 0xf;
6318 rt2
= (insn
>> 16) & 0xf;
6320 crn
= (insn
>> 16) & 0xf;
6321 opc1
= (insn
>> 21) & 7;
6322 opc2
= (insn
>> 5) & 7;
6325 isread
= (insn
>> 20) & 1;
6326 rt
= (insn
>> 12) & 0xf;
6328 ri
= get_arm_cp_reginfo(cpu
,
6329 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6331 /* Check access permissions */
6332 if (!cp_access_ok(env
, ri
, isread
)) {
6336 /* Handle special cases first */
6337 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6344 gen_set_pc_im(s
, s
->pc
);
6345 s
->is_jmp
= DISAS_WFI
;
6351 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6360 if (ri
->type
& ARM_CP_CONST
) {
6361 tmp64
= tcg_const_i64(ri
->resetvalue
);
6362 } else if (ri
->readfn
) {
6364 gen_set_pc_im(s
, s
->pc
);
6365 tmp64
= tcg_temp_new_i64();
6366 tmpptr
= tcg_const_ptr(ri
);
6367 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6368 tcg_temp_free_ptr(tmpptr
);
6370 tmp64
= tcg_temp_new_i64();
6371 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6373 tmp
= tcg_temp_new_i32();
6374 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6375 store_reg(s
, rt
, tmp
);
6376 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6377 tmp
= tcg_temp_new_i32();
6378 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6379 tcg_temp_free_i64(tmp64
);
6380 store_reg(s
, rt2
, tmp
);
6383 if (ri
->type
& ARM_CP_CONST
) {
6384 tmp
= tcg_const_i32(ri
->resetvalue
);
6385 } else if (ri
->readfn
) {
6387 gen_set_pc_im(s
, s
->pc
);
6388 tmp
= tcg_temp_new_i32();
6389 tmpptr
= tcg_const_ptr(ri
);
6390 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6391 tcg_temp_free_ptr(tmpptr
);
6393 tmp
= load_cpu_offset(ri
->fieldoffset
);
6396 /* Destination register of r15 for 32 bit loads sets
6397 * the condition codes from the high 4 bits of the value
6400 tcg_temp_free_i32(tmp
);
6402 store_reg(s
, rt
, tmp
);
6407 if (ri
->type
& ARM_CP_CONST
) {
6408 /* If not forbidden by access permissions, treat as WI */
6413 TCGv_i32 tmplo
, tmphi
;
6414 TCGv_i64 tmp64
= tcg_temp_new_i64();
6415 tmplo
= load_reg(s
, rt
);
6416 tmphi
= load_reg(s
, rt2
);
6417 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6418 tcg_temp_free_i32(tmplo
);
6419 tcg_temp_free_i32(tmphi
);
6421 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6422 gen_set_pc_im(s
, s
->pc
);
6423 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6424 tcg_temp_free_ptr(tmpptr
);
6426 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6428 tcg_temp_free_i64(tmp64
);
6433 gen_set_pc_im(s
, s
->pc
);
6434 tmp
= load_reg(s
, rt
);
6435 tmpptr
= tcg_const_ptr(ri
);
6436 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6437 tcg_temp_free_ptr(tmpptr
);
6438 tcg_temp_free_i32(tmp
);
6440 TCGv_i32 tmp
= load_reg(s
, rt
);
6441 store_cpu_offset(tmp
, ri
->fieldoffset
);
6446 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6447 /* I/O operations must end the TB here (whether read or write) */
6450 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6451 /* We default to ending the TB on a coprocessor register write,
6452 * but allow this to be suppressed by the register definition
6453 * (usually only necessary to work around guest bugs).
6465 /* Store a 64-bit value to a register pair. Clobbers val. */
6466 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6469 tmp
= tcg_temp_new_i32();
6470 tcg_gen_trunc_i64_i32(tmp
, val
);
6471 store_reg(s
, rlow
, tmp
);
6472 tmp
= tcg_temp_new_i32();
6473 tcg_gen_shri_i64(val
, val
, 32);
6474 tcg_gen_trunc_i64_i32(tmp
, val
);
6475 store_reg(s
, rhigh
, tmp
);
6478 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6479 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6484 /* Load value and extend to 64 bits. */
6485 tmp
= tcg_temp_new_i64();
6486 tmp2
= load_reg(s
, rlow
);
6487 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6488 tcg_temp_free_i32(tmp2
);
6489 tcg_gen_add_i64(val
, val
, tmp
);
6490 tcg_temp_free_i64(tmp
);
6493 /* load and add a 64-bit value from a register pair. */
6494 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6500 /* Load 64-bit value rd:rn. */
6501 tmpl
= load_reg(s
, rlow
);
6502 tmph
= load_reg(s
, rhigh
);
6503 tmp
= tcg_temp_new_i64();
6504 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6505 tcg_temp_free_i32(tmpl
);
6506 tcg_temp_free_i32(tmph
);
6507 tcg_gen_add_i64(val
, val
, tmp
);
6508 tcg_temp_free_i64(tmp
);
6511 /* Set N and Z flags from hi|lo. */
6512 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6514 tcg_gen_mov_i32(cpu_NF
, hi
);
6515 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6518 /* Load/Store exclusive instructions are implemented by remembering
6519 the value/address loaded, and seeing if these are the same
6520 when the store is performed. This should be sufficient to implement
6521 the architecturally mandated semantics, and avoids having to monitor
6524 In system emulation mode only one CPU will be running at once, so
6525 this sequence is effectively atomic. In user emulation mode we
6526 throw an exception and handle the atomic operation elsewhere. */
6527 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6528 TCGv_i32 addr
, int size
)
6530 TCGv_i32 tmp
= tcg_temp_new_i32();
6534 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6537 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6541 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6546 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6547 store_reg(s
, rt
, tmp
);
6549 TCGv_i32 tmp2
= tcg_temp_new_i32();
6550 tcg_gen_addi_i32(tmp2
, addr
, 4);
6551 tmp
= tcg_temp_new_i32();
6552 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6553 tcg_temp_free_i32(tmp2
);
6554 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6555 store_reg(s
, rt2
, tmp
);
6557 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6560 static void gen_clrex(DisasContext
*s
)
6562 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6565 #ifdef CONFIG_USER_ONLY
6566 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6567 TCGv_i32 addr
, int size
)
6569 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6570 tcg_gen_movi_i32(cpu_exclusive_info
,
6571 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6572 gen_exception_insn(s
, 4, EXCP_STREX
);
6575 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6576 TCGv_i32 addr
, int size
)
6582 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6588 fail_label
= gen_new_label();
6589 done_label
= gen_new_label();
6590 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6591 tmp
= tcg_temp_new_i32();
6594 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6597 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6601 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6606 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6607 tcg_temp_free_i32(tmp
);
6609 TCGv_i32 tmp2
= tcg_temp_new_i32();
6610 tcg_gen_addi_i32(tmp2
, addr
, 4);
6611 tmp
= tcg_temp_new_i32();
6612 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6613 tcg_temp_free_i32(tmp2
);
6614 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6615 tcg_temp_free_i32(tmp
);
6617 tmp
= load_reg(s
, rt
);
6620 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
6623 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
6627 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6632 tcg_temp_free_i32(tmp
);
6634 tcg_gen_addi_i32(addr
, addr
, 4);
6635 tmp
= load_reg(s
, rt2
);
6636 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6637 tcg_temp_free_i32(tmp
);
6639 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6640 tcg_gen_br(done_label
);
6641 gen_set_label(fail_label
);
6642 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6643 gen_set_label(done_label
);
6644 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6651 * @mode: mode field from insn (which stack to store to)
6652 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6653 * @writeback: true if writeback bit set
6655 * Generate code for the SRS (Store Return State) insn.
6657 static void gen_srs(DisasContext
*s
,
6658 uint32_t mode
, uint32_t amode
, bool writeback
)
6661 TCGv_i32 addr
= tcg_temp_new_i32();
6662 TCGv_i32 tmp
= tcg_const_i32(mode
);
6663 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6664 tcg_temp_free_i32(tmp
);
6681 tcg_gen_addi_i32(addr
, addr
, offset
);
6682 tmp
= load_reg(s
, 14);
6683 gen_aa32_st32(tmp
, addr
, 0);
6684 tcg_temp_free_i32(tmp
);
6685 tmp
= load_cpu_field(spsr
);
6686 tcg_gen_addi_i32(addr
, addr
, 4);
6687 gen_aa32_st32(tmp
, addr
, 0);
6688 tcg_temp_free_i32(tmp
);
6706 tcg_gen_addi_i32(addr
, addr
, offset
);
6707 tmp
= tcg_const_i32(mode
);
6708 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6709 tcg_temp_free_i32(tmp
);
6711 tcg_temp_free_i32(addr
);
6714 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6716 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6723 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6726 /* M variants do not implement ARM mode. */
6731 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6732 * choose to UNDEF. In ARMv5 and above the space is used
6733 * for miscellaneous unconditional instructions.
6737 /* Unconditional instructions. */
6738 if (((insn
>> 25) & 7) == 1) {
6739 /* NEON Data processing. */
6740 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6743 if (disas_neon_data_insn(env
, s
, insn
))
6747 if ((insn
& 0x0f100000) == 0x04000000) {
6748 /* NEON load/store. */
6749 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6752 if (disas_neon_ls_insn(env
, s
, insn
))
6756 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6757 ((insn
& 0x0f30f010) == 0x0710f000)) {
6758 if ((insn
& (1 << 22)) == 0) {
6760 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6764 /* Otherwise PLD; v5TE+ */
6768 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6769 ((insn
& 0x0f70f010) == 0x0650f000)) {
6771 return; /* PLI; V7 */
6773 if (((insn
& 0x0f700000) == 0x04100000) ||
6774 ((insn
& 0x0f700010) == 0x06100000)) {
6775 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6778 return; /* v7MP: Unallocated memory hint: must NOP */
6781 if ((insn
& 0x0ffffdff) == 0x01010000) {
6784 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6785 /* Dynamic endianness switching not implemented. */
6786 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
6790 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6791 switch ((insn
>> 4) & 0xf) {
6800 /* We don't emulate caches so these are a no-op. */
6805 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6811 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
6813 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6819 rn
= (insn
>> 16) & 0xf;
6820 addr
= load_reg(s
, rn
);
6821 i
= (insn
>> 23) & 3;
6823 case 0: offset
= -4; break; /* DA */
6824 case 1: offset
= 0; break; /* IA */
6825 case 2: offset
= -8; break; /* DB */
6826 case 3: offset
= 4; break; /* IB */
6830 tcg_gen_addi_i32(addr
, addr
, offset
);
6831 /* Load PC into tmp and CPSR into tmp2. */
6832 tmp
= tcg_temp_new_i32();
6833 gen_aa32_ld32u(tmp
, addr
, 0);
6834 tcg_gen_addi_i32(addr
, addr
, 4);
6835 tmp2
= tcg_temp_new_i32();
6836 gen_aa32_ld32u(tmp2
, addr
, 0);
6837 if (insn
& (1 << 21)) {
6838 /* Base writeback. */
6840 case 0: offset
= -8; break;
6841 case 1: offset
= 4; break;
6842 case 2: offset
= -4; break;
6843 case 3: offset
= 0; break;
6847 tcg_gen_addi_i32(addr
, addr
, offset
);
6848 store_reg(s
, rn
, addr
);
6850 tcg_temp_free_i32(addr
);
6852 gen_rfe(s
, tmp
, tmp2
);
6854 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6855 /* branch link and change to thumb (blx <offset>) */
6858 val
= (uint32_t)s
->pc
;
6859 tmp
= tcg_temp_new_i32();
6860 tcg_gen_movi_i32(tmp
, val
);
6861 store_reg(s
, 14, tmp
);
6862 /* Sign-extend the 24-bit offset */
6863 offset
= (((int32_t)insn
) << 8) >> 8;
6864 /* offset * 4 + bit24 * 2 + (thumb bit) */
6865 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6866 /* pipeline offset */
6868 /* protected by ARCH(5); above, near the start of uncond block */
6871 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6872 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6873 /* iWMMXt register transfer. */
6874 if (env
->cp15
.c15_cpar
& (1 << 1))
6875 if (!disas_iwmmxt_insn(env
, s
, insn
))
6878 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6879 /* Coprocessor double register transfer. */
6881 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6882 /* Additional coprocessor register transfer. */
6883 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6886 /* cps (privileged) */
6890 if (insn
& (1 << 19)) {
6891 if (insn
& (1 << 8))
6893 if (insn
& (1 << 7))
6895 if (insn
& (1 << 6))
6897 if (insn
& (1 << 18))
6900 if (insn
& (1 << 17)) {
6902 val
|= (insn
& 0x1f);
6905 gen_set_psr_im(s
, mask
, 0, val
);
6912 /* if not always execute, we generate a conditional jump to
6914 s
->condlabel
= gen_new_label();
6915 gen_test_cc(cond
^ 1, s
->condlabel
);
6918 if ((insn
& 0x0f900000) == 0x03000000) {
6919 if ((insn
& (1 << 21)) == 0) {
6921 rd
= (insn
>> 12) & 0xf;
6922 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6923 if ((insn
& (1 << 22)) == 0) {
6925 tmp
= tcg_temp_new_i32();
6926 tcg_gen_movi_i32(tmp
, val
);
6929 tmp
= load_reg(s
, rd
);
6930 tcg_gen_ext16u_i32(tmp
, tmp
);
6931 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6933 store_reg(s
, rd
, tmp
);
6935 if (((insn
>> 12) & 0xf) != 0xf)
6937 if (((insn
>> 16) & 0xf) == 0) {
6938 gen_nop_hint(s
, insn
& 0xff);
6940 /* CPSR = immediate */
6942 shift
= ((insn
>> 8) & 0xf) * 2;
6944 val
= (val
>> shift
) | (val
<< (32 - shift
));
6945 i
= ((insn
& (1 << 22)) != 0);
6946 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6950 } else if ((insn
& 0x0f900000) == 0x01000000
6951 && (insn
& 0x00000090) != 0x00000090) {
6952 /* miscellaneous instructions */
6953 op1
= (insn
>> 21) & 3;
6954 sh
= (insn
>> 4) & 0xf;
6957 case 0x0: /* move program status register */
6960 tmp
= load_reg(s
, rm
);
6961 i
= ((op1
& 2) != 0);
6962 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6966 rd
= (insn
>> 12) & 0xf;
6970 tmp
= load_cpu_field(spsr
);
6972 tmp
= tcg_temp_new_i32();
6973 gen_helper_cpsr_read(tmp
, cpu_env
);
6975 store_reg(s
, rd
, tmp
);
6980 /* branch/exchange thumb (bx). */
6982 tmp
= load_reg(s
, rm
);
6984 } else if (op1
== 3) {
6987 rd
= (insn
>> 12) & 0xf;
6988 tmp
= load_reg(s
, rm
);
6989 gen_helper_clz(tmp
, tmp
);
6990 store_reg(s
, rd
, tmp
);
6998 /* Trivial implementation equivalent to bx. */
6999 tmp
= load_reg(s
, rm
);
7010 /* branch link/exchange thumb (blx) */
7011 tmp
= load_reg(s
, rm
);
7012 tmp2
= tcg_temp_new_i32();
7013 tcg_gen_movi_i32(tmp2
, s
->pc
);
7014 store_reg(s
, 14, tmp2
);
7017 case 0x5: /* saturating add/subtract */
7019 rd
= (insn
>> 12) & 0xf;
7020 rn
= (insn
>> 16) & 0xf;
7021 tmp
= load_reg(s
, rm
);
7022 tmp2
= load_reg(s
, rn
);
7024 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7026 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7028 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7029 tcg_temp_free_i32(tmp2
);
7030 store_reg(s
, rd
, tmp
);
7033 /* SMC instruction (op1 == 3)
7034 and undefined instructions (op1 == 0 || op1 == 2)
7041 gen_exception_insn(s
, 4, EXCP_BKPT
);
7043 case 0x8: /* signed multiply */
7048 rs
= (insn
>> 8) & 0xf;
7049 rn
= (insn
>> 12) & 0xf;
7050 rd
= (insn
>> 16) & 0xf;
7052 /* (32 * 16) >> 16 */
7053 tmp
= load_reg(s
, rm
);
7054 tmp2
= load_reg(s
, rs
);
7056 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7059 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7060 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7061 tmp
= tcg_temp_new_i32();
7062 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7063 tcg_temp_free_i64(tmp64
);
7064 if ((sh
& 2) == 0) {
7065 tmp2
= load_reg(s
, rn
);
7066 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7067 tcg_temp_free_i32(tmp2
);
7069 store_reg(s
, rd
, tmp
);
7072 tmp
= load_reg(s
, rm
);
7073 tmp2
= load_reg(s
, rs
);
7074 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7075 tcg_temp_free_i32(tmp2
);
7077 tmp64
= tcg_temp_new_i64();
7078 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7079 tcg_temp_free_i32(tmp
);
7080 gen_addq(s
, tmp64
, rn
, rd
);
7081 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7082 tcg_temp_free_i64(tmp64
);
7085 tmp2
= load_reg(s
, rn
);
7086 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7087 tcg_temp_free_i32(tmp2
);
7089 store_reg(s
, rd
, tmp
);
7096 } else if (((insn
& 0x0e000000) == 0 &&
7097 (insn
& 0x00000090) != 0x90) ||
7098 ((insn
& 0x0e000000) == (1 << 25))) {
7099 int set_cc
, logic_cc
, shiftop
;
7101 op1
= (insn
>> 21) & 0xf;
7102 set_cc
= (insn
>> 20) & 1;
7103 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7105 /* data processing instruction */
7106 if (insn
& (1 << 25)) {
7107 /* immediate operand */
7109 shift
= ((insn
>> 8) & 0xf) * 2;
7111 val
= (val
>> shift
) | (val
<< (32 - shift
));
7113 tmp2
= tcg_temp_new_i32();
7114 tcg_gen_movi_i32(tmp2
, val
);
7115 if (logic_cc
&& shift
) {
7116 gen_set_CF_bit31(tmp2
);
7121 tmp2
= load_reg(s
, rm
);
7122 shiftop
= (insn
>> 5) & 3;
7123 if (!(insn
& (1 << 4))) {
7124 shift
= (insn
>> 7) & 0x1f;
7125 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7127 rs
= (insn
>> 8) & 0xf;
7128 tmp
= load_reg(s
, rs
);
7129 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7132 if (op1
!= 0x0f && op1
!= 0x0d) {
7133 rn
= (insn
>> 16) & 0xf;
7134 tmp
= load_reg(s
, rn
);
7136 TCGV_UNUSED_I32(tmp
);
7138 rd
= (insn
>> 12) & 0xf;
7141 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7145 store_reg_bx(env
, s
, rd
, tmp
);
7148 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7152 store_reg_bx(env
, s
, rd
, tmp
);
7155 if (set_cc
&& rd
== 15) {
7156 /* SUBS r15, ... is used for exception return. */
7160 gen_sub_CC(tmp
, tmp
, tmp2
);
7161 gen_exception_return(s
, tmp
);
7164 gen_sub_CC(tmp
, tmp
, tmp2
);
7166 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7168 store_reg_bx(env
, s
, rd
, tmp
);
7173 gen_sub_CC(tmp
, tmp2
, tmp
);
7175 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7177 store_reg_bx(env
, s
, rd
, tmp
);
7181 gen_add_CC(tmp
, tmp
, tmp2
);
7183 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7185 store_reg_bx(env
, s
, rd
, tmp
);
7189 gen_adc_CC(tmp
, tmp
, tmp2
);
7191 gen_add_carry(tmp
, tmp
, tmp2
);
7193 store_reg_bx(env
, s
, rd
, tmp
);
7197 gen_sbc_CC(tmp
, tmp
, tmp2
);
7199 gen_sub_carry(tmp
, tmp
, tmp2
);
7201 store_reg_bx(env
, s
, rd
, tmp
);
7205 gen_sbc_CC(tmp
, tmp2
, tmp
);
7207 gen_sub_carry(tmp
, tmp2
, tmp
);
7209 store_reg_bx(env
, s
, rd
, tmp
);
7213 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7216 tcg_temp_free_i32(tmp
);
7220 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7223 tcg_temp_free_i32(tmp
);
7227 gen_sub_CC(tmp
, tmp
, tmp2
);
7229 tcg_temp_free_i32(tmp
);
7233 gen_add_CC(tmp
, tmp
, tmp2
);
7235 tcg_temp_free_i32(tmp
);
7238 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7242 store_reg_bx(env
, s
, rd
, tmp
);
7245 if (logic_cc
&& rd
== 15) {
7246 /* MOVS r15, ... is used for exception return. */
7250 gen_exception_return(s
, tmp2
);
7255 store_reg_bx(env
, s
, rd
, tmp2
);
7259 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7263 store_reg_bx(env
, s
, rd
, tmp
);
7267 tcg_gen_not_i32(tmp2
, tmp2
);
7271 store_reg_bx(env
, s
, rd
, tmp2
);
7274 if (op1
!= 0x0f && op1
!= 0x0d) {
7275 tcg_temp_free_i32(tmp2
);
7278 /* other instructions */
7279 op1
= (insn
>> 24) & 0xf;
7283 /* multiplies, extra load/stores */
7284 sh
= (insn
>> 5) & 3;
7287 rd
= (insn
>> 16) & 0xf;
7288 rn
= (insn
>> 12) & 0xf;
7289 rs
= (insn
>> 8) & 0xf;
7291 op1
= (insn
>> 20) & 0xf;
7293 case 0: case 1: case 2: case 3: case 6:
7295 tmp
= load_reg(s
, rs
);
7296 tmp2
= load_reg(s
, rm
);
7297 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7298 tcg_temp_free_i32(tmp2
);
7299 if (insn
& (1 << 22)) {
7300 /* Subtract (mls) */
7302 tmp2
= load_reg(s
, rn
);
7303 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7304 tcg_temp_free_i32(tmp2
);
7305 } else if (insn
& (1 << 21)) {
7307 tmp2
= load_reg(s
, rn
);
7308 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7309 tcg_temp_free_i32(tmp2
);
7311 if (insn
& (1 << 20))
7313 store_reg(s
, rd
, tmp
);
7316 /* 64 bit mul double accumulate (UMAAL) */
7318 tmp
= load_reg(s
, rs
);
7319 tmp2
= load_reg(s
, rm
);
7320 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7321 gen_addq_lo(s
, tmp64
, rn
);
7322 gen_addq_lo(s
, tmp64
, rd
);
7323 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7324 tcg_temp_free_i64(tmp64
);
7326 case 8: case 9: case 10: case 11:
7327 case 12: case 13: case 14: case 15:
7328 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7329 tmp
= load_reg(s
, rs
);
7330 tmp2
= load_reg(s
, rm
);
7331 if (insn
& (1 << 22)) {
7332 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7334 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7336 if (insn
& (1 << 21)) { /* mult accumulate */
7337 TCGv_i32 al
= load_reg(s
, rn
);
7338 TCGv_i32 ah
= load_reg(s
, rd
);
7339 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7340 tcg_temp_free_i32(al
);
7341 tcg_temp_free_i32(ah
);
7343 if (insn
& (1 << 20)) {
7344 gen_logicq_cc(tmp
, tmp2
);
7346 store_reg(s
, rn
, tmp
);
7347 store_reg(s
, rd
, tmp2
);
7353 rn
= (insn
>> 16) & 0xf;
7354 rd
= (insn
>> 12) & 0xf;
7355 if (insn
& (1 << 23)) {
7356 /* load/store exclusive */
7357 int op2
= (insn
>> 8) & 3;
7358 op1
= (insn
>> 21) & 0x3;
7361 case 0: /* lda/stl */
7367 case 1: /* reserved */
7369 case 2: /* ldaex/stlex */
7372 case 3: /* ldrex/strex */
7381 addr
= tcg_temp_local_new_i32();
7382 load_reg_var(s
, addr
, rn
);
7384 /* Since the emulation does not have barriers,
7385 the acquire/release semantics need no special
7388 if (insn
& (1 << 20)) {
7389 tmp
= tcg_temp_new_i32();
7392 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7395 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7398 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7403 store_reg(s
, rd
, tmp
);
7406 tmp
= load_reg(s
, rm
);
7409 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7412 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7415 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7420 tcg_temp_free_i32(tmp
);
7422 } else if (insn
& (1 << 20)) {
7425 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7427 case 1: /* ldrexd */
7428 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7430 case 2: /* ldrexb */
7431 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7433 case 3: /* ldrexh */
7434 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7443 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7445 case 1: /* strexd */
7446 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7448 case 2: /* strexb */
7449 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7451 case 3: /* strexh */
7452 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7458 tcg_temp_free_i32(addr
);
7460 /* SWP instruction */
7463 /* ??? This is not really atomic. However we know
7464 we never have multiple CPUs running in parallel,
7465 so it is good enough. */
7466 addr
= load_reg(s
, rn
);
7467 tmp
= load_reg(s
, rm
);
7468 tmp2
= tcg_temp_new_i32();
7469 if (insn
& (1 << 22)) {
7470 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7471 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7473 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7474 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7476 tcg_temp_free_i32(tmp
);
7477 tcg_temp_free_i32(addr
);
7478 store_reg(s
, rd
, tmp2
);
7484 /* Misc load/store */
7485 rn
= (insn
>> 16) & 0xf;
7486 rd
= (insn
>> 12) & 0xf;
7487 addr
= load_reg(s
, rn
);
7488 if (insn
& (1 << 24))
7489 gen_add_datah_offset(s
, insn
, 0, addr
);
7491 if (insn
& (1 << 20)) {
7493 tmp
= tcg_temp_new_i32();
7496 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7499 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7503 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7507 } else if (sh
& 2) {
7512 tmp
= load_reg(s
, rd
);
7513 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7514 tcg_temp_free_i32(tmp
);
7515 tcg_gen_addi_i32(addr
, addr
, 4);
7516 tmp
= load_reg(s
, rd
+ 1);
7517 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7518 tcg_temp_free_i32(tmp
);
7522 tmp
= tcg_temp_new_i32();
7523 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7524 store_reg(s
, rd
, tmp
);
7525 tcg_gen_addi_i32(addr
, addr
, 4);
7526 tmp
= tcg_temp_new_i32();
7527 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7531 address_offset
= -4;
7534 tmp
= load_reg(s
, rd
);
7535 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7536 tcg_temp_free_i32(tmp
);
7539 /* Perform base writeback before the loaded value to
7540 ensure correct behavior with overlapping index registers.
7541 ldrd with base writeback is is undefined if the
7542 destination and index registers overlap. */
7543 if (!(insn
& (1 << 24))) {
7544 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7545 store_reg(s
, rn
, addr
);
7546 } else if (insn
& (1 << 21)) {
7548 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7549 store_reg(s
, rn
, addr
);
7551 tcg_temp_free_i32(addr
);
7554 /* Complete the load. */
7555 store_reg(s
, rd
, tmp
);
7564 if (insn
& (1 << 4)) {
7566 /* Armv6 Media instructions. */
7568 rn
= (insn
>> 16) & 0xf;
7569 rd
= (insn
>> 12) & 0xf;
7570 rs
= (insn
>> 8) & 0xf;
7571 switch ((insn
>> 23) & 3) {
7572 case 0: /* Parallel add/subtract. */
7573 op1
= (insn
>> 20) & 7;
7574 tmp
= load_reg(s
, rn
);
7575 tmp2
= load_reg(s
, rm
);
7576 sh
= (insn
>> 5) & 7;
7577 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7579 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7580 tcg_temp_free_i32(tmp2
);
7581 store_reg(s
, rd
, tmp
);
7584 if ((insn
& 0x00700020) == 0) {
7585 /* Halfword pack. */
7586 tmp
= load_reg(s
, rn
);
7587 tmp2
= load_reg(s
, rm
);
7588 shift
= (insn
>> 7) & 0x1f;
7589 if (insn
& (1 << 6)) {
7593 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7594 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7595 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7599 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7600 tcg_gen_ext16u_i32(tmp
, tmp
);
7601 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7603 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7604 tcg_temp_free_i32(tmp2
);
7605 store_reg(s
, rd
, tmp
);
7606 } else if ((insn
& 0x00200020) == 0x00200000) {
7608 tmp
= load_reg(s
, rm
);
7609 shift
= (insn
>> 7) & 0x1f;
7610 if (insn
& (1 << 6)) {
7613 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7615 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7617 sh
= (insn
>> 16) & 0x1f;
7618 tmp2
= tcg_const_i32(sh
);
7619 if (insn
& (1 << 22))
7620 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7622 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7623 tcg_temp_free_i32(tmp2
);
7624 store_reg(s
, rd
, tmp
);
7625 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7627 tmp
= load_reg(s
, rm
);
7628 sh
= (insn
>> 16) & 0x1f;
7629 tmp2
= tcg_const_i32(sh
);
7630 if (insn
& (1 << 22))
7631 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7633 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7634 tcg_temp_free_i32(tmp2
);
7635 store_reg(s
, rd
, tmp
);
7636 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7638 tmp
= load_reg(s
, rn
);
7639 tmp2
= load_reg(s
, rm
);
7640 tmp3
= tcg_temp_new_i32();
7641 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7642 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7643 tcg_temp_free_i32(tmp3
);
7644 tcg_temp_free_i32(tmp2
);
7645 store_reg(s
, rd
, tmp
);
7646 } else if ((insn
& 0x000003e0) == 0x00000060) {
7647 tmp
= load_reg(s
, rm
);
7648 shift
= (insn
>> 10) & 3;
7649 /* ??? In many cases it's not necessary to do a
7650 rotate, a shift is sufficient. */
7652 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7653 op1
= (insn
>> 20) & 7;
7655 case 0: gen_sxtb16(tmp
); break;
7656 case 2: gen_sxtb(tmp
); break;
7657 case 3: gen_sxth(tmp
); break;
7658 case 4: gen_uxtb16(tmp
); break;
7659 case 6: gen_uxtb(tmp
); break;
7660 case 7: gen_uxth(tmp
); break;
7661 default: goto illegal_op
;
7664 tmp2
= load_reg(s
, rn
);
7665 if ((op1
& 3) == 0) {
7666 gen_add16(tmp
, tmp2
);
7668 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7669 tcg_temp_free_i32(tmp2
);
7672 store_reg(s
, rd
, tmp
);
7673 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7675 tmp
= load_reg(s
, rm
);
7676 if (insn
& (1 << 22)) {
7677 if (insn
& (1 << 7)) {
7681 gen_helper_rbit(tmp
, tmp
);
7684 if (insn
& (1 << 7))
7687 tcg_gen_bswap32_i32(tmp
, tmp
);
7689 store_reg(s
, rd
, tmp
);
7694 case 2: /* Multiplies (Type 3). */
7695 switch ((insn
>> 20) & 0x7) {
7697 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7698 /* op2 not 00x or 11x : UNDEF */
7701 /* Signed multiply most significant [accumulate].
7702 (SMMUL, SMMLA, SMMLS) */
7703 tmp
= load_reg(s
, rm
);
7704 tmp2
= load_reg(s
, rs
);
7705 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7708 tmp
= load_reg(s
, rd
);
7709 if (insn
& (1 << 6)) {
7710 tmp64
= gen_subq_msw(tmp64
, tmp
);
7712 tmp64
= gen_addq_msw(tmp64
, tmp
);
7715 if (insn
& (1 << 5)) {
7716 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7718 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7719 tmp
= tcg_temp_new_i32();
7720 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7721 tcg_temp_free_i64(tmp64
);
7722 store_reg(s
, rn
, tmp
);
7726 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7727 if (insn
& (1 << 7)) {
7730 tmp
= load_reg(s
, rm
);
7731 tmp2
= load_reg(s
, rs
);
7732 if (insn
& (1 << 5))
7733 gen_swap_half(tmp2
);
7734 gen_smul_dual(tmp
, tmp2
);
7735 if (insn
& (1 << 6)) {
7736 /* This subtraction cannot overflow. */
7737 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7739 /* This addition cannot overflow 32 bits;
7740 * however it may overflow considered as a signed
7741 * operation, in which case we must set the Q flag.
7743 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7745 tcg_temp_free_i32(tmp2
);
7746 if (insn
& (1 << 22)) {
7747 /* smlald, smlsld */
7748 tmp64
= tcg_temp_new_i64();
7749 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7750 tcg_temp_free_i32(tmp
);
7751 gen_addq(s
, tmp64
, rd
, rn
);
7752 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7753 tcg_temp_free_i64(tmp64
);
7755 /* smuad, smusd, smlad, smlsd */
7758 tmp2
= load_reg(s
, rd
);
7759 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7760 tcg_temp_free_i32(tmp2
);
7762 store_reg(s
, rn
, tmp
);
7768 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7771 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7774 tmp
= load_reg(s
, rm
);
7775 tmp2
= load_reg(s
, rs
);
7776 if (insn
& (1 << 21)) {
7777 gen_helper_udiv(tmp
, tmp
, tmp2
);
7779 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7781 tcg_temp_free_i32(tmp2
);
7782 store_reg(s
, rn
, tmp
);
7789 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7791 case 0: /* Unsigned sum of absolute differences. */
7793 tmp
= load_reg(s
, rm
);
7794 tmp2
= load_reg(s
, rs
);
7795 gen_helper_usad8(tmp
, tmp
, tmp2
);
7796 tcg_temp_free_i32(tmp2
);
7798 tmp2
= load_reg(s
, rd
);
7799 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7800 tcg_temp_free_i32(tmp2
);
7802 store_reg(s
, rn
, tmp
);
7804 case 0x20: case 0x24: case 0x28: case 0x2c:
7805 /* Bitfield insert/clear. */
7807 shift
= (insn
>> 7) & 0x1f;
7808 i
= (insn
>> 16) & 0x1f;
7811 tmp
= tcg_temp_new_i32();
7812 tcg_gen_movi_i32(tmp
, 0);
7814 tmp
= load_reg(s
, rm
);
7817 tmp2
= load_reg(s
, rd
);
7818 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7819 tcg_temp_free_i32(tmp2
);
7821 store_reg(s
, rd
, tmp
);
7823 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7824 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7826 tmp
= load_reg(s
, rm
);
7827 shift
= (insn
>> 7) & 0x1f;
7828 i
= ((insn
>> 16) & 0x1f) + 1;
7833 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7835 gen_sbfx(tmp
, shift
, i
);
7838 store_reg(s
, rd
, tmp
);
7848 /* Check for undefined extension instructions
7849 * per the ARM Bible IE:
7850 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7852 sh
= (0xf << 20) | (0xf << 4);
7853 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7857 /* load/store byte/word */
7858 rn
= (insn
>> 16) & 0xf;
7859 rd
= (insn
>> 12) & 0xf;
7860 tmp2
= load_reg(s
, rn
);
7861 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7862 if (insn
& (1 << 24))
7863 gen_add_data_offset(s
, insn
, tmp2
);
7864 if (insn
& (1 << 20)) {
7866 tmp
= tcg_temp_new_i32();
7867 if (insn
& (1 << 22)) {
7868 gen_aa32_ld8u(tmp
, tmp2
, i
);
7870 gen_aa32_ld32u(tmp
, tmp2
, i
);
7874 tmp
= load_reg(s
, rd
);
7875 if (insn
& (1 << 22)) {
7876 gen_aa32_st8(tmp
, tmp2
, i
);
7878 gen_aa32_st32(tmp
, tmp2
, i
);
7880 tcg_temp_free_i32(tmp
);
7882 if (!(insn
& (1 << 24))) {
7883 gen_add_data_offset(s
, insn
, tmp2
);
7884 store_reg(s
, rn
, tmp2
);
7885 } else if (insn
& (1 << 21)) {
7886 store_reg(s
, rn
, tmp2
);
7888 tcg_temp_free_i32(tmp2
);
7890 if (insn
& (1 << 20)) {
7891 /* Complete the load. */
7892 store_reg_from_load(env
, s
, rd
, tmp
);
7898 int j
, n
, user
, loaded_base
;
7899 TCGv_i32 loaded_var
;
7900 /* load/store multiple words */
7901 /* XXX: store correct base if write back */
7903 if (insn
& (1 << 22)) {
7905 goto illegal_op
; /* only usable in supervisor mode */
7907 if ((insn
& (1 << 15)) == 0)
7910 rn
= (insn
>> 16) & 0xf;
7911 addr
= load_reg(s
, rn
);
7913 /* compute total size */
7915 TCGV_UNUSED_I32(loaded_var
);
7918 if (insn
& (1 << i
))
7921 /* XXX: test invalid n == 0 case ? */
7922 if (insn
& (1 << 23)) {
7923 if (insn
& (1 << 24)) {
7925 tcg_gen_addi_i32(addr
, addr
, 4);
7927 /* post increment */
7930 if (insn
& (1 << 24)) {
7932 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7934 /* post decrement */
7936 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7941 if (insn
& (1 << i
)) {
7942 if (insn
& (1 << 20)) {
7944 tmp
= tcg_temp_new_i32();
7945 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7947 tmp2
= tcg_const_i32(i
);
7948 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7949 tcg_temp_free_i32(tmp2
);
7950 tcg_temp_free_i32(tmp
);
7951 } else if (i
== rn
) {
7955 store_reg_from_load(env
, s
, i
, tmp
);
7960 /* special case: r15 = PC + 8 */
7961 val
= (long)s
->pc
+ 4;
7962 tmp
= tcg_temp_new_i32();
7963 tcg_gen_movi_i32(tmp
, val
);
7965 tmp
= tcg_temp_new_i32();
7966 tmp2
= tcg_const_i32(i
);
7967 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7968 tcg_temp_free_i32(tmp2
);
7970 tmp
= load_reg(s
, i
);
7972 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7973 tcg_temp_free_i32(tmp
);
7976 /* no need to add after the last transfer */
7978 tcg_gen_addi_i32(addr
, addr
, 4);
7981 if (insn
& (1 << 21)) {
7983 if (insn
& (1 << 23)) {
7984 if (insn
& (1 << 24)) {
7987 /* post increment */
7988 tcg_gen_addi_i32(addr
, addr
, 4);
7991 if (insn
& (1 << 24)) {
7994 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7996 /* post decrement */
7997 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8000 store_reg(s
, rn
, addr
);
8002 tcg_temp_free_i32(addr
);
8005 store_reg(s
, rn
, loaded_var
);
8007 if ((insn
& (1 << 22)) && !user
) {
8008 /* Restore CPSR from SPSR. */
8009 tmp
= load_cpu_field(spsr
);
8010 gen_set_cpsr(tmp
, 0xffffffff);
8011 tcg_temp_free_i32(tmp
);
8012 s
->is_jmp
= DISAS_UPDATE
;
8021 /* branch (and link) */
8022 val
= (int32_t)s
->pc
;
8023 if (insn
& (1 << 24)) {
8024 tmp
= tcg_temp_new_i32();
8025 tcg_gen_movi_i32(tmp
, val
);
8026 store_reg(s
, 14, tmp
);
8028 offset
= sextract32(insn
<< 2, 0, 26);
8037 if (disas_coproc_insn(env
, s
, insn
))
8042 gen_set_pc_im(s
, s
->pc
);
8043 s
->is_jmp
= DISAS_SWI
;
8047 gen_exception_insn(s
, 4, EXCP_UDEF
);
8053 /* Return true if this is a Thumb-2 logical op. */
8055 thumb2_logic_op(int op
)
8060 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8061 then set condition code flags based on the result of the operation.
8062 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8063 to the high bit of T1.
8064 Returns zero if the opcode is valid. */
8067 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8068 TCGv_i32 t0
, TCGv_i32 t1
)
8075 tcg_gen_and_i32(t0
, t0
, t1
);
8079 tcg_gen_andc_i32(t0
, t0
, t1
);
8083 tcg_gen_or_i32(t0
, t0
, t1
);
8087 tcg_gen_orc_i32(t0
, t0
, t1
);
8091 tcg_gen_xor_i32(t0
, t0
, t1
);
8096 gen_add_CC(t0
, t0
, t1
);
8098 tcg_gen_add_i32(t0
, t0
, t1
);
8102 gen_adc_CC(t0
, t0
, t1
);
8108 gen_sbc_CC(t0
, t0
, t1
);
8110 gen_sub_carry(t0
, t0
, t1
);
8115 gen_sub_CC(t0
, t0
, t1
);
8117 tcg_gen_sub_i32(t0
, t0
, t1
);
8121 gen_sub_CC(t0
, t1
, t0
);
8123 tcg_gen_sub_i32(t0
, t1
, t0
);
8125 default: /* 5, 6, 7, 9, 12, 15. */
8131 gen_set_CF_bit31(t1
);
8136 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8138 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8140 uint32_t insn
, imm
, shift
, offset
;
8141 uint32_t rd
, rn
, rm
, rs
;
8152 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8153 || arm_feature (env
, ARM_FEATURE_M
))) {
8154 /* Thumb-1 cores may need to treat bl and blx as a pair of
8155 16-bit instructions to get correct prefetch abort behavior. */
8157 if ((insn
& (1 << 12)) == 0) {
8159 /* Second half of blx. */
8160 offset
= ((insn
& 0x7ff) << 1);
8161 tmp
= load_reg(s
, 14);
8162 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8163 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8165 tmp2
= tcg_temp_new_i32();
8166 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8167 store_reg(s
, 14, tmp2
);
8171 if (insn
& (1 << 11)) {
8172 /* Second half of bl. */
8173 offset
= ((insn
& 0x7ff) << 1) | 1;
8174 tmp
= load_reg(s
, 14);
8175 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8177 tmp2
= tcg_temp_new_i32();
8178 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8179 store_reg(s
, 14, tmp2
);
8183 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8184 /* Instruction spans a page boundary. Implement it as two
8185 16-bit instructions in case the second half causes an
8187 offset
= ((int32_t)insn
<< 21) >> 9;
8188 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8191 /* Fall through to 32-bit decode. */
8194 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8196 insn
|= (uint32_t)insn_hw1
<< 16;
8198 if ((insn
& 0xf800e800) != 0xf000e800) {
8202 rn
= (insn
>> 16) & 0xf;
8203 rs
= (insn
>> 12) & 0xf;
8204 rd
= (insn
>> 8) & 0xf;
8206 switch ((insn
>> 25) & 0xf) {
8207 case 0: case 1: case 2: case 3:
8208 /* 16-bit instructions. Should never happen. */
8211 if (insn
& (1 << 22)) {
8212 /* Other load/store, table branch. */
8213 if (insn
& 0x01200000) {
8214 /* Load/store doubleword. */
8216 addr
= tcg_temp_new_i32();
8217 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8219 addr
= load_reg(s
, rn
);
8221 offset
= (insn
& 0xff) * 4;
8222 if ((insn
& (1 << 23)) == 0)
8224 if (insn
& (1 << 24)) {
8225 tcg_gen_addi_i32(addr
, addr
, offset
);
8228 if (insn
& (1 << 20)) {
8230 tmp
= tcg_temp_new_i32();
8231 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8232 store_reg(s
, rs
, tmp
);
8233 tcg_gen_addi_i32(addr
, addr
, 4);
8234 tmp
= tcg_temp_new_i32();
8235 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8236 store_reg(s
, rd
, tmp
);
8239 tmp
= load_reg(s
, rs
);
8240 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8241 tcg_temp_free_i32(tmp
);
8242 tcg_gen_addi_i32(addr
, addr
, 4);
8243 tmp
= load_reg(s
, rd
);
8244 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8245 tcg_temp_free_i32(tmp
);
8247 if (insn
& (1 << 21)) {
8248 /* Base writeback. */
8251 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8252 store_reg(s
, rn
, addr
);
8254 tcg_temp_free_i32(addr
);
8256 } else if ((insn
& (1 << 23)) == 0) {
8257 /* Load/store exclusive word. */
8258 addr
= tcg_temp_local_new_i32();
8259 load_reg_var(s
, addr
, rn
);
8260 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8261 if (insn
& (1 << 20)) {
8262 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8264 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8266 tcg_temp_free_i32(addr
);
8267 } else if ((insn
& (7 << 5)) == 0) {
8270 addr
= tcg_temp_new_i32();
8271 tcg_gen_movi_i32(addr
, s
->pc
);
8273 addr
= load_reg(s
, rn
);
8275 tmp
= load_reg(s
, rm
);
8276 tcg_gen_add_i32(addr
, addr
, tmp
);
8277 if (insn
& (1 << 4)) {
8279 tcg_gen_add_i32(addr
, addr
, tmp
);
8280 tcg_temp_free_i32(tmp
);
8281 tmp
= tcg_temp_new_i32();
8282 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8284 tcg_temp_free_i32(tmp
);
8285 tmp
= tcg_temp_new_i32();
8286 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8288 tcg_temp_free_i32(addr
);
8289 tcg_gen_shli_i32(tmp
, tmp
, 1);
8290 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8291 store_reg(s
, 15, tmp
);
8293 int op2
= (insn
>> 6) & 0x3;
8294 op
= (insn
>> 4) & 0x3;
8299 /* Load/store exclusive byte/halfword/doubleword */
8306 /* Load-acquire/store-release */
8312 /* Load-acquire/store-release exclusive */
8316 addr
= tcg_temp_local_new_i32();
8317 load_reg_var(s
, addr
, rn
);
8319 if (insn
& (1 << 20)) {
8320 tmp
= tcg_temp_new_i32();
8323 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8326 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8329 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8334 store_reg(s
, rs
, tmp
);
8336 tmp
= load_reg(s
, rs
);
8339 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8342 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8345 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8350 tcg_temp_free_i32(tmp
);
8352 } else if (insn
& (1 << 20)) {
8353 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8355 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8357 tcg_temp_free_i32(addr
);
8360 /* Load/store multiple, RFE, SRS. */
8361 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8362 /* RFE, SRS: not available in user mode or on M profile */
8363 if (IS_USER(s
) || IS_M(env
)) {
8366 if (insn
& (1 << 20)) {
8368 addr
= load_reg(s
, rn
);
8369 if ((insn
& (1 << 24)) == 0)
8370 tcg_gen_addi_i32(addr
, addr
, -8);
8371 /* Load PC into tmp and CPSR into tmp2. */
8372 tmp
= tcg_temp_new_i32();
8373 gen_aa32_ld32u(tmp
, addr
, 0);
8374 tcg_gen_addi_i32(addr
, addr
, 4);
8375 tmp2
= tcg_temp_new_i32();
8376 gen_aa32_ld32u(tmp2
, addr
, 0);
8377 if (insn
& (1 << 21)) {
8378 /* Base writeback. */
8379 if (insn
& (1 << 24)) {
8380 tcg_gen_addi_i32(addr
, addr
, 4);
8382 tcg_gen_addi_i32(addr
, addr
, -4);
8384 store_reg(s
, rn
, addr
);
8386 tcg_temp_free_i32(addr
);
8388 gen_rfe(s
, tmp
, tmp2
);
8391 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8395 int i
, loaded_base
= 0;
8396 TCGv_i32 loaded_var
;
8397 /* Load/store multiple. */
8398 addr
= load_reg(s
, rn
);
8400 for (i
= 0; i
< 16; i
++) {
8401 if (insn
& (1 << i
))
8404 if (insn
& (1 << 24)) {
8405 tcg_gen_addi_i32(addr
, addr
, -offset
);
8408 TCGV_UNUSED_I32(loaded_var
);
8409 for (i
= 0; i
< 16; i
++) {
8410 if ((insn
& (1 << i
)) == 0)
8412 if (insn
& (1 << 20)) {
8414 tmp
= tcg_temp_new_i32();
8415 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8418 } else if (i
== rn
) {
8422 store_reg(s
, i
, tmp
);
8426 tmp
= load_reg(s
, i
);
8427 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8428 tcg_temp_free_i32(tmp
);
8430 tcg_gen_addi_i32(addr
, addr
, 4);
8433 store_reg(s
, rn
, loaded_var
);
8435 if (insn
& (1 << 21)) {
8436 /* Base register writeback. */
8437 if (insn
& (1 << 24)) {
8438 tcg_gen_addi_i32(addr
, addr
, -offset
);
8440 /* Fault if writeback register is in register list. */
8441 if (insn
& (1 << rn
))
8443 store_reg(s
, rn
, addr
);
8445 tcg_temp_free_i32(addr
);
8452 op
= (insn
>> 21) & 0xf;
8454 /* Halfword pack. */
8455 tmp
= load_reg(s
, rn
);
8456 tmp2
= load_reg(s
, rm
);
8457 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8458 if (insn
& (1 << 5)) {
8462 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8463 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8464 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8468 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8469 tcg_gen_ext16u_i32(tmp
, tmp
);
8470 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8472 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8473 tcg_temp_free_i32(tmp2
);
8474 store_reg(s
, rd
, tmp
);
8476 /* Data processing register constant shift. */
8478 tmp
= tcg_temp_new_i32();
8479 tcg_gen_movi_i32(tmp
, 0);
8481 tmp
= load_reg(s
, rn
);
8483 tmp2
= load_reg(s
, rm
);
8485 shiftop
= (insn
>> 4) & 3;
8486 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8487 conds
= (insn
& (1 << 20)) != 0;
8488 logic_cc
= (conds
&& thumb2_logic_op(op
));
8489 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8490 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8492 tcg_temp_free_i32(tmp2
);
8494 store_reg(s
, rd
, tmp
);
8496 tcg_temp_free_i32(tmp
);
8500 case 13: /* Misc data processing. */
8501 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8502 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8505 case 0: /* Register controlled shift. */
8506 tmp
= load_reg(s
, rn
);
8507 tmp2
= load_reg(s
, rm
);
8508 if ((insn
& 0x70) != 0)
8510 op
= (insn
>> 21) & 3;
8511 logic_cc
= (insn
& (1 << 20)) != 0;
8512 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8515 store_reg_bx(env
, s
, rd
, tmp
);
8517 case 1: /* Sign/zero extend. */
8518 tmp
= load_reg(s
, rm
);
8519 shift
= (insn
>> 4) & 3;
8520 /* ??? In many cases it's not necessary to do a
8521 rotate, a shift is sufficient. */
8523 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8524 op
= (insn
>> 20) & 7;
8526 case 0: gen_sxth(tmp
); break;
8527 case 1: gen_uxth(tmp
); break;
8528 case 2: gen_sxtb16(tmp
); break;
8529 case 3: gen_uxtb16(tmp
); break;
8530 case 4: gen_sxtb(tmp
); break;
8531 case 5: gen_uxtb(tmp
); break;
8532 default: goto illegal_op
;
8535 tmp2
= load_reg(s
, rn
);
8536 if ((op
>> 1) == 1) {
8537 gen_add16(tmp
, tmp2
);
8539 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8540 tcg_temp_free_i32(tmp2
);
8543 store_reg(s
, rd
, tmp
);
8545 case 2: /* SIMD add/subtract. */
8546 op
= (insn
>> 20) & 7;
8547 shift
= (insn
>> 4) & 7;
8548 if ((op
& 3) == 3 || (shift
& 3) == 3)
8550 tmp
= load_reg(s
, rn
);
8551 tmp2
= load_reg(s
, rm
);
8552 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8553 tcg_temp_free_i32(tmp2
);
8554 store_reg(s
, rd
, tmp
);
8556 case 3: /* Other data processing. */
8557 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8559 /* Saturating add/subtract. */
8560 tmp
= load_reg(s
, rn
);
8561 tmp2
= load_reg(s
, rm
);
8563 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8565 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8567 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8568 tcg_temp_free_i32(tmp2
);
8570 tmp
= load_reg(s
, rn
);
8572 case 0x0a: /* rbit */
8573 gen_helper_rbit(tmp
, tmp
);
8575 case 0x08: /* rev */
8576 tcg_gen_bswap32_i32(tmp
, tmp
);
8578 case 0x09: /* rev16 */
8581 case 0x0b: /* revsh */
8584 case 0x10: /* sel */
8585 tmp2
= load_reg(s
, rm
);
8586 tmp3
= tcg_temp_new_i32();
8587 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8588 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8589 tcg_temp_free_i32(tmp3
);
8590 tcg_temp_free_i32(tmp2
);
8592 case 0x18: /* clz */
8593 gen_helper_clz(tmp
, tmp
);
8599 store_reg(s
, rd
, tmp
);
8601 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8602 op
= (insn
>> 4) & 0xf;
8603 tmp
= load_reg(s
, rn
);
8604 tmp2
= load_reg(s
, rm
);
8605 switch ((insn
>> 20) & 7) {
8606 case 0: /* 32 x 32 -> 32 */
8607 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8608 tcg_temp_free_i32(tmp2
);
8610 tmp2
= load_reg(s
, rs
);
8612 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8614 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8615 tcg_temp_free_i32(tmp2
);
8618 case 1: /* 16 x 16 -> 32 */
8619 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8620 tcg_temp_free_i32(tmp2
);
8622 tmp2
= load_reg(s
, rs
);
8623 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8624 tcg_temp_free_i32(tmp2
);
8627 case 2: /* Dual multiply add. */
8628 case 4: /* Dual multiply subtract. */
8630 gen_swap_half(tmp2
);
8631 gen_smul_dual(tmp
, tmp2
);
8632 if (insn
& (1 << 22)) {
8633 /* This subtraction cannot overflow. */
8634 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8636 /* This addition cannot overflow 32 bits;
8637 * however it may overflow considered as a signed
8638 * operation, in which case we must set the Q flag.
8640 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8642 tcg_temp_free_i32(tmp2
);
8645 tmp2
= load_reg(s
, rs
);
8646 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8647 tcg_temp_free_i32(tmp2
);
8650 case 3: /* 32 * 16 -> 32msb */
8652 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8655 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8656 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8657 tmp
= tcg_temp_new_i32();
8658 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8659 tcg_temp_free_i64(tmp64
);
8662 tmp2
= load_reg(s
, rs
);
8663 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8664 tcg_temp_free_i32(tmp2
);
8667 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8668 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8670 tmp
= load_reg(s
, rs
);
8671 if (insn
& (1 << 20)) {
8672 tmp64
= gen_addq_msw(tmp64
, tmp
);
8674 tmp64
= gen_subq_msw(tmp64
, tmp
);
8677 if (insn
& (1 << 4)) {
8678 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8680 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8681 tmp
= tcg_temp_new_i32();
8682 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8683 tcg_temp_free_i64(tmp64
);
8685 case 7: /* Unsigned sum of absolute differences. */
8686 gen_helper_usad8(tmp
, tmp
, tmp2
);
8687 tcg_temp_free_i32(tmp2
);
8689 tmp2
= load_reg(s
, rs
);
8690 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8691 tcg_temp_free_i32(tmp2
);
8695 store_reg(s
, rd
, tmp
);
8697 case 6: case 7: /* 64-bit multiply, Divide. */
8698 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8699 tmp
= load_reg(s
, rn
);
8700 tmp2
= load_reg(s
, rm
);
8701 if ((op
& 0x50) == 0x10) {
8703 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8707 gen_helper_udiv(tmp
, tmp
, tmp2
);
8709 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8710 tcg_temp_free_i32(tmp2
);
8711 store_reg(s
, rd
, tmp
);
8712 } else if ((op
& 0xe) == 0xc) {
8713 /* Dual multiply accumulate long. */
8715 gen_swap_half(tmp2
);
8716 gen_smul_dual(tmp
, tmp2
);
8718 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8720 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8722 tcg_temp_free_i32(tmp2
);
8724 tmp64
= tcg_temp_new_i64();
8725 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8726 tcg_temp_free_i32(tmp
);
8727 gen_addq(s
, tmp64
, rs
, rd
);
8728 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8729 tcg_temp_free_i64(tmp64
);
8732 /* Unsigned 64-bit multiply */
8733 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8737 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8738 tcg_temp_free_i32(tmp2
);
8739 tmp64
= tcg_temp_new_i64();
8740 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8741 tcg_temp_free_i32(tmp
);
8743 /* Signed 64-bit multiply */
8744 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8749 gen_addq_lo(s
, tmp64
, rs
);
8750 gen_addq_lo(s
, tmp64
, rd
);
8751 } else if (op
& 0x40) {
8752 /* 64-bit accumulate. */
8753 gen_addq(s
, tmp64
, rs
, rd
);
8755 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8756 tcg_temp_free_i64(tmp64
);
8761 case 6: case 7: case 14: case 15:
8763 if (((insn
>> 24) & 3) == 3) {
8764 /* Translate into the equivalent ARM encoding. */
8765 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8766 if (disas_neon_data_insn(env
, s
, insn
))
8769 if (insn
& (1 << 28))
8771 if (disas_coproc_insn (env
, s
, insn
))
8775 case 8: case 9: case 10: case 11:
8776 if (insn
& (1 << 15)) {
8777 /* Branches, misc control. */
8778 if (insn
& 0x5000) {
8779 /* Unconditional branch. */
8780 /* signextend(hw1[10:0]) -> offset[:12]. */
8781 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8782 /* hw1[10:0] -> offset[11:1]. */
8783 offset
|= (insn
& 0x7ff) << 1;
8784 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8785 offset[24:22] already have the same value because of the
8786 sign extension above. */
8787 offset
^= ((~insn
) & (1 << 13)) << 10;
8788 offset
^= ((~insn
) & (1 << 11)) << 11;
8790 if (insn
& (1 << 14)) {
8791 /* Branch and link. */
8792 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8796 if (insn
& (1 << 12)) {
8801 offset
&= ~(uint32_t)2;
8802 /* thumb2 bx, no need to check */
8803 gen_bx_im(s
, offset
);
8805 } else if (((insn
>> 23) & 7) == 7) {
8807 if (insn
& (1 << 13))
8810 if (insn
& (1 << 26)) {
8811 /* Secure monitor call (v6Z) */
8812 qemu_log_mask(LOG_UNIMP
,
8813 "arm: unimplemented secure monitor call\n");
8814 goto illegal_op
; /* not implemented. */
8816 op
= (insn
>> 20) & 7;
8818 case 0: /* msr cpsr. */
8820 tmp
= load_reg(s
, rn
);
8821 addr
= tcg_const_i32(insn
& 0xff);
8822 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8823 tcg_temp_free_i32(addr
);
8824 tcg_temp_free_i32(tmp
);
8829 case 1: /* msr spsr. */
8832 tmp
= load_reg(s
, rn
);
8834 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8838 case 2: /* cps, nop-hint. */
8839 if (((insn
>> 8) & 7) == 0) {
8840 gen_nop_hint(s
, insn
& 0xff);
8842 /* Implemented as NOP in user mode. */
8847 if (insn
& (1 << 10)) {
8848 if (insn
& (1 << 7))
8850 if (insn
& (1 << 6))
8852 if (insn
& (1 << 5))
8854 if (insn
& (1 << 9))
8855 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8857 if (insn
& (1 << 8)) {
8859 imm
|= (insn
& 0x1f);
8862 gen_set_psr_im(s
, offset
, 0, imm
);
8865 case 3: /* Special control operations. */
8867 op
= (insn
>> 4) & 0xf;
8875 /* These execute as NOPs. */
8882 /* Trivial implementation equivalent to bx. */
8883 tmp
= load_reg(s
, rn
);
8886 case 5: /* Exception return. */
8890 if (rn
!= 14 || rd
!= 15) {
8893 tmp
= load_reg(s
, rn
);
8894 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8895 gen_exception_return(s
, tmp
);
8897 case 6: /* mrs cpsr. */
8898 tmp
= tcg_temp_new_i32();
8900 addr
= tcg_const_i32(insn
& 0xff);
8901 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8902 tcg_temp_free_i32(addr
);
8904 gen_helper_cpsr_read(tmp
, cpu_env
);
8906 store_reg(s
, rd
, tmp
);
8908 case 7: /* mrs spsr. */
8909 /* Not accessible in user mode. */
8910 if (IS_USER(s
) || IS_M(env
))
8912 tmp
= load_cpu_field(spsr
);
8913 store_reg(s
, rd
, tmp
);
8918 /* Conditional branch. */
8919 op
= (insn
>> 22) & 0xf;
8920 /* Generate a conditional jump to next instruction. */
8921 s
->condlabel
= gen_new_label();
8922 gen_test_cc(op
^ 1, s
->condlabel
);
8925 /* offset[11:1] = insn[10:0] */
8926 offset
= (insn
& 0x7ff) << 1;
8927 /* offset[17:12] = insn[21:16]. */
8928 offset
|= (insn
& 0x003f0000) >> 4;
8929 /* offset[31:20] = insn[26]. */
8930 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8931 /* offset[18] = insn[13]. */
8932 offset
|= (insn
& (1 << 13)) << 5;
8933 /* offset[19] = insn[11]. */
8934 offset
|= (insn
& (1 << 11)) << 8;
8936 /* jump to the offset */
8937 gen_jmp(s
, s
->pc
+ offset
);
8940 /* Data processing immediate. */
8941 if (insn
& (1 << 25)) {
8942 if (insn
& (1 << 24)) {
8943 if (insn
& (1 << 20))
8945 /* Bitfield/Saturate. */
8946 op
= (insn
>> 21) & 7;
8948 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8950 tmp
= tcg_temp_new_i32();
8951 tcg_gen_movi_i32(tmp
, 0);
8953 tmp
= load_reg(s
, rn
);
8956 case 2: /* Signed bitfield extract. */
8958 if (shift
+ imm
> 32)
8961 gen_sbfx(tmp
, shift
, imm
);
8963 case 6: /* Unsigned bitfield extract. */
8965 if (shift
+ imm
> 32)
8968 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8970 case 3: /* Bitfield insert/clear. */
8973 imm
= imm
+ 1 - shift
;
8975 tmp2
= load_reg(s
, rd
);
8976 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8977 tcg_temp_free_i32(tmp2
);
8982 default: /* Saturate. */
8985 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8987 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8989 tmp2
= tcg_const_i32(imm
);
8992 if ((op
& 1) && shift
== 0)
8993 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8995 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8998 if ((op
& 1) && shift
== 0)
8999 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9001 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9003 tcg_temp_free_i32(tmp2
);
9006 store_reg(s
, rd
, tmp
);
9008 imm
= ((insn
& 0x04000000) >> 15)
9009 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9010 if (insn
& (1 << 22)) {
9011 /* 16-bit immediate. */
9012 imm
|= (insn
>> 4) & 0xf000;
9013 if (insn
& (1 << 23)) {
9015 tmp
= load_reg(s
, rd
);
9016 tcg_gen_ext16u_i32(tmp
, tmp
);
9017 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9020 tmp
= tcg_temp_new_i32();
9021 tcg_gen_movi_i32(tmp
, imm
);
9024 /* Add/sub 12-bit immediate. */
9026 offset
= s
->pc
& ~(uint32_t)3;
9027 if (insn
& (1 << 23))
9031 tmp
= tcg_temp_new_i32();
9032 tcg_gen_movi_i32(tmp
, offset
);
9034 tmp
= load_reg(s
, rn
);
9035 if (insn
& (1 << 23))
9036 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9038 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9041 store_reg(s
, rd
, tmp
);
9044 int shifter_out
= 0;
9045 /* modified 12-bit immediate. */
9046 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9047 imm
= (insn
& 0xff);
9050 /* Nothing to do. */
9052 case 1: /* 00XY00XY */
9055 case 2: /* XY00XY00 */
9059 case 3: /* XYXYXYXY */
9063 default: /* Rotated constant. */
9064 shift
= (shift
<< 1) | (imm
>> 7);
9066 imm
= imm
<< (32 - shift
);
9070 tmp2
= tcg_temp_new_i32();
9071 tcg_gen_movi_i32(tmp2
, imm
);
9072 rn
= (insn
>> 16) & 0xf;
9074 tmp
= tcg_temp_new_i32();
9075 tcg_gen_movi_i32(tmp
, 0);
9077 tmp
= load_reg(s
, rn
);
9079 op
= (insn
>> 21) & 0xf;
9080 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9081 shifter_out
, tmp
, tmp2
))
9083 tcg_temp_free_i32(tmp2
);
9084 rd
= (insn
>> 8) & 0xf;
9086 store_reg(s
, rd
, tmp
);
9088 tcg_temp_free_i32(tmp
);
9093 case 12: /* Load/store single data item. */
9098 if ((insn
& 0x01100000) == 0x01000000) {
9099 if (disas_neon_ls_insn(env
, s
, insn
))
9103 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9105 if (!(insn
& (1 << 20))) {
9109 /* Byte or halfword load space with dest == r15 : memory hints.
9110 * Catch them early so we don't emit pointless addressing code.
9111 * This space is a mix of:
9112 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9113 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9115 * unallocated hints, which must be treated as NOPs
9116 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9117 * which is easiest for the decoding logic
9118 * Some space which must UNDEF
9120 int op1
= (insn
>> 23) & 3;
9121 int op2
= (insn
>> 6) & 0x3f;
9126 /* UNPREDICTABLE, unallocated hint or
9127 * PLD/PLDW/PLI (literal)
9132 return 0; /* PLD/PLDW/PLI or unallocated hint */
9134 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9135 return 0; /* PLD/PLDW/PLI or unallocated hint */
9137 /* UNDEF space, or an UNPREDICTABLE */
9143 addr
= tcg_temp_new_i32();
9145 /* s->pc has already been incremented by 4. */
9146 imm
= s
->pc
& 0xfffffffc;
9147 if (insn
& (1 << 23))
9148 imm
+= insn
& 0xfff;
9150 imm
-= insn
& 0xfff;
9151 tcg_gen_movi_i32(addr
, imm
);
9153 addr
= load_reg(s
, rn
);
9154 if (insn
& (1 << 23)) {
9155 /* Positive offset. */
9157 tcg_gen_addi_i32(addr
, addr
, imm
);
9160 switch ((insn
>> 8) & 0xf) {
9161 case 0x0: /* Shifted Register. */
9162 shift
= (insn
>> 4) & 0xf;
9164 tcg_temp_free_i32(addr
);
9167 tmp
= load_reg(s
, rm
);
9169 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9170 tcg_gen_add_i32(addr
, addr
, tmp
);
9171 tcg_temp_free_i32(tmp
);
9173 case 0xc: /* Negative offset. */
9174 tcg_gen_addi_i32(addr
, addr
, -imm
);
9176 case 0xe: /* User privilege. */
9177 tcg_gen_addi_i32(addr
, addr
, imm
);
9180 case 0x9: /* Post-decrement. */
9183 case 0xb: /* Post-increment. */
9187 case 0xd: /* Pre-decrement. */
9190 case 0xf: /* Pre-increment. */
9191 tcg_gen_addi_i32(addr
, addr
, imm
);
9195 tcg_temp_free_i32(addr
);
9200 if (insn
& (1 << 20)) {
9202 tmp
= tcg_temp_new_i32();
9205 gen_aa32_ld8u(tmp
, addr
, user
);
9208 gen_aa32_ld8s(tmp
, addr
, user
);
9211 gen_aa32_ld16u(tmp
, addr
, user
);
9214 gen_aa32_ld16s(tmp
, addr
, user
);
9217 gen_aa32_ld32u(tmp
, addr
, user
);
9220 tcg_temp_free_i32(tmp
);
9221 tcg_temp_free_i32(addr
);
9227 store_reg(s
, rs
, tmp
);
9231 tmp
= load_reg(s
, rs
);
9234 gen_aa32_st8(tmp
, addr
, user
);
9237 gen_aa32_st16(tmp
, addr
, user
);
9240 gen_aa32_st32(tmp
, addr
, user
);
9243 tcg_temp_free_i32(tmp
);
9244 tcg_temp_free_i32(addr
);
9247 tcg_temp_free_i32(tmp
);
9250 tcg_gen_addi_i32(addr
, addr
, imm
);
9252 store_reg(s
, rn
, addr
);
9254 tcg_temp_free_i32(addr
);
9266 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9268 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9275 if (s
->condexec_mask
) {
9276 cond
= s
->condexec_cond
;
9277 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9278 s
->condlabel
= gen_new_label();
9279 gen_test_cc(cond
^ 1, s
->condlabel
);
9284 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9287 switch (insn
>> 12) {
9291 op
= (insn
>> 11) & 3;
9294 rn
= (insn
>> 3) & 7;
9295 tmp
= load_reg(s
, rn
);
9296 if (insn
& (1 << 10)) {
9298 tmp2
= tcg_temp_new_i32();
9299 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9302 rm
= (insn
>> 6) & 7;
9303 tmp2
= load_reg(s
, rm
);
9305 if (insn
& (1 << 9)) {
9306 if (s
->condexec_mask
)
9307 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9309 gen_sub_CC(tmp
, tmp
, tmp2
);
9311 if (s
->condexec_mask
)
9312 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9314 gen_add_CC(tmp
, tmp
, tmp2
);
9316 tcg_temp_free_i32(tmp2
);
9317 store_reg(s
, rd
, tmp
);
9319 /* shift immediate */
9320 rm
= (insn
>> 3) & 7;
9321 shift
= (insn
>> 6) & 0x1f;
9322 tmp
= load_reg(s
, rm
);
9323 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9324 if (!s
->condexec_mask
)
9326 store_reg(s
, rd
, tmp
);
9330 /* arithmetic large immediate */
9331 op
= (insn
>> 11) & 3;
9332 rd
= (insn
>> 8) & 0x7;
9333 if (op
== 0) { /* mov */
9334 tmp
= tcg_temp_new_i32();
9335 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9336 if (!s
->condexec_mask
)
9338 store_reg(s
, rd
, tmp
);
9340 tmp
= load_reg(s
, rd
);
9341 tmp2
= tcg_temp_new_i32();
9342 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9345 gen_sub_CC(tmp
, tmp
, tmp2
);
9346 tcg_temp_free_i32(tmp
);
9347 tcg_temp_free_i32(tmp2
);
9350 if (s
->condexec_mask
)
9351 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9353 gen_add_CC(tmp
, tmp
, tmp2
);
9354 tcg_temp_free_i32(tmp2
);
9355 store_reg(s
, rd
, tmp
);
9358 if (s
->condexec_mask
)
9359 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9361 gen_sub_CC(tmp
, tmp
, tmp2
);
9362 tcg_temp_free_i32(tmp2
);
9363 store_reg(s
, rd
, tmp
);
9369 if (insn
& (1 << 11)) {
9370 rd
= (insn
>> 8) & 7;
9371 /* load pc-relative. Bit 1 of PC is ignored. */
9372 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9373 val
&= ~(uint32_t)2;
9374 addr
= tcg_temp_new_i32();
9375 tcg_gen_movi_i32(addr
, val
);
9376 tmp
= tcg_temp_new_i32();
9377 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9378 tcg_temp_free_i32(addr
);
9379 store_reg(s
, rd
, tmp
);
9382 if (insn
& (1 << 10)) {
9383 /* data processing extended or blx */
9384 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9385 rm
= (insn
>> 3) & 0xf;
9386 op
= (insn
>> 8) & 3;
9389 tmp
= load_reg(s
, rd
);
9390 tmp2
= load_reg(s
, rm
);
9391 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9392 tcg_temp_free_i32(tmp2
);
9393 store_reg(s
, rd
, tmp
);
9396 tmp
= load_reg(s
, rd
);
9397 tmp2
= load_reg(s
, rm
);
9398 gen_sub_CC(tmp
, tmp
, tmp2
);
9399 tcg_temp_free_i32(tmp2
);
9400 tcg_temp_free_i32(tmp
);
9402 case 2: /* mov/cpy */
9403 tmp
= load_reg(s
, rm
);
9404 store_reg(s
, rd
, tmp
);
9406 case 3:/* branch [and link] exchange thumb register */
9407 tmp
= load_reg(s
, rm
);
9408 if (insn
& (1 << 7)) {
9410 val
= (uint32_t)s
->pc
| 1;
9411 tmp2
= tcg_temp_new_i32();
9412 tcg_gen_movi_i32(tmp2
, val
);
9413 store_reg(s
, 14, tmp2
);
9415 /* already thumb, no need to check */
9422 /* data processing register */
9424 rm
= (insn
>> 3) & 7;
9425 op
= (insn
>> 6) & 0xf;
9426 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9427 /* the shift/rotate ops want the operands backwards */
9436 if (op
== 9) { /* neg */
9437 tmp
= tcg_temp_new_i32();
9438 tcg_gen_movi_i32(tmp
, 0);
9439 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9440 tmp
= load_reg(s
, rd
);
9442 TCGV_UNUSED_I32(tmp
);
9445 tmp2
= load_reg(s
, rm
);
9448 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9449 if (!s
->condexec_mask
)
9453 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9454 if (!s
->condexec_mask
)
9458 if (s
->condexec_mask
) {
9459 gen_shl(tmp2
, tmp2
, tmp
);
9461 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9466 if (s
->condexec_mask
) {
9467 gen_shr(tmp2
, tmp2
, tmp
);
9469 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9474 if (s
->condexec_mask
) {
9475 gen_sar(tmp2
, tmp2
, tmp
);
9477 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9482 if (s
->condexec_mask
) {
9485 gen_adc_CC(tmp
, tmp
, tmp2
);
9489 if (s
->condexec_mask
) {
9490 gen_sub_carry(tmp
, tmp
, tmp2
);
9492 gen_sbc_CC(tmp
, tmp
, tmp2
);
9496 if (s
->condexec_mask
) {
9497 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9498 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9500 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9505 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9510 if (s
->condexec_mask
)
9511 tcg_gen_neg_i32(tmp
, tmp2
);
9513 gen_sub_CC(tmp
, tmp
, tmp2
);
9516 gen_sub_CC(tmp
, tmp
, tmp2
);
9520 gen_add_CC(tmp
, tmp
, tmp2
);
9524 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9525 if (!s
->condexec_mask
)
9529 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9530 if (!s
->condexec_mask
)
9534 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9535 if (!s
->condexec_mask
)
9539 tcg_gen_not_i32(tmp2
, tmp2
);
9540 if (!s
->condexec_mask
)
9548 store_reg(s
, rm
, tmp2
);
9550 tcg_temp_free_i32(tmp
);
9552 store_reg(s
, rd
, tmp
);
9553 tcg_temp_free_i32(tmp2
);
9556 tcg_temp_free_i32(tmp
);
9557 tcg_temp_free_i32(tmp2
);
9562 /* load/store register offset. */
9564 rn
= (insn
>> 3) & 7;
9565 rm
= (insn
>> 6) & 7;
9566 op
= (insn
>> 9) & 7;
9567 addr
= load_reg(s
, rn
);
9568 tmp
= load_reg(s
, rm
);
9569 tcg_gen_add_i32(addr
, addr
, tmp
);
9570 tcg_temp_free_i32(tmp
);
9572 if (op
< 3) { /* store */
9573 tmp
= load_reg(s
, rd
);
9575 tmp
= tcg_temp_new_i32();
9580 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9583 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9586 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9589 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
9592 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9595 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9598 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9601 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
9604 if (op
>= 3) { /* load */
9605 store_reg(s
, rd
, tmp
);
9607 tcg_temp_free_i32(tmp
);
9609 tcg_temp_free_i32(addr
);
9613 /* load/store word immediate offset */
9615 rn
= (insn
>> 3) & 7;
9616 addr
= load_reg(s
, rn
);
9617 val
= (insn
>> 4) & 0x7c;
9618 tcg_gen_addi_i32(addr
, addr
, val
);
9620 if (insn
& (1 << 11)) {
9622 tmp
= tcg_temp_new_i32();
9623 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9624 store_reg(s
, rd
, tmp
);
9627 tmp
= load_reg(s
, rd
);
9628 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9629 tcg_temp_free_i32(tmp
);
9631 tcg_temp_free_i32(addr
);
9635 /* load/store byte immediate offset */
9637 rn
= (insn
>> 3) & 7;
9638 addr
= load_reg(s
, rn
);
9639 val
= (insn
>> 6) & 0x1f;
9640 tcg_gen_addi_i32(addr
, addr
, val
);
9642 if (insn
& (1 << 11)) {
9644 tmp
= tcg_temp_new_i32();
9645 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9646 store_reg(s
, rd
, tmp
);
9649 tmp
= load_reg(s
, rd
);
9650 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9651 tcg_temp_free_i32(tmp
);
9653 tcg_temp_free_i32(addr
);
9657 /* load/store halfword immediate offset */
9659 rn
= (insn
>> 3) & 7;
9660 addr
= load_reg(s
, rn
);
9661 val
= (insn
>> 5) & 0x3e;
9662 tcg_gen_addi_i32(addr
, addr
, val
);
9664 if (insn
& (1 << 11)) {
9666 tmp
= tcg_temp_new_i32();
9667 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9668 store_reg(s
, rd
, tmp
);
9671 tmp
= load_reg(s
, rd
);
9672 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9673 tcg_temp_free_i32(tmp
);
9675 tcg_temp_free_i32(addr
);
9679 /* load/store from stack */
9680 rd
= (insn
>> 8) & 7;
9681 addr
= load_reg(s
, 13);
9682 val
= (insn
& 0xff) * 4;
9683 tcg_gen_addi_i32(addr
, addr
, val
);
9685 if (insn
& (1 << 11)) {
9687 tmp
= tcg_temp_new_i32();
9688 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9689 store_reg(s
, rd
, tmp
);
9692 tmp
= load_reg(s
, rd
);
9693 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9694 tcg_temp_free_i32(tmp
);
9696 tcg_temp_free_i32(addr
);
9700 /* add to high reg */
9701 rd
= (insn
>> 8) & 7;
9702 if (insn
& (1 << 11)) {
9704 tmp
= load_reg(s
, 13);
9706 /* PC. bit 1 is ignored. */
9707 tmp
= tcg_temp_new_i32();
9708 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9710 val
= (insn
& 0xff) * 4;
9711 tcg_gen_addi_i32(tmp
, tmp
, val
);
9712 store_reg(s
, rd
, tmp
);
9717 op
= (insn
>> 8) & 0xf;
9720 /* adjust stack pointer */
9721 tmp
= load_reg(s
, 13);
9722 val
= (insn
& 0x7f) * 4;
9723 if (insn
& (1 << 7))
9724 val
= -(int32_t)val
;
9725 tcg_gen_addi_i32(tmp
, tmp
, val
);
9726 store_reg(s
, 13, tmp
);
9729 case 2: /* sign/zero extend. */
9732 rm
= (insn
>> 3) & 7;
9733 tmp
= load_reg(s
, rm
);
9734 switch ((insn
>> 6) & 3) {
9735 case 0: gen_sxth(tmp
); break;
9736 case 1: gen_sxtb(tmp
); break;
9737 case 2: gen_uxth(tmp
); break;
9738 case 3: gen_uxtb(tmp
); break;
9740 store_reg(s
, rd
, tmp
);
9742 case 4: case 5: case 0xc: case 0xd:
9744 addr
= load_reg(s
, 13);
9745 if (insn
& (1 << 8))
9749 for (i
= 0; i
< 8; i
++) {
9750 if (insn
& (1 << i
))
9753 if ((insn
& (1 << 11)) == 0) {
9754 tcg_gen_addi_i32(addr
, addr
, -offset
);
9756 for (i
= 0; i
< 8; i
++) {
9757 if (insn
& (1 << i
)) {
9758 if (insn
& (1 << 11)) {
9760 tmp
= tcg_temp_new_i32();
9761 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9762 store_reg(s
, i
, tmp
);
9765 tmp
= load_reg(s
, i
);
9766 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9767 tcg_temp_free_i32(tmp
);
9769 /* advance to the next address. */
9770 tcg_gen_addi_i32(addr
, addr
, 4);
9773 TCGV_UNUSED_I32(tmp
);
9774 if (insn
& (1 << 8)) {
9775 if (insn
& (1 << 11)) {
9777 tmp
= tcg_temp_new_i32();
9778 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9779 /* don't set the pc until the rest of the instruction
9783 tmp
= load_reg(s
, 14);
9784 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9785 tcg_temp_free_i32(tmp
);
9787 tcg_gen_addi_i32(addr
, addr
, 4);
9789 if ((insn
& (1 << 11)) == 0) {
9790 tcg_gen_addi_i32(addr
, addr
, -offset
);
9792 /* write back the new stack pointer */
9793 store_reg(s
, 13, addr
);
9794 /* set the new PC value */
9795 if ((insn
& 0x0900) == 0x0900) {
9796 store_reg_from_load(env
, s
, 15, tmp
);
9800 case 1: case 3: case 9: case 11: /* czb */
9802 tmp
= load_reg(s
, rm
);
9803 s
->condlabel
= gen_new_label();
9805 if (insn
& (1 << 11))
9806 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9808 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9809 tcg_temp_free_i32(tmp
);
9810 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9811 val
= (uint32_t)s
->pc
+ 2;
9816 case 15: /* IT, nop-hint. */
9817 if ((insn
& 0xf) == 0) {
9818 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9822 s
->condexec_cond
= (insn
>> 4) & 0xe;
9823 s
->condexec_mask
= insn
& 0x1f;
9824 /* No actual code generated for this insn, just setup state. */
9827 case 0xe: /* bkpt */
9829 gen_exception_insn(s
, 2, EXCP_BKPT
);
9834 rn
= (insn
>> 3) & 0x7;
9836 tmp
= load_reg(s
, rn
);
9837 switch ((insn
>> 6) & 3) {
9838 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9839 case 1: gen_rev16(tmp
); break;
9840 case 3: gen_revsh(tmp
); break;
9841 default: goto illegal_op
;
9843 store_reg(s
, rd
, tmp
);
9847 switch ((insn
>> 5) & 7) {
9851 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9852 /* Dynamic endianness switching not implemented. */
9853 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
9864 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9867 addr
= tcg_const_i32(19);
9868 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9869 tcg_temp_free_i32(addr
);
9873 addr
= tcg_const_i32(16);
9874 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9875 tcg_temp_free_i32(addr
);
9877 tcg_temp_free_i32(tmp
);
9880 if (insn
& (1 << 4)) {
9881 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9885 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9900 /* load/store multiple */
9901 TCGv_i32 loaded_var
;
9902 TCGV_UNUSED_I32(loaded_var
);
9903 rn
= (insn
>> 8) & 0x7;
9904 addr
= load_reg(s
, rn
);
9905 for (i
= 0; i
< 8; i
++) {
9906 if (insn
& (1 << i
)) {
9907 if (insn
& (1 << 11)) {
9909 tmp
= tcg_temp_new_i32();
9910 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9914 store_reg(s
, i
, tmp
);
9918 tmp
= load_reg(s
, i
);
9919 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9920 tcg_temp_free_i32(tmp
);
9922 /* advance to the next address */
9923 tcg_gen_addi_i32(addr
, addr
, 4);
9926 if ((insn
& (1 << rn
)) == 0) {
9927 /* base reg not in list: base register writeback */
9928 store_reg(s
, rn
, addr
);
9930 /* base reg in list: if load, complete it now */
9931 if (insn
& (1 << 11)) {
9932 store_reg(s
, rn
, loaded_var
);
9934 tcg_temp_free_i32(addr
);
9939 /* conditional branch or swi */
9940 cond
= (insn
>> 8) & 0xf;
9946 gen_set_pc_im(s
, s
->pc
);
9947 s
->is_jmp
= DISAS_SWI
;
9950 /* generate a conditional jump to next instruction */
9951 s
->condlabel
= gen_new_label();
9952 gen_test_cc(cond
^ 1, s
->condlabel
);
9955 /* jump to the offset */
9956 val
= (uint32_t)s
->pc
+ 2;
9957 offset
= ((int32_t)insn
<< 24) >> 24;
9963 if (insn
& (1 << 11)) {
9964 if (disas_thumb2_insn(env
, s
, insn
))
9968 /* unconditional branch */
9969 val
= (uint32_t)s
->pc
;
9970 offset
= ((int32_t)insn
<< 21) >> 21;
9971 val
+= (offset
<< 1) + 2;
9976 if (disas_thumb2_insn(env
, s
, insn
))
9982 gen_exception_insn(s
, 4, EXCP_UDEF
);
9986 gen_exception_insn(s
, 2, EXCP_UDEF
);
9989 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9990 basic block 'tb'. If search_pc is TRUE, also generate PC
9991 information for each intermediate instruction. */
9992 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
9993 TranslationBlock
*tb
,
9996 CPUState
*cs
= CPU(cpu
);
9997 CPUARMState
*env
= &cpu
->env
;
9998 DisasContext dc1
, *dc
= &dc1
;
10000 uint16_t *gen_opc_end
;
10002 target_ulong pc_start
;
10003 target_ulong next_page_start
;
10007 /* generate intermediate code */
10012 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10014 dc
->is_jmp
= DISAS_NEXT
;
10016 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10019 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10022 dc
->bswap_code
= 0;
10023 dc
->condexec_mask
= 0;
10024 dc
->condexec_cond
= 0;
10025 #if !defined(CONFIG_USER_ONLY)
10028 dc
->vfp_enabled
= 0;
10030 dc
->vec_stride
= 0;
10033 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10034 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10035 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10036 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10037 #if !defined(CONFIG_USER_ONLY)
10038 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10040 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10041 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10042 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10044 cpu_F0s
= tcg_temp_new_i32();
10045 cpu_F1s
= tcg_temp_new_i32();
10046 cpu_F0d
= tcg_temp_new_i64();
10047 cpu_F1d
= tcg_temp_new_i64();
10050 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10051 cpu_M0
= tcg_temp_new_i64();
10052 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10055 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10056 if (max_insns
== 0)
10057 max_insns
= CF_COUNT_MASK
;
10061 tcg_clear_temp_count();
10063 /* A note on handling of the condexec (IT) bits:
10065 * We want to avoid the overhead of having to write the updated condexec
10066 * bits back to the CPUARMState for every instruction in an IT block. So:
10067 * (1) if the condexec bits are not already zero then we write
10068 * zero back into the CPUARMState now. This avoids complications trying
10069 * to do it at the end of the block. (For example if we don't do this
10070 * it's hard to identify whether we can safely skip writing condexec
10071 * at the end of the TB, which we definitely want to do for the case
10072 * where a TB doesn't do anything with the IT state at all.)
10073 * (2) if we are going to leave the TB then we call gen_set_condexec()
10074 * which will write the correct value into CPUARMState if zero is wrong.
10075 * This is done both for leaving the TB at the end, and for leaving
10076 * it because of an exception we know will happen, which is done in
10077 * gen_exception_insn(). The latter is necessary because we need to
10078 * leave the TB with the PC/IT state just prior to execution of the
10079 * instruction which caused the exception.
10080 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10081 * then the CPUARMState will be wrong and we need to reset it.
10082 * This is handled in the same way as restoration of the
10083 * PC in these situations: we will be called again with search_pc=1
10084 * and generate a mapping of the condexec bits for each PC in
10085 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10086 * this to restore the condexec bits.
10088 * Note that there are no instructions which can read the condexec
10089 * bits, and none which can write non-static values to them, so
10090 * we don't need to care about whether CPUARMState is correct in the
10094 /* Reset the conditional execution bits immediately. This avoids
10095 complications trying to do it at the end of the block. */
10096 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10098 TCGv_i32 tmp
= tcg_temp_new_i32();
10099 tcg_gen_movi_i32(tmp
, 0);
10100 store_cpu_field(tmp
, condexec_bits
);
10103 #ifdef CONFIG_USER_ONLY
10104 /* Intercept jump to the magic kernel page. */
10105 if (!dc
->aarch64
&& dc
->pc
>= 0xffff0000) {
10106 /* We always get here via a jump, so know we are not in a
10107 conditional execution block. */
10108 gen_exception(EXCP_KERNEL_TRAP
);
10109 dc
->is_jmp
= DISAS_UPDATE
;
10113 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10114 /* We always get here via a jump, so know we are not in a
10115 conditional execution block. */
10116 gen_exception(EXCP_EXCEPTION_EXIT
);
10117 dc
->is_jmp
= DISAS_UPDATE
;
10122 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10123 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10124 if (bp
->pc
== dc
->pc
) {
10125 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10126 /* Advance PC so that clearing the breakpoint will
10127 invalidate this TB. */
10129 goto done_generating
;
10134 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10138 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10140 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10141 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10142 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10143 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10146 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10149 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10150 tcg_gen_debug_insn_start(dc
->pc
);
10154 disas_a64_insn(env
, dc
);
10155 } else if (dc
->thumb
) {
10156 disas_thumb_insn(env
, dc
);
10157 if (dc
->condexec_mask
) {
10158 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10159 | ((dc
->condexec_mask
>> 4) & 1);
10160 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10161 if (dc
->condexec_mask
== 0) {
10162 dc
->condexec_cond
= 0;
10166 disas_arm_insn(env
, dc
);
10169 if (dc
->condjmp
&& !dc
->is_jmp
) {
10170 gen_set_label(dc
->condlabel
);
10174 if (tcg_check_temp_count()) {
10175 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10179 /* Translation stops when a conditional branch is encountered.
10180 * Otherwise the subsequent code could get translated several times.
10181 * Also stop translation when a page boundary is reached. This
10182 * ensures prefetch aborts occur at the right place. */
10184 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10185 !cs
->singlestep_enabled
&&
10187 dc
->pc
< next_page_start
&&
10188 num_insns
< max_insns
);
10190 if (tb
->cflags
& CF_LAST_IO
) {
10192 /* FIXME: This can theoretically happen with self-modifying
10194 cpu_abort(env
, "IO on conditional branch instruction");
10199 /* At this stage dc->condjmp will only be set when the skipped
10200 instruction was a conditional branch or trap, and the PC has
10201 already been written. */
10202 if (unlikely(cs
->singlestep_enabled
)) {
10203 /* Make sure the pc is updated, and raise a debug exception. */
10205 gen_set_condexec(dc
);
10206 if (dc
->is_jmp
== DISAS_SWI
) {
10207 gen_exception(EXCP_SWI
);
10209 gen_exception(EXCP_DEBUG
);
10211 gen_set_label(dc
->condlabel
);
10213 if (dc
->condjmp
|| !dc
->is_jmp
) {
10214 gen_set_pc_im(dc
, dc
->pc
);
10217 gen_set_condexec(dc
);
10218 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10219 gen_exception(EXCP_SWI
);
10221 /* FIXME: Single stepping a WFI insn will not halt
10223 gen_exception(EXCP_DEBUG
);
10226 /* While branches must always occur at the end of an IT block,
10227 there are a few other things that can cause us to terminate
10228 the TB in the middle of an IT block:
10229 - Exception generating instructions (bkpt, swi, undefined).
10231 - Hardware watchpoints.
10232 Hardware breakpoints have already been handled and skip this code.
10234 gen_set_condexec(dc
);
10235 switch(dc
->is_jmp
) {
10237 gen_goto_tb(dc
, 1, dc
->pc
);
10242 /* indicate that the hash table must be used to find the next TB */
10243 tcg_gen_exit_tb(0);
10245 case DISAS_TB_JUMP
:
10246 /* nothing more to generate */
10249 gen_helper_wfi(cpu_env
);
10252 gen_exception(EXCP_SWI
);
10256 gen_set_label(dc
->condlabel
);
10257 gen_set_condexec(dc
);
10258 gen_goto_tb(dc
, 1, dc
->pc
);
10264 gen_tb_end(tb
, num_insns
);
10265 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10268 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10269 qemu_log("----------------\n");
10270 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10271 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10272 dc
->thumb
| (dc
->bswap_code
<< 1));
10277 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10280 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10282 tb
->size
= dc
->pc
- pc_start
;
10283 tb
->icount
= num_insns
;
10287 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10289 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10292 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10294 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10297 static const char *cpu_mode_names
[16] = {
10298 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10299 "???", "???", "???", "und", "???", "???", "???", "sys"
10302 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10305 ARMCPU
*cpu
= ARM_CPU(cs
);
10306 CPUARMState
*env
= &cpu
->env
;
10310 for(i
=0;i
<16;i
++) {
10311 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10313 cpu_fprintf(f
, "\n");
10315 cpu_fprintf(f
, " ");
10317 psr
= cpsr_read(env
);
10318 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10320 psr
& (1 << 31) ? 'N' : '-',
10321 psr
& (1 << 30) ? 'Z' : '-',
10322 psr
& (1 << 29) ? 'C' : '-',
10323 psr
& (1 << 28) ? 'V' : '-',
10324 psr
& CPSR_T
? 'T' : 'A',
10325 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10327 if (flags
& CPU_DUMP_FPU
) {
10328 int numvfpregs
= 0;
10329 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10332 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10335 for (i
= 0; i
< numvfpregs
; i
++) {
10336 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10337 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10338 i
* 2, (uint32_t)v
,
10339 i
* 2 + 1, (uint32_t)(v
>> 32),
10342 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10346 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10349 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10351 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10353 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];