]> git.proxmox.com Git - mirror_qemu.git/blob - target/arm/translate.c
target/arm: Use gvec for NEON_3R_VTST_VCEQ, NEON_3R_VCGT, NEON_3R_VCGE
[mirror_qemu.git] / target / arm / translate.c
1 /*
2 * ARM translation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
7 *
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.
12 *
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.
17 *
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/>.
20 */
21 #include "qemu/osdep.h"
22
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "exec/semihost.h"
33
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
36
37 #include "trace-tcg.h"
38 #include "exec/log.h"
39
40
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53
54 #include "translate.h"
55
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
61
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
68
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
72
73 #include "exec/gen-icount.h"
74
75 static const char * const regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
78
79 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
81 TCGv_i32, TCGv_i32);
82
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
85 {
86 int i;
87
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
92 }
93 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
97
98 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102
103 a64_translate_init();
104 }
105
106 /* Flags for the disas_set_da_iss info argument:
107 * lower bits hold the Rt register number, higher bits are flags.
108 */
109 typedef enum ISSInfo {
110 ISSNone = 0,
111 ISSRegMask = 0x1f,
112 ISSInvalid = (1 << 5),
113 ISSIsAcqRel = (1 << 6),
114 ISSIsWrite = (1 << 7),
115 ISSIs16Bit = (1 << 8),
116 } ISSInfo;
117
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
120 {
121 uint32_t syn;
122 int sas = memop & MO_SIZE;
123 bool sse = memop & MO_SIGN;
124 bool is_acqrel = issinfo & ISSIsAcqRel;
125 bool is_write = issinfo & ISSIsWrite;
126 bool is_16bit = issinfo & ISSIs16Bit;
127 int srt = issinfo & ISSRegMask;
128
129 if (issinfo & ISSInvalid) {
130 /* Some callsites want to conditionally provide ISS info,
131 * eg "only if this was not a writeback"
132 */
133 return;
134 }
135
136 if (srt == 15) {
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
139 * the call sites.
140 */
141 return;
142 }
143
144 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
145 0, 0, 0, is_write, 0, is_16bit);
146 disas_set_insn_syndrome(s, syn);
147 }
148
149 static inline int get_a32_user_mem_index(DisasContext *s)
150 {
151 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * insns:
153 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
154 * otherwise, access as if at PL0.
155 */
156 switch (s->mmu_idx) {
157 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
158 case ARMMMUIdx_S12NSE0:
159 case ARMMMUIdx_S12NSE1:
160 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
161 case ARMMMUIdx_S1E3:
162 case ARMMMUIdx_S1SE0:
163 case ARMMMUIdx_S1SE1:
164 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 case ARMMMUIdx_S2NS:
178 default:
179 g_assert_not_reached();
180 }
181 }
182
183 static inline TCGv_i32 load_cpu_offset(int offset)
184 {
185 TCGv_i32 tmp = tcg_temp_new_i32();
186 tcg_gen_ld_i32(tmp, cpu_env, offset);
187 return tmp;
188 }
189
190 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
191
192 static inline void store_cpu_offset(TCGv_i32 var, int offset)
193 {
194 tcg_gen_st_i32(var, cpu_env, offset);
195 tcg_temp_free_i32(var);
196 }
197
198 #define store_cpu_field(var, name) \
199 store_cpu_offset(var, offsetof(CPUARMState, name))
200
201 /* Set a variable to the value of a CPU register. */
202 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
203 {
204 if (reg == 15) {
205 uint32_t addr;
206 /* normally, since we updated PC, we need only to add one insn */
207 if (s->thumb)
208 addr = (long)s->pc + 2;
209 else
210 addr = (long)s->pc + 4;
211 tcg_gen_movi_i32(var, addr);
212 } else {
213 tcg_gen_mov_i32(var, cpu_R[reg]);
214 }
215 }
216
217 /* Create a new temporary and set it to the value of a CPU register. */
218 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
219 {
220 TCGv_i32 tmp = tcg_temp_new_i32();
221 load_reg_var(s, tmp, reg);
222 return tmp;
223 }
224
225 /* Set a CPU register. The source must be a temporary and will be
226 marked as dead. */
227 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
228 {
229 if (reg == 15) {
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
234 */
235 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
236 s->base.is_jmp = DISAS_JUMP;
237 }
238 tcg_gen_mov_i32(cpu_R[reg], var);
239 tcg_temp_free_i32(var);
240 }
241
242 /*
243 * Variant of store_reg which applies v8M stack-limit checks before updating
244 * SP. If the check fails this will result in an exception being taken.
245 * We disable the stack checks for CONFIG_USER_ONLY because we have
246 * no idea what the stack limits should be in that case.
247 * If stack checking is not being done this just acts like store_reg().
248 */
249 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
250 {
251 #ifndef CONFIG_USER_ONLY
252 if (s->v8m_stackcheck) {
253 gen_helper_v8m_stackcheck(cpu_env, var);
254 }
255 #endif
256 store_reg(s, 13, var);
257 }
258
259 /* Value extensions. */
260 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
261 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
262 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
263 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
264
265 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
266 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
267
268
269 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
270 {
271 TCGv_i32 tmp_mask = tcg_const_i32(mask);
272 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
273 tcg_temp_free_i32(tmp_mask);
274 }
275 /* Set NZCV flags from the high 4 bits of var. */
276 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
277
278 static void gen_exception_internal(int excp)
279 {
280 TCGv_i32 tcg_excp = tcg_const_i32(excp);
281
282 assert(excp_is_internal(excp));
283 gen_helper_exception_internal(cpu_env, tcg_excp);
284 tcg_temp_free_i32(tcg_excp);
285 }
286
287 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
288 {
289 TCGv_i32 tcg_excp = tcg_const_i32(excp);
290 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
291 TCGv_i32 tcg_el = tcg_const_i32(target_el);
292
293 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
294 tcg_syn, tcg_el);
295
296 tcg_temp_free_i32(tcg_el);
297 tcg_temp_free_i32(tcg_syn);
298 tcg_temp_free_i32(tcg_excp);
299 }
300
301 static void gen_ss_advance(DisasContext *s)
302 {
303 /* If the singlestep state is Active-not-pending, advance to
304 * Active-pending.
305 */
306 if (s->ss_active) {
307 s->pstate_ss = 0;
308 gen_helper_clear_pstate_ss(cpu_env);
309 }
310 }
311
312 static void gen_step_complete_exception(DisasContext *s)
313 {
314 /* We just completed step of an insn. Move from Active-not-pending
315 * to Active-pending, and then also take the swstep exception.
316 * This corresponds to making the (IMPDEF) choice to prioritize
317 * swstep exceptions over asynchronous exceptions taken to an exception
318 * level where debug is disabled. This choice has the advantage that
319 * we do not need to maintain internal state corresponding to the
320 * ISV/EX syndrome bits between completion of the step and generation
321 * of the exception, and our syndrome information is always correct.
322 */
323 gen_ss_advance(s);
324 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
325 default_exception_el(s));
326 s->base.is_jmp = DISAS_NORETURN;
327 }
328
329 static void gen_singlestep_exception(DisasContext *s)
330 {
331 /* Generate the right kind of exception for singlestep, which is
332 * either the architectural singlestep or EXCP_DEBUG for QEMU's
333 * gdb singlestepping.
334 */
335 if (s->ss_active) {
336 gen_step_complete_exception(s);
337 } else {
338 gen_exception_internal(EXCP_DEBUG);
339 }
340 }
341
342 static inline bool is_singlestepping(DisasContext *s)
343 {
344 /* Return true if we are singlestepping either because of
345 * architectural singlestep or QEMU gdbstub singlestep. This does
346 * not include the command line '-singlestep' mode which is rather
347 * misnamed as it only means "one instruction per TB" and doesn't
348 * affect the code we generate.
349 */
350 return s->base.singlestep_enabled || s->ss_active;
351 }
352
353 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
354 {
355 TCGv_i32 tmp1 = tcg_temp_new_i32();
356 TCGv_i32 tmp2 = tcg_temp_new_i32();
357 tcg_gen_ext16s_i32(tmp1, a);
358 tcg_gen_ext16s_i32(tmp2, b);
359 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
360 tcg_temp_free_i32(tmp2);
361 tcg_gen_sari_i32(a, a, 16);
362 tcg_gen_sari_i32(b, b, 16);
363 tcg_gen_mul_i32(b, b, a);
364 tcg_gen_mov_i32(a, tmp1);
365 tcg_temp_free_i32(tmp1);
366 }
367
368 /* Byteswap each halfword. */
369 static void gen_rev16(TCGv_i32 var)
370 {
371 TCGv_i32 tmp = tcg_temp_new_i32();
372 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
373 tcg_gen_shri_i32(tmp, var, 8);
374 tcg_gen_and_i32(tmp, tmp, mask);
375 tcg_gen_and_i32(var, var, mask);
376 tcg_gen_shli_i32(var, var, 8);
377 tcg_gen_or_i32(var, var, tmp);
378 tcg_temp_free_i32(mask);
379 tcg_temp_free_i32(tmp);
380 }
381
382 /* Byteswap low halfword and sign extend. */
383 static void gen_revsh(TCGv_i32 var)
384 {
385 tcg_gen_ext16u_i32(var, var);
386 tcg_gen_bswap16_i32(var, var);
387 tcg_gen_ext16s_i32(var, var);
388 }
389
390 /* Return (b << 32) + a. Mark inputs as dead */
391 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
392 {
393 TCGv_i64 tmp64 = tcg_temp_new_i64();
394
395 tcg_gen_extu_i32_i64(tmp64, b);
396 tcg_temp_free_i32(b);
397 tcg_gen_shli_i64(tmp64, tmp64, 32);
398 tcg_gen_add_i64(a, tmp64, a);
399
400 tcg_temp_free_i64(tmp64);
401 return a;
402 }
403
404 /* Return (b << 32) - a. Mark inputs as dead. */
405 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
406 {
407 TCGv_i64 tmp64 = tcg_temp_new_i64();
408
409 tcg_gen_extu_i32_i64(tmp64, b);
410 tcg_temp_free_i32(b);
411 tcg_gen_shli_i64(tmp64, tmp64, 32);
412 tcg_gen_sub_i64(a, tmp64, a);
413
414 tcg_temp_free_i64(tmp64);
415 return a;
416 }
417
418 /* 32x32->64 multiply. Marks inputs as dead. */
419 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
420 {
421 TCGv_i32 lo = tcg_temp_new_i32();
422 TCGv_i32 hi = tcg_temp_new_i32();
423 TCGv_i64 ret;
424
425 tcg_gen_mulu2_i32(lo, hi, a, b);
426 tcg_temp_free_i32(a);
427 tcg_temp_free_i32(b);
428
429 ret = tcg_temp_new_i64();
430 tcg_gen_concat_i32_i64(ret, lo, hi);
431 tcg_temp_free_i32(lo);
432 tcg_temp_free_i32(hi);
433
434 return ret;
435 }
436
437 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
438 {
439 TCGv_i32 lo = tcg_temp_new_i32();
440 TCGv_i32 hi = tcg_temp_new_i32();
441 TCGv_i64 ret;
442
443 tcg_gen_muls2_i32(lo, hi, a, b);
444 tcg_temp_free_i32(a);
445 tcg_temp_free_i32(b);
446
447 ret = tcg_temp_new_i64();
448 tcg_gen_concat_i32_i64(ret, lo, hi);
449 tcg_temp_free_i32(lo);
450 tcg_temp_free_i32(hi);
451
452 return ret;
453 }
454
455 /* Swap low and high halfwords. */
456 static void gen_swap_half(TCGv_i32 var)
457 {
458 TCGv_i32 tmp = tcg_temp_new_i32();
459 tcg_gen_shri_i32(tmp, var, 16);
460 tcg_gen_shli_i32(var, var, 16);
461 tcg_gen_or_i32(var, var, tmp);
462 tcg_temp_free_i32(tmp);
463 }
464
465 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
466 tmp = (t0 ^ t1) & 0x8000;
467 t0 &= ~0x8000;
468 t1 &= ~0x8000;
469 t0 = (t0 + t1) ^ tmp;
470 */
471
472 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
473 {
474 TCGv_i32 tmp = tcg_temp_new_i32();
475 tcg_gen_xor_i32(tmp, t0, t1);
476 tcg_gen_andi_i32(tmp, tmp, 0x8000);
477 tcg_gen_andi_i32(t0, t0, ~0x8000);
478 tcg_gen_andi_i32(t1, t1, ~0x8000);
479 tcg_gen_add_i32(t0, t0, t1);
480 tcg_gen_xor_i32(t0, t0, tmp);
481 tcg_temp_free_i32(tmp);
482 tcg_temp_free_i32(t1);
483 }
484
485 /* Set CF to the top bit of var. */
486 static void gen_set_CF_bit31(TCGv_i32 var)
487 {
488 tcg_gen_shri_i32(cpu_CF, var, 31);
489 }
490
491 /* Set N and Z flags from var. */
492 static inline void gen_logic_CC(TCGv_i32 var)
493 {
494 tcg_gen_mov_i32(cpu_NF, var);
495 tcg_gen_mov_i32(cpu_ZF, var);
496 }
497
498 /* T0 += T1 + CF. */
499 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
500 {
501 tcg_gen_add_i32(t0, t0, t1);
502 tcg_gen_add_i32(t0, t0, cpu_CF);
503 }
504
505 /* dest = T0 + T1 + CF. */
506 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
507 {
508 tcg_gen_add_i32(dest, t0, t1);
509 tcg_gen_add_i32(dest, dest, cpu_CF);
510 }
511
512 /* dest = T0 - T1 + CF - 1. */
513 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
514 {
515 tcg_gen_sub_i32(dest, t0, t1);
516 tcg_gen_add_i32(dest, dest, cpu_CF);
517 tcg_gen_subi_i32(dest, dest, 1);
518 }
519
520 /* dest = T0 + T1. Compute C, N, V and Z flags */
521 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
522 {
523 TCGv_i32 tmp = tcg_temp_new_i32();
524 tcg_gen_movi_i32(tmp, 0);
525 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
526 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
527 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
530 tcg_temp_free_i32(tmp);
531 tcg_gen_mov_i32(dest, cpu_NF);
532 }
533
534 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
535 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
536 {
537 TCGv_i32 tmp = tcg_temp_new_i32();
538 if (TCG_TARGET_HAS_add2_i32) {
539 tcg_gen_movi_i32(tmp, 0);
540 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
541 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
542 } else {
543 TCGv_i64 q0 = tcg_temp_new_i64();
544 TCGv_i64 q1 = tcg_temp_new_i64();
545 tcg_gen_extu_i32_i64(q0, t0);
546 tcg_gen_extu_i32_i64(q1, t1);
547 tcg_gen_add_i64(q0, q0, q1);
548 tcg_gen_extu_i32_i64(q1, cpu_CF);
549 tcg_gen_add_i64(q0, q0, q1);
550 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
551 tcg_temp_free_i64(q0);
552 tcg_temp_free_i64(q1);
553 }
554 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
555 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
556 tcg_gen_xor_i32(tmp, t0, t1);
557 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
558 tcg_temp_free_i32(tmp);
559 tcg_gen_mov_i32(dest, cpu_NF);
560 }
561
562 /* dest = T0 - T1. Compute C, N, V and Z flags */
563 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
564 {
565 TCGv_i32 tmp;
566 tcg_gen_sub_i32(cpu_NF, t0, t1);
567 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
568 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
569 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
570 tmp = tcg_temp_new_i32();
571 tcg_gen_xor_i32(tmp, t0, t1);
572 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
573 tcg_temp_free_i32(tmp);
574 tcg_gen_mov_i32(dest, cpu_NF);
575 }
576
577 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
578 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
579 {
580 TCGv_i32 tmp = tcg_temp_new_i32();
581 tcg_gen_not_i32(tmp, t1);
582 gen_adc_CC(dest, t0, tmp);
583 tcg_temp_free_i32(tmp);
584 }
585
586 #define GEN_SHIFT(name) \
587 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
588 { \
589 TCGv_i32 tmp1, tmp2, tmp3; \
590 tmp1 = tcg_temp_new_i32(); \
591 tcg_gen_andi_i32(tmp1, t1, 0xff); \
592 tmp2 = tcg_const_i32(0); \
593 tmp3 = tcg_const_i32(0x1f); \
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
595 tcg_temp_free_i32(tmp3); \
596 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
597 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
598 tcg_temp_free_i32(tmp2); \
599 tcg_temp_free_i32(tmp1); \
600 }
601 GEN_SHIFT(shl)
602 GEN_SHIFT(shr)
603 #undef GEN_SHIFT
604
605 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
606 {
607 TCGv_i32 tmp1, tmp2;
608 tmp1 = tcg_temp_new_i32();
609 tcg_gen_andi_i32(tmp1, t1, 0xff);
610 tmp2 = tcg_const_i32(0x1f);
611 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
612 tcg_temp_free_i32(tmp2);
613 tcg_gen_sar_i32(dest, t0, tmp1);
614 tcg_temp_free_i32(tmp1);
615 }
616
617 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
618 {
619 TCGv_i32 c0 = tcg_const_i32(0);
620 TCGv_i32 tmp = tcg_temp_new_i32();
621 tcg_gen_neg_i32(tmp, src);
622 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
623 tcg_temp_free_i32(c0);
624 tcg_temp_free_i32(tmp);
625 }
626
627 static void shifter_out_im(TCGv_i32 var, int shift)
628 {
629 if (shift == 0) {
630 tcg_gen_andi_i32(cpu_CF, var, 1);
631 } else {
632 tcg_gen_shri_i32(cpu_CF, var, shift);
633 if (shift != 31) {
634 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
635 }
636 }
637 }
638
639 /* Shift by immediate. Includes special handling for shift == 0. */
640 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
641 int shift, int flags)
642 {
643 switch (shiftop) {
644 case 0: /* LSL */
645 if (shift != 0) {
646 if (flags)
647 shifter_out_im(var, 32 - shift);
648 tcg_gen_shli_i32(var, var, shift);
649 }
650 break;
651 case 1: /* LSR */
652 if (shift == 0) {
653 if (flags) {
654 tcg_gen_shri_i32(cpu_CF, var, 31);
655 }
656 tcg_gen_movi_i32(var, 0);
657 } else {
658 if (flags)
659 shifter_out_im(var, shift - 1);
660 tcg_gen_shri_i32(var, var, shift);
661 }
662 break;
663 case 2: /* ASR */
664 if (shift == 0)
665 shift = 32;
666 if (flags)
667 shifter_out_im(var, shift - 1);
668 if (shift == 32)
669 shift = 31;
670 tcg_gen_sari_i32(var, var, shift);
671 break;
672 case 3: /* ROR/RRX */
673 if (shift != 0) {
674 if (flags)
675 shifter_out_im(var, shift - 1);
676 tcg_gen_rotri_i32(var, var, shift); break;
677 } else {
678 TCGv_i32 tmp = tcg_temp_new_i32();
679 tcg_gen_shli_i32(tmp, cpu_CF, 31);
680 if (flags)
681 shifter_out_im(var, 0);
682 tcg_gen_shri_i32(var, var, 1);
683 tcg_gen_or_i32(var, var, tmp);
684 tcg_temp_free_i32(tmp);
685 }
686 }
687 };
688
689 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
690 TCGv_i32 shift, int flags)
691 {
692 if (flags) {
693 switch (shiftop) {
694 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
695 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
696 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
697 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
698 }
699 } else {
700 switch (shiftop) {
701 case 0:
702 gen_shl(var, var, shift);
703 break;
704 case 1:
705 gen_shr(var, var, shift);
706 break;
707 case 2:
708 gen_sar(var, var, shift);
709 break;
710 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
711 tcg_gen_rotr_i32(var, var, shift); break;
712 }
713 }
714 tcg_temp_free_i32(shift);
715 }
716
717 #define PAS_OP(pfx) \
718 switch (op2) { \
719 case 0: gen_pas_helper(glue(pfx,add16)); break; \
720 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
721 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
722 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
723 case 4: gen_pas_helper(glue(pfx,add8)); break; \
724 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
725 }
726 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
727 {
728 TCGv_ptr tmp;
729
730 switch (op1) {
731 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
732 case 1:
733 tmp = tcg_temp_new_ptr();
734 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
735 PAS_OP(s)
736 tcg_temp_free_ptr(tmp);
737 break;
738 case 5:
739 tmp = tcg_temp_new_ptr();
740 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
741 PAS_OP(u)
742 tcg_temp_free_ptr(tmp);
743 break;
744 #undef gen_pas_helper
745 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
746 case 2:
747 PAS_OP(q);
748 break;
749 case 3:
750 PAS_OP(sh);
751 break;
752 case 6:
753 PAS_OP(uq);
754 break;
755 case 7:
756 PAS_OP(uh);
757 break;
758 #undef gen_pas_helper
759 }
760 }
761 #undef PAS_OP
762
763 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
764 #define PAS_OP(pfx) \
765 switch (op1) { \
766 case 0: gen_pas_helper(glue(pfx,add8)); break; \
767 case 1: gen_pas_helper(glue(pfx,add16)); break; \
768 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
769 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
770 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
771 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
772 }
773 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
774 {
775 TCGv_ptr tmp;
776
777 switch (op2) {
778 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
779 case 0:
780 tmp = tcg_temp_new_ptr();
781 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
782 PAS_OP(s)
783 tcg_temp_free_ptr(tmp);
784 break;
785 case 4:
786 tmp = tcg_temp_new_ptr();
787 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
788 PAS_OP(u)
789 tcg_temp_free_ptr(tmp);
790 break;
791 #undef gen_pas_helper
792 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
793 case 1:
794 PAS_OP(q);
795 break;
796 case 2:
797 PAS_OP(sh);
798 break;
799 case 5:
800 PAS_OP(uq);
801 break;
802 case 6:
803 PAS_OP(uh);
804 break;
805 #undef gen_pas_helper
806 }
807 }
808 #undef PAS_OP
809
810 /*
811 * Generate a conditional based on ARM condition code cc.
812 * This is common between ARM and Aarch64 targets.
813 */
814 void arm_test_cc(DisasCompare *cmp, int cc)
815 {
816 TCGv_i32 value;
817 TCGCond cond;
818 bool global = true;
819
820 switch (cc) {
821 case 0: /* eq: Z */
822 case 1: /* ne: !Z */
823 cond = TCG_COND_EQ;
824 value = cpu_ZF;
825 break;
826
827 case 2: /* cs: C */
828 case 3: /* cc: !C */
829 cond = TCG_COND_NE;
830 value = cpu_CF;
831 break;
832
833 case 4: /* mi: N */
834 case 5: /* pl: !N */
835 cond = TCG_COND_LT;
836 value = cpu_NF;
837 break;
838
839 case 6: /* vs: V */
840 case 7: /* vc: !V */
841 cond = TCG_COND_LT;
842 value = cpu_VF;
843 break;
844
845 case 8: /* hi: C && !Z */
846 case 9: /* ls: !C || Z -> !(C && !Z) */
847 cond = TCG_COND_NE;
848 value = tcg_temp_new_i32();
849 global = false;
850 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
851 ZF is non-zero for !Z; so AND the two subexpressions. */
852 tcg_gen_neg_i32(value, cpu_CF);
853 tcg_gen_and_i32(value, value, cpu_ZF);
854 break;
855
856 case 10: /* ge: N == V -> N ^ V == 0 */
857 case 11: /* lt: N != V -> N ^ V != 0 */
858 /* Since we're only interested in the sign bit, == 0 is >= 0. */
859 cond = TCG_COND_GE;
860 value = tcg_temp_new_i32();
861 global = false;
862 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
863 break;
864
865 case 12: /* gt: !Z && N == V */
866 case 13: /* le: Z || N != V */
867 cond = TCG_COND_NE;
868 value = tcg_temp_new_i32();
869 global = false;
870 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
871 * the sign bit then AND with ZF to yield the result. */
872 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
873 tcg_gen_sari_i32(value, value, 31);
874 tcg_gen_andc_i32(value, cpu_ZF, value);
875 break;
876
877 case 14: /* always */
878 case 15: /* always */
879 /* Use the ALWAYS condition, which will fold early.
880 * It doesn't matter what we use for the value. */
881 cond = TCG_COND_ALWAYS;
882 value = cpu_ZF;
883 goto no_invert;
884
885 default:
886 fprintf(stderr, "Bad condition code 0x%x\n", cc);
887 abort();
888 }
889
890 if (cc & 1) {
891 cond = tcg_invert_cond(cond);
892 }
893
894 no_invert:
895 cmp->cond = cond;
896 cmp->value = value;
897 cmp->value_global = global;
898 }
899
900 void arm_free_cc(DisasCompare *cmp)
901 {
902 if (!cmp->value_global) {
903 tcg_temp_free_i32(cmp->value);
904 }
905 }
906
907 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
908 {
909 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
910 }
911
912 void arm_gen_test_cc(int cc, TCGLabel *label)
913 {
914 DisasCompare cmp;
915 arm_test_cc(&cmp, cc);
916 arm_jump_cc(&cmp, label);
917 arm_free_cc(&cmp);
918 }
919
920 static const uint8_t table_logic_cc[16] = {
921 1, /* and */
922 1, /* xor */
923 0, /* sub */
924 0, /* rsb */
925 0, /* add */
926 0, /* adc */
927 0, /* sbc */
928 0, /* rsc */
929 1, /* andl */
930 1, /* xorl */
931 0, /* cmp */
932 0, /* cmn */
933 1, /* orr */
934 1, /* mov */
935 1, /* bic */
936 1, /* mvn */
937 };
938
939 static inline void gen_set_condexec(DisasContext *s)
940 {
941 if (s->condexec_mask) {
942 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
943 TCGv_i32 tmp = tcg_temp_new_i32();
944 tcg_gen_movi_i32(tmp, val);
945 store_cpu_field(tmp, condexec_bits);
946 }
947 }
948
949 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
950 {
951 tcg_gen_movi_i32(cpu_R[15], val);
952 }
953
954 /* Set PC and Thumb state from an immediate address. */
955 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
956 {
957 TCGv_i32 tmp;
958
959 s->base.is_jmp = DISAS_JUMP;
960 if (s->thumb != (addr & 1)) {
961 tmp = tcg_temp_new_i32();
962 tcg_gen_movi_i32(tmp, addr & 1);
963 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
964 tcg_temp_free_i32(tmp);
965 }
966 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
967 }
968
969 /* Set PC and Thumb state from var. var is marked as dead. */
970 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
971 {
972 s->base.is_jmp = DISAS_JUMP;
973 tcg_gen_andi_i32(cpu_R[15], var, ~1);
974 tcg_gen_andi_i32(var, var, 1);
975 store_cpu_field(var, thumb);
976 }
977
978 /* Set PC and Thumb state from var. var is marked as dead.
979 * For M-profile CPUs, include logic to detect exception-return
980 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
981 * and BX reg, and no others, and happens only for code in Handler mode.
982 */
983 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
984 {
985 /* Generate the same code here as for a simple bx, but flag via
986 * s->base.is_jmp that we need to do the rest of the work later.
987 */
988 gen_bx(s, var);
989 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
990 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
991 s->base.is_jmp = DISAS_BX_EXCRET;
992 }
993 }
994
995 static inline void gen_bx_excret_final_code(DisasContext *s)
996 {
997 /* Generate the code to finish possible exception return and end the TB */
998 TCGLabel *excret_label = gen_new_label();
999 uint32_t min_magic;
1000
1001 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
1002 /* Covers FNC_RETURN and EXC_RETURN magic */
1003 min_magic = FNC_RETURN_MIN_MAGIC;
1004 } else {
1005 /* EXC_RETURN magic only */
1006 min_magic = EXC_RETURN_MIN_MAGIC;
1007 }
1008
1009 /* Is the new PC value in the magic range indicating exception return? */
1010 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
1011 /* No: end the TB as we would for a DISAS_JMP */
1012 if (is_singlestepping(s)) {
1013 gen_singlestep_exception(s);
1014 } else {
1015 tcg_gen_exit_tb(NULL, 0);
1016 }
1017 gen_set_label(excret_label);
1018 /* Yes: this is an exception return.
1019 * At this point in runtime env->regs[15] and env->thumb will hold
1020 * the exception-return magic number, which do_v7m_exception_exit()
1021 * will read. Nothing else will be able to see those values because
1022 * the cpu-exec main loop guarantees that we will always go straight
1023 * from raising the exception to the exception-handling code.
1024 *
1025 * gen_ss_advance(s) does nothing on M profile currently but
1026 * calling it is conceptually the right thing as we have executed
1027 * this instruction (compare SWI, HVC, SMC handling).
1028 */
1029 gen_ss_advance(s);
1030 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1031 }
1032
1033 static inline void gen_bxns(DisasContext *s, int rm)
1034 {
1035 TCGv_i32 var = load_reg(s, rm);
1036
1037 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1038 * we need to sync state before calling it, but:
1039 * - we don't need to do gen_set_pc_im() because the bxns helper will
1040 * always set the PC itself
1041 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1042 * unless it's outside an IT block or the last insn in an IT block,
1043 * so we know that condexec == 0 (already set at the top of the TB)
1044 * is correct in the non-UNPREDICTABLE cases, and we can choose
1045 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1046 */
1047 gen_helper_v7m_bxns(cpu_env, var);
1048 tcg_temp_free_i32(var);
1049 s->base.is_jmp = DISAS_EXIT;
1050 }
1051
1052 static inline void gen_blxns(DisasContext *s, int rm)
1053 {
1054 TCGv_i32 var = load_reg(s, rm);
1055
1056 /* We don't need to sync condexec state, for the same reason as bxns.
1057 * We do however need to set the PC, because the blxns helper reads it.
1058 * The blxns helper may throw an exception.
1059 */
1060 gen_set_pc_im(s, s->pc);
1061 gen_helper_v7m_blxns(cpu_env, var);
1062 tcg_temp_free_i32(var);
1063 s->base.is_jmp = DISAS_EXIT;
1064 }
1065
1066 /* Variant of store_reg which uses branch&exchange logic when storing
1067 to r15 in ARM architecture v7 and above. The source must be a temporary
1068 and will be marked as dead. */
1069 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1070 {
1071 if (reg == 15 && ENABLE_ARCH_7) {
1072 gen_bx(s, var);
1073 } else {
1074 store_reg(s, reg, var);
1075 }
1076 }
1077
1078 /* Variant of store_reg which uses branch&exchange logic when storing
1079 * to r15 in ARM architecture v5T and above. This is used for storing
1080 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1081 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1082 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1083 {
1084 if (reg == 15 && ENABLE_ARCH_5) {
1085 gen_bx_excret(s, var);
1086 } else {
1087 store_reg(s, reg, var);
1088 }
1089 }
1090
1091 #ifdef CONFIG_USER_ONLY
1092 #define IS_USER_ONLY 1
1093 #else
1094 #define IS_USER_ONLY 0
1095 #endif
1096
1097 /* Abstractions of "generate code to do a guest load/store for
1098 * AArch32", where a vaddr is always 32 bits (and is zero
1099 * extended if we're a 64 bit core) and data is also
1100 * 32 bits unless specifically doing a 64 bit access.
1101 * These functions work like tcg_gen_qemu_{ld,st}* except
1102 * that the address argument is TCGv_i32 rather than TCGv.
1103 */
1104
1105 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1106 {
1107 TCGv addr = tcg_temp_new();
1108 tcg_gen_extu_i32_tl(addr, a32);
1109
1110 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1111 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1112 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1113 }
1114 return addr;
1115 }
1116
1117 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1118 int index, TCGMemOp opc)
1119 {
1120 TCGv addr;
1121
1122 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1123 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1124 opc |= MO_ALIGN;
1125 }
1126
1127 addr = gen_aa32_addr(s, a32, opc);
1128 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1129 tcg_temp_free(addr);
1130 }
1131
1132 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1133 int index, TCGMemOp opc)
1134 {
1135 TCGv addr;
1136
1137 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1138 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1139 opc |= MO_ALIGN;
1140 }
1141
1142 addr = gen_aa32_addr(s, a32, opc);
1143 tcg_gen_qemu_st_i32(val, addr, index, opc);
1144 tcg_temp_free(addr);
1145 }
1146
1147 #define DO_GEN_LD(SUFF, OPC) \
1148 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1149 TCGv_i32 a32, int index) \
1150 { \
1151 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1152 } \
1153 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1154 TCGv_i32 val, \
1155 TCGv_i32 a32, int index, \
1156 ISSInfo issinfo) \
1157 { \
1158 gen_aa32_ld##SUFF(s, val, a32, index); \
1159 disas_set_da_iss(s, OPC, issinfo); \
1160 }
1161
1162 #define DO_GEN_ST(SUFF, OPC) \
1163 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1164 TCGv_i32 a32, int index) \
1165 { \
1166 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1167 } \
1168 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1169 TCGv_i32 val, \
1170 TCGv_i32 a32, int index, \
1171 ISSInfo issinfo) \
1172 { \
1173 gen_aa32_st##SUFF(s, val, a32, index); \
1174 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1175 }
1176
1177 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1178 {
1179 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1180 if (!IS_USER_ONLY && s->sctlr_b) {
1181 tcg_gen_rotri_i64(val, val, 32);
1182 }
1183 }
1184
1185 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1186 int index, TCGMemOp opc)
1187 {
1188 TCGv addr = gen_aa32_addr(s, a32, opc);
1189 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1190 gen_aa32_frob64(s, val);
1191 tcg_temp_free(addr);
1192 }
1193
1194 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1195 TCGv_i32 a32, int index)
1196 {
1197 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1198 }
1199
1200 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1201 int index, TCGMemOp opc)
1202 {
1203 TCGv addr = gen_aa32_addr(s, a32, opc);
1204
1205 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1206 if (!IS_USER_ONLY && s->sctlr_b) {
1207 TCGv_i64 tmp = tcg_temp_new_i64();
1208 tcg_gen_rotri_i64(tmp, val, 32);
1209 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1210 tcg_temp_free_i64(tmp);
1211 } else {
1212 tcg_gen_qemu_st_i64(val, addr, index, opc);
1213 }
1214 tcg_temp_free(addr);
1215 }
1216
1217 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1218 TCGv_i32 a32, int index)
1219 {
1220 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1221 }
1222
1223 DO_GEN_LD(8s, MO_SB)
1224 DO_GEN_LD(8u, MO_UB)
1225 DO_GEN_LD(16s, MO_SW)
1226 DO_GEN_LD(16u, MO_UW)
1227 DO_GEN_LD(32u, MO_UL)
1228 DO_GEN_ST(8, MO_UB)
1229 DO_GEN_ST(16, MO_UW)
1230 DO_GEN_ST(32, MO_UL)
1231
1232 static inline void gen_hvc(DisasContext *s, int imm16)
1233 {
1234 /* The pre HVC helper handles cases when HVC gets trapped
1235 * as an undefined insn by runtime configuration (ie before
1236 * the insn really executes).
1237 */
1238 gen_set_pc_im(s, s->pc - 4);
1239 gen_helper_pre_hvc(cpu_env);
1240 /* Otherwise we will treat this as a real exception which
1241 * happens after execution of the insn. (The distinction matters
1242 * for the PC value reported to the exception handler and also
1243 * for single stepping.)
1244 */
1245 s->svc_imm = imm16;
1246 gen_set_pc_im(s, s->pc);
1247 s->base.is_jmp = DISAS_HVC;
1248 }
1249
1250 static inline void gen_smc(DisasContext *s)
1251 {
1252 /* As with HVC, we may take an exception either before or after
1253 * the insn executes.
1254 */
1255 TCGv_i32 tmp;
1256
1257 gen_set_pc_im(s, s->pc - 4);
1258 tmp = tcg_const_i32(syn_aa32_smc());
1259 gen_helper_pre_smc(cpu_env, tmp);
1260 tcg_temp_free_i32(tmp);
1261 gen_set_pc_im(s, s->pc);
1262 s->base.is_jmp = DISAS_SMC;
1263 }
1264
1265 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1266 {
1267 gen_set_condexec(s);
1268 gen_set_pc_im(s, s->pc - offset);
1269 gen_exception_internal(excp);
1270 s->base.is_jmp = DISAS_NORETURN;
1271 }
1272
1273 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1274 int syn, uint32_t target_el)
1275 {
1276 gen_set_condexec(s);
1277 gen_set_pc_im(s, s->pc - offset);
1278 gen_exception(excp, syn, target_el);
1279 s->base.is_jmp = DISAS_NORETURN;
1280 }
1281
1282 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1283 {
1284 TCGv_i32 tcg_syn;
1285
1286 gen_set_condexec(s);
1287 gen_set_pc_im(s, s->pc - offset);
1288 tcg_syn = tcg_const_i32(syn);
1289 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1290 tcg_temp_free_i32(tcg_syn);
1291 s->base.is_jmp = DISAS_NORETURN;
1292 }
1293
1294 /* Force a TB lookup after an instruction that changes the CPU state. */
1295 static inline void gen_lookup_tb(DisasContext *s)
1296 {
1297 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1298 s->base.is_jmp = DISAS_EXIT;
1299 }
1300
1301 static inline void gen_hlt(DisasContext *s, int imm)
1302 {
1303 /* HLT. This has two purposes.
1304 * Architecturally, it is an external halting debug instruction.
1305 * Since QEMU doesn't implement external debug, we treat this as
1306 * it is required for halting debug disabled: it will UNDEF.
1307 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1308 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1309 * must trigger semihosting even for ARMv7 and earlier, where
1310 * HLT was an undefined encoding.
1311 * In system mode, we don't allow userspace access to
1312 * semihosting, to provide some semblance of security
1313 * (and for consistency with our 32-bit semihosting).
1314 */
1315 if (semihosting_enabled() &&
1316 #ifndef CONFIG_USER_ONLY
1317 s->current_el != 0 &&
1318 #endif
1319 (imm == (s->thumb ? 0x3c : 0xf000))) {
1320 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1321 return;
1322 }
1323
1324 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1325 default_exception_el(s));
1326 }
1327
1328 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1329 TCGv_i32 var)
1330 {
1331 int val, rm, shift, shiftop;
1332 TCGv_i32 offset;
1333
1334 if (!(insn & (1 << 25))) {
1335 /* immediate */
1336 val = insn & 0xfff;
1337 if (!(insn & (1 << 23)))
1338 val = -val;
1339 if (val != 0)
1340 tcg_gen_addi_i32(var, var, val);
1341 } else {
1342 /* shift/register */
1343 rm = (insn) & 0xf;
1344 shift = (insn >> 7) & 0x1f;
1345 shiftop = (insn >> 5) & 3;
1346 offset = load_reg(s, rm);
1347 gen_arm_shift_im(offset, shiftop, shift, 0);
1348 if (!(insn & (1 << 23)))
1349 tcg_gen_sub_i32(var, var, offset);
1350 else
1351 tcg_gen_add_i32(var, var, offset);
1352 tcg_temp_free_i32(offset);
1353 }
1354 }
1355
1356 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1357 int extra, TCGv_i32 var)
1358 {
1359 int val, rm;
1360 TCGv_i32 offset;
1361
1362 if (insn & (1 << 22)) {
1363 /* immediate */
1364 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1365 if (!(insn & (1 << 23)))
1366 val = -val;
1367 val += extra;
1368 if (val != 0)
1369 tcg_gen_addi_i32(var, var, val);
1370 } else {
1371 /* register */
1372 if (extra)
1373 tcg_gen_addi_i32(var, var, extra);
1374 rm = (insn) & 0xf;
1375 offset = load_reg(s, rm);
1376 if (!(insn & (1 << 23)))
1377 tcg_gen_sub_i32(var, var, offset);
1378 else
1379 tcg_gen_add_i32(var, var, offset);
1380 tcg_temp_free_i32(offset);
1381 }
1382 }
1383
1384 static TCGv_ptr get_fpstatus_ptr(int neon)
1385 {
1386 TCGv_ptr statusptr = tcg_temp_new_ptr();
1387 int offset;
1388 if (neon) {
1389 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1390 } else {
1391 offset = offsetof(CPUARMState, vfp.fp_status);
1392 }
1393 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1394 return statusptr;
1395 }
1396
1397 #define VFP_OP2(name) \
1398 static inline void gen_vfp_##name(int dp) \
1399 { \
1400 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1401 if (dp) { \
1402 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1403 } else { \
1404 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1405 } \
1406 tcg_temp_free_ptr(fpst); \
1407 }
1408
1409 VFP_OP2(add)
1410 VFP_OP2(sub)
1411 VFP_OP2(mul)
1412 VFP_OP2(div)
1413
1414 #undef VFP_OP2
1415
1416 static inline void gen_vfp_F1_mul(int dp)
1417 {
1418 /* Like gen_vfp_mul() but put result in F1 */
1419 TCGv_ptr fpst = get_fpstatus_ptr(0);
1420 if (dp) {
1421 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1422 } else {
1423 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1424 }
1425 tcg_temp_free_ptr(fpst);
1426 }
1427
1428 static inline void gen_vfp_F1_neg(int dp)
1429 {
1430 /* Like gen_vfp_neg() but put result in F1 */
1431 if (dp) {
1432 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1433 } else {
1434 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1435 }
1436 }
1437
1438 static inline void gen_vfp_abs(int dp)
1439 {
1440 if (dp)
1441 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1442 else
1443 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1444 }
1445
1446 static inline void gen_vfp_neg(int dp)
1447 {
1448 if (dp)
1449 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1450 else
1451 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1452 }
1453
1454 static inline void gen_vfp_sqrt(int dp)
1455 {
1456 if (dp)
1457 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1458 else
1459 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1460 }
1461
1462 static inline void gen_vfp_cmp(int dp)
1463 {
1464 if (dp)
1465 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1466 else
1467 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1468 }
1469
1470 static inline void gen_vfp_cmpe(int dp)
1471 {
1472 if (dp)
1473 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1474 else
1475 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1476 }
1477
1478 static inline void gen_vfp_F1_ld0(int dp)
1479 {
1480 if (dp)
1481 tcg_gen_movi_i64(cpu_F1d, 0);
1482 else
1483 tcg_gen_movi_i32(cpu_F1s, 0);
1484 }
1485
1486 #define VFP_GEN_ITOF(name) \
1487 static inline void gen_vfp_##name(int dp, int neon) \
1488 { \
1489 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1490 if (dp) { \
1491 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1492 } else { \
1493 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1494 } \
1495 tcg_temp_free_ptr(statusptr); \
1496 }
1497
1498 VFP_GEN_ITOF(uito)
1499 VFP_GEN_ITOF(sito)
1500 #undef VFP_GEN_ITOF
1501
1502 #define VFP_GEN_FTOI(name) \
1503 static inline void gen_vfp_##name(int dp, int neon) \
1504 { \
1505 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1506 if (dp) { \
1507 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1508 } else { \
1509 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1510 } \
1511 tcg_temp_free_ptr(statusptr); \
1512 }
1513
1514 VFP_GEN_FTOI(toui)
1515 VFP_GEN_FTOI(touiz)
1516 VFP_GEN_FTOI(tosi)
1517 VFP_GEN_FTOI(tosiz)
1518 #undef VFP_GEN_FTOI
1519
1520 #define VFP_GEN_FIX(name, round) \
1521 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1522 { \
1523 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1524 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1525 if (dp) { \
1526 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1527 statusptr); \
1528 } else { \
1529 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1530 statusptr); \
1531 } \
1532 tcg_temp_free_i32(tmp_shift); \
1533 tcg_temp_free_ptr(statusptr); \
1534 }
1535 VFP_GEN_FIX(tosh, _round_to_zero)
1536 VFP_GEN_FIX(tosl, _round_to_zero)
1537 VFP_GEN_FIX(touh, _round_to_zero)
1538 VFP_GEN_FIX(toul, _round_to_zero)
1539 VFP_GEN_FIX(shto, )
1540 VFP_GEN_FIX(slto, )
1541 VFP_GEN_FIX(uhto, )
1542 VFP_GEN_FIX(ulto, )
1543 #undef VFP_GEN_FIX
1544
1545 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1546 {
1547 if (dp) {
1548 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1549 } else {
1550 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1551 }
1552 }
1553
1554 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1555 {
1556 if (dp) {
1557 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1558 } else {
1559 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1560 }
1561 }
1562
1563 static inline long vfp_reg_offset(bool dp, unsigned reg)
1564 {
1565 if (dp) {
1566 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1567 } else {
1568 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1569 if (reg & 1) {
1570 ofs += offsetof(CPU_DoubleU, l.upper);
1571 } else {
1572 ofs += offsetof(CPU_DoubleU, l.lower);
1573 }
1574 return ofs;
1575 }
1576 }
1577
1578 /* Return the offset of a 32-bit piece of a NEON register.
1579 zero is the least significant end of the register. */
1580 static inline long
1581 neon_reg_offset (int reg, int n)
1582 {
1583 int sreg;
1584 sreg = reg * 2 + n;
1585 return vfp_reg_offset(0, sreg);
1586 }
1587
1588 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1589 * where 0 is the least significant end of the register.
1590 */
1591 static inline long
1592 neon_element_offset(int reg, int element, TCGMemOp size)
1593 {
1594 int element_size = 1 << size;
1595 int ofs = element * element_size;
1596 #ifdef HOST_WORDS_BIGENDIAN
1597 /* Calculate the offset assuming fully little-endian,
1598 * then XOR to account for the order of the 8-byte units.
1599 */
1600 if (element_size < 8) {
1601 ofs ^= 8 - element_size;
1602 }
1603 #endif
1604 return neon_reg_offset(reg, 0) + ofs;
1605 }
1606
1607 static TCGv_i32 neon_load_reg(int reg, int pass)
1608 {
1609 TCGv_i32 tmp = tcg_temp_new_i32();
1610 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1611 return tmp;
1612 }
1613
1614 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1615 {
1616 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1617 tcg_temp_free_i32(var);
1618 }
1619
1620 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1621 {
1622 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1623 }
1624
1625 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1626 {
1627 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1628 }
1629
1630 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1631 {
1632 TCGv_ptr ret = tcg_temp_new_ptr();
1633 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1634 return ret;
1635 }
1636
1637 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1638 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1639 #define tcg_gen_st_f32 tcg_gen_st_i32
1640 #define tcg_gen_st_f64 tcg_gen_st_i64
1641
1642 static inline void gen_mov_F0_vreg(int dp, int reg)
1643 {
1644 if (dp)
1645 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1646 else
1647 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1648 }
1649
1650 static inline void gen_mov_F1_vreg(int dp, int reg)
1651 {
1652 if (dp)
1653 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1654 else
1655 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1656 }
1657
1658 static inline void gen_mov_vreg_F0(int dp, int reg)
1659 {
1660 if (dp)
1661 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1662 else
1663 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1664 }
1665
1666 #define ARM_CP_RW_BIT (1 << 20)
1667
1668 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1669 {
1670 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1671 }
1672
1673 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1674 {
1675 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1676 }
1677
1678 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1679 {
1680 TCGv_i32 var = tcg_temp_new_i32();
1681 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1682 return var;
1683 }
1684
1685 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1686 {
1687 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1688 tcg_temp_free_i32(var);
1689 }
1690
1691 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1692 {
1693 iwmmxt_store_reg(cpu_M0, rn);
1694 }
1695
1696 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1697 {
1698 iwmmxt_load_reg(cpu_M0, rn);
1699 }
1700
1701 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1702 {
1703 iwmmxt_load_reg(cpu_V1, rn);
1704 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1705 }
1706
1707 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1708 {
1709 iwmmxt_load_reg(cpu_V1, rn);
1710 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1711 }
1712
1713 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1714 {
1715 iwmmxt_load_reg(cpu_V1, rn);
1716 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1717 }
1718
1719 #define IWMMXT_OP(name) \
1720 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1721 { \
1722 iwmmxt_load_reg(cpu_V1, rn); \
1723 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1724 }
1725
1726 #define IWMMXT_OP_ENV(name) \
1727 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1728 { \
1729 iwmmxt_load_reg(cpu_V1, rn); \
1730 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1731 }
1732
1733 #define IWMMXT_OP_ENV_SIZE(name) \
1734 IWMMXT_OP_ENV(name##b) \
1735 IWMMXT_OP_ENV(name##w) \
1736 IWMMXT_OP_ENV(name##l)
1737
1738 #define IWMMXT_OP_ENV1(name) \
1739 static inline void gen_op_iwmmxt_##name##_M0(void) \
1740 { \
1741 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1742 }
1743
1744 IWMMXT_OP(maddsq)
1745 IWMMXT_OP(madduq)
1746 IWMMXT_OP(sadb)
1747 IWMMXT_OP(sadw)
1748 IWMMXT_OP(mulslw)
1749 IWMMXT_OP(mulshw)
1750 IWMMXT_OP(mululw)
1751 IWMMXT_OP(muluhw)
1752 IWMMXT_OP(macsw)
1753 IWMMXT_OP(macuw)
1754
1755 IWMMXT_OP_ENV_SIZE(unpackl)
1756 IWMMXT_OP_ENV_SIZE(unpackh)
1757
1758 IWMMXT_OP_ENV1(unpacklub)
1759 IWMMXT_OP_ENV1(unpackluw)
1760 IWMMXT_OP_ENV1(unpacklul)
1761 IWMMXT_OP_ENV1(unpackhub)
1762 IWMMXT_OP_ENV1(unpackhuw)
1763 IWMMXT_OP_ENV1(unpackhul)
1764 IWMMXT_OP_ENV1(unpacklsb)
1765 IWMMXT_OP_ENV1(unpacklsw)
1766 IWMMXT_OP_ENV1(unpacklsl)
1767 IWMMXT_OP_ENV1(unpackhsb)
1768 IWMMXT_OP_ENV1(unpackhsw)
1769 IWMMXT_OP_ENV1(unpackhsl)
1770
1771 IWMMXT_OP_ENV_SIZE(cmpeq)
1772 IWMMXT_OP_ENV_SIZE(cmpgtu)
1773 IWMMXT_OP_ENV_SIZE(cmpgts)
1774
1775 IWMMXT_OP_ENV_SIZE(mins)
1776 IWMMXT_OP_ENV_SIZE(minu)
1777 IWMMXT_OP_ENV_SIZE(maxs)
1778 IWMMXT_OP_ENV_SIZE(maxu)
1779
1780 IWMMXT_OP_ENV_SIZE(subn)
1781 IWMMXT_OP_ENV_SIZE(addn)
1782 IWMMXT_OP_ENV_SIZE(subu)
1783 IWMMXT_OP_ENV_SIZE(addu)
1784 IWMMXT_OP_ENV_SIZE(subs)
1785 IWMMXT_OP_ENV_SIZE(adds)
1786
1787 IWMMXT_OP_ENV(avgb0)
1788 IWMMXT_OP_ENV(avgb1)
1789 IWMMXT_OP_ENV(avgw0)
1790 IWMMXT_OP_ENV(avgw1)
1791
1792 IWMMXT_OP_ENV(packuw)
1793 IWMMXT_OP_ENV(packul)
1794 IWMMXT_OP_ENV(packuq)
1795 IWMMXT_OP_ENV(packsw)
1796 IWMMXT_OP_ENV(packsl)
1797 IWMMXT_OP_ENV(packsq)
1798
1799 static void gen_op_iwmmxt_set_mup(void)
1800 {
1801 TCGv_i32 tmp;
1802 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1803 tcg_gen_ori_i32(tmp, tmp, 2);
1804 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1805 }
1806
1807 static void gen_op_iwmmxt_set_cup(void)
1808 {
1809 TCGv_i32 tmp;
1810 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1811 tcg_gen_ori_i32(tmp, tmp, 1);
1812 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1813 }
1814
1815 static void gen_op_iwmmxt_setpsr_nz(void)
1816 {
1817 TCGv_i32 tmp = tcg_temp_new_i32();
1818 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1819 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1820 }
1821
1822 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1823 {
1824 iwmmxt_load_reg(cpu_V1, rn);
1825 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1826 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1827 }
1828
1829 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1830 TCGv_i32 dest)
1831 {
1832 int rd;
1833 uint32_t offset;
1834 TCGv_i32 tmp;
1835
1836 rd = (insn >> 16) & 0xf;
1837 tmp = load_reg(s, rd);
1838
1839 offset = (insn & 0xff) << ((insn >> 7) & 2);
1840 if (insn & (1 << 24)) {
1841 /* Pre indexed */
1842 if (insn & (1 << 23))
1843 tcg_gen_addi_i32(tmp, tmp, offset);
1844 else
1845 tcg_gen_addi_i32(tmp, tmp, -offset);
1846 tcg_gen_mov_i32(dest, tmp);
1847 if (insn & (1 << 21))
1848 store_reg(s, rd, tmp);
1849 else
1850 tcg_temp_free_i32(tmp);
1851 } else if (insn & (1 << 21)) {
1852 /* Post indexed */
1853 tcg_gen_mov_i32(dest, tmp);
1854 if (insn & (1 << 23))
1855 tcg_gen_addi_i32(tmp, tmp, offset);
1856 else
1857 tcg_gen_addi_i32(tmp, tmp, -offset);
1858 store_reg(s, rd, tmp);
1859 } else if (!(insn & (1 << 23)))
1860 return 1;
1861 return 0;
1862 }
1863
1864 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1865 {
1866 int rd = (insn >> 0) & 0xf;
1867 TCGv_i32 tmp;
1868
1869 if (insn & (1 << 8)) {
1870 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1871 return 1;
1872 } else {
1873 tmp = iwmmxt_load_creg(rd);
1874 }
1875 } else {
1876 tmp = tcg_temp_new_i32();
1877 iwmmxt_load_reg(cpu_V0, rd);
1878 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1879 }
1880 tcg_gen_andi_i32(tmp, tmp, mask);
1881 tcg_gen_mov_i32(dest, tmp);
1882 tcg_temp_free_i32(tmp);
1883 return 0;
1884 }
1885
1886 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1887 (ie. an undefined instruction). */
1888 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1889 {
1890 int rd, wrd;
1891 int rdhi, rdlo, rd0, rd1, i;
1892 TCGv_i32 addr;
1893 TCGv_i32 tmp, tmp2, tmp3;
1894
1895 if ((insn & 0x0e000e00) == 0x0c000000) {
1896 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1897 wrd = insn & 0xf;
1898 rdlo = (insn >> 12) & 0xf;
1899 rdhi = (insn >> 16) & 0xf;
1900 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1901 iwmmxt_load_reg(cpu_V0, wrd);
1902 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1903 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1904 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1905 } else { /* TMCRR */
1906 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1907 iwmmxt_store_reg(cpu_V0, wrd);
1908 gen_op_iwmmxt_set_mup();
1909 }
1910 return 0;
1911 }
1912
1913 wrd = (insn >> 12) & 0xf;
1914 addr = tcg_temp_new_i32();
1915 if (gen_iwmmxt_address(s, insn, addr)) {
1916 tcg_temp_free_i32(addr);
1917 return 1;
1918 }
1919 if (insn & ARM_CP_RW_BIT) {
1920 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1921 tmp = tcg_temp_new_i32();
1922 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1923 iwmmxt_store_creg(wrd, tmp);
1924 } else {
1925 i = 1;
1926 if (insn & (1 << 8)) {
1927 if (insn & (1 << 22)) { /* WLDRD */
1928 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1929 i = 0;
1930 } else { /* WLDRW wRd */
1931 tmp = tcg_temp_new_i32();
1932 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1933 }
1934 } else {
1935 tmp = tcg_temp_new_i32();
1936 if (insn & (1 << 22)) { /* WLDRH */
1937 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1938 } else { /* WLDRB */
1939 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1940 }
1941 }
1942 if (i) {
1943 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1944 tcg_temp_free_i32(tmp);
1945 }
1946 gen_op_iwmmxt_movq_wRn_M0(wrd);
1947 }
1948 } else {
1949 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1950 tmp = iwmmxt_load_creg(wrd);
1951 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1952 } else {
1953 gen_op_iwmmxt_movq_M0_wRn(wrd);
1954 tmp = tcg_temp_new_i32();
1955 if (insn & (1 << 8)) {
1956 if (insn & (1 << 22)) { /* WSTRD */
1957 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1958 } else { /* WSTRW wRd */
1959 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1960 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1961 }
1962 } else {
1963 if (insn & (1 << 22)) { /* WSTRH */
1964 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1965 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1966 } else { /* WSTRB */
1967 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1968 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1969 }
1970 }
1971 }
1972 tcg_temp_free_i32(tmp);
1973 }
1974 tcg_temp_free_i32(addr);
1975 return 0;
1976 }
1977
1978 if ((insn & 0x0f000000) != 0x0e000000)
1979 return 1;
1980
1981 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1982 case 0x000: /* WOR */
1983 wrd = (insn >> 12) & 0xf;
1984 rd0 = (insn >> 0) & 0xf;
1985 rd1 = (insn >> 16) & 0xf;
1986 gen_op_iwmmxt_movq_M0_wRn(rd0);
1987 gen_op_iwmmxt_orq_M0_wRn(rd1);
1988 gen_op_iwmmxt_setpsr_nz();
1989 gen_op_iwmmxt_movq_wRn_M0(wrd);
1990 gen_op_iwmmxt_set_mup();
1991 gen_op_iwmmxt_set_cup();
1992 break;
1993 case 0x011: /* TMCR */
1994 if (insn & 0xf)
1995 return 1;
1996 rd = (insn >> 12) & 0xf;
1997 wrd = (insn >> 16) & 0xf;
1998 switch (wrd) {
1999 case ARM_IWMMXT_wCID:
2000 case ARM_IWMMXT_wCASF:
2001 break;
2002 case ARM_IWMMXT_wCon:
2003 gen_op_iwmmxt_set_cup();
2004 /* Fall through. */
2005 case ARM_IWMMXT_wCSSF:
2006 tmp = iwmmxt_load_creg(wrd);
2007 tmp2 = load_reg(s, rd);
2008 tcg_gen_andc_i32(tmp, tmp, tmp2);
2009 tcg_temp_free_i32(tmp2);
2010 iwmmxt_store_creg(wrd, tmp);
2011 break;
2012 case ARM_IWMMXT_wCGR0:
2013 case ARM_IWMMXT_wCGR1:
2014 case ARM_IWMMXT_wCGR2:
2015 case ARM_IWMMXT_wCGR3:
2016 gen_op_iwmmxt_set_cup();
2017 tmp = load_reg(s, rd);
2018 iwmmxt_store_creg(wrd, tmp);
2019 break;
2020 default:
2021 return 1;
2022 }
2023 break;
2024 case 0x100: /* WXOR */
2025 wrd = (insn >> 12) & 0xf;
2026 rd0 = (insn >> 0) & 0xf;
2027 rd1 = (insn >> 16) & 0xf;
2028 gen_op_iwmmxt_movq_M0_wRn(rd0);
2029 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2030 gen_op_iwmmxt_setpsr_nz();
2031 gen_op_iwmmxt_movq_wRn_M0(wrd);
2032 gen_op_iwmmxt_set_mup();
2033 gen_op_iwmmxt_set_cup();
2034 break;
2035 case 0x111: /* TMRC */
2036 if (insn & 0xf)
2037 return 1;
2038 rd = (insn >> 12) & 0xf;
2039 wrd = (insn >> 16) & 0xf;
2040 tmp = iwmmxt_load_creg(wrd);
2041 store_reg(s, rd, tmp);
2042 break;
2043 case 0x300: /* WANDN */
2044 wrd = (insn >> 12) & 0xf;
2045 rd0 = (insn >> 0) & 0xf;
2046 rd1 = (insn >> 16) & 0xf;
2047 gen_op_iwmmxt_movq_M0_wRn(rd0);
2048 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2049 gen_op_iwmmxt_andq_M0_wRn(rd1);
2050 gen_op_iwmmxt_setpsr_nz();
2051 gen_op_iwmmxt_movq_wRn_M0(wrd);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2054 break;
2055 case 0x200: /* WAND */
2056 wrd = (insn >> 12) & 0xf;
2057 rd0 = (insn >> 0) & 0xf;
2058 rd1 = (insn >> 16) & 0xf;
2059 gen_op_iwmmxt_movq_M0_wRn(rd0);
2060 gen_op_iwmmxt_andq_M0_wRn(rd1);
2061 gen_op_iwmmxt_setpsr_nz();
2062 gen_op_iwmmxt_movq_wRn_M0(wrd);
2063 gen_op_iwmmxt_set_mup();
2064 gen_op_iwmmxt_set_cup();
2065 break;
2066 case 0x810: case 0xa10: /* WMADD */
2067 wrd = (insn >> 12) & 0xf;
2068 rd0 = (insn >> 0) & 0xf;
2069 rd1 = (insn >> 16) & 0xf;
2070 gen_op_iwmmxt_movq_M0_wRn(rd0);
2071 if (insn & (1 << 21))
2072 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2073 else
2074 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2075 gen_op_iwmmxt_movq_wRn_M0(wrd);
2076 gen_op_iwmmxt_set_mup();
2077 break;
2078 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2079 wrd = (insn >> 12) & 0xf;
2080 rd0 = (insn >> 16) & 0xf;
2081 rd1 = (insn >> 0) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 switch ((insn >> 22) & 3) {
2084 case 0:
2085 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2086 break;
2087 case 1:
2088 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2089 break;
2090 case 2:
2091 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2092 break;
2093 case 3:
2094 return 1;
2095 }
2096 gen_op_iwmmxt_movq_wRn_M0(wrd);
2097 gen_op_iwmmxt_set_mup();
2098 gen_op_iwmmxt_set_cup();
2099 break;
2100 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2101 wrd = (insn >> 12) & 0xf;
2102 rd0 = (insn >> 16) & 0xf;
2103 rd1 = (insn >> 0) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0);
2105 switch ((insn >> 22) & 3) {
2106 case 0:
2107 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2108 break;
2109 case 1:
2110 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2111 break;
2112 case 2:
2113 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2114 break;
2115 case 3:
2116 return 1;
2117 }
2118 gen_op_iwmmxt_movq_wRn_M0(wrd);
2119 gen_op_iwmmxt_set_mup();
2120 gen_op_iwmmxt_set_cup();
2121 break;
2122 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2123 wrd = (insn >> 12) & 0xf;
2124 rd0 = (insn >> 16) & 0xf;
2125 rd1 = (insn >> 0) & 0xf;
2126 gen_op_iwmmxt_movq_M0_wRn(rd0);
2127 if (insn & (1 << 22))
2128 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2129 else
2130 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2131 if (!(insn & (1 << 20)))
2132 gen_op_iwmmxt_addl_M0_wRn(wrd);
2133 gen_op_iwmmxt_movq_wRn_M0(wrd);
2134 gen_op_iwmmxt_set_mup();
2135 break;
2136 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2137 wrd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 rd1 = (insn >> 0) & 0xf;
2140 gen_op_iwmmxt_movq_M0_wRn(rd0);
2141 if (insn & (1 << 21)) {
2142 if (insn & (1 << 20))
2143 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2144 else
2145 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2146 } else {
2147 if (insn & (1 << 20))
2148 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2149 else
2150 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2151 }
2152 gen_op_iwmmxt_movq_wRn_M0(wrd);
2153 gen_op_iwmmxt_set_mup();
2154 break;
2155 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2156 wrd = (insn >> 12) & 0xf;
2157 rd0 = (insn >> 16) & 0xf;
2158 rd1 = (insn >> 0) & 0xf;
2159 gen_op_iwmmxt_movq_M0_wRn(rd0);
2160 if (insn & (1 << 21))
2161 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2162 else
2163 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2164 if (!(insn & (1 << 20))) {
2165 iwmmxt_load_reg(cpu_V1, wrd);
2166 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2167 }
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2170 break;
2171 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2172 wrd = (insn >> 12) & 0xf;
2173 rd0 = (insn >> 16) & 0xf;
2174 rd1 = (insn >> 0) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 switch ((insn >> 22) & 3) {
2177 case 0:
2178 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2179 break;
2180 case 1:
2181 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2182 break;
2183 case 2:
2184 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2185 break;
2186 case 3:
2187 return 1;
2188 }
2189 gen_op_iwmmxt_movq_wRn_M0(wrd);
2190 gen_op_iwmmxt_set_mup();
2191 gen_op_iwmmxt_set_cup();
2192 break;
2193 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2194 wrd = (insn >> 12) & 0xf;
2195 rd0 = (insn >> 16) & 0xf;
2196 rd1 = (insn >> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0);
2198 if (insn & (1 << 22)) {
2199 if (insn & (1 << 20))
2200 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2201 else
2202 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2203 } else {
2204 if (insn & (1 << 20))
2205 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2206 else
2207 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2208 }
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 gen_op_iwmmxt_set_cup();
2212 break;
2213 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2214 wrd = (insn >> 12) & 0xf;
2215 rd0 = (insn >> 16) & 0xf;
2216 rd1 = (insn >> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0);
2218 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2219 tcg_gen_andi_i32(tmp, tmp, 7);
2220 iwmmxt_load_reg(cpu_V1, rd1);
2221 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2222 tcg_temp_free_i32(tmp);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd);
2224 gen_op_iwmmxt_set_mup();
2225 break;
2226 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2227 if (((insn >> 6) & 3) == 3)
2228 return 1;
2229 rd = (insn >> 12) & 0xf;
2230 wrd = (insn >> 16) & 0xf;
2231 tmp = load_reg(s, rd);
2232 gen_op_iwmmxt_movq_M0_wRn(wrd);
2233 switch ((insn >> 6) & 3) {
2234 case 0:
2235 tmp2 = tcg_const_i32(0xff);
2236 tmp3 = tcg_const_i32((insn & 7) << 3);
2237 break;
2238 case 1:
2239 tmp2 = tcg_const_i32(0xffff);
2240 tmp3 = tcg_const_i32((insn & 3) << 4);
2241 break;
2242 case 2:
2243 tmp2 = tcg_const_i32(0xffffffff);
2244 tmp3 = tcg_const_i32((insn & 1) << 5);
2245 break;
2246 default:
2247 tmp2 = NULL;
2248 tmp3 = NULL;
2249 }
2250 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2251 tcg_temp_free_i32(tmp3);
2252 tcg_temp_free_i32(tmp2);
2253 tcg_temp_free_i32(tmp);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2256 break;
2257 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2258 rd = (insn >> 12) & 0xf;
2259 wrd = (insn >> 16) & 0xf;
2260 if (rd == 15 || ((insn >> 22) & 3) == 3)
2261 return 1;
2262 gen_op_iwmmxt_movq_M0_wRn(wrd);
2263 tmp = tcg_temp_new_i32();
2264 switch ((insn >> 22) & 3) {
2265 case 0:
2266 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2267 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2268 if (insn & 8) {
2269 tcg_gen_ext8s_i32(tmp, tmp);
2270 } else {
2271 tcg_gen_andi_i32(tmp, tmp, 0xff);
2272 }
2273 break;
2274 case 1:
2275 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2276 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2277 if (insn & 8) {
2278 tcg_gen_ext16s_i32(tmp, tmp);
2279 } else {
2280 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2281 }
2282 break;
2283 case 2:
2284 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2285 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2286 break;
2287 }
2288 store_reg(s, rd, tmp);
2289 break;
2290 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2291 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2292 return 1;
2293 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2294 switch ((insn >> 22) & 3) {
2295 case 0:
2296 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2297 break;
2298 case 1:
2299 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2300 break;
2301 case 2:
2302 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2303 break;
2304 }
2305 tcg_gen_shli_i32(tmp, tmp, 28);
2306 gen_set_nzcv(tmp);
2307 tcg_temp_free_i32(tmp);
2308 break;
2309 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2310 if (((insn >> 6) & 3) == 3)
2311 return 1;
2312 rd = (insn >> 12) & 0xf;
2313 wrd = (insn >> 16) & 0xf;
2314 tmp = load_reg(s, rd);
2315 switch ((insn >> 6) & 3) {
2316 case 0:
2317 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2318 break;
2319 case 1:
2320 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2321 break;
2322 case 2:
2323 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2324 break;
2325 }
2326 tcg_temp_free_i32(tmp);
2327 gen_op_iwmmxt_movq_wRn_M0(wrd);
2328 gen_op_iwmmxt_set_mup();
2329 break;
2330 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2331 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2332 return 1;
2333 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2334 tmp2 = tcg_temp_new_i32();
2335 tcg_gen_mov_i32(tmp2, tmp);
2336 switch ((insn >> 22) & 3) {
2337 case 0:
2338 for (i = 0; i < 7; i ++) {
2339 tcg_gen_shli_i32(tmp2, tmp2, 4);
2340 tcg_gen_and_i32(tmp, tmp, tmp2);
2341 }
2342 break;
2343 case 1:
2344 for (i = 0; i < 3; i ++) {
2345 tcg_gen_shli_i32(tmp2, tmp2, 8);
2346 tcg_gen_and_i32(tmp, tmp, tmp2);
2347 }
2348 break;
2349 case 2:
2350 tcg_gen_shli_i32(tmp2, tmp2, 16);
2351 tcg_gen_and_i32(tmp, tmp, tmp2);
2352 break;
2353 }
2354 gen_set_nzcv(tmp);
2355 tcg_temp_free_i32(tmp2);
2356 tcg_temp_free_i32(tmp);
2357 break;
2358 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2359 wrd = (insn >> 12) & 0xf;
2360 rd0 = (insn >> 16) & 0xf;
2361 gen_op_iwmmxt_movq_M0_wRn(rd0);
2362 switch ((insn >> 22) & 3) {
2363 case 0:
2364 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2365 break;
2366 case 1:
2367 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2368 break;
2369 case 2:
2370 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2371 break;
2372 case 3:
2373 return 1;
2374 }
2375 gen_op_iwmmxt_movq_wRn_M0(wrd);
2376 gen_op_iwmmxt_set_mup();
2377 break;
2378 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2379 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2380 return 1;
2381 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2382 tmp2 = tcg_temp_new_i32();
2383 tcg_gen_mov_i32(tmp2, tmp);
2384 switch ((insn >> 22) & 3) {
2385 case 0:
2386 for (i = 0; i < 7; i ++) {
2387 tcg_gen_shli_i32(tmp2, tmp2, 4);
2388 tcg_gen_or_i32(tmp, tmp, tmp2);
2389 }
2390 break;
2391 case 1:
2392 for (i = 0; i < 3; i ++) {
2393 tcg_gen_shli_i32(tmp2, tmp2, 8);
2394 tcg_gen_or_i32(tmp, tmp, tmp2);
2395 }
2396 break;
2397 case 2:
2398 tcg_gen_shli_i32(tmp2, tmp2, 16);
2399 tcg_gen_or_i32(tmp, tmp, tmp2);
2400 break;
2401 }
2402 gen_set_nzcv(tmp);
2403 tcg_temp_free_i32(tmp2);
2404 tcg_temp_free_i32(tmp);
2405 break;
2406 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2407 rd = (insn >> 12) & 0xf;
2408 rd0 = (insn >> 16) & 0xf;
2409 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2410 return 1;
2411 gen_op_iwmmxt_movq_M0_wRn(rd0);
2412 tmp = tcg_temp_new_i32();
2413 switch ((insn >> 22) & 3) {
2414 case 0:
2415 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2416 break;
2417 case 1:
2418 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2419 break;
2420 case 2:
2421 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2422 break;
2423 }
2424 store_reg(s, rd, tmp);
2425 break;
2426 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2427 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2428 wrd = (insn >> 12) & 0xf;
2429 rd0 = (insn >> 16) & 0xf;
2430 rd1 = (insn >> 0) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 switch ((insn >> 22) & 3) {
2433 case 0:
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2436 else
2437 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2438 break;
2439 case 1:
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2442 else
2443 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2444 break;
2445 case 2:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2448 else
2449 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2450 break;
2451 case 3:
2452 return 1;
2453 }
2454 gen_op_iwmmxt_movq_wRn_M0(wrd);
2455 gen_op_iwmmxt_set_mup();
2456 gen_op_iwmmxt_set_cup();
2457 break;
2458 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2459 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2460 wrd = (insn >> 12) & 0xf;
2461 rd0 = (insn >> 16) & 0xf;
2462 gen_op_iwmmxt_movq_M0_wRn(rd0);
2463 switch ((insn >> 22) & 3) {
2464 case 0:
2465 if (insn & (1 << 21))
2466 gen_op_iwmmxt_unpacklsb_M0();
2467 else
2468 gen_op_iwmmxt_unpacklub_M0();
2469 break;
2470 case 1:
2471 if (insn & (1 << 21))
2472 gen_op_iwmmxt_unpacklsw_M0();
2473 else
2474 gen_op_iwmmxt_unpackluw_M0();
2475 break;
2476 case 2:
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_unpacklsl_M0();
2479 else
2480 gen_op_iwmmxt_unpacklul_M0();
2481 break;
2482 case 3:
2483 return 1;
2484 }
2485 gen_op_iwmmxt_movq_wRn_M0(wrd);
2486 gen_op_iwmmxt_set_mup();
2487 gen_op_iwmmxt_set_cup();
2488 break;
2489 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2490 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2491 wrd = (insn >> 12) & 0xf;
2492 rd0 = (insn >> 16) & 0xf;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0);
2494 switch ((insn >> 22) & 3) {
2495 case 0:
2496 if (insn & (1 << 21))
2497 gen_op_iwmmxt_unpackhsb_M0();
2498 else
2499 gen_op_iwmmxt_unpackhub_M0();
2500 break;
2501 case 1:
2502 if (insn & (1 << 21))
2503 gen_op_iwmmxt_unpackhsw_M0();
2504 else
2505 gen_op_iwmmxt_unpackhuw_M0();
2506 break;
2507 case 2:
2508 if (insn & (1 << 21))
2509 gen_op_iwmmxt_unpackhsl_M0();
2510 else
2511 gen_op_iwmmxt_unpackhul_M0();
2512 break;
2513 case 3:
2514 return 1;
2515 }
2516 gen_op_iwmmxt_movq_wRn_M0(wrd);
2517 gen_op_iwmmxt_set_mup();
2518 gen_op_iwmmxt_set_cup();
2519 break;
2520 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2521 case 0x214: case 0x614: case 0xa14: case 0xe14:
2522 if (((insn >> 22) & 3) == 0)
2523 return 1;
2524 wrd = (insn >> 12) & 0xf;
2525 rd0 = (insn >> 16) & 0xf;
2526 gen_op_iwmmxt_movq_M0_wRn(rd0);
2527 tmp = tcg_temp_new_i32();
2528 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2529 tcg_temp_free_i32(tmp);
2530 return 1;
2531 }
2532 switch ((insn >> 22) & 3) {
2533 case 1:
2534 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2535 break;
2536 case 2:
2537 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2538 break;
2539 case 3:
2540 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2541 break;
2542 }
2543 tcg_temp_free_i32(tmp);
2544 gen_op_iwmmxt_movq_wRn_M0(wrd);
2545 gen_op_iwmmxt_set_mup();
2546 gen_op_iwmmxt_set_cup();
2547 break;
2548 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2549 case 0x014: case 0x414: case 0x814: case 0xc14:
2550 if (((insn >> 22) & 3) == 0)
2551 return 1;
2552 wrd = (insn >> 12) & 0xf;
2553 rd0 = (insn >> 16) & 0xf;
2554 gen_op_iwmmxt_movq_M0_wRn(rd0);
2555 tmp = tcg_temp_new_i32();
2556 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2557 tcg_temp_free_i32(tmp);
2558 return 1;
2559 }
2560 switch ((insn >> 22) & 3) {
2561 case 1:
2562 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2563 break;
2564 case 2:
2565 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2566 break;
2567 case 3:
2568 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2569 break;
2570 }
2571 tcg_temp_free_i32(tmp);
2572 gen_op_iwmmxt_movq_wRn_M0(wrd);
2573 gen_op_iwmmxt_set_mup();
2574 gen_op_iwmmxt_set_cup();
2575 break;
2576 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2577 case 0x114: case 0x514: case 0x914: case 0xd14:
2578 if (((insn >> 22) & 3) == 0)
2579 return 1;
2580 wrd = (insn >> 12) & 0xf;
2581 rd0 = (insn >> 16) & 0xf;
2582 gen_op_iwmmxt_movq_M0_wRn(rd0);
2583 tmp = tcg_temp_new_i32();
2584 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2585 tcg_temp_free_i32(tmp);
2586 return 1;
2587 }
2588 switch ((insn >> 22) & 3) {
2589 case 1:
2590 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2591 break;
2592 case 2:
2593 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2594 break;
2595 case 3:
2596 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2597 break;
2598 }
2599 tcg_temp_free_i32(tmp);
2600 gen_op_iwmmxt_movq_wRn_M0(wrd);
2601 gen_op_iwmmxt_set_mup();
2602 gen_op_iwmmxt_set_cup();
2603 break;
2604 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2605 case 0x314: case 0x714: case 0xb14: case 0xf14:
2606 if (((insn >> 22) & 3) == 0)
2607 return 1;
2608 wrd = (insn >> 12) & 0xf;
2609 rd0 = (insn >> 16) & 0xf;
2610 gen_op_iwmmxt_movq_M0_wRn(rd0);
2611 tmp = tcg_temp_new_i32();
2612 switch ((insn >> 22) & 3) {
2613 case 1:
2614 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2615 tcg_temp_free_i32(tmp);
2616 return 1;
2617 }
2618 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2619 break;
2620 case 2:
2621 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2622 tcg_temp_free_i32(tmp);
2623 return 1;
2624 }
2625 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2626 break;
2627 case 3:
2628 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2629 tcg_temp_free_i32(tmp);
2630 return 1;
2631 }
2632 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2633 break;
2634 }
2635 tcg_temp_free_i32(tmp);
2636 gen_op_iwmmxt_movq_wRn_M0(wrd);
2637 gen_op_iwmmxt_set_mup();
2638 gen_op_iwmmxt_set_cup();
2639 break;
2640 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2641 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2642 wrd = (insn >> 12) & 0xf;
2643 rd0 = (insn >> 16) & 0xf;
2644 rd1 = (insn >> 0) & 0xf;
2645 gen_op_iwmmxt_movq_M0_wRn(rd0);
2646 switch ((insn >> 22) & 3) {
2647 case 0:
2648 if (insn & (1 << 21))
2649 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2650 else
2651 gen_op_iwmmxt_minub_M0_wRn(rd1);
2652 break;
2653 case 1:
2654 if (insn & (1 << 21))
2655 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2656 else
2657 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2658 break;
2659 case 2:
2660 if (insn & (1 << 21))
2661 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2662 else
2663 gen_op_iwmmxt_minul_M0_wRn(rd1);
2664 break;
2665 case 3:
2666 return 1;
2667 }
2668 gen_op_iwmmxt_movq_wRn_M0(wrd);
2669 gen_op_iwmmxt_set_mup();
2670 break;
2671 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2672 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2673 wrd = (insn >> 12) & 0xf;
2674 rd0 = (insn >> 16) & 0xf;
2675 rd1 = (insn >> 0) & 0xf;
2676 gen_op_iwmmxt_movq_M0_wRn(rd0);
2677 switch ((insn >> 22) & 3) {
2678 case 0:
2679 if (insn & (1 << 21))
2680 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2681 else
2682 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2683 break;
2684 case 1:
2685 if (insn & (1 << 21))
2686 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2687 else
2688 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2689 break;
2690 case 2:
2691 if (insn & (1 << 21))
2692 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2693 else
2694 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2695 break;
2696 case 3:
2697 return 1;
2698 }
2699 gen_op_iwmmxt_movq_wRn_M0(wrd);
2700 gen_op_iwmmxt_set_mup();
2701 break;
2702 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2703 case 0x402: case 0x502: case 0x602: case 0x702:
2704 wrd = (insn >> 12) & 0xf;
2705 rd0 = (insn >> 16) & 0xf;
2706 rd1 = (insn >> 0) & 0xf;
2707 gen_op_iwmmxt_movq_M0_wRn(rd0);
2708 tmp = tcg_const_i32((insn >> 20) & 3);
2709 iwmmxt_load_reg(cpu_V1, rd1);
2710 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2711 tcg_temp_free_i32(tmp);
2712 gen_op_iwmmxt_movq_wRn_M0(wrd);
2713 gen_op_iwmmxt_set_mup();
2714 break;
2715 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2716 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2717 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2718 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2719 wrd = (insn >> 12) & 0xf;
2720 rd0 = (insn >> 16) & 0xf;
2721 rd1 = (insn >> 0) & 0xf;
2722 gen_op_iwmmxt_movq_M0_wRn(rd0);
2723 switch ((insn >> 20) & 0xf) {
2724 case 0x0:
2725 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2726 break;
2727 case 0x1:
2728 gen_op_iwmmxt_subub_M0_wRn(rd1);
2729 break;
2730 case 0x3:
2731 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2732 break;
2733 case 0x4:
2734 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2735 break;
2736 case 0x5:
2737 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2738 break;
2739 case 0x7:
2740 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2741 break;
2742 case 0x8:
2743 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2744 break;
2745 case 0x9:
2746 gen_op_iwmmxt_subul_M0_wRn(rd1);
2747 break;
2748 case 0xb:
2749 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2750 break;
2751 default:
2752 return 1;
2753 }
2754 gen_op_iwmmxt_movq_wRn_M0(wrd);
2755 gen_op_iwmmxt_set_mup();
2756 gen_op_iwmmxt_set_cup();
2757 break;
2758 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2759 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2760 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2761 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2762 wrd = (insn >> 12) & 0xf;
2763 rd0 = (insn >> 16) & 0xf;
2764 gen_op_iwmmxt_movq_M0_wRn(rd0);
2765 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2766 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2767 tcg_temp_free_i32(tmp);
2768 gen_op_iwmmxt_movq_wRn_M0(wrd);
2769 gen_op_iwmmxt_set_mup();
2770 gen_op_iwmmxt_set_cup();
2771 break;
2772 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2773 case 0x418: case 0x518: case 0x618: case 0x718:
2774 case 0x818: case 0x918: case 0xa18: case 0xb18:
2775 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2776 wrd = (insn >> 12) & 0xf;
2777 rd0 = (insn >> 16) & 0xf;
2778 rd1 = (insn >> 0) & 0xf;
2779 gen_op_iwmmxt_movq_M0_wRn(rd0);
2780 switch ((insn >> 20) & 0xf) {
2781 case 0x0:
2782 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2783 break;
2784 case 0x1:
2785 gen_op_iwmmxt_addub_M0_wRn(rd1);
2786 break;
2787 case 0x3:
2788 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2789 break;
2790 case 0x4:
2791 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2792 break;
2793 case 0x5:
2794 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2795 break;
2796 case 0x7:
2797 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2798 break;
2799 case 0x8:
2800 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2801 break;
2802 case 0x9:
2803 gen_op_iwmmxt_addul_M0_wRn(rd1);
2804 break;
2805 case 0xb:
2806 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2807 break;
2808 default:
2809 return 1;
2810 }
2811 gen_op_iwmmxt_movq_wRn_M0(wrd);
2812 gen_op_iwmmxt_set_mup();
2813 gen_op_iwmmxt_set_cup();
2814 break;
2815 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2816 case 0x408: case 0x508: case 0x608: case 0x708:
2817 case 0x808: case 0x908: case 0xa08: case 0xb08:
2818 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2819 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2820 return 1;
2821 wrd = (insn >> 12) & 0xf;
2822 rd0 = (insn >> 16) & 0xf;
2823 rd1 = (insn >> 0) & 0xf;
2824 gen_op_iwmmxt_movq_M0_wRn(rd0);
2825 switch ((insn >> 22) & 3) {
2826 case 1:
2827 if (insn & (1 << 21))
2828 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2829 else
2830 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2831 break;
2832 case 2:
2833 if (insn & (1 << 21))
2834 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2835 else
2836 gen_op_iwmmxt_packul_M0_wRn(rd1);
2837 break;
2838 case 3:
2839 if (insn & (1 << 21))
2840 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2841 else
2842 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2843 break;
2844 }
2845 gen_op_iwmmxt_movq_wRn_M0(wrd);
2846 gen_op_iwmmxt_set_mup();
2847 gen_op_iwmmxt_set_cup();
2848 break;
2849 case 0x201: case 0x203: case 0x205: case 0x207:
2850 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2851 case 0x211: case 0x213: case 0x215: case 0x217:
2852 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2853 wrd = (insn >> 5) & 0xf;
2854 rd0 = (insn >> 12) & 0xf;
2855 rd1 = (insn >> 0) & 0xf;
2856 if (rd0 == 0xf || rd1 == 0xf)
2857 return 1;
2858 gen_op_iwmmxt_movq_M0_wRn(wrd);
2859 tmp = load_reg(s, rd0);
2860 tmp2 = load_reg(s, rd1);
2861 switch ((insn >> 16) & 0xf) {
2862 case 0x0: /* TMIA */
2863 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2864 break;
2865 case 0x8: /* TMIAPH */
2866 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2867 break;
2868 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2869 if (insn & (1 << 16))
2870 tcg_gen_shri_i32(tmp, tmp, 16);
2871 if (insn & (1 << 17))
2872 tcg_gen_shri_i32(tmp2, tmp2, 16);
2873 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2874 break;
2875 default:
2876 tcg_temp_free_i32(tmp2);
2877 tcg_temp_free_i32(tmp);
2878 return 1;
2879 }
2880 tcg_temp_free_i32(tmp2);
2881 tcg_temp_free_i32(tmp);
2882 gen_op_iwmmxt_movq_wRn_M0(wrd);
2883 gen_op_iwmmxt_set_mup();
2884 break;
2885 default:
2886 return 1;
2887 }
2888
2889 return 0;
2890 }
2891
2892 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2893 (ie. an undefined instruction). */
2894 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2895 {
2896 int acc, rd0, rd1, rdhi, rdlo;
2897 TCGv_i32 tmp, tmp2;
2898
2899 if ((insn & 0x0ff00f10) == 0x0e200010) {
2900 /* Multiply with Internal Accumulate Format */
2901 rd0 = (insn >> 12) & 0xf;
2902 rd1 = insn & 0xf;
2903 acc = (insn >> 5) & 7;
2904
2905 if (acc != 0)
2906 return 1;
2907
2908 tmp = load_reg(s, rd0);
2909 tmp2 = load_reg(s, rd1);
2910 switch ((insn >> 16) & 0xf) {
2911 case 0x0: /* MIA */
2912 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2913 break;
2914 case 0x8: /* MIAPH */
2915 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2916 break;
2917 case 0xc: /* MIABB */
2918 case 0xd: /* MIABT */
2919 case 0xe: /* MIATB */
2920 case 0xf: /* MIATT */
2921 if (insn & (1 << 16))
2922 tcg_gen_shri_i32(tmp, tmp, 16);
2923 if (insn & (1 << 17))
2924 tcg_gen_shri_i32(tmp2, tmp2, 16);
2925 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2926 break;
2927 default:
2928 return 1;
2929 }
2930 tcg_temp_free_i32(tmp2);
2931 tcg_temp_free_i32(tmp);
2932
2933 gen_op_iwmmxt_movq_wRn_M0(acc);
2934 return 0;
2935 }
2936
2937 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2938 /* Internal Accumulator Access Format */
2939 rdhi = (insn >> 16) & 0xf;
2940 rdlo = (insn >> 12) & 0xf;
2941 acc = insn & 7;
2942
2943 if (acc != 0)
2944 return 1;
2945
2946 if (insn & ARM_CP_RW_BIT) { /* MRA */
2947 iwmmxt_load_reg(cpu_V0, acc);
2948 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2949 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2950 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2951 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2952 } else { /* MAR */
2953 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2954 iwmmxt_store_reg(cpu_V0, acc);
2955 }
2956 return 0;
2957 }
2958
2959 return 1;
2960 }
2961
2962 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2963 #define VFP_SREG(insn, bigbit, smallbit) \
2964 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2965 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2966 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2967 reg = (((insn) >> (bigbit)) & 0x0f) \
2968 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2969 } else { \
2970 if (insn & (1 << (smallbit))) \
2971 return 1; \
2972 reg = ((insn) >> (bigbit)) & 0x0f; \
2973 }} while (0)
2974
2975 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2976 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2977 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2978 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2979 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2980 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2981
2982 /* Move between integer and VFP cores. */
2983 static TCGv_i32 gen_vfp_mrs(void)
2984 {
2985 TCGv_i32 tmp = tcg_temp_new_i32();
2986 tcg_gen_mov_i32(tmp, cpu_F0s);
2987 return tmp;
2988 }
2989
2990 static void gen_vfp_msr(TCGv_i32 tmp)
2991 {
2992 tcg_gen_mov_i32(cpu_F0s, tmp);
2993 tcg_temp_free_i32(tmp);
2994 }
2995
2996 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2997 {
2998 TCGv_i32 tmp = tcg_temp_new_i32();
2999 if (shift)
3000 tcg_gen_shri_i32(var, var, shift);
3001 tcg_gen_ext8u_i32(var, var);
3002 tcg_gen_shli_i32(tmp, var, 8);
3003 tcg_gen_or_i32(var, var, tmp);
3004 tcg_gen_shli_i32(tmp, var, 16);
3005 tcg_gen_or_i32(var, var, tmp);
3006 tcg_temp_free_i32(tmp);
3007 }
3008
3009 static void gen_neon_dup_low16(TCGv_i32 var)
3010 {
3011 TCGv_i32 tmp = tcg_temp_new_i32();
3012 tcg_gen_ext16u_i32(var, var);
3013 tcg_gen_shli_i32(tmp, var, 16);
3014 tcg_gen_or_i32(var, var, tmp);
3015 tcg_temp_free_i32(tmp);
3016 }
3017
3018 static void gen_neon_dup_high16(TCGv_i32 var)
3019 {
3020 TCGv_i32 tmp = tcg_temp_new_i32();
3021 tcg_gen_andi_i32(var, var, 0xffff0000);
3022 tcg_gen_shri_i32(tmp, var, 16);
3023 tcg_gen_or_i32(var, var, tmp);
3024 tcg_temp_free_i32(tmp);
3025 }
3026
3027 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
3028 {
3029 /* Load a single Neon element and replicate into a 32 bit TCG reg */
3030 TCGv_i32 tmp = tcg_temp_new_i32();
3031 switch (size) {
3032 case 0:
3033 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
3034 gen_neon_dup_u8(tmp, 0);
3035 break;
3036 case 1:
3037 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
3038 gen_neon_dup_low16(tmp);
3039 break;
3040 case 2:
3041 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
3042 break;
3043 default: /* Avoid compiler warnings. */
3044 abort();
3045 }
3046 return tmp;
3047 }
3048
3049 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3050 uint32_t dp)
3051 {
3052 uint32_t cc = extract32(insn, 20, 2);
3053
3054 if (dp) {
3055 TCGv_i64 frn, frm, dest;
3056 TCGv_i64 tmp, zero, zf, nf, vf;
3057
3058 zero = tcg_const_i64(0);
3059
3060 frn = tcg_temp_new_i64();
3061 frm = tcg_temp_new_i64();
3062 dest = tcg_temp_new_i64();
3063
3064 zf = tcg_temp_new_i64();
3065 nf = tcg_temp_new_i64();
3066 vf = tcg_temp_new_i64();
3067
3068 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3069 tcg_gen_ext_i32_i64(nf, cpu_NF);
3070 tcg_gen_ext_i32_i64(vf, cpu_VF);
3071
3072 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3073 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3074 switch (cc) {
3075 case 0: /* eq: Z */
3076 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3077 frn, frm);
3078 break;
3079 case 1: /* vs: V */
3080 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3081 frn, frm);
3082 break;
3083 case 2: /* ge: N == V -> N ^ V == 0 */
3084 tmp = tcg_temp_new_i64();
3085 tcg_gen_xor_i64(tmp, vf, nf);
3086 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3087 frn, frm);
3088 tcg_temp_free_i64(tmp);
3089 break;
3090 case 3: /* gt: !Z && N == V */
3091 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3092 frn, frm);
3093 tmp = tcg_temp_new_i64();
3094 tcg_gen_xor_i64(tmp, vf, nf);
3095 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3096 dest, frm);
3097 tcg_temp_free_i64(tmp);
3098 break;
3099 }
3100 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3101 tcg_temp_free_i64(frn);
3102 tcg_temp_free_i64(frm);
3103 tcg_temp_free_i64(dest);
3104
3105 tcg_temp_free_i64(zf);
3106 tcg_temp_free_i64(nf);
3107 tcg_temp_free_i64(vf);
3108
3109 tcg_temp_free_i64(zero);
3110 } else {
3111 TCGv_i32 frn, frm, dest;
3112 TCGv_i32 tmp, zero;
3113
3114 zero = tcg_const_i32(0);
3115
3116 frn = tcg_temp_new_i32();
3117 frm = tcg_temp_new_i32();
3118 dest = tcg_temp_new_i32();
3119 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3120 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3121 switch (cc) {
3122 case 0: /* eq: Z */
3123 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3124 frn, frm);
3125 break;
3126 case 1: /* vs: V */
3127 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3128 frn, frm);
3129 break;
3130 case 2: /* ge: N == V -> N ^ V == 0 */
3131 tmp = tcg_temp_new_i32();
3132 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3133 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3134 frn, frm);
3135 tcg_temp_free_i32(tmp);
3136 break;
3137 case 3: /* gt: !Z && N == V */
3138 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3139 frn, frm);
3140 tmp = tcg_temp_new_i32();
3141 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3142 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3143 dest, frm);
3144 tcg_temp_free_i32(tmp);
3145 break;
3146 }
3147 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3148 tcg_temp_free_i32(frn);
3149 tcg_temp_free_i32(frm);
3150 tcg_temp_free_i32(dest);
3151
3152 tcg_temp_free_i32(zero);
3153 }
3154
3155 return 0;
3156 }
3157
3158 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3159 uint32_t rm, uint32_t dp)
3160 {
3161 uint32_t vmin = extract32(insn, 6, 1);
3162 TCGv_ptr fpst = get_fpstatus_ptr(0);
3163
3164 if (dp) {
3165 TCGv_i64 frn, frm, dest;
3166
3167 frn = tcg_temp_new_i64();
3168 frm = tcg_temp_new_i64();
3169 dest = tcg_temp_new_i64();
3170
3171 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3172 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3173 if (vmin) {
3174 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3175 } else {
3176 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3177 }
3178 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3179 tcg_temp_free_i64(frn);
3180 tcg_temp_free_i64(frm);
3181 tcg_temp_free_i64(dest);
3182 } else {
3183 TCGv_i32 frn, frm, dest;
3184
3185 frn = tcg_temp_new_i32();
3186 frm = tcg_temp_new_i32();
3187 dest = tcg_temp_new_i32();
3188
3189 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3190 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3191 if (vmin) {
3192 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3193 } else {
3194 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3195 }
3196 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3197 tcg_temp_free_i32(frn);
3198 tcg_temp_free_i32(frm);
3199 tcg_temp_free_i32(dest);
3200 }
3201
3202 tcg_temp_free_ptr(fpst);
3203 return 0;
3204 }
3205
3206 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3207 int rounding)
3208 {
3209 TCGv_ptr fpst = get_fpstatus_ptr(0);
3210 TCGv_i32 tcg_rmode;
3211
3212 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3213 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3214
3215 if (dp) {
3216 TCGv_i64 tcg_op;
3217 TCGv_i64 tcg_res;
3218 tcg_op = tcg_temp_new_i64();
3219 tcg_res = tcg_temp_new_i64();
3220 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3221 gen_helper_rintd(tcg_res, tcg_op, fpst);
3222 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3223 tcg_temp_free_i64(tcg_op);
3224 tcg_temp_free_i64(tcg_res);
3225 } else {
3226 TCGv_i32 tcg_op;
3227 TCGv_i32 tcg_res;
3228 tcg_op = tcg_temp_new_i32();
3229 tcg_res = tcg_temp_new_i32();
3230 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3231 gen_helper_rints(tcg_res, tcg_op, fpst);
3232 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3233 tcg_temp_free_i32(tcg_op);
3234 tcg_temp_free_i32(tcg_res);
3235 }
3236
3237 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3238 tcg_temp_free_i32(tcg_rmode);
3239
3240 tcg_temp_free_ptr(fpst);
3241 return 0;
3242 }
3243
3244 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3245 int rounding)
3246 {
3247 bool is_signed = extract32(insn, 7, 1);
3248 TCGv_ptr fpst = get_fpstatus_ptr(0);
3249 TCGv_i32 tcg_rmode, tcg_shift;
3250
3251 tcg_shift = tcg_const_i32(0);
3252
3253 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3254 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3255
3256 if (dp) {
3257 TCGv_i64 tcg_double, tcg_res;
3258 TCGv_i32 tcg_tmp;
3259 /* Rd is encoded as a single precision register even when the source
3260 * is double precision.
3261 */
3262 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3263 tcg_double = tcg_temp_new_i64();
3264 tcg_res = tcg_temp_new_i64();
3265 tcg_tmp = tcg_temp_new_i32();
3266 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3267 if (is_signed) {
3268 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3269 } else {
3270 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3271 }
3272 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3273 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3274 tcg_temp_free_i32(tcg_tmp);
3275 tcg_temp_free_i64(tcg_res);
3276 tcg_temp_free_i64(tcg_double);
3277 } else {
3278 TCGv_i32 tcg_single, tcg_res;
3279 tcg_single = tcg_temp_new_i32();
3280 tcg_res = tcg_temp_new_i32();
3281 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3282 if (is_signed) {
3283 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3284 } else {
3285 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3286 }
3287 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3288 tcg_temp_free_i32(tcg_res);
3289 tcg_temp_free_i32(tcg_single);
3290 }
3291
3292 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3293 tcg_temp_free_i32(tcg_rmode);
3294
3295 tcg_temp_free_i32(tcg_shift);
3296
3297 tcg_temp_free_ptr(fpst);
3298
3299 return 0;
3300 }
3301
3302 /* Table for converting the most common AArch32 encoding of
3303 * rounding mode to arm_fprounding order (which matches the
3304 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3305 */
3306 static const uint8_t fp_decode_rm[] = {
3307 FPROUNDING_TIEAWAY,
3308 FPROUNDING_TIEEVEN,
3309 FPROUNDING_POSINF,
3310 FPROUNDING_NEGINF,
3311 };
3312
3313 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3314 {
3315 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3316
3317 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3318 return 1;
3319 }
3320
3321 if (dp) {
3322 VFP_DREG_D(rd, insn);
3323 VFP_DREG_N(rn, insn);
3324 VFP_DREG_M(rm, insn);
3325 } else {
3326 rd = VFP_SREG_D(insn);
3327 rn = VFP_SREG_N(insn);
3328 rm = VFP_SREG_M(insn);
3329 }
3330
3331 if ((insn & 0x0f800e50) == 0x0e000a00) {
3332 return handle_vsel(insn, rd, rn, rm, dp);
3333 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3334 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3335 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3336 /* VRINTA, VRINTN, VRINTP, VRINTM */
3337 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3338 return handle_vrint(insn, rd, rm, dp, rounding);
3339 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3340 /* VCVTA, VCVTN, VCVTP, VCVTM */
3341 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3342 return handle_vcvt(insn, rd, rm, dp, rounding);
3343 }
3344 return 1;
3345 }
3346
3347 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3348 (ie. an undefined instruction). */
3349 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3350 {
3351 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3352 int dp, veclen;
3353 TCGv_i32 addr;
3354 TCGv_i32 tmp;
3355 TCGv_i32 tmp2;
3356
3357 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3358 return 1;
3359 }
3360
3361 /* FIXME: this access check should not take precedence over UNDEF
3362 * for invalid encodings; we will generate incorrect syndrome information
3363 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3364 */
3365 if (s->fp_excp_el) {
3366 gen_exception_insn(s, 4, EXCP_UDEF,
3367 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3368 return 0;
3369 }
3370
3371 if (!s->vfp_enabled) {
3372 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3373 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3374 return 1;
3375 rn = (insn >> 16) & 0xf;
3376 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3377 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3378 return 1;
3379 }
3380 }
3381
3382 if (extract32(insn, 28, 4) == 0xf) {
3383 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3384 * only used in v8 and above.
3385 */
3386 return disas_vfp_v8_insn(s, insn);
3387 }
3388
3389 dp = ((insn & 0xf00) == 0xb00);
3390 switch ((insn >> 24) & 0xf) {
3391 case 0xe:
3392 if (insn & (1 << 4)) {
3393 /* single register transfer */
3394 rd = (insn >> 12) & 0xf;
3395 if (dp) {
3396 int size;
3397 int pass;
3398
3399 VFP_DREG_N(rn, insn);
3400 if (insn & 0xf)
3401 return 1;
3402 if (insn & 0x00c00060
3403 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3404 return 1;
3405 }
3406
3407 pass = (insn >> 21) & 1;
3408 if (insn & (1 << 22)) {
3409 size = 0;
3410 offset = ((insn >> 5) & 3) * 8;
3411 } else if (insn & (1 << 5)) {
3412 size = 1;
3413 offset = (insn & (1 << 6)) ? 16 : 0;
3414 } else {
3415 size = 2;
3416 offset = 0;
3417 }
3418 if (insn & ARM_CP_RW_BIT) {
3419 /* vfp->arm */
3420 tmp = neon_load_reg(rn, pass);
3421 switch (size) {
3422 case 0:
3423 if (offset)
3424 tcg_gen_shri_i32(tmp, tmp, offset);
3425 if (insn & (1 << 23))
3426 gen_uxtb(tmp);
3427 else
3428 gen_sxtb(tmp);
3429 break;
3430 case 1:
3431 if (insn & (1 << 23)) {
3432 if (offset) {
3433 tcg_gen_shri_i32(tmp, tmp, 16);
3434 } else {
3435 gen_uxth(tmp);
3436 }
3437 } else {
3438 if (offset) {
3439 tcg_gen_sari_i32(tmp, tmp, 16);
3440 } else {
3441 gen_sxth(tmp);
3442 }
3443 }
3444 break;
3445 case 2:
3446 break;
3447 }
3448 store_reg(s, rd, tmp);
3449 } else {
3450 /* arm->vfp */
3451 tmp = load_reg(s, rd);
3452 if (insn & (1 << 23)) {
3453 /* VDUP */
3454 int vec_size = pass ? 16 : 8;
3455 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3456 vec_size, vec_size, tmp);
3457 tcg_temp_free_i32(tmp);
3458 } else {
3459 /* VMOV */
3460 switch (size) {
3461 case 0:
3462 tmp2 = neon_load_reg(rn, pass);
3463 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3464 tcg_temp_free_i32(tmp2);
3465 break;
3466 case 1:
3467 tmp2 = neon_load_reg(rn, pass);
3468 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3469 tcg_temp_free_i32(tmp2);
3470 break;
3471 case 2:
3472 break;
3473 }
3474 neon_store_reg(rn, pass, tmp);
3475 }
3476 }
3477 } else { /* !dp */
3478 if ((insn & 0x6f) != 0x00)
3479 return 1;
3480 rn = VFP_SREG_N(insn);
3481 if (insn & ARM_CP_RW_BIT) {
3482 /* vfp->arm */
3483 if (insn & (1 << 21)) {
3484 /* system register */
3485 rn >>= 1;
3486
3487 switch (rn) {
3488 case ARM_VFP_FPSID:
3489 /* VFP2 allows access to FSID from userspace.
3490 VFP3 restricts all id registers to privileged
3491 accesses. */
3492 if (IS_USER(s)
3493 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3494 return 1;
3495 }
3496 tmp = load_cpu_field(vfp.xregs[rn]);
3497 break;
3498 case ARM_VFP_FPEXC:
3499 if (IS_USER(s))
3500 return 1;
3501 tmp = load_cpu_field(vfp.xregs[rn]);
3502 break;
3503 case ARM_VFP_FPINST:
3504 case ARM_VFP_FPINST2:
3505 /* Not present in VFP3. */
3506 if (IS_USER(s)
3507 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3508 return 1;
3509 }
3510 tmp = load_cpu_field(vfp.xregs[rn]);
3511 break;
3512 case ARM_VFP_FPSCR:
3513 if (rd == 15) {
3514 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3515 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3516 } else {
3517 tmp = tcg_temp_new_i32();
3518 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3519 }
3520 break;
3521 case ARM_VFP_MVFR2:
3522 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3523 return 1;
3524 }
3525 /* fall through */
3526 case ARM_VFP_MVFR0:
3527 case ARM_VFP_MVFR1:
3528 if (IS_USER(s)
3529 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3530 return 1;
3531 }
3532 tmp = load_cpu_field(vfp.xregs[rn]);
3533 break;
3534 default:
3535 return 1;
3536 }
3537 } else {
3538 gen_mov_F0_vreg(0, rn);
3539 tmp = gen_vfp_mrs();
3540 }
3541 if (rd == 15) {
3542 /* Set the 4 flag bits in the CPSR. */
3543 gen_set_nzcv(tmp);
3544 tcg_temp_free_i32(tmp);
3545 } else {
3546 store_reg(s, rd, tmp);
3547 }
3548 } else {
3549 /* arm->vfp */
3550 if (insn & (1 << 21)) {
3551 rn >>= 1;
3552 /* system register */
3553 switch (rn) {
3554 case ARM_VFP_FPSID:
3555 case ARM_VFP_MVFR0:
3556 case ARM_VFP_MVFR1:
3557 /* Writes are ignored. */
3558 break;
3559 case ARM_VFP_FPSCR:
3560 tmp = load_reg(s, rd);
3561 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3562 tcg_temp_free_i32(tmp);
3563 gen_lookup_tb(s);
3564 break;
3565 case ARM_VFP_FPEXC:
3566 if (IS_USER(s))
3567 return 1;
3568 /* TODO: VFP subarchitecture support.
3569 * For now, keep the EN bit only */
3570 tmp = load_reg(s, rd);
3571 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3572 store_cpu_field(tmp, vfp.xregs[rn]);
3573 gen_lookup_tb(s);
3574 break;
3575 case ARM_VFP_FPINST:
3576 case ARM_VFP_FPINST2:
3577 if (IS_USER(s)) {
3578 return 1;
3579 }
3580 tmp = load_reg(s, rd);
3581 store_cpu_field(tmp, vfp.xregs[rn]);
3582 break;
3583 default:
3584 return 1;
3585 }
3586 } else {
3587 tmp = load_reg(s, rd);
3588 gen_vfp_msr(tmp);
3589 gen_mov_vreg_F0(0, rn);
3590 }
3591 }
3592 }
3593 } else {
3594 /* data processing */
3595 /* The opcode is in bits 23, 21, 20 and 6. */
3596 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3597 if (dp) {
3598 if (op == 15) {
3599 /* rn is opcode */
3600 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3601 } else {
3602 /* rn is register number */
3603 VFP_DREG_N(rn, insn);
3604 }
3605
3606 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3607 ((rn & 0x1e) == 0x6))) {
3608 /* Integer or single/half precision destination. */
3609 rd = VFP_SREG_D(insn);
3610 } else {
3611 VFP_DREG_D(rd, insn);
3612 }
3613 if (op == 15 &&
3614 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3615 ((rn & 0x1e) == 0x4))) {
3616 /* VCVT from int or half precision is always from S reg
3617 * regardless of dp bit. VCVT with immediate frac_bits
3618 * has same format as SREG_M.
3619 */
3620 rm = VFP_SREG_M(insn);
3621 } else {
3622 VFP_DREG_M(rm, insn);
3623 }
3624 } else {
3625 rn = VFP_SREG_N(insn);
3626 if (op == 15 && rn == 15) {
3627 /* Double precision destination. */
3628 VFP_DREG_D(rd, insn);
3629 } else {
3630 rd = VFP_SREG_D(insn);
3631 }
3632 /* NB that we implicitly rely on the encoding for the frac_bits
3633 * in VCVT of fixed to float being the same as that of an SREG_M
3634 */
3635 rm = VFP_SREG_M(insn);
3636 }
3637
3638 veclen = s->vec_len;
3639 if (op == 15 && rn > 3)
3640 veclen = 0;
3641
3642 /* Shut up compiler warnings. */
3643 delta_m = 0;
3644 delta_d = 0;
3645 bank_mask = 0;
3646
3647 if (veclen > 0) {
3648 if (dp)
3649 bank_mask = 0xc;
3650 else
3651 bank_mask = 0x18;
3652
3653 /* Figure out what type of vector operation this is. */
3654 if ((rd & bank_mask) == 0) {
3655 /* scalar */
3656 veclen = 0;
3657 } else {
3658 if (dp)
3659 delta_d = (s->vec_stride >> 1) + 1;
3660 else
3661 delta_d = s->vec_stride + 1;
3662
3663 if ((rm & bank_mask) == 0) {
3664 /* mixed scalar/vector */
3665 delta_m = 0;
3666 } else {
3667 /* vector */
3668 delta_m = delta_d;
3669 }
3670 }
3671 }
3672
3673 /* Load the initial operands. */
3674 if (op == 15) {
3675 switch (rn) {
3676 case 16:
3677 case 17:
3678 /* Integer source */
3679 gen_mov_F0_vreg(0, rm);
3680 break;
3681 case 8:
3682 case 9:
3683 /* Compare */
3684 gen_mov_F0_vreg(dp, rd);
3685 gen_mov_F1_vreg(dp, rm);
3686 break;
3687 case 10:
3688 case 11:
3689 /* Compare with zero */
3690 gen_mov_F0_vreg(dp, rd);
3691 gen_vfp_F1_ld0(dp);
3692 break;
3693 case 20:
3694 case 21:
3695 case 22:
3696 case 23:
3697 case 28:
3698 case 29:
3699 case 30:
3700 case 31:
3701 /* Source and destination the same. */
3702 gen_mov_F0_vreg(dp, rd);
3703 break;
3704 case 4:
3705 case 5:
3706 case 6:
3707 case 7:
3708 /* VCVTB, VCVTT: only present with the halfprec extension
3709 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3710 * (we choose to UNDEF)
3711 */
3712 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3713 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3714 return 1;
3715 }
3716 if (!extract32(rn, 1, 1)) {
3717 /* Half precision source. */
3718 gen_mov_F0_vreg(0, rm);
3719 break;
3720 }
3721 /* Otherwise fall through */
3722 default:
3723 /* One source operand. */
3724 gen_mov_F0_vreg(dp, rm);
3725 break;
3726 }
3727 } else {
3728 /* Two source operands. */
3729 gen_mov_F0_vreg(dp, rn);
3730 gen_mov_F1_vreg(dp, rm);
3731 }
3732
3733 for (;;) {
3734 /* Perform the calculation. */
3735 switch (op) {
3736 case 0: /* VMLA: fd + (fn * fm) */
3737 /* Note that order of inputs to the add matters for NaNs */
3738 gen_vfp_F1_mul(dp);
3739 gen_mov_F0_vreg(dp, rd);
3740 gen_vfp_add(dp);
3741 break;
3742 case 1: /* VMLS: fd + -(fn * fm) */
3743 gen_vfp_mul(dp);
3744 gen_vfp_F1_neg(dp);
3745 gen_mov_F0_vreg(dp, rd);
3746 gen_vfp_add(dp);
3747 break;
3748 case 2: /* VNMLS: -fd + (fn * fm) */
3749 /* Note that it isn't valid to replace (-A + B) with (B - A)
3750 * or similar plausible looking simplifications
3751 * because this will give wrong results for NaNs.
3752 */
3753 gen_vfp_F1_mul(dp);
3754 gen_mov_F0_vreg(dp, rd);
3755 gen_vfp_neg(dp);
3756 gen_vfp_add(dp);
3757 break;
3758 case 3: /* VNMLA: -fd + -(fn * fm) */
3759 gen_vfp_mul(dp);
3760 gen_vfp_F1_neg(dp);
3761 gen_mov_F0_vreg(dp, rd);
3762 gen_vfp_neg(dp);
3763 gen_vfp_add(dp);
3764 break;
3765 case 4: /* mul: fn * fm */
3766 gen_vfp_mul(dp);
3767 break;
3768 case 5: /* nmul: -(fn * fm) */
3769 gen_vfp_mul(dp);
3770 gen_vfp_neg(dp);
3771 break;
3772 case 6: /* add: fn + fm */
3773 gen_vfp_add(dp);
3774 break;
3775 case 7: /* sub: fn - fm */
3776 gen_vfp_sub(dp);
3777 break;
3778 case 8: /* div: fn / fm */
3779 gen_vfp_div(dp);
3780 break;
3781 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3782 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3783 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3784 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3785 /* These are fused multiply-add, and must be done as one
3786 * floating point operation with no rounding between the
3787 * multiplication and addition steps.
3788 * NB that doing the negations here as separate steps is
3789 * correct : an input NaN should come out with its sign bit
3790 * flipped if it is a negated-input.
3791 */
3792 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3793 return 1;
3794 }
3795 if (dp) {
3796 TCGv_ptr fpst;
3797 TCGv_i64 frd;
3798 if (op & 1) {
3799 /* VFNMS, VFMS */
3800 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3801 }
3802 frd = tcg_temp_new_i64();
3803 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3804 if (op & 2) {
3805 /* VFNMA, VFNMS */
3806 gen_helper_vfp_negd(frd, frd);
3807 }
3808 fpst = get_fpstatus_ptr(0);
3809 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3810 cpu_F1d, frd, fpst);
3811 tcg_temp_free_ptr(fpst);
3812 tcg_temp_free_i64(frd);
3813 } else {
3814 TCGv_ptr fpst;
3815 TCGv_i32 frd;
3816 if (op & 1) {
3817 /* VFNMS, VFMS */
3818 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3819 }
3820 frd = tcg_temp_new_i32();
3821 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3822 if (op & 2) {
3823 gen_helper_vfp_negs(frd, frd);
3824 }
3825 fpst = get_fpstatus_ptr(0);
3826 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3827 cpu_F1s, frd, fpst);
3828 tcg_temp_free_ptr(fpst);
3829 tcg_temp_free_i32(frd);
3830 }
3831 break;
3832 case 14: /* fconst */
3833 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3834 return 1;
3835 }
3836
3837 n = (insn << 12) & 0x80000000;
3838 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3839 if (dp) {
3840 if (i & 0x40)
3841 i |= 0x3f80;
3842 else
3843 i |= 0x4000;
3844 n |= i << 16;
3845 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3846 } else {
3847 if (i & 0x40)
3848 i |= 0x780;
3849 else
3850 i |= 0x800;
3851 n |= i << 19;
3852 tcg_gen_movi_i32(cpu_F0s, n);
3853 }
3854 break;
3855 case 15: /* extension space */
3856 switch (rn) {
3857 case 0: /* cpy */
3858 /* no-op */
3859 break;
3860 case 1: /* abs */
3861 gen_vfp_abs(dp);
3862 break;
3863 case 2: /* neg */
3864 gen_vfp_neg(dp);
3865 break;
3866 case 3: /* sqrt */
3867 gen_vfp_sqrt(dp);
3868 break;
3869 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3870 {
3871 TCGv_ptr fpst = get_fpstatus_ptr(false);
3872 TCGv_i32 ahp_mode = get_ahp_flag();
3873 tmp = gen_vfp_mrs();
3874 tcg_gen_ext16u_i32(tmp, tmp);
3875 if (dp) {
3876 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3877 fpst, ahp_mode);
3878 } else {
3879 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3880 fpst, ahp_mode);
3881 }
3882 tcg_temp_free_i32(ahp_mode);
3883 tcg_temp_free_ptr(fpst);
3884 tcg_temp_free_i32(tmp);
3885 break;
3886 }
3887 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3888 {
3889 TCGv_ptr fpst = get_fpstatus_ptr(false);
3890 TCGv_i32 ahp = get_ahp_flag();
3891 tmp = gen_vfp_mrs();
3892 tcg_gen_shri_i32(tmp, tmp, 16);
3893 if (dp) {
3894 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3895 fpst, ahp);
3896 } else {
3897 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3898 fpst, ahp);
3899 }
3900 tcg_temp_free_i32(tmp);
3901 tcg_temp_free_i32(ahp);
3902 tcg_temp_free_ptr(fpst);
3903 break;
3904 }
3905 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3906 {
3907 TCGv_ptr fpst = get_fpstatus_ptr(false);
3908 TCGv_i32 ahp = get_ahp_flag();
3909 tmp = tcg_temp_new_i32();
3910
3911 if (dp) {
3912 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3913 fpst, ahp);
3914 } else {
3915 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3916 fpst, ahp);
3917 }
3918 tcg_temp_free_i32(ahp);
3919 tcg_temp_free_ptr(fpst);
3920 gen_mov_F0_vreg(0, rd);
3921 tmp2 = gen_vfp_mrs();
3922 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3923 tcg_gen_or_i32(tmp, tmp, tmp2);
3924 tcg_temp_free_i32(tmp2);
3925 gen_vfp_msr(tmp);
3926 break;
3927 }
3928 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3929 {
3930 TCGv_ptr fpst = get_fpstatus_ptr(false);
3931 TCGv_i32 ahp = get_ahp_flag();
3932 tmp = tcg_temp_new_i32();
3933 if (dp) {
3934 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3935 fpst, ahp);
3936 } else {
3937 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3938 fpst, ahp);
3939 }
3940 tcg_temp_free_i32(ahp);
3941 tcg_temp_free_ptr(fpst);
3942 tcg_gen_shli_i32(tmp, tmp, 16);
3943 gen_mov_F0_vreg(0, rd);
3944 tmp2 = gen_vfp_mrs();
3945 tcg_gen_ext16u_i32(tmp2, tmp2);
3946 tcg_gen_or_i32(tmp, tmp, tmp2);
3947 tcg_temp_free_i32(tmp2);
3948 gen_vfp_msr(tmp);
3949 break;
3950 }
3951 case 8: /* cmp */
3952 gen_vfp_cmp(dp);
3953 break;
3954 case 9: /* cmpe */
3955 gen_vfp_cmpe(dp);
3956 break;
3957 case 10: /* cmpz */
3958 gen_vfp_cmp(dp);
3959 break;
3960 case 11: /* cmpez */
3961 gen_vfp_F1_ld0(dp);
3962 gen_vfp_cmpe(dp);
3963 break;
3964 case 12: /* vrintr */
3965 {
3966 TCGv_ptr fpst = get_fpstatus_ptr(0);
3967 if (dp) {
3968 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3969 } else {
3970 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3971 }
3972 tcg_temp_free_ptr(fpst);
3973 break;
3974 }
3975 case 13: /* vrintz */
3976 {
3977 TCGv_ptr fpst = get_fpstatus_ptr(0);
3978 TCGv_i32 tcg_rmode;
3979 tcg_rmode = tcg_const_i32(float_round_to_zero);
3980 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3981 if (dp) {
3982 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3983 } else {
3984 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3985 }
3986 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3987 tcg_temp_free_i32(tcg_rmode);
3988 tcg_temp_free_ptr(fpst);
3989 break;
3990 }
3991 case 14: /* vrintx */
3992 {
3993 TCGv_ptr fpst = get_fpstatus_ptr(0);
3994 if (dp) {
3995 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3996 } else {
3997 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3998 }
3999 tcg_temp_free_ptr(fpst);
4000 break;
4001 }
4002 case 15: /* single<->double conversion */
4003 if (dp)
4004 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
4005 else
4006 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
4007 break;
4008 case 16: /* fuito */
4009 gen_vfp_uito(dp, 0);
4010 break;
4011 case 17: /* fsito */
4012 gen_vfp_sito(dp, 0);
4013 break;
4014 case 20: /* fshto */
4015 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4016 return 1;
4017 }
4018 gen_vfp_shto(dp, 16 - rm, 0);
4019 break;
4020 case 21: /* fslto */
4021 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4022 return 1;
4023 }
4024 gen_vfp_slto(dp, 32 - rm, 0);
4025 break;
4026 case 22: /* fuhto */
4027 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4028 return 1;
4029 }
4030 gen_vfp_uhto(dp, 16 - rm, 0);
4031 break;
4032 case 23: /* fulto */
4033 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4034 return 1;
4035 }
4036 gen_vfp_ulto(dp, 32 - rm, 0);
4037 break;
4038 case 24: /* ftoui */
4039 gen_vfp_toui(dp, 0);
4040 break;
4041 case 25: /* ftouiz */
4042 gen_vfp_touiz(dp, 0);
4043 break;
4044 case 26: /* ftosi */
4045 gen_vfp_tosi(dp, 0);
4046 break;
4047 case 27: /* ftosiz */
4048 gen_vfp_tosiz(dp, 0);
4049 break;
4050 case 28: /* ftosh */
4051 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4052 return 1;
4053 }
4054 gen_vfp_tosh(dp, 16 - rm, 0);
4055 break;
4056 case 29: /* ftosl */
4057 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4058 return 1;
4059 }
4060 gen_vfp_tosl(dp, 32 - rm, 0);
4061 break;
4062 case 30: /* ftouh */
4063 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4064 return 1;
4065 }
4066 gen_vfp_touh(dp, 16 - rm, 0);
4067 break;
4068 case 31: /* ftoul */
4069 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4070 return 1;
4071 }
4072 gen_vfp_toul(dp, 32 - rm, 0);
4073 break;
4074 default: /* undefined */
4075 return 1;
4076 }
4077 break;
4078 default: /* undefined */
4079 return 1;
4080 }
4081
4082 /* Write back the result. */
4083 if (op == 15 && (rn >= 8 && rn <= 11)) {
4084 /* Comparison, do nothing. */
4085 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4086 (rn & 0x1e) == 0x6)) {
4087 /* VCVT double to int: always integer result.
4088 * VCVT double to half precision is always a single
4089 * precision result.
4090 */
4091 gen_mov_vreg_F0(0, rd);
4092 } else if (op == 15 && rn == 15) {
4093 /* conversion */
4094 gen_mov_vreg_F0(!dp, rd);
4095 } else {
4096 gen_mov_vreg_F0(dp, rd);
4097 }
4098
4099 /* break out of the loop if we have finished */
4100 if (veclen == 0)
4101 break;
4102
4103 if (op == 15 && delta_m == 0) {
4104 /* single source one-many */
4105 while (veclen--) {
4106 rd = ((rd + delta_d) & (bank_mask - 1))
4107 | (rd & bank_mask);
4108 gen_mov_vreg_F0(dp, rd);
4109 }
4110 break;
4111 }
4112 /* Setup the next operands. */
4113 veclen--;
4114 rd = ((rd + delta_d) & (bank_mask - 1))
4115 | (rd & bank_mask);
4116
4117 if (op == 15) {
4118 /* One source operand. */
4119 rm = ((rm + delta_m) & (bank_mask - 1))
4120 | (rm & bank_mask);
4121 gen_mov_F0_vreg(dp, rm);
4122 } else {
4123 /* Two source operands. */
4124 rn = ((rn + delta_d) & (bank_mask - 1))
4125 | (rn & bank_mask);
4126 gen_mov_F0_vreg(dp, rn);
4127 if (delta_m) {
4128 rm = ((rm + delta_m) & (bank_mask - 1))
4129 | (rm & bank_mask);
4130 gen_mov_F1_vreg(dp, rm);
4131 }
4132 }
4133 }
4134 }
4135 break;
4136 case 0xc:
4137 case 0xd:
4138 if ((insn & 0x03e00000) == 0x00400000) {
4139 /* two-register transfer */
4140 rn = (insn >> 16) & 0xf;
4141 rd = (insn >> 12) & 0xf;
4142 if (dp) {
4143 VFP_DREG_M(rm, insn);
4144 } else {
4145 rm = VFP_SREG_M(insn);
4146 }
4147
4148 if (insn & ARM_CP_RW_BIT) {
4149 /* vfp->arm */
4150 if (dp) {
4151 gen_mov_F0_vreg(0, rm * 2);
4152 tmp = gen_vfp_mrs();
4153 store_reg(s, rd, tmp);
4154 gen_mov_F0_vreg(0, rm * 2 + 1);
4155 tmp = gen_vfp_mrs();
4156 store_reg(s, rn, tmp);
4157 } else {
4158 gen_mov_F0_vreg(0, rm);
4159 tmp = gen_vfp_mrs();
4160 store_reg(s, rd, tmp);
4161 gen_mov_F0_vreg(0, rm + 1);
4162 tmp = gen_vfp_mrs();
4163 store_reg(s, rn, tmp);
4164 }
4165 } else {
4166 /* arm->vfp */
4167 if (dp) {
4168 tmp = load_reg(s, rd);
4169 gen_vfp_msr(tmp);
4170 gen_mov_vreg_F0(0, rm * 2);
4171 tmp = load_reg(s, rn);
4172 gen_vfp_msr(tmp);
4173 gen_mov_vreg_F0(0, rm * 2 + 1);
4174 } else {
4175 tmp = load_reg(s, rd);
4176 gen_vfp_msr(tmp);
4177 gen_mov_vreg_F0(0, rm);
4178 tmp = load_reg(s, rn);
4179 gen_vfp_msr(tmp);
4180 gen_mov_vreg_F0(0, rm + 1);
4181 }
4182 }
4183 } else {
4184 /* Load/store */
4185 rn = (insn >> 16) & 0xf;
4186 if (dp)
4187 VFP_DREG_D(rd, insn);
4188 else
4189 rd = VFP_SREG_D(insn);
4190 if ((insn & 0x01200000) == 0x01000000) {
4191 /* Single load/store */
4192 offset = (insn & 0xff) << 2;
4193 if ((insn & (1 << 23)) == 0)
4194 offset = -offset;
4195 if (s->thumb && rn == 15) {
4196 /* This is actually UNPREDICTABLE */
4197 addr = tcg_temp_new_i32();
4198 tcg_gen_movi_i32(addr, s->pc & ~2);
4199 } else {
4200 addr = load_reg(s, rn);
4201 }
4202 tcg_gen_addi_i32(addr, addr, offset);
4203 if (insn & (1 << 20)) {
4204 gen_vfp_ld(s, dp, addr);
4205 gen_mov_vreg_F0(dp, rd);
4206 } else {
4207 gen_mov_F0_vreg(dp, rd);
4208 gen_vfp_st(s, dp, addr);
4209 }
4210 tcg_temp_free_i32(addr);
4211 } else {
4212 /* load/store multiple */
4213 int w = insn & (1 << 21);
4214 if (dp)
4215 n = (insn >> 1) & 0x7f;
4216 else
4217 n = insn & 0xff;
4218
4219 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4220 /* P == U , W == 1 => UNDEF */
4221 return 1;
4222 }
4223 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4224 /* UNPREDICTABLE cases for bad immediates: we choose to
4225 * UNDEF to avoid generating huge numbers of TCG ops
4226 */
4227 return 1;
4228 }
4229 if (rn == 15 && w) {
4230 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4231 return 1;
4232 }
4233
4234 if (s->thumb && rn == 15) {
4235 /* This is actually UNPREDICTABLE */
4236 addr = tcg_temp_new_i32();
4237 tcg_gen_movi_i32(addr, s->pc & ~2);
4238 } else {
4239 addr = load_reg(s, rn);
4240 }
4241 if (insn & (1 << 24)) /* pre-decrement */
4242 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4243
4244 if (s->v8m_stackcheck && rn == 13 && w) {
4245 /*
4246 * Here 'addr' is the lowest address we will store to,
4247 * and is either the old SP (if post-increment) or
4248 * the new SP (if pre-decrement). For post-increment
4249 * where the old value is below the limit and the new
4250 * value is above, it is UNKNOWN whether the limit check
4251 * triggers; we choose to trigger.
4252 */
4253 gen_helper_v8m_stackcheck(cpu_env, addr);
4254 }
4255
4256 if (dp)
4257 offset = 8;
4258 else
4259 offset = 4;
4260 for (i = 0; i < n; i++) {
4261 if (insn & ARM_CP_RW_BIT) {
4262 /* load */
4263 gen_vfp_ld(s, dp, addr);
4264 gen_mov_vreg_F0(dp, rd + i);
4265 } else {
4266 /* store */
4267 gen_mov_F0_vreg(dp, rd + i);
4268 gen_vfp_st(s, dp, addr);
4269 }
4270 tcg_gen_addi_i32(addr, addr, offset);
4271 }
4272 if (w) {
4273 /* writeback */
4274 if (insn & (1 << 24))
4275 offset = -offset * n;
4276 else if (dp && (insn & 1))
4277 offset = 4;
4278 else
4279 offset = 0;
4280
4281 if (offset != 0)
4282 tcg_gen_addi_i32(addr, addr, offset);
4283 store_reg(s, rn, addr);
4284 } else {
4285 tcg_temp_free_i32(addr);
4286 }
4287 }
4288 }
4289 break;
4290 default:
4291 /* Should never happen. */
4292 return 1;
4293 }
4294 return 0;
4295 }
4296
4297 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4298 {
4299 #ifndef CONFIG_USER_ONLY
4300 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4301 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4302 #else
4303 return true;
4304 #endif
4305 }
4306
4307 static void gen_goto_ptr(void)
4308 {
4309 tcg_gen_lookup_and_goto_ptr();
4310 }
4311
4312 /* This will end the TB but doesn't guarantee we'll return to
4313 * cpu_loop_exec. Any live exit_requests will be processed as we
4314 * enter the next TB.
4315 */
4316 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4317 {
4318 if (use_goto_tb(s, dest)) {
4319 tcg_gen_goto_tb(n);
4320 gen_set_pc_im(s, dest);
4321 tcg_gen_exit_tb(s->base.tb, n);
4322 } else {
4323 gen_set_pc_im(s, dest);
4324 gen_goto_ptr();
4325 }
4326 s->base.is_jmp = DISAS_NORETURN;
4327 }
4328
4329 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4330 {
4331 if (unlikely(is_singlestepping(s))) {
4332 /* An indirect jump so that we still trigger the debug exception. */
4333 if (s->thumb)
4334 dest |= 1;
4335 gen_bx_im(s, dest);
4336 } else {
4337 gen_goto_tb(s, 0, dest);
4338 }
4339 }
4340
4341 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4342 {
4343 if (x)
4344 tcg_gen_sari_i32(t0, t0, 16);
4345 else
4346 gen_sxth(t0);
4347 if (y)
4348 tcg_gen_sari_i32(t1, t1, 16);
4349 else
4350 gen_sxth(t1);
4351 tcg_gen_mul_i32(t0, t0, t1);
4352 }
4353
4354 /* Return the mask of PSR bits set by a MSR instruction. */
4355 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4356 {
4357 uint32_t mask;
4358
4359 mask = 0;
4360 if (flags & (1 << 0))
4361 mask |= 0xff;
4362 if (flags & (1 << 1))
4363 mask |= 0xff00;
4364 if (flags & (1 << 2))
4365 mask |= 0xff0000;
4366 if (flags & (1 << 3))
4367 mask |= 0xff000000;
4368
4369 /* Mask out undefined bits. */
4370 mask &= ~CPSR_RESERVED;
4371 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4372 mask &= ~CPSR_T;
4373 }
4374 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4375 mask &= ~CPSR_Q; /* V5TE in reality*/
4376 }
4377 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4378 mask &= ~(CPSR_E | CPSR_GE);
4379 }
4380 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4381 mask &= ~CPSR_IT;
4382 }
4383 /* Mask out execution state and reserved bits. */
4384 if (!spsr) {
4385 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4386 }
4387 /* Mask out privileged bits. */
4388 if (IS_USER(s))
4389 mask &= CPSR_USER;
4390 return mask;
4391 }
4392
4393 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4394 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4395 {
4396 TCGv_i32 tmp;
4397 if (spsr) {
4398 /* ??? This is also undefined in system mode. */
4399 if (IS_USER(s))
4400 return 1;
4401
4402 tmp = load_cpu_field(spsr);
4403 tcg_gen_andi_i32(tmp, tmp, ~mask);
4404 tcg_gen_andi_i32(t0, t0, mask);
4405 tcg_gen_or_i32(tmp, tmp, t0);
4406 store_cpu_field(tmp, spsr);
4407 } else {
4408 gen_set_cpsr(t0, mask);
4409 }
4410 tcg_temp_free_i32(t0);
4411 gen_lookup_tb(s);
4412 return 0;
4413 }
4414
4415 /* Returns nonzero if access to the PSR is not permitted. */
4416 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4417 {
4418 TCGv_i32 tmp;
4419 tmp = tcg_temp_new_i32();
4420 tcg_gen_movi_i32(tmp, val);
4421 return gen_set_psr(s, mask, spsr, tmp);
4422 }
4423
4424 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4425 int *tgtmode, int *regno)
4426 {
4427 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4428 * the target mode and register number, and identify the various
4429 * unpredictable cases.
4430 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4431 * + executed in user mode
4432 * + using R15 as the src/dest register
4433 * + accessing an unimplemented register
4434 * + accessing a register that's inaccessible at current PL/security state*
4435 * + accessing a register that you could access with a different insn
4436 * We choose to UNDEF in all these cases.
4437 * Since we don't know which of the various AArch32 modes we are in
4438 * we have to defer some checks to runtime.
4439 * Accesses to Monitor mode registers from Secure EL1 (which implies
4440 * that EL3 is AArch64) must trap to EL3.
4441 *
4442 * If the access checks fail this function will emit code to take
4443 * an exception and return false. Otherwise it will return true,
4444 * and set *tgtmode and *regno appropriately.
4445 */
4446 int exc_target = default_exception_el(s);
4447
4448 /* These instructions are present only in ARMv8, or in ARMv7 with the
4449 * Virtualization Extensions.
4450 */
4451 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4452 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4453 goto undef;
4454 }
4455
4456 if (IS_USER(s) || rn == 15) {
4457 goto undef;
4458 }
4459
4460 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4461 * of registers into (r, sysm).
4462 */
4463 if (r) {
4464 /* SPSRs for other modes */
4465 switch (sysm) {
4466 case 0xe: /* SPSR_fiq */
4467 *tgtmode = ARM_CPU_MODE_FIQ;
4468 break;
4469 case 0x10: /* SPSR_irq */
4470 *tgtmode = ARM_CPU_MODE_IRQ;
4471 break;
4472 case 0x12: /* SPSR_svc */
4473 *tgtmode = ARM_CPU_MODE_SVC;
4474 break;
4475 case 0x14: /* SPSR_abt */
4476 *tgtmode = ARM_CPU_MODE_ABT;
4477 break;
4478 case 0x16: /* SPSR_und */
4479 *tgtmode = ARM_CPU_MODE_UND;
4480 break;
4481 case 0x1c: /* SPSR_mon */
4482 *tgtmode = ARM_CPU_MODE_MON;
4483 break;
4484 case 0x1e: /* SPSR_hyp */
4485 *tgtmode = ARM_CPU_MODE_HYP;
4486 break;
4487 default: /* unallocated */
4488 goto undef;
4489 }
4490 /* We arbitrarily assign SPSR a register number of 16. */
4491 *regno = 16;
4492 } else {
4493 /* general purpose registers for other modes */
4494 switch (sysm) {
4495 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4496 *tgtmode = ARM_CPU_MODE_USR;
4497 *regno = sysm + 8;
4498 break;
4499 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4500 *tgtmode = ARM_CPU_MODE_FIQ;
4501 *regno = sysm;
4502 break;
4503 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4504 *tgtmode = ARM_CPU_MODE_IRQ;
4505 *regno = sysm & 1 ? 13 : 14;
4506 break;
4507 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4508 *tgtmode = ARM_CPU_MODE_SVC;
4509 *regno = sysm & 1 ? 13 : 14;
4510 break;
4511 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4512 *tgtmode = ARM_CPU_MODE_ABT;
4513 *regno = sysm & 1 ? 13 : 14;
4514 break;
4515 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4516 *tgtmode = ARM_CPU_MODE_UND;
4517 *regno = sysm & 1 ? 13 : 14;
4518 break;
4519 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4520 *tgtmode = ARM_CPU_MODE_MON;
4521 *regno = sysm & 1 ? 13 : 14;
4522 break;
4523 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4524 *tgtmode = ARM_CPU_MODE_HYP;
4525 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4526 *regno = sysm & 1 ? 13 : 17;
4527 break;
4528 default: /* unallocated */
4529 goto undef;
4530 }
4531 }
4532
4533 /* Catch the 'accessing inaccessible register' cases we can detect
4534 * at translate time.
4535 */
4536 switch (*tgtmode) {
4537 case ARM_CPU_MODE_MON:
4538 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4539 goto undef;
4540 }
4541 if (s->current_el == 1) {
4542 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4543 * then accesses to Mon registers trap to EL3
4544 */
4545 exc_target = 3;
4546 goto undef;
4547 }
4548 break;
4549 case ARM_CPU_MODE_HYP:
4550 /*
4551 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4552 * (and so we can forbid accesses from EL2 or below). elr_hyp
4553 * can be accessed also from Hyp mode, so forbid accesses from
4554 * EL0 or EL1.
4555 */
4556 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4557 (s->current_el < 3 && *regno != 17)) {
4558 goto undef;
4559 }
4560 break;
4561 default:
4562 break;
4563 }
4564
4565 return true;
4566
4567 undef:
4568 /* If we get here then some access check did not pass */
4569 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4570 return false;
4571 }
4572
4573 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4574 {
4575 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4576 int tgtmode = 0, regno = 0;
4577
4578 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4579 return;
4580 }
4581
4582 /* Sync state because msr_banked() can raise exceptions */
4583 gen_set_condexec(s);
4584 gen_set_pc_im(s, s->pc - 4);
4585 tcg_reg = load_reg(s, rn);
4586 tcg_tgtmode = tcg_const_i32(tgtmode);
4587 tcg_regno = tcg_const_i32(regno);
4588 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4589 tcg_temp_free_i32(tcg_tgtmode);
4590 tcg_temp_free_i32(tcg_regno);
4591 tcg_temp_free_i32(tcg_reg);
4592 s->base.is_jmp = DISAS_UPDATE;
4593 }
4594
4595 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4596 {
4597 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4598 int tgtmode = 0, regno = 0;
4599
4600 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4601 return;
4602 }
4603
4604 /* Sync state because mrs_banked() can raise exceptions */
4605 gen_set_condexec(s);
4606 gen_set_pc_im(s, s->pc - 4);
4607 tcg_reg = tcg_temp_new_i32();
4608 tcg_tgtmode = tcg_const_i32(tgtmode);
4609 tcg_regno = tcg_const_i32(regno);
4610 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4611 tcg_temp_free_i32(tcg_tgtmode);
4612 tcg_temp_free_i32(tcg_regno);
4613 store_reg(s, rn, tcg_reg);
4614 s->base.is_jmp = DISAS_UPDATE;
4615 }
4616
4617 /* Store value to PC as for an exception return (ie don't
4618 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4619 * will do the masking based on the new value of the Thumb bit.
4620 */
4621 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4622 {
4623 tcg_gen_mov_i32(cpu_R[15], pc);
4624 tcg_temp_free_i32(pc);
4625 }
4626
4627 /* Generate a v6 exception return. Marks both values as dead. */
4628 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4629 {
4630 store_pc_exc_ret(s, pc);
4631 /* The cpsr_write_eret helper will mask the low bits of PC
4632 * appropriately depending on the new Thumb bit, so it must
4633 * be called after storing the new PC.
4634 */
4635 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4636 gen_io_start();
4637 }
4638 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4639 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4640 gen_io_end();
4641 }
4642 tcg_temp_free_i32(cpsr);
4643 /* Must exit loop to check un-masked IRQs */
4644 s->base.is_jmp = DISAS_EXIT;
4645 }
4646
4647 /* Generate an old-style exception return. Marks pc as dead. */
4648 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4649 {
4650 gen_rfe(s, pc, load_cpu_field(spsr));
4651 }
4652
4653 /*
4654 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4655 * only call the helper when running single threaded TCG code to ensure
4656 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4657 * just skip this instruction. Currently the SEV/SEVL instructions
4658 * which are *one* of many ways to wake the CPU from WFE are not
4659 * implemented so we can't sleep like WFI does.
4660 */
4661 static void gen_nop_hint(DisasContext *s, int val)
4662 {
4663 switch (val) {
4664 /* When running in MTTCG we don't generate jumps to the yield and
4665 * WFE helpers as it won't affect the scheduling of other vCPUs.
4666 * If we wanted to more completely model WFE/SEV so we don't busy
4667 * spin unnecessarily we would need to do something more involved.
4668 */
4669 case 1: /* yield */
4670 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4671 gen_set_pc_im(s, s->pc);
4672 s->base.is_jmp = DISAS_YIELD;
4673 }
4674 break;
4675 case 3: /* wfi */
4676 gen_set_pc_im(s, s->pc);
4677 s->base.is_jmp = DISAS_WFI;
4678 break;
4679 case 2: /* wfe */
4680 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4681 gen_set_pc_im(s, s->pc);
4682 s->base.is_jmp = DISAS_WFE;
4683 }
4684 break;
4685 case 4: /* sev */
4686 case 5: /* sevl */
4687 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4688 default: /* nop */
4689 break;
4690 }
4691 }
4692
4693 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4694
4695 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4696 {
4697 switch (size) {
4698 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4699 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4700 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4701 default: abort();
4702 }
4703 }
4704
4705 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4706 {
4707 switch (size) {
4708 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4709 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4710 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4711 default: return;
4712 }
4713 }
4714
4715 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4716 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4717 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4718 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4719 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4720
4721 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4722 switch ((size << 1) | u) { \
4723 case 0: \
4724 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4725 break; \
4726 case 1: \
4727 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4728 break; \
4729 case 2: \
4730 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4731 break; \
4732 case 3: \
4733 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4734 break; \
4735 case 4: \
4736 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4737 break; \
4738 case 5: \
4739 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4740 break; \
4741 default: return 1; \
4742 }} while (0)
4743
4744 #define GEN_NEON_INTEGER_OP(name) do { \
4745 switch ((size << 1) | u) { \
4746 case 0: \
4747 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4748 break; \
4749 case 1: \
4750 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4751 break; \
4752 case 2: \
4753 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4754 break; \
4755 case 3: \
4756 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4757 break; \
4758 case 4: \
4759 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4760 break; \
4761 case 5: \
4762 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4763 break; \
4764 default: return 1; \
4765 }} while (0)
4766
4767 static TCGv_i32 neon_load_scratch(int scratch)
4768 {
4769 TCGv_i32 tmp = tcg_temp_new_i32();
4770 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4771 return tmp;
4772 }
4773
4774 static void neon_store_scratch(int scratch, TCGv_i32 var)
4775 {
4776 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4777 tcg_temp_free_i32(var);
4778 }
4779
4780 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4781 {
4782 TCGv_i32 tmp;
4783 if (size == 1) {
4784 tmp = neon_load_reg(reg & 7, reg >> 4);
4785 if (reg & 8) {
4786 gen_neon_dup_high16(tmp);
4787 } else {
4788 gen_neon_dup_low16(tmp);
4789 }
4790 } else {
4791 tmp = neon_load_reg(reg & 15, reg >> 4);
4792 }
4793 return tmp;
4794 }
4795
4796 static int gen_neon_unzip(int rd, int rm, int size, int q)
4797 {
4798 TCGv_ptr pd, pm;
4799
4800 if (!q && size == 2) {
4801 return 1;
4802 }
4803 pd = vfp_reg_ptr(true, rd);
4804 pm = vfp_reg_ptr(true, rm);
4805 if (q) {
4806 switch (size) {
4807 case 0:
4808 gen_helper_neon_qunzip8(pd, pm);
4809 break;
4810 case 1:
4811 gen_helper_neon_qunzip16(pd, pm);
4812 break;
4813 case 2:
4814 gen_helper_neon_qunzip32(pd, pm);
4815 break;
4816 default:
4817 abort();
4818 }
4819 } else {
4820 switch (size) {
4821 case 0:
4822 gen_helper_neon_unzip8(pd, pm);
4823 break;
4824 case 1:
4825 gen_helper_neon_unzip16(pd, pm);
4826 break;
4827 default:
4828 abort();
4829 }
4830 }
4831 tcg_temp_free_ptr(pd);
4832 tcg_temp_free_ptr(pm);
4833 return 0;
4834 }
4835
4836 static int gen_neon_zip(int rd, int rm, int size, int q)
4837 {
4838 TCGv_ptr pd, pm;
4839
4840 if (!q && size == 2) {
4841 return 1;
4842 }
4843 pd = vfp_reg_ptr(true, rd);
4844 pm = vfp_reg_ptr(true, rm);
4845 if (q) {
4846 switch (size) {
4847 case 0:
4848 gen_helper_neon_qzip8(pd, pm);
4849 break;
4850 case 1:
4851 gen_helper_neon_qzip16(pd, pm);
4852 break;
4853 case 2:
4854 gen_helper_neon_qzip32(pd, pm);
4855 break;
4856 default:
4857 abort();
4858 }
4859 } else {
4860 switch (size) {
4861 case 0:
4862 gen_helper_neon_zip8(pd, pm);
4863 break;
4864 case 1:
4865 gen_helper_neon_zip16(pd, pm);
4866 break;
4867 default:
4868 abort();
4869 }
4870 }
4871 tcg_temp_free_ptr(pd);
4872 tcg_temp_free_ptr(pm);
4873 return 0;
4874 }
4875
4876 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4877 {
4878 TCGv_i32 rd, tmp;
4879
4880 rd = tcg_temp_new_i32();
4881 tmp = tcg_temp_new_i32();
4882
4883 tcg_gen_shli_i32(rd, t0, 8);
4884 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4885 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4886 tcg_gen_or_i32(rd, rd, tmp);
4887
4888 tcg_gen_shri_i32(t1, t1, 8);
4889 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4890 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4891 tcg_gen_or_i32(t1, t1, tmp);
4892 tcg_gen_mov_i32(t0, rd);
4893
4894 tcg_temp_free_i32(tmp);
4895 tcg_temp_free_i32(rd);
4896 }
4897
4898 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4899 {
4900 TCGv_i32 rd, tmp;
4901
4902 rd = tcg_temp_new_i32();
4903 tmp = tcg_temp_new_i32();
4904
4905 tcg_gen_shli_i32(rd, t0, 16);
4906 tcg_gen_andi_i32(tmp, t1, 0xffff);
4907 tcg_gen_or_i32(rd, rd, tmp);
4908 tcg_gen_shri_i32(t1, t1, 16);
4909 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4910 tcg_gen_or_i32(t1, t1, tmp);
4911 tcg_gen_mov_i32(t0, rd);
4912
4913 tcg_temp_free_i32(tmp);
4914 tcg_temp_free_i32(rd);
4915 }
4916
4917
4918 static struct {
4919 int nregs;
4920 int interleave;
4921 int spacing;
4922 } const neon_ls_element_type[11] = {
4923 {4, 4, 1},
4924 {4, 4, 2},
4925 {4, 1, 1},
4926 {4, 2, 1},
4927 {3, 3, 1},
4928 {3, 3, 2},
4929 {3, 1, 1},
4930 {1, 1, 1},
4931 {2, 2, 1},
4932 {2, 2, 2},
4933 {2, 1, 1}
4934 };
4935
4936 /* Translate a NEON load/store element instruction. Return nonzero if the
4937 instruction is invalid. */
4938 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4939 {
4940 int rd, rn, rm;
4941 int op;
4942 int nregs;
4943 int interleave;
4944 int spacing;
4945 int stride;
4946 int size;
4947 int reg;
4948 int pass;
4949 int load;
4950 int shift;
4951 int n;
4952 TCGv_i32 addr;
4953 TCGv_i32 tmp;
4954 TCGv_i32 tmp2;
4955 TCGv_i64 tmp64;
4956
4957 /* FIXME: this access check should not take precedence over UNDEF
4958 * for invalid encodings; we will generate incorrect syndrome information
4959 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4960 */
4961 if (s->fp_excp_el) {
4962 gen_exception_insn(s, 4, EXCP_UDEF,
4963 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4964 return 0;
4965 }
4966
4967 if (!s->vfp_enabled)
4968 return 1;
4969 VFP_DREG_D(rd, insn);
4970 rn = (insn >> 16) & 0xf;
4971 rm = insn & 0xf;
4972 load = (insn & (1 << 21)) != 0;
4973 if ((insn & (1 << 23)) == 0) {
4974 /* Load store all elements. */
4975 op = (insn >> 8) & 0xf;
4976 size = (insn >> 6) & 3;
4977 if (op > 10)
4978 return 1;
4979 /* Catch UNDEF cases for bad values of align field */
4980 switch (op & 0xc) {
4981 case 4:
4982 if (((insn >> 5) & 1) == 1) {
4983 return 1;
4984 }
4985 break;
4986 case 8:
4987 if (((insn >> 4) & 3) == 3) {
4988 return 1;
4989 }
4990 break;
4991 default:
4992 break;
4993 }
4994 nregs = neon_ls_element_type[op].nregs;
4995 interleave = neon_ls_element_type[op].interleave;
4996 spacing = neon_ls_element_type[op].spacing;
4997 if (size == 3 && (interleave | spacing) != 1)
4998 return 1;
4999 addr = tcg_temp_new_i32();
5000 load_reg_var(s, addr, rn);
5001 stride = (1 << size) * interleave;
5002 for (reg = 0; reg < nregs; reg++) {
5003 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
5004 load_reg_var(s, addr, rn);
5005 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
5006 } else if (interleave == 2 && nregs == 4 && reg == 2) {
5007 load_reg_var(s, addr, rn);
5008 tcg_gen_addi_i32(addr, addr, 1 << size);
5009 }
5010 if (size == 3) {
5011 tmp64 = tcg_temp_new_i64();
5012 if (load) {
5013 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
5014 neon_store_reg64(tmp64, rd);
5015 } else {
5016 neon_load_reg64(tmp64, rd);
5017 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
5018 }
5019 tcg_temp_free_i64(tmp64);
5020 tcg_gen_addi_i32(addr, addr, stride);
5021 } else {
5022 for (pass = 0; pass < 2; pass++) {
5023 if (size == 2) {
5024 if (load) {
5025 tmp = tcg_temp_new_i32();
5026 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5027 neon_store_reg(rd, pass, tmp);
5028 } else {
5029 tmp = neon_load_reg(rd, pass);
5030 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5031 tcg_temp_free_i32(tmp);
5032 }
5033 tcg_gen_addi_i32(addr, addr, stride);
5034 } else if (size == 1) {
5035 if (load) {
5036 tmp = tcg_temp_new_i32();
5037 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5038 tcg_gen_addi_i32(addr, addr, stride);
5039 tmp2 = tcg_temp_new_i32();
5040 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
5041 tcg_gen_addi_i32(addr, addr, stride);
5042 tcg_gen_shli_i32(tmp2, tmp2, 16);
5043 tcg_gen_or_i32(tmp, tmp, tmp2);
5044 tcg_temp_free_i32(tmp2);
5045 neon_store_reg(rd, pass, tmp);
5046 } else {
5047 tmp = neon_load_reg(rd, pass);
5048 tmp2 = tcg_temp_new_i32();
5049 tcg_gen_shri_i32(tmp2, tmp, 16);
5050 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5051 tcg_temp_free_i32(tmp);
5052 tcg_gen_addi_i32(addr, addr, stride);
5053 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
5054 tcg_temp_free_i32(tmp2);
5055 tcg_gen_addi_i32(addr, addr, stride);
5056 }
5057 } else /* size == 0 */ {
5058 if (load) {
5059 tmp2 = NULL;
5060 for (n = 0; n < 4; n++) {
5061 tmp = tcg_temp_new_i32();
5062 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5063 tcg_gen_addi_i32(addr, addr, stride);
5064 if (n == 0) {
5065 tmp2 = tmp;
5066 } else {
5067 tcg_gen_shli_i32(tmp, tmp, n * 8);
5068 tcg_gen_or_i32(tmp2, tmp2, tmp);
5069 tcg_temp_free_i32(tmp);
5070 }
5071 }
5072 neon_store_reg(rd, pass, tmp2);
5073 } else {
5074 tmp2 = neon_load_reg(rd, pass);
5075 for (n = 0; n < 4; n++) {
5076 tmp = tcg_temp_new_i32();
5077 if (n == 0) {
5078 tcg_gen_mov_i32(tmp, tmp2);
5079 } else {
5080 tcg_gen_shri_i32(tmp, tmp2, n * 8);
5081 }
5082 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5083 tcg_temp_free_i32(tmp);
5084 tcg_gen_addi_i32(addr, addr, stride);
5085 }
5086 tcg_temp_free_i32(tmp2);
5087 }
5088 }
5089 }
5090 }
5091 rd += spacing;
5092 }
5093 tcg_temp_free_i32(addr);
5094 stride = nregs * 8;
5095 } else {
5096 size = (insn >> 10) & 3;
5097 if (size == 3) {
5098 /* Load single element to all lanes. */
5099 int a = (insn >> 4) & 1;
5100 if (!load) {
5101 return 1;
5102 }
5103 size = (insn >> 6) & 3;
5104 nregs = ((insn >> 8) & 3) + 1;
5105
5106 if (size == 3) {
5107 if (nregs != 4 || a == 0) {
5108 return 1;
5109 }
5110 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5111 size = 2;
5112 }
5113 if (nregs == 1 && a == 1 && size == 0) {
5114 return 1;
5115 }
5116 if (nregs == 3 && a == 1) {
5117 return 1;
5118 }
5119 addr = tcg_temp_new_i32();
5120 load_reg_var(s, addr, rn);
5121 if (nregs == 1) {
5122 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5123 tmp = gen_load_and_replicate(s, addr, size);
5124 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5125 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5126 if (insn & (1 << 5)) {
5127 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5128 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5129 }
5130 tcg_temp_free_i32(tmp);
5131 } else {
5132 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5133 stride = (insn & (1 << 5)) ? 2 : 1;
5134 for (reg = 0; reg < nregs; reg++) {
5135 tmp = gen_load_and_replicate(s, addr, size);
5136 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5137 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5138 tcg_temp_free_i32(tmp);
5139 tcg_gen_addi_i32(addr, addr, 1 << size);
5140 rd += stride;
5141 }
5142 }
5143 tcg_temp_free_i32(addr);
5144 stride = (1 << size) * nregs;
5145 } else {
5146 /* Single element. */
5147 int idx = (insn >> 4) & 0xf;
5148 pass = (insn >> 7) & 1;
5149 switch (size) {
5150 case 0:
5151 shift = ((insn >> 5) & 3) * 8;
5152 stride = 1;
5153 break;
5154 case 1:
5155 shift = ((insn >> 6) & 1) * 16;
5156 stride = (insn & (1 << 5)) ? 2 : 1;
5157 break;
5158 case 2:
5159 shift = 0;
5160 stride = (insn & (1 << 6)) ? 2 : 1;
5161 break;
5162 default:
5163 abort();
5164 }
5165 nregs = ((insn >> 8) & 3) + 1;
5166 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5167 switch (nregs) {
5168 case 1:
5169 if (((idx & (1 << size)) != 0) ||
5170 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5171 return 1;
5172 }
5173 break;
5174 case 3:
5175 if ((idx & 1) != 0) {
5176 return 1;
5177 }
5178 /* fall through */
5179 case 2:
5180 if (size == 2 && (idx & 2) != 0) {
5181 return 1;
5182 }
5183 break;
5184 case 4:
5185 if ((size == 2) && ((idx & 3) == 3)) {
5186 return 1;
5187 }
5188 break;
5189 default:
5190 abort();
5191 }
5192 if ((rd + stride * (nregs - 1)) > 31) {
5193 /* Attempts to write off the end of the register file
5194 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5195 * the neon_load_reg() would write off the end of the array.
5196 */
5197 return 1;
5198 }
5199 addr = tcg_temp_new_i32();
5200 load_reg_var(s, addr, rn);
5201 for (reg = 0; reg < nregs; reg++) {
5202 if (load) {
5203 tmp = tcg_temp_new_i32();
5204 switch (size) {
5205 case 0:
5206 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5207 break;
5208 case 1:
5209 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5210 break;
5211 case 2:
5212 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5213 break;
5214 default: /* Avoid compiler warnings. */
5215 abort();
5216 }
5217 if (size != 2) {
5218 tmp2 = neon_load_reg(rd, pass);
5219 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5220 shift, size ? 16 : 8);
5221 tcg_temp_free_i32(tmp2);
5222 }
5223 neon_store_reg(rd, pass, tmp);
5224 } else { /* Store */
5225 tmp = neon_load_reg(rd, pass);
5226 if (shift)
5227 tcg_gen_shri_i32(tmp, tmp, shift);
5228 switch (size) {
5229 case 0:
5230 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5231 break;
5232 case 1:
5233 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5234 break;
5235 case 2:
5236 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5237 break;
5238 }
5239 tcg_temp_free_i32(tmp);
5240 }
5241 rd += stride;
5242 tcg_gen_addi_i32(addr, addr, 1 << size);
5243 }
5244 tcg_temp_free_i32(addr);
5245 stride = nregs * (1 << size);
5246 }
5247 }
5248 if (rm != 15) {
5249 TCGv_i32 base;
5250
5251 base = load_reg(s, rn);
5252 if (rm == 13) {
5253 tcg_gen_addi_i32(base, base, stride);
5254 } else {
5255 TCGv_i32 index;
5256 index = load_reg(s, rm);
5257 tcg_gen_add_i32(base, base, index);
5258 tcg_temp_free_i32(index);
5259 }
5260 store_reg(s, rn, base);
5261 }
5262 return 0;
5263 }
5264
5265 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5266 {
5267 switch (size) {
5268 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5269 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5270 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5271 default: abort();
5272 }
5273 }
5274
5275 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5276 {
5277 switch (size) {
5278 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5279 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5280 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5281 default: abort();
5282 }
5283 }
5284
5285 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5286 {
5287 switch (size) {
5288 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5289 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5290 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5291 default: abort();
5292 }
5293 }
5294
5295 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5296 {
5297 switch (size) {
5298 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5299 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5300 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5301 default: abort();
5302 }
5303 }
5304
5305 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5306 int q, int u)
5307 {
5308 if (q) {
5309 if (u) {
5310 switch (size) {
5311 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5312 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5313 default: abort();
5314 }
5315 } else {
5316 switch (size) {
5317 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5318 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5319 default: abort();
5320 }
5321 }
5322 } else {
5323 if (u) {
5324 switch (size) {
5325 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5326 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5327 default: abort();
5328 }
5329 } else {
5330 switch (size) {
5331 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5332 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5333 default: abort();
5334 }
5335 }
5336 }
5337 }
5338
5339 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5340 {
5341 if (u) {
5342 switch (size) {
5343 case 0: gen_helper_neon_widen_u8(dest, src); break;
5344 case 1: gen_helper_neon_widen_u16(dest, src); break;
5345 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5346 default: abort();
5347 }
5348 } else {
5349 switch (size) {
5350 case 0: gen_helper_neon_widen_s8(dest, src); break;
5351 case 1: gen_helper_neon_widen_s16(dest, src); break;
5352 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5353 default: abort();
5354 }
5355 }
5356 tcg_temp_free_i32(src);
5357 }
5358
5359 static inline void gen_neon_addl(int size)
5360 {
5361 switch (size) {
5362 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5363 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5364 case 2: tcg_gen_add_i64(CPU_V001); break;
5365 default: abort();
5366 }
5367 }
5368
5369 static inline void gen_neon_subl(int size)
5370 {
5371 switch (size) {
5372 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5373 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5374 case 2: tcg_gen_sub_i64(CPU_V001); break;
5375 default: abort();
5376 }
5377 }
5378
5379 static inline void gen_neon_negl(TCGv_i64 var, int size)
5380 {
5381 switch (size) {
5382 case 0: gen_helper_neon_negl_u16(var, var); break;
5383 case 1: gen_helper_neon_negl_u32(var, var); break;
5384 case 2:
5385 tcg_gen_neg_i64(var, var);
5386 break;
5387 default: abort();
5388 }
5389 }
5390
5391 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5392 {
5393 switch (size) {
5394 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5395 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5396 default: abort();
5397 }
5398 }
5399
5400 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5401 int size, int u)
5402 {
5403 TCGv_i64 tmp;
5404
5405 switch ((size << 1) | u) {
5406 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5407 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5408 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5409 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5410 case 4:
5411 tmp = gen_muls_i64_i32(a, b);
5412 tcg_gen_mov_i64(dest, tmp);
5413 tcg_temp_free_i64(tmp);
5414 break;
5415 case 5:
5416 tmp = gen_mulu_i64_i32(a, b);
5417 tcg_gen_mov_i64(dest, tmp);
5418 tcg_temp_free_i64(tmp);
5419 break;
5420 default: abort();
5421 }
5422
5423 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5424 Don't forget to clean them now. */
5425 if (size < 2) {
5426 tcg_temp_free_i32(a);
5427 tcg_temp_free_i32(b);
5428 }
5429 }
5430
5431 static void gen_neon_narrow_op(int op, int u, int size,
5432 TCGv_i32 dest, TCGv_i64 src)
5433 {
5434 if (op) {
5435 if (u) {
5436 gen_neon_unarrow_sats(size, dest, src);
5437 } else {
5438 gen_neon_narrow(size, dest, src);
5439 }
5440 } else {
5441 if (u) {
5442 gen_neon_narrow_satu(size, dest, src);
5443 } else {
5444 gen_neon_narrow_sats(size, dest, src);
5445 }
5446 }
5447 }
5448
5449 /* Symbolic constants for op fields for Neon 3-register same-length.
5450 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5451 * table A7-9.
5452 */
5453 #define NEON_3R_VHADD 0
5454 #define NEON_3R_VQADD 1
5455 #define NEON_3R_VRHADD 2
5456 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5457 #define NEON_3R_VHSUB 4
5458 #define NEON_3R_VQSUB 5
5459 #define NEON_3R_VCGT 6
5460 #define NEON_3R_VCGE 7
5461 #define NEON_3R_VSHL 8
5462 #define NEON_3R_VQSHL 9
5463 #define NEON_3R_VRSHL 10
5464 #define NEON_3R_VQRSHL 11
5465 #define NEON_3R_VMAX 12
5466 #define NEON_3R_VMIN 13
5467 #define NEON_3R_VABD 14
5468 #define NEON_3R_VABA 15
5469 #define NEON_3R_VADD_VSUB 16
5470 #define NEON_3R_VTST_VCEQ 17
5471 #define NEON_3R_VML 18 /* VMLA, VMLS */
5472 #define NEON_3R_VMUL 19
5473 #define NEON_3R_VPMAX 20
5474 #define NEON_3R_VPMIN 21
5475 #define NEON_3R_VQDMULH_VQRDMULH 22
5476 #define NEON_3R_VPADD_VQRDMLAH 23
5477 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5478 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5479 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5480 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5481 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5482 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5483 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5484 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5485
5486 static const uint8_t neon_3r_sizes[] = {
5487 [NEON_3R_VHADD] = 0x7,
5488 [NEON_3R_VQADD] = 0xf,
5489 [NEON_3R_VRHADD] = 0x7,
5490 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5491 [NEON_3R_VHSUB] = 0x7,
5492 [NEON_3R_VQSUB] = 0xf,
5493 [NEON_3R_VCGT] = 0x7,
5494 [NEON_3R_VCGE] = 0x7,
5495 [NEON_3R_VSHL] = 0xf,
5496 [NEON_3R_VQSHL] = 0xf,
5497 [NEON_3R_VRSHL] = 0xf,
5498 [NEON_3R_VQRSHL] = 0xf,
5499 [NEON_3R_VMAX] = 0x7,
5500 [NEON_3R_VMIN] = 0x7,
5501 [NEON_3R_VABD] = 0x7,
5502 [NEON_3R_VABA] = 0x7,
5503 [NEON_3R_VADD_VSUB] = 0xf,
5504 [NEON_3R_VTST_VCEQ] = 0x7,
5505 [NEON_3R_VML] = 0x7,
5506 [NEON_3R_VMUL] = 0x7,
5507 [NEON_3R_VPMAX] = 0x7,
5508 [NEON_3R_VPMIN] = 0x7,
5509 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5510 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5511 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5512 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5513 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5514 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5515 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5516 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5517 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5518 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5519 };
5520
5521 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5522 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5523 * table A7-13.
5524 */
5525 #define NEON_2RM_VREV64 0
5526 #define NEON_2RM_VREV32 1
5527 #define NEON_2RM_VREV16 2
5528 #define NEON_2RM_VPADDL 4
5529 #define NEON_2RM_VPADDL_U 5
5530 #define NEON_2RM_AESE 6 /* Includes AESD */
5531 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5532 #define NEON_2RM_VCLS 8
5533 #define NEON_2RM_VCLZ 9
5534 #define NEON_2RM_VCNT 10
5535 #define NEON_2RM_VMVN 11
5536 #define NEON_2RM_VPADAL 12
5537 #define NEON_2RM_VPADAL_U 13
5538 #define NEON_2RM_VQABS 14
5539 #define NEON_2RM_VQNEG 15
5540 #define NEON_2RM_VCGT0 16
5541 #define NEON_2RM_VCGE0 17
5542 #define NEON_2RM_VCEQ0 18
5543 #define NEON_2RM_VCLE0 19
5544 #define NEON_2RM_VCLT0 20
5545 #define NEON_2RM_SHA1H 21
5546 #define NEON_2RM_VABS 22
5547 #define NEON_2RM_VNEG 23
5548 #define NEON_2RM_VCGT0_F 24
5549 #define NEON_2RM_VCGE0_F 25
5550 #define NEON_2RM_VCEQ0_F 26
5551 #define NEON_2RM_VCLE0_F 27
5552 #define NEON_2RM_VCLT0_F 28
5553 #define NEON_2RM_VABS_F 30
5554 #define NEON_2RM_VNEG_F 31
5555 #define NEON_2RM_VSWP 32
5556 #define NEON_2RM_VTRN 33
5557 #define NEON_2RM_VUZP 34
5558 #define NEON_2RM_VZIP 35
5559 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5560 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5561 #define NEON_2RM_VSHLL 38
5562 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5563 #define NEON_2RM_VRINTN 40
5564 #define NEON_2RM_VRINTX 41
5565 #define NEON_2RM_VRINTA 42
5566 #define NEON_2RM_VRINTZ 43
5567 #define NEON_2RM_VCVT_F16_F32 44
5568 #define NEON_2RM_VRINTM 45
5569 #define NEON_2RM_VCVT_F32_F16 46
5570 #define NEON_2RM_VRINTP 47
5571 #define NEON_2RM_VCVTAU 48
5572 #define NEON_2RM_VCVTAS 49
5573 #define NEON_2RM_VCVTNU 50
5574 #define NEON_2RM_VCVTNS 51
5575 #define NEON_2RM_VCVTPU 52
5576 #define NEON_2RM_VCVTPS 53
5577 #define NEON_2RM_VCVTMU 54
5578 #define NEON_2RM_VCVTMS 55
5579 #define NEON_2RM_VRECPE 56
5580 #define NEON_2RM_VRSQRTE 57
5581 #define NEON_2RM_VRECPE_F 58
5582 #define NEON_2RM_VRSQRTE_F 59
5583 #define NEON_2RM_VCVT_FS 60
5584 #define NEON_2RM_VCVT_FU 61
5585 #define NEON_2RM_VCVT_SF 62
5586 #define NEON_2RM_VCVT_UF 63
5587
5588 static int neon_2rm_is_float_op(int op)
5589 {
5590 /* Return true if this neon 2reg-misc op is float-to-float */
5591 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5592 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5593 op == NEON_2RM_VRINTM ||
5594 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5595 op >= NEON_2RM_VRECPE_F);
5596 }
5597
5598 static bool neon_2rm_is_v8_op(int op)
5599 {
5600 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5601 switch (op) {
5602 case NEON_2RM_VRINTN:
5603 case NEON_2RM_VRINTA:
5604 case NEON_2RM_VRINTM:
5605 case NEON_2RM_VRINTP:
5606 case NEON_2RM_VRINTZ:
5607 case NEON_2RM_VRINTX:
5608 case NEON_2RM_VCVTAU:
5609 case NEON_2RM_VCVTAS:
5610 case NEON_2RM_VCVTNU:
5611 case NEON_2RM_VCVTNS:
5612 case NEON_2RM_VCVTPU:
5613 case NEON_2RM_VCVTPS:
5614 case NEON_2RM_VCVTMU:
5615 case NEON_2RM_VCVTMS:
5616 return true;
5617 default:
5618 return false;
5619 }
5620 }
5621
5622 /* Each entry in this array has bit n set if the insn allows
5623 * size value n (otherwise it will UNDEF). Since unallocated
5624 * op values will have no bits set they always UNDEF.
5625 */
5626 static const uint8_t neon_2rm_sizes[] = {
5627 [NEON_2RM_VREV64] = 0x7,
5628 [NEON_2RM_VREV32] = 0x3,
5629 [NEON_2RM_VREV16] = 0x1,
5630 [NEON_2RM_VPADDL] = 0x7,
5631 [NEON_2RM_VPADDL_U] = 0x7,
5632 [NEON_2RM_AESE] = 0x1,
5633 [NEON_2RM_AESMC] = 0x1,
5634 [NEON_2RM_VCLS] = 0x7,
5635 [NEON_2RM_VCLZ] = 0x7,
5636 [NEON_2RM_VCNT] = 0x1,
5637 [NEON_2RM_VMVN] = 0x1,
5638 [NEON_2RM_VPADAL] = 0x7,
5639 [NEON_2RM_VPADAL_U] = 0x7,
5640 [NEON_2RM_VQABS] = 0x7,
5641 [NEON_2RM_VQNEG] = 0x7,
5642 [NEON_2RM_VCGT0] = 0x7,
5643 [NEON_2RM_VCGE0] = 0x7,
5644 [NEON_2RM_VCEQ0] = 0x7,
5645 [NEON_2RM_VCLE0] = 0x7,
5646 [NEON_2RM_VCLT0] = 0x7,
5647 [NEON_2RM_SHA1H] = 0x4,
5648 [NEON_2RM_VABS] = 0x7,
5649 [NEON_2RM_VNEG] = 0x7,
5650 [NEON_2RM_VCGT0_F] = 0x4,
5651 [NEON_2RM_VCGE0_F] = 0x4,
5652 [NEON_2RM_VCEQ0_F] = 0x4,
5653 [NEON_2RM_VCLE0_F] = 0x4,
5654 [NEON_2RM_VCLT0_F] = 0x4,
5655 [NEON_2RM_VABS_F] = 0x4,
5656 [NEON_2RM_VNEG_F] = 0x4,
5657 [NEON_2RM_VSWP] = 0x1,
5658 [NEON_2RM_VTRN] = 0x7,
5659 [NEON_2RM_VUZP] = 0x7,
5660 [NEON_2RM_VZIP] = 0x7,
5661 [NEON_2RM_VMOVN] = 0x7,
5662 [NEON_2RM_VQMOVN] = 0x7,
5663 [NEON_2RM_VSHLL] = 0x7,
5664 [NEON_2RM_SHA1SU1] = 0x4,
5665 [NEON_2RM_VRINTN] = 0x4,
5666 [NEON_2RM_VRINTX] = 0x4,
5667 [NEON_2RM_VRINTA] = 0x4,
5668 [NEON_2RM_VRINTZ] = 0x4,
5669 [NEON_2RM_VCVT_F16_F32] = 0x2,
5670 [NEON_2RM_VRINTM] = 0x4,
5671 [NEON_2RM_VCVT_F32_F16] = 0x2,
5672 [NEON_2RM_VRINTP] = 0x4,
5673 [NEON_2RM_VCVTAU] = 0x4,
5674 [NEON_2RM_VCVTAS] = 0x4,
5675 [NEON_2RM_VCVTNU] = 0x4,
5676 [NEON_2RM_VCVTNS] = 0x4,
5677 [NEON_2RM_VCVTPU] = 0x4,
5678 [NEON_2RM_VCVTPS] = 0x4,
5679 [NEON_2RM_VCVTMU] = 0x4,
5680 [NEON_2RM_VCVTMS] = 0x4,
5681 [NEON_2RM_VRECPE] = 0x4,
5682 [NEON_2RM_VRSQRTE] = 0x4,
5683 [NEON_2RM_VRECPE_F] = 0x4,
5684 [NEON_2RM_VRSQRTE_F] = 0x4,
5685 [NEON_2RM_VCVT_FS] = 0x4,
5686 [NEON_2RM_VCVT_FU] = 0x4,
5687 [NEON_2RM_VCVT_SF] = 0x4,
5688 [NEON_2RM_VCVT_UF] = 0x4,
5689 };
5690
5691
5692 /* Expand v8.1 simd helper. */
5693 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5694 int q, int rd, int rn, int rm)
5695 {
5696 if (dc_isar_feature(aa32_rdm, s)) {
5697 int opr_sz = (1 + q) * 8;
5698 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5699 vfp_reg_offset(1, rn),
5700 vfp_reg_offset(1, rm), cpu_env,
5701 opr_sz, opr_sz, 0, fn);
5702 return 0;
5703 }
5704 return 1;
5705 }
5706
5707 /*
5708 * Expanders for VBitOps_VBIF, VBIT, VBSL.
5709 */
5710 static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5711 {
5712 tcg_gen_xor_i64(rn, rn, rm);
5713 tcg_gen_and_i64(rn, rn, rd);
5714 tcg_gen_xor_i64(rd, rm, rn);
5715 }
5716
5717 static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5718 {
5719 tcg_gen_xor_i64(rn, rn, rd);
5720 tcg_gen_and_i64(rn, rn, rm);
5721 tcg_gen_xor_i64(rd, rd, rn);
5722 }
5723
5724 static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5725 {
5726 tcg_gen_xor_i64(rn, rn, rd);
5727 tcg_gen_andc_i64(rn, rn, rm);
5728 tcg_gen_xor_i64(rd, rd, rn);
5729 }
5730
5731 static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5732 {
5733 tcg_gen_xor_vec(vece, rn, rn, rm);
5734 tcg_gen_and_vec(vece, rn, rn, rd);
5735 tcg_gen_xor_vec(vece, rd, rm, rn);
5736 }
5737
5738 static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5739 {
5740 tcg_gen_xor_vec(vece, rn, rn, rd);
5741 tcg_gen_and_vec(vece, rn, rn, rm);
5742 tcg_gen_xor_vec(vece, rd, rd, rn);
5743 }
5744
5745 static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5746 {
5747 tcg_gen_xor_vec(vece, rn, rn, rd);
5748 tcg_gen_andc_vec(vece, rn, rn, rm);
5749 tcg_gen_xor_vec(vece, rd, rd, rn);
5750 }
5751
5752 const GVecGen3 bsl_op = {
5753 .fni8 = gen_bsl_i64,
5754 .fniv = gen_bsl_vec,
5755 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5756 .load_dest = true
5757 };
5758
5759 const GVecGen3 bit_op = {
5760 .fni8 = gen_bit_i64,
5761 .fniv = gen_bit_vec,
5762 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5763 .load_dest = true
5764 };
5765
5766 const GVecGen3 bif_op = {
5767 .fni8 = gen_bif_i64,
5768 .fniv = gen_bif_vec,
5769 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5770 .load_dest = true
5771 };
5772
5773 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5774 {
5775 tcg_gen_vec_sar8i_i64(a, a, shift);
5776 tcg_gen_vec_add8_i64(d, d, a);
5777 }
5778
5779 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5780 {
5781 tcg_gen_vec_sar16i_i64(a, a, shift);
5782 tcg_gen_vec_add16_i64(d, d, a);
5783 }
5784
5785 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5786 {
5787 tcg_gen_sari_i32(a, a, shift);
5788 tcg_gen_add_i32(d, d, a);
5789 }
5790
5791 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5792 {
5793 tcg_gen_sari_i64(a, a, shift);
5794 tcg_gen_add_i64(d, d, a);
5795 }
5796
5797 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5798 {
5799 tcg_gen_sari_vec(vece, a, a, sh);
5800 tcg_gen_add_vec(vece, d, d, a);
5801 }
5802
5803 const GVecGen2i ssra_op[4] = {
5804 { .fni8 = gen_ssra8_i64,
5805 .fniv = gen_ssra_vec,
5806 .load_dest = true,
5807 .opc = INDEX_op_sari_vec,
5808 .vece = MO_8 },
5809 { .fni8 = gen_ssra16_i64,
5810 .fniv = gen_ssra_vec,
5811 .load_dest = true,
5812 .opc = INDEX_op_sari_vec,
5813 .vece = MO_16 },
5814 { .fni4 = gen_ssra32_i32,
5815 .fniv = gen_ssra_vec,
5816 .load_dest = true,
5817 .opc = INDEX_op_sari_vec,
5818 .vece = MO_32 },
5819 { .fni8 = gen_ssra64_i64,
5820 .fniv = gen_ssra_vec,
5821 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5822 .load_dest = true,
5823 .opc = INDEX_op_sari_vec,
5824 .vece = MO_64 },
5825 };
5826
5827 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5828 {
5829 tcg_gen_vec_shr8i_i64(a, a, shift);
5830 tcg_gen_vec_add8_i64(d, d, a);
5831 }
5832
5833 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5834 {
5835 tcg_gen_vec_shr16i_i64(a, a, shift);
5836 tcg_gen_vec_add16_i64(d, d, a);
5837 }
5838
5839 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5840 {
5841 tcg_gen_shri_i32(a, a, shift);
5842 tcg_gen_add_i32(d, d, a);
5843 }
5844
5845 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5846 {
5847 tcg_gen_shri_i64(a, a, shift);
5848 tcg_gen_add_i64(d, d, a);
5849 }
5850
5851 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5852 {
5853 tcg_gen_shri_vec(vece, a, a, sh);
5854 tcg_gen_add_vec(vece, d, d, a);
5855 }
5856
5857 const GVecGen2i usra_op[4] = {
5858 { .fni8 = gen_usra8_i64,
5859 .fniv = gen_usra_vec,
5860 .load_dest = true,
5861 .opc = INDEX_op_shri_vec,
5862 .vece = MO_8, },
5863 { .fni8 = gen_usra16_i64,
5864 .fniv = gen_usra_vec,
5865 .load_dest = true,
5866 .opc = INDEX_op_shri_vec,
5867 .vece = MO_16, },
5868 { .fni4 = gen_usra32_i32,
5869 .fniv = gen_usra_vec,
5870 .load_dest = true,
5871 .opc = INDEX_op_shri_vec,
5872 .vece = MO_32, },
5873 { .fni8 = gen_usra64_i64,
5874 .fniv = gen_usra_vec,
5875 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5876 .load_dest = true,
5877 .opc = INDEX_op_shri_vec,
5878 .vece = MO_64, },
5879 };
5880
5881 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5882 {
5883 uint64_t mask = dup_const(MO_8, 0xff >> shift);
5884 TCGv_i64 t = tcg_temp_new_i64();
5885
5886 tcg_gen_shri_i64(t, a, shift);
5887 tcg_gen_andi_i64(t, t, mask);
5888 tcg_gen_andi_i64(d, d, ~mask);
5889 tcg_gen_or_i64(d, d, t);
5890 tcg_temp_free_i64(t);
5891 }
5892
5893 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5894 {
5895 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5896 TCGv_i64 t = tcg_temp_new_i64();
5897
5898 tcg_gen_shri_i64(t, a, shift);
5899 tcg_gen_andi_i64(t, t, mask);
5900 tcg_gen_andi_i64(d, d, ~mask);
5901 tcg_gen_or_i64(d, d, t);
5902 tcg_temp_free_i64(t);
5903 }
5904
5905 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5906 {
5907 tcg_gen_shri_i32(a, a, shift);
5908 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5909 }
5910
5911 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5912 {
5913 tcg_gen_shri_i64(a, a, shift);
5914 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5915 }
5916
5917 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5918 {
5919 if (sh == 0) {
5920 tcg_gen_mov_vec(d, a);
5921 } else {
5922 TCGv_vec t = tcg_temp_new_vec_matching(d);
5923 TCGv_vec m = tcg_temp_new_vec_matching(d);
5924
5925 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5926 tcg_gen_shri_vec(vece, t, a, sh);
5927 tcg_gen_and_vec(vece, d, d, m);
5928 tcg_gen_or_vec(vece, d, d, t);
5929
5930 tcg_temp_free_vec(t);
5931 tcg_temp_free_vec(m);
5932 }
5933 }
5934
5935 const GVecGen2i sri_op[4] = {
5936 { .fni8 = gen_shr8_ins_i64,
5937 .fniv = gen_shr_ins_vec,
5938 .load_dest = true,
5939 .opc = INDEX_op_shri_vec,
5940 .vece = MO_8 },
5941 { .fni8 = gen_shr16_ins_i64,
5942 .fniv = gen_shr_ins_vec,
5943 .load_dest = true,
5944 .opc = INDEX_op_shri_vec,
5945 .vece = MO_16 },
5946 { .fni4 = gen_shr32_ins_i32,
5947 .fniv = gen_shr_ins_vec,
5948 .load_dest = true,
5949 .opc = INDEX_op_shri_vec,
5950 .vece = MO_32 },
5951 { .fni8 = gen_shr64_ins_i64,
5952 .fniv = gen_shr_ins_vec,
5953 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5954 .load_dest = true,
5955 .opc = INDEX_op_shri_vec,
5956 .vece = MO_64 },
5957 };
5958
5959 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5960 {
5961 uint64_t mask = dup_const(MO_8, 0xff << shift);
5962 TCGv_i64 t = tcg_temp_new_i64();
5963
5964 tcg_gen_shli_i64(t, a, shift);
5965 tcg_gen_andi_i64(t, t, mask);
5966 tcg_gen_andi_i64(d, d, ~mask);
5967 tcg_gen_or_i64(d, d, t);
5968 tcg_temp_free_i64(t);
5969 }
5970
5971 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5972 {
5973 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5974 TCGv_i64 t = tcg_temp_new_i64();
5975
5976 tcg_gen_shli_i64(t, a, shift);
5977 tcg_gen_andi_i64(t, t, mask);
5978 tcg_gen_andi_i64(d, d, ~mask);
5979 tcg_gen_or_i64(d, d, t);
5980 tcg_temp_free_i64(t);
5981 }
5982
5983 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5984 {
5985 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5986 }
5987
5988 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5989 {
5990 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5991 }
5992
5993 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5994 {
5995 if (sh == 0) {
5996 tcg_gen_mov_vec(d, a);
5997 } else {
5998 TCGv_vec t = tcg_temp_new_vec_matching(d);
5999 TCGv_vec m = tcg_temp_new_vec_matching(d);
6000
6001 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
6002 tcg_gen_shli_vec(vece, t, a, sh);
6003 tcg_gen_and_vec(vece, d, d, m);
6004 tcg_gen_or_vec(vece, d, d, t);
6005
6006 tcg_temp_free_vec(t);
6007 tcg_temp_free_vec(m);
6008 }
6009 }
6010
6011 const GVecGen2i sli_op[4] = {
6012 { .fni8 = gen_shl8_ins_i64,
6013 .fniv = gen_shl_ins_vec,
6014 .load_dest = true,
6015 .opc = INDEX_op_shli_vec,
6016 .vece = MO_8 },
6017 { .fni8 = gen_shl16_ins_i64,
6018 .fniv = gen_shl_ins_vec,
6019 .load_dest = true,
6020 .opc = INDEX_op_shli_vec,
6021 .vece = MO_16 },
6022 { .fni4 = gen_shl32_ins_i32,
6023 .fniv = gen_shl_ins_vec,
6024 .load_dest = true,
6025 .opc = INDEX_op_shli_vec,
6026 .vece = MO_32 },
6027 { .fni8 = gen_shl64_ins_i64,
6028 .fniv = gen_shl_ins_vec,
6029 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6030 .load_dest = true,
6031 .opc = INDEX_op_shli_vec,
6032 .vece = MO_64 },
6033 };
6034
6035 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6036 {
6037 gen_helper_neon_mul_u8(a, a, b);
6038 gen_helper_neon_add_u8(d, d, a);
6039 }
6040
6041 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6042 {
6043 gen_helper_neon_mul_u8(a, a, b);
6044 gen_helper_neon_sub_u8(d, d, a);
6045 }
6046
6047 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6048 {
6049 gen_helper_neon_mul_u16(a, a, b);
6050 gen_helper_neon_add_u16(d, d, a);
6051 }
6052
6053 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6054 {
6055 gen_helper_neon_mul_u16(a, a, b);
6056 gen_helper_neon_sub_u16(d, d, a);
6057 }
6058
6059 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6060 {
6061 tcg_gen_mul_i32(a, a, b);
6062 tcg_gen_add_i32(d, d, a);
6063 }
6064
6065 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6066 {
6067 tcg_gen_mul_i32(a, a, b);
6068 tcg_gen_sub_i32(d, d, a);
6069 }
6070
6071 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6072 {
6073 tcg_gen_mul_i64(a, a, b);
6074 tcg_gen_add_i64(d, d, a);
6075 }
6076
6077 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6078 {
6079 tcg_gen_mul_i64(a, a, b);
6080 tcg_gen_sub_i64(d, d, a);
6081 }
6082
6083 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6084 {
6085 tcg_gen_mul_vec(vece, a, a, b);
6086 tcg_gen_add_vec(vece, d, d, a);
6087 }
6088
6089 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6090 {
6091 tcg_gen_mul_vec(vece, a, a, b);
6092 tcg_gen_sub_vec(vece, d, d, a);
6093 }
6094
6095 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
6096 * these tables are shared with AArch64 which does support them.
6097 */
6098 const GVecGen3 mla_op[4] = {
6099 { .fni4 = gen_mla8_i32,
6100 .fniv = gen_mla_vec,
6101 .opc = INDEX_op_mul_vec,
6102 .load_dest = true,
6103 .vece = MO_8 },
6104 { .fni4 = gen_mla16_i32,
6105 .fniv = gen_mla_vec,
6106 .opc = INDEX_op_mul_vec,
6107 .load_dest = true,
6108 .vece = MO_16 },
6109 { .fni4 = gen_mla32_i32,
6110 .fniv = gen_mla_vec,
6111 .opc = INDEX_op_mul_vec,
6112 .load_dest = true,
6113 .vece = MO_32 },
6114 { .fni8 = gen_mla64_i64,
6115 .fniv = gen_mla_vec,
6116 .opc = INDEX_op_mul_vec,
6117 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6118 .load_dest = true,
6119 .vece = MO_64 },
6120 };
6121
6122 const GVecGen3 mls_op[4] = {
6123 { .fni4 = gen_mls8_i32,
6124 .fniv = gen_mls_vec,
6125 .opc = INDEX_op_mul_vec,
6126 .load_dest = true,
6127 .vece = MO_8 },
6128 { .fni4 = gen_mls16_i32,
6129 .fniv = gen_mls_vec,
6130 .opc = INDEX_op_mul_vec,
6131 .load_dest = true,
6132 .vece = MO_16 },
6133 { .fni4 = gen_mls32_i32,
6134 .fniv = gen_mls_vec,
6135 .opc = INDEX_op_mul_vec,
6136 .load_dest = true,
6137 .vece = MO_32 },
6138 { .fni8 = gen_mls64_i64,
6139 .fniv = gen_mls_vec,
6140 .opc = INDEX_op_mul_vec,
6141 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6142 .load_dest = true,
6143 .vece = MO_64 },
6144 };
6145
6146 /* CMTST : test is "if (X & Y != 0)". */
6147 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6148 {
6149 tcg_gen_and_i32(d, a, b);
6150 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
6151 tcg_gen_neg_i32(d, d);
6152 }
6153
6154 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6155 {
6156 tcg_gen_and_i64(d, a, b);
6157 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
6158 tcg_gen_neg_i64(d, d);
6159 }
6160
6161 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6162 {
6163 tcg_gen_and_vec(vece, d, a, b);
6164 tcg_gen_dupi_vec(vece, a, 0);
6165 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
6166 }
6167
6168 const GVecGen3 cmtst_op[4] = {
6169 { .fni4 = gen_helper_neon_tst_u8,
6170 .fniv = gen_cmtst_vec,
6171 .vece = MO_8 },
6172 { .fni4 = gen_helper_neon_tst_u16,
6173 .fniv = gen_cmtst_vec,
6174 .vece = MO_16 },
6175 { .fni4 = gen_cmtst_i32,
6176 .fniv = gen_cmtst_vec,
6177 .vece = MO_32 },
6178 { .fni8 = gen_cmtst_i64,
6179 .fniv = gen_cmtst_vec,
6180 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6181 .vece = MO_64 },
6182 };
6183
6184 /* Translate a NEON data processing instruction. Return nonzero if the
6185 instruction is invalid.
6186 We process data in a mixture of 32-bit and 64-bit chunks.
6187 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
6188
6189 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
6190 {
6191 int op;
6192 int q;
6193 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
6194 int size;
6195 int shift;
6196 int pass;
6197 int count;
6198 int pairwise;
6199 int u;
6200 int vec_size;
6201 uint32_t imm;
6202 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
6203 TCGv_ptr ptr1, ptr2, ptr3;
6204 TCGv_i64 tmp64;
6205
6206 /* FIXME: this access check should not take precedence over UNDEF
6207 * for invalid encodings; we will generate incorrect syndrome information
6208 * for attempts to execute invalid vfp/neon encodings with FP disabled.
6209 */
6210 if (s->fp_excp_el) {
6211 gen_exception_insn(s, 4, EXCP_UDEF,
6212 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6213 return 0;
6214 }
6215
6216 if (!s->vfp_enabled)
6217 return 1;
6218 q = (insn & (1 << 6)) != 0;
6219 u = (insn >> 24) & 1;
6220 VFP_DREG_D(rd, insn);
6221 VFP_DREG_N(rn, insn);
6222 VFP_DREG_M(rm, insn);
6223 size = (insn >> 20) & 3;
6224 vec_size = q ? 16 : 8;
6225 rd_ofs = neon_reg_offset(rd, 0);
6226 rn_ofs = neon_reg_offset(rn, 0);
6227 rm_ofs = neon_reg_offset(rm, 0);
6228
6229 if ((insn & (1 << 23)) == 0) {
6230 /* Three register same length. */
6231 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
6232 /* Catch invalid op and bad size combinations: UNDEF */
6233 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
6234 return 1;
6235 }
6236 /* All insns of this form UNDEF for either this condition or the
6237 * superset of cases "Q==1"; we catch the latter later.
6238 */
6239 if (q && ((rd | rn | rm) & 1)) {
6240 return 1;
6241 }
6242 switch (op) {
6243 case NEON_3R_SHA:
6244 /* The SHA-1/SHA-256 3-register instructions require special
6245 * treatment here, as their size field is overloaded as an
6246 * op type selector, and they all consume their input in a
6247 * single pass.
6248 */
6249 if (!q) {
6250 return 1;
6251 }
6252 if (!u) { /* SHA-1 */
6253 if (!dc_isar_feature(aa32_sha1, s)) {
6254 return 1;
6255 }
6256 ptr1 = vfp_reg_ptr(true, rd);
6257 ptr2 = vfp_reg_ptr(true, rn);
6258 ptr3 = vfp_reg_ptr(true, rm);
6259 tmp4 = tcg_const_i32(size);
6260 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
6261 tcg_temp_free_i32(tmp4);
6262 } else { /* SHA-256 */
6263 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
6264 return 1;
6265 }
6266 ptr1 = vfp_reg_ptr(true, rd);
6267 ptr2 = vfp_reg_ptr(true, rn);
6268 ptr3 = vfp_reg_ptr(true, rm);
6269 switch (size) {
6270 case 0:
6271 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
6272 break;
6273 case 1:
6274 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
6275 break;
6276 case 2:
6277 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
6278 break;
6279 }
6280 }
6281 tcg_temp_free_ptr(ptr1);
6282 tcg_temp_free_ptr(ptr2);
6283 tcg_temp_free_ptr(ptr3);
6284 return 0;
6285
6286 case NEON_3R_VPADD_VQRDMLAH:
6287 if (!u) {
6288 break; /* VPADD */
6289 }
6290 /* VQRDMLAH */
6291 switch (size) {
6292 case 1:
6293 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
6294 q, rd, rn, rm);
6295 case 2:
6296 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
6297 q, rd, rn, rm);
6298 }
6299 return 1;
6300
6301 case NEON_3R_VFM_VQRDMLSH:
6302 if (!u) {
6303 /* VFM, VFMS */
6304 if (size == 1) {
6305 return 1;
6306 }
6307 break;
6308 }
6309 /* VQRDMLSH */
6310 switch (size) {
6311 case 1:
6312 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
6313 q, rd, rn, rm);
6314 case 2:
6315 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
6316 q, rd, rn, rm);
6317 }
6318 return 1;
6319
6320 case NEON_3R_LOGIC: /* Logic ops. */
6321 switch ((u << 2) | size) {
6322 case 0: /* VAND */
6323 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
6324 vec_size, vec_size);
6325 break;
6326 case 1: /* VBIC */
6327 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
6328 vec_size, vec_size);
6329 break;
6330 case 2:
6331 if (rn == rm) {
6332 /* VMOV */
6333 tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
6334 } else {
6335 /* VORR */
6336 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
6337 vec_size, vec_size);
6338 }
6339 break;
6340 case 3: /* VORN */
6341 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
6342 vec_size, vec_size);
6343 break;
6344 case 4: /* VEOR */
6345 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
6346 vec_size, vec_size);
6347 break;
6348 case 5: /* VBSL */
6349 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6350 vec_size, vec_size, &bsl_op);
6351 break;
6352 case 6: /* VBIT */
6353 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6354 vec_size, vec_size, &bit_op);
6355 break;
6356 case 7: /* VBIF */
6357 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6358 vec_size, vec_size, &bif_op);
6359 break;
6360 }
6361 return 0;
6362
6363 case NEON_3R_VADD_VSUB:
6364 if (u) {
6365 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
6366 vec_size, vec_size);
6367 } else {
6368 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
6369 vec_size, vec_size);
6370 }
6371 return 0;
6372
6373 case NEON_3R_VMUL: /* VMUL */
6374 if (u) {
6375 /* Polynomial case allows only P8 and is handled below. */
6376 if (size != 0) {
6377 return 1;
6378 }
6379 } else {
6380 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
6381 vec_size, vec_size);
6382 return 0;
6383 }
6384 break;
6385
6386 case NEON_3R_VML: /* VMLA, VMLS */
6387 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
6388 u ? &mls_op[size] : &mla_op[size]);
6389 return 0;
6390
6391 case NEON_3R_VTST_VCEQ:
6392 if (u) { /* VCEQ */
6393 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
6394 vec_size, vec_size);
6395 } else { /* VTST */
6396 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6397 vec_size, vec_size, &cmtst_op[size]);
6398 }
6399 return 0;
6400
6401 case NEON_3R_VCGT:
6402 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
6403 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6404 return 0;
6405
6406 case NEON_3R_VCGE:
6407 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
6408 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6409 return 0;
6410 }
6411
6412 if (size == 3) {
6413 /* 64-bit element instructions. */
6414 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6415 neon_load_reg64(cpu_V0, rn + pass);
6416 neon_load_reg64(cpu_V1, rm + pass);
6417 switch (op) {
6418 case NEON_3R_VQADD:
6419 if (u) {
6420 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
6421 cpu_V0, cpu_V1);
6422 } else {
6423 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
6424 cpu_V0, cpu_V1);
6425 }
6426 break;
6427 case NEON_3R_VQSUB:
6428 if (u) {
6429 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
6430 cpu_V0, cpu_V1);
6431 } else {
6432 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
6433 cpu_V0, cpu_V1);
6434 }
6435 break;
6436 case NEON_3R_VSHL:
6437 if (u) {
6438 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6439 } else {
6440 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6441 }
6442 break;
6443 case NEON_3R_VQSHL:
6444 if (u) {
6445 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6446 cpu_V1, cpu_V0);
6447 } else {
6448 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6449 cpu_V1, cpu_V0);
6450 }
6451 break;
6452 case NEON_3R_VRSHL:
6453 if (u) {
6454 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6455 } else {
6456 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6457 }
6458 break;
6459 case NEON_3R_VQRSHL:
6460 if (u) {
6461 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6462 cpu_V1, cpu_V0);
6463 } else {
6464 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6465 cpu_V1, cpu_V0);
6466 }
6467 break;
6468 default:
6469 abort();
6470 }
6471 neon_store_reg64(cpu_V0, rd + pass);
6472 }
6473 return 0;
6474 }
6475 pairwise = 0;
6476 switch (op) {
6477 case NEON_3R_VSHL:
6478 case NEON_3R_VQSHL:
6479 case NEON_3R_VRSHL:
6480 case NEON_3R_VQRSHL:
6481 {
6482 int rtmp;
6483 /* Shift instruction operands are reversed. */
6484 rtmp = rn;
6485 rn = rm;
6486 rm = rtmp;
6487 }
6488 break;
6489 case NEON_3R_VPADD_VQRDMLAH:
6490 case NEON_3R_VPMAX:
6491 case NEON_3R_VPMIN:
6492 pairwise = 1;
6493 break;
6494 case NEON_3R_FLOAT_ARITH:
6495 pairwise = (u && size < 2); /* if VPADD (float) */
6496 break;
6497 case NEON_3R_FLOAT_MINMAX:
6498 pairwise = u; /* if VPMIN/VPMAX (float) */
6499 break;
6500 case NEON_3R_FLOAT_CMP:
6501 if (!u && size) {
6502 /* no encoding for U=0 C=1x */
6503 return 1;
6504 }
6505 break;
6506 case NEON_3R_FLOAT_ACMP:
6507 if (!u) {
6508 return 1;
6509 }
6510 break;
6511 case NEON_3R_FLOAT_MISC:
6512 /* VMAXNM/VMINNM in ARMv8 */
6513 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6514 return 1;
6515 }
6516 break;
6517 case NEON_3R_VFM_VQRDMLSH:
6518 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6519 return 1;
6520 }
6521 break;
6522 default:
6523 break;
6524 }
6525
6526 if (pairwise && q) {
6527 /* All the pairwise insns UNDEF if Q is set */
6528 return 1;
6529 }
6530
6531 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6532
6533 if (pairwise) {
6534 /* Pairwise. */
6535 if (pass < 1) {
6536 tmp = neon_load_reg(rn, 0);
6537 tmp2 = neon_load_reg(rn, 1);
6538 } else {
6539 tmp = neon_load_reg(rm, 0);
6540 tmp2 = neon_load_reg(rm, 1);
6541 }
6542 } else {
6543 /* Elementwise. */
6544 tmp = neon_load_reg(rn, pass);
6545 tmp2 = neon_load_reg(rm, pass);
6546 }
6547 switch (op) {
6548 case NEON_3R_VHADD:
6549 GEN_NEON_INTEGER_OP(hadd);
6550 break;
6551 case NEON_3R_VQADD:
6552 GEN_NEON_INTEGER_OP_ENV(qadd);
6553 break;
6554 case NEON_3R_VRHADD:
6555 GEN_NEON_INTEGER_OP(rhadd);
6556 break;
6557 case NEON_3R_VHSUB:
6558 GEN_NEON_INTEGER_OP(hsub);
6559 break;
6560 case NEON_3R_VQSUB:
6561 GEN_NEON_INTEGER_OP_ENV(qsub);
6562 break;
6563 case NEON_3R_VSHL:
6564 GEN_NEON_INTEGER_OP(shl);
6565 break;
6566 case NEON_3R_VQSHL:
6567 GEN_NEON_INTEGER_OP_ENV(qshl);
6568 break;
6569 case NEON_3R_VRSHL:
6570 GEN_NEON_INTEGER_OP(rshl);
6571 break;
6572 case NEON_3R_VQRSHL:
6573 GEN_NEON_INTEGER_OP_ENV(qrshl);
6574 break;
6575 case NEON_3R_VMAX:
6576 GEN_NEON_INTEGER_OP(max);
6577 break;
6578 case NEON_3R_VMIN:
6579 GEN_NEON_INTEGER_OP(min);
6580 break;
6581 case NEON_3R_VABD:
6582 GEN_NEON_INTEGER_OP(abd);
6583 break;
6584 case NEON_3R_VABA:
6585 GEN_NEON_INTEGER_OP(abd);
6586 tcg_temp_free_i32(tmp2);
6587 tmp2 = neon_load_reg(rd, pass);
6588 gen_neon_add(size, tmp, tmp2);
6589 break;
6590 case NEON_3R_VMUL:
6591 /* VMUL.P8; other cases already eliminated. */
6592 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6593 break;
6594 case NEON_3R_VPMAX:
6595 GEN_NEON_INTEGER_OP(pmax);
6596 break;
6597 case NEON_3R_VPMIN:
6598 GEN_NEON_INTEGER_OP(pmin);
6599 break;
6600 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6601 if (!u) { /* VQDMULH */
6602 switch (size) {
6603 case 1:
6604 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6605 break;
6606 case 2:
6607 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6608 break;
6609 default: abort();
6610 }
6611 } else { /* VQRDMULH */
6612 switch (size) {
6613 case 1:
6614 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6615 break;
6616 case 2:
6617 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6618 break;
6619 default: abort();
6620 }
6621 }
6622 break;
6623 case NEON_3R_VPADD_VQRDMLAH:
6624 switch (size) {
6625 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6626 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6627 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6628 default: abort();
6629 }
6630 break;
6631 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6632 {
6633 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6634 switch ((u << 2) | size) {
6635 case 0: /* VADD */
6636 case 4: /* VPADD */
6637 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6638 break;
6639 case 2: /* VSUB */
6640 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6641 break;
6642 case 6: /* VABD */
6643 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6644 break;
6645 default:
6646 abort();
6647 }
6648 tcg_temp_free_ptr(fpstatus);
6649 break;
6650 }
6651 case NEON_3R_FLOAT_MULTIPLY:
6652 {
6653 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6654 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6655 if (!u) {
6656 tcg_temp_free_i32(tmp2);
6657 tmp2 = neon_load_reg(rd, pass);
6658 if (size == 0) {
6659 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6660 } else {
6661 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6662 }
6663 }
6664 tcg_temp_free_ptr(fpstatus);
6665 break;
6666 }
6667 case NEON_3R_FLOAT_CMP:
6668 {
6669 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6670 if (!u) {
6671 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6672 } else {
6673 if (size == 0) {
6674 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6675 } else {
6676 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6677 }
6678 }
6679 tcg_temp_free_ptr(fpstatus);
6680 break;
6681 }
6682 case NEON_3R_FLOAT_ACMP:
6683 {
6684 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6685 if (size == 0) {
6686 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6687 } else {
6688 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6689 }
6690 tcg_temp_free_ptr(fpstatus);
6691 break;
6692 }
6693 case NEON_3R_FLOAT_MINMAX:
6694 {
6695 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6696 if (size == 0) {
6697 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6698 } else {
6699 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6700 }
6701 tcg_temp_free_ptr(fpstatus);
6702 break;
6703 }
6704 case NEON_3R_FLOAT_MISC:
6705 if (u) {
6706 /* VMAXNM/VMINNM */
6707 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6708 if (size == 0) {
6709 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6710 } else {
6711 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6712 }
6713 tcg_temp_free_ptr(fpstatus);
6714 } else {
6715 if (size == 0) {
6716 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6717 } else {
6718 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6719 }
6720 }
6721 break;
6722 case NEON_3R_VFM_VQRDMLSH:
6723 {
6724 /* VFMA, VFMS: fused multiply-add */
6725 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6726 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6727 if (size) {
6728 /* VFMS */
6729 gen_helper_vfp_negs(tmp, tmp);
6730 }
6731 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6732 tcg_temp_free_i32(tmp3);
6733 tcg_temp_free_ptr(fpstatus);
6734 break;
6735 }
6736 default:
6737 abort();
6738 }
6739 tcg_temp_free_i32(tmp2);
6740
6741 /* Save the result. For elementwise operations we can put it
6742 straight into the destination register. For pairwise operations
6743 we have to be careful to avoid clobbering the source operands. */
6744 if (pairwise && rd == rm) {
6745 neon_store_scratch(pass, tmp);
6746 } else {
6747 neon_store_reg(rd, pass, tmp);
6748 }
6749
6750 } /* for pass */
6751 if (pairwise && rd == rm) {
6752 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6753 tmp = neon_load_scratch(pass);
6754 neon_store_reg(rd, pass, tmp);
6755 }
6756 }
6757 /* End of 3 register same size operations. */
6758 } else if (insn & (1 << 4)) {
6759 if ((insn & 0x00380080) != 0) {
6760 /* Two registers and shift. */
6761 op = (insn >> 8) & 0xf;
6762 if (insn & (1 << 7)) {
6763 /* 64-bit shift. */
6764 if (op > 7) {
6765 return 1;
6766 }
6767 size = 3;
6768 } else {
6769 size = 2;
6770 while ((insn & (1 << (size + 19))) == 0)
6771 size--;
6772 }
6773 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6774 if (op < 8) {
6775 /* Shift by immediate:
6776 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6777 if (q && ((rd | rm) & 1)) {
6778 return 1;
6779 }
6780 if (!u && (op == 4 || op == 6)) {
6781 return 1;
6782 }
6783 /* Right shifts are encoded as N - shift, where N is the
6784 element size in bits. */
6785 if (op <= 4) {
6786 shift = shift - (1 << (size + 3));
6787 }
6788
6789 switch (op) {
6790 case 0: /* VSHR */
6791 /* Right shift comes here negative. */
6792 shift = -shift;
6793 /* Shifts larger than the element size are architecturally
6794 * valid. Unsigned results in all zeros; signed results
6795 * in all sign bits.
6796 */
6797 if (!u) {
6798 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6799 MIN(shift, (8 << size) - 1),
6800 vec_size, vec_size);
6801 } else if (shift >= 8 << size) {
6802 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6803 } else {
6804 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6805 vec_size, vec_size);
6806 }
6807 return 0;
6808
6809 case 1: /* VSRA */
6810 /* Right shift comes here negative. */
6811 shift = -shift;
6812 /* Shifts larger than the element size are architecturally
6813 * valid. Unsigned results in all zeros; signed results
6814 * in all sign bits.
6815 */
6816 if (!u) {
6817 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6818 MIN(shift, (8 << size) - 1),
6819 &ssra_op[size]);
6820 } else if (shift >= 8 << size) {
6821 /* rd += 0 */
6822 } else {
6823 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6824 shift, &usra_op[size]);
6825 }
6826 return 0;
6827
6828 case 4: /* VSRI */
6829 if (!u) {
6830 return 1;
6831 }
6832 /* Right shift comes here negative. */
6833 shift = -shift;
6834 /* Shift out of range leaves destination unchanged. */
6835 if (shift < 8 << size) {
6836 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6837 shift, &sri_op[size]);
6838 }
6839 return 0;
6840
6841 case 5: /* VSHL, VSLI */
6842 if (u) { /* VSLI */
6843 /* Shift out of range leaves destination unchanged. */
6844 if (shift < 8 << size) {
6845 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6846 vec_size, shift, &sli_op[size]);
6847 }
6848 } else { /* VSHL */
6849 /* Shifts larger than the element size are
6850 * architecturally valid and results in zero.
6851 */
6852 if (shift >= 8 << size) {
6853 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6854 } else {
6855 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6856 vec_size, vec_size);
6857 }
6858 }
6859 return 0;
6860 }
6861
6862 if (size == 3) {
6863 count = q + 1;
6864 } else {
6865 count = q ? 4: 2;
6866 }
6867
6868 /* To avoid excessive duplication of ops we implement shift
6869 * by immediate using the variable shift operations.
6870 */
6871 imm = dup_const(size, shift);
6872
6873 for (pass = 0; pass < count; pass++) {
6874 if (size == 3) {
6875 neon_load_reg64(cpu_V0, rm + pass);
6876 tcg_gen_movi_i64(cpu_V1, imm);
6877 switch (op) {
6878 case 2: /* VRSHR */
6879 case 3: /* VRSRA */
6880 if (u)
6881 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6882 else
6883 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6884 break;
6885 case 6: /* VQSHLU */
6886 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6887 cpu_V0, cpu_V1);
6888 break;
6889 case 7: /* VQSHL */
6890 if (u) {
6891 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6892 cpu_V0, cpu_V1);
6893 } else {
6894 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6895 cpu_V0, cpu_V1);
6896 }
6897 break;
6898 default:
6899 g_assert_not_reached();
6900 }
6901 if (op == 3) {
6902 /* Accumulate. */
6903 neon_load_reg64(cpu_V1, rd + pass);
6904 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6905 }
6906 neon_store_reg64(cpu_V0, rd + pass);
6907 } else { /* size < 3 */
6908 /* Operands in T0 and T1. */
6909 tmp = neon_load_reg(rm, pass);
6910 tmp2 = tcg_temp_new_i32();
6911 tcg_gen_movi_i32(tmp2, imm);
6912 switch (op) {
6913 case 2: /* VRSHR */
6914 case 3: /* VRSRA */
6915 GEN_NEON_INTEGER_OP(rshl);
6916 break;
6917 case 6: /* VQSHLU */
6918 switch (size) {
6919 case 0:
6920 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6921 tmp, tmp2);
6922 break;
6923 case 1:
6924 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6925 tmp, tmp2);
6926 break;
6927 case 2:
6928 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6929 tmp, tmp2);
6930 break;
6931 default:
6932 abort();
6933 }
6934 break;
6935 case 7: /* VQSHL */
6936 GEN_NEON_INTEGER_OP_ENV(qshl);
6937 break;
6938 default:
6939 g_assert_not_reached();
6940 }
6941 tcg_temp_free_i32(tmp2);
6942
6943 if (op == 3) {
6944 /* Accumulate. */
6945 tmp2 = neon_load_reg(rd, pass);
6946 gen_neon_add(size, tmp, tmp2);
6947 tcg_temp_free_i32(tmp2);
6948 }
6949 neon_store_reg(rd, pass, tmp);
6950 }
6951 } /* for pass */
6952 } else if (op < 10) {
6953 /* Shift by immediate and narrow:
6954 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6955 int input_unsigned = (op == 8) ? !u : u;
6956 if (rm & 1) {
6957 return 1;
6958 }
6959 shift = shift - (1 << (size + 3));
6960 size++;
6961 if (size == 3) {
6962 tmp64 = tcg_const_i64(shift);
6963 neon_load_reg64(cpu_V0, rm);
6964 neon_load_reg64(cpu_V1, rm + 1);
6965 for (pass = 0; pass < 2; pass++) {
6966 TCGv_i64 in;
6967 if (pass == 0) {
6968 in = cpu_V0;
6969 } else {
6970 in = cpu_V1;
6971 }
6972 if (q) {
6973 if (input_unsigned) {
6974 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6975 } else {
6976 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6977 }
6978 } else {
6979 if (input_unsigned) {
6980 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6981 } else {
6982 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6983 }
6984 }
6985 tmp = tcg_temp_new_i32();
6986 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6987 neon_store_reg(rd, pass, tmp);
6988 } /* for pass */
6989 tcg_temp_free_i64(tmp64);
6990 } else {
6991 if (size == 1) {
6992 imm = (uint16_t)shift;
6993 imm |= imm << 16;
6994 } else {
6995 /* size == 2 */
6996 imm = (uint32_t)shift;
6997 }
6998 tmp2 = tcg_const_i32(imm);
6999 tmp4 = neon_load_reg(rm + 1, 0);
7000 tmp5 = neon_load_reg(rm + 1, 1);
7001 for (pass = 0; pass < 2; pass++) {
7002 if (pass == 0) {
7003 tmp = neon_load_reg(rm, 0);
7004 } else {
7005 tmp = tmp4;
7006 }
7007 gen_neon_shift_narrow(size, tmp, tmp2, q,
7008 input_unsigned);
7009 if (pass == 0) {
7010 tmp3 = neon_load_reg(rm, 1);
7011 } else {
7012 tmp3 = tmp5;
7013 }
7014 gen_neon_shift_narrow(size, tmp3, tmp2, q,
7015 input_unsigned);
7016 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
7017 tcg_temp_free_i32(tmp);
7018 tcg_temp_free_i32(tmp3);
7019 tmp = tcg_temp_new_i32();
7020 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
7021 neon_store_reg(rd, pass, tmp);
7022 } /* for pass */
7023 tcg_temp_free_i32(tmp2);
7024 }
7025 } else if (op == 10) {
7026 /* VSHLL, VMOVL */
7027 if (q || (rd & 1)) {
7028 return 1;
7029 }
7030 tmp = neon_load_reg(rm, 0);
7031 tmp2 = neon_load_reg(rm, 1);
7032 for (pass = 0; pass < 2; pass++) {
7033 if (pass == 1)
7034 tmp = tmp2;
7035
7036 gen_neon_widen(cpu_V0, tmp, size, u);
7037
7038 if (shift != 0) {
7039 /* The shift is less than the width of the source
7040 type, so we can just shift the whole register. */
7041 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
7042 /* Widen the result of shift: we need to clear
7043 * the potential overflow bits resulting from
7044 * left bits of the narrow input appearing as
7045 * right bits of left the neighbour narrow
7046 * input. */
7047 if (size < 2 || !u) {
7048 uint64_t imm64;
7049 if (size == 0) {
7050 imm = (0xffu >> (8 - shift));
7051 imm |= imm << 16;
7052 } else if (size == 1) {
7053 imm = 0xffff >> (16 - shift);
7054 } else {
7055 /* size == 2 */
7056 imm = 0xffffffff >> (32 - shift);
7057 }
7058 if (size < 2) {
7059 imm64 = imm | (((uint64_t)imm) << 32);
7060 } else {
7061 imm64 = imm;
7062 }
7063 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
7064 }
7065 }
7066 neon_store_reg64(cpu_V0, rd + pass);
7067 }
7068 } else if (op >= 14) {
7069 /* VCVT fixed-point. */
7070 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
7071 return 1;
7072 }
7073 /* We have already masked out the must-be-1 top bit of imm6,
7074 * hence this 32-shift where the ARM ARM has 64-imm6.
7075 */
7076 shift = 32 - shift;
7077 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7078 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
7079 if (!(op & 1)) {
7080 if (u)
7081 gen_vfp_ulto(0, shift, 1);
7082 else
7083 gen_vfp_slto(0, shift, 1);
7084 } else {
7085 if (u)
7086 gen_vfp_toul(0, shift, 1);
7087 else
7088 gen_vfp_tosl(0, shift, 1);
7089 }
7090 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
7091 }
7092 } else {
7093 return 1;
7094 }
7095 } else { /* (insn & 0x00380080) == 0 */
7096 int invert, reg_ofs, vec_size;
7097
7098 if (q && (rd & 1)) {
7099 return 1;
7100 }
7101
7102 op = (insn >> 8) & 0xf;
7103 /* One register and immediate. */
7104 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
7105 invert = (insn & (1 << 5)) != 0;
7106 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
7107 * We choose to not special-case this and will behave as if a
7108 * valid constant encoding of 0 had been given.
7109 */
7110 switch (op) {
7111 case 0: case 1:
7112 /* no-op */
7113 break;
7114 case 2: case 3:
7115 imm <<= 8;
7116 break;
7117 case 4: case 5:
7118 imm <<= 16;
7119 break;
7120 case 6: case 7:
7121 imm <<= 24;
7122 break;
7123 case 8: case 9:
7124 imm |= imm << 16;
7125 break;
7126 case 10: case 11:
7127 imm = (imm << 8) | (imm << 24);
7128 break;
7129 case 12:
7130 imm = (imm << 8) | 0xff;
7131 break;
7132 case 13:
7133 imm = (imm << 16) | 0xffff;
7134 break;
7135 case 14:
7136 imm |= (imm << 8) | (imm << 16) | (imm << 24);
7137 if (invert) {
7138 imm = ~imm;
7139 }
7140 break;
7141 case 15:
7142 if (invert) {
7143 return 1;
7144 }
7145 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
7146 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
7147 break;
7148 }
7149 if (invert) {
7150 imm = ~imm;
7151 }
7152
7153 reg_ofs = neon_reg_offset(rd, 0);
7154 vec_size = q ? 16 : 8;
7155
7156 if (op & 1 && op < 12) {
7157 if (invert) {
7158 /* The immediate value has already been inverted,
7159 * so BIC becomes AND.
7160 */
7161 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
7162 vec_size, vec_size);
7163 } else {
7164 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
7165 vec_size, vec_size);
7166 }
7167 } else {
7168 /* VMOV, VMVN. */
7169 if (op == 14 && invert) {
7170 TCGv_i64 t64 = tcg_temp_new_i64();
7171
7172 for (pass = 0; pass <= q; ++pass) {
7173 uint64_t val = 0;
7174 int n;
7175
7176 for (n = 0; n < 8; n++) {
7177 if (imm & (1 << (n + pass * 8))) {
7178 val |= 0xffull << (n * 8);
7179 }
7180 }
7181 tcg_gen_movi_i64(t64, val);
7182 neon_store_reg64(t64, rd + pass);
7183 }
7184 tcg_temp_free_i64(t64);
7185 } else {
7186 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
7187 }
7188 }
7189 }
7190 } else { /* (insn & 0x00800010 == 0x00800000) */
7191 if (size != 3) {
7192 op = (insn >> 8) & 0xf;
7193 if ((insn & (1 << 6)) == 0) {
7194 /* Three registers of different lengths. */
7195 int src1_wide;
7196 int src2_wide;
7197 int prewiden;
7198 /* undefreq: bit 0 : UNDEF if size == 0
7199 * bit 1 : UNDEF if size == 1
7200 * bit 2 : UNDEF if size == 2
7201 * bit 3 : UNDEF if U == 1
7202 * Note that [2:0] set implies 'always UNDEF'
7203 */
7204 int undefreq;
7205 /* prewiden, src1_wide, src2_wide, undefreq */
7206 static const int neon_3reg_wide[16][4] = {
7207 {1, 0, 0, 0}, /* VADDL */
7208 {1, 1, 0, 0}, /* VADDW */
7209 {1, 0, 0, 0}, /* VSUBL */
7210 {1, 1, 0, 0}, /* VSUBW */
7211 {0, 1, 1, 0}, /* VADDHN */
7212 {0, 0, 0, 0}, /* VABAL */
7213 {0, 1, 1, 0}, /* VSUBHN */
7214 {0, 0, 0, 0}, /* VABDL */
7215 {0, 0, 0, 0}, /* VMLAL */
7216 {0, 0, 0, 9}, /* VQDMLAL */
7217 {0, 0, 0, 0}, /* VMLSL */
7218 {0, 0, 0, 9}, /* VQDMLSL */
7219 {0, 0, 0, 0}, /* Integer VMULL */
7220 {0, 0, 0, 1}, /* VQDMULL */
7221 {0, 0, 0, 0xa}, /* Polynomial VMULL */
7222 {0, 0, 0, 7}, /* Reserved: always UNDEF */
7223 };
7224
7225 prewiden = neon_3reg_wide[op][0];
7226 src1_wide = neon_3reg_wide[op][1];
7227 src2_wide = neon_3reg_wide[op][2];
7228 undefreq = neon_3reg_wide[op][3];
7229
7230 if ((undefreq & (1 << size)) ||
7231 ((undefreq & 8) && u)) {
7232 return 1;
7233 }
7234 if ((src1_wide && (rn & 1)) ||
7235 (src2_wide && (rm & 1)) ||
7236 (!src2_wide && (rd & 1))) {
7237 return 1;
7238 }
7239
7240 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7241 * outside the loop below as it only performs a single pass.
7242 */
7243 if (op == 14 && size == 2) {
7244 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
7245
7246 if (!dc_isar_feature(aa32_pmull, s)) {
7247 return 1;
7248 }
7249 tcg_rn = tcg_temp_new_i64();
7250 tcg_rm = tcg_temp_new_i64();
7251 tcg_rd = tcg_temp_new_i64();
7252 neon_load_reg64(tcg_rn, rn);
7253 neon_load_reg64(tcg_rm, rm);
7254 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
7255 neon_store_reg64(tcg_rd, rd);
7256 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
7257 neon_store_reg64(tcg_rd, rd + 1);
7258 tcg_temp_free_i64(tcg_rn);
7259 tcg_temp_free_i64(tcg_rm);
7260 tcg_temp_free_i64(tcg_rd);
7261 return 0;
7262 }
7263
7264 /* Avoid overlapping operands. Wide source operands are
7265 always aligned so will never overlap with wide
7266 destinations in problematic ways. */
7267 if (rd == rm && !src2_wide) {
7268 tmp = neon_load_reg(rm, 1);
7269 neon_store_scratch(2, tmp);
7270 } else if (rd == rn && !src1_wide) {
7271 tmp = neon_load_reg(rn, 1);
7272 neon_store_scratch(2, tmp);
7273 }
7274 tmp3 = NULL;
7275 for (pass = 0; pass < 2; pass++) {
7276 if (src1_wide) {
7277 neon_load_reg64(cpu_V0, rn + pass);
7278 tmp = NULL;
7279 } else {
7280 if (pass == 1 && rd == rn) {
7281 tmp = neon_load_scratch(2);
7282 } else {
7283 tmp = neon_load_reg(rn, pass);
7284 }
7285 if (prewiden) {
7286 gen_neon_widen(cpu_V0, tmp, size, u);
7287 }
7288 }
7289 if (src2_wide) {
7290 neon_load_reg64(cpu_V1, rm + pass);
7291 tmp2 = NULL;
7292 } else {
7293 if (pass == 1 && rd == rm) {
7294 tmp2 = neon_load_scratch(2);
7295 } else {
7296 tmp2 = neon_load_reg(rm, pass);
7297 }
7298 if (prewiden) {
7299 gen_neon_widen(cpu_V1, tmp2, size, u);
7300 }
7301 }
7302 switch (op) {
7303 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7304 gen_neon_addl(size);
7305 break;
7306 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7307 gen_neon_subl(size);
7308 break;
7309 case 5: case 7: /* VABAL, VABDL */
7310 switch ((size << 1) | u) {
7311 case 0:
7312 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
7313 break;
7314 case 1:
7315 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
7316 break;
7317 case 2:
7318 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
7319 break;
7320 case 3:
7321 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
7322 break;
7323 case 4:
7324 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
7325 break;
7326 case 5:
7327 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
7328 break;
7329 default: abort();
7330 }
7331 tcg_temp_free_i32(tmp2);
7332 tcg_temp_free_i32(tmp);
7333 break;
7334 case 8: case 9: case 10: case 11: case 12: case 13:
7335 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7336 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7337 break;
7338 case 14: /* Polynomial VMULL */
7339 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
7340 tcg_temp_free_i32(tmp2);
7341 tcg_temp_free_i32(tmp);
7342 break;
7343 default: /* 15 is RESERVED: caught earlier */
7344 abort();
7345 }
7346 if (op == 13) {
7347 /* VQDMULL */
7348 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7349 neon_store_reg64(cpu_V0, rd + pass);
7350 } else if (op == 5 || (op >= 8 && op <= 11)) {
7351 /* Accumulate. */
7352 neon_load_reg64(cpu_V1, rd + pass);
7353 switch (op) {
7354 case 10: /* VMLSL */
7355 gen_neon_negl(cpu_V0, size);
7356 /* Fall through */
7357 case 5: case 8: /* VABAL, VMLAL */
7358 gen_neon_addl(size);
7359 break;
7360 case 9: case 11: /* VQDMLAL, VQDMLSL */
7361 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7362 if (op == 11) {
7363 gen_neon_negl(cpu_V0, size);
7364 }
7365 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7366 break;
7367 default:
7368 abort();
7369 }
7370 neon_store_reg64(cpu_V0, rd + pass);
7371 } else if (op == 4 || op == 6) {
7372 /* Narrowing operation. */
7373 tmp = tcg_temp_new_i32();
7374 if (!u) {
7375 switch (size) {
7376 case 0:
7377 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7378 break;
7379 case 1:
7380 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7381 break;
7382 case 2:
7383 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7384 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7385 break;
7386 default: abort();
7387 }
7388 } else {
7389 switch (size) {
7390 case 0:
7391 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7392 break;
7393 case 1:
7394 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7395 break;
7396 case 2:
7397 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7398 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7399 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7400 break;
7401 default: abort();
7402 }
7403 }
7404 if (pass == 0) {
7405 tmp3 = tmp;
7406 } else {
7407 neon_store_reg(rd, 0, tmp3);
7408 neon_store_reg(rd, 1, tmp);
7409 }
7410 } else {
7411 /* Write back the result. */
7412 neon_store_reg64(cpu_V0, rd + pass);
7413 }
7414 }
7415 } else {
7416 /* Two registers and a scalar. NB that for ops of this form
7417 * the ARM ARM labels bit 24 as Q, but it is in our variable
7418 * 'u', not 'q'.
7419 */
7420 if (size == 0) {
7421 return 1;
7422 }
7423 switch (op) {
7424 case 1: /* Float VMLA scalar */
7425 case 5: /* Floating point VMLS scalar */
7426 case 9: /* Floating point VMUL scalar */
7427 if (size == 1) {
7428 return 1;
7429 }
7430 /* fall through */
7431 case 0: /* Integer VMLA scalar */
7432 case 4: /* Integer VMLS scalar */
7433 case 8: /* Integer VMUL scalar */
7434 case 12: /* VQDMULH scalar */
7435 case 13: /* VQRDMULH scalar */
7436 if (u && ((rd | rn) & 1)) {
7437 return 1;
7438 }
7439 tmp = neon_get_scalar(size, rm);
7440 neon_store_scratch(0, tmp);
7441 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7442 tmp = neon_load_scratch(0);
7443 tmp2 = neon_load_reg(rn, pass);
7444 if (op == 12) {
7445 if (size == 1) {
7446 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7447 } else {
7448 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7449 }
7450 } else if (op == 13) {
7451 if (size == 1) {
7452 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7453 } else {
7454 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7455 }
7456 } else if (op & 1) {
7457 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7458 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7459 tcg_temp_free_ptr(fpstatus);
7460 } else {
7461 switch (size) {
7462 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7463 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7464 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7465 default: abort();
7466 }
7467 }
7468 tcg_temp_free_i32(tmp2);
7469 if (op < 8) {
7470 /* Accumulate. */
7471 tmp2 = neon_load_reg(rd, pass);
7472 switch (op) {
7473 case 0:
7474 gen_neon_add(size, tmp, tmp2);
7475 break;
7476 case 1:
7477 {
7478 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7479 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7480 tcg_temp_free_ptr(fpstatus);
7481 break;
7482 }
7483 case 4:
7484 gen_neon_rsb(size, tmp, tmp2);
7485 break;
7486 case 5:
7487 {
7488 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7489 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7490 tcg_temp_free_ptr(fpstatus);
7491 break;
7492 }
7493 default:
7494 abort();
7495 }
7496 tcg_temp_free_i32(tmp2);
7497 }
7498 neon_store_reg(rd, pass, tmp);
7499 }
7500 break;
7501 case 3: /* VQDMLAL scalar */
7502 case 7: /* VQDMLSL scalar */
7503 case 11: /* VQDMULL scalar */
7504 if (u == 1) {
7505 return 1;
7506 }
7507 /* fall through */
7508 case 2: /* VMLAL sclar */
7509 case 6: /* VMLSL scalar */
7510 case 10: /* VMULL scalar */
7511 if (rd & 1) {
7512 return 1;
7513 }
7514 tmp2 = neon_get_scalar(size, rm);
7515 /* We need a copy of tmp2 because gen_neon_mull
7516 * deletes it during pass 0. */
7517 tmp4 = tcg_temp_new_i32();
7518 tcg_gen_mov_i32(tmp4, tmp2);
7519 tmp3 = neon_load_reg(rn, 1);
7520
7521 for (pass = 0; pass < 2; pass++) {
7522 if (pass == 0) {
7523 tmp = neon_load_reg(rn, 0);
7524 } else {
7525 tmp = tmp3;
7526 tmp2 = tmp4;
7527 }
7528 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7529 if (op != 11) {
7530 neon_load_reg64(cpu_V1, rd + pass);
7531 }
7532 switch (op) {
7533 case 6:
7534 gen_neon_negl(cpu_V0, size);
7535 /* Fall through */
7536 case 2:
7537 gen_neon_addl(size);
7538 break;
7539 case 3: case 7:
7540 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7541 if (op == 7) {
7542 gen_neon_negl(cpu_V0, size);
7543 }
7544 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7545 break;
7546 case 10:
7547 /* no-op */
7548 break;
7549 case 11:
7550 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7551 break;
7552 default:
7553 abort();
7554 }
7555 neon_store_reg64(cpu_V0, rd + pass);
7556 }
7557 break;
7558 case 14: /* VQRDMLAH scalar */
7559 case 15: /* VQRDMLSH scalar */
7560 {
7561 NeonGenThreeOpEnvFn *fn;
7562
7563 if (!dc_isar_feature(aa32_rdm, s)) {
7564 return 1;
7565 }
7566 if (u && ((rd | rn) & 1)) {
7567 return 1;
7568 }
7569 if (op == 14) {
7570 if (size == 1) {
7571 fn = gen_helper_neon_qrdmlah_s16;
7572 } else {
7573 fn = gen_helper_neon_qrdmlah_s32;
7574 }
7575 } else {
7576 if (size == 1) {
7577 fn = gen_helper_neon_qrdmlsh_s16;
7578 } else {
7579 fn = gen_helper_neon_qrdmlsh_s32;
7580 }
7581 }
7582
7583 tmp2 = neon_get_scalar(size, rm);
7584 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7585 tmp = neon_load_reg(rn, pass);
7586 tmp3 = neon_load_reg(rd, pass);
7587 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7588 tcg_temp_free_i32(tmp3);
7589 neon_store_reg(rd, pass, tmp);
7590 }
7591 tcg_temp_free_i32(tmp2);
7592 }
7593 break;
7594 default:
7595 g_assert_not_reached();
7596 }
7597 }
7598 } else { /* size == 3 */
7599 if (!u) {
7600 /* Extract. */
7601 imm = (insn >> 8) & 0xf;
7602
7603 if (imm > 7 && !q)
7604 return 1;
7605
7606 if (q && ((rd | rn | rm) & 1)) {
7607 return 1;
7608 }
7609
7610 if (imm == 0) {
7611 neon_load_reg64(cpu_V0, rn);
7612 if (q) {
7613 neon_load_reg64(cpu_V1, rn + 1);
7614 }
7615 } else if (imm == 8) {
7616 neon_load_reg64(cpu_V0, rn + 1);
7617 if (q) {
7618 neon_load_reg64(cpu_V1, rm);
7619 }
7620 } else if (q) {
7621 tmp64 = tcg_temp_new_i64();
7622 if (imm < 8) {
7623 neon_load_reg64(cpu_V0, rn);
7624 neon_load_reg64(tmp64, rn + 1);
7625 } else {
7626 neon_load_reg64(cpu_V0, rn + 1);
7627 neon_load_reg64(tmp64, rm);
7628 }
7629 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7630 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7631 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7632 if (imm < 8) {
7633 neon_load_reg64(cpu_V1, rm);
7634 } else {
7635 neon_load_reg64(cpu_V1, rm + 1);
7636 imm -= 8;
7637 }
7638 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7639 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7640 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7641 tcg_temp_free_i64(tmp64);
7642 } else {
7643 /* BUGFIX */
7644 neon_load_reg64(cpu_V0, rn);
7645 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7646 neon_load_reg64(cpu_V1, rm);
7647 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7648 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7649 }
7650 neon_store_reg64(cpu_V0, rd);
7651 if (q) {
7652 neon_store_reg64(cpu_V1, rd + 1);
7653 }
7654 } else if ((insn & (1 << 11)) == 0) {
7655 /* Two register misc. */
7656 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7657 size = (insn >> 18) & 3;
7658 /* UNDEF for unknown op values and bad op-size combinations */
7659 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7660 return 1;
7661 }
7662 if (neon_2rm_is_v8_op(op) &&
7663 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7664 return 1;
7665 }
7666 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7667 q && ((rm | rd) & 1)) {
7668 return 1;
7669 }
7670 switch (op) {
7671 case NEON_2RM_VREV64:
7672 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7673 tmp = neon_load_reg(rm, pass * 2);
7674 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7675 switch (size) {
7676 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7677 case 1: gen_swap_half(tmp); break;
7678 case 2: /* no-op */ break;
7679 default: abort();
7680 }
7681 neon_store_reg(rd, pass * 2 + 1, tmp);
7682 if (size == 2) {
7683 neon_store_reg(rd, pass * 2, tmp2);
7684 } else {
7685 switch (size) {
7686 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7687 case 1: gen_swap_half(tmp2); break;
7688 default: abort();
7689 }
7690 neon_store_reg(rd, pass * 2, tmp2);
7691 }
7692 }
7693 break;
7694 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7695 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7696 for (pass = 0; pass < q + 1; pass++) {
7697 tmp = neon_load_reg(rm, pass * 2);
7698 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7699 tmp = neon_load_reg(rm, pass * 2 + 1);
7700 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7701 switch (size) {
7702 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7703 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7704 case 2: tcg_gen_add_i64(CPU_V001); break;
7705 default: abort();
7706 }
7707 if (op >= NEON_2RM_VPADAL) {
7708 /* Accumulate. */
7709 neon_load_reg64(cpu_V1, rd + pass);
7710 gen_neon_addl(size);
7711 }
7712 neon_store_reg64(cpu_V0, rd + pass);
7713 }
7714 break;
7715 case NEON_2RM_VTRN:
7716 if (size == 2) {
7717 int n;
7718 for (n = 0; n < (q ? 4 : 2); n += 2) {
7719 tmp = neon_load_reg(rm, n);
7720 tmp2 = neon_load_reg(rd, n + 1);
7721 neon_store_reg(rm, n, tmp2);
7722 neon_store_reg(rd, n + 1, tmp);
7723 }
7724 } else {
7725 goto elementwise;
7726 }
7727 break;
7728 case NEON_2RM_VUZP:
7729 if (gen_neon_unzip(rd, rm, size, q)) {
7730 return 1;
7731 }
7732 break;
7733 case NEON_2RM_VZIP:
7734 if (gen_neon_zip(rd, rm, size, q)) {
7735 return 1;
7736 }
7737 break;
7738 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7739 /* also VQMOVUN; op field and mnemonics don't line up */
7740 if (rm & 1) {
7741 return 1;
7742 }
7743 tmp2 = NULL;
7744 for (pass = 0; pass < 2; pass++) {
7745 neon_load_reg64(cpu_V0, rm + pass);
7746 tmp = tcg_temp_new_i32();
7747 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7748 tmp, cpu_V0);
7749 if (pass == 0) {
7750 tmp2 = tmp;
7751 } else {
7752 neon_store_reg(rd, 0, tmp2);
7753 neon_store_reg(rd, 1, tmp);
7754 }
7755 }
7756 break;
7757 case NEON_2RM_VSHLL:
7758 if (q || (rd & 1)) {
7759 return 1;
7760 }
7761 tmp = neon_load_reg(rm, 0);
7762 tmp2 = neon_load_reg(rm, 1);
7763 for (pass = 0; pass < 2; pass++) {
7764 if (pass == 1)
7765 tmp = tmp2;
7766 gen_neon_widen(cpu_V0, tmp, size, 1);
7767 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7768 neon_store_reg64(cpu_V0, rd + pass);
7769 }
7770 break;
7771 case NEON_2RM_VCVT_F16_F32:
7772 {
7773 TCGv_ptr fpst;
7774 TCGv_i32 ahp;
7775
7776 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7777 q || (rm & 1)) {
7778 return 1;
7779 }
7780 tmp = tcg_temp_new_i32();
7781 tmp2 = tcg_temp_new_i32();
7782 fpst = get_fpstatus_ptr(true);
7783 ahp = get_ahp_flag();
7784 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7785 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7786 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7787 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7788 tcg_gen_shli_i32(tmp2, tmp2, 16);
7789 tcg_gen_or_i32(tmp2, tmp2, tmp);
7790 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7791 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7792 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7793 neon_store_reg(rd, 0, tmp2);
7794 tmp2 = tcg_temp_new_i32();
7795 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7796 tcg_gen_shli_i32(tmp2, tmp2, 16);
7797 tcg_gen_or_i32(tmp2, tmp2, tmp);
7798 neon_store_reg(rd, 1, tmp2);
7799 tcg_temp_free_i32(tmp);
7800 tcg_temp_free_i32(ahp);
7801 tcg_temp_free_ptr(fpst);
7802 break;
7803 }
7804 case NEON_2RM_VCVT_F32_F16:
7805 {
7806 TCGv_ptr fpst;
7807 TCGv_i32 ahp;
7808 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7809 q || (rd & 1)) {
7810 return 1;
7811 }
7812 fpst = get_fpstatus_ptr(true);
7813 ahp = get_ahp_flag();
7814 tmp3 = tcg_temp_new_i32();
7815 tmp = neon_load_reg(rm, 0);
7816 tmp2 = neon_load_reg(rm, 1);
7817 tcg_gen_ext16u_i32(tmp3, tmp);
7818 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7819 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7820 tcg_gen_shri_i32(tmp3, tmp, 16);
7821 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7822 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7823 tcg_temp_free_i32(tmp);
7824 tcg_gen_ext16u_i32(tmp3, tmp2);
7825 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7826 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7827 tcg_gen_shri_i32(tmp3, tmp2, 16);
7828 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7829 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7830 tcg_temp_free_i32(tmp2);
7831 tcg_temp_free_i32(tmp3);
7832 tcg_temp_free_i32(ahp);
7833 tcg_temp_free_ptr(fpst);
7834 break;
7835 }
7836 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7837 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7838 return 1;
7839 }
7840 ptr1 = vfp_reg_ptr(true, rd);
7841 ptr2 = vfp_reg_ptr(true, rm);
7842
7843 /* Bit 6 is the lowest opcode bit; it distinguishes between
7844 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7845 */
7846 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7847
7848 if (op == NEON_2RM_AESE) {
7849 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7850 } else {
7851 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7852 }
7853 tcg_temp_free_ptr(ptr1);
7854 tcg_temp_free_ptr(ptr2);
7855 tcg_temp_free_i32(tmp3);
7856 break;
7857 case NEON_2RM_SHA1H:
7858 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7859 return 1;
7860 }
7861 ptr1 = vfp_reg_ptr(true, rd);
7862 ptr2 = vfp_reg_ptr(true, rm);
7863
7864 gen_helper_crypto_sha1h(ptr1, ptr2);
7865
7866 tcg_temp_free_ptr(ptr1);
7867 tcg_temp_free_ptr(ptr2);
7868 break;
7869 case NEON_2RM_SHA1SU1:
7870 if ((rm | rd) & 1) {
7871 return 1;
7872 }
7873 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7874 if (q) {
7875 if (!dc_isar_feature(aa32_sha2, s)) {
7876 return 1;
7877 }
7878 } else if (!dc_isar_feature(aa32_sha1, s)) {
7879 return 1;
7880 }
7881 ptr1 = vfp_reg_ptr(true, rd);
7882 ptr2 = vfp_reg_ptr(true, rm);
7883 if (q) {
7884 gen_helper_crypto_sha256su0(ptr1, ptr2);
7885 } else {
7886 gen_helper_crypto_sha1su1(ptr1, ptr2);
7887 }
7888 tcg_temp_free_ptr(ptr1);
7889 tcg_temp_free_ptr(ptr2);
7890 break;
7891
7892 case NEON_2RM_VMVN:
7893 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7894 break;
7895 case NEON_2RM_VNEG:
7896 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7897 break;
7898
7899 default:
7900 elementwise:
7901 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7902 if (neon_2rm_is_float_op(op)) {
7903 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7904 neon_reg_offset(rm, pass));
7905 tmp = NULL;
7906 } else {
7907 tmp = neon_load_reg(rm, pass);
7908 }
7909 switch (op) {
7910 case NEON_2RM_VREV32:
7911 switch (size) {
7912 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7913 case 1: gen_swap_half(tmp); break;
7914 default: abort();
7915 }
7916 break;
7917 case NEON_2RM_VREV16:
7918 gen_rev16(tmp);
7919 break;
7920 case NEON_2RM_VCLS:
7921 switch (size) {
7922 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7923 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7924 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7925 default: abort();
7926 }
7927 break;
7928 case NEON_2RM_VCLZ:
7929 switch (size) {
7930 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7931 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7932 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7933 default: abort();
7934 }
7935 break;
7936 case NEON_2RM_VCNT:
7937 gen_helper_neon_cnt_u8(tmp, tmp);
7938 break;
7939 case NEON_2RM_VQABS:
7940 switch (size) {
7941 case 0:
7942 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7943 break;
7944 case 1:
7945 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7946 break;
7947 case 2:
7948 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7949 break;
7950 default: abort();
7951 }
7952 break;
7953 case NEON_2RM_VQNEG:
7954 switch (size) {
7955 case 0:
7956 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7957 break;
7958 case 1:
7959 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7960 break;
7961 case 2:
7962 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7963 break;
7964 default: abort();
7965 }
7966 break;
7967 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7968 tmp2 = tcg_const_i32(0);
7969 switch(size) {
7970 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7971 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7972 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7973 default: abort();
7974 }
7975 tcg_temp_free_i32(tmp2);
7976 if (op == NEON_2RM_VCLE0) {
7977 tcg_gen_not_i32(tmp, tmp);
7978 }
7979 break;
7980 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7981 tmp2 = tcg_const_i32(0);
7982 switch(size) {
7983 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7984 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7985 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7986 default: abort();
7987 }
7988 tcg_temp_free_i32(tmp2);
7989 if (op == NEON_2RM_VCLT0) {
7990 tcg_gen_not_i32(tmp, tmp);
7991 }
7992 break;
7993 case NEON_2RM_VCEQ0:
7994 tmp2 = tcg_const_i32(0);
7995 switch(size) {
7996 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7997 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7998 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7999 default: abort();
8000 }
8001 tcg_temp_free_i32(tmp2);
8002 break;
8003 case NEON_2RM_VABS:
8004 switch(size) {
8005 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
8006 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
8007 case 2: tcg_gen_abs_i32(tmp, tmp); break;
8008 default: abort();
8009 }
8010 break;
8011 case NEON_2RM_VCGT0_F:
8012 {
8013 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8014 tmp2 = tcg_const_i32(0);
8015 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
8016 tcg_temp_free_i32(tmp2);
8017 tcg_temp_free_ptr(fpstatus);
8018 break;
8019 }
8020 case NEON_2RM_VCGE0_F:
8021 {
8022 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8023 tmp2 = tcg_const_i32(0);
8024 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
8025 tcg_temp_free_i32(tmp2);
8026 tcg_temp_free_ptr(fpstatus);
8027 break;
8028 }
8029 case NEON_2RM_VCEQ0_F:
8030 {
8031 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8032 tmp2 = tcg_const_i32(0);
8033 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
8034 tcg_temp_free_i32(tmp2);
8035 tcg_temp_free_ptr(fpstatus);
8036 break;
8037 }
8038 case NEON_2RM_VCLE0_F:
8039 {
8040 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8041 tmp2 = tcg_const_i32(0);
8042 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
8043 tcg_temp_free_i32(tmp2);
8044 tcg_temp_free_ptr(fpstatus);
8045 break;
8046 }
8047 case NEON_2RM_VCLT0_F:
8048 {
8049 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8050 tmp2 = tcg_const_i32(0);
8051 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
8052 tcg_temp_free_i32(tmp2);
8053 tcg_temp_free_ptr(fpstatus);
8054 break;
8055 }
8056 case NEON_2RM_VABS_F:
8057 gen_vfp_abs(0);
8058 break;
8059 case NEON_2RM_VNEG_F:
8060 gen_vfp_neg(0);
8061 break;
8062 case NEON_2RM_VSWP:
8063 tmp2 = neon_load_reg(rd, pass);
8064 neon_store_reg(rm, pass, tmp2);
8065 break;
8066 case NEON_2RM_VTRN:
8067 tmp2 = neon_load_reg(rd, pass);
8068 switch (size) {
8069 case 0: gen_neon_trn_u8(tmp, tmp2); break;
8070 case 1: gen_neon_trn_u16(tmp, tmp2); break;
8071 default: abort();
8072 }
8073 neon_store_reg(rm, pass, tmp2);
8074 break;
8075 case NEON_2RM_VRINTN:
8076 case NEON_2RM_VRINTA:
8077 case NEON_2RM_VRINTM:
8078 case NEON_2RM_VRINTP:
8079 case NEON_2RM_VRINTZ:
8080 {
8081 TCGv_i32 tcg_rmode;
8082 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8083 int rmode;
8084
8085 if (op == NEON_2RM_VRINTZ) {
8086 rmode = FPROUNDING_ZERO;
8087 } else {
8088 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
8089 }
8090
8091 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8092 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8093 cpu_env);
8094 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
8095 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8096 cpu_env);
8097 tcg_temp_free_ptr(fpstatus);
8098 tcg_temp_free_i32(tcg_rmode);
8099 break;
8100 }
8101 case NEON_2RM_VRINTX:
8102 {
8103 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8104 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
8105 tcg_temp_free_ptr(fpstatus);
8106 break;
8107 }
8108 case NEON_2RM_VCVTAU:
8109 case NEON_2RM_VCVTAS:
8110 case NEON_2RM_VCVTNU:
8111 case NEON_2RM_VCVTNS:
8112 case NEON_2RM_VCVTPU:
8113 case NEON_2RM_VCVTPS:
8114 case NEON_2RM_VCVTMU:
8115 case NEON_2RM_VCVTMS:
8116 {
8117 bool is_signed = !extract32(insn, 7, 1);
8118 TCGv_ptr fpst = get_fpstatus_ptr(1);
8119 TCGv_i32 tcg_rmode, tcg_shift;
8120 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
8121
8122 tcg_shift = tcg_const_i32(0);
8123 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8124 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8125 cpu_env);
8126
8127 if (is_signed) {
8128 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
8129 tcg_shift, fpst);
8130 } else {
8131 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
8132 tcg_shift, fpst);
8133 }
8134
8135 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8136 cpu_env);
8137 tcg_temp_free_i32(tcg_rmode);
8138 tcg_temp_free_i32(tcg_shift);
8139 tcg_temp_free_ptr(fpst);
8140 break;
8141 }
8142 case NEON_2RM_VRECPE:
8143 {
8144 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8145 gen_helper_recpe_u32(tmp, tmp, fpstatus);
8146 tcg_temp_free_ptr(fpstatus);
8147 break;
8148 }
8149 case NEON_2RM_VRSQRTE:
8150 {
8151 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8152 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
8153 tcg_temp_free_ptr(fpstatus);
8154 break;
8155 }
8156 case NEON_2RM_VRECPE_F:
8157 {
8158 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8159 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
8160 tcg_temp_free_ptr(fpstatus);
8161 break;
8162 }
8163 case NEON_2RM_VRSQRTE_F:
8164 {
8165 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8166 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
8167 tcg_temp_free_ptr(fpstatus);
8168 break;
8169 }
8170 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
8171 gen_vfp_sito(0, 1);
8172 break;
8173 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
8174 gen_vfp_uito(0, 1);
8175 break;
8176 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
8177 gen_vfp_tosiz(0, 1);
8178 break;
8179 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
8180 gen_vfp_touiz(0, 1);
8181 break;
8182 default:
8183 /* Reserved op values were caught by the
8184 * neon_2rm_sizes[] check earlier.
8185 */
8186 abort();
8187 }
8188 if (neon_2rm_is_float_op(op)) {
8189 tcg_gen_st_f32(cpu_F0s, cpu_env,
8190 neon_reg_offset(rd, pass));
8191 } else {
8192 neon_store_reg(rd, pass, tmp);
8193 }
8194 }
8195 break;
8196 }
8197 } else if ((insn & (1 << 10)) == 0) {
8198 /* VTBL, VTBX. */
8199 int n = ((insn >> 8) & 3) + 1;
8200 if ((rn + n) > 32) {
8201 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8202 * helper function running off the end of the register file.
8203 */
8204 return 1;
8205 }
8206 n <<= 3;
8207 if (insn & (1 << 6)) {
8208 tmp = neon_load_reg(rd, 0);
8209 } else {
8210 tmp = tcg_temp_new_i32();
8211 tcg_gen_movi_i32(tmp, 0);
8212 }
8213 tmp2 = neon_load_reg(rm, 0);
8214 ptr1 = vfp_reg_ptr(true, rn);
8215 tmp5 = tcg_const_i32(n);
8216 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
8217 tcg_temp_free_i32(tmp);
8218 if (insn & (1 << 6)) {
8219 tmp = neon_load_reg(rd, 1);
8220 } else {
8221 tmp = tcg_temp_new_i32();
8222 tcg_gen_movi_i32(tmp, 0);
8223 }
8224 tmp3 = neon_load_reg(rm, 1);
8225 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
8226 tcg_temp_free_i32(tmp5);
8227 tcg_temp_free_ptr(ptr1);
8228 neon_store_reg(rd, 0, tmp2);
8229 neon_store_reg(rd, 1, tmp3);
8230 tcg_temp_free_i32(tmp);
8231 } else if ((insn & 0x380) == 0) {
8232 /* VDUP */
8233 int element;
8234 TCGMemOp size;
8235
8236 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
8237 return 1;
8238 }
8239 if (insn & (1 << 16)) {
8240 size = MO_8;
8241 element = (insn >> 17) & 7;
8242 } else if (insn & (1 << 17)) {
8243 size = MO_16;
8244 element = (insn >> 18) & 3;
8245 } else {
8246 size = MO_32;
8247 element = (insn >> 19) & 1;
8248 }
8249 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
8250 neon_element_offset(rm, element, size),
8251 q ? 16 : 8, q ? 16 : 8);
8252 } else {
8253 return 1;
8254 }
8255 }
8256 }
8257 return 0;
8258 }
8259
8260 /* Advanced SIMD three registers of the same length extension.
8261 * 31 25 23 22 20 16 12 11 10 9 8 3 0
8262 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8263 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8264 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8265 */
8266 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
8267 {
8268 gen_helper_gvec_3 *fn_gvec = NULL;
8269 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8270 int rd, rn, rm, opr_sz;
8271 int data = 0;
8272 bool q;
8273
8274 q = extract32(insn, 6, 1);
8275 VFP_DREG_D(rd, insn);
8276 VFP_DREG_N(rn, insn);
8277 VFP_DREG_M(rm, insn);
8278 if ((rd | rn | rm) & q) {
8279 return 1;
8280 }
8281
8282 if ((insn & 0xfe200f10) == 0xfc200800) {
8283 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8284 int size = extract32(insn, 20, 1);
8285 data = extract32(insn, 23, 2); /* rot */
8286 if (!dc_isar_feature(aa32_vcma, s)
8287 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8288 return 1;
8289 }
8290 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
8291 } else if ((insn & 0xfea00f10) == 0xfc800800) {
8292 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8293 int size = extract32(insn, 20, 1);
8294 data = extract32(insn, 24, 1); /* rot */
8295 if (!dc_isar_feature(aa32_vcma, s)
8296 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8297 return 1;
8298 }
8299 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
8300 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
8301 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8302 bool u = extract32(insn, 4, 1);
8303 if (!dc_isar_feature(aa32_dp, s)) {
8304 return 1;
8305 }
8306 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
8307 } else {
8308 return 1;
8309 }
8310
8311 if (s->fp_excp_el) {
8312 gen_exception_insn(s, 4, EXCP_UDEF,
8313 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8314 return 0;
8315 }
8316 if (!s->vfp_enabled) {
8317 return 1;
8318 }
8319
8320 opr_sz = (1 + q) * 8;
8321 if (fn_gvec_ptr) {
8322 TCGv_ptr fpst = get_fpstatus_ptr(1);
8323 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8324 vfp_reg_offset(1, rn),
8325 vfp_reg_offset(1, rm), fpst,
8326 opr_sz, opr_sz, data, fn_gvec_ptr);
8327 tcg_temp_free_ptr(fpst);
8328 } else {
8329 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8330 vfp_reg_offset(1, rn),
8331 vfp_reg_offset(1, rm),
8332 opr_sz, opr_sz, data, fn_gvec);
8333 }
8334 return 0;
8335 }
8336
8337 /* Advanced SIMD two registers and a scalar extension.
8338 * 31 24 23 22 20 16 12 11 10 9 8 3 0
8339 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8340 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8341 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8342 *
8343 */
8344
8345 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
8346 {
8347 gen_helper_gvec_3 *fn_gvec = NULL;
8348 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8349 int rd, rn, rm, opr_sz, data;
8350 bool q;
8351
8352 q = extract32(insn, 6, 1);
8353 VFP_DREG_D(rd, insn);
8354 VFP_DREG_N(rn, insn);
8355 if ((rd | rn) & q) {
8356 return 1;
8357 }
8358
8359 if ((insn & 0xff000f10) == 0xfe000800) {
8360 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8361 int rot = extract32(insn, 20, 2);
8362 int size = extract32(insn, 23, 1);
8363 int index;
8364
8365 if (!dc_isar_feature(aa32_vcma, s)) {
8366 return 1;
8367 }
8368 if (size == 0) {
8369 if (!dc_isar_feature(aa32_fp16_arith, s)) {
8370 return 1;
8371 }
8372 /* For fp16, rm is just Vm, and index is M. */
8373 rm = extract32(insn, 0, 4);
8374 index = extract32(insn, 5, 1);
8375 } else {
8376 /* For fp32, rm is the usual M:Vm, and index is 0. */
8377 VFP_DREG_M(rm, insn);
8378 index = 0;
8379 }
8380 data = (index << 2) | rot;
8381 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8382 : gen_helper_gvec_fcmlah_idx);
8383 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8384 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8385 int u = extract32(insn, 4, 1);
8386 if (!dc_isar_feature(aa32_dp, s)) {
8387 return 1;
8388 }
8389 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8390 /* rm is just Vm, and index is M. */
8391 data = extract32(insn, 5, 1); /* index */
8392 rm = extract32(insn, 0, 4);
8393 } else {
8394 return 1;
8395 }
8396
8397 if (s->fp_excp_el) {
8398 gen_exception_insn(s, 4, EXCP_UDEF,
8399 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8400 return 0;
8401 }
8402 if (!s->vfp_enabled) {
8403 return 1;
8404 }
8405
8406 opr_sz = (1 + q) * 8;
8407 if (fn_gvec_ptr) {
8408 TCGv_ptr fpst = get_fpstatus_ptr(1);
8409 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8410 vfp_reg_offset(1, rn),
8411 vfp_reg_offset(1, rm), fpst,
8412 opr_sz, opr_sz, data, fn_gvec_ptr);
8413 tcg_temp_free_ptr(fpst);
8414 } else {
8415 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8416 vfp_reg_offset(1, rn),
8417 vfp_reg_offset(1, rm),
8418 opr_sz, opr_sz, data, fn_gvec);
8419 }
8420 return 0;
8421 }
8422
8423 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8424 {
8425 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8426 const ARMCPRegInfo *ri;
8427
8428 cpnum = (insn >> 8) & 0xf;
8429
8430 /* First check for coprocessor space used for XScale/iwMMXt insns */
8431 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8432 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8433 return 1;
8434 }
8435 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8436 return disas_iwmmxt_insn(s, insn);
8437 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8438 return disas_dsp_insn(s, insn);
8439 }
8440 return 1;
8441 }
8442
8443 /* Otherwise treat as a generic register access */
8444 is64 = (insn & (1 << 25)) == 0;
8445 if (!is64 && ((insn & (1 << 4)) == 0)) {
8446 /* cdp */
8447 return 1;
8448 }
8449
8450 crm = insn & 0xf;
8451 if (is64) {
8452 crn = 0;
8453 opc1 = (insn >> 4) & 0xf;
8454 opc2 = 0;
8455 rt2 = (insn >> 16) & 0xf;
8456 } else {
8457 crn = (insn >> 16) & 0xf;
8458 opc1 = (insn >> 21) & 7;
8459 opc2 = (insn >> 5) & 7;
8460 rt2 = 0;
8461 }
8462 isread = (insn >> 20) & 1;
8463 rt = (insn >> 12) & 0xf;
8464
8465 ri = get_arm_cp_reginfo(s->cp_regs,
8466 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8467 if (ri) {
8468 /* Check access permissions */
8469 if (!cp_access_ok(s->current_el, ri, isread)) {
8470 return 1;
8471 }
8472
8473 if (ri->accessfn ||
8474 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8475 /* Emit code to perform further access permissions checks at
8476 * runtime; this may result in an exception.
8477 * Note that on XScale all cp0..c13 registers do an access check
8478 * call in order to handle c15_cpar.
8479 */
8480 TCGv_ptr tmpptr;
8481 TCGv_i32 tcg_syn, tcg_isread;
8482 uint32_t syndrome;
8483
8484 /* Note that since we are an implementation which takes an
8485 * exception on a trapped conditional instruction only if the
8486 * instruction passes its condition code check, we can take
8487 * advantage of the clause in the ARM ARM that allows us to set
8488 * the COND field in the instruction to 0xE in all cases.
8489 * We could fish the actual condition out of the insn (ARM)
8490 * or the condexec bits (Thumb) but it isn't necessary.
8491 */
8492 switch (cpnum) {
8493 case 14:
8494 if (is64) {
8495 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8496 isread, false);
8497 } else {
8498 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8499 rt, isread, false);
8500 }
8501 break;
8502 case 15:
8503 if (is64) {
8504 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8505 isread, false);
8506 } else {
8507 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8508 rt, isread, false);
8509 }
8510 break;
8511 default:
8512 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8513 * so this can only happen if this is an ARMv7 or earlier CPU,
8514 * in which case the syndrome information won't actually be
8515 * guest visible.
8516 */
8517 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8518 syndrome = syn_uncategorized();
8519 break;
8520 }
8521
8522 gen_set_condexec(s);
8523 gen_set_pc_im(s, s->pc - 4);
8524 tmpptr = tcg_const_ptr(ri);
8525 tcg_syn = tcg_const_i32(syndrome);
8526 tcg_isread = tcg_const_i32(isread);
8527 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8528 tcg_isread);
8529 tcg_temp_free_ptr(tmpptr);
8530 tcg_temp_free_i32(tcg_syn);
8531 tcg_temp_free_i32(tcg_isread);
8532 }
8533
8534 /* Handle special cases first */
8535 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8536 case ARM_CP_NOP:
8537 return 0;
8538 case ARM_CP_WFI:
8539 if (isread) {
8540 return 1;
8541 }
8542 gen_set_pc_im(s, s->pc);
8543 s->base.is_jmp = DISAS_WFI;
8544 return 0;
8545 default:
8546 break;
8547 }
8548
8549 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8550 gen_io_start();
8551 }
8552
8553 if (isread) {
8554 /* Read */
8555 if (is64) {
8556 TCGv_i64 tmp64;
8557 TCGv_i32 tmp;
8558 if (ri->type & ARM_CP_CONST) {
8559 tmp64 = tcg_const_i64(ri->resetvalue);
8560 } else if (ri->readfn) {
8561 TCGv_ptr tmpptr;
8562 tmp64 = tcg_temp_new_i64();
8563 tmpptr = tcg_const_ptr(ri);
8564 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8565 tcg_temp_free_ptr(tmpptr);
8566 } else {
8567 tmp64 = tcg_temp_new_i64();
8568 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8569 }
8570 tmp = tcg_temp_new_i32();
8571 tcg_gen_extrl_i64_i32(tmp, tmp64);
8572 store_reg(s, rt, tmp);
8573 tcg_gen_shri_i64(tmp64, tmp64, 32);
8574 tmp = tcg_temp_new_i32();
8575 tcg_gen_extrl_i64_i32(tmp, tmp64);
8576 tcg_temp_free_i64(tmp64);
8577 store_reg(s, rt2, tmp);
8578 } else {
8579 TCGv_i32 tmp;
8580 if (ri->type & ARM_CP_CONST) {
8581 tmp = tcg_const_i32(ri->resetvalue);
8582 } else if (ri->readfn) {
8583 TCGv_ptr tmpptr;
8584 tmp = tcg_temp_new_i32();
8585 tmpptr = tcg_const_ptr(ri);
8586 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8587 tcg_temp_free_ptr(tmpptr);
8588 } else {
8589 tmp = load_cpu_offset(ri->fieldoffset);
8590 }
8591 if (rt == 15) {
8592 /* Destination register of r15 for 32 bit loads sets
8593 * the condition codes from the high 4 bits of the value
8594 */
8595 gen_set_nzcv(tmp);
8596 tcg_temp_free_i32(tmp);
8597 } else {
8598 store_reg(s, rt, tmp);
8599 }
8600 }
8601 } else {
8602 /* Write */
8603 if (ri->type & ARM_CP_CONST) {
8604 /* If not forbidden by access permissions, treat as WI */
8605 return 0;
8606 }
8607
8608 if (is64) {
8609 TCGv_i32 tmplo, tmphi;
8610 TCGv_i64 tmp64 = tcg_temp_new_i64();
8611 tmplo = load_reg(s, rt);
8612 tmphi = load_reg(s, rt2);
8613 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8614 tcg_temp_free_i32(tmplo);
8615 tcg_temp_free_i32(tmphi);
8616 if (ri->writefn) {
8617 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8618 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8619 tcg_temp_free_ptr(tmpptr);
8620 } else {
8621 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8622 }
8623 tcg_temp_free_i64(tmp64);
8624 } else {
8625 if (ri->writefn) {
8626 TCGv_i32 tmp;
8627 TCGv_ptr tmpptr;
8628 tmp = load_reg(s, rt);
8629 tmpptr = tcg_const_ptr(ri);
8630 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8631 tcg_temp_free_ptr(tmpptr);
8632 tcg_temp_free_i32(tmp);
8633 } else {
8634 TCGv_i32 tmp = load_reg(s, rt);
8635 store_cpu_offset(tmp, ri->fieldoffset);
8636 }
8637 }
8638 }
8639
8640 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8641 /* I/O operations must end the TB here (whether read or write) */
8642 gen_io_end();
8643 gen_lookup_tb(s);
8644 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8645 /* We default to ending the TB on a coprocessor register write,
8646 * but allow this to be suppressed by the register definition
8647 * (usually only necessary to work around guest bugs).
8648 */
8649 gen_lookup_tb(s);
8650 }
8651
8652 return 0;
8653 }
8654
8655 /* Unknown register; this might be a guest error or a QEMU
8656 * unimplemented feature.
8657 */
8658 if (is64) {
8659 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8660 "64 bit system register cp:%d opc1: %d crm:%d "
8661 "(%s)\n",
8662 isread ? "read" : "write", cpnum, opc1, crm,
8663 s->ns ? "non-secure" : "secure");
8664 } else {
8665 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8666 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8667 "(%s)\n",
8668 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8669 s->ns ? "non-secure" : "secure");
8670 }
8671
8672 return 1;
8673 }
8674
8675
8676 /* Store a 64-bit value to a register pair. Clobbers val. */
8677 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8678 {
8679 TCGv_i32 tmp;
8680 tmp = tcg_temp_new_i32();
8681 tcg_gen_extrl_i64_i32(tmp, val);
8682 store_reg(s, rlow, tmp);
8683 tmp = tcg_temp_new_i32();
8684 tcg_gen_shri_i64(val, val, 32);
8685 tcg_gen_extrl_i64_i32(tmp, val);
8686 store_reg(s, rhigh, tmp);
8687 }
8688
8689 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8690 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8691 {
8692 TCGv_i64 tmp;
8693 TCGv_i32 tmp2;
8694
8695 /* Load value and extend to 64 bits. */
8696 tmp = tcg_temp_new_i64();
8697 tmp2 = load_reg(s, rlow);
8698 tcg_gen_extu_i32_i64(tmp, tmp2);
8699 tcg_temp_free_i32(tmp2);
8700 tcg_gen_add_i64(val, val, tmp);
8701 tcg_temp_free_i64(tmp);
8702 }
8703
8704 /* load and add a 64-bit value from a register pair. */
8705 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8706 {
8707 TCGv_i64 tmp;
8708 TCGv_i32 tmpl;
8709 TCGv_i32 tmph;
8710
8711 /* Load 64-bit value rd:rn. */
8712 tmpl = load_reg(s, rlow);
8713 tmph = load_reg(s, rhigh);
8714 tmp = tcg_temp_new_i64();
8715 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8716 tcg_temp_free_i32(tmpl);
8717 tcg_temp_free_i32(tmph);
8718 tcg_gen_add_i64(val, val, tmp);
8719 tcg_temp_free_i64(tmp);
8720 }
8721
8722 /* Set N and Z flags from hi|lo. */
8723 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8724 {
8725 tcg_gen_mov_i32(cpu_NF, hi);
8726 tcg_gen_or_i32(cpu_ZF, lo, hi);
8727 }
8728
8729 /* Load/Store exclusive instructions are implemented by remembering
8730 the value/address loaded, and seeing if these are the same
8731 when the store is performed. This should be sufficient to implement
8732 the architecturally mandated semantics, and avoids having to monitor
8733 regular stores. The compare vs the remembered value is done during
8734 the cmpxchg operation, but we must compare the addresses manually. */
8735 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8736 TCGv_i32 addr, int size)
8737 {
8738 TCGv_i32 tmp = tcg_temp_new_i32();
8739 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8740
8741 s->is_ldex = true;
8742
8743 if (size == 3) {
8744 TCGv_i32 tmp2 = tcg_temp_new_i32();
8745 TCGv_i64 t64 = tcg_temp_new_i64();
8746
8747 /* For AArch32, architecturally the 32-bit word at the lowest
8748 * address is always Rt and the one at addr+4 is Rt2, even if
8749 * the CPU is big-endian. That means we don't want to do a
8750 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8751 * for an architecturally 64-bit access, but instead do a
8752 * 64-bit access using MO_BE if appropriate and then split
8753 * the two halves.
8754 * This only makes a difference for BE32 user-mode, where
8755 * frob64() must not flip the two halves of the 64-bit data
8756 * but this code must treat BE32 user-mode like BE32 system.
8757 */
8758 TCGv taddr = gen_aa32_addr(s, addr, opc);
8759
8760 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8761 tcg_temp_free(taddr);
8762 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8763 if (s->be_data == MO_BE) {
8764 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8765 } else {
8766 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8767 }
8768 tcg_temp_free_i64(t64);
8769
8770 store_reg(s, rt2, tmp2);
8771 } else {
8772 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8773 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8774 }
8775
8776 store_reg(s, rt, tmp);
8777 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8778 }
8779
8780 static void gen_clrex(DisasContext *s)
8781 {
8782 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8783 }
8784
8785 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8786 TCGv_i32 addr, int size)
8787 {
8788 TCGv_i32 t0, t1, t2;
8789 TCGv_i64 extaddr;
8790 TCGv taddr;
8791 TCGLabel *done_label;
8792 TCGLabel *fail_label;
8793 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8794
8795 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8796 [addr] = {Rt};
8797 {Rd} = 0;
8798 } else {
8799 {Rd} = 1;
8800 } */
8801 fail_label = gen_new_label();
8802 done_label = gen_new_label();
8803 extaddr = tcg_temp_new_i64();
8804 tcg_gen_extu_i32_i64(extaddr, addr);
8805 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8806 tcg_temp_free_i64(extaddr);
8807
8808 taddr = gen_aa32_addr(s, addr, opc);
8809 t0 = tcg_temp_new_i32();
8810 t1 = load_reg(s, rt);
8811 if (size == 3) {
8812 TCGv_i64 o64 = tcg_temp_new_i64();
8813 TCGv_i64 n64 = tcg_temp_new_i64();
8814
8815 t2 = load_reg(s, rt2);
8816 /* For AArch32, architecturally the 32-bit word at the lowest
8817 * address is always Rt and the one at addr+4 is Rt2, even if
8818 * the CPU is big-endian. Since we're going to treat this as a
8819 * single 64-bit BE store, we need to put the two halves in the
8820 * opposite order for BE to LE, so that they end up in the right
8821 * places.
8822 * We don't want gen_aa32_frob64() because that does the wrong
8823 * thing for BE32 usermode.
8824 */
8825 if (s->be_data == MO_BE) {
8826 tcg_gen_concat_i32_i64(n64, t2, t1);
8827 } else {
8828 tcg_gen_concat_i32_i64(n64, t1, t2);
8829 }
8830 tcg_temp_free_i32(t2);
8831
8832 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8833 get_mem_index(s), opc);
8834 tcg_temp_free_i64(n64);
8835
8836 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8837 tcg_gen_extrl_i64_i32(t0, o64);
8838
8839 tcg_temp_free_i64(o64);
8840 } else {
8841 t2 = tcg_temp_new_i32();
8842 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8843 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8844 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8845 tcg_temp_free_i32(t2);
8846 }
8847 tcg_temp_free_i32(t1);
8848 tcg_temp_free(taddr);
8849 tcg_gen_mov_i32(cpu_R[rd], t0);
8850 tcg_temp_free_i32(t0);
8851 tcg_gen_br(done_label);
8852
8853 gen_set_label(fail_label);
8854 tcg_gen_movi_i32(cpu_R[rd], 1);
8855 gen_set_label(done_label);
8856 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8857 }
8858
8859 /* gen_srs:
8860 * @env: CPUARMState
8861 * @s: DisasContext
8862 * @mode: mode field from insn (which stack to store to)
8863 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8864 * @writeback: true if writeback bit set
8865 *
8866 * Generate code for the SRS (Store Return State) insn.
8867 */
8868 static void gen_srs(DisasContext *s,
8869 uint32_t mode, uint32_t amode, bool writeback)
8870 {
8871 int32_t offset;
8872 TCGv_i32 addr, tmp;
8873 bool undef = false;
8874
8875 /* SRS is:
8876 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8877 * and specified mode is monitor mode
8878 * - UNDEFINED in Hyp mode
8879 * - UNPREDICTABLE in User or System mode
8880 * - UNPREDICTABLE if the specified mode is:
8881 * -- not implemented
8882 * -- not a valid mode number
8883 * -- a mode that's at a higher exception level
8884 * -- Monitor, if we are Non-secure
8885 * For the UNPREDICTABLE cases we choose to UNDEF.
8886 */
8887 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8888 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8889 return;
8890 }
8891
8892 if (s->current_el == 0 || s->current_el == 2) {
8893 undef = true;
8894 }
8895
8896 switch (mode) {
8897 case ARM_CPU_MODE_USR:
8898 case ARM_CPU_MODE_FIQ:
8899 case ARM_CPU_MODE_IRQ:
8900 case ARM_CPU_MODE_SVC:
8901 case ARM_CPU_MODE_ABT:
8902 case ARM_CPU_MODE_UND:
8903 case ARM_CPU_MODE_SYS:
8904 break;
8905 case ARM_CPU_MODE_HYP:
8906 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8907 undef = true;
8908 }
8909 break;
8910 case ARM_CPU_MODE_MON:
8911 /* No need to check specifically for "are we non-secure" because
8912 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8913 * so if this isn't EL3 then we must be non-secure.
8914 */
8915 if (s->current_el != 3) {
8916 undef = true;
8917 }
8918 break;
8919 default:
8920 undef = true;
8921 }
8922
8923 if (undef) {
8924 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8925 default_exception_el(s));
8926 return;
8927 }
8928
8929 addr = tcg_temp_new_i32();
8930 tmp = tcg_const_i32(mode);
8931 /* get_r13_banked() will raise an exception if called from System mode */
8932 gen_set_condexec(s);
8933 gen_set_pc_im(s, s->pc - 4);
8934 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8935 tcg_temp_free_i32(tmp);
8936 switch (amode) {
8937 case 0: /* DA */
8938 offset = -4;
8939 break;
8940 case 1: /* IA */
8941 offset = 0;
8942 break;
8943 case 2: /* DB */
8944 offset = -8;
8945 break;
8946 case 3: /* IB */
8947 offset = 4;
8948 break;
8949 default:
8950 abort();
8951 }
8952 tcg_gen_addi_i32(addr, addr, offset);
8953 tmp = load_reg(s, 14);
8954 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8955 tcg_temp_free_i32(tmp);
8956 tmp = load_cpu_field(spsr);
8957 tcg_gen_addi_i32(addr, addr, 4);
8958 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8959 tcg_temp_free_i32(tmp);
8960 if (writeback) {
8961 switch (amode) {
8962 case 0:
8963 offset = -8;
8964 break;
8965 case 1:
8966 offset = 4;
8967 break;
8968 case 2:
8969 offset = -4;
8970 break;
8971 case 3:
8972 offset = 0;
8973 break;
8974 default:
8975 abort();
8976 }
8977 tcg_gen_addi_i32(addr, addr, offset);
8978 tmp = tcg_const_i32(mode);
8979 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8980 tcg_temp_free_i32(tmp);
8981 }
8982 tcg_temp_free_i32(addr);
8983 s->base.is_jmp = DISAS_UPDATE;
8984 }
8985
8986 /* Generate a label used for skipping this instruction */
8987 static void arm_gen_condlabel(DisasContext *s)
8988 {
8989 if (!s->condjmp) {
8990 s->condlabel = gen_new_label();
8991 s->condjmp = 1;
8992 }
8993 }
8994
8995 /* Skip this instruction if the ARM condition is false */
8996 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8997 {
8998 arm_gen_condlabel(s);
8999 arm_gen_test_cc(cond ^ 1, s->condlabel);
9000 }
9001
9002 static void disas_arm_insn(DisasContext *s, unsigned int insn)
9003 {
9004 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
9005 TCGv_i32 tmp;
9006 TCGv_i32 tmp2;
9007 TCGv_i32 tmp3;
9008 TCGv_i32 addr;
9009 TCGv_i64 tmp64;
9010
9011 /* M variants do not implement ARM mode; this must raise the INVSTATE
9012 * UsageFault exception.
9013 */
9014 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9015 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
9016 default_exception_el(s));
9017 return;
9018 }
9019 cond = insn >> 28;
9020 if (cond == 0xf){
9021 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9022 * choose to UNDEF. In ARMv5 and above the space is used
9023 * for miscellaneous unconditional instructions.
9024 */
9025 ARCH(5);
9026
9027 /* Unconditional instructions. */
9028 if (((insn >> 25) & 7) == 1) {
9029 /* NEON Data processing. */
9030 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9031 goto illegal_op;
9032 }
9033
9034 if (disas_neon_data_insn(s, insn)) {
9035 goto illegal_op;
9036 }
9037 return;
9038 }
9039 if ((insn & 0x0f100000) == 0x04000000) {
9040 /* NEON load/store. */
9041 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9042 goto illegal_op;
9043 }
9044
9045 if (disas_neon_ls_insn(s, insn)) {
9046 goto illegal_op;
9047 }
9048 return;
9049 }
9050 if ((insn & 0x0f000e10) == 0x0e000a00) {
9051 /* VFP. */
9052 if (disas_vfp_insn(s, insn)) {
9053 goto illegal_op;
9054 }
9055 return;
9056 }
9057 if (((insn & 0x0f30f000) == 0x0510f000) ||
9058 ((insn & 0x0f30f010) == 0x0710f000)) {
9059 if ((insn & (1 << 22)) == 0) {
9060 /* PLDW; v7MP */
9061 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9062 goto illegal_op;
9063 }
9064 }
9065 /* Otherwise PLD; v5TE+ */
9066 ARCH(5TE);
9067 return;
9068 }
9069 if (((insn & 0x0f70f000) == 0x0450f000) ||
9070 ((insn & 0x0f70f010) == 0x0650f000)) {
9071 ARCH(7);
9072 return; /* PLI; V7 */
9073 }
9074 if (((insn & 0x0f700000) == 0x04100000) ||
9075 ((insn & 0x0f700010) == 0x06100000)) {
9076 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9077 goto illegal_op;
9078 }
9079 return; /* v7MP: Unallocated memory hint: must NOP */
9080 }
9081
9082 if ((insn & 0x0ffffdff) == 0x01010000) {
9083 ARCH(6);
9084 /* setend */
9085 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
9086 gen_helper_setend(cpu_env);
9087 s->base.is_jmp = DISAS_UPDATE;
9088 }
9089 return;
9090 } else if ((insn & 0x0fffff00) == 0x057ff000) {
9091 switch ((insn >> 4) & 0xf) {
9092 case 1: /* clrex */
9093 ARCH(6K);
9094 gen_clrex(s);
9095 return;
9096 case 4: /* dsb */
9097 case 5: /* dmb */
9098 ARCH(7);
9099 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9100 return;
9101 case 6: /* isb */
9102 /* We need to break the TB after this insn to execute
9103 * self-modifying code correctly and also to take
9104 * any pending interrupts immediately.
9105 */
9106 gen_goto_tb(s, 0, s->pc & ~1);
9107 return;
9108 default:
9109 goto illegal_op;
9110 }
9111 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
9112 /* srs */
9113 ARCH(6);
9114 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
9115 return;
9116 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
9117 /* rfe */
9118 int32_t offset;
9119 if (IS_USER(s))
9120 goto illegal_op;
9121 ARCH(6);
9122 rn = (insn >> 16) & 0xf;
9123 addr = load_reg(s, rn);
9124 i = (insn >> 23) & 3;
9125 switch (i) {
9126 case 0: offset = -4; break; /* DA */
9127 case 1: offset = 0; break; /* IA */
9128 case 2: offset = -8; break; /* DB */
9129 case 3: offset = 4; break; /* IB */
9130 default: abort();
9131 }
9132 if (offset)
9133 tcg_gen_addi_i32(addr, addr, offset);
9134 /* Load PC into tmp and CPSR into tmp2. */
9135 tmp = tcg_temp_new_i32();
9136 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9137 tcg_gen_addi_i32(addr, addr, 4);
9138 tmp2 = tcg_temp_new_i32();
9139 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9140 if (insn & (1 << 21)) {
9141 /* Base writeback. */
9142 switch (i) {
9143 case 0: offset = -8; break;
9144 case 1: offset = 4; break;
9145 case 2: offset = -4; break;
9146 case 3: offset = 0; break;
9147 default: abort();
9148 }
9149 if (offset)
9150 tcg_gen_addi_i32(addr, addr, offset);
9151 store_reg(s, rn, addr);
9152 } else {
9153 tcg_temp_free_i32(addr);
9154 }
9155 gen_rfe(s, tmp, tmp2);
9156 return;
9157 } else if ((insn & 0x0e000000) == 0x0a000000) {
9158 /* branch link and change to thumb (blx <offset>) */
9159 int32_t offset;
9160
9161 val = (uint32_t)s->pc;
9162 tmp = tcg_temp_new_i32();
9163 tcg_gen_movi_i32(tmp, val);
9164 store_reg(s, 14, tmp);
9165 /* Sign-extend the 24-bit offset */
9166 offset = (((int32_t)insn) << 8) >> 8;
9167 /* offset * 4 + bit24 * 2 + (thumb bit) */
9168 val += (offset << 2) | ((insn >> 23) & 2) | 1;
9169 /* pipeline offset */
9170 val += 4;
9171 /* protected by ARCH(5); above, near the start of uncond block */
9172 gen_bx_im(s, val);
9173 return;
9174 } else if ((insn & 0x0e000f00) == 0x0c000100) {
9175 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9176 /* iWMMXt register transfer. */
9177 if (extract32(s->c15_cpar, 1, 1)) {
9178 if (!disas_iwmmxt_insn(s, insn)) {
9179 return;
9180 }
9181 }
9182 }
9183 } else if ((insn & 0x0e000a00) == 0x0c000800
9184 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9185 if (disas_neon_insn_3same_ext(s, insn)) {
9186 goto illegal_op;
9187 }
9188 return;
9189 } else if ((insn & 0x0f000a00) == 0x0e000800
9190 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9191 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
9192 goto illegal_op;
9193 }
9194 return;
9195 } else if ((insn & 0x0fe00000) == 0x0c400000) {
9196 /* Coprocessor double register transfer. */
9197 ARCH(5TE);
9198 } else if ((insn & 0x0f000010) == 0x0e000010) {
9199 /* Additional coprocessor register transfer. */
9200 } else if ((insn & 0x0ff10020) == 0x01000000) {
9201 uint32_t mask;
9202 uint32_t val;
9203 /* cps (privileged) */
9204 if (IS_USER(s))
9205 return;
9206 mask = val = 0;
9207 if (insn & (1 << 19)) {
9208 if (insn & (1 << 8))
9209 mask |= CPSR_A;
9210 if (insn & (1 << 7))
9211 mask |= CPSR_I;
9212 if (insn & (1 << 6))
9213 mask |= CPSR_F;
9214 if (insn & (1 << 18))
9215 val |= mask;
9216 }
9217 if (insn & (1 << 17)) {
9218 mask |= CPSR_M;
9219 val |= (insn & 0x1f);
9220 }
9221 if (mask) {
9222 gen_set_psr_im(s, mask, 0, val);
9223 }
9224 return;
9225 }
9226 goto illegal_op;
9227 }
9228 if (cond != 0xe) {
9229 /* if not always execute, we generate a conditional jump to
9230 next instruction */
9231 arm_skip_unless(s, cond);
9232 }
9233 if ((insn & 0x0f900000) == 0x03000000) {
9234 if ((insn & (1 << 21)) == 0) {
9235 ARCH(6T2);
9236 rd = (insn >> 12) & 0xf;
9237 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
9238 if ((insn & (1 << 22)) == 0) {
9239 /* MOVW */
9240 tmp = tcg_temp_new_i32();
9241 tcg_gen_movi_i32(tmp, val);
9242 } else {
9243 /* MOVT */
9244 tmp = load_reg(s, rd);
9245 tcg_gen_ext16u_i32(tmp, tmp);
9246 tcg_gen_ori_i32(tmp, tmp, val << 16);
9247 }
9248 store_reg(s, rd, tmp);
9249 } else {
9250 if (((insn >> 12) & 0xf) != 0xf)
9251 goto illegal_op;
9252 if (((insn >> 16) & 0xf) == 0) {
9253 gen_nop_hint(s, insn & 0xff);
9254 } else {
9255 /* CPSR = immediate */
9256 val = insn & 0xff;
9257 shift = ((insn >> 8) & 0xf) * 2;
9258 if (shift)
9259 val = (val >> shift) | (val << (32 - shift));
9260 i = ((insn & (1 << 22)) != 0);
9261 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
9262 i, val)) {
9263 goto illegal_op;
9264 }
9265 }
9266 }
9267 } else if ((insn & 0x0f900000) == 0x01000000
9268 && (insn & 0x00000090) != 0x00000090) {
9269 /* miscellaneous instructions */
9270 op1 = (insn >> 21) & 3;
9271 sh = (insn >> 4) & 0xf;
9272 rm = insn & 0xf;
9273 switch (sh) {
9274 case 0x0: /* MSR, MRS */
9275 if (insn & (1 << 9)) {
9276 /* MSR (banked) and MRS (banked) */
9277 int sysm = extract32(insn, 16, 4) |
9278 (extract32(insn, 8, 1) << 4);
9279 int r = extract32(insn, 22, 1);
9280
9281 if (op1 & 1) {
9282 /* MSR (banked) */
9283 gen_msr_banked(s, r, sysm, rm);
9284 } else {
9285 /* MRS (banked) */
9286 int rd = extract32(insn, 12, 4);
9287
9288 gen_mrs_banked(s, r, sysm, rd);
9289 }
9290 break;
9291 }
9292
9293 /* MSR, MRS (for PSRs) */
9294 if (op1 & 1) {
9295 /* PSR = reg */
9296 tmp = load_reg(s, rm);
9297 i = ((op1 & 2) != 0);
9298 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
9299 goto illegal_op;
9300 } else {
9301 /* reg = PSR */
9302 rd = (insn >> 12) & 0xf;
9303 if (op1 & 2) {
9304 if (IS_USER(s))
9305 goto illegal_op;
9306 tmp = load_cpu_field(spsr);
9307 } else {
9308 tmp = tcg_temp_new_i32();
9309 gen_helper_cpsr_read(tmp, cpu_env);
9310 }
9311 store_reg(s, rd, tmp);
9312 }
9313 break;
9314 case 0x1:
9315 if (op1 == 1) {
9316 /* branch/exchange thumb (bx). */
9317 ARCH(4T);
9318 tmp = load_reg(s, rm);
9319 gen_bx(s, tmp);
9320 } else if (op1 == 3) {
9321 /* clz */
9322 ARCH(5);
9323 rd = (insn >> 12) & 0xf;
9324 tmp = load_reg(s, rm);
9325 tcg_gen_clzi_i32(tmp, tmp, 32);
9326 store_reg(s, rd, tmp);
9327 } else {
9328 goto illegal_op;
9329 }
9330 break;
9331 case 0x2:
9332 if (op1 == 1) {
9333 ARCH(5J); /* bxj */
9334 /* Trivial implementation equivalent to bx. */
9335 tmp = load_reg(s, rm);
9336 gen_bx(s, tmp);
9337 } else {
9338 goto illegal_op;
9339 }
9340 break;
9341 case 0x3:
9342 if (op1 != 1)
9343 goto illegal_op;
9344
9345 ARCH(5);
9346 /* branch link/exchange thumb (blx) */
9347 tmp = load_reg(s, rm);
9348 tmp2 = tcg_temp_new_i32();
9349 tcg_gen_movi_i32(tmp2, s->pc);
9350 store_reg(s, 14, tmp2);
9351 gen_bx(s, tmp);
9352 break;
9353 case 0x4:
9354 {
9355 /* crc32/crc32c */
9356 uint32_t c = extract32(insn, 8, 4);
9357
9358 /* Check this CPU supports ARMv8 CRC instructions.
9359 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9360 * Bits 8, 10 and 11 should be zero.
9361 */
9362 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9363 goto illegal_op;
9364 }
9365
9366 rn = extract32(insn, 16, 4);
9367 rd = extract32(insn, 12, 4);
9368
9369 tmp = load_reg(s, rn);
9370 tmp2 = load_reg(s, rm);
9371 if (op1 == 0) {
9372 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9373 } else if (op1 == 1) {
9374 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9375 }
9376 tmp3 = tcg_const_i32(1 << op1);
9377 if (c & 0x2) {
9378 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9379 } else {
9380 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9381 }
9382 tcg_temp_free_i32(tmp2);
9383 tcg_temp_free_i32(tmp3);
9384 store_reg(s, rd, tmp);
9385 break;
9386 }
9387 case 0x5: /* saturating add/subtract */
9388 ARCH(5TE);
9389 rd = (insn >> 12) & 0xf;
9390 rn = (insn >> 16) & 0xf;
9391 tmp = load_reg(s, rm);
9392 tmp2 = load_reg(s, rn);
9393 if (op1 & 2)
9394 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9395 if (op1 & 1)
9396 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9397 else
9398 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9399 tcg_temp_free_i32(tmp2);
9400 store_reg(s, rd, tmp);
9401 break;
9402 case 0x6: /* ERET */
9403 if (op1 != 3) {
9404 goto illegal_op;
9405 }
9406 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9407 goto illegal_op;
9408 }
9409 if ((insn & 0x000fff0f) != 0x0000000e) {
9410 /* UNPREDICTABLE; we choose to UNDEF */
9411 goto illegal_op;
9412 }
9413
9414 if (s->current_el == 2) {
9415 tmp = load_cpu_field(elr_el[2]);
9416 } else {
9417 tmp = load_reg(s, 14);
9418 }
9419 gen_exception_return(s, tmp);
9420 break;
9421 case 7:
9422 {
9423 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9424 switch (op1) {
9425 case 0:
9426 /* HLT */
9427 gen_hlt(s, imm16);
9428 break;
9429 case 1:
9430 /* bkpt */
9431 ARCH(5);
9432 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9433 break;
9434 case 2:
9435 /* Hypervisor call (v7) */
9436 ARCH(7);
9437 if (IS_USER(s)) {
9438 goto illegal_op;
9439 }
9440 gen_hvc(s, imm16);
9441 break;
9442 case 3:
9443 /* Secure monitor call (v6+) */
9444 ARCH(6K);
9445 if (IS_USER(s)) {
9446 goto illegal_op;
9447 }
9448 gen_smc(s);
9449 break;
9450 default:
9451 g_assert_not_reached();
9452 }
9453 break;
9454 }
9455 case 0x8: /* signed multiply */
9456 case 0xa:
9457 case 0xc:
9458 case 0xe:
9459 ARCH(5TE);
9460 rs = (insn >> 8) & 0xf;
9461 rn = (insn >> 12) & 0xf;
9462 rd = (insn >> 16) & 0xf;
9463 if (op1 == 1) {
9464 /* (32 * 16) >> 16 */
9465 tmp = load_reg(s, rm);
9466 tmp2 = load_reg(s, rs);
9467 if (sh & 4)
9468 tcg_gen_sari_i32(tmp2, tmp2, 16);
9469 else
9470 gen_sxth(tmp2);
9471 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9472 tcg_gen_shri_i64(tmp64, tmp64, 16);
9473 tmp = tcg_temp_new_i32();
9474 tcg_gen_extrl_i64_i32(tmp, tmp64);
9475 tcg_temp_free_i64(tmp64);
9476 if ((sh & 2) == 0) {
9477 tmp2 = load_reg(s, rn);
9478 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9479 tcg_temp_free_i32(tmp2);
9480 }
9481 store_reg(s, rd, tmp);
9482 } else {
9483 /* 16 * 16 */
9484 tmp = load_reg(s, rm);
9485 tmp2 = load_reg(s, rs);
9486 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9487 tcg_temp_free_i32(tmp2);
9488 if (op1 == 2) {
9489 tmp64 = tcg_temp_new_i64();
9490 tcg_gen_ext_i32_i64(tmp64, tmp);
9491 tcg_temp_free_i32(tmp);
9492 gen_addq(s, tmp64, rn, rd);
9493 gen_storeq_reg(s, rn, rd, tmp64);
9494 tcg_temp_free_i64(tmp64);
9495 } else {
9496 if (op1 == 0) {
9497 tmp2 = load_reg(s, rn);
9498 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9499 tcg_temp_free_i32(tmp2);
9500 }
9501 store_reg(s, rd, tmp);
9502 }
9503 }
9504 break;
9505 default:
9506 goto illegal_op;
9507 }
9508 } else if (((insn & 0x0e000000) == 0 &&
9509 (insn & 0x00000090) != 0x90) ||
9510 ((insn & 0x0e000000) == (1 << 25))) {
9511 int set_cc, logic_cc, shiftop;
9512
9513 op1 = (insn >> 21) & 0xf;
9514 set_cc = (insn >> 20) & 1;
9515 logic_cc = table_logic_cc[op1] & set_cc;
9516
9517 /* data processing instruction */
9518 if (insn & (1 << 25)) {
9519 /* immediate operand */
9520 val = insn & 0xff;
9521 shift = ((insn >> 8) & 0xf) * 2;
9522 if (shift) {
9523 val = (val >> shift) | (val << (32 - shift));
9524 }
9525 tmp2 = tcg_temp_new_i32();
9526 tcg_gen_movi_i32(tmp2, val);
9527 if (logic_cc && shift) {
9528 gen_set_CF_bit31(tmp2);
9529 }
9530 } else {
9531 /* register */
9532 rm = (insn) & 0xf;
9533 tmp2 = load_reg(s, rm);
9534 shiftop = (insn >> 5) & 3;
9535 if (!(insn & (1 << 4))) {
9536 shift = (insn >> 7) & 0x1f;
9537 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9538 } else {
9539 rs = (insn >> 8) & 0xf;
9540 tmp = load_reg(s, rs);
9541 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9542 }
9543 }
9544 if (op1 != 0x0f && op1 != 0x0d) {
9545 rn = (insn >> 16) & 0xf;
9546 tmp = load_reg(s, rn);
9547 } else {
9548 tmp = NULL;
9549 }
9550 rd = (insn >> 12) & 0xf;
9551 switch(op1) {
9552 case 0x00:
9553 tcg_gen_and_i32(tmp, tmp, tmp2);
9554 if (logic_cc) {
9555 gen_logic_CC(tmp);
9556 }
9557 store_reg_bx(s, rd, tmp);
9558 break;
9559 case 0x01:
9560 tcg_gen_xor_i32(tmp, tmp, tmp2);
9561 if (logic_cc) {
9562 gen_logic_CC(tmp);
9563 }
9564 store_reg_bx(s, rd, tmp);
9565 break;
9566 case 0x02:
9567 if (set_cc && rd == 15) {
9568 /* SUBS r15, ... is used for exception return. */
9569 if (IS_USER(s)) {
9570 goto illegal_op;
9571 }
9572 gen_sub_CC(tmp, tmp, tmp2);
9573 gen_exception_return(s, tmp);
9574 } else {
9575 if (set_cc) {
9576 gen_sub_CC(tmp, tmp, tmp2);
9577 } else {
9578 tcg_gen_sub_i32(tmp, tmp, tmp2);
9579 }
9580 store_reg_bx(s, rd, tmp);
9581 }
9582 break;
9583 case 0x03:
9584 if (set_cc) {
9585 gen_sub_CC(tmp, tmp2, tmp);
9586 } else {
9587 tcg_gen_sub_i32(tmp, tmp2, tmp);
9588 }
9589 store_reg_bx(s, rd, tmp);
9590 break;
9591 case 0x04:
9592 if (set_cc) {
9593 gen_add_CC(tmp, tmp, tmp2);
9594 } else {
9595 tcg_gen_add_i32(tmp, tmp, tmp2);
9596 }
9597 store_reg_bx(s, rd, tmp);
9598 break;
9599 case 0x05:
9600 if (set_cc) {
9601 gen_adc_CC(tmp, tmp, tmp2);
9602 } else {
9603 gen_add_carry(tmp, tmp, tmp2);
9604 }
9605 store_reg_bx(s, rd, tmp);
9606 break;
9607 case 0x06:
9608 if (set_cc) {
9609 gen_sbc_CC(tmp, tmp, tmp2);
9610 } else {
9611 gen_sub_carry(tmp, tmp, tmp2);
9612 }
9613 store_reg_bx(s, rd, tmp);
9614 break;
9615 case 0x07:
9616 if (set_cc) {
9617 gen_sbc_CC(tmp, tmp2, tmp);
9618 } else {
9619 gen_sub_carry(tmp, tmp2, tmp);
9620 }
9621 store_reg_bx(s, rd, tmp);
9622 break;
9623 case 0x08:
9624 if (set_cc) {
9625 tcg_gen_and_i32(tmp, tmp, tmp2);
9626 gen_logic_CC(tmp);
9627 }
9628 tcg_temp_free_i32(tmp);
9629 break;
9630 case 0x09:
9631 if (set_cc) {
9632 tcg_gen_xor_i32(tmp, tmp, tmp2);
9633 gen_logic_CC(tmp);
9634 }
9635 tcg_temp_free_i32(tmp);
9636 break;
9637 case 0x0a:
9638 if (set_cc) {
9639 gen_sub_CC(tmp, tmp, tmp2);
9640 }
9641 tcg_temp_free_i32(tmp);
9642 break;
9643 case 0x0b:
9644 if (set_cc) {
9645 gen_add_CC(tmp, tmp, tmp2);
9646 }
9647 tcg_temp_free_i32(tmp);
9648 break;
9649 case 0x0c:
9650 tcg_gen_or_i32(tmp, tmp, tmp2);
9651 if (logic_cc) {
9652 gen_logic_CC(tmp);
9653 }
9654 store_reg_bx(s, rd, tmp);
9655 break;
9656 case 0x0d:
9657 if (logic_cc && rd == 15) {
9658 /* MOVS r15, ... is used for exception return. */
9659 if (IS_USER(s)) {
9660 goto illegal_op;
9661 }
9662 gen_exception_return(s, tmp2);
9663 } else {
9664 if (logic_cc) {
9665 gen_logic_CC(tmp2);
9666 }
9667 store_reg_bx(s, rd, tmp2);
9668 }
9669 break;
9670 case 0x0e:
9671 tcg_gen_andc_i32(tmp, tmp, tmp2);
9672 if (logic_cc) {
9673 gen_logic_CC(tmp);
9674 }
9675 store_reg_bx(s, rd, tmp);
9676 break;
9677 default:
9678 case 0x0f:
9679 tcg_gen_not_i32(tmp2, tmp2);
9680 if (logic_cc) {
9681 gen_logic_CC(tmp2);
9682 }
9683 store_reg_bx(s, rd, tmp2);
9684 break;
9685 }
9686 if (op1 != 0x0f && op1 != 0x0d) {
9687 tcg_temp_free_i32(tmp2);
9688 }
9689 } else {
9690 /* other instructions */
9691 op1 = (insn >> 24) & 0xf;
9692 switch(op1) {
9693 case 0x0:
9694 case 0x1:
9695 /* multiplies, extra load/stores */
9696 sh = (insn >> 5) & 3;
9697 if (sh == 0) {
9698 if (op1 == 0x0) {
9699 rd = (insn >> 16) & 0xf;
9700 rn = (insn >> 12) & 0xf;
9701 rs = (insn >> 8) & 0xf;
9702 rm = (insn) & 0xf;
9703 op1 = (insn >> 20) & 0xf;
9704 switch (op1) {
9705 case 0: case 1: case 2: case 3: case 6:
9706 /* 32 bit mul */
9707 tmp = load_reg(s, rs);
9708 tmp2 = load_reg(s, rm);
9709 tcg_gen_mul_i32(tmp, tmp, tmp2);
9710 tcg_temp_free_i32(tmp2);
9711 if (insn & (1 << 22)) {
9712 /* Subtract (mls) */
9713 ARCH(6T2);
9714 tmp2 = load_reg(s, rn);
9715 tcg_gen_sub_i32(tmp, tmp2, tmp);
9716 tcg_temp_free_i32(tmp2);
9717 } else if (insn & (1 << 21)) {
9718 /* Add */
9719 tmp2 = load_reg(s, rn);
9720 tcg_gen_add_i32(tmp, tmp, tmp2);
9721 tcg_temp_free_i32(tmp2);
9722 }
9723 if (insn & (1 << 20))
9724 gen_logic_CC(tmp);
9725 store_reg(s, rd, tmp);
9726 break;
9727 case 4:
9728 /* 64 bit mul double accumulate (UMAAL) */
9729 ARCH(6);
9730 tmp = load_reg(s, rs);
9731 tmp2 = load_reg(s, rm);
9732 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9733 gen_addq_lo(s, tmp64, rn);
9734 gen_addq_lo(s, tmp64, rd);
9735 gen_storeq_reg(s, rn, rd, tmp64);
9736 tcg_temp_free_i64(tmp64);
9737 break;
9738 case 8: case 9: case 10: case 11:
9739 case 12: case 13: case 14: case 15:
9740 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9741 tmp = load_reg(s, rs);
9742 tmp2 = load_reg(s, rm);
9743 if (insn & (1 << 22)) {
9744 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9745 } else {
9746 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9747 }
9748 if (insn & (1 << 21)) { /* mult accumulate */
9749 TCGv_i32 al = load_reg(s, rn);
9750 TCGv_i32 ah = load_reg(s, rd);
9751 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9752 tcg_temp_free_i32(al);
9753 tcg_temp_free_i32(ah);
9754 }
9755 if (insn & (1 << 20)) {
9756 gen_logicq_cc(tmp, tmp2);
9757 }
9758 store_reg(s, rn, tmp);
9759 store_reg(s, rd, tmp2);
9760 break;
9761 default:
9762 goto illegal_op;
9763 }
9764 } else {
9765 rn = (insn >> 16) & 0xf;
9766 rd = (insn >> 12) & 0xf;
9767 if (insn & (1 << 23)) {
9768 /* load/store exclusive */
9769 int op2 = (insn >> 8) & 3;
9770 op1 = (insn >> 21) & 0x3;
9771
9772 switch (op2) {
9773 case 0: /* lda/stl */
9774 if (op1 == 1) {
9775 goto illegal_op;
9776 }
9777 ARCH(8);
9778 break;
9779 case 1: /* reserved */
9780 goto illegal_op;
9781 case 2: /* ldaex/stlex */
9782 ARCH(8);
9783 break;
9784 case 3: /* ldrex/strex */
9785 if (op1) {
9786 ARCH(6K);
9787 } else {
9788 ARCH(6);
9789 }
9790 break;
9791 }
9792
9793 addr = tcg_temp_local_new_i32();
9794 load_reg_var(s, addr, rn);
9795
9796 /* Since the emulation does not have barriers,
9797 the acquire/release semantics need no special
9798 handling */
9799 if (op2 == 0) {
9800 if (insn & (1 << 20)) {
9801 tmp = tcg_temp_new_i32();
9802 switch (op1) {
9803 case 0: /* lda */
9804 gen_aa32_ld32u_iss(s, tmp, addr,
9805 get_mem_index(s),
9806 rd | ISSIsAcqRel);
9807 break;
9808 case 2: /* ldab */
9809 gen_aa32_ld8u_iss(s, tmp, addr,
9810 get_mem_index(s),
9811 rd | ISSIsAcqRel);
9812 break;
9813 case 3: /* ldah */
9814 gen_aa32_ld16u_iss(s, tmp, addr,
9815 get_mem_index(s),
9816 rd | ISSIsAcqRel);
9817 break;
9818 default:
9819 abort();
9820 }
9821 store_reg(s, rd, tmp);
9822 } else {
9823 rm = insn & 0xf;
9824 tmp = load_reg(s, rm);
9825 switch (op1) {
9826 case 0: /* stl */
9827 gen_aa32_st32_iss(s, tmp, addr,
9828 get_mem_index(s),
9829 rm | ISSIsAcqRel);
9830 break;
9831 case 2: /* stlb */
9832 gen_aa32_st8_iss(s, tmp, addr,
9833 get_mem_index(s),
9834 rm | ISSIsAcqRel);
9835 break;
9836 case 3: /* stlh */
9837 gen_aa32_st16_iss(s, tmp, addr,
9838 get_mem_index(s),
9839 rm | ISSIsAcqRel);
9840 break;
9841 default:
9842 abort();
9843 }
9844 tcg_temp_free_i32(tmp);
9845 }
9846 } else if (insn & (1 << 20)) {
9847 switch (op1) {
9848 case 0: /* ldrex */
9849 gen_load_exclusive(s, rd, 15, addr, 2);
9850 break;
9851 case 1: /* ldrexd */
9852 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9853 break;
9854 case 2: /* ldrexb */
9855 gen_load_exclusive(s, rd, 15, addr, 0);
9856 break;
9857 case 3: /* ldrexh */
9858 gen_load_exclusive(s, rd, 15, addr, 1);
9859 break;
9860 default:
9861 abort();
9862 }
9863 } else {
9864 rm = insn & 0xf;
9865 switch (op1) {
9866 case 0: /* strex */
9867 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9868 break;
9869 case 1: /* strexd */
9870 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9871 break;
9872 case 2: /* strexb */
9873 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9874 break;
9875 case 3: /* strexh */
9876 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9877 break;
9878 default:
9879 abort();
9880 }
9881 }
9882 tcg_temp_free_i32(addr);
9883 } else if ((insn & 0x00300f00) == 0) {
9884 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9885 * - SWP, SWPB
9886 */
9887
9888 TCGv taddr;
9889 TCGMemOp opc = s->be_data;
9890
9891 rm = (insn) & 0xf;
9892
9893 if (insn & (1 << 22)) {
9894 opc |= MO_UB;
9895 } else {
9896 opc |= MO_UL | MO_ALIGN;
9897 }
9898
9899 addr = load_reg(s, rn);
9900 taddr = gen_aa32_addr(s, addr, opc);
9901 tcg_temp_free_i32(addr);
9902
9903 tmp = load_reg(s, rm);
9904 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9905 get_mem_index(s), opc);
9906 tcg_temp_free(taddr);
9907 store_reg(s, rd, tmp);
9908 } else {
9909 goto illegal_op;
9910 }
9911 }
9912 } else {
9913 int address_offset;
9914 bool load = insn & (1 << 20);
9915 bool wbit = insn & (1 << 21);
9916 bool pbit = insn & (1 << 24);
9917 bool doubleword = false;
9918 ISSInfo issinfo;
9919
9920 /* Misc load/store */
9921 rn = (insn >> 16) & 0xf;
9922 rd = (insn >> 12) & 0xf;
9923
9924 /* ISS not valid if writeback */
9925 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9926
9927 if (!load && (sh & 2)) {
9928 /* doubleword */
9929 ARCH(5TE);
9930 if (rd & 1) {
9931 /* UNPREDICTABLE; we choose to UNDEF */
9932 goto illegal_op;
9933 }
9934 load = (sh & 1) == 0;
9935 doubleword = true;
9936 }
9937
9938 addr = load_reg(s, rn);
9939 if (pbit) {
9940 gen_add_datah_offset(s, insn, 0, addr);
9941 }
9942 address_offset = 0;
9943
9944 if (doubleword) {
9945 if (!load) {
9946 /* store */
9947 tmp = load_reg(s, rd);
9948 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9949 tcg_temp_free_i32(tmp);
9950 tcg_gen_addi_i32(addr, addr, 4);
9951 tmp = load_reg(s, rd + 1);
9952 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9953 tcg_temp_free_i32(tmp);
9954 } else {
9955 /* load */
9956 tmp = tcg_temp_new_i32();
9957 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9958 store_reg(s, rd, tmp);
9959 tcg_gen_addi_i32(addr, addr, 4);
9960 tmp = tcg_temp_new_i32();
9961 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9962 rd++;
9963 }
9964 address_offset = -4;
9965 } else if (load) {
9966 /* load */
9967 tmp = tcg_temp_new_i32();
9968 switch (sh) {
9969 case 1:
9970 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9971 issinfo);
9972 break;
9973 case 2:
9974 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9975 issinfo);
9976 break;
9977 default:
9978 case 3:
9979 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9980 issinfo);
9981 break;
9982 }
9983 } else {
9984 /* store */
9985 tmp = load_reg(s, rd);
9986 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9987 tcg_temp_free_i32(tmp);
9988 }
9989 /* Perform base writeback before the loaded value to
9990 ensure correct behavior with overlapping index registers.
9991 ldrd with base writeback is undefined if the
9992 destination and index registers overlap. */
9993 if (!pbit) {
9994 gen_add_datah_offset(s, insn, address_offset, addr);
9995 store_reg(s, rn, addr);
9996 } else if (wbit) {
9997 if (address_offset)
9998 tcg_gen_addi_i32(addr, addr, address_offset);
9999 store_reg(s, rn, addr);
10000 } else {
10001 tcg_temp_free_i32(addr);
10002 }
10003 if (load) {
10004 /* Complete the load. */
10005 store_reg(s, rd, tmp);
10006 }
10007 }
10008 break;
10009 case 0x4:
10010 case 0x5:
10011 goto do_ldst;
10012 case 0x6:
10013 case 0x7:
10014 if (insn & (1 << 4)) {
10015 ARCH(6);
10016 /* Armv6 Media instructions. */
10017 rm = insn & 0xf;
10018 rn = (insn >> 16) & 0xf;
10019 rd = (insn >> 12) & 0xf;
10020 rs = (insn >> 8) & 0xf;
10021 switch ((insn >> 23) & 3) {
10022 case 0: /* Parallel add/subtract. */
10023 op1 = (insn >> 20) & 7;
10024 tmp = load_reg(s, rn);
10025 tmp2 = load_reg(s, rm);
10026 sh = (insn >> 5) & 7;
10027 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
10028 goto illegal_op;
10029 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
10030 tcg_temp_free_i32(tmp2);
10031 store_reg(s, rd, tmp);
10032 break;
10033 case 1:
10034 if ((insn & 0x00700020) == 0) {
10035 /* Halfword pack. */
10036 tmp = load_reg(s, rn);
10037 tmp2 = load_reg(s, rm);
10038 shift = (insn >> 7) & 0x1f;
10039 if (insn & (1 << 6)) {
10040 /* pkhtb */
10041 if (shift == 0)
10042 shift = 31;
10043 tcg_gen_sari_i32(tmp2, tmp2, shift);
10044 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10045 tcg_gen_ext16u_i32(tmp2, tmp2);
10046 } else {
10047 /* pkhbt */
10048 if (shift)
10049 tcg_gen_shli_i32(tmp2, tmp2, shift);
10050 tcg_gen_ext16u_i32(tmp, tmp);
10051 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10052 }
10053 tcg_gen_or_i32(tmp, tmp, tmp2);
10054 tcg_temp_free_i32(tmp2);
10055 store_reg(s, rd, tmp);
10056 } else if ((insn & 0x00200020) == 0x00200000) {
10057 /* [us]sat */
10058 tmp = load_reg(s, rm);
10059 shift = (insn >> 7) & 0x1f;
10060 if (insn & (1 << 6)) {
10061 if (shift == 0)
10062 shift = 31;
10063 tcg_gen_sari_i32(tmp, tmp, shift);
10064 } else {
10065 tcg_gen_shli_i32(tmp, tmp, shift);
10066 }
10067 sh = (insn >> 16) & 0x1f;
10068 tmp2 = tcg_const_i32(sh);
10069 if (insn & (1 << 22))
10070 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10071 else
10072 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10073 tcg_temp_free_i32(tmp2);
10074 store_reg(s, rd, tmp);
10075 } else if ((insn & 0x00300fe0) == 0x00200f20) {
10076 /* [us]sat16 */
10077 tmp = load_reg(s, rm);
10078 sh = (insn >> 16) & 0x1f;
10079 tmp2 = tcg_const_i32(sh);
10080 if (insn & (1 << 22))
10081 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10082 else
10083 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10084 tcg_temp_free_i32(tmp2);
10085 store_reg(s, rd, tmp);
10086 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
10087 /* Select bytes. */
10088 tmp = load_reg(s, rn);
10089 tmp2 = load_reg(s, rm);
10090 tmp3 = tcg_temp_new_i32();
10091 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10092 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10093 tcg_temp_free_i32(tmp3);
10094 tcg_temp_free_i32(tmp2);
10095 store_reg(s, rd, tmp);
10096 } else if ((insn & 0x000003e0) == 0x00000060) {
10097 tmp = load_reg(s, rm);
10098 shift = (insn >> 10) & 3;
10099 /* ??? In many cases it's not necessary to do a
10100 rotate, a shift is sufficient. */
10101 if (shift != 0)
10102 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10103 op1 = (insn >> 20) & 7;
10104 switch (op1) {
10105 case 0: gen_sxtb16(tmp); break;
10106 case 2: gen_sxtb(tmp); break;
10107 case 3: gen_sxth(tmp); break;
10108 case 4: gen_uxtb16(tmp); break;
10109 case 6: gen_uxtb(tmp); break;
10110 case 7: gen_uxth(tmp); break;
10111 default: goto illegal_op;
10112 }
10113 if (rn != 15) {
10114 tmp2 = load_reg(s, rn);
10115 if ((op1 & 3) == 0) {
10116 gen_add16(tmp, tmp2);
10117 } else {
10118 tcg_gen_add_i32(tmp, tmp, tmp2);
10119 tcg_temp_free_i32(tmp2);
10120 }
10121 }
10122 store_reg(s, rd, tmp);
10123 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
10124 /* rev */
10125 tmp = load_reg(s, rm);
10126 if (insn & (1 << 22)) {
10127 if (insn & (1 << 7)) {
10128 gen_revsh(tmp);
10129 } else {
10130 ARCH(6T2);
10131 gen_helper_rbit(tmp, tmp);
10132 }
10133 } else {
10134 if (insn & (1 << 7))
10135 gen_rev16(tmp);
10136 else
10137 tcg_gen_bswap32_i32(tmp, tmp);
10138 }
10139 store_reg(s, rd, tmp);
10140 } else {
10141 goto illegal_op;
10142 }
10143 break;
10144 case 2: /* Multiplies (Type 3). */
10145 switch ((insn >> 20) & 0x7) {
10146 case 5:
10147 if (((insn >> 6) ^ (insn >> 7)) & 1) {
10148 /* op2 not 00x or 11x : UNDEF */
10149 goto illegal_op;
10150 }
10151 /* Signed multiply most significant [accumulate].
10152 (SMMUL, SMMLA, SMMLS) */
10153 tmp = load_reg(s, rm);
10154 tmp2 = load_reg(s, rs);
10155 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10156
10157 if (rd != 15) {
10158 tmp = load_reg(s, rd);
10159 if (insn & (1 << 6)) {
10160 tmp64 = gen_subq_msw(tmp64, tmp);
10161 } else {
10162 tmp64 = gen_addq_msw(tmp64, tmp);
10163 }
10164 }
10165 if (insn & (1 << 5)) {
10166 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10167 }
10168 tcg_gen_shri_i64(tmp64, tmp64, 32);
10169 tmp = tcg_temp_new_i32();
10170 tcg_gen_extrl_i64_i32(tmp, tmp64);
10171 tcg_temp_free_i64(tmp64);
10172 store_reg(s, rn, tmp);
10173 break;
10174 case 0:
10175 case 4:
10176 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10177 if (insn & (1 << 7)) {
10178 goto illegal_op;
10179 }
10180 tmp = load_reg(s, rm);
10181 tmp2 = load_reg(s, rs);
10182 if (insn & (1 << 5))
10183 gen_swap_half(tmp2);
10184 gen_smul_dual(tmp, tmp2);
10185 if (insn & (1 << 22)) {
10186 /* smlald, smlsld */
10187 TCGv_i64 tmp64_2;
10188
10189 tmp64 = tcg_temp_new_i64();
10190 tmp64_2 = tcg_temp_new_i64();
10191 tcg_gen_ext_i32_i64(tmp64, tmp);
10192 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
10193 tcg_temp_free_i32(tmp);
10194 tcg_temp_free_i32(tmp2);
10195 if (insn & (1 << 6)) {
10196 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
10197 } else {
10198 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
10199 }
10200 tcg_temp_free_i64(tmp64_2);
10201 gen_addq(s, tmp64, rd, rn);
10202 gen_storeq_reg(s, rd, rn, tmp64);
10203 tcg_temp_free_i64(tmp64);
10204 } else {
10205 /* smuad, smusd, smlad, smlsd */
10206 if (insn & (1 << 6)) {
10207 /* This subtraction cannot overflow. */
10208 tcg_gen_sub_i32(tmp, tmp, tmp2);
10209 } else {
10210 /* This addition cannot overflow 32 bits;
10211 * however it may overflow considered as a
10212 * signed operation, in which case we must set
10213 * the Q flag.
10214 */
10215 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10216 }
10217 tcg_temp_free_i32(tmp2);
10218 if (rd != 15)
10219 {
10220 tmp2 = load_reg(s, rd);
10221 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10222 tcg_temp_free_i32(tmp2);
10223 }
10224 store_reg(s, rn, tmp);
10225 }
10226 break;
10227 case 1:
10228 case 3:
10229 /* SDIV, UDIV */
10230 if (!dc_isar_feature(arm_div, s)) {
10231 goto illegal_op;
10232 }
10233 if (((insn >> 5) & 7) || (rd != 15)) {
10234 goto illegal_op;
10235 }
10236 tmp = load_reg(s, rm);
10237 tmp2 = load_reg(s, rs);
10238 if (insn & (1 << 21)) {
10239 gen_helper_udiv(tmp, tmp, tmp2);
10240 } else {
10241 gen_helper_sdiv(tmp, tmp, tmp2);
10242 }
10243 tcg_temp_free_i32(tmp2);
10244 store_reg(s, rn, tmp);
10245 break;
10246 default:
10247 goto illegal_op;
10248 }
10249 break;
10250 case 3:
10251 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
10252 switch (op1) {
10253 case 0: /* Unsigned sum of absolute differences. */
10254 ARCH(6);
10255 tmp = load_reg(s, rm);
10256 tmp2 = load_reg(s, rs);
10257 gen_helper_usad8(tmp, tmp, tmp2);
10258 tcg_temp_free_i32(tmp2);
10259 if (rd != 15) {
10260 tmp2 = load_reg(s, rd);
10261 tcg_gen_add_i32(tmp, tmp, tmp2);
10262 tcg_temp_free_i32(tmp2);
10263 }
10264 store_reg(s, rn, tmp);
10265 break;
10266 case 0x20: case 0x24: case 0x28: case 0x2c:
10267 /* Bitfield insert/clear. */
10268 ARCH(6T2);
10269 shift = (insn >> 7) & 0x1f;
10270 i = (insn >> 16) & 0x1f;
10271 if (i < shift) {
10272 /* UNPREDICTABLE; we choose to UNDEF */
10273 goto illegal_op;
10274 }
10275 i = i + 1 - shift;
10276 if (rm == 15) {
10277 tmp = tcg_temp_new_i32();
10278 tcg_gen_movi_i32(tmp, 0);
10279 } else {
10280 tmp = load_reg(s, rm);
10281 }
10282 if (i != 32) {
10283 tmp2 = load_reg(s, rd);
10284 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
10285 tcg_temp_free_i32(tmp2);
10286 }
10287 store_reg(s, rd, tmp);
10288 break;
10289 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10290 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10291 ARCH(6T2);
10292 tmp = load_reg(s, rm);
10293 shift = (insn >> 7) & 0x1f;
10294 i = ((insn >> 16) & 0x1f) + 1;
10295 if (shift + i > 32)
10296 goto illegal_op;
10297 if (i < 32) {
10298 if (op1 & 0x20) {
10299 tcg_gen_extract_i32(tmp, tmp, shift, i);
10300 } else {
10301 tcg_gen_sextract_i32(tmp, tmp, shift, i);
10302 }
10303 }
10304 store_reg(s, rd, tmp);
10305 break;
10306 default:
10307 goto illegal_op;
10308 }
10309 break;
10310 }
10311 break;
10312 }
10313 do_ldst:
10314 /* Check for undefined extension instructions
10315 * per the ARM Bible IE:
10316 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
10317 */
10318 sh = (0xf << 20) | (0xf << 4);
10319 if (op1 == 0x7 && ((insn & sh) == sh))
10320 {
10321 goto illegal_op;
10322 }
10323 /* load/store byte/word */
10324 rn = (insn >> 16) & 0xf;
10325 rd = (insn >> 12) & 0xf;
10326 tmp2 = load_reg(s, rn);
10327 if ((insn & 0x01200000) == 0x00200000) {
10328 /* ldrt/strt */
10329 i = get_a32_user_mem_index(s);
10330 } else {
10331 i = get_mem_index(s);
10332 }
10333 if (insn & (1 << 24))
10334 gen_add_data_offset(s, insn, tmp2);
10335 if (insn & (1 << 20)) {
10336 /* load */
10337 tmp = tcg_temp_new_i32();
10338 if (insn & (1 << 22)) {
10339 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
10340 } else {
10341 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
10342 }
10343 } else {
10344 /* store */
10345 tmp = load_reg(s, rd);
10346 if (insn & (1 << 22)) {
10347 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
10348 } else {
10349 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
10350 }
10351 tcg_temp_free_i32(tmp);
10352 }
10353 if (!(insn & (1 << 24))) {
10354 gen_add_data_offset(s, insn, tmp2);
10355 store_reg(s, rn, tmp2);
10356 } else if (insn & (1 << 21)) {
10357 store_reg(s, rn, tmp2);
10358 } else {
10359 tcg_temp_free_i32(tmp2);
10360 }
10361 if (insn & (1 << 20)) {
10362 /* Complete the load. */
10363 store_reg_from_load(s, rd, tmp);
10364 }
10365 break;
10366 case 0x08:
10367 case 0x09:
10368 {
10369 int j, n, loaded_base;
10370 bool exc_return = false;
10371 bool is_load = extract32(insn, 20, 1);
10372 bool user = false;
10373 TCGv_i32 loaded_var;
10374 /* load/store multiple words */
10375 /* XXX: store correct base if write back */
10376 if (insn & (1 << 22)) {
10377 /* LDM (user), LDM (exception return) and STM (user) */
10378 if (IS_USER(s))
10379 goto illegal_op; /* only usable in supervisor mode */
10380
10381 if (is_load && extract32(insn, 15, 1)) {
10382 exc_return = true;
10383 } else {
10384 user = true;
10385 }
10386 }
10387 rn = (insn >> 16) & 0xf;
10388 addr = load_reg(s, rn);
10389
10390 /* compute total size */
10391 loaded_base = 0;
10392 loaded_var = NULL;
10393 n = 0;
10394 for(i=0;i<16;i++) {
10395 if (insn & (1 << i))
10396 n++;
10397 }
10398 /* XXX: test invalid n == 0 case ? */
10399 if (insn & (1 << 23)) {
10400 if (insn & (1 << 24)) {
10401 /* pre increment */
10402 tcg_gen_addi_i32(addr, addr, 4);
10403 } else {
10404 /* post increment */
10405 }
10406 } else {
10407 if (insn & (1 << 24)) {
10408 /* pre decrement */
10409 tcg_gen_addi_i32(addr, addr, -(n * 4));
10410 } else {
10411 /* post decrement */
10412 if (n != 1)
10413 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10414 }
10415 }
10416 j = 0;
10417 for(i=0;i<16;i++) {
10418 if (insn & (1 << i)) {
10419 if (is_load) {
10420 /* load */
10421 tmp = tcg_temp_new_i32();
10422 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10423 if (user) {
10424 tmp2 = tcg_const_i32(i);
10425 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10426 tcg_temp_free_i32(tmp2);
10427 tcg_temp_free_i32(tmp);
10428 } else if (i == rn) {
10429 loaded_var = tmp;
10430 loaded_base = 1;
10431 } else if (rn == 15 && exc_return) {
10432 store_pc_exc_ret(s, tmp);
10433 } else {
10434 store_reg_from_load(s, i, tmp);
10435 }
10436 } else {
10437 /* store */
10438 if (i == 15) {
10439 /* special case: r15 = PC + 8 */
10440 val = (long)s->pc + 4;
10441 tmp = tcg_temp_new_i32();
10442 tcg_gen_movi_i32(tmp, val);
10443 } else if (user) {
10444 tmp = tcg_temp_new_i32();
10445 tmp2 = tcg_const_i32(i);
10446 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10447 tcg_temp_free_i32(tmp2);
10448 } else {
10449 tmp = load_reg(s, i);
10450 }
10451 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10452 tcg_temp_free_i32(tmp);
10453 }
10454 j++;
10455 /* no need to add after the last transfer */
10456 if (j != n)
10457 tcg_gen_addi_i32(addr, addr, 4);
10458 }
10459 }
10460 if (insn & (1 << 21)) {
10461 /* write back */
10462 if (insn & (1 << 23)) {
10463 if (insn & (1 << 24)) {
10464 /* pre increment */
10465 } else {
10466 /* post increment */
10467 tcg_gen_addi_i32(addr, addr, 4);
10468 }
10469 } else {
10470 if (insn & (1 << 24)) {
10471 /* pre decrement */
10472 if (n != 1)
10473 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10474 } else {
10475 /* post decrement */
10476 tcg_gen_addi_i32(addr, addr, -(n * 4));
10477 }
10478 }
10479 store_reg(s, rn, addr);
10480 } else {
10481 tcg_temp_free_i32(addr);
10482 }
10483 if (loaded_base) {
10484 store_reg(s, rn, loaded_var);
10485 }
10486 if (exc_return) {
10487 /* Restore CPSR from SPSR. */
10488 tmp = load_cpu_field(spsr);
10489 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10490 gen_io_start();
10491 }
10492 gen_helper_cpsr_write_eret(cpu_env, tmp);
10493 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10494 gen_io_end();
10495 }
10496 tcg_temp_free_i32(tmp);
10497 /* Must exit loop to check un-masked IRQs */
10498 s->base.is_jmp = DISAS_EXIT;
10499 }
10500 }
10501 break;
10502 case 0xa:
10503 case 0xb:
10504 {
10505 int32_t offset;
10506
10507 /* branch (and link) */
10508 val = (int32_t)s->pc;
10509 if (insn & (1 << 24)) {
10510 tmp = tcg_temp_new_i32();
10511 tcg_gen_movi_i32(tmp, val);
10512 store_reg(s, 14, tmp);
10513 }
10514 offset = sextract32(insn << 2, 0, 26);
10515 val += offset + 4;
10516 gen_jmp(s, val);
10517 }
10518 break;
10519 case 0xc:
10520 case 0xd:
10521 case 0xe:
10522 if (((insn >> 8) & 0xe) == 10) {
10523 /* VFP. */
10524 if (disas_vfp_insn(s, insn)) {
10525 goto illegal_op;
10526 }
10527 } else if (disas_coproc_insn(s, insn)) {
10528 /* Coprocessor. */
10529 goto illegal_op;
10530 }
10531 break;
10532 case 0xf:
10533 /* swi */
10534 gen_set_pc_im(s, s->pc);
10535 s->svc_imm = extract32(insn, 0, 24);
10536 s->base.is_jmp = DISAS_SWI;
10537 break;
10538 default:
10539 illegal_op:
10540 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10541 default_exception_el(s));
10542 break;
10543 }
10544 }
10545 }
10546
10547 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10548 {
10549 /* Return true if this is a 16 bit instruction. We must be precise
10550 * about this (matching the decode). We assume that s->pc still
10551 * points to the first 16 bits of the insn.
10552 */
10553 if ((insn >> 11) < 0x1d) {
10554 /* Definitely a 16-bit instruction */
10555 return true;
10556 }
10557
10558 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10559 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10560 * end up actually treating this as two 16-bit insns, though,
10561 * if it's half of a bl/blx pair that might span a page boundary.
10562 */
10563 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10564 arm_dc_feature(s, ARM_FEATURE_M)) {
10565 /* Thumb2 cores (including all M profile ones) always treat
10566 * 32-bit insns as 32-bit.
10567 */
10568 return false;
10569 }
10570
10571 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10572 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10573 * is not on the next page; we merge this into a 32-bit
10574 * insn.
10575 */
10576 return false;
10577 }
10578 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10579 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10580 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10581 * -- handle as single 16 bit insn
10582 */
10583 return true;
10584 }
10585
10586 /* Return true if this is a Thumb-2 logical op. */
10587 static int
10588 thumb2_logic_op(int op)
10589 {
10590 return (op < 8);
10591 }
10592
10593 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10594 then set condition code flags based on the result of the operation.
10595 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10596 to the high bit of T1.
10597 Returns zero if the opcode is valid. */
10598
10599 static int
10600 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10601 TCGv_i32 t0, TCGv_i32 t1)
10602 {
10603 int logic_cc;
10604
10605 logic_cc = 0;
10606 switch (op) {
10607 case 0: /* and */
10608 tcg_gen_and_i32(t0, t0, t1);
10609 logic_cc = conds;
10610 break;
10611 case 1: /* bic */
10612 tcg_gen_andc_i32(t0, t0, t1);
10613 logic_cc = conds;
10614 break;
10615 case 2: /* orr */
10616 tcg_gen_or_i32(t0, t0, t1);
10617 logic_cc = conds;
10618 break;
10619 case 3: /* orn */
10620 tcg_gen_orc_i32(t0, t0, t1);
10621 logic_cc = conds;
10622 break;
10623 case 4: /* eor */
10624 tcg_gen_xor_i32(t0, t0, t1);
10625 logic_cc = conds;
10626 break;
10627 case 8: /* add */
10628 if (conds)
10629 gen_add_CC(t0, t0, t1);
10630 else
10631 tcg_gen_add_i32(t0, t0, t1);
10632 break;
10633 case 10: /* adc */
10634 if (conds)
10635 gen_adc_CC(t0, t0, t1);
10636 else
10637 gen_adc(t0, t1);
10638 break;
10639 case 11: /* sbc */
10640 if (conds) {
10641 gen_sbc_CC(t0, t0, t1);
10642 } else {
10643 gen_sub_carry(t0, t0, t1);
10644 }
10645 break;
10646 case 13: /* sub */
10647 if (conds)
10648 gen_sub_CC(t0, t0, t1);
10649 else
10650 tcg_gen_sub_i32(t0, t0, t1);
10651 break;
10652 case 14: /* rsb */
10653 if (conds)
10654 gen_sub_CC(t0, t1, t0);
10655 else
10656 tcg_gen_sub_i32(t0, t1, t0);
10657 break;
10658 default: /* 5, 6, 7, 9, 12, 15. */
10659 return 1;
10660 }
10661 if (logic_cc) {
10662 gen_logic_CC(t0);
10663 if (shifter_out)
10664 gen_set_CF_bit31(t1);
10665 }
10666 return 0;
10667 }
10668
10669 /* Translate a 32-bit thumb instruction. */
10670 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10671 {
10672 uint32_t imm, shift, offset;
10673 uint32_t rd, rn, rm, rs;
10674 TCGv_i32 tmp;
10675 TCGv_i32 tmp2;
10676 TCGv_i32 tmp3;
10677 TCGv_i32 addr;
10678 TCGv_i64 tmp64;
10679 int op;
10680 int shiftop;
10681 int conds;
10682 int logic_cc;
10683
10684 /*
10685 * ARMv6-M supports a limited subset of Thumb2 instructions.
10686 * Other Thumb1 architectures allow only 32-bit
10687 * combined BL/BLX prefix and suffix.
10688 */
10689 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10690 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10691 int i;
10692 bool found = false;
10693 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10694 0xf3b08040 /* dsb */,
10695 0xf3b08050 /* dmb */,
10696 0xf3b08060 /* isb */,
10697 0xf3e08000 /* mrs */,
10698 0xf000d000 /* bl */};
10699 static const uint32_t armv6m_mask[] = {0xffe0d000,
10700 0xfff0d0f0,
10701 0xfff0d0f0,
10702 0xfff0d0f0,
10703 0xffe0d000,
10704 0xf800d000};
10705
10706 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10707 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10708 found = true;
10709 break;
10710 }
10711 }
10712 if (!found) {
10713 goto illegal_op;
10714 }
10715 } else if ((insn & 0xf800e800) != 0xf000e800) {
10716 ARCH(6T2);
10717 }
10718
10719 rn = (insn >> 16) & 0xf;
10720 rs = (insn >> 12) & 0xf;
10721 rd = (insn >> 8) & 0xf;
10722 rm = insn & 0xf;
10723 switch ((insn >> 25) & 0xf) {
10724 case 0: case 1: case 2: case 3:
10725 /* 16-bit instructions. Should never happen. */
10726 abort();
10727 case 4:
10728 if (insn & (1 << 22)) {
10729 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10730 * - load/store doubleword, load/store exclusive, ldacq/strel,
10731 * table branch, TT.
10732 */
10733 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10734 arm_dc_feature(s, ARM_FEATURE_V8)) {
10735 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10736 * - SG (v8M only)
10737 * The bulk of the behaviour for this instruction is implemented
10738 * in v7m_handle_execute_nsc(), which deals with the insn when
10739 * it is executed by a CPU in non-secure state from memory
10740 * which is Secure & NonSecure-Callable.
10741 * Here we only need to handle the remaining cases:
10742 * * in NS memory (including the "security extension not
10743 * implemented" case) : NOP
10744 * * in S memory but CPU already secure (clear IT bits)
10745 * We know that the attribute for the memory this insn is
10746 * in must match the current CPU state, because otherwise
10747 * get_phys_addr_pmsav8 would have generated an exception.
10748 */
10749 if (s->v8m_secure) {
10750 /* Like the IT insn, we don't need to generate any code */
10751 s->condexec_cond = 0;
10752 s->condexec_mask = 0;
10753 }
10754 } else if (insn & 0x01200000) {
10755 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10756 * - load/store dual (post-indexed)
10757 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10758 * - load/store dual (literal and immediate)
10759 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10760 * - load/store dual (pre-indexed)
10761 */
10762 bool wback = extract32(insn, 21, 1);
10763
10764 if (rn == 15) {
10765 if (insn & (1 << 21)) {
10766 /* UNPREDICTABLE */
10767 goto illegal_op;
10768 }
10769 addr = tcg_temp_new_i32();
10770 tcg_gen_movi_i32(addr, s->pc & ~3);
10771 } else {
10772 addr = load_reg(s, rn);
10773 }
10774 offset = (insn & 0xff) * 4;
10775 if ((insn & (1 << 23)) == 0) {
10776 offset = -offset;
10777 }
10778
10779 if (s->v8m_stackcheck && rn == 13 && wback) {
10780 /*
10781 * Here 'addr' is the current SP; if offset is +ve we're
10782 * moving SP up, else down. It is UNKNOWN whether the limit
10783 * check triggers when SP starts below the limit and ends
10784 * up above it; check whichever of the current and final
10785 * SP is lower, so QEMU will trigger in that situation.
10786 */
10787 if ((int32_t)offset < 0) {
10788 TCGv_i32 newsp = tcg_temp_new_i32();
10789
10790 tcg_gen_addi_i32(newsp, addr, offset);
10791 gen_helper_v8m_stackcheck(cpu_env, newsp);
10792 tcg_temp_free_i32(newsp);
10793 } else {
10794 gen_helper_v8m_stackcheck(cpu_env, addr);
10795 }
10796 }
10797
10798 if (insn & (1 << 24)) {
10799 tcg_gen_addi_i32(addr, addr, offset);
10800 offset = 0;
10801 }
10802 if (insn & (1 << 20)) {
10803 /* ldrd */
10804 tmp = tcg_temp_new_i32();
10805 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10806 store_reg(s, rs, tmp);
10807 tcg_gen_addi_i32(addr, addr, 4);
10808 tmp = tcg_temp_new_i32();
10809 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10810 store_reg(s, rd, tmp);
10811 } else {
10812 /* strd */
10813 tmp = load_reg(s, rs);
10814 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10815 tcg_temp_free_i32(tmp);
10816 tcg_gen_addi_i32(addr, addr, 4);
10817 tmp = load_reg(s, rd);
10818 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10819 tcg_temp_free_i32(tmp);
10820 }
10821 if (wback) {
10822 /* Base writeback. */
10823 tcg_gen_addi_i32(addr, addr, offset - 4);
10824 store_reg(s, rn, addr);
10825 } else {
10826 tcg_temp_free_i32(addr);
10827 }
10828 } else if ((insn & (1 << 23)) == 0) {
10829 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10830 * - load/store exclusive word
10831 * - TT (v8M only)
10832 */
10833 if (rs == 15) {
10834 if (!(insn & (1 << 20)) &&
10835 arm_dc_feature(s, ARM_FEATURE_M) &&
10836 arm_dc_feature(s, ARM_FEATURE_V8)) {
10837 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10838 * - TT (v8M only)
10839 */
10840 bool alt = insn & (1 << 7);
10841 TCGv_i32 addr, op, ttresp;
10842
10843 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10844 /* we UNDEF for these UNPREDICTABLE cases */
10845 goto illegal_op;
10846 }
10847
10848 if (alt && !s->v8m_secure) {
10849 goto illegal_op;
10850 }
10851
10852 addr = load_reg(s, rn);
10853 op = tcg_const_i32(extract32(insn, 6, 2));
10854 ttresp = tcg_temp_new_i32();
10855 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10856 tcg_temp_free_i32(addr);
10857 tcg_temp_free_i32(op);
10858 store_reg(s, rd, ttresp);
10859 break;
10860 }
10861 goto illegal_op;
10862 }
10863 addr = tcg_temp_local_new_i32();
10864 load_reg_var(s, addr, rn);
10865 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10866 if (insn & (1 << 20)) {
10867 gen_load_exclusive(s, rs, 15, addr, 2);
10868 } else {
10869 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10870 }
10871 tcg_temp_free_i32(addr);
10872 } else if ((insn & (7 << 5)) == 0) {
10873 /* Table Branch. */
10874 if (rn == 15) {
10875 addr = tcg_temp_new_i32();
10876 tcg_gen_movi_i32(addr, s->pc);
10877 } else {
10878 addr = load_reg(s, rn);
10879 }
10880 tmp = load_reg(s, rm);
10881 tcg_gen_add_i32(addr, addr, tmp);
10882 if (insn & (1 << 4)) {
10883 /* tbh */
10884 tcg_gen_add_i32(addr, addr, tmp);
10885 tcg_temp_free_i32(tmp);
10886 tmp = tcg_temp_new_i32();
10887 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10888 } else { /* tbb */
10889 tcg_temp_free_i32(tmp);
10890 tmp = tcg_temp_new_i32();
10891 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10892 }
10893 tcg_temp_free_i32(addr);
10894 tcg_gen_shli_i32(tmp, tmp, 1);
10895 tcg_gen_addi_i32(tmp, tmp, s->pc);
10896 store_reg(s, 15, tmp);
10897 } else {
10898 int op2 = (insn >> 6) & 0x3;
10899 op = (insn >> 4) & 0x3;
10900 switch (op2) {
10901 case 0:
10902 goto illegal_op;
10903 case 1:
10904 /* Load/store exclusive byte/halfword/doubleword */
10905 if (op == 2) {
10906 goto illegal_op;
10907 }
10908 ARCH(7);
10909 break;
10910 case 2:
10911 /* Load-acquire/store-release */
10912 if (op == 3) {
10913 goto illegal_op;
10914 }
10915 /* Fall through */
10916 case 3:
10917 /* Load-acquire/store-release exclusive */
10918 ARCH(8);
10919 break;
10920 }
10921 addr = tcg_temp_local_new_i32();
10922 load_reg_var(s, addr, rn);
10923 if (!(op2 & 1)) {
10924 if (insn & (1 << 20)) {
10925 tmp = tcg_temp_new_i32();
10926 switch (op) {
10927 case 0: /* ldab */
10928 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10929 rs | ISSIsAcqRel);
10930 break;
10931 case 1: /* ldah */
10932 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10933 rs | ISSIsAcqRel);
10934 break;
10935 case 2: /* lda */
10936 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10937 rs | ISSIsAcqRel);
10938 break;
10939 default:
10940 abort();
10941 }
10942 store_reg(s, rs, tmp);
10943 } else {
10944 tmp = load_reg(s, rs);
10945 switch (op) {
10946 case 0: /* stlb */
10947 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10948 rs | ISSIsAcqRel);
10949 break;
10950 case 1: /* stlh */
10951 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10952 rs | ISSIsAcqRel);
10953 break;
10954 case 2: /* stl */
10955 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10956 rs | ISSIsAcqRel);
10957 break;
10958 default:
10959 abort();
10960 }
10961 tcg_temp_free_i32(tmp);
10962 }
10963 } else if (insn & (1 << 20)) {
10964 gen_load_exclusive(s, rs, rd, addr, op);
10965 } else {
10966 gen_store_exclusive(s, rm, rs, rd, addr, op);
10967 }
10968 tcg_temp_free_i32(addr);
10969 }
10970 } else {
10971 /* Load/store multiple, RFE, SRS. */
10972 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10973 /* RFE, SRS: not available in user mode or on M profile */
10974 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10975 goto illegal_op;
10976 }
10977 if (insn & (1 << 20)) {
10978 /* rfe */
10979 addr = load_reg(s, rn);
10980 if ((insn & (1 << 24)) == 0)
10981 tcg_gen_addi_i32(addr, addr, -8);
10982 /* Load PC into tmp and CPSR into tmp2. */
10983 tmp = tcg_temp_new_i32();
10984 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10985 tcg_gen_addi_i32(addr, addr, 4);
10986 tmp2 = tcg_temp_new_i32();
10987 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10988 if (insn & (1 << 21)) {
10989 /* Base writeback. */
10990 if (insn & (1 << 24)) {
10991 tcg_gen_addi_i32(addr, addr, 4);
10992 } else {
10993 tcg_gen_addi_i32(addr, addr, -4);
10994 }
10995 store_reg(s, rn, addr);
10996 } else {
10997 tcg_temp_free_i32(addr);
10998 }
10999 gen_rfe(s, tmp, tmp2);
11000 } else {
11001 /* srs */
11002 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
11003 insn & (1 << 21));
11004 }
11005 } else {
11006 int i, loaded_base = 0;
11007 TCGv_i32 loaded_var;
11008 bool wback = extract32(insn, 21, 1);
11009 /* Load/store multiple. */
11010 addr = load_reg(s, rn);
11011 offset = 0;
11012 for (i = 0; i < 16; i++) {
11013 if (insn & (1 << i))
11014 offset += 4;
11015 }
11016
11017 if (insn & (1 << 24)) {
11018 tcg_gen_addi_i32(addr, addr, -offset);
11019 }
11020
11021 if (s->v8m_stackcheck && rn == 13 && wback) {
11022 /*
11023 * If the writeback is incrementing SP rather than
11024 * decrementing it, and the initial SP is below the
11025 * stack limit but the final written-back SP would
11026 * be above, then then we must not perform any memory
11027 * accesses, but it is IMPDEF whether we generate
11028 * an exception. We choose to do so in this case.
11029 * At this point 'addr' is the lowest address, so
11030 * either the original SP (if incrementing) or our
11031 * final SP (if decrementing), so that's what we check.
11032 */
11033 gen_helper_v8m_stackcheck(cpu_env, addr);
11034 }
11035
11036 loaded_var = NULL;
11037 for (i = 0; i < 16; i++) {
11038 if ((insn & (1 << i)) == 0)
11039 continue;
11040 if (insn & (1 << 20)) {
11041 /* Load. */
11042 tmp = tcg_temp_new_i32();
11043 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11044 if (i == 15) {
11045 gen_bx_excret(s, tmp);
11046 } else if (i == rn) {
11047 loaded_var = tmp;
11048 loaded_base = 1;
11049 } else {
11050 store_reg(s, i, tmp);
11051 }
11052 } else {
11053 /* Store. */
11054 tmp = load_reg(s, i);
11055 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11056 tcg_temp_free_i32(tmp);
11057 }
11058 tcg_gen_addi_i32(addr, addr, 4);
11059 }
11060 if (loaded_base) {
11061 store_reg(s, rn, loaded_var);
11062 }
11063 if (wback) {
11064 /* Base register writeback. */
11065 if (insn & (1 << 24)) {
11066 tcg_gen_addi_i32(addr, addr, -offset);
11067 }
11068 /* Fault if writeback register is in register list. */
11069 if (insn & (1 << rn))
11070 goto illegal_op;
11071 store_reg(s, rn, addr);
11072 } else {
11073 tcg_temp_free_i32(addr);
11074 }
11075 }
11076 }
11077 break;
11078 case 5:
11079
11080 op = (insn >> 21) & 0xf;
11081 if (op == 6) {
11082 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11083 goto illegal_op;
11084 }
11085 /* Halfword pack. */
11086 tmp = load_reg(s, rn);
11087 tmp2 = load_reg(s, rm);
11088 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
11089 if (insn & (1 << 5)) {
11090 /* pkhtb */
11091 if (shift == 0)
11092 shift = 31;
11093 tcg_gen_sari_i32(tmp2, tmp2, shift);
11094 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
11095 tcg_gen_ext16u_i32(tmp2, tmp2);
11096 } else {
11097 /* pkhbt */
11098 if (shift)
11099 tcg_gen_shli_i32(tmp2, tmp2, shift);
11100 tcg_gen_ext16u_i32(tmp, tmp);
11101 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
11102 }
11103 tcg_gen_or_i32(tmp, tmp, tmp2);
11104 tcg_temp_free_i32(tmp2);
11105 store_reg(s, rd, tmp);
11106 } else {
11107 /* Data processing register constant shift. */
11108 if (rn == 15) {
11109 tmp = tcg_temp_new_i32();
11110 tcg_gen_movi_i32(tmp, 0);
11111 } else {
11112 tmp = load_reg(s, rn);
11113 }
11114 tmp2 = load_reg(s, rm);
11115
11116 shiftop = (insn >> 4) & 3;
11117 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11118 conds = (insn & (1 << 20)) != 0;
11119 logic_cc = (conds && thumb2_logic_op(op));
11120 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
11121 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
11122 goto illegal_op;
11123 tcg_temp_free_i32(tmp2);
11124 if (rd == 13 &&
11125 ((op == 2 && rn == 15) ||
11126 (op == 8 && rn == 13) ||
11127 (op == 13 && rn == 13))) {
11128 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11129 store_sp_checked(s, tmp);
11130 } else if (rd != 15) {
11131 store_reg(s, rd, tmp);
11132 } else {
11133 tcg_temp_free_i32(tmp);
11134 }
11135 }
11136 break;
11137 case 13: /* Misc data processing. */
11138 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
11139 if (op < 4 && (insn & 0xf000) != 0xf000)
11140 goto illegal_op;
11141 switch (op) {
11142 case 0: /* Register controlled shift. */
11143 tmp = load_reg(s, rn);
11144 tmp2 = load_reg(s, rm);
11145 if ((insn & 0x70) != 0)
11146 goto illegal_op;
11147 /*
11148 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11149 * - MOV, MOVS (register-shifted register), flagsetting
11150 */
11151 op = (insn >> 21) & 3;
11152 logic_cc = (insn & (1 << 20)) != 0;
11153 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
11154 if (logic_cc)
11155 gen_logic_CC(tmp);
11156 store_reg(s, rd, tmp);
11157 break;
11158 case 1: /* Sign/zero extend. */
11159 op = (insn >> 20) & 7;
11160 switch (op) {
11161 case 0: /* SXTAH, SXTH */
11162 case 1: /* UXTAH, UXTH */
11163 case 4: /* SXTAB, SXTB */
11164 case 5: /* UXTAB, UXTB */
11165 break;
11166 case 2: /* SXTAB16, SXTB16 */
11167 case 3: /* UXTAB16, UXTB16 */
11168 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11169 goto illegal_op;
11170 }
11171 break;
11172 default:
11173 goto illegal_op;
11174 }
11175 if (rn != 15) {
11176 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11177 goto illegal_op;
11178 }
11179 }
11180 tmp = load_reg(s, rm);
11181 shift = (insn >> 4) & 3;
11182 /* ??? In many cases it's not necessary to do a
11183 rotate, a shift is sufficient. */
11184 if (shift != 0)
11185 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
11186 op = (insn >> 20) & 7;
11187 switch (op) {
11188 case 0: gen_sxth(tmp); break;
11189 case 1: gen_uxth(tmp); break;
11190 case 2: gen_sxtb16(tmp); break;
11191 case 3: gen_uxtb16(tmp); break;
11192 case 4: gen_sxtb(tmp); break;
11193 case 5: gen_uxtb(tmp); break;
11194 default:
11195 g_assert_not_reached();
11196 }
11197 if (rn != 15) {
11198 tmp2 = load_reg(s, rn);
11199 if ((op >> 1) == 1) {
11200 gen_add16(tmp, tmp2);
11201 } else {
11202 tcg_gen_add_i32(tmp, tmp, tmp2);
11203 tcg_temp_free_i32(tmp2);
11204 }
11205 }
11206 store_reg(s, rd, tmp);
11207 break;
11208 case 2: /* SIMD add/subtract. */
11209 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11210 goto illegal_op;
11211 }
11212 op = (insn >> 20) & 7;
11213 shift = (insn >> 4) & 7;
11214 if ((op & 3) == 3 || (shift & 3) == 3)
11215 goto illegal_op;
11216 tmp = load_reg(s, rn);
11217 tmp2 = load_reg(s, rm);
11218 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
11219 tcg_temp_free_i32(tmp2);
11220 store_reg(s, rd, tmp);
11221 break;
11222 case 3: /* Other data processing. */
11223 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
11224 if (op < 4) {
11225 /* Saturating add/subtract. */
11226 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11227 goto illegal_op;
11228 }
11229 tmp = load_reg(s, rn);
11230 tmp2 = load_reg(s, rm);
11231 if (op & 1)
11232 gen_helper_double_saturate(tmp, cpu_env, tmp);
11233 if (op & 2)
11234 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
11235 else
11236 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
11237 tcg_temp_free_i32(tmp2);
11238 } else {
11239 switch (op) {
11240 case 0x0a: /* rbit */
11241 case 0x08: /* rev */
11242 case 0x09: /* rev16 */
11243 case 0x0b: /* revsh */
11244 case 0x18: /* clz */
11245 break;
11246 case 0x10: /* sel */
11247 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11248 goto illegal_op;
11249 }
11250 break;
11251 case 0x20: /* crc32/crc32c */
11252 case 0x21:
11253 case 0x22:
11254 case 0x28:
11255 case 0x29:
11256 case 0x2a:
11257 if (!dc_isar_feature(aa32_crc32, s)) {
11258 goto illegal_op;
11259 }
11260 break;
11261 default:
11262 goto illegal_op;
11263 }
11264 tmp = load_reg(s, rn);
11265 switch (op) {
11266 case 0x0a: /* rbit */
11267 gen_helper_rbit(tmp, tmp);
11268 break;
11269 case 0x08: /* rev */
11270 tcg_gen_bswap32_i32(tmp, tmp);
11271 break;
11272 case 0x09: /* rev16 */
11273 gen_rev16(tmp);
11274 break;
11275 case 0x0b: /* revsh */
11276 gen_revsh(tmp);
11277 break;
11278 case 0x10: /* sel */
11279 tmp2 = load_reg(s, rm);
11280 tmp3 = tcg_temp_new_i32();
11281 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
11282 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
11283 tcg_temp_free_i32(tmp3);
11284 tcg_temp_free_i32(tmp2);
11285 break;
11286 case 0x18: /* clz */
11287 tcg_gen_clzi_i32(tmp, tmp, 32);
11288 break;
11289 case 0x20:
11290 case 0x21:
11291 case 0x22:
11292 case 0x28:
11293 case 0x29:
11294 case 0x2a:
11295 {
11296 /* crc32/crc32c */
11297 uint32_t sz = op & 0x3;
11298 uint32_t c = op & 0x8;
11299
11300 tmp2 = load_reg(s, rm);
11301 if (sz == 0) {
11302 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
11303 } else if (sz == 1) {
11304 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
11305 }
11306 tmp3 = tcg_const_i32(1 << sz);
11307 if (c) {
11308 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
11309 } else {
11310 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
11311 }
11312 tcg_temp_free_i32(tmp2);
11313 tcg_temp_free_i32(tmp3);
11314 break;
11315 }
11316 default:
11317 g_assert_not_reached();
11318 }
11319 }
11320 store_reg(s, rd, tmp);
11321 break;
11322 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
11323 switch ((insn >> 20) & 7) {
11324 case 0: /* 32 x 32 -> 32 */
11325 case 7: /* Unsigned sum of absolute differences. */
11326 break;
11327 case 1: /* 16 x 16 -> 32 */
11328 case 2: /* Dual multiply add. */
11329 case 3: /* 32 * 16 -> 32msb */
11330 case 4: /* Dual multiply subtract. */
11331 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11332 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11333 goto illegal_op;
11334 }
11335 break;
11336 }
11337 op = (insn >> 4) & 0xf;
11338 tmp = load_reg(s, rn);
11339 tmp2 = load_reg(s, rm);
11340 switch ((insn >> 20) & 7) {
11341 case 0: /* 32 x 32 -> 32 */
11342 tcg_gen_mul_i32(tmp, tmp, tmp2);
11343 tcg_temp_free_i32(tmp2);
11344 if (rs != 15) {
11345 tmp2 = load_reg(s, rs);
11346 if (op)
11347 tcg_gen_sub_i32(tmp, tmp2, tmp);
11348 else
11349 tcg_gen_add_i32(tmp, tmp, tmp2);
11350 tcg_temp_free_i32(tmp2);
11351 }
11352 break;
11353 case 1: /* 16 x 16 -> 32 */
11354 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11355 tcg_temp_free_i32(tmp2);
11356 if (rs != 15) {
11357 tmp2 = load_reg(s, rs);
11358 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11359 tcg_temp_free_i32(tmp2);
11360 }
11361 break;
11362 case 2: /* Dual multiply add. */
11363 case 4: /* Dual multiply subtract. */
11364 if (op)
11365 gen_swap_half(tmp2);
11366 gen_smul_dual(tmp, tmp2);
11367 if (insn & (1 << 22)) {
11368 /* This subtraction cannot overflow. */
11369 tcg_gen_sub_i32(tmp, tmp, tmp2);
11370 } else {
11371 /* This addition cannot overflow 32 bits;
11372 * however it may overflow considered as a signed
11373 * operation, in which case we must set the Q flag.
11374 */
11375 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11376 }
11377 tcg_temp_free_i32(tmp2);
11378 if (rs != 15)
11379 {
11380 tmp2 = load_reg(s, rs);
11381 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11382 tcg_temp_free_i32(tmp2);
11383 }
11384 break;
11385 case 3: /* 32 * 16 -> 32msb */
11386 if (op)
11387 tcg_gen_sari_i32(tmp2, tmp2, 16);
11388 else
11389 gen_sxth(tmp2);
11390 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11391 tcg_gen_shri_i64(tmp64, tmp64, 16);
11392 tmp = tcg_temp_new_i32();
11393 tcg_gen_extrl_i64_i32(tmp, tmp64);
11394 tcg_temp_free_i64(tmp64);
11395 if (rs != 15)
11396 {
11397 tmp2 = load_reg(s, rs);
11398 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11399 tcg_temp_free_i32(tmp2);
11400 }
11401 break;
11402 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11403 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11404 if (rs != 15) {
11405 tmp = load_reg(s, rs);
11406 if (insn & (1 << 20)) {
11407 tmp64 = gen_addq_msw(tmp64, tmp);
11408 } else {
11409 tmp64 = gen_subq_msw(tmp64, tmp);
11410 }
11411 }
11412 if (insn & (1 << 4)) {
11413 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11414 }
11415 tcg_gen_shri_i64(tmp64, tmp64, 32);
11416 tmp = tcg_temp_new_i32();
11417 tcg_gen_extrl_i64_i32(tmp, tmp64);
11418 tcg_temp_free_i64(tmp64);
11419 break;
11420 case 7: /* Unsigned sum of absolute differences. */
11421 gen_helper_usad8(tmp, tmp, tmp2);
11422 tcg_temp_free_i32(tmp2);
11423 if (rs != 15) {
11424 tmp2 = load_reg(s, rs);
11425 tcg_gen_add_i32(tmp, tmp, tmp2);
11426 tcg_temp_free_i32(tmp2);
11427 }
11428 break;
11429 }
11430 store_reg(s, rd, tmp);
11431 break;
11432 case 6: case 7: /* 64-bit multiply, Divide. */
11433 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11434 tmp = load_reg(s, rn);
11435 tmp2 = load_reg(s, rm);
11436 if ((op & 0x50) == 0x10) {
11437 /* sdiv, udiv */
11438 if (!dc_isar_feature(thumb_div, s)) {
11439 goto illegal_op;
11440 }
11441 if (op & 0x20)
11442 gen_helper_udiv(tmp, tmp, tmp2);
11443 else
11444 gen_helper_sdiv(tmp, tmp, tmp2);
11445 tcg_temp_free_i32(tmp2);
11446 store_reg(s, rd, tmp);
11447 } else if ((op & 0xe) == 0xc) {
11448 /* Dual multiply accumulate long. */
11449 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11450 tcg_temp_free_i32(tmp);
11451 tcg_temp_free_i32(tmp2);
11452 goto illegal_op;
11453 }
11454 if (op & 1)
11455 gen_swap_half(tmp2);
11456 gen_smul_dual(tmp, tmp2);
11457 if (op & 0x10) {
11458 tcg_gen_sub_i32(tmp, tmp, tmp2);
11459 } else {
11460 tcg_gen_add_i32(tmp, tmp, tmp2);
11461 }
11462 tcg_temp_free_i32(tmp2);
11463 /* BUGFIX */
11464 tmp64 = tcg_temp_new_i64();
11465 tcg_gen_ext_i32_i64(tmp64, tmp);
11466 tcg_temp_free_i32(tmp);
11467 gen_addq(s, tmp64, rs, rd);
11468 gen_storeq_reg(s, rs, rd, tmp64);
11469 tcg_temp_free_i64(tmp64);
11470 } else {
11471 if (op & 0x20) {
11472 /* Unsigned 64-bit multiply */
11473 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11474 } else {
11475 if (op & 8) {
11476 /* smlalxy */
11477 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11478 tcg_temp_free_i32(tmp2);
11479 tcg_temp_free_i32(tmp);
11480 goto illegal_op;
11481 }
11482 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11483 tcg_temp_free_i32(tmp2);
11484 tmp64 = tcg_temp_new_i64();
11485 tcg_gen_ext_i32_i64(tmp64, tmp);
11486 tcg_temp_free_i32(tmp);
11487 } else {
11488 /* Signed 64-bit multiply */
11489 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11490 }
11491 }
11492 if (op & 4) {
11493 /* umaal */
11494 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11495 tcg_temp_free_i64(tmp64);
11496 goto illegal_op;
11497 }
11498 gen_addq_lo(s, tmp64, rs);
11499 gen_addq_lo(s, tmp64, rd);
11500 } else if (op & 0x40) {
11501 /* 64-bit accumulate. */
11502 gen_addq(s, tmp64, rs, rd);
11503 }
11504 gen_storeq_reg(s, rs, rd, tmp64);
11505 tcg_temp_free_i64(tmp64);
11506 }
11507 break;
11508 }
11509 break;
11510 case 6: case 7: case 14: case 15:
11511 /* Coprocessor. */
11512 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11513 /* We don't currently implement M profile FP support,
11514 * so this entire space should give a NOCP fault, with
11515 * the exception of the v8M VLLDM and VLSTM insns, which
11516 * must be NOPs in Secure state and UNDEF in Nonsecure state.
11517 */
11518 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11519 (insn & 0xffa00f00) == 0xec200a00) {
11520 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11521 * - VLLDM, VLSTM
11522 * We choose to UNDEF if the RAZ bits are non-zero.
11523 */
11524 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11525 goto illegal_op;
11526 }
11527 /* Just NOP since FP support is not implemented */
11528 break;
11529 }
11530 /* All other insns: NOCP */
11531 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11532 default_exception_el(s));
11533 break;
11534 }
11535 if ((insn & 0xfe000a00) == 0xfc000800
11536 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11537 /* The Thumb2 and ARM encodings are identical. */
11538 if (disas_neon_insn_3same_ext(s, insn)) {
11539 goto illegal_op;
11540 }
11541 } else if ((insn & 0xff000a00) == 0xfe000800
11542 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11543 /* The Thumb2 and ARM encodings are identical. */
11544 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11545 goto illegal_op;
11546 }
11547 } else if (((insn >> 24) & 3) == 3) {
11548 /* Translate into the equivalent ARM encoding. */
11549 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11550 if (disas_neon_data_insn(s, insn)) {
11551 goto illegal_op;
11552 }
11553 } else if (((insn >> 8) & 0xe) == 10) {
11554 if (disas_vfp_insn(s, insn)) {
11555 goto illegal_op;
11556 }
11557 } else {
11558 if (insn & (1 << 28))
11559 goto illegal_op;
11560 if (disas_coproc_insn(s, insn)) {
11561 goto illegal_op;
11562 }
11563 }
11564 break;
11565 case 8: case 9: case 10: case 11:
11566 if (insn & (1 << 15)) {
11567 /* Branches, misc control. */
11568 if (insn & 0x5000) {
11569 /* Unconditional branch. */
11570 /* signextend(hw1[10:0]) -> offset[:12]. */
11571 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11572 /* hw1[10:0] -> offset[11:1]. */
11573 offset |= (insn & 0x7ff) << 1;
11574 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11575 offset[24:22] already have the same value because of the
11576 sign extension above. */
11577 offset ^= ((~insn) & (1 << 13)) << 10;
11578 offset ^= ((~insn) & (1 << 11)) << 11;
11579
11580 if (insn & (1 << 14)) {
11581 /* Branch and link. */
11582 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11583 }
11584
11585 offset += s->pc;
11586 if (insn & (1 << 12)) {
11587 /* b/bl */
11588 gen_jmp(s, offset);
11589 } else {
11590 /* blx */
11591 offset &= ~(uint32_t)2;
11592 /* thumb2 bx, no need to check */
11593 gen_bx_im(s, offset);
11594 }
11595 } else if (((insn >> 23) & 7) == 7) {
11596 /* Misc control */
11597 if (insn & (1 << 13))
11598 goto illegal_op;
11599
11600 if (insn & (1 << 26)) {
11601 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11602 goto illegal_op;
11603 }
11604 if (!(insn & (1 << 20))) {
11605 /* Hypervisor call (v7) */
11606 int imm16 = extract32(insn, 16, 4) << 12
11607 | extract32(insn, 0, 12);
11608 ARCH(7);
11609 if (IS_USER(s)) {
11610 goto illegal_op;
11611 }
11612 gen_hvc(s, imm16);
11613 } else {
11614 /* Secure monitor call (v6+) */
11615 ARCH(6K);
11616 if (IS_USER(s)) {
11617 goto illegal_op;
11618 }
11619 gen_smc(s);
11620 }
11621 } else {
11622 op = (insn >> 20) & 7;
11623 switch (op) {
11624 case 0: /* msr cpsr. */
11625 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11626 tmp = load_reg(s, rn);
11627 /* the constant is the mask and SYSm fields */
11628 addr = tcg_const_i32(insn & 0xfff);
11629 gen_helper_v7m_msr(cpu_env, addr, tmp);
11630 tcg_temp_free_i32(addr);
11631 tcg_temp_free_i32(tmp);
11632 gen_lookup_tb(s);
11633 break;
11634 }
11635 /* fall through */
11636 case 1: /* msr spsr. */
11637 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11638 goto illegal_op;
11639 }
11640
11641 if (extract32(insn, 5, 1)) {
11642 /* MSR (banked) */
11643 int sysm = extract32(insn, 8, 4) |
11644 (extract32(insn, 4, 1) << 4);
11645 int r = op & 1;
11646
11647 gen_msr_banked(s, r, sysm, rm);
11648 break;
11649 }
11650
11651 /* MSR (for PSRs) */
11652 tmp = load_reg(s, rn);
11653 if (gen_set_psr(s,
11654 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11655 op == 1, tmp))
11656 goto illegal_op;
11657 break;
11658 case 2: /* cps, nop-hint. */
11659 if (((insn >> 8) & 7) == 0) {
11660 gen_nop_hint(s, insn & 0xff);
11661 }
11662 /* Implemented as NOP in user mode. */
11663 if (IS_USER(s))
11664 break;
11665 offset = 0;
11666 imm = 0;
11667 if (insn & (1 << 10)) {
11668 if (insn & (1 << 7))
11669 offset |= CPSR_A;
11670 if (insn & (1 << 6))
11671 offset |= CPSR_I;
11672 if (insn & (1 << 5))
11673 offset |= CPSR_F;
11674 if (insn & (1 << 9))
11675 imm = CPSR_A | CPSR_I | CPSR_F;
11676 }
11677 if (insn & (1 << 8)) {
11678 offset |= 0x1f;
11679 imm |= (insn & 0x1f);
11680 }
11681 if (offset) {
11682 gen_set_psr_im(s, offset, 0, imm);
11683 }
11684 break;
11685 case 3: /* Special control operations. */
11686 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11687 !arm_dc_feature(s, ARM_FEATURE_M)) {
11688 goto illegal_op;
11689 }
11690 op = (insn >> 4) & 0xf;
11691 switch (op) {
11692 case 2: /* clrex */
11693 gen_clrex(s);
11694 break;
11695 case 4: /* dsb */
11696 case 5: /* dmb */
11697 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11698 break;
11699 case 6: /* isb */
11700 /* We need to break the TB after this insn
11701 * to execute self-modifying code correctly
11702 * and also to take any pending interrupts
11703 * immediately.
11704 */
11705 gen_goto_tb(s, 0, s->pc & ~1);
11706 break;
11707 default:
11708 goto illegal_op;
11709 }
11710 break;
11711 case 4: /* bxj */
11712 /* Trivial implementation equivalent to bx.
11713 * This instruction doesn't exist at all for M-profile.
11714 */
11715 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11716 goto illegal_op;
11717 }
11718 tmp = load_reg(s, rn);
11719 gen_bx(s, tmp);
11720 break;
11721 case 5: /* Exception return. */
11722 if (IS_USER(s)) {
11723 goto illegal_op;
11724 }
11725 if (rn != 14 || rd != 15) {
11726 goto illegal_op;
11727 }
11728 if (s->current_el == 2) {
11729 /* ERET from Hyp uses ELR_Hyp, not LR */
11730 if (insn & 0xff) {
11731 goto illegal_op;
11732 }
11733 tmp = load_cpu_field(elr_el[2]);
11734 } else {
11735 tmp = load_reg(s, rn);
11736 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11737 }
11738 gen_exception_return(s, tmp);
11739 break;
11740 case 6: /* MRS */
11741 if (extract32(insn, 5, 1) &&
11742 !arm_dc_feature(s, ARM_FEATURE_M)) {
11743 /* MRS (banked) */
11744 int sysm = extract32(insn, 16, 4) |
11745 (extract32(insn, 4, 1) << 4);
11746
11747 gen_mrs_banked(s, 0, sysm, rd);
11748 break;
11749 }
11750
11751 if (extract32(insn, 16, 4) != 0xf) {
11752 goto illegal_op;
11753 }
11754 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11755 extract32(insn, 0, 8) != 0) {
11756 goto illegal_op;
11757 }
11758
11759 /* mrs cpsr */
11760 tmp = tcg_temp_new_i32();
11761 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11762 addr = tcg_const_i32(insn & 0xff);
11763 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11764 tcg_temp_free_i32(addr);
11765 } else {
11766 gen_helper_cpsr_read(tmp, cpu_env);
11767 }
11768 store_reg(s, rd, tmp);
11769 break;
11770 case 7: /* MRS */
11771 if (extract32(insn, 5, 1) &&
11772 !arm_dc_feature(s, ARM_FEATURE_M)) {
11773 /* MRS (banked) */
11774 int sysm = extract32(insn, 16, 4) |
11775 (extract32(insn, 4, 1) << 4);
11776
11777 gen_mrs_banked(s, 1, sysm, rd);
11778 break;
11779 }
11780
11781 /* mrs spsr. */
11782 /* Not accessible in user mode. */
11783 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11784 goto illegal_op;
11785 }
11786
11787 if (extract32(insn, 16, 4) != 0xf ||
11788 extract32(insn, 0, 8) != 0) {
11789 goto illegal_op;
11790 }
11791
11792 tmp = load_cpu_field(spsr);
11793 store_reg(s, rd, tmp);
11794 break;
11795 }
11796 }
11797 } else {
11798 /* Conditional branch. */
11799 op = (insn >> 22) & 0xf;
11800 /* Generate a conditional jump to next instruction. */
11801 arm_skip_unless(s, op);
11802
11803 /* offset[11:1] = insn[10:0] */
11804 offset = (insn & 0x7ff) << 1;
11805 /* offset[17:12] = insn[21:16]. */
11806 offset |= (insn & 0x003f0000) >> 4;
11807 /* offset[31:20] = insn[26]. */
11808 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11809 /* offset[18] = insn[13]. */
11810 offset |= (insn & (1 << 13)) << 5;
11811 /* offset[19] = insn[11]. */
11812 offset |= (insn & (1 << 11)) << 8;
11813
11814 /* jump to the offset */
11815 gen_jmp(s, s->pc + offset);
11816 }
11817 } else {
11818 /*
11819 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11820 * - Data-processing (modified immediate, plain binary immediate)
11821 */
11822 if (insn & (1 << 25)) {
11823 /*
11824 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11825 * - Data-processing (plain binary immediate)
11826 */
11827 if (insn & (1 << 24)) {
11828 if (insn & (1 << 20))
11829 goto illegal_op;
11830 /* Bitfield/Saturate. */
11831 op = (insn >> 21) & 7;
11832 imm = insn & 0x1f;
11833 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11834 if (rn == 15) {
11835 tmp = tcg_temp_new_i32();
11836 tcg_gen_movi_i32(tmp, 0);
11837 } else {
11838 tmp = load_reg(s, rn);
11839 }
11840 switch (op) {
11841 case 2: /* Signed bitfield extract. */
11842 imm++;
11843 if (shift + imm > 32)
11844 goto illegal_op;
11845 if (imm < 32) {
11846 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11847 }
11848 break;
11849 case 6: /* Unsigned bitfield extract. */
11850 imm++;
11851 if (shift + imm > 32)
11852 goto illegal_op;
11853 if (imm < 32) {
11854 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11855 }
11856 break;
11857 case 3: /* Bitfield insert/clear. */
11858 if (imm < shift)
11859 goto illegal_op;
11860 imm = imm + 1 - shift;
11861 if (imm != 32) {
11862 tmp2 = load_reg(s, rd);
11863 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11864 tcg_temp_free_i32(tmp2);
11865 }
11866 break;
11867 case 7:
11868 goto illegal_op;
11869 default: /* Saturate. */
11870 if (shift) {
11871 if (op & 1)
11872 tcg_gen_sari_i32(tmp, tmp, shift);
11873 else
11874 tcg_gen_shli_i32(tmp, tmp, shift);
11875 }
11876 tmp2 = tcg_const_i32(imm);
11877 if (op & 4) {
11878 /* Unsigned. */
11879 if ((op & 1) && shift == 0) {
11880 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11881 tcg_temp_free_i32(tmp);
11882 tcg_temp_free_i32(tmp2);
11883 goto illegal_op;
11884 }
11885 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11886 } else {
11887 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11888 }
11889 } else {
11890 /* Signed. */
11891 if ((op & 1) && shift == 0) {
11892 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11893 tcg_temp_free_i32(tmp);
11894 tcg_temp_free_i32(tmp2);
11895 goto illegal_op;
11896 }
11897 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11898 } else {
11899 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11900 }
11901 }
11902 tcg_temp_free_i32(tmp2);
11903 break;
11904 }
11905 store_reg(s, rd, tmp);
11906 } else {
11907 imm = ((insn & 0x04000000) >> 15)
11908 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11909 if (insn & (1 << 22)) {
11910 /* 16-bit immediate. */
11911 imm |= (insn >> 4) & 0xf000;
11912 if (insn & (1 << 23)) {
11913 /* movt */
11914 tmp = load_reg(s, rd);
11915 tcg_gen_ext16u_i32(tmp, tmp);
11916 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11917 } else {
11918 /* movw */
11919 tmp = tcg_temp_new_i32();
11920 tcg_gen_movi_i32(tmp, imm);
11921 }
11922 store_reg(s, rd, tmp);
11923 } else {
11924 /* Add/sub 12-bit immediate. */
11925 if (rn == 15) {
11926 offset = s->pc & ~(uint32_t)3;
11927 if (insn & (1 << 23))
11928 offset -= imm;
11929 else
11930 offset += imm;
11931 tmp = tcg_temp_new_i32();
11932 tcg_gen_movi_i32(tmp, offset);
11933 store_reg(s, rd, tmp);
11934 } else {
11935 tmp = load_reg(s, rn);
11936 if (insn & (1 << 23))
11937 tcg_gen_subi_i32(tmp, tmp, imm);
11938 else
11939 tcg_gen_addi_i32(tmp, tmp, imm);
11940 if (rn == 13 && rd == 13) {
11941 /* ADD SP, SP, imm or SUB SP, SP, imm */
11942 store_sp_checked(s, tmp);
11943 } else {
11944 store_reg(s, rd, tmp);
11945 }
11946 }
11947 }
11948 }
11949 } else {
11950 /*
11951 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11952 * - Data-processing (modified immediate)
11953 */
11954 int shifter_out = 0;
11955 /* modified 12-bit immediate. */
11956 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11957 imm = (insn & 0xff);
11958 switch (shift) {
11959 case 0: /* XY */
11960 /* Nothing to do. */
11961 break;
11962 case 1: /* 00XY00XY */
11963 imm |= imm << 16;
11964 break;
11965 case 2: /* XY00XY00 */
11966 imm |= imm << 16;
11967 imm <<= 8;
11968 break;
11969 case 3: /* XYXYXYXY */
11970 imm |= imm << 16;
11971 imm |= imm << 8;
11972 break;
11973 default: /* Rotated constant. */
11974 shift = (shift << 1) | (imm >> 7);
11975 imm |= 0x80;
11976 imm = imm << (32 - shift);
11977 shifter_out = 1;
11978 break;
11979 }
11980 tmp2 = tcg_temp_new_i32();
11981 tcg_gen_movi_i32(tmp2, imm);
11982 rn = (insn >> 16) & 0xf;
11983 if (rn == 15) {
11984 tmp = tcg_temp_new_i32();
11985 tcg_gen_movi_i32(tmp, 0);
11986 } else {
11987 tmp = load_reg(s, rn);
11988 }
11989 op = (insn >> 21) & 0xf;
11990 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11991 shifter_out, tmp, tmp2))
11992 goto illegal_op;
11993 tcg_temp_free_i32(tmp2);
11994 rd = (insn >> 8) & 0xf;
11995 if (rd == 13 && rn == 13
11996 && (op == 8 || op == 13)) {
11997 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11998 store_sp_checked(s, tmp);
11999 } else if (rd != 15) {
12000 store_reg(s, rd, tmp);
12001 } else {
12002 tcg_temp_free_i32(tmp);
12003 }
12004 }
12005 }
12006 break;
12007 case 12: /* Load/store single data item. */
12008 {
12009 int postinc = 0;
12010 int writeback = 0;
12011 int memidx;
12012 ISSInfo issinfo;
12013
12014 if ((insn & 0x01100000) == 0x01000000) {
12015 if (disas_neon_ls_insn(s, insn)) {
12016 goto illegal_op;
12017 }
12018 break;
12019 }
12020 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
12021 if (rs == 15) {
12022 if (!(insn & (1 << 20))) {
12023 goto illegal_op;
12024 }
12025 if (op != 2) {
12026 /* Byte or halfword load space with dest == r15 : memory hints.
12027 * Catch them early so we don't emit pointless addressing code.
12028 * This space is a mix of:
12029 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
12030 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
12031 * cores)
12032 * unallocated hints, which must be treated as NOPs
12033 * UNPREDICTABLE space, which we NOP or UNDEF depending on
12034 * which is easiest for the decoding logic
12035 * Some space which must UNDEF
12036 */
12037 int op1 = (insn >> 23) & 3;
12038 int op2 = (insn >> 6) & 0x3f;
12039 if (op & 2) {
12040 goto illegal_op;
12041 }
12042 if (rn == 15) {
12043 /* UNPREDICTABLE, unallocated hint or
12044 * PLD/PLDW/PLI (literal)
12045 */
12046 return;
12047 }
12048 if (op1 & 1) {
12049 return; /* PLD/PLDW/PLI or unallocated hint */
12050 }
12051 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
12052 return; /* PLD/PLDW/PLI or unallocated hint */
12053 }
12054 /* UNDEF space, or an UNPREDICTABLE */
12055 goto illegal_op;
12056 }
12057 }
12058 memidx = get_mem_index(s);
12059 if (rn == 15) {
12060 addr = tcg_temp_new_i32();
12061 /* PC relative. */
12062 /* s->pc has already been incremented by 4. */
12063 imm = s->pc & 0xfffffffc;
12064 if (insn & (1 << 23))
12065 imm += insn & 0xfff;
12066 else
12067 imm -= insn & 0xfff;
12068 tcg_gen_movi_i32(addr, imm);
12069 } else {
12070 addr = load_reg(s, rn);
12071 if (insn & (1 << 23)) {
12072 /* Positive offset. */
12073 imm = insn & 0xfff;
12074 tcg_gen_addi_i32(addr, addr, imm);
12075 } else {
12076 imm = insn & 0xff;
12077 switch ((insn >> 8) & 0xf) {
12078 case 0x0: /* Shifted Register. */
12079 shift = (insn >> 4) & 0xf;
12080 if (shift > 3) {
12081 tcg_temp_free_i32(addr);
12082 goto illegal_op;
12083 }
12084 tmp = load_reg(s, rm);
12085 if (shift)
12086 tcg_gen_shli_i32(tmp, tmp, shift);
12087 tcg_gen_add_i32(addr, addr, tmp);
12088 tcg_temp_free_i32(tmp);
12089 break;
12090 case 0xc: /* Negative offset. */
12091 tcg_gen_addi_i32(addr, addr, -imm);
12092 break;
12093 case 0xe: /* User privilege. */
12094 tcg_gen_addi_i32(addr, addr, imm);
12095 memidx = get_a32_user_mem_index(s);
12096 break;
12097 case 0x9: /* Post-decrement. */
12098 imm = -imm;
12099 /* Fall through. */
12100 case 0xb: /* Post-increment. */
12101 postinc = 1;
12102 writeback = 1;
12103 break;
12104 case 0xd: /* Pre-decrement. */
12105 imm = -imm;
12106 /* Fall through. */
12107 case 0xf: /* Pre-increment. */
12108 writeback = 1;
12109 break;
12110 default:
12111 tcg_temp_free_i32(addr);
12112 goto illegal_op;
12113 }
12114 }
12115 }
12116
12117 issinfo = writeback ? ISSInvalid : rs;
12118
12119 if (s->v8m_stackcheck && rn == 13 && writeback) {
12120 /*
12121 * Stackcheck. Here we know 'addr' is the current SP;
12122 * if imm is +ve we're moving SP up, else down. It is
12123 * UNKNOWN whether the limit check triggers when SP starts
12124 * below the limit and ends up above it; we chose to do so.
12125 */
12126 if ((int32_t)imm < 0) {
12127 TCGv_i32 newsp = tcg_temp_new_i32();
12128
12129 tcg_gen_addi_i32(newsp, addr, imm);
12130 gen_helper_v8m_stackcheck(cpu_env, newsp);
12131 tcg_temp_free_i32(newsp);
12132 } else {
12133 gen_helper_v8m_stackcheck(cpu_env, addr);
12134 }
12135 }
12136
12137 if (writeback && !postinc) {
12138 tcg_gen_addi_i32(addr, addr, imm);
12139 }
12140
12141 if (insn & (1 << 20)) {
12142 /* Load. */
12143 tmp = tcg_temp_new_i32();
12144 switch (op) {
12145 case 0:
12146 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
12147 break;
12148 case 4:
12149 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
12150 break;
12151 case 1:
12152 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
12153 break;
12154 case 5:
12155 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
12156 break;
12157 case 2:
12158 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
12159 break;
12160 default:
12161 tcg_temp_free_i32(tmp);
12162 tcg_temp_free_i32(addr);
12163 goto illegal_op;
12164 }
12165 if (rs == 15) {
12166 gen_bx_excret(s, tmp);
12167 } else {
12168 store_reg(s, rs, tmp);
12169 }
12170 } else {
12171 /* Store. */
12172 tmp = load_reg(s, rs);
12173 switch (op) {
12174 case 0:
12175 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
12176 break;
12177 case 1:
12178 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
12179 break;
12180 case 2:
12181 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
12182 break;
12183 default:
12184 tcg_temp_free_i32(tmp);
12185 tcg_temp_free_i32(addr);
12186 goto illegal_op;
12187 }
12188 tcg_temp_free_i32(tmp);
12189 }
12190 if (postinc)
12191 tcg_gen_addi_i32(addr, addr, imm);
12192 if (writeback) {
12193 store_reg(s, rn, addr);
12194 } else {
12195 tcg_temp_free_i32(addr);
12196 }
12197 }
12198 break;
12199 default:
12200 goto illegal_op;
12201 }
12202 return;
12203 illegal_op:
12204 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
12205 default_exception_el(s));
12206 }
12207
12208 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
12209 {
12210 uint32_t val, op, rm, rn, rd, shift, cond;
12211 int32_t offset;
12212 int i;
12213 TCGv_i32 tmp;
12214 TCGv_i32 tmp2;
12215 TCGv_i32 addr;
12216
12217 switch (insn >> 12) {
12218 case 0: case 1:
12219
12220 rd = insn & 7;
12221 op = (insn >> 11) & 3;
12222 if (op == 3) {
12223 /*
12224 * 0b0001_1xxx_xxxx_xxxx
12225 * - Add, subtract (three low registers)
12226 * - Add, subtract (two low registers and immediate)
12227 */
12228 rn = (insn >> 3) & 7;
12229 tmp = load_reg(s, rn);
12230 if (insn & (1 << 10)) {
12231 /* immediate */
12232 tmp2 = tcg_temp_new_i32();
12233 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
12234 } else {
12235 /* reg */
12236 rm = (insn >> 6) & 7;
12237 tmp2 = load_reg(s, rm);
12238 }
12239 if (insn & (1 << 9)) {
12240 if (s->condexec_mask)
12241 tcg_gen_sub_i32(tmp, tmp, tmp2);
12242 else
12243 gen_sub_CC(tmp, tmp, tmp2);
12244 } else {
12245 if (s->condexec_mask)
12246 tcg_gen_add_i32(tmp, tmp, tmp2);
12247 else
12248 gen_add_CC(tmp, tmp, tmp2);
12249 }
12250 tcg_temp_free_i32(tmp2);
12251 store_reg(s, rd, tmp);
12252 } else {
12253 /* shift immediate */
12254 rm = (insn >> 3) & 7;
12255 shift = (insn >> 6) & 0x1f;
12256 tmp = load_reg(s, rm);
12257 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
12258 if (!s->condexec_mask)
12259 gen_logic_CC(tmp);
12260 store_reg(s, rd, tmp);
12261 }
12262 break;
12263 case 2: case 3:
12264 /*
12265 * 0b001x_xxxx_xxxx_xxxx
12266 * - Add, subtract, compare, move (one low register and immediate)
12267 */
12268 op = (insn >> 11) & 3;
12269 rd = (insn >> 8) & 0x7;
12270 if (op == 0) { /* mov */
12271 tmp = tcg_temp_new_i32();
12272 tcg_gen_movi_i32(tmp, insn & 0xff);
12273 if (!s->condexec_mask)
12274 gen_logic_CC(tmp);
12275 store_reg(s, rd, tmp);
12276 } else {
12277 tmp = load_reg(s, rd);
12278 tmp2 = tcg_temp_new_i32();
12279 tcg_gen_movi_i32(tmp2, insn & 0xff);
12280 switch (op) {
12281 case 1: /* cmp */
12282 gen_sub_CC(tmp, tmp, tmp2);
12283 tcg_temp_free_i32(tmp);
12284 tcg_temp_free_i32(tmp2);
12285 break;
12286 case 2: /* add */
12287 if (s->condexec_mask)
12288 tcg_gen_add_i32(tmp, tmp, tmp2);
12289 else
12290 gen_add_CC(tmp, tmp, tmp2);
12291 tcg_temp_free_i32(tmp2);
12292 store_reg(s, rd, tmp);
12293 break;
12294 case 3: /* sub */
12295 if (s->condexec_mask)
12296 tcg_gen_sub_i32(tmp, tmp, tmp2);
12297 else
12298 gen_sub_CC(tmp, tmp, tmp2);
12299 tcg_temp_free_i32(tmp2);
12300 store_reg(s, rd, tmp);
12301 break;
12302 }
12303 }
12304 break;
12305 case 4:
12306 if (insn & (1 << 11)) {
12307 rd = (insn >> 8) & 7;
12308 /* load pc-relative. Bit 1 of PC is ignored. */
12309 val = s->pc + 2 + ((insn & 0xff) * 4);
12310 val &= ~(uint32_t)2;
12311 addr = tcg_temp_new_i32();
12312 tcg_gen_movi_i32(addr, val);
12313 tmp = tcg_temp_new_i32();
12314 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
12315 rd | ISSIs16Bit);
12316 tcg_temp_free_i32(addr);
12317 store_reg(s, rd, tmp);
12318 break;
12319 }
12320 if (insn & (1 << 10)) {
12321 /* 0b0100_01xx_xxxx_xxxx
12322 * - data processing extended, branch and exchange
12323 */
12324 rd = (insn & 7) | ((insn >> 4) & 8);
12325 rm = (insn >> 3) & 0xf;
12326 op = (insn >> 8) & 3;
12327 switch (op) {
12328 case 0: /* add */
12329 tmp = load_reg(s, rd);
12330 tmp2 = load_reg(s, rm);
12331 tcg_gen_add_i32(tmp, tmp, tmp2);
12332 tcg_temp_free_i32(tmp2);
12333 if (rd == 13) {
12334 /* ADD SP, SP, reg */
12335 store_sp_checked(s, tmp);
12336 } else {
12337 store_reg(s, rd, tmp);
12338 }
12339 break;
12340 case 1: /* cmp */
12341 tmp = load_reg(s, rd);
12342 tmp2 = load_reg(s, rm);
12343 gen_sub_CC(tmp, tmp, tmp2);
12344 tcg_temp_free_i32(tmp2);
12345 tcg_temp_free_i32(tmp);
12346 break;
12347 case 2: /* mov/cpy */
12348 tmp = load_reg(s, rm);
12349 if (rd == 13) {
12350 /* MOV SP, reg */
12351 store_sp_checked(s, tmp);
12352 } else {
12353 store_reg(s, rd, tmp);
12354 }
12355 break;
12356 case 3:
12357 {
12358 /* 0b0100_0111_xxxx_xxxx
12359 * - branch [and link] exchange thumb register
12360 */
12361 bool link = insn & (1 << 7);
12362
12363 if (insn & 3) {
12364 goto undef;
12365 }
12366 if (link) {
12367 ARCH(5);
12368 }
12369 if ((insn & 4)) {
12370 /* BXNS/BLXNS: only exists for v8M with the
12371 * security extensions, and always UNDEF if NonSecure.
12372 * We don't implement these in the user-only mode
12373 * either (in theory you can use them from Secure User
12374 * mode but they are too tied in to system emulation.)
12375 */
12376 if (!s->v8m_secure || IS_USER_ONLY) {
12377 goto undef;
12378 }
12379 if (link) {
12380 gen_blxns(s, rm);
12381 } else {
12382 gen_bxns(s, rm);
12383 }
12384 break;
12385 }
12386 /* BLX/BX */
12387 tmp = load_reg(s, rm);
12388 if (link) {
12389 val = (uint32_t)s->pc | 1;
12390 tmp2 = tcg_temp_new_i32();
12391 tcg_gen_movi_i32(tmp2, val);
12392 store_reg(s, 14, tmp2);
12393 gen_bx(s, tmp);
12394 } else {
12395 /* Only BX works as exception-return, not BLX */
12396 gen_bx_excret(s, tmp);
12397 }
12398 break;
12399 }
12400 }
12401 break;
12402 }
12403
12404 /*
12405 * 0b0100_00xx_xxxx_xxxx
12406 * - Data-processing (two low registers)
12407 */
12408 rd = insn & 7;
12409 rm = (insn >> 3) & 7;
12410 op = (insn >> 6) & 0xf;
12411 if (op == 2 || op == 3 || op == 4 || op == 7) {
12412 /* the shift/rotate ops want the operands backwards */
12413 val = rm;
12414 rm = rd;
12415 rd = val;
12416 val = 1;
12417 } else {
12418 val = 0;
12419 }
12420
12421 if (op == 9) { /* neg */
12422 tmp = tcg_temp_new_i32();
12423 tcg_gen_movi_i32(tmp, 0);
12424 } else if (op != 0xf) { /* mvn doesn't read its first operand */
12425 tmp = load_reg(s, rd);
12426 } else {
12427 tmp = NULL;
12428 }
12429
12430 tmp2 = load_reg(s, rm);
12431 switch (op) {
12432 case 0x0: /* and */
12433 tcg_gen_and_i32(tmp, tmp, tmp2);
12434 if (!s->condexec_mask)
12435 gen_logic_CC(tmp);
12436 break;
12437 case 0x1: /* eor */
12438 tcg_gen_xor_i32(tmp, tmp, tmp2);
12439 if (!s->condexec_mask)
12440 gen_logic_CC(tmp);
12441 break;
12442 case 0x2: /* lsl */
12443 if (s->condexec_mask) {
12444 gen_shl(tmp2, tmp2, tmp);
12445 } else {
12446 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12447 gen_logic_CC(tmp2);
12448 }
12449 break;
12450 case 0x3: /* lsr */
12451 if (s->condexec_mask) {
12452 gen_shr(tmp2, tmp2, tmp);
12453 } else {
12454 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12455 gen_logic_CC(tmp2);
12456 }
12457 break;
12458 case 0x4: /* asr */
12459 if (s->condexec_mask) {
12460 gen_sar(tmp2, tmp2, tmp);
12461 } else {
12462 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12463 gen_logic_CC(tmp2);
12464 }
12465 break;
12466 case 0x5: /* adc */
12467 if (s->condexec_mask) {
12468 gen_adc(tmp, tmp2);
12469 } else {
12470 gen_adc_CC(tmp, tmp, tmp2);
12471 }
12472 break;
12473 case 0x6: /* sbc */
12474 if (s->condexec_mask) {
12475 gen_sub_carry(tmp, tmp, tmp2);
12476 } else {
12477 gen_sbc_CC(tmp, tmp, tmp2);
12478 }
12479 break;
12480 case 0x7: /* ror */
12481 if (s->condexec_mask) {
12482 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12483 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12484 } else {
12485 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12486 gen_logic_CC(tmp2);
12487 }
12488 break;
12489 case 0x8: /* tst */
12490 tcg_gen_and_i32(tmp, tmp, tmp2);
12491 gen_logic_CC(tmp);
12492 rd = 16;
12493 break;
12494 case 0x9: /* neg */
12495 if (s->condexec_mask)
12496 tcg_gen_neg_i32(tmp, tmp2);
12497 else
12498 gen_sub_CC(tmp, tmp, tmp2);
12499 break;
12500 case 0xa: /* cmp */
12501 gen_sub_CC(tmp, tmp, tmp2);
12502 rd = 16;
12503 break;
12504 case 0xb: /* cmn */
12505 gen_add_CC(tmp, tmp, tmp2);
12506 rd = 16;
12507 break;
12508 case 0xc: /* orr */
12509 tcg_gen_or_i32(tmp, tmp, tmp2);
12510 if (!s->condexec_mask)
12511 gen_logic_CC(tmp);
12512 break;
12513 case 0xd: /* mul */
12514 tcg_gen_mul_i32(tmp, tmp, tmp2);
12515 if (!s->condexec_mask)
12516 gen_logic_CC(tmp);
12517 break;
12518 case 0xe: /* bic */
12519 tcg_gen_andc_i32(tmp, tmp, tmp2);
12520 if (!s->condexec_mask)
12521 gen_logic_CC(tmp);
12522 break;
12523 case 0xf: /* mvn */
12524 tcg_gen_not_i32(tmp2, tmp2);
12525 if (!s->condexec_mask)
12526 gen_logic_CC(tmp2);
12527 val = 1;
12528 rm = rd;
12529 break;
12530 }
12531 if (rd != 16) {
12532 if (val) {
12533 store_reg(s, rm, tmp2);
12534 if (op != 0xf)
12535 tcg_temp_free_i32(tmp);
12536 } else {
12537 store_reg(s, rd, tmp);
12538 tcg_temp_free_i32(tmp2);
12539 }
12540 } else {
12541 tcg_temp_free_i32(tmp);
12542 tcg_temp_free_i32(tmp2);
12543 }
12544 break;
12545
12546 case 5:
12547 /* load/store register offset. */
12548 rd = insn & 7;
12549 rn = (insn >> 3) & 7;
12550 rm = (insn >> 6) & 7;
12551 op = (insn >> 9) & 7;
12552 addr = load_reg(s, rn);
12553 tmp = load_reg(s, rm);
12554 tcg_gen_add_i32(addr, addr, tmp);
12555 tcg_temp_free_i32(tmp);
12556
12557 if (op < 3) { /* store */
12558 tmp = load_reg(s, rd);
12559 } else {
12560 tmp = tcg_temp_new_i32();
12561 }
12562
12563 switch (op) {
12564 case 0: /* str */
12565 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12566 break;
12567 case 1: /* strh */
12568 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12569 break;
12570 case 2: /* strb */
12571 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12572 break;
12573 case 3: /* ldrsb */
12574 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12575 break;
12576 case 4: /* ldr */
12577 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12578 break;
12579 case 5: /* ldrh */
12580 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12581 break;
12582 case 6: /* ldrb */
12583 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12584 break;
12585 case 7: /* ldrsh */
12586 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12587 break;
12588 }
12589 if (op >= 3) { /* load */
12590 store_reg(s, rd, tmp);
12591 } else {
12592 tcg_temp_free_i32(tmp);
12593 }
12594 tcg_temp_free_i32(addr);
12595 break;
12596
12597 case 6:
12598 /* load/store word immediate offset */
12599 rd = insn & 7;
12600 rn = (insn >> 3) & 7;
12601 addr = load_reg(s, rn);
12602 val = (insn >> 4) & 0x7c;
12603 tcg_gen_addi_i32(addr, addr, val);
12604
12605 if (insn & (1 << 11)) {
12606 /* load */
12607 tmp = tcg_temp_new_i32();
12608 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12609 store_reg(s, rd, tmp);
12610 } else {
12611 /* store */
12612 tmp = load_reg(s, rd);
12613 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12614 tcg_temp_free_i32(tmp);
12615 }
12616 tcg_temp_free_i32(addr);
12617 break;
12618
12619 case 7:
12620 /* load/store byte immediate offset */
12621 rd = insn & 7;
12622 rn = (insn >> 3) & 7;
12623 addr = load_reg(s, rn);
12624 val = (insn >> 6) & 0x1f;
12625 tcg_gen_addi_i32(addr, addr, val);
12626
12627 if (insn & (1 << 11)) {
12628 /* load */
12629 tmp = tcg_temp_new_i32();
12630 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12631 store_reg(s, rd, tmp);
12632 } else {
12633 /* store */
12634 tmp = load_reg(s, rd);
12635 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12636 tcg_temp_free_i32(tmp);
12637 }
12638 tcg_temp_free_i32(addr);
12639 break;
12640
12641 case 8:
12642 /* load/store halfword immediate offset */
12643 rd = insn & 7;
12644 rn = (insn >> 3) & 7;
12645 addr = load_reg(s, rn);
12646 val = (insn >> 5) & 0x3e;
12647 tcg_gen_addi_i32(addr, addr, val);
12648
12649 if (insn & (1 << 11)) {
12650 /* load */
12651 tmp = tcg_temp_new_i32();
12652 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12653 store_reg(s, rd, tmp);
12654 } else {
12655 /* store */
12656 tmp = load_reg(s, rd);
12657 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12658 tcg_temp_free_i32(tmp);
12659 }
12660 tcg_temp_free_i32(addr);
12661 break;
12662
12663 case 9:
12664 /* load/store from stack */
12665 rd = (insn >> 8) & 7;
12666 addr = load_reg(s, 13);
12667 val = (insn & 0xff) * 4;
12668 tcg_gen_addi_i32(addr, addr, val);
12669
12670 if (insn & (1 << 11)) {
12671 /* load */
12672 tmp = tcg_temp_new_i32();
12673 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12674 store_reg(s, rd, tmp);
12675 } else {
12676 /* store */
12677 tmp = load_reg(s, rd);
12678 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12679 tcg_temp_free_i32(tmp);
12680 }
12681 tcg_temp_free_i32(addr);
12682 break;
12683
12684 case 10:
12685 /*
12686 * 0b1010_xxxx_xxxx_xxxx
12687 * - Add PC/SP (immediate)
12688 */
12689 rd = (insn >> 8) & 7;
12690 if (insn & (1 << 11)) {
12691 /* SP */
12692 tmp = load_reg(s, 13);
12693 } else {
12694 /* PC. bit 1 is ignored. */
12695 tmp = tcg_temp_new_i32();
12696 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12697 }
12698 val = (insn & 0xff) * 4;
12699 tcg_gen_addi_i32(tmp, tmp, val);
12700 store_reg(s, rd, tmp);
12701 break;
12702
12703 case 11:
12704 /* misc */
12705 op = (insn >> 8) & 0xf;
12706 switch (op) {
12707 case 0:
12708 /*
12709 * 0b1011_0000_xxxx_xxxx
12710 * - ADD (SP plus immediate)
12711 * - SUB (SP minus immediate)
12712 */
12713 tmp = load_reg(s, 13);
12714 val = (insn & 0x7f) * 4;
12715 if (insn & (1 << 7))
12716 val = -(int32_t)val;
12717 tcg_gen_addi_i32(tmp, tmp, val);
12718 store_sp_checked(s, tmp);
12719 break;
12720
12721 case 2: /* sign/zero extend. */
12722 ARCH(6);
12723 rd = insn & 7;
12724 rm = (insn >> 3) & 7;
12725 tmp = load_reg(s, rm);
12726 switch ((insn >> 6) & 3) {
12727 case 0: gen_sxth(tmp); break;
12728 case 1: gen_sxtb(tmp); break;
12729 case 2: gen_uxth(tmp); break;
12730 case 3: gen_uxtb(tmp); break;
12731 }
12732 store_reg(s, rd, tmp);
12733 break;
12734 case 4: case 5: case 0xc: case 0xd:
12735 /*
12736 * 0b1011_x10x_xxxx_xxxx
12737 * - push/pop
12738 */
12739 addr = load_reg(s, 13);
12740 if (insn & (1 << 8))
12741 offset = 4;
12742 else
12743 offset = 0;
12744 for (i = 0; i < 8; i++) {
12745 if (insn & (1 << i))
12746 offset += 4;
12747 }
12748 if ((insn & (1 << 11)) == 0) {
12749 tcg_gen_addi_i32(addr, addr, -offset);
12750 }
12751
12752 if (s->v8m_stackcheck) {
12753 /*
12754 * Here 'addr' is the lower of "old SP" and "new SP";
12755 * if this is a pop that starts below the limit and ends
12756 * above it, it is UNKNOWN whether the limit check triggers;
12757 * we choose to trigger.
12758 */
12759 gen_helper_v8m_stackcheck(cpu_env, addr);
12760 }
12761
12762 for (i = 0; i < 8; i++) {
12763 if (insn & (1 << i)) {
12764 if (insn & (1 << 11)) {
12765 /* pop */
12766 tmp = tcg_temp_new_i32();
12767 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12768 store_reg(s, i, tmp);
12769 } else {
12770 /* push */
12771 tmp = load_reg(s, i);
12772 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12773 tcg_temp_free_i32(tmp);
12774 }
12775 /* advance to the next address. */
12776 tcg_gen_addi_i32(addr, addr, 4);
12777 }
12778 }
12779 tmp = NULL;
12780 if (insn & (1 << 8)) {
12781 if (insn & (1 << 11)) {
12782 /* pop pc */
12783 tmp = tcg_temp_new_i32();
12784 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12785 /* don't set the pc until the rest of the instruction
12786 has completed */
12787 } else {
12788 /* push lr */
12789 tmp = load_reg(s, 14);
12790 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12791 tcg_temp_free_i32(tmp);
12792 }
12793 tcg_gen_addi_i32(addr, addr, 4);
12794 }
12795 if ((insn & (1 << 11)) == 0) {
12796 tcg_gen_addi_i32(addr, addr, -offset);
12797 }
12798 /* write back the new stack pointer */
12799 store_reg(s, 13, addr);
12800 /* set the new PC value */
12801 if ((insn & 0x0900) == 0x0900) {
12802 store_reg_from_load(s, 15, tmp);
12803 }
12804 break;
12805
12806 case 1: case 3: case 9: case 11: /* czb */
12807 rm = insn & 7;
12808 tmp = load_reg(s, rm);
12809 arm_gen_condlabel(s);
12810 if (insn & (1 << 11))
12811 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12812 else
12813 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12814 tcg_temp_free_i32(tmp);
12815 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12816 val = (uint32_t)s->pc + 2;
12817 val += offset;
12818 gen_jmp(s, val);
12819 break;
12820
12821 case 15: /* IT, nop-hint. */
12822 if ((insn & 0xf) == 0) {
12823 gen_nop_hint(s, (insn >> 4) & 0xf);
12824 break;
12825 }
12826 /* If Then. */
12827 s->condexec_cond = (insn >> 4) & 0xe;
12828 s->condexec_mask = insn & 0x1f;
12829 /* No actual code generated for this insn, just setup state. */
12830 break;
12831
12832 case 0xe: /* bkpt */
12833 {
12834 int imm8 = extract32(insn, 0, 8);
12835 ARCH(5);
12836 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12837 break;
12838 }
12839
12840 case 0xa: /* rev, and hlt */
12841 {
12842 int op1 = extract32(insn, 6, 2);
12843
12844 if (op1 == 2) {
12845 /* HLT */
12846 int imm6 = extract32(insn, 0, 6);
12847
12848 gen_hlt(s, imm6);
12849 break;
12850 }
12851
12852 /* Otherwise this is rev */
12853 ARCH(6);
12854 rn = (insn >> 3) & 0x7;
12855 rd = insn & 0x7;
12856 tmp = load_reg(s, rn);
12857 switch (op1) {
12858 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12859 case 1: gen_rev16(tmp); break;
12860 case 3: gen_revsh(tmp); break;
12861 default:
12862 g_assert_not_reached();
12863 }
12864 store_reg(s, rd, tmp);
12865 break;
12866 }
12867
12868 case 6:
12869 switch ((insn >> 5) & 7) {
12870 case 2:
12871 /* setend */
12872 ARCH(6);
12873 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12874 gen_helper_setend(cpu_env);
12875 s->base.is_jmp = DISAS_UPDATE;
12876 }
12877 break;
12878 case 3:
12879 /* cps */
12880 ARCH(6);
12881 if (IS_USER(s)) {
12882 break;
12883 }
12884 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12885 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12886 /* FAULTMASK */
12887 if (insn & 1) {
12888 addr = tcg_const_i32(19);
12889 gen_helper_v7m_msr(cpu_env, addr, tmp);
12890 tcg_temp_free_i32(addr);
12891 }
12892 /* PRIMASK */
12893 if (insn & 2) {
12894 addr = tcg_const_i32(16);
12895 gen_helper_v7m_msr(cpu_env, addr, tmp);
12896 tcg_temp_free_i32(addr);
12897 }
12898 tcg_temp_free_i32(tmp);
12899 gen_lookup_tb(s);
12900 } else {
12901 if (insn & (1 << 4)) {
12902 shift = CPSR_A | CPSR_I | CPSR_F;
12903 } else {
12904 shift = 0;
12905 }
12906 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12907 }
12908 break;
12909 default:
12910 goto undef;
12911 }
12912 break;
12913
12914 default:
12915 goto undef;
12916 }
12917 break;
12918
12919 case 12:
12920 {
12921 /* load/store multiple */
12922 TCGv_i32 loaded_var = NULL;
12923 rn = (insn >> 8) & 0x7;
12924 addr = load_reg(s, rn);
12925 for (i = 0; i < 8; i++) {
12926 if (insn & (1 << i)) {
12927 if (insn & (1 << 11)) {
12928 /* load */
12929 tmp = tcg_temp_new_i32();
12930 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12931 if (i == rn) {
12932 loaded_var = tmp;
12933 } else {
12934 store_reg(s, i, tmp);
12935 }
12936 } else {
12937 /* store */
12938 tmp = load_reg(s, i);
12939 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12940 tcg_temp_free_i32(tmp);
12941 }
12942 /* advance to the next address */
12943 tcg_gen_addi_i32(addr, addr, 4);
12944 }
12945 }
12946 if ((insn & (1 << rn)) == 0) {
12947 /* base reg not in list: base register writeback */
12948 store_reg(s, rn, addr);
12949 } else {
12950 /* base reg in list: if load, complete it now */
12951 if (insn & (1 << 11)) {
12952 store_reg(s, rn, loaded_var);
12953 }
12954 tcg_temp_free_i32(addr);
12955 }
12956 break;
12957 }
12958 case 13:
12959 /* conditional branch or swi */
12960 cond = (insn >> 8) & 0xf;
12961 if (cond == 0xe)
12962 goto undef;
12963
12964 if (cond == 0xf) {
12965 /* swi */
12966 gen_set_pc_im(s, s->pc);
12967 s->svc_imm = extract32(insn, 0, 8);
12968 s->base.is_jmp = DISAS_SWI;
12969 break;
12970 }
12971 /* generate a conditional jump to next instruction */
12972 arm_skip_unless(s, cond);
12973
12974 /* jump to the offset */
12975 val = (uint32_t)s->pc + 2;
12976 offset = ((int32_t)insn << 24) >> 24;
12977 val += offset << 1;
12978 gen_jmp(s, val);
12979 break;
12980
12981 case 14:
12982 if (insn & (1 << 11)) {
12983 /* thumb_insn_is_16bit() ensures we can't get here for
12984 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12985 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12986 */
12987 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12988 ARCH(5);
12989 offset = ((insn & 0x7ff) << 1);
12990 tmp = load_reg(s, 14);
12991 tcg_gen_addi_i32(tmp, tmp, offset);
12992 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12993
12994 tmp2 = tcg_temp_new_i32();
12995 tcg_gen_movi_i32(tmp2, s->pc | 1);
12996 store_reg(s, 14, tmp2);
12997 gen_bx(s, tmp);
12998 break;
12999 }
13000 /* unconditional branch */
13001 val = (uint32_t)s->pc;
13002 offset = ((int32_t)insn << 21) >> 21;
13003 val += (offset << 1) + 2;
13004 gen_jmp(s, val);
13005 break;
13006
13007 case 15:
13008 /* thumb_insn_is_16bit() ensures we can't get here for
13009 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
13010 */
13011 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
13012
13013 if (insn & (1 << 11)) {
13014 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
13015 offset = ((insn & 0x7ff) << 1) | 1;
13016 tmp = load_reg(s, 14);
13017 tcg_gen_addi_i32(tmp, tmp, offset);
13018
13019 tmp2 = tcg_temp_new_i32();
13020 tcg_gen_movi_i32(tmp2, s->pc | 1);
13021 store_reg(s, 14, tmp2);
13022 gen_bx(s, tmp);
13023 } else {
13024 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
13025 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
13026
13027 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
13028 }
13029 break;
13030 }
13031 return;
13032 illegal_op:
13033 undef:
13034 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
13035 default_exception_el(s));
13036 }
13037
13038 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
13039 {
13040 /* Return true if the insn at dc->pc might cross a page boundary.
13041 * (False positives are OK, false negatives are not.)
13042 * We know this is a Thumb insn, and our caller ensures we are
13043 * only called if dc->pc is less than 4 bytes from the page
13044 * boundary, so we cross the page if the first 16 bits indicate
13045 * that this is a 32 bit insn.
13046 */
13047 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
13048
13049 return !thumb_insn_is_16bit(s, insn);
13050 }
13051
13052 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
13053 {
13054 DisasContext *dc = container_of(dcbase, DisasContext, base);
13055 CPUARMState *env = cs->env_ptr;
13056 ARMCPU *cpu = arm_env_get_cpu(env);
13057
13058 dc->isar = &cpu->isar;
13059 dc->pc = dc->base.pc_first;
13060 dc->condjmp = 0;
13061
13062 dc->aarch64 = 0;
13063 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13064 * there is no secure EL1, so we route exceptions to EL3.
13065 */
13066 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
13067 !arm_el_is_aa64(env, 3);
13068 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
13069 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
13070 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
13071 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
13072 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
13073 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
13074 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
13075 #if !defined(CONFIG_USER_ONLY)
13076 dc->user = (dc->current_el == 0);
13077 #endif
13078 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
13079 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
13080 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
13081 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
13082 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
13083 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
13084 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
13085 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13086 regime_is_secure(env, dc->mmu_idx);
13087 dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
13088 dc->cp_regs = cpu->cp_regs;
13089 dc->features = env->features;
13090
13091 /* Single step state. The code-generation logic here is:
13092 * SS_ACTIVE == 0:
13093 * generate code with no special handling for single-stepping (except
13094 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13095 * this happens anyway because those changes are all system register or
13096 * PSTATE writes).
13097 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13098 * emit code for one insn
13099 * emit code to clear PSTATE.SS
13100 * emit code to generate software step exception for completed step
13101 * end TB (as usual for having generated an exception)
13102 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13103 * emit code to generate a software step exception
13104 * end the TB
13105 */
13106 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
13107 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
13108 dc->is_ldex = false;
13109 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
13110
13111 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
13112
13113 /* If architectural single step active, limit to 1. */
13114 if (is_singlestepping(dc)) {
13115 dc->base.max_insns = 1;
13116 }
13117
13118 /* ARM is a fixed-length ISA. Bound the number of insns to execute
13119 to those left on the page. */
13120 if (!dc->thumb) {
13121 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
13122 dc->base.max_insns = MIN(dc->base.max_insns, bound);
13123 }
13124
13125 cpu_F0s = tcg_temp_new_i32();
13126 cpu_F1s = tcg_temp_new_i32();
13127 cpu_F0d = tcg_temp_new_i64();
13128 cpu_F1d = tcg_temp_new_i64();
13129 cpu_V0 = cpu_F0d;
13130 cpu_V1 = cpu_F1d;
13131 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
13132 cpu_M0 = tcg_temp_new_i64();
13133 }
13134
13135 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
13136 {
13137 DisasContext *dc = container_of(dcbase, DisasContext, base);
13138
13139 /* A note on handling of the condexec (IT) bits:
13140 *
13141 * We want to avoid the overhead of having to write the updated condexec
13142 * bits back to the CPUARMState for every instruction in an IT block. So:
13143 * (1) if the condexec bits are not already zero then we write
13144 * zero back into the CPUARMState now. This avoids complications trying
13145 * to do it at the end of the block. (For example if we don't do this
13146 * it's hard to identify whether we can safely skip writing condexec
13147 * at the end of the TB, which we definitely want to do for the case
13148 * where a TB doesn't do anything with the IT state at all.)
13149 * (2) if we are going to leave the TB then we call gen_set_condexec()
13150 * which will write the correct value into CPUARMState if zero is wrong.
13151 * This is done both for leaving the TB at the end, and for leaving
13152 * it because of an exception we know will happen, which is done in
13153 * gen_exception_insn(). The latter is necessary because we need to
13154 * leave the TB with the PC/IT state just prior to execution of the
13155 * instruction which caused the exception.
13156 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13157 * then the CPUARMState will be wrong and we need to reset it.
13158 * This is handled in the same way as restoration of the
13159 * PC in these situations; we save the value of the condexec bits
13160 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13161 * then uses this to restore them after an exception.
13162 *
13163 * Note that there are no instructions which can read the condexec
13164 * bits, and none which can write non-static values to them, so
13165 * we don't need to care about whether CPUARMState is correct in the
13166 * middle of a TB.
13167 */
13168
13169 /* Reset the conditional execution bits immediately. This avoids
13170 complications trying to do it at the end of the block. */
13171 if (dc->condexec_mask || dc->condexec_cond) {
13172 TCGv_i32 tmp = tcg_temp_new_i32();
13173 tcg_gen_movi_i32(tmp, 0);
13174 store_cpu_field(tmp, condexec_bits);
13175 }
13176 }
13177
13178 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
13179 {
13180 DisasContext *dc = container_of(dcbase, DisasContext, base);
13181
13182 tcg_gen_insn_start(dc->pc,
13183 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
13184 0);
13185 dc->insn_start = tcg_last_op();
13186 }
13187
13188 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
13189 const CPUBreakpoint *bp)
13190 {
13191 DisasContext *dc = container_of(dcbase, DisasContext, base);
13192
13193 if (bp->flags & BP_CPU) {
13194 gen_set_condexec(dc);
13195 gen_set_pc_im(dc, dc->pc);
13196 gen_helper_check_breakpoints(cpu_env);
13197 /* End the TB early; it's likely not going to be executed */
13198 dc->base.is_jmp = DISAS_TOO_MANY;
13199 } else {
13200 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
13201 /* The address covered by the breakpoint must be
13202 included in [tb->pc, tb->pc + tb->size) in order
13203 to for it to be properly cleared -- thus we
13204 increment the PC here so that the logic setting
13205 tb->size below does the right thing. */
13206 /* TODO: Advance PC by correct instruction length to
13207 * avoid disassembler error messages */
13208 dc->pc += 2;
13209 dc->base.is_jmp = DISAS_NORETURN;
13210 }
13211
13212 return true;
13213 }
13214
13215 static bool arm_pre_translate_insn(DisasContext *dc)
13216 {
13217 #ifdef CONFIG_USER_ONLY
13218 /* Intercept jump to the magic kernel page. */
13219 if (dc->pc >= 0xffff0000) {
13220 /* We always get here via a jump, so know we are not in a
13221 conditional execution block. */
13222 gen_exception_internal(EXCP_KERNEL_TRAP);
13223 dc->base.is_jmp = DISAS_NORETURN;
13224 return true;
13225 }
13226 #endif
13227
13228 if (dc->ss_active && !dc->pstate_ss) {
13229 /* Singlestep state is Active-pending.
13230 * If we're in this state at the start of a TB then either
13231 * a) we just took an exception to an EL which is being debugged
13232 * and this is the first insn in the exception handler
13233 * b) debug exceptions were masked and we just unmasked them
13234 * without changing EL (eg by clearing PSTATE.D)
13235 * In either case we're going to take a swstep exception in the
13236 * "did not step an insn" case, and so the syndrome ISV and EX
13237 * bits should be zero.
13238 */
13239 assert(dc->base.num_insns == 1);
13240 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
13241 default_exception_el(dc));
13242 dc->base.is_jmp = DISAS_NORETURN;
13243 return true;
13244 }
13245
13246 return false;
13247 }
13248
13249 static void arm_post_translate_insn(DisasContext *dc)
13250 {
13251 if (dc->condjmp && !dc->base.is_jmp) {
13252 gen_set_label(dc->condlabel);
13253 dc->condjmp = 0;
13254 }
13255 dc->base.pc_next = dc->pc;
13256 translator_loop_temp_check(&dc->base);
13257 }
13258
13259 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13260 {
13261 DisasContext *dc = container_of(dcbase, DisasContext, base);
13262 CPUARMState *env = cpu->env_ptr;
13263 unsigned int insn;
13264
13265 if (arm_pre_translate_insn(dc)) {
13266 return;
13267 }
13268
13269 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
13270 dc->insn = insn;
13271 dc->pc += 4;
13272 disas_arm_insn(dc, insn);
13273
13274 arm_post_translate_insn(dc);
13275
13276 /* ARM is a fixed-length ISA. We performed the cross-page check
13277 in init_disas_context by adjusting max_insns. */
13278 }
13279
13280 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
13281 {
13282 /* Return true if this Thumb insn is always unconditional,
13283 * even inside an IT block. This is true of only a very few
13284 * instructions: BKPT, HLT, and SG.
13285 *
13286 * A larger class of instructions are UNPREDICTABLE if used
13287 * inside an IT block; we do not need to detect those here, because
13288 * what we do by default (perform the cc check and update the IT
13289 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13290 * choice for those situations.
13291 *
13292 * insn is either a 16-bit or a 32-bit instruction; the two are
13293 * distinguishable because for the 16-bit case the top 16 bits
13294 * are zeroes, and that isn't a valid 32-bit encoding.
13295 */
13296 if ((insn & 0xffffff00) == 0xbe00) {
13297 /* BKPT */
13298 return true;
13299 }
13300
13301 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
13302 !arm_dc_feature(s, ARM_FEATURE_M)) {
13303 /* HLT: v8A only. This is unconditional even when it is going to
13304 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13305 * For v7 cores this was a plain old undefined encoding and so
13306 * honours its cc check. (We might be using the encoding as
13307 * a semihosting trap, but we don't change the cc check behaviour
13308 * on that account, because a debugger connected to a real v7A
13309 * core and emulating semihosting traps by catching the UNDEF
13310 * exception would also only see cases where the cc check passed.
13311 * No guest code should be trying to do a HLT semihosting trap
13312 * in an IT block anyway.
13313 */
13314 return true;
13315 }
13316
13317 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
13318 arm_dc_feature(s, ARM_FEATURE_M)) {
13319 /* SG: v8M only */
13320 return true;
13321 }
13322
13323 return false;
13324 }
13325
13326 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13327 {
13328 DisasContext *dc = container_of(dcbase, DisasContext, base);
13329 CPUARMState *env = cpu->env_ptr;
13330 uint32_t insn;
13331 bool is_16bit;
13332
13333 if (arm_pre_translate_insn(dc)) {
13334 return;
13335 }
13336
13337 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13338 is_16bit = thumb_insn_is_16bit(dc, insn);
13339 dc->pc += 2;
13340 if (!is_16bit) {
13341 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13342
13343 insn = insn << 16 | insn2;
13344 dc->pc += 2;
13345 }
13346 dc->insn = insn;
13347
13348 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
13349 uint32_t cond = dc->condexec_cond;
13350
13351 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
13352 arm_skip_unless(dc, cond);
13353 }
13354 }
13355
13356 if (is_16bit) {
13357 disas_thumb_insn(dc, insn);
13358 } else {
13359 disas_thumb2_insn(dc, insn);
13360 }
13361
13362 /* Advance the Thumb condexec condition. */
13363 if (dc->condexec_mask) {
13364 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13365 ((dc->condexec_mask >> 4) & 1));
13366 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13367 if (dc->condexec_mask == 0) {
13368 dc->condexec_cond = 0;
13369 }
13370 }
13371
13372 arm_post_translate_insn(dc);
13373
13374 /* Thumb is a variable-length ISA. Stop translation when the next insn
13375 * will touch a new page. This ensures that prefetch aborts occur at
13376 * the right place.
13377 *
13378 * We want to stop the TB if the next insn starts in a new page,
13379 * or if it spans between this page and the next. This means that
13380 * if we're looking at the last halfword in the page we need to
13381 * see if it's a 16-bit Thumb insn (which will fit in this TB)
13382 * or a 32-bit Thumb insn (which won't).
13383 * This is to avoid generating a silly TB with a single 16-bit insn
13384 * in it at the end of this page (which would execute correctly
13385 * but isn't very efficient).
13386 */
13387 if (dc->base.is_jmp == DISAS_NEXT
13388 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13389 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13390 && insn_crosses_page(env, dc)))) {
13391 dc->base.is_jmp = DISAS_TOO_MANY;
13392 }
13393 }
13394
13395 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13396 {
13397 DisasContext *dc = container_of(dcbase, DisasContext, base);
13398
13399 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13400 /* FIXME: This can theoretically happen with self-modifying code. */
13401 cpu_abort(cpu, "IO on conditional branch instruction");
13402 }
13403
13404 /* At this stage dc->condjmp will only be set when the skipped
13405 instruction was a conditional branch or trap, and the PC has
13406 already been written. */
13407 gen_set_condexec(dc);
13408 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13409 /* Exception return branches need some special case code at the
13410 * end of the TB, which is complex enough that it has to
13411 * handle the single-step vs not and the condition-failed
13412 * insn codepath itself.
13413 */
13414 gen_bx_excret_final_code(dc);
13415 } else if (unlikely(is_singlestepping(dc))) {
13416 /* Unconditional and "condition passed" instruction codepath. */
13417 switch (dc->base.is_jmp) {
13418 case DISAS_SWI:
13419 gen_ss_advance(dc);
13420 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13421 default_exception_el(dc));
13422 break;
13423 case DISAS_HVC:
13424 gen_ss_advance(dc);
13425 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13426 break;
13427 case DISAS_SMC:
13428 gen_ss_advance(dc);
13429 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13430 break;
13431 case DISAS_NEXT:
13432 case DISAS_TOO_MANY:
13433 case DISAS_UPDATE:
13434 gen_set_pc_im(dc, dc->pc);
13435 /* fall through */
13436 default:
13437 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13438 gen_singlestep_exception(dc);
13439 break;
13440 case DISAS_NORETURN:
13441 break;
13442 }
13443 } else {
13444 /* While branches must always occur at the end of an IT block,
13445 there are a few other things that can cause us to terminate
13446 the TB in the middle of an IT block:
13447 - Exception generating instructions (bkpt, swi, undefined).
13448 - Page boundaries.
13449 - Hardware watchpoints.
13450 Hardware breakpoints have already been handled and skip this code.
13451 */
13452 switch(dc->base.is_jmp) {
13453 case DISAS_NEXT:
13454 case DISAS_TOO_MANY:
13455 gen_goto_tb(dc, 1, dc->pc);
13456 break;
13457 case DISAS_JUMP:
13458 gen_goto_ptr();
13459 break;
13460 case DISAS_UPDATE:
13461 gen_set_pc_im(dc, dc->pc);
13462 /* fall through */
13463 default:
13464 /* indicate that the hash table must be used to find the next TB */
13465 tcg_gen_exit_tb(NULL, 0);
13466 break;
13467 case DISAS_NORETURN:
13468 /* nothing more to generate */
13469 break;
13470 case DISAS_WFI:
13471 {
13472 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13473 !(dc->insn & (1U << 31))) ? 2 : 4);
13474
13475 gen_helper_wfi(cpu_env, tmp);
13476 tcg_temp_free_i32(tmp);
13477 /* The helper doesn't necessarily throw an exception, but we
13478 * must go back to the main loop to check for interrupts anyway.
13479 */
13480 tcg_gen_exit_tb(NULL, 0);
13481 break;
13482 }
13483 case DISAS_WFE:
13484 gen_helper_wfe(cpu_env);
13485 break;
13486 case DISAS_YIELD:
13487 gen_helper_yield(cpu_env);
13488 break;
13489 case DISAS_SWI:
13490 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13491 default_exception_el(dc));
13492 break;
13493 case DISAS_HVC:
13494 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13495 break;
13496 case DISAS_SMC:
13497 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13498 break;
13499 }
13500 }
13501
13502 if (dc->condjmp) {
13503 /* "Condition failed" instruction codepath for the branch/trap insn */
13504 gen_set_label(dc->condlabel);
13505 gen_set_condexec(dc);
13506 if (unlikely(is_singlestepping(dc))) {
13507 gen_set_pc_im(dc, dc->pc);
13508 gen_singlestep_exception(dc);
13509 } else {
13510 gen_goto_tb(dc, 1, dc->pc);
13511 }
13512 }
13513
13514 /* Functions above can change dc->pc, so re-align db->pc_next */
13515 dc->base.pc_next = dc->pc;
13516 }
13517
13518 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13519 {
13520 DisasContext *dc = container_of(dcbase, DisasContext, base);
13521
13522 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13523 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13524 }
13525
13526 static const TranslatorOps arm_translator_ops = {
13527 .init_disas_context = arm_tr_init_disas_context,
13528 .tb_start = arm_tr_tb_start,
13529 .insn_start = arm_tr_insn_start,
13530 .breakpoint_check = arm_tr_breakpoint_check,
13531 .translate_insn = arm_tr_translate_insn,
13532 .tb_stop = arm_tr_tb_stop,
13533 .disas_log = arm_tr_disas_log,
13534 };
13535
13536 static const TranslatorOps thumb_translator_ops = {
13537 .init_disas_context = arm_tr_init_disas_context,
13538 .tb_start = arm_tr_tb_start,
13539 .insn_start = arm_tr_insn_start,
13540 .breakpoint_check = arm_tr_breakpoint_check,
13541 .translate_insn = thumb_tr_translate_insn,
13542 .tb_stop = arm_tr_tb_stop,
13543 .disas_log = arm_tr_disas_log,
13544 };
13545
13546 /* generate intermediate code for basic block 'tb'. */
13547 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13548 {
13549 DisasContext dc;
13550 const TranslatorOps *ops = &arm_translator_ops;
13551
13552 if (ARM_TBFLAG_THUMB(tb->flags)) {
13553 ops = &thumb_translator_ops;
13554 }
13555 #ifdef TARGET_AARCH64
13556 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
13557 ops = &aarch64_translator_ops;
13558 }
13559 #endif
13560
13561 translator_loop(ops, &dc.base, cpu, tb);
13562 }
13563
13564 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13565 int flags)
13566 {
13567 ARMCPU *cpu = ARM_CPU(cs);
13568 CPUARMState *env = &cpu->env;
13569 int i;
13570
13571 if (is_a64(env)) {
13572 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13573 return;
13574 }
13575
13576 for(i=0;i<16;i++) {
13577 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13578 if ((i % 4) == 3)
13579 cpu_fprintf(f, "\n");
13580 else
13581 cpu_fprintf(f, " ");
13582 }
13583
13584 if (arm_feature(env, ARM_FEATURE_M)) {
13585 uint32_t xpsr = xpsr_read(env);
13586 const char *mode;
13587 const char *ns_status = "";
13588
13589 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13590 ns_status = env->v7m.secure ? "S " : "NS ";
13591 }
13592
13593 if (xpsr & XPSR_EXCP) {
13594 mode = "handler";
13595 } else {
13596 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13597 mode = "unpriv-thread";
13598 } else {
13599 mode = "priv-thread";
13600 }
13601 }
13602
13603 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13604 xpsr,
13605 xpsr & XPSR_N ? 'N' : '-',
13606 xpsr & XPSR_Z ? 'Z' : '-',
13607 xpsr & XPSR_C ? 'C' : '-',
13608 xpsr & XPSR_V ? 'V' : '-',
13609 xpsr & XPSR_T ? 'T' : 'A',
13610 ns_status,
13611 mode);
13612 } else {
13613 uint32_t psr = cpsr_read(env);
13614 const char *ns_status = "";
13615
13616 if (arm_feature(env, ARM_FEATURE_EL3) &&
13617 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13618 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13619 }
13620
13621 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13622 psr,
13623 psr & CPSR_N ? 'N' : '-',
13624 psr & CPSR_Z ? 'Z' : '-',
13625 psr & CPSR_C ? 'C' : '-',
13626 psr & CPSR_V ? 'V' : '-',
13627 psr & CPSR_T ? 'T' : 'A',
13628 ns_status,
13629 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13630 }
13631
13632 if (flags & CPU_DUMP_FPU) {
13633 int numvfpregs = 0;
13634 if (arm_feature(env, ARM_FEATURE_VFP)) {
13635 numvfpregs += 16;
13636 }
13637 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13638 numvfpregs += 16;
13639 }
13640 for (i = 0; i < numvfpregs; i++) {
13641 uint64_t v = *aa32_vfp_dreg(env, i);
13642 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13643 i * 2, (uint32_t)v,
13644 i * 2 + 1, (uint32_t)(v >> 32),
13645 i, v);
13646 }
13647 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
13648 }
13649 }
13650
13651 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13652 target_ulong *data)
13653 {
13654 if (is_a64(env)) {
13655 env->pc = data[0];
13656 env->condexec_bits = 0;
13657 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13658 } else {
13659 env->regs[15] = data[0];
13660 env->condexec_bits = data[1];
13661 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13662 }
13663 }