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 the address argument is TCGv_i32 rather than TCGv.
830 #if TARGET_LONG_BITS == 32
832 #define DO_GEN_LD(SUFF, OPC) \
833 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
835 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
838 #define DO_GEN_ST(SUFF, OPC) \
839 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
841 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
844 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
846 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
849 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
851 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
856 #define DO_GEN_LD(SUFF, OPC) \
857 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
859 TCGv addr64 = tcg_temp_new(); \
860 tcg_gen_extu_i32_i64(addr64, addr); \
861 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
862 tcg_temp_free(addr64); \
865 #define DO_GEN_ST(SUFF, OPC) \
866 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
868 TCGv addr64 = tcg_temp_new(); \
869 tcg_gen_extu_i32_i64(addr64, addr); \
870 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
871 tcg_temp_free(addr64); \
874 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
876 TCGv addr64
= tcg_temp_new();
877 tcg_gen_extu_i32_i64(addr64
, addr
);
878 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
879 tcg_temp_free(addr64
);
882 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
884 TCGv addr64
= tcg_temp_new();
885 tcg_gen_extu_i32_i64(addr64
, addr
);
886 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
887 tcg_temp_free(addr64
);
894 DO_GEN_LD(16s
, MO_TESW
)
895 DO_GEN_LD(16u, MO_TEUW
)
896 DO_GEN_LD(32u, MO_TEUL
)
898 DO_GEN_ST(16, MO_TEUW
)
899 DO_GEN_ST(32, MO_TEUL
)
901 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
904 gen_a64_set_pc_im(val
);
906 tcg_gen_movi_i32(cpu_R
[15], val
);
910 /* Force a TB lookup after an instruction that changes the CPU state. */
911 static inline void gen_lookup_tb(DisasContext
*s
)
913 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
914 s
->is_jmp
= DISAS_UPDATE
;
917 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
920 int val
, rm
, shift
, shiftop
;
923 if (!(insn
& (1 << 25))) {
926 if (!(insn
& (1 << 23)))
929 tcg_gen_addi_i32(var
, var
, val
);
933 shift
= (insn
>> 7) & 0x1f;
934 shiftop
= (insn
>> 5) & 3;
935 offset
= load_reg(s
, rm
);
936 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
937 if (!(insn
& (1 << 23)))
938 tcg_gen_sub_i32(var
, var
, offset
);
940 tcg_gen_add_i32(var
, var
, offset
);
941 tcg_temp_free_i32(offset
);
945 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
946 int extra
, TCGv_i32 var
)
951 if (insn
& (1 << 22)) {
953 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
954 if (!(insn
& (1 << 23)))
958 tcg_gen_addi_i32(var
, var
, val
);
962 tcg_gen_addi_i32(var
, var
, extra
);
964 offset
= load_reg(s
, rm
);
965 if (!(insn
& (1 << 23)))
966 tcg_gen_sub_i32(var
, var
, offset
);
968 tcg_gen_add_i32(var
, var
, offset
);
969 tcg_temp_free_i32(offset
);
973 static TCGv_ptr
get_fpstatus_ptr(int neon
)
975 TCGv_ptr statusptr
= tcg_temp_new_ptr();
978 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
980 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
982 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
986 #define VFP_OP2(name) \
987 static inline void gen_vfp_##name(int dp) \
989 TCGv_ptr fpst = get_fpstatus_ptr(0); \
991 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
993 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
995 tcg_temp_free_ptr(fpst); \
1005 static inline void gen_vfp_F1_mul(int dp
)
1007 /* Like gen_vfp_mul() but put result in F1 */
1008 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1010 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1012 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1014 tcg_temp_free_ptr(fpst
);
1017 static inline void gen_vfp_F1_neg(int dp
)
1019 /* Like gen_vfp_neg() but put result in F1 */
1021 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1023 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1027 static inline void gen_vfp_abs(int dp
)
1030 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1032 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1035 static inline void gen_vfp_neg(int dp
)
1038 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1040 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1043 static inline void gen_vfp_sqrt(int dp
)
1046 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1048 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1051 static inline void gen_vfp_cmp(int dp
)
1054 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1056 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1059 static inline void gen_vfp_cmpe(int dp
)
1062 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1064 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1067 static inline void gen_vfp_F1_ld0(int dp
)
1070 tcg_gen_movi_i64(cpu_F1d
, 0);
1072 tcg_gen_movi_i32(cpu_F1s
, 0);
1075 #define VFP_GEN_ITOF(name) \
1076 static inline void gen_vfp_##name(int dp, int neon) \
1078 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1080 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1082 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1084 tcg_temp_free_ptr(statusptr); \
1091 #define VFP_GEN_FTOI(name) \
1092 static inline void gen_vfp_##name(int dp, int neon) \
1094 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1096 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1098 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1100 tcg_temp_free_ptr(statusptr); \
1109 #define VFP_GEN_FIX(name) \
1110 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1112 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1113 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1115 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1117 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1119 tcg_temp_free_i32(tmp_shift); \
1120 tcg_temp_free_ptr(statusptr); \
1132 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1135 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1137 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1141 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1144 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1146 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1151 vfp_reg_offset (int dp
, int reg
)
1154 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1156 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1157 + offsetof(CPU_DoubleU
, l
.upper
);
1159 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1160 + offsetof(CPU_DoubleU
, l
.lower
);
1164 /* Return the offset of a 32-bit piece of a NEON register.
1165 zero is the least significant end of the register. */
1167 neon_reg_offset (int reg
, int n
)
1171 return vfp_reg_offset(0, sreg
);
1174 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1176 TCGv_i32 tmp
= tcg_temp_new_i32();
1177 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1181 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1183 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1184 tcg_temp_free_i32(var
);
1187 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1189 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1192 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1194 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1197 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1198 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1199 #define tcg_gen_st_f32 tcg_gen_st_i32
1200 #define tcg_gen_st_f64 tcg_gen_st_i64
1202 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1205 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1207 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1210 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1213 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1215 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1218 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1221 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1223 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1226 #define ARM_CP_RW_BIT (1 << 20)
1228 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1230 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1233 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1235 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1238 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1240 TCGv_i32 var
= tcg_temp_new_i32();
1241 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1245 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1247 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1248 tcg_temp_free_i32(var
);
1251 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1253 iwmmxt_store_reg(cpu_M0
, rn
);
1256 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1258 iwmmxt_load_reg(cpu_M0
, rn
);
1261 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1263 iwmmxt_load_reg(cpu_V1
, rn
);
1264 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1267 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1269 iwmmxt_load_reg(cpu_V1
, rn
);
1270 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1273 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1275 iwmmxt_load_reg(cpu_V1
, rn
);
1276 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1279 #define IWMMXT_OP(name) \
1280 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1282 iwmmxt_load_reg(cpu_V1, rn); \
1283 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1286 #define IWMMXT_OP_ENV(name) \
1287 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289 iwmmxt_load_reg(cpu_V1, rn); \
1290 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1293 #define IWMMXT_OP_ENV_SIZE(name) \
1294 IWMMXT_OP_ENV(name##b) \
1295 IWMMXT_OP_ENV(name##w) \
1296 IWMMXT_OP_ENV(name##l)
1298 #define IWMMXT_OP_ENV1(name) \
1299 static inline void gen_op_iwmmxt_##name##_M0(void) \
1301 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1315 IWMMXT_OP_ENV_SIZE(unpackl
)
1316 IWMMXT_OP_ENV_SIZE(unpackh
)
1318 IWMMXT_OP_ENV1(unpacklub
)
1319 IWMMXT_OP_ENV1(unpackluw
)
1320 IWMMXT_OP_ENV1(unpacklul
)
1321 IWMMXT_OP_ENV1(unpackhub
)
1322 IWMMXT_OP_ENV1(unpackhuw
)
1323 IWMMXT_OP_ENV1(unpackhul
)
1324 IWMMXT_OP_ENV1(unpacklsb
)
1325 IWMMXT_OP_ENV1(unpacklsw
)
1326 IWMMXT_OP_ENV1(unpacklsl
)
1327 IWMMXT_OP_ENV1(unpackhsb
)
1328 IWMMXT_OP_ENV1(unpackhsw
)
1329 IWMMXT_OP_ENV1(unpackhsl
)
1331 IWMMXT_OP_ENV_SIZE(cmpeq
)
1332 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1333 IWMMXT_OP_ENV_SIZE(cmpgts
)
1335 IWMMXT_OP_ENV_SIZE(mins
)
1336 IWMMXT_OP_ENV_SIZE(minu
)
1337 IWMMXT_OP_ENV_SIZE(maxs
)
1338 IWMMXT_OP_ENV_SIZE(maxu
)
1340 IWMMXT_OP_ENV_SIZE(subn
)
1341 IWMMXT_OP_ENV_SIZE(addn
)
1342 IWMMXT_OP_ENV_SIZE(subu
)
1343 IWMMXT_OP_ENV_SIZE(addu
)
1344 IWMMXT_OP_ENV_SIZE(subs
)
1345 IWMMXT_OP_ENV_SIZE(adds
)
1347 IWMMXT_OP_ENV(avgb0
)
1348 IWMMXT_OP_ENV(avgb1
)
1349 IWMMXT_OP_ENV(avgw0
)
1350 IWMMXT_OP_ENV(avgw1
)
1354 IWMMXT_OP_ENV(packuw
)
1355 IWMMXT_OP_ENV(packul
)
1356 IWMMXT_OP_ENV(packuq
)
1357 IWMMXT_OP_ENV(packsw
)
1358 IWMMXT_OP_ENV(packsl
)
1359 IWMMXT_OP_ENV(packsq
)
1361 static void gen_op_iwmmxt_set_mup(void)
1364 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1365 tcg_gen_ori_i32(tmp
, tmp
, 2);
1366 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1369 static void gen_op_iwmmxt_set_cup(void)
1372 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1373 tcg_gen_ori_i32(tmp
, tmp
, 1);
1374 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1377 static void gen_op_iwmmxt_setpsr_nz(void)
1379 TCGv_i32 tmp
= tcg_temp_new_i32();
1380 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1381 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1384 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1386 iwmmxt_load_reg(cpu_V1
, rn
);
1387 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1388 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1391 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1398 rd
= (insn
>> 16) & 0xf;
1399 tmp
= load_reg(s
, rd
);
1401 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1402 if (insn
& (1 << 24)) {
1404 if (insn
& (1 << 23))
1405 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1407 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1408 tcg_gen_mov_i32(dest
, tmp
);
1409 if (insn
& (1 << 21))
1410 store_reg(s
, rd
, tmp
);
1412 tcg_temp_free_i32(tmp
);
1413 } else if (insn
& (1 << 21)) {
1415 tcg_gen_mov_i32(dest
, tmp
);
1416 if (insn
& (1 << 23))
1417 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1419 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1420 store_reg(s
, rd
, tmp
);
1421 } else if (!(insn
& (1 << 23)))
1426 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1428 int rd
= (insn
>> 0) & 0xf;
1431 if (insn
& (1 << 8)) {
1432 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1435 tmp
= iwmmxt_load_creg(rd
);
1438 tmp
= tcg_temp_new_i32();
1439 iwmmxt_load_reg(cpu_V0
, rd
);
1440 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1442 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1443 tcg_gen_mov_i32(dest
, tmp
);
1444 tcg_temp_free_i32(tmp
);
1448 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1449 (ie. an undefined instruction). */
1450 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1453 int rdhi
, rdlo
, rd0
, rd1
, i
;
1455 TCGv_i32 tmp
, tmp2
, tmp3
;
1457 if ((insn
& 0x0e000e00) == 0x0c000000) {
1458 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1460 rdlo
= (insn
>> 12) & 0xf;
1461 rdhi
= (insn
>> 16) & 0xf;
1462 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1463 iwmmxt_load_reg(cpu_V0
, wrd
);
1464 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1465 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1466 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1467 } else { /* TMCRR */
1468 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1469 iwmmxt_store_reg(cpu_V0
, wrd
);
1470 gen_op_iwmmxt_set_mup();
1475 wrd
= (insn
>> 12) & 0xf;
1476 addr
= tcg_temp_new_i32();
1477 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1478 tcg_temp_free_i32(addr
);
1481 if (insn
& ARM_CP_RW_BIT
) {
1482 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1483 tmp
= tcg_temp_new_i32();
1484 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1485 iwmmxt_store_creg(wrd
, tmp
);
1488 if (insn
& (1 << 8)) {
1489 if (insn
& (1 << 22)) { /* WLDRD */
1490 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1492 } else { /* WLDRW wRd */
1493 tmp
= tcg_temp_new_i32();
1494 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1497 tmp
= tcg_temp_new_i32();
1498 if (insn
& (1 << 22)) { /* WLDRH */
1499 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1500 } else { /* WLDRB */
1501 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1505 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1506 tcg_temp_free_i32(tmp
);
1508 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1511 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1512 tmp
= iwmmxt_load_creg(wrd
);
1513 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1515 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1516 tmp
= tcg_temp_new_i32();
1517 if (insn
& (1 << 8)) {
1518 if (insn
& (1 << 22)) { /* WSTRD */
1519 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1520 } else { /* WSTRW wRd */
1521 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1522 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1525 if (insn
& (1 << 22)) { /* WSTRH */
1526 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1527 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1528 } else { /* WSTRB */
1529 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1530 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1534 tcg_temp_free_i32(tmp
);
1536 tcg_temp_free_i32(addr
);
1540 if ((insn
& 0x0f000000) != 0x0e000000)
1543 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1544 case 0x000: /* WOR */
1545 wrd
= (insn
>> 12) & 0xf;
1546 rd0
= (insn
>> 0) & 0xf;
1547 rd1
= (insn
>> 16) & 0xf;
1548 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1549 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1550 gen_op_iwmmxt_setpsr_nz();
1551 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1552 gen_op_iwmmxt_set_mup();
1553 gen_op_iwmmxt_set_cup();
1555 case 0x011: /* TMCR */
1558 rd
= (insn
>> 12) & 0xf;
1559 wrd
= (insn
>> 16) & 0xf;
1561 case ARM_IWMMXT_wCID
:
1562 case ARM_IWMMXT_wCASF
:
1564 case ARM_IWMMXT_wCon
:
1565 gen_op_iwmmxt_set_cup();
1567 case ARM_IWMMXT_wCSSF
:
1568 tmp
= iwmmxt_load_creg(wrd
);
1569 tmp2
= load_reg(s
, rd
);
1570 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1571 tcg_temp_free_i32(tmp2
);
1572 iwmmxt_store_creg(wrd
, tmp
);
1574 case ARM_IWMMXT_wCGR0
:
1575 case ARM_IWMMXT_wCGR1
:
1576 case ARM_IWMMXT_wCGR2
:
1577 case ARM_IWMMXT_wCGR3
:
1578 gen_op_iwmmxt_set_cup();
1579 tmp
= load_reg(s
, rd
);
1580 iwmmxt_store_creg(wrd
, tmp
);
1586 case 0x100: /* WXOR */
1587 wrd
= (insn
>> 12) & 0xf;
1588 rd0
= (insn
>> 0) & 0xf;
1589 rd1
= (insn
>> 16) & 0xf;
1590 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1591 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1592 gen_op_iwmmxt_setpsr_nz();
1593 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1594 gen_op_iwmmxt_set_mup();
1595 gen_op_iwmmxt_set_cup();
1597 case 0x111: /* TMRC */
1600 rd
= (insn
>> 12) & 0xf;
1601 wrd
= (insn
>> 16) & 0xf;
1602 tmp
= iwmmxt_load_creg(wrd
);
1603 store_reg(s
, rd
, tmp
);
1605 case 0x300: /* WANDN */
1606 wrd
= (insn
>> 12) & 0xf;
1607 rd0
= (insn
>> 0) & 0xf;
1608 rd1
= (insn
>> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1610 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1611 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1612 gen_op_iwmmxt_setpsr_nz();
1613 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1614 gen_op_iwmmxt_set_mup();
1615 gen_op_iwmmxt_set_cup();
1617 case 0x200: /* WAND */
1618 wrd
= (insn
>> 12) & 0xf;
1619 rd0
= (insn
>> 0) & 0xf;
1620 rd1
= (insn
>> 16) & 0xf;
1621 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1622 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1623 gen_op_iwmmxt_setpsr_nz();
1624 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1625 gen_op_iwmmxt_set_mup();
1626 gen_op_iwmmxt_set_cup();
1628 case 0x810: case 0xa10: /* WMADD */
1629 wrd
= (insn
>> 12) & 0xf;
1630 rd0
= (insn
>> 0) & 0xf;
1631 rd1
= (insn
>> 16) & 0xf;
1632 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1633 if (insn
& (1 << 21))
1634 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1636 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1638 gen_op_iwmmxt_set_mup();
1640 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1641 wrd
= (insn
>> 12) & 0xf;
1642 rd0
= (insn
>> 16) & 0xf;
1643 rd1
= (insn
>> 0) & 0xf;
1644 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1645 switch ((insn
>> 22) & 3) {
1647 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1650 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1653 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1658 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1659 gen_op_iwmmxt_set_mup();
1660 gen_op_iwmmxt_set_cup();
1662 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1663 wrd
= (insn
>> 12) & 0xf;
1664 rd0
= (insn
>> 16) & 0xf;
1665 rd1
= (insn
>> 0) & 0xf;
1666 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1667 switch ((insn
>> 22) & 3) {
1669 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1672 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1675 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1680 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1681 gen_op_iwmmxt_set_mup();
1682 gen_op_iwmmxt_set_cup();
1684 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1685 wrd
= (insn
>> 12) & 0xf;
1686 rd0
= (insn
>> 16) & 0xf;
1687 rd1
= (insn
>> 0) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1689 if (insn
& (1 << 22))
1690 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1692 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1693 if (!(insn
& (1 << 20)))
1694 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1695 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1696 gen_op_iwmmxt_set_mup();
1698 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1699 wrd
= (insn
>> 12) & 0xf;
1700 rd0
= (insn
>> 16) & 0xf;
1701 rd1
= (insn
>> 0) & 0xf;
1702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1703 if (insn
& (1 << 21)) {
1704 if (insn
& (1 << 20))
1705 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1707 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1709 if (insn
& (1 << 20))
1710 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1712 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1714 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1715 gen_op_iwmmxt_set_mup();
1717 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1718 wrd
= (insn
>> 12) & 0xf;
1719 rd0
= (insn
>> 16) & 0xf;
1720 rd1
= (insn
>> 0) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1722 if (insn
& (1 << 21))
1723 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1725 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1726 if (!(insn
& (1 << 20))) {
1727 iwmmxt_load_reg(cpu_V1
, wrd
);
1728 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1730 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1731 gen_op_iwmmxt_set_mup();
1733 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1734 wrd
= (insn
>> 12) & 0xf;
1735 rd0
= (insn
>> 16) & 0xf;
1736 rd1
= (insn
>> 0) & 0xf;
1737 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1738 switch ((insn
>> 22) & 3) {
1740 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1743 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1746 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1751 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1752 gen_op_iwmmxt_set_mup();
1753 gen_op_iwmmxt_set_cup();
1755 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1756 wrd
= (insn
>> 12) & 0xf;
1757 rd0
= (insn
>> 16) & 0xf;
1758 rd1
= (insn
>> 0) & 0xf;
1759 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1760 if (insn
& (1 << 22)) {
1761 if (insn
& (1 << 20))
1762 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1764 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1766 if (insn
& (1 << 20))
1767 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1769 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1771 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1772 gen_op_iwmmxt_set_mup();
1773 gen_op_iwmmxt_set_cup();
1775 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1776 wrd
= (insn
>> 12) & 0xf;
1777 rd0
= (insn
>> 16) & 0xf;
1778 rd1
= (insn
>> 0) & 0xf;
1779 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1780 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1781 tcg_gen_andi_i32(tmp
, tmp
, 7);
1782 iwmmxt_load_reg(cpu_V1
, rd1
);
1783 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1784 tcg_temp_free_i32(tmp
);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1786 gen_op_iwmmxt_set_mup();
1788 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1789 if (((insn
>> 6) & 3) == 3)
1791 rd
= (insn
>> 12) & 0xf;
1792 wrd
= (insn
>> 16) & 0xf;
1793 tmp
= load_reg(s
, rd
);
1794 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1795 switch ((insn
>> 6) & 3) {
1797 tmp2
= tcg_const_i32(0xff);
1798 tmp3
= tcg_const_i32((insn
& 7) << 3);
1801 tmp2
= tcg_const_i32(0xffff);
1802 tmp3
= tcg_const_i32((insn
& 3) << 4);
1805 tmp2
= tcg_const_i32(0xffffffff);
1806 tmp3
= tcg_const_i32((insn
& 1) << 5);
1809 TCGV_UNUSED_I32(tmp2
);
1810 TCGV_UNUSED_I32(tmp3
);
1812 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1813 tcg_temp_free_i32(tmp3
);
1814 tcg_temp_free_i32(tmp2
);
1815 tcg_temp_free_i32(tmp
);
1816 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1817 gen_op_iwmmxt_set_mup();
1819 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1820 rd
= (insn
>> 12) & 0xf;
1821 wrd
= (insn
>> 16) & 0xf;
1822 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1824 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1825 tmp
= tcg_temp_new_i32();
1826 switch ((insn
>> 22) & 3) {
1828 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1829 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1831 tcg_gen_ext8s_i32(tmp
, tmp
);
1833 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1837 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1838 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1840 tcg_gen_ext16s_i32(tmp
, tmp
);
1842 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1846 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1847 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1850 store_reg(s
, rd
, tmp
);
1852 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1853 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1855 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1856 switch ((insn
>> 22) & 3) {
1858 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1861 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1864 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1867 tcg_gen_shli_i32(tmp
, tmp
, 28);
1869 tcg_temp_free_i32(tmp
);
1871 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1872 if (((insn
>> 6) & 3) == 3)
1874 rd
= (insn
>> 12) & 0xf;
1875 wrd
= (insn
>> 16) & 0xf;
1876 tmp
= load_reg(s
, rd
);
1877 switch ((insn
>> 6) & 3) {
1879 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1882 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1885 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1888 tcg_temp_free_i32(tmp
);
1889 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1890 gen_op_iwmmxt_set_mup();
1892 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1893 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1895 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1896 tmp2
= tcg_temp_new_i32();
1897 tcg_gen_mov_i32(tmp2
, tmp
);
1898 switch ((insn
>> 22) & 3) {
1900 for (i
= 0; i
< 7; i
++) {
1901 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1902 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1906 for (i
= 0; i
< 3; i
++) {
1907 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1908 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1912 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1913 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1917 tcg_temp_free_i32(tmp2
);
1918 tcg_temp_free_i32(tmp
);
1920 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1921 wrd
= (insn
>> 12) & 0xf;
1922 rd0
= (insn
>> 16) & 0xf;
1923 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1924 switch ((insn
>> 22) & 3) {
1926 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1929 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1932 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1941 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1943 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1944 tmp2
= tcg_temp_new_i32();
1945 tcg_gen_mov_i32(tmp2
, tmp
);
1946 switch ((insn
>> 22) & 3) {
1948 for (i
= 0; i
< 7; i
++) {
1949 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1950 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1954 for (i
= 0; i
< 3; i
++) {
1955 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1956 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1960 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1961 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1965 tcg_temp_free_i32(tmp2
);
1966 tcg_temp_free_i32(tmp
);
1968 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1969 rd
= (insn
>> 12) & 0xf;
1970 rd0
= (insn
>> 16) & 0xf;
1971 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1973 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1974 tmp
= tcg_temp_new_i32();
1975 switch ((insn
>> 22) & 3) {
1977 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1980 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1983 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1986 store_reg(s
, rd
, tmp
);
1988 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1989 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1990 wrd
= (insn
>> 12) & 0xf;
1991 rd0
= (insn
>> 16) & 0xf;
1992 rd1
= (insn
>> 0) & 0xf;
1993 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1994 switch ((insn
>> 22) & 3) {
1996 if (insn
& (1 << 21))
1997 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1999 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2002 if (insn
& (1 << 21))
2003 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2005 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2008 if (insn
& (1 << 21))
2009 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2011 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2016 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2017 gen_op_iwmmxt_set_mup();
2018 gen_op_iwmmxt_set_cup();
2020 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2021 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2022 wrd
= (insn
>> 12) & 0xf;
2023 rd0
= (insn
>> 16) & 0xf;
2024 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2025 switch ((insn
>> 22) & 3) {
2027 if (insn
& (1 << 21))
2028 gen_op_iwmmxt_unpacklsb_M0();
2030 gen_op_iwmmxt_unpacklub_M0();
2033 if (insn
& (1 << 21))
2034 gen_op_iwmmxt_unpacklsw_M0();
2036 gen_op_iwmmxt_unpackluw_M0();
2039 if (insn
& (1 << 21))
2040 gen_op_iwmmxt_unpacklsl_M0();
2042 gen_op_iwmmxt_unpacklul_M0();
2047 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2052 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2053 wrd
= (insn
>> 12) & 0xf;
2054 rd0
= (insn
>> 16) & 0xf;
2055 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2056 switch ((insn
>> 22) & 3) {
2058 if (insn
& (1 << 21))
2059 gen_op_iwmmxt_unpackhsb_M0();
2061 gen_op_iwmmxt_unpackhub_M0();
2064 if (insn
& (1 << 21))
2065 gen_op_iwmmxt_unpackhsw_M0();
2067 gen_op_iwmmxt_unpackhuw_M0();
2070 if (insn
& (1 << 21))
2071 gen_op_iwmmxt_unpackhsl_M0();
2073 gen_op_iwmmxt_unpackhul_M0();
2078 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2082 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2083 case 0x214: case 0x614: case 0xa14: case 0xe14:
2084 if (((insn
>> 22) & 3) == 0)
2086 wrd
= (insn
>> 12) & 0xf;
2087 rd0
= (insn
>> 16) & 0xf;
2088 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2089 tmp
= tcg_temp_new_i32();
2090 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2091 tcg_temp_free_i32(tmp
);
2094 switch ((insn
>> 22) & 3) {
2096 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2099 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2102 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2105 tcg_temp_free_i32(tmp
);
2106 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2107 gen_op_iwmmxt_set_mup();
2108 gen_op_iwmmxt_set_cup();
2110 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2111 case 0x014: case 0x414: case 0x814: case 0xc14:
2112 if (((insn
>> 22) & 3) == 0)
2114 wrd
= (insn
>> 12) & 0xf;
2115 rd0
= (insn
>> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2117 tmp
= tcg_temp_new_i32();
2118 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2119 tcg_temp_free_i32(tmp
);
2122 switch ((insn
>> 22) & 3) {
2124 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2127 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2130 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2133 tcg_temp_free_i32(tmp
);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2138 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2139 case 0x114: case 0x514: case 0x914: case 0xd14:
2140 if (((insn
>> 22) & 3) == 0)
2142 wrd
= (insn
>> 12) & 0xf;
2143 rd0
= (insn
>> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2145 tmp
= tcg_temp_new_i32();
2146 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2147 tcg_temp_free_i32(tmp
);
2150 switch ((insn
>> 22) & 3) {
2152 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2155 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2158 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2161 tcg_temp_free_i32(tmp
);
2162 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2163 gen_op_iwmmxt_set_mup();
2164 gen_op_iwmmxt_set_cup();
2166 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2167 case 0x314: case 0x714: case 0xb14: case 0xf14:
2168 if (((insn
>> 22) & 3) == 0)
2170 wrd
= (insn
>> 12) & 0xf;
2171 rd0
= (insn
>> 16) & 0xf;
2172 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2173 tmp
= tcg_temp_new_i32();
2174 switch ((insn
>> 22) & 3) {
2176 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2177 tcg_temp_free_i32(tmp
);
2180 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2183 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2184 tcg_temp_free_i32(tmp
);
2187 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2190 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2191 tcg_temp_free_i32(tmp
);
2194 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2197 tcg_temp_free_i32(tmp
);
2198 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2202 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2203 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2204 wrd
= (insn
>> 12) & 0xf;
2205 rd0
= (insn
>> 16) & 0xf;
2206 rd1
= (insn
>> 0) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2208 switch ((insn
>> 22) & 3) {
2210 if (insn
& (1 << 21))
2211 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2213 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2216 if (insn
& (1 << 21))
2217 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2219 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2222 if (insn
& (1 << 21))
2223 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2225 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2230 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2231 gen_op_iwmmxt_set_mup();
2233 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2234 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2235 wrd
= (insn
>> 12) & 0xf;
2236 rd0
= (insn
>> 16) & 0xf;
2237 rd1
= (insn
>> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 switch ((insn
>> 22) & 3) {
2241 if (insn
& (1 << 21))
2242 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2244 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2247 if (insn
& (1 << 21))
2248 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2250 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2253 if (insn
& (1 << 21))
2254 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2256 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2261 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2262 gen_op_iwmmxt_set_mup();
2264 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2265 case 0x402: case 0x502: case 0x602: case 0x702:
2266 wrd
= (insn
>> 12) & 0xf;
2267 rd0
= (insn
>> 16) & 0xf;
2268 rd1
= (insn
>> 0) & 0xf;
2269 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2270 tmp
= tcg_const_i32((insn
>> 20) & 3);
2271 iwmmxt_load_reg(cpu_V1
, rd1
);
2272 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2273 tcg_temp_free_i32(tmp
);
2274 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2275 gen_op_iwmmxt_set_mup();
2277 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2278 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2279 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2280 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2281 wrd
= (insn
>> 12) & 0xf;
2282 rd0
= (insn
>> 16) & 0xf;
2283 rd1
= (insn
>> 0) & 0xf;
2284 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2285 switch ((insn
>> 20) & 0xf) {
2287 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2290 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2293 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2296 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2299 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2302 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2308 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2311 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2316 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2317 gen_op_iwmmxt_set_mup();
2318 gen_op_iwmmxt_set_cup();
2320 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2321 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2322 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2323 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2324 wrd
= (insn
>> 12) & 0xf;
2325 rd0
= (insn
>> 16) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2327 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2328 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2329 tcg_temp_free_i32(tmp
);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2334 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2335 case 0x418: case 0x518: case 0x618: case 0x718:
2336 case 0x818: case 0x918: case 0xa18: case 0xb18:
2337 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2338 wrd
= (insn
>> 12) & 0xf;
2339 rd0
= (insn
>> 16) & 0xf;
2340 rd1
= (insn
>> 0) & 0xf;
2341 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2342 switch ((insn
>> 20) & 0xf) {
2344 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2347 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2350 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2353 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2356 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2359 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2362 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2365 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2368 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2373 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2374 gen_op_iwmmxt_set_mup();
2375 gen_op_iwmmxt_set_cup();
2377 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2378 case 0x408: case 0x508: case 0x608: case 0x708:
2379 case 0x808: case 0x908: case 0xa08: case 0xb08:
2380 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2381 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2383 wrd
= (insn
>> 12) & 0xf;
2384 rd0
= (insn
>> 16) & 0xf;
2385 rd1
= (insn
>> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2387 switch ((insn
>> 22) & 3) {
2389 if (insn
& (1 << 21))
2390 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2392 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2395 if (insn
& (1 << 21))
2396 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2398 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2401 if (insn
& (1 << 21))
2402 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2404 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2407 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2408 gen_op_iwmmxt_set_mup();
2409 gen_op_iwmmxt_set_cup();
2411 case 0x201: case 0x203: case 0x205: case 0x207:
2412 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2413 case 0x211: case 0x213: case 0x215: case 0x217:
2414 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2415 wrd
= (insn
>> 5) & 0xf;
2416 rd0
= (insn
>> 12) & 0xf;
2417 rd1
= (insn
>> 0) & 0xf;
2418 if (rd0
== 0xf || rd1
== 0xf)
2420 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2421 tmp
= load_reg(s
, rd0
);
2422 tmp2
= load_reg(s
, rd1
);
2423 switch ((insn
>> 16) & 0xf) {
2424 case 0x0: /* TMIA */
2425 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2427 case 0x8: /* TMIAPH */
2428 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2430 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2431 if (insn
& (1 << 16))
2432 tcg_gen_shri_i32(tmp
, tmp
, 16);
2433 if (insn
& (1 << 17))
2434 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2435 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2438 tcg_temp_free_i32(tmp2
);
2439 tcg_temp_free_i32(tmp
);
2442 tcg_temp_free_i32(tmp2
);
2443 tcg_temp_free_i32(tmp
);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2445 gen_op_iwmmxt_set_mup();
2454 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2455 (ie. an undefined instruction). */
2456 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2458 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2461 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2462 /* Multiply with Internal Accumulate Format */
2463 rd0
= (insn
>> 12) & 0xf;
2465 acc
= (insn
>> 5) & 7;
2470 tmp
= load_reg(s
, rd0
);
2471 tmp2
= load_reg(s
, rd1
);
2472 switch ((insn
>> 16) & 0xf) {
2474 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2476 case 0x8: /* MIAPH */
2477 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2479 case 0xc: /* MIABB */
2480 case 0xd: /* MIABT */
2481 case 0xe: /* MIATB */
2482 case 0xf: /* MIATT */
2483 if (insn
& (1 << 16))
2484 tcg_gen_shri_i32(tmp
, tmp
, 16);
2485 if (insn
& (1 << 17))
2486 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2487 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2492 tcg_temp_free_i32(tmp2
);
2493 tcg_temp_free_i32(tmp
);
2495 gen_op_iwmmxt_movq_wRn_M0(acc
);
2499 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2500 /* Internal Accumulator Access Format */
2501 rdhi
= (insn
>> 16) & 0xf;
2502 rdlo
= (insn
>> 12) & 0xf;
2508 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2509 iwmmxt_load_reg(cpu_V0
, acc
);
2510 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2511 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2512 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2513 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2515 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2516 iwmmxt_store_reg(cpu_V0
, acc
);
2524 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2525 #define VFP_SREG(insn, bigbit, smallbit) \
2526 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2527 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2528 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2529 reg = (((insn) >> (bigbit)) & 0x0f) \
2530 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2532 if (insn & (1 << (smallbit))) \
2534 reg = ((insn) >> (bigbit)) & 0x0f; \
2537 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2538 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2539 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2540 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2541 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2542 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2544 /* Move between integer and VFP cores. */
2545 static TCGv_i32
gen_vfp_mrs(void)
2547 TCGv_i32 tmp
= tcg_temp_new_i32();
2548 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2552 static void gen_vfp_msr(TCGv_i32 tmp
)
2554 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2555 tcg_temp_free_i32(tmp
);
2558 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2560 TCGv_i32 tmp
= tcg_temp_new_i32();
2562 tcg_gen_shri_i32(var
, var
, shift
);
2563 tcg_gen_ext8u_i32(var
, var
);
2564 tcg_gen_shli_i32(tmp
, var
, 8);
2565 tcg_gen_or_i32(var
, var
, tmp
);
2566 tcg_gen_shli_i32(tmp
, var
, 16);
2567 tcg_gen_or_i32(var
, var
, tmp
);
2568 tcg_temp_free_i32(tmp
);
2571 static void gen_neon_dup_low16(TCGv_i32 var
)
2573 TCGv_i32 tmp
= tcg_temp_new_i32();
2574 tcg_gen_ext16u_i32(var
, var
);
2575 tcg_gen_shli_i32(tmp
, var
, 16);
2576 tcg_gen_or_i32(var
, var
, tmp
);
2577 tcg_temp_free_i32(tmp
);
2580 static void gen_neon_dup_high16(TCGv_i32 var
)
2582 TCGv_i32 tmp
= tcg_temp_new_i32();
2583 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2584 tcg_gen_shri_i32(tmp
, var
, 16);
2585 tcg_gen_or_i32(var
, var
, tmp
);
2586 tcg_temp_free_i32(tmp
);
2589 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2591 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2592 TCGv_i32 tmp
= tcg_temp_new_i32();
2595 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2596 gen_neon_dup_u8(tmp
, 0);
2599 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2600 gen_neon_dup_low16(tmp
);
2603 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2605 default: /* Avoid compiler warnings. */
2611 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2614 uint32_t cc
= extract32(insn
, 20, 2);
2617 TCGv_i64 frn
, frm
, dest
;
2618 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2620 zero
= tcg_const_i64(0);
2622 frn
= tcg_temp_new_i64();
2623 frm
= tcg_temp_new_i64();
2624 dest
= tcg_temp_new_i64();
2626 zf
= tcg_temp_new_i64();
2627 nf
= tcg_temp_new_i64();
2628 vf
= tcg_temp_new_i64();
2630 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2631 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2632 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2634 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2635 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2638 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2642 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2645 case 2: /* ge: N == V -> N ^ V == 0 */
2646 tmp
= tcg_temp_new_i64();
2647 tcg_gen_xor_i64(tmp
, vf
, nf
);
2648 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2650 tcg_temp_free_i64(tmp
);
2652 case 3: /* gt: !Z && N == V */
2653 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2655 tmp
= tcg_temp_new_i64();
2656 tcg_gen_xor_i64(tmp
, vf
, nf
);
2657 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2659 tcg_temp_free_i64(tmp
);
2662 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2663 tcg_temp_free_i64(frn
);
2664 tcg_temp_free_i64(frm
);
2665 tcg_temp_free_i64(dest
);
2667 tcg_temp_free_i64(zf
);
2668 tcg_temp_free_i64(nf
);
2669 tcg_temp_free_i64(vf
);
2671 tcg_temp_free_i64(zero
);
2673 TCGv_i32 frn
, frm
, dest
;
2676 zero
= tcg_const_i32(0);
2678 frn
= tcg_temp_new_i32();
2679 frm
= tcg_temp_new_i32();
2680 dest
= tcg_temp_new_i32();
2681 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2682 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2685 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2689 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2692 case 2: /* ge: N == V -> N ^ V == 0 */
2693 tmp
= tcg_temp_new_i32();
2694 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2695 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2697 tcg_temp_free_i32(tmp
);
2699 case 3: /* gt: !Z && N == V */
2700 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2702 tmp
= tcg_temp_new_i32();
2703 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2704 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2706 tcg_temp_free_i32(tmp
);
2709 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2710 tcg_temp_free_i32(frn
);
2711 tcg_temp_free_i32(frm
);
2712 tcg_temp_free_i32(dest
);
2714 tcg_temp_free_i32(zero
);
2720 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2721 uint32_t rm
, uint32_t dp
)
2723 uint32_t vmin
= extract32(insn
, 6, 1);
2724 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2727 TCGv_i64 frn
, frm
, dest
;
2729 frn
= tcg_temp_new_i64();
2730 frm
= tcg_temp_new_i64();
2731 dest
= tcg_temp_new_i64();
2733 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2734 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2736 gen_helper_vfp_minnmd(dest
, frn
, frm
, fpst
);
2738 gen_helper_vfp_maxnmd(dest
, frn
, frm
, fpst
);
2740 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2741 tcg_temp_free_i64(frn
);
2742 tcg_temp_free_i64(frm
);
2743 tcg_temp_free_i64(dest
);
2745 TCGv_i32 frn
, frm
, dest
;
2747 frn
= tcg_temp_new_i32();
2748 frm
= tcg_temp_new_i32();
2749 dest
= tcg_temp_new_i32();
2751 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2752 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2754 gen_helper_vfp_minnms(dest
, frn
, frm
, fpst
);
2756 gen_helper_vfp_maxnms(dest
, frn
, frm
, fpst
);
2758 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2759 tcg_temp_free_i32(frn
);
2760 tcg_temp_free_i32(frm
);
2761 tcg_temp_free_i32(dest
);
2764 tcg_temp_free_ptr(fpst
);
2768 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2770 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2772 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2777 VFP_DREG_D(rd
, insn
);
2778 VFP_DREG_N(rn
, insn
);
2779 VFP_DREG_M(rm
, insn
);
2781 rd
= VFP_SREG_D(insn
);
2782 rn
= VFP_SREG_N(insn
);
2783 rm
= VFP_SREG_M(insn
);
2786 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2787 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2788 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2789 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2794 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2795 (ie. an undefined instruction). */
2796 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2798 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2804 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2807 if (!s
->vfp_enabled
) {
2808 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2809 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2811 rn
= (insn
>> 16) & 0xf;
2812 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2813 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2817 if (extract32(insn
, 28, 4) == 0xf) {
2818 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2819 * only used in v8 and above.
2821 return disas_vfp_v8_insn(env
, s
, insn
);
2824 dp
= ((insn
& 0xf00) == 0xb00);
2825 switch ((insn
>> 24) & 0xf) {
2827 if (insn
& (1 << 4)) {
2828 /* single register transfer */
2829 rd
= (insn
>> 12) & 0xf;
2834 VFP_DREG_N(rn
, insn
);
2837 if (insn
& 0x00c00060
2838 && !arm_feature(env
, ARM_FEATURE_NEON
))
2841 pass
= (insn
>> 21) & 1;
2842 if (insn
& (1 << 22)) {
2844 offset
= ((insn
>> 5) & 3) * 8;
2845 } else if (insn
& (1 << 5)) {
2847 offset
= (insn
& (1 << 6)) ? 16 : 0;
2852 if (insn
& ARM_CP_RW_BIT
) {
2854 tmp
= neon_load_reg(rn
, pass
);
2858 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2859 if (insn
& (1 << 23))
2865 if (insn
& (1 << 23)) {
2867 tcg_gen_shri_i32(tmp
, tmp
, 16);
2873 tcg_gen_sari_i32(tmp
, tmp
, 16);
2882 store_reg(s
, rd
, tmp
);
2885 tmp
= load_reg(s
, rd
);
2886 if (insn
& (1 << 23)) {
2889 gen_neon_dup_u8(tmp
, 0);
2890 } else if (size
== 1) {
2891 gen_neon_dup_low16(tmp
);
2893 for (n
= 0; n
<= pass
* 2; n
++) {
2894 tmp2
= tcg_temp_new_i32();
2895 tcg_gen_mov_i32(tmp2
, tmp
);
2896 neon_store_reg(rn
, n
, tmp2
);
2898 neon_store_reg(rn
, n
, tmp
);
2903 tmp2
= neon_load_reg(rn
, pass
);
2904 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2905 tcg_temp_free_i32(tmp2
);
2908 tmp2
= neon_load_reg(rn
, pass
);
2909 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2910 tcg_temp_free_i32(tmp2
);
2915 neon_store_reg(rn
, pass
, tmp
);
2919 if ((insn
& 0x6f) != 0x00)
2921 rn
= VFP_SREG_N(insn
);
2922 if (insn
& ARM_CP_RW_BIT
) {
2924 if (insn
& (1 << 21)) {
2925 /* system register */
2930 /* VFP2 allows access to FSID from userspace.
2931 VFP3 restricts all id registers to privileged
2934 && arm_feature(env
, ARM_FEATURE_VFP3
))
2936 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2941 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2943 case ARM_VFP_FPINST
:
2944 case ARM_VFP_FPINST2
:
2945 /* Not present in VFP3. */
2947 || arm_feature(env
, ARM_FEATURE_VFP3
))
2949 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2953 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2954 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2956 tmp
= tcg_temp_new_i32();
2957 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2963 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2965 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2971 gen_mov_F0_vreg(0, rn
);
2972 tmp
= gen_vfp_mrs();
2975 /* Set the 4 flag bits in the CPSR. */
2977 tcg_temp_free_i32(tmp
);
2979 store_reg(s
, rd
, tmp
);
2983 if (insn
& (1 << 21)) {
2985 /* system register */
2990 /* Writes are ignored. */
2993 tmp
= load_reg(s
, rd
);
2994 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2995 tcg_temp_free_i32(tmp
);
3001 /* TODO: VFP subarchitecture support.
3002 * For now, keep the EN bit only */
3003 tmp
= load_reg(s
, rd
);
3004 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3005 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3008 case ARM_VFP_FPINST
:
3009 case ARM_VFP_FPINST2
:
3010 tmp
= load_reg(s
, rd
);
3011 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3017 tmp
= load_reg(s
, rd
);
3019 gen_mov_vreg_F0(0, rn
);
3024 /* data processing */
3025 /* The opcode is in bits 23, 21, 20 and 6. */
3026 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3030 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3032 /* rn is register number */
3033 VFP_DREG_N(rn
, insn
);
3036 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
3037 /* Integer or single precision destination. */
3038 rd
= VFP_SREG_D(insn
);
3040 VFP_DREG_D(rd
, insn
);
3043 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
3044 /* VCVT from int is always from S reg regardless of dp bit.
3045 * VCVT with immediate frac_bits has same format as SREG_M
3047 rm
= VFP_SREG_M(insn
);
3049 VFP_DREG_M(rm
, insn
);
3052 rn
= VFP_SREG_N(insn
);
3053 if (op
== 15 && rn
== 15) {
3054 /* Double precision destination. */
3055 VFP_DREG_D(rd
, insn
);
3057 rd
= VFP_SREG_D(insn
);
3059 /* NB that we implicitly rely on the encoding for the frac_bits
3060 * in VCVT of fixed to float being the same as that of an SREG_M
3062 rm
= VFP_SREG_M(insn
);
3065 veclen
= s
->vec_len
;
3066 if (op
== 15 && rn
> 3)
3069 /* Shut up compiler warnings. */
3080 /* Figure out what type of vector operation this is. */
3081 if ((rd
& bank_mask
) == 0) {
3086 delta_d
= (s
->vec_stride
>> 1) + 1;
3088 delta_d
= s
->vec_stride
+ 1;
3090 if ((rm
& bank_mask
) == 0) {
3091 /* mixed scalar/vector */
3100 /* Load the initial operands. */
3105 /* Integer source */
3106 gen_mov_F0_vreg(0, rm
);
3111 gen_mov_F0_vreg(dp
, rd
);
3112 gen_mov_F1_vreg(dp
, rm
);
3116 /* Compare with zero */
3117 gen_mov_F0_vreg(dp
, rd
);
3128 /* Source and destination the same. */
3129 gen_mov_F0_vreg(dp
, rd
);
3135 /* VCVTB, VCVTT: only present with the halfprec extension,
3136 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3138 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3141 /* Otherwise fall through */
3143 /* One source operand. */
3144 gen_mov_F0_vreg(dp
, rm
);
3148 /* Two source operands. */
3149 gen_mov_F0_vreg(dp
, rn
);
3150 gen_mov_F1_vreg(dp
, rm
);
3154 /* Perform the calculation. */
3156 case 0: /* VMLA: fd + (fn * fm) */
3157 /* Note that order of inputs to the add matters for NaNs */
3159 gen_mov_F0_vreg(dp
, rd
);
3162 case 1: /* VMLS: fd + -(fn * fm) */
3165 gen_mov_F0_vreg(dp
, rd
);
3168 case 2: /* VNMLS: -fd + (fn * fm) */
3169 /* Note that it isn't valid to replace (-A + B) with (B - A)
3170 * or similar plausible looking simplifications
3171 * because this will give wrong results for NaNs.
3174 gen_mov_F0_vreg(dp
, rd
);
3178 case 3: /* VNMLA: -fd + -(fn * fm) */
3181 gen_mov_F0_vreg(dp
, rd
);
3185 case 4: /* mul: fn * fm */
3188 case 5: /* nmul: -(fn * fm) */
3192 case 6: /* add: fn + fm */
3195 case 7: /* sub: fn - fm */
3198 case 8: /* div: fn / fm */
3201 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3202 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3203 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3204 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3205 /* These are fused multiply-add, and must be done as one
3206 * floating point operation with no rounding between the
3207 * multiplication and addition steps.
3208 * NB that doing the negations here as separate steps is
3209 * correct : an input NaN should come out with its sign bit
3210 * flipped if it is a negated-input.
3212 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3220 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3222 frd
= tcg_temp_new_i64();
3223 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3226 gen_helper_vfp_negd(frd
, frd
);
3228 fpst
= get_fpstatus_ptr(0);
3229 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3230 cpu_F1d
, frd
, fpst
);
3231 tcg_temp_free_ptr(fpst
);
3232 tcg_temp_free_i64(frd
);
3238 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3240 frd
= tcg_temp_new_i32();
3241 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3243 gen_helper_vfp_negs(frd
, frd
);
3245 fpst
= get_fpstatus_ptr(0);
3246 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3247 cpu_F1s
, frd
, fpst
);
3248 tcg_temp_free_ptr(fpst
);
3249 tcg_temp_free_i32(frd
);
3252 case 14: /* fconst */
3253 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3256 n
= (insn
<< 12) & 0x80000000;
3257 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3264 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3271 tcg_gen_movi_i32(cpu_F0s
, n
);
3274 case 15: /* extension space */
3288 case 4: /* vcvtb.f32.f16 */
3289 tmp
= gen_vfp_mrs();
3290 tcg_gen_ext16u_i32(tmp
, tmp
);
3291 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3292 tcg_temp_free_i32(tmp
);
3294 case 5: /* vcvtt.f32.f16 */
3295 tmp
= gen_vfp_mrs();
3296 tcg_gen_shri_i32(tmp
, tmp
, 16);
3297 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3298 tcg_temp_free_i32(tmp
);
3300 case 6: /* vcvtb.f16.f32 */
3301 tmp
= tcg_temp_new_i32();
3302 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3303 gen_mov_F0_vreg(0, rd
);
3304 tmp2
= gen_vfp_mrs();
3305 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3306 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3307 tcg_temp_free_i32(tmp2
);
3310 case 7: /* vcvtt.f16.f32 */
3311 tmp
= tcg_temp_new_i32();
3312 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3313 tcg_gen_shli_i32(tmp
, tmp
, 16);
3314 gen_mov_F0_vreg(0, rd
);
3315 tmp2
= gen_vfp_mrs();
3316 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3317 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3318 tcg_temp_free_i32(tmp2
);
3330 case 11: /* cmpez */
3334 case 15: /* single<->double conversion */
3336 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3338 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3340 case 16: /* fuito */
3341 gen_vfp_uito(dp
, 0);
3343 case 17: /* fsito */
3344 gen_vfp_sito(dp
, 0);
3346 case 20: /* fshto */
3347 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3349 gen_vfp_shto(dp
, 16 - rm
, 0);
3351 case 21: /* fslto */
3352 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3354 gen_vfp_slto(dp
, 32 - rm
, 0);
3356 case 22: /* fuhto */
3357 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3359 gen_vfp_uhto(dp
, 16 - rm
, 0);
3361 case 23: /* fulto */
3362 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3364 gen_vfp_ulto(dp
, 32 - rm
, 0);
3366 case 24: /* ftoui */
3367 gen_vfp_toui(dp
, 0);
3369 case 25: /* ftouiz */
3370 gen_vfp_touiz(dp
, 0);
3372 case 26: /* ftosi */
3373 gen_vfp_tosi(dp
, 0);
3375 case 27: /* ftosiz */
3376 gen_vfp_tosiz(dp
, 0);
3378 case 28: /* ftosh */
3379 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3381 gen_vfp_tosh(dp
, 16 - rm
, 0);
3383 case 29: /* ftosl */
3384 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3386 gen_vfp_tosl(dp
, 32 - rm
, 0);
3388 case 30: /* ftouh */
3389 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3391 gen_vfp_touh(dp
, 16 - rm
, 0);
3393 case 31: /* ftoul */
3394 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3396 gen_vfp_toul(dp
, 32 - rm
, 0);
3398 default: /* undefined */
3402 default: /* undefined */
3406 /* Write back the result. */
3407 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3408 ; /* Comparison, do nothing. */
3409 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3410 /* VCVT double to int: always integer result. */
3411 gen_mov_vreg_F0(0, rd
);
3412 else if (op
== 15 && rn
== 15)
3414 gen_mov_vreg_F0(!dp
, rd
);
3416 gen_mov_vreg_F0(dp
, rd
);
3418 /* break out of the loop if we have finished */
3422 if (op
== 15 && delta_m
== 0) {
3423 /* single source one-many */
3425 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3427 gen_mov_vreg_F0(dp
, rd
);
3431 /* Setup the next operands. */
3433 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3437 /* One source operand. */
3438 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3440 gen_mov_F0_vreg(dp
, rm
);
3442 /* Two source operands. */
3443 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3445 gen_mov_F0_vreg(dp
, rn
);
3447 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3449 gen_mov_F1_vreg(dp
, rm
);
3457 if ((insn
& 0x03e00000) == 0x00400000) {
3458 /* two-register transfer */
3459 rn
= (insn
>> 16) & 0xf;
3460 rd
= (insn
>> 12) & 0xf;
3462 VFP_DREG_M(rm
, insn
);
3464 rm
= VFP_SREG_M(insn
);
3467 if (insn
& ARM_CP_RW_BIT
) {
3470 gen_mov_F0_vreg(0, rm
* 2);
3471 tmp
= gen_vfp_mrs();
3472 store_reg(s
, rd
, tmp
);
3473 gen_mov_F0_vreg(0, rm
* 2 + 1);
3474 tmp
= gen_vfp_mrs();
3475 store_reg(s
, rn
, tmp
);
3477 gen_mov_F0_vreg(0, rm
);
3478 tmp
= gen_vfp_mrs();
3479 store_reg(s
, rd
, tmp
);
3480 gen_mov_F0_vreg(0, rm
+ 1);
3481 tmp
= gen_vfp_mrs();
3482 store_reg(s
, rn
, tmp
);
3487 tmp
= load_reg(s
, rd
);
3489 gen_mov_vreg_F0(0, rm
* 2);
3490 tmp
= load_reg(s
, rn
);
3492 gen_mov_vreg_F0(0, rm
* 2 + 1);
3494 tmp
= load_reg(s
, rd
);
3496 gen_mov_vreg_F0(0, rm
);
3497 tmp
= load_reg(s
, rn
);
3499 gen_mov_vreg_F0(0, rm
+ 1);
3504 rn
= (insn
>> 16) & 0xf;
3506 VFP_DREG_D(rd
, insn
);
3508 rd
= VFP_SREG_D(insn
);
3509 if ((insn
& 0x01200000) == 0x01000000) {
3510 /* Single load/store */
3511 offset
= (insn
& 0xff) << 2;
3512 if ((insn
& (1 << 23)) == 0)
3514 if (s
->thumb
&& rn
== 15) {
3515 /* This is actually UNPREDICTABLE */
3516 addr
= tcg_temp_new_i32();
3517 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3519 addr
= load_reg(s
, rn
);
3521 tcg_gen_addi_i32(addr
, addr
, offset
);
3522 if (insn
& (1 << 20)) {
3523 gen_vfp_ld(s
, dp
, addr
);
3524 gen_mov_vreg_F0(dp
, rd
);
3526 gen_mov_F0_vreg(dp
, rd
);
3527 gen_vfp_st(s
, dp
, addr
);
3529 tcg_temp_free_i32(addr
);
3531 /* load/store multiple */
3532 int w
= insn
& (1 << 21);
3534 n
= (insn
>> 1) & 0x7f;
3538 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3539 /* P == U , W == 1 => UNDEF */
3542 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3543 /* UNPREDICTABLE cases for bad immediates: we choose to
3544 * UNDEF to avoid generating huge numbers of TCG ops
3548 if (rn
== 15 && w
) {
3549 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3553 if (s
->thumb
&& rn
== 15) {
3554 /* This is actually UNPREDICTABLE */
3555 addr
= tcg_temp_new_i32();
3556 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3558 addr
= load_reg(s
, rn
);
3560 if (insn
& (1 << 24)) /* pre-decrement */
3561 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3567 for (i
= 0; i
< n
; i
++) {
3568 if (insn
& ARM_CP_RW_BIT
) {
3570 gen_vfp_ld(s
, dp
, addr
);
3571 gen_mov_vreg_F0(dp
, rd
+ i
);
3574 gen_mov_F0_vreg(dp
, rd
+ i
);
3575 gen_vfp_st(s
, dp
, addr
);
3577 tcg_gen_addi_i32(addr
, addr
, offset
);
3581 if (insn
& (1 << 24))
3582 offset
= -offset
* n
;
3583 else if (dp
&& (insn
& 1))
3589 tcg_gen_addi_i32(addr
, addr
, offset
);
3590 store_reg(s
, rn
, addr
);
3592 tcg_temp_free_i32(addr
);
3598 /* Should never happen. */
3604 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3606 TranslationBlock
*tb
;
3609 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3611 gen_set_pc_im(s
, dest
);
3612 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3614 gen_set_pc_im(s
, dest
);
3619 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3621 if (unlikely(s
->singlestep_enabled
)) {
3622 /* An indirect jump so that we still trigger the debug exception. */
3627 gen_goto_tb(s
, 0, dest
);
3628 s
->is_jmp
= DISAS_TB_JUMP
;
3632 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3635 tcg_gen_sari_i32(t0
, t0
, 16);
3639 tcg_gen_sari_i32(t1
, t1
, 16);
3642 tcg_gen_mul_i32(t0
, t0
, t1
);
3645 /* Return the mask of PSR bits set by a MSR instruction. */
3646 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3650 if (flags
& (1 << 0))
3652 if (flags
& (1 << 1))
3654 if (flags
& (1 << 2))
3656 if (flags
& (1 << 3))
3659 /* Mask out undefined bits. */
3660 mask
&= ~CPSR_RESERVED
;
3661 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3663 if (!arm_feature(env
, ARM_FEATURE_V5
))
3664 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3665 if (!arm_feature(env
, ARM_FEATURE_V6
))
3666 mask
&= ~(CPSR_E
| CPSR_GE
);
3667 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3669 /* Mask out execution state bits. */
3672 /* Mask out privileged bits. */
3678 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3679 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3683 /* ??? This is also undefined in system mode. */
3687 tmp
= load_cpu_field(spsr
);
3688 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3689 tcg_gen_andi_i32(t0
, t0
, mask
);
3690 tcg_gen_or_i32(tmp
, tmp
, t0
);
3691 store_cpu_field(tmp
, spsr
);
3693 gen_set_cpsr(t0
, mask
);
3695 tcg_temp_free_i32(t0
);
3700 /* Returns nonzero if access to the PSR is not permitted. */
3701 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3704 tmp
= tcg_temp_new_i32();
3705 tcg_gen_movi_i32(tmp
, val
);
3706 return gen_set_psr(s
, mask
, spsr
, tmp
);
3709 /* Generate an old-style exception return. Marks pc as dead. */
3710 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3713 store_reg(s
, 15, pc
);
3714 tmp
= load_cpu_field(spsr
);
3715 gen_set_cpsr(tmp
, 0xffffffff);
3716 tcg_temp_free_i32(tmp
);
3717 s
->is_jmp
= DISAS_UPDATE
;
3720 /* Generate a v6 exception return. Marks both values as dead. */
3721 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3723 gen_set_cpsr(cpsr
, 0xffffffff);
3724 tcg_temp_free_i32(cpsr
);
3725 store_reg(s
, 15, pc
);
3726 s
->is_jmp
= DISAS_UPDATE
;
3730 gen_set_condexec (DisasContext
*s
)
3732 if (s
->condexec_mask
) {
3733 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3734 TCGv_i32 tmp
= tcg_temp_new_i32();
3735 tcg_gen_movi_i32(tmp
, val
);
3736 store_cpu_field(tmp
, condexec_bits
);
3740 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3742 gen_set_condexec(s
);
3743 gen_set_pc_im(s
, s
->pc
- offset
);
3744 gen_exception(excp
);
3745 s
->is_jmp
= DISAS_JUMP
;
3748 static void gen_nop_hint(DisasContext
*s
, int val
)
3752 gen_set_pc_im(s
, s
->pc
);
3753 s
->is_jmp
= DISAS_WFI
;
3758 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3764 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3766 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3769 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3770 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3771 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3776 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3779 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3780 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3781 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3786 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3787 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3788 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3789 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3790 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3792 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3793 switch ((size << 1) | u) { \
3795 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3798 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3801 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3804 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3807 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3810 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3812 default: return 1; \
3815 #define GEN_NEON_INTEGER_OP(name) do { \
3816 switch ((size << 1) | u) { \
3818 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3821 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3824 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3827 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3830 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3833 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3835 default: return 1; \
3838 static TCGv_i32
neon_load_scratch(int scratch
)
3840 TCGv_i32 tmp
= tcg_temp_new_i32();
3841 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3845 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3847 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3848 tcg_temp_free_i32(var
);
3851 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3855 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3857 gen_neon_dup_high16(tmp
);
3859 gen_neon_dup_low16(tmp
);
3862 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3867 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3870 if (!q
&& size
== 2) {
3873 tmp
= tcg_const_i32(rd
);
3874 tmp2
= tcg_const_i32(rm
);
3878 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3881 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3884 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3892 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3895 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3901 tcg_temp_free_i32(tmp
);
3902 tcg_temp_free_i32(tmp2
);
3906 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3909 if (!q
&& size
== 2) {
3912 tmp
= tcg_const_i32(rd
);
3913 tmp2
= tcg_const_i32(rm
);
3917 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3920 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3923 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3931 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3934 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3940 tcg_temp_free_i32(tmp
);
3941 tcg_temp_free_i32(tmp2
);
3945 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3949 rd
= tcg_temp_new_i32();
3950 tmp
= tcg_temp_new_i32();
3952 tcg_gen_shli_i32(rd
, t0
, 8);
3953 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3954 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3955 tcg_gen_or_i32(rd
, rd
, tmp
);
3957 tcg_gen_shri_i32(t1
, t1
, 8);
3958 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3959 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3960 tcg_gen_or_i32(t1
, t1
, tmp
);
3961 tcg_gen_mov_i32(t0
, rd
);
3963 tcg_temp_free_i32(tmp
);
3964 tcg_temp_free_i32(rd
);
3967 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3971 rd
= tcg_temp_new_i32();
3972 tmp
= tcg_temp_new_i32();
3974 tcg_gen_shli_i32(rd
, t0
, 16);
3975 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3976 tcg_gen_or_i32(rd
, rd
, tmp
);
3977 tcg_gen_shri_i32(t1
, t1
, 16);
3978 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3979 tcg_gen_or_i32(t1
, t1
, tmp
);
3980 tcg_gen_mov_i32(t0
, rd
);
3982 tcg_temp_free_i32(tmp
);
3983 tcg_temp_free_i32(rd
);
3991 } neon_ls_element_type
[11] = {
4005 /* Translate a NEON load/store element instruction. Return nonzero if the
4006 instruction is invalid. */
4007 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4026 if (!s
->vfp_enabled
)
4028 VFP_DREG_D(rd
, insn
);
4029 rn
= (insn
>> 16) & 0xf;
4031 load
= (insn
& (1 << 21)) != 0;
4032 if ((insn
& (1 << 23)) == 0) {
4033 /* Load store all elements. */
4034 op
= (insn
>> 8) & 0xf;
4035 size
= (insn
>> 6) & 3;
4038 /* Catch UNDEF cases for bad values of align field */
4041 if (((insn
>> 5) & 1) == 1) {
4046 if (((insn
>> 4) & 3) == 3) {
4053 nregs
= neon_ls_element_type
[op
].nregs
;
4054 interleave
= neon_ls_element_type
[op
].interleave
;
4055 spacing
= neon_ls_element_type
[op
].spacing
;
4056 if (size
== 3 && (interleave
| spacing
) != 1)
4058 addr
= tcg_temp_new_i32();
4059 load_reg_var(s
, addr
, rn
);
4060 stride
= (1 << size
) * interleave
;
4061 for (reg
= 0; reg
< nregs
; reg
++) {
4062 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4063 load_reg_var(s
, addr
, rn
);
4064 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4065 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4066 load_reg_var(s
, addr
, rn
);
4067 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4070 tmp64
= tcg_temp_new_i64();
4072 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
4073 neon_store_reg64(tmp64
, rd
);
4075 neon_load_reg64(tmp64
, rd
);
4076 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
4078 tcg_temp_free_i64(tmp64
);
4079 tcg_gen_addi_i32(addr
, addr
, stride
);
4081 for (pass
= 0; pass
< 2; pass
++) {
4084 tmp
= tcg_temp_new_i32();
4085 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4086 neon_store_reg(rd
, pass
, tmp
);
4088 tmp
= neon_load_reg(rd
, pass
);
4089 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4090 tcg_temp_free_i32(tmp
);
4092 tcg_gen_addi_i32(addr
, addr
, stride
);
4093 } else if (size
== 1) {
4095 tmp
= tcg_temp_new_i32();
4096 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4097 tcg_gen_addi_i32(addr
, addr
, stride
);
4098 tmp2
= tcg_temp_new_i32();
4099 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
4100 tcg_gen_addi_i32(addr
, addr
, stride
);
4101 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4102 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4103 tcg_temp_free_i32(tmp2
);
4104 neon_store_reg(rd
, pass
, tmp
);
4106 tmp
= neon_load_reg(rd
, pass
);
4107 tmp2
= tcg_temp_new_i32();
4108 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4109 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4110 tcg_temp_free_i32(tmp
);
4111 tcg_gen_addi_i32(addr
, addr
, stride
);
4112 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
4113 tcg_temp_free_i32(tmp2
);
4114 tcg_gen_addi_i32(addr
, addr
, stride
);
4116 } else /* size == 0 */ {
4118 TCGV_UNUSED_I32(tmp2
);
4119 for (n
= 0; n
< 4; n
++) {
4120 tmp
= tcg_temp_new_i32();
4121 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4122 tcg_gen_addi_i32(addr
, addr
, stride
);
4126 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4127 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4128 tcg_temp_free_i32(tmp
);
4131 neon_store_reg(rd
, pass
, tmp2
);
4133 tmp2
= neon_load_reg(rd
, pass
);
4134 for (n
= 0; n
< 4; n
++) {
4135 tmp
= tcg_temp_new_i32();
4137 tcg_gen_mov_i32(tmp
, tmp2
);
4139 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4141 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4142 tcg_temp_free_i32(tmp
);
4143 tcg_gen_addi_i32(addr
, addr
, stride
);
4145 tcg_temp_free_i32(tmp2
);
4152 tcg_temp_free_i32(addr
);
4155 size
= (insn
>> 10) & 3;
4157 /* Load single element to all lanes. */
4158 int a
= (insn
>> 4) & 1;
4162 size
= (insn
>> 6) & 3;
4163 nregs
= ((insn
>> 8) & 3) + 1;
4166 if (nregs
!= 4 || a
== 0) {
4169 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4172 if (nregs
== 1 && a
== 1 && size
== 0) {
4175 if (nregs
== 3 && a
== 1) {
4178 addr
= tcg_temp_new_i32();
4179 load_reg_var(s
, addr
, rn
);
4181 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4182 tmp
= gen_load_and_replicate(s
, addr
, size
);
4183 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4184 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4185 if (insn
& (1 << 5)) {
4186 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4187 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4189 tcg_temp_free_i32(tmp
);
4191 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4192 stride
= (insn
& (1 << 5)) ? 2 : 1;
4193 for (reg
= 0; reg
< nregs
; reg
++) {
4194 tmp
= gen_load_and_replicate(s
, addr
, size
);
4195 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4196 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4197 tcg_temp_free_i32(tmp
);
4198 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4202 tcg_temp_free_i32(addr
);
4203 stride
= (1 << size
) * nregs
;
4205 /* Single element. */
4206 int idx
= (insn
>> 4) & 0xf;
4207 pass
= (insn
>> 7) & 1;
4210 shift
= ((insn
>> 5) & 3) * 8;
4214 shift
= ((insn
>> 6) & 1) * 16;
4215 stride
= (insn
& (1 << 5)) ? 2 : 1;
4219 stride
= (insn
& (1 << 6)) ? 2 : 1;
4224 nregs
= ((insn
>> 8) & 3) + 1;
4225 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4228 if (((idx
& (1 << size
)) != 0) ||
4229 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4234 if ((idx
& 1) != 0) {
4239 if (size
== 2 && (idx
& 2) != 0) {
4244 if ((size
== 2) && ((idx
& 3) == 3)) {
4251 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4252 /* Attempts to write off the end of the register file
4253 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4254 * the neon_load_reg() would write off the end of the array.
4258 addr
= tcg_temp_new_i32();
4259 load_reg_var(s
, addr
, rn
);
4260 for (reg
= 0; reg
< nregs
; reg
++) {
4262 tmp
= tcg_temp_new_i32();
4265 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4268 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4271 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4273 default: /* Avoid compiler warnings. */
4277 tmp2
= neon_load_reg(rd
, pass
);
4278 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4279 shift
, size
? 16 : 8);
4280 tcg_temp_free_i32(tmp2
);
4282 neon_store_reg(rd
, pass
, tmp
);
4283 } else { /* Store */
4284 tmp
= neon_load_reg(rd
, pass
);
4286 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4289 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4292 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4295 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4298 tcg_temp_free_i32(tmp
);
4301 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4303 tcg_temp_free_i32(addr
);
4304 stride
= nregs
* (1 << size
);
4310 base
= load_reg(s
, rn
);
4312 tcg_gen_addi_i32(base
, base
, stride
);
4315 index
= load_reg(s
, rm
);
4316 tcg_gen_add_i32(base
, base
, index
);
4317 tcg_temp_free_i32(index
);
4319 store_reg(s
, rn
, base
);
4324 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4325 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4327 tcg_gen_and_i32(t
, t
, c
);
4328 tcg_gen_andc_i32(f
, f
, c
);
4329 tcg_gen_or_i32(dest
, t
, f
);
4332 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4335 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4336 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4337 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4342 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4345 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4346 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4347 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4352 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4355 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4356 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4357 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4362 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4365 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4366 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4367 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4372 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4378 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4379 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4384 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4385 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4392 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4393 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4398 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4399 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4406 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4410 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4411 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4412 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4417 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4418 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4419 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4423 tcg_temp_free_i32(src
);
4426 static inline void gen_neon_addl(int size
)
4429 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4430 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4431 case 2: tcg_gen_add_i64(CPU_V001
); break;
4436 static inline void gen_neon_subl(int size
)
4439 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4440 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4441 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4446 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4449 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4450 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4452 tcg_gen_neg_i64(var
, var
);
4458 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4461 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4462 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4467 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4472 switch ((size
<< 1) | u
) {
4473 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4474 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4475 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4476 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4478 tmp
= gen_muls_i64_i32(a
, b
);
4479 tcg_gen_mov_i64(dest
, tmp
);
4480 tcg_temp_free_i64(tmp
);
4483 tmp
= gen_mulu_i64_i32(a
, b
);
4484 tcg_gen_mov_i64(dest
, tmp
);
4485 tcg_temp_free_i64(tmp
);
4490 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4491 Don't forget to clean them now. */
4493 tcg_temp_free_i32(a
);
4494 tcg_temp_free_i32(b
);
4498 static void gen_neon_narrow_op(int op
, int u
, int size
,
4499 TCGv_i32 dest
, TCGv_i64 src
)
4503 gen_neon_unarrow_sats(size
, dest
, src
);
4505 gen_neon_narrow(size
, dest
, src
);
4509 gen_neon_narrow_satu(size
, dest
, src
);
4511 gen_neon_narrow_sats(size
, dest
, src
);
4516 /* Symbolic constants for op fields for Neon 3-register same-length.
4517 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4520 #define NEON_3R_VHADD 0
4521 #define NEON_3R_VQADD 1
4522 #define NEON_3R_VRHADD 2
4523 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4524 #define NEON_3R_VHSUB 4
4525 #define NEON_3R_VQSUB 5
4526 #define NEON_3R_VCGT 6
4527 #define NEON_3R_VCGE 7
4528 #define NEON_3R_VSHL 8
4529 #define NEON_3R_VQSHL 9
4530 #define NEON_3R_VRSHL 10
4531 #define NEON_3R_VQRSHL 11
4532 #define NEON_3R_VMAX 12
4533 #define NEON_3R_VMIN 13
4534 #define NEON_3R_VABD 14
4535 #define NEON_3R_VABA 15
4536 #define NEON_3R_VADD_VSUB 16
4537 #define NEON_3R_VTST_VCEQ 17
4538 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4539 #define NEON_3R_VMUL 19
4540 #define NEON_3R_VPMAX 20
4541 #define NEON_3R_VPMIN 21
4542 #define NEON_3R_VQDMULH_VQRDMULH 22
4543 #define NEON_3R_VPADD 23
4544 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4545 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4546 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4547 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4548 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4549 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4550 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4552 static const uint8_t neon_3r_sizes
[] = {
4553 [NEON_3R_VHADD
] = 0x7,
4554 [NEON_3R_VQADD
] = 0xf,
4555 [NEON_3R_VRHADD
] = 0x7,
4556 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4557 [NEON_3R_VHSUB
] = 0x7,
4558 [NEON_3R_VQSUB
] = 0xf,
4559 [NEON_3R_VCGT
] = 0x7,
4560 [NEON_3R_VCGE
] = 0x7,
4561 [NEON_3R_VSHL
] = 0xf,
4562 [NEON_3R_VQSHL
] = 0xf,
4563 [NEON_3R_VRSHL
] = 0xf,
4564 [NEON_3R_VQRSHL
] = 0xf,
4565 [NEON_3R_VMAX
] = 0x7,
4566 [NEON_3R_VMIN
] = 0x7,
4567 [NEON_3R_VABD
] = 0x7,
4568 [NEON_3R_VABA
] = 0x7,
4569 [NEON_3R_VADD_VSUB
] = 0xf,
4570 [NEON_3R_VTST_VCEQ
] = 0x7,
4571 [NEON_3R_VML
] = 0x7,
4572 [NEON_3R_VMUL
] = 0x7,
4573 [NEON_3R_VPMAX
] = 0x7,
4574 [NEON_3R_VPMIN
] = 0x7,
4575 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4576 [NEON_3R_VPADD
] = 0x7,
4577 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4578 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4579 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4580 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4581 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4582 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4583 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4586 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4587 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4590 #define NEON_2RM_VREV64 0
4591 #define NEON_2RM_VREV32 1
4592 #define NEON_2RM_VREV16 2
4593 #define NEON_2RM_VPADDL 4
4594 #define NEON_2RM_VPADDL_U 5
4595 #define NEON_2RM_AESE 6 /* Includes AESD */
4596 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4597 #define NEON_2RM_VCLS 8
4598 #define NEON_2RM_VCLZ 9
4599 #define NEON_2RM_VCNT 10
4600 #define NEON_2RM_VMVN 11
4601 #define NEON_2RM_VPADAL 12
4602 #define NEON_2RM_VPADAL_U 13
4603 #define NEON_2RM_VQABS 14
4604 #define NEON_2RM_VQNEG 15
4605 #define NEON_2RM_VCGT0 16
4606 #define NEON_2RM_VCGE0 17
4607 #define NEON_2RM_VCEQ0 18
4608 #define NEON_2RM_VCLE0 19
4609 #define NEON_2RM_VCLT0 20
4610 #define NEON_2RM_VABS 22
4611 #define NEON_2RM_VNEG 23
4612 #define NEON_2RM_VCGT0_F 24
4613 #define NEON_2RM_VCGE0_F 25
4614 #define NEON_2RM_VCEQ0_F 26
4615 #define NEON_2RM_VCLE0_F 27
4616 #define NEON_2RM_VCLT0_F 28
4617 #define NEON_2RM_VABS_F 30
4618 #define NEON_2RM_VNEG_F 31
4619 #define NEON_2RM_VSWP 32
4620 #define NEON_2RM_VTRN 33
4621 #define NEON_2RM_VUZP 34
4622 #define NEON_2RM_VZIP 35
4623 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4624 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4625 #define NEON_2RM_VSHLL 38
4626 #define NEON_2RM_VCVT_F16_F32 44
4627 #define NEON_2RM_VCVT_F32_F16 46
4628 #define NEON_2RM_VRECPE 56
4629 #define NEON_2RM_VRSQRTE 57
4630 #define NEON_2RM_VRECPE_F 58
4631 #define NEON_2RM_VRSQRTE_F 59
4632 #define NEON_2RM_VCVT_FS 60
4633 #define NEON_2RM_VCVT_FU 61
4634 #define NEON_2RM_VCVT_SF 62
4635 #define NEON_2RM_VCVT_UF 63
4637 static int neon_2rm_is_float_op(int op
)
4639 /* Return true if this neon 2reg-misc op is float-to-float */
4640 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4641 op
>= NEON_2RM_VRECPE_F
);
4644 /* Each entry in this array has bit n set if the insn allows
4645 * size value n (otherwise it will UNDEF). Since unallocated
4646 * op values will have no bits set they always UNDEF.
4648 static const uint8_t neon_2rm_sizes
[] = {
4649 [NEON_2RM_VREV64
] = 0x7,
4650 [NEON_2RM_VREV32
] = 0x3,
4651 [NEON_2RM_VREV16
] = 0x1,
4652 [NEON_2RM_VPADDL
] = 0x7,
4653 [NEON_2RM_VPADDL_U
] = 0x7,
4654 [NEON_2RM_AESE
] = 0x1,
4655 [NEON_2RM_AESMC
] = 0x1,
4656 [NEON_2RM_VCLS
] = 0x7,
4657 [NEON_2RM_VCLZ
] = 0x7,
4658 [NEON_2RM_VCNT
] = 0x1,
4659 [NEON_2RM_VMVN
] = 0x1,
4660 [NEON_2RM_VPADAL
] = 0x7,
4661 [NEON_2RM_VPADAL_U
] = 0x7,
4662 [NEON_2RM_VQABS
] = 0x7,
4663 [NEON_2RM_VQNEG
] = 0x7,
4664 [NEON_2RM_VCGT0
] = 0x7,
4665 [NEON_2RM_VCGE0
] = 0x7,
4666 [NEON_2RM_VCEQ0
] = 0x7,
4667 [NEON_2RM_VCLE0
] = 0x7,
4668 [NEON_2RM_VCLT0
] = 0x7,
4669 [NEON_2RM_VABS
] = 0x7,
4670 [NEON_2RM_VNEG
] = 0x7,
4671 [NEON_2RM_VCGT0_F
] = 0x4,
4672 [NEON_2RM_VCGE0_F
] = 0x4,
4673 [NEON_2RM_VCEQ0_F
] = 0x4,
4674 [NEON_2RM_VCLE0_F
] = 0x4,
4675 [NEON_2RM_VCLT0_F
] = 0x4,
4676 [NEON_2RM_VABS_F
] = 0x4,
4677 [NEON_2RM_VNEG_F
] = 0x4,
4678 [NEON_2RM_VSWP
] = 0x1,
4679 [NEON_2RM_VTRN
] = 0x7,
4680 [NEON_2RM_VUZP
] = 0x7,
4681 [NEON_2RM_VZIP
] = 0x7,
4682 [NEON_2RM_VMOVN
] = 0x7,
4683 [NEON_2RM_VQMOVN
] = 0x7,
4684 [NEON_2RM_VSHLL
] = 0x7,
4685 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4686 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4687 [NEON_2RM_VRECPE
] = 0x4,
4688 [NEON_2RM_VRSQRTE
] = 0x4,
4689 [NEON_2RM_VRECPE_F
] = 0x4,
4690 [NEON_2RM_VRSQRTE_F
] = 0x4,
4691 [NEON_2RM_VCVT_FS
] = 0x4,
4692 [NEON_2RM_VCVT_FU
] = 0x4,
4693 [NEON_2RM_VCVT_SF
] = 0x4,
4694 [NEON_2RM_VCVT_UF
] = 0x4,
4697 /* Translate a NEON data processing instruction. Return nonzero if the
4698 instruction is invalid.
4699 We process data in a mixture of 32-bit and 64-bit chunks.
4700 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4702 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4714 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4717 if (!s
->vfp_enabled
)
4719 q
= (insn
& (1 << 6)) != 0;
4720 u
= (insn
>> 24) & 1;
4721 VFP_DREG_D(rd
, insn
);
4722 VFP_DREG_N(rn
, insn
);
4723 VFP_DREG_M(rm
, insn
);
4724 size
= (insn
>> 20) & 3;
4725 if ((insn
& (1 << 23)) == 0) {
4726 /* Three register same length. */
4727 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4728 /* Catch invalid op and bad size combinations: UNDEF */
4729 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4732 /* All insns of this form UNDEF for either this condition or the
4733 * superset of cases "Q==1"; we catch the latter later.
4735 if (q
&& ((rd
| rn
| rm
) & 1)) {
4738 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4739 /* 64-bit element instructions. */
4740 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4741 neon_load_reg64(cpu_V0
, rn
+ pass
);
4742 neon_load_reg64(cpu_V1
, rm
+ pass
);
4746 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4749 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4755 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4758 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4764 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4766 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4771 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4774 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4780 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4782 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4785 case NEON_3R_VQRSHL
:
4787 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4790 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4794 case NEON_3R_VADD_VSUB
:
4796 tcg_gen_sub_i64(CPU_V001
);
4798 tcg_gen_add_i64(CPU_V001
);
4804 neon_store_reg64(cpu_V0
, rd
+ pass
);
4813 case NEON_3R_VQRSHL
:
4816 /* Shift instruction operands are reversed. */
4831 case NEON_3R_FLOAT_ARITH
:
4832 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4834 case NEON_3R_FLOAT_MINMAX
:
4835 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4837 case NEON_3R_FLOAT_CMP
:
4839 /* no encoding for U=0 C=1x */
4843 case NEON_3R_FLOAT_ACMP
:
4848 case NEON_3R_FLOAT_MISC
:
4849 /* VMAXNM/VMINNM in ARMv8 */
4850 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
4855 if (u
&& (size
!= 0)) {
4856 /* UNDEF on invalid size for polynomial subcase */
4861 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4869 if (pairwise
&& q
) {
4870 /* All the pairwise insns UNDEF if Q is set */
4874 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4879 tmp
= neon_load_reg(rn
, 0);
4880 tmp2
= neon_load_reg(rn
, 1);
4882 tmp
= neon_load_reg(rm
, 0);
4883 tmp2
= neon_load_reg(rm
, 1);
4887 tmp
= neon_load_reg(rn
, pass
);
4888 tmp2
= neon_load_reg(rm
, pass
);
4892 GEN_NEON_INTEGER_OP(hadd
);
4895 GEN_NEON_INTEGER_OP_ENV(qadd
);
4897 case NEON_3R_VRHADD
:
4898 GEN_NEON_INTEGER_OP(rhadd
);
4900 case NEON_3R_LOGIC
: /* Logic ops. */
4901 switch ((u
<< 2) | size
) {
4903 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4906 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4909 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4912 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4915 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4918 tmp3
= neon_load_reg(rd
, pass
);
4919 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4920 tcg_temp_free_i32(tmp3
);
4923 tmp3
= neon_load_reg(rd
, pass
);
4924 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4925 tcg_temp_free_i32(tmp3
);
4928 tmp3
= neon_load_reg(rd
, pass
);
4929 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4930 tcg_temp_free_i32(tmp3
);
4935 GEN_NEON_INTEGER_OP(hsub
);
4938 GEN_NEON_INTEGER_OP_ENV(qsub
);
4941 GEN_NEON_INTEGER_OP(cgt
);
4944 GEN_NEON_INTEGER_OP(cge
);
4947 GEN_NEON_INTEGER_OP(shl
);
4950 GEN_NEON_INTEGER_OP_ENV(qshl
);
4953 GEN_NEON_INTEGER_OP(rshl
);
4955 case NEON_3R_VQRSHL
:
4956 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4959 GEN_NEON_INTEGER_OP(max
);
4962 GEN_NEON_INTEGER_OP(min
);
4965 GEN_NEON_INTEGER_OP(abd
);
4968 GEN_NEON_INTEGER_OP(abd
);
4969 tcg_temp_free_i32(tmp2
);
4970 tmp2
= neon_load_reg(rd
, pass
);
4971 gen_neon_add(size
, tmp
, tmp2
);
4973 case NEON_3R_VADD_VSUB
:
4974 if (!u
) { /* VADD */
4975 gen_neon_add(size
, tmp
, tmp2
);
4978 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4979 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4980 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4985 case NEON_3R_VTST_VCEQ
:
4986 if (!u
) { /* VTST */
4988 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4989 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4990 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4995 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4996 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4997 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5002 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5004 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5005 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5006 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5009 tcg_temp_free_i32(tmp2
);
5010 tmp2
= neon_load_reg(rd
, pass
);
5012 gen_neon_rsb(size
, tmp
, tmp2
);
5014 gen_neon_add(size
, tmp
, tmp2
);
5018 if (u
) { /* polynomial */
5019 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5020 } else { /* Integer */
5022 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5023 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5024 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5030 GEN_NEON_INTEGER_OP(pmax
);
5033 GEN_NEON_INTEGER_OP(pmin
);
5035 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5036 if (!u
) { /* VQDMULH */
5039 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5042 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5046 } else { /* VQRDMULH */
5049 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5052 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5060 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5061 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5062 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5066 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5068 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5069 switch ((u
<< 2) | size
) {
5072 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5075 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5078 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5083 tcg_temp_free_ptr(fpstatus
);
5086 case NEON_3R_FLOAT_MULTIPLY
:
5088 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5089 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5091 tcg_temp_free_i32(tmp2
);
5092 tmp2
= neon_load_reg(rd
, pass
);
5094 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5096 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5099 tcg_temp_free_ptr(fpstatus
);
5102 case NEON_3R_FLOAT_CMP
:
5104 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5106 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5109 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5111 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5114 tcg_temp_free_ptr(fpstatus
);
5117 case NEON_3R_FLOAT_ACMP
:
5119 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5121 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5123 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5125 tcg_temp_free_ptr(fpstatus
);
5128 case NEON_3R_FLOAT_MINMAX
:
5130 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5132 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
5134 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
5136 tcg_temp_free_ptr(fpstatus
);
5139 case NEON_3R_FLOAT_MISC
:
5142 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5144 gen_helper_vfp_maxnms(tmp
, tmp
, tmp2
, fpstatus
);
5146 gen_helper_vfp_minnms(tmp
, tmp
, tmp2
, fpstatus
);
5148 tcg_temp_free_ptr(fpstatus
);
5151 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5153 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5159 /* VFMA, VFMS: fused multiply-add */
5160 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5161 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5164 gen_helper_vfp_negs(tmp
, tmp
);
5166 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5167 tcg_temp_free_i32(tmp3
);
5168 tcg_temp_free_ptr(fpstatus
);
5174 tcg_temp_free_i32(tmp2
);
5176 /* Save the result. For elementwise operations we can put it
5177 straight into the destination register. For pairwise operations
5178 we have to be careful to avoid clobbering the source operands. */
5179 if (pairwise
&& rd
== rm
) {
5180 neon_store_scratch(pass
, tmp
);
5182 neon_store_reg(rd
, pass
, tmp
);
5186 if (pairwise
&& rd
== rm
) {
5187 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5188 tmp
= neon_load_scratch(pass
);
5189 neon_store_reg(rd
, pass
, tmp
);
5192 /* End of 3 register same size operations. */
5193 } else if (insn
& (1 << 4)) {
5194 if ((insn
& 0x00380080) != 0) {
5195 /* Two registers and shift. */
5196 op
= (insn
>> 8) & 0xf;
5197 if (insn
& (1 << 7)) {
5205 while ((insn
& (1 << (size
+ 19))) == 0)
5208 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5209 /* To avoid excessive duplication of ops we implement shift
5210 by immediate using the variable shift operations. */
5212 /* Shift by immediate:
5213 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5214 if (q
&& ((rd
| rm
) & 1)) {
5217 if (!u
&& (op
== 4 || op
== 6)) {
5220 /* Right shifts are encoded as N - shift, where N is the
5221 element size in bits. */
5223 shift
= shift
- (1 << (size
+ 3));
5231 imm
= (uint8_t) shift
;
5236 imm
= (uint16_t) shift
;
5247 for (pass
= 0; pass
< count
; pass
++) {
5249 neon_load_reg64(cpu_V0
, rm
+ pass
);
5250 tcg_gen_movi_i64(cpu_V1
, imm
);
5255 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5257 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5262 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5264 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5267 case 5: /* VSHL, VSLI */
5268 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5270 case 6: /* VQSHLU */
5271 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5276 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5279 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5284 if (op
== 1 || op
== 3) {
5286 neon_load_reg64(cpu_V1
, rd
+ pass
);
5287 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5288 } else if (op
== 4 || (op
== 5 && u
)) {
5290 neon_load_reg64(cpu_V1
, rd
+ pass
);
5292 if (shift
< -63 || shift
> 63) {
5296 mask
= 0xffffffffffffffffull
>> -shift
;
5298 mask
= 0xffffffffffffffffull
<< shift
;
5301 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5302 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5304 neon_store_reg64(cpu_V0
, rd
+ pass
);
5305 } else { /* size < 3 */
5306 /* Operands in T0 and T1. */
5307 tmp
= neon_load_reg(rm
, pass
);
5308 tmp2
= tcg_temp_new_i32();
5309 tcg_gen_movi_i32(tmp2
, imm
);
5313 GEN_NEON_INTEGER_OP(shl
);
5317 GEN_NEON_INTEGER_OP(rshl
);
5320 case 5: /* VSHL, VSLI */
5322 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5323 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5324 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5328 case 6: /* VQSHLU */
5331 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5335 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5339 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5347 GEN_NEON_INTEGER_OP_ENV(qshl
);
5350 tcg_temp_free_i32(tmp2
);
5352 if (op
== 1 || op
== 3) {
5354 tmp2
= neon_load_reg(rd
, pass
);
5355 gen_neon_add(size
, tmp
, tmp2
);
5356 tcg_temp_free_i32(tmp2
);
5357 } else if (op
== 4 || (op
== 5 && u
)) {
5362 mask
= 0xff >> -shift
;
5364 mask
= (uint8_t)(0xff << shift
);
5370 mask
= 0xffff >> -shift
;
5372 mask
= (uint16_t)(0xffff << shift
);
5376 if (shift
< -31 || shift
> 31) {
5380 mask
= 0xffffffffu
>> -shift
;
5382 mask
= 0xffffffffu
<< shift
;
5388 tmp2
= neon_load_reg(rd
, pass
);
5389 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5390 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5391 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5392 tcg_temp_free_i32(tmp2
);
5394 neon_store_reg(rd
, pass
, tmp
);
5397 } else if (op
< 10) {
5398 /* Shift by immediate and narrow:
5399 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5400 int input_unsigned
= (op
== 8) ? !u
: u
;
5404 shift
= shift
- (1 << (size
+ 3));
5407 tmp64
= tcg_const_i64(shift
);
5408 neon_load_reg64(cpu_V0
, rm
);
5409 neon_load_reg64(cpu_V1
, rm
+ 1);
5410 for (pass
= 0; pass
< 2; pass
++) {
5418 if (input_unsigned
) {
5419 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5421 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5424 if (input_unsigned
) {
5425 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5427 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5430 tmp
= tcg_temp_new_i32();
5431 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5432 neon_store_reg(rd
, pass
, tmp
);
5434 tcg_temp_free_i64(tmp64
);
5437 imm
= (uint16_t)shift
;
5441 imm
= (uint32_t)shift
;
5443 tmp2
= tcg_const_i32(imm
);
5444 tmp4
= neon_load_reg(rm
+ 1, 0);
5445 tmp5
= neon_load_reg(rm
+ 1, 1);
5446 for (pass
= 0; pass
< 2; pass
++) {
5448 tmp
= neon_load_reg(rm
, 0);
5452 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5455 tmp3
= neon_load_reg(rm
, 1);
5459 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5461 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5462 tcg_temp_free_i32(tmp
);
5463 tcg_temp_free_i32(tmp3
);
5464 tmp
= tcg_temp_new_i32();
5465 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5466 neon_store_reg(rd
, pass
, tmp
);
5468 tcg_temp_free_i32(tmp2
);
5470 } else if (op
== 10) {
5472 if (q
|| (rd
& 1)) {
5475 tmp
= neon_load_reg(rm
, 0);
5476 tmp2
= neon_load_reg(rm
, 1);
5477 for (pass
= 0; pass
< 2; pass
++) {
5481 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5484 /* The shift is less than the width of the source
5485 type, so we can just shift the whole register. */
5486 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5487 /* Widen the result of shift: we need to clear
5488 * the potential overflow bits resulting from
5489 * left bits of the narrow input appearing as
5490 * right bits of left the neighbour narrow
5492 if (size
< 2 || !u
) {
5495 imm
= (0xffu
>> (8 - shift
));
5497 } else if (size
== 1) {
5498 imm
= 0xffff >> (16 - shift
);
5501 imm
= 0xffffffff >> (32 - shift
);
5504 imm64
= imm
| (((uint64_t)imm
) << 32);
5508 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5511 neon_store_reg64(cpu_V0
, rd
+ pass
);
5513 } else if (op
>= 14) {
5514 /* VCVT fixed-point. */
5515 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5518 /* We have already masked out the must-be-1 top bit of imm6,
5519 * hence this 32-shift where the ARM ARM has 64-imm6.
5522 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5523 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5526 gen_vfp_ulto(0, shift
, 1);
5528 gen_vfp_slto(0, shift
, 1);
5531 gen_vfp_toul(0, shift
, 1);
5533 gen_vfp_tosl(0, shift
, 1);
5535 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5540 } else { /* (insn & 0x00380080) == 0 */
5542 if (q
&& (rd
& 1)) {
5546 op
= (insn
>> 8) & 0xf;
5547 /* One register and immediate. */
5548 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5549 invert
= (insn
& (1 << 5)) != 0;
5550 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5551 * We choose to not special-case this and will behave as if a
5552 * valid constant encoding of 0 had been given.
5571 imm
= (imm
<< 8) | (imm
<< 24);
5574 imm
= (imm
<< 8) | 0xff;
5577 imm
= (imm
<< 16) | 0xffff;
5580 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5588 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5589 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5595 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5596 if (op
& 1 && op
< 12) {
5597 tmp
= neon_load_reg(rd
, pass
);
5599 /* The immediate value has already been inverted, so
5601 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5603 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5607 tmp
= tcg_temp_new_i32();
5608 if (op
== 14 && invert
) {
5612 for (n
= 0; n
< 4; n
++) {
5613 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5614 val
|= 0xff << (n
* 8);
5616 tcg_gen_movi_i32(tmp
, val
);
5618 tcg_gen_movi_i32(tmp
, imm
);
5621 neon_store_reg(rd
, pass
, tmp
);
5624 } else { /* (insn & 0x00800010 == 0x00800000) */
5626 op
= (insn
>> 8) & 0xf;
5627 if ((insn
& (1 << 6)) == 0) {
5628 /* Three registers of different lengths. */
5632 /* undefreq: bit 0 : UNDEF if size != 0
5633 * bit 1 : UNDEF if size == 0
5634 * bit 2 : UNDEF if U == 1
5635 * Note that [1:0] set implies 'always UNDEF'
5638 /* prewiden, src1_wide, src2_wide, undefreq */
5639 static const int neon_3reg_wide
[16][4] = {
5640 {1, 0, 0, 0}, /* VADDL */
5641 {1, 1, 0, 0}, /* VADDW */
5642 {1, 0, 0, 0}, /* VSUBL */
5643 {1, 1, 0, 0}, /* VSUBW */
5644 {0, 1, 1, 0}, /* VADDHN */
5645 {0, 0, 0, 0}, /* VABAL */
5646 {0, 1, 1, 0}, /* VSUBHN */
5647 {0, 0, 0, 0}, /* VABDL */
5648 {0, 0, 0, 0}, /* VMLAL */
5649 {0, 0, 0, 6}, /* VQDMLAL */
5650 {0, 0, 0, 0}, /* VMLSL */
5651 {0, 0, 0, 6}, /* VQDMLSL */
5652 {0, 0, 0, 0}, /* Integer VMULL */
5653 {0, 0, 0, 2}, /* VQDMULL */
5654 {0, 0, 0, 5}, /* Polynomial VMULL */
5655 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5658 prewiden
= neon_3reg_wide
[op
][0];
5659 src1_wide
= neon_3reg_wide
[op
][1];
5660 src2_wide
= neon_3reg_wide
[op
][2];
5661 undefreq
= neon_3reg_wide
[op
][3];
5663 if (((undefreq
& 1) && (size
!= 0)) ||
5664 ((undefreq
& 2) && (size
== 0)) ||
5665 ((undefreq
& 4) && u
)) {
5668 if ((src1_wide
&& (rn
& 1)) ||
5669 (src2_wide
&& (rm
& 1)) ||
5670 (!src2_wide
&& (rd
& 1))) {
5674 /* Avoid overlapping operands. Wide source operands are
5675 always aligned so will never overlap with wide
5676 destinations in problematic ways. */
5677 if (rd
== rm
&& !src2_wide
) {
5678 tmp
= neon_load_reg(rm
, 1);
5679 neon_store_scratch(2, tmp
);
5680 } else if (rd
== rn
&& !src1_wide
) {
5681 tmp
= neon_load_reg(rn
, 1);
5682 neon_store_scratch(2, tmp
);
5684 TCGV_UNUSED_I32(tmp3
);
5685 for (pass
= 0; pass
< 2; pass
++) {
5687 neon_load_reg64(cpu_V0
, rn
+ pass
);
5688 TCGV_UNUSED_I32(tmp
);
5690 if (pass
== 1 && rd
== rn
) {
5691 tmp
= neon_load_scratch(2);
5693 tmp
= neon_load_reg(rn
, pass
);
5696 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5700 neon_load_reg64(cpu_V1
, rm
+ pass
);
5701 TCGV_UNUSED_I32(tmp2
);
5703 if (pass
== 1 && rd
== rm
) {
5704 tmp2
= neon_load_scratch(2);
5706 tmp2
= neon_load_reg(rm
, pass
);
5709 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5713 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5714 gen_neon_addl(size
);
5716 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5717 gen_neon_subl(size
);
5719 case 5: case 7: /* VABAL, VABDL */
5720 switch ((size
<< 1) | u
) {
5722 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5725 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5728 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5731 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5734 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5737 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5741 tcg_temp_free_i32(tmp2
);
5742 tcg_temp_free_i32(tmp
);
5744 case 8: case 9: case 10: case 11: case 12: case 13:
5745 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5746 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5748 case 14: /* Polynomial VMULL */
5749 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5750 tcg_temp_free_i32(tmp2
);
5751 tcg_temp_free_i32(tmp
);
5753 default: /* 15 is RESERVED: caught earlier */
5758 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5759 neon_store_reg64(cpu_V0
, rd
+ pass
);
5760 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5762 neon_load_reg64(cpu_V1
, rd
+ pass
);
5764 case 10: /* VMLSL */
5765 gen_neon_negl(cpu_V0
, size
);
5767 case 5: case 8: /* VABAL, VMLAL */
5768 gen_neon_addl(size
);
5770 case 9: case 11: /* VQDMLAL, VQDMLSL */
5771 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5773 gen_neon_negl(cpu_V0
, size
);
5775 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5780 neon_store_reg64(cpu_V0
, rd
+ pass
);
5781 } else if (op
== 4 || op
== 6) {
5782 /* Narrowing operation. */
5783 tmp
= tcg_temp_new_i32();
5787 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5790 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5793 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5794 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5801 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5804 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5807 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5808 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5809 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5817 neon_store_reg(rd
, 0, tmp3
);
5818 neon_store_reg(rd
, 1, tmp
);
5821 /* Write back the result. */
5822 neon_store_reg64(cpu_V0
, rd
+ pass
);
5826 /* Two registers and a scalar. NB that for ops of this form
5827 * the ARM ARM labels bit 24 as Q, but it is in our variable
5834 case 1: /* Float VMLA scalar */
5835 case 5: /* Floating point VMLS scalar */
5836 case 9: /* Floating point VMUL scalar */
5841 case 0: /* Integer VMLA scalar */
5842 case 4: /* Integer VMLS scalar */
5843 case 8: /* Integer VMUL scalar */
5844 case 12: /* VQDMULH scalar */
5845 case 13: /* VQRDMULH scalar */
5846 if (u
&& ((rd
| rn
) & 1)) {
5849 tmp
= neon_get_scalar(size
, rm
);
5850 neon_store_scratch(0, tmp
);
5851 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5852 tmp
= neon_load_scratch(0);
5853 tmp2
= neon_load_reg(rn
, pass
);
5856 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5858 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5860 } else if (op
== 13) {
5862 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5864 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5866 } else if (op
& 1) {
5867 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5868 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5869 tcg_temp_free_ptr(fpstatus
);
5872 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5873 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5874 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5878 tcg_temp_free_i32(tmp2
);
5881 tmp2
= neon_load_reg(rd
, pass
);
5884 gen_neon_add(size
, tmp
, tmp2
);
5888 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5889 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5890 tcg_temp_free_ptr(fpstatus
);
5894 gen_neon_rsb(size
, tmp
, tmp2
);
5898 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5899 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5900 tcg_temp_free_ptr(fpstatus
);
5906 tcg_temp_free_i32(tmp2
);
5908 neon_store_reg(rd
, pass
, tmp
);
5911 case 3: /* VQDMLAL scalar */
5912 case 7: /* VQDMLSL scalar */
5913 case 11: /* VQDMULL scalar */
5918 case 2: /* VMLAL sclar */
5919 case 6: /* VMLSL scalar */
5920 case 10: /* VMULL scalar */
5924 tmp2
= neon_get_scalar(size
, rm
);
5925 /* We need a copy of tmp2 because gen_neon_mull
5926 * deletes it during pass 0. */
5927 tmp4
= tcg_temp_new_i32();
5928 tcg_gen_mov_i32(tmp4
, tmp2
);
5929 tmp3
= neon_load_reg(rn
, 1);
5931 for (pass
= 0; pass
< 2; pass
++) {
5933 tmp
= neon_load_reg(rn
, 0);
5938 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5940 neon_load_reg64(cpu_V1
, rd
+ pass
);
5944 gen_neon_negl(cpu_V0
, size
);
5947 gen_neon_addl(size
);
5950 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5952 gen_neon_negl(cpu_V0
, size
);
5954 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5960 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5965 neon_store_reg64(cpu_V0
, rd
+ pass
);
5970 default: /* 14 and 15 are RESERVED */
5974 } else { /* size == 3 */
5977 imm
= (insn
>> 8) & 0xf;
5982 if (q
&& ((rd
| rn
| rm
) & 1)) {
5987 neon_load_reg64(cpu_V0
, rn
);
5989 neon_load_reg64(cpu_V1
, rn
+ 1);
5991 } else if (imm
== 8) {
5992 neon_load_reg64(cpu_V0
, rn
+ 1);
5994 neon_load_reg64(cpu_V1
, rm
);
5997 tmp64
= tcg_temp_new_i64();
5999 neon_load_reg64(cpu_V0
, rn
);
6000 neon_load_reg64(tmp64
, rn
+ 1);
6002 neon_load_reg64(cpu_V0
, rn
+ 1);
6003 neon_load_reg64(tmp64
, rm
);
6005 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6006 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6007 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6009 neon_load_reg64(cpu_V1
, rm
);
6011 neon_load_reg64(cpu_V1
, rm
+ 1);
6014 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6015 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6016 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6017 tcg_temp_free_i64(tmp64
);
6020 neon_load_reg64(cpu_V0
, rn
);
6021 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6022 neon_load_reg64(cpu_V1
, rm
);
6023 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6024 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6026 neon_store_reg64(cpu_V0
, rd
);
6028 neon_store_reg64(cpu_V1
, rd
+ 1);
6030 } else if ((insn
& (1 << 11)) == 0) {
6031 /* Two register misc. */
6032 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6033 size
= (insn
>> 18) & 3;
6034 /* UNDEF for unknown op values and bad op-size combinations */
6035 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6038 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6039 q
&& ((rm
| rd
) & 1)) {
6043 case NEON_2RM_VREV64
:
6044 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6045 tmp
= neon_load_reg(rm
, pass
* 2);
6046 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6048 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6049 case 1: gen_swap_half(tmp
); break;
6050 case 2: /* no-op */ break;
6053 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6055 neon_store_reg(rd
, pass
* 2, tmp2
);
6058 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6059 case 1: gen_swap_half(tmp2
); break;
6062 neon_store_reg(rd
, pass
* 2, tmp2
);
6066 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6067 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6068 for (pass
= 0; pass
< q
+ 1; pass
++) {
6069 tmp
= neon_load_reg(rm
, pass
* 2);
6070 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6071 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6072 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6074 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6075 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6076 case 2: tcg_gen_add_i64(CPU_V001
); break;
6079 if (op
>= NEON_2RM_VPADAL
) {
6081 neon_load_reg64(cpu_V1
, rd
+ pass
);
6082 gen_neon_addl(size
);
6084 neon_store_reg64(cpu_V0
, rd
+ pass
);
6090 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6091 tmp
= neon_load_reg(rm
, n
);
6092 tmp2
= neon_load_reg(rd
, n
+ 1);
6093 neon_store_reg(rm
, n
, tmp2
);
6094 neon_store_reg(rd
, n
+ 1, tmp
);
6101 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6106 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6110 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6111 /* also VQMOVUN; op field and mnemonics don't line up */
6115 TCGV_UNUSED_I32(tmp2
);
6116 for (pass
= 0; pass
< 2; pass
++) {
6117 neon_load_reg64(cpu_V0
, rm
+ pass
);
6118 tmp
= tcg_temp_new_i32();
6119 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6124 neon_store_reg(rd
, 0, tmp2
);
6125 neon_store_reg(rd
, 1, tmp
);
6129 case NEON_2RM_VSHLL
:
6130 if (q
|| (rd
& 1)) {
6133 tmp
= neon_load_reg(rm
, 0);
6134 tmp2
= neon_load_reg(rm
, 1);
6135 for (pass
= 0; pass
< 2; pass
++) {
6138 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6139 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6140 neon_store_reg64(cpu_V0
, rd
+ pass
);
6143 case NEON_2RM_VCVT_F16_F32
:
6144 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6148 tmp
= tcg_temp_new_i32();
6149 tmp2
= tcg_temp_new_i32();
6150 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6151 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6152 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6153 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6154 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6155 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6156 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6157 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6158 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6159 neon_store_reg(rd
, 0, tmp2
);
6160 tmp2
= tcg_temp_new_i32();
6161 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6162 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6163 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6164 neon_store_reg(rd
, 1, tmp2
);
6165 tcg_temp_free_i32(tmp
);
6167 case NEON_2RM_VCVT_F32_F16
:
6168 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6172 tmp3
= tcg_temp_new_i32();
6173 tmp
= neon_load_reg(rm
, 0);
6174 tmp2
= neon_load_reg(rm
, 1);
6175 tcg_gen_ext16u_i32(tmp3
, tmp
);
6176 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6177 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6178 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6179 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6180 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6181 tcg_temp_free_i32(tmp
);
6182 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6183 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6184 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6185 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6186 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6187 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6188 tcg_temp_free_i32(tmp2
);
6189 tcg_temp_free_i32(tmp3
);
6191 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6192 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6193 || ((rm
| rd
) & 1)) {
6196 tmp
= tcg_const_i32(rd
);
6197 tmp2
= tcg_const_i32(rm
);
6199 /* Bit 6 is the lowest opcode bit; it distinguishes between
6200 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6202 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6204 if (op
== NEON_2RM_AESE
) {
6205 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6207 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6209 tcg_temp_free_i32(tmp
);
6210 tcg_temp_free_i32(tmp2
);
6211 tcg_temp_free_i32(tmp3
);
6215 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6216 if (neon_2rm_is_float_op(op
)) {
6217 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6218 neon_reg_offset(rm
, pass
));
6219 TCGV_UNUSED_I32(tmp
);
6221 tmp
= neon_load_reg(rm
, pass
);
6224 case NEON_2RM_VREV32
:
6226 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6227 case 1: gen_swap_half(tmp
); break;
6231 case NEON_2RM_VREV16
:
6236 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6237 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6238 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6244 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6245 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6246 case 2: gen_helper_clz(tmp
, tmp
); break;
6251 gen_helper_neon_cnt_u8(tmp
, tmp
);
6254 tcg_gen_not_i32(tmp
, tmp
);
6256 case NEON_2RM_VQABS
:
6259 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6262 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6265 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6270 case NEON_2RM_VQNEG
:
6273 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6276 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6279 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6284 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6285 tmp2
= tcg_const_i32(0);
6287 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6288 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6289 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6292 tcg_temp_free_i32(tmp2
);
6293 if (op
== NEON_2RM_VCLE0
) {
6294 tcg_gen_not_i32(tmp
, tmp
);
6297 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6298 tmp2
= tcg_const_i32(0);
6300 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6301 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6302 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6305 tcg_temp_free_i32(tmp2
);
6306 if (op
== NEON_2RM_VCLT0
) {
6307 tcg_gen_not_i32(tmp
, tmp
);
6310 case NEON_2RM_VCEQ0
:
6311 tmp2
= tcg_const_i32(0);
6313 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6314 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6315 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6318 tcg_temp_free_i32(tmp2
);
6322 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6323 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6324 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6329 tmp2
= tcg_const_i32(0);
6330 gen_neon_rsb(size
, tmp
, tmp2
);
6331 tcg_temp_free_i32(tmp2
);
6333 case NEON_2RM_VCGT0_F
:
6335 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6336 tmp2
= tcg_const_i32(0);
6337 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6338 tcg_temp_free_i32(tmp2
);
6339 tcg_temp_free_ptr(fpstatus
);
6342 case NEON_2RM_VCGE0_F
:
6344 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6345 tmp2
= tcg_const_i32(0);
6346 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6347 tcg_temp_free_i32(tmp2
);
6348 tcg_temp_free_ptr(fpstatus
);
6351 case NEON_2RM_VCEQ0_F
:
6353 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6354 tmp2
= tcg_const_i32(0);
6355 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6356 tcg_temp_free_i32(tmp2
);
6357 tcg_temp_free_ptr(fpstatus
);
6360 case NEON_2RM_VCLE0_F
:
6362 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6363 tmp2
= tcg_const_i32(0);
6364 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6365 tcg_temp_free_i32(tmp2
);
6366 tcg_temp_free_ptr(fpstatus
);
6369 case NEON_2RM_VCLT0_F
:
6371 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6372 tmp2
= tcg_const_i32(0);
6373 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6374 tcg_temp_free_i32(tmp2
);
6375 tcg_temp_free_ptr(fpstatus
);
6378 case NEON_2RM_VABS_F
:
6381 case NEON_2RM_VNEG_F
:
6385 tmp2
= neon_load_reg(rd
, pass
);
6386 neon_store_reg(rm
, pass
, tmp2
);
6389 tmp2
= neon_load_reg(rd
, pass
);
6391 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6392 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6395 neon_store_reg(rm
, pass
, tmp2
);
6397 case NEON_2RM_VRECPE
:
6398 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6400 case NEON_2RM_VRSQRTE
:
6401 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6403 case NEON_2RM_VRECPE_F
:
6404 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6406 case NEON_2RM_VRSQRTE_F
:
6407 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6409 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6412 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6415 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6416 gen_vfp_tosiz(0, 1);
6418 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6419 gen_vfp_touiz(0, 1);
6422 /* Reserved op values were caught by the
6423 * neon_2rm_sizes[] check earlier.
6427 if (neon_2rm_is_float_op(op
)) {
6428 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6429 neon_reg_offset(rd
, pass
));
6431 neon_store_reg(rd
, pass
, tmp
);
6436 } else if ((insn
& (1 << 10)) == 0) {
6438 int n
= ((insn
>> 8) & 3) + 1;
6439 if ((rn
+ n
) > 32) {
6440 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6441 * helper function running off the end of the register file.
6446 if (insn
& (1 << 6)) {
6447 tmp
= neon_load_reg(rd
, 0);
6449 tmp
= tcg_temp_new_i32();
6450 tcg_gen_movi_i32(tmp
, 0);
6452 tmp2
= neon_load_reg(rm
, 0);
6453 tmp4
= tcg_const_i32(rn
);
6454 tmp5
= tcg_const_i32(n
);
6455 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6456 tcg_temp_free_i32(tmp
);
6457 if (insn
& (1 << 6)) {
6458 tmp
= neon_load_reg(rd
, 1);
6460 tmp
= tcg_temp_new_i32();
6461 tcg_gen_movi_i32(tmp
, 0);
6463 tmp3
= neon_load_reg(rm
, 1);
6464 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6465 tcg_temp_free_i32(tmp5
);
6466 tcg_temp_free_i32(tmp4
);
6467 neon_store_reg(rd
, 0, tmp2
);
6468 neon_store_reg(rd
, 1, tmp3
);
6469 tcg_temp_free_i32(tmp
);
6470 } else if ((insn
& 0x380) == 0) {
6472 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6475 if (insn
& (1 << 19)) {
6476 tmp
= neon_load_reg(rm
, 1);
6478 tmp
= neon_load_reg(rm
, 0);
6480 if (insn
& (1 << 16)) {
6481 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6482 } else if (insn
& (1 << 17)) {
6483 if ((insn
>> 18) & 1)
6484 gen_neon_dup_high16(tmp
);
6486 gen_neon_dup_low16(tmp
);
6488 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6489 tmp2
= tcg_temp_new_i32();
6490 tcg_gen_mov_i32(tmp2
, tmp
);
6491 neon_store_reg(rd
, pass
, tmp2
);
6493 tcg_temp_free_i32(tmp
);
6502 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6504 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6505 const ARMCPRegInfo
*ri
;
6506 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6508 cpnum
= (insn
>> 8) & 0xf;
6509 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6510 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6513 /* First check for coprocessor space used for actual instructions */
6517 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6518 return disas_iwmmxt_insn(env
, s
, insn
);
6519 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6520 return disas_dsp_insn(env
, s
, insn
);
6527 /* Otherwise treat as a generic register access */
6528 is64
= (insn
& (1 << 25)) == 0;
6529 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6537 opc1
= (insn
>> 4) & 0xf;
6539 rt2
= (insn
>> 16) & 0xf;
6541 crn
= (insn
>> 16) & 0xf;
6542 opc1
= (insn
>> 21) & 7;
6543 opc2
= (insn
>> 5) & 7;
6546 isread
= (insn
>> 20) & 1;
6547 rt
= (insn
>> 12) & 0xf;
6549 ri
= get_arm_cp_reginfo(cpu
,
6550 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6552 /* Check access permissions */
6553 if (!cp_access_ok(env
, ri
, isread
)) {
6557 /* Handle special cases first */
6558 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6565 gen_set_pc_im(s
, s
->pc
);
6566 s
->is_jmp
= DISAS_WFI
;
6572 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6581 if (ri
->type
& ARM_CP_CONST
) {
6582 tmp64
= tcg_const_i64(ri
->resetvalue
);
6583 } else if (ri
->readfn
) {
6585 gen_set_pc_im(s
, s
->pc
);
6586 tmp64
= tcg_temp_new_i64();
6587 tmpptr
= tcg_const_ptr(ri
);
6588 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6589 tcg_temp_free_ptr(tmpptr
);
6591 tmp64
= tcg_temp_new_i64();
6592 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6594 tmp
= tcg_temp_new_i32();
6595 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6596 store_reg(s
, rt
, tmp
);
6597 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6598 tmp
= tcg_temp_new_i32();
6599 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6600 tcg_temp_free_i64(tmp64
);
6601 store_reg(s
, rt2
, tmp
);
6604 if (ri
->type
& ARM_CP_CONST
) {
6605 tmp
= tcg_const_i32(ri
->resetvalue
);
6606 } else if (ri
->readfn
) {
6608 gen_set_pc_im(s
, s
->pc
);
6609 tmp
= tcg_temp_new_i32();
6610 tmpptr
= tcg_const_ptr(ri
);
6611 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6612 tcg_temp_free_ptr(tmpptr
);
6614 tmp
= load_cpu_offset(ri
->fieldoffset
);
6617 /* Destination register of r15 for 32 bit loads sets
6618 * the condition codes from the high 4 bits of the value
6621 tcg_temp_free_i32(tmp
);
6623 store_reg(s
, rt
, tmp
);
6628 if (ri
->type
& ARM_CP_CONST
) {
6629 /* If not forbidden by access permissions, treat as WI */
6634 TCGv_i32 tmplo
, tmphi
;
6635 TCGv_i64 tmp64
= tcg_temp_new_i64();
6636 tmplo
= load_reg(s
, rt
);
6637 tmphi
= load_reg(s
, rt2
);
6638 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6639 tcg_temp_free_i32(tmplo
);
6640 tcg_temp_free_i32(tmphi
);
6642 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6643 gen_set_pc_im(s
, s
->pc
);
6644 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6645 tcg_temp_free_ptr(tmpptr
);
6647 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6649 tcg_temp_free_i64(tmp64
);
6654 gen_set_pc_im(s
, s
->pc
);
6655 tmp
= load_reg(s
, rt
);
6656 tmpptr
= tcg_const_ptr(ri
);
6657 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6658 tcg_temp_free_ptr(tmpptr
);
6659 tcg_temp_free_i32(tmp
);
6661 TCGv_i32 tmp
= load_reg(s
, rt
);
6662 store_cpu_offset(tmp
, ri
->fieldoffset
);
6667 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6668 /* I/O operations must end the TB here (whether read or write) */
6671 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6672 /* We default to ending the TB on a coprocessor register write,
6673 * but allow this to be suppressed by the register definition
6674 * (usually only necessary to work around guest bugs).
6686 /* Store a 64-bit value to a register pair. Clobbers val. */
6687 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6690 tmp
= tcg_temp_new_i32();
6691 tcg_gen_trunc_i64_i32(tmp
, val
);
6692 store_reg(s
, rlow
, tmp
);
6693 tmp
= tcg_temp_new_i32();
6694 tcg_gen_shri_i64(val
, val
, 32);
6695 tcg_gen_trunc_i64_i32(tmp
, val
);
6696 store_reg(s
, rhigh
, tmp
);
6699 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6700 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6705 /* Load value and extend to 64 bits. */
6706 tmp
= tcg_temp_new_i64();
6707 tmp2
= load_reg(s
, rlow
);
6708 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6709 tcg_temp_free_i32(tmp2
);
6710 tcg_gen_add_i64(val
, val
, tmp
);
6711 tcg_temp_free_i64(tmp
);
6714 /* load and add a 64-bit value from a register pair. */
6715 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6721 /* Load 64-bit value rd:rn. */
6722 tmpl
= load_reg(s
, rlow
);
6723 tmph
= load_reg(s
, rhigh
);
6724 tmp
= tcg_temp_new_i64();
6725 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6726 tcg_temp_free_i32(tmpl
);
6727 tcg_temp_free_i32(tmph
);
6728 tcg_gen_add_i64(val
, val
, tmp
);
6729 tcg_temp_free_i64(tmp
);
6732 /* Set N and Z flags from hi|lo. */
6733 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6735 tcg_gen_mov_i32(cpu_NF
, hi
);
6736 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6739 /* Load/Store exclusive instructions are implemented by remembering
6740 the value/address loaded, and seeing if these are the same
6741 when the store is performed. This should be sufficient to implement
6742 the architecturally mandated semantics, and avoids having to monitor
6745 In system emulation mode only one CPU will be running at once, so
6746 this sequence is effectively atomic. In user emulation mode we
6747 throw an exception and handle the atomic operation elsewhere. */
6748 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6749 TCGv_i32 addr
, int size
)
6751 TCGv_i32 tmp
= tcg_temp_new_i32();
6755 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6758 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6762 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6767 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6768 store_reg(s
, rt
, tmp
);
6770 TCGv_i32 tmp2
= tcg_temp_new_i32();
6771 tcg_gen_addi_i32(tmp2
, addr
, 4);
6772 tmp
= tcg_temp_new_i32();
6773 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6774 tcg_temp_free_i32(tmp2
);
6775 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6776 store_reg(s
, rt2
, tmp
);
6778 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6781 static void gen_clrex(DisasContext
*s
)
6783 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6786 #ifdef CONFIG_USER_ONLY
6787 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6788 TCGv_i32 addr
, int size
)
6790 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6791 tcg_gen_movi_i32(cpu_exclusive_info
,
6792 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6793 gen_exception_insn(s
, 4, EXCP_STREX
);
6796 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6797 TCGv_i32 addr
, int size
)
6803 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6809 fail_label
= gen_new_label();
6810 done_label
= gen_new_label();
6811 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6812 tmp
= tcg_temp_new_i32();
6815 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
6818 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
6822 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
6827 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6828 tcg_temp_free_i32(tmp
);
6830 TCGv_i32 tmp2
= tcg_temp_new_i32();
6831 tcg_gen_addi_i32(tmp2
, addr
, 4);
6832 tmp
= tcg_temp_new_i32();
6833 gen_aa32_ld32u(tmp
, tmp2
, IS_USER(s
));
6834 tcg_temp_free_i32(tmp2
);
6835 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6836 tcg_temp_free_i32(tmp
);
6838 tmp
= load_reg(s
, rt
);
6841 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
6844 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
6848 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6853 tcg_temp_free_i32(tmp
);
6855 tcg_gen_addi_i32(addr
, addr
, 4);
6856 tmp
= load_reg(s
, rt2
);
6857 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
6858 tcg_temp_free_i32(tmp
);
6860 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6861 tcg_gen_br(done_label
);
6862 gen_set_label(fail_label
);
6863 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6864 gen_set_label(done_label
);
6865 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6872 * @mode: mode field from insn (which stack to store to)
6873 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6874 * @writeback: true if writeback bit set
6876 * Generate code for the SRS (Store Return State) insn.
6878 static void gen_srs(DisasContext
*s
,
6879 uint32_t mode
, uint32_t amode
, bool writeback
)
6882 TCGv_i32 addr
= tcg_temp_new_i32();
6883 TCGv_i32 tmp
= tcg_const_i32(mode
);
6884 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6885 tcg_temp_free_i32(tmp
);
6902 tcg_gen_addi_i32(addr
, addr
, offset
);
6903 tmp
= load_reg(s
, 14);
6904 gen_aa32_st32(tmp
, addr
, 0);
6905 tcg_temp_free_i32(tmp
);
6906 tmp
= load_cpu_field(spsr
);
6907 tcg_gen_addi_i32(addr
, addr
, 4);
6908 gen_aa32_st32(tmp
, addr
, 0);
6909 tcg_temp_free_i32(tmp
);
6927 tcg_gen_addi_i32(addr
, addr
, offset
);
6928 tmp
= tcg_const_i32(mode
);
6929 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6930 tcg_temp_free_i32(tmp
);
6932 tcg_temp_free_i32(addr
);
6935 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6937 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6944 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6947 /* M variants do not implement ARM mode. */
6952 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6953 * choose to UNDEF. In ARMv5 and above the space is used
6954 * for miscellaneous unconditional instructions.
6958 /* Unconditional instructions. */
6959 if (((insn
>> 25) & 7) == 1) {
6960 /* NEON Data processing. */
6961 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6964 if (disas_neon_data_insn(env
, s
, insn
))
6968 if ((insn
& 0x0f100000) == 0x04000000) {
6969 /* NEON load/store. */
6970 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6973 if (disas_neon_ls_insn(env
, s
, insn
))
6977 if ((insn
& 0x0f000e10) == 0x0e000a00) {
6979 if (disas_vfp_insn(env
, s
, insn
)) {
6984 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6985 ((insn
& 0x0f30f010) == 0x0710f000)) {
6986 if ((insn
& (1 << 22)) == 0) {
6988 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6992 /* Otherwise PLD; v5TE+ */
6996 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6997 ((insn
& 0x0f70f010) == 0x0650f000)) {
6999 return; /* PLI; V7 */
7001 if (((insn
& 0x0f700000) == 0x04100000) ||
7002 ((insn
& 0x0f700010) == 0x06100000)) {
7003 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7006 return; /* v7MP: Unallocated memory hint: must NOP */
7009 if ((insn
& 0x0ffffdff) == 0x01010000) {
7012 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7013 /* Dynamic endianness switching not implemented. */
7014 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7018 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7019 switch ((insn
>> 4) & 0xf) {
7028 /* We don't emulate caches so these are a no-op. */
7033 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7039 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7041 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7047 rn
= (insn
>> 16) & 0xf;
7048 addr
= load_reg(s
, rn
);
7049 i
= (insn
>> 23) & 3;
7051 case 0: offset
= -4; break; /* DA */
7052 case 1: offset
= 0; break; /* IA */
7053 case 2: offset
= -8; break; /* DB */
7054 case 3: offset
= 4; break; /* IB */
7058 tcg_gen_addi_i32(addr
, addr
, offset
);
7059 /* Load PC into tmp and CPSR into tmp2. */
7060 tmp
= tcg_temp_new_i32();
7061 gen_aa32_ld32u(tmp
, addr
, 0);
7062 tcg_gen_addi_i32(addr
, addr
, 4);
7063 tmp2
= tcg_temp_new_i32();
7064 gen_aa32_ld32u(tmp2
, addr
, 0);
7065 if (insn
& (1 << 21)) {
7066 /* Base writeback. */
7068 case 0: offset
= -8; break;
7069 case 1: offset
= 4; break;
7070 case 2: offset
= -4; break;
7071 case 3: offset
= 0; break;
7075 tcg_gen_addi_i32(addr
, addr
, offset
);
7076 store_reg(s
, rn
, addr
);
7078 tcg_temp_free_i32(addr
);
7080 gen_rfe(s
, tmp
, tmp2
);
7082 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7083 /* branch link and change to thumb (blx <offset>) */
7086 val
= (uint32_t)s
->pc
;
7087 tmp
= tcg_temp_new_i32();
7088 tcg_gen_movi_i32(tmp
, val
);
7089 store_reg(s
, 14, tmp
);
7090 /* Sign-extend the 24-bit offset */
7091 offset
= (((int32_t)insn
) << 8) >> 8;
7092 /* offset * 4 + bit24 * 2 + (thumb bit) */
7093 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7094 /* pipeline offset */
7096 /* protected by ARCH(5); above, near the start of uncond block */
7099 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7100 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7101 /* iWMMXt register transfer. */
7102 if (env
->cp15
.c15_cpar
& (1 << 1))
7103 if (!disas_iwmmxt_insn(env
, s
, insn
))
7106 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7107 /* Coprocessor double register transfer. */
7109 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7110 /* Additional coprocessor register transfer. */
7111 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7114 /* cps (privileged) */
7118 if (insn
& (1 << 19)) {
7119 if (insn
& (1 << 8))
7121 if (insn
& (1 << 7))
7123 if (insn
& (1 << 6))
7125 if (insn
& (1 << 18))
7128 if (insn
& (1 << 17)) {
7130 val
|= (insn
& 0x1f);
7133 gen_set_psr_im(s
, mask
, 0, val
);
7140 /* if not always execute, we generate a conditional jump to
7142 s
->condlabel
= gen_new_label();
7143 gen_test_cc(cond
^ 1, s
->condlabel
);
7146 if ((insn
& 0x0f900000) == 0x03000000) {
7147 if ((insn
& (1 << 21)) == 0) {
7149 rd
= (insn
>> 12) & 0xf;
7150 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7151 if ((insn
& (1 << 22)) == 0) {
7153 tmp
= tcg_temp_new_i32();
7154 tcg_gen_movi_i32(tmp
, val
);
7157 tmp
= load_reg(s
, rd
);
7158 tcg_gen_ext16u_i32(tmp
, tmp
);
7159 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7161 store_reg(s
, rd
, tmp
);
7163 if (((insn
>> 12) & 0xf) != 0xf)
7165 if (((insn
>> 16) & 0xf) == 0) {
7166 gen_nop_hint(s
, insn
& 0xff);
7168 /* CPSR = immediate */
7170 shift
= ((insn
>> 8) & 0xf) * 2;
7172 val
= (val
>> shift
) | (val
<< (32 - shift
));
7173 i
= ((insn
& (1 << 22)) != 0);
7174 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7178 } else if ((insn
& 0x0f900000) == 0x01000000
7179 && (insn
& 0x00000090) != 0x00000090) {
7180 /* miscellaneous instructions */
7181 op1
= (insn
>> 21) & 3;
7182 sh
= (insn
>> 4) & 0xf;
7185 case 0x0: /* move program status register */
7188 tmp
= load_reg(s
, rm
);
7189 i
= ((op1
& 2) != 0);
7190 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7194 rd
= (insn
>> 12) & 0xf;
7198 tmp
= load_cpu_field(spsr
);
7200 tmp
= tcg_temp_new_i32();
7201 gen_helper_cpsr_read(tmp
, cpu_env
);
7203 store_reg(s
, rd
, tmp
);
7208 /* branch/exchange thumb (bx). */
7210 tmp
= load_reg(s
, rm
);
7212 } else if (op1
== 3) {
7215 rd
= (insn
>> 12) & 0xf;
7216 tmp
= load_reg(s
, rm
);
7217 gen_helper_clz(tmp
, tmp
);
7218 store_reg(s
, rd
, tmp
);
7226 /* Trivial implementation equivalent to bx. */
7227 tmp
= load_reg(s
, rm
);
7238 /* branch link/exchange thumb (blx) */
7239 tmp
= load_reg(s
, rm
);
7240 tmp2
= tcg_temp_new_i32();
7241 tcg_gen_movi_i32(tmp2
, s
->pc
);
7242 store_reg(s
, 14, tmp2
);
7245 case 0x5: /* saturating add/subtract */
7247 rd
= (insn
>> 12) & 0xf;
7248 rn
= (insn
>> 16) & 0xf;
7249 tmp
= load_reg(s
, rm
);
7250 tmp2
= load_reg(s
, rn
);
7252 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7254 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7256 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7257 tcg_temp_free_i32(tmp2
);
7258 store_reg(s
, rd
, tmp
);
7261 /* SMC instruction (op1 == 3)
7262 and undefined instructions (op1 == 0 || op1 == 2)
7269 gen_exception_insn(s
, 4, EXCP_BKPT
);
7271 case 0x8: /* signed multiply */
7276 rs
= (insn
>> 8) & 0xf;
7277 rn
= (insn
>> 12) & 0xf;
7278 rd
= (insn
>> 16) & 0xf;
7280 /* (32 * 16) >> 16 */
7281 tmp
= load_reg(s
, rm
);
7282 tmp2
= load_reg(s
, rs
);
7284 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7287 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7288 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7289 tmp
= tcg_temp_new_i32();
7290 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7291 tcg_temp_free_i64(tmp64
);
7292 if ((sh
& 2) == 0) {
7293 tmp2
= load_reg(s
, rn
);
7294 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7295 tcg_temp_free_i32(tmp2
);
7297 store_reg(s
, rd
, tmp
);
7300 tmp
= load_reg(s
, rm
);
7301 tmp2
= load_reg(s
, rs
);
7302 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7303 tcg_temp_free_i32(tmp2
);
7305 tmp64
= tcg_temp_new_i64();
7306 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7307 tcg_temp_free_i32(tmp
);
7308 gen_addq(s
, tmp64
, rn
, rd
);
7309 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7310 tcg_temp_free_i64(tmp64
);
7313 tmp2
= load_reg(s
, rn
);
7314 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7315 tcg_temp_free_i32(tmp2
);
7317 store_reg(s
, rd
, tmp
);
7324 } else if (((insn
& 0x0e000000) == 0 &&
7325 (insn
& 0x00000090) != 0x90) ||
7326 ((insn
& 0x0e000000) == (1 << 25))) {
7327 int set_cc
, logic_cc
, shiftop
;
7329 op1
= (insn
>> 21) & 0xf;
7330 set_cc
= (insn
>> 20) & 1;
7331 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7333 /* data processing instruction */
7334 if (insn
& (1 << 25)) {
7335 /* immediate operand */
7337 shift
= ((insn
>> 8) & 0xf) * 2;
7339 val
= (val
>> shift
) | (val
<< (32 - shift
));
7341 tmp2
= tcg_temp_new_i32();
7342 tcg_gen_movi_i32(tmp2
, val
);
7343 if (logic_cc
&& shift
) {
7344 gen_set_CF_bit31(tmp2
);
7349 tmp2
= load_reg(s
, rm
);
7350 shiftop
= (insn
>> 5) & 3;
7351 if (!(insn
& (1 << 4))) {
7352 shift
= (insn
>> 7) & 0x1f;
7353 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7355 rs
= (insn
>> 8) & 0xf;
7356 tmp
= load_reg(s
, rs
);
7357 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7360 if (op1
!= 0x0f && op1
!= 0x0d) {
7361 rn
= (insn
>> 16) & 0xf;
7362 tmp
= load_reg(s
, rn
);
7364 TCGV_UNUSED_I32(tmp
);
7366 rd
= (insn
>> 12) & 0xf;
7369 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7373 store_reg_bx(env
, s
, rd
, tmp
);
7376 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7380 store_reg_bx(env
, s
, rd
, tmp
);
7383 if (set_cc
&& rd
== 15) {
7384 /* SUBS r15, ... is used for exception return. */
7388 gen_sub_CC(tmp
, tmp
, tmp2
);
7389 gen_exception_return(s
, tmp
);
7392 gen_sub_CC(tmp
, tmp
, tmp2
);
7394 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7396 store_reg_bx(env
, s
, rd
, tmp
);
7401 gen_sub_CC(tmp
, tmp2
, tmp
);
7403 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7405 store_reg_bx(env
, s
, rd
, tmp
);
7409 gen_add_CC(tmp
, tmp
, tmp2
);
7411 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7413 store_reg_bx(env
, s
, rd
, tmp
);
7417 gen_adc_CC(tmp
, tmp
, tmp2
);
7419 gen_add_carry(tmp
, tmp
, tmp2
);
7421 store_reg_bx(env
, s
, rd
, tmp
);
7425 gen_sbc_CC(tmp
, tmp
, tmp2
);
7427 gen_sub_carry(tmp
, tmp
, tmp2
);
7429 store_reg_bx(env
, s
, rd
, tmp
);
7433 gen_sbc_CC(tmp
, tmp2
, tmp
);
7435 gen_sub_carry(tmp
, tmp2
, tmp
);
7437 store_reg_bx(env
, s
, rd
, tmp
);
7441 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7444 tcg_temp_free_i32(tmp
);
7448 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7451 tcg_temp_free_i32(tmp
);
7455 gen_sub_CC(tmp
, tmp
, tmp2
);
7457 tcg_temp_free_i32(tmp
);
7461 gen_add_CC(tmp
, tmp
, tmp2
);
7463 tcg_temp_free_i32(tmp
);
7466 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7470 store_reg_bx(env
, s
, rd
, tmp
);
7473 if (logic_cc
&& rd
== 15) {
7474 /* MOVS r15, ... is used for exception return. */
7478 gen_exception_return(s
, tmp2
);
7483 store_reg_bx(env
, s
, rd
, tmp2
);
7487 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7491 store_reg_bx(env
, s
, rd
, tmp
);
7495 tcg_gen_not_i32(tmp2
, tmp2
);
7499 store_reg_bx(env
, s
, rd
, tmp2
);
7502 if (op1
!= 0x0f && op1
!= 0x0d) {
7503 tcg_temp_free_i32(tmp2
);
7506 /* other instructions */
7507 op1
= (insn
>> 24) & 0xf;
7511 /* multiplies, extra load/stores */
7512 sh
= (insn
>> 5) & 3;
7515 rd
= (insn
>> 16) & 0xf;
7516 rn
= (insn
>> 12) & 0xf;
7517 rs
= (insn
>> 8) & 0xf;
7519 op1
= (insn
>> 20) & 0xf;
7521 case 0: case 1: case 2: case 3: case 6:
7523 tmp
= load_reg(s
, rs
);
7524 tmp2
= load_reg(s
, rm
);
7525 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7526 tcg_temp_free_i32(tmp2
);
7527 if (insn
& (1 << 22)) {
7528 /* Subtract (mls) */
7530 tmp2
= load_reg(s
, rn
);
7531 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7532 tcg_temp_free_i32(tmp2
);
7533 } else if (insn
& (1 << 21)) {
7535 tmp2
= load_reg(s
, rn
);
7536 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7537 tcg_temp_free_i32(tmp2
);
7539 if (insn
& (1 << 20))
7541 store_reg(s
, rd
, tmp
);
7544 /* 64 bit mul double accumulate (UMAAL) */
7546 tmp
= load_reg(s
, rs
);
7547 tmp2
= load_reg(s
, rm
);
7548 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7549 gen_addq_lo(s
, tmp64
, rn
);
7550 gen_addq_lo(s
, tmp64
, rd
);
7551 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7552 tcg_temp_free_i64(tmp64
);
7554 case 8: case 9: case 10: case 11:
7555 case 12: case 13: case 14: case 15:
7556 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7557 tmp
= load_reg(s
, rs
);
7558 tmp2
= load_reg(s
, rm
);
7559 if (insn
& (1 << 22)) {
7560 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7562 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7564 if (insn
& (1 << 21)) { /* mult accumulate */
7565 TCGv_i32 al
= load_reg(s
, rn
);
7566 TCGv_i32 ah
= load_reg(s
, rd
);
7567 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7568 tcg_temp_free_i32(al
);
7569 tcg_temp_free_i32(ah
);
7571 if (insn
& (1 << 20)) {
7572 gen_logicq_cc(tmp
, tmp2
);
7574 store_reg(s
, rn
, tmp
);
7575 store_reg(s
, rd
, tmp2
);
7581 rn
= (insn
>> 16) & 0xf;
7582 rd
= (insn
>> 12) & 0xf;
7583 if (insn
& (1 << 23)) {
7584 /* load/store exclusive */
7585 int op2
= (insn
>> 8) & 3;
7586 op1
= (insn
>> 21) & 0x3;
7589 case 0: /* lda/stl */
7595 case 1: /* reserved */
7597 case 2: /* ldaex/stlex */
7600 case 3: /* ldrex/strex */
7609 addr
= tcg_temp_local_new_i32();
7610 load_reg_var(s
, addr
, rn
);
7612 /* Since the emulation does not have barriers,
7613 the acquire/release semantics need no special
7616 if (insn
& (1 << 20)) {
7617 tmp
= tcg_temp_new_i32();
7620 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7623 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7626 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7631 store_reg(s
, rd
, tmp
);
7634 tmp
= load_reg(s
, rm
);
7637 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7640 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7643 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7648 tcg_temp_free_i32(tmp
);
7650 } else if (insn
& (1 << 20)) {
7653 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7655 case 1: /* ldrexd */
7656 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7658 case 2: /* ldrexb */
7659 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7661 case 3: /* ldrexh */
7662 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7671 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7673 case 1: /* strexd */
7674 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7676 case 2: /* strexb */
7677 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7679 case 3: /* strexh */
7680 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7686 tcg_temp_free_i32(addr
);
7688 /* SWP instruction */
7691 /* ??? This is not really atomic. However we know
7692 we never have multiple CPUs running in parallel,
7693 so it is good enough. */
7694 addr
= load_reg(s
, rn
);
7695 tmp
= load_reg(s
, rm
);
7696 tmp2
= tcg_temp_new_i32();
7697 if (insn
& (1 << 22)) {
7698 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7699 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7701 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7702 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7704 tcg_temp_free_i32(tmp
);
7705 tcg_temp_free_i32(addr
);
7706 store_reg(s
, rd
, tmp2
);
7712 /* Misc load/store */
7713 rn
= (insn
>> 16) & 0xf;
7714 rd
= (insn
>> 12) & 0xf;
7715 addr
= load_reg(s
, rn
);
7716 if (insn
& (1 << 24))
7717 gen_add_datah_offset(s
, insn
, 0, addr
);
7719 if (insn
& (1 << 20)) {
7721 tmp
= tcg_temp_new_i32();
7724 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7727 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7731 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7735 } else if (sh
& 2) {
7740 tmp
= load_reg(s
, rd
);
7741 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7742 tcg_temp_free_i32(tmp
);
7743 tcg_gen_addi_i32(addr
, addr
, 4);
7744 tmp
= load_reg(s
, rd
+ 1);
7745 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7746 tcg_temp_free_i32(tmp
);
7750 tmp
= tcg_temp_new_i32();
7751 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7752 store_reg(s
, rd
, tmp
);
7753 tcg_gen_addi_i32(addr
, addr
, 4);
7754 tmp
= tcg_temp_new_i32();
7755 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7759 address_offset
= -4;
7762 tmp
= load_reg(s
, rd
);
7763 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7764 tcg_temp_free_i32(tmp
);
7767 /* Perform base writeback before the loaded value to
7768 ensure correct behavior with overlapping index registers.
7769 ldrd with base writeback is is undefined if the
7770 destination and index registers overlap. */
7771 if (!(insn
& (1 << 24))) {
7772 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7773 store_reg(s
, rn
, addr
);
7774 } else if (insn
& (1 << 21)) {
7776 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7777 store_reg(s
, rn
, addr
);
7779 tcg_temp_free_i32(addr
);
7782 /* Complete the load. */
7783 store_reg(s
, rd
, tmp
);
7792 if (insn
& (1 << 4)) {
7794 /* Armv6 Media instructions. */
7796 rn
= (insn
>> 16) & 0xf;
7797 rd
= (insn
>> 12) & 0xf;
7798 rs
= (insn
>> 8) & 0xf;
7799 switch ((insn
>> 23) & 3) {
7800 case 0: /* Parallel add/subtract. */
7801 op1
= (insn
>> 20) & 7;
7802 tmp
= load_reg(s
, rn
);
7803 tmp2
= load_reg(s
, rm
);
7804 sh
= (insn
>> 5) & 7;
7805 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7807 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7808 tcg_temp_free_i32(tmp2
);
7809 store_reg(s
, rd
, tmp
);
7812 if ((insn
& 0x00700020) == 0) {
7813 /* Halfword pack. */
7814 tmp
= load_reg(s
, rn
);
7815 tmp2
= load_reg(s
, rm
);
7816 shift
= (insn
>> 7) & 0x1f;
7817 if (insn
& (1 << 6)) {
7821 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7822 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7823 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7827 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7828 tcg_gen_ext16u_i32(tmp
, tmp
);
7829 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7831 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7832 tcg_temp_free_i32(tmp2
);
7833 store_reg(s
, rd
, tmp
);
7834 } else if ((insn
& 0x00200020) == 0x00200000) {
7836 tmp
= load_reg(s
, rm
);
7837 shift
= (insn
>> 7) & 0x1f;
7838 if (insn
& (1 << 6)) {
7841 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7843 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7845 sh
= (insn
>> 16) & 0x1f;
7846 tmp2
= tcg_const_i32(sh
);
7847 if (insn
& (1 << 22))
7848 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7850 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7851 tcg_temp_free_i32(tmp2
);
7852 store_reg(s
, rd
, tmp
);
7853 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7855 tmp
= load_reg(s
, rm
);
7856 sh
= (insn
>> 16) & 0x1f;
7857 tmp2
= tcg_const_i32(sh
);
7858 if (insn
& (1 << 22))
7859 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7861 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7862 tcg_temp_free_i32(tmp2
);
7863 store_reg(s
, rd
, tmp
);
7864 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7866 tmp
= load_reg(s
, rn
);
7867 tmp2
= load_reg(s
, rm
);
7868 tmp3
= tcg_temp_new_i32();
7869 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7870 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7871 tcg_temp_free_i32(tmp3
);
7872 tcg_temp_free_i32(tmp2
);
7873 store_reg(s
, rd
, tmp
);
7874 } else if ((insn
& 0x000003e0) == 0x00000060) {
7875 tmp
= load_reg(s
, rm
);
7876 shift
= (insn
>> 10) & 3;
7877 /* ??? In many cases it's not necessary to do a
7878 rotate, a shift is sufficient. */
7880 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7881 op1
= (insn
>> 20) & 7;
7883 case 0: gen_sxtb16(tmp
); break;
7884 case 2: gen_sxtb(tmp
); break;
7885 case 3: gen_sxth(tmp
); break;
7886 case 4: gen_uxtb16(tmp
); break;
7887 case 6: gen_uxtb(tmp
); break;
7888 case 7: gen_uxth(tmp
); break;
7889 default: goto illegal_op
;
7892 tmp2
= load_reg(s
, rn
);
7893 if ((op1
& 3) == 0) {
7894 gen_add16(tmp
, tmp2
);
7896 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7897 tcg_temp_free_i32(tmp2
);
7900 store_reg(s
, rd
, tmp
);
7901 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7903 tmp
= load_reg(s
, rm
);
7904 if (insn
& (1 << 22)) {
7905 if (insn
& (1 << 7)) {
7909 gen_helper_rbit(tmp
, tmp
);
7912 if (insn
& (1 << 7))
7915 tcg_gen_bswap32_i32(tmp
, tmp
);
7917 store_reg(s
, rd
, tmp
);
7922 case 2: /* Multiplies (Type 3). */
7923 switch ((insn
>> 20) & 0x7) {
7925 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7926 /* op2 not 00x or 11x : UNDEF */
7929 /* Signed multiply most significant [accumulate].
7930 (SMMUL, SMMLA, SMMLS) */
7931 tmp
= load_reg(s
, rm
);
7932 tmp2
= load_reg(s
, rs
);
7933 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7936 tmp
= load_reg(s
, rd
);
7937 if (insn
& (1 << 6)) {
7938 tmp64
= gen_subq_msw(tmp64
, tmp
);
7940 tmp64
= gen_addq_msw(tmp64
, tmp
);
7943 if (insn
& (1 << 5)) {
7944 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7946 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7947 tmp
= tcg_temp_new_i32();
7948 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7949 tcg_temp_free_i64(tmp64
);
7950 store_reg(s
, rn
, tmp
);
7954 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7955 if (insn
& (1 << 7)) {
7958 tmp
= load_reg(s
, rm
);
7959 tmp2
= load_reg(s
, rs
);
7960 if (insn
& (1 << 5))
7961 gen_swap_half(tmp2
);
7962 gen_smul_dual(tmp
, tmp2
);
7963 if (insn
& (1 << 6)) {
7964 /* This subtraction cannot overflow. */
7965 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7967 /* This addition cannot overflow 32 bits;
7968 * however it may overflow considered as a signed
7969 * operation, in which case we must set the Q flag.
7971 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7973 tcg_temp_free_i32(tmp2
);
7974 if (insn
& (1 << 22)) {
7975 /* smlald, smlsld */
7976 tmp64
= tcg_temp_new_i64();
7977 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7978 tcg_temp_free_i32(tmp
);
7979 gen_addq(s
, tmp64
, rd
, rn
);
7980 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7981 tcg_temp_free_i64(tmp64
);
7983 /* smuad, smusd, smlad, smlsd */
7986 tmp2
= load_reg(s
, rd
);
7987 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7988 tcg_temp_free_i32(tmp2
);
7990 store_reg(s
, rn
, tmp
);
7996 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7999 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8002 tmp
= load_reg(s
, rm
);
8003 tmp2
= load_reg(s
, rs
);
8004 if (insn
& (1 << 21)) {
8005 gen_helper_udiv(tmp
, tmp
, tmp2
);
8007 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8009 tcg_temp_free_i32(tmp2
);
8010 store_reg(s
, rn
, tmp
);
8017 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8019 case 0: /* Unsigned sum of absolute differences. */
8021 tmp
= load_reg(s
, rm
);
8022 tmp2
= load_reg(s
, rs
);
8023 gen_helper_usad8(tmp
, tmp
, tmp2
);
8024 tcg_temp_free_i32(tmp2
);
8026 tmp2
= load_reg(s
, rd
);
8027 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8028 tcg_temp_free_i32(tmp2
);
8030 store_reg(s
, rn
, tmp
);
8032 case 0x20: case 0x24: case 0x28: case 0x2c:
8033 /* Bitfield insert/clear. */
8035 shift
= (insn
>> 7) & 0x1f;
8036 i
= (insn
>> 16) & 0x1f;
8039 tmp
= tcg_temp_new_i32();
8040 tcg_gen_movi_i32(tmp
, 0);
8042 tmp
= load_reg(s
, rm
);
8045 tmp2
= load_reg(s
, rd
);
8046 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8047 tcg_temp_free_i32(tmp2
);
8049 store_reg(s
, rd
, tmp
);
8051 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8052 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8054 tmp
= load_reg(s
, rm
);
8055 shift
= (insn
>> 7) & 0x1f;
8056 i
= ((insn
>> 16) & 0x1f) + 1;
8061 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8063 gen_sbfx(tmp
, shift
, i
);
8066 store_reg(s
, rd
, tmp
);
8076 /* Check for undefined extension instructions
8077 * per the ARM Bible IE:
8078 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8080 sh
= (0xf << 20) | (0xf << 4);
8081 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8085 /* load/store byte/word */
8086 rn
= (insn
>> 16) & 0xf;
8087 rd
= (insn
>> 12) & 0xf;
8088 tmp2
= load_reg(s
, rn
);
8089 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
8090 if (insn
& (1 << 24))
8091 gen_add_data_offset(s
, insn
, tmp2
);
8092 if (insn
& (1 << 20)) {
8094 tmp
= tcg_temp_new_i32();
8095 if (insn
& (1 << 22)) {
8096 gen_aa32_ld8u(tmp
, tmp2
, i
);
8098 gen_aa32_ld32u(tmp
, tmp2
, i
);
8102 tmp
= load_reg(s
, rd
);
8103 if (insn
& (1 << 22)) {
8104 gen_aa32_st8(tmp
, tmp2
, i
);
8106 gen_aa32_st32(tmp
, tmp2
, i
);
8108 tcg_temp_free_i32(tmp
);
8110 if (!(insn
& (1 << 24))) {
8111 gen_add_data_offset(s
, insn
, tmp2
);
8112 store_reg(s
, rn
, tmp2
);
8113 } else if (insn
& (1 << 21)) {
8114 store_reg(s
, rn
, tmp2
);
8116 tcg_temp_free_i32(tmp2
);
8118 if (insn
& (1 << 20)) {
8119 /* Complete the load. */
8120 store_reg_from_load(env
, s
, rd
, tmp
);
8126 int j
, n
, user
, loaded_base
;
8127 TCGv_i32 loaded_var
;
8128 /* load/store multiple words */
8129 /* XXX: store correct base if write back */
8131 if (insn
& (1 << 22)) {
8133 goto illegal_op
; /* only usable in supervisor mode */
8135 if ((insn
& (1 << 15)) == 0)
8138 rn
= (insn
>> 16) & 0xf;
8139 addr
= load_reg(s
, rn
);
8141 /* compute total size */
8143 TCGV_UNUSED_I32(loaded_var
);
8146 if (insn
& (1 << i
))
8149 /* XXX: test invalid n == 0 case ? */
8150 if (insn
& (1 << 23)) {
8151 if (insn
& (1 << 24)) {
8153 tcg_gen_addi_i32(addr
, addr
, 4);
8155 /* post increment */
8158 if (insn
& (1 << 24)) {
8160 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8162 /* post decrement */
8164 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8169 if (insn
& (1 << i
)) {
8170 if (insn
& (1 << 20)) {
8172 tmp
= tcg_temp_new_i32();
8173 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8175 tmp2
= tcg_const_i32(i
);
8176 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8177 tcg_temp_free_i32(tmp2
);
8178 tcg_temp_free_i32(tmp
);
8179 } else if (i
== rn
) {
8183 store_reg_from_load(env
, s
, i
, tmp
);
8188 /* special case: r15 = PC + 8 */
8189 val
= (long)s
->pc
+ 4;
8190 tmp
= tcg_temp_new_i32();
8191 tcg_gen_movi_i32(tmp
, val
);
8193 tmp
= tcg_temp_new_i32();
8194 tmp2
= tcg_const_i32(i
);
8195 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8196 tcg_temp_free_i32(tmp2
);
8198 tmp
= load_reg(s
, i
);
8200 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8201 tcg_temp_free_i32(tmp
);
8204 /* no need to add after the last transfer */
8206 tcg_gen_addi_i32(addr
, addr
, 4);
8209 if (insn
& (1 << 21)) {
8211 if (insn
& (1 << 23)) {
8212 if (insn
& (1 << 24)) {
8215 /* post increment */
8216 tcg_gen_addi_i32(addr
, addr
, 4);
8219 if (insn
& (1 << 24)) {
8222 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8224 /* post decrement */
8225 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8228 store_reg(s
, rn
, addr
);
8230 tcg_temp_free_i32(addr
);
8233 store_reg(s
, rn
, loaded_var
);
8235 if ((insn
& (1 << 22)) && !user
) {
8236 /* Restore CPSR from SPSR. */
8237 tmp
= load_cpu_field(spsr
);
8238 gen_set_cpsr(tmp
, 0xffffffff);
8239 tcg_temp_free_i32(tmp
);
8240 s
->is_jmp
= DISAS_UPDATE
;
8249 /* branch (and link) */
8250 val
= (int32_t)s
->pc
;
8251 if (insn
& (1 << 24)) {
8252 tmp
= tcg_temp_new_i32();
8253 tcg_gen_movi_i32(tmp
, val
);
8254 store_reg(s
, 14, tmp
);
8256 offset
= sextract32(insn
<< 2, 0, 26);
8264 if (((insn
>> 8) & 0xe) == 10) {
8266 if (disas_vfp_insn(env
, s
, insn
)) {
8269 } else if (disas_coproc_insn(env
, s
, insn
)) {
8276 gen_set_pc_im(s
, s
->pc
);
8277 s
->is_jmp
= DISAS_SWI
;
8281 gen_exception_insn(s
, 4, EXCP_UDEF
);
8287 /* Return true if this is a Thumb-2 logical op. */
8289 thumb2_logic_op(int op
)
8294 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8295 then set condition code flags based on the result of the operation.
8296 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8297 to the high bit of T1.
8298 Returns zero if the opcode is valid. */
8301 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8302 TCGv_i32 t0
, TCGv_i32 t1
)
8309 tcg_gen_and_i32(t0
, t0
, t1
);
8313 tcg_gen_andc_i32(t0
, t0
, t1
);
8317 tcg_gen_or_i32(t0
, t0
, t1
);
8321 tcg_gen_orc_i32(t0
, t0
, t1
);
8325 tcg_gen_xor_i32(t0
, t0
, t1
);
8330 gen_add_CC(t0
, t0
, t1
);
8332 tcg_gen_add_i32(t0
, t0
, t1
);
8336 gen_adc_CC(t0
, t0
, t1
);
8342 gen_sbc_CC(t0
, t0
, t1
);
8344 gen_sub_carry(t0
, t0
, t1
);
8349 gen_sub_CC(t0
, t0
, t1
);
8351 tcg_gen_sub_i32(t0
, t0
, t1
);
8355 gen_sub_CC(t0
, t1
, t0
);
8357 tcg_gen_sub_i32(t0
, t1
, t0
);
8359 default: /* 5, 6, 7, 9, 12, 15. */
8365 gen_set_CF_bit31(t1
);
8370 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8372 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8374 uint32_t insn
, imm
, shift
, offset
;
8375 uint32_t rd
, rn
, rm
, rs
;
8386 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8387 || arm_feature (env
, ARM_FEATURE_M
))) {
8388 /* Thumb-1 cores may need to treat bl and blx as a pair of
8389 16-bit instructions to get correct prefetch abort behavior. */
8391 if ((insn
& (1 << 12)) == 0) {
8393 /* Second half of blx. */
8394 offset
= ((insn
& 0x7ff) << 1);
8395 tmp
= load_reg(s
, 14);
8396 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8397 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8399 tmp2
= tcg_temp_new_i32();
8400 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8401 store_reg(s
, 14, tmp2
);
8405 if (insn
& (1 << 11)) {
8406 /* Second half of bl. */
8407 offset
= ((insn
& 0x7ff) << 1) | 1;
8408 tmp
= load_reg(s
, 14);
8409 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8411 tmp2
= tcg_temp_new_i32();
8412 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8413 store_reg(s
, 14, tmp2
);
8417 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8418 /* Instruction spans a page boundary. Implement it as two
8419 16-bit instructions in case the second half causes an
8421 offset
= ((int32_t)insn
<< 21) >> 9;
8422 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8425 /* Fall through to 32-bit decode. */
8428 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8430 insn
|= (uint32_t)insn_hw1
<< 16;
8432 if ((insn
& 0xf800e800) != 0xf000e800) {
8436 rn
= (insn
>> 16) & 0xf;
8437 rs
= (insn
>> 12) & 0xf;
8438 rd
= (insn
>> 8) & 0xf;
8440 switch ((insn
>> 25) & 0xf) {
8441 case 0: case 1: case 2: case 3:
8442 /* 16-bit instructions. Should never happen. */
8445 if (insn
& (1 << 22)) {
8446 /* Other load/store, table branch. */
8447 if (insn
& 0x01200000) {
8448 /* Load/store doubleword. */
8450 addr
= tcg_temp_new_i32();
8451 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8453 addr
= load_reg(s
, rn
);
8455 offset
= (insn
& 0xff) * 4;
8456 if ((insn
& (1 << 23)) == 0)
8458 if (insn
& (1 << 24)) {
8459 tcg_gen_addi_i32(addr
, addr
, offset
);
8462 if (insn
& (1 << 20)) {
8464 tmp
= tcg_temp_new_i32();
8465 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8466 store_reg(s
, rs
, tmp
);
8467 tcg_gen_addi_i32(addr
, addr
, 4);
8468 tmp
= tcg_temp_new_i32();
8469 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8470 store_reg(s
, rd
, tmp
);
8473 tmp
= load_reg(s
, rs
);
8474 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8475 tcg_temp_free_i32(tmp
);
8476 tcg_gen_addi_i32(addr
, addr
, 4);
8477 tmp
= load_reg(s
, rd
);
8478 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8479 tcg_temp_free_i32(tmp
);
8481 if (insn
& (1 << 21)) {
8482 /* Base writeback. */
8485 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8486 store_reg(s
, rn
, addr
);
8488 tcg_temp_free_i32(addr
);
8490 } else if ((insn
& (1 << 23)) == 0) {
8491 /* Load/store exclusive word. */
8492 addr
= tcg_temp_local_new_i32();
8493 load_reg_var(s
, addr
, rn
);
8494 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8495 if (insn
& (1 << 20)) {
8496 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8498 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8500 tcg_temp_free_i32(addr
);
8501 } else if ((insn
& (7 << 5)) == 0) {
8504 addr
= tcg_temp_new_i32();
8505 tcg_gen_movi_i32(addr
, s
->pc
);
8507 addr
= load_reg(s
, rn
);
8509 tmp
= load_reg(s
, rm
);
8510 tcg_gen_add_i32(addr
, addr
, tmp
);
8511 if (insn
& (1 << 4)) {
8513 tcg_gen_add_i32(addr
, addr
, tmp
);
8514 tcg_temp_free_i32(tmp
);
8515 tmp
= tcg_temp_new_i32();
8516 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8518 tcg_temp_free_i32(tmp
);
8519 tmp
= tcg_temp_new_i32();
8520 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8522 tcg_temp_free_i32(addr
);
8523 tcg_gen_shli_i32(tmp
, tmp
, 1);
8524 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8525 store_reg(s
, 15, tmp
);
8527 int op2
= (insn
>> 6) & 0x3;
8528 op
= (insn
>> 4) & 0x3;
8533 /* Load/store exclusive byte/halfword/doubleword */
8540 /* Load-acquire/store-release */
8546 /* Load-acquire/store-release exclusive */
8550 addr
= tcg_temp_local_new_i32();
8551 load_reg_var(s
, addr
, rn
);
8553 if (insn
& (1 << 20)) {
8554 tmp
= tcg_temp_new_i32();
8557 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8560 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8563 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8568 store_reg(s
, rs
, tmp
);
8570 tmp
= load_reg(s
, rs
);
8573 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8576 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8579 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8584 tcg_temp_free_i32(tmp
);
8586 } else if (insn
& (1 << 20)) {
8587 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8589 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8591 tcg_temp_free_i32(addr
);
8594 /* Load/store multiple, RFE, SRS. */
8595 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8596 /* RFE, SRS: not available in user mode or on M profile */
8597 if (IS_USER(s
) || IS_M(env
)) {
8600 if (insn
& (1 << 20)) {
8602 addr
= load_reg(s
, rn
);
8603 if ((insn
& (1 << 24)) == 0)
8604 tcg_gen_addi_i32(addr
, addr
, -8);
8605 /* Load PC into tmp and CPSR into tmp2. */
8606 tmp
= tcg_temp_new_i32();
8607 gen_aa32_ld32u(tmp
, addr
, 0);
8608 tcg_gen_addi_i32(addr
, addr
, 4);
8609 tmp2
= tcg_temp_new_i32();
8610 gen_aa32_ld32u(tmp2
, addr
, 0);
8611 if (insn
& (1 << 21)) {
8612 /* Base writeback. */
8613 if (insn
& (1 << 24)) {
8614 tcg_gen_addi_i32(addr
, addr
, 4);
8616 tcg_gen_addi_i32(addr
, addr
, -4);
8618 store_reg(s
, rn
, addr
);
8620 tcg_temp_free_i32(addr
);
8622 gen_rfe(s
, tmp
, tmp2
);
8625 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8629 int i
, loaded_base
= 0;
8630 TCGv_i32 loaded_var
;
8631 /* Load/store multiple. */
8632 addr
= load_reg(s
, rn
);
8634 for (i
= 0; i
< 16; i
++) {
8635 if (insn
& (1 << i
))
8638 if (insn
& (1 << 24)) {
8639 tcg_gen_addi_i32(addr
, addr
, -offset
);
8642 TCGV_UNUSED_I32(loaded_var
);
8643 for (i
= 0; i
< 16; i
++) {
8644 if ((insn
& (1 << i
)) == 0)
8646 if (insn
& (1 << 20)) {
8648 tmp
= tcg_temp_new_i32();
8649 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8652 } else if (i
== rn
) {
8656 store_reg(s
, i
, tmp
);
8660 tmp
= load_reg(s
, i
);
8661 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8662 tcg_temp_free_i32(tmp
);
8664 tcg_gen_addi_i32(addr
, addr
, 4);
8667 store_reg(s
, rn
, loaded_var
);
8669 if (insn
& (1 << 21)) {
8670 /* Base register writeback. */
8671 if (insn
& (1 << 24)) {
8672 tcg_gen_addi_i32(addr
, addr
, -offset
);
8674 /* Fault if writeback register is in register list. */
8675 if (insn
& (1 << rn
))
8677 store_reg(s
, rn
, addr
);
8679 tcg_temp_free_i32(addr
);
8686 op
= (insn
>> 21) & 0xf;
8688 /* Halfword pack. */
8689 tmp
= load_reg(s
, rn
);
8690 tmp2
= load_reg(s
, rm
);
8691 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8692 if (insn
& (1 << 5)) {
8696 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8697 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8698 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8702 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8703 tcg_gen_ext16u_i32(tmp
, tmp
);
8704 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8706 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8707 tcg_temp_free_i32(tmp2
);
8708 store_reg(s
, rd
, tmp
);
8710 /* Data processing register constant shift. */
8712 tmp
= tcg_temp_new_i32();
8713 tcg_gen_movi_i32(tmp
, 0);
8715 tmp
= load_reg(s
, rn
);
8717 tmp2
= load_reg(s
, rm
);
8719 shiftop
= (insn
>> 4) & 3;
8720 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8721 conds
= (insn
& (1 << 20)) != 0;
8722 logic_cc
= (conds
&& thumb2_logic_op(op
));
8723 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8724 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8726 tcg_temp_free_i32(tmp2
);
8728 store_reg(s
, rd
, tmp
);
8730 tcg_temp_free_i32(tmp
);
8734 case 13: /* Misc data processing. */
8735 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8736 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8739 case 0: /* Register controlled shift. */
8740 tmp
= load_reg(s
, rn
);
8741 tmp2
= load_reg(s
, rm
);
8742 if ((insn
& 0x70) != 0)
8744 op
= (insn
>> 21) & 3;
8745 logic_cc
= (insn
& (1 << 20)) != 0;
8746 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8749 store_reg_bx(env
, s
, rd
, tmp
);
8751 case 1: /* Sign/zero extend. */
8752 tmp
= load_reg(s
, rm
);
8753 shift
= (insn
>> 4) & 3;
8754 /* ??? In many cases it's not necessary to do a
8755 rotate, a shift is sufficient. */
8757 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8758 op
= (insn
>> 20) & 7;
8760 case 0: gen_sxth(tmp
); break;
8761 case 1: gen_uxth(tmp
); break;
8762 case 2: gen_sxtb16(tmp
); break;
8763 case 3: gen_uxtb16(tmp
); break;
8764 case 4: gen_sxtb(tmp
); break;
8765 case 5: gen_uxtb(tmp
); break;
8766 default: goto illegal_op
;
8769 tmp2
= load_reg(s
, rn
);
8770 if ((op
>> 1) == 1) {
8771 gen_add16(tmp
, tmp2
);
8773 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8774 tcg_temp_free_i32(tmp2
);
8777 store_reg(s
, rd
, tmp
);
8779 case 2: /* SIMD add/subtract. */
8780 op
= (insn
>> 20) & 7;
8781 shift
= (insn
>> 4) & 7;
8782 if ((op
& 3) == 3 || (shift
& 3) == 3)
8784 tmp
= load_reg(s
, rn
);
8785 tmp2
= load_reg(s
, rm
);
8786 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8787 tcg_temp_free_i32(tmp2
);
8788 store_reg(s
, rd
, tmp
);
8790 case 3: /* Other data processing. */
8791 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8793 /* Saturating add/subtract. */
8794 tmp
= load_reg(s
, rn
);
8795 tmp2
= load_reg(s
, rm
);
8797 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8799 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8801 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8802 tcg_temp_free_i32(tmp2
);
8804 tmp
= load_reg(s
, rn
);
8806 case 0x0a: /* rbit */
8807 gen_helper_rbit(tmp
, tmp
);
8809 case 0x08: /* rev */
8810 tcg_gen_bswap32_i32(tmp
, tmp
);
8812 case 0x09: /* rev16 */
8815 case 0x0b: /* revsh */
8818 case 0x10: /* sel */
8819 tmp2
= load_reg(s
, rm
);
8820 tmp3
= tcg_temp_new_i32();
8821 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8822 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8823 tcg_temp_free_i32(tmp3
);
8824 tcg_temp_free_i32(tmp2
);
8826 case 0x18: /* clz */
8827 gen_helper_clz(tmp
, tmp
);
8833 store_reg(s
, rd
, tmp
);
8835 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8836 op
= (insn
>> 4) & 0xf;
8837 tmp
= load_reg(s
, rn
);
8838 tmp2
= load_reg(s
, rm
);
8839 switch ((insn
>> 20) & 7) {
8840 case 0: /* 32 x 32 -> 32 */
8841 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8842 tcg_temp_free_i32(tmp2
);
8844 tmp2
= load_reg(s
, rs
);
8846 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8848 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8849 tcg_temp_free_i32(tmp2
);
8852 case 1: /* 16 x 16 -> 32 */
8853 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8854 tcg_temp_free_i32(tmp2
);
8856 tmp2
= load_reg(s
, rs
);
8857 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8858 tcg_temp_free_i32(tmp2
);
8861 case 2: /* Dual multiply add. */
8862 case 4: /* Dual multiply subtract. */
8864 gen_swap_half(tmp2
);
8865 gen_smul_dual(tmp
, tmp2
);
8866 if (insn
& (1 << 22)) {
8867 /* This subtraction cannot overflow. */
8868 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8870 /* This addition cannot overflow 32 bits;
8871 * however it may overflow considered as a signed
8872 * operation, in which case we must set the Q flag.
8874 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8876 tcg_temp_free_i32(tmp2
);
8879 tmp2
= load_reg(s
, rs
);
8880 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8881 tcg_temp_free_i32(tmp2
);
8884 case 3: /* 32 * 16 -> 32msb */
8886 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8889 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8890 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8891 tmp
= tcg_temp_new_i32();
8892 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8893 tcg_temp_free_i64(tmp64
);
8896 tmp2
= load_reg(s
, rs
);
8897 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8898 tcg_temp_free_i32(tmp2
);
8901 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8902 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8904 tmp
= load_reg(s
, rs
);
8905 if (insn
& (1 << 20)) {
8906 tmp64
= gen_addq_msw(tmp64
, tmp
);
8908 tmp64
= gen_subq_msw(tmp64
, tmp
);
8911 if (insn
& (1 << 4)) {
8912 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8914 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8915 tmp
= tcg_temp_new_i32();
8916 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8917 tcg_temp_free_i64(tmp64
);
8919 case 7: /* Unsigned sum of absolute differences. */
8920 gen_helper_usad8(tmp
, tmp
, tmp2
);
8921 tcg_temp_free_i32(tmp2
);
8923 tmp2
= load_reg(s
, rs
);
8924 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8925 tcg_temp_free_i32(tmp2
);
8929 store_reg(s
, rd
, tmp
);
8931 case 6: case 7: /* 64-bit multiply, Divide. */
8932 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8933 tmp
= load_reg(s
, rn
);
8934 tmp2
= load_reg(s
, rm
);
8935 if ((op
& 0x50) == 0x10) {
8937 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8941 gen_helper_udiv(tmp
, tmp
, tmp2
);
8943 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8944 tcg_temp_free_i32(tmp2
);
8945 store_reg(s
, rd
, tmp
);
8946 } else if ((op
& 0xe) == 0xc) {
8947 /* Dual multiply accumulate long. */
8949 gen_swap_half(tmp2
);
8950 gen_smul_dual(tmp
, tmp2
);
8952 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8954 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8956 tcg_temp_free_i32(tmp2
);
8958 tmp64
= tcg_temp_new_i64();
8959 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8960 tcg_temp_free_i32(tmp
);
8961 gen_addq(s
, tmp64
, rs
, rd
);
8962 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8963 tcg_temp_free_i64(tmp64
);
8966 /* Unsigned 64-bit multiply */
8967 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8971 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8972 tcg_temp_free_i32(tmp2
);
8973 tmp64
= tcg_temp_new_i64();
8974 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8975 tcg_temp_free_i32(tmp
);
8977 /* Signed 64-bit multiply */
8978 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8983 gen_addq_lo(s
, tmp64
, rs
);
8984 gen_addq_lo(s
, tmp64
, rd
);
8985 } else if (op
& 0x40) {
8986 /* 64-bit accumulate. */
8987 gen_addq(s
, tmp64
, rs
, rd
);
8989 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8990 tcg_temp_free_i64(tmp64
);
8995 case 6: case 7: case 14: case 15:
8997 if (((insn
>> 24) & 3) == 3) {
8998 /* Translate into the equivalent ARM encoding. */
8999 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9000 if (disas_neon_data_insn(env
, s
, insn
))
9002 } else if (((insn
>> 8) & 0xe) == 10) {
9003 if (disas_vfp_insn(env
, s
, insn
)) {
9007 if (insn
& (1 << 28))
9009 if (disas_coproc_insn (env
, s
, insn
))
9013 case 8: case 9: case 10: case 11:
9014 if (insn
& (1 << 15)) {
9015 /* Branches, misc control. */
9016 if (insn
& 0x5000) {
9017 /* Unconditional branch. */
9018 /* signextend(hw1[10:0]) -> offset[:12]. */
9019 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9020 /* hw1[10:0] -> offset[11:1]. */
9021 offset
|= (insn
& 0x7ff) << 1;
9022 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9023 offset[24:22] already have the same value because of the
9024 sign extension above. */
9025 offset
^= ((~insn
) & (1 << 13)) << 10;
9026 offset
^= ((~insn
) & (1 << 11)) << 11;
9028 if (insn
& (1 << 14)) {
9029 /* Branch and link. */
9030 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9034 if (insn
& (1 << 12)) {
9039 offset
&= ~(uint32_t)2;
9040 /* thumb2 bx, no need to check */
9041 gen_bx_im(s
, offset
);
9043 } else if (((insn
>> 23) & 7) == 7) {
9045 if (insn
& (1 << 13))
9048 if (insn
& (1 << 26)) {
9049 /* Secure monitor call (v6Z) */
9050 qemu_log_mask(LOG_UNIMP
,
9051 "arm: unimplemented secure monitor call\n");
9052 goto illegal_op
; /* not implemented. */
9054 op
= (insn
>> 20) & 7;
9056 case 0: /* msr cpsr. */
9058 tmp
= load_reg(s
, rn
);
9059 addr
= tcg_const_i32(insn
& 0xff);
9060 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9061 tcg_temp_free_i32(addr
);
9062 tcg_temp_free_i32(tmp
);
9067 case 1: /* msr spsr. */
9070 tmp
= load_reg(s
, rn
);
9072 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9076 case 2: /* cps, nop-hint. */
9077 if (((insn
>> 8) & 7) == 0) {
9078 gen_nop_hint(s
, insn
& 0xff);
9080 /* Implemented as NOP in user mode. */
9085 if (insn
& (1 << 10)) {
9086 if (insn
& (1 << 7))
9088 if (insn
& (1 << 6))
9090 if (insn
& (1 << 5))
9092 if (insn
& (1 << 9))
9093 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9095 if (insn
& (1 << 8)) {
9097 imm
|= (insn
& 0x1f);
9100 gen_set_psr_im(s
, offset
, 0, imm
);
9103 case 3: /* Special control operations. */
9105 op
= (insn
>> 4) & 0xf;
9113 /* These execute as NOPs. */
9120 /* Trivial implementation equivalent to bx. */
9121 tmp
= load_reg(s
, rn
);
9124 case 5: /* Exception return. */
9128 if (rn
!= 14 || rd
!= 15) {
9131 tmp
= load_reg(s
, rn
);
9132 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9133 gen_exception_return(s
, tmp
);
9135 case 6: /* mrs cpsr. */
9136 tmp
= tcg_temp_new_i32();
9138 addr
= tcg_const_i32(insn
& 0xff);
9139 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9140 tcg_temp_free_i32(addr
);
9142 gen_helper_cpsr_read(tmp
, cpu_env
);
9144 store_reg(s
, rd
, tmp
);
9146 case 7: /* mrs spsr. */
9147 /* Not accessible in user mode. */
9148 if (IS_USER(s
) || IS_M(env
))
9150 tmp
= load_cpu_field(spsr
);
9151 store_reg(s
, rd
, tmp
);
9156 /* Conditional branch. */
9157 op
= (insn
>> 22) & 0xf;
9158 /* Generate a conditional jump to next instruction. */
9159 s
->condlabel
= gen_new_label();
9160 gen_test_cc(op
^ 1, s
->condlabel
);
9163 /* offset[11:1] = insn[10:0] */
9164 offset
= (insn
& 0x7ff) << 1;
9165 /* offset[17:12] = insn[21:16]. */
9166 offset
|= (insn
& 0x003f0000) >> 4;
9167 /* offset[31:20] = insn[26]. */
9168 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9169 /* offset[18] = insn[13]. */
9170 offset
|= (insn
& (1 << 13)) << 5;
9171 /* offset[19] = insn[11]. */
9172 offset
|= (insn
& (1 << 11)) << 8;
9174 /* jump to the offset */
9175 gen_jmp(s
, s
->pc
+ offset
);
9178 /* Data processing immediate. */
9179 if (insn
& (1 << 25)) {
9180 if (insn
& (1 << 24)) {
9181 if (insn
& (1 << 20))
9183 /* Bitfield/Saturate. */
9184 op
= (insn
>> 21) & 7;
9186 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9188 tmp
= tcg_temp_new_i32();
9189 tcg_gen_movi_i32(tmp
, 0);
9191 tmp
= load_reg(s
, rn
);
9194 case 2: /* Signed bitfield extract. */
9196 if (shift
+ imm
> 32)
9199 gen_sbfx(tmp
, shift
, imm
);
9201 case 6: /* Unsigned bitfield extract. */
9203 if (shift
+ imm
> 32)
9206 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9208 case 3: /* Bitfield insert/clear. */
9211 imm
= imm
+ 1 - shift
;
9213 tmp2
= load_reg(s
, rd
);
9214 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9215 tcg_temp_free_i32(tmp2
);
9220 default: /* Saturate. */
9223 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9225 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9227 tmp2
= tcg_const_i32(imm
);
9230 if ((op
& 1) && shift
== 0)
9231 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9233 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9236 if ((op
& 1) && shift
== 0)
9237 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9239 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9241 tcg_temp_free_i32(tmp2
);
9244 store_reg(s
, rd
, tmp
);
9246 imm
= ((insn
& 0x04000000) >> 15)
9247 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9248 if (insn
& (1 << 22)) {
9249 /* 16-bit immediate. */
9250 imm
|= (insn
>> 4) & 0xf000;
9251 if (insn
& (1 << 23)) {
9253 tmp
= load_reg(s
, rd
);
9254 tcg_gen_ext16u_i32(tmp
, tmp
);
9255 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9258 tmp
= tcg_temp_new_i32();
9259 tcg_gen_movi_i32(tmp
, imm
);
9262 /* Add/sub 12-bit immediate. */
9264 offset
= s
->pc
& ~(uint32_t)3;
9265 if (insn
& (1 << 23))
9269 tmp
= tcg_temp_new_i32();
9270 tcg_gen_movi_i32(tmp
, offset
);
9272 tmp
= load_reg(s
, rn
);
9273 if (insn
& (1 << 23))
9274 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9276 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9279 store_reg(s
, rd
, tmp
);
9282 int shifter_out
= 0;
9283 /* modified 12-bit immediate. */
9284 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9285 imm
= (insn
& 0xff);
9288 /* Nothing to do. */
9290 case 1: /* 00XY00XY */
9293 case 2: /* XY00XY00 */
9297 case 3: /* XYXYXYXY */
9301 default: /* Rotated constant. */
9302 shift
= (shift
<< 1) | (imm
>> 7);
9304 imm
= imm
<< (32 - shift
);
9308 tmp2
= tcg_temp_new_i32();
9309 tcg_gen_movi_i32(tmp2
, imm
);
9310 rn
= (insn
>> 16) & 0xf;
9312 tmp
= tcg_temp_new_i32();
9313 tcg_gen_movi_i32(tmp
, 0);
9315 tmp
= load_reg(s
, rn
);
9317 op
= (insn
>> 21) & 0xf;
9318 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9319 shifter_out
, tmp
, tmp2
))
9321 tcg_temp_free_i32(tmp2
);
9322 rd
= (insn
>> 8) & 0xf;
9324 store_reg(s
, rd
, tmp
);
9326 tcg_temp_free_i32(tmp
);
9331 case 12: /* Load/store single data item. */
9336 if ((insn
& 0x01100000) == 0x01000000) {
9337 if (disas_neon_ls_insn(env
, s
, insn
))
9341 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9343 if (!(insn
& (1 << 20))) {
9347 /* Byte or halfword load space with dest == r15 : memory hints.
9348 * Catch them early so we don't emit pointless addressing code.
9349 * This space is a mix of:
9350 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9351 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9353 * unallocated hints, which must be treated as NOPs
9354 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9355 * which is easiest for the decoding logic
9356 * Some space which must UNDEF
9358 int op1
= (insn
>> 23) & 3;
9359 int op2
= (insn
>> 6) & 0x3f;
9364 /* UNPREDICTABLE, unallocated hint or
9365 * PLD/PLDW/PLI (literal)
9370 return 0; /* PLD/PLDW/PLI or unallocated hint */
9372 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9373 return 0; /* PLD/PLDW/PLI or unallocated hint */
9375 /* UNDEF space, or an UNPREDICTABLE */
9381 addr
= tcg_temp_new_i32();
9383 /* s->pc has already been incremented by 4. */
9384 imm
= s
->pc
& 0xfffffffc;
9385 if (insn
& (1 << 23))
9386 imm
+= insn
& 0xfff;
9388 imm
-= insn
& 0xfff;
9389 tcg_gen_movi_i32(addr
, imm
);
9391 addr
= load_reg(s
, rn
);
9392 if (insn
& (1 << 23)) {
9393 /* Positive offset. */
9395 tcg_gen_addi_i32(addr
, addr
, imm
);
9398 switch ((insn
>> 8) & 0xf) {
9399 case 0x0: /* Shifted Register. */
9400 shift
= (insn
>> 4) & 0xf;
9402 tcg_temp_free_i32(addr
);
9405 tmp
= load_reg(s
, rm
);
9407 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9408 tcg_gen_add_i32(addr
, addr
, tmp
);
9409 tcg_temp_free_i32(tmp
);
9411 case 0xc: /* Negative offset. */
9412 tcg_gen_addi_i32(addr
, addr
, -imm
);
9414 case 0xe: /* User privilege. */
9415 tcg_gen_addi_i32(addr
, addr
, imm
);
9418 case 0x9: /* Post-decrement. */
9421 case 0xb: /* Post-increment. */
9425 case 0xd: /* Pre-decrement. */
9428 case 0xf: /* Pre-increment. */
9429 tcg_gen_addi_i32(addr
, addr
, imm
);
9433 tcg_temp_free_i32(addr
);
9438 if (insn
& (1 << 20)) {
9440 tmp
= tcg_temp_new_i32();
9443 gen_aa32_ld8u(tmp
, addr
, user
);
9446 gen_aa32_ld8s(tmp
, addr
, user
);
9449 gen_aa32_ld16u(tmp
, addr
, user
);
9452 gen_aa32_ld16s(tmp
, addr
, user
);
9455 gen_aa32_ld32u(tmp
, addr
, user
);
9458 tcg_temp_free_i32(tmp
);
9459 tcg_temp_free_i32(addr
);
9465 store_reg(s
, rs
, tmp
);
9469 tmp
= load_reg(s
, rs
);
9472 gen_aa32_st8(tmp
, addr
, user
);
9475 gen_aa32_st16(tmp
, addr
, user
);
9478 gen_aa32_st32(tmp
, addr
, user
);
9481 tcg_temp_free_i32(tmp
);
9482 tcg_temp_free_i32(addr
);
9485 tcg_temp_free_i32(tmp
);
9488 tcg_gen_addi_i32(addr
, addr
, imm
);
9490 store_reg(s
, rn
, addr
);
9492 tcg_temp_free_i32(addr
);
9504 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9506 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9513 if (s
->condexec_mask
) {
9514 cond
= s
->condexec_cond
;
9515 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9516 s
->condlabel
= gen_new_label();
9517 gen_test_cc(cond
^ 1, s
->condlabel
);
9522 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9525 switch (insn
>> 12) {
9529 op
= (insn
>> 11) & 3;
9532 rn
= (insn
>> 3) & 7;
9533 tmp
= load_reg(s
, rn
);
9534 if (insn
& (1 << 10)) {
9536 tmp2
= tcg_temp_new_i32();
9537 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9540 rm
= (insn
>> 6) & 7;
9541 tmp2
= load_reg(s
, rm
);
9543 if (insn
& (1 << 9)) {
9544 if (s
->condexec_mask
)
9545 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9547 gen_sub_CC(tmp
, tmp
, tmp2
);
9549 if (s
->condexec_mask
)
9550 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9552 gen_add_CC(tmp
, tmp
, tmp2
);
9554 tcg_temp_free_i32(tmp2
);
9555 store_reg(s
, rd
, tmp
);
9557 /* shift immediate */
9558 rm
= (insn
>> 3) & 7;
9559 shift
= (insn
>> 6) & 0x1f;
9560 tmp
= load_reg(s
, rm
);
9561 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9562 if (!s
->condexec_mask
)
9564 store_reg(s
, rd
, tmp
);
9568 /* arithmetic large immediate */
9569 op
= (insn
>> 11) & 3;
9570 rd
= (insn
>> 8) & 0x7;
9571 if (op
== 0) { /* mov */
9572 tmp
= tcg_temp_new_i32();
9573 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9574 if (!s
->condexec_mask
)
9576 store_reg(s
, rd
, tmp
);
9578 tmp
= load_reg(s
, rd
);
9579 tmp2
= tcg_temp_new_i32();
9580 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9583 gen_sub_CC(tmp
, tmp
, tmp2
);
9584 tcg_temp_free_i32(tmp
);
9585 tcg_temp_free_i32(tmp2
);
9588 if (s
->condexec_mask
)
9589 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9591 gen_add_CC(tmp
, tmp
, tmp2
);
9592 tcg_temp_free_i32(tmp2
);
9593 store_reg(s
, rd
, tmp
);
9596 if (s
->condexec_mask
)
9597 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9599 gen_sub_CC(tmp
, tmp
, tmp2
);
9600 tcg_temp_free_i32(tmp2
);
9601 store_reg(s
, rd
, tmp
);
9607 if (insn
& (1 << 11)) {
9608 rd
= (insn
>> 8) & 7;
9609 /* load pc-relative. Bit 1 of PC is ignored. */
9610 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9611 val
&= ~(uint32_t)2;
9612 addr
= tcg_temp_new_i32();
9613 tcg_gen_movi_i32(addr
, val
);
9614 tmp
= tcg_temp_new_i32();
9615 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9616 tcg_temp_free_i32(addr
);
9617 store_reg(s
, rd
, tmp
);
9620 if (insn
& (1 << 10)) {
9621 /* data processing extended or blx */
9622 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9623 rm
= (insn
>> 3) & 0xf;
9624 op
= (insn
>> 8) & 3;
9627 tmp
= load_reg(s
, rd
);
9628 tmp2
= load_reg(s
, rm
);
9629 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9630 tcg_temp_free_i32(tmp2
);
9631 store_reg(s
, rd
, tmp
);
9634 tmp
= load_reg(s
, rd
);
9635 tmp2
= load_reg(s
, rm
);
9636 gen_sub_CC(tmp
, tmp
, tmp2
);
9637 tcg_temp_free_i32(tmp2
);
9638 tcg_temp_free_i32(tmp
);
9640 case 2: /* mov/cpy */
9641 tmp
= load_reg(s
, rm
);
9642 store_reg(s
, rd
, tmp
);
9644 case 3:/* branch [and link] exchange thumb register */
9645 tmp
= load_reg(s
, rm
);
9646 if (insn
& (1 << 7)) {
9648 val
= (uint32_t)s
->pc
| 1;
9649 tmp2
= tcg_temp_new_i32();
9650 tcg_gen_movi_i32(tmp2
, val
);
9651 store_reg(s
, 14, tmp2
);
9653 /* already thumb, no need to check */
9660 /* data processing register */
9662 rm
= (insn
>> 3) & 7;
9663 op
= (insn
>> 6) & 0xf;
9664 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9665 /* the shift/rotate ops want the operands backwards */
9674 if (op
== 9) { /* neg */
9675 tmp
= tcg_temp_new_i32();
9676 tcg_gen_movi_i32(tmp
, 0);
9677 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9678 tmp
= load_reg(s
, rd
);
9680 TCGV_UNUSED_I32(tmp
);
9683 tmp2
= load_reg(s
, rm
);
9686 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9687 if (!s
->condexec_mask
)
9691 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9692 if (!s
->condexec_mask
)
9696 if (s
->condexec_mask
) {
9697 gen_shl(tmp2
, tmp2
, tmp
);
9699 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9704 if (s
->condexec_mask
) {
9705 gen_shr(tmp2
, tmp2
, tmp
);
9707 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9712 if (s
->condexec_mask
) {
9713 gen_sar(tmp2
, tmp2
, tmp
);
9715 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9720 if (s
->condexec_mask
) {
9723 gen_adc_CC(tmp
, tmp
, tmp2
);
9727 if (s
->condexec_mask
) {
9728 gen_sub_carry(tmp
, tmp
, tmp2
);
9730 gen_sbc_CC(tmp
, tmp
, tmp2
);
9734 if (s
->condexec_mask
) {
9735 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9736 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9738 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9743 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9748 if (s
->condexec_mask
)
9749 tcg_gen_neg_i32(tmp
, tmp2
);
9751 gen_sub_CC(tmp
, tmp
, tmp2
);
9754 gen_sub_CC(tmp
, tmp
, tmp2
);
9758 gen_add_CC(tmp
, tmp
, tmp2
);
9762 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9763 if (!s
->condexec_mask
)
9767 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9768 if (!s
->condexec_mask
)
9772 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9773 if (!s
->condexec_mask
)
9777 tcg_gen_not_i32(tmp2
, tmp2
);
9778 if (!s
->condexec_mask
)
9786 store_reg(s
, rm
, tmp2
);
9788 tcg_temp_free_i32(tmp
);
9790 store_reg(s
, rd
, tmp
);
9791 tcg_temp_free_i32(tmp2
);
9794 tcg_temp_free_i32(tmp
);
9795 tcg_temp_free_i32(tmp2
);
9800 /* load/store register offset. */
9802 rn
= (insn
>> 3) & 7;
9803 rm
= (insn
>> 6) & 7;
9804 op
= (insn
>> 9) & 7;
9805 addr
= load_reg(s
, rn
);
9806 tmp
= load_reg(s
, rm
);
9807 tcg_gen_add_i32(addr
, addr
, tmp
);
9808 tcg_temp_free_i32(tmp
);
9810 if (op
< 3) { /* store */
9811 tmp
= load_reg(s
, rd
);
9813 tmp
= tcg_temp_new_i32();
9818 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9821 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9824 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9827 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
9830 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9833 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9836 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9839 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
9842 if (op
>= 3) { /* load */
9843 store_reg(s
, rd
, tmp
);
9845 tcg_temp_free_i32(tmp
);
9847 tcg_temp_free_i32(addr
);
9851 /* load/store word immediate offset */
9853 rn
= (insn
>> 3) & 7;
9854 addr
= load_reg(s
, rn
);
9855 val
= (insn
>> 4) & 0x7c;
9856 tcg_gen_addi_i32(addr
, addr
, val
);
9858 if (insn
& (1 << 11)) {
9860 tmp
= tcg_temp_new_i32();
9861 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9862 store_reg(s
, rd
, tmp
);
9865 tmp
= load_reg(s
, rd
);
9866 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9867 tcg_temp_free_i32(tmp
);
9869 tcg_temp_free_i32(addr
);
9873 /* load/store byte immediate offset */
9875 rn
= (insn
>> 3) & 7;
9876 addr
= load_reg(s
, rn
);
9877 val
= (insn
>> 6) & 0x1f;
9878 tcg_gen_addi_i32(addr
, addr
, val
);
9880 if (insn
& (1 << 11)) {
9882 tmp
= tcg_temp_new_i32();
9883 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
9884 store_reg(s
, rd
, tmp
);
9887 tmp
= load_reg(s
, rd
);
9888 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
9889 tcg_temp_free_i32(tmp
);
9891 tcg_temp_free_i32(addr
);
9895 /* load/store halfword immediate offset */
9897 rn
= (insn
>> 3) & 7;
9898 addr
= load_reg(s
, rn
);
9899 val
= (insn
>> 5) & 0x3e;
9900 tcg_gen_addi_i32(addr
, addr
, val
);
9902 if (insn
& (1 << 11)) {
9904 tmp
= tcg_temp_new_i32();
9905 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
9906 store_reg(s
, rd
, tmp
);
9909 tmp
= load_reg(s
, rd
);
9910 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
9911 tcg_temp_free_i32(tmp
);
9913 tcg_temp_free_i32(addr
);
9917 /* load/store from stack */
9918 rd
= (insn
>> 8) & 7;
9919 addr
= load_reg(s
, 13);
9920 val
= (insn
& 0xff) * 4;
9921 tcg_gen_addi_i32(addr
, addr
, val
);
9923 if (insn
& (1 << 11)) {
9925 tmp
= tcg_temp_new_i32();
9926 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9927 store_reg(s
, rd
, tmp
);
9930 tmp
= load_reg(s
, rd
);
9931 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9932 tcg_temp_free_i32(tmp
);
9934 tcg_temp_free_i32(addr
);
9938 /* add to high reg */
9939 rd
= (insn
>> 8) & 7;
9940 if (insn
& (1 << 11)) {
9942 tmp
= load_reg(s
, 13);
9944 /* PC. bit 1 is ignored. */
9945 tmp
= tcg_temp_new_i32();
9946 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9948 val
= (insn
& 0xff) * 4;
9949 tcg_gen_addi_i32(tmp
, tmp
, val
);
9950 store_reg(s
, rd
, tmp
);
9955 op
= (insn
>> 8) & 0xf;
9958 /* adjust stack pointer */
9959 tmp
= load_reg(s
, 13);
9960 val
= (insn
& 0x7f) * 4;
9961 if (insn
& (1 << 7))
9962 val
= -(int32_t)val
;
9963 tcg_gen_addi_i32(tmp
, tmp
, val
);
9964 store_reg(s
, 13, tmp
);
9967 case 2: /* sign/zero extend. */
9970 rm
= (insn
>> 3) & 7;
9971 tmp
= load_reg(s
, rm
);
9972 switch ((insn
>> 6) & 3) {
9973 case 0: gen_sxth(tmp
); break;
9974 case 1: gen_sxtb(tmp
); break;
9975 case 2: gen_uxth(tmp
); break;
9976 case 3: gen_uxtb(tmp
); break;
9978 store_reg(s
, rd
, tmp
);
9980 case 4: case 5: case 0xc: case 0xd:
9982 addr
= load_reg(s
, 13);
9983 if (insn
& (1 << 8))
9987 for (i
= 0; i
< 8; i
++) {
9988 if (insn
& (1 << i
))
9991 if ((insn
& (1 << 11)) == 0) {
9992 tcg_gen_addi_i32(addr
, addr
, -offset
);
9994 for (i
= 0; i
< 8; i
++) {
9995 if (insn
& (1 << i
)) {
9996 if (insn
& (1 << 11)) {
9998 tmp
= tcg_temp_new_i32();
9999 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10000 store_reg(s
, i
, tmp
);
10003 tmp
= load_reg(s
, i
);
10004 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10005 tcg_temp_free_i32(tmp
);
10007 /* advance to the next address. */
10008 tcg_gen_addi_i32(addr
, addr
, 4);
10011 TCGV_UNUSED_I32(tmp
);
10012 if (insn
& (1 << 8)) {
10013 if (insn
& (1 << 11)) {
10015 tmp
= tcg_temp_new_i32();
10016 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10017 /* don't set the pc until the rest of the instruction
10021 tmp
= load_reg(s
, 14);
10022 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10023 tcg_temp_free_i32(tmp
);
10025 tcg_gen_addi_i32(addr
, addr
, 4);
10027 if ((insn
& (1 << 11)) == 0) {
10028 tcg_gen_addi_i32(addr
, addr
, -offset
);
10030 /* write back the new stack pointer */
10031 store_reg(s
, 13, addr
);
10032 /* set the new PC value */
10033 if ((insn
& 0x0900) == 0x0900) {
10034 store_reg_from_load(env
, s
, 15, tmp
);
10038 case 1: case 3: case 9: case 11: /* czb */
10040 tmp
= load_reg(s
, rm
);
10041 s
->condlabel
= gen_new_label();
10043 if (insn
& (1 << 11))
10044 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10046 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10047 tcg_temp_free_i32(tmp
);
10048 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10049 val
= (uint32_t)s
->pc
+ 2;
10054 case 15: /* IT, nop-hint. */
10055 if ((insn
& 0xf) == 0) {
10056 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10060 s
->condexec_cond
= (insn
>> 4) & 0xe;
10061 s
->condexec_mask
= insn
& 0x1f;
10062 /* No actual code generated for this insn, just setup state. */
10065 case 0xe: /* bkpt */
10067 gen_exception_insn(s
, 2, EXCP_BKPT
);
10070 case 0xa: /* rev */
10072 rn
= (insn
>> 3) & 0x7;
10074 tmp
= load_reg(s
, rn
);
10075 switch ((insn
>> 6) & 3) {
10076 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10077 case 1: gen_rev16(tmp
); break;
10078 case 3: gen_revsh(tmp
); break;
10079 default: goto illegal_op
;
10081 store_reg(s
, rd
, tmp
);
10085 switch ((insn
>> 5) & 7) {
10089 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10090 /* Dynamic endianness switching not implemented. */
10091 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10102 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10105 addr
= tcg_const_i32(19);
10106 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10107 tcg_temp_free_i32(addr
);
10111 addr
= tcg_const_i32(16);
10112 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10113 tcg_temp_free_i32(addr
);
10115 tcg_temp_free_i32(tmp
);
10118 if (insn
& (1 << 4)) {
10119 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10123 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10138 /* load/store multiple */
10139 TCGv_i32 loaded_var
;
10140 TCGV_UNUSED_I32(loaded_var
);
10141 rn
= (insn
>> 8) & 0x7;
10142 addr
= load_reg(s
, rn
);
10143 for (i
= 0; i
< 8; i
++) {
10144 if (insn
& (1 << i
)) {
10145 if (insn
& (1 << 11)) {
10147 tmp
= tcg_temp_new_i32();
10148 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10152 store_reg(s
, i
, tmp
);
10156 tmp
= load_reg(s
, i
);
10157 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10158 tcg_temp_free_i32(tmp
);
10160 /* advance to the next address */
10161 tcg_gen_addi_i32(addr
, addr
, 4);
10164 if ((insn
& (1 << rn
)) == 0) {
10165 /* base reg not in list: base register writeback */
10166 store_reg(s
, rn
, addr
);
10168 /* base reg in list: if load, complete it now */
10169 if (insn
& (1 << 11)) {
10170 store_reg(s
, rn
, loaded_var
);
10172 tcg_temp_free_i32(addr
);
10177 /* conditional branch or swi */
10178 cond
= (insn
>> 8) & 0xf;
10184 gen_set_pc_im(s
, s
->pc
);
10185 s
->is_jmp
= DISAS_SWI
;
10188 /* generate a conditional jump to next instruction */
10189 s
->condlabel
= gen_new_label();
10190 gen_test_cc(cond
^ 1, s
->condlabel
);
10193 /* jump to the offset */
10194 val
= (uint32_t)s
->pc
+ 2;
10195 offset
= ((int32_t)insn
<< 24) >> 24;
10196 val
+= offset
<< 1;
10201 if (insn
& (1 << 11)) {
10202 if (disas_thumb2_insn(env
, s
, insn
))
10206 /* unconditional branch */
10207 val
= (uint32_t)s
->pc
;
10208 offset
= ((int32_t)insn
<< 21) >> 21;
10209 val
+= (offset
<< 1) + 2;
10214 if (disas_thumb2_insn(env
, s
, insn
))
10220 gen_exception_insn(s
, 4, EXCP_UDEF
);
10224 gen_exception_insn(s
, 2, EXCP_UDEF
);
10227 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10228 basic block 'tb'. If search_pc is TRUE, also generate PC
10229 information for each intermediate instruction. */
10230 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10231 TranslationBlock
*tb
,
10234 CPUState
*cs
= CPU(cpu
);
10235 CPUARMState
*env
= &cpu
->env
;
10236 DisasContext dc1
, *dc
= &dc1
;
10238 uint16_t *gen_opc_end
;
10240 target_ulong pc_start
;
10241 target_ulong next_page_start
;
10245 /* generate intermediate code */
10250 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10252 dc
->is_jmp
= DISAS_NEXT
;
10254 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10257 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10260 dc
->bswap_code
= 0;
10261 dc
->condexec_mask
= 0;
10262 dc
->condexec_cond
= 0;
10263 #if !defined(CONFIG_USER_ONLY)
10266 dc
->vfp_enabled
= 0;
10268 dc
->vec_stride
= 0;
10271 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10272 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10273 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10274 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10275 #if !defined(CONFIG_USER_ONLY)
10276 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10278 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10279 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10280 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10282 cpu_F0s
= tcg_temp_new_i32();
10283 cpu_F1s
= tcg_temp_new_i32();
10284 cpu_F0d
= tcg_temp_new_i64();
10285 cpu_F1d
= tcg_temp_new_i64();
10288 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10289 cpu_M0
= tcg_temp_new_i64();
10290 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10293 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10294 if (max_insns
== 0)
10295 max_insns
= CF_COUNT_MASK
;
10299 tcg_clear_temp_count();
10301 /* A note on handling of the condexec (IT) bits:
10303 * We want to avoid the overhead of having to write the updated condexec
10304 * bits back to the CPUARMState for every instruction in an IT block. So:
10305 * (1) if the condexec bits are not already zero then we write
10306 * zero back into the CPUARMState now. This avoids complications trying
10307 * to do it at the end of the block. (For example if we don't do this
10308 * it's hard to identify whether we can safely skip writing condexec
10309 * at the end of the TB, which we definitely want to do for the case
10310 * where a TB doesn't do anything with the IT state at all.)
10311 * (2) if we are going to leave the TB then we call gen_set_condexec()
10312 * which will write the correct value into CPUARMState if zero is wrong.
10313 * This is done both for leaving the TB at the end, and for leaving
10314 * it because of an exception we know will happen, which is done in
10315 * gen_exception_insn(). The latter is necessary because we need to
10316 * leave the TB with the PC/IT state just prior to execution of the
10317 * instruction which caused the exception.
10318 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10319 * then the CPUARMState will be wrong and we need to reset it.
10320 * This is handled in the same way as restoration of the
10321 * PC in these situations: we will be called again with search_pc=1
10322 * and generate a mapping of the condexec bits for each PC in
10323 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10324 * this to restore the condexec bits.
10326 * Note that there are no instructions which can read the condexec
10327 * bits, and none which can write non-static values to them, so
10328 * we don't need to care about whether CPUARMState is correct in the
10332 /* Reset the conditional execution bits immediately. This avoids
10333 complications trying to do it at the end of the block. */
10334 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10336 TCGv_i32 tmp
= tcg_temp_new_i32();
10337 tcg_gen_movi_i32(tmp
, 0);
10338 store_cpu_field(tmp
, condexec_bits
);
10341 #ifdef CONFIG_USER_ONLY
10342 /* Intercept jump to the magic kernel page. */
10343 if (!dc
->aarch64
&& dc
->pc
>= 0xffff0000) {
10344 /* We always get here via a jump, so know we are not in a
10345 conditional execution block. */
10346 gen_exception(EXCP_KERNEL_TRAP
);
10347 dc
->is_jmp
= DISAS_UPDATE
;
10351 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10352 /* We always get here via a jump, so know we are not in a
10353 conditional execution block. */
10354 gen_exception(EXCP_EXCEPTION_EXIT
);
10355 dc
->is_jmp
= DISAS_UPDATE
;
10360 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10361 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10362 if (bp
->pc
== dc
->pc
) {
10363 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10364 /* Advance PC so that clearing the breakpoint will
10365 invalidate this TB. */
10367 goto done_generating
;
10372 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10376 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10378 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10379 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10380 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10381 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10384 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10387 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10388 tcg_gen_debug_insn_start(dc
->pc
);
10392 disas_a64_insn(env
, dc
);
10393 } else if (dc
->thumb
) {
10394 disas_thumb_insn(env
, dc
);
10395 if (dc
->condexec_mask
) {
10396 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10397 | ((dc
->condexec_mask
>> 4) & 1);
10398 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10399 if (dc
->condexec_mask
== 0) {
10400 dc
->condexec_cond
= 0;
10404 disas_arm_insn(env
, dc
);
10407 if (dc
->condjmp
&& !dc
->is_jmp
) {
10408 gen_set_label(dc
->condlabel
);
10412 if (tcg_check_temp_count()) {
10413 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10417 /* Translation stops when a conditional branch is encountered.
10418 * Otherwise the subsequent code could get translated several times.
10419 * Also stop translation when a page boundary is reached. This
10420 * ensures prefetch aborts occur at the right place. */
10422 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10423 !cs
->singlestep_enabled
&&
10425 dc
->pc
< next_page_start
&&
10426 num_insns
< max_insns
);
10428 if (tb
->cflags
& CF_LAST_IO
) {
10430 /* FIXME: This can theoretically happen with self-modifying
10432 cpu_abort(env
, "IO on conditional branch instruction");
10437 /* At this stage dc->condjmp will only be set when the skipped
10438 instruction was a conditional branch or trap, and the PC has
10439 already been written. */
10440 if (unlikely(cs
->singlestep_enabled
)) {
10441 /* Make sure the pc is updated, and raise a debug exception. */
10443 gen_set_condexec(dc
);
10444 if (dc
->is_jmp
== DISAS_SWI
) {
10445 gen_exception(EXCP_SWI
);
10447 gen_exception(EXCP_DEBUG
);
10449 gen_set_label(dc
->condlabel
);
10451 if (dc
->condjmp
|| !dc
->is_jmp
) {
10452 gen_set_pc_im(dc
, dc
->pc
);
10455 gen_set_condexec(dc
);
10456 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10457 gen_exception(EXCP_SWI
);
10459 /* FIXME: Single stepping a WFI insn will not halt
10461 gen_exception(EXCP_DEBUG
);
10464 /* While branches must always occur at the end of an IT block,
10465 there are a few other things that can cause us to terminate
10466 the TB in the middle of an IT block:
10467 - Exception generating instructions (bkpt, swi, undefined).
10469 - Hardware watchpoints.
10470 Hardware breakpoints have already been handled and skip this code.
10472 gen_set_condexec(dc
);
10473 switch(dc
->is_jmp
) {
10475 gen_goto_tb(dc
, 1, dc
->pc
);
10480 /* indicate that the hash table must be used to find the next TB */
10481 tcg_gen_exit_tb(0);
10483 case DISAS_TB_JUMP
:
10484 /* nothing more to generate */
10487 gen_helper_wfi(cpu_env
);
10490 gen_exception(EXCP_SWI
);
10494 gen_set_label(dc
->condlabel
);
10495 gen_set_condexec(dc
);
10496 gen_goto_tb(dc
, 1, dc
->pc
);
10502 gen_tb_end(tb
, num_insns
);
10503 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10506 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10507 qemu_log("----------------\n");
10508 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10509 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10510 dc
->thumb
| (dc
->bswap_code
<< 1));
10515 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10518 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10520 tb
->size
= dc
->pc
- pc_start
;
10521 tb
->icount
= num_insns
;
10525 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10527 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10530 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10532 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10535 static const char *cpu_mode_names
[16] = {
10536 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10537 "???", "???", "???", "und", "???", "???", "???", "sys"
10540 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10543 ARMCPU
*cpu
= ARM_CPU(cs
);
10544 CPUARMState
*env
= &cpu
->env
;
10548 for(i
=0;i
<16;i
++) {
10549 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10551 cpu_fprintf(f
, "\n");
10553 cpu_fprintf(f
, " ");
10555 psr
= cpsr_read(env
);
10556 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10558 psr
& (1 << 31) ? 'N' : '-',
10559 psr
& (1 << 30) ? 'Z' : '-',
10560 psr
& (1 << 29) ? 'C' : '-',
10561 psr
& (1 << 28) ? 'V' : '-',
10562 psr
& CPSR_T
? 'T' : 'A',
10563 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10565 if (flags
& CPU_DUMP_FPU
) {
10566 int numvfpregs
= 0;
10567 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10570 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10573 for (i
= 0; i
< numvfpregs
; i
++) {
10574 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10575 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10576 i
* 2, (uint32_t)v
,
10577 i
* 2 + 1, (uint32_t)(v
>> 32),
10580 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10584 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10587 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10589 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10591 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];