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 static TCGv_ptr
get_fpstatus_ptr(int neon
)
897 TCGv_ptr statusptr
= tcg_temp_new_ptr();
900 offset
= offsetof(CPUState
, vfp
.standard_fp_status
);
902 offset
= offsetof(CPUState
, vfp
.fp_status
);
904 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
908 #define VFP_OP2(name) \
909 static inline void gen_vfp_##name(int dp) \
911 TCGv_ptr fpst = get_fpstatus_ptr(0); \
913 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
915 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
917 tcg_temp_free_ptr(fpst); \
927 static inline void gen_vfp_F1_mul(int dp
)
929 /* Like gen_vfp_mul() but put result in F1 */
930 TCGv_ptr fpst
= get_fpstatus_ptr(0);
932 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
934 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
936 tcg_temp_free_ptr(fpst
);
939 static inline void gen_vfp_F1_neg(int dp
)
941 /* Like gen_vfp_neg() but put result in F1 */
943 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
945 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
949 static inline void gen_vfp_abs(int dp
)
952 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
954 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
957 static inline void gen_vfp_neg(int dp
)
960 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
962 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
965 static inline void gen_vfp_sqrt(int dp
)
968 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
970 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
973 static inline void gen_vfp_cmp(int dp
)
976 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
978 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
981 static inline void gen_vfp_cmpe(int dp
)
984 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
986 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
989 static inline void gen_vfp_F1_ld0(int dp
)
992 tcg_gen_movi_i64(cpu_F1d
, 0);
994 tcg_gen_movi_i32(cpu_F1s
, 0);
997 #define VFP_GEN_ITOF(name) \
998 static inline void gen_vfp_##name(int dp, int neon) \
1000 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1002 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1004 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1006 tcg_temp_free_ptr(statusptr); \
1013 #define VFP_GEN_FTOI(name) \
1014 static inline void gen_vfp_##name(int dp, int neon) \
1016 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1018 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1020 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1022 tcg_temp_free_ptr(statusptr); \
1031 #define VFP_GEN_FIX(name) \
1032 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1034 TCGv tmp_shift = tcg_const_i32(shift); \
1035 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1037 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1039 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1041 tcg_temp_free_i32(tmp_shift); \
1042 tcg_temp_free_ptr(statusptr); \
1054 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1057 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1059 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1062 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1065 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1067 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1071 vfp_reg_offset (int dp
, int reg
)
1074 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1076 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1077 + offsetof(CPU_DoubleU
, l
.upper
);
1079 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1080 + offsetof(CPU_DoubleU
, l
.lower
);
1084 /* Return the offset of a 32-bit piece of a NEON register.
1085 zero is the least significant end of the register. */
1087 neon_reg_offset (int reg
, int n
)
1091 return vfp_reg_offset(0, sreg
);
1094 static TCGv
neon_load_reg(int reg
, int pass
)
1096 TCGv tmp
= tcg_temp_new_i32();
1097 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1101 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1103 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1104 tcg_temp_free_i32(var
);
1107 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1109 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1112 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1114 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1117 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1118 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1119 #define tcg_gen_st_f32 tcg_gen_st_i32
1120 #define tcg_gen_st_f64 tcg_gen_st_i64
1122 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1125 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1127 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1130 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1133 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1135 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1138 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1141 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1143 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1146 #define ARM_CP_RW_BIT (1 << 20)
1148 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1150 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1153 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1155 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.regs
[reg
]));
1158 static inline TCGv
iwmmxt_load_creg(int reg
)
1160 TCGv var
= tcg_temp_new_i32();
1161 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1165 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1167 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUState
, iwmmxt
.cregs
[reg
]));
1168 tcg_temp_free_i32(var
);
1171 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1173 iwmmxt_store_reg(cpu_M0
, rn
);
1176 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1178 iwmmxt_load_reg(cpu_M0
, rn
);
1181 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1183 iwmmxt_load_reg(cpu_V1
, rn
);
1184 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1187 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1189 iwmmxt_load_reg(cpu_V1
, rn
);
1190 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1193 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1195 iwmmxt_load_reg(cpu_V1
, rn
);
1196 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1199 #define IWMMXT_OP(name) \
1200 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1202 iwmmxt_load_reg(cpu_V1, rn); \
1203 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1206 #define IWMMXT_OP_ENV(name) \
1207 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1209 iwmmxt_load_reg(cpu_V1, rn); \
1210 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1213 #define IWMMXT_OP_ENV_SIZE(name) \
1214 IWMMXT_OP_ENV(name##b) \
1215 IWMMXT_OP_ENV(name##w) \
1216 IWMMXT_OP_ENV(name##l)
1218 #define IWMMXT_OP_ENV1(name) \
1219 static inline void gen_op_iwmmxt_##name##_M0(void) \
1221 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1235 IWMMXT_OP_ENV_SIZE(unpackl
)
1236 IWMMXT_OP_ENV_SIZE(unpackh
)
1238 IWMMXT_OP_ENV1(unpacklub
)
1239 IWMMXT_OP_ENV1(unpackluw
)
1240 IWMMXT_OP_ENV1(unpacklul
)
1241 IWMMXT_OP_ENV1(unpackhub
)
1242 IWMMXT_OP_ENV1(unpackhuw
)
1243 IWMMXT_OP_ENV1(unpackhul
)
1244 IWMMXT_OP_ENV1(unpacklsb
)
1245 IWMMXT_OP_ENV1(unpacklsw
)
1246 IWMMXT_OP_ENV1(unpacklsl
)
1247 IWMMXT_OP_ENV1(unpackhsb
)
1248 IWMMXT_OP_ENV1(unpackhsw
)
1249 IWMMXT_OP_ENV1(unpackhsl
)
1251 IWMMXT_OP_ENV_SIZE(cmpeq
)
1252 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1253 IWMMXT_OP_ENV_SIZE(cmpgts
)
1255 IWMMXT_OP_ENV_SIZE(mins
)
1256 IWMMXT_OP_ENV_SIZE(minu
)
1257 IWMMXT_OP_ENV_SIZE(maxs
)
1258 IWMMXT_OP_ENV_SIZE(maxu
)
1260 IWMMXT_OP_ENV_SIZE(subn
)
1261 IWMMXT_OP_ENV_SIZE(addn
)
1262 IWMMXT_OP_ENV_SIZE(subu
)
1263 IWMMXT_OP_ENV_SIZE(addu
)
1264 IWMMXT_OP_ENV_SIZE(subs
)
1265 IWMMXT_OP_ENV_SIZE(adds
)
1267 IWMMXT_OP_ENV(avgb0
)
1268 IWMMXT_OP_ENV(avgb1
)
1269 IWMMXT_OP_ENV(avgw0
)
1270 IWMMXT_OP_ENV(avgw1
)
1274 IWMMXT_OP_ENV(packuw
)
1275 IWMMXT_OP_ENV(packul
)
1276 IWMMXT_OP_ENV(packuq
)
1277 IWMMXT_OP_ENV(packsw
)
1278 IWMMXT_OP_ENV(packsl
)
1279 IWMMXT_OP_ENV(packsq
)
1281 static void gen_op_iwmmxt_set_mup(void)
1284 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1285 tcg_gen_ori_i32(tmp
, tmp
, 2);
1286 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1289 static void gen_op_iwmmxt_set_cup(void)
1292 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1293 tcg_gen_ori_i32(tmp
, tmp
, 1);
1294 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1297 static void gen_op_iwmmxt_setpsr_nz(void)
1299 TCGv tmp
= tcg_temp_new_i32();
1300 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1301 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1304 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1306 iwmmxt_load_reg(cpu_V1
, rn
);
1307 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1308 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1311 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1317 rd
= (insn
>> 16) & 0xf;
1318 tmp
= load_reg(s
, rd
);
1320 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1321 if (insn
& (1 << 24)) {
1323 if (insn
& (1 << 23))
1324 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1326 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1327 tcg_gen_mov_i32(dest
, tmp
);
1328 if (insn
& (1 << 21))
1329 store_reg(s
, rd
, tmp
);
1331 tcg_temp_free_i32(tmp
);
1332 } else if (insn
& (1 << 21)) {
1334 tcg_gen_mov_i32(dest
, tmp
);
1335 if (insn
& (1 << 23))
1336 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1338 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1339 store_reg(s
, rd
, tmp
);
1340 } else if (!(insn
& (1 << 23)))
1345 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1347 int rd
= (insn
>> 0) & 0xf;
1350 if (insn
& (1 << 8)) {
1351 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1354 tmp
= iwmmxt_load_creg(rd
);
1357 tmp
= tcg_temp_new_i32();
1358 iwmmxt_load_reg(cpu_V0
, rd
);
1359 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1361 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1362 tcg_gen_mov_i32(dest
, tmp
);
1363 tcg_temp_free_i32(tmp
);
1367 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1368 (ie. an undefined instruction). */
1369 static int disas_iwmmxt_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
1372 int rdhi
, rdlo
, rd0
, rd1
, i
;
1374 TCGv tmp
, tmp2
, tmp3
;
1376 if ((insn
& 0x0e000e00) == 0x0c000000) {
1377 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1379 rdlo
= (insn
>> 12) & 0xf;
1380 rdhi
= (insn
>> 16) & 0xf;
1381 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1382 iwmmxt_load_reg(cpu_V0
, wrd
);
1383 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1384 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1385 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1386 } else { /* TMCRR */
1387 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1388 iwmmxt_store_reg(cpu_V0
, wrd
);
1389 gen_op_iwmmxt_set_mup();
1394 wrd
= (insn
>> 12) & 0xf;
1395 addr
= tcg_temp_new_i32();
1396 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1397 tcg_temp_free_i32(addr
);
1400 if (insn
& ARM_CP_RW_BIT
) {
1401 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1402 tmp
= tcg_temp_new_i32();
1403 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1404 iwmmxt_store_creg(wrd
, tmp
);
1407 if (insn
& (1 << 8)) {
1408 if (insn
& (1 << 22)) { /* WLDRD */
1409 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1411 } else { /* WLDRW wRd */
1412 tmp
= gen_ld32(addr
, IS_USER(s
));
1415 if (insn
& (1 << 22)) { /* WLDRH */
1416 tmp
= gen_ld16u(addr
, IS_USER(s
));
1417 } else { /* WLDRB */
1418 tmp
= gen_ld8u(addr
, IS_USER(s
));
1422 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1423 tcg_temp_free_i32(tmp
);
1425 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1428 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1429 tmp
= iwmmxt_load_creg(wrd
);
1430 gen_st32(tmp
, addr
, IS_USER(s
));
1432 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1433 tmp
= tcg_temp_new_i32();
1434 if (insn
& (1 << 8)) {
1435 if (insn
& (1 << 22)) { /* WSTRD */
1436 tcg_temp_free_i32(tmp
);
1437 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1438 } else { /* WSTRW wRd */
1439 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1440 gen_st32(tmp
, addr
, IS_USER(s
));
1443 if (insn
& (1 << 22)) { /* WSTRH */
1444 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1445 gen_st16(tmp
, addr
, IS_USER(s
));
1446 } else { /* WSTRB */
1447 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1448 gen_st8(tmp
, addr
, IS_USER(s
));
1453 tcg_temp_free_i32(addr
);
1457 if ((insn
& 0x0f000000) != 0x0e000000)
1460 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1461 case 0x000: /* WOR */
1462 wrd
= (insn
>> 12) & 0xf;
1463 rd0
= (insn
>> 0) & 0xf;
1464 rd1
= (insn
>> 16) & 0xf;
1465 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1466 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1467 gen_op_iwmmxt_setpsr_nz();
1468 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1469 gen_op_iwmmxt_set_mup();
1470 gen_op_iwmmxt_set_cup();
1472 case 0x011: /* TMCR */
1475 rd
= (insn
>> 12) & 0xf;
1476 wrd
= (insn
>> 16) & 0xf;
1478 case ARM_IWMMXT_wCID
:
1479 case ARM_IWMMXT_wCASF
:
1481 case ARM_IWMMXT_wCon
:
1482 gen_op_iwmmxt_set_cup();
1484 case ARM_IWMMXT_wCSSF
:
1485 tmp
= iwmmxt_load_creg(wrd
);
1486 tmp2
= load_reg(s
, rd
);
1487 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1488 tcg_temp_free_i32(tmp2
);
1489 iwmmxt_store_creg(wrd
, tmp
);
1491 case ARM_IWMMXT_wCGR0
:
1492 case ARM_IWMMXT_wCGR1
:
1493 case ARM_IWMMXT_wCGR2
:
1494 case ARM_IWMMXT_wCGR3
:
1495 gen_op_iwmmxt_set_cup();
1496 tmp
= load_reg(s
, rd
);
1497 iwmmxt_store_creg(wrd
, tmp
);
1503 case 0x100: /* WXOR */
1504 wrd
= (insn
>> 12) & 0xf;
1505 rd0
= (insn
>> 0) & 0xf;
1506 rd1
= (insn
>> 16) & 0xf;
1507 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1508 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1509 gen_op_iwmmxt_setpsr_nz();
1510 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1511 gen_op_iwmmxt_set_mup();
1512 gen_op_iwmmxt_set_cup();
1514 case 0x111: /* TMRC */
1517 rd
= (insn
>> 12) & 0xf;
1518 wrd
= (insn
>> 16) & 0xf;
1519 tmp
= iwmmxt_load_creg(wrd
);
1520 store_reg(s
, rd
, tmp
);
1522 case 0x300: /* WANDN */
1523 wrd
= (insn
>> 12) & 0xf;
1524 rd0
= (insn
>> 0) & 0xf;
1525 rd1
= (insn
>> 16) & 0xf;
1526 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1527 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1528 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1529 gen_op_iwmmxt_setpsr_nz();
1530 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1531 gen_op_iwmmxt_set_mup();
1532 gen_op_iwmmxt_set_cup();
1534 case 0x200: /* WAND */
1535 wrd
= (insn
>> 12) & 0xf;
1536 rd0
= (insn
>> 0) & 0xf;
1537 rd1
= (insn
>> 16) & 0xf;
1538 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1539 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1540 gen_op_iwmmxt_setpsr_nz();
1541 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1542 gen_op_iwmmxt_set_mup();
1543 gen_op_iwmmxt_set_cup();
1545 case 0x810: case 0xa10: /* WMADD */
1546 wrd
= (insn
>> 12) & 0xf;
1547 rd0
= (insn
>> 0) & 0xf;
1548 rd1
= (insn
>> 16) & 0xf;
1549 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1550 if (insn
& (1 << 21))
1551 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1553 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1554 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1555 gen_op_iwmmxt_set_mup();
1557 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1558 wrd
= (insn
>> 12) & 0xf;
1559 rd0
= (insn
>> 16) & 0xf;
1560 rd1
= (insn
>> 0) & 0xf;
1561 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1562 switch ((insn
>> 22) & 3) {
1564 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1567 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1570 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1575 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1576 gen_op_iwmmxt_set_mup();
1577 gen_op_iwmmxt_set_cup();
1579 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1580 wrd
= (insn
>> 12) & 0xf;
1581 rd0
= (insn
>> 16) & 0xf;
1582 rd1
= (insn
>> 0) & 0xf;
1583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1584 switch ((insn
>> 22) & 3) {
1586 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1589 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1592 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1597 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1598 gen_op_iwmmxt_set_mup();
1599 gen_op_iwmmxt_set_cup();
1601 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1602 wrd
= (insn
>> 12) & 0xf;
1603 rd0
= (insn
>> 16) & 0xf;
1604 rd1
= (insn
>> 0) & 0xf;
1605 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1606 if (insn
& (1 << 22))
1607 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1609 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1610 if (!(insn
& (1 << 20)))
1611 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1612 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1613 gen_op_iwmmxt_set_mup();
1615 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1616 wrd
= (insn
>> 12) & 0xf;
1617 rd0
= (insn
>> 16) & 0xf;
1618 rd1
= (insn
>> 0) & 0xf;
1619 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1620 if (insn
& (1 << 21)) {
1621 if (insn
& (1 << 20))
1622 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1624 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1626 if (insn
& (1 << 20))
1627 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1629 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1632 gen_op_iwmmxt_set_mup();
1634 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1635 wrd
= (insn
>> 12) & 0xf;
1636 rd0
= (insn
>> 16) & 0xf;
1637 rd1
= (insn
>> 0) & 0xf;
1638 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1639 if (insn
& (1 << 21))
1640 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1642 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1643 if (!(insn
& (1 << 20))) {
1644 iwmmxt_load_reg(cpu_V1
, wrd
);
1645 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1647 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1648 gen_op_iwmmxt_set_mup();
1650 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1651 wrd
= (insn
>> 12) & 0xf;
1652 rd0
= (insn
>> 16) & 0xf;
1653 rd1
= (insn
>> 0) & 0xf;
1654 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1655 switch ((insn
>> 22) & 3) {
1657 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1660 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1663 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1668 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1669 gen_op_iwmmxt_set_mup();
1670 gen_op_iwmmxt_set_cup();
1672 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1673 wrd
= (insn
>> 12) & 0xf;
1674 rd0
= (insn
>> 16) & 0xf;
1675 rd1
= (insn
>> 0) & 0xf;
1676 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1677 if (insn
& (1 << 22)) {
1678 if (insn
& (1 << 20))
1679 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1681 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1683 if (insn
& (1 << 20))
1684 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1686 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1688 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1689 gen_op_iwmmxt_set_mup();
1690 gen_op_iwmmxt_set_cup();
1692 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1693 wrd
= (insn
>> 12) & 0xf;
1694 rd0
= (insn
>> 16) & 0xf;
1695 rd1
= (insn
>> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1697 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1698 tcg_gen_andi_i32(tmp
, tmp
, 7);
1699 iwmmxt_load_reg(cpu_V1
, rd1
);
1700 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1701 tcg_temp_free_i32(tmp
);
1702 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1703 gen_op_iwmmxt_set_mup();
1705 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1706 if (((insn
>> 6) & 3) == 3)
1708 rd
= (insn
>> 12) & 0xf;
1709 wrd
= (insn
>> 16) & 0xf;
1710 tmp
= load_reg(s
, rd
);
1711 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1712 switch ((insn
>> 6) & 3) {
1714 tmp2
= tcg_const_i32(0xff);
1715 tmp3
= tcg_const_i32((insn
& 7) << 3);
1718 tmp2
= tcg_const_i32(0xffff);
1719 tmp3
= tcg_const_i32((insn
& 3) << 4);
1722 tmp2
= tcg_const_i32(0xffffffff);
1723 tmp3
= tcg_const_i32((insn
& 1) << 5);
1729 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1730 tcg_temp_free(tmp3
);
1731 tcg_temp_free(tmp2
);
1732 tcg_temp_free_i32(tmp
);
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 gen_op_iwmmxt_set_mup();
1736 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1737 rd
= (insn
>> 12) & 0xf;
1738 wrd
= (insn
>> 16) & 0xf;
1739 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1741 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1742 tmp
= tcg_temp_new_i32();
1743 switch ((insn
>> 22) & 3) {
1745 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1746 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1748 tcg_gen_ext8s_i32(tmp
, tmp
);
1750 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1754 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1755 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1757 tcg_gen_ext16s_i32(tmp
, tmp
);
1759 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1763 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1764 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1767 store_reg(s
, rd
, tmp
);
1769 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1770 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1772 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1773 switch ((insn
>> 22) & 3) {
1775 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1778 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1781 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1784 tcg_gen_shli_i32(tmp
, tmp
, 28);
1786 tcg_temp_free_i32(tmp
);
1788 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1789 if (((insn
>> 6) & 3) == 3)
1791 rd
= (insn
>> 12) & 0xf;
1792 wrd
= (insn
>> 16) & 0xf;
1793 tmp
= load_reg(s
, rd
);
1794 switch ((insn
>> 6) & 3) {
1796 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1799 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1802 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1805 tcg_temp_free_i32(tmp
);
1806 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1807 gen_op_iwmmxt_set_mup();
1809 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1810 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1812 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1813 tmp2
= tcg_temp_new_i32();
1814 tcg_gen_mov_i32(tmp2
, tmp
);
1815 switch ((insn
>> 22) & 3) {
1817 for (i
= 0; i
< 7; i
++) {
1818 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1819 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1823 for (i
= 0; i
< 3; i
++) {
1824 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1825 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1829 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1830 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1834 tcg_temp_free_i32(tmp2
);
1835 tcg_temp_free_i32(tmp
);
1837 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1838 wrd
= (insn
>> 12) & 0xf;
1839 rd0
= (insn
>> 16) & 0xf;
1840 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1841 switch ((insn
>> 22) & 3) {
1843 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1846 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1849 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1854 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1855 gen_op_iwmmxt_set_mup();
1857 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1858 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1860 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1861 tmp2
= tcg_temp_new_i32();
1862 tcg_gen_mov_i32(tmp2
, tmp
);
1863 switch ((insn
>> 22) & 3) {
1865 for (i
= 0; i
< 7; i
++) {
1866 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1867 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1871 for (i
= 0; i
< 3; i
++) {
1872 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1873 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1877 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1878 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1882 tcg_temp_free_i32(tmp2
);
1883 tcg_temp_free_i32(tmp
);
1885 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1886 rd
= (insn
>> 12) & 0xf;
1887 rd0
= (insn
>> 16) & 0xf;
1888 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1890 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1891 tmp
= tcg_temp_new_i32();
1892 switch ((insn
>> 22) & 3) {
1894 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1897 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1900 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1903 store_reg(s
, rd
, tmp
);
1905 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1906 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1907 wrd
= (insn
>> 12) & 0xf;
1908 rd0
= (insn
>> 16) & 0xf;
1909 rd1
= (insn
>> 0) & 0xf;
1910 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1911 switch ((insn
>> 22) & 3) {
1913 if (insn
& (1 << 21))
1914 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1916 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1919 if (insn
& (1 << 21))
1920 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1922 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1925 if (insn
& (1 << 21))
1926 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1928 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1933 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1934 gen_op_iwmmxt_set_mup();
1935 gen_op_iwmmxt_set_cup();
1937 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1938 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1939 wrd
= (insn
>> 12) & 0xf;
1940 rd0
= (insn
>> 16) & 0xf;
1941 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1942 switch ((insn
>> 22) & 3) {
1944 if (insn
& (1 << 21))
1945 gen_op_iwmmxt_unpacklsb_M0();
1947 gen_op_iwmmxt_unpacklub_M0();
1950 if (insn
& (1 << 21))
1951 gen_op_iwmmxt_unpacklsw_M0();
1953 gen_op_iwmmxt_unpackluw_M0();
1956 if (insn
& (1 << 21))
1957 gen_op_iwmmxt_unpacklsl_M0();
1959 gen_op_iwmmxt_unpacklul_M0();
1964 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1965 gen_op_iwmmxt_set_mup();
1966 gen_op_iwmmxt_set_cup();
1968 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1969 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1970 wrd
= (insn
>> 12) & 0xf;
1971 rd0
= (insn
>> 16) & 0xf;
1972 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1973 switch ((insn
>> 22) & 3) {
1975 if (insn
& (1 << 21))
1976 gen_op_iwmmxt_unpackhsb_M0();
1978 gen_op_iwmmxt_unpackhub_M0();
1981 if (insn
& (1 << 21))
1982 gen_op_iwmmxt_unpackhsw_M0();
1984 gen_op_iwmmxt_unpackhuw_M0();
1987 if (insn
& (1 << 21))
1988 gen_op_iwmmxt_unpackhsl_M0();
1990 gen_op_iwmmxt_unpackhul_M0();
1995 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2000 case 0x214: case 0x614: case 0xa14: case 0xe14:
2001 if (((insn
>> 22) & 3) == 0)
2003 wrd
= (insn
>> 12) & 0xf;
2004 rd0
= (insn
>> 16) & 0xf;
2005 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2006 tmp
= tcg_temp_new_i32();
2007 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2008 tcg_temp_free_i32(tmp
);
2011 switch ((insn
>> 22) & 3) {
2013 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2016 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2019 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2022 tcg_temp_free_i32(tmp
);
2023 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2024 gen_op_iwmmxt_set_mup();
2025 gen_op_iwmmxt_set_cup();
2027 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2028 case 0x014: case 0x414: case 0x814: case 0xc14:
2029 if (((insn
>> 22) & 3) == 0)
2031 wrd
= (insn
>> 12) & 0xf;
2032 rd0
= (insn
>> 16) & 0xf;
2033 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2034 tmp
= tcg_temp_new_i32();
2035 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2036 tcg_temp_free_i32(tmp
);
2039 switch ((insn
>> 22) & 3) {
2041 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2044 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2047 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2050 tcg_temp_free_i32(tmp
);
2051 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2055 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2056 case 0x114: case 0x514: case 0x914: case 0xd14:
2057 if (((insn
>> 22) & 3) == 0)
2059 wrd
= (insn
>> 12) & 0xf;
2060 rd0
= (insn
>> 16) & 0xf;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2062 tmp
= tcg_temp_new_i32();
2063 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2064 tcg_temp_free_i32(tmp
);
2067 switch ((insn
>> 22) & 3) {
2069 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2072 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2075 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2078 tcg_temp_free_i32(tmp
);
2079 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2080 gen_op_iwmmxt_set_mup();
2081 gen_op_iwmmxt_set_cup();
2083 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2084 case 0x314: case 0x714: case 0xb14: case 0xf14:
2085 if (((insn
>> 22) & 3) == 0)
2087 wrd
= (insn
>> 12) & 0xf;
2088 rd0
= (insn
>> 16) & 0xf;
2089 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2090 tmp
= tcg_temp_new_i32();
2091 switch ((insn
>> 22) & 3) {
2093 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2094 tcg_temp_free_i32(tmp
);
2097 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2100 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2101 tcg_temp_free_i32(tmp
);
2104 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2107 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2108 tcg_temp_free_i32(tmp
);
2111 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2114 tcg_temp_free_i32(tmp
);
2115 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2116 gen_op_iwmmxt_set_mup();
2117 gen_op_iwmmxt_set_cup();
2119 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2120 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2121 wrd
= (insn
>> 12) & 0xf;
2122 rd0
= (insn
>> 16) & 0xf;
2123 rd1
= (insn
>> 0) & 0xf;
2124 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2125 switch ((insn
>> 22) & 3) {
2127 if (insn
& (1 << 21))
2128 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2130 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2133 if (insn
& (1 << 21))
2134 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2136 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2139 if (insn
& (1 << 21))
2140 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2142 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2148 gen_op_iwmmxt_set_mup();
2150 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2151 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2152 wrd
= (insn
>> 12) & 0xf;
2153 rd0
= (insn
>> 16) & 0xf;
2154 rd1
= (insn
>> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2156 switch ((insn
>> 22) & 3) {
2158 if (insn
& (1 << 21))
2159 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2161 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2164 if (insn
& (1 << 21))
2165 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2167 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2170 if (insn
& (1 << 21))
2171 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2173 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2178 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2179 gen_op_iwmmxt_set_mup();
2181 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2182 case 0x402: case 0x502: case 0x602: case 0x702:
2183 wrd
= (insn
>> 12) & 0xf;
2184 rd0
= (insn
>> 16) & 0xf;
2185 rd1
= (insn
>> 0) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2187 tmp
= tcg_const_i32((insn
>> 20) & 3);
2188 iwmmxt_load_reg(cpu_V1
, rd1
);
2189 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2191 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2192 gen_op_iwmmxt_set_mup();
2194 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2195 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2196 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2197 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2198 wrd
= (insn
>> 12) & 0xf;
2199 rd0
= (insn
>> 16) & 0xf;
2200 rd1
= (insn
>> 0) & 0xf;
2201 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2202 switch ((insn
>> 20) & 0xf) {
2204 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2207 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2210 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2213 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2216 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2219 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2222 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2225 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2228 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2233 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2234 gen_op_iwmmxt_set_mup();
2235 gen_op_iwmmxt_set_cup();
2237 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2238 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2239 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2240 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2241 wrd
= (insn
>> 12) & 0xf;
2242 rd0
= (insn
>> 16) & 0xf;
2243 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2244 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2245 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2247 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2248 gen_op_iwmmxt_set_mup();
2249 gen_op_iwmmxt_set_cup();
2251 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2252 case 0x418: case 0x518: case 0x618: case 0x718:
2253 case 0x818: case 0x918: case 0xa18: case 0xb18:
2254 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2255 wrd
= (insn
>> 12) & 0xf;
2256 rd0
= (insn
>> 16) & 0xf;
2257 rd1
= (insn
>> 0) & 0xf;
2258 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2259 switch ((insn
>> 20) & 0xf) {
2261 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2264 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2267 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2270 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2273 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2276 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2279 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2282 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2285 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2290 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2291 gen_op_iwmmxt_set_mup();
2292 gen_op_iwmmxt_set_cup();
2294 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2295 case 0x408: case 0x508: case 0x608: case 0x708:
2296 case 0x808: case 0x908: case 0xa08: case 0xb08:
2297 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2298 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2300 wrd
= (insn
>> 12) & 0xf;
2301 rd0
= (insn
>> 16) & 0xf;
2302 rd1
= (insn
>> 0) & 0xf;
2303 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2304 switch ((insn
>> 22) & 3) {
2306 if (insn
& (1 << 21))
2307 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2309 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2312 if (insn
& (1 << 21))
2313 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2315 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2318 if (insn
& (1 << 21))
2319 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2321 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2328 case 0x201: case 0x203: case 0x205: case 0x207:
2329 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2330 case 0x211: case 0x213: case 0x215: case 0x217:
2331 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2332 wrd
= (insn
>> 5) & 0xf;
2333 rd0
= (insn
>> 12) & 0xf;
2334 rd1
= (insn
>> 0) & 0xf;
2335 if (rd0
== 0xf || rd1
== 0xf)
2337 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2338 tmp
= load_reg(s
, rd0
);
2339 tmp2
= load_reg(s
, rd1
);
2340 switch ((insn
>> 16) & 0xf) {
2341 case 0x0: /* TMIA */
2342 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2344 case 0x8: /* TMIAPH */
2345 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2347 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2348 if (insn
& (1 << 16))
2349 tcg_gen_shri_i32(tmp
, tmp
, 16);
2350 if (insn
& (1 << 17))
2351 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2352 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2355 tcg_temp_free_i32(tmp2
);
2356 tcg_temp_free_i32(tmp
);
2359 tcg_temp_free_i32(tmp2
);
2360 tcg_temp_free_i32(tmp
);
2361 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2362 gen_op_iwmmxt_set_mup();
2371 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2372 (ie. an undefined instruction). */
2373 static int disas_dsp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2375 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2378 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2379 /* Multiply with Internal Accumulate Format */
2380 rd0
= (insn
>> 12) & 0xf;
2382 acc
= (insn
>> 5) & 7;
2387 tmp
= load_reg(s
, rd0
);
2388 tmp2
= load_reg(s
, rd1
);
2389 switch ((insn
>> 16) & 0xf) {
2391 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2393 case 0x8: /* MIAPH */
2394 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2396 case 0xc: /* MIABB */
2397 case 0xd: /* MIABT */
2398 case 0xe: /* MIATB */
2399 case 0xf: /* MIATT */
2400 if (insn
& (1 << 16))
2401 tcg_gen_shri_i32(tmp
, tmp
, 16);
2402 if (insn
& (1 << 17))
2403 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2404 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2409 tcg_temp_free_i32(tmp2
);
2410 tcg_temp_free_i32(tmp
);
2412 gen_op_iwmmxt_movq_wRn_M0(acc
);
2416 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2417 /* Internal Accumulator Access Format */
2418 rdhi
= (insn
>> 16) & 0xf;
2419 rdlo
= (insn
>> 12) & 0xf;
2425 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2426 iwmmxt_load_reg(cpu_V0
, acc
);
2427 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2428 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2429 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2430 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2432 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2433 iwmmxt_store_reg(cpu_V0
, acc
);
2441 /* Disassemble system coprocessor instruction. Return nonzero if
2442 instruction is not defined. */
2443 static int disas_cp_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2446 uint32_t rd
= (insn
>> 12) & 0xf;
2447 uint32_t cp
= (insn
>> 8) & 0xf;
2452 if (insn
& ARM_CP_RW_BIT
) {
2453 if (!env
->cp
[cp
].cp_read
)
2455 gen_set_pc_im(s
->pc
);
2456 tmp
= tcg_temp_new_i32();
2457 tmp2
= tcg_const_i32(insn
);
2458 gen_helper_get_cp(tmp
, cpu_env
, tmp2
);
2459 tcg_temp_free(tmp2
);
2460 store_reg(s
, rd
, tmp
);
2462 if (!env
->cp
[cp
].cp_write
)
2464 gen_set_pc_im(s
->pc
);
2465 tmp
= load_reg(s
, rd
);
2466 tmp2
= tcg_const_i32(insn
);
2467 gen_helper_set_cp(cpu_env
, tmp2
, tmp
);
2468 tcg_temp_free(tmp2
);
2469 tcg_temp_free_i32(tmp
);
2474 static int cp15_user_ok(CPUState
*env
, uint32_t insn
)
2476 int cpn
= (insn
>> 16) & 0xf;
2477 int cpm
= insn
& 0xf;
2478 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2480 if (arm_feature(env
, ARM_FEATURE_V7
) && cpn
== 9) {
2481 /* Performance monitor registers fall into three categories:
2482 * (a) always UNDEF in usermode
2483 * (b) UNDEF only if PMUSERENR.EN is 0
2484 * (c) always read OK and UNDEF on write (PMUSERENR only)
2486 if ((cpm
== 12 && (op
< 6)) ||
2487 (cpm
== 13 && (op
< 3))) {
2488 return env
->cp15
.c9_pmuserenr
;
2489 } else if (cpm
== 14 && op
== 0 && (insn
& ARM_CP_RW_BIT
)) {
2490 /* PMUSERENR, read only */
2496 if (cpn
== 13 && cpm
== 0) {
2498 if (op
== 2 || (op
== 3 && (insn
& ARM_CP_RW_BIT
)))
2504 static int cp15_tls_load_store(CPUState
*env
, DisasContext
*s
, uint32_t insn
, uint32_t rd
)
2507 int cpn
= (insn
>> 16) & 0xf;
2508 int cpm
= insn
& 0xf;
2509 int op
= ((insn
>> 5) & 7) | ((insn
>> 18) & 0x38);
2511 if (!arm_feature(env
, ARM_FEATURE_V6K
))
2514 if (!(cpn
== 13 && cpm
== 0))
2517 if (insn
& ARM_CP_RW_BIT
) {
2520 tmp
= load_cpu_field(cp15
.c13_tls1
);
2523 tmp
= load_cpu_field(cp15
.c13_tls2
);
2526 tmp
= load_cpu_field(cp15
.c13_tls3
);
2531 store_reg(s
, rd
, tmp
);
2534 tmp
= load_reg(s
, rd
);
2537 store_cpu_field(tmp
, cp15
.c13_tls1
);
2540 store_cpu_field(tmp
, cp15
.c13_tls2
);
2543 store_cpu_field(tmp
, cp15
.c13_tls3
);
2546 tcg_temp_free_i32(tmp
);
2553 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2554 instruction is not defined. */
2555 static int disas_cp15_insn(CPUState
*env
, DisasContext
*s
, uint32_t insn
)
2560 /* M profile cores use memory mapped registers instead of cp15. */
2561 if (arm_feature(env
, ARM_FEATURE_M
))
2564 if ((insn
& (1 << 25)) == 0) {
2565 if (insn
& (1 << 20)) {
2569 /* mcrr. Used for block cache operations, so implement as no-op. */
2572 if ((insn
& (1 << 4)) == 0) {
2576 /* We special case a number of cp15 instructions which were used
2577 * for things which are real instructions in ARMv7. This allows
2578 * them to work in linux-user mode which doesn't provide functional
2579 * get_cp15/set_cp15 helpers, and is more efficient anyway.
2581 switch ((insn
& 0x0fff0fff)) {
2583 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2584 * In v7, this must NOP.
2589 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
2590 /* Wait for interrupt. */
2591 gen_set_pc_im(s
->pc
);
2592 s
->is_jmp
= DISAS_WFI
;
2596 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2597 * so this is slightly over-broad.
2599 if (!IS_USER(s
) && !arm_feature(env
, ARM_FEATURE_V6
)) {
2600 /* Wait for interrupt. */
2601 gen_set_pc_im(s
->pc
);
2602 s
->is_jmp
= DISAS_WFI
;
2605 /* Otherwise continue to handle via helper function.
2606 * In particular, on v7 and some v6 cores this is one of
2607 * the VA-PA registers.
2611 /* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */
2612 if (arm_feature(env
, ARM_FEATURE_V6
)) {
2613 return IS_USER(s
) ? 1 : 0;
2616 case 0x0e070f95: /* 0,c7,c5,4 : ISB */
2617 case 0x0e070f9a: /* 0,c7,c10,4: DSB */
2618 case 0x0e070fba: /* 0,c7,c10,5: DMB */
2619 /* Barriers in both v6 and v7 */
2620 if (arm_feature(env
, ARM_FEATURE_V6
)) {
2628 if (IS_USER(s
) && !cp15_user_ok(env
, insn
)) {
2632 rd
= (insn
>> 12) & 0xf;
2634 if (cp15_tls_load_store(env
, s
, insn
, rd
))
2637 tmp2
= tcg_const_i32(insn
);
2638 if (insn
& ARM_CP_RW_BIT
) {
2639 tmp
= tcg_temp_new_i32();
2640 gen_helper_get_cp15(tmp
, cpu_env
, tmp2
);
2641 /* If the destination register is r15 then sets condition codes. */
2643 store_reg(s
, rd
, tmp
);
2645 tcg_temp_free_i32(tmp
);
2647 tmp
= load_reg(s
, rd
);
2648 gen_helper_set_cp15(cpu_env
, tmp2
, tmp
);
2649 tcg_temp_free_i32(tmp
);
2650 /* Normally we would always end the TB here, but Linux
2651 * arch/arm/mach-pxa/sleep.S expects two instructions following
2652 * an MMU enable to execute from cache. Imitate this behaviour. */
2653 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) ||
2654 (insn
& 0x0fff0fff) != 0x0e010f10)
2657 tcg_temp_free_i32(tmp2
);
2661 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2662 #define VFP_SREG(insn, bigbit, smallbit) \
2663 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2664 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2665 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2666 reg = (((insn) >> (bigbit)) & 0x0f) \
2667 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2669 if (insn & (1 << (smallbit))) \
2671 reg = ((insn) >> (bigbit)) & 0x0f; \
2674 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2675 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2676 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2677 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2678 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2679 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2681 /* Move between integer and VFP cores. */
2682 static TCGv
gen_vfp_mrs(void)
2684 TCGv tmp
= tcg_temp_new_i32();
2685 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2689 static void gen_vfp_msr(TCGv tmp
)
2691 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2692 tcg_temp_free_i32(tmp
);
2695 static void gen_neon_dup_u8(TCGv var
, int shift
)
2697 TCGv tmp
= tcg_temp_new_i32();
2699 tcg_gen_shri_i32(var
, var
, shift
);
2700 tcg_gen_ext8u_i32(var
, var
);
2701 tcg_gen_shli_i32(tmp
, var
, 8);
2702 tcg_gen_or_i32(var
, var
, tmp
);
2703 tcg_gen_shli_i32(tmp
, var
, 16);
2704 tcg_gen_or_i32(var
, var
, tmp
);
2705 tcg_temp_free_i32(tmp
);
2708 static void gen_neon_dup_low16(TCGv var
)
2710 TCGv tmp
= tcg_temp_new_i32();
2711 tcg_gen_ext16u_i32(var
, var
);
2712 tcg_gen_shli_i32(tmp
, var
, 16);
2713 tcg_gen_or_i32(var
, var
, tmp
);
2714 tcg_temp_free_i32(tmp
);
2717 static void gen_neon_dup_high16(TCGv var
)
2719 TCGv tmp
= tcg_temp_new_i32();
2720 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2721 tcg_gen_shri_i32(tmp
, var
, 16);
2722 tcg_gen_or_i32(var
, var
, tmp
);
2723 tcg_temp_free_i32(tmp
);
2726 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2728 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2732 tmp
= gen_ld8u(addr
, IS_USER(s
));
2733 gen_neon_dup_u8(tmp
, 0);
2736 tmp
= gen_ld16u(addr
, IS_USER(s
));
2737 gen_neon_dup_low16(tmp
);
2740 tmp
= gen_ld32(addr
, IS_USER(s
));
2742 default: /* Avoid compiler warnings. */
2748 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2749 (ie. an undefined instruction). */
2750 static int disas_vfp_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
2752 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2758 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2761 if (!s
->vfp_enabled
) {
2762 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2763 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2765 rn
= (insn
>> 16) & 0xf;
2766 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2767 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2770 dp
= ((insn
& 0xf00) == 0xb00);
2771 switch ((insn
>> 24) & 0xf) {
2773 if (insn
& (1 << 4)) {
2774 /* single register transfer */
2775 rd
= (insn
>> 12) & 0xf;
2780 VFP_DREG_N(rn
, insn
);
2783 if (insn
& 0x00c00060
2784 && !arm_feature(env
, ARM_FEATURE_NEON
))
2787 pass
= (insn
>> 21) & 1;
2788 if (insn
& (1 << 22)) {
2790 offset
= ((insn
>> 5) & 3) * 8;
2791 } else if (insn
& (1 << 5)) {
2793 offset
= (insn
& (1 << 6)) ? 16 : 0;
2798 if (insn
& ARM_CP_RW_BIT
) {
2800 tmp
= neon_load_reg(rn
, pass
);
2804 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2805 if (insn
& (1 << 23))
2811 if (insn
& (1 << 23)) {
2813 tcg_gen_shri_i32(tmp
, tmp
, 16);
2819 tcg_gen_sari_i32(tmp
, tmp
, 16);
2828 store_reg(s
, rd
, tmp
);
2831 tmp
= load_reg(s
, rd
);
2832 if (insn
& (1 << 23)) {
2835 gen_neon_dup_u8(tmp
, 0);
2836 } else if (size
== 1) {
2837 gen_neon_dup_low16(tmp
);
2839 for (n
= 0; n
<= pass
* 2; n
++) {
2840 tmp2
= tcg_temp_new_i32();
2841 tcg_gen_mov_i32(tmp2
, tmp
);
2842 neon_store_reg(rn
, n
, tmp2
);
2844 neon_store_reg(rn
, n
, tmp
);
2849 tmp2
= neon_load_reg(rn
, pass
);
2850 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xff);
2851 tcg_temp_free_i32(tmp2
);
2854 tmp2
= neon_load_reg(rn
, pass
);
2855 gen_bfi(tmp
, tmp2
, tmp
, offset
, 0xffff);
2856 tcg_temp_free_i32(tmp2
);
2861 neon_store_reg(rn
, pass
, tmp
);
2865 if ((insn
& 0x6f) != 0x00)
2867 rn
= VFP_SREG_N(insn
);
2868 if (insn
& ARM_CP_RW_BIT
) {
2870 if (insn
& (1 << 21)) {
2871 /* system register */
2876 /* VFP2 allows access to FSID from userspace.
2877 VFP3 restricts all id registers to privileged
2880 && arm_feature(env
, ARM_FEATURE_VFP3
))
2882 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2887 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2889 case ARM_VFP_FPINST
:
2890 case ARM_VFP_FPINST2
:
2891 /* Not present in VFP3. */
2893 || arm_feature(env
, ARM_FEATURE_VFP3
))
2895 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2899 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2900 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2902 tmp
= tcg_temp_new_i32();
2903 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2909 || !arm_feature(env
, ARM_FEATURE_VFP3
))
2911 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2917 gen_mov_F0_vreg(0, rn
);
2918 tmp
= gen_vfp_mrs();
2921 /* Set the 4 flag bits in the CPSR. */
2923 tcg_temp_free_i32(tmp
);
2925 store_reg(s
, rd
, tmp
);
2929 tmp
= load_reg(s
, rd
);
2930 if (insn
& (1 << 21)) {
2932 /* system register */
2937 /* Writes are ignored. */
2940 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2941 tcg_temp_free_i32(tmp
);
2947 /* TODO: VFP subarchitecture support.
2948 * For now, keep the EN bit only */
2949 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2950 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2953 case ARM_VFP_FPINST
:
2954 case ARM_VFP_FPINST2
:
2955 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2962 gen_mov_vreg_F0(0, rn
);
2967 /* data processing */
2968 /* The opcode is in bits 23, 21, 20 and 6. */
2969 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2973 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2975 /* rn is register number */
2976 VFP_DREG_N(rn
, insn
);
2979 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2980 /* Integer or single precision destination. */
2981 rd
= VFP_SREG_D(insn
);
2983 VFP_DREG_D(rd
, insn
);
2986 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2987 /* VCVT from int is always from S reg regardless of dp bit.
2988 * VCVT with immediate frac_bits has same format as SREG_M
2990 rm
= VFP_SREG_M(insn
);
2992 VFP_DREG_M(rm
, insn
);
2995 rn
= VFP_SREG_N(insn
);
2996 if (op
== 15 && rn
== 15) {
2997 /* Double precision destination. */
2998 VFP_DREG_D(rd
, insn
);
3000 rd
= VFP_SREG_D(insn
);
3002 /* NB that we implicitly rely on the encoding for the frac_bits
3003 * in VCVT of fixed to float being the same as that of an SREG_M
3005 rm
= VFP_SREG_M(insn
);
3008 veclen
= s
->vec_len
;
3009 if (op
== 15 && rn
> 3)
3012 /* Shut up compiler warnings. */
3023 /* Figure out what type of vector operation this is. */
3024 if ((rd
& bank_mask
) == 0) {
3029 delta_d
= (s
->vec_stride
>> 1) + 1;
3031 delta_d
= s
->vec_stride
+ 1;
3033 if ((rm
& bank_mask
) == 0) {
3034 /* mixed scalar/vector */
3043 /* Load the initial operands. */
3048 /* Integer source */
3049 gen_mov_F0_vreg(0, rm
);
3054 gen_mov_F0_vreg(dp
, rd
);
3055 gen_mov_F1_vreg(dp
, rm
);
3059 /* Compare with zero */
3060 gen_mov_F0_vreg(dp
, rd
);
3071 /* Source and destination the same. */
3072 gen_mov_F0_vreg(dp
, rd
);
3075 /* One source operand. */
3076 gen_mov_F0_vreg(dp
, rm
);
3080 /* Two source operands. */
3081 gen_mov_F0_vreg(dp
, rn
);
3082 gen_mov_F1_vreg(dp
, rm
);
3086 /* Perform the calculation. */
3088 case 0: /* VMLA: fd + (fn * fm) */
3089 /* Note that order of inputs to the add matters for NaNs */
3091 gen_mov_F0_vreg(dp
, rd
);
3094 case 1: /* VMLS: fd + -(fn * fm) */
3097 gen_mov_F0_vreg(dp
, rd
);
3100 case 2: /* VNMLS: -fd + (fn * fm) */
3101 /* Note that it isn't valid to replace (-A + B) with (B - A)
3102 * or similar plausible looking simplifications
3103 * because this will give wrong results for NaNs.
3106 gen_mov_F0_vreg(dp
, rd
);
3110 case 3: /* VNMLA: -fd + -(fn * fm) */
3113 gen_mov_F0_vreg(dp
, rd
);
3117 case 4: /* mul: fn * fm */
3120 case 5: /* nmul: -(fn * fm) */
3124 case 6: /* add: fn + fm */
3127 case 7: /* sub: fn - fm */
3130 case 8: /* div: fn / fm */
3133 case 14: /* fconst */
3134 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3137 n
= (insn
<< 12) & 0x80000000;
3138 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3145 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3152 tcg_gen_movi_i32(cpu_F0s
, n
);
3155 case 15: /* extension space */
3169 case 4: /* vcvtb.f32.f16 */
3170 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3172 tmp
= gen_vfp_mrs();
3173 tcg_gen_ext16u_i32(tmp
, tmp
);
3174 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3175 tcg_temp_free_i32(tmp
);
3177 case 5: /* vcvtt.f32.f16 */
3178 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3180 tmp
= gen_vfp_mrs();
3181 tcg_gen_shri_i32(tmp
, tmp
, 16);
3182 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3183 tcg_temp_free_i32(tmp
);
3185 case 6: /* vcvtb.f16.f32 */
3186 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3188 tmp
= tcg_temp_new_i32();
3189 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3190 gen_mov_F0_vreg(0, rd
);
3191 tmp2
= gen_vfp_mrs();
3192 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3193 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3194 tcg_temp_free_i32(tmp2
);
3197 case 7: /* vcvtt.f16.f32 */
3198 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
))
3200 tmp
= tcg_temp_new_i32();
3201 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3202 tcg_gen_shli_i32(tmp
, tmp
, 16);
3203 gen_mov_F0_vreg(0, rd
);
3204 tmp2
= gen_vfp_mrs();
3205 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3206 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3207 tcg_temp_free_i32(tmp2
);
3219 case 11: /* cmpez */
3223 case 15: /* single<->double conversion */
3225 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3227 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3229 case 16: /* fuito */
3230 gen_vfp_uito(dp
, 0);
3232 case 17: /* fsito */
3233 gen_vfp_sito(dp
, 0);
3235 case 20: /* fshto */
3236 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3238 gen_vfp_shto(dp
, 16 - rm
, 0);
3240 case 21: /* fslto */
3241 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3243 gen_vfp_slto(dp
, 32 - rm
, 0);
3245 case 22: /* fuhto */
3246 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3248 gen_vfp_uhto(dp
, 16 - rm
, 0);
3250 case 23: /* fulto */
3251 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3253 gen_vfp_ulto(dp
, 32 - rm
, 0);
3255 case 24: /* ftoui */
3256 gen_vfp_toui(dp
, 0);
3258 case 25: /* ftouiz */
3259 gen_vfp_touiz(dp
, 0);
3261 case 26: /* ftosi */
3262 gen_vfp_tosi(dp
, 0);
3264 case 27: /* ftosiz */
3265 gen_vfp_tosiz(dp
, 0);
3267 case 28: /* ftosh */
3268 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3270 gen_vfp_tosh(dp
, 16 - rm
, 0);
3272 case 29: /* ftosl */
3273 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3275 gen_vfp_tosl(dp
, 32 - rm
, 0);
3277 case 30: /* ftouh */
3278 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3280 gen_vfp_touh(dp
, 16 - rm
, 0);
3282 case 31: /* ftoul */
3283 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3285 gen_vfp_toul(dp
, 32 - rm
, 0);
3287 default: /* undefined */
3288 printf ("rn:%d\n", rn
);
3292 default: /* undefined */
3293 printf ("op:%d\n", op
);
3297 /* Write back the result. */
3298 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3299 ; /* Comparison, do nothing. */
3300 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3301 /* VCVT double to int: always integer result. */
3302 gen_mov_vreg_F0(0, rd
);
3303 else if (op
== 15 && rn
== 15)
3305 gen_mov_vreg_F0(!dp
, rd
);
3307 gen_mov_vreg_F0(dp
, rd
);
3309 /* break out of the loop if we have finished */
3313 if (op
== 15 && delta_m
== 0) {
3314 /* single source one-many */
3316 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3318 gen_mov_vreg_F0(dp
, rd
);
3322 /* Setup the next operands. */
3324 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3328 /* One source operand. */
3329 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3331 gen_mov_F0_vreg(dp
, rm
);
3333 /* Two source operands. */
3334 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3336 gen_mov_F0_vreg(dp
, rn
);
3338 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3340 gen_mov_F1_vreg(dp
, rm
);
3348 if ((insn
& 0x03e00000) == 0x00400000) {
3349 /* two-register transfer */
3350 rn
= (insn
>> 16) & 0xf;
3351 rd
= (insn
>> 12) & 0xf;
3353 VFP_DREG_M(rm
, insn
);
3355 rm
= VFP_SREG_M(insn
);
3358 if (insn
& ARM_CP_RW_BIT
) {
3361 gen_mov_F0_vreg(0, rm
* 2);
3362 tmp
= gen_vfp_mrs();
3363 store_reg(s
, rd
, tmp
);
3364 gen_mov_F0_vreg(0, rm
* 2 + 1);
3365 tmp
= gen_vfp_mrs();
3366 store_reg(s
, rn
, tmp
);
3368 gen_mov_F0_vreg(0, rm
);
3369 tmp
= gen_vfp_mrs();
3370 store_reg(s
, rd
, tmp
);
3371 gen_mov_F0_vreg(0, rm
+ 1);
3372 tmp
= gen_vfp_mrs();
3373 store_reg(s
, rn
, tmp
);
3378 tmp
= load_reg(s
, rd
);
3380 gen_mov_vreg_F0(0, rm
* 2);
3381 tmp
= load_reg(s
, rn
);
3383 gen_mov_vreg_F0(0, rm
* 2 + 1);
3385 tmp
= load_reg(s
, rd
);
3387 gen_mov_vreg_F0(0, rm
);
3388 tmp
= load_reg(s
, rn
);
3390 gen_mov_vreg_F0(0, rm
+ 1);
3395 rn
= (insn
>> 16) & 0xf;
3397 VFP_DREG_D(rd
, insn
);
3399 rd
= VFP_SREG_D(insn
);
3400 if (s
->thumb
&& rn
== 15) {
3401 addr
= tcg_temp_new_i32();
3402 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3404 addr
= load_reg(s
, rn
);
3406 if ((insn
& 0x01200000) == 0x01000000) {
3407 /* Single load/store */
3408 offset
= (insn
& 0xff) << 2;
3409 if ((insn
& (1 << 23)) == 0)
3411 tcg_gen_addi_i32(addr
, addr
, offset
);
3412 if (insn
& (1 << 20)) {
3413 gen_vfp_ld(s
, dp
, addr
);
3414 gen_mov_vreg_F0(dp
, rd
);
3416 gen_mov_F0_vreg(dp
, rd
);
3417 gen_vfp_st(s
, dp
, addr
);
3419 tcg_temp_free_i32(addr
);
3421 /* load/store multiple */
3423 n
= (insn
>> 1) & 0x7f;
3427 if (insn
& (1 << 24)) /* pre-decrement */
3428 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3434 for (i
= 0; i
< n
; i
++) {
3435 if (insn
& ARM_CP_RW_BIT
) {
3437 gen_vfp_ld(s
, dp
, addr
);
3438 gen_mov_vreg_F0(dp
, rd
+ i
);
3441 gen_mov_F0_vreg(dp
, rd
+ i
);
3442 gen_vfp_st(s
, dp
, addr
);
3444 tcg_gen_addi_i32(addr
, addr
, offset
);
3446 if (insn
& (1 << 21)) {
3448 if (insn
& (1 << 24))
3449 offset
= -offset
* n
;
3450 else if (dp
&& (insn
& 1))
3456 tcg_gen_addi_i32(addr
, addr
, offset
);
3457 store_reg(s
, rn
, addr
);
3459 tcg_temp_free_i32(addr
);
3465 /* Should never happen. */
3471 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3473 TranslationBlock
*tb
;
3476 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3478 gen_set_pc_im(dest
);
3479 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3481 gen_set_pc_im(dest
);
3486 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3488 if (unlikely(s
->singlestep_enabled
)) {
3489 /* An indirect jump so that we still trigger the debug exception. */
3494 gen_goto_tb(s
, 0, dest
);
3495 s
->is_jmp
= DISAS_TB_JUMP
;
3499 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3502 tcg_gen_sari_i32(t0
, t0
, 16);
3506 tcg_gen_sari_i32(t1
, t1
, 16);
3509 tcg_gen_mul_i32(t0
, t0
, t1
);
3512 /* Return the mask of PSR bits set by a MSR instruction. */
3513 static uint32_t msr_mask(CPUState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3517 if (flags
& (1 << 0))
3519 if (flags
& (1 << 1))
3521 if (flags
& (1 << 2))
3523 if (flags
& (1 << 3))
3526 /* Mask out undefined bits. */
3527 mask
&= ~CPSR_RESERVED
;
3528 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3530 if (!arm_feature(env
, ARM_FEATURE_V5
))
3531 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3532 if (!arm_feature(env
, ARM_FEATURE_V6
))
3533 mask
&= ~(CPSR_E
| CPSR_GE
);
3534 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3536 /* Mask out execution state bits. */
3539 /* Mask out privileged bits. */
3545 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3546 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3550 /* ??? This is also undefined in system mode. */
3554 tmp
= load_cpu_field(spsr
);
3555 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3556 tcg_gen_andi_i32(t0
, t0
, mask
);
3557 tcg_gen_or_i32(tmp
, tmp
, t0
);
3558 store_cpu_field(tmp
, spsr
);
3560 gen_set_cpsr(t0
, mask
);
3562 tcg_temp_free_i32(t0
);
3567 /* Returns nonzero if access to the PSR is not permitted. */
3568 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3571 tmp
= tcg_temp_new_i32();
3572 tcg_gen_movi_i32(tmp
, val
);
3573 return gen_set_psr(s
, mask
, spsr
, tmp
);
3576 /* Generate an old-style exception return. Marks pc as dead. */
3577 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3580 store_reg(s
, 15, pc
);
3581 tmp
= load_cpu_field(spsr
);
3582 gen_set_cpsr(tmp
, 0xffffffff);
3583 tcg_temp_free_i32(tmp
);
3584 s
->is_jmp
= DISAS_UPDATE
;
3587 /* Generate a v6 exception return. Marks both values as dead. */
3588 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3590 gen_set_cpsr(cpsr
, 0xffffffff);
3591 tcg_temp_free_i32(cpsr
);
3592 store_reg(s
, 15, pc
);
3593 s
->is_jmp
= DISAS_UPDATE
;
3597 gen_set_condexec (DisasContext
*s
)
3599 if (s
->condexec_mask
) {
3600 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3601 TCGv tmp
= tcg_temp_new_i32();
3602 tcg_gen_movi_i32(tmp
, val
);
3603 store_cpu_field(tmp
, condexec_bits
);
3607 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3609 gen_set_condexec(s
);
3610 gen_set_pc_im(s
->pc
- offset
);
3611 gen_exception(excp
);
3612 s
->is_jmp
= DISAS_JUMP
;
3615 static void gen_nop_hint(DisasContext
*s
, int val
)
3619 gen_set_pc_im(s
->pc
);
3620 s
->is_jmp
= DISAS_WFI
;
3624 /* TODO: Implement SEV and WFE. May help SMP performance. */
3630 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3632 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3635 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3636 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3637 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3642 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3645 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3646 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3647 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3652 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3653 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3654 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3655 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3656 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3658 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3659 switch ((size << 1) | u) { \
3661 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3664 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3667 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3670 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3673 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3676 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3678 default: return 1; \
3681 #define GEN_NEON_INTEGER_OP(name) do { \
3682 switch ((size << 1) | u) { \
3684 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3687 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3690 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3693 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3696 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3699 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3701 default: return 1; \
3704 static TCGv
neon_load_scratch(int scratch
)
3706 TCGv tmp
= tcg_temp_new_i32();
3707 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3711 static void neon_store_scratch(int scratch
, TCGv var
)
3713 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3714 tcg_temp_free_i32(var
);
3717 static inline TCGv
neon_get_scalar(int size
, int reg
)
3721 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3723 gen_neon_dup_high16(tmp
);
3725 gen_neon_dup_low16(tmp
);
3728 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3733 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3736 if (!q
&& size
== 2) {
3739 tmp
= tcg_const_i32(rd
);
3740 tmp2
= tcg_const_i32(rm
);
3744 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3747 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3750 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3758 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3761 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3767 tcg_temp_free_i32(tmp
);
3768 tcg_temp_free_i32(tmp2
);
3772 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3775 if (!q
&& size
== 2) {
3778 tmp
= tcg_const_i32(rd
);
3779 tmp2
= tcg_const_i32(rm
);
3783 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3786 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3789 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3797 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3800 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3806 tcg_temp_free_i32(tmp
);
3807 tcg_temp_free_i32(tmp2
);
3811 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3815 rd
= tcg_temp_new_i32();
3816 tmp
= tcg_temp_new_i32();
3818 tcg_gen_shli_i32(rd
, t0
, 8);
3819 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3820 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3821 tcg_gen_or_i32(rd
, rd
, tmp
);
3823 tcg_gen_shri_i32(t1
, t1
, 8);
3824 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3825 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3826 tcg_gen_or_i32(t1
, t1
, tmp
);
3827 tcg_gen_mov_i32(t0
, rd
);
3829 tcg_temp_free_i32(tmp
);
3830 tcg_temp_free_i32(rd
);
3833 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3837 rd
= tcg_temp_new_i32();
3838 tmp
= tcg_temp_new_i32();
3840 tcg_gen_shli_i32(rd
, t0
, 16);
3841 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3842 tcg_gen_or_i32(rd
, rd
, tmp
);
3843 tcg_gen_shri_i32(t1
, t1
, 16);
3844 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3845 tcg_gen_or_i32(t1
, t1
, tmp
);
3846 tcg_gen_mov_i32(t0
, rd
);
3848 tcg_temp_free_i32(tmp
);
3849 tcg_temp_free_i32(rd
);
3857 } neon_ls_element_type
[11] = {
3871 /* Translate a NEON load/store element instruction. Return nonzero if the
3872 instruction is invalid. */
3873 static int disas_neon_ls_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
3892 if (!s
->vfp_enabled
)
3894 VFP_DREG_D(rd
, insn
);
3895 rn
= (insn
>> 16) & 0xf;
3897 load
= (insn
& (1 << 21)) != 0;
3898 if ((insn
& (1 << 23)) == 0) {
3899 /* Load store all elements. */
3900 op
= (insn
>> 8) & 0xf;
3901 size
= (insn
>> 6) & 3;
3904 /* Catch UNDEF cases for bad values of align field */
3907 if (((insn
>> 5) & 1) == 1) {
3912 if (((insn
>> 4) & 3) == 3) {
3919 nregs
= neon_ls_element_type
[op
].nregs
;
3920 interleave
= neon_ls_element_type
[op
].interleave
;
3921 spacing
= neon_ls_element_type
[op
].spacing
;
3922 if (size
== 3 && (interleave
| spacing
) != 1)
3924 addr
= tcg_temp_new_i32();
3925 load_reg_var(s
, addr
, rn
);
3926 stride
= (1 << size
) * interleave
;
3927 for (reg
= 0; reg
< nregs
; reg
++) {
3928 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3929 load_reg_var(s
, addr
, rn
);
3930 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3931 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3932 load_reg_var(s
, addr
, rn
);
3933 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3937 tmp64
= gen_ld64(addr
, IS_USER(s
));
3938 neon_store_reg64(tmp64
, rd
);
3939 tcg_temp_free_i64(tmp64
);
3941 tmp64
= tcg_temp_new_i64();
3942 neon_load_reg64(tmp64
, rd
);
3943 gen_st64(tmp64
, addr
, IS_USER(s
));
3945 tcg_gen_addi_i32(addr
, addr
, stride
);
3947 for (pass
= 0; pass
< 2; pass
++) {
3950 tmp
= gen_ld32(addr
, IS_USER(s
));
3951 neon_store_reg(rd
, pass
, tmp
);
3953 tmp
= neon_load_reg(rd
, pass
);
3954 gen_st32(tmp
, addr
, IS_USER(s
));
3956 tcg_gen_addi_i32(addr
, addr
, stride
);
3957 } else if (size
== 1) {
3959 tmp
= gen_ld16u(addr
, IS_USER(s
));
3960 tcg_gen_addi_i32(addr
, addr
, stride
);
3961 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3962 tcg_gen_addi_i32(addr
, addr
, stride
);
3963 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3964 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3965 tcg_temp_free_i32(tmp2
);
3966 neon_store_reg(rd
, pass
, tmp
);
3968 tmp
= neon_load_reg(rd
, pass
);
3969 tmp2
= tcg_temp_new_i32();
3970 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3971 gen_st16(tmp
, addr
, IS_USER(s
));
3972 tcg_gen_addi_i32(addr
, addr
, stride
);
3973 gen_st16(tmp2
, addr
, IS_USER(s
));
3974 tcg_gen_addi_i32(addr
, addr
, stride
);
3976 } else /* size == 0 */ {
3979 for (n
= 0; n
< 4; n
++) {
3980 tmp
= gen_ld8u(addr
, IS_USER(s
));
3981 tcg_gen_addi_i32(addr
, addr
, stride
);
3985 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3986 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3987 tcg_temp_free_i32(tmp
);
3990 neon_store_reg(rd
, pass
, tmp2
);
3992 tmp2
= neon_load_reg(rd
, pass
);
3993 for (n
= 0; n
< 4; n
++) {
3994 tmp
= tcg_temp_new_i32();
3996 tcg_gen_mov_i32(tmp
, tmp2
);
3998 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4000 gen_st8(tmp
, addr
, IS_USER(s
));
4001 tcg_gen_addi_i32(addr
, addr
, stride
);
4003 tcg_temp_free_i32(tmp2
);
4010 tcg_temp_free_i32(addr
);
4013 size
= (insn
>> 10) & 3;
4015 /* Load single element to all lanes. */
4016 int a
= (insn
>> 4) & 1;
4020 size
= (insn
>> 6) & 3;
4021 nregs
= ((insn
>> 8) & 3) + 1;
4024 if (nregs
!= 4 || a
== 0) {
4027 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4030 if (nregs
== 1 && a
== 1 && size
== 0) {
4033 if (nregs
== 3 && a
== 1) {
4036 addr
= tcg_temp_new_i32();
4037 load_reg_var(s
, addr
, rn
);
4039 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4040 tmp
= gen_load_and_replicate(s
, addr
, size
);
4041 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4042 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4043 if (insn
& (1 << 5)) {
4044 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4045 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4047 tcg_temp_free_i32(tmp
);
4049 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4050 stride
= (insn
& (1 << 5)) ? 2 : 1;
4051 for (reg
= 0; reg
< nregs
; reg
++) {
4052 tmp
= gen_load_and_replicate(s
, addr
, size
);
4053 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4054 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4055 tcg_temp_free_i32(tmp
);
4056 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4060 tcg_temp_free_i32(addr
);
4061 stride
= (1 << size
) * nregs
;
4063 /* Single element. */
4064 int idx
= (insn
>> 4) & 0xf;
4065 pass
= (insn
>> 7) & 1;
4068 shift
= ((insn
>> 5) & 3) * 8;
4072 shift
= ((insn
>> 6) & 1) * 16;
4073 stride
= (insn
& (1 << 5)) ? 2 : 1;
4077 stride
= (insn
& (1 << 6)) ? 2 : 1;
4082 nregs
= ((insn
>> 8) & 3) + 1;
4083 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4086 if (((idx
& (1 << size
)) != 0) ||
4087 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4092 if ((idx
& 1) != 0) {
4097 if (size
== 2 && (idx
& 2) != 0) {
4102 if ((size
== 2) && ((idx
& 3) == 3)) {
4109 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4110 /* Attempts to write off the end of the register file
4111 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4112 * the neon_load_reg() would write off the end of the array.
4116 addr
= tcg_temp_new_i32();
4117 load_reg_var(s
, addr
, rn
);
4118 for (reg
= 0; reg
< nregs
; reg
++) {
4122 tmp
= gen_ld8u(addr
, IS_USER(s
));
4125 tmp
= gen_ld16u(addr
, IS_USER(s
));
4128 tmp
= gen_ld32(addr
, IS_USER(s
));
4130 default: /* Avoid compiler warnings. */
4134 tmp2
= neon_load_reg(rd
, pass
);
4135 gen_bfi(tmp
, tmp2
, tmp
, shift
, size
? 0xffff : 0xff);
4136 tcg_temp_free_i32(tmp2
);
4138 neon_store_reg(rd
, pass
, tmp
);
4139 } else { /* Store */
4140 tmp
= neon_load_reg(rd
, pass
);
4142 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4145 gen_st8(tmp
, addr
, IS_USER(s
));
4148 gen_st16(tmp
, addr
, IS_USER(s
));
4151 gen_st32(tmp
, addr
, IS_USER(s
));
4156 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4158 tcg_temp_free_i32(addr
);
4159 stride
= nregs
* (1 << size
);
4165 base
= load_reg(s
, rn
);
4167 tcg_gen_addi_i32(base
, base
, stride
);
4170 index
= load_reg(s
, rm
);
4171 tcg_gen_add_i32(base
, base
, index
);
4172 tcg_temp_free_i32(index
);
4174 store_reg(s
, rn
, base
);
4179 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4180 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4182 tcg_gen_and_i32(t
, t
, c
);
4183 tcg_gen_andc_i32(f
, f
, c
);
4184 tcg_gen_or_i32(dest
, t
, f
);
4187 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4190 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4191 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4192 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4197 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4200 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4201 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4202 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4207 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4210 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4211 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4212 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4217 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4220 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4221 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4222 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4227 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4233 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4234 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4239 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4240 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4247 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4248 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4253 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4254 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4261 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4265 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4266 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4267 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4272 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4273 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4274 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4278 tcg_temp_free_i32(src
);
4281 static inline void gen_neon_addl(int size
)
4284 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4285 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4286 case 2: tcg_gen_add_i64(CPU_V001
); break;
4291 static inline void gen_neon_subl(int size
)
4294 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4295 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4296 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4301 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4304 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4305 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4306 case 2: gen_helper_neon_negl_u64(var
, var
); break;
4311 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4314 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4315 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4320 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4324 switch ((size
<< 1) | u
) {
4325 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4326 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4327 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4328 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4330 tmp
= gen_muls_i64_i32(a
, b
);
4331 tcg_gen_mov_i64(dest
, tmp
);
4332 tcg_temp_free_i64(tmp
);
4335 tmp
= gen_mulu_i64_i32(a
, b
);
4336 tcg_gen_mov_i64(dest
, tmp
);
4337 tcg_temp_free_i64(tmp
);
4342 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4343 Don't forget to clean them now. */
4345 tcg_temp_free_i32(a
);
4346 tcg_temp_free_i32(b
);
4350 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4354 gen_neon_unarrow_sats(size
, dest
, src
);
4356 gen_neon_narrow(size
, dest
, src
);
4360 gen_neon_narrow_satu(size
, dest
, src
);
4362 gen_neon_narrow_sats(size
, dest
, src
);
4367 /* Symbolic constants for op fields for Neon 3-register same-length.
4368 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4371 #define NEON_3R_VHADD 0
4372 #define NEON_3R_VQADD 1
4373 #define NEON_3R_VRHADD 2
4374 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4375 #define NEON_3R_VHSUB 4
4376 #define NEON_3R_VQSUB 5
4377 #define NEON_3R_VCGT 6
4378 #define NEON_3R_VCGE 7
4379 #define NEON_3R_VSHL 8
4380 #define NEON_3R_VQSHL 9
4381 #define NEON_3R_VRSHL 10
4382 #define NEON_3R_VQRSHL 11
4383 #define NEON_3R_VMAX 12
4384 #define NEON_3R_VMIN 13
4385 #define NEON_3R_VABD 14
4386 #define NEON_3R_VABA 15
4387 #define NEON_3R_VADD_VSUB 16
4388 #define NEON_3R_VTST_VCEQ 17
4389 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4390 #define NEON_3R_VMUL 19
4391 #define NEON_3R_VPMAX 20
4392 #define NEON_3R_VPMIN 21
4393 #define NEON_3R_VQDMULH_VQRDMULH 22
4394 #define NEON_3R_VPADD 23
4395 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4396 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4397 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4398 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4399 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4400 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4402 static const uint8_t neon_3r_sizes
[] = {
4403 [NEON_3R_VHADD
] = 0x7,
4404 [NEON_3R_VQADD
] = 0xf,
4405 [NEON_3R_VRHADD
] = 0x7,
4406 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4407 [NEON_3R_VHSUB
] = 0x7,
4408 [NEON_3R_VQSUB
] = 0xf,
4409 [NEON_3R_VCGT
] = 0x7,
4410 [NEON_3R_VCGE
] = 0x7,
4411 [NEON_3R_VSHL
] = 0xf,
4412 [NEON_3R_VQSHL
] = 0xf,
4413 [NEON_3R_VRSHL
] = 0xf,
4414 [NEON_3R_VQRSHL
] = 0xf,
4415 [NEON_3R_VMAX
] = 0x7,
4416 [NEON_3R_VMIN
] = 0x7,
4417 [NEON_3R_VABD
] = 0x7,
4418 [NEON_3R_VABA
] = 0x7,
4419 [NEON_3R_VADD_VSUB
] = 0xf,
4420 [NEON_3R_VTST_VCEQ
] = 0x7,
4421 [NEON_3R_VML
] = 0x7,
4422 [NEON_3R_VMUL
] = 0x7,
4423 [NEON_3R_VPMAX
] = 0x7,
4424 [NEON_3R_VPMIN
] = 0x7,
4425 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4426 [NEON_3R_VPADD
] = 0x7,
4427 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4428 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4429 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4430 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4431 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4432 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4435 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4436 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4439 #define NEON_2RM_VREV64 0
4440 #define NEON_2RM_VREV32 1
4441 #define NEON_2RM_VREV16 2
4442 #define NEON_2RM_VPADDL 4
4443 #define NEON_2RM_VPADDL_U 5
4444 #define NEON_2RM_VCLS 8
4445 #define NEON_2RM_VCLZ 9
4446 #define NEON_2RM_VCNT 10
4447 #define NEON_2RM_VMVN 11
4448 #define NEON_2RM_VPADAL 12
4449 #define NEON_2RM_VPADAL_U 13
4450 #define NEON_2RM_VQABS 14
4451 #define NEON_2RM_VQNEG 15
4452 #define NEON_2RM_VCGT0 16
4453 #define NEON_2RM_VCGE0 17
4454 #define NEON_2RM_VCEQ0 18
4455 #define NEON_2RM_VCLE0 19
4456 #define NEON_2RM_VCLT0 20
4457 #define NEON_2RM_VABS 22
4458 #define NEON_2RM_VNEG 23
4459 #define NEON_2RM_VCGT0_F 24
4460 #define NEON_2RM_VCGE0_F 25
4461 #define NEON_2RM_VCEQ0_F 26
4462 #define NEON_2RM_VCLE0_F 27
4463 #define NEON_2RM_VCLT0_F 28
4464 #define NEON_2RM_VABS_F 30
4465 #define NEON_2RM_VNEG_F 31
4466 #define NEON_2RM_VSWP 32
4467 #define NEON_2RM_VTRN 33
4468 #define NEON_2RM_VUZP 34
4469 #define NEON_2RM_VZIP 35
4470 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4471 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4472 #define NEON_2RM_VSHLL 38
4473 #define NEON_2RM_VCVT_F16_F32 44
4474 #define NEON_2RM_VCVT_F32_F16 46
4475 #define NEON_2RM_VRECPE 56
4476 #define NEON_2RM_VRSQRTE 57
4477 #define NEON_2RM_VRECPE_F 58
4478 #define NEON_2RM_VRSQRTE_F 59
4479 #define NEON_2RM_VCVT_FS 60
4480 #define NEON_2RM_VCVT_FU 61
4481 #define NEON_2RM_VCVT_SF 62
4482 #define NEON_2RM_VCVT_UF 63
4484 static int neon_2rm_is_float_op(int op
)
4486 /* Return true if this neon 2reg-misc op is float-to-float */
4487 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4488 op
>= NEON_2RM_VRECPE_F
);
4491 /* Each entry in this array has bit n set if the insn allows
4492 * size value n (otherwise it will UNDEF). Since unallocated
4493 * op values will have no bits set they always UNDEF.
4495 static const uint8_t neon_2rm_sizes
[] = {
4496 [NEON_2RM_VREV64
] = 0x7,
4497 [NEON_2RM_VREV32
] = 0x3,
4498 [NEON_2RM_VREV16
] = 0x1,
4499 [NEON_2RM_VPADDL
] = 0x7,
4500 [NEON_2RM_VPADDL_U
] = 0x7,
4501 [NEON_2RM_VCLS
] = 0x7,
4502 [NEON_2RM_VCLZ
] = 0x7,
4503 [NEON_2RM_VCNT
] = 0x1,
4504 [NEON_2RM_VMVN
] = 0x1,
4505 [NEON_2RM_VPADAL
] = 0x7,
4506 [NEON_2RM_VPADAL_U
] = 0x7,
4507 [NEON_2RM_VQABS
] = 0x7,
4508 [NEON_2RM_VQNEG
] = 0x7,
4509 [NEON_2RM_VCGT0
] = 0x7,
4510 [NEON_2RM_VCGE0
] = 0x7,
4511 [NEON_2RM_VCEQ0
] = 0x7,
4512 [NEON_2RM_VCLE0
] = 0x7,
4513 [NEON_2RM_VCLT0
] = 0x7,
4514 [NEON_2RM_VABS
] = 0x7,
4515 [NEON_2RM_VNEG
] = 0x7,
4516 [NEON_2RM_VCGT0_F
] = 0x4,
4517 [NEON_2RM_VCGE0_F
] = 0x4,
4518 [NEON_2RM_VCEQ0_F
] = 0x4,
4519 [NEON_2RM_VCLE0_F
] = 0x4,
4520 [NEON_2RM_VCLT0_F
] = 0x4,
4521 [NEON_2RM_VABS_F
] = 0x4,
4522 [NEON_2RM_VNEG_F
] = 0x4,
4523 [NEON_2RM_VSWP
] = 0x1,
4524 [NEON_2RM_VTRN
] = 0x7,
4525 [NEON_2RM_VUZP
] = 0x7,
4526 [NEON_2RM_VZIP
] = 0x7,
4527 [NEON_2RM_VMOVN
] = 0x7,
4528 [NEON_2RM_VQMOVN
] = 0x7,
4529 [NEON_2RM_VSHLL
] = 0x7,
4530 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4531 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4532 [NEON_2RM_VRECPE
] = 0x4,
4533 [NEON_2RM_VRSQRTE
] = 0x4,
4534 [NEON_2RM_VRECPE_F
] = 0x4,
4535 [NEON_2RM_VRSQRTE_F
] = 0x4,
4536 [NEON_2RM_VCVT_FS
] = 0x4,
4537 [NEON_2RM_VCVT_FU
] = 0x4,
4538 [NEON_2RM_VCVT_SF
] = 0x4,
4539 [NEON_2RM_VCVT_UF
] = 0x4,
4542 /* Translate a NEON data processing instruction. Return nonzero if the
4543 instruction is invalid.
4544 We process data in a mixture of 32-bit and 64-bit chunks.
4545 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4547 static int disas_neon_data_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
4559 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4562 if (!s
->vfp_enabled
)
4564 q
= (insn
& (1 << 6)) != 0;
4565 u
= (insn
>> 24) & 1;
4566 VFP_DREG_D(rd
, insn
);
4567 VFP_DREG_N(rn
, insn
);
4568 VFP_DREG_M(rm
, insn
);
4569 size
= (insn
>> 20) & 3;
4570 if ((insn
& (1 << 23)) == 0) {
4571 /* Three register same length. */
4572 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4573 /* Catch invalid op and bad size combinations: UNDEF */
4574 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4577 /* All insns of this form UNDEF for either this condition or the
4578 * superset of cases "Q==1"; we catch the latter later.
4580 if (q
&& ((rd
| rn
| rm
) & 1)) {
4583 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4584 /* 64-bit element instructions. */
4585 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4586 neon_load_reg64(cpu_V0
, rn
+ pass
);
4587 neon_load_reg64(cpu_V1
, rm
+ pass
);
4591 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4594 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4600 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4603 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4609 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4611 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4616 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4619 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4625 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4627 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4630 case NEON_3R_VQRSHL
:
4632 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4635 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4639 case NEON_3R_VADD_VSUB
:
4641 tcg_gen_sub_i64(CPU_V001
);
4643 tcg_gen_add_i64(CPU_V001
);
4649 neon_store_reg64(cpu_V0
, rd
+ pass
);
4658 case NEON_3R_VQRSHL
:
4661 /* Shift instruction operands are reversed. */
4676 case NEON_3R_FLOAT_ARITH
:
4677 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4679 case NEON_3R_FLOAT_MINMAX
:
4680 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4682 case NEON_3R_FLOAT_CMP
:
4684 /* no encoding for U=0 C=1x */
4688 case NEON_3R_FLOAT_ACMP
:
4693 case NEON_3R_VRECPS_VRSQRTS
:
4699 if (u
&& (size
!= 0)) {
4700 /* UNDEF on invalid size for polynomial subcase */
4708 if (pairwise
&& q
) {
4709 /* All the pairwise insns UNDEF if Q is set */
4713 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4718 tmp
= neon_load_reg(rn
, 0);
4719 tmp2
= neon_load_reg(rn
, 1);
4721 tmp
= neon_load_reg(rm
, 0);
4722 tmp2
= neon_load_reg(rm
, 1);
4726 tmp
= neon_load_reg(rn
, pass
);
4727 tmp2
= neon_load_reg(rm
, pass
);
4731 GEN_NEON_INTEGER_OP(hadd
);
4734 GEN_NEON_INTEGER_OP_ENV(qadd
);
4736 case NEON_3R_VRHADD
:
4737 GEN_NEON_INTEGER_OP(rhadd
);
4739 case NEON_3R_LOGIC
: /* Logic ops. */
4740 switch ((u
<< 2) | size
) {
4742 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4745 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4748 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4751 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4754 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4757 tmp3
= neon_load_reg(rd
, pass
);
4758 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4759 tcg_temp_free_i32(tmp3
);
4762 tmp3
= neon_load_reg(rd
, pass
);
4763 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4764 tcg_temp_free_i32(tmp3
);
4767 tmp3
= neon_load_reg(rd
, pass
);
4768 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4769 tcg_temp_free_i32(tmp3
);
4774 GEN_NEON_INTEGER_OP(hsub
);
4777 GEN_NEON_INTEGER_OP_ENV(qsub
);
4780 GEN_NEON_INTEGER_OP(cgt
);
4783 GEN_NEON_INTEGER_OP(cge
);
4786 GEN_NEON_INTEGER_OP(shl
);
4789 GEN_NEON_INTEGER_OP_ENV(qshl
);
4792 GEN_NEON_INTEGER_OP(rshl
);
4794 case NEON_3R_VQRSHL
:
4795 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4798 GEN_NEON_INTEGER_OP(max
);
4801 GEN_NEON_INTEGER_OP(min
);
4804 GEN_NEON_INTEGER_OP(abd
);
4807 GEN_NEON_INTEGER_OP(abd
);
4808 tcg_temp_free_i32(tmp2
);
4809 tmp2
= neon_load_reg(rd
, pass
);
4810 gen_neon_add(size
, tmp
, tmp2
);
4812 case NEON_3R_VADD_VSUB
:
4813 if (!u
) { /* VADD */
4814 gen_neon_add(size
, tmp
, tmp2
);
4817 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4818 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4819 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4824 case NEON_3R_VTST_VCEQ
:
4825 if (!u
) { /* VTST */
4827 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4828 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4829 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4834 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4835 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4836 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4841 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4843 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4844 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4845 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4848 tcg_temp_free_i32(tmp2
);
4849 tmp2
= neon_load_reg(rd
, pass
);
4851 gen_neon_rsb(size
, tmp
, tmp2
);
4853 gen_neon_add(size
, tmp
, tmp2
);
4857 if (u
) { /* polynomial */
4858 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4859 } else { /* Integer */
4861 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4862 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4863 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4869 GEN_NEON_INTEGER_OP(pmax
);
4872 GEN_NEON_INTEGER_OP(pmin
);
4874 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4875 if (!u
) { /* VQDMULH */
4878 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4881 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4885 } else { /* VQRDMULH */
4888 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4891 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4899 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4900 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4901 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4905 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4907 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4908 switch ((u
<< 2) | size
) {
4911 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4914 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4917 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4922 tcg_temp_free_ptr(fpstatus
);
4925 case NEON_3R_FLOAT_MULTIPLY
:
4927 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4928 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4930 tcg_temp_free_i32(tmp2
);
4931 tmp2
= neon_load_reg(rd
, pass
);
4933 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4935 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4938 tcg_temp_free_ptr(fpstatus
);
4941 case NEON_3R_FLOAT_CMP
:
4943 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4945 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4948 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4950 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4953 tcg_temp_free_ptr(fpstatus
);
4956 case NEON_3R_FLOAT_ACMP
:
4958 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4960 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4962 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4964 tcg_temp_free_ptr(fpstatus
);
4967 case NEON_3R_FLOAT_MINMAX
:
4969 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4971 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4973 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4975 tcg_temp_free_ptr(fpstatus
);
4978 case NEON_3R_VRECPS_VRSQRTS
:
4980 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4982 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4987 tcg_temp_free_i32(tmp2
);
4989 /* Save the result. For elementwise operations we can put it
4990 straight into the destination register. For pairwise operations
4991 we have to be careful to avoid clobbering the source operands. */
4992 if (pairwise
&& rd
== rm
) {
4993 neon_store_scratch(pass
, tmp
);
4995 neon_store_reg(rd
, pass
, tmp
);
4999 if (pairwise
&& rd
== rm
) {
5000 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5001 tmp
= neon_load_scratch(pass
);
5002 neon_store_reg(rd
, pass
, tmp
);
5005 /* End of 3 register same size operations. */
5006 } else if (insn
& (1 << 4)) {
5007 if ((insn
& 0x00380080) != 0) {
5008 /* Two registers and shift. */
5009 op
= (insn
>> 8) & 0xf;
5010 if (insn
& (1 << 7)) {
5018 while ((insn
& (1 << (size
+ 19))) == 0)
5021 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5022 /* To avoid excessive dumplication of ops we implement shift
5023 by immediate using the variable shift operations. */
5025 /* Shift by immediate:
5026 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5027 if (q
&& ((rd
| rm
) & 1)) {
5030 if (!u
&& (op
== 4 || op
== 6)) {
5033 /* Right shifts are encoded as N - shift, where N is the
5034 element size in bits. */
5036 shift
= shift
- (1 << (size
+ 3));
5044 imm
= (uint8_t) shift
;
5049 imm
= (uint16_t) shift
;
5060 for (pass
= 0; pass
< count
; pass
++) {
5062 neon_load_reg64(cpu_V0
, rm
+ pass
);
5063 tcg_gen_movi_i64(cpu_V1
, imm
);
5068 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5070 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5075 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5077 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5080 case 5: /* VSHL, VSLI */
5081 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5083 case 6: /* VQSHLU */
5084 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5089 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5092 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5097 if (op
== 1 || op
== 3) {
5099 neon_load_reg64(cpu_V1
, rd
+ pass
);
5100 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5101 } else if (op
== 4 || (op
== 5 && u
)) {
5103 neon_load_reg64(cpu_V1
, rd
+ pass
);
5105 if (shift
< -63 || shift
> 63) {
5109 mask
= 0xffffffffffffffffull
>> -shift
;
5111 mask
= 0xffffffffffffffffull
<< shift
;
5114 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5115 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5117 neon_store_reg64(cpu_V0
, rd
+ pass
);
5118 } else { /* size < 3 */
5119 /* Operands in T0 and T1. */
5120 tmp
= neon_load_reg(rm
, pass
);
5121 tmp2
= tcg_temp_new_i32();
5122 tcg_gen_movi_i32(tmp2
, imm
);
5126 GEN_NEON_INTEGER_OP(shl
);
5130 GEN_NEON_INTEGER_OP(rshl
);
5133 case 5: /* VSHL, VSLI */
5135 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5136 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5137 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5141 case 6: /* VQSHLU */
5144 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5148 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5152 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5160 GEN_NEON_INTEGER_OP_ENV(qshl
);
5163 tcg_temp_free_i32(tmp2
);
5165 if (op
== 1 || op
== 3) {
5167 tmp2
= neon_load_reg(rd
, pass
);
5168 gen_neon_add(size
, tmp
, tmp2
);
5169 tcg_temp_free_i32(tmp2
);
5170 } else if (op
== 4 || (op
== 5 && u
)) {
5175 mask
= 0xff >> -shift
;
5177 mask
= (uint8_t)(0xff << shift
);
5183 mask
= 0xffff >> -shift
;
5185 mask
= (uint16_t)(0xffff << shift
);
5189 if (shift
< -31 || shift
> 31) {
5193 mask
= 0xffffffffu
>> -shift
;
5195 mask
= 0xffffffffu
<< shift
;
5201 tmp2
= neon_load_reg(rd
, pass
);
5202 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5203 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5204 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5205 tcg_temp_free_i32(tmp2
);
5207 neon_store_reg(rd
, pass
, tmp
);
5210 } else if (op
< 10) {
5211 /* Shift by immediate and narrow:
5212 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5213 int input_unsigned
= (op
== 8) ? !u
: u
;
5217 shift
= shift
- (1 << (size
+ 3));
5220 tmp64
= tcg_const_i64(shift
);
5221 neon_load_reg64(cpu_V0
, rm
);
5222 neon_load_reg64(cpu_V1
, rm
+ 1);
5223 for (pass
= 0; pass
< 2; pass
++) {
5231 if (input_unsigned
) {
5232 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5234 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5237 if (input_unsigned
) {
5238 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5240 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5243 tmp
= tcg_temp_new_i32();
5244 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5245 neon_store_reg(rd
, pass
, tmp
);
5247 tcg_temp_free_i64(tmp64
);
5250 imm
= (uint16_t)shift
;
5254 imm
= (uint32_t)shift
;
5256 tmp2
= tcg_const_i32(imm
);
5257 tmp4
= neon_load_reg(rm
+ 1, 0);
5258 tmp5
= neon_load_reg(rm
+ 1, 1);
5259 for (pass
= 0; pass
< 2; pass
++) {
5261 tmp
= neon_load_reg(rm
, 0);
5265 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5268 tmp3
= neon_load_reg(rm
, 1);
5272 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5274 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5275 tcg_temp_free_i32(tmp
);
5276 tcg_temp_free_i32(tmp3
);
5277 tmp
= tcg_temp_new_i32();
5278 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5279 neon_store_reg(rd
, pass
, tmp
);
5281 tcg_temp_free_i32(tmp2
);
5283 } else if (op
== 10) {
5285 if (q
|| (rd
& 1)) {
5288 tmp
= neon_load_reg(rm
, 0);
5289 tmp2
= neon_load_reg(rm
, 1);
5290 for (pass
= 0; pass
< 2; pass
++) {
5294 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5297 /* The shift is less than the width of the source
5298 type, so we can just shift the whole register. */
5299 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5300 /* Widen the result of shift: we need to clear
5301 * the potential overflow bits resulting from
5302 * left bits of the narrow input appearing as
5303 * right bits of left the neighbour narrow
5305 if (size
< 2 || !u
) {
5308 imm
= (0xffu
>> (8 - shift
));
5310 } else if (size
== 1) {
5311 imm
= 0xffff >> (16 - shift
);
5314 imm
= 0xffffffff >> (32 - shift
);
5317 imm64
= imm
| (((uint64_t)imm
) << 32);
5321 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5324 neon_store_reg64(cpu_V0
, rd
+ pass
);
5326 } else if (op
>= 14) {
5327 /* VCVT fixed-point. */
5328 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5331 /* We have already masked out the must-be-1 top bit of imm6,
5332 * hence this 32-shift where the ARM ARM has 64-imm6.
5335 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5336 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5339 gen_vfp_ulto(0, shift
, 1);
5341 gen_vfp_slto(0, shift
, 1);
5344 gen_vfp_toul(0, shift
, 1);
5346 gen_vfp_tosl(0, shift
, 1);
5348 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5353 } else { /* (insn & 0x00380080) == 0 */
5355 if (q
&& (rd
& 1)) {
5359 op
= (insn
>> 8) & 0xf;
5360 /* One register and immediate. */
5361 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5362 invert
= (insn
& (1 << 5)) != 0;
5363 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5364 * We choose to not special-case this and will behave as if a
5365 * valid constant encoding of 0 had been given.
5384 imm
= (imm
<< 8) | (imm
<< 24);
5387 imm
= (imm
<< 8) | 0xff;
5390 imm
= (imm
<< 16) | 0xffff;
5393 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5401 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5402 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5408 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5409 if (op
& 1 && op
< 12) {
5410 tmp
= neon_load_reg(rd
, pass
);
5412 /* The immediate value has already been inverted, so
5414 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5416 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5420 tmp
= tcg_temp_new_i32();
5421 if (op
== 14 && invert
) {
5425 for (n
= 0; n
< 4; n
++) {
5426 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5427 val
|= 0xff << (n
* 8);
5429 tcg_gen_movi_i32(tmp
, val
);
5431 tcg_gen_movi_i32(tmp
, imm
);
5434 neon_store_reg(rd
, pass
, tmp
);
5437 } else { /* (insn & 0x00800010 == 0x00800000) */
5439 op
= (insn
>> 8) & 0xf;
5440 if ((insn
& (1 << 6)) == 0) {
5441 /* Three registers of different lengths. */
5445 /* undefreq: bit 0 : UNDEF if size != 0
5446 * bit 1 : UNDEF if size == 0
5447 * bit 2 : UNDEF if U == 1
5448 * Note that [1:0] set implies 'always UNDEF'
5451 /* prewiden, src1_wide, src2_wide, undefreq */
5452 static const int neon_3reg_wide
[16][4] = {
5453 {1, 0, 0, 0}, /* VADDL */
5454 {1, 1, 0, 0}, /* VADDW */
5455 {1, 0, 0, 0}, /* VSUBL */
5456 {1, 1, 0, 0}, /* VSUBW */
5457 {0, 1, 1, 0}, /* VADDHN */
5458 {0, 0, 0, 0}, /* VABAL */
5459 {0, 1, 1, 0}, /* VSUBHN */
5460 {0, 0, 0, 0}, /* VABDL */
5461 {0, 0, 0, 0}, /* VMLAL */
5462 {0, 0, 0, 6}, /* VQDMLAL */
5463 {0, 0, 0, 0}, /* VMLSL */
5464 {0, 0, 0, 6}, /* VQDMLSL */
5465 {0, 0, 0, 0}, /* Integer VMULL */
5466 {0, 0, 0, 2}, /* VQDMULL */
5467 {0, 0, 0, 5}, /* Polynomial VMULL */
5468 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5471 prewiden
= neon_3reg_wide
[op
][0];
5472 src1_wide
= neon_3reg_wide
[op
][1];
5473 src2_wide
= neon_3reg_wide
[op
][2];
5474 undefreq
= neon_3reg_wide
[op
][3];
5476 if (((undefreq
& 1) && (size
!= 0)) ||
5477 ((undefreq
& 2) && (size
== 0)) ||
5478 ((undefreq
& 4) && u
)) {
5481 if ((src1_wide
&& (rn
& 1)) ||
5482 (src2_wide
&& (rm
& 1)) ||
5483 (!src2_wide
&& (rd
& 1))) {
5487 /* Avoid overlapping operands. Wide source operands are
5488 always aligned so will never overlap with wide
5489 destinations in problematic ways. */
5490 if (rd
== rm
&& !src2_wide
) {
5491 tmp
= neon_load_reg(rm
, 1);
5492 neon_store_scratch(2, tmp
);
5493 } else if (rd
== rn
&& !src1_wide
) {
5494 tmp
= neon_load_reg(rn
, 1);
5495 neon_store_scratch(2, tmp
);
5498 for (pass
= 0; pass
< 2; pass
++) {
5500 neon_load_reg64(cpu_V0
, rn
+ pass
);
5503 if (pass
== 1 && rd
== rn
) {
5504 tmp
= neon_load_scratch(2);
5506 tmp
= neon_load_reg(rn
, pass
);
5509 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5513 neon_load_reg64(cpu_V1
, rm
+ pass
);
5516 if (pass
== 1 && rd
== rm
) {
5517 tmp2
= neon_load_scratch(2);
5519 tmp2
= neon_load_reg(rm
, pass
);
5522 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5526 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5527 gen_neon_addl(size
);
5529 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5530 gen_neon_subl(size
);
5532 case 5: case 7: /* VABAL, VABDL */
5533 switch ((size
<< 1) | u
) {
5535 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5538 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5541 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5544 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5547 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5550 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5554 tcg_temp_free_i32(tmp2
);
5555 tcg_temp_free_i32(tmp
);
5557 case 8: case 9: case 10: case 11: case 12: case 13:
5558 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5559 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5561 case 14: /* Polynomial VMULL */
5562 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5563 tcg_temp_free_i32(tmp2
);
5564 tcg_temp_free_i32(tmp
);
5566 default: /* 15 is RESERVED: caught earlier */
5571 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5572 neon_store_reg64(cpu_V0
, rd
+ pass
);
5573 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5575 neon_load_reg64(cpu_V1
, rd
+ pass
);
5577 case 10: /* VMLSL */
5578 gen_neon_negl(cpu_V0
, size
);
5580 case 5: case 8: /* VABAL, VMLAL */
5581 gen_neon_addl(size
);
5583 case 9: case 11: /* VQDMLAL, VQDMLSL */
5584 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5586 gen_neon_negl(cpu_V0
, size
);
5588 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5593 neon_store_reg64(cpu_V0
, rd
+ pass
);
5594 } else if (op
== 4 || op
== 6) {
5595 /* Narrowing operation. */
5596 tmp
= tcg_temp_new_i32();
5600 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5603 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5606 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5607 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5614 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5617 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5620 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5621 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5622 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5630 neon_store_reg(rd
, 0, tmp3
);
5631 neon_store_reg(rd
, 1, tmp
);
5634 /* Write back the result. */
5635 neon_store_reg64(cpu_V0
, rd
+ pass
);
5639 /* Two registers and a scalar. NB that for ops of this form
5640 * the ARM ARM labels bit 24 as Q, but it is in our variable
5647 case 1: /* Float VMLA scalar */
5648 case 5: /* Floating point VMLS scalar */
5649 case 9: /* Floating point VMUL scalar */
5654 case 0: /* Integer VMLA scalar */
5655 case 4: /* Integer VMLS scalar */
5656 case 8: /* Integer VMUL scalar */
5657 case 12: /* VQDMULH scalar */
5658 case 13: /* VQRDMULH scalar */
5659 if (u
&& ((rd
| rn
) & 1)) {
5662 tmp
= neon_get_scalar(size
, rm
);
5663 neon_store_scratch(0, tmp
);
5664 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5665 tmp
= neon_load_scratch(0);
5666 tmp2
= neon_load_reg(rn
, pass
);
5669 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5671 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5673 } else if (op
== 13) {
5675 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5677 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5679 } else if (op
& 1) {
5680 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5681 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5682 tcg_temp_free_ptr(fpstatus
);
5685 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5686 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5687 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5691 tcg_temp_free_i32(tmp2
);
5694 tmp2
= neon_load_reg(rd
, pass
);
5697 gen_neon_add(size
, tmp
, tmp2
);
5701 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5702 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5703 tcg_temp_free_ptr(fpstatus
);
5707 gen_neon_rsb(size
, tmp
, tmp2
);
5711 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5712 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5713 tcg_temp_free_ptr(fpstatus
);
5719 tcg_temp_free_i32(tmp2
);
5721 neon_store_reg(rd
, pass
, tmp
);
5724 case 3: /* VQDMLAL scalar */
5725 case 7: /* VQDMLSL scalar */
5726 case 11: /* VQDMULL scalar */
5731 case 2: /* VMLAL sclar */
5732 case 6: /* VMLSL scalar */
5733 case 10: /* VMULL scalar */
5737 tmp2
= neon_get_scalar(size
, rm
);
5738 /* We need a copy of tmp2 because gen_neon_mull
5739 * deletes it during pass 0. */
5740 tmp4
= tcg_temp_new_i32();
5741 tcg_gen_mov_i32(tmp4
, tmp2
);
5742 tmp3
= neon_load_reg(rn
, 1);
5744 for (pass
= 0; pass
< 2; pass
++) {
5746 tmp
= neon_load_reg(rn
, 0);
5751 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5753 neon_load_reg64(cpu_V1
, rd
+ pass
);
5757 gen_neon_negl(cpu_V0
, size
);
5760 gen_neon_addl(size
);
5763 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5765 gen_neon_negl(cpu_V0
, size
);
5767 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5773 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5778 neon_store_reg64(cpu_V0
, rd
+ pass
);
5783 default: /* 14 and 15 are RESERVED */
5787 } else { /* size == 3 */
5790 imm
= (insn
>> 8) & 0xf;
5795 if (q
&& ((rd
| rn
| rm
) & 1)) {
5800 neon_load_reg64(cpu_V0
, rn
);
5802 neon_load_reg64(cpu_V1
, rn
+ 1);
5804 } else if (imm
== 8) {
5805 neon_load_reg64(cpu_V0
, rn
+ 1);
5807 neon_load_reg64(cpu_V1
, rm
);
5810 tmp64
= tcg_temp_new_i64();
5812 neon_load_reg64(cpu_V0
, rn
);
5813 neon_load_reg64(tmp64
, rn
+ 1);
5815 neon_load_reg64(cpu_V0
, rn
+ 1);
5816 neon_load_reg64(tmp64
, rm
);
5818 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5819 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5820 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5822 neon_load_reg64(cpu_V1
, rm
);
5824 neon_load_reg64(cpu_V1
, rm
+ 1);
5827 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5828 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5829 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5830 tcg_temp_free_i64(tmp64
);
5833 neon_load_reg64(cpu_V0
, rn
);
5834 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5835 neon_load_reg64(cpu_V1
, rm
);
5836 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5837 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5839 neon_store_reg64(cpu_V0
, rd
);
5841 neon_store_reg64(cpu_V1
, rd
+ 1);
5843 } else if ((insn
& (1 << 11)) == 0) {
5844 /* Two register misc. */
5845 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5846 size
= (insn
>> 18) & 3;
5847 /* UNDEF for unknown op values and bad op-size combinations */
5848 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5851 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5852 q
&& ((rm
| rd
) & 1)) {
5856 case NEON_2RM_VREV64
:
5857 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5858 tmp
= neon_load_reg(rm
, pass
* 2);
5859 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5861 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5862 case 1: gen_swap_half(tmp
); break;
5863 case 2: /* no-op */ break;
5866 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5868 neon_store_reg(rd
, pass
* 2, tmp2
);
5871 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5872 case 1: gen_swap_half(tmp2
); break;
5875 neon_store_reg(rd
, pass
* 2, tmp2
);
5879 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5880 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5881 for (pass
= 0; pass
< q
+ 1; pass
++) {
5882 tmp
= neon_load_reg(rm
, pass
* 2);
5883 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5884 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5885 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5887 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5888 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5889 case 2: tcg_gen_add_i64(CPU_V001
); break;
5892 if (op
>= NEON_2RM_VPADAL
) {
5894 neon_load_reg64(cpu_V1
, rd
+ pass
);
5895 gen_neon_addl(size
);
5897 neon_store_reg64(cpu_V0
, rd
+ pass
);
5903 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5904 tmp
= neon_load_reg(rm
, n
);
5905 tmp2
= neon_load_reg(rd
, n
+ 1);
5906 neon_store_reg(rm
, n
, tmp2
);
5907 neon_store_reg(rd
, n
+ 1, tmp
);
5914 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5919 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5923 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5924 /* also VQMOVUN; op field and mnemonics don't line up */
5929 for (pass
= 0; pass
< 2; pass
++) {
5930 neon_load_reg64(cpu_V0
, rm
+ pass
);
5931 tmp
= tcg_temp_new_i32();
5932 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5937 neon_store_reg(rd
, 0, tmp2
);
5938 neon_store_reg(rd
, 1, tmp
);
5942 case NEON_2RM_VSHLL
:
5943 if (q
|| (rd
& 1)) {
5946 tmp
= neon_load_reg(rm
, 0);
5947 tmp2
= neon_load_reg(rm
, 1);
5948 for (pass
= 0; pass
< 2; pass
++) {
5951 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5952 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5953 neon_store_reg64(cpu_V0
, rd
+ pass
);
5956 case NEON_2RM_VCVT_F16_F32
:
5957 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5961 tmp
= tcg_temp_new_i32();
5962 tmp2
= tcg_temp_new_i32();
5963 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5964 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5965 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5966 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5967 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5968 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5969 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5970 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5971 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5972 neon_store_reg(rd
, 0, tmp2
);
5973 tmp2
= tcg_temp_new_i32();
5974 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5975 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5976 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5977 neon_store_reg(rd
, 1, tmp2
);
5978 tcg_temp_free_i32(tmp
);
5980 case NEON_2RM_VCVT_F32_F16
:
5981 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5985 tmp3
= tcg_temp_new_i32();
5986 tmp
= neon_load_reg(rm
, 0);
5987 tmp2
= neon_load_reg(rm
, 1);
5988 tcg_gen_ext16u_i32(tmp3
, tmp
);
5989 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5990 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5991 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5992 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5993 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5994 tcg_temp_free_i32(tmp
);
5995 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5996 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5997 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5998 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5999 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6000 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6001 tcg_temp_free_i32(tmp2
);
6002 tcg_temp_free_i32(tmp3
);
6006 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6007 if (neon_2rm_is_float_op(op
)) {
6008 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6009 neon_reg_offset(rm
, pass
));
6012 tmp
= neon_load_reg(rm
, pass
);
6015 case NEON_2RM_VREV32
:
6017 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6018 case 1: gen_swap_half(tmp
); break;
6022 case NEON_2RM_VREV16
:
6027 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6028 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6029 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6035 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6036 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6037 case 2: gen_helper_clz(tmp
, tmp
); break;
6042 gen_helper_neon_cnt_u8(tmp
, tmp
);
6045 tcg_gen_not_i32(tmp
, tmp
);
6047 case NEON_2RM_VQABS
:
6050 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6053 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6056 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6061 case NEON_2RM_VQNEG
:
6064 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6067 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6070 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6075 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6076 tmp2
= tcg_const_i32(0);
6078 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6079 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6080 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6083 tcg_temp_free(tmp2
);
6084 if (op
== NEON_2RM_VCLE0
) {
6085 tcg_gen_not_i32(tmp
, tmp
);
6088 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6089 tmp2
= tcg_const_i32(0);
6091 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6092 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6093 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6096 tcg_temp_free(tmp2
);
6097 if (op
== NEON_2RM_VCLT0
) {
6098 tcg_gen_not_i32(tmp
, tmp
);
6101 case NEON_2RM_VCEQ0
:
6102 tmp2
= tcg_const_i32(0);
6104 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6105 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6106 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6109 tcg_temp_free(tmp2
);
6113 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6114 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6115 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6120 tmp2
= tcg_const_i32(0);
6121 gen_neon_rsb(size
, tmp
, tmp2
);
6122 tcg_temp_free(tmp2
);
6124 case NEON_2RM_VCGT0_F
:
6126 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6127 tmp2
= tcg_const_i32(0);
6128 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6129 tcg_temp_free(tmp2
);
6130 tcg_temp_free_ptr(fpstatus
);
6133 case NEON_2RM_VCGE0_F
:
6135 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6136 tmp2
= tcg_const_i32(0);
6137 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6138 tcg_temp_free(tmp2
);
6139 tcg_temp_free_ptr(fpstatus
);
6142 case NEON_2RM_VCEQ0_F
:
6144 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6145 tmp2
= tcg_const_i32(0);
6146 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6147 tcg_temp_free(tmp2
);
6148 tcg_temp_free_ptr(fpstatus
);
6151 case NEON_2RM_VCLE0_F
:
6153 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6154 tmp2
= tcg_const_i32(0);
6155 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6156 tcg_temp_free(tmp2
);
6157 tcg_temp_free_ptr(fpstatus
);
6160 case NEON_2RM_VCLT0_F
:
6162 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6163 tmp2
= tcg_const_i32(0);
6164 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6165 tcg_temp_free(tmp2
);
6166 tcg_temp_free_ptr(fpstatus
);
6169 case NEON_2RM_VABS_F
:
6172 case NEON_2RM_VNEG_F
:
6176 tmp2
= neon_load_reg(rd
, pass
);
6177 neon_store_reg(rm
, pass
, tmp2
);
6180 tmp2
= neon_load_reg(rd
, pass
);
6182 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6183 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6186 neon_store_reg(rm
, pass
, tmp2
);
6188 case NEON_2RM_VRECPE
:
6189 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6191 case NEON_2RM_VRSQRTE
:
6192 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6194 case NEON_2RM_VRECPE_F
:
6195 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6197 case NEON_2RM_VRSQRTE_F
:
6198 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6200 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6203 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6206 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6207 gen_vfp_tosiz(0, 1);
6209 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6210 gen_vfp_touiz(0, 1);
6213 /* Reserved op values were caught by the
6214 * neon_2rm_sizes[] check earlier.
6218 if (neon_2rm_is_float_op(op
)) {
6219 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6220 neon_reg_offset(rd
, pass
));
6222 neon_store_reg(rd
, pass
, tmp
);
6227 } else if ((insn
& (1 << 10)) == 0) {
6229 int n
= ((insn
>> 8) & 3) + 1;
6230 if ((rn
+ n
) > 32) {
6231 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6232 * helper function running off the end of the register file.
6237 if (insn
& (1 << 6)) {
6238 tmp
= neon_load_reg(rd
, 0);
6240 tmp
= tcg_temp_new_i32();
6241 tcg_gen_movi_i32(tmp
, 0);
6243 tmp2
= neon_load_reg(rm
, 0);
6244 tmp4
= tcg_const_i32(rn
);
6245 tmp5
= tcg_const_i32(n
);
6246 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, tmp4
, tmp5
);
6247 tcg_temp_free_i32(tmp
);
6248 if (insn
& (1 << 6)) {
6249 tmp
= neon_load_reg(rd
, 1);
6251 tmp
= tcg_temp_new_i32();
6252 tcg_gen_movi_i32(tmp
, 0);
6254 tmp3
= neon_load_reg(rm
, 1);
6255 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, tmp4
, tmp5
);
6256 tcg_temp_free_i32(tmp5
);
6257 tcg_temp_free_i32(tmp4
);
6258 neon_store_reg(rd
, 0, tmp2
);
6259 neon_store_reg(rd
, 1, tmp3
);
6260 tcg_temp_free_i32(tmp
);
6261 } else if ((insn
& 0x380) == 0) {
6263 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6266 if (insn
& (1 << 19)) {
6267 tmp
= neon_load_reg(rm
, 1);
6269 tmp
= neon_load_reg(rm
, 0);
6271 if (insn
& (1 << 16)) {
6272 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6273 } else if (insn
& (1 << 17)) {
6274 if ((insn
>> 18) & 1)
6275 gen_neon_dup_high16(tmp
);
6277 gen_neon_dup_low16(tmp
);
6279 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6280 tmp2
= tcg_temp_new_i32();
6281 tcg_gen_mov_i32(tmp2
, tmp
);
6282 neon_store_reg(rd
, pass
, tmp2
);
6284 tcg_temp_free_i32(tmp
);
6293 static int disas_cp14_read(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6295 int crn
= (insn
>> 16) & 0xf;
6296 int crm
= insn
& 0xf;
6297 int op1
= (insn
>> 21) & 7;
6298 int op2
= (insn
>> 5) & 7;
6299 int rt
= (insn
>> 12) & 0xf;
6302 /* Minimal set of debug registers, since we don't support debug */
6303 if (op1
== 0 && crn
== 0 && op2
== 0) {
6306 /* DBGDIDR: just RAZ. In particular this means the
6307 * "debug architecture version" bits will read as
6308 * a reserved value, which should cause Linux to
6309 * not try to use the debug hardware.
6311 tmp
= tcg_const_i32(0);
6312 store_reg(s
, rt
, tmp
);
6316 /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
6317 * don't implement memory mapped debug components
6319 if (ENABLE_ARCH_7
) {
6320 tmp
= tcg_const_i32(0);
6321 store_reg(s
, rt
, tmp
);
6330 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6331 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6335 tmp
= load_cpu_field(teecr
);
6336 store_reg(s
, rt
, tmp
);
6339 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6341 if (IS_USER(s
) && (env
->teecr
& 1))
6343 tmp
= load_cpu_field(teehbr
);
6344 store_reg(s
, rt
, tmp
);
6348 fprintf(stderr
, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
6349 op1
, crn
, crm
, op2
);
6353 static int disas_cp14_write(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6355 int crn
= (insn
>> 16) & 0xf;
6356 int crm
= insn
& 0xf;
6357 int op1
= (insn
>> 21) & 7;
6358 int op2
= (insn
>> 5) & 7;
6359 int rt
= (insn
>> 12) & 0xf;
6362 if (arm_feature(env
, ARM_FEATURE_THUMB2EE
)) {
6363 if (op1
== 6 && crn
== 0 && crm
== 0 && op2
== 0) {
6367 tmp
= load_reg(s
, rt
);
6368 gen_helper_set_teecr(cpu_env
, tmp
);
6369 tcg_temp_free_i32(tmp
);
6372 if (op1
== 6 && crn
== 1 && crm
== 0 && op2
== 0) {
6374 if (IS_USER(s
) && (env
->teecr
& 1))
6376 tmp
= load_reg(s
, rt
);
6377 store_cpu_field(tmp
, teehbr
);
6381 fprintf(stderr
, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
6382 op1
, crn
, crm
, op2
);
6386 static int disas_coproc_insn(CPUState
* env
, DisasContext
*s
, uint32_t insn
)
6390 cpnum
= (insn
>> 8) & 0xf;
6391 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6392 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6398 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6399 return disas_iwmmxt_insn(env
, s
, insn
);
6400 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6401 return disas_dsp_insn(env
, s
, insn
);
6406 return disas_vfp_insn (env
, s
, insn
);
6408 /* Coprocessors 7-15 are architecturally reserved by ARM.
6409 Unfortunately Intel decided to ignore this. */
6410 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
6412 if (insn
& (1 << 20))
6413 return disas_cp14_read(env
, s
, insn
);
6415 return disas_cp14_write(env
, s
, insn
);
6417 return disas_cp15_insn (env
, s
, insn
);
6420 /* Unknown coprocessor. See if the board has hooked it. */
6421 return disas_cp_insn (env
, s
, insn
);
6426 /* Store a 64-bit value to a register pair. Clobbers val. */
6427 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6430 tmp
= tcg_temp_new_i32();
6431 tcg_gen_trunc_i64_i32(tmp
, val
);
6432 store_reg(s
, rlow
, tmp
);
6433 tmp
= tcg_temp_new_i32();
6434 tcg_gen_shri_i64(val
, val
, 32);
6435 tcg_gen_trunc_i64_i32(tmp
, val
);
6436 store_reg(s
, rhigh
, tmp
);
6439 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6440 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6445 /* Load value and extend to 64 bits. */
6446 tmp
= tcg_temp_new_i64();
6447 tmp2
= load_reg(s
, rlow
);
6448 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6449 tcg_temp_free_i32(tmp2
);
6450 tcg_gen_add_i64(val
, val
, tmp
);
6451 tcg_temp_free_i64(tmp
);
6454 /* load and add a 64-bit value from a register pair. */
6455 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6461 /* Load 64-bit value rd:rn. */
6462 tmpl
= load_reg(s
, rlow
);
6463 tmph
= load_reg(s
, rhigh
);
6464 tmp
= tcg_temp_new_i64();
6465 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6466 tcg_temp_free_i32(tmpl
);
6467 tcg_temp_free_i32(tmph
);
6468 tcg_gen_add_i64(val
, val
, tmp
);
6469 tcg_temp_free_i64(tmp
);
6472 /* Set N and Z flags from a 64-bit value. */
6473 static void gen_logicq_cc(TCGv_i64 val
)
6475 TCGv tmp
= tcg_temp_new_i32();
6476 gen_helper_logicq_cc(tmp
, val
);
6478 tcg_temp_free_i32(tmp
);
6481 /* Load/Store exclusive instructions are implemented by remembering
6482 the value/address loaded, and seeing if these are the same
6483 when the store is performed. This should be is sufficient to implement
6484 the architecturally mandated semantics, and avoids having to monitor
6487 In system emulation mode only one CPU will be running at once, so
6488 this sequence is effectively atomic. In user emulation mode we
6489 throw an exception and handle the atomic operation elsewhere. */
6490 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6491 TCGv addr
, int size
)
6497 tmp
= gen_ld8u(addr
, IS_USER(s
));
6500 tmp
= gen_ld16u(addr
, IS_USER(s
));
6504 tmp
= gen_ld32(addr
, IS_USER(s
));
6509 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6510 store_reg(s
, rt
, tmp
);
6512 TCGv tmp2
= tcg_temp_new_i32();
6513 tcg_gen_addi_i32(tmp2
, addr
, 4);
6514 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6515 tcg_temp_free_i32(tmp2
);
6516 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6517 store_reg(s
, rt2
, tmp
);
6519 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6522 static void gen_clrex(DisasContext
*s
)
6524 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6527 #ifdef CONFIG_USER_ONLY
6528 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6529 TCGv addr
, int size
)
6531 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6532 tcg_gen_movi_i32(cpu_exclusive_info
,
6533 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6534 gen_exception_insn(s
, 4, EXCP_STREX
);
6537 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6538 TCGv addr
, int size
)
6544 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6550 fail_label
= gen_new_label();
6551 done_label
= gen_new_label();
6552 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6555 tmp
= gen_ld8u(addr
, IS_USER(s
));
6558 tmp
= gen_ld16u(addr
, IS_USER(s
));
6562 tmp
= gen_ld32(addr
, IS_USER(s
));
6567 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6568 tcg_temp_free_i32(tmp
);
6570 TCGv tmp2
= tcg_temp_new_i32();
6571 tcg_gen_addi_i32(tmp2
, addr
, 4);
6572 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6573 tcg_temp_free_i32(tmp2
);
6574 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6575 tcg_temp_free_i32(tmp
);
6577 tmp
= load_reg(s
, rt
);
6580 gen_st8(tmp
, addr
, IS_USER(s
));
6583 gen_st16(tmp
, addr
, IS_USER(s
));
6587 gen_st32(tmp
, addr
, IS_USER(s
));
6593 tcg_gen_addi_i32(addr
, addr
, 4);
6594 tmp
= load_reg(s
, rt2
);
6595 gen_st32(tmp
, addr
, IS_USER(s
));
6597 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6598 tcg_gen_br(done_label
);
6599 gen_set_label(fail_label
);
6600 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6601 gen_set_label(done_label
);
6602 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6606 static void disas_arm_insn(CPUState
* env
, DisasContext
*s
)
6608 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6615 insn
= ldl_code(s
->pc
);
6618 /* M variants do not implement ARM mode. */
6623 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6624 * choose to UNDEF. In ARMv5 and above the space is used
6625 * for miscellaneous unconditional instructions.
6629 /* Unconditional instructions. */
6630 if (((insn
>> 25) & 7) == 1) {
6631 /* NEON Data processing. */
6632 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6635 if (disas_neon_data_insn(env
, s
, insn
))
6639 if ((insn
& 0x0f100000) == 0x04000000) {
6640 /* NEON load/store. */
6641 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6644 if (disas_neon_ls_insn(env
, s
, insn
))
6648 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6649 ((insn
& 0x0f30f010) == 0x0710f000)) {
6650 if ((insn
& (1 << 22)) == 0) {
6652 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6656 /* Otherwise PLD; v5TE+ */
6660 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6661 ((insn
& 0x0f70f010) == 0x0650f000)) {
6663 return; /* PLI; V7 */
6665 if (((insn
& 0x0f700000) == 0x04100000) ||
6666 ((insn
& 0x0f700010) == 0x06100000)) {
6667 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6670 return; /* v7MP: Unallocated memory hint: must NOP */
6673 if ((insn
& 0x0ffffdff) == 0x01010000) {
6676 if (insn
& (1 << 9)) {
6677 /* BE8 mode not implemented. */
6681 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6682 switch ((insn
>> 4) & 0xf) {
6691 /* We don't emulate caches so these are a no-op. */
6696 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6702 op1
= (insn
& 0x1f);
6703 addr
= tcg_temp_new_i32();
6704 tmp
= tcg_const_i32(op1
);
6705 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6706 tcg_temp_free_i32(tmp
);
6707 i
= (insn
>> 23) & 3;
6709 case 0: offset
= -4; break; /* DA */
6710 case 1: offset
= 0; break; /* IA */
6711 case 2: offset
= -8; break; /* DB */
6712 case 3: offset
= 4; break; /* IB */
6716 tcg_gen_addi_i32(addr
, addr
, offset
);
6717 tmp
= load_reg(s
, 14);
6718 gen_st32(tmp
, addr
, 0);
6719 tmp
= load_cpu_field(spsr
);
6720 tcg_gen_addi_i32(addr
, addr
, 4);
6721 gen_st32(tmp
, addr
, 0);
6722 if (insn
& (1 << 21)) {
6723 /* Base writeback. */
6725 case 0: offset
= -8; break;
6726 case 1: offset
= 4; break;
6727 case 2: offset
= -4; break;
6728 case 3: offset
= 0; break;
6732 tcg_gen_addi_i32(addr
, addr
, offset
);
6733 tmp
= tcg_const_i32(op1
);
6734 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6735 tcg_temp_free_i32(tmp
);
6736 tcg_temp_free_i32(addr
);
6738 tcg_temp_free_i32(addr
);
6741 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6747 rn
= (insn
>> 16) & 0xf;
6748 addr
= load_reg(s
, rn
);
6749 i
= (insn
>> 23) & 3;
6751 case 0: offset
= -4; break; /* DA */
6752 case 1: offset
= 0; break; /* IA */
6753 case 2: offset
= -8; break; /* DB */
6754 case 3: offset
= 4; break; /* IB */
6758 tcg_gen_addi_i32(addr
, addr
, offset
);
6759 /* Load PC into tmp and CPSR into tmp2. */
6760 tmp
= gen_ld32(addr
, 0);
6761 tcg_gen_addi_i32(addr
, addr
, 4);
6762 tmp2
= gen_ld32(addr
, 0);
6763 if (insn
& (1 << 21)) {
6764 /* Base writeback. */
6766 case 0: offset
= -8; break;
6767 case 1: offset
= 4; break;
6768 case 2: offset
= -4; break;
6769 case 3: offset
= 0; break;
6773 tcg_gen_addi_i32(addr
, addr
, offset
);
6774 store_reg(s
, rn
, addr
);
6776 tcg_temp_free_i32(addr
);
6778 gen_rfe(s
, tmp
, tmp2
);
6780 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6781 /* branch link and change to thumb (blx <offset>) */
6784 val
= (uint32_t)s
->pc
;
6785 tmp
= tcg_temp_new_i32();
6786 tcg_gen_movi_i32(tmp
, val
);
6787 store_reg(s
, 14, tmp
);
6788 /* Sign-extend the 24-bit offset */
6789 offset
= (((int32_t)insn
) << 8) >> 8;
6790 /* offset * 4 + bit24 * 2 + (thumb bit) */
6791 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6792 /* pipeline offset */
6794 /* protected by ARCH(5); above, near the start of uncond block */
6797 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6798 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6799 /* iWMMXt register transfer. */
6800 if (env
->cp15
.c15_cpar
& (1 << 1))
6801 if (!disas_iwmmxt_insn(env
, s
, insn
))
6804 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6805 /* Coprocessor double register transfer. */
6807 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6808 /* Additional coprocessor register transfer. */
6809 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6812 /* cps (privileged) */
6816 if (insn
& (1 << 19)) {
6817 if (insn
& (1 << 8))
6819 if (insn
& (1 << 7))
6821 if (insn
& (1 << 6))
6823 if (insn
& (1 << 18))
6826 if (insn
& (1 << 17)) {
6828 val
|= (insn
& 0x1f);
6831 gen_set_psr_im(s
, mask
, 0, val
);
6838 /* if not always execute, we generate a conditional jump to
6840 s
->condlabel
= gen_new_label();
6841 gen_test_cc(cond
^ 1, s
->condlabel
);
6844 if ((insn
& 0x0f900000) == 0x03000000) {
6845 if ((insn
& (1 << 21)) == 0) {
6847 rd
= (insn
>> 12) & 0xf;
6848 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6849 if ((insn
& (1 << 22)) == 0) {
6851 tmp
= tcg_temp_new_i32();
6852 tcg_gen_movi_i32(tmp
, val
);
6855 tmp
= load_reg(s
, rd
);
6856 tcg_gen_ext16u_i32(tmp
, tmp
);
6857 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6859 store_reg(s
, rd
, tmp
);
6861 if (((insn
>> 12) & 0xf) != 0xf)
6863 if (((insn
>> 16) & 0xf) == 0) {
6864 gen_nop_hint(s
, insn
& 0xff);
6866 /* CPSR = immediate */
6868 shift
= ((insn
>> 8) & 0xf) * 2;
6870 val
= (val
>> shift
) | (val
<< (32 - shift
));
6871 i
= ((insn
& (1 << 22)) != 0);
6872 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6876 } else if ((insn
& 0x0f900000) == 0x01000000
6877 && (insn
& 0x00000090) != 0x00000090) {
6878 /* miscellaneous instructions */
6879 op1
= (insn
>> 21) & 3;
6880 sh
= (insn
>> 4) & 0xf;
6883 case 0x0: /* move program status register */
6886 tmp
= load_reg(s
, rm
);
6887 i
= ((op1
& 2) != 0);
6888 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6892 rd
= (insn
>> 12) & 0xf;
6896 tmp
= load_cpu_field(spsr
);
6898 tmp
= tcg_temp_new_i32();
6899 gen_helper_cpsr_read(tmp
);
6901 store_reg(s
, rd
, tmp
);
6906 /* branch/exchange thumb (bx). */
6908 tmp
= load_reg(s
, rm
);
6910 } else if (op1
== 3) {
6913 rd
= (insn
>> 12) & 0xf;
6914 tmp
= load_reg(s
, rm
);
6915 gen_helper_clz(tmp
, tmp
);
6916 store_reg(s
, rd
, tmp
);
6924 /* Trivial implementation equivalent to bx. */
6925 tmp
= load_reg(s
, rm
);
6936 /* branch link/exchange thumb (blx) */
6937 tmp
= load_reg(s
, rm
);
6938 tmp2
= tcg_temp_new_i32();
6939 tcg_gen_movi_i32(tmp2
, s
->pc
);
6940 store_reg(s
, 14, tmp2
);
6943 case 0x5: /* saturating add/subtract */
6945 rd
= (insn
>> 12) & 0xf;
6946 rn
= (insn
>> 16) & 0xf;
6947 tmp
= load_reg(s
, rm
);
6948 tmp2
= load_reg(s
, rn
);
6950 gen_helper_double_saturate(tmp2
, tmp2
);
6952 gen_helper_sub_saturate(tmp
, tmp
, tmp2
);
6954 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
6955 tcg_temp_free_i32(tmp2
);
6956 store_reg(s
, rd
, tmp
);
6959 /* SMC instruction (op1 == 3)
6960 and undefined instructions (op1 == 0 || op1 == 2)
6967 gen_exception_insn(s
, 4, EXCP_BKPT
);
6969 case 0x8: /* signed multiply */
6974 rs
= (insn
>> 8) & 0xf;
6975 rn
= (insn
>> 12) & 0xf;
6976 rd
= (insn
>> 16) & 0xf;
6978 /* (32 * 16) >> 16 */
6979 tmp
= load_reg(s
, rm
);
6980 tmp2
= load_reg(s
, rs
);
6982 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6985 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6986 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6987 tmp
= tcg_temp_new_i32();
6988 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6989 tcg_temp_free_i64(tmp64
);
6990 if ((sh
& 2) == 0) {
6991 tmp2
= load_reg(s
, rn
);
6992 gen_helper_add_setq(tmp
, tmp
, tmp2
);
6993 tcg_temp_free_i32(tmp2
);
6995 store_reg(s
, rd
, tmp
);
6998 tmp
= load_reg(s
, rm
);
6999 tmp2
= load_reg(s
, rs
);
7000 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7001 tcg_temp_free_i32(tmp2
);
7003 tmp64
= tcg_temp_new_i64();
7004 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7005 tcg_temp_free_i32(tmp
);
7006 gen_addq(s
, tmp64
, rn
, rd
);
7007 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7008 tcg_temp_free_i64(tmp64
);
7011 tmp2
= load_reg(s
, rn
);
7012 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7013 tcg_temp_free_i32(tmp2
);
7015 store_reg(s
, rd
, tmp
);
7022 } else if (((insn
& 0x0e000000) == 0 &&
7023 (insn
& 0x00000090) != 0x90) ||
7024 ((insn
& 0x0e000000) == (1 << 25))) {
7025 int set_cc
, logic_cc
, shiftop
;
7027 op1
= (insn
>> 21) & 0xf;
7028 set_cc
= (insn
>> 20) & 1;
7029 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7031 /* data processing instruction */
7032 if (insn
& (1 << 25)) {
7033 /* immediate operand */
7035 shift
= ((insn
>> 8) & 0xf) * 2;
7037 val
= (val
>> shift
) | (val
<< (32 - shift
));
7039 tmp2
= tcg_temp_new_i32();
7040 tcg_gen_movi_i32(tmp2
, val
);
7041 if (logic_cc
&& shift
) {
7042 gen_set_CF_bit31(tmp2
);
7047 tmp2
= load_reg(s
, rm
);
7048 shiftop
= (insn
>> 5) & 3;
7049 if (!(insn
& (1 << 4))) {
7050 shift
= (insn
>> 7) & 0x1f;
7051 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7053 rs
= (insn
>> 8) & 0xf;
7054 tmp
= load_reg(s
, rs
);
7055 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7058 if (op1
!= 0x0f && op1
!= 0x0d) {
7059 rn
= (insn
>> 16) & 0xf;
7060 tmp
= load_reg(s
, rn
);
7064 rd
= (insn
>> 12) & 0xf;
7067 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7071 store_reg_bx(env
, s
, rd
, tmp
);
7074 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7078 store_reg_bx(env
, s
, rd
, tmp
);
7081 if (set_cc
&& rd
== 15) {
7082 /* SUBS r15, ... is used for exception return. */
7086 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7087 gen_exception_return(s
, tmp
);
7090 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7092 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7094 store_reg_bx(env
, s
, rd
, tmp
);
7099 gen_helper_sub_cc(tmp
, tmp2
, tmp
);
7101 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7103 store_reg_bx(env
, s
, rd
, tmp
);
7107 gen_helper_add_cc(tmp
, tmp
, tmp2
);
7109 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7111 store_reg_bx(env
, s
, rd
, tmp
);
7115 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
7117 gen_add_carry(tmp
, tmp
, tmp2
);
7119 store_reg_bx(env
, s
, rd
, tmp
);
7123 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
7125 gen_sub_carry(tmp
, tmp
, tmp2
);
7127 store_reg_bx(env
, s
, rd
, tmp
);
7131 gen_helper_sbc_cc(tmp
, tmp2
, tmp
);
7133 gen_sub_carry(tmp
, tmp2
, tmp
);
7135 store_reg_bx(env
, s
, rd
, tmp
);
7139 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7142 tcg_temp_free_i32(tmp
);
7146 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7149 tcg_temp_free_i32(tmp
);
7153 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
7155 tcg_temp_free_i32(tmp
);
7159 gen_helper_add_cc(tmp
, tmp
, tmp2
);
7161 tcg_temp_free_i32(tmp
);
7164 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7168 store_reg_bx(env
, s
, rd
, tmp
);
7171 if (logic_cc
&& rd
== 15) {
7172 /* MOVS r15, ... is used for exception return. */
7176 gen_exception_return(s
, tmp2
);
7181 store_reg_bx(env
, s
, rd
, tmp2
);
7185 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7189 store_reg_bx(env
, s
, rd
, tmp
);
7193 tcg_gen_not_i32(tmp2
, tmp2
);
7197 store_reg_bx(env
, s
, rd
, tmp2
);
7200 if (op1
!= 0x0f && op1
!= 0x0d) {
7201 tcg_temp_free_i32(tmp2
);
7204 /* other instructions */
7205 op1
= (insn
>> 24) & 0xf;
7209 /* multiplies, extra load/stores */
7210 sh
= (insn
>> 5) & 3;
7213 rd
= (insn
>> 16) & 0xf;
7214 rn
= (insn
>> 12) & 0xf;
7215 rs
= (insn
>> 8) & 0xf;
7217 op1
= (insn
>> 20) & 0xf;
7219 case 0: case 1: case 2: case 3: case 6:
7221 tmp
= load_reg(s
, rs
);
7222 tmp2
= load_reg(s
, rm
);
7223 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7224 tcg_temp_free_i32(tmp2
);
7225 if (insn
& (1 << 22)) {
7226 /* Subtract (mls) */
7228 tmp2
= load_reg(s
, rn
);
7229 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7230 tcg_temp_free_i32(tmp2
);
7231 } else if (insn
& (1 << 21)) {
7233 tmp2
= load_reg(s
, rn
);
7234 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7235 tcg_temp_free_i32(tmp2
);
7237 if (insn
& (1 << 20))
7239 store_reg(s
, rd
, tmp
);
7242 /* 64 bit mul double accumulate (UMAAL) */
7244 tmp
= load_reg(s
, rs
);
7245 tmp2
= load_reg(s
, rm
);
7246 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7247 gen_addq_lo(s
, tmp64
, rn
);
7248 gen_addq_lo(s
, tmp64
, rd
);
7249 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7250 tcg_temp_free_i64(tmp64
);
7252 case 8: case 9: case 10: case 11:
7253 case 12: case 13: case 14: case 15:
7254 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7255 tmp
= load_reg(s
, rs
);
7256 tmp2
= load_reg(s
, rm
);
7257 if (insn
& (1 << 22)) {
7258 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7260 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7262 if (insn
& (1 << 21)) { /* mult accumulate */
7263 gen_addq(s
, tmp64
, rn
, rd
);
7265 if (insn
& (1 << 20)) {
7266 gen_logicq_cc(tmp64
);
7268 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7269 tcg_temp_free_i64(tmp64
);
7275 rn
= (insn
>> 16) & 0xf;
7276 rd
= (insn
>> 12) & 0xf;
7277 if (insn
& (1 << 23)) {
7278 /* load/store exclusive */
7279 op1
= (insn
>> 21) & 0x3;
7284 addr
= tcg_temp_local_new_i32();
7285 load_reg_var(s
, addr
, rn
);
7286 if (insn
& (1 << 20)) {
7289 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7291 case 1: /* ldrexd */
7292 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7294 case 2: /* ldrexb */
7295 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7297 case 3: /* ldrexh */
7298 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7307 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7309 case 1: /* strexd */
7310 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7312 case 2: /* strexb */
7313 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7315 case 3: /* strexh */
7316 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7322 tcg_temp_free(addr
);
7324 /* SWP instruction */
7327 /* ??? This is not really atomic. However we know
7328 we never have multiple CPUs running in parallel,
7329 so it is good enough. */
7330 addr
= load_reg(s
, rn
);
7331 tmp
= load_reg(s
, rm
);
7332 if (insn
& (1 << 22)) {
7333 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7334 gen_st8(tmp
, addr
, IS_USER(s
));
7336 tmp2
= gen_ld32(addr
, IS_USER(s
));
7337 gen_st32(tmp
, addr
, IS_USER(s
));
7339 tcg_temp_free_i32(addr
);
7340 store_reg(s
, rd
, tmp2
);
7346 /* Misc load/store */
7347 rn
= (insn
>> 16) & 0xf;
7348 rd
= (insn
>> 12) & 0xf;
7349 addr
= load_reg(s
, rn
);
7350 if (insn
& (1 << 24))
7351 gen_add_datah_offset(s
, insn
, 0, addr
);
7353 if (insn
& (1 << 20)) {
7357 tmp
= gen_ld16u(addr
, IS_USER(s
));
7360 tmp
= gen_ld8s(addr
, IS_USER(s
));
7364 tmp
= gen_ld16s(addr
, IS_USER(s
));
7368 } else if (sh
& 2) {
7373 tmp
= load_reg(s
, rd
);
7374 gen_st32(tmp
, addr
, IS_USER(s
));
7375 tcg_gen_addi_i32(addr
, addr
, 4);
7376 tmp
= load_reg(s
, rd
+ 1);
7377 gen_st32(tmp
, addr
, IS_USER(s
));
7381 tmp
= gen_ld32(addr
, IS_USER(s
));
7382 store_reg(s
, rd
, tmp
);
7383 tcg_gen_addi_i32(addr
, addr
, 4);
7384 tmp
= gen_ld32(addr
, IS_USER(s
));
7388 address_offset
= -4;
7391 tmp
= load_reg(s
, rd
);
7392 gen_st16(tmp
, addr
, IS_USER(s
));
7395 /* Perform base writeback before the loaded value to
7396 ensure correct behavior with overlapping index registers.
7397 ldrd with base writeback is is undefined if the
7398 destination and index registers overlap. */
7399 if (!(insn
& (1 << 24))) {
7400 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7401 store_reg(s
, rn
, addr
);
7402 } else if (insn
& (1 << 21)) {
7404 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7405 store_reg(s
, rn
, addr
);
7407 tcg_temp_free_i32(addr
);
7410 /* Complete the load. */
7411 store_reg(s
, rd
, tmp
);
7420 if (insn
& (1 << 4)) {
7422 /* Armv6 Media instructions. */
7424 rn
= (insn
>> 16) & 0xf;
7425 rd
= (insn
>> 12) & 0xf;
7426 rs
= (insn
>> 8) & 0xf;
7427 switch ((insn
>> 23) & 3) {
7428 case 0: /* Parallel add/subtract. */
7429 op1
= (insn
>> 20) & 7;
7430 tmp
= load_reg(s
, rn
);
7431 tmp2
= load_reg(s
, rm
);
7432 sh
= (insn
>> 5) & 7;
7433 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7435 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7436 tcg_temp_free_i32(tmp2
);
7437 store_reg(s
, rd
, tmp
);
7440 if ((insn
& 0x00700020) == 0) {
7441 /* Halfword pack. */
7442 tmp
= load_reg(s
, rn
);
7443 tmp2
= load_reg(s
, rm
);
7444 shift
= (insn
>> 7) & 0x1f;
7445 if (insn
& (1 << 6)) {
7449 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7450 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7451 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7455 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7456 tcg_gen_ext16u_i32(tmp
, tmp
);
7457 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7459 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7460 tcg_temp_free_i32(tmp2
);
7461 store_reg(s
, rd
, tmp
);
7462 } else if ((insn
& 0x00200020) == 0x00200000) {
7464 tmp
= load_reg(s
, rm
);
7465 shift
= (insn
>> 7) & 0x1f;
7466 if (insn
& (1 << 6)) {
7469 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7471 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7473 sh
= (insn
>> 16) & 0x1f;
7474 tmp2
= tcg_const_i32(sh
);
7475 if (insn
& (1 << 22))
7476 gen_helper_usat(tmp
, tmp
, tmp2
);
7478 gen_helper_ssat(tmp
, tmp
, tmp2
);
7479 tcg_temp_free_i32(tmp2
);
7480 store_reg(s
, rd
, tmp
);
7481 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7483 tmp
= load_reg(s
, rm
);
7484 sh
= (insn
>> 16) & 0x1f;
7485 tmp2
= tcg_const_i32(sh
);
7486 if (insn
& (1 << 22))
7487 gen_helper_usat16(tmp
, tmp
, tmp2
);
7489 gen_helper_ssat16(tmp
, tmp
, tmp2
);
7490 tcg_temp_free_i32(tmp2
);
7491 store_reg(s
, rd
, tmp
);
7492 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7494 tmp
= load_reg(s
, rn
);
7495 tmp2
= load_reg(s
, rm
);
7496 tmp3
= tcg_temp_new_i32();
7497 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
7498 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7499 tcg_temp_free_i32(tmp3
);
7500 tcg_temp_free_i32(tmp2
);
7501 store_reg(s
, rd
, tmp
);
7502 } else if ((insn
& 0x000003e0) == 0x00000060) {
7503 tmp
= load_reg(s
, rm
);
7504 shift
= (insn
>> 10) & 3;
7505 /* ??? In many cases it's not necessary to do a
7506 rotate, a shift is sufficient. */
7508 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7509 op1
= (insn
>> 20) & 7;
7511 case 0: gen_sxtb16(tmp
); break;
7512 case 2: gen_sxtb(tmp
); break;
7513 case 3: gen_sxth(tmp
); break;
7514 case 4: gen_uxtb16(tmp
); break;
7515 case 6: gen_uxtb(tmp
); break;
7516 case 7: gen_uxth(tmp
); break;
7517 default: goto illegal_op
;
7520 tmp2
= load_reg(s
, rn
);
7521 if ((op1
& 3) == 0) {
7522 gen_add16(tmp
, tmp2
);
7524 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7525 tcg_temp_free_i32(tmp2
);
7528 store_reg(s
, rd
, tmp
);
7529 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7531 tmp
= load_reg(s
, rm
);
7532 if (insn
& (1 << 22)) {
7533 if (insn
& (1 << 7)) {
7537 gen_helper_rbit(tmp
, tmp
);
7540 if (insn
& (1 << 7))
7543 tcg_gen_bswap32_i32(tmp
, tmp
);
7545 store_reg(s
, rd
, tmp
);
7550 case 2: /* Multiplies (Type 3). */
7551 tmp
= load_reg(s
, rm
);
7552 tmp2
= load_reg(s
, rs
);
7553 if (insn
& (1 << 20)) {
7554 /* Signed multiply most significant [accumulate].
7555 (SMMUL, SMMLA, SMMLS) */
7556 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7559 tmp
= load_reg(s
, rd
);
7560 if (insn
& (1 << 6)) {
7561 tmp64
= gen_subq_msw(tmp64
, tmp
);
7563 tmp64
= gen_addq_msw(tmp64
, tmp
);
7566 if (insn
& (1 << 5)) {
7567 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7569 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7570 tmp
= tcg_temp_new_i32();
7571 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7572 tcg_temp_free_i64(tmp64
);
7573 store_reg(s
, rn
, tmp
);
7575 if (insn
& (1 << 5))
7576 gen_swap_half(tmp2
);
7577 gen_smul_dual(tmp
, tmp2
);
7578 if (insn
& (1 << 6)) {
7579 /* This subtraction cannot overflow. */
7580 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7582 /* This addition cannot overflow 32 bits;
7583 * however it may overflow considered as a signed
7584 * operation, in which case we must set the Q flag.
7586 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7588 tcg_temp_free_i32(tmp2
);
7589 if (insn
& (1 << 22)) {
7590 /* smlald, smlsld */
7591 tmp64
= tcg_temp_new_i64();
7592 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7593 tcg_temp_free_i32(tmp
);
7594 gen_addq(s
, tmp64
, rd
, rn
);
7595 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7596 tcg_temp_free_i64(tmp64
);
7598 /* smuad, smusd, smlad, smlsd */
7601 tmp2
= load_reg(s
, rd
);
7602 gen_helper_add_setq(tmp
, tmp
, tmp2
);
7603 tcg_temp_free_i32(tmp2
);
7605 store_reg(s
, rn
, tmp
);
7610 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7612 case 0: /* Unsigned sum of absolute differences. */
7614 tmp
= load_reg(s
, rm
);
7615 tmp2
= load_reg(s
, rs
);
7616 gen_helper_usad8(tmp
, tmp
, tmp2
);
7617 tcg_temp_free_i32(tmp2
);
7619 tmp2
= load_reg(s
, rd
);
7620 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7621 tcg_temp_free_i32(tmp2
);
7623 store_reg(s
, rn
, tmp
);
7625 case 0x20: case 0x24: case 0x28: case 0x2c:
7626 /* Bitfield insert/clear. */
7628 shift
= (insn
>> 7) & 0x1f;
7629 i
= (insn
>> 16) & 0x1f;
7632 tmp
= tcg_temp_new_i32();
7633 tcg_gen_movi_i32(tmp
, 0);
7635 tmp
= load_reg(s
, rm
);
7638 tmp2
= load_reg(s
, rd
);
7639 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << i
) - 1);
7640 tcg_temp_free_i32(tmp2
);
7642 store_reg(s
, rd
, tmp
);
7644 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7645 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7647 tmp
= load_reg(s
, rm
);
7648 shift
= (insn
>> 7) & 0x1f;
7649 i
= ((insn
>> 16) & 0x1f) + 1;
7654 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7656 gen_sbfx(tmp
, shift
, i
);
7659 store_reg(s
, rd
, tmp
);
7669 /* Check for undefined extension instructions
7670 * per the ARM Bible IE:
7671 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7673 sh
= (0xf << 20) | (0xf << 4);
7674 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7678 /* load/store byte/word */
7679 rn
= (insn
>> 16) & 0xf;
7680 rd
= (insn
>> 12) & 0xf;
7681 tmp2
= load_reg(s
, rn
);
7682 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7683 if (insn
& (1 << 24))
7684 gen_add_data_offset(s
, insn
, tmp2
);
7685 if (insn
& (1 << 20)) {
7687 if (insn
& (1 << 22)) {
7688 tmp
= gen_ld8u(tmp2
, i
);
7690 tmp
= gen_ld32(tmp2
, i
);
7694 tmp
= load_reg(s
, rd
);
7695 if (insn
& (1 << 22))
7696 gen_st8(tmp
, tmp2
, i
);
7698 gen_st32(tmp
, tmp2
, i
);
7700 if (!(insn
& (1 << 24))) {
7701 gen_add_data_offset(s
, insn
, tmp2
);
7702 store_reg(s
, rn
, tmp2
);
7703 } else if (insn
& (1 << 21)) {
7704 store_reg(s
, rn
, tmp2
);
7706 tcg_temp_free_i32(tmp2
);
7708 if (insn
& (1 << 20)) {
7709 /* Complete the load. */
7710 store_reg_from_load(env
, s
, rd
, tmp
);
7716 int j
, n
, user
, loaded_base
;
7718 /* load/store multiple words */
7719 /* XXX: store correct base if write back */
7721 if (insn
& (1 << 22)) {
7723 goto illegal_op
; /* only usable in supervisor mode */
7725 if ((insn
& (1 << 15)) == 0)
7728 rn
= (insn
>> 16) & 0xf;
7729 addr
= load_reg(s
, rn
);
7731 /* compute total size */
7733 TCGV_UNUSED(loaded_var
);
7736 if (insn
& (1 << i
))
7739 /* XXX: test invalid n == 0 case ? */
7740 if (insn
& (1 << 23)) {
7741 if (insn
& (1 << 24)) {
7743 tcg_gen_addi_i32(addr
, addr
, 4);
7745 /* post increment */
7748 if (insn
& (1 << 24)) {
7750 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7752 /* post decrement */
7754 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7759 if (insn
& (1 << i
)) {
7760 if (insn
& (1 << 20)) {
7762 tmp
= gen_ld32(addr
, IS_USER(s
));
7764 tmp2
= tcg_const_i32(i
);
7765 gen_helper_set_user_reg(tmp2
, tmp
);
7766 tcg_temp_free_i32(tmp2
);
7767 tcg_temp_free_i32(tmp
);
7768 } else if (i
== rn
) {
7772 store_reg_from_load(env
, s
, i
, tmp
);
7777 /* special case: r15 = PC + 8 */
7778 val
= (long)s
->pc
+ 4;
7779 tmp
= tcg_temp_new_i32();
7780 tcg_gen_movi_i32(tmp
, val
);
7782 tmp
= tcg_temp_new_i32();
7783 tmp2
= tcg_const_i32(i
);
7784 gen_helper_get_user_reg(tmp
, tmp2
);
7785 tcg_temp_free_i32(tmp2
);
7787 tmp
= load_reg(s
, i
);
7789 gen_st32(tmp
, addr
, IS_USER(s
));
7792 /* no need to add after the last transfer */
7794 tcg_gen_addi_i32(addr
, addr
, 4);
7797 if (insn
& (1 << 21)) {
7799 if (insn
& (1 << 23)) {
7800 if (insn
& (1 << 24)) {
7803 /* post increment */
7804 tcg_gen_addi_i32(addr
, addr
, 4);
7807 if (insn
& (1 << 24)) {
7810 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7812 /* post decrement */
7813 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7816 store_reg(s
, rn
, addr
);
7818 tcg_temp_free_i32(addr
);
7821 store_reg(s
, rn
, loaded_var
);
7823 if ((insn
& (1 << 22)) && !user
) {
7824 /* Restore CPSR from SPSR. */
7825 tmp
= load_cpu_field(spsr
);
7826 gen_set_cpsr(tmp
, 0xffffffff);
7827 tcg_temp_free_i32(tmp
);
7828 s
->is_jmp
= DISAS_UPDATE
;
7837 /* branch (and link) */
7838 val
= (int32_t)s
->pc
;
7839 if (insn
& (1 << 24)) {
7840 tmp
= tcg_temp_new_i32();
7841 tcg_gen_movi_i32(tmp
, val
);
7842 store_reg(s
, 14, tmp
);
7844 offset
= (((int32_t)insn
<< 8) >> 8);
7845 val
+= (offset
<< 2) + 4;
7853 if (disas_coproc_insn(env
, s
, insn
))
7858 gen_set_pc_im(s
->pc
);
7859 s
->is_jmp
= DISAS_SWI
;
7863 gen_exception_insn(s
, 4, EXCP_UDEF
);
7869 /* Return true if this is a Thumb-2 logical op. */
7871 thumb2_logic_op(int op
)
7876 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7877 then set condition code flags based on the result of the operation.
7878 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7879 to the high bit of T1.
7880 Returns zero if the opcode is valid. */
7883 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7890 tcg_gen_and_i32(t0
, t0
, t1
);
7894 tcg_gen_andc_i32(t0
, t0
, t1
);
7898 tcg_gen_or_i32(t0
, t0
, t1
);
7902 tcg_gen_orc_i32(t0
, t0
, t1
);
7906 tcg_gen_xor_i32(t0
, t0
, t1
);
7911 gen_helper_add_cc(t0
, t0
, t1
);
7913 tcg_gen_add_i32(t0
, t0
, t1
);
7917 gen_helper_adc_cc(t0
, t0
, t1
);
7923 gen_helper_sbc_cc(t0
, t0
, t1
);
7925 gen_sub_carry(t0
, t0
, t1
);
7929 gen_helper_sub_cc(t0
, t0
, t1
);
7931 tcg_gen_sub_i32(t0
, t0
, t1
);
7935 gen_helper_sub_cc(t0
, t1
, t0
);
7937 tcg_gen_sub_i32(t0
, t1
, t0
);
7939 default: /* 5, 6, 7, 9, 12, 15. */
7945 gen_set_CF_bit31(t1
);
7950 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7952 static int disas_thumb2_insn(CPUState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7954 uint32_t insn
, imm
, shift
, offset
;
7955 uint32_t rd
, rn
, rm
, rs
;
7966 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7967 || arm_feature (env
, ARM_FEATURE_M
))) {
7968 /* Thumb-1 cores may need to treat bl and blx as a pair of
7969 16-bit instructions to get correct prefetch abort behavior. */
7971 if ((insn
& (1 << 12)) == 0) {
7973 /* Second half of blx. */
7974 offset
= ((insn
& 0x7ff) << 1);
7975 tmp
= load_reg(s
, 14);
7976 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7977 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7979 tmp2
= tcg_temp_new_i32();
7980 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7981 store_reg(s
, 14, tmp2
);
7985 if (insn
& (1 << 11)) {
7986 /* Second half of bl. */
7987 offset
= ((insn
& 0x7ff) << 1) | 1;
7988 tmp
= load_reg(s
, 14);
7989 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7991 tmp2
= tcg_temp_new_i32();
7992 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7993 store_reg(s
, 14, tmp2
);
7997 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7998 /* Instruction spans a page boundary. Implement it as two
7999 16-bit instructions in case the second half causes an
8001 offset
= ((int32_t)insn
<< 21) >> 9;
8002 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8005 /* Fall through to 32-bit decode. */
8008 insn
= lduw_code(s
->pc
);
8010 insn
|= (uint32_t)insn_hw1
<< 16;
8012 if ((insn
& 0xf800e800) != 0xf000e800) {
8016 rn
= (insn
>> 16) & 0xf;
8017 rs
= (insn
>> 12) & 0xf;
8018 rd
= (insn
>> 8) & 0xf;
8020 switch ((insn
>> 25) & 0xf) {
8021 case 0: case 1: case 2: case 3:
8022 /* 16-bit instructions. Should never happen. */
8025 if (insn
& (1 << 22)) {
8026 /* Other load/store, table branch. */
8027 if (insn
& 0x01200000) {
8028 /* Load/store doubleword. */
8030 addr
= tcg_temp_new_i32();
8031 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8033 addr
= load_reg(s
, rn
);
8035 offset
= (insn
& 0xff) * 4;
8036 if ((insn
& (1 << 23)) == 0)
8038 if (insn
& (1 << 24)) {
8039 tcg_gen_addi_i32(addr
, addr
, offset
);
8042 if (insn
& (1 << 20)) {
8044 tmp
= gen_ld32(addr
, IS_USER(s
));
8045 store_reg(s
, rs
, tmp
);
8046 tcg_gen_addi_i32(addr
, addr
, 4);
8047 tmp
= gen_ld32(addr
, IS_USER(s
));
8048 store_reg(s
, rd
, tmp
);
8051 tmp
= load_reg(s
, rs
);
8052 gen_st32(tmp
, addr
, IS_USER(s
));
8053 tcg_gen_addi_i32(addr
, addr
, 4);
8054 tmp
= load_reg(s
, rd
);
8055 gen_st32(tmp
, addr
, IS_USER(s
));
8057 if (insn
& (1 << 21)) {
8058 /* Base writeback. */
8061 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8062 store_reg(s
, rn
, addr
);
8064 tcg_temp_free_i32(addr
);
8066 } else if ((insn
& (1 << 23)) == 0) {
8067 /* Load/store exclusive word. */
8068 addr
= tcg_temp_local_new();
8069 load_reg_var(s
, addr
, rn
);
8070 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8071 if (insn
& (1 << 20)) {
8072 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8074 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8076 tcg_temp_free(addr
);
8077 } else if ((insn
& (1 << 6)) == 0) {
8080 addr
= tcg_temp_new_i32();
8081 tcg_gen_movi_i32(addr
, s
->pc
);
8083 addr
= load_reg(s
, rn
);
8085 tmp
= load_reg(s
, rm
);
8086 tcg_gen_add_i32(addr
, addr
, tmp
);
8087 if (insn
& (1 << 4)) {
8089 tcg_gen_add_i32(addr
, addr
, tmp
);
8090 tcg_temp_free_i32(tmp
);
8091 tmp
= gen_ld16u(addr
, IS_USER(s
));
8093 tcg_temp_free_i32(tmp
);
8094 tmp
= gen_ld8u(addr
, IS_USER(s
));
8096 tcg_temp_free_i32(addr
);
8097 tcg_gen_shli_i32(tmp
, tmp
, 1);
8098 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8099 store_reg(s
, 15, tmp
);
8101 /* Load/store exclusive byte/halfword/doubleword. */
8103 op
= (insn
>> 4) & 0x3;
8107 addr
= tcg_temp_local_new();
8108 load_reg_var(s
, addr
, rn
);
8109 if (insn
& (1 << 20)) {
8110 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8112 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8114 tcg_temp_free(addr
);
8117 /* Load/store multiple, RFE, SRS. */
8118 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8119 /* Not available in user mode. */
8122 if (insn
& (1 << 20)) {
8124 addr
= load_reg(s
, rn
);
8125 if ((insn
& (1 << 24)) == 0)
8126 tcg_gen_addi_i32(addr
, addr
, -8);
8127 /* Load PC into tmp and CPSR into tmp2. */
8128 tmp
= gen_ld32(addr
, 0);
8129 tcg_gen_addi_i32(addr
, addr
, 4);
8130 tmp2
= gen_ld32(addr
, 0);
8131 if (insn
& (1 << 21)) {
8132 /* Base writeback. */
8133 if (insn
& (1 << 24)) {
8134 tcg_gen_addi_i32(addr
, addr
, 4);
8136 tcg_gen_addi_i32(addr
, addr
, -4);
8138 store_reg(s
, rn
, addr
);
8140 tcg_temp_free_i32(addr
);
8142 gen_rfe(s
, tmp
, tmp2
);
8146 addr
= tcg_temp_new_i32();
8147 tmp
= tcg_const_i32(op
);
8148 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8149 tcg_temp_free_i32(tmp
);
8150 if ((insn
& (1 << 24)) == 0) {
8151 tcg_gen_addi_i32(addr
, addr
, -8);
8153 tmp
= load_reg(s
, 14);
8154 gen_st32(tmp
, addr
, 0);
8155 tcg_gen_addi_i32(addr
, addr
, 4);
8156 tmp
= tcg_temp_new_i32();
8157 gen_helper_cpsr_read(tmp
);
8158 gen_st32(tmp
, addr
, 0);
8159 if (insn
& (1 << 21)) {
8160 if ((insn
& (1 << 24)) == 0) {
8161 tcg_gen_addi_i32(addr
, addr
, -4);
8163 tcg_gen_addi_i32(addr
, addr
, 4);
8165 tmp
= tcg_const_i32(op
);
8166 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8167 tcg_temp_free_i32(tmp
);
8169 tcg_temp_free_i32(addr
);
8173 int i
, loaded_base
= 0;
8175 /* Load/store multiple. */
8176 addr
= load_reg(s
, rn
);
8178 for (i
= 0; i
< 16; i
++) {
8179 if (insn
& (1 << i
))
8182 if (insn
& (1 << 24)) {
8183 tcg_gen_addi_i32(addr
, addr
, -offset
);
8186 TCGV_UNUSED(loaded_var
);
8187 for (i
= 0; i
< 16; i
++) {
8188 if ((insn
& (1 << i
)) == 0)
8190 if (insn
& (1 << 20)) {
8192 tmp
= gen_ld32(addr
, IS_USER(s
));
8195 } else if (i
== rn
) {
8199 store_reg(s
, i
, tmp
);
8203 tmp
= load_reg(s
, i
);
8204 gen_st32(tmp
, addr
, IS_USER(s
));
8206 tcg_gen_addi_i32(addr
, addr
, 4);
8209 store_reg(s
, rn
, loaded_var
);
8211 if (insn
& (1 << 21)) {
8212 /* Base register writeback. */
8213 if (insn
& (1 << 24)) {
8214 tcg_gen_addi_i32(addr
, addr
, -offset
);
8216 /* Fault if writeback register is in register list. */
8217 if (insn
& (1 << rn
))
8219 store_reg(s
, rn
, addr
);
8221 tcg_temp_free_i32(addr
);
8228 op
= (insn
>> 21) & 0xf;
8230 /* Halfword pack. */
8231 tmp
= load_reg(s
, rn
);
8232 tmp2
= load_reg(s
, rm
);
8233 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8234 if (insn
& (1 << 5)) {
8238 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8239 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8240 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8244 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8245 tcg_gen_ext16u_i32(tmp
, tmp
);
8246 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8248 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8249 tcg_temp_free_i32(tmp2
);
8250 store_reg(s
, rd
, tmp
);
8252 /* Data processing register constant shift. */
8254 tmp
= tcg_temp_new_i32();
8255 tcg_gen_movi_i32(tmp
, 0);
8257 tmp
= load_reg(s
, rn
);
8259 tmp2
= load_reg(s
, rm
);
8261 shiftop
= (insn
>> 4) & 3;
8262 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8263 conds
= (insn
& (1 << 20)) != 0;
8264 logic_cc
= (conds
&& thumb2_logic_op(op
));
8265 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8266 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8268 tcg_temp_free_i32(tmp2
);
8270 store_reg(s
, rd
, tmp
);
8272 tcg_temp_free_i32(tmp
);
8276 case 13: /* Misc data processing. */
8277 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8278 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8281 case 0: /* Register controlled shift. */
8282 tmp
= load_reg(s
, rn
);
8283 tmp2
= load_reg(s
, rm
);
8284 if ((insn
& 0x70) != 0)
8286 op
= (insn
>> 21) & 3;
8287 logic_cc
= (insn
& (1 << 20)) != 0;
8288 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8291 store_reg_bx(env
, s
, rd
, tmp
);
8293 case 1: /* Sign/zero extend. */
8294 tmp
= load_reg(s
, rm
);
8295 shift
= (insn
>> 4) & 3;
8296 /* ??? In many cases it's not necessary to do a
8297 rotate, a shift is sufficient. */
8299 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8300 op
= (insn
>> 20) & 7;
8302 case 0: gen_sxth(tmp
); break;
8303 case 1: gen_uxth(tmp
); break;
8304 case 2: gen_sxtb16(tmp
); break;
8305 case 3: gen_uxtb16(tmp
); break;
8306 case 4: gen_sxtb(tmp
); break;
8307 case 5: gen_uxtb(tmp
); break;
8308 default: goto illegal_op
;
8311 tmp2
= load_reg(s
, rn
);
8312 if ((op
>> 1) == 1) {
8313 gen_add16(tmp
, tmp2
);
8315 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8316 tcg_temp_free_i32(tmp2
);
8319 store_reg(s
, rd
, tmp
);
8321 case 2: /* SIMD add/subtract. */
8322 op
= (insn
>> 20) & 7;
8323 shift
= (insn
>> 4) & 7;
8324 if ((op
& 3) == 3 || (shift
& 3) == 3)
8326 tmp
= load_reg(s
, rn
);
8327 tmp2
= load_reg(s
, rm
);
8328 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8329 tcg_temp_free_i32(tmp2
);
8330 store_reg(s
, rd
, tmp
);
8332 case 3: /* Other data processing. */
8333 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8335 /* Saturating add/subtract. */
8336 tmp
= load_reg(s
, rn
);
8337 tmp2
= load_reg(s
, rm
);
8339 gen_helper_double_saturate(tmp
, tmp
);
8341 gen_helper_sub_saturate(tmp
, tmp2
, tmp
);
8343 gen_helper_add_saturate(tmp
, tmp
, tmp2
);
8344 tcg_temp_free_i32(tmp2
);
8346 tmp
= load_reg(s
, rn
);
8348 case 0x0a: /* rbit */
8349 gen_helper_rbit(tmp
, tmp
);
8351 case 0x08: /* rev */
8352 tcg_gen_bswap32_i32(tmp
, tmp
);
8354 case 0x09: /* rev16 */
8357 case 0x0b: /* revsh */
8360 case 0x10: /* sel */
8361 tmp2
= load_reg(s
, rm
);
8362 tmp3
= tcg_temp_new_i32();
8363 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUState
, GE
));
8364 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8365 tcg_temp_free_i32(tmp3
);
8366 tcg_temp_free_i32(tmp2
);
8368 case 0x18: /* clz */
8369 gen_helper_clz(tmp
, tmp
);
8375 store_reg(s
, rd
, tmp
);
8377 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8378 op
= (insn
>> 4) & 0xf;
8379 tmp
= load_reg(s
, rn
);
8380 tmp2
= load_reg(s
, rm
);
8381 switch ((insn
>> 20) & 7) {
8382 case 0: /* 32 x 32 -> 32 */
8383 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8384 tcg_temp_free_i32(tmp2
);
8386 tmp2
= load_reg(s
, rs
);
8388 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8390 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8391 tcg_temp_free_i32(tmp2
);
8394 case 1: /* 16 x 16 -> 32 */
8395 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8396 tcg_temp_free_i32(tmp2
);
8398 tmp2
= load_reg(s
, rs
);
8399 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8400 tcg_temp_free_i32(tmp2
);
8403 case 2: /* Dual multiply add. */
8404 case 4: /* Dual multiply subtract. */
8406 gen_swap_half(tmp2
);
8407 gen_smul_dual(tmp
, tmp2
);
8408 if (insn
& (1 << 22)) {
8409 /* This subtraction cannot overflow. */
8410 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8412 /* This addition cannot overflow 32 bits;
8413 * however it may overflow considered as a signed
8414 * operation, in which case we must set the Q flag.
8416 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8418 tcg_temp_free_i32(tmp2
);
8421 tmp2
= load_reg(s
, rs
);
8422 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8423 tcg_temp_free_i32(tmp2
);
8426 case 3: /* 32 * 16 -> 32msb */
8428 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8431 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8432 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8433 tmp
= tcg_temp_new_i32();
8434 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8435 tcg_temp_free_i64(tmp64
);
8438 tmp2
= load_reg(s
, rs
);
8439 gen_helper_add_setq(tmp
, tmp
, tmp2
);
8440 tcg_temp_free_i32(tmp2
);
8443 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8444 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8446 tmp
= load_reg(s
, rs
);
8447 if (insn
& (1 << 20)) {
8448 tmp64
= gen_addq_msw(tmp64
, tmp
);
8450 tmp64
= gen_subq_msw(tmp64
, tmp
);
8453 if (insn
& (1 << 4)) {
8454 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8456 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8457 tmp
= tcg_temp_new_i32();
8458 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8459 tcg_temp_free_i64(tmp64
);
8461 case 7: /* Unsigned sum of absolute differences. */
8462 gen_helper_usad8(tmp
, tmp
, tmp2
);
8463 tcg_temp_free_i32(tmp2
);
8465 tmp2
= load_reg(s
, rs
);
8466 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8467 tcg_temp_free_i32(tmp2
);
8471 store_reg(s
, rd
, tmp
);
8473 case 6: case 7: /* 64-bit multiply, Divide. */
8474 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8475 tmp
= load_reg(s
, rn
);
8476 tmp2
= load_reg(s
, rm
);
8477 if ((op
& 0x50) == 0x10) {
8479 if (!arm_feature(env
, ARM_FEATURE_DIV
))
8482 gen_helper_udiv(tmp
, tmp
, tmp2
);
8484 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8485 tcg_temp_free_i32(tmp2
);
8486 store_reg(s
, rd
, tmp
);
8487 } else if ((op
& 0xe) == 0xc) {
8488 /* Dual multiply accumulate long. */
8490 gen_swap_half(tmp2
);
8491 gen_smul_dual(tmp
, tmp2
);
8493 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8495 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8497 tcg_temp_free_i32(tmp2
);
8499 tmp64
= tcg_temp_new_i64();
8500 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8501 tcg_temp_free_i32(tmp
);
8502 gen_addq(s
, tmp64
, rs
, rd
);
8503 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8504 tcg_temp_free_i64(tmp64
);
8507 /* Unsigned 64-bit multiply */
8508 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8512 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8513 tcg_temp_free_i32(tmp2
);
8514 tmp64
= tcg_temp_new_i64();
8515 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8516 tcg_temp_free_i32(tmp
);
8518 /* Signed 64-bit multiply */
8519 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8524 gen_addq_lo(s
, tmp64
, rs
);
8525 gen_addq_lo(s
, tmp64
, rd
);
8526 } else if (op
& 0x40) {
8527 /* 64-bit accumulate. */
8528 gen_addq(s
, tmp64
, rs
, rd
);
8530 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8531 tcg_temp_free_i64(tmp64
);
8536 case 6: case 7: case 14: case 15:
8538 if (((insn
>> 24) & 3) == 3) {
8539 /* Translate into the equivalent ARM encoding. */
8540 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8541 if (disas_neon_data_insn(env
, s
, insn
))
8544 if (insn
& (1 << 28))
8546 if (disas_coproc_insn (env
, s
, insn
))
8550 case 8: case 9: case 10: case 11:
8551 if (insn
& (1 << 15)) {
8552 /* Branches, misc control. */
8553 if (insn
& 0x5000) {
8554 /* Unconditional branch. */
8555 /* signextend(hw1[10:0]) -> offset[:12]. */
8556 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8557 /* hw1[10:0] -> offset[11:1]. */
8558 offset
|= (insn
& 0x7ff) << 1;
8559 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8560 offset[24:22] already have the same value because of the
8561 sign extension above. */
8562 offset
^= ((~insn
) & (1 << 13)) << 10;
8563 offset
^= ((~insn
) & (1 << 11)) << 11;
8565 if (insn
& (1 << 14)) {
8566 /* Branch and link. */
8567 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8571 if (insn
& (1 << 12)) {
8576 offset
&= ~(uint32_t)2;
8577 /* thumb2 bx, no need to check */
8578 gen_bx_im(s
, offset
);
8580 } else if (((insn
>> 23) & 7) == 7) {
8582 if (insn
& (1 << 13))
8585 if (insn
& (1 << 26)) {
8586 /* Secure monitor call (v6Z) */
8587 goto illegal_op
; /* not implemented. */
8589 op
= (insn
>> 20) & 7;
8591 case 0: /* msr cpsr. */
8593 tmp
= load_reg(s
, rn
);
8594 addr
= tcg_const_i32(insn
& 0xff);
8595 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8596 tcg_temp_free_i32(addr
);
8597 tcg_temp_free_i32(tmp
);
8602 case 1: /* msr spsr. */
8605 tmp
= load_reg(s
, rn
);
8607 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8611 case 2: /* cps, nop-hint. */
8612 if (((insn
>> 8) & 7) == 0) {
8613 gen_nop_hint(s
, insn
& 0xff);
8615 /* Implemented as NOP in user mode. */
8620 if (insn
& (1 << 10)) {
8621 if (insn
& (1 << 7))
8623 if (insn
& (1 << 6))
8625 if (insn
& (1 << 5))
8627 if (insn
& (1 << 9))
8628 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8630 if (insn
& (1 << 8)) {
8632 imm
|= (insn
& 0x1f);
8635 gen_set_psr_im(s
, offset
, 0, imm
);
8638 case 3: /* Special control operations. */
8640 op
= (insn
>> 4) & 0xf;
8648 /* These execute as NOPs. */
8655 /* Trivial implementation equivalent to bx. */
8656 tmp
= load_reg(s
, rn
);
8659 case 5: /* Exception return. */
8663 if (rn
!= 14 || rd
!= 15) {
8666 tmp
= load_reg(s
, rn
);
8667 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8668 gen_exception_return(s
, tmp
);
8670 case 6: /* mrs cpsr. */
8671 tmp
= tcg_temp_new_i32();
8673 addr
= tcg_const_i32(insn
& 0xff);
8674 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8675 tcg_temp_free_i32(addr
);
8677 gen_helper_cpsr_read(tmp
);
8679 store_reg(s
, rd
, tmp
);
8681 case 7: /* mrs spsr. */
8682 /* Not accessible in user mode. */
8683 if (IS_USER(s
) || IS_M(env
))
8685 tmp
= load_cpu_field(spsr
);
8686 store_reg(s
, rd
, tmp
);
8691 /* Conditional branch. */
8692 op
= (insn
>> 22) & 0xf;
8693 /* Generate a conditional jump to next instruction. */
8694 s
->condlabel
= gen_new_label();
8695 gen_test_cc(op
^ 1, s
->condlabel
);
8698 /* offset[11:1] = insn[10:0] */
8699 offset
= (insn
& 0x7ff) << 1;
8700 /* offset[17:12] = insn[21:16]. */
8701 offset
|= (insn
& 0x003f0000) >> 4;
8702 /* offset[31:20] = insn[26]. */
8703 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8704 /* offset[18] = insn[13]. */
8705 offset
|= (insn
& (1 << 13)) << 5;
8706 /* offset[19] = insn[11]. */
8707 offset
|= (insn
& (1 << 11)) << 8;
8709 /* jump to the offset */
8710 gen_jmp(s
, s
->pc
+ offset
);
8713 /* Data processing immediate. */
8714 if (insn
& (1 << 25)) {
8715 if (insn
& (1 << 24)) {
8716 if (insn
& (1 << 20))
8718 /* Bitfield/Saturate. */
8719 op
= (insn
>> 21) & 7;
8721 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8723 tmp
= tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp
, 0);
8726 tmp
= load_reg(s
, rn
);
8729 case 2: /* Signed bitfield extract. */
8731 if (shift
+ imm
> 32)
8734 gen_sbfx(tmp
, shift
, imm
);
8736 case 6: /* Unsigned bitfield extract. */
8738 if (shift
+ imm
> 32)
8741 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8743 case 3: /* Bitfield insert/clear. */
8746 imm
= imm
+ 1 - shift
;
8748 tmp2
= load_reg(s
, rd
);
8749 gen_bfi(tmp
, tmp2
, tmp
, shift
, (1u << imm
) - 1);
8750 tcg_temp_free_i32(tmp2
);
8755 default: /* Saturate. */
8758 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8760 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8762 tmp2
= tcg_const_i32(imm
);
8765 if ((op
& 1) && shift
== 0)
8766 gen_helper_usat16(tmp
, tmp
, tmp2
);
8768 gen_helper_usat(tmp
, tmp
, tmp2
);
8771 if ((op
& 1) && shift
== 0)
8772 gen_helper_ssat16(tmp
, tmp
, tmp2
);
8774 gen_helper_ssat(tmp
, tmp
, tmp2
);
8776 tcg_temp_free_i32(tmp2
);
8779 store_reg(s
, rd
, tmp
);
8781 imm
= ((insn
& 0x04000000) >> 15)
8782 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8783 if (insn
& (1 << 22)) {
8784 /* 16-bit immediate. */
8785 imm
|= (insn
>> 4) & 0xf000;
8786 if (insn
& (1 << 23)) {
8788 tmp
= load_reg(s
, rd
);
8789 tcg_gen_ext16u_i32(tmp
, tmp
);
8790 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8793 tmp
= tcg_temp_new_i32();
8794 tcg_gen_movi_i32(tmp
, imm
);
8797 /* Add/sub 12-bit immediate. */
8799 offset
= s
->pc
& ~(uint32_t)3;
8800 if (insn
& (1 << 23))
8804 tmp
= tcg_temp_new_i32();
8805 tcg_gen_movi_i32(tmp
, offset
);
8807 tmp
= load_reg(s
, rn
);
8808 if (insn
& (1 << 23))
8809 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8811 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8814 store_reg(s
, rd
, tmp
);
8817 int shifter_out
= 0;
8818 /* modified 12-bit immediate. */
8819 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8820 imm
= (insn
& 0xff);
8823 /* Nothing to do. */
8825 case 1: /* 00XY00XY */
8828 case 2: /* XY00XY00 */
8832 case 3: /* XYXYXYXY */
8836 default: /* Rotated constant. */
8837 shift
= (shift
<< 1) | (imm
>> 7);
8839 imm
= imm
<< (32 - shift
);
8843 tmp2
= tcg_temp_new_i32();
8844 tcg_gen_movi_i32(tmp2
, imm
);
8845 rn
= (insn
>> 16) & 0xf;
8847 tmp
= tcg_temp_new_i32();
8848 tcg_gen_movi_i32(tmp
, 0);
8850 tmp
= load_reg(s
, rn
);
8852 op
= (insn
>> 21) & 0xf;
8853 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8854 shifter_out
, tmp
, tmp2
))
8856 tcg_temp_free_i32(tmp2
);
8857 rd
= (insn
>> 8) & 0xf;
8859 store_reg(s
, rd
, tmp
);
8861 tcg_temp_free_i32(tmp
);
8866 case 12: /* Load/store single data item. */
8871 if ((insn
& 0x01100000) == 0x01000000) {
8872 if (disas_neon_ls_insn(env
, s
, insn
))
8876 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8878 if (!(insn
& (1 << 20))) {
8882 /* Byte or halfword load space with dest == r15 : memory hints.
8883 * Catch them early so we don't emit pointless addressing code.
8884 * This space is a mix of:
8885 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8886 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8888 * unallocated hints, which must be treated as NOPs
8889 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8890 * which is easiest for the decoding logic
8891 * Some space which must UNDEF
8893 int op1
= (insn
>> 23) & 3;
8894 int op2
= (insn
>> 6) & 0x3f;
8899 /* UNPREDICTABLE or unallocated hint */
8903 return 0; /* PLD* or unallocated hint */
8905 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8906 return 0; /* PLD* or unallocated hint */
8908 /* UNDEF space, or an UNPREDICTABLE */
8914 addr
= tcg_temp_new_i32();
8916 /* s->pc has already been incremented by 4. */
8917 imm
= s
->pc
& 0xfffffffc;
8918 if (insn
& (1 << 23))
8919 imm
+= insn
& 0xfff;
8921 imm
-= insn
& 0xfff;
8922 tcg_gen_movi_i32(addr
, imm
);
8924 addr
= load_reg(s
, rn
);
8925 if (insn
& (1 << 23)) {
8926 /* Positive offset. */
8928 tcg_gen_addi_i32(addr
, addr
, imm
);
8931 switch ((insn
>> 8) & 0xf) {
8932 case 0x0: /* Shifted Register. */
8933 shift
= (insn
>> 4) & 0xf;
8935 tcg_temp_free_i32(addr
);
8938 tmp
= load_reg(s
, rm
);
8940 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8941 tcg_gen_add_i32(addr
, addr
, tmp
);
8942 tcg_temp_free_i32(tmp
);
8944 case 0xc: /* Negative offset. */
8945 tcg_gen_addi_i32(addr
, addr
, -imm
);
8947 case 0xe: /* User privilege. */
8948 tcg_gen_addi_i32(addr
, addr
, imm
);
8951 case 0x9: /* Post-decrement. */
8954 case 0xb: /* Post-increment. */
8958 case 0xd: /* Pre-decrement. */
8961 case 0xf: /* Pre-increment. */
8962 tcg_gen_addi_i32(addr
, addr
, imm
);
8966 tcg_temp_free_i32(addr
);
8971 if (insn
& (1 << 20)) {
8974 case 0: tmp
= gen_ld8u(addr
, user
); break;
8975 case 4: tmp
= gen_ld8s(addr
, user
); break;
8976 case 1: tmp
= gen_ld16u(addr
, user
); break;
8977 case 5: tmp
= gen_ld16s(addr
, user
); break;
8978 case 2: tmp
= gen_ld32(addr
, user
); break;
8980 tcg_temp_free_i32(addr
);
8986 store_reg(s
, rs
, tmp
);
8990 tmp
= load_reg(s
, rs
);
8992 case 0: gen_st8(tmp
, addr
, user
); break;
8993 case 1: gen_st16(tmp
, addr
, user
); break;
8994 case 2: gen_st32(tmp
, addr
, user
); break;
8996 tcg_temp_free_i32(addr
);
9001 tcg_gen_addi_i32(addr
, addr
, imm
);
9003 store_reg(s
, rn
, addr
);
9005 tcg_temp_free_i32(addr
);
9017 static void disas_thumb_insn(CPUState
*env
, DisasContext
*s
)
9019 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9026 if (s
->condexec_mask
) {
9027 cond
= s
->condexec_cond
;
9028 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9029 s
->condlabel
= gen_new_label();
9030 gen_test_cc(cond
^ 1, s
->condlabel
);
9035 insn
= lduw_code(s
->pc
);
9038 switch (insn
>> 12) {
9042 op
= (insn
>> 11) & 3;
9045 rn
= (insn
>> 3) & 7;
9046 tmp
= load_reg(s
, rn
);
9047 if (insn
& (1 << 10)) {
9049 tmp2
= tcg_temp_new_i32();
9050 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9053 rm
= (insn
>> 6) & 7;
9054 tmp2
= load_reg(s
, rm
);
9056 if (insn
& (1 << 9)) {
9057 if (s
->condexec_mask
)
9058 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9060 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9062 if (s
->condexec_mask
)
9063 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9065 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9067 tcg_temp_free_i32(tmp2
);
9068 store_reg(s
, rd
, tmp
);
9070 /* shift immediate */
9071 rm
= (insn
>> 3) & 7;
9072 shift
= (insn
>> 6) & 0x1f;
9073 tmp
= load_reg(s
, rm
);
9074 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9075 if (!s
->condexec_mask
)
9077 store_reg(s
, rd
, tmp
);
9081 /* arithmetic large immediate */
9082 op
= (insn
>> 11) & 3;
9083 rd
= (insn
>> 8) & 0x7;
9084 if (op
== 0) { /* mov */
9085 tmp
= tcg_temp_new_i32();
9086 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9087 if (!s
->condexec_mask
)
9089 store_reg(s
, rd
, tmp
);
9091 tmp
= load_reg(s
, rd
);
9092 tmp2
= tcg_temp_new_i32();
9093 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9096 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9097 tcg_temp_free_i32(tmp
);
9098 tcg_temp_free_i32(tmp2
);
9101 if (s
->condexec_mask
)
9102 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9104 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9105 tcg_temp_free_i32(tmp2
);
9106 store_reg(s
, rd
, tmp
);
9109 if (s
->condexec_mask
)
9110 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9112 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9113 tcg_temp_free_i32(tmp2
);
9114 store_reg(s
, rd
, tmp
);
9120 if (insn
& (1 << 11)) {
9121 rd
= (insn
>> 8) & 7;
9122 /* load pc-relative. Bit 1 of PC is ignored. */
9123 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9124 val
&= ~(uint32_t)2;
9125 addr
= tcg_temp_new_i32();
9126 tcg_gen_movi_i32(addr
, val
);
9127 tmp
= gen_ld32(addr
, IS_USER(s
));
9128 tcg_temp_free_i32(addr
);
9129 store_reg(s
, rd
, tmp
);
9132 if (insn
& (1 << 10)) {
9133 /* data processing extended or blx */
9134 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9135 rm
= (insn
>> 3) & 0xf;
9136 op
= (insn
>> 8) & 3;
9139 tmp
= load_reg(s
, rd
);
9140 tmp2
= load_reg(s
, rm
);
9141 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9142 tcg_temp_free_i32(tmp2
);
9143 store_reg(s
, rd
, tmp
);
9146 tmp
= load_reg(s
, rd
);
9147 tmp2
= load_reg(s
, rm
);
9148 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9149 tcg_temp_free_i32(tmp2
);
9150 tcg_temp_free_i32(tmp
);
9152 case 2: /* mov/cpy */
9153 tmp
= load_reg(s
, rm
);
9154 store_reg(s
, rd
, tmp
);
9156 case 3:/* branch [and link] exchange thumb register */
9157 tmp
= load_reg(s
, rm
);
9158 if (insn
& (1 << 7)) {
9160 val
= (uint32_t)s
->pc
| 1;
9161 tmp2
= tcg_temp_new_i32();
9162 tcg_gen_movi_i32(tmp2
, val
);
9163 store_reg(s
, 14, tmp2
);
9165 /* already thumb, no need to check */
9172 /* data processing register */
9174 rm
= (insn
>> 3) & 7;
9175 op
= (insn
>> 6) & 0xf;
9176 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9177 /* the shift/rotate ops want the operands backwards */
9186 if (op
== 9) { /* neg */
9187 tmp
= tcg_temp_new_i32();
9188 tcg_gen_movi_i32(tmp
, 0);
9189 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9190 tmp
= load_reg(s
, rd
);
9195 tmp2
= load_reg(s
, rm
);
9198 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9199 if (!s
->condexec_mask
)
9203 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9204 if (!s
->condexec_mask
)
9208 if (s
->condexec_mask
) {
9209 gen_helper_shl(tmp2
, tmp2
, tmp
);
9211 gen_helper_shl_cc(tmp2
, tmp2
, tmp
);
9216 if (s
->condexec_mask
) {
9217 gen_helper_shr(tmp2
, tmp2
, tmp
);
9219 gen_helper_shr_cc(tmp2
, tmp2
, tmp
);
9224 if (s
->condexec_mask
) {
9225 gen_helper_sar(tmp2
, tmp2
, tmp
);
9227 gen_helper_sar_cc(tmp2
, tmp2
, tmp
);
9232 if (s
->condexec_mask
)
9235 gen_helper_adc_cc(tmp
, tmp
, tmp2
);
9238 if (s
->condexec_mask
)
9239 gen_sub_carry(tmp
, tmp
, tmp2
);
9241 gen_helper_sbc_cc(tmp
, tmp
, tmp2
);
9244 if (s
->condexec_mask
) {
9245 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9246 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9248 gen_helper_ror_cc(tmp2
, tmp2
, tmp
);
9253 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9258 if (s
->condexec_mask
)
9259 tcg_gen_neg_i32(tmp
, tmp2
);
9261 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9264 gen_helper_sub_cc(tmp
, tmp
, tmp2
);
9268 gen_helper_add_cc(tmp
, tmp
, tmp2
);
9272 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9273 if (!s
->condexec_mask
)
9277 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9278 if (!s
->condexec_mask
)
9282 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9283 if (!s
->condexec_mask
)
9287 tcg_gen_not_i32(tmp2
, tmp2
);
9288 if (!s
->condexec_mask
)
9296 store_reg(s
, rm
, tmp2
);
9298 tcg_temp_free_i32(tmp
);
9300 store_reg(s
, rd
, tmp
);
9301 tcg_temp_free_i32(tmp2
);
9304 tcg_temp_free_i32(tmp
);
9305 tcg_temp_free_i32(tmp2
);
9310 /* load/store register offset. */
9312 rn
= (insn
>> 3) & 7;
9313 rm
= (insn
>> 6) & 7;
9314 op
= (insn
>> 9) & 7;
9315 addr
= load_reg(s
, rn
);
9316 tmp
= load_reg(s
, rm
);
9317 tcg_gen_add_i32(addr
, addr
, tmp
);
9318 tcg_temp_free_i32(tmp
);
9320 if (op
< 3) /* store */
9321 tmp
= load_reg(s
, rd
);
9325 gen_st32(tmp
, addr
, IS_USER(s
));
9328 gen_st16(tmp
, addr
, IS_USER(s
));
9331 gen_st8(tmp
, addr
, IS_USER(s
));
9334 tmp
= gen_ld8s(addr
, IS_USER(s
));
9337 tmp
= gen_ld32(addr
, IS_USER(s
));
9340 tmp
= gen_ld16u(addr
, IS_USER(s
));
9343 tmp
= gen_ld8u(addr
, IS_USER(s
));
9346 tmp
= gen_ld16s(addr
, IS_USER(s
));
9349 if (op
>= 3) /* load */
9350 store_reg(s
, rd
, tmp
);
9351 tcg_temp_free_i32(addr
);
9355 /* load/store word immediate offset */
9357 rn
= (insn
>> 3) & 7;
9358 addr
= load_reg(s
, rn
);
9359 val
= (insn
>> 4) & 0x7c;
9360 tcg_gen_addi_i32(addr
, addr
, val
);
9362 if (insn
& (1 << 11)) {
9364 tmp
= gen_ld32(addr
, IS_USER(s
));
9365 store_reg(s
, rd
, tmp
);
9368 tmp
= load_reg(s
, rd
);
9369 gen_st32(tmp
, addr
, IS_USER(s
));
9371 tcg_temp_free_i32(addr
);
9375 /* load/store byte immediate offset */
9377 rn
= (insn
>> 3) & 7;
9378 addr
= load_reg(s
, rn
);
9379 val
= (insn
>> 6) & 0x1f;
9380 tcg_gen_addi_i32(addr
, addr
, val
);
9382 if (insn
& (1 << 11)) {
9384 tmp
= gen_ld8u(addr
, IS_USER(s
));
9385 store_reg(s
, rd
, tmp
);
9388 tmp
= load_reg(s
, rd
);
9389 gen_st8(tmp
, addr
, IS_USER(s
));
9391 tcg_temp_free_i32(addr
);
9395 /* load/store halfword immediate offset */
9397 rn
= (insn
>> 3) & 7;
9398 addr
= load_reg(s
, rn
);
9399 val
= (insn
>> 5) & 0x3e;
9400 tcg_gen_addi_i32(addr
, addr
, val
);
9402 if (insn
& (1 << 11)) {
9404 tmp
= gen_ld16u(addr
, IS_USER(s
));
9405 store_reg(s
, rd
, tmp
);
9408 tmp
= load_reg(s
, rd
);
9409 gen_st16(tmp
, addr
, IS_USER(s
));
9411 tcg_temp_free_i32(addr
);
9415 /* load/store from stack */
9416 rd
= (insn
>> 8) & 7;
9417 addr
= load_reg(s
, 13);
9418 val
= (insn
& 0xff) * 4;
9419 tcg_gen_addi_i32(addr
, addr
, val
);
9421 if (insn
& (1 << 11)) {
9423 tmp
= gen_ld32(addr
, IS_USER(s
));
9424 store_reg(s
, rd
, tmp
);
9427 tmp
= load_reg(s
, rd
);
9428 gen_st32(tmp
, addr
, IS_USER(s
));
9430 tcg_temp_free_i32(addr
);
9434 /* add to high reg */
9435 rd
= (insn
>> 8) & 7;
9436 if (insn
& (1 << 11)) {
9438 tmp
= load_reg(s
, 13);
9440 /* PC. bit 1 is ignored. */
9441 tmp
= tcg_temp_new_i32();
9442 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9444 val
= (insn
& 0xff) * 4;
9445 tcg_gen_addi_i32(tmp
, tmp
, val
);
9446 store_reg(s
, rd
, tmp
);
9451 op
= (insn
>> 8) & 0xf;
9454 /* adjust stack pointer */
9455 tmp
= load_reg(s
, 13);
9456 val
= (insn
& 0x7f) * 4;
9457 if (insn
& (1 << 7))
9458 val
= -(int32_t)val
;
9459 tcg_gen_addi_i32(tmp
, tmp
, val
);
9460 store_reg(s
, 13, tmp
);
9463 case 2: /* sign/zero extend. */
9466 rm
= (insn
>> 3) & 7;
9467 tmp
= load_reg(s
, rm
);
9468 switch ((insn
>> 6) & 3) {
9469 case 0: gen_sxth(tmp
); break;
9470 case 1: gen_sxtb(tmp
); break;
9471 case 2: gen_uxth(tmp
); break;
9472 case 3: gen_uxtb(tmp
); break;
9474 store_reg(s
, rd
, tmp
);
9476 case 4: case 5: case 0xc: case 0xd:
9478 addr
= load_reg(s
, 13);
9479 if (insn
& (1 << 8))
9483 for (i
= 0; i
< 8; i
++) {
9484 if (insn
& (1 << i
))
9487 if ((insn
& (1 << 11)) == 0) {
9488 tcg_gen_addi_i32(addr
, addr
, -offset
);
9490 for (i
= 0; i
< 8; i
++) {
9491 if (insn
& (1 << i
)) {
9492 if (insn
& (1 << 11)) {
9494 tmp
= gen_ld32(addr
, IS_USER(s
));
9495 store_reg(s
, i
, tmp
);
9498 tmp
= load_reg(s
, i
);
9499 gen_st32(tmp
, addr
, IS_USER(s
));
9501 /* advance to the next address. */
9502 tcg_gen_addi_i32(addr
, addr
, 4);
9506 if (insn
& (1 << 8)) {
9507 if (insn
& (1 << 11)) {
9509 tmp
= gen_ld32(addr
, IS_USER(s
));
9510 /* don't set the pc until the rest of the instruction
9514 tmp
= load_reg(s
, 14);
9515 gen_st32(tmp
, addr
, IS_USER(s
));
9517 tcg_gen_addi_i32(addr
, addr
, 4);
9519 if ((insn
& (1 << 11)) == 0) {
9520 tcg_gen_addi_i32(addr
, addr
, -offset
);
9522 /* write back the new stack pointer */
9523 store_reg(s
, 13, addr
);
9524 /* set the new PC value */
9525 if ((insn
& 0x0900) == 0x0900) {
9526 store_reg_from_load(env
, s
, 15, tmp
);
9530 case 1: case 3: case 9: case 11: /* czb */
9532 tmp
= load_reg(s
, rm
);
9533 s
->condlabel
= gen_new_label();
9535 if (insn
& (1 << 11))
9536 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9538 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9539 tcg_temp_free_i32(tmp
);
9540 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9541 val
= (uint32_t)s
->pc
+ 2;
9546 case 15: /* IT, nop-hint. */
9547 if ((insn
& 0xf) == 0) {
9548 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9552 s
->condexec_cond
= (insn
>> 4) & 0xe;
9553 s
->condexec_mask
= insn
& 0x1f;
9554 /* No actual code generated for this insn, just setup state. */
9557 case 0xe: /* bkpt */
9559 gen_exception_insn(s
, 2, EXCP_BKPT
);
9564 rn
= (insn
>> 3) & 0x7;
9566 tmp
= load_reg(s
, rn
);
9567 switch ((insn
>> 6) & 3) {
9568 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9569 case 1: gen_rev16(tmp
); break;
9570 case 3: gen_revsh(tmp
); break;
9571 default: goto illegal_op
;
9573 store_reg(s
, rd
, tmp
);
9581 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9584 addr
= tcg_const_i32(16);
9585 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9586 tcg_temp_free_i32(addr
);
9590 addr
= tcg_const_i32(17);
9591 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9592 tcg_temp_free_i32(addr
);
9594 tcg_temp_free_i32(tmp
);
9597 if (insn
& (1 << 4))
9598 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9601 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9612 /* load/store multiple */
9614 TCGV_UNUSED(loaded_var
);
9615 rn
= (insn
>> 8) & 0x7;
9616 addr
= load_reg(s
, rn
);
9617 for (i
= 0; i
< 8; i
++) {
9618 if (insn
& (1 << i
)) {
9619 if (insn
& (1 << 11)) {
9621 tmp
= gen_ld32(addr
, IS_USER(s
));
9625 store_reg(s
, i
, tmp
);
9629 tmp
= load_reg(s
, i
);
9630 gen_st32(tmp
, addr
, IS_USER(s
));
9632 /* advance to the next address */
9633 tcg_gen_addi_i32(addr
, addr
, 4);
9636 if ((insn
& (1 << rn
)) == 0) {
9637 /* base reg not in list: base register writeback */
9638 store_reg(s
, rn
, addr
);
9640 /* base reg in list: if load, complete it now */
9641 if (insn
& (1 << 11)) {
9642 store_reg(s
, rn
, loaded_var
);
9644 tcg_temp_free_i32(addr
);
9649 /* conditional branch or swi */
9650 cond
= (insn
>> 8) & 0xf;
9656 gen_set_pc_im(s
->pc
);
9657 s
->is_jmp
= DISAS_SWI
;
9660 /* generate a conditional jump to next instruction */
9661 s
->condlabel
= gen_new_label();
9662 gen_test_cc(cond
^ 1, s
->condlabel
);
9665 /* jump to the offset */
9666 val
= (uint32_t)s
->pc
+ 2;
9667 offset
= ((int32_t)insn
<< 24) >> 24;
9673 if (insn
& (1 << 11)) {
9674 if (disas_thumb2_insn(env
, s
, insn
))
9678 /* unconditional branch */
9679 val
= (uint32_t)s
->pc
;
9680 offset
= ((int32_t)insn
<< 21) >> 21;
9681 val
+= (offset
<< 1) + 2;
9686 if (disas_thumb2_insn(env
, s
, insn
))
9692 gen_exception_insn(s
, 4, EXCP_UDEF
);
9696 gen_exception_insn(s
, 2, EXCP_UDEF
);
9699 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9700 basic block 'tb'. If search_pc is TRUE, also generate PC
9701 information for each intermediate instruction. */
9702 static inline void gen_intermediate_code_internal(CPUState
*env
,
9703 TranslationBlock
*tb
,
9706 DisasContext dc1
, *dc
= &dc1
;
9708 uint16_t *gen_opc_end
;
9710 target_ulong pc_start
;
9711 uint32_t next_page_start
;
9715 /* generate intermediate code */
9720 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
9722 dc
->is_jmp
= DISAS_NEXT
;
9724 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9726 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9727 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9728 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9729 #if !defined(CONFIG_USER_ONLY)
9730 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9732 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9733 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9734 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9735 cpu_F0s
= tcg_temp_new_i32();
9736 cpu_F1s
= tcg_temp_new_i32();
9737 cpu_F0d
= tcg_temp_new_i64();
9738 cpu_F1d
= tcg_temp_new_i64();
9741 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9742 cpu_M0
= tcg_temp_new_i64();
9743 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9746 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9748 max_insns
= CF_COUNT_MASK
;
9752 tcg_clear_temp_count();
9754 /* A note on handling of the condexec (IT) bits:
9756 * We want to avoid the overhead of having to write the updated condexec
9757 * bits back to the CPUState for every instruction in an IT block. So:
9758 * (1) if the condexec bits are not already zero then we write
9759 * zero back into the CPUState now. This avoids complications trying
9760 * to do it at the end of the block. (For example if we don't do this
9761 * it's hard to identify whether we can safely skip writing condexec
9762 * at the end of the TB, which we definitely want to do for the case
9763 * where a TB doesn't do anything with the IT state at all.)
9764 * (2) if we are going to leave the TB then we call gen_set_condexec()
9765 * which will write the correct value into CPUState if zero is wrong.
9766 * This is done both for leaving the TB at the end, and for leaving
9767 * it because of an exception we know will happen, which is done in
9768 * gen_exception_insn(). The latter is necessary because we need to
9769 * leave the TB with the PC/IT state just prior to execution of the
9770 * instruction which caused the exception.
9771 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9772 * then the CPUState will be wrong and we need to reset it.
9773 * This is handled in the same way as restoration of the
9774 * PC in these situations: we will be called again with search_pc=1
9775 * and generate a mapping of the condexec bits for each PC in
9776 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9777 * this to restore the condexec bits.
9779 * Note that there are no instructions which can read the condexec
9780 * bits, and none which can write non-static values to them, so
9781 * we don't need to care about whether CPUState is correct in the
9785 /* Reset the conditional execution bits immediately. This avoids
9786 complications trying to do it at the end of the block. */
9787 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9789 TCGv tmp
= tcg_temp_new_i32();
9790 tcg_gen_movi_i32(tmp
, 0);
9791 store_cpu_field(tmp
, condexec_bits
);
9794 #ifdef CONFIG_USER_ONLY
9795 /* Intercept jump to the magic kernel page. */
9796 if (dc
->pc
>= 0xffff0000) {
9797 /* We always get here via a jump, so know we are not in a
9798 conditional execution block. */
9799 gen_exception(EXCP_KERNEL_TRAP
);
9800 dc
->is_jmp
= DISAS_UPDATE
;
9804 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9805 /* We always get here via a jump, so know we are not in a
9806 conditional execution block. */
9807 gen_exception(EXCP_EXCEPTION_EXIT
);
9808 dc
->is_jmp
= DISAS_UPDATE
;
9813 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9814 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9815 if (bp
->pc
== dc
->pc
) {
9816 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9817 /* Advance PC so that clearing the breakpoint will
9818 invalidate this TB. */
9820 goto done_generating
;
9826 j
= gen_opc_ptr
- gen_opc_buf
;
9830 gen_opc_instr_start
[lj
++] = 0;
9832 gen_opc_pc
[lj
] = dc
->pc
;
9833 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9834 gen_opc_instr_start
[lj
] = 1;
9835 gen_opc_icount
[lj
] = num_insns
;
9838 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9841 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
9842 tcg_gen_debug_insn_start(dc
->pc
);
9846 disas_thumb_insn(env
, dc
);
9847 if (dc
->condexec_mask
) {
9848 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9849 | ((dc
->condexec_mask
>> 4) & 1);
9850 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9851 if (dc
->condexec_mask
== 0) {
9852 dc
->condexec_cond
= 0;
9856 disas_arm_insn(env
, dc
);
9859 if (dc
->condjmp
&& !dc
->is_jmp
) {
9860 gen_set_label(dc
->condlabel
);
9864 if (tcg_check_temp_count()) {
9865 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9868 /* Translation stops when a conditional branch is encountered.
9869 * Otherwise the subsequent code could get translated several times.
9870 * Also stop translation when a page boundary is reached. This
9871 * ensures prefetch aborts occur at the right place. */
9873 } while (!dc
->is_jmp
&& gen_opc_ptr
< gen_opc_end
&&
9874 !env
->singlestep_enabled
&&
9876 dc
->pc
< next_page_start
&&
9877 num_insns
< max_insns
);
9879 if (tb
->cflags
& CF_LAST_IO
) {
9881 /* FIXME: This can theoretically happen with self-modifying
9883 cpu_abort(env
, "IO on conditional branch instruction");
9888 /* At this stage dc->condjmp will only be set when the skipped
9889 instruction was a conditional branch or trap, and the PC has
9890 already been written. */
9891 if (unlikely(env
->singlestep_enabled
)) {
9892 /* Make sure the pc is updated, and raise a debug exception. */
9894 gen_set_condexec(dc
);
9895 if (dc
->is_jmp
== DISAS_SWI
) {
9896 gen_exception(EXCP_SWI
);
9898 gen_exception(EXCP_DEBUG
);
9900 gen_set_label(dc
->condlabel
);
9902 if (dc
->condjmp
|| !dc
->is_jmp
) {
9903 gen_set_pc_im(dc
->pc
);
9906 gen_set_condexec(dc
);
9907 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9908 gen_exception(EXCP_SWI
);
9910 /* FIXME: Single stepping a WFI insn will not halt
9912 gen_exception(EXCP_DEBUG
);
9915 /* While branches must always occur at the end of an IT block,
9916 there are a few other things that can cause us to terminate
9917 the TB in the middel of an IT block:
9918 - Exception generating instructions (bkpt, swi, undefined).
9920 - Hardware watchpoints.
9921 Hardware breakpoints have already been handled and skip this code.
9923 gen_set_condexec(dc
);
9924 switch(dc
->is_jmp
) {
9926 gen_goto_tb(dc
, 1, dc
->pc
);
9931 /* indicate that the hash table must be used to find the next TB */
9935 /* nothing more to generate */
9941 gen_exception(EXCP_SWI
);
9945 gen_set_label(dc
->condlabel
);
9946 gen_set_condexec(dc
);
9947 gen_goto_tb(dc
, 1, dc
->pc
);
9953 gen_icount_end(tb
, num_insns
);
9954 *gen_opc_ptr
= INDEX_op_end
;
9957 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9958 qemu_log("----------------\n");
9959 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9960 log_target_disas(pc_start
, dc
->pc
- pc_start
, dc
->thumb
);
9965 j
= gen_opc_ptr
- gen_opc_buf
;
9968 gen_opc_instr_start
[lj
++] = 0;
9970 tb
->size
= dc
->pc
- pc_start
;
9971 tb
->icount
= num_insns
;
9975 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
9977 gen_intermediate_code_internal(env
, tb
, 0);
9980 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
9982 gen_intermediate_code_internal(env
, tb
, 1);
9985 static const char *cpu_mode_names
[16] = {
9986 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9987 "???", "???", "???", "und", "???", "???", "???", "sys"
9990 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10000 /* ??? This assumes float64 and double have the same layout.
10001 Oh well, it's only debug dumps. */
10009 for(i
=0;i
<16;i
++) {
10010 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10012 cpu_fprintf(f
, "\n");
10014 cpu_fprintf(f
, " ");
10016 psr
= cpsr_read(env
);
10017 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10019 psr
& (1 << 31) ? 'N' : '-',
10020 psr
& (1 << 30) ? 'Z' : '-',
10021 psr
& (1 << 29) ? 'C' : '-',
10022 psr
& (1 << 28) ? 'V' : '-',
10023 psr
& CPSR_T
? 'T' : 'A',
10024 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10027 for (i
= 0; i
< 16; i
++) {
10028 d
.d
= env
->vfp
.regs
[i
];
10032 cpu_fprintf(f
, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
10033 i
* 2, (int)s0
.i
, s0
.s
,
10034 i
* 2 + 1, (int)s1
.i
, s1
.s
,
10035 i
, (int)(uint32_t)d
.l
.upper
, (int)(uint32_t)d
.l
.lower
,
10038 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10042 void restore_state_to_opc(CPUState
*env
, TranslationBlock
*tb
, int pc_pos
)
10044 env
->regs
[15] = gen_opc_pc
[pc_pos
];
10045 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];