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/>.
36 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
37 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
38 /* currently all emulated v5 cores are also v5TE, so don't bother */
39 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
40 #define ENABLE_ARCH_5J 0
41 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
42 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
43 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
44 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
48 /* internal defines */
49 typedef struct DisasContext
{
52 /* Nonzero if this instruction has been conditionally skipped. */
54 /* The label that will be jumped to when the instruction is skipped. */
56 /* Thumb-2 condtional execution bits. */
59 struct TranslationBlock
*tb
;
60 int singlestep_enabled
;
62 #if !defined(CONFIG_USER_ONLY)
70 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
72 #if defined(CONFIG_USER_ONLY)
75 #define IS_USER(s) (s->user)
78 /* These instructions trap after executing, so defer them until after the
79 conditional executions state has been updated. */
83 static TCGv_ptr cpu_env
;
84 /* We reuse the same 64-bit temporaries for efficiency. */
85 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
86 static TCGv_i32 cpu_R
[16];
87 static TCGv_i32 cpu_exclusive_addr
;
88 static TCGv_i32 cpu_exclusive_val
;
89 static TCGv_i32 cpu_exclusive_high
;
90 #ifdef CONFIG_USER_ONLY
91 static TCGv_i32 cpu_exclusive_test
;
92 static TCGv_i32 cpu_exclusive_info
;
95 /* FIXME: These should be removed. */
96 static TCGv cpu_F0s
, cpu_F1s
;
97 static TCGv_i64 cpu_F0d
, cpu_F1d
;
99 #include "gen-icount.h"
101 static const char *regnames
[] =
102 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
103 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
105 /* initialize TCG globals. */
106 void arm_translate_init(void)
110 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
112 for (i
= 0; i
< 16; i
++) {
113 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
114 offsetof(CPUState
, regs
[i
]),
117 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
118 offsetof(CPUState
, exclusive_addr
), "exclusive_addr");
119 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
120 offsetof(CPUState
, exclusive_val
), "exclusive_val");
121 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
122 offsetof(CPUState
, exclusive_high
), "exclusive_high");
123 #ifdef CONFIG_USER_ONLY
124 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
125 offsetof(CPUState
, exclusive_test
), "exclusive_test");
126 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
127 offsetof(CPUState
, exclusive_info
), "exclusive_info");
134 static inline TCGv
load_cpu_offset(int offset
)
136 TCGv tmp
= tcg_temp_new_i32();
137 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
141 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
143 static inline void store_cpu_offset(TCGv var
, int offset
)
145 tcg_gen_st_i32(var
, cpu_env
, offset
);
146 tcg_temp_free_i32(var
);
149 #define store_cpu_field(var, name) \
150 store_cpu_offset(var, offsetof(CPUState, name))
152 /* Set a variable to the value of a CPU register. */
153 static void load_reg_var(DisasContext
*s
, TCGv var
, int reg
)
157 /* normaly, since we updated PC, we need only to add one insn */
159 addr
= (long)s
->pc
+ 2;
161 addr
= (long)s
->pc
+ 4;
162 tcg_gen_movi_i32(var
, addr
);
164 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
168 /* Create a new temporary and set it to the value of a CPU register. */
169 static inline TCGv
load_reg(DisasContext
*s
, int reg
)
171 TCGv tmp
= tcg_temp_new_i32();
172 load_reg_var(s
, tmp
, reg
);
176 /* Set a CPU register. The source must be a temporary and will be
178 static void store_reg(DisasContext
*s
, int reg
, TCGv var
)
181 tcg_gen_andi_i32(var
, var
, ~1);
182 s
->is_jmp
= DISAS_JUMP
;
184 tcg_gen_mov_i32(cpu_R
[reg
], var
);
185 tcg_temp_free_i32(var
);
188 /* Value extensions. */
189 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
190 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
191 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
192 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
195 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
198 static inline void gen_set_cpsr(TCGv var
, uint32_t mask
)
200 TCGv tmp_mask
= tcg_const_i32(mask
);
201 gen_helper_cpsr_write(var
, tmp_mask
);
202 tcg_temp_free_i32(tmp_mask
);
204 /* Set NZCV flags from the high 4 bits of var. */
205 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207 static void gen_exception(int excp
)
209 TCGv tmp
= tcg_temp_new_i32();
210 tcg_gen_movi_i32(tmp
, excp
);
211 gen_helper_exception(tmp
);
212 tcg_temp_free_i32(tmp
);
215 static void gen_smul_dual(TCGv a
, TCGv b
)
217 TCGv tmp1
= tcg_temp_new_i32();
218 TCGv tmp2
= tcg_temp_new_i32();
219 tcg_gen_ext16s_i32(tmp1
, a
);
220 tcg_gen_ext16s_i32(tmp2
, b
);
221 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
222 tcg_temp_free_i32(tmp2
);
223 tcg_gen_sari_i32(a
, a
, 16);
224 tcg_gen_sari_i32(b
, b
, 16);
225 tcg_gen_mul_i32(b
, b
, a
);
226 tcg_gen_mov_i32(a
, tmp1
);
227 tcg_temp_free_i32(tmp1
);
230 /* Byteswap each halfword. */
231 static void gen_rev16(TCGv var
)
233 TCGv tmp
= tcg_temp_new_i32();
234 tcg_gen_shri_i32(tmp
, var
, 8);
235 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
236 tcg_gen_shli_i32(var
, var
, 8);
237 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
238 tcg_gen_or_i32(var
, var
, tmp
);
239 tcg_temp_free_i32(tmp
);
242 /* Byteswap low halfword and sign extend. */
243 static void gen_revsh(TCGv var
)
245 tcg_gen_ext16u_i32(var
, var
);
246 tcg_gen_bswap16_i32(var
, var
);
247 tcg_gen_ext16s_i32(var
, var
);
250 /* Unsigned bitfield extract. */
251 static void gen_ubfx(TCGv var
, int shift
, uint32_t mask
)
254 tcg_gen_shri_i32(var
, var
, shift
);
255 tcg_gen_andi_i32(var
, var
, mask
);
258 /* Signed bitfield extract. */
259 static void gen_sbfx(TCGv var
, int shift
, int width
)
264 tcg_gen_sari_i32(var
, var
, shift
);
265 if (shift
+ width
< 32) {
266 signbit
= 1u << (width
- 1);
267 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
268 tcg_gen_xori_i32(var
, var
, signbit
);
269 tcg_gen_subi_i32(var
, var
, signbit
);
273 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
274 static void gen_bfi(TCGv dest
, TCGv base
, TCGv val
, int shift
, uint32_t mask
)
276 tcg_gen_andi_i32(val
, val
, mask
);
277 tcg_gen_shli_i32(val
, val
, shift
);
278 tcg_gen_andi_i32(base
, base
, ~(mask
<< shift
));
279 tcg_gen_or_i32(dest
, base
, val
);
282 /* Return (b << 32) + a. Mark inputs as dead */
283 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
285 TCGv_i64 tmp64
= tcg_temp_new_i64();
287 tcg_gen_extu_i32_i64(tmp64
, b
);
288 tcg_temp_free_i32(b
);
289 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
290 tcg_gen_add_i64(a
, tmp64
, a
);
292 tcg_temp_free_i64(tmp64
);
296 /* Return (b << 32) - a. Mark inputs as dead. */
297 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
299 TCGv_i64 tmp64
= tcg_temp_new_i64();
301 tcg_gen_extu_i32_i64(tmp64
, b
);
302 tcg_temp_free_i32(b
);
303 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
304 tcg_gen_sub_i64(a
, tmp64
, a
);
306 tcg_temp_free_i64(tmp64
);
310 /* FIXME: Most targets have native widening multiplication.
311 It would be good to use that instead of a full wide multiply. */
312 /* 32x32->64 multiply. Marks inputs as dead. */
313 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
315 TCGv_i64 tmp1
= tcg_temp_new_i64();
316 TCGv_i64 tmp2
= tcg_temp_new_i64();
318 tcg_gen_extu_i32_i64(tmp1
, a
);
319 tcg_temp_free_i32(a
);
320 tcg_gen_extu_i32_i64(tmp2
, b
);
321 tcg_temp_free_i32(b
);
322 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
323 tcg_temp_free_i64(tmp2
);
327 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
329 TCGv_i64 tmp1
= tcg_temp_new_i64();
330 TCGv_i64 tmp2
= tcg_temp_new_i64();
332 tcg_gen_ext_i32_i64(tmp1
, a
);
333 tcg_temp_free_i32(a
);
334 tcg_gen_ext_i32_i64(tmp2
, b
);
335 tcg_temp_free_i32(b
);
336 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
337 tcg_temp_free_i64(tmp2
);
341 /* Swap low and high halfwords. */
342 static void gen_swap_half(TCGv var
)
344 TCGv tmp
= tcg_temp_new_i32();
345 tcg_gen_shri_i32(tmp
, var
, 16);
346 tcg_gen_shli_i32(var
, var
, 16);
347 tcg_gen_or_i32(var
, var
, tmp
);
348 tcg_temp_free_i32(tmp
);
351 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
352 tmp = (t0 ^ t1) & 0x8000;
355 t0 = (t0 + t1) ^ tmp;
358 static void gen_add16(TCGv t0
, TCGv t1
)
360 TCGv tmp
= tcg_temp_new_i32();
361 tcg_gen_xor_i32(tmp
, t0
, t1
);
362 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
363 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
364 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
365 tcg_gen_add_i32(t0
, t0
, t1
);
366 tcg_gen_xor_i32(t0
, t0
, tmp
);
367 tcg_temp_free_i32(tmp
);
368 tcg_temp_free_i32(t1
);
371 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
373 /* Set CF to the top bit of var. */
374 static void gen_set_CF_bit31(TCGv var
)
376 TCGv tmp
= tcg_temp_new_i32();
377 tcg_gen_shri_i32(tmp
, var
, 31);
379 tcg_temp_free_i32(tmp
);
382 /* Set N and Z flags from var. */
383 static inline void gen_logic_CC(TCGv var
)
385 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, NF
));
386 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, ZF
));
390 static void gen_adc(TCGv t0
, TCGv t1
)
393 tcg_gen_add_i32(t0
, t0
, t1
);
394 tmp
= load_cpu_field(CF
);
395 tcg_gen_add_i32(t0
, t0
, tmp
);
396 tcg_temp_free_i32(tmp
);
399 /* dest = T0 + T1 + CF. */
400 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
403 tcg_gen_add_i32(dest
, t0
, t1
);
404 tmp
= load_cpu_field(CF
);
405 tcg_gen_add_i32(dest
, dest
, tmp
);
406 tcg_temp_free_i32(tmp
);
409 /* dest = T0 - T1 + CF - 1. */
410 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
413 tcg_gen_sub_i32(dest
, t0
, t1
);
414 tmp
= load_cpu_field(CF
);
415 tcg_gen_add_i32(dest
, dest
, tmp
);
416 tcg_gen_subi_i32(dest
, dest
, 1);
417 tcg_temp_free_i32(tmp
);
420 /* FIXME: Implement this natively. */
421 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
423 static void shifter_out_im(TCGv var
, int shift
)
425 TCGv tmp
= tcg_temp_new_i32();
427 tcg_gen_andi_i32(tmp
, var
, 1);
429 tcg_gen_shri_i32(tmp
, var
, shift
);
431 tcg_gen_andi_i32(tmp
, tmp
, 1);
434 tcg_temp_free_i32(tmp
);
437 /* Shift by immediate. Includes special handling for shift == 0. */
438 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
444 shifter_out_im(var
, 32 - shift
);
445 tcg_gen_shli_i32(var
, var
, shift
);
451 tcg_gen_shri_i32(var
, var
, 31);
454 tcg_gen_movi_i32(var
, 0);
457 shifter_out_im(var
, shift
- 1);
458 tcg_gen_shri_i32(var
, var
, shift
);
465 shifter_out_im(var
, shift
- 1);
468 tcg_gen_sari_i32(var
, var
, shift
);
470 case 3: /* ROR/RRX */
473 shifter_out_im(var
, shift
- 1);
474 tcg_gen_rotri_i32(var
, var
, shift
); break;
476 TCGv tmp
= load_cpu_field(CF
);
478 shifter_out_im(var
, 0);
479 tcg_gen_shri_i32(var
, var
, 1);
480 tcg_gen_shli_i32(tmp
, tmp
, 31);
481 tcg_gen_or_i32(var
, var
, tmp
);
482 tcg_temp_free_i32(tmp
);
487 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
488 TCGv shift
, int flags
)
492 case 0: gen_helper_shl_cc(var
, var
, shift
); break;
493 case 1: gen_helper_shr_cc(var
, var
, shift
); break;
494 case 2: gen_helper_sar_cc(var
, var
, shift
); break;
495 case 3: gen_helper_ror_cc(var
, var
, shift
); break;
499 case 0: gen_helper_shl(var
, var
, shift
); break;
500 case 1: gen_helper_shr(var
, var
, shift
); break;
501 case 2: gen_helper_sar(var
, var
, shift
); break;
502 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
503 tcg_gen_rotr_i32(var
, var
, shift
); break;
506 tcg_temp_free_i32(shift
);
509 #define PAS_OP(pfx) \
511 case 0: gen_pas_helper(glue(pfx,add16)); break; \
512 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
513 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
514 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
515 case 4: gen_pas_helper(glue(pfx,add8)); break; \
516 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
518 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
523 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
525 tmp
= tcg_temp_new_ptr();
526 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
528 tcg_temp_free_ptr(tmp
);
531 tmp
= tcg_temp_new_ptr();
532 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
534 tcg_temp_free_ptr(tmp
);
536 #undef gen_pas_helper
537 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
550 #undef gen_pas_helper
555 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
556 #define PAS_OP(pfx) \
558 case 0: gen_pas_helper(glue(pfx,add8)); break; \
559 case 1: gen_pas_helper(glue(pfx,add16)); break; \
560 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
561 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
562 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
563 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
565 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
570 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
572 tmp
= tcg_temp_new_ptr();
573 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
575 tcg_temp_free_ptr(tmp
);
578 tmp
= tcg_temp_new_ptr();
579 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUState
, GE
));
581 tcg_temp_free_ptr(tmp
);
583 #undef gen_pas_helper
584 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
597 #undef gen_pas_helper
602 static void gen_test_cc(int cc
, int label
)
610 tmp
= load_cpu_field(ZF
);
611 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
614 tmp
= load_cpu_field(ZF
);
615 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
618 tmp
= load_cpu_field(CF
);
619 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
622 tmp
= load_cpu_field(CF
);
623 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
626 tmp
= load_cpu_field(NF
);
627 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
630 tmp
= load_cpu_field(NF
);
631 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
634 tmp
= load_cpu_field(VF
);
635 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
638 tmp
= load_cpu_field(VF
);
639 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
641 case 8: /* hi: C && !Z */
642 inv
= gen_new_label();
643 tmp
= load_cpu_field(CF
);
644 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
645 tcg_temp_free_i32(tmp
);
646 tmp
= load_cpu_field(ZF
);
647 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, label
);
650 case 9: /* ls: !C || Z */
651 tmp
= load_cpu_field(CF
);
652 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
653 tcg_temp_free_i32(tmp
);
654 tmp
= load_cpu_field(ZF
);
655 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
657 case 10: /* ge: N == V -> N ^ V == 0 */
658 tmp
= load_cpu_field(VF
);
659 tmp2
= load_cpu_field(NF
);
660 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
661 tcg_temp_free_i32(tmp2
);
662 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
664 case 11: /* lt: N != V -> N ^ V != 0 */
665 tmp
= load_cpu_field(VF
);
666 tmp2
= load_cpu_field(NF
);
667 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
668 tcg_temp_free_i32(tmp2
);
669 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
671 case 12: /* gt: !Z && N == V */
672 inv
= gen_new_label();
673 tmp
= load_cpu_field(ZF
);
674 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, inv
);
675 tcg_temp_free_i32(tmp
);
676 tmp
= load_cpu_field(VF
);
677 tmp2
= load_cpu_field(NF
);
678 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
679 tcg_temp_free_i32(tmp2
);
680 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
683 case 13: /* le: Z || N != V */
684 tmp
= load_cpu_field(ZF
);
685 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, label
);
686 tcg_temp_free_i32(tmp
);
687 tmp
= load_cpu_field(VF
);
688 tmp2
= load_cpu_field(NF
);
689 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
690 tcg_temp_free_i32(tmp2
);
691 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
694 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
697 tcg_temp_free_i32(tmp
);
700 static const uint8_t table_logic_cc
[16] = {
719 /* Set PC and Thumb state from an immediate address. */
720 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
724 s
->is_jmp
= DISAS_UPDATE
;
725 if (s
->thumb
!= (addr
& 1)) {
726 tmp
= tcg_temp_new_i32();
727 tcg_gen_movi_i32(tmp
, addr
& 1);
728 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUState
, thumb
));
729 tcg_temp_free_i32(tmp
);
731 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
734 /* Set PC and Thumb state from var. var is marked as dead. */
735 static inline void gen_bx(DisasContext
*s
, TCGv var
)
737 s
->is_jmp
= DISAS_UPDATE
;
738 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
739 tcg_gen_andi_i32(var
, var
, 1);
740 store_cpu_field(var
, thumb
);
743 /* Variant of store_reg which uses branch&exchange logic when storing
744 to r15 in ARM architecture v7 and above. The source must be a temporary
745 and will be marked as dead. */
746 static inline void store_reg_bx(CPUState
*env
, DisasContext
*s
,
749 if (reg
== 15 && ENABLE_ARCH_7
) {
752 store_reg(s
, reg
, var
);
756 /* Variant of store_reg which uses branch&exchange logic when storing
757 * to r15 in ARM architecture v5T and above. This is used for storing
758 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
759 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
760 static inline void store_reg_from_load(CPUState
*env
, DisasContext
*s
,
763 if (reg
== 15 && ENABLE_ARCH_5
) {
766 store_reg(s
, reg
, var
);
770 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
772 TCGv tmp
= tcg_temp_new_i32();
773 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
776 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
778 TCGv tmp
= tcg_temp_new_i32();
779 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
782 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
784 TCGv tmp
= tcg_temp_new_i32();
785 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
788 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
790 TCGv tmp
= tcg_temp_new_i32();
791 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
794 static inline TCGv
gen_ld32(TCGv addr
, int index
)
796 TCGv tmp
= tcg_temp_new_i32();
797 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
800 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
802 TCGv_i64 tmp
= tcg_temp_new_i64();
803 tcg_gen_qemu_ld64(tmp
, addr
, index
);
806 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
808 tcg_gen_qemu_st8(val
, addr
, index
);
809 tcg_temp_free_i32(val
);
811 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
813 tcg_gen_qemu_st16(val
, addr
, index
);
814 tcg_temp_free_i32(val
);
816 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
818 tcg_gen_qemu_st32(val
, addr
, index
);
819 tcg_temp_free_i32(val
);
821 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
823 tcg_gen_qemu_st64(val
, addr
, index
);
824 tcg_temp_free_i64(val
);
827 static inline void gen_set_pc_im(uint32_t val
)
829 tcg_gen_movi_i32(cpu_R
[15], val
);
832 /* Force a TB lookup after an instruction that changes the CPU state. */
833 static inline void gen_lookup_tb(DisasContext
*s
)
835 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
836 s
->is_jmp
= DISAS_UPDATE
;
839 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
842 int val
, rm
, shift
, shiftop
;
845 if (!(insn
& (1 << 25))) {
848 if (!(insn
& (1 << 23)))
851 tcg_gen_addi_i32(var
, var
, val
);
855 shift
= (insn
>> 7) & 0x1f;
856 shiftop
= (insn
>> 5) & 3;
857 offset
= load_reg(s
, rm
);
858 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
859 if (!(insn
& (1 << 23)))
860 tcg_gen_sub_i32(var
, var
, offset
);
862 tcg_gen_add_i32(var
, var
, offset
);
863 tcg_temp_free_i32(offset
);
867 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
873 if (insn
& (1 << 22)) {
875 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
876 if (!(insn
& (1 << 23)))
880 tcg_gen_addi_i32(var
, var
, val
);
884 tcg_gen_addi_i32(var
, var
, extra
);
886 offset
= load_reg(s
, rm
);
887 if (!(insn
& (1 << 23)))
888 tcg_gen_sub_i32(var
, var
, offset
);
890 tcg_gen_add_i32(var
, var
, offset
);
891 tcg_temp_free_i32(offset
);
895 #define VFP_OP2(name) \
896 static inline void gen_vfp_##name(int dp) \
899 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
901 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
911 static inline void gen_vfp_F1_mul(int dp
)
913 /* Like gen_vfp_mul() but put result in F1 */
915 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, cpu_env
);
917 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, cpu_env
);
921 static inline void gen_vfp_F1_neg(int dp
)
923 /* Like gen_vfp_neg() but put result in F1 */
925 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
927 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
931 static inline void gen_vfp_abs(int dp
)
934 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
936 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
939 static inline void gen_vfp_neg(int dp
)
942 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
944 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
947 static inline void gen_vfp_sqrt(int dp
)
950 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
952 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
955 static inline void gen_vfp_cmp(int dp
)
958 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
960 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
963 static inline void gen_vfp_cmpe(int dp
)
966 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
968 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
971 static inline void gen_vfp_F1_ld0(int dp
)
974 tcg_gen_movi_i64(cpu_F1d
, 0);
976 tcg_gen_movi_i32(cpu_F1s
, 0);
979 #define VFP_GEN_ITOF(name) \
980 static inline void gen_vfp_##name(int dp, int neon) \
982 TCGv_ptr statusptr = tcg_temp_new_ptr(); \
985 offset = offsetof(CPUState, vfp.standard_fp_status); \
987 offset = offsetof(CPUState, vfp.fp_status); \
989 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
991 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
993 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
995 tcg_temp_free_ptr(statusptr); \
1002 #define VFP_GEN_FTOI(name) \
1003 static inline void gen_vfp_##name(int dp, int neon) \
1005 TCGv_ptr statusptr = tcg_temp_new_ptr(); \
1008 offset = offsetof(CPUState, vfp.standard_fp_status); \
1010 offset = offsetof(CPUState, vfp.fp_status); \
1012 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
1014 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1016 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1018 tcg_temp_free_ptr(statusptr); \
1027 #define VFP_GEN_FIX(name) \
1028 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1030 TCGv tmp_shift = tcg_const_i32(shift); \
1031 TCGv_ptr statusptr = tcg_temp_new_ptr(); \
1034 offset = offsetof(CPUState, vfp.standard_fp_status); \
1036 offset = offsetof(CPUState, vfp.fp_status); \
1038 tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
1040 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1042 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1044 tcg_temp_free_i32(tmp_shift); \
1045 tcg_temp_free_ptr(statusptr); \
1057 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1060 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1062 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1065 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1068 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1070 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1074 vfp_reg_offset (int dp
, int reg
)
1077 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1079 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1080 + offsetof(CPU_DoubleU
, l
.upper
);
1082 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1083 + offsetof(CPU_DoubleU
, l
.lower
);
1087 /* Return the offset of a 32-bit piece of a NEON register.
1088 zero is the least significant end of the register. */
1090 neon_reg_offset (int reg
, int n
)
1094 return vfp_reg_offset(0, sreg
);
1097 static TCGv
neon_load_reg(int reg
, int pass
)
1099 TCGv tmp
= tcg_temp_new_i32();
1100 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1104 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1106 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1107 tcg_temp_free_i32(var
);
1110 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1112 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1115 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1117 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1120 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1121 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1122 #define tcg_gen_st_f32 tcg_gen_st_i32
1123 #define tcg_gen_st_f64 tcg_gen_st_i64
1125 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1128 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1130 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1133 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1136 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1138 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1141 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1144 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1146 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1149 #define ARM_CP_RW_BIT (1 << 20)
1151 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1153 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1156 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1158 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1161 static inline TCGv
iwmmxt_load_creg(int reg
)
1163 TCGv var
= tcg_temp_new_i32();
1164 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1168 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1170 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1171 tcg_temp_free_i32(var
);
1174 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1176 iwmmxt_store_reg(cpu_M0
, rn
);
1179 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1181 iwmmxt_load_reg(cpu_M0
, rn
);
1184 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1186 iwmmxt_load_reg(cpu_V1
, rn
);
1187 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1190 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1192 iwmmxt_load_reg(cpu_V1
, rn
);
1193 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1196 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1198 iwmmxt_load_reg(cpu_V1
, rn
);
1199 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1202 #define IWMMXT_OP(name) \
1203 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1205 iwmmxt_load_reg(cpu_V1, rn); \
1206 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1209 #define IWMMXT_OP_SIZE(name) \
1210 IWMMXT_OP(name##b) \
1211 IWMMXT_OP(name##w) \
1214 #define IWMMXT_OP_1(name) \
1215 static inline void gen_op_iwmmxt_##name##_M0(void) \
1217 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \
1231 IWMMXT_OP_SIZE(unpackl
)
1232 IWMMXT_OP_SIZE(unpackh
)
1234 IWMMXT_OP_1(unpacklub
)
1235 IWMMXT_OP_1(unpackluw
)
1236 IWMMXT_OP_1(unpacklul
)
1237 IWMMXT_OP_1(unpackhub
)
1238 IWMMXT_OP_1(unpackhuw
)
1239 IWMMXT_OP_1(unpackhul
)
1240 IWMMXT_OP_1(unpacklsb
)
1241 IWMMXT_OP_1(unpacklsw
)
1242 IWMMXT_OP_1(unpacklsl
)
1243 IWMMXT_OP_1(unpackhsb
)
1244 IWMMXT_OP_1(unpackhsw
)
1245 IWMMXT_OP_1(unpackhsl
)
1247 IWMMXT_OP_SIZE(cmpeq
)
1248 IWMMXT_OP_SIZE(cmpgtu
)
1249 IWMMXT_OP_SIZE(cmpgts
)
1251 IWMMXT_OP_SIZE(mins
)
1252 IWMMXT_OP_SIZE(minu
)
1253 IWMMXT_OP_SIZE(maxs
)
1254 IWMMXT_OP_SIZE(maxu
)
1256 IWMMXT_OP_SIZE(subn
)
1257 IWMMXT_OP_SIZE(addn
)
1258 IWMMXT_OP_SIZE(subu
)
1259 IWMMXT_OP_SIZE(addu
)
1260 IWMMXT_OP_SIZE(subs
)
1261 IWMMXT_OP_SIZE(adds
)
1277 static void gen_op_iwmmxt_set_mup(void)
1280 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1281 tcg_gen_ori_i32(tmp
, tmp
, 2);
1282 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1285 static void gen_op_iwmmxt_set_cup(void)
1288 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1289 tcg_gen_ori_i32(tmp
, tmp
, 1);
1290 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1293 static void gen_op_iwmmxt_setpsr_nz(void)
1295 TCGv tmp
= tcg_temp_new_i32();
1296 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1297 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1300 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1302 iwmmxt_load_reg(cpu_V1
, rn
);
1303 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1304 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1307 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1313 rd
= (insn
>> 16) & 0xf;
1314 tmp
= load_reg(s
, rd
);
1316 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1317 if (insn
& (1 << 24)) {
1319 if (insn
& (1 << 23))
1320 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1322 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1323 tcg_gen_mov_i32(dest
, tmp
);
1324 if (insn
& (1 << 21))
1325 store_reg(s
, rd
, tmp
);
1327 tcg_temp_free_i32(tmp
);
1328 } else if (insn
& (1 << 21)) {
1330 tcg_gen_mov_i32(dest
, tmp
);
1331 if (insn
& (1 << 23))
1332 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1334 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1335 store_reg(s
, rd
, tmp
);
1336 } else if (!(insn
& (1 << 23)))
1341 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1343 int rd
= (insn
>> 0) & 0xf;
1346 if (insn
& (1 << 8)) {
1347 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1350 tmp
= iwmmxt_load_creg(rd
);
1353 tmp
= tcg_temp_new_i32();
1354 iwmmxt_load_reg(cpu_V0
, rd
);
1355 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1357 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1358 tcg_gen_mov_i32(dest
, tmp
);
1359 tcg_temp_free_i32(tmp
);
1363 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1364 (ie. an undefined instruction). */
1365 static int disas_iwmmxt_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
1368 int rdhi
, rdlo
, rd0
, rd1
, i
;
1370 TCGv tmp
, tmp2
, tmp3
;
1372 if ((insn
& 0x0e000e00) == 0x0c000000) {
1373 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1375 rdlo
= (insn
>> 12) & 0xf;
1376 rdhi
= (insn
>> 16) & 0xf;
1377 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1378 iwmmxt_load_reg(cpu_V0
, wrd
);
1379 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1380 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1381 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1382 } else { /* TMCRR */
1383 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1384 iwmmxt_store_reg(cpu_V0
, wrd
);
1385 gen_op_iwmmxt_set_mup();
1390 wrd
= (insn
>> 12) & 0xf;
1391 addr
= tcg_temp_new_i32();
1392 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1393 tcg_temp_free_i32(addr
);
1396 if (insn
& ARM_CP_RW_BIT
) {
1397 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1398 tmp
= tcg_temp_new_i32();
1399 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1400 iwmmxt_store_creg(wrd
, tmp
);
1403 if (insn
& (1 << 8)) {
1404 if (insn
& (1 << 22)) { /* WLDRD */
1405 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1407 } else { /* WLDRW wRd */
1408 tmp
= gen_ld32(addr
, IS_USER(s
));
1411 if (insn
& (1 << 22)) { /* WLDRH */
1412 tmp
= gen_ld16u(addr
, IS_USER(s
));
1413 } else { /* WLDRB */
1414 tmp
= gen_ld8u(addr
, IS_USER(s
));
1418 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1419 tcg_temp_free_i32(tmp
);
1421 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1424 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1425 tmp
= iwmmxt_load_creg(wrd
);
1426 gen_st32(tmp
, addr
, IS_USER(s
));
1428 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1429 tmp
= tcg_temp_new_i32();
1430 if (insn
& (1 << 8)) {
1431 if (insn
& (1 << 22)) { /* WSTRD */
1432 tcg_temp_free_i32(tmp
);
1433 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1434 } else { /* WSTRW wRd */
1435 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1436 gen_st32(tmp
, addr
, IS_USER(s
));
1439 if (insn
& (1 << 22)) { /* WSTRH */
1440 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1441 gen_st16(tmp
, addr
, IS_USER(s
));
1442 } else { /* WSTRB */
1443 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1444 gen_st8(tmp
, addr
, IS_USER(s
));
1449 tcg_temp_free_i32(addr
);
1453 if ((insn
& 0x0f000000) != 0x0e000000)
1456 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1457 case 0x000: /* WOR */
1458 wrd
= (insn
>> 12) & 0xf;
1459 rd0
= (insn
>> 0) & 0xf;
1460 rd1
= (insn
>> 16) & 0xf;
1461 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1462 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1463 gen_op_iwmmxt_setpsr_nz();
1464 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1465 gen_op_iwmmxt_set_mup();
1466 gen_op_iwmmxt_set_cup();
1468 case 0x011: /* TMCR */
1471 rd
= (insn
>> 12) & 0xf;
1472 wrd
= (insn
>> 16) & 0xf;
1474 case ARM_IWMMXT_wCID
:
1475 case ARM_IWMMXT_wCASF
:
1477 case ARM_IWMMXT_wCon
:
1478 gen_op_iwmmxt_set_cup();
1480 case ARM_IWMMXT_wCSSF
:
1481 tmp
= iwmmxt_load_creg(wrd
);
1482 tmp2
= load_reg(s
, rd
);
1483 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1484 tcg_temp_free_i32(tmp2
);
1485 iwmmxt_store_creg(wrd
, tmp
);
1487 case ARM_IWMMXT_wCGR0
:
1488 case ARM_IWMMXT_wCGR1
:
1489 case ARM_IWMMXT_wCGR2
:
1490 case ARM_IWMMXT_wCGR3
:
1491 gen_op_iwmmxt_set_cup();
1492 tmp
= load_reg(s
, rd
);
1493 iwmmxt_store_creg(wrd
, tmp
);
1499 case 0x100: /* WXOR */
1500 wrd
= (insn
>> 12) & 0xf;
1501 rd0
= (insn
>> 0) & 0xf;
1502 rd1
= (insn
>> 16) & 0xf;
1503 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1504 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1505 gen_op_iwmmxt_setpsr_nz();
1506 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1507 gen_op_iwmmxt_set_mup();
1508 gen_op_iwmmxt_set_cup();
1510 case 0x111: /* TMRC */
1513 rd
= (insn
>> 12) & 0xf;
1514 wrd
= (insn
>> 16) & 0xf;
1515 tmp
= iwmmxt_load_creg(wrd
);
1516 store_reg(s
, rd
, tmp
);
1518 case 0x300: /* WANDN */
1519 wrd
= (insn
>> 12) & 0xf;
1520 rd0
= (insn
>> 0) & 0xf;
1521 rd1
= (insn
>> 16) & 0xf;
1522 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1523 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1524 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1525 gen_op_iwmmxt_setpsr_nz();
1526 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1527 gen_op_iwmmxt_set_mup();
1528 gen_op_iwmmxt_set_cup();
1530 case 0x200: /* WAND */
1531 wrd
= (insn
>> 12) & 0xf;
1532 rd0
= (insn
>> 0) & 0xf;
1533 rd1
= (insn
>> 16) & 0xf;
1534 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1535 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1536 gen_op_iwmmxt_setpsr_nz();
1537 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1538 gen_op_iwmmxt_set_mup();
1539 gen_op_iwmmxt_set_cup();
1541 case 0x810: case 0xa10: /* WMADD */
1542 wrd
= (insn
>> 12) & 0xf;
1543 rd0
= (insn
>> 0) & 0xf;
1544 rd1
= (insn
>> 16) & 0xf;
1545 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1546 if (insn
& (1 << 21))
1547 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1549 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1550 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1551 gen_op_iwmmxt_set_mup();
1553 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1554 wrd
= (insn
>> 12) & 0xf;
1555 rd0
= (insn
>> 16) & 0xf;
1556 rd1
= (insn
>> 0) & 0xf;
1557 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1558 switch ((insn
>> 22) & 3) {
1560 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1563 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1566 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1571 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1572 gen_op_iwmmxt_set_mup();
1573 gen_op_iwmmxt_set_cup();
1575 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1576 wrd
= (insn
>> 12) & 0xf;
1577 rd0
= (insn
>> 16) & 0xf;
1578 rd1
= (insn
>> 0) & 0xf;
1579 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1580 switch ((insn
>> 22) & 3) {
1582 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1585 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1588 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1593 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1594 gen_op_iwmmxt_set_mup();
1595 gen_op_iwmmxt_set_cup();
1597 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1598 wrd
= (insn
>> 12) & 0xf;
1599 rd0
= (insn
>> 16) & 0xf;
1600 rd1
= (insn
>> 0) & 0xf;
1601 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1602 if (insn
& (1 << 22))
1603 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1605 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1606 if (!(insn
& (1 << 20)))
1607 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1608 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1609 gen_op_iwmmxt_set_mup();
1611 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1612 wrd
= (insn
>> 12) & 0xf;
1613 rd0
= (insn
>> 16) & 0xf;
1614 rd1
= (insn
>> 0) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1616 if (insn
& (1 << 21)) {
1617 if (insn
& (1 << 20))
1618 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1620 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1622 if (insn
& (1 << 20))
1623 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1625 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1627 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1628 gen_op_iwmmxt_set_mup();
1630 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1631 wrd
= (insn
>> 12) & 0xf;
1632 rd0
= (insn
>> 16) & 0xf;
1633 rd1
= (insn
>> 0) & 0xf;
1634 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1635 if (insn
& (1 << 21))
1636 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1638 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1639 if (!(insn
& (1 << 20))) {
1640 iwmmxt_load_reg(cpu_V1
, wrd
);
1641 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1643 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1644 gen_op_iwmmxt_set_mup();
1646 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1647 wrd
= (insn
>> 12) & 0xf;
1648 rd0
= (insn
>> 16) & 0xf;
1649 rd1
= (insn
>> 0) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1651 switch ((insn
>> 22) & 3) {
1653 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1656 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1659 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1664 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1665 gen_op_iwmmxt_set_mup();
1666 gen_op_iwmmxt_set_cup();
1668 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1669 wrd
= (insn
>> 12) & 0xf;
1670 rd0
= (insn
>> 16) & 0xf;
1671 rd1
= (insn
>> 0) & 0xf;
1672 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1673 if (insn
& (1 << 22)) {
1674 if (insn
& (1 << 20))
1675 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1677 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1679 if (insn
& (1 << 20))
1680 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1682 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1684 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1685 gen_op_iwmmxt_set_mup();
1686 gen_op_iwmmxt_set_cup();
1688 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1689 wrd
= (insn
>> 12) & 0xf;
1690 rd0
= (insn
>> 16) & 0xf;
1691 rd1
= (insn
>> 0) & 0xf;
1692 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1693 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1694 tcg_gen_andi_i32(tmp
, tmp
, 7);
1695 iwmmxt_load_reg(cpu_V1
, rd1
);
1696 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1697 tcg_temp_free_i32(tmp
);
1698 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1699 gen_op_iwmmxt_set_mup();
1701 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1702 if (((insn
>> 6) & 3) == 3)
1704 rd
= (insn
>> 12) & 0xf;
1705 wrd
= (insn
>> 16) & 0xf;
1706 tmp
= load_reg(s
, rd
);
1707 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1708 switch ((insn
>> 6) & 3) {
1710 tmp2
= tcg_const_i32(0xff);
1711 tmp3
= tcg_const_i32((insn
& 7) << 3);
1714 tmp2
= tcg_const_i32(0xffff);
1715 tmp3
= tcg_const_i32((insn
& 3) << 4);
1718 tmp2
= tcg_const_i32(0xffffffff);
1719 tmp3
= tcg_const_i32((insn
& 1) << 5);
1725 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1726 tcg_temp_free(tmp3
);
1727 tcg_temp_free(tmp2
);
1728 tcg_temp_free_i32(tmp
);
1729 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1730 gen_op_iwmmxt_set_mup();
1732 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1733 rd
= (insn
>> 12) & 0xf;
1734 wrd
= (insn
>> 16) & 0xf;
1735 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1737 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1738 tmp
= tcg_temp_new_i32();
1739 switch ((insn
>> 22) & 3) {
1741 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1742 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1744 tcg_gen_ext8s_i32(tmp
, tmp
);
1746 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1750 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1751 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1753 tcg_gen_ext16s_i32(tmp
, tmp
);
1755 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1759 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1760 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1763 store_reg(s
, rd
, tmp
);
1765 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1766 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1768 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1769 switch ((insn
>> 22) & 3) {
1771 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1774 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1777 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1780 tcg_gen_shli_i32(tmp
, tmp
, 28);
1782 tcg_temp_free_i32(tmp
);
1784 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1785 if (((insn
>> 6) & 3) == 3)
1787 rd
= (insn
>> 12) & 0xf;
1788 wrd
= (insn
>> 16) & 0xf;
1789 tmp
= load_reg(s
, rd
);
1790 switch ((insn
>> 6) & 3) {
1792 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1795 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1798 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1801 tcg_temp_free_i32(tmp
);
1802 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1803 gen_op_iwmmxt_set_mup();
1805 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1806 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1808 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1809 tmp2
= tcg_temp_new_i32();
1810 tcg_gen_mov_i32(tmp2
, tmp
);
1811 switch ((insn
>> 22) & 3) {
1813 for (i
= 0; i
< 7; i
++) {
1814 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1815 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1819 for (i
= 0; i
< 3; i
++) {
1820 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1821 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1825 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1826 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1830 tcg_temp_free_i32(tmp2
);
1831 tcg_temp_free_i32(tmp
);
1833 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1834 wrd
= (insn
>> 12) & 0xf;
1835 rd0
= (insn
>> 16) & 0xf;
1836 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1837 switch ((insn
>> 22) & 3) {
1839 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1842 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1845 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1854 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1856 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1857 tmp2
= tcg_temp_new_i32();
1858 tcg_gen_mov_i32(tmp2
, tmp
);
1859 switch ((insn
>> 22) & 3) {
1861 for (i
= 0; i
< 7; i
++) {
1862 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1863 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1867 for (i
= 0; i
< 3; i
++) {
1868 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1869 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1873 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1874 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1878 tcg_temp_free_i32(tmp2
);
1879 tcg_temp_free_i32(tmp
);
1881 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1882 rd
= (insn
>> 12) & 0xf;
1883 rd0
= (insn
>> 16) & 0xf;
1884 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1886 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1887 tmp
= tcg_temp_new_i32();
1888 switch ((insn
>> 22) & 3) {
1890 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1893 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1896 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1899 store_reg(s
, rd
, tmp
);
1901 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1902 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1903 wrd
= (insn
>> 12) & 0xf;
1904 rd0
= (insn
>> 16) & 0xf;
1905 rd1
= (insn
>> 0) & 0xf;
1906 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1907 switch ((insn
>> 22) & 3) {
1909 if (insn
& (1 << 21))
1910 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1912 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1915 if (insn
& (1 << 21))
1916 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1918 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1921 if (insn
& (1 << 21))
1922 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1924 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1929 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1930 gen_op_iwmmxt_set_mup();
1931 gen_op_iwmmxt_set_cup();
1933 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1934 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1935 wrd
= (insn
>> 12) & 0xf;
1936 rd0
= (insn
>> 16) & 0xf;
1937 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1938 switch ((insn
>> 22) & 3) {
1940 if (insn
& (1 << 21))
1941 gen_op_iwmmxt_unpacklsb_M0();
1943 gen_op_iwmmxt_unpacklub_M0();
1946 if (insn
& (1 << 21))
1947 gen_op_iwmmxt_unpacklsw_M0();
1949 gen_op_iwmmxt_unpackluw_M0();
1952 if (insn
& (1 << 21))
1953 gen_op_iwmmxt_unpacklsl_M0();
1955 gen_op_iwmmxt_unpacklul_M0();
1960 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1961 gen_op_iwmmxt_set_mup();
1962 gen_op_iwmmxt_set_cup();
1964 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1965 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1966 wrd
= (insn
>> 12) & 0xf;
1967 rd0
= (insn
>> 16) & 0xf;
1968 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1969 switch ((insn
>> 22) & 3) {
1971 if (insn
& (1 << 21))
1972 gen_op_iwmmxt_unpackhsb_M0();
1974 gen_op_iwmmxt_unpackhub_M0();
1977 if (insn
& (1 << 21))
1978 gen_op_iwmmxt_unpackhsw_M0();
1980 gen_op_iwmmxt_unpackhuw_M0();
1983 if (insn
& (1 << 21))
1984 gen_op_iwmmxt_unpackhsl_M0();
1986 gen_op_iwmmxt_unpackhul_M0();
1991 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1992 gen_op_iwmmxt_set_mup();
1993 gen_op_iwmmxt_set_cup();
1995 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1996 case 0x214: case 0x614: case 0xa14: case 0xe14:
1997 if (((insn
>> 22) & 3) == 0)
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2002 tmp
= tcg_temp_new_i32();
2003 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2004 tcg_temp_free_i32(tmp
);
2007 switch ((insn
>> 22) & 3) {
2009 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_M0
, tmp
);
2012 gen_helper_iwmmxt_srll(cpu_M0
, cpu_M0
, tmp
);
2015 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_M0
, tmp
);
2018 tcg_temp_free_i32(tmp
);
2019 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2020 gen_op_iwmmxt_set_mup();
2021 gen_op_iwmmxt_set_cup();
2023 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2024 case 0x014: case 0x414: case 0x814: case 0xc14:
2025 if (((insn
>> 22) & 3) == 0)
2027 wrd
= (insn
>> 12) & 0xf;
2028 rd0
= (insn
>> 16) & 0xf;
2029 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2030 tmp
= tcg_temp_new_i32();
2031 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2032 tcg_temp_free_i32(tmp
);
2035 switch ((insn
>> 22) & 3) {
2037 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_M0
, tmp
);
2040 gen_helper_iwmmxt_sral(cpu_M0
, cpu_M0
, tmp
);
2043 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_M0
, tmp
);
2046 tcg_temp_free_i32(tmp
);
2047 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2052 case 0x114: case 0x514: case 0x914: case 0xd14:
2053 if (((insn
>> 22) & 3) == 0)
2055 wrd
= (insn
>> 12) & 0xf;
2056 rd0
= (insn
>> 16) & 0xf;
2057 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2058 tmp
= tcg_temp_new_i32();
2059 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2060 tcg_temp_free_i32(tmp
);
2063 switch ((insn
>> 22) & 3) {
2065 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_M0
, tmp
);
2068 gen_helper_iwmmxt_slll(cpu_M0
, cpu_M0
, tmp
);
2071 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_M0
, tmp
);
2074 tcg_temp_free_i32(tmp
);
2075 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2076 gen_op_iwmmxt_set_mup();
2077 gen_op_iwmmxt_set_cup();
2079 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2080 case 0x314: case 0x714: case 0xb14: case 0xf14:
2081 if (((insn
>> 22) & 3) == 0)
2083 wrd
= (insn
>> 12) & 0xf;
2084 rd0
= (insn
>> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2086 tmp
= tcg_temp_new_i32();
2087 switch ((insn
>> 22) & 3) {
2089 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2090 tcg_temp_free_i32(tmp
);
2093 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_M0
, tmp
);
2096 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2097 tcg_temp_free_i32(tmp
);
2100 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_M0
, tmp
);
2103 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2104 tcg_temp_free_i32(tmp
);
2107 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_M0
, tmp
);
2110 tcg_temp_free_i32(tmp
);
2111 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2112 gen_op_iwmmxt_set_mup();
2113 gen_op_iwmmxt_set_cup();
2115 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2116 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2117 wrd
= (insn
>> 12) & 0xf;
2118 rd0
= (insn
>> 16) & 0xf;
2119 rd1
= (insn
>> 0) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2121 switch ((insn
>> 22) & 3) {
2123 if (insn
& (1 << 21))
2124 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2126 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2129 if (insn
& (1 << 21))
2130 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2132 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2135 if (insn
& (1 << 21))
2136 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2138 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2143 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2144 gen_op_iwmmxt_set_mup();
2146 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2147 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2148 wrd
= (insn
>> 12) & 0xf;
2149 rd0
= (insn
>> 16) & 0xf;
2150 rd1
= (insn
>> 0) & 0xf;
2151 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2152 switch ((insn
>> 22) & 3) {
2154 if (insn
& (1 << 21))
2155 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2157 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2160 if (insn
& (1 << 21))
2161 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2163 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2166 if (insn
& (1 << 21))
2167 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2169 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2174 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2175 gen_op_iwmmxt_set_mup();
2177 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2178 case 0x402: case 0x502: case 0x602: case 0x702:
2179 wrd
= (insn
>> 12) & 0xf;
2180 rd0
= (insn
>> 16) & 0xf;
2181 rd1
= (insn
>> 0) & 0xf;
2182 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2183 tmp
= tcg_const_i32((insn
>> 20) & 3);
2184 iwmmxt_load_reg(cpu_V1
, rd1
);
2185 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2187 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2188 gen_op_iwmmxt_set_mup();
2190 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2191 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2192 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2193 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2194 wrd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 rd1
= (insn
>> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2198 switch ((insn
>> 20) & 0xf) {
2200 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2203 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2206 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2209 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2212 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2215 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2218 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2221 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2224 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2229 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2233 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2234 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2235 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2236 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2240 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2241 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_M0
, tmp
);
2243 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2244 gen_op_iwmmxt_set_mup();
2245 gen_op_iwmmxt_set_cup();
2247 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2248 case 0x418: case 0x518: case 0x618: case 0x718:
2249 case 0x818: case 0x918: case 0xa18: case 0xb18:
2250 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2251 wrd
= (insn
>> 12) & 0xf;
2252 rd0
= (insn
>> 16) & 0xf;
2253 rd1
= (insn
>> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2255 switch ((insn
>> 20) & 0xf) {
2257 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2260 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2263 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2266 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2269 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2272 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2275 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2278 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2281 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2287 gen_op_iwmmxt_set_mup();
2288 gen_op_iwmmxt_set_cup();
2290 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2291 case 0x408: case 0x508: case 0x608: case 0x708:
2292 case 0x808: case 0x908: case 0xa08: case 0xb08:
2293 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2294 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2296 wrd
= (insn
>> 12) & 0xf;
2297 rd0
= (insn
>> 16) & 0xf;
2298 rd1
= (insn
>> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2300 switch ((insn
>> 22) & 3) {
2302 if (insn
& (1 << 21))
2303 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2308 if (insn
& (1 << 21))
2309 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2311 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2314 if (insn
& (1 << 21))
2315 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2317 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2320 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2321 gen_op_iwmmxt_set_mup();
2322 gen_op_iwmmxt_set_cup();
2324 case 0x201: case 0x203: case 0x205: case 0x207:
2325 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2326 case 0x211: case 0x213: case 0x215: case 0x217:
2327 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2328 wrd
= (insn
>> 5) & 0xf;
2329 rd0
= (insn
>> 12) & 0xf;
2330 rd1
= (insn
>> 0) & 0xf;
2331 if (rd0
== 0xf || rd1
== 0xf)
2333 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2334 tmp
= load_reg(s
, rd0
);
2335 tmp2
= load_reg(s
, rd1
);
2336 switch ((insn
>> 16) & 0xf) {
2337 case 0x0: /* TMIA */
2338 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2340 case 0x8: /* TMIAPH */
2341 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2343 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2344 if (insn
& (1 << 16))
2345 tcg_gen_shri_i32(tmp
, tmp
, 16);
2346 if (insn
& (1 << 17))
2347 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2348 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2351 tcg_temp_free_i32(tmp2
);
2352 tcg_temp_free_i32(tmp
);
2355 tcg_temp_free_i32(tmp2
);
2356 tcg_temp_free_i32(tmp
);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2358 gen_op_iwmmxt_set_mup();
2367 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2368 (ie. an undefined instruction). */
2369 static int disas_dsp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2371 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2374 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2375 /* Multiply with Internal Accumulate Format */
2376 rd0
= (insn
>> 12) & 0xf;
2378 acc
= (insn
>> 5) & 7;
2383 tmp
= load_reg(s
, rd0
);
2384 tmp2
= load_reg(s
, rd1
);
2385 switch ((insn
>> 16) & 0xf) {
2387 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2389 case 0x8: /* MIAPH */
2390 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2392 case 0xc: /* MIABB */
2393 case 0xd: /* MIABT */
2394 case 0xe: /* MIATB */
2395 case 0xf: /* MIATT */
2396 if (insn
& (1 << 16))
2397 tcg_gen_shri_i32(tmp
, tmp
, 16);
2398 if (insn
& (1 << 17))
2399 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2400 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2405 tcg_temp_free_i32(tmp2
);
2406 tcg_temp_free_i32(tmp
);
2408 gen_op_iwmmxt_movq_wRn_M0(acc
);
2412 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2413 /* Internal Accumulator Access Format */
2414 rdhi
= (insn
>> 16) & 0xf;
2415 rdlo
= (insn
>> 12) & 0xf;
2421 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2422 iwmmxt_load_reg(cpu_V0
, acc
);
2423 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2424 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2425 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2426 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2428 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2429 iwmmxt_store_reg(cpu_V0
, acc
);
2437 /* Disassemble system coprocessor instruction. Return nonzero if
2438 instruction is not defined. */
2439 static int disas_cp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2442 uint32_t rd
= (insn
>> 12) & 0xf;
2443 uint32_t cp
= (insn
>> 8) & 0xf;
2448 if (insn
& ARM_CP_RW_BIT
) {
2449 if (!env
->cp
[cp
].cp_read
)
2451 gen_set_pc_im(s
->pc
);
2452 tmp
= tcg_temp_new_i32();
2453 tmp2
= tcg_const_i32(insn
);
2454 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2455 tcg_temp_free(tmp2
);
2456 store_reg(s
, rd
, tmp
);
2458 if (!env
->cp
[cp
].cp_write
)
2460 gen_set_pc_im(s
->pc
);
2461 tmp
= load_reg(s
, rd
);
2462 tmp2
= tcg_const_i32(insn
);
2463 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2464 tcg_temp_free(tmp2
);
2465 tcg_temp_free_i32(tmp
);
2470 static int cp15_user_ok(uint32_t insn
)
2472 int cpn
= (insn
>> 16) & 0xf;
2473 int cpm
= insn
& 0xf;
2474 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2476 if (cpn
== 13 && cpm
== 0) {
2478 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2482 /* ISB, DSB, DMB. */
2483 if ((cpm
== 5 && op
== 4)
2484 || (cpm
== 10 && (op
== 4 || op
== 5)))
2490 static int cp15_tls_load_store(CPUState
*env
, DisasContext
*s
, uint32_t insn
, uint32_t rd
)
2493 int cpn
= (insn
>> 16) & 0xf;
2494 int cpm
= insn
& 0xf;
2495 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2497 if (!arm_feature(env
, ARM_FEATURE_V6K
))
2500 if (!(cpn
== 13 && cpm
== 0))
2503 if (insn
& ARM_CP_RW_BIT
) {
2506 tmp
= load_cpu_field(cp15
.c13_tls1
);
2509 tmp
= load_cpu_field(cp15
.c13_tls2
);
2512 tmp
= load_cpu_field(cp15
.c13_tls3
);
2517 store_reg(s
, rd
, tmp
);
2520 tmp
= load_reg(s
, rd
);
2523 store_cpu_field(tmp
, cp15
.c13_tls1
);
2526 store_cpu_field(tmp
, cp15
.c13_tls2
);
2529 store_cpu_field(tmp
, cp15
.c13_tls3
);
2532 tcg_temp_free_i32(tmp
);
2539 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2540 instruction is not defined. */
2541 static int disas_cp15_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2546 /* M profile cores use memory mapped registers instead of cp15. */
2547 if (arm_feature(env
, ARM_FEATURE_M
))
2550 if ((insn
& (1 << 25)) == 0) {
2551 if (insn
& (1 << 20)) {
2555 /* mcrr. Used for block cache operations, so implement as no-op. */
2558 if ((insn
& (1 << 4)) == 0) {
2562 if (IS_USER(s
) && !cp15_user_ok(insn
)) {
2566 /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2567 * instructions rather than a separate instruction.
2569 if ((insn
& 0x0fff0fff) == 0x0e070f90) {
2570 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2571 * In v7, this must NOP.
2573 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
2574 /* Wait for interrupt. */
2575 gen_set_pc_im(s
->pc
);
2576 s
->is_jmp
= DISAS_WFI
;
2581 if ((insn
& 0x0fff0fff) == 0x0e070f58) {
2582 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2583 * so this is slightly over-broad.
2585 if (!arm_feature(env
, ARM_FEATURE_V6
)) {
2586 /* Wait for interrupt. */
2587 gen_set_pc_im(s
->pc
);
2588 s
->is_jmp
= DISAS_WFI
;
2591 /* Otherwise fall through to handle via helper function.
2592 * In particular, on v7 and some v6 cores this is one of
2593 * the VA-PA registers.
2597 rd
= (insn
>> 12) & 0xf;
2599 if (cp15_tls_load_store(env
, s
, insn
, rd
))
2602 tmp2
= tcg_const_i32(insn
);
2603 if (insn
& ARM_CP_RW_BIT
) {
2604 tmp
= tcg_temp_new_i32();
2605 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2606 /* If the destination register is r15 then sets condition codes. */
2608 store_reg(s
, rd
, tmp
);
2610 tcg_temp_free_i32(tmp
);
2612 tmp
= load_reg(s
, rd
);
2613 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2614 tcg_temp_free_i32(tmp
);
2615 /* Normally we would always end the TB here, but Linux
2616 * arch/arm/mach-pxa/sleep.S expects two instructions following
2617 * an MMU enable to execute from cache. Imitate this behaviour. */
2618 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2619 (insn
& 0x0fff0fff) != 0x0e010f10)
2622 tcg_temp_free_i32(tmp2
);
2626 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2627 #define VFP_SREG(insn, bigbit, smallbit) \
2628 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2629 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2630 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2631 reg = (((insn) >> (bigbit)) & 0x0f) \
2632 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2634 if (insn & (1 << (smallbit))) \
2636 reg = ((insn) >> (bigbit)) & 0x0f; \
2639 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2640 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2641 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2642 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2643 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2644 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2646 /* Move between integer and VFP cores. */
2647 static TCGv
gen_vfp_mrs(void)
2649 TCGv tmp
= tcg_temp_new_i32();
2650 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2654 static void gen_vfp_msr(TCGv tmp
)
2656 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2657 tcg_temp_free_i32(tmp
);
2660 static void gen_neon_dup_u8(TCGv var
, int shift
)
2662 TCGv tmp
= tcg_temp_new_i32();
2664 tcg_gen_shri_i32(var
, var
, shift
);
2665 tcg_gen_ext8u_i32(var
, var
);
2666 tcg_gen_shli_i32(tmp
, var
, 8);
2667 tcg_gen_or_i32(var
, var
, tmp
);
2668 tcg_gen_shli_i32(tmp
, var
, 16);
2669 tcg_gen_or_i32(var
, var
, tmp
);
2670 tcg_temp_free_i32(tmp
);
2673 static void gen_neon_dup_low16(TCGv var
)
2675 TCGv tmp
= tcg_temp_new_i32();
2676 tcg_gen_ext16u_i32(var
, var
);
2677 tcg_gen_shli_i32(tmp
, var
, 16);
2678 tcg_gen_or_i32(var
, var
, tmp
);
2679 tcg_temp_free_i32(tmp
);
2682 static void gen_neon_dup_high16(TCGv var
)
2684 TCGv tmp
= tcg_temp_new_i32();
2685 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2686 tcg_gen_shri_i32(tmp
, var
, 16);
2687 tcg_gen_or_i32(var
, var
, tmp
);
2688 tcg_temp_free_i32(tmp
);
2691 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2693 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2697 tmp
= gen_ld8u(addr
, IS_USER(s
));
2698 gen_neon_dup_u8(tmp
, 0);
2701 tmp
= gen_ld16u(addr
, IS_USER(s
));
2702 gen_neon_dup_low16(tmp
);
2705 tmp
= gen_ld32(addr
, IS_USER(s
));
2707 default: /* Avoid compiler warnings. */
2713 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2714 (ie. an undefined instruction). */
2715 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2717 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2723 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2726 if (!s
->vfp_enabled
) {
2727 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2728 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2730 rn
= (insn
>> 16) & 0xf;
2731 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2732 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2735 dp
= ((insn
& 0xf00) == 0xb00);
2736 switch ((insn
>> 24) & 0xf) {
2738 if (insn
& (1 << 4)) {
2739 /* single register transfer */
2740 rd
= (insn
>> 12) & 0xf;
2745 VFP_DREG_N(rn
, insn
);
2748 if (insn
& 0x00c00060
2749 && !arm_feature(env
, ARM_FEATURE_NEON
))
2752 pass
= (insn
>> 21) & 1;
2753 if (insn
& (1 << 22)) {
2755 offset
= ((insn
>> 5) & 3) * 8;
2756 } else if (insn
& (1 << 5)) {
2758 offset
= (insn
& (1 << 6)) ? 16 : 0;
2763 if (insn
& ARM_CP_RW_BIT
) {
2765 tmp
= neon_load_reg(rn
, pass
);
2769 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2770 if (insn
& (1 << 23))
2776 if (insn
& (1 << 23)) {
2778 tcg_gen_shri_i32(tmp
, tmp
, 16);
2784 tcg_gen_sari_i32(tmp
, tmp
, 16);
2793 store_reg(s
, rd
, tmp
);
2796 tmp
= load_reg(s
, rd
);
2797 if (insn
& (1 << 23)) {
2800 gen_neon_dup_u8(tmp
, 0);
2801 } else if (size
== 1) {
2802 gen_neon_dup_low16(tmp
);
2804 for (n
= 0; n
<= pass
* 2; n
++) {
2805 tmp2
= tcg_temp_new_i32();
2806 tcg_gen_mov_i32(tmp2
, tmp
);
2807 neon_store_reg(rn
, n
, tmp2
);
2809 neon_store_reg(rn
, n
, tmp
);
2814 tmp2
= neon_load_reg(rn
, pass
);
2815 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2816 tcg_temp_free_i32(tmp2
);
2819 tmp2
= neon_load_reg(rn
, pass
);
2820 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2821 tcg_temp_free_i32(tmp2
);
2826 neon_store_reg(rn
, pass
, tmp
);
2830 if ((insn
& 0x6f) != 0x00)
2832 rn
= VFP_SREG_N(insn
);
2833 if (insn
& ARM_CP_RW_BIT
) {
2835 if (insn
& (1 << 21)) {
2836 /* system register */
2841 /* VFP2 allows access to FSID from userspace.
2842 VFP3 restricts all id registers to privileged
2845 && arm_feature(env
, ARM_FEATURE_VFP3
))
2847 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2852 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2854 case ARM_VFP_FPINST
:
2855 case ARM_VFP_FPINST2
:
2856 /* Not present in VFP3. */
2858 || arm_feature(env
, ARM_FEATURE_VFP3
))
2860 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2864 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2865 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2867 tmp
= tcg_temp_new_i32();
2868 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2874 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2876 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2882 gen_mov_F0_vreg(0, rn
);
2883 tmp
= gen_vfp_mrs();
2886 /* Set the 4 flag bits in the CPSR. */
2888 tcg_temp_free_i32(tmp
);
2890 store_reg(s
, rd
, tmp
);
2894 tmp
= load_reg(s
, rd
);
2895 if (insn
& (1 << 21)) {
2897 /* system register */
2902 /* Writes are ignored. */
2905 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2906 tcg_temp_free_i32(tmp
);
2912 /* TODO: VFP subarchitecture support.
2913 * For now, keep the EN bit only */
2914 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2915 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2918 case ARM_VFP_FPINST
:
2919 case ARM_VFP_FPINST2
:
2920 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2927 gen_mov_vreg_F0(0, rn
);
2932 /* data processing */
2933 /* The opcode is in bits 23, 21, 20 and 6. */
2934 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2938 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2940 /* rn is register number */
2941 VFP_DREG_N(rn
, insn
);
2944 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2945 /* Integer or single precision destination. */
2946 rd
= VFP_SREG_D(insn
);
2948 VFP_DREG_D(rd
, insn
);
2951 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2952 /* VCVT from int is always from S reg regardless of dp bit.
2953 * VCVT with immediate frac_bits has same format as SREG_M
2955 rm
= VFP_SREG_M(insn
);
2957 VFP_DREG_M(rm
, insn
);
2960 rn
= VFP_SREG_N(insn
);
2961 if (op
== 15 && rn
== 15) {
2962 /* Double precision destination. */
2963 VFP_DREG_D(rd
, insn
);
2965 rd
= VFP_SREG_D(insn
);
2967 /* NB that we implicitly rely on the encoding for the frac_bits
2968 * in VCVT of fixed to float being the same as that of an SREG_M
2970 rm
= VFP_SREG_M(insn
);
2973 veclen
= s
->vec_len
;
2974 if (op
== 15 && rn
> 3)
2977 /* Shut up compiler warnings. */
2988 /* Figure out what type of vector operation this is. */
2989 if ((rd
& bank_mask
) == 0) {
2994 delta_d
= (s
->vec_stride
>> 1) + 1;
2996 delta_d
= s
->vec_stride
+ 1;
2998 if ((rm
& bank_mask
) == 0) {
2999 /* mixed scalar/vector */
3008 /* Load the initial operands. */
3013 /* Integer source */
3014 gen_mov_F0_vreg(0, rm
);
3019 gen_mov_F0_vreg(dp
, rd
);
3020 gen_mov_F1_vreg(dp
, rm
);
3024 /* Compare with zero */
3025 gen_mov_F0_vreg(dp
, rd
);
3036 /* Source and destination the same. */
3037 gen_mov_F0_vreg(dp
, rd
);
3040 /* One source operand. */
3041 gen_mov_F0_vreg(dp
, rm
);
3045 /* Two source operands. */
3046 gen_mov_F0_vreg(dp
, rn
);
3047 gen_mov_F1_vreg(dp
, rm
);
3051 /* Perform the calculation. */
3053 case 0: /* VMLA: fd + (fn * fm) */
3054 /* Note that order of inputs to the add matters for NaNs */
3056 gen_mov_F0_vreg(dp
, rd
);
3059 case 1: /* VMLS: fd + -(fn * fm) */
3062 gen_mov_F0_vreg(dp
, rd
);
3065 case 2: /* VNMLS: -fd + (fn * fm) */
3066 /* Note that it isn't valid to replace (-A + B) with (B - A)
3067 * or similar plausible looking simplifications
3068 * because this will give wrong results for NaNs.
3071 gen_mov_F0_vreg(dp
, rd
);
3075 case 3: /* VNMLA: -fd + -(fn * fm) */
3078 gen_mov_F0_vreg(dp
, rd
);
3082 case 4: /* mul: fn * fm */
3085 case 5: /* nmul: -(fn * fm) */
3089 case 6: /* add: fn + fm */
3092 case 7: /* sub: fn - fm */
3095 case 8: /* div: fn / fm */
3098 case 14: /* fconst */
3099 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3102 n
= (insn
<< 12) & 0x80000000;
3103 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3110 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3117 tcg_gen_movi_i32(cpu_F0s
, n
);
3120 case 15: /* extension space */
3134 case 4: /* vcvtb.f32.f16 */
3135 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3137 tmp
= gen_vfp_mrs();
3138 tcg_gen_ext16u_i32(tmp
, tmp
);
3139 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3140 tcg_temp_free_i32(tmp
);
3142 case 5: /* vcvtt.f32.f16 */
3143 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3145 tmp
= gen_vfp_mrs();
3146 tcg_gen_shri_i32(tmp
, tmp
, 16);
3147 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3148 tcg_temp_free_i32(tmp
);
3150 case 6: /* vcvtb.f16.f32 */
3151 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3153 tmp
= tcg_temp_new_i32();
3154 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3155 gen_mov_F0_vreg(0, rd
);
3156 tmp2
= gen_vfp_mrs();
3157 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3158 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3159 tcg_temp_free_i32(tmp2
);
3162 case 7: /* vcvtt.f16.f32 */
3163 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3165 tmp
= tcg_temp_new_i32();
3166 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3167 tcg_gen_shli_i32(tmp
, tmp
, 16);
3168 gen_mov_F0_vreg(0, rd
);
3169 tmp2
= gen_vfp_mrs();
3170 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3171 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3172 tcg_temp_free_i32(tmp2
);
3184 case 11: /* cmpez */
3188 case 15: /* single<->double conversion */
3190 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3192 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3194 case 16: /* fuito */
3195 gen_vfp_uito(dp
, 0);
3197 case 17: /* fsito */
3198 gen_vfp_sito(dp
, 0);
3200 case 20: /* fshto */
3201 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3203 gen_vfp_shto(dp
, 16 - rm
, 0);
3205 case 21: /* fslto */
3206 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3208 gen_vfp_slto(dp
, 32 - rm
, 0);
3210 case 22: /* fuhto */
3211 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3213 gen_vfp_uhto(dp
, 16 - rm
, 0);
3215 case 23: /* fulto */
3216 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3218 gen_vfp_ulto(dp
, 32 - rm
, 0);
3220 case 24: /* ftoui */
3221 gen_vfp_toui(dp
, 0);
3223 case 25: /* ftouiz */
3224 gen_vfp_touiz(dp
, 0);
3226 case 26: /* ftosi */
3227 gen_vfp_tosi(dp
, 0);
3229 case 27: /* ftosiz */
3230 gen_vfp_tosiz(dp
, 0);
3232 case 28: /* ftosh */
3233 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3235 gen_vfp_tosh(dp
, 16 - rm
, 0);
3237 case 29: /* ftosl */
3238 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3240 gen_vfp_tosl(dp
, 32 - rm
, 0);
3242 case 30: /* ftouh */
3243 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3245 gen_vfp_touh(dp
, 16 - rm
, 0);
3247 case 31: /* ftoul */
3248 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3250 gen_vfp_toul(dp
, 32 - rm
, 0);
3252 default: /* undefined */
3253 printf ("rn:%d\n", rn
);
3257 default: /* undefined */
3258 printf ("op:%d\n", op
);
3262 /* Write back the result. */
3263 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3264 ; /* Comparison, do nothing. */
3265 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3266 /* VCVT double to int: always integer result. */
3267 gen_mov_vreg_F0(0, rd
);
3268 else if (op
== 15 && rn
== 15)
3270 gen_mov_vreg_F0(!dp
, rd
);
3272 gen_mov_vreg_F0(dp
, rd
);
3274 /* break out of the loop if we have finished */
3278 if (op
== 15 && delta_m
== 0) {
3279 /* single source one-many */
3281 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3283 gen_mov_vreg_F0(dp
, rd
);
3287 /* Setup the next operands. */
3289 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3293 /* One source operand. */
3294 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3296 gen_mov_F0_vreg(dp
, rm
);
3298 /* Two source operands. */
3299 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3301 gen_mov_F0_vreg(dp
, rn
);
3303 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3305 gen_mov_F1_vreg(dp
, rm
);
3313 if ((insn
& 0x03e00000) == 0x00400000) {
3314 /* two-register transfer */
3315 rn
= (insn
>> 16) & 0xf;
3316 rd
= (insn
>> 12) & 0xf;
3318 VFP_DREG_M(rm
, insn
);
3320 rm
= VFP_SREG_M(insn
);
3323 if (insn
& ARM_CP_RW_BIT
) {
3326 gen_mov_F0_vreg(0, rm
* 2);
3327 tmp
= gen_vfp_mrs();
3328 store_reg(s
, rd
, tmp
);
3329 gen_mov_F0_vreg(0, rm
* 2 + 1);
3330 tmp
= gen_vfp_mrs();
3331 store_reg(s
, rn
, tmp
);
3333 gen_mov_F0_vreg(0, rm
);
3334 tmp
= gen_vfp_mrs();
3335 store_reg(s
, rd
, tmp
);
3336 gen_mov_F0_vreg(0, rm
+ 1);
3337 tmp
= gen_vfp_mrs();
3338 store_reg(s
, rn
, tmp
);
3343 tmp
= load_reg(s
, rd
);
3345 gen_mov_vreg_F0(0, rm
* 2);
3346 tmp
= load_reg(s
, rn
);
3348 gen_mov_vreg_F0(0, rm
* 2 + 1);
3350 tmp
= load_reg(s
, rd
);
3352 gen_mov_vreg_F0(0, rm
);
3353 tmp
= load_reg(s
, rn
);
3355 gen_mov_vreg_F0(0, rm
+ 1);
3360 rn
= (insn
>> 16) & 0xf;
3362 VFP_DREG_D(rd
, insn
);
3364 rd
= VFP_SREG_D(insn
);
3365 if (s
->thumb
&& rn
== 15) {
3366 addr
= tcg_temp_new_i32();
3367 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3369 addr
= load_reg(s
, rn
);
3371 if ((insn
& 0x01200000) == 0x01000000) {
3372 /* Single load/store */
3373 offset
= (insn
& 0xff) << 2;
3374 if ((insn
& (1 << 23)) == 0)
3376 tcg_gen_addi_i32(addr
, addr
, offset
);
3377 if (insn
& (1 << 20)) {
3378 gen_vfp_ld(s
, dp
, addr
);
3379 gen_mov_vreg_F0(dp
, rd
);
3381 gen_mov_F0_vreg(dp
, rd
);
3382 gen_vfp_st(s
, dp
, addr
);
3384 tcg_temp_free_i32(addr
);
3386 /* load/store multiple */
3388 n
= (insn
>> 1) & 0x7f;
3392 if (insn
& (1 << 24)) /* pre-decrement */
3393 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3399 for (i
= 0; i
< n
; i
++) {
3400 if (insn
& ARM_CP_RW_BIT
) {
3402 gen_vfp_ld(s
, dp
, addr
);
3403 gen_mov_vreg_F0(dp
, rd
+ i
);
3406 gen_mov_F0_vreg(dp
, rd
+ i
);
3407 gen_vfp_st(s
, dp
, addr
);
3409 tcg_gen_addi_i32(addr
, addr
, offset
);
3411 if (insn
& (1 << 21)) {
3413 if (insn
& (1 << 24))
3414 offset
= -offset
* n
;
3415 else if (dp
&& (insn
& 1))
3421 tcg_gen_addi_i32(addr
, addr
, offset
);
3422 store_reg(s
, rn
, addr
);
3424 tcg_temp_free_i32(addr
);
3430 /* Should never happen. */
3436 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3438 TranslationBlock
*tb
;
3441 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3443 gen_set_pc_im(dest
);
3444 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3446 gen_set_pc_im(dest
);
3451 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3453 if (unlikely(s
->singlestep_enabled
)) {
3454 /* An indirect jump so that we still trigger the debug exception. */
3459 gen_goto_tb(s
, 0, dest
);
3460 s
->is_jmp
= DISAS_TB_JUMP
;
3464 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3467 tcg_gen_sari_i32(t0
, t0
, 16);
3471 tcg_gen_sari_i32(t1
, t1
, 16);
3474 tcg_gen_mul_i32(t0
, t0
, t1
);
3477 /* Return the mask of PSR bits set by a MSR instruction. */
3478 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3482 if (flags
& (1 << 0))
3484 if (flags
& (1 << 1))
3486 if (flags
& (1 << 2))
3488 if (flags
& (1 << 3))
3491 /* Mask out undefined bits. */
3492 mask
&= ~CPSR_RESERVED
;
3493 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3495 if (!arm_feature(env
, ARM_FEATURE_V5
))
3496 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3497 if (!arm_feature(env
, ARM_FEATURE_V6
))
3498 mask
&= ~(CPSR_E
| CPSR_GE
);
3499 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3501 /* Mask out execution state bits. */
3504 /* Mask out privileged bits. */
3510 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3511 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3515 /* ??? This is also undefined in system mode. */
3519 tmp
= load_cpu_field(spsr
);
3520 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3521 tcg_gen_andi_i32(t0
, t0
, mask
);
3522 tcg_gen_or_i32(tmp
, tmp
, t0
);
3523 store_cpu_field(tmp
, spsr
);
3525 gen_set_cpsr(t0
, mask
);
3527 tcg_temp_free_i32(t0
);
3532 /* Returns nonzero if access to the PSR is not permitted. */
3533 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3536 tmp
= tcg_temp_new_i32();
3537 tcg_gen_movi_i32(tmp
, val
);
3538 return gen_set_psr(s
, mask
, spsr
, tmp
);
3541 /* Generate an old-style exception return. Marks pc as dead. */
3542 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3545 store_reg(s
, 15, pc
);
3546 tmp
= load_cpu_field(spsr
);
3547 gen_set_cpsr(tmp
, 0xffffffff);
3548 tcg_temp_free_i32(tmp
);
3549 s
->is_jmp
= DISAS_UPDATE
;
3552 /* Generate a v6 exception return. Marks both values as dead. */
3553 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3555 gen_set_cpsr(cpsr
, 0xffffffff);
3556 tcg_temp_free_i32(cpsr
);
3557 store_reg(s
, 15, pc
);
3558 s
->is_jmp
= DISAS_UPDATE
;
3562 gen_set_condexec (DisasContext
*s
)
3564 if (s
->condexec_mask
) {
3565 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3566 TCGv tmp
= tcg_temp_new_i32();
3567 tcg_gen_movi_i32(tmp
, val
);
3568 store_cpu_field(tmp
, condexec_bits
);
3572 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3574 gen_set_condexec(s
);
3575 gen_set_pc_im(s
->pc
- offset
);
3576 gen_exception(excp
);
3577 s
->is_jmp
= DISAS_JUMP
;
3580 static void gen_nop_hint(DisasContext
*s
, int val
)
3584 gen_set_pc_im(s
->pc
);
3585 s
->is_jmp
= DISAS_WFI
;
3589 /* TODO: Implement SEV and WFE. May help SMP performance. */
3595 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3597 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3600 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3601 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3602 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3607 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3610 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3611 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3612 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3617 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3618 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3619 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3620 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3621 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3623 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3624 switch ((size << 1) | u) { \
3626 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3629 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3632 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3635 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3638 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3641 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3643 default: return 1; \
3646 #define GEN_NEON_INTEGER_OP(name) do { \
3647 switch ((size << 1) | u) { \
3649 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3652 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3655 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3658 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3661 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3664 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3666 default: return 1; \
3669 static TCGv
neon_load_scratch(int scratch
)
3671 TCGv tmp
= tcg_temp_new_i32();
3672 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3676 static void neon_store_scratch(int scratch
, TCGv var
)
3678 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3679 tcg_temp_free_i32(var
);
3682 static inline TCGv
neon_get_scalar(int size
, int reg
)
3686 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3688 gen_neon_dup_high16(tmp
);
3690 gen_neon_dup_low16(tmp
);
3693 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3698 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3701 if (!q
&& size
== 2) {
3704 tmp
= tcg_const_i32(rd
);
3705 tmp2
= tcg_const_i32(rm
);
3709 gen_helper_neon_qunzip8(tmp
, tmp2
);
3712 gen_helper_neon_qunzip16(tmp
, tmp2
);
3715 gen_helper_neon_qunzip32(tmp
, tmp2
);
3723 gen_helper_neon_unzip8(tmp
, tmp2
);
3726 gen_helper_neon_unzip16(tmp
, tmp2
);
3732 tcg_temp_free_i32(tmp
);
3733 tcg_temp_free_i32(tmp2
);
3737 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3740 if (!q
&& size
== 2) {
3743 tmp
= tcg_const_i32(rd
);
3744 tmp2
= tcg_const_i32(rm
);
3748 gen_helper_neon_qzip8(tmp
, tmp2
);
3751 gen_helper_neon_qzip16(tmp
, tmp2
);
3754 gen_helper_neon_qzip32(tmp
, tmp2
);
3762 gen_helper_neon_zip8(tmp
, tmp2
);
3765 gen_helper_neon_zip16(tmp
, tmp2
);
3771 tcg_temp_free_i32(tmp
);
3772 tcg_temp_free_i32(tmp2
);
3776 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3780 rd
= tcg_temp_new_i32();
3781 tmp
= tcg_temp_new_i32();
3783 tcg_gen_shli_i32(rd
, t0
, 8);
3784 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3785 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3786 tcg_gen_or_i32(rd
, rd
, tmp
);
3788 tcg_gen_shri_i32(t1
, t1
, 8);
3789 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3790 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3791 tcg_gen_or_i32(t1
, t1
, tmp
);
3792 tcg_gen_mov_i32(t0
, rd
);
3794 tcg_temp_free_i32(tmp
);
3795 tcg_temp_free_i32(rd
);
3798 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3802 rd
= tcg_temp_new_i32();
3803 tmp
= tcg_temp_new_i32();
3805 tcg_gen_shli_i32(rd
, t0
, 16);
3806 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3807 tcg_gen_or_i32(rd
, rd
, tmp
);
3808 tcg_gen_shri_i32(t1
, t1
, 16);
3809 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3810 tcg_gen_or_i32(t1
, t1
, tmp
);
3811 tcg_gen_mov_i32(t0
, rd
);
3813 tcg_temp_free_i32(tmp
);
3814 tcg_temp_free_i32(rd
);
3822 } neon_ls_element_type
[11] = {
3836 /* Translate a NEON load/store element instruction. Return nonzero if the
3837 instruction is invalid. */
3838 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3857 if (!s
->vfp_enabled
)
3859 VFP_DREG_D(rd
, insn
);
3860 rn
= (insn
>> 16) & 0xf;
3862 load
= (insn
& (1 << 21)) != 0;
3863 if ((insn
& (1 << 23)) == 0) {
3864 /* Load store all elements. */
3865 op
= (insn
>> 8) & 0xf;
3866 size
= (insn
>> 6) & 3;
3869 /* Catch UNDEF cases for bad values of align field */
3872 if (((insn
>> 5) & 1) == 1) {
3877 if (((insn
>> 4) & 3) == 3) {
3884 nregs
= neon_ls_element_type
[op
].nregs
;
3885 interleave
= neon_ls_element_type
[op
].interleave
;
3886 spacing
= neon_ls_element_type
[op
].spacing
;
3887 if (size
== 3 && (interleave
| spacing
) != 1)
3889 addr
= tcg_temp_new_i32();
3890 load_reg_var(s
, addr
, rn
);
3891 stride
= (1 << size
) * interleave
;
3892 for (reg
= 0; reg
< nregs
; reg
++) {
3893 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3894 load_reg_var(s
, addr
, rn
);
3895 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3896 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3897 load_reg_var(s
, addr
, rn
);
3898 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3902 tmp64
= gen_ld64(addr
, IS_USER(s
));
3903 neon_store_reg64(tmp64
, rd
);
3904 tcg_temp_free_i64(tmp64
);
3906 tmp64
= tcg_temp_new_i64();
3907 neon_load_reg64(tmp64
, rd
);
3908 gen_st64(tmp64
, addr
, IS_USER(s
));
3910 tcg_gen_addi_i32(addr
, addr
, stride
);
3912 for (pass
= 0; pass
< 2; pass
++) {
3915 tmp
= gen_ld32(addr
, IS_USER(s
));
3916 neon_store_reg(rd
, pass
, tmp
);
3918 tmp
= neon_load_reg(rd
, pass
);
3919 gen_st32(tmp
, addr
, IS_USER(s
));
3921 tcg_gen_addi_i32(addr
, addr
, stride
);
3922 } else if (size
== 1) {
3924 tmp
= gen_ld16u(addr
, IS_USER(s
));
3925 tcg_gen_addi_i32(addr
, addr
, stride
);
3926 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3927 tcg_gen_addi_i32(addr
, addr
, stride
);
3928 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3929 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3930 tcg_temp_free_i32(tmp2
);
3931 neon_store_reg(rd
, pass
, tmp
);
3933 tmp
= neon_load_reg(rd
, pass
);
3934 tmp2
= tcg_temp_new_i32();
3935 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3936 gen_st16(tmp
, addr
, IS_USER(s
));
3937 tcg_gen_addi_i32(addr
, addr
, stride
);
3938 gen_st16(tmp2
, addr
, IS_USER(s
));
3939 tcg_gen_addi_i32(addr
, addr
, stride
);
3941 } else /* size == 0 */ {
3944 for (n
= 0; n
< 4; n
++) {
3945 tmp
= gen_ld8u(addr
, IS_USER(s
));
3946 tcg_gen_addi_i32(addr
, addr
, stride
);
3950 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3951 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3952 tcg_temp_free_i32(tmp
);
3955 neon_store_reg(rd
, pass
, tmp2
);
3957 tmp2
= neon_load_reg(rd
, pass
);
3958 for (n
= 0; n
< 4; n
++) {
3959 tmp
= tcg_temp_new_i32();
3961 tcg_gen_mov_i32(tmp
, tmp2
);
3963 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3965 gen_st8(tmp
, addr
, IS_USER(s
));
3966 tcg_gen_addi_i32(addr
, addr
, stride
);
3968 tcg_temp_free_i32(tmp2
);
3975 tcg_temp_free_i32(addr
);
3978 size
= (insn
>> 10) & 3;
3980 /* Load single element to all lanes. */
3981 int a
= (insn
>> 4) & 1;
3985 size
= (insn
>> 6) & 3;
3986 nregs
= ((insn
>> 8) & 3) + 1;
3989 if (nregs
!= 4 || a
== 0) {
3992 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3995 if (nregs
== 1 && a
== 1 && size
== 0) {
3998 if (nregs
== 3 && a
== 1) {
4001 addr
= tcg_temp_new_i32();
4002 load_reg_var(s
, addr
, rn
);
4004 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4005 tmp
= gen_load_and_replicate(s
, addr
, size
);
4006 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4007 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4008 if (insn
& (1 << 5)) {
4009 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4010 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4012 tcg_temp_free_i32(tmp
);
4014 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4015 stride
= (insn
& (1 << 5)) ? 2 : 1;
4016 for (reg
= 0; reg
< nregs
; reg
++) {
4017 tmp
= gen_load_and_replicate(s
, addr
, size
);
4018 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4019 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4020 tcg_temp_free_i32(tmp
);
4021 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4025 tcg_temp_free_i32(addr
);
4026 stride
= (1 << size
) * nregs
;
4028 /* Single element. */
4029 int idx
= (insn
>> 4) & 0xf;
4030 pass
= (insn
>> 7) & 1;
4033 shift
= ((insn
>> 5) & 3) * 8;
4037 shift
= ((insn
>> 6) & 1) * 16;
4038 stride
= (insn
& (1 << 5)) ? 2 : 1;
4042 stride
= (insn
& (1 << 6)) ? 2 : 1;
4047 nregs
= ((insn
>> 8) & 3) + 1;
4048 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4051 if (((idx
& (1 << size
)) != 0) ||
4052 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4057 if ((idx
& 1) != 0) {
4062 if (size
== 2 && (idx
& 2) != 0) {
4067 if ((size
== 2) && ((idx
& 3) == 3)) {
4074 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4075 /* Attempts to write off the end of the register file
4076 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4077 * the neon_load_reg() would write off the end of the array.
4081 addr
= tcg_temp_new_i32();
4082 load_reg_var(s
, addr
, rn
);
4083 for (reg
= 0; reg
< nregs
; reg
++) {
4087 tmp
= gen_ld8u(addr
, IS_USER(s
));
4090 tmp
= gen_ld16u(addr
, IS_USER(s
));
4093 tmp
= gen_ld32(addr
, IS_USER(s
));
4095 default: /* Avoid compiler warnings. */
4099 tmp2
= neon_load_reg(rd
, pass
);
4100 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
4101 tcg_temp_free_i32(tmp2
);
4103 neon_store_reg(rd
, pass
, tmp
);
4104 } else { /* Store */
4105 tmp
= neon_load_reg(rd
, pass
);
4107 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4110 gen_st8(tmp
, addr
, IS_USER(s
));
4113 gen_st16(tmp
, addr
, IS_USER(s
));
4116 gen_st32(tmp
, addr
, IS_USER(s
));
4121 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4123 tcg_temp_free_i32(addr
);
4124 stride
= nregs
* (1 << size
);
4130 base
= load_reg(s
, rn
);
4132 tcg_gen_addi_i32(base
, base
, stride
);
4135 index
= load_reg(s
, rm
);
4136 tcg_gen_add_i32(base
, base
, index
);
4137 tcg_temp_free_i32(index
);
4139 store_reg(s
, rn
, base
);
4144 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4145 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4147 tcg_gen_and_i32(t
, t
, c
);
4148 tcg_gen_andc_i32(f
, f
, c
);
4149 tcg_gen_or_i32(dest
, t
, f
);
4152 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4155 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4156 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4157 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4162 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4165 case 0: gen_helper_neon_narrow_sat_s8(dest
, src
); break;
4166 case 1: gen_helper_neon_narrow_sat_s16(dest
, src
); break;
4167 case 2: gen_helper_neon_narrow_sat_s32(dest
, src
); break;
4172 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4175 case 0: gen_helper_neon_narrow_sat_u8(dest
, src
); break;
4176 case 1: gen_helper_neon_narrow_sat_u16(dest
, src
); break;
4177 case 2: gen_helper_neon_narrow_sat_u32(dest
, src
); break;
4182 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4185 case 0: gen_helper_neon_unarrow_sat8(dest
, src
); break;
4186 case 1: gen_helper_neon_unarrow_sat16(dest
, src
); break;
4187 case 2: gen_helper_neon_unarrow_sat32(dest
, src
); break;
4192 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4198 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4199 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4204 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4205 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4212 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4213 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4218 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4219 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4226 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4230 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4231 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4232 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4237 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4238 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4239 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4243 tcg_temp_free_i32(src
);
4246 static inline void gen_neon_addl(int size
)
4249 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4250 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4251 case 2: tcg_gen_add_i64(CPU_V001
); break;
4256 static inline void gen_neon_subl(int size
)
4259 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4260 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4261 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4266 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4269 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4270 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4271 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4276 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4279 case 1: gen_helper_neon_addl_saturate_s32(op0
, op0
, op1
); break;
4280 case 2: gen_helper_neon_addl_saturate_s64(op0
, op0
, op1
); break;
4285 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4289 switch ((size
<< 1) | u
) {
4290 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4291 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4292 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4293 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4295 tmp
= gen_muls_i64_i32(a
, b
);
4296 tcg_gen_mov_i64(dest
, tmp
);
4297 tcg_temp_free_i64(tmp
);
4300 tmp
= gen_mulu_i64_i32(a
, b
);
4301 tcg_gen_mov_i64(dest
, tmp
);
4302 tcg_temp_free_i64(tmp
);
4307 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4308 Don't forget to clean them now. */
4310 tcg_temp_free_i32(a
);
4311 tcg_temp_free_i32(b
);
4315 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4319 gen_neon_unarrow_sats(size
, dest
, src
);
4321 gen_neon_narrow(size
, dest
, src
);
4325 gen_neon_narrow_satu(size
, dest
, src
);
4327 gen_neon_narrow_sats(size
, dest
, src
);
4332 /* Symbolic constants for op fields for Neon 3-register same-length.
4333 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4336 #define NEON_3R_VHADD 0
4337 #define NEON_3R_VQADD 1
4338 #define NEON_3R_VRHADD 2
4339 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4340 #define NEON_3R_VHSUB 4
4341 #define NEON_3R_VQSUB 5
4342 #define NEON_3R_VCGT 6
4343 #define NEON_3R_VCGE 7
4344 #define NEON_3R_VSHL 8
4345 #define NEON_3R_VQSHL 9
4346 #define NEON_3R_VRSHL 10
4347 #define NEON_3R_VQRSHL 11
4348 #define NEON_3R_VMAX 12
4349 #define NEON_3R_VMIN 13
4350 #define NEON_3R_VABD 14
4351 #define NEON_3R_VABA 15
4352 #define NEON_3R_VADD_VSUB 16
4353 #define NEON_3R_VTST_VCEQ 17
4354 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4355 #define NEON_3R_VMUL 19
4356 #define NEON_3R_VPMAX 20
4357 #define NEON_3R_VPMIN 21
4358 #define NEON_3R_VQDMULH_VQRDMULH 22
4359 #define NEON_3R_VPADD 23
4360 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4361 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4362 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4363 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4364 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4365 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4367 static const uint8_t neon_3r_sizes
[] = {
4368 [NEON_3R_VHADD
] = 0x7,
4369 [NEON_3R_VQADD
] = 0xf,
4370 [NEON_3R_VRHADD
] = 0x7,
4371 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4372 [NEON_3R_VHSUB
] = 0x7,
4373 [NEON_3R_VQSUB
] = 0xf,
4374 [NEON_3R_VCGT
] = 0x7,
4375 [NEON_3R_VCGE
] = 0x7,
4376 [NEON_3R_VSHL
] = 0xf,
4377 [NEON_3R_VQSHL
] = 0xf,
4378 [NEON_3R_VRSHL
] = 0xf,
4379 [NEON_3R_VQRSHL
] = 0xf,
4380 [NEON_3R_VMAX
] = 0x7,
4381 [NEON_3R_VMIN
] = 0x7,
4382 [NEON_3R_VABD
] = 0x7,
4383 [NEON_3R_VABA
] = 0x7,
4384 [NEON_3R_VADD_VSUB
] = 0xf,
4385 [NEON_3R_VTST_VCEQ
] = 0x7,
4386 [NEON_3R_VML
] = 0x7,
4387 [NEON_3R_VMUL
] = 0x7,
4388 [NEON_3R_VPMAX
] = 0x7,
4389 [NEON_3R_VPMIN
] = 0x7,
4390 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4391 [NEON_3R_VPADD
] = 0x7,
4392 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4393 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4394 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4395 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4396 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4397 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4400 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4401 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4404 #define NEON_2RM_VREV64 0
4405 #define NEON_2RM_VREV32 1
4406 #define NEON_2RM_VREV16 2
4407 #define NEON_2RM_VPADDL 4
4408 #define NEON_2RM_VPADDL_U 5
4409 #define NEON_2RM_VCLS 8
4410 #define NEON_2RM_VCLZ 9
4411 #define NEON_2RM_VCNT 10
4412 #define NEON_2RM_VMVN 11
4413 #define NEON_2RM_VPADAL 12
4414 #define NEON_2RM_VPADAL_U 13
4415 #define NEON_2RM_VQABS 14
4416 #define NEON_2RM_VQNEG 15
4417 #define NEON_2RM_VCGT0 16
4418 #define NEON_2RM_VCGE0 17
4419 #define NEON_2RM_VCEQ0 18
4420 #define NEON_2RM_VCLE0 19
4421 #define NEON_2RM_VCLT0 20
4422 #define NEON_2RM_VABS 22
4423 #define NEON_2RM_VNEG 23
4424 #define NEON_2RM_VCGT0_F 24
4425 #define NEON_2RM_VCGE0_F 25
4426 #define NEON_2RM_VCEQ0_F 26
4427 #define NEON_2RM_VCLE0_F 27
4428 #define NEON_2RM_VCLT0_F 28
4429 #define NEON_2RM_VABS_F 30
4430 #define NEON_2RM_VNEG_F 31
4431 #define NEON_2RM_VSWP 32
4432 #define NEON_2RM_VTRN 33
4433 #define NEON_2RM_VUZP 34
4434 #define NEON_2RM_VZIP 35
4435 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4436 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4437 #define NEON_2RM_VSHLL 38
4438 #define NEON_2RM_VCVT_F16_F32 44
4439 #define NEON_2RM_VCVT_F32_F16 46
4440 #define NEON_2RM_VRECPE 56
4441 #define NEON_2RM_VRSQRTE 57
4442 #define NEON_2RM_VRECPE_F 58
4443 #define NEON_2RM_VRSQRTE_F 59
4444 #define NEON_2RM_VCVT_FS 60
4445 #define NEON_2RM_VCVT_FU 61
4446 #define NEON_2RM_VCVT_SF 62
4447 #define NEON_2RM_VCVT_UF 63
4449 static int neon_2rm_is_float_op(int op
)
4451 /* Return true if this neon 2reg-misc op is float-to-float */
4452 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4453 op
>= NEON_2RM_VRECPE_F
);
4456 /* Each entry in this array has bit n set if the insn allows
4457 * size value n (otherwise it will UNDEF). Since unallocated
4458 * op values will have no bits set they always UNDEF.
4460 static const uint8_t neon_2rm_sizes
[] = {
4461 [NEON_2RM_VREV64
] = 0x7,
4462 [NEON_2RM_VREV32
] = 0x3,
4463 [NEON_2RM_VREV16
] = 0x1,
4464 [NEON_2RM_VPADDL
] = 0x7,
4465 [NEON_2RM_VPADDL_U
] = 0x7,
4466 [NEON_2RM_VCLS
] = 0x7,
4467 [NEON_2RM_VCLZ
] = 0x7,
4468 [NEON_2RM_VCNT
] = 0x1,
4469 [NEON_2RM_VMVN
] = 0x1,
4470 [NEON_2RM_VPADAL
] = 0x7,
4471 [NEON_2RM_VPADAL_U
] = 0x7,
4472 [NEON_2RM_VQABS
] = 0x7,
4473 [NEON_2RM_VQNEG
] = 0x7,
4474 [NEON_2RM_VCGT0
] = 0x7,
4475 [NEON_2RM_VCGE0
] = 0x7,
4476 [NEON_2RM_VCEQ0
] = 0x7,
4477 [NEON_2RM_VCLE0
] = 0x7,
4478 [NEON_2RM_VCLT0
] = 0x7,
4479 [NEON_2RM_VABS
] = 0x7,
4480 [NEON_2RM_VNEG
] = 0x7,
4481 [NEON_2RM_VCGT0_F
] = 0x4,
4482 [NEON_2RM_VCGE0_F
] = 0x4,
4483 [NEON_2RM_VCEQ0_F
] = 0x4,
4484 [NEON_2RM_VCLE0_F
] = 0x4,
4485 [NEON_2RM_VCLT0_F
] = 0x4,
4486 [NEON_2RM_VABS_F
] = 0x4,
4487 [NEON_2RM_VNEG_F
] = 0x4,
4488 [NEON_2RM_VSWP
] = 0x1,
4489 [NEON_2RM_VTRN
] = 0x7,
4490 [NEON_2RM_VUZP
] = 0x7,
4491 [NEON_2RM_VZIP
] = 0x7,
4492 [NEON_2RM_VMOVN
] = 0x7,
4493 [NEON_2RM_VQMOVN
] = 0x7,
4494 [NEON_2RM_VSHLL
] = 0x7,
4495 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4496 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4497 [NEON_2RM_VRECPE
] = 0x4,
4498 [NEON_2RM_VRSQRTE
] = 0x4,
4499 [NEON_2RM_VRECPE_F
] = 0x4,
4500 [NEON_2RM_VRSQRTE_F
] = 0x4,
4501 [NEON_2RM_VCVT_FS
] = 0x4,
4502 [NEON_2RM_VCVT_FU
] = 0x4,
4503 [NEON_2RM_VCVT_SF
] = 0x4,
4504 [NEON_2RM_VCVT_UF
] = 0x4,
4507 /* Translate a NEON data processing instruction. Return nonzero if the
4508 instruction is invalid.
4509 We process data in a mixture of 32-bit and 64-bit chunks.
4510 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4512 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4524 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4527 if (!s
->vfp_enabled
)
4529 q
= (insn
& (1 << 6)) != 0;
4530 u
= (insn
>> 24) & 1;
4531 VFP_DREG_D(rd
, insn
);
4532 VFP_DREG_N(rn
, insn
);
4533 VFP_DREG_M(rm
, insn
);
4534 size
= (insn
>> 20) & 3;
4535 if ((insn
& (1 << 23)) == 0) {
4536 /* Three register same length. */
4537 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4538 /* Catch invalid op and bad size combinations: UNDEF */
4539 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4542 /* All insns of this form UNDEF for either this condition or the
4543 * superset of cases "Q==1"; we catch the latter later.
4545 if (q
&& ((rd
| rn
| rm
) & 1)) {
4548 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4549 /* 64-bit element instructions. */
4550 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4551 neon_load_reg64(cpu_V0
, rn
+ pass
);
4552 neon_load_reg64(cpu_V1
, rm
+ pass
);
4556 gen_helper_neon_qadd_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4558 gen_helper_neon_qadd_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4563 gen_helper_neon_qsub_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4565 gen_helper_neon_qsub_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4570 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4572 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4577 gen_helper_neon_qshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4579 gen_helper_neon_qshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4584 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4586 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4589 case NEON_3R_VQRSHL
:
4591 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4593 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4596 case NEON_3R_VADD_VSUB
:
4598 tcg_gen_sub_i64(CPU_V001
);
4600 tcg_gen_add_i64(CPU_V001
);
4606 neon_store_reg64(cpu_V0
, rd
+ pass
);
4615 case NEON_3R_VQRSHL
:
4618 /* Shift instruction operands are reversed. */
4633 case NEON_3R_FLOAT_ARITH
:
4634 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4636 case NEON_3R_FLOAT_MINMAX
:
4637 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4639 case NEON_3R_FLOAT_CMP
:
4641 /* no encoding for U=0 C=1x */
4645 case NEON_3R_FLOAT_ACMP
:
4650 case NEON_3R_VRECPS_VRSQRTS
:
4656 if (u
&& (size
!= 0)) {
4657 /* UNDEF on invalid size for polynomial subcase */
4665 if (pairwise
&& q
) {
4666 /* All the pairwise insns UNDEF if Q is set */
4670 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4675 tmp
= neon_load_reg(rn
, 0);
4676 tmp2
= neon_load_reg(rn
, 1);
4678 tmp
= neon_load_reg(rm
, 0);
4679 tmp2
= neon_load_reg(rm
, 1);
4683 tmp
= neon_load_reg(rn
, pass
);
4684 tmp2
= neon_load_reg(rm
, pass
);
4688 GEN_NEON_INTEGER_OP(hadd
);
4691 GEN_NEON_INTEGER_OP(qadd
);
4693 case NEON_3R_VRHADD
:
4694 GEN_NEON_INTEGER_OP(rhadd
);
4696 case NEON_3R_LOGIC
: /* Logic ops. */
4697 switch ((u
<< 2) | size
) {
4699 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4702 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4705 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4708 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4711 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4714 tmp3
= neon_load_reg(rd
, pass
);
4715 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4716 tcg_temp_free_i32(tmp3
);
4719 tmp3
= neon_load_reg(rd
, pass
);
4720 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4721 tcg_temp_free_i32(tmp3
);
4724 tmp3
= neon_load_reg(rd
, pass
);
4725 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4726 tcg_temp_free_i32(tmp3
);
4731 GEN_NEON_INTEGER_OP(hsub
);
4734 GEN_NEON_INTEGER_OP(qsub
);
4737 GEN_NEON_INTEGER_OP(cgt
);
4740 GEN_NEON_INTEGER_OP(cge
);
4743 GEN_NEON_INTEGER_OP(shl
);
4746 GEN_NEON_INTEGER_OP(qshl
);
4749 GEN_NEON_INTEGER_OP(rshl
);
4751 case NEON_3R_VQRSHL
:
4752 GEN_NEON_INTEGER_OP(qrshl
);
4755 GEN_NEON_INTEGER_OP(max
);
4758 GEN_NEON_INTEGER_OP(min
);
4761 GEN_NEON_INTEGER_OP(abd
);
4764 GEN_NEON_INTEGER_OP(abd
);
4765 tcg_temp_free_i32(tmp2
);
4766 tmp2
= neon_load_reg(rd
, pass
);
4767 gen_neon_add(size
, tmp
, tmp2
);
4769 case NEON_3R_VADD_VSUB
:
4770 if (!u
) { /* VADD */
4771 gen_neon_add(size
, tmp
, tmp2
);
4774 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4775 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4776 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4781 case NEON_3R_VTST_VCEQ
:
4782 if (!u
) { /* VTST */
4784 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4785 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4786 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4791 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4792 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4793 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4798 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4800 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4801 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4802 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4805 tcg_temp_free_i32(tmp2
);
4806 tmp2
= neon_load_reg(rd
, pass
);
4808 gen_neon_rsb(size
, tmp
, tmp2
);
4810 gen_neon_add(size
, tmp
, tmp2
);
4814 if (u
) { /* polynomial */
4815 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4816 } else { /* Integer */
4818 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4819 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4820 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4826 GEN_NEON_INTEGER_OP(pmax
);
4829 GEN_NEON_INTEGER_OP(pmin
);
4831 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4832 if (!u
) { /* VQDMULH */
4834 case 1: gen_helper_neon_qdmulh_s16(tmp
, tmp
, tmp2
); break;
4835 case 2: gen_helper_neon_qdmulh_s32(tmp
, tmp
, tmp2
); break;
4838 } else { /* VQRDMULH */
4840 case 1: gen_helper_neon_qrdmulh_s16(tmp
, tmp
, tmp2
); break;
4841 case 2: gen_helper_neon_qrdmulh_s32(tmp
, tmp
, tmp2
); break;
4848 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4849 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4850 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4854 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4855 switch ((u
<< 2) | size
) {
4857 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4860 gen_helper_neon_sub_f32(tmp
, tmp
, tmp2
);
4863 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4866 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
);
4872 case NEON_3R_FLOAT_MULTIPLY
:
4873 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
4875 tcg_temp_free_i32(tmp2
);
4876 tmp2
= neon_load_reg(rd
, pass
);
4878 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
4880 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
4884 case NEON_3R_FLOAT_CMP
:
4886 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
4889 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
4891 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
4894 case NEON_3R_FLOAT_ACMP
:
4896 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
);
4898 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
);
4900 case NEON_3R_FLOAT_MINMAX
:
4902 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
);
4904 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
);
4906 case NEON_3R_VRECPS_VRSQRTS
:
4908 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4910 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4915 tcg_temp_free_i32(tmp2
);
4917 /* Save the result. For elementwise operations we can put it
4918 straight into the destination register. For pairwise operations
4919 we have to be careful to avoid clobbering the source operands. */
4920 if (pairwise
&& rd
== rm
) {
4921 neon_store_scratch(pass
, tmp
);
4923 neon_store_reg(rd
, pass
, tmp
);
4927 if (pairwise
&& rd
== rm
) {
4928 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4929 tmp
= neon_load_scratch(pass
);
4930 neon_store_reg(rd
, pass
, tmp
);
4933 /* End of 3 register same size operations. */
4934 } else if (insn
& (1 << 4)) {
4935 if ((insn
& 0x00380080) != 0) {
4936 /* Two registers and shift. */
4937 op
= (insn
>> 8) & 0xf;
4938 if (insn
& (1 << 7)) {
4946 while ((insn
& (1 << (size
+ 19))) == 0)
4949 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4950 /* To avoid excessive dumplication of ops we implement shift
4951 by immediate using the variable shift operations. */
4953 /* Shift by immediate:
4954 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4955 if (q
&& ((rd
| rm
) & 1)) {
4958 if (!u
&& (op
== 4 || op
== 6)) {
4961 /* Right shifts are encoded as N - shift, where N is the
4962 element size in bits. */
4964 shift
= shift
- (1 << (size
+ 3));
4972 imm
= (uint8_t) shift
;
4977 imm
= (uint16_t) shift
;
4988 for (pass
= 0; pass
< count
; pass
++) {
4990 neon_load_reg64(cpu_V0
, rm
+ pass
);
4991 tcg_gen_movi_i64(cpu_V1
, imm
);
4996 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4998 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5003 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5005 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5008 case 5: /* VSHL, VSLI */
5009 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5011 case 6: /* VQSHLU */
5012 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5016 gen_helper_neon_qshl_u64(cpu_V0
,
5019 gen_helper_neon_qshl_s64(cpu_V0
,
5024 if (op
== 1 || op
== 3) {
5026 neon_load_reg64(cpu_V1
, rd
+ pass
);
5027 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5028 } else if (op
== 4 || (op
== 5 && u
)) {
5030 neon_load_reg64(cpu_V1
, rd
+ pass
);
5032 if (shift
< -63 || shift
> 63) {
5036 mask
= 0xffffffffffffffffull
>> -shift
;
5038 mask
= 0xffffffffffffffffull
<< shift
;
5041 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5042 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5044 neon_store_reg64(cpu_V0
, rd
+ pass
);
5045 } else { /* size < 3 */
5046 /* Operands in T0 and T1. */
5047 tmp
= neon_load_reg(rm
, pass
);
5048 tmp2
= tcg_temp_new_i32();
5049 tcg_gen_movi_i32(tmp2
, imm
);
5053 GEN_NEON_INTEGER_OP(shl
);
5057 GEN_NEON_INTEGER_OP(rshl
);
5060 case 5: /* VSHL, VSLI */
5062 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5063 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5064 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5068 case 6: /* VQSHLU */
5071 gen_helper_neon_qshlu_s8(tmp
, tmp
, tmp2
);
5074 gen_helper_neon_qshlu_s16(tmp
, tmp
, tmp2
);
5077 gen_helper_neon_qshlu_s32(tmp
, tmp
, tmp2
);
5084 GEN_NEON_INTEGER_OP(qshl
);
5087 tcg_temp_free_i32(tmp2
);
5089 if (op
== 1 || op
== 3) {
5091 tmp2
= neon_load_reg(rd
, pass
);
5092 gen_neon_add(size
, tmp
, tmp2
);
5093 tcg_temp_free_i32(tmp2
);
5094 } else if (op
== 4 || (op
== 5 && u
)) {
5099 mask
= 0xff >> -shift
;
5101 mask
= (uint8_t)(0xff << shift
);
5107 mask
= 0xffff >> -shift
;
5109 mask
= (uint16_t)(0xffff << shift
);
5113 if (shift
< -31 || shift
> 31) {
5117 mask
= 0xffffffffu
>> -shift
;
5119 mask
= 0xffffffffu
<< shift
;
5125 tmp2
= neon_load_reg(rd
, pass
);
5126 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5127 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5128 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5129 tcg_temp_free_i32(tmp2
);
5131 neon_store_reg(rd
, pass
, tmp
);
5134 } else if (op
< 10) {
5135 /* Shift by immediate and narrow:
5136 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5137 int input_unsigned
= (op
== 8) ? !u
: u
;
5141 shift
= shift
- (1 << (size
+ 3));
5144 tmp64
= tcg_const_i64(shift
);
5145 neon_load_reg64(cpu_V0
, rm
);
5146 neon_load_reg64(cpu_V1
, rm
+ 1);
5147 for (pass
= 0; pass
< 2; pass
++) {
5155 if (input_unsigned
) {
5156 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5158 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5161 if (input_unsigned
) {
5162 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5164 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5167 tmp
= tcg_temp_new_i32();
5168 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5169 neon_store_reg(rd
, pass
, tmp
);
5171 tcg_temp_free_i64(tmp64
);
5174 imm
= (uint16_t)shift
;
5178 imm
= (uint32_t)shift
;
5180 tmp2
= tcg_const_i32(imm
);
5181 tmp4
= neon_load_reg(rm
+ 1, 0);
5182 tmp5
= neon_load_reg(rm
+ 1, 1);
5183 for (pass
= 0; pass
< 2; pass
++) {
5185 tmp
= neon_load_reg(rm
, 0);
5189 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5192 tmp3
= neon_load_reg(rm
, 1);
5196 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5198 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5199 tcg_temp_free_i32(tmp
);
5200 tcg_temp_free_i32(tmp3
);
5201 tmp
= tcg_temp_new_i32();
5202 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5203 neon_store_reg(rd
, pass
, tmp
);
5205 tcg_temp_free_i32(tmp2
);
5207 } else if (op
== 10) {
5209 if (q
|| (rd
& 1)) {
5212 tmp
= neon_load_reg(rm
, 0);
5213 tmp2
= neon_load_reg(rm
, 1);
5214 for (pass
= 0; pass
< 2; pass
++) {
5218 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5221 /* The shift is less than the width of the source
5222 type, so we can just shift the whole register. */
5223 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5224 /* Widen the result of shift: we need to clear
5225 * the potential overflow bits resulting from
5226 * left bits of the narrow input appearing as
5227 * right bits of left the neighbour narrow
5229 if (size
< 2 || !u
) {
5232 imm
= (0xffu
>> (8 - shift
));
5234 } else if (size
== 1) {
5235 imm
= 0xffff >> (16 - shift
);
5238 imm
= 0xffffffff >> (32 - shift
);
5241 imm64
= imm
| (((uint64_t)imm
) << 32);
5245 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5248 neon_store_reg64(cpu_V0
, rd
+ pass
);
5250 } else if (op
>= 14) {
5251 /* VCVT fixed-point. */
5252 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5255 /* We have already masked out the must-be-1 top bit of imm6,
5256 * hence this 32-shift where the ARM ARM has 64-imm6.
5259 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5260 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5263 gen_vfp_ulto(0, shift
, 1);
5265 gen_vfp_slto(0, shift
, 1);
5268 gen_vfp_toul(0, shift
, 1);
5270 gen_vfp_tosl(0, shift
, 1);
5272 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5277 } else { /* (insn & 0x00380080) == 0 */
5279 if (q
&& (rd
& 1)) {
5283 op
= (insn
>> 8) & 0xf;
5284 /* One register and immediate. */
5285 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5286 invert
= (insn
& (1 << 5)) != 0;
5287 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5288 * We choose to not special-case this and will behave as if a
5289 * valid constant encoding of 0 had been given.
5308 imm
= (imm
<< 8) | (imm
<< 24);
5311 imm
= (imm
<< 8) | 0xff;
5314 imm
= (imm
<< 16) | 0xffff;
5317 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5325 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5326 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5332 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5333 if (op
& 1 && op
< 12) {
5334 tmp
= neon_load_reg(rd
, pass
);
5336 /* The immediate value has already been inverted, so
5338 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5340 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5344 tmp
= tcg_temp_new_i32();
5345 if (op
== 14 && invert
) {
5349 for (n
= 0; n
< 4; n
++) {
5350 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5351 val
|= 0xff << (n
* 8);
5353 tcg_gen_movi_i32(tmp
, val
);
5355 tcg_gen_movi_i32(tmp
, imm
);
5358 neon_store_reg(rd
, pass
, tmp
);
5361 } else { /* (insn & 0x00800010 == 0x00800000) */
5363 op
= (insn
>> 8) & 0xf;
5364 if ((insn
& (1 << 6)) == 0) {
5365 /* Three registers of different lengths. */
5369 /* undefreq: bit 0 : UNDEF if size != 0
5370 * bit 1 : UNDEF if size == 0
5371 * bit 2 : UNDEF if U == 1
5372 * Note that [1:0] set implies 'always UNDEF'
5375 /* prewiden, src1_wide, src2_wide, undefreq */
5376 static const int neon_3reg_wide
[16][4] = {
5377 {1, 0, 0, 0}, /* VADDL */
5378 {1, 1, 0, 0}, /* VADDW */
5379 {1, 0, 0, 0}, /* VSUBL */
5380 {1, 1, 0, 0}, /* VSUBW */
5381 {0, 1, 1, 0}, /* VADDHN */
5382 {0, 0, 0, 0}, /* VABAL */
5383 {0, 1, 1, 0}, /* VSUBHN */
5384 {0, 0, 0, 0}, /* VABDL */
5385 {0, 0, 0, 0}, /* VMLAL */
5386 {0, 0, 0, 6}, /* VQDMLAL */
5387 {0, 0, 0, 0}, /* VMLSL */
5388 {0, 0, 0, 6}, /* VQDMLSL */
5389 {0, 0, 0, 0}, /* Integer VMULL */
5390 {0, 0, 0, 2}, /* VQDMULL */
5391 {0, 0, 0, 5}, /* Polynomial VMULL */
5392 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5395 prewiden
= neon_3reg_wide
[op
][0];
5396 src1_wide
= neon_3reg_wide
[op
][1];
5397 src2_wide
= neon_3reg_wide
[op
][2];
5398 undefreq
= neon_3reg_wide
[op
][3];
5400 if (((undefreq
& 1) && (size
!= 0)) ||
5401 ((undefreq
& 2) && (size
== 0)) ||
5402 ((undefreq
& 4) && u
)) {
5405 if ((src1_wide
&& (rn
& 1)) ||
5406 (src2_wide
&& (rm
& 1)) ||
5407 (!src2_wide
&& (rd
& 1))) {
5411 /* Avoid overlapping operands. Wide source operands are
5412 always aligned so will never overlap with wide
5413 destinations in problematic ways. */
5414 if (rd
== rm
&& !src2_wide
) {
5415 tmp
= neon_load_reg(rm
, 1);
5416 neon_store_scratch(2, tmp
);
5417 } else if (rd
== rn
&& !src1_wide
) {
5418 tmp
= neon_load_reg(rn
, 1);
5419 neon_store_scratch(2, tmp
);
5422 for (pass
= 0; pass
< 2; pass
++) {
5424 neon_load_reg64(cpu_V0
, rn
+ pass
);
5427 if (pass
== 1 && rd
== rn
) {
5428 tmp
= neon_load_scratch(2);
5430 tmp
= neon_load_reg(rn
, pass
);
5433 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5437 neon_load_reg64(cpu_V1
, rm
+ pass
);
5440 if (pass
== 1 && rd
== rm
) {
5441 tmp2
= neon_load_scratch(2);
5443 tmp2
= neon_load_reg(rm
, pass
);
5446 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5450 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5451 gen_neon_addl(size
);
5453 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5454 gen_neon_subl(size
);
5456 case 5: case 7: /* VABAL, VABDL */
5457 switch ((size
<< 1) | u
) {
5459 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5462 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5465 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5468 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5471 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5474 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5478 tcg_temp_free_i32(tmp2
);
5479 tcg_temp_free_i32(tmp
);
5481 case 8: case 9: case 10: case 11: case 12: case 13:
5482 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5483 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5485 case 14: /* Polynomial VMULL */
5486 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5487 tcg_temp_free_i32(tmp2
);
5488 tcg_temp_free_i32(tmp
);
5490 default: /* 15 is RESERVED: caught earlier */
5495 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5496 neon_store_reg64(cpu_V0
, rd
+ pass
);
5497 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5499 neon_load_reg64(cpu_V1
, rd
+ pass
);
5501 case 10: /* VMLSL */
5502 gen_neon_negl(cpu_V0
, size
);
5504 case 5: case 8: /* VABAL, VMLAL */
5505 gen_neon_addl(size
);
5507 case 9: case 11: /* VQDMLAL, VQDMLSL */
5508 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5510 gen_neon_negl(cpu_V0
, size
);
5512 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5517 neon_store_reg64(cpu_V0
, rd
+ pass
);
5518 } else if (op
== 4 || op
== 6) {
5519 /* Narrowing operation. */
5520 tmp
= tcg_temp_new_i32();
5524 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5527 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5530 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5531 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5538 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5541 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5544 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5545 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5546 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5554 neon_store_reg(rd
, 0, tmp3
);
5555 neon_store_reg(rd
, 1, tmp
);
5558 /* Write back the result. */
5559 neon_store_reg64(cpu_V0
, rd
+ pass
);
5563 /* Two registers and a scalar. NB that for ops of this form
5564 * the ARM ARM labels bit 24 as Q, but it is in our variable
5571 case 1: /* Float VMLA scalar */
5572 case 5: /* Floating point VMLS scalar */
5573 case 9: /* Floating point VMUL scalar */
5578 case 0: /* Integer VMLA scalar */
5579 case 4: /* Integer VMLS scalar */
5580 case 8: /* Integer VMUL scalar */
5581 case 12: /* VQDMULH scalar */
5582 case 13: /* VQRDMULH scalar */
5583 if (u
&& ((rd
| rn
) & 1)) {
5586 tmp
= neon_get_scalar(size
, rm
);
5587 neon_store_scratch(0, tmp
);
5588 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5589 tmp
= neon_load_scratch(0);
5590 tmp2
= neon_load_reg(rn
, pass
);
5593 gen_helper_neon_qdmulh_s16(tmp
, tmp
, tmp2
);
5595 gen_helper_neon_qdmulh_s32(tmp
, tmp
, tmp2
);
5597 } else if (op
== 13) {
5599 gen_helper_neon_qrdmulh_s16(tmp
, tmp
, tmp2
);
5601 gen_helper_neon_qrdmulh_s32(tmp
, tmp
, tmp2
);
5603 } else if (op
& 1) {
5604 gen_helper_neon_mul_f32(tmp
, tmp
, tmp2
);
5607 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5608 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5609 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5613 tcg_temp_free_i32(tmp2
);
5616 tmp2
= neon_load_reg(rd
, pass
);
5619 gen_neon_add(size
, tmp
, tmp2
);
5622 gen_helper_neon_add_f32(tmp
, tmp
, tmp2
);
5625 gen_neon_rsb(size
, tmp
, tmp2
);
5628 gen_helper_neon_sub_f32(tmp
, tmp2
, tmp
);
5633 tcg_temp_free_i32(tmp2
);
5635 neon_store_reg(rd
, pass
, tmp
);
5638 case 3: /* VQDMLAL scalar */
5639 case 7: /* VQDMLSL scalar */
5640 case 11: /* VQDMULL scalar */
5645 case 2: /* VMLAL sclar */
5646 case 6: /* VMLSL scalar */
5647 case 10: /* VMULL scalar */
5651 tmp2
= neon_get_scalar(size
, rm
);
5652 /* We need a copy of tmp2 because gen_neon_mull
5653 * deletes it during pass 0. */
5654 tmp4
= tcg_temp_new_i32();
5655 tcg_gen_mov_i32(tmp4
, tmp2
);
5656 tmp3
= neon_load_reg(rn
, 1);
5658 for (pass
= 0; pass
< 2; pass
++) {
5660 tmp
= neon_load_reg(rn
, 0);
5665 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5667 neon_load_reg64(cpu_V1
, rd
+ pass
);
5671 gen_neon_negl(cpu_V0
, size
);
5674 gen_neon_addl(size
);
5677 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5679 gen_neon_negl(cpu_V0
, size
);
5681 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5687 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5692 neon_store_reg64(cpu_V0
, rd
+ pass
);
5697 default: /* 14 and 15 are RESERVED */
5701 } else { /* size == 3 */
5704 imm
= (insn
>> 8) & 0xf;
5709 if (q
&& ((rd
| rn
| rm
) & 1)) {
5714 neon_load_reg64(cpu_V0
, rn
);
5716 neon_load_reg64(cpu_V1
, rn
+ 1);
5718 } else if (imm
== 8) {
5719 neon_load_reg64(cpu_V0
, rn
+ 1);
5721 neon_load_reg64(cpu_V1
, rm
);
5724 tmp64
= tcg_temp_new_i64();
5726 neon_load_reg64(cpu_V0
, rn
);
5727 neon_load_reg64(tmp64
, rn
+ 1);
5729 neon_load_reg64(cpu_V0
, rn
+ 1);
5730 neon_load_reg64(tmp64
, rm
);
5732 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5733 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5734 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5736 neon_load_reg64(cpu_V1
, rm
);
5738 neon_load_reg64(cpu_V1
, rm
+ 1);
5741 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5742 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5743 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5744 tcg_temp_free_i64(tmp64
);
5747 neon_load_reg64(cpu_V0
, rn
);
5748 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5749 neon_load_reg64(cpu_V1
, rm
);
5750 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5751 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5753 neon_store_reg64(cpu_V0
, rd
);
5755 neon_store_reg64(cpu_V1
, rd
+ 1);
5757 } else if ((insn
& (1 << 11)) == 0) {
5758 /* Two register misc. */
5759 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5760 size
= (insn
>> 18) & 3;
5761 /* UNDEF for unknown op values and bad op-size combinations */
5762 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5765 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5766 q
&& ((rm
| rd
) & 1)) {
5770 case NEON_2RM_VREV64
:
5771 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5772 tmp
= neon_load_reg(rm
, pass
* 2);
5773 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5775 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5776 case 1: gen_swap_half(tmp
); break;
5777 case 2: /* no-op */ break;
5780 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5782 neon_store_reg(rd
, pass
* 2, tmp2
);
5785 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5786 case 1: gen_swap_half(tmp2
); break;
5789 neon_store_reg(rd
, pass
* 2, tmp2
);
5793 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5794 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5795 for (pass
= 0; pass
< q
+ 1; pass
++) {
5796 tmp
= neon_load_reg(rm
, pass
* 2);
5797 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5798 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5799 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5801 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5802 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5803 case 2: tcg_gen_add_i64(CPU_V001
); break;
5806 if (op
>= NEON_2RM_VPADAL
) {
5808 neon_load_reg64(cpu_V1
, rd
+ pass
);
5809 gen_neon_addl(size
);
5811 neon_store_reg64(cpu_V0
, rd
+ pass
);
5817 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5818 tmp
= neon_load_reg(rm
, n
);
5819 tmp2
= neon_load_reg(rd
, n
+ 1);
5820 neon_store_reg(rm
, n
, tmp2
);
5821 neon_store_reg(rd
, n
+ 1, tmp
);
5828 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5833 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5837 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5838 /* also VQMOVUN; op field and mnemonics don't line up */
5843 for (pass
= 0; pass
< 2; pass
++) {
5844 neon_load_reg64(cpu_V0
, rm
+ pass
);
5845 tmp
= tcg_temp_new_i32();
5846 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5851 neon_store_reg(rd
, 0, tmp2
);
5852 neon_store_reg(rd
, 1, tmp
);
5856 case NEON_2RM_VSHLL
:
5857 if (q
|| (rd
& 1)) {
5860 tmp
= neon_load_reg(rm
, 0);
5861 tmp2
= neon_load_reg(rm
, 1);
5862 for (pass
= 0; pass
< 2; pass
++) {
5865 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5866 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5867 neon_store_reg64(cpu_V0
, rd
+ pass
);
5870 case NEON_2RM_VCVT_F16_F32
:
5871 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5875 tmp
= tcg_temp_new_i32();
5876 tmp2
= tcg_temp_new_i32();
5877 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5878 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5879 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5880 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5881 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5882 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5883 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5884 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5885 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5886 neon_store_reg(rd
, 0, tmp2
);
5887 tmp2
= tcg_temp_new_i32();
5888 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5889 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5890 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5891 neon_store_reg(rd
, 1, tmp2
);
5892 tcg_temp_free_i32(tmp
);
5894 case NEON_2RM_VCVT_F32_F16
:
5895 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5899 tmp3
= tcg_temp_new_i32();
5900 tmp
= neon_load_reg(rm
, 0);
5901 tmp2
= neon_load_reg(rm
, 1);
5902 tcg_gen_ext16u_i32(tmp3
, tmp
);
5903 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5904 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5905 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5906 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5907 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5908 tcg_temp_free_i32(tmp
);
5909 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5910 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5911 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5912 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5913 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5914 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5915 tcg_temp_free_i32(tmp2
);
5916 tcg_temp_free_i32(tmp3
);
5920 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5921 if (neon_2rm_is_float_op(op
)) {
5922 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5923 neon_reg_offset(rm
, pass
));
5926 tmp
= neon_load_reg(rm
, pass
);
5929 case NEON_2RM_VREV32
:
5931 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5932 case 1: gen_swap_half(tmp
); break;
5936 case NEON_2RM_VREV16
:
5941 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5942 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5943 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5949 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5950 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5951 case 2: gen_helper_clz(tmp
, tmp
); break;
5956 gen_helper_neon_cnt_u8(tmp
, tmp
);
5959 tcg_gen_not_i32(tmp
, tmp
);
5961 case NEON_2RM_VQABS
:
5963 case 0: gen_helper_neon_qabs_s8(tmp
, tmp
); break;
5964 case 1: gen_helper_neon_qabs_s16(tmp
, tmp
); break;
5965 case 2: gen_helper_neon_qabs_s32(tmp
, tmp
); break;
5969 case NEON_2RM_VQNEG
:
5971 case 0: gen_helper_neon_qneg_s8(tmp
, tmp
); break;
5972 case 1: gen_helper_neon_qneg_s16(tmp
, tmp
); break;
5973 case 2: gen_helper_neon_qneg_s32(tmp
, tmp
); break;
5977 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
5978 tmp2
= tcg_const_i32(0);
5980 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5981 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5982 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
5985 tcg_temp_free(tmp2
);
5986 if (op
== NEON_2RM_VCLE0
) {
5987 tcg_gen_not_i32(tmp
, tmp
);
5990 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
5991 tmp2
= tcg_const_i32(0);
5993 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
5994 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
5995 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
5998 tcg_temp_free(tmp2
);
5999 if (op
== NEON_2RM_VCLT0
) {
6000 tcg_gen_not_i32(tmp
, tmp
);
6003 case NEON_2RM_VCEQ0
:
6004 tmp2
= tcg_const_i32(0);
6006 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6007 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6008 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6011 tcg_temp_free(tmp2
);
6015 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6016 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6017 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6022 tmp2
= tcg_const_i32(0);
6023 gen_neon_rsb(size
, tmp
, tmp2
);
6024 tcg_temp_free(tmp2
);
6026 case NEON_2RM_VCGT0_F
:
6027 tmp2
= tcg_const_i32(0);
6028 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
);
6029 tcg_temp_free(tmp2
);
6031 case NEON_2RM_VCGE0_F
:
6032 tmp2
= tcg_const_i32(0);
6033 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
);
6034 tcg_temp_free(tmp2
);
6036 case NEON_2RM_VCEQ0_F
:
6037 tmp2
= tcg_const_i32(0);
6038 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
);
6039 tcg_temp_free(tmp2
);
6041 case NEON_2RM_VCLE0_F
:
6042 tmp2
= tcg_const_i32(0);
6043 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
);
6044 tcg_temp_free(tmp2
);
6046 case NEON_2RM_VCLT0_F
:
6047 tmp2
= tcg_const_i32(0);
6048 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
);
6049 tcg_temp_free(tmp2
);
6051 case NEON_2RM_VABS_F
:
6054 case NEON_2RM_VNEG_F
:
6058 tmp2
= neon_load_reg(rd
, pass
);
6059 neon_store_reg(rm
, pass
, tmp2
);
6062 tmp2
= neon_load_reg(rd
, pass
);
6064 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6065 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6068 neon_store_reg(rm
, pass
, tmp2
);
6070 case NEON_2RM_VRECPE
:
6071 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6073 case NEON_2RM_VRSQRTE
:
6074 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6076 case NEON_2RM_VRECPE_F
:
6077 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6079 case NEON_2RM_VRSQRTE_F
:
6080 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6082 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6085 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6088 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6089 gen_vfp_tosiz(0, 1);
6091 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6092 gen_vfp_touiz(0, 1);
6095 /* Reserved op values were caught by the
6096 * neon_2rm_sizes[] check earlier.
6100 if (neon_2rm_is_float_op(op
)) {
6101 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6102 neon_reg_offset(rd
, pass
));
6104 neon_store_reg(rd
, pass
, tmp
);
6109 } else if ((insn
& (1 << 10)) == 0) {
6111 int n
= ((insn
>> 8) & 3) + 1;
6112 if ((rn
+ n
) > 32) {
6113 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6114 * helper function running off the end of the register file.
6119 if (insn
& (1 << 6)) {
6120 tmp
= neon_load_reg(rd
, 0);
6122 tmp
= tcg_temp_new_i32();
6123 tcg_gen_movi_i32(tmp
, 0);
6125 tmp2
= neon_load_reg(rm
, 0);
6126 tmp4
= tcg_const_i32(rn
);
6127 tmp5
= tcg_const_i32(n
);
6128 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
6129 tcg_temp_free_i32(tmp
);
6130 if (insn
& (1 << 6)) {
6131 tmp
= neon_load_reg(rd
, 1);
6133 tmp
= tcg_temp_new_i32();
6134 tcg_gen_movi_i32(tmp
, 0);
6136 tmp3
= neon_load_reg(rm
, 1);
6137 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
6138 tcg_temp_free_i32(tmp5
);
6139 tcg_temp_free_i32(tmp4
);
6140 neon_store_reg(rd
, 0, tmp2
);
6141 neon_store_reg(rd
, 1, tmp3
);
6142 tcg_temp_free_i32(tmp
);
6143 } else if ((insn
& 0x380) == 0) {
6145 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6148 if (insn
& (1 << 19)) {
6149 tmp
= neon_load_reg(rm
, 1);
6151 tmp
= neon_load_reg(rm
, 0);
6153 if (insn
& (1 << 16)) {
6154 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6155 } else if (insn
& (1 << 17)) {
6156 if ((insn
>> 18) & 1)
6157 gen_neon_dup_high16(tmp
);
6159 gen_neon_dup_low16(tmp
);
6161 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6162 tmp2
= tcg_temp_new_i32();
6163 tcg_gen_mov_i32(tmp2
, tmp
);
6164 neon_store_reg(rd
, pass
, tmp2
);
6166 tcg_temp_free_i32(tmp
);
6175 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6177 int crn
= (insn
>> 16) & 0xf;
6178 int crm
= insn
& 0xf;
6179 int op1
= (insn
>> 21) & 7;
6180 int op2
= (insn
>> 5) & 7;
6181 int rt
= (insn
>> 12) & 0xf;
6184 /* Minimal set of debug registers, since we don't support debug */
6185 if (op1
== 0 && crn
== 0 && op2
== 0) {
6188 /* DBGDIDR: just RAZ. In particular this means the
6189 * "debug architecture version" bits will read as
6190 * a reserved value, which should cause Linux to
6191 * not try to use the debug hardware.
6193 tmp
= tcg_const_i32(0);
6194 store_reg(s
, rt
, tmp
);
6198 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
6199 * don't implement memory mapped debug components
6201 if (ENABLE_ARCH_7
) {
6202 tmp
= tcg_const_i32(0);
6203 store_reg(s
, rt
, tmp
);
6212 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6213 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6217 tmp
= load_cpu_field(teecr
);
6218 store_reg(s
, rt
, tmp
);
6221 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6223 if (IS_USER(s
) && (env
->teecr
& 1))
6225 tmp
= load_cpu_field(teehbr
);
6226 store_reg(s
, rt
, tmp
);
6230 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
6231 op1
, crn
, crm
, op2
);
6235 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6237 int crn
= (insn
>> 16) & 0xf;
6238 int crm
= insn
& 0xf;
6239 int op1
= (insn
>> 21) & 7;
6240 int op2
= (insn
>> 5) & 7;
6241 int rt
= (insn
>> 12) & 0xf;
6244 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6245 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6249 tmp
= load_reg(s
, rt
);
6250 gen_helper_set_teecr(cpu_env
, tmp
);
6251 tcg_temp_free_i32(tmp
);
6254 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6256 if (IS_USER(s
) && (env
->teecr
& 1))
6258 tmp
= load_reg(s
, rt
);
6259 store_cpu_field(tmp
, teehbr
);
6263 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
6264 op1
, crn
, crm
, op2
);
6268 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6272 cpnum
= (insn
>> 8) & 0xf;
6273 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6274 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6280 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6281 return disas_iwmmxt_insn(env
, s
, insn
);
6282 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6283 return disas_dsp_insn(env
, s
, insn
);
6288 return disas_vfp_insn (env
, s
, insn
);
6290 /* Coprocessors 7-15 are architecturally reserved by ARM.
6291 Unfortunately Intel decided to ignore this. */
6292 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
6294 if (insn
& (1 << 20))
6295 return disas_cp14_read(env
, s
, insn
);
6297 return disas_cp14_write(env
, s
, insn
);
6299 return disas_cp15_insn (env
, s
, insn
);
6302 /* Unknown coprocessor. See if the board has hooked it. */
6303 return disas_cp_insn (env
, s
, insn
);
6308 /* Store a 64-bit value to a register pair. Clobbers val. */
6309 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6312 tmp
= tcg_temp_new_i32();
6313 tcg_gen_trunc_i64_i32(tmp
, val
);
6314 store_reg(s
, rlow
, tmp
);
6315 tmp
= tcg_temp_new_i32();
6316 tcg_gen_shri_i64(val
, val
, 32);
6317 tcg_gen_trunc_i64_i32(tmp
, val
);
6318 store_reg(s
, rhigh
, tmp
);
6321 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6322 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6327 /* Load value and extend to 64 bits. */
6328 tmp
= tcg_temp_new_i64();
6329 tmp2
= load_reg(s
, rlow
);
6330 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6331 tcg_temp_free_i32(tmp2
);
6332 tcg_gen_add_i64(val
, val
, tmp
);
6333 tcg_temp_free_i64(tmp
);
6336 /* load and add a 64-bit value from a register pair. */
6337 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6343 /* Load 64-bit value rd:rn. */
6344 tmpl
= load_reg(s
, rlow
);
6345 tmph
= load_reg(s
, rhigh
);
6346 tmp
= tcg_temp_new_i64();
6347 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6348 tcg_temp_free_i32(tmpl
);
6349 tcg_temp_free_i32(tmph
);
6350 tcg_gen_add_i64(val
, val
, tmp
);
6351 tcg_temp_free_i64(tmp
);
6354 /* Set N and Z flags from a 64-bit value. */
6355 static void gen_logicq_cc(TCGv_i64 val
)
6357 TCGv tmp
= tcg_temp_new_i32();
6358 gen_helper_logicq_cc(tmp
, val
);
6360 tcg_temp_free_i32(tmp
);
6363 /* Load/Store exclusive instructions are implemented by remembering
6364 the value/address loaded, and seeing if these are the same
6365 when the store is performed. This should be is sufficient to implement
6366 the architecturally mandated semantics, and avoids having to monitor
6369 In system emulation mode only one CPU will be running at once, so
6370 this sequence is effectively atomic. In user emulation mode we
6371 throw an exception and handle the atomic operation elsewhere. */
6372 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6373 TCGv addr
, int size
)
6379 tmp
= gen_ld8u(addr
, IS_USER(s
));
6382 tmp
= gen_ld16u(addr
, IS_USER(s
));
6386 tmp
= gen_ld32(addr
, IS_USER(s
));
6391 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6392 store_reg(s
, rt
, tmp
);
6394 TCGv tmp2
= tcg_temp_new_i32();
6395 tcg_gen_addi_i32(tmp2
, addr
, 4);
6396 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6397 tcg_temp_free_i32(tmp2
);
6398 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6399 store_reg(s
, rt2
, tmp
);
6401 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6404 static void gen_clrex(DisasContext
*s
)
6406 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6409 #ifdef CONFIG_USER_ONLY
6410 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6411 TCGv addr
, int size
)
6413 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6414 tcg_gen_movi_i32(cpu_exclusive_info
,
6415 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6416 gen_exception_insn(s
, 4, EXCP_STREX
);
6419 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6420 TCGv addr
, int size
)
6426 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6432 fail_label
= gen_new_label();
6433 done_label
= gen_new_label();
6434 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6437 tmp
= gen_ld8u(addr
, IS_USER(s
));
6440 tmp
= gen_ld16u(addr
, IS_USER(s
));
6444 tmp
= gen_ld32(addr
, IS_USER(s
));
6449 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6450 tcg_temp_free_i32(tmp
);
6452 TCGv tmp2
= tcg_temp_new_i32();
6453 tcg_gen_addi_i32(tmp2
, addr
, 4);
6454 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6455 tcg_temp_free_i32(tmp2
);
6456 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6457 tcg_temp_free_i32(tmp
);
6459 tmp
= load_reg(s
, rt
);
6462 gen_st8(tmp
, addr
, IS_USER(s
));
6465 gen_st16(tmp
, addr
, IS_USER(s
));
6469 gen_st32(tmp
, addr
, IS_USER(s
));
6475 tcg_gen_addi_i32(addr
, addr
, 4);
6476 tmp
= load_reg(s
, rt2
);
6477 gen_st32(tmp
, addr
, IS_USER(s
));
6479 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6480 tcg_gen_br(done_label
);
6481 gen_set_label(fail_label
);
6482 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6483 gen_set_label(done_label
);
6484 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6488 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
6490 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6497 insn
= ldl_code(s
->pc
);
6500 /* M variants do not implement ARM mode. */
6505 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6506 * choose to UNDEF. In ARMv5 and above the space is used
6507 * for miscellaneous unconditional instructions.
6511 /* Unconditional instructions. */
6512 if (((insn
>> 25) & 7) == 1) {
6513 /* NEON Data processing. */
6514 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6517 if (disas_neon_data_insn(env
, s
, insn
))
6521 if ((insn
& 0x0f100000) == 0x04000000) {
6522 /* NEON load/store. */
6523 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6526 if (disas_neon_ls_insn(env
, s
, insn
))
6530 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6531 ((insn
& 0x0f30f010) == 0x0710f000)) {
6532 if ((insn
& (1 << 22)) == 0) {
6534 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6538 /* Otherwise PLD; v5TE+ */
6542 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6543 ((insn
& 0x0f70f010) == 0x0650f000)) {
6545 return; /* PLI; V7 */
6547 if (((insn
& 0x0f700000) == 0x04100000) ||
6548 ((insn
& 0x0f700010) == 0x06100000)) {
6549 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6552 return; /* v7MP: Unallocated memory hint: must NOP */
6555 if ((insn
& 0x0ffffdff) == 0x01010000) {
6558 if (insn
& (1 << 9)) {
6559 /* BE8 mode not implemented. */
6563 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6564 switch ((insn
>> 4) & 0xf) {
6573 /* We don't emulate caches so these are a no-op. */
6578 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6584 op1
= (insn
& 0x1f);
6585 addr
= tcg_temp_new_i32();
6586 tmp
= tcg_const_i32(op1
);
6587 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6588 tcg_temp_free_i32(tmp
);
6589 i
= (insn
>> 23) & 3;
6591 case 0: offset
= -4; break; /* DA */
6592 case 1: offset
= 0; break; /* IA */
6593 case 2: offset
= -8; break; /* DB */
6594 case 3: offset
= 4; break; /* IB */
6598 tcg_gen_addi_i32(addr
, addr
, offset
);
6599 tmp
= load_reg(s
, 14);
6600 gen_st32(tmp
, addr
, 0);
6601 tmp
= load_cpu_field(spsr
);
6602 tcg_gen_addi_i32(addr
, addr
, 4);
6603 gen_st32(tmp
, addr
, 0);
6604 if (insn
& (1 << 21)) {
6605 /* Base writeback. */
6607 case 0: offset
= -8; break;
6608 case 1: offset
= 4; break;
6609 case 2: offset
= -4; break;
6610 case 3: offset
= 0; break;
6614 tcg_gen_addi_i32(addr
, addr
, offset
);
6615 tmp
= tcg_const_i32(op1
);
6616 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6617 tcg_temp_free_i32(tmp
);
6618 tcg_temp_free_i32(addr
);
6620 tcg_temp_free_i32(addr
);
6623 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6629 rn
= (insn
>> 16) & 0xf;
6630 addr
= load_reg(s
, rn
);
6631 i
= (insn
>> 23) & 3;
6633 case 0: offset
= -4; break; /* DA */
6634 case 1: offset
= 0; break; /* IA */
6635 case 2: offset
= -8; break; /* DB */
6636 case 3: offset
= 4; break; /* IB */
6640 tcg_gen_addi_i32(addr
, addr
, offset
);
6641 /* Load PC into tmp and CPSR into tmp2. */
6642 tmp
= gen_ld32(addr
, 0);
6643 tcg_gen_addi_i32(addr
, addr
, 4);
6644 tmp2
= gen_ld32(addr
, 0);
6645 if (insn
& (1 << 21)) {
6646 /* Base writeback. */
6648 case 0: offset
= -8; break;
6649 case 1: offset
= 4; break;
6650 case 2: offset
= -4; break;
6651 case 3: offset
= 0; break;
6655 tcg_gen_addi_i32(addr
, addr
, offset
);
6656 store_reg(s
, rn
, addr
);
6658 tcg_temp_free_i32(addr
);
6660 gen_rfe(s
, tmp
, tmp2
);
6662 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6663 /* branch link and change to thumb (blx <offset>) */
6666 val
= (uint32_t)s
->pc
;
6667 tmp
= tcg_temp_new_i32();
6668 tcg_gen_movi_i32(tmp
, val
);
6669 store_reg(s
, 14, tmp
);
6670 /* Sign-extend the 24-bit offset */
6671 offset
= (((int32_t)insn
) << 8) >> 8;
6672 /* offset * 4 + bit24 * 2 + (thumb bit) */
6673 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6674 /* pipeline offset */
6676 /* protected by ARCH(5); above, near the start of uncond block */
6679 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6680 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6681 /* iWMMXt register transfer. */
6682 if (env
->cp15
.c15_cpar
& (1 << 1))
6683 if (!disas_iwmmxt_insn(env
, s
, insn
))
6686 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6687 /* Coprocessor double register transfer. */
6689 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6690 /* Additional coprocessor register transfer. */
6691 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6694 /* cps (privileged) */
6698 if (insn
& (1 << 19)) {
6699 if (insn
& (1 << 8))
6701 if (insn
& (1 << 7))
6703 if (insn
& (1 << 6))
6705 if (insn
& (1 << 18))
6708 if (insn
& (1 << 17)) {
6710 val
|= (insn
& 0x1f);
6713 gen_set_psr_im(s
, mask
, 0, val
);
6720 /* if not always execute, we generate a conditional jump to
6722 s
->condlabel
= gen_new_label();
6723 gen_test_cc(cond
^ 1, s
->condlabel
);
6726 if ((insn
& 0x0f900000) == 0x03000000) {
6727 if ((insn
& (1 << 21)) == 0) {
6729 rd
= (insn
>> 12) & 0xf;
6730 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6731 if ((insn
& (1 << 22)) == 0) {
6733 tmp
= tcg_temp_new_i32();
6734 tcg_gen_movi_i32(tmp
, val
);
6737 tmp
= load_reg(s
, rd
);
6738 tcg_gen_ext16u_i32(tmp
, tmp
);
6739 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6741 store_reg(s
, rd
, tmp
);
6743 if (((insn
>> 12) & 0xf) != 0xf)
6745 if (((insn
>> 16) & 0xf) == 0) {
6746 gen_nop_hint(s
, insn
& 0xff);
6748 /* CPSR = immediate */
6750 shift
= ((insn
>> 8) & 0xf) * 2;
6752 val
= (val
>> shift
) | (val
<< (32 - shift
));
6753 i
= ((insn
& (1 << 22)) != 0);
6754 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6758 } else if ((insn
& 0x0f900000) == 0x01000000
6759 && (insn
& 0x00000090) != 0x00000090) {
6760 /* miscellaneous instructions */
6761 op1
= (insn
>> 21) & 3;
6762 sh
= (insn
>> 4) & 0xf;
6765 case 0x0: /* move program status register */
6768 tmp
= load_reg(s
, rm
);
6769 i
= ((op1
& 2) != 0);
6770 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6774 rd
= (insn
>> 12) & 0xf;
6778 tmp
= load_cpu_field(spsr
);
6780 tmp
= tcg_temp_new_i32();
6781 gen_helper_cpsr_read(tmp
);
6783 store_reg(s
, rd
, tmp
);
6788 /* branch/exchange thumb (bx). */
6790 tmp
= load_reg(s
, rm
);
6792 } else if (op1
== 3) {
6795 rd
= (insn
>> 12) & 0xf;
6796 tmp
= load_reg(s
, rm
);
6797 gen_helper_clz(tmp
, tmp
);
6798 store_reg(s
, rd
, tmp
);
6806 /* Trivial implementation equivalent to bx. */
6807 tmp
= load_reg(s
, rm
);
6818 /* branch link/exchange thumb (blx) */
6819 tmp
= load_reg(s
, rm
);
6820 tmp2
= tcg_temp_new_i32();
6821 tcg_gen_movi_i32(tmp2
, s
->pc
);
6822 store_reg(s
, 14, tmp2
);
6825 case 0x5: /* saturating add/subtract */
6827 rd
= (insn
>> 12) & 0xf;
6828 rn
= (insn
>> 16) & 0xf;
6829 tmp
= load_reg(s
, rm
);
6830 tmp2
= load_reg(s
, rn
);
6832 gen_helper_double_saturate(tmp2
, tmp2
);
6834 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6836 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6837 tcg_temp_free_i32(tmp2
);
6838 store_reg(s
, rd
, tmp
);
6841 /* SMC instruction (op1 == 3)
6842 and undefined instructions (op1 == 0 || op1 == 2)
6849 gen_exception_insn(s
, 4, EXCP_BKPT
);
6851 case 0x8: /* signed multiply */
6856 rs
= (insn
>> 8) & 0xf;
6857 rn
= (insn
>> 12) & 0xf;
6858 rd
= (insn
>> 16) & 0xf;
6860 /* (32 * 16) >> 16 */
6861 tmp
= load_reg(s
, rm
);
6862 tmp2
= load_reg(s
, rs
);
6864 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6867 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6868 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6869 tmp
= tcg_temp_new_i32();
6870 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6871 tcg_temp_free_i64(tmp64
);
6872 if ((sh
& 2) == 0) {
6873 tmp2
= load_reg(s
, rn
);
6874 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6875 tcg_temp_free_i32(tmp2
);
6877 store_reg(s
, rd
, tmp
);
6880 tmp
= load_reg(s
, rm
);
6881 tmp2
= load_reg(s
, rs
);
6882 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6883 tcg_temp_free_i32(tmp2
);
6885 tmp64
= tcg_temp_new_i64();
6886 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6887 tcg_temp_free_i32(tmp
);
6888 gen_addq(s
, tmp64
, rn
, rd
);
6889 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6890 tcg_temp_free_i64(tmp64
);
6893 tmp2
= load_reg(s
, rn
);
6894 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6895 tcg_temp_free_i32(tmp2
);
6897 store_reg(s
, rd
, tmp
);
6904 } else if (((insn
& 0x0e000000) == 0 &&
6905 (insn
& 0x00000090) != 0x90) ||
6906 ((insn
& 0x0e000000) == (1 << 25))) {
6907 int set_cc
, logic_cc
, shiftop
;
6909 op1
= (insn
>> 21) & 0xf;
6910 set_cc
= (insn
>> 20) & 1;
6911 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6913 /* data processing instruction */
6914 if (insn
& (1 << 25)) {
6915 /* immediate operand */
6917 shift
= ((insn
>> 8) & 0xf) * 2;
6919 val
= (val
>> shift
) | (val
<< (32 - shift
));
6921 tmp2
= tcg_temp_new_i32();
6922 tcg_gen_movi_i32(tmp2
, val
);
6923 if (logic_cc
&& shift
) {
6924 gen_set_CF_bit31(tmp2
);
6929 tmp2
= load_reg(s
, rm
);
6930 shiftop
= (insn
>> 5) & 3;
6931 if (!(insn
& (1 << 4))) {
6932 shift
= (insn
>> 7) & 0x1f;
6933 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
6935 rs
= (insn
>> 8) & 0xf;
6936 tmp
= load_reg(s
, rs
);
6937 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
6940 if (op1
!= 0x0f && op1
!= 0x0d) {
6941 rn
= (insn
>> 16) & 0xf;
6942 tmp
= load_reg(s
, rn
);
6946 rd
= (insn
>> 12) & 0xf;
6949 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
6953 store_reg_bx(env
, s
, rd
, tmp
);
6956 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
6960 store_reg_bx(env
, s
, rd
, tmp
);
6963 if (set_cc
&& rd
== 15) {
6964 /* SUBS r15, ... is used for exception return. */
6968 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6969 gen_exception_return(s
, tmp
);
6972 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
6974 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
6976 store_reg_bx(env
, s
, rd
, tmp
);
6981 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
6983 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
6985 store_reg_bx(env
, s
, rd
, tmp
);
6989 gen_helper_add_cc(tmp
, tmp
, tmp2
);
6991 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
6993 store_reg_bx(env
, s
, rd
, tmp
);
6997 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
6999 gen_add_carry(tmp
, tmp
, tmp2
);
7001 store_reg_bx(env
, s
, rd
, tmp
);
7005 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
7007 gen_sub_carry(tmp
, tmp
, tmp2
);
7009 store_reg_bx(env
, s
, rd
, tmp
);
7013 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
7015 gen_sub_carry(tmp
, tmp2
, tmp
);
7017 store_reg_bx(env
, s
, rd
, tmp
);
7021 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7024 tcg_temp_free_i32(tmp
);
7028 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7031 tcg_temp_free_i32(tmp
);
7035 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7037 tcg_temp_free_i32(tmp
);
7041 gen_helper_add_cc(tmp
, tmp
, tmp2
);
7043 tcg_temp_free_i32(tmp
);
7046 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7050 store_reg_bx(env
, s
, rd
, tmp
);
7053 if (logic_cc
&& rd
== 15) {
7054 /* MOVS r15, ... is used for exception return. */
7058 gen_exception_return(s
, tmp2
);
7063 store_reg_bx(env
, s
, rd
, tmp2
);
7067 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7071 store_reg_bx(env
, s
, rd
, tmp
);
7075 tcg_gen_not_i32(tmp2
, tmp2
);
7079 store_reg_bx(env
, s
, rd
, tmp2
);
7082 if (op1
!= 0x0f && op1
!= 0x0d) {
7083 tcg_temp_free_i32(tmp2
);
7086 /* other instructions */
7087 op1
= (insn
>> 24) & 0xf;
7091 /* multiplies, extra load/stores */
7092 sh
= (insn
>> 5) & 3;
7095 rd
= (insn
>> 16) & 0xf;
7096 rn
= (insn
>> 12) & 0xf;
7097 rs
= (insn
>> 8) & 0xf;
7099 op1
= (insn
>> 20) & 0xf;
7101 case 0: case 1: case 2: case 3: case 6:
7103 tmp
= load_reg(s
, rs
);
7104 tmp2
= load_reg(s
, rm
);
7105 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7106 tcg_temp_free_i32(tmp2
);
7107 if (insn
& (1 << 22)) {
7108 /* Subtract (mls) */
7110 tmp2
= load_reg(s
, rn
);
7111 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7112 tcg_temp_free_i32(tmp2
);
7113 } else if (insn
& (1 << 21)) {
7115 tmp2
= load_reg(s
, rn
);
7116 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7117 tcg_temp_free_i32(tmp2
);
7119 if (insn
& (1 << 20))
7121 store_reg(s
, rd
, tmp
);
7124 /* 64 bit mul double accumulate (UMAAL) */
7126 tmp
= load_reg(s
, rs
);
7127 tmp2
= load_reg(s
, rm
);
7128 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7129 gen_addq_lo(s
, tmp64
, rn
);
7130 gen_addq_lo(s
, tmp64
, rd
);
7131 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7132 tcg_temp_free_i64(tmp64
);
7134 case 8: case 9: case 10: case 11:
7135 case 12: case 13: case 14: case 15:
7136 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7137 tmp
= load_reg(s
, rs
);
7138 tmp2
= load_reg(s
, rm
);
7139 if (insn
& (1 << 22)) {
7140 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7142 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7144 if (insn
& (1 << 21)) { /* mult accumulate */
7145 gen_addq(s
, tmp64
, rn
, rd
);
7147 if (insn
& (1 << 20)) {
7148 gen_logicq_cc(tmp64
);
7150 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7151 tcg_temp_free_i64(tmp64
);
7157 rn
= (insn
>> 16) & 0xf;
7158 rd
= (insn
>> 12) & 0xf;
7159 if (insn
& (1 << 23)) {
7160 /* load/store exclusive */
7161 op1
= (insn
>> 21) & 0x3;
7166 addr
= tcg_temp_local_new_i32();
7167 load_reg_var(s
, addr
, rn
);
7168 if (insn
& (1 << 20)) {
7171 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7173 case 1: /* ldrexd */
7174 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7176 case 2: /* ldrexb */
7177 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7179 case 3: /* ldrexh */
7180 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7189 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7191 case 1: /* strexd */
7192 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7194 case 2: /* strexb */
7195 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7197 case 3: /* strexh */
7198 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7204 tcg_temp_free(addr
);
7206 /* SWP instruction */
7209 /* ??? This is not really atomic. However we know
7210 we never have multiple CPUs running in parallel,
7211 so it is good enough. */
7212 addr
= load_reg(s
, rn
);
7213 tmp
= load_reg(s
, rm
);
7214 if (insn
& (1 << 22)) {
7215 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7216 gen_st8(tmp
, addr
, IS_USER(s
));
7218 tmp2
= gen_ld32(addr
, IS_USER(s
));
7219 gen_st32(tmp
, addr
, IS_USER(s
));
7221 tcg_temp_free_i32(addr
);
7222 store_reg(s
, rd
, tmp2
);
7228 /* Misc load/store */
7229 rn
= (insn
>> 16) & 0xf;
7230 rd
= (insn
>> 12) & 0xf;
7231 addr
= load_reg(s
, rn
);
7232 if (insn
& (1 << 24))
7233 gen_add_datah_offset(s
, insn
, 0, addr
);
7235 if (insn
& (1 << 20)) {
7239 tmp
= gen_ld16u(addr
, IS_USER(s
));
7242 tmp
= gen_ld8s(addr
, IS_USER(s
));
7246 tmp
= gen_ld16s(addr
, IS_USER(s
));
7250 } else if (sh
& 2) {
7255 tmp
= load_reg(s
, rd
);
7256 gen_st32(tmp
, addr
, IS_USER(s
));
7257 tcg_gen_addi_i32(addr
, addr
, 4);
7258 tmp
= load_reg(s
, rd
+ 1);
7259 gen_st32(tmp
, addr
, IS_USER(s
));
7263 tmp
= gen_ld32(addr
, IS_USER(s
));
7264 store_reg(s
, rd
, tmp
);
7265 tcg_gen_addi_i32(addr
, addr
, 4);
7266 tmp
= gen_ld32(addr
, IS_USER(s
));
7270 address_offset
= -4;
7273 tmp
= load_reg(s
, rd
);
7274 gen_st16(tmp
, addr
, IS_USER(s
));
7277 /* Perform base writeback before the loaded value to
7278 ensure correct behavior with overlapping index registers.
7279 ldrd with base writeback is is undefined if the
7280 destination and index registers overlap. */
7281 if (!(insn
& (1 << 24))) {
7282 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7283 store_reg(s
, rn
, addr
);
7284 } else if (insn
& (1 << 21)) {
7286 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7287 store_reg(s
, rn
, addr
);
7289 tcg_temp_free_i32(addr
);
7292 /* Complete the load. */
7293 store_reg(s
, rd
, tmp
);
7302 if (insn
& (1 << 4)) {
7304 /* Armv6 Media instructions. */
7306 rn
= (insn
>> 16) & 0xf;
7307 rd
= (insn
>> 12) & 0xf;
7308 rs
= (insn
>> 8) & 0xf;
7309 switch ((insn
>> 23) & 3) {
7310 case 0: /* Parallel add/subtract. */
7311 op1
= (insn
>> 20) & 7;
7312 tmp
= load_reg(s
, rn
);
7313 tmp2
= load_reg(s
, rm
);
7314 sh
= (insn
>> 5) & 7;
7315 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7317 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7318 tcg_temp_free_i32(tmp2
);
7319 store_reg(s
, rd
, tmp
);
7322 if ((insn
& 0x00700020) == 0) {
7323 /* Halfword pack. */
7324 tmp
= load_reg(s
, rn
);
7325 tmp2
= load_reg(s
, rm
);
7326 shift
= (insn
>> 7) & 0x1f;
7327 if (insn
& (1 << 6)) {
7331 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7332 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7333 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7337 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7338 tcg_gen_ext16u_i32(tmp
, tmp
);
7339 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7341 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7342 tcg_temp_free_i32(tmp2
);
7343 store_reg(s
, rd
, tmp
);
7344 } else if ((insn
& 0x00200020) == 0x00200000) {
7346 tmp
= load_reg(s
, rm
);
7347 shift
= (insn
>> 7) & 0x1f;
7348 if (insn
& (1 << 6)) {
7351 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7353 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7355 sh
= (insn
>> 16) & 0x1f;
7356 tmp2
= tcg_const_i32(sh
);
7357 if (insn
& (1 << 22))
7358 gen_helper_usat(tmp
, tmp
, tmp2
);
7360 gen_helper_ssat(tmp
, tmp
, tmp2
);
7361 tcg_temp_free_i32(tmp2
);
7362 store_reg(s
, rd
, tmp
);
7363 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7365 tmp
= load_reg(s
, rm
);
7366 sh
= (insn
>> 16) & 0x1f;
7367 tmp2
= tcg_const_i32(sh
);
7368 if (insn
& (1 << 22))
7369 gen_helper_usat16(tmp
, tmp
, tmp2
);
7371 gen_helper_ssat16(tmp
, tmp
, tmp2
);
7372 tcg_temp_free_i32(tmp2
);
7373 store_reg(s
, rd
, tmp
);
7374 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7376 tmp
= load_reg(s
, rn
);
7377 tmp2
= load_reg(s
, rm
);
7378 tmp3
= tcg_temp_new_i32();
7379 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7380 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7381 tcg_temp_free_i32(tmp3
);
7382 tcg_temp_free_i32(tmp2
);
7383 store_reg(s
, rd
, tmp
);
7384 } else if ((insn
& 0x000003e0) == 0x00000060) {
7385 tmp
= load_reg(s
, rm
);
7386 shift
= (insn
>> 10) & 3;
7387 /* ??? In many cases it's not necessary to do a
7388 rotate, a shift is sufficient. */
7390 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7391 op1
= (insn
>> 20) & 7;
7393 case 0: gen_sxtb16(tmp
); break;
7394 case 2: gen_sxtb(tmp
); break;
7395 case 3: gen_sxth(tmp
); break;
7396 case 4: gen_uxtb16(tmp
); break;
7397 case 6: gen_uxtb(tmp
); break;
7398 case 7: gen_uxth(tmp
); break;
7399 default: goto illegal_op
;
7402 tmp2
= load_reg(s
, rn
);
7403 if ((op1
& 3) == 0) {
7404 gen_add16(tmp
, tmp2
);
7406 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7407 tcg_temp_free_i32(tmp2
);
7410 store_reg(s
, rd
, tmp
);
7411 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7413 tmp
= load_reg(s
, rm
);
7414 if (insn
& (1 << 22)) {
7415 if (insn
& (1 << 7)) {
7419 gen_helper_rbit(tmp
, tmp
);
7422 if (insn
& (1 << 7))
7425 tcg_gen_bswap32_i32(tmp
, tmp
);
7427 store_reg(s
, rd
, tmp
);
7432 case 2: /* Multiplies (Type 3). */
7433 tmp
= load_reg(s
, rm
);
7434 tmp2
= load_reg(s
, rs
);
7435 if (insn
& (1 << 20)) {
7436 /* Signed multiply most significant [accumulate].
7437 (SMMUL, SMMLA, SMMLS) */
7438 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7441 tmp
= load_reg(s
, rd
);
7442 if (insn
& (1 << 6)) {
7443 tmp64
= gen_subq_msw(tmp64
, tmp
);
7445 tmp64
= gen_addq_msw(tmp64
, tmp
);
7448 if (insn
& (1 << 5)) {
7449 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7451 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7452 tmp
= tcg_temp_new_i32();
7453 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7454 tcg_temp_free_i64(tmp64
);
7455 store_reg(s
, rn
, tmp
);
7457 if (insn
& (1 << 5))
7458 gen_swap_half(tmp2
);
7459 gen_smul_dual(tmp
, tmp2
);
7460 if (insn
& (1 << 6)) {
7461 /* This subtraction cannot overflow. */
7462 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7464 /* This addition cannot overflow 32 bits;
7465 * however it may overflow considered as a signed
7466 * operation, in which case we must set the Q flag.
7468 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7470 tcg_temp_free_i32(tmp2
);
7471 if (insn
& (1 << 22)) {
7472 /* smlald, smlsld */
7473 tmp64
= tcg_temp_new_i64();
7474 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7475 tcg_temp_free_i32(tmp
);
7476 gen_addq(s
, tmp64
, rd
, rn
);
7477 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7478 tcg_temp_free_i64(tmp64
);
7480 /* smuad, smusd, smlad, smlsd */
7483 tmp2
= load_reg(s
, rd
);
7484 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7485 tcg_temp_free_i32(tmp2
);
7487 store_reg(s
, rn
, tmp
);
7492 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7494 case 0: /* Unsigned sum of absolute differences. */
7496 tmp
= load_reg(s
, rm
);
7497 tmp2
= load_reg(s
, rs
);
7498 gen_helper_usad8(tmp
, tmp
, tmp2
);
7499 tcg_temp_free_i32(tmp2
);
7501 tmp2
= load_reg(s
, rd
);
7502 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7503 tcg_temp_free_i32(tmp2
);
7505 store_reg(s
, rn
, tmp
);
7507 case 0x20: case 0x24: case 0x28: case 0x2c:
7508 /* Bitfield insert/clear. */
7510 shift
= (insn
>> 7) & 0x1f;
7511 i
= (insn
>> 16) & 0x1f;
7514 tmp
= tcg_temp_new_i32();
7515 tcg_gen_movi_i32(tmp
, 0);
7517 tmp
= load_reg(s
, rm
);
7520 tmp2
= load_reg(s
, rd
);
7521 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7522 tcg_temp_free_i32(tmp2
);
7524 store_reg(s
, rd
, tmp
);
7526 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7527 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7529 tmp
= load_reg(s
, rm
);
7530 shift
= (insn
>> 7) & 0x1f;
7531 i
= ((insn
>> 16) & 0x1f) + 1;
7536 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7538 gen_sbfx(tmp
, shift
, i
);
7541 store_reg(s
, rd
, tmp
);
7551 /* Check for undefined extension instructions
7552 * per the ARM Bible IE:
7553 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7555 sh
= (0xf << 20) | (0xf << 4);
7556 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7560 /* load/store byte/word */
7561 rn
= (insn
>> 16) & 0xf;
7562 rd
= (insn
>> 12) & 0xf;
7563 tmp2
= load_reg(s
, rn
);
7564 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7565 if (insn
& (1 << 24))
7566 gen_add_data_offset(s
, insn
, tmp2
);
7567 if (insn
& (1 << 20)) {
7569 if (insn
& (1 << 22)) {
7570 tmp
= gen_ld8u(tmp2
, i
);
7572 tmp
= gen_ld32(tmp2
, i
);
7576 tmp
= load_reg(s
, rd
);
7577 if (insn
& (1 << 22))
7578 gen_st8(tmp
, tmp2
, i
);
7580 gen_st32(tmp
, tmp2
, i
);
7582 if (!(insn
& (1 << 24))) {
7583 gen_add_data_offset(s
, insn
, tmp2
);
7584 store_reg(s
, rn
, tmp2
);
7585 } else if (insn
& (1 << 21)) {
7586 store_reg(s
, rn
, tmp2
);
7588 tcg_temp_free_i32(tmp2
);
7590 if (insn
& (1 << 20)) {
7591 /* Complete the load. */
7592 store_reg_from_load(env
, s
, rd
, tmp
);
7598 int j
, n
, user
, loaded_base
;
7600 /* load/store multiple words */
7601 /* XXX: store correct base if write back */
7603 if (insn
& (1 << 22)) {
7605 goto illegal_op
; /* only usable in supervisor mode */
7607 if ((insn
& (1 << 15)) == 0)
7610 rn
= (insn
>> 16) & 0xf;
7611 addr
= load_reg(s
, rn
);
7613 /* compute total size */
7615 TCGV_UNUSED(loaded_var
);
7618 if (insn
& (1 << i
))
7621 /* XXX: test invalid n == 0 case ? */
7622 if (insn
& (1 << 23)) {
7623 if (insn
& (1 << 24)) {
7625 tcg_gen_addi_i32(addr
, addr
, 4);
7627 /* post increment */
7630 if (insn
& (1 << 24)) {
7632 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7634 /* post decrement */
7636 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7641 if (insn
& (1 << i
)) {
7642 if (insn
& (1 << 20)) {
7644 tmp
= gen_ld32(addr
, IS_USER(s
));
7646 tmp2
= tcg_const_i32(i
);
7647 gen_helper_set_user_reg(tmp2
, tmp
);
7648 tcg_temp_free_i32(tmp2
);
7649 tcg_temp_free_i32(tmp
);
7650 } else if (i
== rn
) {
7654 store_reg_from_load(env
, s
, i
, tmp
);
7659 /* special case: r15 = PC + 8 */
7660 val
= (long)s
->pc
+ 4;
7661 tmp
= tcg_temp_new_i32();
7662 tcg_gen_movi_i32(tmp
, val
);
7664 tmp
= tcg_temp_new_i32();
7665 tmp2
= tcg_const_i32(i
);
7666 gen_helper_get_user_reg(tmp
, tmp2
);
7667 tcg_temp_free_i32(tmp2
);
7669 tmp
= load_reg(s
, i
);
7671 gen_st32(tmp
, addr
, IS_USER(s
));
7674 /* no need to add after the last transfer */
7676 tcg_gen_addi_i32(addr
, addr
, 4);
7679 if (insn
& (1 << 21)) {
7681 if (insn
& (1 << 23)) {
7682 if (insn
& (1 << 24)) {
7685 /* post increment */
7686 tcg_gen_addi_i32(addr
, addr
, 4);
7689 if (insn
& (1 << 24)) {
7692 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7694 /* post decrement */
7695 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7698 store_reg(s
, rn
, addr
);
7700 tcg_temp_free_i32(addr
);
7703 store_reg(s
, rn
, loaded_var
);
7705 if ((insn
& (1 << 22)) && !user
) {
7706 /* Restore CPSR from SPSR. */
7707 tmp
= load_cpu_field(spsr
);
7708 gen_set_cpsr(tmp
, 0xffffffff);
7709 tcg_temp_free_i32(tmp
);
7710 s
->is_jmp
= DISAS_UPDATE
;
7719 /* branch (and link) */
7720 val
= (int32_t)s
->pc
;
7721 if (insn
& (1 << 24)) {
7722 tmp
= tcg_temp_new_i32();
7723 tcg_gen_movi_i32(tmp
, val
);
7724 store_reg(s
, 14, tmp
);
7726 offset
= (((int32_t)insn
<< 8) >> 8);
7727 val
+= (offset
<< 2) + 4;
7735 if (disas_coproc_insn(env
, s
, insn
))
7740 gen_set_pc_im(s
->pc
);
7741 s
->is_jmp
= DISAS_SWI
;
7745 gen_exception_insn(s
, 4, EXCP_UDEF
);
7751 /* Return true if this is a Thumb-2 logical op. */
7753 thumb2_logic_op(int op
)
7758 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7759 then set condition code flags based on the result of the operation.
7760 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7761 to the high bit of T1.
7762 Returns zero if the opcode is valid. */
7765 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7772 tcg_gen_and_i32(t0
, t0
, t1
);
7776 tcg_gen_andc_i32(t0
, t0
, t1
);
7780 tcg_gen_or_i32(t0
, t0
, t1
);
7784 tcg_gen_orc_i32(t0
, t0
, t1
);
7788 tcg_gen_xor_i32(t0
, t0
, t1
);
7793 gen_helper_add_cc(t0
, t0
, t1
);
7795 tcg_gen_add_i32(t0
, t0
, t1
);
7799 gen_helper_adc_cc(t0
, t0
, t1
);
7805 gen_helper_sbc_cc(t0
, t0
, t1
);
7807 gen_sub_carry(t0
, t0
, t1
);
7811 gen_helper_sub_cc(t0
, t0
, t1
);
7813 tcg_gen_sub_i32(t0
, t0
, t1
);
7817 gen_helper_sub_cc(t0
, t1
, t0
);
7819 tcg_gen_sub_i32(t0
, t1
, t0
);
7821 default: /* 5, 6, 7, 9, 12, 15. */
7827 gen_set_CF_bit31(t1
);
7832 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7834 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7836 uint32_t insn
, imm
, shift
, offset
;
7837 uint32_t rd
, rn
, rm
, rs
;
7848 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7849 || arm_feature (env
, ARM_FEATURE_M
))) {
7850 /* Thumb-1 cores may need to treat bl and blx as a pair of
7851 16-bit instructions to get correct prefetch abort behavior. */
7853 if ((insn
& (1 << 12)) == 0) {
7855 /* Second half of blx. */
7856 offset
= ((insn
& 0x7ff) << 1);
7857 tmp
= load_reg(s
, 14);
7858 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7859 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7861 tmp2
= tcg_temp_new_i32();
7862 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7863 store_reg(s
, 14, tmp2
);
7867 if (insn
& (1 << 11)) {
7868 /* Second half of bl. */
7869 offset
= ((insn
& 0x7ff) << 1) | 1;
7870 tmp
= load_reg(s
, 14);
7871 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7873 tmp2
= tcg_temp_new_i32();
7874 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7875 store_reg(s
, 14, tmp2
);
7879 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7880 /* Instruction spans a page boundary. Implement it as two
7881 16-bit instructions in case the second half causes an
7883 offset
= ((int32_t)insn
<< 21) >> 9;
7884 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
7887 /* Fall through to 32-bit decode. */
7890 insn
= lduw_code(s
->pc
);
7892 insn
|= (uint32_t)insn_hw1
<< 16;
7894 if ((insn
& 0xf800e800) != 0xf000e800) {
7898 rn
= (insn
>> 16) & 0xf;
7899 rs
= (insn
>> 12) & 0xf;
7900 rd
= (insn
>> 8) & 0xf;
7902 switch ((insn
>> 25) & 0xf) {
7903 case 0: case 1: case 2: case 3:
7904 /* 16-bit instructions. Should never happen. */
7907 if (insn
& (1 << 22)) {
7908 /* Other load/store, table branch. */
7909 if (insn
& 0x01200000) {
7910 /* Load/store doubleword. */
7912 addr
= tcg_temp_new_i32();
7913 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
7915 addr
= load_reg(s
, rn
);
7917 offset
= (insn
& 0xff) * 4;
7918 if ((insn
& (1 << 23)) == 0)
7920 if (insn
& (1 << 24)) {
7921 tcg_gen_addi_i32(addr
, addr
, offset
);
7924 if (insn
& (1 << 20)) {
7926 tmp
= gen_ld32(addr
, IS_USER(s
));
7927 store_reg(s
, rs
, tmp
);
7928 tcg_gen_addi_i32(addr
, addr
, 4);
7929 tmp
= gen_ld32(addr
, IS_USER(s
));
7930 store_reg(s
, rd
, tmp
);
7933 tmp
= load_reg(s
, rs
);
7934 gen_st32(tmp
, addr
, IS_USER(s
));
7935 tcg_gen_addi_i32(addr
, addr
, 4);
7936 tmp
= load_reg(s
, rd
);
7937 gen_st32(tmp
, addr
, IS_USER(s
));
7939 if (insn
& (1 << 21)) {
7940 /* Base writeback. */
7943 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
7944 store_reg(s
, rn
, addr
);
7946 tcg_temp_free_i32(addr
);
7948 } else if ((insn
& (1 << 23)) == 0) {
7949 /* Load/store exclusive word. */
7950 addr
= tcg_temp_local_new();
7951 load_reg_var(s
, addr
, rn
);
7952 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
7953 if (insn
& (1 << 20)) {
7954 gen_load_exclusive(s
, rs
, 15, addr
, 2);
7956 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
7958 tcg_temp_free(addr
);
7959 } else if ((insn
& (1 << 6)) == 0) {
7962 addr
= tcg_temp_new_i32();
7963 tcg_gen_movi_i32(addr
, s
->pc
);
7965 addr
= load_reg(s
, rn
);
7967 tmp
= load_reg(s
, rm
);
7968 tcg_gen_add_i32(addr
, addr
, tmp
);
7969 if (insn
& (1 << 4)) {
7971 tcg_gen_add_i32(addr
, addr
, tmp
);
7972 tcg_temp_free_i32(tmp
);
7973 tmp
= gen_ld16u(addr
, IS_USER(s
));
7975 tcg_temp_free_i32(tmp
);
7976 tmp
= gen_ld8u(addr
, IS_USER(s
));
7978 tcg_temp_free_i32(addr
);
7979 tcg_gen_shli_i32(tmp
, tmp
, 1);
7980 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
7981 store_reg(s
, 15, tmp
);
7983 /* Load/store exclusive byte/halfword/doubleword. */
7985 op
= (insn
>> 4) & 0x3;
7989 addr
= tcg_temp_local_new();
7990 load_reg_var(s
, addr
, rn
);
7991 if (insn
& (1 << 20)) {
7992 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
7994 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
7996 tcg_temp_free(addr
);
7999 /* Load/store multiple, RFE, SRS. */
8000 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8001 /* Not available in user mode. */
8004 if (insn
& (1 << 20)) {
8006 addr
= load_reg(s
, rn
);
8007 if ((insn
& (1 << 24)) == 0)
8008 tcg_gen_addi_i32(addr
, addr
, -8);
8009 /* Load PC into tmp and CPSR into tmp2. */
8010 tmp
= gen_ld32(addr
, 0);
8011 tcg_gen_addi_i32(addr
, addr
, 4);
8012 tmp2
= gen_ld32(addr
, 0);
8013 if (insn
& (1 << 21)) {
8014 /* Base writeback. */
8015 if (insn
& (1 << 24)) {
8016 tcg_gen_addi_i32(addr
, addr
, 4);
8018 tcg_gen_addi_i32(addr
, addr
, -4);
8020 store_reg(s
, rn
, addr
);
8022 tcg_temp_free_i32(addr
);
8024 gen_rfe(s
, tmp
, tmp2
);
8028 addr
= tcg_temp_new_i32();
8029 tmp
= tcg_const_i32(op
);
8030 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8031 tcg_temp_free_i32(tmp
);
8032 if ((insn
& (1 << 24)) == 0) {
8033 tcg_gen_addi_i32(addr
, addr
, -8);
8035 tmp
= load_reg(s
, 14);
8036 gen_st32(tmp
, addr
, 0);
8037 tcg_gen_addi_i32(addr
, addr
, 4);
8038 tmp
= tcg_temp_new_i32();
8039 gen_helper_cpsr_read(tmp
);
8040 gen_st32(tmp
, addr
, 0);
8041 if (insn
& (1 << 21)) {
8042 if ((insn
& (1 << 24)) == 0) {
8043 tcg_gen_addi_i32(addr
, addr
, -4);
8045 tcg_gen_addi_i32(addr
, addr
, 4);
8047 tmp
= tcg_const_i32(op
);
8048 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8049 tcg_temp_free_i32(tmp
);
8051 tcg_temp_free_i32(addr
);
8055 int i
, loaded_base
= 0;
8057 /* Load/store multiple. */
8058 addr
= load_reg(s
, rn
);
8060 for (i
= 0; i
< 16; i
++) {
8061 if (insn
& (1 << i
))
8064 if (insn
& (1 << 24)) {
8065 tcg_gen_addi_i32(addr
, addr
, -offset
);
8068 TCGV_UNUSED(loaded_var
);
8069 for (i
= 0; i
< 16; i
++) {
8070 if ((insn
& (1 << i
)) == 0)
8072 if (insn
& (1 << 20)) {
8074 tmp
= gen_ld32(addr
, IS_USER(s
));
8077 } else if (i
== rn
) {
8081 store_reg(s
, i
, tmp
);
8085 tmp
= load_reg(s
, i
);
8086 gen_st32(tmp
, addr
, IS_USER(s
));
8088 tcg_gen_addi_i32(addr
, addr
, 4);
8091 store_reg(s
, rn
, loaded_var
);
8093 if (insn
& (1 << 21)) {
8094 /* Base register writeback. */
8095 if (insn
& (1 << 24)) {
8096 tcg_gen_addi_i32(addr
, addr
, -offset
);
8098 /* Fault if writeback register is in register list. */
8099 if (insn
& (1 << rn
))
8101 store_reg(s
, rn
, addr
);
8103 tcg_temp_free_i32(addr
);
8110 op
= (insn
>> 21) & 0xf;
8112 /* Halfword pack. */
8113 tmp
= load_reg(s
, rn
);
8114 tmp2
= load_reg(s
, rm
);
8115 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8116 if (insn
& (1 << 5)) {
8120 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8121 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8122 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8126 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8127 tcg_gen_ext16u_i32(tmp
, tmp
);
8128 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8130 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8131 tcg_temp_free_i32(tmp2
);
8132 store_reg(s
, rd
, tmp
);
8134 /* Data processing register constant shift. */
8136 tmp
= tcg_temp_new_i32();
8137 tcg_gen_movi_i32(tmp
, 0);
8139 tmp
= load_reg(s
, rn
);
8141 tmp2
= load_reg(s
, rm
);
8143 shiftop
= (insn
>> 4) & 3;
8144 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8145 conds
= (insn
& (1 << 20)) != 0;
8146 logic_cc
= (conds
&& thumb2_logic_op(op
));
8147 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8148 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8150 tcg_temp_free_i32(tmp2
);
8152 store_reg(s
, rd
, tmp
);
8154 tcg_temp_free_i32(tmp
);
8158 case 13: /* Misc data processing. */
8159 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8160 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8163 case 0: /* Register controlled shift. */
8164 tmp
= load_reg(s
, rn
);
8165 tmp2
= load_reg(s
, rm
);
8166 if ((insn
& 0x70) != 0)
8168 op
= (insn
>> 21) & 3;
8169 logic_cc
= (insn
& (1 << 20)) != 0;
8170 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8173 store_reg_bx(env
, s
, rd
, tmp
);
8175 case 1: /* Sign/zero extend. */
8176 tmp
= load_reg(s
, rm
);
8177 shift
= (insn
>> 4) & 3;
8178 /* ??? In many cases it's not necessary to do a
8179 rotate, a shift is sufficient. */
8181 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8182 op
= (insn
>> 20) & 7;
8184 case 0: gen_sxth(tmp
); break;
8185 case 1: gen_uxth(tmp
); break;
8186 case 2: gen_sxtb16(tmp
); break;
8187 case 3: gen_uxtb16(tmp
); break;
8188 case 4: gen_sxtb(tmp
); break;
8189 case 5: gen_uxtb(tmp
); break;
8190 default: goto illegal_op
;
8193 tmp2
= load_reg(s
, rn
);
8194 if ((op
>> 1) == 1) {
8195 gen_add16(tmp
, tmp2
);
8197 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8198 tcg_temp_free_i32(tmp2
);
8201 store_reg(s
, rd
, tmp
);
8203 case 2: /* SIMD add/subtract. */
8204 op
= (insn
>> 20) & 7;
8205 shift
= (insn
>> 4) & 7;
8206 if ((op
& 3) == 3 || (shift
& 3) == 3)
8208 tmp
= load_reg(s
, rn
);
8209 tmp2
= load_reg(s
, rm
);
8210 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8211 tcg_temp_free_i32(tmp2
);
8212 store_reg(s
, rd
, tmp
);
8214 case 3: /* Other data processing. */
8215 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8217 /* Saturating add/subtract. */
8218 tmp
= load_reg(s
, rn
);
8219 tmp2
= load_reg(s
, rm
);
8221 gen_helper_double_saturate(tmp
, tmp
);
8223 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
8225 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
8226 tcg_temp_free_i32(tmp2
);
8228 tmp
= load_reg(s
, rn
);
8230 case 0x0a: /* rbit */
8231 gen_helper_rbit(tmp
, tmp
);
8233 case 0x08: /* rev */
8234 tcg_gen_bswap32_i32(tmp
, tmp
);
8236 case 0x09: /* rev16 */
8239 case 0x0b: /* revsh */
8242 case 0x10: /* sel */
8243 tmp2
= load_reg(s
, rm
);
8244 tmp3
= tcg_temp_new_i32();
8245 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
8246 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8247 tcg_temp_free_i32(tmp3
);
8248 tcg_temp_free_i32(tmp2
);
8250 case 0x18: /* clz */
8251 gen_helper_clz(tmp
, tmp
);
8257 store_reg(s
, rd
, tmp
);
8259 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8260 op
= (insn
>> 4) & 0xf;
8261 tmp
= load_reg(s
, rn
);
8262 tmp2
= load_reg(s
, rm
);
8263 switch ((insn
>> 20) & 7) {
8264 case 0: /* 32 x 32 -> 32 */
8265 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8266 tcg_temp_free_i32(tmp2
);
8268 tmp2
= load_reg(s
, rs
);
8270 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8272 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8273 tcg_temp_free_i32(tmp2
);
8276 case 1: /* 16 x 16 -> 32 */
8277 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8278 tcg_temp_free_i32(tmp2
);
8280 tmp2
= load_reg(s
, rs
);
8281 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8282 tcg_temp_free_i32(tmp2
);
8285 case 2: /* Dual multiply add. */
8286 case 4: /* Dual multiply subtract. */
8288 gen_swap_half(tmp2
);
8289 gen_smul_dual(tmp
, tmp2
);
8290 if (insn
& (1 << 22)) {
8291 /* This subtraction cannot overflow. */
8292 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8294 /* This addition cannot overflow 32 bits;
8295 * however it may overflow considered as a signed
8296 * operation, in which case we must set the Q flag.
8298 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8300 tcg_temp_free_i32(tmp2
);
8303 tmp2
= load_reg(s
, rs
);
8304 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8305 tcg_temp_free_i32(tmp2
);
8308 case 3: /* 32 * 16 -> 32msb */
8310 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8313 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8314 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8315 tmp
= tcg_temp_new_i32();
8316 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8317 tcg_temp_free_i64(tmp64
);
8320 tmp2
= load_reg(s
, rs
);
8321 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8322 tcg_temp_free_i32(tmp2
);
8325 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8326 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8328 tmp
= load_reg(s
, rs
);
8329 if (insn
& (1 << 20)) {
8330 tmp64
= gen_addq_msw(tmp64
, tmp
);
8332 tmp64
= gen_subq_msw(tmp64
, tmp
);
8335 if (insn
& (1 << 4)) {
8336 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8338 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8339 tmp
= tcg_temp_new_i32();
8340 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8341 tcg_temp_free_i64(tmp64
);
8343 case 7: /* Unsigned sum of absolute differences. */
8344 gen_helper_usad8(tmp
, tmp
, tmp2
);
8345 tcg_temp_free_i32(tmp2
);
8347 tmp2
= load_reg(s
, rs
);
8348 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8349 tcg_temp_free_i32(tmp2
);
8353 store_reg(s
, rd
, tmp
);
8355 case 6: case 7: /* 64-bit multiply, Divide. */
8356 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8357 tmp
= load_reg(s
, rn
);
8358 tmp2
= load_reg(s
, rm
);
8359 if ((op
& 0x50) == 0x10) {
8361 if (!arm_feature(env
, ARM_FEATURE_DIV
))
8364 gen_helper_udiv(tmp
, tmp
, tmp2
);
8366 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8367 tcg_temp_free_i32(tmp2
);
8368 store_reg(s
, rd
, tmp
);
8369 } else if ((op
& 0xe) == 0xc) {
8370 /* Dual multiply accumulate long. */
8372 gen_swap_half(tmp2
);
8373 gen_smul_dual(tmp
, tmp2
);
8375 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8377 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8379 tcg_temp_free_i32(tmp2
);
8381 tmp64
= tcg_temp_new_i64();
8382 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8383 tcg_temp_free_i32(tmp
);
8384 gen_addq(s
, tmp64
, rs
, rd
);
8385 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8386 tcg_temp_free_i64(tmp64
);
8389 /* Unsigned 64-bit multiply */
8390 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8394 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8395 tcg_temp_free_i32(tmp2
);
8396 tmp64
= tcg_temp_new_i64();
8397 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8398 tcg_temp_free_i32(tmp
);
8400 /* Signed 64-bit multiply */
8401 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8406 gen_addq_lo(s
, tmp64
, rs
);
8407 gen_addq_lo(s
, tmp64
, rd
);
8408 } else if (op
& 0x40) {
8409 /* 64-bit accumulate. */
8410 gen_addq(s
, tmp64
, rs
, rd
);
8412 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8413 tcg_temp_free_i64(tmp64
);
8418 case 6: case 7: case 14: case 15:
8420 if (((insn
>> 24) & 3) == 3) {
8421 /* Translate into the equivalent ARM encoding. */
8422 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8423 if (disas_neon_data_insn(env
, s
, insn
))
8426 if (insn
& (1 << 28))
8428 if (disas_coproc_insn (env
, s
, insn
))
8432 case 8: case 9: case 10: case 11:
8433 if (insn
& (1 << 15)) {
8434 /* Branches, misc control. */
8435 if (insn
& 0x5000) {
8436 /* Unconditional branch. */
8437 /* signextend(hw1[10:0]) -> offset[:12]. */
8438 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8439 /* hw1[10:0] -> offset[11:1]. */
8440 offset
|= (insn
& 0x7ff) << 1;
8441 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8442 offset[24:22] already have the same value because of the
8443 sign extension above. */
8444 offset
^= ((~insn
) & (1 << 13)) << 10;
8445 offset
^= ((~insn
) & (1 << 11)) << 11;
8447 if (insn
& (1 << 14)) {
8448 /* Branch and link. */
8449 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8453 if (insn
& (1 << 12)) {
8458 offset
&= ~(uint32_t)2;
8459 /* thumb2 bx, no need to check */
8460 gen_bx_im(s
, offset
);
8462 } else if (((insn
>> 23) & 7) == 7) {
8464 if (insn
& (1 << 13))
8467 if (insn
& (1 << 26)) {
8468 /* Secure monitor call (v6Z) */
8469 goto illegal_op
; /* not implemented. */
8471 op
= (insn
>> 20) & 7;
8473 case 0: /* msr cpsr. */
8475 tmp
= load_reg(s
, rn
);
8476 addr
= tcg_const_i32(insn
& 0xff);
8477 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8478 tcg_temp_free_i32(addr
);
8479 tcg_temp_free_i32(tmp
);
8484 case 1: /* msr spsr. */
8487 tmp
= load_reg(s
, rn
);
8489 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8493 case 2: /* cps, nop-hint. */
8494 if (((insn
>> 8) & 7) == 0) {
8495 gen_nop_hint(s
, insn
& 0xff);
8497 /* Implemented as NOP in user mode. */
8502 if (insn
& (1 << 10)) {
8503 if (insn
& (1 << 7))
8505 if (insn
& (1 << 6))
8507 if (insn
& (1 << 5))
8509 if (insn
& (1 << 9))
8510 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8512 if (insn
& (1 << 8)) {
8514 imm
|= (insn
& 0x1f);
8517 gen_set_psr_im(s
, offset
, 0, imm
);
8520 case 3: /* Special control operations. */
8522 op
= (insn
>> 4) & 0xf;
8530 /* These execute as NOPs. */
8537 /* Trivial implementation equivalent to bx. */
8538 tmp
= load_reg(s
, rn
);
8541 case 5: /* Exception return. */
8545 if (rn
!= 14 || rd
!= 15) {
8548 tmp
= load_reg(s
, rn
);
8549 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8550 gen_exception_return(s
, tmp
);
8552 case 6: /* mrs cpsr. */
8553 tmp
= tcg_temp_new_i32();
8555 addr
= tcg_const_i32(insn
& 0xff);
8556 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8557 tcg_temp_free_i32(addr
);
8559 gen_helper_cpsr_read(tmp
);
8561 store_reg(s
, rd
, tmp
);
8563 case 7: /* mrs spsr. */
8564 /* Not accessible in user mode. */
8565 if (IS_USER(s
) || IS_M(env
))
8567 tmp
= load_cpu_field(spsr
);
8568 store_reg(s
, rd
, tmp
);
8573 /* Conditional branch. */
8574 op
= (insn
>> 22) & 0xf;
8575 /* Generate a conditional jump to next instruction. */
8576 s
->condlabel
= gen_new_label();
8577 gen_test_cc(op
^ 1, s
->condlabel
);
8580 /* offset[11:1] = insn[10:0] */
8581 offset
= (insn
& 0x7ff) << 1;
8582 /* offset[17:12] = insn[21:16]. */
8583 offset
|= (insn
& 0x003f0000) >> 4;
8584 /* offset[31:20] = insn[26]. */
8585 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8586 /* offset[18] = insn[13]. */
8587 offset
|= (insn
& (1 << 13)) << 5;
8588 /* offset[19] = insn[11]. */
8589 offset
|= (insn
& (1 << 11)) << 8;
8591 /* jump to the offset */
8592 gen_jmp(s
, s
->pc
+ offset
);
8595 /* Data processing immediate. */
8596 if (insn
& (1 << 25)) {
8597 if (insn
& (1 << 24)) {
8598 if (insn
& (1 << 20))
8600 /* Bitfield/Saturate. */
8601 op
= (insn
>> 21) & 7;
8603 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8605 tmp
= tcg_temp_new_i32();
8606 tcg_gen_movi_i32(tmp
, 0);
8608 tmp
= load_reg(s
, rn
);
8611 case 2: /* Signed bitfield extract. */
8613 if (shift
+ imm
> 32)
8616 gen_sbfx(tmp
, shift
, imm
);
8618 case 6: /* Unsigned bitfield extract. */
8620 if (shift
+ imm
> 32)
8623 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8625 case 3: /* Bitfield insert/clear. */
8628 imm
= imm
+ 1 - shift
;
8630 tmp2
= load_reg(s
, rd
);
8631 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8632 tcg_temp_free_i32(tmp2
);
8637 default: /* Saturate. */
8640 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8642 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8644 tmp2
= tcg_const_i32(imm
);
8647 if ((op
& 1) && shift
== 0)
8648 gen_helper_usat16(tmp
, tmp
, tmp2
);
8650 gen_helper_usat(tmp
, tmp
, tmp2
);
8653 if ((op
& 1) && shift
== 0)
8654 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8656 gen_helper_ssat(tmp
, tmp
, tmp2
);
8658 tcg_temp_free_i32(tmp2
);
8661 store_reg(s
, rd
, tmp
);
8663 imm
= ((insn
& 0x04000000) >> 15)
8664 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8665 if (insn
& (1 << 22)) {
8666 /* 16-bit immediate. */
8667 imm
|= (insn
>> 4) & 0xf000;
8668 if (insn
& (1 << 23)) {
8670 tmp
= load_reg(s
, rd
);
8671 tcg_gen_ext16u_i32(tmp
, tmp
);
8672 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8675 tmp
= tcg_temp_new_i32();
8676 tcg_gen_movi_i32(tmp
, imm
);
8679 /* Add/sub 12-bit immediate. */
8681 offset
= s
->pc
& ~(uint32_t)3;
8682 if (insn
& (1 << 23))
8686 tmp
= tcg_temp_new_i32();
8687 tcg_gen_movi_i32(tmp
, offset
);
8689 tmp
= load_reg(s
, rn
);
8690 if (insn
& (1 << 23))
8691 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8693 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8696 store_reg(s
, rd
, tmp
);
8699 int shifter_out
= 0;
8700 /* modified 12-bit immediate. */
8701 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8702 imm
= (insn
& 0xff);
8705 /* Nothing to do. */
8707 case 1: /* 00XY00XY */
8710 case 2: /* XY00XY00 */
8714 case 3: /* XYXYXYXY */
8718 default: /* Rotated constant. */
8719 shift
= (shift
<< 1) | (imm
>> 7);
8721 imm
= imm
<< (32 - shift
);
8725 tmp2
= tcg_temp_new_i32();
8726 tcg_gen_movi_i32(tmp2
, imm
);
8727 rn
= (insn
>> 16) & 0xf;
8729 tmp
= tcg_temp_new_i32();
8730 tcg_gen_movi_i32(tmp
, 0);
8732 tmp
= load_reg(s
, rn
);
8734 op
= (insn
>> 21) & 0xf;
8735 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8736 shifter_out
, tmp
, tmp2
))
8738 tcg_temp_free_i32(tmp2
);
8739 rd
= (insn
>> 8) & 0xf;
8741 store_reg(s
, rd
, tmp
);
8743 tcg_temp_free_i32(tmp
);
8748 case 12: /* Load/store single data item. */
8753 if ((insn
& 0x01100000) == 0x01000000) {
8754 if (disas_neon_ls_insn(env
, s
, insn
))
8758 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8760 if (!(insn
& (1 << 20))) {
8764 /* Byte or halfword load space with dest == r15 : memory hints.
8765 * Catch them early so we don't emit pointless addressing code.
8766 * This space is a mix of:
8767 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8768 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8770 * unallocated hints, which must be treated as NOPs
8771 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8772 * which is easiest for the decoding logic
8773 * Some space which must UNDEF
8775 int op1
= (insn
>> 23) & 3;
8776 int op2
= (insn
>> 6) & 0x3f;
8781 /* UNPREDICTABLE or unallocated hint */
8785 return 0; /* PLD* or unallocated hint */
8787 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8788 return 0; /* PLD* or unallocated hint */
8790 /* UNDEF space, or an UNPREDICTABLE */
8796 addr
= tcg_temp_new_i32();
8798 /* s->pc has already been incremented by 4. */
8799 imm
= s
->pc
& 0xfffffffc;
8800 if (insn
& (1 << 23))
8801 imm
+= insn
& 0xfff;
8803 imm
-= insn
& 0xfff;
8804 tcg_gen_movi_i32(addr
, imm
);
8806 addr
= load_reg(s
, rn
);
8807 if (insn
& (1 << 23)) {
8808 /* Positive offset. */
8810 tcg_gen_addi_i32(addr
, addr
, imm
);
8813 switch ((insn
>> 8) & 0xf) {
8814 case 0x0: /* Shifted Register. */
8815 shift
= (insn
>> 4) & 0xf;
8817 tcg_temp_free_i32(addr
);
8820 tmp
= load_reg(s
, rm
);
8822 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8823 tcg_gen_add_i32(addr
, addr
, tmp
);
8824 tcg_temp_free_i32(tmp
);
8826 case 0xc: /* Negative offset. */
8827 tcg_gen_addi_i32(addr
, addr
, -imm
);
8829 case 0xe: /* User privilege. */
8830 tcg_gen_addi_i32(addr
, addr
, imm
);
8833 case 0x9: /* Post-decrement. */
8836 case 0xb: /* Post-increment. */
8840 case 0xd: /* Pre-decrement. */
8843 case 0xf: /* Pre-increment. */
8844 tcg_gen_addi_i32(addr
, addr
, imm
);
8848 tcg_temp_free_i32(addr
);
8853 if (insn
& (1 << 20)) {
8856 case 0: tmp
= gen_ld8u(addr
, user
); break;
8857 case 4: tmp
= gen_ld8s(addr
, user
); break;
8858 case 1: tmp
= gen_ld16u(addr
, user
); break;
8859 case 5: tmp
= gen_ld16s(addr
, user
); break;
8860 case 2: tmp
= gen_ld32(addr
, user
); break;
8862 tcg_temp_free_i32(addr
);
8868 store_reg(s
, rs
, tmp
);
8872 tmp
= load_reg(s
, rs
);
8874 case 0: gen_st8(tmp
, addr
, user
); break;
8875 case 1: gen_st16(tmp
, addr
, user
); break;
8876 case 2: gen_st32(tmp
, addr
, user
); break;
8878 tcg_temp_free_i32(addr
);
8883 tcg_gen_addi_i32(addr
, addr
, imm
);
8885 store_reg(s
, rn
, addr
);
8887 tcg_temp_free_i32(addr
);
8899 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
8901 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
8908 if (s
->condexec_mask
) {
8909 cond
= s
->condexec_cond
;
8910 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
8911 s
->condlabel
= gen_new_label();
8912 gen_test_cc(cond
^ 1, s
->condlabel
);
8917 insn
= lduw_code(s
->pc
);
8920 switch (insn
>> 12) {
8924 op
= (insn
>> 11) & 3;
8927 rn
= (insn
>> 3) & 7;
8928 tmp
= load_reg(s
, rn
);
8929 if (insn
& (1 << 10)) {
8931 tmp2
= tcg_temp_new_i32();
8932 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
8935 rm
= (insn
>> 6) & 7;
8936 tmp2
= load_reg(s
, rm
);
8938 if (insn
& (1 << 9)) {
8939 if (s
->condexec_mask
)
8940 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8942 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8944 if (s
->condexec_mask
)
8945 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8947 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8949 tcg_temp_free_i32(tmp2
);
8950 store_reg(s
, rd
, tmp
);
8952 /* shift immediate */
8953 rm
= (insn
>> 3) & 7;
8954 shift
= (insn
>> 6) & 0x1f;
8955 tmp
= load_reg(s
, rm
);
8956 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
8957 if (!s
->condexec_mask
)
8959 store_reg(s
, rd
, tmp
);
8963 /* arithmetic large immediate */
8964 op
= (insn
>> 11) & 3;
8965 rd
= (insn
>> 8) & 0x7;
8966 if (op
== 0) { /* mov */
8967 tmp
= tcg_temp_new_i32();
8968 tcg_gen_movi_i32(tmp
, insn
& 0xff);
8969 if (!s
->condexec_mask
)
8971 store_reg(s
, rd
, tmp
);
8973 tmp
= load_reg(s
, rd
);
8974 tmp2
= tcg_temp_new_i32();
8975 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
8978 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8979 tcg_temp_free_i32(tmp
);
8980 tcg_temp_free_i32(tmp2
);
8983 if (s
->condexec_mask
)
8984 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8986 gen_helper_add_cc(tmp
, tmp
, tmp2
);
8987 tcg_temp_free_i32(tmp2
);
8988 store_reg(s
, rd
, tmp
);
8991 if (s
->condexec_mask
)
8992 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8994 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
8995 tcg_temp_free_i32(tmp2
);
8996 store_reg(s
, rd
, tmp
);
9002 if (insn
& (1 << 11)) {
9003 rd
= (insn
>> 8) & 7;
9004 /* load pc-relative. Bit 1 of PC is ignored. */
9005 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9006 val
&= ~(uint32_t)2;
9007 addr
= tcg_temp_new_i32();
9008 tcg_gen_movi_i32(addr
, val
);
9009 tmp
= gen_ld32(addr
, IS_USER(s
));
9010 tcg_temp_free_i32(addr
);
9011 store_reg(s
, rd
, tmp
);
9014 if (insn
& (1 << 10)) {
9015 /* data processing extended or blx */
9016 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9017 rm
= (insn
>> 3) & 0xf;
9018 op
= (insn
>> 8) & 3;
9021 tmp
= load_reg(s
, rd
);
9022 tmp2
= load_reg(s
, rm
);
9023 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9024 tcg_temp_free_i32(tmp2
);
9025 store_reg(s
, rd
, tmp
);
9028 tmp
= load_reg(s
, rd
);
9029 tmp2
= load_reg(s
, rm
);
9030 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9031 tcg_temp_free_i32(tmp2
);
9032 tcg_temp_free_i32(tmp
);
9034 case 2: /* mov/cpy */
9035 tmp
= load_reg(s
, rm
);
9036 store_reg(s
, rd
, tmp
);
9038 case 3:/* branch [and link] exchange thumb register */
9039 tmp
= load_reg(s
, rm
);
9040 if (insn
& (1 << 7)) {
9042 val
= (uint32_t)s
->pc
| 1;
9043 tmp2
= tcg_temp_new_i32();
9044 tcg_gen_movi_i32(tmp2
, val
);
9045 store_reg(s
, 14, tmp2
);
9047 /* already thumb, no need to check */
9054 /* data processing register */
9056 rm
= (insn
>> 3) & 7;
9057 op
= (insn
>> 6) & 0xf;
9058 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9059 /* the shift/rotate ops want the operands backwards */
9068 if (op
== 9) { /* neg */
9069 tmp
= tcg_temp_new_i32();
9070 tcg_gen_movi_i32(tmp
, 0);
9071 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9072 tmp
= load_reg(s
, rd
);
9077 tmp2
= load_reg(s
, rm
);
9080 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9081 if (!s
->condexec_mask
)
9085 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9086 if (!s
->condexec_mask
)
9090 if (s
->condexec_mask
) {
9091 gen_helper_shl(tmp2
, tmp2
, tmp
);
9093 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
9098 if (s
->condexec_mask
) {
9099 gen_helper_shr(tmp2
, tmp2
, tmp
);
9101 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
9106 if (s
->condexec_mask
) {
9107 gen_helper_sar(tmp2
, tmp2
, tmp
);
9109 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
9114 if (s
->condexec_mask
)
9117 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
9120 if (s
->condexec_mask
)
9121 gen_sub_carry(tmp
, tmp
, tmp2
);
9123 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
9126 if (s
->condexec_mask
) {
9127 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9128 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9130 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
9135 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9140 if (s
->condexec_mask
)
9141 tcg_gen_neg_i32(tmp
, tmp2
);
9143 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9146 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9150 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9154 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9155 if (!s
->condexec_mask
)
9159 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9160 if (!s
->condexec_mask
)
9164 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9165 if (!s
->condexec_mask
)
9169 tcg_gen_not_i32(tmp2
, tmp2
);
9170 if (!s
->condexec_mask
)
9178 store_reg(s
, rm
, tmp2
);
9180 tcg_temp_free_i32(tmp
);
9182 store_reg(s
, rd
, tmp
);
9183 tcg_temp_free_i32(tmp2
);
9186 tcg_temp_free_i32(tmp
);
9187 tcg_temp_free_i32(tmp2
);
9192 /* load/store register offset. */
9194 rn
= (insn
>> 3) & 7;
9195 rm
= (insn
>> 6) & 7;
9196 op
= (insn
>> 9) & 7;
9197 addr
= load_reg(s
, rn
);
9198 tmp
= load_reg(s
, rm
);
9199 tcg_gen_add_i32(addr
, addr
, tmp
);
9200 tcg_temp_free_i32(tmp
);
9202 if (op
< 3) /* store */
9203 tmp
= load_reg(s
, rd
);
9207 gen_st32(tmp
, addr
, IS_USER(s
));
9210 gen_st16(tmp
, addr
, IS_USER(s
));
9213 gen_st8(tmp
, addr
, IS_USER(s
));
9216 tmp
= gen_ld8s(addr
, IS_USER(s
));
9219 tmp
= gen_ld32(addr
, IS_USER(s
));
9222 tmp
= gen_ld16u(addr
, IS_USER(s
));
9225 tmp
= gen_ld8u(addr
, IS_USER(s
));
9228 tmp
= gen_ld16s(addr
, IS_USER(s
));
9231 if (op
>= 3) /* load */
9232 store_reg(s
, rd
, tmp
);
9233 tcg_temp_free_i32(addr
);
9237 /* load/store word immediate offset */
9239 rn
= (insn
>> 3) & 7;
9240 addr
= load_reg(s
, rn
);
9241 val
= (insn
>> 4) & 0x7c;
9242 tcg_gen_addi_i32(addr
, addr
, val
);
9244 if (insn
& (1 << 11)) {
9246 tmp
= gen_ld32(addr
, IS_USER(s
));
9247 store_reg(s
, rd
, tmp
);
9250 tmp
= load_reg(s
, rd
);
9251 gen_st32(tmp
, addr
, IS_USER(s
));
9253 tcg_temp_free_i32(addr
);
9257 /* load/store byte immediate offset */
9259 rn
= (insn
>> 3) & 7;
9260 addr
= load_reg(s
, rn
);
9261 val
= (insn
>> 6) & 0x1f;
9262 tcg_gen_addi_i32(addr
, addr
, val
);
9264 if (insn
& (1 << 11)) {
9266 tmp
= gen_ld8u(addr
, IS_USER(s
));
9267 store_reg(s
, rd
, tmp
);
9270 tmp
= load_reg(s
, rd
);
9271 gen_st8(tmp
, addr
, IS_USER(s
));
9273 tcg_temp_free_i32(addr
);
9277 /* load/store halfword immediate offset */
9279 rn
= (insn
>> 3) & 7;
9280 addr
= load_reg(s
, rn
);
9281 val
= (insn
>> 5) & 0x3e;
9282 tcg_gen_addi_i32(addr
, addr
, val
);
9284 if (insn
& (1 << 11)) {
9286 tmp
= gen_ld16u(addr
, IS_USER(s
));
9287 store_reg(s
, rd
, tmp
);
9290 tmp
= load_reg(s
, rd
);
9291 gen_st16(tmp
, addr
, IS_USER(s
));
9293 tcg_temp_free_i32(addr
);
9297 /* load/store from stack */
9298 rd
= (insn
>> 8) & 7;
9299 addr
= load_reg(s
, 13);
9300 val
= (insn
& 0xff) * 4;
9301 tcg_gen_addi_i32(addr
, addr
, val
);
9303 if (insn
& (1 << 11)) {
9305 tmp
= gen_ld32(addr
, IS_USER(s
));
9306 store_reg(s
, rd
, tmp
);
9309 tmp
= load_reg(s
, rd
);
9310 gen_st32(tmp
, addr
, IS_USER(s
));
9312 tcg_temp_free_i32(addr
);
9316 /* add to high reg */
9317 rd
= (insn
>> 8) & 7;
9318 if (insn
& (1 << 11)) {
9320 tmp
= load_reg(s
, 13);
9322 /* PC. bit 1 is ignored. */
9323 tmp
= tcg_temp_new_i32();
9324 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9326 val
= (insn
& 0xff) * 4;
9327 tcg_gen_addi_i32(tmp
, tmp
, val
);
9328 store_reg(s
, rd
, tmp
);
9333 op
= (insn
>> 8) & 0xf;
9336 /* adjust stack pointer */
9337 tmp
= load_reg(s
, 13);
9338 val
= (insn
& 0x7f) * 4;
9339 if (insn
& (1 << 7))
9340 val
= -(int32_t)val
;
9341 tcg_gen_addi_i32(tmp
, tmp
, val
);
9342 store_reg(s
, 13, tmp
);
9345 case 2: /* sign/zero extend. */
9348 rm
= (insn
>> 3) & 7;
9349 tmp
= load_reg(s
, rm
);
9350 switch ((insn
>> 6) & 3) {
9351 case 0: gen_sxth(tmp
); break;
9352 case 1: gen_sxtb(tmp
); break;
9353 case 2: gen_uxth(tmp
); break;
9354 case 3: gen_uxtb(tmp
); break;
9356 store_reg(s
, rd
, tmp
);
9358 case 4: case 5: case 0xc: case 0xd:
9360 addr
= load_reg(s
, 13);
9361 if (insn
& (1 << 8))
9365 for (i
= 0; i
< 8; i
++) {
9366 if (insn
& (1 << i
))
9369 if ((insn
& (1 << 11)) == 0) {
9370 tcg_gen_addi_i32(addr
, addr
, -offset
);
9372 for (i
= 0; i
< 8; i
++) {
9373 if (insn
& (1 << i
)) {
9374 if (insn
& (1 << 11)) {
9376 tmp
= gen_ld32(addr
, IS_USER(s
));
9377 store_reg(s
, i
, tmp
);
9380 tmp
= load_reg(s
, i
);
9381 gen_st32(tmp
, addr
, IS_USER(s
));
9383 /* advance to the next address. */
9384 tcg_gen_addi_i32(addr
, addr
, 4);
9388 if (insn
& (1 << 8)) {
9389 if (insn
& (1 << 11)) {
9391 tmp
= gen_ld32(addr
, IS_USER(s
));
9392 /* don't set the pc until the rest of the instruction
9396 tmp
= load_reg(s
, 14);
9397 gen_st32(tmp
, addr
, IS_USER(s
));
9399 tcg_gen_addi_i32(addr
, addr
, 4);
9401 if ((insn
& (1 << 11)) == 0) {
9402 tcg_gen_addi_i32(addr
, addr
, -offset
);
9404 /* write back the new stack pointer */
9405 store_reg(s
, 13, addr
);
9406 /* set the new PC value */
9407 if ((insn
& 0x0900) == 0x0900) {
9408 store_reg_from_load(env
, s
, 15, tmp
);
9412 case 1: case 3: case 9: case 11: /* czb */
9414 tmp
= load_reg(s
, rm
);
9415 s
->condlabel
= gen_new_label();
9417 if (insn
& (1 << 11))
9418 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9420 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9421 tcg_temp_free_i32(tmp
);
9422 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9423 val
= (uint32_t)s
->pc
+ 2;
9428 case 15: /* IT, nop-hint. */
9429 if ((insn
& 0xf) == 0) {
9430 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9434 s
->condexec_cond
= (insn
>> 4) & 0xe;
9435 s
->condexec_mask
= insn
& 0x1f;
9436 /* No actual code generated for this insn, just setup state. */
9439 case 0xe: /* bkpt */
9441 gen_exception_insn(s
, 2, EXCP_BKPT
);
9446 rn
= (insn
>> 3) & 0x7;
9448 tmp
= load_reg(s
, rn
);
9449 switch ((insn
>> 6) & 3) {
9450 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9451 case 1: gen_rev16(tmp
); break;
9452 case 3: gen_revsh(tmp
); break;
9453 default: goto illegal_op
;
9455 store_reg(s
, rd
, tmp
);
9463 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9466 addr
= tcg_const_i32(16);
9467 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9468 tcg_temp_free_i32(addr
);
9472 addr
= tcg_const_i32(17);
9473 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9474 tcg_temp_free_i32(addr
);
9476 tcg_temp_free_i32(tmp
);
9479 if (insn
& (1 << 4))
9480 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9483 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9494 /* load/store multiple */
9496 TCGV_UNUSED(loaded_var
);
9497 rn
= (insn
>> 8) & 0x7;
9498 addr
= load_reg(s
, rn
);
9499 for (i
= 0; i
< 8; i
++) {
9500 if (insn
& (1 << i
)) {
9501 if (insn
& (1 << 11)) {
9503 tmp
= gen_ld32(addr
, IS_USER(s
));
9507 store_reg(s
, i
, tmp
);
9511 tmp
= load_reg(s
, i
);
9512 gen_st32(tmp
, addr
, IS_USER(s
));
9514 /* advance to the next address */
9515 tcg_gen_addi_i32(addr
, addr
, 4);
9518 if ((insn
& (1 << rn
)) == 0) {
9519 /* base reg not in list: base register writeback */
9520 store_reg(s
, rn
, addr
);
9522 /* base reg in list: if load, complete it now */
9523 if (insn
& (1 << 11)) {
9524 store_reg(s
, rn
, loaded_var
);
9526 tcg_temp_free_i32(addr
);
9531 /* conditional branch or swi */
9532 cond
= (insn
>> 8) & 0xf;
9538 gen_set_pc_im(s
->pc
);
9539 s
->is_jmp
= DISAS_SWI
;
9542 /* generate a conditional jump to next instruction */
9543 s
->condlabel
= gen_new_label();
9544 gen_test_cc(cond
^ 1, s
->condlabel
);
9547 /* jump to the offset */
9548 val
= (uint32_t)s
->pc
+ 2;
9549 offset
= ((int32_t)insn
<< 24) >> 24;
9555 if (insn
& (1 << 11)) {
9556 if (disas_thumb2_insn(env
, s
, insn
))
9560 /* unconditional branch */
9561 val
= (uint32_t)s
->pc
;
9562 offset
= ((int32_t)insn
<< 21) >> 21;
9563 val
+= (offset
<< 1) + 2;
9568 if (disas_thumb2_insn(env
, s
, insn
))
9574 gen_exception_insn(s
, 4, EXCP_UDEF
);
9578 gen_exception_insn(s
, 2, EXCP_UDEF
);
9581 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9582 basic block 'tb'. If search_pc is TRUE, also generate PC
9583 information for each intermediate instruction. */
9584 static inline void gen_intermediate_code_internal(CPUState
*env
,
9585 TranslationBlock
*tb
,
9588 DisasContext dc1
, *dc
= &dc1
;
9590 uint16_t *gen_opc_end
;
9592 target_ulong pc_start
;
9593 uint32_t next_page_start
;
9597 /* generate intermediate code */
9602 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9604 dc
->is_jmp
= DISAS_NEXT
;
9606 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9608 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9609 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9610 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9611 #if !defined(CONFIG_USER_ONLY)
9612 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9614 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9615 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9616 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9617 cpu_F0s
= tcg_temp_new_i32();
9618 cpu_F1s
= tcg_temp_new_i32();
9619 cpu_F0d
= tcg_temp_new_i64();
9620 cpu_F1d
= tcg_temp_new_i64();
9623 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9624 cpu_M0
= tcg_temp_new_i64();
9625 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9628 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9630 max_insns
= CF_COUNT_MASK
;
9634 tcg_clear_temp_count();
9636 /* A note on handling of the condexec (IT) bits:
9638 * We want to avoid the overhead of having to write the updated condexec
9639 * bits back to the CPUState for every instruction in an IT block. So:
9640 * (1) if the condexec bits are not already zero then we write
9641 * zero back into the CPUState now. This avoids complications trying
9642 * to do it at the end of the block. (For example if we don't do this
9643 * it's hard to identify whether we can safely skip writing condexec
9644 * at the end of the TB, which we definitely want to do for the case
9645 * where a TB doesn't do anything with the IT state at all.)
9646 * (2) if we are going to leave the TB then we call gen_set_condexec()
9647 * which will write the correct value into CPUState if zero is wrong.
9648 * This is done both for leaving the TB at the end, and for leaving
9649 * it because of an exception we know will happen, which is done in
9650 * gen_exception_insn(). The latter is necessary because we need to
9651 * leave the TB with the PC/IT state just prior to execution of the
9652 * instruction which caused the exception.
9653 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9654 * then the CPUState will be wrong and we need to reset it.
9655 * This is handled in the same way as restoration of the
9656 * PC in these situations: we will be called again with search_pc=1
9657 * and generate a mapping of the condexec bits for each PC in
9658 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9659 * this to restore the condexec bits.
9661 * Note that there are no instructions which can read the condexec
9662 * bits, and none which can write non-static values to them, so
9663 * we don't need to care about whether CPUState is correct in the
9667 /* Reset the conditional execution bits immediately. This avoids
9668 complications trying to do it at the end of the block. */
9669 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9671 TCGv tmp
= tcg_temp_new_i32();
9672 tcg_gen_movi_i32(tmp
, 0);
9673 store_cpu_field(tmp
, condexec_bits
);
9676 #ifdef CONFIG_USER_ONLY
9677 /* Intercept jump to the magic kernel page. */
9678 if (dc
->pc
>= 0xffff0000) {
9679 /* We always get here via a jump, so know we are not in a
9680 conditional execution block. */
9681 gen_exception(EXCP_KERNEL_TRAP
);
9682 dc
->is_jmp
= DISAS_UPDATE
;
9686 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9687 /* We always get here via a jump, so know we are not in a
9688 conditional execution block. */
9689 gen_exception(EXCP_EXCEPTION_EXIT
);
9690 dc
->is_jmp
= DISAS_UPDATE
;
9695 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9696 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9697 if (bp
->pc
== dc
->pc
) {
9698 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9699 /* Advance PC so that clearing the breakpoint will
9700 invalidate this TB. */
9702 goto done_generating
;
9708 j
= gen_opc_ptr
- gen_opc_buf
;
9712 gen_opc_instr_start
[lj
++] = 0;
9714 gen_opc_pc
[lj
] = dc
->pc
;
9715 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9716 gen_opc_instr_start
[lj
] = 1;
9717 gen_opc_icount
[lj
] = num_insns
;
9720 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9723 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9724 tcg_gen_debug_insn_start(dc
->pc
);
9728 disas_thumb_insn(env
, dc
);
9729 if (dc
->condexec_mask
) {
9730 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9731 | ((dc
->condexec_mask
>> 4) & 1);
9732 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9733 if (dc
->condexec_mask
== 0) {
9734 dc
->condexec_cond
= 0;
9738 disas_arm_insn(env
, dc
);
9741 if (dc
->condjmp
&& !dc
->is_jmp
) {
9742 gen_set_label(dc
->condlabel
);
9746 if (tcg_check_temp_count()) {
9747 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9750 /* Translation stops when a conditional branch is encountered.
9751 * Otherwise the subsequent code could get translated several times.
9752 * Also stop translation when a page boundary is reached. This
9753 * ensures prefetch aborts occur at the right place. */
9755 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9756 !env
->singlestep_enabled
&&
9758 dc
->pc
< next_page_start
&&
9759 num_insns
< max_insns
);
9761 if (tb
->cflags
& CF_LAST_IO
) {
9763 /* FIXME: This can theoretically happen with self-modifying
9765 cpu_abort(env
, "IO on conditional branch instruction");
9770 /* At this stage dc->condjmp will only be set when the skipped
9771 instruction was a conditional branch or trap, and the PC has
9772 already been written. */
9773 if (unlikely(env
->singlestep_enabled
)) {
9774 /* Make sure the pc is updated, and raise a debug exception. */
9776 gen_set_condexec(dc
);
9777 if (dc
->is_jmp
== DISAS_SWI
) {
9778 gen_exception(EXCP_SWI
);
9780 gen_exception(EXCP_DEBUG
);
9782 gen_set_label(dc
->condlabel
);
9784 if (dc
->condjmp
|| !dc
->is_jmp
) {
9785 gen_set_pc_im(dc
->pc
);
9788 gen_set_condexec(dc
);
9789 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9790 gen_exception(EXCP_SWI
);
9792 /* FIXME: Single stepping a WFI insn will not halt
9794 gen_exception(EXCP_DEBUG
);
9797 /* While branches must always occur at the end of an IT block,
9798 there are a few other things that can cause us to terminate
9799 the TB in the middel of an IT block:
9800 - Exception generating instructions (bkpt, swi, undefined).
9802 - Hardware watchpoints.
9803 Hardware breakpoints have already been handled and skip this code.
9805 gen_set_condexec(dc
);
9806 switch(dc
->is_jmp
) {
9808 gen_goto_tb(dc
, 1, dc
->pc
);
9813 /* indicate that the hash table must be used to find the next TB */
9817 /* nothing more to generate */
9823 gen_exception(EXCP_SWI
);
9827 gen_set_label(dc
->condlabel
);
9828 gen_set_condexec(dc
);
9829 gen_goto_tb(dc
, 1, dc
->pc
);
9835 gen_icount_end(tb
, num_insns
);
9836 *gen_opc_ptr
= INDEX_op_end
;
9839 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9840 qemu_log("----------------\n");
9841 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9842 log_target_disas(pc_start
, dc
->pc
- pc_start
, dc
->thumb
);
9847 j
= gen_opc_ptr
- gen_opc_buf
;
9850 gen_opc_instr_start
[lj
++] = 0;
9852 tb
->size
= dc
->pc
- pc_start
;
9853 tb
->icount
= num_insns
;
9857 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9859 gen_intermediate_code_internal(env
, tb
, 0);
9862 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9864 gen_intermediate_code_internal(env
, tb
, 1);
9867 static const char *cpu_mode_names
[16] = {
9868 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9869 "???", "???", "???", "und", "???", "???", "???", "sys"
9872 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
9882 /* ??? This assumes float64 and double have the same layout.
9883 Oh well, it's only debug dumps. */
9892 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
9894 cpu_fprintf(f
, "\n");
9896 cpu_fprintf(f
, " ");
9898 psr
= cpsr_read(env
);
9899 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
9901 psr
& (1 << 31) ? 'N' : '-',
9902 psr
& (1 << 30) ? 'Z' : '-',
9903 psr
& (1 << 29) ? 'C' : '-',
9904 psr
& (1 << 28) ? 'V' : '-',
9905 psr
& CPSR_T
? 'T' : 'A',
9906 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
9909 for (i
= 0; i
< 16; i
++) {
9910 d
.d
= env
->vfp
.regs
[i
];
9914 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9915 i
* 2, (int)s0
.i
, s0
.s
,
9916 i
* 2 + 1, (int)s1
.i
, s1
.s
,
9917 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
9920 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
9924 void restore_state_to_opc(CPUState
*env
, TranslationBlock
*tb
, int pc_pos
)
9926 env
->regs
[15] = gen_opc_pc
[pc_pos
];
9927 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];