]> git.proxmox.com Git - mirror_qemu.git/blob - target/arm/translate.c
4c11407e9e205aa7a0f4fa798990f27dc3f4eccc
[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 "qemu/qemu-print.h"
32 #include "arm_ldst.h"
33 #include "hw/semihosting/semihost.h"
34
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
37
38 #include "trace-tcg.h"
39 #include "exec/log.h"
40
41
42 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
43 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
44 /* currently all emulated v5 cores are also v5TE, so don't bother */
45 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
46 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
47 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
48 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
49 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
50 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
51 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52
53 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54
55 #include "translate.h"
56
57 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) 1
59 #else
60 #define IS_USER(s) (s->user)
61 #endif
62
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
65 static TCGv_i32 cpu_R[16];
66 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
67 TCGv_i64 cpu_exclusive_addr;
68 TCGv_i64 cpu_exclusive_val;
69
70 /* FIXME: These should be removed. */
71 static TCGv_i32 cpu_F0s, cpu_F1s;
72 static TCGv_i64 cpu_F0d, cpu_F1d;
73
74 #include "exec/gen-icount.h"
75
76 static const char * const regnames[] =
77 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79
80 /* Function prototypes for gen_ functions calling Neon helpers. */
81 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
82 TCGv_i32, TCGv_i32);
83
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
86 {
87 int i;
88
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
91 offsetof(CPUARMState, regs[i]),
92 regnames[i]);
93 }
94 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
98
99 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103
104 a64_translate_init();
105 }
106
107 /* Flags for the disas_set_da_iss info argument:
108 * lower bits hold the Rt register number, higher bits are flags.
109 */
110 typedef enum ISSInfo {
111 ISSNone = 0,
112 ISSRegMask = 0x1f,
113 ISSInvalid = (1 << 5),
114 ISSIsAcqRel = (1 << 6),
115 ISSIsWrite = (1 << 7),
116 ISSIs16Bit = (1 << 8),
117 } ISSInfo;
118
119 /* Save the syndrome information for a Data Abort */
120 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
121 {
122 uint32_t syn;
123 int sas = memop & MO_SIZE;
124 bool sse = memop & MO_SIGN;
125 bool is_acqrel = issinfo & ISSIsAcqRel;
126 bool is_write = issinfo & ISSIsWrite;
127 bool is_16bit = issinfo & ISSIs16Bit;
128 int srt = issinfo & ISSRegMask;
129
130 if (issinfo & ISSInvalid) {
131 /* Some callsites want to conditionally provide ISS info,
132 * eg "only if this was not a writeback"
133 */
134 return;
135 }
136
137 if (srt == 15) {
138 /* For AArch32, insns where the src/dest is R15 never generate
139 * ISS information. Catching that here saves checking at all
140 * the call sites.
141 */
142 return;
143 }
144
145 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
146 0, 0, 0, is_write, 0, is_16bit);
147 disas_set_insn_syndrome(s, syn);
148 }
149
150 static inline int get_a32_user_mem_index(DisasContext *s)
151 {
152 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
153 * insns:
154 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
155 * otherwise, access as if at PL0.
156 */
157 switch (s->mmu_idx) {
158 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
159 case ARMMMUIdx_S12NSE0:
160 case ARMMMUIdx_S12NSE1:
161 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
162 case ARMMMUIdx_S1E3:
163 case ARMMMUIdx_S1SE0:
164 case ARMMMUIdx_S1SE1:
165 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
166 case ARMMMUIdx_MUser:
167 case ARMMMUIdx_MPriv:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
169 case ARMMMUIdx_MUserNegPri:
170 case ARMMMUIdx_MPrivNegPri:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
172 case ARMMMUIdx_MSUser:
173 case ARMMMUIdx_MSPriv:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
175 case ARMMMUIdx_MSUserNegPri:
176 case ARMMMUIdx_MSPrivNegPri:
177 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
178 case ARMMMUIdx_S2NS:
179 default:
180 g_assert_not_reached();
181 }
182 }
183
184 static inline TCGv_i32 load_cpu_offset(int offset)
185 {
186 TCGv_i32 tmp = tcg_temp_new_i32();
187 tcg_gen_ld_i32(tmp, cpu_env, offset);
188 return tmp;
189 }
190
191 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
192
193 static inline void store_cpu_offset(TCGv_i32 var, int offset)
194 {
195 tcg_gen_st_i32(var, cpu_env, offset);
196 tcg_temp_free_i32(var);
197 }
198
199 #define store_cpu_field(var, name) \
200 store_cpu_offset(var, offsetof(CPUARMState, name))
201
202 /* Set a variable to the value of a CPU register. */
203 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
204 {
205 if (reg == 15) {
206 uint32_t addr;
207 /* normally, since we updated PC, we need only to add one insn */
208 if (s->thumb)
209 addr = (long)s->pc + 2;
210 else
211 addr = (long)s->pc + 4;
212 tcg_gen_movi_i32(var, addr);
213 } else {
214 tcg_gen_mov_i32(var, cpu_R[reg]);
215 }
216 }
217
218 /* Create a new temporary and set it to the value of a CPU register. */
219 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
220 {
221 TCGv_i32 tmp = tcg_temp_new_i32();
222 load_reg_var(s, tmp, reg);
223 return tmp;
224 }
225
226 /* Set a CPU register. The source must be a temporary and will be
227 marked as dead. */
228 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
229 {
230 if (reg == 15) {
231 /* In Thumb mode, we must ignore bit 0.
232 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
233 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
234 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 */
236 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
237 s->base.is_jmp = DISAS_JUMP;
238 }
239 tcg_gen_mov_i32(cpu_R[reg], var);
240 tcg_temp_free_i32(var);
241 }
242
243 /*
244 * Variant of store_reg which applies v8M stack-limit checks before updating
245 * SP. If the check fails this will result in an exception being taken.
246 * We disable the stack checks for CONFIG_USER_ONLY because we have
247 * no idea what the stack limits should be in that case.
248 * If stack checking is not being done this just acts like store_reg().
249 */
250 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
251 {
252 #ifndef CONFIG_USER_ONLY
253 if (s->v8m_stackcheck) {
254 gen_helper_v8m_stackcheck(cpu_env, var);
255 }
256 #endif
257 store_reg(s, 13, var);
258 }
259
260 /* Value extensions. */
261 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
262 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
263 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
264 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
265
266 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
267 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
268
269
270 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
271 {
272 TCGv_i32 tmp_mask = tcg_const_i32(mask);
273 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
274 tcg_temp_free_i32(tmp_mask);
275 }
276 /* Set NZCV flags from the high 4 bits of var. */
277 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
278
279 static void gen_exception_internal(int excp)
280 {
281 TCGv_i32 tcg_excp = tcg_const_i32(excp);
282
283 assert(excp_is_internal(excp));
284 gen_helper_exception_internal(cpu_env, tcg_excp);
285 tcg_temp_free_i32(tcg_excp);
286 }
287
288 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
289 {
290 TCGv_i32 tcg_excp = tcg_const_i32(excp);
291 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
292 TCGv_i32 tcg_el = tcg_const_i32(target_el);
293
294 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
295 tcg_syn, tcg_el);
296
297 tcg_temp_free_i32(tcg_el);
298 tcg_temp_free_i32(tcg_syn);
299 tcg_temp_free_i32(tcg_excp);
300 }
301
302 static void gen_step_complete_exception(DisasContext *s)
303 {
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
312 */
313 gen_ss_advance(s);
314 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
315 default_exception_el(s));
316 s->base.is_jmp = DISAS_NORETURN;
317 }
318
319 static void gen_singlestep_exception(DisasContext *s)
320 {
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
324 */
325 if (s->ss_active) {
326 gen_step_complete_exception(s);
327 } else {
328 gen_exception_internal(EXCP_DEBUG);
329 }
330 }
331
332 static inline bool is_singlestepping(DisasContext *s)
333 {
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
339 */
340 return s->base.singlestep_enabled || s->ss_active;
341 }
342
343 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
344 {
345 TCGv_i32 tmp1 = tcg_temp_new_i32();
346 TCGv_i32 tmp2 = tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1, a);
348 tcg_gen_ext16s_i32(tmp2, b);
349 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
350 tcg_temp_free_i32(tmp2);
351 tcg_gen_sari_i32(a, a, 16);
352 tcg_gen_sari_i32(b, b, 16);
353 tcg_gen_mul_i32(b, b, a);
354 tcg_gen_mov_i32(a, tmp1);
355 tcg_temp_free_i32(tmp1);
356 }
357
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 var)
360 {
361 TCGv_i32 tmp = tcg_temp_new_i32();
362 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp, var, 8);
364 tcg_gen_and_i32(tmp, tmp, mask);
365 tcg_gen_and_i32(var, var, mask);
366 tcg_gen_shli_i32(var, var, 8);
367 tcg_gen_or_i32(var, var, tmp);
368 tcg_temp_free_i32(mask);
369 tcg_temp_free_i32(tmp);
370 }
371
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 var)
374 {
375 tcg_gen_ext16u_i32(var, var);
376 tcg_gen_bswap16_i32(var, var);
377 tcg_gen_ext16s_i32(var, var);
378 }
379
380 /* Return (b << 32) + a. Mark inputs as dead */
381 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
382 {
383 TCGv_i64 tmp64 = tcg_temp_new_i64();
384
385 tcg_gen_extu_i32_i64(tmp64, b);
386 tcg_temp_free_i32(b);
387 tcg_gen_shli_i64(tmp64, tmp64, 32);
388 tcg_gen_add_i64(a, tmp64, a);
389
390 tcg_temp_free_i64(tmp64);
391 return a;
392 }
393
394 /* Return (b << 32) - a. Mark inputs as dead. */
395 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
396 {
397 TCGv_i64 tmp64 = tcg_temp_new_i64();
398
399 tcg_gen_extu_i32_i64(tmp64, b);
400 tcg_temp_free_i32(b);
401 tcg_gen_shli_i64(tmp64, tmp64, 32);
402 tcg_gen_sub_i64(a, tmp64, a);
403
404 tcg_temp_free_i64(tmp64);
405 return a;
406 }
407
408 /* 32x32->64 multiply. Marks inputs as dead. */
409 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
410 {
411 TCGv_i32 lo = tcg_temp_new_i32();
412 TCGv_i32 hi = tcg_temp_new_i32();
413 TCGv_i64 ret;
414
415 tcg_gen_mulu2_i32(lo, hi, a, b);
416 tcg_temp_free_i32(a);
417 tcg_temp_free_i32(b);
418
419 ret = tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret, lo, hi);
421 tcg_temp_free_i32(lo);
422 tcg_temp_free_i32(hi);
423
424 return ret;
425 }
426
427 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
428 {
429 TCGv_i32 lo = tcg_temp_new_i32();
430 TCGv_i32 hi = tcg_temp_new_i32();
431 TCGv_i64 ret;
432
433 tcg_gen_muls2_i32(lo, hi, a, b);
434 tcg_temp_free_i32(a);
435 tcg_temp_free_i32(b);
436
437 ret = tcg_temp_new_i64();
438 tcg_gen_concat_i32_i64(ret, lo, hi);
439 tcg_temp_free_i32(lo);
440 tcg_temp_free_i32(hi);
441
442 return ret;
443 }
444
445 /* Swap low and high halfwords. */
446 static void gen_swap_half(TCGv_i32 var)
447 {
448 TCGv_i32 tmp = tcg_temp_new_i32();
449 tcg_gen_shri_i32(tmp, var, 16);
450 tcg_gen_shli_i32(var, var, 16);
451 tcg_gen_or_i32(var, var, tmp);
452 tcg_temp_free_i32(tmp);
453 }
454
455 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
456 tmp = (t0 ^ t1) & 0x8000;
457 t0 &= ~0x8000;
458 t1 &= ~0x8000;
459 t0 = (t0 + t1) ^ tmp;
460 */
461
462 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
463 {
464 TCGv_i32 tmp = tcg_temp_new_i32();
465 tcg_gen_xor_i32(tmp, t0, t1);
466 tcg_gen_andi_i32(tmp, tmp, 0x8000);
467 tcg_gen_andi_i32(t0, t0, ~0x8000);
468 tcg_gen_andi_i32(t1, t1, ~0x8000);
469 tcg_gen_add_i32(t0, t0, t1);
470 tcg_gen_xor_i32(t0, t0, tmp);
471 tcg_temp_free_i32(tmp);
472 tcg_temp_free_i32(t1);
473 }
474
475 /* Set CF to the top bit of var. */
476 static void gen_set_CF_bit31(TCGv_i32 var)
477 {
478 tcg_gen_shri_i32(cpu_CF, var, 31);
479 }
480
481 /* Set N and Z flags from var. */
482 static inline void gen_logic_CC(TCGv_i32 var)
483 {
484 tcg_gen_mov_i32(cpu_NF, var);
485 tcg_gen_mov_i32(cpu_ZF, var);
486 }
487
488 /* T0 += T1 + CF. */
489 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
490 {
491 tcg_gen_add_i32(t0, t0, t1);
492 tcg_gen_add_i32(t0, t0, cpu_CF);
493 }
494
495 /* dest = T0 + T1 + CF. */
496 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
497 {
498 tcg_gen_add_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
500 }
501
502 /* dest = T0 - T1 + CF - 1. */
503 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
504 {
505 tcg_gen_sub_i32(dest, t0, t1);
506 tcg_gen_add_i32(dest, dest, cpu_CF);
507 tcg_gen_subi_i32(dest, dest, 1);
508 }
509
510 /* dest = T0 + T1. Compute C, N, V and Z flags */
511 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
512 {
513 TCGv_i32 tmp = tcg_temp_new_i32();
514 tcg_gen_movi_i32(tmp, 0);
515 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
516 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
517 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
518 tcg_gen_xor_i32(tmp, t0, t1);
519 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
520 tcg_temp_free_i32(tmp);
521 tcg_gen_mov_i32(dest, cpu_NF);
522 }
523
524 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
525 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
526 {
527 TCGv_i32 tmp = tcg_temp_new_i32();
528 if (TCG_TARGET_HAS_add2_i32) {
529 tcg_gen_movi_i32(tmp, 0);
530 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
531 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
532 } else {
533 TCGv_i64 q0 = tcg_temp_new_i64();
534 TCGv_i64 q1 = tcg_temp_new_i64();
535 tcg_gen_extu_i32_i64(q0, t0);
536 tcg_gen_extu_i32_i64(q1, t1);
537 tcg_gen_add_i64(q0, q0, q1);
538 tcg_gen_extu_i32_i64(q1, cpu_CF);
539 tcg_gen_add_i64(q0, q0, q1);
540 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
541 tcg_temp_free_i64(q0);
542 tcg_temp_free_i64(q1);
543 }
544 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
545 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
546 tcg_gen_xor_i32(tmp, t0, t1);
547 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
548 tcg_temp_free_i32(tmp);
549 tcg_gen_mov_i32(dest, cpu_NF);
550 }
551
552 /* dest = T0 - T1. Compute C, N, V and Z flags */
553 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
554 {
555 TCGv_i32 tmp;
556 tcg_gen_sub_i32(cpu_NF, t0, t1);
557 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
558 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
559 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
560 tmp = tcg_temp_new_i32();
561 tcg_gen_xor_i32(tmp, t0, t1);
562 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
563 tcg_temp_free_i32(tmp);
564 tcg_gen_mov_i32(dest, cpu_NF);
565 }
566
567 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
568 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
569 {
570 TCGv_i32 tmp = tcg_temp_new_i32();
571 tcg_gen_not_i32(tmp, t1);
572 gen_adc_CC(dest, t0, tmp);
573 tcg_temp_free_i32(tmp);
574 }
575
576 #define GEN_SHIFT(name) \
577 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
578 { \
579 TCGv_i32 tmp1, tmp2, tmp3; \
580 tmp1 = tcg_temp_new_i32(); \
581 tcg_gen_andi_i32(tmp1, t1, 0xff); \
582 tmp2 = tcg_const_i32(0); \
583 tmp3 = tcg_const_i32(0x1f); \
584 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
585 tcg_temp_free_i32(tmp3); \
586 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
587 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
588 tcg_temp_free_i32(tmp2); \
589 tcg_temp_free_i32(tmp1); \
590 }
591 GEN_SHIFT(shl)
592 GEN_SHIFT(shr)
593 #undef GEN_SHIFT
594
595 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
596 {
597 TCGv_i32 tmp1, tmp2;
598 tmp1 = tcg_temp_new_i32();
599 tcg_gen_andi_i32(tmp1, t1, 0xff);
600 tmp2 = tcg_const_i32(0x1f);
601 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
602 tcg_temp_free_i32(tmp2);
603 tcg_gen_sar_i32(dest, t0, tmp1);
604 tcg_temp_free_i32(tmp1);
605 }
606
607 static void shifter_out_im(TCGv_i32 var, int shift)
608 {
609 if (shift == 0) {
610 tcg_gen_andi_i32(cpu_CF, var, 1);
611 } else {
612 tcg_gen_shri_i32(cpu_CF, var, shift);
613 if (shift != 31) {
614 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
615 }
616 }
617 }
618
619 /* Shift by immediate. Includes special handling for shift == 0. */
620 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
621 int shift, int flags)
622 {
623 switch (shiftop) {
624 case 0: /* LSL */
625 if (shift != 0) {
626 if (flags)
627 shifter_out_im(var, 32 - shift);
628 tcg_gen_shli_i32(var, var, shift);
629 }
630 break;
631 case 1: /* LSR */
632 if (shift == 0) {
633 if (flags) {
634 tcg_gen_shri_i32(cpu_CF, var, 31);
635 }
636 tcg_gen_movi_i32(var, 0);
637 } else {
638 if (flags)
639 shifter_out_im(var, shift - 1);
640 tcg_gen_shri_i32(var, var, shift);
641 }
642 break;
643 case 2: /* ASR */
644 if (shift == 0)
645 shift = 32;
646 if (flags)
647 shifter_out_im(var, shift - 1);
648 if (shift == 32)
649 shift = 31;
650 tcg_gen_sari_i32(var, var, shift);
651 break;
652 case 3: /* ROR/RRX */
653 if (shift != 0) {
654 if (flags)
655 shifter_out_im(var, shift - 1);
656 tcg_gen_rotri_i32(var, var, shift); break;
657 } else {
658 TCGv_i32 tmp = tcg_temp_new_i32();
659 tcg_gen_shli_i32(tmp, cpu_CF, 31);
660 if (flags)
661 shifter_out_im(var, 0);
662 tcg_gen_shri_i32(var, var, 1);
663 tcg_gen_or_i32(var, var, tmp);
664 tcg_temp_free_i32(tmp);
665 }
666 }
667 };
668
669 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
670 TCGv_i32 shift, int flags)
671 {
672 if (flags) {
673 switch (shiftop) {
674 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
675 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
676 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
677 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
678 }
679 } else {
680 switch (shiftop) {
681 case 0:
682 gen_shl(var, var, shift);
683 break;
684 case 1:
685 gen_shr(var, var, shift);
686 break;
687 case 2:
688 gen_sar(var, var, shift);
689 break;
690 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
691 tcg_gen_rotr_i32(var, var, shift); break;
692 }
693 }
694 tcg_temp_free_i32(shift);
695 }
696
697 #define PAS_OP(pfx) \
698 switch (op2) { \
699 case 0: gen_pas_helper(glue(pfx,add16)); break; \
700 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
701 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
702 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
703 case 4: gen_pas_helper(glue(pfx,add8)); break; \
704 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
705 }
706 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
707 {
708 TCGv_ptr tmp;
709
710 switch (op1) {
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
712 case 1:
713 tmp = tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
715 PAS_OP(s)
716 tcg_temp_free_ptr(tmp);
717 break;
718 case 5:
719 tmp = tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
721 PAS_OP(u)
722 tcg_temp_free_ptr(tmp);
723 break;
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
726 case 2:
727 PAS_OP(q);
728 break;
729 case 3:
730 PAS_OP(sh);
731 break;
732 case 6:
733 PAS_OP(uq);
734 break;
735 case 7:
736 PAS_OP(uh);
737 break;
738 #undef gen_pas_helper
739 }
740 }
741 #undef PAS_OP
742
743 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
744 #define PAS_OP(pfx) \
745 switch (op1) { \
746 case 0: gen_pas_helper(glue(pfx,add8)); break; \
747 case 1: gen_pas_helper(glue(pfx,add16)); break; \
748 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
749 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
750 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
751 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
752 }
753 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
754 {
755 TCGv_ptr tmp;
756
757 switch (op2) {
758 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
759 case 0:
760 tmp = tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
762 PAS_OP(s)
763 tcg_temp_free_ptr(tmp);
764 break;
765 case 4:
766 tmp = tcg_temp_new_ptr();
767 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
768 PAS_OP(u)
769 tcg_temp_free_ptr(tmp);
770 break;
771 #undef gen_pas_helper
772 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
773 case 1:
774 PAS_OP(q);
775 break;
776 case 2:
777 PAS_OP(sh);
778 break;
779 case 5:
780 PAS_OP(uq);
781 break;
782 case 6:
783 PAS_OP(uh);
784 break;
785 #undef gen_pas_helper
786 }
787 }
788 #undef PAS_OP
789
790 /*
791 * Generate a conditional based on ARM condition code cc.
792 * This is common between ARM and Aarch64 targets.
793 */
794 void arm_test_cc(DisasCompare *cmp, int cc)
795 {
796 TCGv_i32 value;
797 TCGCond cond;
798 bool global = true;
799
800 switch (cc) {
801 case 0: /* eq: Z */
802 case 1: /* ne: !Z */
803 cond = TCG_COND_EQ;
804 value = cpu_ZF;
805 break;
806
807 case 2: /* cs: C */
808 case 3: /* cc: !C */
809 cond = TCG_COND_NE;
810 value = cpu_CF;
811 break;
812
813 case 4: /* mi: N */
814 case 5: /* pl: !N */
815 cond = TCG_COND_LT;
816 value = cpu_NF;
817 break;
818
819 case 6: /* vs: V */
820 case 7: /* vc: !V */
821 cond = TCG_COND_LT;
822 value = cpu_VF;
823 break;
824
825 case 8: /* hi: C && !Z */
826 case 9: /* ls: !C || Z -> !(C && !Z) */
827 cond = TCG_COND_NE;
828 value = tcg_temp_new_i32();
829 global = false;
830 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
831 ZF is non-zero for !Z; so AND the two subexpressions. */
832 tcg_gen_neg_i32(value, cpu_CF);
833 tcg_gen_and_i32(value, value, cpu_ZF);
834 break;
835
836 case 10: /* ge: N == V -> N ^ V == 0 */
837 case 11: /* lt: N != V -> N ^ V != 0 */
838 /* Since we're only interested in the sign bit, == 0 is >= 0. */
839 cond = TCG_COND_GE;
840 value = tcg_temp_new_i32();
841 global = false;
842 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
843 break;
844
845 case 12: /* gt: !Z && N == V */
846 case 13: /* le: Z || N != V */
847 cond = TCG_COND_NE;
848 value = tcg_temp_new_i32();
849 global = false;
850 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
851 * the sign bit then AND with ZF to yield the result. */
852 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
853 tcg_gen_sari_i32(value, value, 31);
854 tcg_gen_andc_i32(value, cpu_ZF, value);
855 break;
856
857 case 14: /* always */
858 case 15: /* always */
859 /* Use the ALWAYS condition, which will fold early.
860 * It doesn't matter what we use for the value. */
861 cond = TCG_COND_ALWAYS;
862 value = cpu_ZF;
863 goto no_invert;
864
865 default:
866 fprintf(stderr, "Bad condition code 0x%x\n", cc);
867 abort();
868 }
869
870 if (cc & 1) {
871 cond = tcg_invert_cond(cond);
872 }
873
874 no_invert:
875 cmp->cond = cond;
876 cmp->value = value;
877 cmp->value_global = global;
878 }
879
880 void arm_free_cc(DisasCompare *cmp)
881 {
882 if (!cmp->value_global) {
883 tcg_temp_free_i32(cmp->value);
884 }
885 }
886
887 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
888 {
889 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
890 }
891
892 void arm_gen_test_cc(int cc, TCGLabel *label)
893 {
894 DisasCompare cmp;
895 arm_test_cc(&cmp, cc);
896 arm_jump_cc(&cmp, label);
897 arm_free_cc(&cmp);
898 }
899
900 static const uint8_t table_logic_cc[16] = {
901 1, /* and */
902 1, /* xor */
903 0, /* sub */
904 0, /* rsb */
905 0, /* add */
906 0, /* adc */
907 0, /* sbc */
908 0, /* rsc */
909 1, /* andl */
910 1, /* xorl */
911 0, /* cmp */
912 0, /* cmn */
913 1, /* orr */
914 1, /* mov */
915 1, /* bic */
916 1, /* mvn */
917 };
918
919 static inline void gen_set_condexec(DisasContext *s)
920 {
921 if (s->condexec_mask) {
922 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
923 TCGv_i32 tmp = tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp, val);
925 store_cpu_field(tmp, condexec_bits);
926 }
927 }
928
929 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
930 {
931 tcg_gen_movi_i32(cpu_R[15], val);
932 }
933
934 /* Set PC and Thumb state from an immediate address. */
935 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
936 {
937 TCGv_i32 tmp;
938
939 s->base.is_jmp = DISAS_JUMP;
940 if (s->thumb != (addr & 1)) {
941 tmp = tcg_temp_new_i32();
942 tcg_gen_movi_i32(tmp, addr & 1);
943 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
944 tcg_temp_free_i32(tmp);
945 }
946 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
947 }
948
949 /* Set PC and Thumb state from var. var is marked as dead. */
950 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
951 {
952 s->base.is_jmp = DISAS_JUMP;
953 tcg_gen_andi_i32(cpu_R[15], var, ~1);
954 tcg_gen_andi_i32(var, var, 1);
955 store_cpu_field(var, thumb);
956 }
957
958 /* Set PC and Thumb state from var. var is marked as dead.
959 * For M-profile CPUs, include logic to detect exception-return
960 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
961 * and BX reg, and no others, and happens only for code in Handler mode.
962 */
963 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
964 {
965 /* Generate the same code here as for a simple bx, but flag via
966 * s->base.is_jmp that we need to do the rest of the work later.
967 */
968 gen_bx(s, var);
969 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
970 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
971 s->base.is_jmp = DISAS_BX_EXCRET;
972 }
973 }
974
975 static inline void gen_bx_excret_final_code(DisasContext *s)
976 {
977 /* Generate the code to finish possible exception return and end the TB */
978 TCGLabel *excret_label = gen_new_label();
979 uint32_t min_magic;
980
981 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
982 /* Covers FNC_RETURN and EXC_RETURN magic */
983 min_magic = FNC_RETURN_MIN_MAGIC;
984 } else {
985 /* EXC_RETURN magic only */
986 min_magic = EXC_RETURN_MIN_MAGIC;
987 }
988
989 /* Is the new PC value in the magic range indicating exception return? */
990 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
991 /* No: end the TB as we would for a DISAS_JMP */
992 if (is_singlestepping(s)) {
993 gen_singlestep_exception(s);
994 } else {
995 tcg_gen_exit_tb(NULL, 0);
996 }
997 gen_set_label(excret_label);
998 /* Yes: this is an exception return.
999 * At this point in runtime env->regs[15] and env->thumb will hold
1000 * the exception-return magic number, which do_v7m_exception_exit()
1001 * will read. Nothing else will be able to see those values because
1002 * the cpu-exec main loop guarantees that we will always go straight
1003 * from raising the exception to the exception-handling code.
1004 *
1005 * gen_ss_advance(s) does nothing on M profile currently but
1006 * calling it is conceptually the right thing as we have executed
1007 * this instruction (compare SWI, HVC, SMC handling).
1008 */
1009 gen_ss_advance(s);
1010 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1011 }
1012
1013 static inline void gen_bxns(DisasContext *s, int rm)
1014 {
1015 TCGv_i32 var = load_reg(s, rm);
1016
1017 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1018 * we need to sync state before calling it, but:
1019 * - we don't need to do gen_set_pc_im() because the bxns helper will
1020 * always set the PC itself
1021 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1022 * unless it's outside an IT block or the last insn in an IT block,
1023 * so we know that condexec == 0 (already set at the top of the TB)
1024 * is correct in the non-UNPREDICTABLE cases, and we can choose
1025 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1026 */
1027 gen_helper_v7m_bxns(cpu_env, var);
1028 tcg_temp_free_i32(var);
1029 s->base.is_jmp = DISAS_EXIT;
1030 }
1031
1032 static inline void gen_blxns(DisasContext *s, int rm)
1033 {
1034 TCGv_i32 var = load_reg(s, rm);
1035
1036 /* We don't need to sync condexec state, for the same reason as bxns.
1037 * We do however need to set the PC, because the blxns helper reads it.
1038 * The blxns helper may throw an exception.
1039 */
1040 gen_set_pc_im(s, s->pc);
1041 gen_helper_v7m_blxns(cpu_env, var);
1042 tcg_temp_free_i32(var);
1043 s->base.is_jmp = DISAS_EXIT;
1044 }
1045
1046 /* Variant of store_reg which uses branch&exchange logic when storing
1047 to r15 in ARM architecture v7 and above. The source must be a temporary
1048 and will be marked as dead. */
1049 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1050 {
1051 if (reg == 15 && ENABLE_ARCH_7) {
1052 gen_bx(s, var);
1053 } else {
1054 store_reg(s, reg, var);
1055 }
1056 }
1057
1058 /* Variant of store_reg which uses branch&exchange logic when storing
1059 * to r15 in ARM architecture v5T and above. This is used for storing
1060 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1061 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1062 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1063 {
1064 if (reg == 15 && ENABLE_ARCH_5) {
1065 gen_bx_excret(s, var);
1066 } else {
1067 store_reg(s, reg, var);
1068 }
1069 }
1070
1071 #ifdef CONFIG_USER_ONLY
1072 #define IS_USER_ONLY 1
1073 #else
1074 #define IS_USER_ONLY 0
1075 #endif
1076
1077 /* Abstractions of "generate code to do a guest load/store for
1078 * AArch32", where a vaddr is always 32 bits (and is zero
1079 * extended if we're a 64 bit core) and data is also
1080 * 32 bits unless specifically doing a 64 bit access.
1081 * These functions work like tcg_gen_qemu_{ld,st}* except
1082 * that the address argument is TCGv_i32 rather than TCGv.
1083 */
1084
1085 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1086 {
1087 TCGv addr = tcg_temp_new();
1088 tcg_gen_extu_i32_tl(addr, a32);
1089
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1092 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1093 }
1094 return addr;
1095 }
1096
1097 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1098 int index, TCGMemOp opc)
1099 {
1100 TCGv addr;
1101
1102 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1103 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1104 opc |= MO_ALIGN;
1105 }
1106
1107 addr = gen_aa32_addr(s, a32, opc);
1108 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1109 tcg_temp_free(addr);
1110 }
1111
1112 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1113 int index, TCGMemOp opc)
1114 {
1115 TCGv addr;
1116
1117 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1118 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1119 opc |= MO_ALIGN;
1120 }
1121
1122 addr = gen_aa32_addr(s, a32, opc);
1123 tcg_gen_qemu_st_i32(val, addr, index, opc);
1124 tcg_temp_free(addr);
1125 }
1126
1127 #define DO_GEN_LD(SUFF, OPC) \
1128 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1129 TCGv_i32 a32, int index) \
1130 { \
1131 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1132 } \
1133 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1134 TCGv_i32 val, \
1135 TCGv_i32 a32, int index, \
1136 ISSInfo issinfo) \
1137 { \
1138 gen_aa32_ld##SUFF(s, val, a32, index); \
1139 disas_set_da_iss(s, OPC, issinfo); \
1140 }
1141
1142 #define DO_GEN_ST(SUFF, OPC) \
1143 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1144 TCGv_i32 a32, int index) \
1145 { \
1146 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1147 } \
1148 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1149 TCGv_i32 val, \
1150 TCGv_i32 a32, int index, \
1151 ISSInfo issinfo) \
1152 { \
1153 gen_aa32_st##SUFF(s, val, a32, index); \
1154 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1155 }
1156
1157 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1158 {
1159 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1160 if (!IS_USER_ONLY && s->sctlr_b) {
1161 tcg_gen_rotri_i64(val, val, 32);
1162 }
1163 }
1164
1165 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1166 int index, TCGMemOp opc)
1167 {
1168 TCGv addr = gen_aa32_addr(s, a32, opc);
1169 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1170 gen_aa32_frob64(s, val);
1171 tcg_temp_free(addr);
1172 }
1173
1174 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1175 TCGv_i32 a32, int index)
1176 {
1177 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1178 }
1179
1180 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1181 int index, TCGMemOp opc)
1182 {
1183 TCGv addr = gen_aa32_addr(s, a32, opc);
1184
1185 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1186 if (!IS_USER_ONLY && s->sctlr_b) {
1187 TCGv_i64 tmp = tcg_temp_new_i64();
1188 tcg_gen_rotri_i64(tmp, val, 32);
1189 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1190 tcg_temp_free_i64(tmp);
1191 } else {
1192 tcg_gen_qemu_st_i64(val, addr, index, opc);
1193 }
1194 tcg_temp_free(addr);
1195 }
1196
1197 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1198 TCGv_i32 a32, int index)
1199 {
1200 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1201 }
1202
1203 DO_GEN_LD(8s, MO_SB)
1204 DO_GEN_LD(8u, MO_UB)
1205 DO_GEN_LD(16s, MO_SW)
1206 DO_GEN_LD(16u, MO_UW)
1207 DO_GEN_LD(32u, MO_UL)
1208 DO_GEN_ST(8, MO_UB)
1209 DO_GEN_ST(16, MO_UW)
1210 DO_GEN_ST(32, MO_UL)
1211
1212 static inline void gen_hvc(DisasContext *s, int imm16)
1213 {
1214 /* The pre HVC helper handles cases when HVC gets trapped
1215 * as an undefined insn by runtime configuration (ie before
1216 * the insn really executes).
1217 */
1218 gen_set_pc_im(s, s->pc - 4);
1219 gen_helper_pre_hvc(cpu_env);
1220 /* Otherwise we will treat this as a real exception which
1221 * happens after execution of the insn. (The distinction matters
1222 * for the PC value reported to the exception handler and also
1223 * for single stepping.)
1224 */
1225 s->svc_imm = imm16;
1226 gen_set_pc_im(s, s->pc);
1227 s->base.is_jmp = DISAS_HVC;
1228 }
1229
1230 static inline void gen_smc(DisasContext *s)
1231 {
1232 /* As with HVC, we may take an exception either before or after
1233 * the insn executes.
1234 */
1235 TCGv_i32 tmp;
1236
1237 gen_set_pc_im(s, s->pc - 4);
1238 tmp = tcg_const_i32(syn_aa32_smc());
1239 gen_helper_pre_smc(cpu_env, tmp);
1240 tcg_temp_free_i32(tmp);
1241 gen_set_pc_im(s, s->pc);
1242 s->base.is_jmp = DISAS_SMC;
1243 }
1244
1245 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1246 {
1247 gen_set_condexec(s);
1248 gen_set_pc_im(s, s->pc - offset);
1249 gen_exception_internal(excp);
1250 s->base.is_jmp = DISAS_NORETURN;
1251 }
1252
1253 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1254 int syn, uint32_t target_el)
1255 {
1256 gen_set_condexec(s);
1257 gen_set_pc_im(s, s->pc - offset);
1258 gen_exception(excp, syn, target_el);
1259 s->base.is_jmp = DISAS_NORETURN;
1260 }
1261
1262 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1263 {
1264 TCGv_i32 tcg_syn;
1265
1266 gen_set_condexec(s);
1267 gen_set_pc_im(s, s->pc - offset);
1268 tcg_syn = tcg_const_i32(syn);
1269 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1270 tcg_temp_free_i32(tcg_syn);
1271 s->base.is_jmp = DISAS_NORETURN;
1272 }
1273
1274 /* Force a TB lookup after an instruction that changes the CPU state. */
1275 static inline void gen_lookup_tb(DisasContext *s)
1276 {
1277 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1278 s->base.is_jmp = DISAS_EXIT;
1279 }
1280
1281 static inline void gen_hlt(DisasContext *s, int imm)
1282 {
1283 /* HLT. This has two purposes.
1284 * Architecturally, it is an external halting debug instruction.
1285 * Since QEMU doesn't implement external debug, we treat this as
1286 * it is required for halting debug disabled: it will UNDEF.
1287 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1288 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1289 * must trigger semihosting even for ARMv7 and earlier, where
1290 * HLT was an undefined encoding.
1291 * In system mode, we don't allow userspace access to
1292 * semihosting, to provide some semblance of security
1293 * (and for consistency with our 32-bit semihosting).
1294 */
1295 if (semihosting_enabled() &&
1296 #ifndef CONFIG_USER_ONLY
1297 s->current_el != 0 &&
1298 #endif
1299 (imm == (s->thumb ? 0x3c : 0xf000))) {
1300 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1301 return;
1302 }
1303
1304 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1305 default_exception_el(s));
1306 }
1307
1308 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1309 TCGv_i32 var)
1310 {
1311 int val, rm, shift, shiftop;
1312 TCGv_i32 offset;
1313
1314 if (!(insn & (1 << 25))) {
1315 /* immediate */
1316 val = insn & 0xfff;
1317 if (!(insn & (1 << 23)))
1318 val = -val;
1319 if (val != 0)
1320 tcg_gen_addi_i32(var, var, val);
1321 } else {
1322 /* shift/register */
1323 rm = (insn) & 0xf;
1324 shift = (insn >> 7) & 0x1f;
1325 shiftop = (insn >> 5) & 3;
1326 offset = load_reg(s, rm);
1327 gen_arm_shift_im(offset, shiftop, shift, 0);
1328 if (!(insn & (1 << 23)))
1329 tcg_gen_sub_i32(var, var, offset);
1330 else
1331 tcg_gen_add_i32(var, var, offset);
1332 tcg_temp_free_i32(offset);
1333 }
1334 }
1335
1336 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1337 int extra, TCGv_i32 var)
1338 {
1339 int val, rm;
1340 TCGv_i32 offset;
1341
1342 if (insn & (1 << 22)) {
1343 /* immediate */
1344 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1345 if (!(insn & (1 << 23)))
1346 val = -val;
1347 val += extra;
1348 if (val != 0)
1349 tcg_gen_addi_i32(var, var, val);
1350 } else {
1351 /* register */
1352 if (extra)
1353 tcg_gen_addi_i32(var, var, extra);
1354 rm = (insn) & 0xf;
1355 offset = load_reg(s, rm);
1356 if (!(insn & (1 << 23)))
1357 tcg_gen_sub_i32(var, var, offset);
1358 else
1359 tcg_gen_add_i32(var, var, offset);
1360 tcg_temp_free_i32(offset);
1361 }
1362 }
1363
1364 static TCGv_ptr get_fpstatus_ptr(int neon)
1365 {
1366 TCGv_ptr statusptr = tcg_temp_new_ptr();
1367 int offset;
1368 if (neon) {
1369 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1370 } else {
1371 offset = offsetof(CPUARMState, vfp.fp_status);
1372 }
1373 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1374 return statusptr;
1375 }
1376
1377 #define VFP_OP2(name) \
1378 static inline void gen_vfp_##name(int dp) \
1379 { \
1380 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1381 if (dp) { \
1382 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1383 } else { \
1384 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1385 } \
1386 tcg_temp_free_ptr(fpst); \
1387 }
1388
1389 VFP_OP2(add)
1390 VFP_OP2(sub)
1391 VFP_OP2(mul)
1392 VFP_OP2(div)
1393
1394 #undef VFP_OP2
1395
1396 static inline void gen_vfp_F1_mul(int dp)
1397 {
1398 /* Like gen_vfp_mul() but put result in F1 */
1399 TCGv_ptr fpst = get_fpstatus_ptr(0);
1400 if (dp) {
1401 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1402 } else {
1403 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1404 }
1405 tcg_temp_free_ptr(fpst);
1406 }
1407
1408 static inline void gen_vfp_F1_neg(int dp)
1409 {
1410 /* Like gen_vfp_neg() but put result in F1 */
1411 if (dp) {
1412 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1413 } else {
1414 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1415 }
1416 }
1417
1418 static inline void gen_vfp_abs(int dp)
1419 {
1420 if (dp)
1421 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1422 else
1423 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1424 }
1425
1426 static inline void gen_vfp_neg(int dp)
1427 {
1428 if (dp)
1429 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1430 else
1431 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1432 }
1433
1434 static inline void gen_vfp_sqrt(int dp)
1435 {
1436 if (dp)
1437 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1438 else
1439 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1440 }
1441
1442 static inline void gen_vfp_cmp(int dp)
1443 {
1444 if (dp)
1445 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1446 else
1447 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1448 }
1449
1450 static inline void gen_vfp_cmpe(int dp)
1451 {
1452 if (dp)
1453 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1454 else
1455 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1456 }
1457
1458 static inline void gen_vfp_F1_ld0(int dp)
1459 {
1460 if (dp)
1461 tcg_gen_movi_i64(cpu_F1d, 0);
1462 else
1463 tcg_gen_movi_i32(cpu_F1s, 0);
1464 }
1465
1466 #define VFP_GEN_ITOF(name) \
1467 static inline void gen_vfp_##name(int dp, int neon) \
1468 { \
1469 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1470 if (dp) { \
1471 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1472 } else { \
1473 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1474 } \
1475 tcg_temp_free_ptr(statusptr); \
1476 }
1477
1478 VFP_GEN_ITOF(uito)
1479 VFP_GEN_ITOF(sito)
1480 #undef VFP_GEN_ITOF
1481
1482 #define VFP_GEN_FTOI(name) \
1483 static inline void gen_vfp_##name(int dp, int neon) \
1484 { \
1485 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1486 if (dp) { \
1487 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1488 } else { \
1489 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1490 } \
1491 tcg_temp_free_ptr(statusptr); \
1492 }
1493
1494 VFP_GEN_FTOI(toui)
1495 VFP_GEN_FTOI(touiz)
1496 VFP_GEN_FTOI(tosi)
1497 VFP_GEN_FTOI(tosiz)
1498 #undef VFP_GEN_FTOI
1499
1500 #define VFP_GEN_FIX(name, round) \
1501 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1502 { \
1503 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1504 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1505 if (dp) { \
1506 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1507 statusptr); \
1508 } else { \
1509 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1510 statusptr); \
1511 } \
1512 tcg_temp_free_i32(tmp_shift); \
1513 tcg_temp_free_ptr(statusptr); \
1514 }
1515 VFP_GEN_FIX(tosh, _round_to_zero)
1516 VFP_GEN_FIX(tosl, _round_to_zero)
1517 VFP_GEN_FIX(touh, _round_to_zero)
1518 VFP_GEN_FIX(toul, _round_to_zero)
1519 VFP_GEN_FIX(shto, )
1520 VFP_GEN_FIX(slto, )
1521 VFP_GEN_FIX(uhto, )
1522 VFP_GEN_FIX(ulto, )
1523 #undef VFP_GEN_FIX
1524
1525 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1526 {
1527 if (dp) {
1528 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1529 } else {
1530 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1531 }
1532 }
1533
1534 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1535 {
1536 if (dp) {
1537 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1538 } else {
1539 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1540 }
1541 }
1542
1543 static inline long vfp_reg_offset(bool dp, unsigned reg)
1544 {
1545 if (dp) {
1546 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1547 } else {
1548 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1549 if (reg & 1) {
1550 ofs += offsetof(CPU_DoubleU, l.upper);
1551 } else {
1552 ofs += offsetof(CPU_DoubleU, l.lower);
1553 }
1554 return ofs;
1555 }
1556 }
1557
1558 /* Return the offset of a 32-bit piece of a NEON register.
1559 zero is the least significant end of the register. */
1560 static inline long
1561 neon_reg_offset (int reg, int n)
1562 {
1563 int sreg;
1564 sreg = reg * 2 + n;
1565 return vfp_reg_offset(0, sreg);
1566 }
1567
1568 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1569 * where 0 is the least significant end of the register.
1570 */
1571 static inline long
1572 neon_element_offset(int reg, int element, TCGMemOp size)
1573 {
1574 int element_size = 1 << size;
1575 int ofs = element * element_size;
1576 #ifdef HOST_WORDS_BIGENDIAN
1577 /* Calculate the offset assuming fully little-endian,
1578 * then XOR to account for the order of the 8-byte units.
1579 */
1580 if (element_size < 8) {
1581 ofs ^= 8 - element_size;
1582 }
1583 #endif
1584 return neon_reg_offset(reg, 0) + ofs;
1585 }
1586
1587 static TCGv_i32 neon_load_reg(int reg, int pass)
1588 {
1589 TCGv_i32 tmp = tcg_temp_new_i32();
1590 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1591 return tmp;
1592 }
1593
1594 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1595 {
1596 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1597
1598 switch (mop) {
1599 case MO_UB:
1600 tcg_gen_ld8u_i32(var, cpu_env, offset);
1601 break;
1602 case MO_UW:
1603 tcg_gen_ld16u_i32(var, cpu_env, offset);
1604 break;
1605 case MO_UL:
1606 tcg_gen_ld_i32(var, cpu_env, offset);
1607 break;
1608 default:
1609 g_assert_not_reached();
1610 }
1611 }
1612
1613 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1614 {
1615 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1616
1617 switch (mop) {
1618 case MO_UB:
1619 tcg_gen_ld8u_i64(var, cpu_env, offset);
1620 break;
1621 case MO_UW:
1622 tcg_gen_ld16u_i64(var, cpu_env, offset);
1623 break;
1624 case MO_UL:
1625 tcg_gen_ld32u_i64(var, cpu_env, offset);
1626 break;
1627 case MO_Q:
1628 tcg_gen_ld_i64(var, cpu_env, offset);
1629 break;
1630 default:
1631 g_assert_not_reached();
1632 }
1633 }
1634
1635 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1636 {
1637 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1638 tcg_temp_free_i32(var);
1639 }
1640
1641 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1642 {
1643 long offset = neon_element_offset(reg, ele, size);
1644
1645 switch (size) {
1646 case MO_8:
1647 tcg_gen_st8_i32(var, cpu_env, offset);
1648 break;
1649 case MO_16:
1650 tcg_gen_st16_i32(var, cpu_env, offset);
1651 break;
1652 case MO_32:
1653 tcg_gen_st_i32(var, cpu_env, offset);
1654 break;
1655 default:
1656 g_assert_not_reached();
1657 }
1658 }
1659
1660 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1661 {
1662 long offset = neon_element_offset(reg, ele, size);
1663
1664 switch (size) {
1665 case MO_8:
1666 tcg_gen_st8_i64(var, cpu_env, offset);
1667 break;
1668 case MO_16:
1669 tcg_gen_st16_i64(var, cpu_env, offset);
1670 break;
1671 case MO_32:
1672 tcg_gen_st32_i64(var, cpu_env, offset);
1673 break;
1674 case MO_64:
1675 tcg_gen_st_i64(var, cpu_env, offset);
1676 break;
1677 default:
1678 g_assert_not_reached();
1679 }
1680 }
1681
1682 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1683 {
1684 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1685 }
1686
1687 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1688 {
1689 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1690 }
1691
1692 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1693 {
1694 TCGv_ptr ret = tcg_temp_new_ptr();
1695 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1696 return ret;
1697 }
1698
1699 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1700 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1701 #define tcg_gen_st_f32 tcg_gen_st_i32
1702 #define tcg_gen_st_f64 tcg_gen_st_i64
1703
1704 static inline void gen_mov_F0_vreg(int dp, int reg)
1705 {
1706 if (dp)
1707 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1708 else
1709 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1710 }
1711
1712 static inline void gen_mov_F1_vreg(int dp, int reg)
1713 {
1714 if (dp)
1715 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1716 else
1717 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1718 }
1719
1720 static inline void gen_mov_vreg_F0(int dp, int reg)
1721 {
1722 if (dp)
1723 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1724 else
1725 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1726 }
1727
1728 #define ARM_CP_RW_BIT (1 << 20)
1729
1730 /* Include the VFP decoder */
1731 #include "translate-vfp.inc.c"
1732
1733 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1734 {
1735 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1736 }
1737
1738 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1739 {
1740 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1741 }
1742
1743 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1744 {
1745 TCGv_i32 var = tcg_temp_new_i32();
1746 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1747 return var;
1748 }
1749
1750 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1751 {
1752 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1753 tcg_temp_free_i32(var);
1754 }
1755
1756 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1757 {
1758 iwmmxt_store_reg(cpu_M0, rn);
1759 }
1760
1761 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1762 {
1763 iwmmxt_load_reg(cpu_M0, rn);
1764 }
1765
1766 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1767 {
1768 iwmmxt_load_reg(cpu_V1, rn);
1769 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1770 }
1771
1772 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1773 {
1774 iwmmxt_load_reg(cpu_V1, rn);
1775 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1776 }
1777
1778 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1779 {
1780 iwmmxt_load_reg(cpu_V1, rn);
1781 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1782 }
1783
1784 #define IWMMXT_OP(name) \
1785 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1786 { \
1787 iwmmxt_load_reg(cpu_V1, rn); \
1788 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1789 }
1790
1791 #define IWMMXT_OP_ENV(name) \
1792 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1793 { \
1794 iwmmxt_load_reg(cpu_V1, rn); \
1795 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1796 }
1797
1798 #define IWMMXT_OP_ENV_SIZE(name) \
1799 IWMMXT_OP_ENV(name##b) \
1800 IWMMXT_OP_ENV(name##w) \
1801 IWMMXT_OP_ENV(name##l)
1802
1803 #define IWMMXT_OP_ENV1(name) \
1804 static inline void gen_op_iwmmxt_##name##_M0(void) \
1805 { \
1806 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1807 }
1808
1809 IWMMXT_OP(maddsq)
1810 IWMMXT_OP(madduq)
1811 IWMMXT_OP(sadb)
1812 IWMMXT_OP(sadw)
1813 IWMMXT_OP(mulslw)
1814 IWMMXT_OP(mulshw)
1815 IWMMXT_OP(mululw)
1816 IWMMXT_OP(muluhw)
1817 IWMMXT_OP(macsw)
1818 IWMMXT_OP(macuw)
1819
1820 IWMMXT_OP_ENV_SIZE(unpackl)
1821 IWMMXT_OP_ENV_SIZE(unpackh)
1822
1823 IWMMXT_OP_ENV1(unpacklub)
1824 IWMMXT_OP_ENV1(unpackluw)
1825 IWMMXT_OP_ENV1(unpacklul)
1826 IWMMXT_OP_ENV1(unpackhub)
1827 IWMMXT_OP_ENV1(unpackhuw)
1828 IWMMXT_OP_ENV1(unpackhul)
1829 IWMMXT_OP_ENV1(unpacklsb)
1830 IWMMXT_OP_ENV1(unpacklsw)
1831 IWMMXT_OP_ENV1(unpacklsl)
1832 IWMMXT_OP_ENV1(unpackhsb)
1833 IWMMXT_OP_ENV1(unpackhsw)
1834 IWMMXT_OP_ENV1(unpackhsl)
1835
1836 IWMMXT_OP_ENV_SIZE(cmpeq)
1837 IWMMXT_OP_ENV_SIZE(cmpgtu)
1838 IWMMXT_OP_ENV_SIZE(cmpgts)
1839
1840 IWMMXT_OP_ENV_SIZE(mins)
1841 IWMMXT_OP_ENV_SIZE(minu)
1842 IWMMXT_OP_ENV_SIZE(maxs)
1843 IWMMXT_OP_ENV_SIZE(maxu)
1844
1845 IWMMXT_OP_ENV_SIZE(subn)
1846 IWMMXT_OP_ENV_SIZE(addn)
1847 IWMMXT_OP_ENV_SIZE(subu)
1848 IWMMXT_OP_ENV_SIZE(addu)
1849 IWMMXT_OP_ENV_SIZE(subs)
1850 IWMMXT_OP_ENV_SIZE(adds)
1851
1852 IWMMXT_OP_ENV(avgb0)
1853 IWMMXT_OP_ENV(avgb1)
1854 IWMMXT_OP_ENV(avgw0)
1855 IWMMXT_OP_ENV(avgw1)
1856
1857 IWMMXT_OP_ENV(packuw)
1858 IWMMXT_OP_ENV(packul)
1859 IWMMXT_OP_ENV(packuq)
1860 IWMMXT_OP_ENV(packsw)
1861 IWMMXT_OP_ENV(packsl)
1862 IWMMXT_OP_ENV(packsq)
1863
1864 static void gen_op_iwmmxt_set_mup(void)
1865 {
1866 TCGv_i32 tmp;
1867 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1868 tcg_gen_ori_i32(tmp, tmp, 2);
1869 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1870 }
1871
1872 static void gen_op_iwmmxt_set_cup(void)
1873 {
1874 TCGv_i32 tmp;
1875 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1876 tcg_gen_ori_i32(tmp, tmp, 1);
1877 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1878 }
1879
1880 static void gen_op_iwmmxt_setpsr_nz(void)
1881 {
1882 TCGv_i32 tmp = tcg_temp_new_i32();
1883 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1884 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1885 }
1886
1887 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1888 {
1889 iwmmxt_load_reg(cpu_V1, rn);
1890 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1891 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1892 }
1893
1894 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1895 TCGv_i32 dest)
1896 {
1897 int rd;
1898 uint32_t offset;
1899 TCGv_i32 tmp;
1900
1901 rd = (insn >> 16) & 0xf;
1902 tmp = load_reg(s, rd);
1903
1904 offset = (insn & 0xff) << ((insn >> 7) & 2);
1905 if (insn & (1 << 24)) {
1906 /* Pre indexed */
1907 if (insn & (1 << 23))
1908 tcg_gen_addi_i32(tmp, tmp, offset);
1909 else
1910 tcg_gen_addi_i32(tmp, tmp, -offset);
1911 tcg_gen_mov_i32(dest, tmp);
1912 if (insn & (1 << 21))
1913 store_reg(s, rd, tmp);
1914 else
1915 tcg_temp_free_i32(tmp);
1916 } else if (insn & (1 << 21)) {
1917 /* Post indexed */
1918 tcg_gen_mov_i32(dest, tmp);
1919 if (insn & (1 << 23))
1920 tcg_gen_addi_i32(tmp, tmp, offset);
1921 else
1922 tcg_gen_addi_i32(tmp, tmp, -offset);
1923 store_reg(s, rd, tmp);
1924 } else if (!(insn & (1 << 23)))
1925 return 1;
1926 return 0;
1927 }
1928
1929 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1930 {
1931 int rd = (insn >> 0) & 0xf;
1932 TCGv_i32 tmp;
1933
1934 if (insn & (1 << 8)) {
1935 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1936 return 1;
1937 } else {
1938 tmp = iwmmxt_load_creg(rd);
1939 }
1940 } else {
1941 tmp = tcg_temp_new_i32();
1942 iwmmxt_load_reg(cpu_V0, rd);
1943 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1944 }
1945 tcg_gen_andi_i32(tmp, tmp, mask);
1946 tcg_gen_mov_i32(dest, tmp);
1947 tcg_temp_free_i32(tmp);
1948 return 0;
1949 }
1950
1951 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1952 (ie. an undefined instruction). */
1953 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1954 {
1955 int rd, wrd;
1956 int rdhi, rdlo, rd0, rd1, i;
1957 TCGv_i32 addr;
1958 TCGv_i32 tmp, tmp2, tmp3;
1959
1960 if ((insn & 0x0e000e00) == 0x0c000000) {
1961 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1962 wrd = insn & 0xf;
1963 rdlo = (insn >> 12) & 0xf;
1964 rdhi = (insn >> 16) & 0xf;
1965 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1966 iwmmxt_load_reg(cpu_V0, wrd);
1967 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1968 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1969 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1970 } else { /* TMCRR */
1971 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1972 iwmmxt_store_reg(cpu_V0, wrd);
1973 gen_op_iwmmxt_set_mup();
1974 }
1975 return 0;
1976 }
1977
1978 wrd = (insn >> 12) & 0xf;
1979 addr = tcg_temp_new_i32();
1980 if (gen_iwmmxt_address(s, insn, addr)) {
1981 tcg_temp_free_i32(addr);
1982 return 1;
1983 }
1984 if (insn & ARM_CP_RW_BIT) {
1985 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1986 tmp = tcg_temp_new_i32();
1987 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1988 iwmmxt_store_creg(wrd, tmp);
1989 } else {
1990 i = 1;
1991 if (insn & (1 << 8)) {
1992 if (insn & (1 << 22)) { /* WLDRD */
1993 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1994 i = 0;
1995 } else { /* WLDRW wRd */
1996 tmp = tcg_temp_new_i32();
1997 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1998 }
1999 } else {
2000 tmp = tcg_temp_new_i32();
2001 if (insn & (1 << 22)) { /* WLDRH */
2002 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2003 } else { /* WLDRB */
2004 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2005 }
2006 }
2007 if (i) {
2008 tcg_gen_extu_i32_i64(cpu_M0, tmp);
2009 tcg_temp_free_i32(tmp);
2010 }
2011 gen_op_iwmmxt_movq_wRn_M0(wrd);
2012 }
2013 } else {
2014 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
2015 tmp = iwmmxt_load_creg(wrd);
2016 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2017 } else {
2018 gen_op_iwmmxt_movq_M0_wRn(wrd);
2019 tmp = tcg_temp_new_i32();
2020 if (insn & (1 << 8)) {
2021 if (insn & (1 << 22)) { /* WSTRD */
2022 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
2023 } else { /* WSTRW wRd */
2024 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2025 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2026 }
2027 } else {
2028 if (insn & (1 << 22)) { /* WSTRH */
2029 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2030 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
2031 } else { /* WSTRB */
2032 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2033 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
2034 }
2035 }
2036 }
2037 tcg_temp_free_i32(tmp);
2038 }
2039 tcg_temp_free_i32(addr);
2040 return 0;
2041 }
2042
2043 if ((insn & 0x0f000000) != 0x0e000000)
2044 return 1;
2045
2046 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
2047 case 0x000: /* WOR */
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 0) & 0xf;
2050 rd1 = (insn >> 16) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0);
2052 gen_op_iwmmxt_orq_M0_wRn(rd1);
2053 gen_op_iwmmxt_setpsr_nz();
2054 gen_op_iwmmxt_movq_wRn_M0(wrd);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2057 break;
2058 case 0x011: /* TMCR */
2059 if (insn & 0xf)
2060 return 1;
2061 rd = (insn >> 12) & 0xf;
2062 wrd = (insn >> 16) & 0xf;
2063 switch (wrd) {
2064 case ARM_IWMMXT_wCID:
2065 case ARM_IWMMXT_wCASF:
2066 break;
2067 case ARM_IWMMXT_wCon:
2068 gen_op_iwmmxt_set_cup();
2069 /* Fall through. */
2070 case ARM_IWMMXT_wCSSF:
2071 tmp = iwmmxt_load_creg(wrd);
2072 tmp2 = load_reg(s, rd);
2073 tcg_gen_andc_i32(tmp, tmp, tmp2);
2074 tcg_temp_free_i32(tmp2);
2075 iwmmxt_store_creg(wrd, tmp);
2076 break;
2077 case ARM_IWMMXT_wCGR0:
2078 case ARM_IWMMXT_wCGR1:
2079 case ARM_IWMMXT_wCGR2:
2080 case ARM_IWMMXT_wCGR3:
2081 gen_op_iwmmxt_set_cup();
2082 tmp = load_reg(s, rd);
2083 iwmmxt_store_creg(wrd, tmp);
2084 break;
2085 default:
2086 return 1;
2087 }
2088 break;
2089 case 0x100: /* WXOR */
2090 wrd = (insn >> 12) & 0xf;
2091 rd0 = (insn >> 0) & 0xf;
2092 rd1 = (insn >> 16) & 0xf;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0);
2094 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2095 gen_op_iwmmxt_setpsr_nz();
2096 gen_op_iwmmxt_movq_wRn_M0(wrd);
2097 gen_op_iwmmxt_set_mup();
2098 gen_op_iwmmxt_set_cup();
2099 break;
2100 case 0x111: /* TMRC */
2101 if (insn & 0xf)
2102 return 1;
2103 rd = (insn >> 12) & 0xf;
2104 wrd = (insn >> 16) & 0xf;
2105 tmp = iwmmxt_load_creg(wrd);
2106 store_reg(s, rd, tmp);
2107 break;
2108 case 0x300: /* WANDN */
2109 wrd = (insn >> 12) & 0xf;
2110 rd0 = (insn >> 0) & 0xf;
2111 rd1 = (insn >> 16) & 0xf;
2112 gen_op_iwmmxt_movq_M0_wRn(rd0);
2113 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2114 gen_op_iwmmxt_andq_M0_wRn(rd1);
2115 gen_op_iwmmxt_setpsr_nz();
2116 gen_op_iwmmxt_movq_wRn_M0(wrd);
2117 gen_op_iwmmxt_set_mup();
2118 gen_op_iwmmxt_set_cup();
2119 break;
2120 case 0x200: /* WAND */
2121 wrd = (insn >> 12) & 0xf;
2122 rd0 = (insn >> 0) & 0xf;
2123 rd1 = (insn >> 16) & 0xf;
2124 gen_op_iwmmxt_movq_M0_wRn(rd0);
2125 gen_op_iwmmxt_andq_M0_wRn(rd1);
2126 gen_op_iwmmxt_setpsr_nz();
2127 gen_op_iwmmxt_movq_wRn_M0(wrd);
2128 gen_op_iwmmxt_set_mup();
2129 gen_op_iwmmxt_set_cup();
2130 break;
2131 case 0x810: case 0xa10: /* WMADD */
2132 wrd = (insn >> 12) & 0xf;
2133 rd0 = (insn >> 0) & 0xf;
2134 rd1 = (insn >> 16) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0);
2136 if (insn & (1 << 21))
2137 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2138 else
2139 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd);
2141 gen_op_iwmmxt_set_mup();
2142 break;
2143 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2144 wrd = (insn >> 12) & 0xf;
2145 rd0 = (insn >> 16) & 0xf;
2146 rd1 = (insn >> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0);
2148 switch ((insn >> 22) & 3) {
2149 case 0:
2150 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2151 break;
2152 case 1:
2153 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2154 break;
2155 case 2:
2156 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2157 break;
2158 case 3:
2159 return 1;
2160 }
2161 gen_op_iwmmxt_movq_wRn_M0(wrd);
2162 gen_op_iwmmxt_set_mup();
2163 gen_op_iwmmxt_set_cup();
2164 break;
2165 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2166 wrd = (insn >> 12) & 0xf;
2167 rd0 = (insn >> 16) & 0xf;
2168 rd1 = (insn >> 0) & 0xf;
2169 gen_op_iwmmxt_movq_M0_wRn(rd0);
2170 switch ((insn >> 22) & 3) {
2171 case 0:
2172 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2173 break;
2174 case 1:
2175 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2176 break;
2177 case 2:
2178 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2179 break;
2180 case 3:
2181 return 1;
2182 }
2183 gen_op_iwmmxt_movq_wRn_M0(wrd);
2184 gen_op_iwmmxt_set_mup();
2185 gen_op_iwmmxt_set_cup();
2186 break;
2187 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2188 wrd = (insn >> 12) & 0xf;
2189 rd0 = (insn >> 16) & 0xf;
2190 rd1 = (insn >> 0) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0);
2192 if (insn & (1 << 22))
2193 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2194 else
2195 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2196 if (!(insn & (1 << 20)))
2197 gen_op_iwmmxt_addl_M0_wRn(wrd);
2198 gen_op_iwmmxt_movq_wRn_M0(wrd);
2199 gen_op_iwmmxt_set_mup();
2200 break;
2201 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2202 wrd = (insn >> 12) & 0xf;
2203 rd0 = (insn >> 16) & 0xf;
2204 rd1 = (insn >> 0) & 0xf;
2205 gen_op_iwmmxt_movq_M0_wRn(rd0);
2206 if (insn & (1 << 21)) {
2207 if (insn & (1 << 20))
2208 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2209 else
2210 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2211 } else {
2212 if (insn & (1 << 20))
2213 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2214 else
2215 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2216 }
2217 gen_op_iwmmxt_movq_wRn_M0(wrd);
2218 gen_op_iwmmxt_set_mup();
2219 break;
2220 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2221 wrd = (insn >> 12) & 0xf;
2222 rd0 = (insn >> 16) & 0xf;
2223 rd1 = (insn >> 0) & 0xf;
2224 gen_op_iwmmxt_movq_M0_wRn(rd0);
2225 if (insn & (1 << 21))
2226 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2227 else
2228 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2229 if (!(insn & (1 << 20))) {
2230 iwmmxt_load_reg(cpu_V1, wrd);
2231 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2232 }
2233 gen_op_iwmmxt_movq_wRn_M0(wrd);
2234 gen_op_iwmmxt_set_mup();
2235 break;
2236 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2237 wrd = (insn >> 12) & 0xf;
2238 rd0 = (insn >> 16) & 0xf;
2239 rd1 = (insn >> 0) & 0xf;
2240 gen_op_iwmmxt_movq_M0_wRn(rd0);
2241 switch ((insn >> 22) & 3) {
2242 case 0:
2243 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2244 break;
2245 case 1:
2246 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2247 break;
2248 case 2:
2249 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2250 break;
2251 case 3:
2252 return 1;
2253 }
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2257 break;
2258 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2259 wrd = (insn >> 12) & 0xf;
2260 rd0 = (insn >> 16) & 0xf;
2261 rd1 = (insn >> 0) & 0xf;
2262 gen_op_iwmmxt_movq_M0_wRn(rd0);
2263 if (insn & (1 << 22)) {
2264 if (insn & (1 << 20))
2265 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2266 else
2267 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2268 } else {
2269 if (insn & (1 << 20))
2270 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2271 else
2272 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2273 }
2274 gen_op_iwmmxt_movq_wRn_M0(wrd);
2275 gen_op_iwmmxt_set_mup();
2276 gen_op_iwmmxt_set_cup();
2277 break;
2278 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2279 wrd = (insn >> 12) & 0xf;
2280 rd0 = (insn >> 16) & 0xf;
2281 rd1 = (insn >> 0) & 0xf;
2282 gen_op_iwmmxt_movq_M0_wRn(rd0);
2283 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2284 tcg_gen_andi_i32(tmp, tmp, 7);
2285 iwmmxt_load_reg(cpu_V1, rd1);
2286 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2287 tcg_temp_free_i32(tmp);
2288 gen_op_iwmmxt_movq_wRn_M0(wrd);
2289 gen_op_iwmmxt_set_mup();
2290 break;
2291 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2292 if (((insn >> 6) & 3) == 3)
2293 return 1;
2294 rd = (insn >> 12) & 0xf;
2295 wrd = (insn >> 16) & 0xf;
2296 tmp = load_reg(s, rd);
2297 gen_op_iwmmxt_movq_M0_wRn(wrd);
2298 switch ((insn >> 6) & 3) {
2299 case 0:
2300 tmp2 = tcg_const_i32(0xff);
2301 tmp3 = tcg_const_i32((insn & 7) << 3);
2302 break;
2303 case 1:
2304 tmp2 = tcg_const_i32(0xffff);
2305 tmp3 = tcg_const_i32((insn & 3) << 4);
2306 break;
2307 case 2:
2308 tmp2 = tcg_const_i32(0xffffffff);
2309 tmp3 = tcg_const_i32((insn & 1) << 5);
2310 break;
2311 default:
2312 tmp2 = NULL;
2313 tmp3 = NULL;
2314 }
2315 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2316 tcg_temp_free_i32(tmp3);
2317 tcg_temp_free_i32(tmp2);
2318 tcg_temp_free_i32(tmp);
2319 gen_op_iwmmxt_movq_wRn_M0(wrd);
2320 gen_op_iwmmxt_set_mup();
2321 break;
2322 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2323 rd = (insn >> 12) & 0xf;
2324 wrd = (insn >> 16) & 0xf;
2325 if (rd == 15 || ((insn >> 22) & 3) == 3)
2326 return 1;
2327 gen_op_iwmmxt_movq_M0_wRn(wrd);
2328 tmp = tcg_temp_new_i32();
2329 switch ((insn >> 22) & 3) {
2330 case 0:
2331 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2332 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2333 if (insn & 8) {
2334 tcg_gen_ext8s_i32(tmp, tmp);
2335 } else {
2336 tcg_gen_andi_i32(tmp, tmp, 0xff);
2337 }
2338 break;
2339 case 1:
2340 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2341 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2342 if (insn & 8) {
2343 tcg_gen_ext16s_i32(tmp, tmp);
2344 } else {
2345 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2346 }
2347 break;
2348 case 2:
2349 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2350 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2351 break;
2352 }
2353 store_reg(s, rd, tmp);
2354 break;
2355 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2356 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2357 return 1;
2358 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2359 switch ((insn >> 22) & 3) {
2360 case 0:
2361 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2362 break;
2363 case 1:
2364 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2365 break;
2366 case 2:
2367 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2368 break;
2369 }
2370 tcg_gen_shli_i32(tmp, tmp, 28);
2371 gen_set_nzcv(tmp);
2372 tcg_temp_free_i32(tmp);
2373 break;
2374 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2375 if (((insn >> 6) & 3) == 3)
2376 return 1;
2377 rd = (insn >> 12) & 0xf;
2378 wrd = (insn >> 16) & 0xf;
2379 tmp = load_reg(s, rd);
2380 switch ((insn >> 6) & 3) {
2381 case 0:
2382 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2383 break;
2384 case 1:
2385 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2386 break;
2387 case 2:
2388 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2389 break;
2390 }
2391 tcg_temp_free_i32(tmp);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd);
2393 gen_op_iwmmxt_set_mup();
2394 break;
2395 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2396 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2397 return 1;
2398 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2399 tmp2 = tcg_temp_new_i32();
2400 tcg_gen_mov_i32(tmp2, tmp);
2401 switch ((insn >> 22) & 3) {
2402 case 0:
2403 for (i = 0; i < 7; i ++) {
2404 tcg_gen_shli_i32(tmp2, tmp2, 4);
2405 tcg_gen_and_i32(tmp, tmp, tmp2);
2406 }
2407 break;
2408 case 1:
2409 for (i = 0; i < 3; i ++) {
2410 tcg_gen_shli_i32(tmp2, tmp2, 8);
2411 tcg_gen_and_i32(tmp, tmp, tmp2);
2412 }
2413 break;
2414 case 2:
2415 tcg_gen_shli_i32(tmp2, tmp2, 16);
2416 tcg_gen_and_i32(tmp, tmp, tmp2);
2417 break;
2418 }
2419 gen_set_nzcv(tmp);
2420 tcg_temp_free_i32(tmp2);
2421 tcg_temp_free_i32(tmp);
2422 break;
2423 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2424 wrd = (insn >> 12) & 0xf;
2425 rd0 = (insn >> 16) & 0xf;
2426 gen_op_iwmmxt_movq_M0_wRn(rd0);
2427 switch ((insn >> 22) & 3) {
2428 case 0:
2429 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2430 break;
2431 case 1:
2432 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2433 break;
2434 case 2:
2435 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2436 break;
2437 case 3:
2438 return 1;
2439 }
2440 gen_op_iwmmxt_movq_wRn_M0(wrd);
2441 gen_op_iwmmxt_set_mup();
2442 break;
2443 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2444 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2445 return 1;
2446 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2447 tmp2 = tcg_temp_new_i32();
2448 tcg_gen_mov_i32(tmp2, tmp);
2449 switch ((insn >> 22) & 3) {
2450 case 0:
2451 for (i = 0; i < 7; i ++) {
2452 tcg_gen_shli_i32(tmp2, tmp2, 4);
2453 tcg_gen_or_i32(tmp, tmp, tmp2);
2454 }
2455 break;
2456 case 1:
2457 for (i = 0; i < 3; i ++) {
2458 tcg_gen_shli_i32(tmp2, tmp2, 8);
2459 tcg_gen_or_i32(tmp, tmp, tmp2);
2460 }
2461 break;
2462 case 2:
2463 tcg_gen_shli_i32(tmp2, tmp2, 16);
2464 tcg_gen_or_i32(tmp, tmp, tmp2);
2465 break;
2466 }
2467 gen_set_nzcv(tmp);
2468 tcg_temp_free_i32(tmp2);
2469 tcg_temp_free_i32(tmp);
2470 break;
2471 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2472 rd = (insn >> 12) & 0xf;
2473 rd0 = (insn >> 16) & 0xf;
2474 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2475 return 1;
2476 gen_op_iwmmxt_movq_M0_wRn(rd0);
2477 tmp = tcg_temp_new_i32();
2478 switch ((insn >> 22) & 3) {
2479 case 0:
2480 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2481 break;
2482 case 1:
2483 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2484 break;
2485 case 2:
2486 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2487 break;
2488 }
2489 store_reg(s, rd, tmp);
2490 break;
2491 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2492 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2493 wrd = (insn >> 12) & 0xf;
2494 rd0 = (insn >> 16) & 0xf;
2495 rd1 = (insn >> 0) & 0xf;
2496 gen_op_iwmmxt_movq_M0_wRn(rd0);
2497 switch ((insn >> 22) & 3) {
2498 case 0:
2499 if (insn & (1 << 21))
2500 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2501 else
2502 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2503 break;
2504 case 1:
2505 if (insn & (1 << 21))
2506 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2507 else
2508 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2509 break;
2510 case 2:
2511 if (insn & (1 << 21))
2512 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2513 else
2514 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2515 break;
2516 case 3:
2517 return 1;
2518 }
2519 gen_op_iwmmxt_movq_wRn_M0(wrd);
2520 gen_op_iwmmxt_set_mup();
2521 gen_op_iwmmxt_set_cup();
2522 break;
2523 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2524 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2525 wrd = (insn >> 12) & 0xf;
2526 rd0 = (insn >> 16) & 0xf;
2527 gen_op_iwmmxt_movq_M0_wRn(rd0);
2528 switch ((insn >> 22) & 3) {
2529 case 0:
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_unpacklsb_M0();
2532 else
2533 gen_op_iwmmxt_unpacklub_M0();
2534 break;
2535 case 1:
2536 if (insn & (1 << 21))
2537 gen_op_iwmmxt_unpacklsw_M0();
2538 else
2539 gen_op_iwmmxt_unpackluw_M0();
2540 break;
2541 case 2:
2542 if (insn & (1 << 21))
2543 gen_op_iwmmxt_unpacklsl_M0();
2544 else
2545 gen_op_iwmmxt_unpacklul_M0();
2546 break;
2547 case 3:
2548 return 1;
2549 }
2550 gen_op_iwmmxt_movq_wRn_M0(wrd);
2551 gen_op_iwmmxt_set_mup();
2552 gen_op_iwmmxt_set_cup();
2553 break;
2554 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2555 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2556 wrd = (insn >> 12) & 0xf;
2557 rd0 = (insn >> 16) & 0xf;
2558 gen_op_iwmmxt_movq_M0_wRn(rd0);
2559 switch ((insn >> 22) & 3) {
2560 case 0:
2561 if (insn & (1 << 21))
2562 gen_op_iwmmxt_unpackhsb_M0();
2563 else
2564 gen_op_iwmmxt_unpackhub_M0();
2565 break;
2566 case 1:
2567 if (insn & (1 << 21))
2568 gen_op_iwmmxt_unpackhsw_M0();
2569 else
2570 gen_op_iwmmxt_unpackhuw_M0();
2571 break;
2572 case 2:
2573 if (insn & (1 << 21))
2574 gen_op_iwmmxt_unpackhsl_M0();
2575 else
2576 gen_op_iwmmxt_unpackhul_M0();
2577 break;
2578 case 3:
2579 return 1;
2580 }
2581 gen_op_iwmmxt_movq_wRn_M0(wrd);
2582 gen_op_iwmmxt_set_mup();
2583 gen_op_iwmmxt_set_cup();
2584 break;
2585 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2586 case 0x214: case 0x614: case 0xa14: case 0xe14:
2587 if (((insn >> 22) & 3) == 0)
2588 return 1;
2589 wrd = (insn >> 12) & 0xf;
2590 rd0 = (insn >> 16) & 0xf;
2591 gen_op_iwmmxt_movq_M0_wRn(rd0);
2592 tmp = tcg_temp_new_i32();
2593 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2594 tcg_temp_free_i32(tmp);
2595 return 1;
2596 }
2597 switch ((insn >> 22) & 3) {
2598 case 1:
2599 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2600 break;
2601 case 2:
2602 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2603 break;
2604 case 3:
2605 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2606 break;
2607 }
2608 tcg_temp_free_i32(tmp);
2609 gen_op_iwmmxt_movq_wRn_M0(wrd);
2610 gen_op_iwmmxt_set_mup();
2611 gen_op_iwmmxt_set_cup();
2612 break;
2613 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2614 case 0x014: case 0x414: case 0x814: case 0xc14:
2615 if (((insn >> 22) & 3) == 0)
2616 return 1;
2617 wrd = (insn >> 12) & 0xf;
2618 rd0 = (insn >> 16) & 0xf;
2619 gen_op_iwmmxt_movq_M0_wRn(rd0);
2620 tmp = tcg_temp_new_i32();
2621 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2622 tcg_temp_free_i32(tmp);
2623 return 1;
2624 }
2625 switch ((insn >> 22) & 3) {
2626 case 1:
2627 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2628 break;
2629 case 2:
2630 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2631 break;
2632 case 3:
2633 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2634 break;
2635 }
2636 tcg_temp_free_i32(tmp);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd);
2638 gen_op_iwmmxt_set_mup();
2639 gen_op_iwmmxt_set_cup();
2640 break;
2641 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2642 case 0x114: case 0x514: case 0x914: case 0xd14:
2643 if (((insn >> 22) & 3) == 0)
2644 return 1;
2645 wrd = (insn >> 12) & 0xf;
2646 rd0 = (insn >> 16) & 0xf;
2647 gen_op_iwmmxt_movq_M0_wRn(rd0);
2648 tmp = tcg_temp_new_i32();
2649 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2650 tcg_temp_free_i32(tmp);
2651 return 1;
2652 }
2653 switch ((insn >> 22) & 3) {
2654 case 1:
2655 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2656 break;
2657 case 2:
2658 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2659 break;
2660 case 3:
2661 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2662 break;
2663 }
2664 tcg_temp_free_i32(tmp);
2665 gen_op_iwmmxt_movq_wRn_M0(wrd);
2666 gen_op_iwmmxt_set_mup();
2667 gen_op_iwmmxt_set_cup();
2668 break;
2669 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2670 case 0x314: case 0x714: case 0xb14: case 0xf14:
2671 if (((insn >> 22) & 3) == 0)
2672 return 1;
2673 wrd = (insn >> 12) & 0xf;
2674 rd0 = (insn >> 16) & 0xf;
2675 gen_op_iwmmxt_movq_M0_wRn(rd0);
2676 tmp = tcg_temp_new_i32();
2677 switch ((insn >> 22) & 3) {
2678 case 1:
2679 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2680 tcg_temp_free_i32(tmp);
2681 return 1;
2682 }
2683 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2684 break;
2685 case 2:
2686 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2687 tcg_temp_free_i32(tmp);
2688 return 1;
2689 }
2690 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2691 break;
2692 case 3:
2693 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2694 tcg_temp_free_i32(tmp);
2695 return 1;
2696 }
2697 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2698 break;
2699 }
2700 tcg_temp_free_i32(tmp);
2701 gen_op_iwmmxt_movq_wRn_M0(wrd);
2702 gen_op_iwmmxt_set_mup();
2703 gen_op_iwmmxt_set_cup();
2704 break;
2705 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2706 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2707 wrd = (insn >> 12) & 0xf;
2708 rd0 = (insn >> 16) & 0xf;
2709 rd1 = (insn >> 0) & 0xf;
2710 gen_op_iwmmxt_movq_M0_wRn(rd0);
2711 switch ((insn >> 22) & 3) {
2712 case 0:
2713 if (insn & (1 << 21))
2714 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2715 else
2716 gen_op_iwmmxt_minub_M0_wRn(rd1);
2717 break;
2718 case 1:
2719 if (insn & (1 << 21))
2720 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2721 else
2722 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2723 break;
2724 case 2:
2725 if (insn & (1 << 21))
2726 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2727 else
2728 gen_op_iwmmxt_minul_M0_wRn(rd1);
2729 break;
2730 case 3:
2731 return 1;
2732 }
2733 gen_op_iwmmxt_movq_wRn_M0(wrd);
2734 gen_op_iwmmxt_set_mup();
2735 break;
2736 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2737 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2738 wrd = (insn >> 12) & 0xf;
2739 rd0 = (insn >> 16) & 0xf;
2740 rd1 = (insn >> 0) & 0xf;
2741 gen_op_iwmmxt_movq_M0_wRn(rd0);
2742 switch ((insn >> 22) & 3) {
2743 case 0:
2744 if (insn & (1 << 21))
2745 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2746 else
2747 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2748 break;
2749 case 1:
2750 if (insn & (1 << 21))
2751 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2752 else
2753 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2754 break;
2755 case 2:
2756 if (insn & (1 << 21))
2757 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2758 else
2759 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2760 break;
2761 case 3:
2762 return 1;
2763 }
2764 gen_op_iwmmxt_movq_wRn_M0(wrd);
2765 gen_op_iwmmxt_set_mup();
2766 break;
2767 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2768 case 0x402: case 0x502: case 0x602: case 0x702:
2769 wrd = (insn >> 12) & 0xf;
2770 rd0 = (insn >> 16) & 0xf;
2771 rd1 = (insn >> 0) & 0xf;
2772 gen_op_iwmmxt_movq_M0_wRn(rd0);
2773 tmp = tcg_const_i32((insn >> 20) & 3);
2774 iwmmxt_load_reg(cpu_V1, rd1);
2775 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2776 tcg_temp_free_i32(tmp);
2777 gen_op_iwmmxt_movq_wRn_M0(wrd);
2778 gen_op_iwmmxt_set_mup();
2779 break;
2780 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2781 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2782 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2783 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2784 wrd = (insn >> 12) & 0xf;
2785 rd0 = (insn >> 16) & 0xf;
2786 rd1 = (insn >> 0) & 0xf;
2787 gen_op_iwmmxt_movq_M0_wRn(rd0);
2788 switch ((insn >> 20) & 0xf) {
2789 case 0x0:
2790 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2791 break;
2792 case 0x1:
2793 gen_op_iwmmxt_subub_M0_wRn(rd1);
2794 break;
2795 case 0x3:
2796 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2797 break;
2798 case 0x4:
2799 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2800 break;
2801 case 0x5:
2802 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2803 break;
2804 case 0x7:
2805 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2806 break;
2807 case 0x8:
2808 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2809 break;
2810 case 0x9:
2811 gen_op_iwmmxt_subul_M0_wRn(rd1);
2812 break;
2813 case 0xb:
2814 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2815 break;
2816 default:
2817 return 1;
2818 }
2819 gen_op_iwmmxt_movq_wRn_M0(wrd);
2820 gen_op_iwmmxt_set_mup();
2821 gen_op_iwmmxt_set_cup();
2822 break;
2823 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2824 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2825 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2826 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2827 wrd = (insn >> 12) & 0xf;
2828 rd0 = (insn >> 16) & 0xf;
2829 gen_op_iwmmxt_movq_M0_wRn(rd0);
2830 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2831 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2832 tcg_temp_free_i32(tmp);
2833 gen_op_iwmmxt_movq_wRn_M0(wrd);
2834 gen_op_iwmmxt_set_mup();
2835 gen_op_iwmmxt_set_cup();
2836 break;
2837 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2838 case 0x418: case 0x518: case 0x618: case 0x718:
2839 case 0x818: case 0x918: case 0xa18: case 0xb18:
2840 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2841 wrd = (insn >> 12) & 0xf;
2842 rd0 = (insn >> 16) & 0xf;
2843 rd1 = (insn >> 0) & 0xf;
2844 gen_op_iwmmxt_movq_M0_wRn(rd0);
2845 switch ((insn >> 20) & 0xf) {
2846 case 0x0:
2847 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2848 break;
2849 case 0x1:
2850 gen_op_iwmmxt_addub_M0_wRn(rd1);
2851 break;
2852 case 0x3:
2853 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2854 break;
2855 case 0x4:
2856 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2857 break;
2858 case 0x5:
2859 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2860 break;
2861 case 0x7:
2862 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2863 break;
2864 case 0x8:
2865 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2866 break;
2867 case 0x9:
2868 gen_op_iwmmxt_addul_M0_wRn(rd1);
2869 break;
2870 case 0xb:
2871 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2872 break;
2873 default:
2874 return 1;
2875 }
2876 gen_op_iwmmxt_movq_wRn_M0(wrd);
2877 gen_op_iwmmxt_set_mup();
2878 gen_op_iwmmxt_set_cup();
2879 break;
2880 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2881 case 0x408: case 0x508: case 0x608: case 0x708:
2882 case 0x808: case 0x908: case 0xa08: case 0xb08:
2883 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2884 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2885 return 1;
2886 wrd = (insn >> 12) & 0xf;
2887 rd0 = (insn >> 16) & 0xf;
2888 rd1 = (insn >> 0) & 0xf;
2889 gen_op_iwmmxt_movq_M0_wRn(rd0);
2890 switch ((insn >> 22) & 3) {
2891 case 1:
2892 if (insn & (1 << 21))
2893 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2894 else
2895 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2896 break;
2897 case 2:
2898 if (insn & (1 << 21))
2899 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2900 else
2901 gen_op_iwmmxt_packul_M0_wRn(rd1);
2902 break;
2903 case 3:
2904 if (insn & (1 << 21))
2905 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2906 else
2907 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2908 break;
2909 }
2910 gen_op_iwmmxt_movq_wRn_M0(wrd);
2911 gen_op_iwmmxt_set_mup();
2912 gen_op_iwmmxt_set_cup();
2913 break;
2914 case 0x201: case 0x203: case 0x205: case 0x207:
2915 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2916 case 0x211: case 0x213: case 0x215: case 0x217:
2917 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2918 wrd = (insn >> 5) & 0xf;
2919 rd0 = (insn >> 12) & 0xf;
2920 rd1 = (insn >> 0) & 0xf;
2921 if (rd0 == 0xf || rd1 == 0xf)
2922 return 1;
2923 gen_op_iwmmxt_movq_M0_wRn(wrd);
2924 tmp = load_reg(s, rd0);
2925 tmp2 = load_reg(s, rd1);
2926 switch ((insn >> 16) & 0xf) {
2927 case 0x0: /* TMIA */
2928 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2929 break;
2930 case 0x8: /* TMIAPH */
2931 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2932 break;
2933 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2934 if (insn & (1 << 16))
2935 tcg_gen_shri_i32(tmp, tmp, 16);
2936 if (insn & (1 << 17))
2937 tcg_gen_shri_i32(tmp2, tmp2, 16);
2938 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2939 break;
2940 default:
2941 tcg_temp_free_i32(tmp2);
2942 tcg_temp_free_i32(tmp);
2943 return 1;
2944 }
2945 tcg_temp_free_i32(tmp2);
2946 tcg_temp_free_i32(tmp);
2947 gen_op_iwmmxt_movq_wRn_M0(wrd);
2948 gen_op_iwmmxt_set_mup();
2949 break;
2950 default:
2951 return 1;
2952 }
2953
2954 return 0;
2955 }
2956
2957 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2958 (ie. an undefined instruction). */
2959 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2960 {
2961 int acc, rd0, rd1, rdhi, rdlo;
2962 TCGv_i32 tmp, tmp2;
2963
2964 if ((insn & 0x0ff00f10) == 0x0e200010) {
2965 /* Multiply with Internal Accumulate Format */
2966 rd0 = (insn >> 12) & 0xf;
2967 rd1 = insn & 0xf;
2968 acc = (insn >> 5) & 7;
2969
2970 if (acc != 0)
2971 return 1;
2972
2973 tmp = load_reg(s, rd0);
2974 tmp2 = load_reg(s, rd1);
2975 switch ((insn >> 16) & 0xf) {
2976 case 0x0: /* MIA */
2977 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2978 break;
2979 case 0x8: /* MIAPH */
2980 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2981 break;
2982 case 0xc: /* MIABB */
2983 case 0xd: /* MIABT */
2984 case 0xe: /* MIATB */
2985 case 0xf: /* MIATT */
2986 if (insn & (1 << 16))
2987 tcg_gen_shri_i32(tmp, tmp, 16);
2988 if (insn & (1 << 17))
2989 tcg_gen_shri_i32(tmp2, tmp2, 16);
2990 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2991 break;
2992 default:
2993 return 1;
2994 }
2995 tcg_temp_free_i32(tmp2);
2996 tcg_temp_free_i32(tmp);
2997
2998 gen_op_iwmmxt_movq_wRn_M0(acc);
2999 return 0;
3000 }
3001
3002 if ((insn & 0x0fe00ff8) == 0x0c400000) {
3003 /* Internal Accumulator Access Format */
3004 rdhi = (insn >> 16) & 0xf;
3005 rdlo = (insn >> 12) & 0xf;
3006 acc = insn & 7;
3007
3008 if (acc != 0)
3009 return 1;
3010
3011 if (insn & ARM_CP_RW_BIT) { /* MRA */
3012 iwmmxt_load_reg(cpu_V0, acc);
3013 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
3014 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
3015 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
3016 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
3017 } else { /* MAR */
3018 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
3019 iwmmxt_store_reg(cpu_V0, acc);
3020 }
3021 return 0;
3022 }
3023
3024 return 1;
3025 }
3026
3027 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3028 #define VFP_SREG(insn, bigbit, smallbit) \
3029 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3030 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3031 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3032 reg = (((insn) >> (bigbit)) & 0x0f) \
3033 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3034 } else { \
3035 if (insn & (1 << (smallbit))) \
3036 return 1; \
3037 reg = ((insn) >> (bigbit)) & 0x0f; \
3038 }} while (0)
3039
3040 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3041 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3042 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3043 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3044 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3045 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3046
3047 /* Move between integer and VFP cores. */
3048 static TCGv_i32 gen_vfp_mrs(void)
3049 {
3050 TCGv_i32 tmp = tcg_temp_new_i32();
3051 tcg_gen_mov_i32(tmp, cpu_F0s);
3052 return tmp;
3053 }
3054
3055 static void gen_vfp_msr(TCGv_i32 tmp)
3056 {
3057 tcg_gen_mov_i32(cpu_F0s, tmp);
3058 tcg_temp_free_i32(tmp);
3059 }
3060
3061 static void gen_neon_dup_low16(TCGv_i32 var)
3062 {
3063 TCGv_i32 tmp = tcg_temp_new_i32();
3064 tcg_gen_ext16u_i32(var, var);
3065 tcg_gen_shli_i32(tmp, var, 16);
3066 tcg_gen_or_i32(var, var, tmp);
3067 tcg_temp_free_i32(tmp);
3068 }
3069
3070 static void gen_neon_dup_high16(TCGv_i32 var)
3071 {
3072 TCGv_i32 tmp = tcg_temp_new_i32();
3073 tcg_gen_andi_i32(var, var, 0xffff0000);
3074 tcg_gen_shri_i32(tmp, var, 16);
3075 tcg_gen_or_i32(var, var, tmp);
3076 tcg_temp_free_i32(tmp);
3077 }
3078
3079 /*
3080 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3081 * (ie. an undefined instruction).
3082 */
3083 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3084 {
3085 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3086 int dp, veclen;
3087 TCGv_i32 addr;
3088 TCGv_i32 tmp;
3089 TCGv_i32 tmp2;
3090 bool ignore_vfp_enabled = false;
3091
3092 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3093 return 1;
3094 }
3095
3096 /*
3097 * If the decodetree decoder handles this insn it will always
3098 * emit code to either execute the insn or generate an appropriate
3099 * exception; so we don't need to ever return non-zero to tell
3100 * the calling code to emit an UNDEF exception.
3101 */
3102 if (extract32(insn, 28, 4) == 0xf) {
3103 if (disas_vfp_uncond(s, insn)) {
3104 return 0;
3105 }
3106 } else {
3107 if (disas_vfp(s, insn)) {
3108 return 0;
3109 }
3110 }
3111
3112 if (extract32(insn, 28, 4) == 0xf) {
3113 /*
3114 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3115 * were all handled by the decodetree decoder, so any insn
3116 * patterns which get here must be UNDEF.
3117 */
3118 return 1;
3119 }
3120
3121 /*
3122 * FIXME: this access check should not take precedence over UNDEF
3123 * for invalid encodings; we will generate incorrect syndrome information
3124 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3125 */
3126 if ((insn & 0x0fe00fff) == 0x0ee00a10) {
3127 rn = (insn >> 16) & 0xf;
3128 if (rn == ARM_VFP_FPSID || rn == ARM_VFP_FPEXC || rn == ARM_VFP_MVFR2
3129 || rn == ARM_VFP_MVFR1 || rn == ARM_VFP_MVFR0) {
3130 ignore_vfp_enabled = true;
3131 }
3132 }
3133 if (!full_vfp_access_check(s, ignore_vfp_enabled)) {
3134 return 0;
3135 }
3136
3137 dp = ((insn & 0xf00) == 0xb00);
3138 switch ((insn >> 24) & 0xf) {
3139 case 0xe:
3140 if (insn & (1 << 4)) {
3141 /* single register transfer */
3142 rd = (insn >> 12) & 0xf;
3143 if (dp) {
3144 int size;
3145 int pass;
3146
3147 VFP_DREG_N(rn, insn);
3148 if (insn & 0xf)
3149 return 1;
3150 if (insn & 0x00c00060
3151 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3152 return 1;
3153 }
3154
3155 pass = (insn >> 21) & 1;
3156 if (insn & (1 << 22)) {
3157 size = 0;
3158 offset = ((insn >> 5) & 3) * 8;
3159 } else if (insn & (1 << 5)) {
3160 size = 1;
3161 offset = (insn & (1 << 6)) ? 16 : 0;
3162 } else {
3163 size = 2;
3164 offset = 0;
3165 }
3166 if (insn & ARM_CP_RW_BIT) {
3167 /* vfp->arm */
3168 tmp = neon_load_reg(rn, pass);
3169 switch (size) {
3170 case 0:
3171 if (offset)
3172 tcg_gen_shri_i32(tmp, tmp, offset);
3173 if (insn & (1 << 23))
3174 gen_uxtb(tmp);
3175 else
3176 gen_sxtb(tmp);
3177 break;
3178 case 1:
3179 if (insn & (1 << 23)) {
3180 if (offset) {
3181 tcg_gen_shri_i32(tmp, tmp, 16);
3182 } else {
3183 gen_uxth(tmp);
3184 }
3185 } else {
3186 if (offset) {
3187 tcg_gen_sari_i32(tmp, tmp, 16);
3188 } else {
3189 gen_sxth(tmp);
3190 }
3191 }
3192 break;
3193 case 2:
3194 break;
3195 }
3196 store_reg(s, rd, tmp);
3197 } else {
3198 /* arm->vfp */
3199 tmp = load_reg(s, rd);
3200 if (insn & (1 << 23)) {
3201 /* VDUP */
3202 int vec_size = pass ? 16 : 8;
3203 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3204 vec_size, vec_size, tmp);
3205 tcg_temp_free_i32(tmp);
3206 } else {
3207 /* VMOV */
3208 switch (size) {
3209 case 0:
3210 tmp2 = neon_load_reg(rn, pass);
3211 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3212 tcg_temp_free_i32(tmp2);
3213 break;
3214 case 1:
3215 tmp2 = neon_load_reg(rn, pass);
3216 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3217 tcg_temp_free_i32(tmp2);
3218 break;
3219 case 2:
3220 break;
3221 }
3222 neon_store_reg(rn, pass, tmp);
3223 }
3224 }
3225 } else { /* !dp */
3226 bool is_sysreg;
3227
3228 if ((insn & 0x6f) != 0x00)
3229 return 1;
3230 rn = VFP_SREG_N(insn);
3231
3232 is_sysreg = extract32(insn, 21, 1);
3233
3234 if (arm_dc_feature(s, ARM_FEATURE_M)) {
3235 /*
3236 * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
3237 * Writes to R15 are UNPREDICTABLE; we choose to undef.
3238 */
3239 if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
3240 return 1;
3241 }
3242 }
3243
3244 if (insn & ARM_CP_RW_BIT) {
3245 /* vfp->arm */
3246 if (is_sysreg) {
3247 /* system register */
3248 rn >>= 1;
3249
3250 switch (rn) {
3251 case ARM_VFP_FPSID:
3252 /* VFP2 allows access to FSID from userspace.
3253 VFP3 restricts all id registers to privileged
3254 accesses. */
3255 if (IS_USER(s)
3256 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3257 return 1;
3258 }
3259 tmp = load_cpu_field(vfp.xregs[rn]);
3260 break;
3261 case ARM_VFP_FPEXC:
3262 if (IS_USER(s))
3263 return 1;
3264 tmp = load_cpu_field(vfp.xregs[rn]);
3265 break;
3266 case ARM_VFP_FPINST:
3267 case ARM_VFP_FPINST2:
3268 /* Not present in VFP3. */
3269 if (IS_USER(s)
3270 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3271 return 1;
3272 }
3273 tmp = load_cpu_field(vfp.xregs[rn]);
3274 break;
3275 case ARM_VFP_FPSCR:
3276 if (rd == 15) {
3277 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3278 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3279 } else {
3280 tmp = tcg_temp_new_i32();
3281 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3282 }
3283 break;
3284 case ARM_VFP_MVFR2:
3285 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3286 return 1;
3287 }
3288 /* fall through */
3289 case ARM_VFP_MVFR0:
3290 case ARM_VFP_MVFR1:
3291 if (IS_USER(s)
3292 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3293 return 1;
3294 }
3295 tmp = load_cpu_field(vfp.xregs[rn]);
3296 break;
3297 default:
3298 return 1;
3299 }
3300 } else {
3301 gen_mov_F0_vreg(0, rn);
3302 tmp = gen_vfp_mrs();
3303 }
3304 if (rd == 15) {
3305 /* Set the 4 flag bits in the CPSR. */
3306 gen_set_nzcv(tmp);
3307 tcg_temp_free_i32(tmp);
3308 } else {
3309 store_reg(s, rd, tmp);
3310 }
3311 } else {
3312 /* arm->vfp */
3313 if (is_sysreg) {
3314 rn >>= 1;
3315 /* system register */
3316 switch (rn) {
3317 case ARM_VFP_FPSID:
3318 case ARM_VFP_MVFR0:
3319 case ARM_VFP_MVFR1:
3320 /* Writes are ignored. */
3321 break;
3322 case ARM_VFP_FPSCR:
3323 tmp = load_reg(s, rd);
3324 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3325 tcg_temp_free_i32(tmp);
3326 gen_lookup_tb(s);
3327 break;
3328 case ARM_VFP_FPEXC:
3329 if (IS_USER(s))
3330 return 1;
3331 /* TODO: VFP subarchitecture support.
3332 * For now, keep the EN bit only */
3333 tmp = load_reg(s, rd);
3334 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3335 store_cpu_field(tmp, vfp.xregs[rn]);
3336 gen_lookup_tb(s);
3337 break;
3338 case ARM_VFP_FPINST:
3339 case ARM_VFP_FPINST2:
3340 if (IS_USER(s)) {
3341 return 1;
3342 }
3343 tmp = load_reg(s, rd);
3344 store_cpu_field(tmp, vfp.xregs[rn]);
3345 break;
3346 default:
3347 return 1;
3348 }
3349 } else {
3350 tmp = load_reg(s, rd);
3351 gen_vfp_msr(tmp);
3352 gen_mov_vreg_F0(0, rn);
3353 }
3354 }
3355 }
3356 } else {
3357 /* data processing */
3358 bool rd_is_dp = dp;
3359 bool rm_is_dp = dp;
3360 bool no_output = false;
3361
3362 /* The opcode is in bits 23, 21, 20 and 6. */
3363 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3364 rn = VFP_SREG_N(insn);
3365
3366 if (op == 15) {
3367 /* rn is opcode, encoded as per VFP_SREG_N. */
3368 switch (rn) {
3369 case 0x00: /* vmov */
3370 case 0x01: /* vabs */
3371 case 0x02: /* vneg */
3372 case 0x03: /* vsqrt */
3373 break;
3374
3375 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3376 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3377 /*
3378 * VCVTB, VCVTT: only present with the halfprec extension
3379 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3380 * (we choose to UNDEF)
3381 */
3382 if (dp) {
3383 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3384 return 1;
3385 }
3386 } else {
3387 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3388 return 1;
3389 }
3390 }
3391 rm_is_dp = false;
3392 break;
3393 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3394 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3395 if (dp) {
3396 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3397 return 1;
3398 }
3399 } else {
3400 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3401 return 1;
3402 }
3403 }
3404 rd_is_dp = false;
3405 break;
3406
3407 case 0x08: case 0x0a: /* vcmp, vcmpz */
3408 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3409 no_output = true;
3410 break;
3411
3412 case 0x0c: /* vrintr */
3413 case 0x0d: /* vrintz */
3414 case 0x0e: /* vrintx */
3415 break;
3416
3417 case 0x0f: /* vcvt double<->single */
3418 rd_is_dp = !dp;
3419 break;
3420
3421 case 0x10: /* vcvt.fxx.u32 */
3422 case 0x11: /* vcvt.fxx.s32 */
3423 rm_is_dp = false;
3424 break;
3425 case 0x18: /* vcvtr.u32.fxx */
3426 case 0x19: /* vcvtz.u32.fxx */
3427 case 0x1a: /* vcvtr.s32.fxx */
3428 case 0x1b: /* vcvtz.s32.fxx */
3429 rd_is_dp = false;
3430 break;
3431
3432 case 0x14: /* vcvt fp <-> fixed */
3433 case 0x15:
3434 case 0x16:
3435 case 0x17:
3436 case 0x1c:
3437 case 0x1d:
3438 case 0x1e:
3439 case 0x1f:
3440 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3441 return 1;
3442 }
3443 /* Immediate frac_bits has same format as SREG_M. */
3444 rm_is_dp = false;
3445 break;
3446
3447 case 0x13: /* vjcvt */
3448 if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
3449 return 1;
3450 }
3451 rd_is_dp = false;
3452 break;
3453
3454 default:
3455 return 1;
3456 }
3457 } else if (dp) {
3458 /* rn is register number */
3459 VFP_DREG_N(rn, insn);
3460 }
3461
3462 if (rd_is_dp) {
3463 VFP_DREG_D(rd, insn);
3464 } else {
3465 rd = VFP_SREG_D(insn);
3466 }
3467 if (rm_is_dp) {
3468 VFP_DREG_M(rm, insn);
3469 } else {
3470 rm = VFP_SREG_M(insn);
3471 }
3472
3473 veclen = s->vec_len;
3474 if (op == 15 && rn > 3) {
3475 veclen = 0;
3476 }
3477
3478 /* Shut up compiler warnings. */
3479 delta_m = 0;
3480 delta_d = 0;
3481 bank_mask = 0;
3482
3483 if (veclen > 0) {
3484 if (dp)
3485 bank_mask = 0xc;
3486 else
3487 bank_mask = 0x18;
3488
3489 /* Figure out what type of vector operation this is. */
3490 if ((rd & bank_mask) == 0) {
3491 /* scalar */
3492 veclen = 0;
3493 } else {
3494 if (dp)
3495 delta_d = (s->vec_stride >> 1) + 1;
3496 else
3497 delta_d = s->vec_stride + 1;
3498
3499 if ((rm & bank_mask) == 0) {
3500 /* mixed scalar/vector */
3501 delta_m = 0;
3502 } else {
3503 /* vector */
3504 delta_m = delta_d;
3505 }
3506 }
3507 }
3508
3509 /* Load the initial operands. */
3510 if (op == 15) {
3511 switch (rn) {
3512 case 0x08: case 0x09: /* Compare */
3513 gen_mov_F0_vreg(dp, rd);
3514 gen_mov_F1_vreg(dp, rm);
3515 break;
3516 case 0x0a: case 0x0b: /* Compare with zero */
3517 gen_mov_F0_vreg(dp, rd);
3518 gen_vfp_F1_ld0(dp);
3519 break;
3520 case 0x14: /* vcvt fp <-> fixed */
3521 case 0x15:
3522 case 0x16:
3523 case 0x17:
3524 case 0x1c:
3525 case 0x1d:
3526 case 0x1e:
3527 case 0x1f:
3528 /* Source and destination the same. */
3529 gen_mov_F0_vreg(dp, rd);
3530 break;
3531 default:
3532 /* One source operand. */
3533 gen_mov_F0_vreg(rm_is_dp, rm);
3534 break;
3535 }
3536 } else {
3537 /* Two source operands. */
3538 gen_mov_F0_vreg(dp, rn);
3539 gen_mov_F1_vreg(dp, rm);
3540 }
3541
3542 for (;;) {
3543 /* Perform the calculation. */
3544 switch (op) {
3545 case 0: /* VMLA: fd + (fn * fm) */
3546 /* Note that order of inputs to the add matters for NaNs */
3547 gen_vfp_F1_mul(dp);
3548 gen_mov_F0_vreg(dp, rd);
3549 gen_vfp_add(dp);
3550 break;
3551 case 1: /* VMLS: fd + -(fn * fm) */
3552 gen_vfp_mul(dp);
3553 gen_vfp_F1_neg(dp);
3554 gen_mov_F0_vreg(dp, rd);
3555 gen_vfp_add(dp);
3556 break;
3557 case 2: /* VNMLS: -fd + (fn * fm) */
3558 /* Note that it isn't valid to replace (-A + B) with (B - A)
3559 * or similar plausible looking simplifications
3560 * because this will give wrong results for NaNs.
3561 */
3562 gen_vfp_F1_mul(dp);
3563 gen_mov_F0_vreg(dp, rd);
3564 gen_vfp_neg(dp);
3565 gen_vfp_add(dp);
3566 break;
3567 case 3: /* VNMLA: -fd + -(fn * fm) */
3568 gen_vfp_mul(dp);
3569 gen_vfp_F1_neg(dp);
3570 gen_mov_F0_vreg(dp, rd);
3571 gen_vfp_neg(dp);
3572 gen_vfp_add(dp);
3573 break;
3574 case 4: /* mul: fn * fm */
3575 gen_vfp_mul(dp);
3576 break;
3577 case 5: /* nmul: -(fn * fm) */
3578 gen_vfp_mul(dp);
3579 gen_vfp_neg(dp);
3580 break;
3581 case 6: /* add: fn + fm */
3582 gen_vfp_add(dp);
3583 break;
3584 case 7: /* sub: fn - fm */
3585 gen_vfp_sub(dp);
3586 break;
3587 case 8: /* div: fn / fm */
3588 gen_vfp_div(dp);
3589 break;
3590 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3591 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3592 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3593 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3594 /* These are fused multiply-add, and must be done as one
3595 * floating point operation with no rounding between the
3596 * multiplication and addition steps.
3597 * NB that doing the negations here as separate steps is
3598 * correct : an input NaN should come out with its sign bit
3599 * flipped if it is a negated-input.
3600 */
3601 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3602 return 1;
3603 }
3604 if (dp) {
3605 TCGv_ptr fpst;
3606 TCGv_i64 frd;
3607 if (op & 1) {
3608 /* VFNMS, VFMS */
3609 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3610 }
3611 frd = tcg_temp_new_i64();
3612 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3613 if (op & 2) {
3614 /* VFNMA, VFNMS */
3615 gen_helper_vfp_negd(frd, frd);
3616 }
3617 fpst = get_fpstatus_ptr(0);
3618 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3619 cpu_F1d, frd, fpst);
3620 tcg_temp_free_ptr(fpst);
3621 tcg_temp_free_i64(frd);
3622 } else {
3623 TCGv_ptr fpst;
3624 TCGv_i32 frd;
3625 if (op & 1) {
3626 /* VFNMS, VFMS */
3627 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3628 }
3629 frd = tcg_temp_new_i32();
3630 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3631 if (op & 2) {
3632 gen_helper_vfp_negs(frd, frd);
3633 }
3634 fpst = get_fpstatus_ptr(0);
3635 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3636 cpu_F1s, frd, fpst);
3637 tcg_temp_free_ptr(fpst);
3638 tcg_temp_free_i32(frd);
3639 }
3640 break;
3641 case 14: /* fconst */
3642 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3643 return 1;
3644 }
3645
3646 n = (insn << 12) & 0x80000000;
3647 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3648 if (dp) {
3649 if (i & 0x40)
3650 i |= 0x3f80;
3651 else
3652 i |= 0x4000;
3653 n |= i << 16;
3654 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3655 } else {
3656 if (i & 0x40)
3657 i |= 0x780;
3658 else
3659 i |= 0x800;
3660 n |= i << 19;
3661 tcg_gen_movi_i32(cpu_F0s, n);
3662 }
3663 break;
3664 case 15: /* extension space */
3665 switch (rn) {
3666 case 0: /* cpy */
3667 /* no-op */
3668 break;
3669 case 1: /* abs */
3670 gen_vfp_abs(dp);
3671 break;
3672 case 2: /* neg */
3673 gen_vfp_neg(dp);
3674 break;
3675 case 3: /* sqrt */
3676 gen_vfp_sqrt(dp);
3677 break;
3678 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3679 {
3680 TCGv_ptr fpst = get_fpstatus_ptr(false);
3681 TCGv_i32 ahp_mode = get_ahp_flag();
3682 tmp = gen_vfp_mrs();
3683 tcg_gen_ext16u_i32(tmp, tmp);
3684 if (dp) {
3685 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3686 fpst, ahp_mode);
3687 } else {
3688 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3689 fpst, ahp_mode);
3690 }
3691 tcg_temp_free_i32(ahp_mode);
3692 tcg_temp_free_ptr(fpst);
3693 tcg_temp_free_i32(tmp);
3694 break;
3695 }
3696 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3697 {
3698 TCGv_ptr fpst = get_fpstatus_ptr(false);
3699 TCGv_i32 ahp = get_ahp_flag();
3700 tmp = gen_vfp_mrs();
3701 tcg_gen_shri_i32(tmp, tmp, 16);
3702 if (dp) {
3703 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3704 fpst, ahp);
3705 } else {
3706 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3707 fpst, ahp);
3708 }
3709 tcg_temp_free_i32(tmp);
3710 tcg_temp_free_i32(ahp);
3711 tcg_temp_free_ptr(fpst);
3712 break;
3713 }
3714 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3715 {
3716 TCGv_ptr fpst = get_fpstatus_ptr(false);
3717 TCGv_i32 ahp = get_ahp_flag();
3718 tmp = tcg_temp_new_i32();
3719
3720 if (dp) {
3721 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3722 fpst, ahp);
3723 } else {
3724 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3725 fpst, ahp);
3726 }
3727 tcg_temp_free_i32(ahp);
3728 tcg_temp_free_ptr(fpst);
3729 gen_mov_F0_vreg(0, rd);
3730 tmp2 = gen_vfp_mrs();
3731 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3732 tcg_gen_or_i32(tmp, tmp, tmp2);
3733 tcg_temp_free_i32(tmp2);
3734 gen_vfp_msr(tmp);
3735 break;
3736 }
3737 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3738 {
3739 TCGv_ptr fpst = get_fpstatus_ptr(false);
3740 TCGv_i32 ahp = get_ahp_flag();
3741 tmp = tcg_temp_new_i32();
3742 if (dp) {
3743 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3744 fpst, ahp);
3745 } else {
3746 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3747 fpst, ahp);
3748 }
3749 tcg_temp_free_i32(ahp);
3750 tcg_temp_free_ptr(fpst);
3751 tcg_gen_shli_i32(tmp, tmp, 16);
3752 gen_mov_F0_vreg(0, rd);
3753 tmp2 = gen_vfp_mrs();
3754 tcg_gen_ext16u_i32(tmp2, tmp2);
3755 tcg_gen_or_i32(tmp, tmp, tmp2);
3756 tcg_temp_free_i32(tmp2);
3757 gen_vfp_msr(tmp);
3758 break;
3759 }
3760 case 8: /* cmp */
3761 gen_vfp_cmp(dp);
3762 break;
3763 case 9: /* cmpe */
3764 gen_vfp_cmpe(dp);
3765 break;
3766 case 10: /* cmpz */
3767 gen_vfp_cmp(dp);
3768 break;
3769 case 11: /* cmpez */
3770 gen_vfp_F1_ld0(dp);
3771 gen_vfp_cmpe(dp);
3772 break;
3773 case 12: /* vrintr */
3774 {
3775 TCGv_ptr fpst = get_fpstatus_ptr(0);
3776 if (dp) {
3777 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3778 } else {
3779 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3780 }
3781 tcg_temp_free_ptr(fpst);
3782 break;
3783 }
3784 case 13: /* vrintz */
3785 {
3786 TCGv_ptr fpst = get_fpstatus_ptr(0);
3787 TCGv_i32 tcg_rmode;
3788 tcg_rmode = tcg_const_i32(float_round_to_zero);
3789 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3790 if (dp) {
3791 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3792 } else {
3793 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3794 }
3795 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3796 tcg_temp_free_i32(tcg_rmode);
3797 tcg_temp_free_ptr(fpst);
3798 break;
3799 }
3800 case 14: /* vrintx */
3801 {
3802 TCGv_ptr fpst = get_fpstatus_ptr(0);
3803 if (dp) {
3804 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3805 } else {
3806 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3807 }
3808 tcg_temp_free_ptr(fpst);
3809 break;
3810 }
3811 case 15: /* single<->double conversion */
3812 if (dp) {
3813 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3814 } else {
3815 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3816 }
3817 break;
3818 case 16: /* fuito */
3819 gen_vfp_uito(dp, 0);
3820 break;
3821 case 17: /* fsito */
3822 gen_vfp_sito(dp, 0);
3823 break;
3824 case 19: /* vjcvt */
3825 gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
3826 break;
3827 case 20: /* fshto */
3828 gen_vfp_shto(dp, 16 - rm, 0);
3829 break;
3830 case 21: /* fslto */
3831 gen_vfp_slto(dp, 32 - rm, 0);
3832 break;
3833 case 22: /* fuhto */
3834 gen_vfp_uhto(dp, 16 - rm, 0);
3835 break;
3836 case 23: /* fulto */
3837 gen_vfp_ulto(dp, 32 - rm, 0);
3838 break;
3839 case 24: /* ftoui */
3840 gen_vfp_toui(dp, 0);
3841 break;
3842 case 25: /* ftouiz */
3843 gen_vfp_touiz(dp, 0);
3844 break;
3845 case 26: /* ftosi */
3846 gen_vfp_tosi(dp, 0);
3847 break;
3848 case 27: /* ftosiz */
3849 gen_vfp_tosiz(dp, 0);
3850 break;
3851 case 28: /* ftosh */
3852 gen_vfp_tosh(dp, 16 - rm, 0);
3853 break;
3854 case 29: /* ftosl */
3855 gen_vfp_tosl(dp, 32 - rm, 0);
3856 break;
3857 case 30: /* ftouh */
3858 gen_vfp_touh(dp, 16 - rm, 0);
3859 break;
3860 case 31: /* ftoul */
3861 gen_vfp_toul(dp, 32 - rm, 0);
3862 break;
3863 default: /* undefined */
3864 g_assert_not_reached();
3865 }
3866 break;
3867 default: /* undefined */
3868 return 1;
3869 }
3870
3871 /* Write back the result, if any. */
3872 if (!no_output) {
3873 gen_mov_vreg_F0(rd_is_dp, rd);
3874 }
3875
3876 /* break out of the loop if we have finished */
3877 if (veclen == 0) {
3878 break;
3879 }
3880
3881 if (op == 15 && delta_m == 0) {
3882 /* single source one-many */
3883 while (veclen--) {
3884 rd = ((rd + delta_d) & (bank_mask - 1))
3885 | (rd & bank_mask);
3886 gen_mov_vreg_F0(dp, rd);
3887 }
3888 break;
3889 }
3890 /* Setup the next operands. */
3891 veclen--;
3892 rd = ((rd + delta_d) & (bank_mask - 1))
3893 | (rd & bank_mask);
3894
3895 if (op == 15) {
3896 /* One source operand. */
3897 rm = ((rm + delta_m) & (bank_mask - 1))
3898 | (rm & bank_mask);
3899 gen_mov_F0_vreg(dp, rm);
3900 } else {
3901 /* Two source operands. */
3902 rn = ((rn + delta_d) & (bank_mask - 1))
3903 | (rn & bank_mask);
3904 gen_mov_F0_vreg(dp, rn);
3905 if (delta_m) {
3906 rm = ((rm + delta_m) & (bank_mask - 1))
3907 | (rm & bank_mask);
3908 gen_mov_F1_vreg(dp, rm);
3909 }
3910 }
3911 }
3912 }
3913 break;
3914 case 0xc:
3915 case 0xd:
3916 if ((insn & 0x03e00000) == 0x00400000) {
3917 /* two-register transfer */
3918 rn = (insn >> 16) & 0xf;
3919 rd = (insn >> 12) & 0xf;
3920 if (dp) {
3921 VFP_DREG_M(rm, insn);
3922 } else {
3923 rm = VFP_SREG_M(insn);
3924 }
3925
3926 if (insn & ARM_CP_RW_BIT) {
3927 /* vfp->arm */
3928 if (dp) {
3929 gen_mov_F0_vreg(0, rm * 2);
3930 tmp = gen_vfp_mrs();
3931 store_reg(s, rd, tmp);
3932 gen_mov_F0_vreg(0, rm * 2 + 1);
3933 tmp = gen_vfp_mrs();
3934 store_reg(s, rn, tmp);
3935 } else {
3936 gen_mov_F0_vreg(0, rm);
3937 tmp = gen_vfp_mrs();
3938 store_reg(s, rd, tmp);
3939 gen_mov_F0_vreg(0, rm + 1);
3940 tmp = gen_vfp_mrs();
3941 store_reg(s, rn, tmp);
3942 }
3943 } else {
3944 /* arm->vfp */
3945 if (dp) {
3946 tmp = load_reg(s, rd);
3947 gen_vfp_msr(tmp);
3948 gen_mov_vreg_F0(0, rm * 2);
3949 tmp = load_reg(s, rn);
3950 gen_vfp_msr(tmp);
3951 gen_mov_vreg_F0(0, rm * 2 + 1);
3952 } else {
3953 tmp = load_reg(s, rd);
3954 gen_vfp_msr(tmp);
3955 gen_mov_vreg_F0(0, rm);
3956 tmp = load_reg(s, rn);
3957 gen_vfp_msr(tmp);
3958 gen_mov_vreg_F0(0, rm + 1);
3959 }
3960 }
3961 } else {
3962 /* Load/store */
3963 rn = (insn >> 16) & 0xf;
3964 if (dp)
3965 VFP_DREG_D(rd, insn);
3966 else
3967 rd = VFP_SREG_D(insn);
3968 if ((insn & 0x01200000) == 0x01000000) {
3969 /* Single load/store */
3970 offset = (insn & 0xff) << 2;
3971 if ((insn & (1 << 23)) == 0)
3972 offset = -offset;
3973 if (s->thumb && rn == 15) {
3974 /* This is actually UNPREDICTABLE */
3975 addr = tcg_temp_new_i32();
3976 tcg_gen_movi_i32(addr, s->pc & ~2);
3977 } else {
3978 addr = load_reg(s, rn);
3979 }
3980 tcg_gen_addi_i32(addr, addr, offset);
3981 if (insn & (1 << 20)) {
3982 gen_vfp_ld(s, dp, addr);
3983 gen_mov_vreg_F0(dp, rd);
3984 } else {
3985 gen_mov_F0_vreg(dp, rd);
3986 gen_vfp_st(s, dp, addr);
3987 }
3988 tcg_temp_free_i32(addr);
3989 } else {
3990 /* load/store multiple */
3991 int w = insn & (1 << 21);
3992 if (dp)
3993 n = (insn >> 1) & 0x7f;
3994 else
3995 n = insn & 0xff;
3996
3997 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3998 /* P == U , W == 1 => UNDEF */
3999 return 1;
4000 }
4001 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4002 /* UNPREDICTABLE cases for bad immediates: we choose to
4003 * UNDEF to avoid generating huge numbers of TCG ops
4004 */
4005 return 1;
4006 }
4007 if (rn == 15 && w) {
4008 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4009 return 1;
4010 }
4011
4012 if (s->thumb && rn == 15) {
4013 /* This is actually UNPREDICTABLE */
4014 addr = tcg_temp_new_i32();
4015 tcg_gen_movi_i32(addr, s->pc & ~2);
4016 } else {
4017 addr = load_reg(s, rn);
4018 }
4019 if (insn & (1 << 24)) /* pre-decrement */
4020 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4021
4022 if (s->v8m_stackcheck && rn == 13 && w) {
4023 /*
4024 * Here 'addr' is the lowest address we will store to,
4025 * and is either the old SP (if post-increment) or
4026 * the new SP (if pre-decrement). For post-increment
4027 * where the old value is below the limit and the new
4028 * value is above, it is UNKNOWN whether the limit check
4029 * triggers; we choose to trigger.
4030 */
4031 gen_helper_v8m_stackcheck(cpu_env, addr);
4032 }
4033
4034 if (dp)
4035 offset = 8;
4036 else
4037 offset = 4;
4038 for (i = 0; i < n; i++) {
4039 if (insn & ARM_CP_RW_BIT) {
4040 /* load */
4041 gen_vfp_ld(s, dp, addr);
4042 gen_mov_vreg_F0(dp, rd + i);
4043 } else {
4044 /* store */
4045 gen_mov_F0_vreg(dp, rd + i);
4046 gen_vfp_st(s, dp, addr);
4047 }
4048 tcg_gen_addi_i32(addr, addr, offset);
4049 }
4050 if (w) {
4051 /* writeback */
4052 if (insn & (1 << 24))
4053 offset = -offset * n;
4054 else if (dp && (insn & 1))
4055 offset = 4;
4056 else
4057 offset = 0;
4058
4059 if (offset != 0)
4060 tcg_gen_addi_i32(addr, addr, offset);
4061 store_reg(s, rn, addr);
4062 } else {
4063 tcg_temp_free_i32(addr);
4064 }
4065 }
4066 }
4067 break;
4068 default:
4069 /* Should never happen. */
4070 return 1;
4071 }
4072 return 0;
4073 }
4074
4075 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4076 {
4077 #ifndef CONFIG_USER_ONLY
4078 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4079 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4080 #else
4081 return true;
4082 #endif
4083 }
4084
4085 static void gen_goto_ptr(void)
4086 {
4087 tcg_gen_lookup_and_goto_ptr();
4088 }
4089
4090 /* This will end the TB but doesn't guarantee we'll return to
4091 * cpu_loop_exec. Any live exit_requests will be processed as we
4092 * enter the next TB.
4093 */
4094 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4095 {
4096 if (use_goto_tb(s, dest)) {
4097 tcg_gen_goto_tb(n);
4098 gen_set_pc_im(s, dest);
4099 tcg_gen_exit_tb(s->base.tb, n);
4100 } else {
4101 gen_set_pc_im(s, dest);
4102 gen_goto_ptr();
4103 }
4104 s->base.is_jmp = DISAS_NORETURN;
4105 }
4106
4107 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4108 {
4109 if (unlikely(is_singlestepping(s))) {
4110 /* An indirect jump so that we still trigger the debug exception. */
4111 if (s->thumb)
4112 dest |= 1;
4113 gen_bx_im(s, dest);
4114 } else {
4115 gen_goto_tb(s, 0, dest);
4116 }
4117 }
4118
4119 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4120 {
4121 if (x)
4122 tcg_gen_sari_i32(t0, t0, 16);
4123 else
4124 gen_sxth(t0);
4125 if (y)
4126 tcg_gen_sari_i32(t1, t1, 16);
4127 else
4128 gen_sxth(t1);
4129 tcg_gen_mul_i32(t0, t0, t1);
4130 }
4131
4132 /* Return the mask of PSR bits set by a MSR instruction. */
4133 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4134 {
4135 uint32_t mask;
4136
4137 mask = 0;
4138 if (flags & (1 << 0))
4139 mask |= 0xff;
4140 if (flags & (1 << 1))
4141 mask |= 0xff00;
4142 if (flags & (1 << 2))
4143 mask |= 0xff0000;
4144 if (flags & (1 << 3))
4145 mask |= 0xff000000;
4146
4147 /* Mask out undefined bits. */
4148 mask &= ~CPSR_RESERVED;
4149 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4150 mask &= ~CPSR_T;
4151 }
4152 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4153 mask &= ~CPSR_Q; /* V5TE in reality*/
4154 }
4155 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4156 mask &= ~(CPSR_E | CPSR_GE);
4157 }
4158 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4159 mask &= ~CPSR_IT;
4160 }
4161 /* Mask out execution state and reserved bits. */
4162 if (!spsr) {
4163 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4164 }
4165 /* Mask out privileged bits. */
4166 if (IS_USER(s))
4167 mask &= CPSR_USER;
4168 return mask;
4169 }
4170
4171 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4172 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4173 {
4174 TCGv_i32 tmp;
4175 if (spsr) {
4176 /* ??? This is also undefined in system mode. */
4177 if (IS_USER(s))
4178 return 1;
4179
4180 tmp = load_cpu_field(spsr);
4181 tcg_gen_andi_i32(tmp, tmp, ~mask);
4182 tcg_gen_andi_i32(t0, t0, mask);
4183 tcg_gen_or_i32(tmp, tmp, t0);
4184 store_cpu_field(tmp, spsr);
4185 } else {
4186 gen_set_cpsr(t0, mask);
4187 }
4188 tcg_temp_free_i32(t0);
4189 gen_lookup_tb(s);
4190 return 0;
4191 }
4192
4193 /* Returns nonzero if access to the PSR is not permitted. */
4194 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4195 {
4196 TCGv_i32 tmp;
4197 tmp = tcg_temp_new_i32();
4198 tcg_gen_movi_i32(tmp, val);
4199 return gen_set_psr(s, mask, spsr, tmp);
4200 }
4201
4202 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4203 int *tgtmode, int *regno)
4204 {
4205 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4206 * the target mode and register number, and identify the various
4207 * unpredictable cases.
4208 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4209 * + executed in user mode
4210 * + using R15 as the src/dest register
4211 * + accessing an unimplemented register
4212 * + accessing a register that's inaccessible at current PL/security state*
4213 * + accessing a register that you could access with a different insn
4214 * We choose to UNDEF in all these cases.
4215 * Since we don't know which of the various AArch32 modes we are in
4216 * we have to defer some checks to runtime.
4217 * Accesses to Monitor mode registers from Secure EL1 (which implies
4218 * that EL3 is AArch64) must trap to EL3.
4219 *
4220 * If the access checks fail this function will emit code to take
4221 * an exception and return false. Otherwise it will return true,
4222 * and set *tgtmode and *regno appropriately.
4223 */
4224 int exc_target = default_exception_el(s);
4225
4226 /* These instructions are present only in ARMv8, or in ARMv7 with the
4227 * Virtualization Extensions.
4228 */
4229 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4230 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4231 goto undef;
4232 }
4233
4234 if (IS_USER(s) || rn == 15) {
4235 goto undef;
4236 }
4237
4238 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4239 * of registers into (r, sysm).
4240 */
4241 if (r) {
4242 /* SPSRs for other modes */
4243 switch (sysm) {
4244 case 0xe: /* SPSR_fiq */
4245 *tgtmode = ARM_CPU_MODE_FIQ;
4246 break;
4247 case 0x10: /* SPSR_irq */
4248 *tgtmode = ARM_CPU_MODE_IRQ;
4249 break;
4250 case 0x12: /* SPSR_svc */
4251 *tgtmode = ARM_CPU_MODE_SVC;
4252 break;
4253 case 0x14: /* SPSR_abt */
4254 *tgtmode = ARM_CPU_MODE_ABT;
4255 break;
4256 case 0x16: /* SPSR_und */
4257 *tgtmode = ARM_CPU_MODE_UND;
4258 break;
4259 case 0x1c: /* SPSR_mon */
4260 *tgtmode = ARM_CPU_MODE_MON;
4261 break;
4262 case 0x1e: /* SPSR_hyp */
4263 *tgtmode = ARM_CPU_MODE_HYP;
4264 break;
4265 default: /* unallocated */
4266 goto undef;
4267 }
4268 /* We arbitrarily assign SPSR a register number of 16. */
4269 *regno = 16;
4270 } else {
4271 /* general purpose registers for other modes */
4272 switch (sysm) {
4273 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4274 *tgtmode = ARM_CPU_MODE_USR;
4275 *regno = sysm + 8;
4276 break;
4277 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4278 *tgtmode = ARM_CPU_MODE_FIQ;
4279 *regno = sysm;
4280 break;
4281 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4282 *tgtmode = ARM_CPU_MODE_IRQ;
4283 *regno = sysm & 1 ? 13 : 14;
4284 break;
4285 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4286 *tgtmode = ARM_CPU_MODE_SVC;
4287 *regno = sysm & 1 ? 13 : 14;
4288 break;
4289 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4290 *tgtmode = ARM_CPU_MODE_ABT;
4291 *regno = sysm & 1 ? 13 : 14;
4292 break;
4293 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4294 *tgtmode = ARM_CPU_MODE_UND;
4295 *regno = sysm & 1 ? 13 : 14;
4296 break;
4297 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4298 *tgtmode = ARM_CPU_MODE_MON;
4299 *regno = sysm & 1 ? 13 : 14;
4300 break;
4301 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4302 *tgtmode = ARM_CPU_MODE_HYP;
4303 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4304 *regno = sysm & 1 ? 13 : 17;
4305 break;
4306 default: /* unallocated */
4307 goto undef;
4308 }
4309 }
4310
4311 /* Catch the 'accessing inaccessible register' cases we can detect
4312 * at translate time.
4313 */
4314 switch (*tgtmode) {
4315 case ARM_CPU_MODE_MON:
4316 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4317 goto undef;
4318 }
4319 if (s->current_el == 1) {
4320 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4321 * then accesses to Mon registers trap to EL3
4322 */
4323 exc_target = 3;
4324 goto undef;
4325 }
4326 break;
4327 case ARM_CPU_MODE_HYP:
4328 /*
4329 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4330 * (and so we can forbid accesses from EL2 or below). elr_hyp
4331 * can be accessed also from Hyp mode, so forbid accesses from
4332 * EL0 or EL1.
4333 */
4334 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4335 (s->current_el < 3 && *regno != 17)) {
4336 goto undef;
4337 }
4338 break;
4339 default:
4340 break;
4341 }
4342
4343 return true;
4344
4345 undef:
4346 /* If we get here then some access check did not pass */
4347 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4348 return false;
4349 }
4350
4351 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4352 {
4353 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4354 int tgtmode = 0, regno = 0;
4355
4356 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4357 return;
4358 }
4359
4360 /* Sync state because msr_banked() can raise exceptions */
4361 gen_set_condexec(s);
4362 gen_set_pc_im(s, s->pc - 4);
4363 tcg_reg = load_reg(s, rn);
4364 tcg_tgtmode = tcg_const_i32(tgtmode);
4365 tcg_regno = tcg_const_i32(regno);
4366 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4367 tcg_temp_free_i32(tcg_tgtmode);
4368 tcg_temp_free_i32(tcg_regno);
4369 tcg_temp_free_i32(tcg_reg);
4370 s->base.is_jmp = DISAS_UPDATE;
4371 }
4372
4373 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4374 {
4375 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4376 int tgtmode = 0, regno = 0;
4377
4378 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4379 return;
4380 }
4381
4382 /* Sync state because mrs_banked() can raise exceptions */
4383 gen_set_condexec(s);
4384 gen_set_pc_im(s, s->pc - 4);
4385 tcg_reg = tcg_temp_new_i32();
4386 tcg_tgtmode = tcg_const_i32(tgtmode);
4387 tcg_regno = tcg_const_i32(regno);
4388 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4389 tcg_temp_free_i32(tcg_tgtmode);
4390 tcg_temp_free_i32(tcg_regno);
4391 store_reg(s, rn, tcg_reg);
4392 s->base.is_jmp = DISAS_UPDATE;
4393 }
4394
4395 /* Store value to PC as for an exception return (ie don't
4396 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4397 * will do the masking based on the new value of the Thumb bit.
4398 */
4399 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4400 {
4401 tcg_gen_mov_i32(cpu_R[15], pc);
4402 tcg_temp_free_i32(pc);
4403 }
4404
4405 /* Generate a v6 exception return. Marks both values as dead. */
4406 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4407 {
4408 store_pc_exc_ret(s, pc);
4409 /* The cpsr_write_eret helper will mask the low bits of PC
4410 * appropriately depending on the new Thumb bit, so it must
4411 * be called after storing the new PC.
4412 */
4413 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4414 gen_io_start();
4415 }
4416 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4417 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4418 gen_io_end();
4419 }
4420 tcg_temp_free_i32(cpsr);
4421 /* Must exit loop to check un-masked IRQs */
4422 s->base.is_jmp = DISAS_EXIT;
4423 }
4424
4425 /* Generate an old-style exception return. Marks pc as dead. */
4426 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4427 {
4428 gen_rfe(s, pc, load_cpu_field(spsr));
4429 }
4430
4431 /*
4432 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4433 * only call the helper when running single threaded TCG code to ensure
4434 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4435 * just skip this instruction. Currently the SEV/SEVL instructions
4436 * which are *one* of many ways to wake the CPU from WFE are not
4437 * implemented so we can't sleep like WFI does.
4438 */
4439 static void gen_nop_hint(DisasContext *s, int val)
4440 {
4441 switch (val) {
4442 /* When running in MTTCG we don't generate jumps to the yield and
4443 * WFE helpers as it won't affect the scheduling of other vCPUs.
4444 * If we wanted to more completely model WFE/SEV so we don't busy
4445 * spin unnecessarily we would need to do something more involved.
4446 */
4447 case 1: /* yield */
4448 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4449 gen_set_pc_im(s, s->pc);
4450 s->base.is_jmp = DISAS_YIELD;
4451 }
4452 break;
4453 case 3: /* wfi */
4454 gen_set_pc_im(s, s->pc);
4455 s->base.is_jmp = DISAS_WFI;
4456 break;
4457 case 2: /* wfe */
4458 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4459 gen_set_pc_im(s, s->pc);
4460 s->base.is_jmp = DISAS_WFE;
4461 }
4462 break;
4463 case 4: /* sev */
4464 case 5: /* sevl */
4465 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4466 default: /* nop */
4467 break;
4468 }
4469 }
4470
4471 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4472
4473 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4474 {
4475 switch (size) {
4476 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4477 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4478 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4479 default: abort();
4480 }
4481 }
4482
4483 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4484 {
4485 switch (size) {
4486 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4487 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4488 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4489 default: return;
4490 }
4491 }
4492
4493 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4494 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4495 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4496 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4497 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4498
4499 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4500 switch ((size << 1) | u) { \
4501 case 0: \
4502 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4503 break; \
4504 case 1: \
4505 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4506 break; \
4507 case 2: \
4508 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4509 break; \
4510 case 3: \
4511 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4512 break; \
4513 case 4: \
4514 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4515 break; \
4516 case 5: \
4517 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4518 break; \
4519 default: return 1; \
4520 }} while (0)
4521
4522 #define GEN_NEON_INTEGER_OP(name) do { \
4523 switch ((size << 1) | u) { \
4524 case 0: \
4525 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4526 break; \
4527 case 1: \
4528 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4529 break; \
4530 case 2: \
4531 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4532 break; \
4533 case 3: \
4534 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4535 break; \
4536 case 4: \
4537 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4538 break; \
4539 case 5: \
4540 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4541 break; \
4542 default: return 1; \
4543 }} while (0)
4544
4545 static TCGv_i32 neon_load_scratch(int scratch)
4546 {
4547 TCGv_i32 tmp = tcg_temp_new_i32();
4548 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4549 return tmp;
4550 }
4551
4552 static void neon_store_scratch(int scratch, TCGv_i32 var)
4553 {
4554 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4555 tcg_temp_free_i32(var);
4556 }
4557
4558 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4559 {
4560 TCGv_i32 tmp;
4561 if (size == 1) {
4562 tmp = neon_load_reg(reg & 7, reg >> 4);
4563 if (reg & 8) {
4564 gen_neon_dup_high16(tmp);
4565 } else {
4566 gen_neon_dup_low16(tmp);
4567 }
4568 } else {
4569 tmp = neon_load_reg(reg & 15, reg >> 4);
4570 }
4571 return tmp;
4572 }
4573
4574 static int gen_neon_unzip(int rd, int rm, int size, int q)
4575 {
4576 TCGv_ptr pd, pm;
4577
4578 if (!q && size == 2) {
4579 return 1;
4580 }
4581 pd = vfp_reg_ptr(true, rd);
4582 pm = vfp_reg_ptr(true, rm);
4583 if (q) {
4584 switch (size) {
4585 case 0:
4586 gen_helper_neon_qunzip8(pd, pm);
4587 break;
4588 case 1:
4589 gen_helper_neon_qunzip16(pd, pm);
4590 break;
4591 case 2:
4592 gen_helper_neon_qunzip32(pd, pm);
4593 break;
4594 default:
4595 abort();
4596 }
4597 } else {
4598 switch (size) {
4599 case 0:
4600 gen_helper_neon_unzip8(pd, pm);
4601 break;
4602 case 1:
4603 gen_helper_neon_unzip16(pd, pm);
4604 break;
4605 default:
4606 abort();
4607 }
4608 }
4609 tcg_temp_free_ptr(pd);
4610 tcg_temp_free_ptr(pm);
4611 return 0;
4612 }
4613
4614 static int gen_neon_zip(int rd, int rm, int size, int q)
4615 {
4616 TCGv_ptr pd, pm;
4617
4618 if (!q && size == 2) {
4619 return 1;
4620 }
4621 pd = vfp_reg_ptr(true, rd);
4622 pm = vfp_reg_ptr(true, rm);
4623 if (q) {
4624 switch (size) {
4625 case 0:
4626 gen_helper_neon_qzip8(pd, pm);
4627 break;
4628 case 1:
4629 gen_helper_neon_qzip16(pd, pm);
4630 break;
4631 case 2:
4632 gen_helper_neon_qzip32(pd, pm);
4633 break;
4634 default:
4635 abort();
4636 }
4637 } else {
4638 switch (size) {
4639 case 0:
4640 gen_helper_neon_zip8(pd, pm);
4641 break;
4642 case 1:
4643 gen_helper_neon_zip16(pd, pm);
4644 break;
4645 default:
4646 abort();
4647 }
4648 }
4649 tcg_temp_free_ptr(pd);
4650 tcg_temp_free_ptr(pm);
4651 return 0;
4652 }
4653
4654 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4655 {
4656 TCGv_i32 rd, tmp;
4657
4658 rd = tcg_temp_new_i32();
4659 tmp = tcg_temp_new_i32();
4660
4661 tcg_gen_shli_i32(rd, t0, 8);
4662 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4663 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4664 tcg_gen_or_i32(rd, rd, tmp);
4665
4666 tcg_gen_shri_i32(t1, t1, 8);
4667 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4668 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4669 tcg_gen_or_i32(t1, t1, tmp);
4670 tcg_gen_mov_i32(t0, rd);
4671
4672 tcg_temp_free_i32(tmp);
4673 tcg_temp_free_i32(rd);
4674 }
4675
4676 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4677 {
4678 TCGv_i32 rd, tmp;
4679
4680 rd = tcg_temp_new_i32();
4681 tmp = tcg_temp_new_i32();
4682
4683 tcg_gen_shli_i32(rd, t0, 16);
4684 tcg_gen_andi_i32(tmp, t1, 0xffff);
4685 tcg_gen_or_i32(rd, rd, tmp);
4686 tcg_gen_shri_i32(t1, t1, 16);
4687 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4688 tcg_gen_or_i32(t1, t1, tmp);
4689 tcg_gen_mov_i32(t0, rd);
4690
4691 tcg_temp_free_i32(tmp);
4692 tcg_temp_free_i32(rd);
4693 }
4694
4695
4696 static struct {
4697 int nregs;
4698 int interleave;
4699 int spacing;
4700 } const neon_ls_element_type[11] = {
4701 {1, 4, 1},
4702 {1, 4, 2},
4703 {4, 1, 1},
4704 {2, 2, 2},
4705 {1, 3, 1},
4706 {1, 3, 2},
4707 {3, 1, 1},
4708 {1, 1, 1},
4709 {1, 2, 1},
4710 {1, 2, 2},
4711 {2, 1, 1}
4712 };
4713
4714 /* Translate a NEON load/store element instruction. Return nonzero if the
4715 instruction is invalid. */
4716 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4717 {
4718 int rd, rn, rm;
4719 int op;
4720 int nregs;
4721 int interleave;
4722 int spacing;
4723 int stride;
4724 int size;
4725 int reg;
4726 int load;
4727 int n;
4728 int vec_size;
4729 int mmu_idx;
4730 TCGMemOp endian;
4731 TCGv_i32 addr;
4732 TCGv_i32 tmp;
4733 TCGv_i32 tmp2;
4734 TCGv_i64 tmp64;
4735
4736 /* FIXME: this access check should not take precedence over UNDEF
4737 * for invalid encodings; we will generate incorrect syndrome information
4738 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4739 */
4740 if (s->fp_excp_el) {
4741 gen_exception_insn(s, 4, EXCP_UDEF,
4742 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4743 return 0;
4744 }
4745
4746 if (!s->vfp_enabled)
4747 return 1;
4748 VFP_DREG_D(rd, insn);
4749 rn = (insn >> 16) & 0xf;
4750 rm = insn & 0xf;
4751 load = (insn & (1 << 21)) != 0;
4752 endian = s->be_data;
4753 mmu_idx = get_mem_index(s);
4754 if ((insn & (1 << 23)) == 0) {
4755 /* Load store all elements. */
4756 op = (insn >> 8) & 0xf;
4757 size = (insn >> 6) & 3;
4758 if (op > 10)
4759 return 1;
4760 /* Catch UNDEF cases for bad values of align field */
4761 switch (op & 0xc) {
4762 case 4:
4763 if (((insn >> 5) & 1) == 1) {
4764 return 1;
4765 }
4766 break;
4767 case 8:
4768 if (((insn >> 4) & 3) == 3) {
4769 return 1;
4770 }
4771 break;
4772 default:
4773 break;
4774 }
4775 nregs = neon_ls_element_type[op].nregs;
4776 interleave = neon_ls_element_type[op].interleave;
4777 spacing = neon_ls_element_type[op].spacing;
4778 if (size == 3 && (interleave | spacing) != 1) {
4779 return 1;
4780 }
4781 /* For our purposes, bytes are always little-endian. */
4782 if (size == 0) {
4783 endian = MO_LE;
4784 }
4785 /* Consecutive little-endian elements from a single register
4786 * can be promoted to a larger little-endian operation.
4787 */
4788 if (interleave == 1 && endian == MO_LE) {
4789 size = 3;
4790 }
4791 tmp64 = tcg_temp_new_i64();
4792 addr = tcg_temp_new_i32();
4793 tmp2 = tcg_const_i32(1 << size);
4794 load_reg_var(s, addr, rn);
4795 for (reg = 0; reg < nregs; reg++) {
4796 for (n = 0; n < 8 >> size; n++) {
4797 int xs;
4798 for (xs = 0; xs < interleave; xs++) {
4799 int tt = rd + reg + spacing * xs;
4800
4801 if (load) {
4802 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
4803 neon_store_element64(tt, n, size, tmp64);
4804 } else {
4805 neon_load_element64(tmp64, tt, n, size);
4806 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
4807 }
4808 tcg_gen_add_i32(addr, addr, tmp2);
4809 }
4810 }
4811 }
4812 tcg_temp_free_i32(addr);
4813 tcg_temp_free_i32(tmp2);
4814 tcg_temp_free_i64(tmp64);
4815 stride = nregs * interleave * 8;
4816 } else {
4817 size = (insn >> 10) & 3;
4818 if (size == 3) {
4819 /* Load single element to all lanes. */
4820 int a = (insn >> 4) & 1;
4821 if (!load) {
4822 return 1;
4823 }
4824 size = (insn >> 6) & 3;
4825 nregs = ((insn >> 8) & 3) + 1;
4826
4827 if (size == 3) {
4828 if (nregs != 4 || a == 0) {
4829 return 1;
4830 }
4831 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4832 size = 2;
4833 }
4834 if (nregs == 1 && a == 1 && size == 0) {
4835 return 1;
4836 }
4837 if (nregs == 3 && a == 1) {
4838 return 1;
4839 }
4840 addr = tcg_temp_new_i32();
4841 load_reg_var(s, addr, rn);
4842
4843 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4844 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4845 */
4846 stride = (insn & (1 << 5)) ? 2 : 1;
4847 vec_size = nregs == 1 ? stride * 8 : 8;
4848
4849 tmp = tcg_temp_new_i32();
4850 for (reg = 0; reg < nregs; reg++) {
4851 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4852 s->be_data | size);
4853 if ((rd & 1) && vec_size == 16) {
4854 /* We cannot write 16 bytes at once because the
4855 * destination is unaligned.
4856 */
4857 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4858 8, 8, tmp);
4859 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
4860 neon_reg_offset(rd, 0), 8, 8);
4861 } else {
4862 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4863 vec_size, vec_size, tmp);
4864 }
4865 tcg_gen_addi_i32(addr, addr, 1 << size);
4866 rd += stride;
4867 }
4868 tcg_temp_free_i32(tmp);
4869 tcg_temp_free_i32(addr);
4870 stride = (1 << size) * nregs;
4871 } else {
4872 /* Single element. */
4873 int idx = (insn >> 4) & 0xf;
4874 int reg_idx;
4875 switch (size) {
4876 case 0:
4877 reg_idx = (insn >> 5) & 7;
4878 stride = 1;
4879 break;
4880 case 1:
4881 reg_idx = (insn >> 6) & 3;
4882 stride = (insn & (1 << 5)) ? 2 : 1;
4883 break;
4884 case 2:
4885 reg_idx = (insn >> 7) & 1;
4886 stride = (insn & (1 << 6)) ? 2 : 1;
4887 break;
4888 default:
4889 abort();
4890 }
4891 nregs = ((insn >> 8) & 3) + 1;
4892 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4893 switch (nregs) {
4894 case 1:
4895 if (((idx & (1 << size)) != 0) ||
4896 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4897 return 1;
4898 }
4899 break;
4900 case 3:
4901 if ((idx & 1) != 0) {
4902 return 1;
4903 }
4904 /* fall through */
4905 case 2:
4906 if (size == 2 && (idx & 2) != 0) {
4907 return 1;
4908 }
4909 break;
4910 case 4:
4911 if ((size == 2) && ((idx & 3) == 3)) {
4912 return 1;
4913 }
4914 break;
4915 default:
4916 abort();
4917 }
4918 if ((rd + stride * (nregs - 1)) > 31) {
4919 /* Attempts to write off the end of the register file
4920 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4921 * the neon_load_reg() would write off the end of the array.
4922 */
4923 return 1;
4924 }
4925 tmp = tcg_temp_new_i32();
4926 addr = tcg_temp_new_i32();
4927 load_reg_var(s, addr, rn);
4928 for (reg = 0; reg < nregs; reg++) {
4929 if (load) {
4930 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4931 s->be_data | size);
4932 neon_store_element(rd, reg_idx, size, tmp);
4933 } else { /* Store */
4934 neon_load_element(tmp, rd, reg_idx, size);
4935 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
4936 s->be_data | size);
4937 }
4938 rd += stride;
4939 tcg_gen_addi_i32(addr, addr, 1 << size);
4940 }
4941 tcg_temp_free_i32(addr);
4942 tcg_temp_free_i32(tmp);
4943 stride = nregs * (1 << size);
4944 }
4945 }
4946 if (rm != 15) {
4947 TCGv_i32 base;
4948
4949 base = load_reg(s, rn);
4950 if (rm == 13) {
4951 tcg_gen_addi_i32(base, base, stride);
4952 } else {
4953 TCGv_i32 index;
4954 index = load_reg(s, rm);
4955 tcg_gen_add_i32(base, base, index);
4956 tcg_temp_free_i32(index);
4957 }
4958 store_reg(s, rn, base);
4959 }
4960 return 0;
4961 }
4962
4963 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4964 {
4965 switch (size) {
4966 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4967 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4968 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4969 default: abort();
4970 }
4971 }
4972
4973 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4974 {
4975 switch (size) {
4976 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4977 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4978 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4979 default: abort();
4980 }
4981 }
4982
4983 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4984 {
4985 switch (size) {
4986 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4987 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4988 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4989 default: abort();
4990 }
4991 }
4992
4993 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4994 {
4995 switch (size) {
4996 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4997 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4998 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4999 default: abort();
5000 }
5001 }
5002
5003 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5004 int q, int u)
5005 {
5006 if (q) {
5007 if (u) {
5008 switch (size) {
5009 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5010 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5011 default: abort();
5012 }
5013 } else {
5014 switch (size) {
5015 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5016 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5017 default: abort();
5018 }
5019 }
5020 } else {
5021 if (u) {
5022 switch (size) {
5023 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5024 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5025 default: abort();
5026 }
5027 } else {
5028 switch (size) {
5029 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5030 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5031 default: abort();
5032 }
5033 }
5034 }
5035 }
5036
5037 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5038 {
5039 if (u) {
5040 switch (size) {
5041 case 0: gen_helper_neon_widen_u8(dest, src); break;
5042 case 1: gen_helper_neon_widen_u16(dest, src); break;
5043 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5044 default: abort();
5045 }
5046 } else {
5047 switch (size) {
5048 case 0: gen_helper_neon_widen_s8(dest, src); break;
5049 case 1: gen_helper_neon_widen_s16(dest, src); break;
5050 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5051 default: abort();
5052 }
5053 }
5054 tcg_temp_free_i32(src);
5055 }
5056
5057 static inline void gen_neon_addl(int size)
5058 {
5059 switch (size) {
5060 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5061 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5062 case 2: tcg_gen_add_i64(CPU_V001); break;
5063 default: abort();
5064 }
5065 }
5066
5067 static inline void gen_neon_subl(int size)
5068 {
5069 switch (size) {
5070 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5071 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5072 case 2: tcg_gen_sub_i64(CPU_V001); break;
5073 default: abort();
5074 }
5075 }
5076
5077 static inline void gen_neon_negl(TCGv_i64 var, int size)
5078 {
5079 switch (size) {
5080 case 0: gen_helper_neon_negl_u16(var, var); break;
5081 case 1: gen_helper_neon_negl_u32(var, var); break;
5082 case 2:
5083 tcg_gen_neg_i64(var, var);
5084 break;
5085 default: abort();
5086 }
5087 }
5088
5089 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5090 {
5091 switch (size) {
5092 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5093 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5094 default: abort();
5095 }
5096 }
5097
5098 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5099 int size, int u)
5100 {
5101 TCGv_i64 tmp;
5102
5103 switch ((size << 1) | u) {
5104 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5105 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5106 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5107 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5108 case 4:
5109 tmp = gen_muls_i64_i32(a, b);
5110 tcg_gen_mov_i64(dest, tmp);
5111 tcg_temp_free_i64(tmp);
5112 break;
5113 case 5:
5114 tmp = gen_mulu_i64_i32(a, b);
5115 tcg_gen_mov_i64(dest, tmp);
5116 tcg_temp_free_i64(tmp);
5117 break;
5118 default: abort();
5119 }
5120
5121 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5122 Don't forget to clean them now. */
5123 if (size < 2) {
5124 tcg_temp_free_i32(a);
5125 tcg_temp_free_i32(b);
5126 }
5127 }
5128
5129 static void gen_neon_narrow_op(int op, int u, int size,
5130 TCGv_i32 dest, TCGv_i64 src)
5131 {
5132 if (op) {
5133 if (u) {
5134 gen_neon_unarrow_sats(size, dest, src);
5135 } else {
5136 gen_neon_narrow(size, dest, src);
5137 }
5138 } else {
5139 if (u) {
5140 gen_neon_narrow_satu(size, dest, src);
5141 } else {
5142 gen_neon_narrow_sats(size, dest, src);
5143 }
5144 }
5145 }
5146
5147 /* Symbolic constants for op fields for Neon 3-register same-length.
5148 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5149 * table A7-9.
5150 */
5151 #define NEON_3R_VHADD 0
5152 #define NEON_3R_VQADD 1
5153 #define NEON_3R_VRHADD 2
5154 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5155 #define NEON_3R_VHSUB 4
5156 #define NEON_3R_VQSUB 5
5157 #define NEON_3R_VCGT 6
5158 #define NEON_3R_VCGE 7
5159 #define NEON_3R_VSHL 8
5160 #define NEON_3R_VQSHL 9
5161 #define NEON_3R_VRSHL 10
5162 #define NEON_3R_VQRSHL 11
5163 #define NEON_3R_VMAX 12
5164 #define NEON_3R_VMIN 13
5165 #define NEON_3R_VABD 14
5166 #define NEON_3R_VABA 15
5167 #define NEON_3R_VADD_VSUB 16
5168 #define NEON_3R_VTST_VCEQ 17
5169 #define NEON_3R_VML 18 /* VMLA, VMLS */
5170 #define NEON_3R_VMUL 19
5171 #define NEON_3R_VPMAX 20
5172 #define NEON_3R_VPMIN 21
5173 #define NEON_3R_VQDMULH_VQRDMULH 22
5174 #define NEON_3R_VPADD_VQRDMLAH 23
5175 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5176 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5177 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5178 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5179 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5180 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5181 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5182 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5183
5184 static const uint8_t neon_3r_sizes[] = {
5185 [NEON_3R_VHADD] = 0x7,
5186 [NEON_3R_VQADD] = 0xf,
5187 [NEON_3R_VRHADD] = 0x7,
5188 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5189 [NEON_3R_VHSUB] = 0x7,
5190 [NEON_3R_VQSUB] = 0xf,
5191 [NEON_3R_VCGT] = 0x7,
5192 [NEON_3R_VCGE] = 0x7,
5193 [NEON_3R_VSHL] = 0xf,
5194 [NEON_3R_VQSHL] = 0xf,
5195 [NEON_3R_VRSHL] = 0xf,
5196 [NEON_3R_VQRSHL] = 0xf,
5197 [NEON_3R_VMAX] = 0x7,
5198 [NEON_3R_VMIN] = 0x7,
5199 [NEON_3R_VABD] = 0x7,
5200 [NEON_3R_VABA] = 0x7,
5201 [NEON_3R_VADD_VSUB] = 0xf,
5202 [NEON_3R_VTST_VCEQ] = 0x7,
5203 [NEON_3R_VML] = 0x7,
5204 [NEON_3R_VMUL] = 0x7,
5205 [NEON_3R_VPMAX] = 0x7,
5206 [NEON_3R_VPMIN] = 0x7,
5207 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5208 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5209 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5210 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5211 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5212 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5213 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5214 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5215 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5216 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5217 };
5218
5219 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5220 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5221 * table A7-13.
5222 */
5223 #define NEON_2RM_VREV64 0
5224 #define NEON_2RM_VREV32 1
5225 #define NEON_2RM_VREV16 2
5226 #define NEON_2RM_VPADDL 4
5227 #define NEON_2RM_VPADDL_U 5
5228 #define NEON_2RM_AESE 6 /* Includes AESD */
5229 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5230 #define NEON_2RM_VCLS 8
5231 #define NEON_2RM_VCLZ 9
5232 #define NEON_2RM_VCNT 10
5233 #define NEON_2RM_VMVN 11
5234 #define NEON_2RM_VPADAL 12
5235 #define NEON_2RM_VPADAL_U 13
5236 #define NEON_2RM_VQABS 14
5237 #define NEON_2RM_VQNEG 15
5238 #define NEON_2RM_VCGT0 16
5239 #define NEON_2RM_VCGE0 17
5240 #define NEON_2RM_VCEQ0 18
5241 #define NEON_2RM_VCLE0 19
5242 #define NEON_2RM_VCLT0 20
5243 #define NEON_2RM_SHA1H 21
5244 #define NEON_2RM_VABS 22
5245 #define NEON_2RM_VNEG 23
5246 #define NEON_2RM_VCGT0_F 24
5247 #define NEON_2RM_VCGE0_F 25
5248 #define NEON_2RM_VCEQ0_F 26
5249 #define NEON_2RM_VCLE0_F 27
5250 #define NEON_2RM_VCLT0_F 28
5251 #define NEON_2RM_VABS_F 30
5252 #define NEON_2RM_VNEG_F 31
5253 #define NEON_2RM_VSWP 32
5254 #define NEON_2RM_VTRN 33
5255 #define NEON_2RM_VUZP 34
5256 #define NEON_2RM_VZIP 35
5257 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5258 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5259 #define NEON_2RM_VSHLL 38
5260 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5261 #define NEON_2RM_VRINTN 40
5262 #define NEON_2RM_VRINTX 41
5263 #define NEON_2RM_VRINTA 42
5264 #define NEON_2RM_VRINTZ 43
5265 #define NEON_2RM_VCVT_F16_F32 44
5266 #define NEON_2RM_VRINTM 45
5267 #define NEON_2RM_VCVT_F32_F16 46
5268 #define NEON_2RM_VRINTP 47
5269 #define NEON_2RM_VCVTAU 48
5270 #define NEON_2RM_VCVTAS 49
5271 #define NEON_2RM_VCVTNU 50
5272 #define NEON_2RM_VCVTNS 51
5273 #define NEON_2RM_VCVTPU 52
5274 #define NEON_2RM_VCVTPS 53
5275 #define NEON_2RM_VCVTMU 54
5276 #define NEON_2RM_VCVTMS 55
5277 #define NEON_2RM_VRECPE 56
5278 #define NEON_2RM_VRSQRTE 57
5279 #define NEON_2RM_VRECPE_F 58
5280 #define NEON_2RM_VRSQRTE_F 59
5281 #define NEON_2RM_VCVT_FS 60
5282 #define NEON_2RM_VCVT_FU 61
5283 #define NEON_2RM_VCVT_SF 62
5284 #define NEON_2RM_VCVT_UF 63
5285
5286 static int neon_2rm_is_float_op(int op)
5287 {
5288 /* Return true if this neon 2reg-misc op is float-to-float */
5289 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5290 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5291 op == NEON_2RM_VRINTM ||
5292 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5293 op >= NEON_2RM_VRECPE_F);
5294 }
5295
5296 static bool neon_2rm_is_v8_op(int op)
5297 {
5298 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5299 switch (op) {
5300 case NEON_2RM_VRINTN:
5301 case NEON_2RM_VRINTA:
5302 case NEON_2RM_VRINTM:
5303 case NEON_2RM_VRINTP:
5304 case NEON_2RM_VRINTZ:
5305 case NEON_2RM_VRINTX:
5306 case NEON_2RM_VCVTAU:
5307 case NEON_2RM_VCVTAS:
5308 case NEON_2RM_VCVTNU:
5309 case NEON_2RM_VCVTNS:
5310 case NEON_2RM_VCVTPU:
5311 case NEON_2RM_VCVTPS:
5312 case NEON_2RM_VCVTMU:
5313 case NEON_2RM_VCVTMS:
5314 return true;
5315 default:
5316 return false;
5317 }
5318 }
5319
5320 /* Each entry in this array has bit n set if the insn allows
5321 * size value n (otherwise it will UNDEF). Since unallocated
5322 * op values will have no bits set they always UNDEF.
5323 */
5324 static const uint8_t neon_2rm_sizes[] = {
5325 [NEON_2RM_VREV64] = 0x7,
5326 [NEON_2RM_VREV32] = 0x3,
5327 [NEON_2RM_VREV16] = 0x1,
5328 [NEON_2RM_VPADDL] = 0x7,
5329 [NEON_2RM_VPADDL_U] = 0x7,
5330 [NEON_2RM_AESE] = 0x1,
5331 [NEON_2RM_AESMC] = 0x1,
5332 [NEON_2RM_VCLS] = 0x7,
5333 [NEON_2RM_VCLZ] = 0x7,
5334 [NEON_2RM_VCNT] = 0x1,
5335 [NEON_2RM_VMVN] = 0x1,
5336 [NEON_2RM_VPADAL] = 0x7,
5337 [NEON_2RM_VPADAL_U] = 0x7,
5338 [NEON_2RM_VQABS] = 0x7,
5339 [NEON_2RM_VQNEG] = 0x7,
5340 [NEON_2RM_VCGT0] = 0x7,
5341 [NEON_2RM_VCGE0] = 0x7,
5342 [NEON_2RM_VCEQ0] = 0x7,
5343 [NEON_2RM_VCLE0] = 0x7,
5344 [NEON_2RM_VCLT0] = 0x7,
5345 [NEON_2RM_SHA1H] = 0x4,
5346 [NEON_2RM_VABS] = 0x7,
5347 [NEON_2RM_VNEG] = 0x7,
5348 [NEON_2RM_VCGT0_F] = 0x4,
5349 [NEON_2RM_VCGE0_F] = 0x4,
5350 [NEON_2RM_VCEQ0_F] = 0x4,
5351 [NEON_2RM_VCLE0_F] = 0x4,
5352 [NEON_2RM_VCLT0_F] = 0x4,
5353 [NEON_2RM_VABS_F] = 0x4,
5354 [NEON_2RM_VNEG_F] = 0x4,
5355 [NEON_2RM_VSWP] = 0x1,
5356 [NEON_2RM_VTRN] = 0x7,
5357 [NEON_2RM_VUZP] = 0x7,
5358 [NEON_2RM_VZIP] = 0x7,
5359 [NEON_2RM_VMOVN] = 0x7,
5360 [NEON_2RM_VQMOVN] = 0x7,
5361 [NEON_2RM_VSHLL] = 0x7,
5362 [NEON_2RM_SHA1SU1] = 0x4,
5363 [NEON_2RM_VRINTN] = 0x4,
5364 [NEON_2RM_VRINTX] = 0x4,
5365 [NEON_2RM_VRINTA] = 0x4,
5366 [NEON_2RM_VRINTZ] = 0x4,
5367 [NEON_2RM_VCVT_F16_F32] = 0x2,
5368 [NEON_2RM_VRINTM] = 0x4,
5369 [NEON_2RM_VCVT_F32_F16] = 0x2,
5370 [NEON_2RM_VRINTP] = 0x4,
5371 [NEON_2RM_VCVTAU] = 0x4,
5372 [NEON_2RM_VCVTAS] = 0x4,
5373 [NEON_2RM_VCVTNU] = 0x4,
5374 [NEON_2RM_VCVTNS] = 0x4,
5375 [NEON_2RM_VCVTPU] = 0x4,
5376 [NEON_2RM_VCVTPS] = 0x4,
5377 [NEON_2RM_VCVTMU] = 0x4,
5378 [NEON_2RM_VCVTMS] = 0x4,
5379 [NEON_2RM_VRECPE] = 0x4,
5380 [NEON_2RM_VRSQRTE] = 0x4,
5381 [NEON_2RM_VRECPE_F] = 0x4,
5382 [NEON_2RM_VRSQRTE_F] = 0x4,
5383 [NEON_2RM_VCVT_FS] = 0x4,
5384 [NEON_2RM_VCVT_FU] = 0x4,
5385 [NEON_2RM_VCVT_SF] = 0x4,
5386 [NEON_2RM_VCVT_UF] = 0x4,
5387 };
5388
5389
5390 /* Expand v8.1 simd helper. */
5391 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5392 int q, int rd, int rn, int rm)
5393 {
5394 if (dc_isar_feature(aa32_rdm, s)) {
5395 int opr_sz = (1 + q) * 8;
5396 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5397 vfp_reg_offset(1, rn),
5398 vfp_reg_offset(1, rm), cpu_env,
5399 opr_sz, opr_sz, 0, fn);
5400 return 0;
5401 }
5402 return 1;
5403 }
5404
5405 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5406 {
5407 tcg_gen_vec_sar8i_i64(a, a, shift);
5408 tcg_gen_vec_add8_i64(d, d, a);
5409 }
5410
5411 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5412 {
5413 tcg_gen_vec_sar16i_i64(a, a, shift);
5414 tcg_gen_vec_add16_i64(d, d, a);
5415 }
5416
5417 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5418 {
5419 tcg_gen_sari_i32(a, a, shift);
5420 tcg_gen_add_i32(d, d, a);
5421 }
5422
5423 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5424 {
5425 tcg_gen_sari_i64(a, a, shift);
5426 tcg_gen_add_i64(d, d, a);
5427 }
5428
5429 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5430 {
5431 tcg_gen_sari_vec(vece, a, a, sh);
5432 tcg_gen_add_vec(vece, d, d, a);
5433 }
5434
5435 static const TCGOpcode vecop_list_ssra[] = {
5436 INDEX_op_sari_vec, INDEX_op_add_vec, 0
5437 };
5438
5439 const GVecGen2i ssra_op[4] = {
5440 { .fni8 = gen_ssra8_i64,
5441 .fniv = gen_ssra_vec,
5442 .load_dest = true,
5443 .opt_opc = vecop_list_ssra,
5444 .vece = MO_8 },
5445 { .fni8 = gen_ssra16_i64,
5446 .fniv = gen_ssra_vec,
5447 .load_dest = true,
5448 .opt_opc = vecop_list_ssra,
5449 .vece = MO_16 },
5450 { .fni4 = gen_ssra32_i32,
5451 .fniv = gen_ssra_vec,
5452 .load_dest = true,
5453 .opt_opc = vecop_list_ssra,
5454 .vece = MO_32 },
5455 { .fni8 = gen_ssra64_i64,
5456 .fniv = gen_ssra_vec,
5457 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5458 .opt_opc = vecop_list_ssra,
5459 .load_dest = true,
5460 .vece = MO_64 },
5461 };
5462
5463 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5464 {
5465 tcg_gen_vec_shr8i_i64(a, a, shift);
5466 tcg_gen_vec_add8_i64(d, d, a);
5467 }
5468
5469 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5470 {
5471 tcg_gen_vec_shr16i_i64(a, a, shift);
5472 tcg_gen_vec_add16_i64(d, d, a);
5473 }
5474
5475 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5476 {
5477 tcg_gen_shri_i32(a, a, shift);
5478 tcg_gen_add_i32(d, d, a);
5479 }
5480
5481 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5482 {
5483 tcg_gen_shri_i64(a, a, shift);
5484 tcg_gen_add_i64(d, d, a);
5485 }
5486
5487 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5488 {
5489 tcg_gen_shri_vec(vece, a, a, sh);
5490 tcg_gen_add_vec(vece, d, d, a);
5491 }
5492
5493 static const TCGOpcode vecop_list_usra[] = {
5494 INDEX_op_shri_vec, INDEX_op_add_vec, 0
5495 };
5496
5497 const GVecGen2i usra_op[4] = {
5498 { .fni8 = gen_usra8_i64,
5499 .fniv = gen_usra_vec,
5500 .load_dest = true,
5501 .opt_opc = vecop_list_usra,
5502 .vece = MO_8, },
5503 { .fni8 = gen_usra16_i64,
5504 .fniv = gen_usra_vec,
5505 .load_dest = true,
5506 .opt_opc = vecop_list_usra,
5507 .vece = MO_16, },
5508 { .fni4 = gen_usra32_i32,
5509 .fniv = gen_usra_vec,
5510 .load_dest = true,
5511 .opt_opc = vecop_list_usra,
5512 .vece = MO_32, },
5513 { .fni8 = gen_usra64_i64,
5514 .fniv = gen_usra_vec,
5515 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5516 .load_dest = true,
5517 .opt_opc = vecop_list_usra,
5518 .vece = MO_64, },
5519 };
5520
5521 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5522 {
5523 uint64_t mask = dup_const(MO_8, 0xff >> shift);
5524 TCGv_i64 t = tcg_temp_new_i64();
5525
5526 tcg_gen_shri_i64(t, a, shift);
5527 tcg_gen_andi_i64(t, t, mask);
5528 tcg_gen_andi_i64(d, d, ~mask);
5529 tcg_gen_or_i64(d, d, t);
5530 tcg_temp_free_i64(t);
5531 }
5532
5533 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5534 {
5535 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5536 TCGv_i64 t = tcg_temp_new_i64();
5537
5538 tcg_gen_shri_i64(t, a, shift);
5539 tcg_gen_andi_i64(t, t, mask);
5540 tcg_gen_andi_i64(d, d, ~mask);
5541 tcg_gen_or_i64(d, d, t);
5542 tcg_temp_free_i64(t);
5543 }
5544
5545 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5546 {
5547 tcg_gen_shri_i32(a, a, shift);
5548 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5549 }
5550
5551 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5552 {
5553 tcg_gen_shri_i64(a, a, shift);
5554 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5555 }
5556
5557 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5558 {
5559 if (sh == 0) {
5560 tcg_gen_mov_vec(d, a);
5561 } else {
5562 TCGv_vec t = tcg_temp_new_vec_matching(d);
5563 TCGv_vec m = tcg_temp_new_vec_matching(d);
5564
5565 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5566 tcg_gen_shri_vec(vece, t, a, sh);
5567 tcg_gen_and_vec(vece, d, d, m);
5568 tcg_gen_or_vec(vece, d, d, t);
5569
5570 tcg_temp_free_vec(t);
5571 tcg_temp_free_vec(m);
5572 }
5573 }
5574
5575 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
5576
5577 const GVecGen2i sri_op[4] = {
5578 { .fni8 = gen_shr8_ins_i64,
5579 .fniv = gen_shr_ins_vec,
5580 .load_dest = true,
5581 .opt_opc = vecop_list_sri,
5582 .vece = MO_8 },
5583 { .fni8 = gen_shr16_ins_i64,
5584 .fniv = gen_shr_ins_vec,
5585 .load_dest = true,
5586 .opt_opc = vecop_list_sri,
5587 .vece = MO_16 },
5588 { .fni4 = gen_shr32_ins_i32,
5589 .fniv = gen_shr_ins_vec,
5590 .load_dest = true,
5591 .opt_opc = vecop_list_sri,
5592 .vece = MO_32 },
5593 { .fni8 = gen_shr64_ins_i64,
5594 .fniv = gen_shr_ins_vec,
5595 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5596 .load_dest = true,
5597 .opt_opc = vecop_list_sri,
5598 .vece = MO_64 },
5599 };
5600
5601 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5602 {
5603 uint64_t mask = dup_const(MO_8, 0xff << shift);
5604 TCGv_i64 t = tcg_temp_new_i64();
5605
5606 tcg_gen_shli_i64(t, a, shift);
5607 tcg_gen_andi_i64(t, t, mask);
5608 tcg_gen_andi_i64(d, d, ~mask);
5609 tcg_gen_or_i64(d, d, t);
5610 tcg_temp_free_i64(t);
5611 }
5612
5613 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5614 {
5615 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5616 TCGv_i64 t = tcg_temp_new_i64();
5617
5618 tcg_gen_shli_i64(t, a, shift);
5619 tcg_gen_andi_i64(t, t, mask);
5620 tcg_gen_andi_i64(d, d, ~mask);
5621 tcg_gen_or_i64(d, d, t);
5622 tcg_temp_free_i64(t);
5623 }
5624
5625 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5626 {
5627 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5628 }
5629
5630 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5631 {
5632 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5633 }
5634
5635 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5636 {
5637 if (sh == 0) {
5638 tcg_gen_mov_vec(d, a);
5639 } else {
5640 TCGv_vec t = tcg_temp_new_vec_matching(d);
5641 TCGv_vec m = tcg_temp_new_vec_matching(d);
5642
5643 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5644 tcg_gen_shli_vec(vece, t, a, sh);
5645 tcg_gen_and_vec(vece, d, d, m);
5646 tcg_gen_or_vec(vece, d, d, t);
5647
5648 tcg_temp_free_vec(t);
5649 tcg_temp_free_vec(m);
5650 }
5651 }
5652
5653 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
5654
5655 const GVecGen2i sli_op[4] = {
5656 { .fni8 = gen_shl8_ins_i64,
5657 .fniv = gen_shl_ins_vec,
5658 .load_dest = true,
5659 .opt_opc = vecop_list_sli,
5660 .vece = MO_8 },
5661 { .fni8 = gen_shl16_ins_i64,
5662 .fniv = gen_shl_ins_vec,
5663 .load_dest = true,
5664 .opt_opc = vecop_list_sli,
5665 .vece = MO_16 },
5666 { .fni4 = gen_shl32_ins_i32,
5667 .fniv = gen_shl_ins_vec,
5668 .load_dest = true,
5669 .opt_opc = vecop_list_sli,
5670 .vece = MO_32 },
5671 { .fni8 = gen_shl64_ins_i64,
5672 .fniv = gen_shl_ins_vec,
5673 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5674 .load_dest = true,
5675 .opt_opc = vecop_list_sli,
5676 .vece = MO_64 },
5677 };
5678
5679 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5680 {
5681 gen_helper_neon_mul_u8(a, a, b);
5682 gen_helper_neon_add_u8(d, d, a);
5683 }
5684
5685 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5686 {
5687 gen_helper_neon_mul_u8(a, a, b);
5688 gen_helper_neon_sub_u8(d, d, a);
5689 }
5690
5691 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5692 {
5693 gen_helper_neon_mul_u16(a, a, b);
5694 gen_helper_neon_add_u16(d, d, a);
5695 }
5696
5697 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5698 {
5699 gen_helper_neon_mul_u16(a, a, b);
5700 gen_helper_neon_sub_u16(d, d, a);
5701 }
5702
5703 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5704 {
5705 tcg_gen_mul_i32(a, a, b);
5706 tcg_gen_add_i32(d, d, a);
5707 }
5708
5709 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5710 {
5711 tcg_gen_mul_i32(a, a, b);
5712 tcg_gen_sub_i32(d, d, a);
5713 }
5714
5715 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5716 {
5717 tcg_gen_mul_i64(a, a, b);
5718 tcg_gen_add_i64(d, d, a);
5719 }
5720
5721 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5722 {
5723 tcg_gen_mul_i64(a, a, b);
5724 tcg_gen_sub_i64(d, d, a);
5725 }
5726
5727 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5728 {
5729 tcg_gen_mul_vec(vece, a, a, b);
5730 tcg_gen_add_vec(vece, d, d, a);
5731 }
5732
5733 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5734 {
5735 tcg_gen_mul_vec(vece, a, a, b);
5736 tcg_gen_sub_vec(vece, d, d, a);
5737 }
5738
5739 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5740 * these tables are shared with AArch64 which does support them.
5741 */
5742
5743 static const TCGOpcode vecop_list_mla[] = {
5744 INDEX_op_mul_vec, INDEX_op_add_vec, 0
5745 };
5746
5747 static const TCGOpcode vecop_list_mls[] = {
5748 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
5749 };
5750
5751 const GVecGen3 mla_op[4] = {
5752 { .fni4 = gen_mla8_i32,
5753 .fniv = gen_mla_vec,
5754 .load_dest = true,
5755 .opt_opc = vecop_list_mla,
5756 .vece = MO_8 },
5757 { .fni4 = gen_mla16_i32,
5758 .fniv = gen_mla_vec,
5759 .load_dest = true,
5760 .opt_opc = vecop_list_mla,
5761 .vece = MO_16 },
5762 { .fni4 = gen_mla32_i32,
5763 .fniv = gen_mla_vec,
5764 .load_dest = true,
5765 .opt_opc = vecop_list_mla,
5766 .vece = MO_32 },
5767 { .fni8 = gen_mla64_i64,
5768 .fniv = gen_mla_vec,
5769 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5770 .load_dest = true,
5771 .opt_opc = vecop_list_mla,
5772 .vece = MO_64 },
5773 };
5774
5775 const GVecGen3 mls_op[4] = {
5776 { .fni4 = gen_mls8_i32,
5777 .fniv = gen_mls_vec,
5778 .load_dest = true,
5779 .opt_opc = vecop_list_mls,
5780 .vece = MO_8 },
5781 { .fni4 = gen_mls16_i32,
5782 .fniv = gen_mls_vec,
5783 .load_dest = true,
5784 .opt_opc = vecop_list_mls,
5785 .vece = MO_16 },
5786 { .fni4 = gen_mls32_i32,
5787 .fniv = gen_mls_vec,
5788 .load_dest = true,
5789 .opt_opc = vecop_list_mls,
5790 .vece = MO_32 },
5791 { .fni8 = gen_mls64_i64,
5792 .fniv = gen_mls_vec,
5793 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5794 .load_dest = true,
5795 .opt_opc = vecop_list_mls,
5796 .vece = MO_64 },
5797 };
5798
5799 /* CMTST : test is "if (X & Y != 0)". */
5800 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5801 {
5802 tcg_gen_and_i32(d, a, b);
5803 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
5804 tcg_gen_neg_i32(d, d);
5805 }
5806
5807 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5808 {
5809 tcg_gen_and_i64(d, a, b);
5810 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
5811 tcg_gen_neg_i64(d, d);
5812 }
5813
5814 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5815 {
5816 tcg_gen_and_vec(vece, d, a, b);
5817 tcg_gen_dupi_vec(vece, a, 0);
5818 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
5819 }
5820
5821 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
5822
5823 const GVecGen3 cmtst_op[4] = {
5824 { .fni4 = gen_helper_neon_tst_u8,
5825 .fniv = gen_cmtst_vec,
5826 .opt_opc = vecop_list_cmtst,
5827 .vece = MO_8 },
5828 { .fni4 = gen_helper_neon_tst_u16,
5829 .fniv = gen_cmtst_vec,
5830 .opt_opc = vecop_list_cmtst,
5831 .vece = MO_16 },
5832 { .fni4 = gen_cmtst_i32,
5833 .fniv = gen_cmtst_vec,
5834 .opt_opc = vecop_list_cmtst,
5835 .vece = MO_32 },
5836 { .fni8 = gen_cmtst_i64,
5837 .fniv = gen_cmtst_vec,
5838 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5839 .opt_opc = vecop_list_cmtst,
5840 .vece = MO_64 },
5841 };
5842
5843 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5844 TCGv_vec a, TCGv_vec b)
5845 {
5846 TCGv_vec x = tcg_temp_new_vec_matching(t);
5847 tcg_gen_add_vec(vece, x, a, b);
5848 tcg_gen_usadd_vec(vece, t, a, b);
5849 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5850 tcg_gen_or_vec(vece, sat, sat, x);
5851 tcg_temp_free_vec(x);
5852 }
5853
5854 static const TCGOpcode vecop_list_uqadd[] = {
5855 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5856 };
5857
5858 const GVecGen4 uqadd_op[4] = {
5859 { .fniv = gen_uqadd_vec,
5860 .fno = gen_helper_gvec_uqadd_b,
5861 .write_aofs = true,
5862 .opt_opc = vecop_list_uqadd,
5863 .vece = MO_8 },
5864 { .fniv = gen_uqadd_vec,
5865 .fno = gen_helper_gvec_uqadd_h,
5866 .write_aofs = true,
5867 .opt_opc = vecop_list_uqadd,
5868 .vece = MO_16 },
5869 { .fniv = gen_uqadd_vec,
5870 .fno = gen_helper_gvec_uqadd_s,
5871 .write_aofs = true,
5872 .opt_opc = vecop_list_uqadd,
5873 .vece = MO_32 },
5874 { .fniv = gen_uqadd_vec,
5875 .fno = gen_helper_gvec_uqadd_d,
5876 .write_aofs = true,
5877 .opt_opc = vecop_list_uqadd,
5878 .vece = MO_64 },
5879 };
5880
5881 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5882 TCGv_vec a, TCGv_vec b)
5883 {
5884 TCGv_vec x = tcg_temp_new_vec_matching(t);
5885 tcg_gen_add_vec(vece, x, a, b);
5886 tcg_gen_ssadd_vec(vece, t, a, b);
5887 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5888 tcg_gen_or_vec(vece, sat, sat, x);
5889 tcg_temp_free_vec(x);
5890 }
5891
5892 static const TCGOpcode vecop_list_sqadd[] = {
5893 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5894 };
5895
5896 const GVecGen4 sqadd_op[4] = {
5897 { .fniv = gen_sqadd_vec,
5898 .fno = gen_helper_gvec_sqadd_b,
5899 .opt_opc = vecop_list_sqadd,
5900 .write_aofs = true,
5901 .vece = MO_8 },
5902 { .fniv = gen_sqadd_vec,
5903 .fno = gen_helper_gvec_sqadd_h,
5904 .opt_opc = vecop_list_sqadd,
5905 .write_aofs = true,
5906 .vece = MO_16 },
5907 { .fniv = gen_sqadd_vec,
5908 .fno = gen_helper_gvec_sqadd_s,
5909 .opt_opc = vecop_list_sqadd,
5910 .write_aofs = true,
5911 .vece = MO_32 },
5912 { .fniv = gen_sqadd_vec,
5913 .fno = gen_helper_gvec_sqadd_d,
5914 .opt_opc = vecop_list_sqadd,
5915 .write_aofs = true,
5916 .vece = MO_64 },
5917 };
5918
5919 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5920 TCGv_vec a, TCGv_vec b)
5921 {
5922 TCGv_vec x = tcg_temp_new_vec_matching(t);
5923 tcg_gen_sub_vec(vece, x, a, b);
5924 tcg_gen_ussub_vec(vece, t, a, b);
5925 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5926 tcg_gen_or_vec(vece, sat, sat, x);
5927 tcg_temp_free_vec(x);
5928 }
5929
5930 static const TCGOpcode vecop_list_uqsub[] = {
5931 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5932 };
5933
5934 const GVecGen4 uqsub_op[4] = {
5935 { .fniv = gen_uqsub_vec,
5936 .fno = gen_helper_gvec_uqsub_b,
5937 .opt_opc = vecop_list_uqsub,
5938 .write_aofs = true,
5939 .vece = MO_8 },
5940 { .fniv = gen_uqsub_vec,
5941 .fno = gen_helper_gvec_uqsub_h,
5942 .opt_opc = vecop_list_uqsub,
5943 .write_aofs = true,
5944 .vece = MO_16 },
5945 { .fniv = gen_uqsub_vec,
5946 .fno = gen_helper_gvec_uqsub_s,
5947 .opt_opc = vecop_list_uqsub,
5948 .write_aofs = true,
5949 .vece = MO_32 },
5950 { .fniv = gen_uqsub_vec,
5951 .fno = gen_helper_gvec_uqsub_d,
5952 .opt_opc = vecop_list_uqsub,
5953 .write_aofs = true,
5954 .vece = MO_64 },
5955 };
5956
5957 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5958 TCGv_vec a, TCGv_vec b)
5959 {
5960 TCGv_vec x = tcg_temp_new_vec_matching(t);
5961 tcg_gen_sub_vec(vece, x, a, b);
5962 tcg_gen_sssub_vec(vece, t, a, b);
5963 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5964 tcg_gen_or_vec(vece, sat, sat, x);
5965 tcg_temp_free_vec(x);
5966 }
5967
5968 static const TCGOpcode vecop_list_sqsub[] = {
5969 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5970 };
5971
5972 const GVecGen4 sqsub_op[4] = {
5973 { .fniv = gen_sqsub_vec,
5974 .fno = gen_helper_gvec_sqsub_b,
5975 .opt_opc = vecop_list_sqsub,
5976 .write_aofs = true,
5977 .vece = MO_8 },
5978 { .fniv = gen_sqsub_vec,
5979 .fno = gen_helper_gvec_sqsub_h,
5980 .opt_opc = vecop_list_sqsub,
5981 .write_aofs = true,
5982 .vece = MO_16 },
5983 { .fniv = gen_sqsub_vec,
5984 .fno = gen_helper_gvec_sqsub_s,
5985 .opt_opc = vecop_list_sqsub,
5986 .write_aofs = true,
5987 .vece = MO_32 },
5988 { .fniv = gen_sqsub_vec,
5989 .fno = gen_helper_gvec_sqsub_d,
5990 .opt_opc = vecop_list_sqsub,
5991 .write_aofs = true,
5992 .vece = MO_64 },
5993 };
5994
5995 /* Translate a NEON data processing instruction. Return nonzero if the
5996 instruction is invalid.
5997 We process data in a mixture of 32-bit and 64-bit chunks.
5998 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5999
6000 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
6001 {
6002 int op;
6003 int q;
6004 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
6005 int size;
6006 int shift;
6007 int pass;
6008 int count;
6009 int pairwise;
6010 int u;
6011 int vec_size;
6012 uint32_t imm;
6013 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
6014 TCGv_ptr ptr1, ptr2, ptr3;
6015 TCGv_i64 tmp64;
6016
6017 /* FIXME: this access check should not take precedence over UNDEF
6018 * for invalid encodings; we will generate incorrect syndrome information
6019 * for attempts to execute invalid vfp/neon encodings with FP disabled.
6020 */
6021 if (s->fp_excp_el) {
6022 gen_exception_insn(s, 4, EXCP_UDEF,
6023 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6024 return 0;
6025 }
6026
6027 if (!s->vfp_enabled)
6028 return 1;
6029 q = (insn & (1 << 6)) != 0;
6030 u = (insn >> 24) & 1;
6031 VFP_DREG_D(rd, insn);
6032 VFP_DREG_N(rn, insn);
6033 VFP_DREG_M(rm, insn);
6034 size = (insn >> 20) & 3;
6035 vec_size = q ? 16 : 8;
6036 rd_ofs = neon_reg_offset(rd, 0);
6037 rn_ofs = neon_reg_offset(rn, 0);
6038 rm_ofs = neon_reg_offset(rm, 0);
6039
6040 if ((insn & (1 << 23)) == 0) {
6041 /* Three register same length. */
6042 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
6043 /* Catch invalid op and bad size combinations: UNDEF */
6044 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
6045 return 1;
6046 }
6047 /* All insns of this form UNDEF for either this condition or the
6048 * superset of cases "Q==1"; we catch the latter later.
6049 */
6050 if (q && ((rd | rn | rm) & 1)) {
6051 return 1;
6052 }
6053 switch (op) {
6054 case NEON_3R_SHA:
6055 /* The SHA-1/SHA-256 3-register instructions require special
6056 * treatment here, as their size field is overloaded as an
6057 * op type selector, and they all consume their input in a
6058 * single pass.
6059 */
6060 if (!q) {
6061 return 1;
6062 }
6063 if (!u) { /* SHA-1 */
6064 if (!dc_isar_feature(aa32_sha1, s)) {
6065 return 1;
6066 }
6067 ptr1 = vfp_reg_ptr(true, rd);
6068 ptr2 = vfp_reg_ptr(true, rn);
6069 ptr3 = vfp_reg_ptr(true, rm);
6070 tmp4 = tcg_const_i32(size);
6071 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
6072 tcg_temp_free_i32(tmp4);
6073 } else { /* SHA-256 */
6074 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
6075 return 1;
6076 }
6077 ptr1 = vfp_reg_ptr(true, rd);
6078 ptr2 = vfp_reg_ptr(true, rn);
6079 ptr3 = vfp_reg_ptr(true, rm);
6080 switch (size) {
6081 case 0:
6082 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
6083 break;
6084 case 1:
6085 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
6086 break;
6087 case 2:
6088 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
6089 break;
6090 }
6091 }
6092 tcg_temp_free_ptr(ptr1);
6093 tcg_temp_free_ptr(ptr2);
6094 tcg_temp_free_ptr(ptr3);
6095 return 0;
6096
6097 case NEON_3R_VPADD_VQRDMLAH:
6098 if (!u) {
6099 break; /* VPADD */
6100 }
6101 /* VQRDMLAH */
6102 switch (size) {
6103 case 1:
6104 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
6105 q, rd, rn, rm);
6106 case 2:
6107 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
6108 q, rd, rn, rm);
6109 }
6110 return 1;
6111
6112 case NEON_3R_VFM_VQRDMLSH:
6113 if (!u) {
6114 /* VFM, VFMS */
6115 if (size == 1) {
6116 return 1;
6117 }
6118 break;
6119 }
6120 /* VQRDMLSH */
6121 switch (size) {
6122 case 1:
6123 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
6124 q, rd, rn, rm);
6125 case 2:
6126 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
6127 q, rd, rn, rm);
6128 }
6129 return 1;
6130
6131 case NEON_3R_LOGIC: /* Logic ops. */
6132 switch ((u << 2) | size) {
6133 case 0: /* VAND */
6134 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
6135 vec_size, vec_size);
6136 break;
6137 case 1: /* VBIC */
6138 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
6139 vec_size, vec_size);
6140 break;
6141 case 2: /* VORR */
6142 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
6143 vec_size, vec_size);
6144 break;
6145 case 3: /* VORN */
6146 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
6147 vec_size, vec_size);
6148 break;
6149 case 4: /* VEOR */
6150 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
6151 vec_size, vec_size);
6152 break;
6153 case 5: /* VBSL */
6154 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
6155 vec_size, vec_size);
6156 break;
6157 case 6: /* VBIT */
6158 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
6159 vec_size, vec_size);
6160 break;
6161 case 7: /* VBIF */
6162 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
6163 vec_size, vec_size);
6164 break;
6165 }
6166 return 0;
6167
6168 case NEON_3R_VADD_VSUB:
6169 if (u) {
6170 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
6171 vec_size, vec_size);
6172 } else {
6173 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
6174 vec_size, vec_size);
6175 }
6176 return 0;
6177
6178 case NEON_3R_VQADD:
6179 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6180 rn_ofs, rm_ofs, vec_size, vec_size,
6181 (u ? uqadd_op : sqadd_op) + size);
6182 return 0;
6183
6184 case NEON_3R_VQSUB:
6185 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6186 rn_ofs, rm_ofs, vec_size, vec_size,
6187 (u ? uqsub_op : sqsub_op) + size);
6188 return 0;
6189
6190 case NEON_3R_VMUL: /* VMUL */
6191 if (u) {
6192 /* Polynomial case allows only P8 and is handled below. */
6193 if (size != 0) {
6194 return 1;
6195 }
6196 } else {
6197 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
6198 vec_size, vec_size);
6199 return 0;
6200 }
6201 break;
6202
6203 case NEON_3R_VML: /* VMLA, VMLS */
6204 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
6205 u ? &mls_op[size] : &mla_op[size]);
6206 return 0;
6207
6208 case NEON_3R_VTST_VCEQ:
6209 if (u) { /* VCEQ */
6210 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
6211 vec_size, vec_size);
6212 } else { /* VTST */
6213 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6214 vec_size, vec_size, &cmtst_op[size]);
6215 }
6216 return 0;
6217
6218 case NEON_3R_VCGT:
6219 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
6220 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6221 return 0;
6222
6223 case NEON_3R_VCGE:
6224 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
6225 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6226 return 0;
6227
6228 case NEON_3R_VMAX:
6229 if (u) {
6230 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
6231 vec_size, vec_size);
6232 } else {
6233 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
6234 vec_size, vec_size);
6235 }
6236 return 0;
6237 case NEON_3R_VMIN:
6238 if (u) {
6239 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
6240 vec_size, vec_size);
6241 } else {
6242 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
6243 vec_size, vec_size);
6244 }
6245 return 0;
6246 }
6247
6248 if (size == 3) {
6249 /* 64-bit element instructions. */
6250 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6251 neon_load_reg64(cpu_V0, rn + pass);
6252 neon_load_reg64(cpu_V1, rm + pass);
6253 switch (op) {
6254 case NEON_3R_VSHL:
6255 if (u) {
6256 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6257 } else {
6258 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6259 }
6260 break;
6261 case NEON_3R_VQSHL:
6262 if (u) {
6263 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6264 cpu_V1, cpu_V0);
6265 } else {
6266 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6267 cpu_V1, cpu_V0);
6268 }
6269 break;
6270 case NEON_3R_VRSHL:
6271 if (u) {
6272 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6273 } else {
6274 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6275 }
6276 break;
6277 case NEON_3R_VQRSHL:
6278 if (u) {
6279 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6280 cpu_V1, cpu_V0);
6281 } else {
6282 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6283 cpu_V1, cpu_V0);
6284 }
6285 break;
6286 default:
6287 abort();
6288 }
6289 neon_store_reg64(cpu_V0, rd + pass);
6290 }
6291 return 0;
6292 }
6293 pairwise = 0;
6294 switch (op) {
6295 case NEON_3R_VSHL:
6296 case NEON_3R_VQSHL:
6297 case NEON_3R_VRSHL:
6298 case NEON_3R_VQRSHL:
6299 {
6300 int rtmp;
6301 /* Shift instruction operands are reversed. */
6302 rtmp = rn;
6303 rn = rm;
6304 rm = rtmp;
6305 }
6306 break;
6307 case NEON_3R_VPADD_VQRDMLAH:
6308 case NEON_3R_VPMAX:
6309 case NEON_3R_VPMIN:
6310 pairwise = 1;
6311 break;
6312 case NEON_3R_FLOAT_ARITH:
6313 pairwise = (u && size < 2); /* if VPADD (float) */
6314 break;
6315 case NEON_3R_FLOAT_MINMAX:
6316 pairwise = u; /* if VPMIN/VPMAX (float) */
6317 break;
6318 case NEON_3R_FLOAT_CMP:
6319 if (!u && size) {
6320 /* no encoding for U=0 C=1x */
6321 return 1;
6322 }
6323 break;
6324 case NEON_3R_FLOAT_ACMP:
6325 if (!u) {
6326 return 1;
6327 }
6328 break;
6329 case NEON_3R_FLOAT_MISC:
6330 /* VMAXNM/VMINNM in ARMv8 */
6331 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6332 return 1;
6333 }
6334 break;
6335 case NEON_3R_VFM_VQRDMLSH:
6336 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6337 return 1;
6338 }
6339 break;
6340 default:
6341 break;
6342 }
6343
6344 if (pairwise && q) {
6345 /* All the pairwise insns UNDEF if Q is set */
6346 return 1;
6347 }
6348
6349 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6350
6351 if (pairwise) {
6352 /* Pairwise. */
6353 if (pass < 1) {
6354 tmp = neon_load_reg(rn, 0);
6355 tmp2 = neon_load_reg(rn, 1);
6356 } else {
6357 tmp = neon_load_reg(rm, 0);
6358 tmp2 = neon_load_reg(rm, 1);
6359 }
6360 } else {
6361 /* Elementwise. */
6362 tmp = neon_load_reg(rn, pass);
6363 tmp2 = neon_load_reg(rm, pass);
6364 }
6365 switch (op) {
6366 case NEON_3R_VHADD:
6367 GEN_NEON_INTEGER_OP(hadd);
6368 break;
6369 case NEON_3R_VRHADD:
6370 GEN_NEON_INTEGER_OP(rhadd);
6371 break;
6372 case NEON_3R_VHSUB:
6373 GEN_NEON_INTEGER_OP(hsub);
6374 break;
6375 case NEON_3R_VSHL:
6376 GEN_NEON_INTEGER_OP(shl);
6377 break;
6378 case NEON_3R_VQSHL:
6379 GEN_NEON_INTEGER_OP_ENV(qshl);
6380 break;
6381 case NEON_3R_VRSHL:
6382 GEN_NEON_INTEGER_OP(rshl);
6383 break;
6384 case NEON_3R_VQRSHL:
6385 GEN_NEON_INTEGER_OP_ENV(qrshl);
6386 break;
6387 case NEON_3R_VABD:
6388 GEN_NEON_INTEGER_OP(abd);
6389 break;
6390 case NEON_3R_VABA:
6391 GEN_NEON_INTEGER_OP(abd);
6392 tcg_temp_free_i32(tmp2);
6393 tmp2 = neon_load_reg(rd, pass);
6394 gen_neon_add(size, tmp, tmp2);
6395 break;
6396 case NEON_3R_VMUL:
6397 /* VMUL.P8; other cases already eliminated. */
6398 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6399 break;
6400 case NEON_3R_VPMAX:
6401 GEN_NEON_INTEGER_OP(pmax);
6402 break;
6403 case NEON_3R_VPMIN:
6404 GEN_NEON_INTEGER_OP(pmin);
6405 break;
6406 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6407 if (!u) { /* VQDMULH */
6408 switch (size) {
6409 case 1:
6410 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6411 break;
6412 case 2:
6413 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6414 break;
6415 default: abort();
6416 }
6417 } else { /* VQRDMULH */
6418 switch (size) {
6419 case 1:
6420 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6421 break;
6422 case 2:
6423 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6424 break;
6425 default: abort();
6426 }
6427 }
6428 break;
6429 case NEON_3R_VPADD_VQRDMLAH:
6430 switch (size) {
6431 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6432 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6433 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6434 default: abort();
6435 }
6436 break;
6437 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6438 {
6439 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6440 switch ((u << 2) | size) {
6441 case 0: /* VADD */
6442 case 4: /* VPADD */
6443 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6444 break;
6445 case 2: /* VSUB */
6446 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6447 break;
6448 case 6: /* VABD */
6449 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6450 break;
6451 default:
6452 abort();
6453 }
6454 tcg_temp_free_ptr(fpstatus);
6455 break;
6456 }
6457 case NEON_3R_FLOAT_MULTIPLY:
6458 {
6459 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6460 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6461 if (!u) {
6462 tcg_temp_free_i32(tmp2);
6463 tmp2 = neon_load_reg(rd, pass);
6464 if (size == 0) {
6465 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6466 } else {
6467 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6468 }
6469 }
6470 tcg_temp_free_ptr(fpstatus);
6471 break;
6472 }
6473 case NEON_3R_FLOAT_CMP:
6474 {
6475 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6476 if (!u) {
6477 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6478 } else {
6479 if (size == 0) {
6480 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6481 } else {
6482 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6483 }
6484 }
6485 tcg_temp_free_ptr(fpstatus);
6486 break;
6487 }
6488 case NEON_3R_FLOAT_ACMP:
6489 {
6490 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6491 if (size == 0) {
6492 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6493 } else {
6494 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6495 }
6496 tcg_temp_free_ptr(fpstatus);
6497 break;
6498 }
6499 case NEON_3R_FLOAT_MINMAX:
6500 {
6501 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6502 if (size == 0) {
6503 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6504 } else {
6505 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6506 }
6507 tcg_temp_free_ptr(fpstatus);
6508 break;
6509 }
6510 case NEON_3R_FLOAT_MISC:
6511 if (u) {
6512 /* VMAXNM/VMINNM */
6513 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6514 if (size == 0) {
6515 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6516 } else {
6517 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6518 }
6519 tcg_temp_free_ptr(fpstatus);
6520 } else {
6521 if (size == 0) {
6522 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6523 } else {
6524 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6525 }
6526 }
6527 break;
6528 case NEON_3R_VFM_VQRDMLSH:
6529 {
6530 /* VFMA, VFMS: fused multiply-add */
6531 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6532 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6533 if (size) {
6534 /* VFMS */
6535 gen_helper_vfp_negs(tmp, tmp);
6536 }
6537 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6538 tcg_temp_free_i32(tmp3);
6539 tcg_temp_free_ptr(fpstatus);
6540 break;
6541 }
6542 default:
6543 abort();
6544 }
6545 tcg_temp_free_i32(tmp2);
6546
6547 /* Save the result. For elementwise operations we can put it
6548 straight into the destination register. For pairwise operations
6549 we have to be careful to avoid clobbering the source operands. */
6550 if (pairwise && rd == rm) {
6551 neon_store_scratch(pass, tmp);
6552 } else {
6553 neon_store_reg(rd, pass, tmp);
6554 }
6555
6556 } /* for pass */
6557 if (pairwise && rd == rm) {
6558 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6559 tmp = neon_load_scratch(pass);
6560 neon_store_reg(rd, pass, tmp);
6561 }
6562 }
6563 /* End of 3 register same size operations. */
6564 } else if (insn & (1 << 4)) {
6565 if ((insn & 0x00380080) != 0) {
6566 /* Two registers and shift. */
6567 op = (insn >> 8) & 0xf;
6568 if (insn & (1 << 7)) {
6569 /* 64-bit shift. */
6570 if (op > 7) {
6571 return 1;
6572 }
6573 size = 3;
6574 } else {
6575 size = 2;
6576 while ((insn & (1 << (size + 19))) == 0)
6577 size--;
6578 }
6579 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6580 if (op < 8) {
6581 /* Shift by immediate:
6582 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6583 if (q && ((rd | rm) & 1)) {
6584 return 1;
6585 }
6586 if (!u && (op == 4 || op == 6)) {
6587 return 1;
6588 }
6589 /* Right shifts are encoded as N - shift, where N is the
6590 element size in bits. */
6591 if (op <= 4) {
6592 shift = shift - (1 << (size + 3));
6593 }
6594
6595 switch (op) {
6596 case 0: /* VSHR */
6597 /* Right shift comes here negative. */
6598 shift = -shift;
6599 /* Shifts larger than the element size are architecturally
6600 * valid. Unsigned results in all zeros; signed results
6601 * in all sign bits.
6602 */
6603 if (!u) {
6604 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6605 MIN(shift, (8 << size) - 1),
6606 vec_size, vec_size);
6607 } else if (shift >= 8 << size) {
6608 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6609 } else {
6610 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6611 vec_size, vec_size);
6612 }
6613 return 0;
6614
6615 case 1: /* VSRA */
6616 /* Right shift comes here negative. */
6617 shift = -shift;
6618 /* Shifts larger than the element size are architecturally
6619 * valid. Unsigned results in all zeros; signed results
6620 * in all sign bits.
6621 */
6622 if (!u) {
6623 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6624 MIN(shift, (8 << size) - 1),
6625 &ssra_op[size]);
6626 } else if (shift >= 8 << size) {
6627 /* rd += 0 */
6628 } else {
6629 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6630 shift, &usra_op[size]);
6631 }
6632 return 0;
6633
6634 case 4: /* VSRI */
6635 if (!u) {
6636 return 1;
6637 }
6638 /* Right shift comes here negative. */
6639 shift = -shift;
6640 /* Shift out of range leaves destination unchanged. */
6641 if (shift < 8 << size) {
6642 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6643 shift, &sri_op[size]);
6644 }
6645 return 0;
6646
6647 case 5: /* VSHL, VSLI */
6648 if (u) { /* VSLI */
6649 /* Shift out of range leaves destination unchanged. */
6650 if (shift < 8 << size) {
6651 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6652 vec_size, shift, &sli_op[size]);
6653 }
6654 } else { /* VSHL */
6655 /* Shifts larger than the element size are
6656 * architecturally valid and results in zero.
6657 */
6658 if (shift >= 8 << size) {
6659 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6660 } else {
6661 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6662 vec_size, vec_size);
6663 }
6664 }
6665 return 0;
6666 }
6667
6668 if (size == 3) {
6669 count = q + 1;
6670 } else {
6671 count = q ? 4: 2;
6672 }
6673
6674 /* To avoid excessive duplication of ops we implement shift
6675 * by immediate using the variable shift operations.
6676 */
6677 imm = dup_const(size, shift);
6678
6679 for (pass = 0; pass < count; pass++) {
6680 if (size == 3) {
6681 neon_load_reg64(cpu_V0, rm + pass);
6682 tcg_gen_movi_i64(cpu_V1, imm);
6683 switch (op) {
6684 case 2: /* VRSHR */
6685 case 3: /* VRSRA */
6686 if (u)
6687 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6688 else
6689 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6690 break;
6691 case 6: /* VQSHLU */
6692 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6693 cpu_V0, cpu_V1);
6694 break;
6695 case 7: /* VQSHL */
6696 if (u) {
6697 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6698 cpu_V0, cpu_V1);
6699 } else {
6700 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6701 cpu_V0, cpu_V1);
6702 }
6703 break;
6704 default:
6705 g_assert_not_reached();
6706 }
6707 if (op == 3) {
6708 /* Accumulate. */
6709 neon_load_reg64(cpu_V1, rd + pass);
6710 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6711 }
6712 neon_store_reg64(cpu_V0, rd + pass);
6713 } else { /* size < 3 */
6714 /* Operands in T0 and T1. */
6715 tmp = neon_load_reg(rm, pass);
6716 tmp2 = tcg_temp_new_i32();
6717 tcg_gen_movi_i32(tmp2, imm);
6718 switch (op) {
6719 case 2: /* VRSHR */
6720 case 3: /* VRSRA */
6721 GEN_NEON_INTEGER_OP(rshl);
6722 break;
6723 case 6: /* VQSHLU */
6724 switch (size) {
6725 case 0:
6726 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6727 tmp, tmp2);
6728 break;
6729 case 1:
6730 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6731 tmp, tmp2);
6732 break;
6733 case 2:
6734 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6735 tmp, tmp2);
6736 break;
6737 default:
6738 abort();
6739 }
6740 break;
6741 case 7: /* VQSHL */
6742 GEN_NEON_INTEGER_OP_ENV(qshl);
6743 break;
6744 default:
6745 g_assert_not_reached();
6746 }
6747 tcg_temp_free_i32(tmp2);
6748
6749 if (op == 3) {
6750 /* Accumulate. */
6751 tmp2 = neon_load_reg(rd, pass);
6752 gen_neon_add(size, tmp, tmp2);
6753 tcg_temp_free_i32(tmp2);
6754 }
6755 neon_store_reg(rd, pass, tmp);
6756 }
6757 } /* for pass */
6758 } else if (op < 10) {
6759 /* Shift by immediate and narrow:
6760 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6761 int input_unsigned = (op == 8) ? !u : u;
6762 if (rm & 1) {
6763 return 1;
6764 }
6765 shift = shift - (1 << (size + 3));
6766 size++;
6767 if (size == 3) {
6768 tmp64 = tcg_const_i64(shift);
6769 neon_load_reg64(cpu_V0, rm);
6770 neon_load_reg64(cpu_V1, rm + 1);
6771 for (pass = 0; pass < 2; pass++) {
6772 TCGv_i64 in;
6773 if (pass == 0) {
6774 in = cpu_V0;
6775 } else {
6776 in = cpu_V1;
6777 }
6778 if (q) {
6779 if (input_unsigned) {
6780 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6781 } else {
6782 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6783 }
6784 } else {
6785 if (input_unsigned) {
6786 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6787 } else {
6788 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6789 }
6790 }
6791 tmp = tcg_temp_new_i32();
6792 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6793 neon_store_reg(rd, pass, tmp);
6794 } /* for pass */
6795 tcg_temp_free_i64(tmp64);
6796 } else {
6797 if (size == 1) {
6798 imm = (uint16_t)shift;
6799 imm |= imm << 16;
6800 } else {
6801 /* size == 2 */
6802 imm = (uint32_t)shift;
6803 }
6804 tmp2 = tcg_const_i32(imm);
6805 tmp4 = neon_load_reg(rm + 1, 0);
6806 tmp5 = neon_load_reg(rm + 1, 1);
6807 for (pass = 0; pass < 2; pass++) {
6808 if (pass == 0) {
6809 tmp = neon_load_reg(rm, 0);
6810 } else {
6811 tmp = tmp4;
6812 }
6813 gen_neon_shift_narrow(size, tmp, tmp2, q,
6814 input_unsigned);
6815 if (pass == 0) {
6816 tmp3 = neon_load_reg(rm, 1);
6817 } else {
6818 tmp3 = tmp5;
6819 }
6820 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6821 input_unsigned);
6822 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6823 tcg_temp_free_i32(tmp);
6824 tcg_temp_free_i32(tmp3);
6825 tmp = tcg_temp_new_i32();
6826 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6827 neon_store_reg(rd, pass, tmp);
6828 } /* for pass */
6829 tcg_temp_free_i32(tmp2);
6830 }
6831 } else if (op == 10) {
6832 /* VSHLL, VMOVL */
6833 if (q || (rd & 1)) {
6834 return 1;
6835 }
6836 tmp = neon_load_reg(rm, 0);
6837 tmp2 = neon_load_reg(rm, 1);
6838 for (pass = 0; pass < 2; pass++) {
6839 if (pass == 1)
6840 tmp = tmp2;
6841
6842 gen_neon_widen(cpu_V0, tmp, size, u);
6843
6844 if (shift != 0) {
6845 /* The shift is less than the width of the source
6846 type, so we can just shift the whole register. */
6847 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6848 /* Widen the result of shift: we need to clear
6849 * the potential overflow bits resulting from
6850 * left bits of the narrow input appearing as
6851 * right bits of left the neighbour narrow
6852 * input. */
6853 if (size < 2 || !u) {
6854 uint64_t imm64;
6855 if (size == 0) {
6856 imm = (0xffu >> (8 - shift));
6857 imm |= imm << 16;
6858 } else if (size == 1) {
6859 imm = 0xffff >> (16 - shift);
6860 } else {
6861 /* size == 2 */
6862 imm = 0xffffffff >> (32 - shift);
6863 }
6864 if (size < 2) {
6865 imm64 = imm | (((uint64_t)imm) << 32);
6866 } else {
6867 imm64 = imm;
6868 }
6869 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6870 }
6871 }
6872 neon_store_reg64(cpu_V0, rd + pass);
6873 }
6874 } else if (op >= 14) {
6875 /* VCVT fixed-point. */
6876 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6877 return 1;
6878 }
6879 /* We have already masked out the must-be-1 top bit of imm6,
6880 * hence this 32-shift where the ARM ARM has 64-imm6.
6881 */
6882 shift = 32 - shift;
6883 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6884 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6885 if (!(op & 1)) {
6886 if (u)
6887 gen_vfp_ulto(0, shift, 1);
6888 else
6889 gen_vfp_slto(0, shift, 1);
6890 } else {
6891 if (u)
6892 gen_vfp_toul(0, shift, 1);
6893 else
6894 gen_vfp_tosl(0, shift, 1);
6895 }
6896 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6897 }
6898 } else {
6899 return 1;
6900 }
6901 } else { /* (insn & 0x00380080) == 0 */
6902 int invert, reg_ofs, vec_size;
6903
6904 if (q && (rd & 1)) {
6905 return 1;
6906 }
6907
6908 op = (insn >> 8) & 0xf;
6909 /* One register and immediate. */
6910 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6911 invert = (insn & (1 << 5)) != 0;
6912 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6913 * We choose to not special-case this and will behave as if a
6914 * valid constant encoding of 0 had been given.
6915 */
6916 switch (op) {
6917 case 0: case 1:
6918 /* no-op */
6919 break;
6920 case 2: case 3:
6921 imm <<= 8;
6922 break;
6923 case 4: case 5:
6924 imm <<= 16;
6925 break;
6926 case 6: case 7:
6927 imm <<= 24;
6928 break;
6929 case 8: case 9:
6930 imm |= imm << 16;
6931 break;
6932 case 10: case 11:
6933 imm = (imm << 8) | (imm << 24);
6934 break;
6935 case 12:
6936 imm = (imm << 8) | 0xff;
6937 break;
6938 case 13:
6939 imm = (imm << 16) | 0xffff;
6940 break;
6941 case 14:
6942 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6943 if (invert) {
6944 imm = ~imm;
6945 }
6946 break;
6947 case 15:
6948 if (invert) {
6949 return 1;
6950 }
6951 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6952 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6953 break;
6954 }
6955 if (invert) {
6956 imm = ~imm;
6957 }
6958
6959 reg_ofs = neon_reg_offset(rd, 0);
6960 vec_size = q ? 16 : 8;
6961
6962 if (op & 1 && op < 12) {
6963 if (invert) {
6964 /* The immediate value has already been inverted,
6965 * so BIC becomes AND.
6966 */
6967 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
6968 vec_size, vec_size);
6969 } else {
6970 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
6971 vec_size, vec_size);
6972 }
6973 } else {
6974 /* VMOV, VMVN. */
6975 if (op == 14 && invert) {
6976 TCGv_i64 t64 = tcg_temp_new_i64();
6977
6978 for (pass = 0; pass <= q; ++pass) {
6979 uint64_t val = 0;
6980 int n;
6981
6982 for (n = 0; n < 8; n++) {
6983 if (imm & (1 << (n + pass * 8))) {
6984 val |= 0xffull << (n * 8);
6985 }
6986 }
6987 tcg_gen_movi_i64(t64, val);
6988 neon_store_reg64(t64, rd + pass);
6989 }
6990 tcg_temp_free_i64(t64);
6991 } else {
6992 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
6993 }
6994 }
6995 }
6996 } else { /* (insn & 0x00800010 == 0x00800000) */
6997 if (size != 3) {
6998 op = (insn >> 8) & 0xf;
6999 if ((insn & (1 << 6)) == 0) {
7000 /* Three registers of different lengths. */
7001 int src1_wide;
7002 int src2_wide;
7003 int prewiden;
7004 /* undefreq: bit 0 : UNDEF if size == 0
7005 * bit 1 : UNDEF if size == 1
7006 * bit 2 : UNDEF if size == 2
7007 * bit 3 : UNDEF if U == 1
7008 * Note that [2:0] set implies 'always UNDEF'
7009 */
7010 int undefreq;
7011 /* prewiden, src1_wide, src2_wide, undefreq */
7012 static const int neon_3reg_wide[16][4] = {
7013 {1, 0, 0, 0}, /* VADDL */
7014 {1, 1, 0, 0}, /* VADDW */
7015 {1, 0, 0, 0}, /* VSUBL */
7016 {1, 1, 0, 0}, /* VSUBW */
7017 {0, 1, 1, 0}, /* VADDHN */
7018 {0, 0, 0, 0}, /* VABAL */
7019 {0, 1, 1, 0}, /* VSUBHN */
7020 {0, 0, 0, 0}, /* VABDL */
7021 {0, 0, 0, 0}, /* VMLAL */
7022 {0, 0, 0, 9}, /* VQDMLAL */
7023 {0, 0, 0, 0}, /* VMLSL */
7024 {0, 0, 0, 9}, /* VQDMLSL */
7025 {0, 0, 0, 0}, /* Integer VMULL */
7026 {0, 0, 0, 1}, /* VQDMULL */
7027 {0, 0, 0, 0xa}, /* Polynomial VMULL */
7028 {0, 0, 0, 7}, /* Reserved: always UNDEF */
7029 };
7030
7031 prewiden = neon_3reg_wide[op][0];
7032 src1_wide = neon_3reg_wide[op][1];
7033 src2_wide = neon_3reg_wide[op][2];
7034 undefreq = neon_3reg_wide[op][3];
7035
7036 if ((undefreq & (1 << size)) ||
7037 ((undefreq & 8) && u)) {
7038 return 1;
7039 }
7040 if ((src1_wide && (rn & 1)) ||
7041 (src2_wide && (rm & 1)) ||
7042 (!src2_wide && (rd & 1))) {
7043 return 1;
7044 }
7045
7046 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7047 * outside the loop below as it only performs a single pass.
7048 */
7049 if (op == 14 && size == 2) {
7050 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
7051
7052 if (!dc_isar_feature(aa32_pmull, s)) {
7053 return 1;
7054 }
7055 tcg_rn = tcg_temp_new_i64();
7056 tcg_rm = tcg_temp_new_i64();
7057 tcg_rd = tcg_temp_new_i64();
7058 neon_load_reg64(tcg_rn, rn);
7059 neon_load_reg64(tcg_rm, rm);
7060 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
7061 neon_store_reg64(tcg_rd, rd);
7062 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
7063 neon_store_reg64(tcg_rd, rd + 1);
7064 tcg_temp_free_i64(tcg_rn);
7065 tcg_temp_free_i64(tcg_rm);
7066 tcg_temp_free_i64(tcg_rd);
7067 return 0;
7068 }
7069
7070 /* Avoid overlapping operands. Wide source operands are
7071 always aligned so will never overlap with wide
7072 destinations in problematic ways. */
7073 if (rd == rm && !src2_wide) {
7074 tmp = neon_load_reg(rm, 1);
7075 neon_store_scratch(2, tmp);
7076 } else if (rd == rn && !src1_wide) {
7077 tmp = neon_load_reg(rn, 1);
7078 neon_store_scratch(2, tmp);
7079 }
7080 tmp3 = NULL;
7081 for (pass = 0; pass < 2; pass++) {
7082 if (src1_wide) {
7083 neon_load_reg64(cpu_V0, rn + pass);
7084 tmp = NULL;
7085 } else {
7086 if (pass == 1 && rd == rn) {
7087 tmp = neon_load_scratch(2);
7088 } else {
7089 tmp = neon_load_reg(rn, pass);
7090 }
7091 if (prewiden) {
7092 gen_neon_widen(cpu_V0, tmp, size, u);
7093 }
7094 }
7095 if (src2_wide) {
7096 neon_load_reg64(cpu_V1, rm + pass);
7097 tmp2 = NULL;
7098 } else {
7099 if (pass == 1 && rd == rm) {
7100 tmp2 = neon_load_scratch(2);
7101 } else {
7102 tmp2 = neon_load_reg(rm, pass);
7103 }
7104 if (prewiden) {
7105 gen_neon_widen(cpu_V1, tmp2, size, u);
7106 }
7107 }
7108 switch (op) {
7109 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7110 gen_neon_addl(size);
7111 break;
7112 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7113 gen_neon_subl(size);
7114 break;
7115 case 5: case 7: /* VABAL, VABDL */
7116 switch ((size << 1) | u) {
7117 case 0:
7118 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
7119 break;
7120 case 1:
7121 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
7122 break;
7123 case 2:
7124 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
7125 break;
7126 case 3:
7127 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
7128 break;
7129 case 4:
7130 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
7131 break;
7132 case 5:
7133 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
7134 break;
7135 default: abort();
7136 }
7137 tcg_temp_free_i32(tmp2);
7138 tcg_temp_free_i32(tmp);
7139 break;
7140 case 8: case 9: case 10: case 11: case 12: case 13:
7141 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7142 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7143 break;
7144 case 14: /* Polynomial VMULL */
7145 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
7146 tcg_temp_free_i32(tmp2);
7147 tcg_temp_free_i32(tmp);
7148 break;
7149 default: /* 15 is RESERVED: caught earlier */
7150 abort();
7151 }
7152 if (op == 13) {
7153 /* VQDMULL */
7154 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7155 neon_store_reg64(cpu_V0, rd + pass);
7156 } else if (op == 5 || (op >= 8 && op <= 11)) {
7157 /* Accumulate. */
7158 neon_load_reg64(cpu_V1, rd + pass);
7159 switch (op) {
7160 case 10: /* VMLSL */
7161 gen_neon_negl(cpu_V0, size);
7162 /* Fall through */
7163 case 5: case 8: /* VABAL, VMLAL */
7164 gen_neon_addl(size);
7165 break;
7166 case 9: case 11: /* VQDMLAL, VQDMLSL */
7167 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7168 if (op == 11) {
7169 gen_neon_negl(cpu_V0, size);
7170 }
7171 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7172 break;
7173 default:
7174 abort();
7175 }
7176 neon_store_reg64(cpu_V0, rd + pass);
7177 } else if (op == 4 || op == 6) {
7178 /* Narrowing operation. */
7179 tmp = tcg_temp_new_i32();
7180 if (!u) {
7181 switch (size) {
7182 case 0:
7183 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7184 break;
7185 case 1:
7186 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7187 break;
7188 case 2:
7189 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7190 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7191 break;
7192 default: abort();
7193 }
7194 } else {
7195 switch (size) {
7196 case 0:
7197 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7198 break;
7199 case 1:
7200 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7201 break;
7202 case 2:
7203 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7204 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7205 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7206 break;
7207 default: abort();
7208 }
7209 }
7210 if (pass == 0) {
7211 tmp3 = tmp;
7212 } else {
7213 neon_store_reg(rd, 0, tmp3);
7214 neon_store_reg(rd, 1, tmp);
7215 }
7216 } else {
7217 /* Write back the result. */
7218 neon_store_reg64(cpu_V0, rd + pass);
7219 }
7220 }
7221 } else {
7222 /* Two registers and a scalar. NB that for ops of this form
7223 * the ARM ARM labels bit 24 as Q, but it is in our variable
7224 * 'u', not 'q'.
7225 */
7226 if (size == 0) {
7227 return 1;
7228 }
7229 switch (op) {
7230 case 1: /* Float VMLA scalar */
7231 case 5: /* Floating point VMLS scalar */
7232 case 9: /* Floating point VMUL scalar */
7233 if (size == 1) {
7234 return 1;
7235 }
7236 /* fall through */
7237 case 0: /* Integer VMLA scalar */
7238 case 4: /* Integer VMLS scalar */
7239 case 8: /* Integer VMUL scalar */
7240 case 12: /* VQDMULH scalar */
7241 case 13: /* VQRDMULH scalar */
7242 if (u && ((rd | rn) & 1)) {
7243 return 1;
7244 }
7245 tmp = neon_get_scalar(size, rm);
7246 neon_store_scratch(0, tmp);
7247 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7248 tmp = neon_load_scratch(0);
7249 tmp2 = neon_load_reg(rn, pass);
7250 if (op == 12) {
7251 if (size == 1) {
7252 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7253 } else {
7254 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7255 }
7256 } else if (op == 13) {
7257 if (size == 1) {
7258 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7259 } else {
7260 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7261 }
7262 } else if (op & 1) {
7263 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7264 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7265 tcg_temp_free_ptr(fpstatus);
7266 } else {
7267 switch (size) {
7268 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7269 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7270 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7271 default: abort();
7272 }
7273 }
7274 tcg_temp_free_i32(tmp2);
7275 if (op < 8) {
7276 /* Accumulate. */
7277 tmp2 = neon_load_reg(rd, pass);
7278 switch (op) {
7279 case 0:
7280 gen_neon_add(size, tmp, tmp2);
7281 break;
7282 case 1:
7283 {
7284 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7285 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7286 tcg_temp_free_ptr(fpstatus);
7287 break;
7288 }
7289 case 4:
7290 gen_neon_rsb(size, tmp, tmp2);
7291 break;
7292 case 5:
7293 {
7294 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7295 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7296 tcg_temp_free_ptr(fpstatus);
7297 break;
7298 }
7299 default:
7300 abort();
7301 }
7302 tcg_temp_free_i32(tmp2);
7303 }
7304 neon_store_reg(rd, pass, tmp);
7305 }
7306 break;
7307 case 3: /* VQDMLAL scalar */
7308 case 7: /* VQDMLSL scalar */
7309 case 11: /* VQDMULL scalar */
7310 if (u == 1) {
7311 return 1;
7312 }
7313 /* fall through */
7314 case 2: /* VMLAL sclar */
7315 case 6: /* VMLSL scalar */
7316 case 10: /* VMULL scalar */
7317 if (rd & 1) {
7318 return 1;
7319 }
7320 tmp2 = neon_get_scalar(size, rm);
7321 /* We need a copy of tmp2 because gen_neon_mull
7322 * deletes it during pass 0. */
7323 tmp4 = tcg_temp_new_i32();
7324 tcg_gen_mov_i32(tmp4, tmp2);
7325 tmp3 = neon_load_reg(rn, 1);
7326
7327 for (pass = 0; pass < 2; pass++) {
7328 if (pass == 0) {
7329 tmp = neon_load_reg(rn, 0);
7330 } else {
7331 tmp = tmp3;
7332 tmp2 = tmp4;
7333 }
7334 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7335 if (op != 11) {
7336 neon_load_reg64(cpu_V1, rd + pass);
7337 }
7338 switch (op) {
7339 case 6:
7340 gen_neon_negl(cpu_V0, size);
7341 /* Fall through */
7342 case 2:
7343 gen_neon_addl(size);
7344 break;
7345 case 3: case 7:
7346 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7347 if (op == 7) {
7348 gen_neon_negl(cpu_V0, size);
7349 }
7350 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7351 break;
7352 case 10:
7353 /* no-op */
7354 break;
7355 case 11:
7356 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7357 break;
7358 default:
7359 abort();
7360 }
7361 neon_store_reg64(cpu_V0, rd + pass);
7362 }
7363 break;
7364 case 14: /* VQRDMLAH scalar */
7365 case 15: /* VQRDMLSH scalar */
7366 {
7367 NeonGenThreeOpEnvFn *fn;
7368
7369 if (!dc_isar_feature(aa32_rdm, s)) {
7370 return 1;
7371 }
7372 if (u && ((rd | rn) & 1)) {
7373 return 1;
7374 }
7375 if (op == 14) {
7376 if (size == 1) {
7377 fn = gen_helper_neon_qrdmlah_s16;
7378 } else {
7379 fn = gen_helper_neon_qrdmlah_s32;
7380 }
7381 } else {
7382 if (size == 1) {
7383 fn = gen_helper_neon_qrdmlsh_s16;
7384 } else {
7385 fn = gen_helper_neon_qrdmlsh_s32;
7386 }
7387 }
7388
7389 tmp2 = neon_get_scalar(size, rm);
7390 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7391 tmp = neon_load_reg(rn, pass);
7392 tmp3 = neon_load_reg(rd, pass);
7393 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7394 tcg_temp_free_i32(tmp3);
7395 neon_store_reg(rd, pass, tmp);
7396 }
7397 tcg_temp_free_i32(tmp2);
7398 }
7399 break;
7400 default:
7401 g_assert_not_reached();
7402 }
7403 }
7404 } else { /* size == 3 */
7405 if (!u) {
7406 /* Extract. */
7407 imm = (insn >> 8) & 0xf;
7408
7409 if (imm > 7 && !q)
7410 return 1;
7411
7412 if (q && ((rd | rn | rm) & 1)) {
7413 return 1;
7414 }
7415
7416 if (imm == 0) {
7417 neon_load_reg64(cpu_V0, rn);
7418 if (q) {
7419 neon_load_reg64(cpu_V1, rn + 1);
7420 }
7421 } else if (imm == 8) {
7422 neon_load_reg64(cpu_V0, rn + 1);
7423 if (q) {
7424 neon_load_reg64(cpu_V1, rm);
7425 }
7426 } else if (q) {
7427 tmp64 = tcg_temp_new_i64();
7428 if (imm < 8) {
7429 neon_load_reg64(cpu_V0, rn);
7430 neon_load_reg64(tmp64, rn + 1);
7431 } else {
7432 neon_load_reg64(cpu_V0, rn + 1);
7433 neon_load_reg64(tmp64, rm);
7434 }
7435 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7436 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7437 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7438 if (imm < 8) {
7439 neon_load_reg64(cpu_V1, rm);
7440 } else {
7441 neon_load_reg64(cpu_V1, rm + 1);
7442 imm -= 8;
7443 }
7444 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7445 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7446 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7447 tcg_temp_free_i64(tmp64);
7448 } else {
7449 /* BUGFIX */
7450 neon_load_reg64(cpu_V0, rn);
7451 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7452 neon_load_reg64(cpu_V1, rm);
7453 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7454 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7455 }
7456 neon_store_reg64(cpu_V0, rd);
7457 if (q) {
7458 neon_store_reg64(cpu_V1, rd + 1);
7459 }
7460 } else if ((insn & (1 << 11)) == 0) {
7461 /* Two register misc. */
7462 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7463 size = (insn >> 18) & 3;
7464 /* UNDEF for unknown op values and bad op-size combinations */
7465 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7466 return 1;
7467 }
7468 if (neon_2rm_is_v8_op(op) &&
7469 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7470 return 1;
7471 }
7472 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7473 q && ((rm | rd) & 1)) {
7474 return 1;
7475 }
7476 switch (op) {
7477 case NEON_2RM_VREV64:
7478 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7479 tmp = neon_load_reg(rm, pass * 2);
7480 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7481 switch (size) {
7482 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7483 case 1: gen_swap_half(tmp); break;
7484 case 2: /* no-op */ break;
7485 default: abort();
7486 }
7487 neon_store_reg(rd, pass * 2 + 1, tmp);
7488 if (size == 2) {
7489 neon_store_reg(rd, pass * 2, tmp2);
7490 } else {
7491 switch (size) {
7492 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7493 case 1: gen_swap_half(tmp2); break;
7494 default: abort();
7495 }
7496 neon_store_reg(rd, pass * 2, tmp2);
7497 }
7498 }
7499 break;
7500 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7501 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7502 for (pass = 0; pass < q + 1; pass++) {
7503 tmp = neon_load_reg(rm, pass * 2);
7504 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7505 tmp = neon_load_reg(rm, pass * 2 + 1);
7506 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7507 switch (size) {
7508 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7509 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7510 case 2: tcg_gen_add_i64(CPU_V001); break;
7511 default: abort();
7512 }
7513 if (op >= NEON_2RM_VPADAL) {
7514 /* Accumulate. */
7515 neon_load_reg64(cpu_V1, rd + pass);
7516 gen_neon_addl(size);
7517 }
7518 neon_store_reg64(cpu_V0, rd + pass);
7519 }
7520 break;
7521 case NEON_2RM_VTRN:
7522 if (size == 2) {
7523 int n;
7524 for (n = 0; n < (q ? 4 : 2); n += 2) {
7525 tmp = neon_load_reg(rm, n);
7526 tmp2 = neon_load_reg(rd, n + 1);
7527 neon_store_reg(rm, n, tmp2);
7528 neon_store_reg(rd, n + 1, tmp);
7529 }
7530 } else {
7531 goto elementwise;
7532 }
7533 break;
7534 case NEON_2RM_VUZP:
7535 if (gen_neon_unzip(rd, rm, size, q)) {
7536 return 1;
7537 }
7538 break;
7539 case NEON_2RM_VZIP:
7540 if (gen_neon_zip(rd, rm, size, q)) {
7541 return 1;
7542 }
7543 break;
7544 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7545 /* also VQMOVUN; op field and mnemonics don't line up */
7546 if (rm & 1) {
7547 return 1;
7548 }
7549 tmp2 = NULL;
7550 for (pass = 0; pass < 2; pass++) {
7551 neon_load_reg64(cpu_V0, rm + pass);
7552 tmp = tcg_temp_new_i32();
7553 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7554 tmp, cpu_V0);
7555 if (pass == 0) {
7556 tmp2 = tmp;
7557 } else {
7558 neon_store_reg(rd, 0, tmp2);
7559 neon_store_reg(rd, 1, tmp);
7560 }
7561 }
7562 break;
7563 case NEON_2RM_VSHLL:
7564 if (q || (rd & 1)) {
7565 return 1;
7566 }
7567 tmp = neon_load_reg(rm, 0);
7568 tmp2 = neon_load_reg(rm, 1);
7569 for (pass = 0; pass < 2; pass++) {
7570 if (pass == 1)
7571 tmp = tmp2;
7572 gen_neon_widen(cpu_V0, tmp, size, 1);
7573 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7574 neon_store_reg64(cpu_V0, rd + pass);
7575 }
7576 break;
7577 case NEON_2RM_VCVT_F16_F32:
7578 {
7579 TCGv_ptr fpst;
7580 TCGv_i32 ahp;
7581
7582 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7583 q || (rm & 1)) {
7584 return 1;
7585 }
7586 tmp = tcg_temp_new_i32();
7587 tmp2 = tcg_temp_new_i32();
7588 fpst = get_fpstatus_ptr(true);
7589 ahp = get_ahp_flag();
7590 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7591 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7592 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7593 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7594 tcg_gen_shli_i32(tmp2, tmp2, 16);
7595 tcg_gen_or_i32(tmp2, tmp2, tmp);
7596 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7597 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7598 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7599 neon_store_reg(rd, 0, tmp2);
7600 tmp2 = tcg_temp_new_i32();
7601 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7602 tcg_gen_shli_i32(tmp2, tmp2, 16);
7603 tcg_gen_or_i32(tmp2, tmp2, tmp);
7604 neon_store_reg(rd, 1, tmp2);
7605 tcg_temp_free_i32(tmp);
7606 tcg_temp_free_i32(ahp);
7607 tcg_temp_free_ptr(fpst);
7608 break;
7609 }
7610 case NEON_2RM_VCVT_F32_F16:
7611 {
7612 TCGv_ptr fpst;
7613 TCGv_i32 ahp;
7614 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7615 q || (rd & 1)) {
7616 return 1;
7617 }
7618 fpst = get_fpstatus_ptr(true);
7619 ahp = get_ahp_flag();
7620 tmp3 = tcg_temp_new_i32();
7621 tmp = neon_load_reg(rm, 0);
7622 tmp2 = neon_load_reg(rm, 1);
7623 tcg_gen_ext16u_i32(tmp3, tmp);
7624 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7625 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7626 tcg_gen_shri_i32(tmp3, tmp, 16);
7627 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7628 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7629 tcg_temp_free_i32(tmp);
7630 tcg_gen_ext16u_i32(tmp3, tmp2);
7631 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7632 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7633 tcg_gen_shri_i32(tmp3, tmp2, 16);
7634 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7635 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7636 tcg_temp_free_i32(tmp2);
7637 tcg_temp_free_i32(tmp3);
7638 tcg_temp_free_i32(ahp);
7639 tcg_temp_free_ptr(fpst);
7640 break;
7641 }
7642 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7643 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7644 return 1;
7645 }
7646 ptr1 = vfp_reg_ptr(true, rd);
7647 ptr2 = vfp_reg_ptr(true, rm);
7648
7649 /* Bit 6 is the lowest opcode bit; it distinguishes between
7650 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7651 */
7652 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7653
7654 if (op == NEON_2RM_AESE) {
7655 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7656 } else {
7657 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7658 }
7659 tcg_temp_free_ptr(ptr1);
7660 tcg_temp_free_ptr(ptr2);
7661 tcg_temp_free_i32(tmp3);
7662 break;
7663 case NEON_2RM_SHA1H:
7664 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7665 return 1;
7666 }
7667 ptr1 = vfp_reg_ptr(true, rd);
7668 ptr2 = vfp_reg_ptr(true, rm);
7669
7670 gen_helper_crypto_sha1h(ptr1, ptr2);
7671
7672 tcg_temp_free_ptr(ptr1);
7673 tcg_temp_free_ptr(ptr2);
7674 break;
7675 case NEON_2RM_SHA1SU1:
7676 if ((rm | rd) & 1) {
7677 return 1;
7678 }
7679 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7680 if (q) {
7681 if (!dc_isar_feature(aa32_sha2, s)) {
7682 return 1;
7683 }
7684 } else if (!dc_isar_feature(aa32_sha1, s)) {
7685 return 1;
7686 }
7687 ptr1 = vfp_reg_ptr(true, rd);
7688 ptr2 = vfp_reg_ptr(true, rm);
7689 if (q) {
7690 gen_helper_crypto_sha256su0(ptr1, ptr2);
7691 } else {
7692 gen_helper_crypto_sha1su1(ptr1, ptr2);
7693 }
7694 tcg_temp_free_ptr(ptr1);
7695 tcg_temp_free_ptr(ptr2);
7696 break;
7697
7698 case NEON_2RM_VMVN:
7699 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7700 break;
7701 case NEON_2RM_VNEG:
7702 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7703 break;
7704 case NEON_2RM_VABS:
7705 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
7706 break;
7707
7708 default:
7709 elementwise:
7710 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7711 if (neon_2rm_is_float_op(op)) {
7712 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7713 neon_reg_offset(rm, pass));
7714 tmp = NULL;
7715 } else {
7716 tmp = neon_load_reg(rm, pass);
7717 }
7718 switch (op) {
7719 case NEON_2RM_VREV32:
7720 switch (size) {
7721 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7722 case 1: gen_swap_half(tmp); break;
7723 default: abort();
7724 }
7725 break;
7726 case NEON_2RM_VREV16:
7727 gen_rev16(tmp);
7728 break;
7729 case NEON_2RM_VCLS:
7730 switch (size) {
7731 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7732 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7733 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7734 default: abort();
7735 }
7736 break;
7737 case NEON_2RM_VCLZ:
7738 switch (size) {
7739 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7740 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7741 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7742 default: abort();
7743 }
7744 break;
7745 case NEON_2RM_VCNT:
7746 gen_helper_neon_cnt_u8(tmp, tmp);
7747 break;
7748 case NEON_2RM_VQABS:
7749 switch (size) {
7750 case 0:
7751 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7752 break;
7753 case 1:
7754 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7755 break;
7756 case 2:
7757 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7758 break;
7759 default: abort();
7760 }
7761 break;
7762 case NEON_2RM_VQNEG:
7763 switch (size) {
7764 case 0:
7765 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7766 break;
7767 case 1:
7768 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7769 break;
7770 case 2:
7771 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7772 break;
7773 default: abort();
7774 }
7775 break;
7776 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7777 tmp2 = tcg_const_i32(0);
7778 switch(size) {
7779 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7780 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7781 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7782 default: abort();
7783 }
7784 tcg_temp_free_i32(tmp2);
7785 if (op == NEON_2RM_VCLE0) {
7786 tcg_gen_not_i32(tmp, tmp);
7787 }
7788 break;
7789 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7790 tmp2 = tcg_const_i32(0);
7791 switch(size) {
7792 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7793 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7794 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7795 default: abort();
7796 }
7797 tcg_temp_free_i32(tmp2);
7798 if (op == NEON_2RM_VCLT0) {
7799 tcg_gen_not_i32(tmp, tmp);
7800 }
7801 break;
7802 case NEON_2RM_VCEQ0:
7803 tmp2 = tcg_const_i32(0);
7804 switch(size) {
7805 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7806 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7807 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7808 default: abort();
7809 }
7810 tcg_temp_free_i32(tmp2);
7811 break;
7812 case NEON_2RM_VCGT0_F:
7813 {
7814 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7815 tmp2 = tcg_const_i32(0);
7816 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7817 tcg_temp_free_i32(tmp2);
7818 tcg_temp_free_ptr(fpstatus);
7819 break;
7820 }
7821 case NEON_2RM_VCGE0_F:
7822 {
7823 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7824 tmp2 = tcg_const_i32(0);
7825 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7826 tcg_temp_free_i32(tmp2);
7827 tcg_temp_free_ptr(fpstatus);
7828 break;
7829 }
7830 case NEON_2RM_VCEQ0_F:
7831 {
7832 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7833 tmp2 = tcg_const_i32(0);
7834 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7835 tcg_temp_free_i32(tmp2);
7836 tcg_temp_free_ptr(fpstatus);
7837 break;
7838 }
7839 case NEON_2RM_VCLE0_F:
7840 {
7841 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7842 tmp2 = tcg_const_i32(0);
7843 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7844 tcg_temp_free_i32(tmp2);
7845 tcg_temp_free_ptr(fpstatus);
7846 break;
7847 }
7848 case NEON_2RM_VCLT0_F:
7849 {
7850 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7851 tmp2 = tcg_const_i32(0);
7852 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7853 tcg_temp_free_i32(tmp2);
7854 tcg_temp_free_ptr(fpstatus);
7855 break;
7856 }
7857 case NEON_2RM_VABS_F:
7858 gen_vfp_abs(0);
7859 break;
7860 case NEON_2RM_VNEG_F:
7861 gen_vfp_neg(0);
7862 break;
7863 case NEON_2RM_VSWP:
7864 tmp2 = neon_load_reg(rd, pass);
7865 neon_store_reg(rm, pass, tmp2);
7866 break;
7867 case NEON_2RM_VTRN:
7868 tmp2 = neon_load_reg(rd, pass);
7869 switch (size) {
7870 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7871 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7872 default: abort();
7873 }
7874 neon_store_reg(rm, pass, tmp2);
7875 break;
7876 case NEON_2RM_VRINTN:
7877 case NEON_2RM_VRINTA:
7878 case NEON_2RM_VRINTM:
7879 case NEON_2RM_VRINTP:
7880 case NEON_2RM_VRINTZ:
7881 {
7882 TCGv_i32 tcg_rmode;
7883 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7884 int rmode;
7885
7886 if (op == NEON_2RM_VRINTZ) {
7887 rmode = FPROUNDING_ZERO;
7888 } else {
7889 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7890 }
7891
7892 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7893 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7894 cpu_env);
7895 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7896 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7897 cpu_env);
7898 tcg_temp_free_ptr(fpstatus);
7899 tcg_temp_free_i32(tcg_rmode);
7900 break;
7901 }
7902 case NEON_2RM_VRINTX:
7903 {
7904 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7905 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7906 tcg_temp_free_ptr(fpstatus);
7907 break;
7908 }
7909 case NEON_2RM_VCVTAU:
7910 case NEON_2RM_VCVTAS:
7911 case NEON_2RM_VCVTNU:
7912 case NEON_2RM_VCVTNS:
7913 case NEON_2RM_VCVTPU:
7914 case NEON_2RM_VCVTPS:
7915 case NEON_2RM_VCVTMU:
7916 case NEON_2RM_VCVTMS:
7917 {
7918 bool is_signed = !extract32(insn, 7, 1);
7919 TCGv_ptr fpst = get_fpstatus_ptr(1);
7920 TCGv_i32 tcg_rmode, tcg_shift;
7921 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7922
7923 tcg_shift = tcg_const_i32(0);
7924 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7925 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7926 cpu_env);
7927
7928 if (is_signed) {
7929 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7930 tcg_shift, fpst);
7931 } else {
7932 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7933 tcg_shift, fpst);
7934 }
7935
7936 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7937 cpu_env);
7938 tcg_temp_free_i32(tcg_rmode);
7939 tcg_temp_free_i32(tcg_shift);
7940 tcg_temp_free_ptr(fpst);
7941 break;
7942 }
7943 case NEON_2RM_VRECPE:
7944 {
7945 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7946 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7947 tcg_temp_free_ptr(fpstatus);
7948 break;
7949 }
7950 case NEON_2RM_VRSQRTE:
7951 {
7952 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7953 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7954 tcg_temp_free_ptr(fpstatus);
7955 break;
7956 }
7957 case NEON_2RM_VRECPE_F:
7958 {
7959 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7960 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7961 tcg_temp_free_ptr(fpstatus);
7962 break;
7963 }
7964 case NEON_2RM_VRSQRTE_F:
7965 {
7966 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7967 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7968 tcg_temp_free_ptr(fpstatus);
7969 break;
7970 }
7971 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7972 gen_vfp_sito(0, 1);
7973 break;
7974 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7975 gen_vfp_uito(0, 1);
7976 break;
7977 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7978 gen_vfp_tosiz(0, 1);
7979 break;
7980 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7981 gen_vfp_touiz(0, 1);
7982 break;
7983 default:
7984 /* Reserved op values were caught by the
7985 * neon_2rm_sizes[] check earlier.
7986 */
7987 abort();
7988 }
7989 if (neon_2rm_is_float_op(op)) {
7990 tcg_gen_st_f32(cpu_F0s, cpu_env,
7991 neon_reg_offset(rd, pass));
7992 } else {
7993 neon_store_reg(rd, pass, tmp);
7994 }
7995 }
7996 break;
7997 }
7998 } else if ((insn & (1 << 10)) == 0) {
7999 /* VTBL, VTBX. */
8000 int n = ((insn >> 8) & 3) + 1;
8001 if ((rn + n) > 32) {
8002 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8003 * helper function running off the end of the register file.
8004 */
8005 return 1;
8006 }
8007 n <<= 3;
8008 if (insn & (1 << 6)) {
8009 tmp = neon_load_reg(rd, 0);
8010 } else {
8011 tmp = tcg_temp_new_i32();
8012 tcg_gen_movi_i32(tmp, 0);
8013 }
8014 tmp2 = neon_load_reg(rm, 0);
8015 ptr1 = vfp_reg_ptr(true, rn);
8016 tmp5 = tcg_const_i32(n);
8017 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
8018 tcg_temp_free_i32(tmp);
8019 if (insn & (1 << 6)) {
8020 tmp = neon_load_reg(rd, 1);
8021 } else {
8022 tmp = tcg_temp_new_i32();
8023 tcg_gen_movi_i32(tmp, 0);
8024 }
8025 tmp3 = neon_load_reg(rm, 1);
8026 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
8027 tcg_temp_free_i32(tmp5);
8028 tcg_temp_free_ptr(ptr1);
8029 neon_store_reg(rd, 0, tmp2);
8030 neon_store_reg(rd, 1, tmp3);
8031 tcg_temp_free_i32(tmp);
8032 } else if ((insn & 0x380) == 0) {
8033 /* VDUP */
8034 int element;
8035 TCGMemOp size;
8036
8037 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
8038 return 1;
8039 }
8040 if (insn & (1 << 16)) {
8041 size = MO_8;
8042 element = (insn >> 17) & 7;
8043 } else if (insn & (1 << 17)) {
8044 size = MO_16;
8045 element = (insn >> 18) & 3;
8046 } else {
8047 size = MO_32;
8048 element = (insn >> 19) & 1;
8049 }
8050 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
8051 neon_element_offset(rm, element, size),
8052 q ? 16 : 8, q ? 16 : 8);
8053 } else {
8054 return 1;
8055 }
8056 }
8057 }
8058 return 0;
8059 }
8060
8061 /* Advanced SIMD three registers of the same length extension.
8062 * 31 25 23 22 20 16 12 11 10 9 8 3 0
8063 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8064 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8065 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8066 */
8067 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
8068 {
8069 gen_helper_gvec_3 *fn_gvec = NULL;
8070 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8071 int rd, rn, rm, opr_sz;
8072 int data = 0;
8073 int off_rn, off_rm;
8074 bool is_long = false, q = extract32(insn, 6, 1);
8075 bool ptr_is_env = false;
8076
8077 if ((insn & 0xfe200f10) == 0xfc200800) {
8078 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8079 int size = extract32(insn, 20, 1);
8080 data = extract32(insn, 23, 2); /* rot */
8081 if (!dc_isar_feature(aa32_vcma, s)
8082 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8083 return 1;
8084 }
8085 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
8086 } else if ((insn & 0xfea00f10) == 0xfc800800) {
8087 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8088 int size = extract32(insn, 20, 1);
8089 data = extract32(insn, 24, 1); /* rot */
8090 if (!dc_isar_feature(aa32_vcma, s)
8091 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8092 return 1;
8093 }
8094 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
8095 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
8096 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8097 bool u = extract32(insn, 4, 1);
8098 if (!dc_isar_feature(aa32_dp, s)) {
8099 return 1;
8100 }
8101 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
8102 } else if ((insn & 0xff300f10) == 0xfc200810) {
8103 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
8104 int is_s = extract32(insn, 23, 1);
8105 if (!dc_isar_feature(aa32_fhm, s)) {
8106 return 1;
8107 }
8108 is_long = true;
8109 data = is_s; /* is_2 == 0 */
8110 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
8111 ptr_is_env = true;
8112 } else {
8113 return 1;
8114 }
8115
8116 VFP_DREG_D(rd, insn);
8117 if (rd & q) {
8118 return 1;
8119 }
8120 if (q || !is_long) {
8121 VFP_DREG_N(rn, insn);
8122 VFP_DREG_M(rm, insn);
8123 if ((rn | rm) & q & !is_long) {
8124 return 1;
8125 }
8126 off_rn = vfp_reg_offset(1, rn);
8127 off_rm = vfp_reg_offset(1, rm);
8128 } else {
8129 rn = VFP_SREG_N(insn);
8130 rm = VFP_SREG_M(insn);
8131 off_rn = vfp_reg_offset(0, rn);
8132 off_rm = vfp_reg_offset(0, rm);
8133 }
8134
8135 if (s->fp_excp_el) {
8136 gen_exception_insn(s, 4, EXCP_UDEF,
8137 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8138 return 0;
8139 }
8140 if (!s->vfp_enabled) {
8141 return 1;
8142 }
8143
8144 opr_sz = (1 + q) * 8;
8145 if (fn_gvec_ptr) {
8146 TCGv_ptr ptr;
8147 if (ptr_is_env) {
8148 ptr = cpu_env;
8149 } else {
8150 ptr = get_fpstatus_ptr(1);
8151 }
8152 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
8153 opr_sz, opr_sz, data, fn_gvec_ptr);
8154 if (!ptr_is_env) {
8155 tcg_temp_free_ptr(ptr);
8156 }
8157 } else {
8158 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
8159 opr_sz, opr_sz, data, fn_gvec);
8160 }
8161 return 0;
8162 }
8163
8164 /* Advanced SIMD two registers and a scalar extension.
8165 * 31 24 23 22 20 16 12 11 10 9 8 3 0
8166 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8167 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8168 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8169 *
8170 */
8171
8172 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
8173 {
8174 gen_helper_gvec_3 *fn_gvec = NULL;
8175 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8176 int rd, rn, rm, opr_sz, data;
8177 int off_rn, off_rm;
8178 bool is_long = false, q = extract32(insn, 6, 1);
8179 bool ptr_is_env = false;
8180
8181 if ((insn & 0xff000f10) == 0xfe000800) {
8182 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8183 int rot = extract32(insn, 20, 2);
8184 int size = extract32(insn, 23, 1);
8185 int index;
8186
8187 if (!dc_isar_feature(aa32_vcma, s)) {
8188 return 1;
8189 }
8190 if (size == 0) {
8191 if (!dc_isar_feature(aa32_fp16_arith, s)) {
8192 return 1;
8193 }
8194 /* For fp16, rm is just Vm, and index is M. */
8195 rm = extract32(insn, 0, 4);
8196 index = extract32(insn, 5, 1);
8197 } else {
8198 /* For fp32, rm is the usual M:Vm, and index is 0. */
8199 VFP_DREG_M(rm, insn);
8200 index = 0;
8201 }
8202 data = (index << 2) | rot;
8203 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8204 : gen_helper_gvec_fcmlah_idx);
8205 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8206 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8207 int u = extract32(insn, 4, 1);
8208
8209 if (!dc_isar_feature(aa32_dp, s)) {
8210 return 1;
8211 }
8212 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8213 /* rm is just Vm, and index is M. */
8214 data = extract32(insn, 5, 1); /* index */
8215 rm = extract32(insn, 0, 4);
8216 } else if ((insn & 0xffa00f10) == 0xfe000810) {
8217 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
8218 int is_s = extract32(insn, 20, 1);
8219 int vm20 = extract32(insn, 0, 3);
8220 int vm3 = extract32(insn, 3, 1);
8221 int m = extract32(insn, 5, 1);
8222 int index;
8223
8224 if (!dc_isar_feature(aa32_fhm, s)) {
8225 return 1;
8226 }
8227 if (q) {
8228 rm = vm20;
8229 index = m * 2 + vm3;
8230 } else {
8231 rm = vm20 * 2 + m;
8232 index = vm3;
8233 }
8234 is_long = true;
8235 data = (index << 2) | is_s; /* is_2 == 0 */
8236 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
8237 ptr_is_env = true;
8238 } else {
8239 return 1;
8240 }
8241
8242 VFP_DREG_D(rd, insn);
8243 if (rd & q) {
8244 return 1;
8245 }
8246 if (q || !is_long) {
8247 VFP_DREG_N(rn, insn);
8248 if (rn & q & !is_long) {
8249 return 1;
8250 }
8251 off_rn = vfp_reg_offset(1, rn);
8252 off_rm = vfp_reg_offset(1, rm);
8253 } else {
8254 rn = VFP_SREG_N(insn);
8255 off_rn = vfp_reg_offset(0, rn);
8256 off_rm = vfp_reg_offset(0, rm);
8257 }
8258 if (s->fp_excp_el) {
8259 gen_exception_insn(s, 4, EXCP_UDEF,
8260 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8261 return 0;
8262 }
8263 if (!s->vfp_enabled) {
8264 return 1;
8265 }
8266
8267 opr_sz = (1 + q) * 8;
8268 if (fn_gvec_ptr) {
8269 TCGv_ptr ptr;
8270 if (ptr_is_env) {
8271 ptr = cpu_env;
8272 } else {
8273 ptr = get_fpstatus_ptr(1);
8274 }
8275 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
8276 opr_sz, opr_sz, data, fn_gvec_ptr);
8277 if (!ptr_is_env) {
8278 tcg_temp_free_ptr(ptr);
8279 }
8280 } else {
8281 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
8282 opr_sz, opr_sz, data, fn_gvec);
8283 }
8284 return 0;
8285 }
8286
8287 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8288 {
8289 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8290 const ARMCPRegInfo *ri;
8291
8292 cpnum = (insn >> 8) & 0xf;
8293
8294 /* First check for coprocessor space used for XScale/iwMMXt insns */
8295 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8296 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8297 return 1;
8298 }
8299 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8300 return disas_iwmmxt_insn(s, insn);
8301 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8302 return disas_dsp_insn(s, insn);
8303 }
8304 return 1;
8305 }
8306
8307 /* Otherwise treat as a generic register access */
8308 is64 = (insn & (1 << 25)) == 0;
8309 if (!is64 && ((insn & (1 << 4)) == 0)) {
8310 /* cdp */
8311 return 1;
8312 }
8313
8314 crm = insn & 0xf;
8315 if (is64) {
8316 crn = 0;
8317 opc1 = (insn >> 4) & 0xf;
8318 opc2 = 0;
8319 rt2 = (insn >> 16) & 0xf;
8320 } else {
8321 crn = (insn >> 16) & 0xf;
8322 opc1 = (insn >> 21) & 7;
8323 opc2 = (insn >> 5) & 7;
8324 rt2 = 0;
8325 }
8326 isread = (insn >> 20) & 1;
8327 rt = (insn >> 12) & 0xf;
8328
8329 ri = get_arm_cp_reginfo(s->cp_regs,
8330 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8331 if (ri) {
8332 /* Check access permissions */
8333 if (!cp_access_ok(s->current_el, ri, isread)) {
8334 return 1;
8335 }
8336
8337 if (ri->accessfn ||
8338 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8339 /* Emit code to perform further access permissions checks at
8340 * runtime; this may result in an exception.
8341 * Note that on XScale all cp0..c13 registers do an access check
8342 * call in order to handle c15_cpar.
8343 */
8344 TCGv_ptr tmpptr;
8345 TCGv_i32 tcg_syn, tcg_isread;
8346 uint32_t syndrome;
8347
8348 /* Note that since we are an implementation which takes an
8349 * exception on a trapped conditional instruction only if the
8350 * instruction passes its condition code check, we can take
8351 * advantage of the clause in the ARM ARM that allows us to set
8352 * the COND field in the instruction to 0xE in all cases.
8353 * We could fish the actual condition out of the insn (ARM)
8354 * or the condexec bits (Thumb) but it isn't necessary.
8355 */
8356 switch (cpnum) {
8357 case 14:
8358 if (is64) {
8359 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8360 isread, false);
8361 } else {
8362 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8363 rt, isread, false);
8364 }
8365 break;
8366 case 15:
8367 if (is64) {
8368 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8369 isread, false);
8370 } else {
8371 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8372 rt, isread, false);
8373 }
8374 break;
8375 default:
8376 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8377 * so this can only happen if this is an ARMv7 or earlier CPU,
8378 * in which case the syndrome information won't actually be
8379 * guest visible.
8380 */
8381 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8382 syndrome = syn_uncategorized();
8383 break;
8384 }
8385
8386 gen_set_condexec(s);
8387 gen_set_pc_im(s, s->pc - 4);
8388 tmpptr = tcg_const_ptr(ri);
8389 tcg_syn = tcg_const_i32(syndrome);
8390 tcg_isread = tcg_const_i32(isread);
8391 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8392 tcg_isread);
8393 tcg_temp_free_ptr(tmpptr);
8394 tcg_temp_free_i32(tcg_syn);
8395 tcg_temp_free_i32(tcg_isread);
8396 }
8397
8398 /* Handle special cases first */
8399 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8400 case ARM_CP_NOP:
8401 return 0;
8402 case ARM_CP_WFI:
8403 if (isread) {
8404 return 1;
8405 }
8406 gen_set_pc_im(s, s->pc);
8407 s->base.is_jmp = DISAS_WFI;
8408 return 0;
8409 default:
8410 break;
8411 }
8412
8413 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8414 gen_io_start();
8415 }
8416
8417 if (isread) {
8418 /* Read */
8419 if (is64) {
8420 TCGv_i64 tmp64;
8421 TCGv_i32 tmp;
8422 if (ri->type & ARM_CP_CONST) {
8423 tmp64 = tcg_const_i64(ri->resetvalue);
8424 } else if (ri->readfn) {
8425 TCGv_ptr tmpptr;
8426 tmp64 = tcg_temp_new_i64();
8427 tmpptr = tcg_const_ptr(ri);
8428 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8429 tcg_temp_free_ptr(tmpptr);
8430 } else {
8431 tmp64 = tcg_temp_new_i64();
8432 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8433 }
8434 tmp = tcg_temp_new_i32();
8435 tcg_gen_extrl_i64_i32(tmp, tmp64);
8436 store_reg(s, rt, tmp);
8437 tcg_gen_shri_i64(tmp64, tmp64, 32);
8438 tmp = tcg_temp_new_i32();
8439 tcg_gen_extrl_i64_i32(tmp, tmp64);
8440 tcg_temp_free_i64(tmp64);
8441 store_reg(s, rt2, tmp);
8442 } else {
8443 TCGv_i32 tmp;
8444 if (ri->type & ARM_CP_CONST) {
8445 tmp = tcg_const_i32(ri->resetvalue);
8446 } else if (ri->readfn) {
8447 TCGv_ptr tmpptr;
8448 tmp = tcg_temp_new_i32();
8449 tmpptr = tcg_const_ptr(ri);
8450 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8451 tcg_temp_free_ptr(tmpptr);
8452 } else {
8453 tmp = load_cpu_offset(ri->fieldoffset);
8454 }
8455 if (rt == 15) {
8456 /* Destination register of r15 for 32 bit loads sets
8457 * the condition codes from the high 4 bits of the value
8458 */
8459 gen_set_nzcv(tmp);
8460 tcg_temp_free_i32(tmp);
8461 } else {
8462 store_reg(s, rt, tmp);
8463 }
8464 }
8465 } else {
8466 /* Write */
8467 if (ri->type & ARM_CP_CONST) {
8468 /* If not forbidden by access permissions, treat as WI */
8469 return 0;
8470 }
8471
8472 if (is64) {
8473 TCGv_i32 tmplo, tmphi;
8474 TCGv_i64 tmp64 = tcg_temp_new_i64();
8475 tmplo = load_reg(s, rt);
8476 tmphi = load_reg(s, rt2);
8477 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8478 tcg_temp_free_i32(tmplo);
8479 tcg_temp_free_i32(tmphi);
8480 if (ri->writefn) {
8481 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8482 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8483 tcg_temp_free_ptr(tmpptr);
8484 } else {
8485 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8486 }
8487 tcg_temp_free_i64(tmp64);
8488 } else {
8489 if (ri->writefn) {
8490 TCGv_i32 tmp;
8491 TCGv_ptr tmpptr;
8492 tmp = load_reg(s, rt);
8493 tmpptr = tcg_const_ptr(ri);
8494 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8495 tcg_temp_free_ptr(tmpptr);
8496 tcg_temp_free_i32(tmp);
8497 } else {
8498 TCGv_i32 tmp = load_reg(s, rt);
8499 store_cpu_offset(tmp, ri->fieldoffset);
8500 }
8501 }
8502 }
8503
8504 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8505 /* I/O operations must end the TB here (whether read or write) */
8506 gen_io_end();
8507 gen_lookup_tb(s);
8508 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8509 /* We default to ending the TB on a coprocessor register write,
8510 * but allow this to be suppressed by the register definition
8511 * (usually only necessary to work around guest bugs).
8512 */
8513 gen_lookup_tb(s);
8514 }
8515
8516 return 0;
8517 }
8518
8519 /* Unknown register; this might be a guest error or a QEMU
8520 * unimplemented feature.
8521 */
8522 if (is64) {
8523 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8524 "64 bit system register cp:%d opc1: %d crm:%d "
8525 "(%s)\n",
8526 isread ? "read" : "write", cpnum, opc1, crm,
8527 s->ns ? "non-secure" : "secure");
8528 } else {
8529 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8530 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8531 "(%s)\n",
8532 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8533 s->ns ? "non-secure" : "secure");
8534 }
8535
8536 return 1;
8537 }
8538
8539
8540 /* Store a 64-bit value to a register pair. Clobbers val. */
8541 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8542 {
8543 TCGv_i32 tmp;
8544 tmp = tcg_temp_new_i32();
8545 tcg_gen_extrl_i64_i32(tmp, val);
8546 store_reg(s, rlow, tmp);
8547 tmp = tcg_temp_new_i32();
8548 tcg_gen_shri_i64(val, val, 32);
8549 tcg_gen_extrl_i64_i32(tmp, val);
8550 store_reg(s, rhigh, tmp);
8551 }
8552
8553 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8554 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8555 {
8556 TCGv_i64 tmp;
8557 TCGv_i32 tmp2;
8558
8559 /* Load value and extend to 64 bits. */
8560 tmp = tcg_temp_new_i64();
8561 tmp2 = load_reg(s, rlow);
8562 tcg_gen_extu_i32_i64(tmp, tmp2);
8563 tcg_temp_free_i32(tmp2);
8564 tcg_gen_add_i64(val, val, tmp);
8565 tcg_temp_free_i64(tmp);
8566 }
8567
8568 /* load and add a 64-bit value from a register pair. */
8569 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8570 {
8571 TCGv_i64 tmp;
8572 TCGv_i32 tmpl;
8573 TCGv_i32 tmph;
8574
8575 /* Load 64-bit value rd:rn. */
8576 tmpl = load_reg(s, rlow);
8577 tmph = load_reg(s, rhigh);
8578 tmp = tcg_temp_new_i64();
8579 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8580 tcg_temp_free_i32(tmpl);
8581 tcg_temp_free_i32(tmph);
8582 tcg_gen_add_i64(val, val, tmp);
8583 tcg_temp_free_i64(tmp);
8584 }
8585
8586 /* Set N and Z flags from hi|lo. */
8587 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8588 {
8589 tcg_gen_mov_i32(cpu_NF, hi);
8590 tcg_gen_or_i32(cpu_ZF, lo, hi);
8591 }
8592
8593 /* Load/Store exclusive instructions are implemented by remembering
8594 the value/address loaded, and seeing if these are the same
8595 when the store is performed. This should be sufficient to implement
8596 the architecturally mandated semantics, and avoids having to monitor
8597 regular stores. The compare vs the remembered value is done during
8598 the cmpxchg operation, but we must compare the addresses manually. */
8599 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8600 TCGv_i32 addr, int size)
8601 {
8602 TCGv_i32 tmp = tcg_temp_new_i32();
8603 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8604
8605 s->is_ldex = true;
8606
8607 if (size == 3) {
8608 TCGv_i32 tmp2 = tcg_temp_new_i32();
8609 TCGv_i64 t64 = tcg_temp_new_i64();
8610
8611 /* For AArch32, architecturally the 32-bit word at the lowest
8612 * address is always Rt and the one at addr+4 is Rt2, even if
8613 * the CPU is big-endian. That means we don't want to do a
8614 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8615 * for an architecturally 64-bit access, but instead do a
8616 * 64-bit access using MO_BE if appropriate and then split
8617 * the two halves.
8618 * This only makes a difference for BE32 user-mode, where
8619 * frob64() must not flip the two halves of the 64-bit data
8620 * but this code must treat BE32 user-mode like BE32 system.
8621 */
8622 TCGv taddr = gen_aa32_addr(s, addr, opc);
8623
8624 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8625 tcg_temp_free(taddr);
8626 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8627 if (s->be_data == MO_BE) {
8628 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8629 } else {
8630 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8631 }
8632 tcg_temp_free_i64(t64);
8633
8634 store_reg(s, rt2, tmp2);
8635 } else {
8636 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8637 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8638 }
8639
8640 store_reg(s, rt, tmp);
8641 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8642 }
8643
8644 static void gen_clrex(DisasContext *s)
8645 {
8646 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8647 }
8648
8649 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8650 TCGv_i32 addr, int size)
8651 {
8652 TCGv_i32 t0, t1, t2;
8653 TCGv_i64 extaddr;
8654 TCGv taddr;
8655 TCGLabel *done_label;
8656 TCGLabel *fail_label;
8657 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8658
8659 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8660 [addr] = {Rt};
8661 {Rd} = 0;
8662 } else {
8663 {Rd} = 1;
8664 } */
8665 fail_label = gen_new_label();
8666 done_label = gen_new_label();
8667 extaddr = tcg_temp_new_i64();
8668 tcg_gen_extu_i32_i64(extaddr, addr);
8669 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8670 tcg_temp_free_i64(extaddr);
8671
8672 taddr = gen_aa32_addr(s, addr, opc);
8673 t0 = tcg_temp_new_i32();
8674 t1 = load_reg(s, rt);
8675 if (size == 3) {
8676 TCGv_i64 o64 = tcg_temp_new_i64();
8677 TCGv_i64 n64 = tcg_temp_new_i64();
8678
8679 t2 = load_reg(s, rt2);
8680 /* For AArch32, architecturally the 32-bit word at the lowest
8681 * address is always Rt and the one at addr+4 is Rt2, even if
8682 * the CPU is big-endian. Since we're going to treat this as a
8683 * single 64-bit BE store, we need to put the two halves in the
8684 * opposite order for BE to LE, so that they end up in the right
8685 * places.
8686 * We don't want gen_aa32_frob64() because that does the wrong
8687 * thing for BE32 usermode.
8688 */
8689 if (s->be_data == MO_BE) {
8690 tcg_gen_concat_i32_i64(n64, t2, t1);
8691 } else {
8692 tcg_gen_concat_i32_i64(n64, t1, t2);
8693 }
8694 tcg_temp_free_i32(t2);
8695
8696 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8697 get_mem_index(s), opc);
8698 tcg_temp_free_i64(n64);
8699
8700 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8701 tcg_gen_extrl_i64_i32(t0, o64);
8702
8703 tcg_temp_free_i64(o64);
8704 } else {
8705 t2 = tcg_temp_new_i32();
8706 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8707 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8708 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8709 tcg_temp_free_i32(t2);
8710 }
8711 tcg_temp_free_i32(t1);
8712 tcg_temp_free(taddr);
8713 tcg_gen_mov_i32(cpu_R[rd], t0);
8714 tcg_temp_free_i32(t0);
8715 tcg_gen_br(done_label);
8716
8717 gen_set_label(fail_label);
8718 tcg_gen_movi_i32(cpu_R[rd], 1);
8719 gen_set_label(done_label);
8720 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8721 }
8722
8723 /* gen_srs:
8724 * @env: CPUARMState
8725 * @s: DisasContext
8726 * @mode: mode field from insn (which stack to store to)
8727 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8728 * @writeback: true if writeback bit set
8729 *
8730 * Generate code for the SRS (Store Return State) insn.
8731 */
8732 static void gen_srs(DisasContext *s,
8733 uint32_t mode, uint32_t amode, bool writeback)
8734 {
8735 int32_t offset;
8736 TCGv_i32 addr, tmp;
8737 bool undef = false;
8738
8739 /* SRS is:
8740 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8741 * and specified mode is monitor mode
8742 * - UNDEFINED in Hyp mode
8743 * - UNPREDICTABLE in User or System mode
8744 * - UNPREDICTABLE if the specified mode is:
8745 * -- not implemented
8746 * -- not a valid mode number
8747 * -- a mode that's at a higher exception level
8748 * -- Monitor, if we are Non-secure
8749 * For the UNPREDICTABLE cases we choose to UNDEF.
8750 */
8751 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8752 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8753 return;
8754 }
8755
8756 if (s->current_el == 0 || s->current_el == 2) {
8757 undef = true;
8758 }
8759
8760 switch (mode) {
8761 case ARM_CPU_MODE_USR:
8762 case ARM_CPU_MODE_FIQ:
8763 case ARM_CPU_MODE_IRQ:
8764 case ARM_CPU_MODE_SVC:
8765 case ARM_CPU_MODE_ABT:
8766 case ARM_CPU_MODE_UND:
8767 case ARM_CPU_MODE_SYS:
8768 break;
8769 case ARM_CPU_MODE_HYP:
8770 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8771 undef = true;
8772 }
8773 break;
8774 case ARM_CPU_MODE_MON:
8775 /* No need to check specifically for "are we non-secure" because
8776 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8777 * so if this isn't EL3 then we must be non-secure.
8778 */
8779 if (s->current_el != 3) {
8780 undef = true;
8781 }
8782 break;
8783 default:
8784 undef = true;
8785 }
8786
8787 if (undef) {
8788 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8789 default_exception_el(s));
8790 return;
8791 }
8792
8793 addr = tcg_temp_new_i32();
8794 tmp = tcg_const_i32(mode);
8795 /* get_r13_banked() will raise an exception if called from System mode */
8796 gen_set_condexec(s);
8797 gen_set_pc_im(s, s->pc - 4);
8798 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8799 tcg_temp_free_i32(tmp);
8800 switch (amode) {
8801 case 0: /* DA */
8802 offset = -4;
8803 break;
8804 case 1: /* IA */
8805 offset = 0;
8806 break;
8807 case 2: /* DB */
8808 offset = -8;
8809 break;
8810 case 3: /* IB */
8811 offset = 4;
8812 break;
8813 default:
8814 abort();
8815 }
8816 tcg_gen_addi_i32(addr, addr, offset);
8817 tmp = load_reg(s, 14);
8818 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8819 tcg_temp_free_i32(tmp);
8820 tmp = load_cpu_field(spsr);
8821 tcg_gen_addi_i32(addr, addr, 4);
8822 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8823 tcg_temp_free_i32(tmp);
8824 if (writeback) {
8825 switch (amode) {
8826 case 0:
8827 offset = -8;
8828 break;
8829 case 1:
8830 offset = 4;
8831 break;
8832 case 2:
8833 offset = -4;
8834 break;
8835 case 3:
8836 offset = 0;
8837 break;
8838 default:
8839 abort();
8840 }
8841 tcg_gen_addi_i32(addr, addr, offset);
8842 tmp = tcg_const_i32(mode);
8843 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8844 tcg_temp_free_i32(tmp);
8845 }
8846 tcg_temp_free_i32(addr);
8847 s->base.is_jmp = DISAS_UPDATE;
8848 }
8849
8850 /* Generate a label used for skipping this instruction */
8851 static void arm_gen_condlabel(DisasContext *s)
8852 {
8853 if (!s->condjmp) {
8854 s->condlabel = gen_new_label();
8855 s->condjmp = 1;
8856 }
8857 }
8858
8859 /* Skip this instruction if the ARM condition is false */
8860 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8861 {
8862 arm_gen_condlabel(s);
8863 arm_gen_test_cc(cond ^ 1, s->condlabel);
8864 }
8865
8866 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8867 {
8868 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8869 TCGv_i32 tmp;
8870 TCGv_i32 tmp2;
8871 TCGv_i32 tmp3;
8872 TCGv_i32 addr;
8873 TCGv_i64 tmp64;
8874
8875 /* M variants do not implement ARM mode; this must raise the INVSTATE
8876 * UsageFault exception.
8877 */
8878 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8879 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8880 default_exception_el(s));
8881 return;
8882 }
8883 cond = insn >> 28;
8884 if (cond == 0xf){
8885 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8886 * choose to UNDEF. In ARMv5 and above the space is used
8887 * for miscellaneous unconditional instructions.
8888 */
8889 ARCH(5);
8890
8891 /* Unconditional instructions. */
8892 if (((insn >> 25) & 7) == 1) {
8893 /* NEON Data processing. */
8894 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8895 goto illegal_op;
8896 }
8897
8898 if (disas_neon_data_insn(s, insn)) {
8899 goto illegal_op;
8900 }
8901 return;
8902 }
8903 if ((insn & 0x0f100000) == 0x04000000) {
8904 /* NEON load/store. */
8905 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8906 goto illegal_op;
8907 }
8908
8909 if (disas_neon_ls_insn(s, insn)) {
8910 goto illegal_op;
8911 }
8912 return;
8913 }
8914 if ((insn & 0x0f000e10) == 0x0e000a00) {
8915 /* VFP. */
8916 if (disas_vfp_insn(s, insn)) {
8917 goto illegal_op;
8918 }
8919 return;
8920 }
8921 if (((insn & 0x0f30f000) == 0x0510f000) ||
8922 ((insn & 0x0f30f010) == 0x0710f000)) {
8923 if ((insn & (1 << 22)) == 0) {
8924 /* PLDW; v7MP */
8925 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8926 goto illegal_op;
8927 }
8928 }
8929 /* Otherwise PLD; v5TE+ */
8930 ARCH(5TE);
8931 return;
8932 }
8933 if (((insn & 0x0f70f000) == 0x0450f000) ||
8934 ((insn & 0x0f70f010) == 0x0650f000)) {
8935 ARCH(7);
8936 return; /* PLI; V7 */
8937 }
8938 if (((insn & 0x0f700000) == 0x04100000) ||
8939 ((insn & 0x0f700010) == 0x06100000)) {
8940 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8941 goto illegal_op;
8942 }
8943 return; /* v7MP: Unallocated memory hint: must NOP */
8944 }
8945
8946 if ((insn & 0x0ffffdff) == 0x01010000) {
8947 ARCH(6);
8948 /* setend */
8949 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8950 gen_helper_setend(cpu_env);
8951 s->base.is_jmp = DISAS_UPDATE;
8952 }
8953 return;
8954 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8955 switch ((insn >> 4) & 0xf) {
8956 case 1: /* clrex */
8957 ARCH(6K);
8958 gen_clrex(s);
8959 return;
8960 case 4: /* dsb */
8961 case 5: /* dmb */
8962 ARCH(7);
8963 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8964 return;
8965 case 6: /* isb */
8966 /* We need to break the TB after this insn to execute
8967 * self-modifying code correctly and also to take
8968 * any pending interrupts immediately.
8969 */
8970 gen_goto_tb(s, 0, s->pc & ~1);
8971 return;
8972 case 7: /* sb */
8973 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
8974 goto illegal_op;
8975 }
8976 /*
8977 * TODO: There is no speculation barrier opcode
8978 * for TCG; MB and end the TB instead.
8979 */
8980 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8981 gen_goto_tb(s, 0, s->pc & ~1);
8982 return;
8983 default:
8984 goto illegal_op;
8985 }
8986 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8987 /* srs */
8988 ARCH(6);
8989 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8990 return;
8991 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8992 /* rfe */
8993 int32_t offset;
8994 if (IS_USER(s))
8995 goto illegal_op;
8996 ARCH(6);
8997 rn = (insn >> 16) & 0xf;
8998 addr = load_reg(s, rn);
8999 i = (insn >> 23) & 3;
9000 switch (i) {
9001 case 0: offset = -4; break; /* DA */
9002 case 1: offset = 0; break; /* IA */
9003 case 2: offset = -8; break; /* DB */
9004 case 3: offset = 4; break; /* IB */
9005 default: abort();
9006 }
9007 if (offset)
9008 tcg_gen_addi_i32(addr, addr, offset);
9009 /* Load PC into tmp and CPSR into tmp2. */
9010 tmp = tcg_temp_new_i32();
9011 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9012 tcg_gen_addi_i32(addr, addr, 4);
9013 tmp2 = tcg_temp_new_i32();
9014 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9015 if (insn & (1 << 21)) {
9016 /* Base writeback. */
9017 switch (i) {
9018 case 0: offset = -8; break;
9019 case 1: offset = 4; break;
9020 case 2: offset = -4; break;
9021 case 3: offset = 0; break;
9022 default: abort();
9023 }
9024 if (offset)
9025 tcg_gen_addi_i32(addr, addr, offset);
9026 store_reg(s, rn, addr);
9027 } else {
9028 tcg_temp_free_i32(addr);
9029 }
9030 gen_rfe(s, tmp, tmp2);
9031 return;
9032 } else if ((insn & 0x0e000000) == 0x0a000000) {
9033 /* branch link and change to thumb (blx <offset>) */
9034 int32_t offset;
9035
9036 val = (uint32_t)s->pc;
9037 tmp = tcg_temp_new_i32();
9038 tcg_gen_movi_i32(tmp, val);
9039 store_reg(s, 14, tmp);
9040 /* Sign-extend the 24-bit offset */
9041 offset = (((int32_t)insn) << 8) >> 8;
9042 /* offset * 4 + bit24 * 2 + (thumb bit) */
9043 val += (offset << 2) | ((insn >> 23) & 2) | 1;
9044 /* pipeline offset */
9045 val += 4;
9046 /* protected by ARCH(5); above, near the start of uncond block */
9047 gen_bx_im(s, val);
9048 return;
9049 } else if ((insn & 0x0e000f00) == 0x0c000100) {
9050 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9051 /* iWMMXt register transfer. */
9052 if (extract32(s->c15_cpar, 1, 1)) {
9053 if (!disas_iwmmxt_insn(s, insn)) {
9054 return;
9055 }
9056 }
9057 }
9058 } else if ((insn & 0x0e000a00) == 0x0c000800
9059 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9060 if (disas_neon_insn_3same_ext(s, insn)) {
9061 goto illegal_op;
9062 }
9063 return;
9064 } else if ((insn & 0x0f000a00) == 0x0e000800
9065 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9066 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
9067 goto illegal_op;
9068 }
9069 return;
9070 } else if ((insn & 0x0fe00000) == 0x0c400000) {
9071 /* Coprocessor double register transfer. */
9072 ARCH(5TE);
9073 } else if ((insn & 0x0f000010) == 0x0e000010) {
9074 /* Additional coprocessor register transfer. */
9075 } else if ((insn & 0x0ff10020) == 0x01000000) {
9076 uint32_t mask;
9077 uint32_t val;
9078 /* cps (privileged) */
9079 if (IS_USER(s))
9080 return;
9081 mask = val = 0;
9082 if (insn & (1 << 19)) {
9083 if (insn & (1 << 8))
9084 mask |= CPSR_A;
9085 if (insn & (1 << 7))
9086 mask |= CPSR_I;
9087 if (insn & (1 << 6))
9088 mask |= CPSR_F;
9089 if (insn & (1 << 18))
9090 val |= mask;
9091 }
9092 if (insn & (1 << 17)) {
9093 mask |= CPSR_M;
9094 val |= (insn & 0x1f);
9095 }
9096 if (mask) {
9097 gen_set_psr_im(s, mask, 0, val);
9098 }
9099 return;
9100 }
9101 goto illegal_op;
9102 }
9103 if (cond != 0xe) {
9104 /* if not always execute, we generate a conditional jump to
9105 next instruction */
9106 arm_skip_unless(s, cond);
9107 }
9108 if ((insn & 0x0f900000) == 0x03000000) {
9109 if ((insn & (1 << 21)) == 0) {
9110 ARCH(6T2);
9111 rd = (insn >> 12) & 0xf;
9112 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
9113 if ((insn & (1 << 22)) == 0) {
9114 /* MOVW */
9115 tmp = tcg_temp_new_i32();
9116 tcg_gen_movi_i32(tmp, val);
9117 } else {
9118 /* MOVT */
9119 tmp = load_reg(s, rd);
9120 tcg_gen_ext16u_i32(tmp, tmp);
9121 tcg_gen_ori_i32(tmp, tmp, val << 16);
9122 }
9123 store_reg(s, rd, tmp);
9124 } else {
9125 if (((insn >> 12) & 0xf) != 0xf)
9126 goto illegal_op;
9127 if (((insn >> 16) & 0xf) == 0) {
9128 gen_nop_hint(s, insn & 0xff);
9129 } else {
9130 /* CPSR = immediate */
9131 val = insn & 0xff;
9132 shift = ((insn >> 8) & 0xf) * 2;
9133 if (shift)
9134 val = (val >> shift) | (val << (32 - shift));
9135 i = ((insn & (1 << 22)) != 0);
9136 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
9137 i, val)) {
9138 goto illegal_op;
9139 }
9140 }
9141 }
9142 } else if ((insn & 0x0f900000) == 0x01000000
9143 && (insn & 0x00000090) != 0x00000090) {
9144 /* miscellaneous instructions */
9145 op1 = (insn >> 21) & 3;
9146 sh = (insn >> 4) & 0xf;
9147 rm = insn & 0xf;
9148 switch (sh) {
9149 case 0x0: /* MSR, MRS */
9150 if (insn & (1 << 9)) {
9151 /* MSR (banked) and MRS (banked) */
9152 int sysm = extract32(insn, 16, 4) |
9153 (extract32(insn, 8, 1) << 4);
9154 int r = extract32(insn, 22, 1);
9155
9156 if (op1 & 1) {
9157 /* MSR (banked) */
9158 gen_msr_banked(s, r, sysm, rm);
9159 } else {
9160 /* MRS (banked) */
9161 int rd = extract32(insn, 12, 4);
9162
9163 gen_mrs_banked(s, r, sysm, rd);
9164 }
9165 break;
9166 }
9167
9168 /* MSR, MRS (for PSRs) */
9169 if (op1 & 1) {
9170 /* PSR = reg */
9171 tmp = load_reg(s, rm);
9172 i = ((op1 & 2) != 0);
9173 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
9174 goto illegal_op;
9175 } else {
9176 /* reg = PSR */
9177 rd = (insn >> 12) & 0xf;
9178 if (op1 & 2) {
9179 if (IS_USER(s))
9180 goto illegal_op;
9181 tmp = load_cpu_field(spsr);
9182 } else {
9183 tmp = tcg_temp_new_i32();
9184 gen_helper_cpsr_read(tmp, cpu_env);
9185 }
9186 store_reg(s, rd, tmp);
9187 }
9188 break;
9189 case 0x1:
9190 if (op1 == 1) {
9191 /* branch/exchange thumb (bx). */
9192 ARCH(4T);
9193 tmp = load_reg(s, rm);
9194 gen_bx(s, tmp);
9195 } else if (op1 == 3) {
9196 /* clz */
9197 ARCH(5);
9198 rd = (insn >> 12) & 0xf;
9199 tmp = load_reg(s, rm);
9200 tcg_gen_clzi_i32(tmp, tmp, 32);
9201 store_reg(s, rd, tmp);
9202 } else {
9203 goto illegal_op;
9204 }
9205 break;
9206 case 0x2:
9207 if (op1 == 1) {
9208 ARCH(5J); /* bxj */
9209 /* Trivial implementation equivalent to bx. */
9210 tmp = load_reg(s, rm);
9211 gen_bx(s, tmp);
9212 } else {
9213 goto illegal_op;
9214 }
9215 break;
9216 case 0x3:
9217 if (op1 != 1)
9218 goto illegal_op;
9219
9220 ARCH(5);
9221 /* branch link/exchange thumb (blx) */
9222 tmp = load_reg(s, rm);
9223 tmp2 = tcg_temp_new_i32();
9224 tcg_gen_movi_i32(tmp2, s->pc);
9225 store_reg(s, 14, tmp2);
9226 gen_bx(s, tmp);
9227 break;
9228 case 0x4:
9229 {
9230 /* crc32/crc32c */
9231 uint32_t c = extract32(insn, 8, 4);
9232
9233 /* Check this CPU supports ARMv8 CRC instructions.
9234 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9235 * Bits 8, 10 and 11 should be zero.
9236 */
9237 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9238 goto illegal_op;
9239 }
9240
9241 rn = extract32(insn, 16, 4);
9242 rd = extract32(insn, 12, 4);
9243
9244 tmp = load_reg(s, rn);
9245 tmp2 = load_reg(s, rm);
9246 if (op1 == 0) {
9247 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9248 } else if (op1 == 1) {
9249 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9250 }
9251 tmp3 = tcg_const_i32(1 << op1);
9252 if (c & 0x2) {
9253 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9254 } else {
9255 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9256 }
9257 tcg_temp_free_i32(tmp2);
9258 tcg_temp_free_i32(tmp3);
9259 store_reg(s, rd, tmp);
9260 break;
9261 }
9262 case 0x5: /* saturating add/subtract */
9263 ARCH(5TE);
9264 rd = (insn >> 12) & 0xf;
9265 rn = (insn >> 16) & 0xf;
9266 tmp = load_reg(s, rm);
9267 tmp2 = load_reg(s, rn);
9268 if (op1 & 2)
9269 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9270 if (op1 & 1)
9271 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9272 else
9273 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9274 tcg_temp_free_i32(tmp2);
9275 store_reg(s, rd, tmp);
9276 break;
9277 case 0x6: /* ERET */
9278 if (op1 != 3) {
9279 goto illegal_op;
9280 }
9281 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9282 goto illegal_op;
9283 }
9284 if ((insn & 0x000fff0f) != 0x0000000e) {
9285 /* UNPREDICTABLE; we choose to UNDEF */
9286 goto illegal_op;
9287 }
9288
9289 if (s->current_el == 2) {
9290 tmp = load_cpu_field(elr_el[2]);
9291 } else {
9292 tmp = load_reg(s, 14);
9293 }
9294 gen_exception_return(s, tmp);
9295 break;
9296 case 7:
9297 {
9298 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9299 switch (op1) {
9300 case 0:
9301 /* HLT */
9302 gen_hlt(s, imm16);
9303 break;
9304 case 1:
9305 /* bkpt */
9306 ARCH(5);
9307 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9308 break;
9309 case 2:
9310 /* Hypervisor call (v7) */
9311 ARCH(7);
9312 if (IS_USER(s)) {
9313 goto illegal_op;
9314 }
9315 gen_hvc(s, imm16);
9316 break;
9317 case 3:
9318 /* Secure monitor call (v6+) */
9319 ARCH(6K);
9320 if (IS_USER(s)) {
9321 goto illegal_op;
9322 }
9323 gen_smc(s);
9324 break;
9325 default:
9326 g_assert_not_reached();
9327 }
9328 break;
9329 }
9330 case 0x8: /* signed multiply */
9331 case 0xa:
9332 case 0xc:
9333 case 0xe:
9334 ARCH(5TE);
9335 rs = (insn >> 8) & 0xf;
9336 rn = (insn >> 12) & 0xf;
9337 rd = (insn >> 16) & 0xf;
9338 if (op1 == 1) {
9339 /* (32 * 16) >> 16 */
9340 tmp = load_reg(s, rm);
9341 tmp2 = load_reg(s, rs);
9342 if (sh & 4)
9343 tcg_gen_sari_i32(tmp2, tmp2, 16);
9344 else
9345 gen_sxth(tmp2);
9346 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9347 tcg_gen_shri_i64(tmp64, tmp64, 16);
9348 tmp = tcg_temp_new_i32();
9349 tcg_gen_extrl_i64_i32(tmp, tmp64);
9350 tcg_temp_free_i64(tmp64);
9351 if ((sh & 2) == 0) {
9352 tmp2 = load_reg(s, rn);
9353 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9354 tcg_temp_free_i32(tmp2);
9355 }
9356 store_reg(s, rd, tmp);
9357 } else {
9358 /* 16 * 16 */
9359 tmp = load_reg(s, rm);
9360 tmp2 = load_reg(s, rs);
9361 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9362 tcg_temp_free_i32(tmp2);
9363 if (op1 == 2) {
9364 tmp64 = tcg_temp_new_i64();
9365 tcg_gen_ext_i32_i64(tmp64, tmp);
9366 tcg_temp_free_i32(tmp);
9367 gen_addq(s, tmp64, rn, rd);
9368 gen_storeq_reg(s, rn, rd, tmp64);
9369 tcg_temp_free_i64(tmp64);
9370 } else {
9371 if (op1 == 0) {
9372 tmp2 = load_reg(s, rn);
9373 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9374 tcg_temp_free_i32(tmp2);
9375 }
9376 store_reg(s, rd, tmp);
9377 }
9378 }
9379 break;
9380 default:
9381 goto illegal_op;
9382 }
9383 } else if (((insn & 0x0e000000) == 0 &&
9384 (insn & 0x00000090) != 0x90) ||
9385 ((insn & 0x0e000000) == (1 << 25))) {
9386 int set_cc, logic_cc, shiftop;
9387
9388 op1 = (insn >> 21) & 0xf;
9389 set_cc = (insn >> 20) & 1;
9390 logic_cc = table_logic_cc[op1] & set_cc;
9391
9392 /* data processing instruction */
9393 if (insn & (1 << 25)) {
9394 /* immediate operand */
9395 val = insn & 0xff;
9396 shift = ((insn >> 8) & 0xf) * 2;
9397 if (shift) {
9398 val = (val >> shift) | (val << (32 - shift));
9399 }
9400 tmp2 = tcg_temp_new_i32();
9401 tcg_gen_movi_i32(tmp2, val);
9402 if (logic_cc && shift) {
9403 gen_set_CF_bit31(tmp2);
9404 }
9405 } else {
9406 /* register */
9407 rm = (insn) & 0xf;
9408 tmp2 = load_reg(s, rm);
9409 shiftop = (insn >> 5) & 3;
9410 if (!(insn & (1 << 4))) {
9411 shift = (insn >> 7) & 0x1f;
9412 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9413 } else {
9414 rs = (insn >> 8) & 0xf;
9415 tmp = load_reg(s, rs);
9416 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9417 }
9418 }
9419 if (op1 != 0x0f && op1 != 0x0d) {
9420 rn = (insn >> 16) & 0xf;
9421 tmp = load_reg(s, rn);
9422 } else {
9423 tmp = NULL;
9424 }
9425 rd = (insn >> 12) & 0xf;
9426 switch(op1) {
9427 case 0x00:
9428 tcg_gen_and_i32(tmp, tmp, tmp2);
9429 if (logic_cc) {
9430 gen_logic_CC(tmp);
9431 }
9432 store_reg_bx(s, rd, tmp);
9433 break;
9434 case 0x01:
9435 tcg_gen_xor_i32(tmp, tmp, tmp2);
9436 if (logic_cc) {
9437 gen_logic_CC(tmp);
9438 }
9439 store_reg_bx(s, rd, tmp);
9440 break;
9441 case 0x02:
9442 if (set_cc && rd == 15) {
9443 /* SUBS r15, ... is used for exception return. */
9444 if (IS_USER(s)) {
9445 goto illegal_op;
9446 }
9447 gen_sub_CC(tmp, tmp, tmp2);
9448 gen_exception_return(s, tmp);
9449 } else {
9450 if (set_cc) {
9451 gen_sub_CC(tmp, tmp, tmp2);
9452 } else {
9453 tcg_gen_sub_i32(tmp, tmp, tmp2);
9454 }
9455 store_reg_bx(s, rd, tmp);
9456 }
9457 break;
9458 case 0x03:
9459 if (set_cc) {
9460 gen_sub_CC(tmp, tmp2, tmp);
9461 } else {
9462 tcg_gen_sub_i32(tmp, tmp2, tmp);
9463 }
9464 store_reg_bx(s, rd, tmp);
9465 break;
9466 case 0x04:
9467 if (set_cc) {
9468 gen_add_CC(tmp, tmp, tmp2);
9469 } else {
9470 tcg_gen_add_i32(tmp, tmp, tmp2);
9471 }
9472 store_reg_bx(s, rd, tmp);
9473 break;
9474 case 0x05:
9475 if (set_cc) {
9476 gen_adc_CC(tmp, tmp, tmp2);
9477 } else {
9478 gen_add_carry(tmp, tmp, tmp2);
9479 }
9480 store_reg_bx(s, rd, tmp);
9481 break;
9482 case 0x06:
9483 if (set_cc) {
9484 gen_sbc_CC(tmp, tmp, tmp2);
9485 } else {
9486 gen_sub_carry(tmp, tmp, tmp2);
9487 }
9488 store_reg_bx(s, rd, tmp);
9489 break;
9490 case 0x07:
9491 if (set_cc) {
9492 gen_sbc_CC(tmp, tmp2, tmp);
9493 } else {
9494 gen_sub_carry(tmp, tmp2, tmp);
9495 }
9496 store_reg_bx(s, rd, tmp);
9497 break;
9498 case 0x08:
9499 if (set_cc) {
9500 tcg_gen_and_i32(tmp, tmp, tmp2);
9501 gen_logic_CC(tmp);
9502 }
9503 tcg_temp_free_i32(tmp);
9504 break;
9505 case 0x09:
9506 if (set_cc) {
9507 tcg_gen_xor_i32(tmp, tmp, tmp2);
9508 gen_logic_CC(tmp);
9509 }
9510 tcg_temp_free_i32(tmp);
9511 break;
9512 case 0x0a:
9513 if (set_cc) {
9514 gen_sub_CC(tmp, tmp, tmp2);
9515 }
9516 tcg_temp_free_i32(tmp);
9517 break;
9518 case 0x0b:
9519 if (set_cc) {
9520 gen_add_CC(tmp, tmp, tmp2);
9521 }
9522 tcg_temp_free_i32(tmp);
9523 break;
9524 case 0x0c:
9525 tcg_gen_or_i32(tmp, tmp, tmp2);
9526 if (logic_cc) {
9527 gen_logic_CC(tmp);
9528 }
9529 store_reg_bx(s, rd, tmp);
9530 break;
9531 case 0x0d:
9532 if (logic_cc && rd == 15) {
9533 /* MOVS r15, ... is used for exception return. */
9534 if (IS_USER(s)) {
9535 goto illegal_op;
9536 }
9537 gen_exception_return(s, tmp2);
9538 } else {
9539 if (logic_cc) {
9540 gen_logic_CC(tmp2);
9541 }
9542 store_reg_bx(s, rd, tmp2);
9543 }
9544 break;
9545 case 0x0e:
9546 tcg_gen_andc_i32(tmp, tmp, tmp2);
9547 if (logic_cc) {
9548 gen_logic_CC(tmp);
9549 }
9550 store_reg_bx(s, rd, tmp);
9551 break;
9552 default:
9553 case 0x0f:
9554 tcg_gen_not_i32(tmp2, tmp2);
9555 if (logic_cc) {
9556 gen_logic_CC(tmp2);
9557 }
9558 store_reg_bx(s, rd, tmp2);
9559 break;
9560 }
9561 if (op1 != 0x0f && op1 != 0x0d) {
9562 tcg_temp_free_i32(tmp2);
9563 }
9564 } else {
9565 /* other instructions */
9566 op1 = (insn >> 24) & 0xf;
9567 switch(op1) {
9568 case 0x0:
9569 case 0x1:
9570 /* multiplies, extra load/stores */
9571 sh = (insn >> 5) & 3;
9572 if (sh == 0) {
9573 if (op1 == 0x0) {
9574 rd = (insn >> 16) & 0xf;
9575 rn = (insn >> 12) & 0xf;
9576 rs = (insn >> 8) & 0xf;
9577 rm = (insn) & 0xf;
9578 op1 = (insn >> 20) & 0xf;
9579 switch (op1) {
9580 case 0: case 1: case 2: case 3: case 6:
9581 /* 32 bit mul */
9582 tmp = load_reg(s, rs);
9583 tmp2 = load_reg(s, rm);
9584 tcg_gen_mul_i32(tmp, tmp, tmp2);
9585 tcg_temp_free_i32(tmp2);
9586 if (insn & (1 << 22)) {
9587 /* Subtract (mls) */
9588 ARCH(6T2);
9589 tmp2 = load_reg(s, rn);
9590 tcg_gen_sub_i32(tmp, tmp2, tmp);
9591 tcg_temp_free_i32(tmp2);
9592 } else if (insn & (1 << 21)) {
9593 /* Add */
9594 tmp2 = load_reg(s, rn);
9595 tcg_gen_add_i32(tmp, tmp, tmp2);
9596 tcg_temp_free_i32(tmp2);
9597 }
9598 if (insn & (1 << 20))
9599 gen_logic_CC(tmp);
9600 store_reg(s, rd, tmp);
9601 break;
9602 case 4:
9603 /* 64 bit mul double accumulate (UMAAL) */
9604 ARCH(6);
9605 tmp = load_reg(s, rs);
9606 tmp2 = load_reg(s, rm);
9607 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9608 gen_addq_lo(s, tmp64, rn);
9609 gen_addq_lo(s, tmp64, rd);
9610 gen_storeq_reg(s, rn, rd, tmp64);
9611 tcg_temp_free_i64(tmp64);
9612 break;
9613 case 8: case 9: case 10: case 11:
9614 case 12: case 13: case 14: case 15:
9615 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9616 tmp = load_reg(s, rs);
9617 tmp2 = load_reg(s, rm);
9618 if (insn & (1 << 22)) {
9619 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9620 } else {
9621 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9622 }
9623 if (insn & (1 << 21)) { /* mult accumulate */
9624 TCGv_i32 al = load_reg(s, rn);
9625 TCGv_i32 ah = load_reg(s, rd);
9626 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9627 tcg_temp_free_i32(al);
9628 tcg_temp_free_i32(ah);
9629 }
9630 if (insn & (1 << 20)) {
9631 gen_logicq_cc(tmp, tmp2);
9632 }
9633 store_reg(s, rn, tmp);
9634 store_reg(s, rd, tmp2);
9635 break;
9636 default:
9637 goto illegal_op;
9638 }
9639 } else {
9640 rn = (insn >> 16) & 0xf;
9641 rd = (insn >> 12) & 0xf;
9642 if (insn & (1 << 23)) {
9643 /* load/store exclusive */
9644 bool is_ld = extract32(insn, 20, 1);
9645 bool is_lasr = !extract32(insn, 8, 1);
9646 int op2 = (insn >> 8) & 3;
9647 op1 = (insn >> 21) & 0x3;
9648
9649 switch (op2) {
9650 case 0: /* lda/stl */
9651 if (op1 == 1) {
9652 goto illegal_op;
9653 }
9654 ARCH(8);
9655 break;
9656 case 1: /* reserved */
9657 goto illegal_op;
9658 case 2: /* ldaex/stlex */
9659 ARCH(8);
9660 break;
9661 case 3: /* ldrex/strex */
9662 if (op1) {
9663 ARCH(6K);
9664 } else {
9665 ARCH(6);
9666 }
9667 break;
9668 }
9669
9670 addr = tcg_temp_local_new_i32();
9671 load_reg_var(s, addr, rn);
9672
9673 if (is_lasr && !is_ld) {
9674 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9675 }
9676
9677 if (op2 == 0) {
9678 if (is_ld) {
9679 tmp = tcg_temp_new_i32();
9680 switch (op1) {
9681 case 0: /* lda */
9682 gen_aa32_ld32u_iss(s, tmp, addr,
9683 get_mem_index(s),
9684 rd | ISSIsAcqRel);
9685 break;
9686 case 2: /* ldab */
9687 gen_aa32_ld8u_iss(s, tmp, addr,
9688 get_mem_index(s),
9689 rd | ISSIsAcqRel);
9690 break;
9691 case 3: /* ldah */
9692 gen_aa32_ld16u_iss(s, tmp, addr,
9693 get_mem_index(s),
9694 rd | ISSIsAcqRel);
9695 break;
9696 default:
9697 abort();
9698 }
9699 store_reg(s, rd, tmp);
9700 } else {
9701 rm = insn & 0xf;
9702 tmp = load_reg(s, rm);
9703 switch (op1) {
9704 case 0: /* stl */
9705 gen_aa32_st32_iss(s, tmp, addr,
9706 get_mem_index(s),
9707 rm | ISSIsAcqRel);
9708 break;
9709 case 2: /* stlb */
9710 gen_aa32_st8_iss(s, tmp, addr,
9711 get_mem_index(s),
9712 rm | ISSIsAcqRel);
9713 break;
9714 case 3: /* stlh */
9715 gen_aa32_st16_iss(s, tmp, addr,
9716 get_mem_index(s),
9717 rm | ISSIsAcqRel);
9718 break;
9719 default:
9720 abort();
9721 }
9722 tcg_temp_free_i32(tmp);
9723 }
9724 } else if (is_ld) {
9725 switch (op1) {
9726 case 0: /* ldrex */
9727 gen_load_exclusive(s, rd, 15, addr, 2);
9728 break;
9729 case 1: /* ldrexd */
9730 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9731 break;
9732 case 2: /* ldrexb */
9733 gen_load_exclusive(s, rd, 15, addr, 0);
9734 break;
9735 case 3: /* ldrexh */
9736 gen_load_exclusive(s, rd, 15, addr, 1);
9737 break;
9738 default:
9739 abort();
9740 }
9741 } else {
9742 rm = insn & 0xf;
9743 switch (op1) {
9744 case 0: /* strex */
9745 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9746 break;
9747 case 1: /* strexd */
9748 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9749 break;
9750 case 2: /* strexb */
9751 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9752 break;
9753 case 3: /* strexh */
9754 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9755 break;
9756 default:
9757 abort();
9758 }
9759 }
9760 tcg_temp_free_i32(addr);
9761
9762 if (is_lasr && is_ld) {
9763 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9764 }
9765 } else if ((insn & 0x00300f00) == 0) {
9766 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9767 * - SWP, SWPB
9768 */
9769
9770 TCGv taddr;
9771 TCGMemOp opc = s->be_data;
9772
9773 rm = (insn) & 0xf;
9774
9775 if (insn & (1 << 22)) {
9776 opc |= MO_UB;
9777 } else {
9778 opc |= MO_UL | MO_ALIGN;
9779 }
9780
9781 addr = load_reg(s, rn);
9782 taddr = gen_aa32_addr(s, addr, opc);
9783 tcg_temp_free_i32(addr);
9784
9785 tmp = load_reg(s, rm);
9786 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9787 get_mem_index(s), opc);
9788 tcg_temp_free(taddr);
9789 store_reg(s, rd, tmp);
9790 } else {
9791 goto illegal_op;
9792 }
9793 }
9794 } else {
9795 int address_offset;
9796 bool load = insn & (1 << 20);
9797 bool wbit = insn & (1 << 21);
9798 bool pbit = insn & (1 << 24);
9799 bool doubleword = false;
9800 ISSInfo issinfo;
9801
9802 /* Misc load/store */
9803 rn = (insn >> 16) & 0xf;
9804 rd = (insn >> 12) & 0xf;
9805
9806 /* ISS not valid if writeback */
9807 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9808
9809 if (!load && (sh & 2)) {
9810 /* doubleword */
9811 ARCH(5TE);
9812 if (rd & 1) {
9813 /* UNPREDICTABLE; we choose to UNDEF */
9814 goto illegal_op;
9815 }
9816 load = (sh & 1) == 0;
9817 doubleword = true;
9818 }
9819
9820 addr = load_reg(s, rn);
9821 if (pbit) {
9822 gen_add_datah_offset(s, insn, 0, addr);
9823 }
9824 address_offset = 0;
9825
9826 if (doubleword) {
9827 if (!load) {
9828 /* store */
9829 tmp = load_reg(s, rd);
9830 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9831 tcg_temp_free_i32(tmp);
9832 tcg_gen_addi_i32(addr, addr, 4);
9833 tmp = load_reg(s, rd + 1);
9834 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9835 tcg_temp_free_i32(tmp);
9836 } else {
9837 /* load */
9838 tmp = tcg_temp_new_i32();
9839 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9840 store_reg(s, rd, tmp);
9841 tcg_gen_addi_i32(addr, addr, 4);
9842 tmp = tcg_temp_new_i32();
9843 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9844 rd++;
9845 }
9846 address_offset = -4;
9847 } else if (load) {
9848 /* load */
9849 tmp = tcg_temp_new_i32();
9850 switch (sh) {
9851 case 1:
9852 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9853 issinfo);
9854 break;
9855 case 2:
9856 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9857 issinfo);
9858 break;
9859 default:
9860 case 3:
9861 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9862 issinfo);
9863 break;
9864 }
9865 } else {
9866 /* store */
9867 tmp = load_reg(s, rd);
9868 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9869 tcg_temp_free_i32(tmp);
9870 }
9871 /* Perform base writeback before the loaded value to
9872 ensure correct behavior with overlapping index registers.
9873 ldrd with base writeback is undefined if the
9874 destination and index registers overlap. */
9875 if (!pbit) {
9876 gen_add_datah_offset(s, insn, address_offset, addr);
9877 store_reg(s, rn, addr);
9878 } else if (wbit) {
9879 if (address_offset)
9880 tcg_gen_addi_i32(addr, addr, address_offset);
9881 store_reg(s, rn, addr);
9882 } else {
9883 tcg_temp_free_i32(addr);
9884 }
9885 if (load) {
9886 /* Complete the load. */
9887 store_reg(s, rd, tmp);
9888 }
9889 }
9890 break;
9891 case 0x4:
9892 case 0x5:
9893 goto do_ldst;
9894 case 0x6:
9895 case 0x7:
9896 if (insn & (1 << 4)) {
9897 ARCH(6);
9898 /* Armv6 Media instructions. */
9899 rm = insn & 0xf;
9900 rn = (insn >> 16) & 0xf;
9901 rd = (insn >> 12) & 0xf;
9902 rs = (insn >> 8) & 0xf;
9903 switch ((insn >> 23) & 3) {
9904 case 0: /* Parallel add/subtract. */
9905 op1 = (insn >> 20) & 7;
9906 tmp = load_reg(s, rn);
9907 tmp2 = load_reg(s, rm);
9908 sh = (insn >> 5) & 7;
9909 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9910 goto illegal_op;
9911 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9912 tcg_temp_free_i32(tmp2);
9913 store_reg(s, rd, tmp);
9914 break;
9915 case 1:
9916 if ((insn & 0x00700020) == 0) {
9917 /* Halfword pack. */
9918 tmp = load_reg(s, rn);
9919 tmp2 = load_reg(s, rm);
9920 shift = (insn >> 7) & 0x1f;
9921 if (insn & (1 << 6)) {
9922 /* pkhtb */
9923 if (shift == 0)
9924 shift = 31;
9925 tcg_gen_sari_i32(tmp2, tmp2, shift);
9926 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9927 tcg_gen_ext16u_i32(tmp2, tmp2);
9928 } else {
9929 /* pkhbt */
9930 if (shift)
9931 tcg_gen_shli_i32(tmp2, tmp2, shift);
9932 tcg_gen_ext16u_i32(tmp, tmp);
9933 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9934 }
9935 tcg_gen_or_i32(tmp, tmp, tmp2);
9936 tcg_temp_free_i32(tmp2);
9937 store_reg(s, rd, tmp);
9938 } else if ((insn & 0x00200020) == 0x00200000) {
9939 /* [us]sat */
9940 tmp = load_reg(s, rm);
9941 shift = (insn >> 7) & 0x1f;
9942 if (insn & (1 << 6)) {
9943 if (shift == 0)
9944 shift = 31;
9945 tcg_gen_sari_i32(tmp, tmp, shift);
9946 } else {
9947 tcg_gen_shli_i32(tmp, tmp, shift);
9948 }
9949 sh = (insn >> 16) & 0x1f;
9950 tmp2 = tcg_const_i32(sh);
9951 if (insn & (1 << 22))
9952 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9953 else
9954 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9955 tcg_temp_free_i32(tmp2);
9956 store_reg(s, rd, tmp);
9957 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9958 /* [us]sat16 */
9959 tmp = load_reg(s, rm);
9960 sh = (insn >> 16) & 0x1f;
9961 tmp2 = tcg_const_i32(sh);
9962 if (insn & (1 << 22))
9963 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9964 else
9965 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9966 tcg_temp_free_i32(tmp2);
9967 store_reg(s, rd, tmp);
9968 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9969 /* Select bytes. */
9970 tmp = load_reg(s, rn);
9971 tmp2 = load_reg(s, rm);
9972 tmp3 = tcg_temp_new_i32();
9973 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9974 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9975 tcg_temp_free_i32(tmp3);
9976 tcg_temp_free_i32(tmp2);
9977 store_reg(s, rd, tmp);
9978 } else if ((insn & 0x000003e0) == 0x00000060) {
9979 tmp = load_reg(s, rm);
9980 shift = (insn >> 10) & 3;
9981 /* ??? In many cases it's not necessary to do a
9982 rotate, a shift is sufficient. */
9983 if (shift != 0)
9984 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9985 op1 = (insn >> 20) & 7;
9986 switch (op1) {
9987 case 0: gen_sxtb16(tmp); break;
9988 case 2: gen_sxtb(tmp); break;
9989 case 3: gen_sxth(tmp); break;
9990 case 4: gen_uxtb16(tmp); break;
9991 case 6: gen_uxtb(tmp); break;
9992 case 7: gen_uxth(tmp); break;
9993 default: goto illegal_op;
9994 }
9995 if (rn != 15) {
9996 tmp2 = load_reg(s, rn);
9997 if ((op1 & 3) == 0) {
9998 gen_add16(tmp, tmp2);
9999 } else {
10000 tcg_gen_add_i32(tmp, tmp, tmp2);
10001 tcg_temp_free_i32(tmp2);
10002 }
10003 }
10004 store_reg(s, rd, tmp);
10005 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
10006 /* rev */
10007 tmp = load_reg(s, rm);
10008 if (insn & (1 << 22)) {
10009 if (insn & (1 << 7)) {
10010 gen_revsh(tmp);
10011 } else {
10012 ARCH(6T2);
10013 gen_helper_rbit(tmp, tmp);
10014 }
10015 } else {
10016 if (insn & (1 << 7))
10017 gen_rev16(tmp);
10018 else
10019 tcg_gen_bswap32_i32(tmp, tmp);
10020 }
10021 store_reg(s, rd, tmp);
10022 } else {
10023 goto illegal_op;
10024 }
10025 break;
10026 case 2: /* Multiplies (Type 3). */
10027 switch ((insn >> 20) & 0x7) {
10028 case 5:
10029 if (((insn >> 6) ^ (insn >> 7)) & 1) {
10030 /* op2 not 00x or 11x : UNDEF */
10031 goto illegal_op;
10032 }
10033 /* Signed multiply most significant [accumulate].
10034 (SMMUL, SMMLA, SMMLS) */
10035 tmp = load_reg(s, rm);
10036 tmp2 = load_reg(s, rs);
10037 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10038
10039 if (rd != 15) {
10040 tmp = load_reg(s, rd);
10041 if (insn & (1 << 6)) {
10042 tmp64 = gen_subq_msw(tmp64, tmp);
10043 } else {
10044 tmp64 = gen_addq_msw(tmp64, tmp);
10045 }
10046 }
10047 if (insn & (1 << 5)) {
10048 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10049 }
10050 tcg_gen_shri_i64(tmp64, tmp64, 32);
10051 tmp = tcg_temp_new_i32();
10052 tcg_gen_extrl_i64_i32(tmp, tmp64);
10053 tcg_temp_free_i64(tmp64);
10054 store_reg(s, rn, tmp);
10055 break;
10056 case 0:
10057 case 4:
10058 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10059 if (insn & (1 << 7)) {
10060 goto illegal_op;
10061 }
10062 tmp = load_reg(s, rm);
10063 tmp2 = load_reg(s, rs);
10064 if (insn & (1 << 5))
10065 gen_swap_half(tmp2);
10066 gen_smul_dual(tmp, tmp2);
10067 if (insn & (1 << 22)) {
10068 /* smlald, smlsld */
10069 TCGv_i64 tmp64_2;
10070
10071 tmp64 = tcg_temp_new_i64();
10072 tmp64_2 = tcg_temp_new_i64();
10073 tcg_gen_ext_i32_i64(tmp64, tmp);
10074 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
10075 tcg_temp_free_i32(tmp);
10076 tcg_temp_free_i32(tmp2);
10077 if (insn & (1 << 6)) {
10078 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
10079 } else {
10080 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
10081 }
10082 tcg_temp_free_i64(tmp64_2);
10083 gen_addq(s, tmp64, rd, rn);
10084 gen_storeq_reg(s, rd, rn, tmp64);
10085 tcg_temp_free_i64(tmp64);
10086 } else {
10087 /* smuad, smusd, smlad, smlsd */
10088 if (insn & (1 << 6)) {
10089 /* This subtraction cannot overflow. */
10090 tcg_gen_sub_i32(tmp, tmp, tmp2);
10091 } else {
10092 /* This addition cannot overflow 32 bits;
10093 * however it may overflow considered as a
10094 * signed operation, in which case we must set
10095 * the Q flag.
10096 */
10097 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10098 }
10099 tcg_temp_free_i32(tmp2);
10100 if (rd != 15)
10101 {
10102 tmp2 = load_reg(s, rd);
10103 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10104 tcg_temp_free_i32(tmp2);
10105 }
10106 store_reg(s, rn, tmp);
10107 }
10108 break;
10109 case 1:
10110 case 3:
10111 /* SDIV, UDIV */
10112 if (!dc_isar_feature(arm_div, s)) {
10113 goto illegal_op;
10114 }
10115 if (((insn >> 5) & 7) || (rd != 15)) {
10116 goto illegal_op;
10117 }
10118 tmp = load_reg(s, rm);
10119 tmp2 = load_reg(s, rs);
10120 if (insn & (1 << 21)) {
10121 gen_helper_udiv(tmp, tmp, tmp2);
10122 } else {
10123 gen_helper_sdiv(tmp, tmp, tmp2);
10124 }
10125 tcg_temp_free_i32(tmp2);
10126 store_reg(s, rn, tmp);
10127 break;
10128 default:
10129 goto illegal_op;
10130 }
10131 break;
10132 case 3:
10133 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
10134 switch (op1) {
10135 case 0: /* Unsigned sum of absolute differences. */
10136 ARCH(6);
10137 tmp = load_reg(s, rm);
10138 tmp2 = load_reg(s, rs);
10139 gen_helper_usad8(tmp, tmp, tmp2);
10140 tcg_temp_free_i32(tmp2);
10141 if (rd != 15) {
10142 tmp2 = load_reg(s, rd);
10143 tcg_gen_add_i32(tmp, tmp, tmp2);
10144 tcg_temp_free_i32(tmp2);
10145 }
10146 store_reg(s, rn, tmp);
10147 break;
10148 case 0x20: case 0x24: case 0x28: case 0x2c:
10149 /* Bitfield insert/clear. */
10150 ARCH(6T2);
10151 shift = (insn >> 7) & 0x1f;
10152 i = (insn >> 16) & 0x1f;
10153 if (i < shift) {
10154 /* UNPREDICTABLE; we choose to UNDEF */
10155 goto illegal_op;
10156 }
10157 i = i + 1 - shift;
10158 if (rm == 15) {
10159 tmp = tcg_temp_new_i32();
10160 tcg_gen_movi_i32(tmp, 0);
10161 } else {
10162 tmp = load_reg(s, rm);
10163 }
10164 if (i != 32) {
10165 tmp2 = load_reg(s, rd);
10166 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
10167 tcg_temp_free_i32(tmp2);
10168 }
10169 store_reg(s, rd, tmp);
10170 break;
10171 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10172 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10173 ARCH(6T2);
10174 tmp = load_reg(s, rm);
10175 shift = (insn >> 7) & 0x1f;
10176 i = ((insn >> 16) & 0x1f) + 1;
10177 if (shift + i > 32)
10178 goto illegal_op;
10179 if (i < 32) {
10180 if (op1 & 0x20) {
10181 tcg_gen_extract_i32(tmp, tmp, shift, i);
10182 } else {
10183 tcg_gen_sextract_i32(tmp, tmp, shift, i);
10184 }
10185 }
10186 store_reg(s, rd, tmp);
10187 break;
10188 default:
10189 goto illegal_op;
10190 }
10191 break;
10192 }
10193 break;
10194 }
10195 do_ldst:
10196 /* Check for undefined extension instructions
10197 * per the ARM Bible IE:
10198 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
10199 */
10200 sh = (0xf << 20) | (0xf << 4);
10201 if (op1 == 0x7 && ((insn & sh) == sh))
10202 {
10203 goto illegal_op;
10204 }
10205 /* load/store byte/word */
10206 rn = (insn >> 16) & 0xf;
10207 rd = (insn >> 12) & 0xf;
10208 tmp2 = load_reg(s, rn);
10209 if ((insn & 0x01200000) == 0x00200000) {
10210 /* ldrt/strt */
10211 i = get_a32_user_mem_index(s);
10212 } else {
10213 i = get_mem_index(s);
10214 }
10215 if (insn & (1 << 24))
10216 gen_add_data_offset(s, insn, tmp2);
10217 if (insn & (1 << 20)) {
10218 /* load */
10219 tmp = tcg_temp_new_i32();
10220 if (insn & (1 << 22)) {
10221 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
10222 } else {
10223 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
10224 }
10225 } else {
10226 /* store */
10227 tmp = load_reg(s, rd);
10228 if (insn & (1 << 22)) {
10229 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
10230 } else {
10231 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
10232 }
10233 tcg_temp_free_i32(tmp);
10234 }
10235 if (!(insn & (1 << 24))) {
10236 gen_add_data_offset(s, insn, tmp2);
10237 store_reg(s, rn, tmp2);
10238 } else if (insn & (1 << 21)) {
10239 store_reg(s, rn, tmp2);
10240 } else {
10241 tcg_temp_free_i32(tmp2);
10242 }
10243 if (insn & (1 << 20)) {
10244 /* Complete the load. */
10245 store_reg_from_load(s, rd, tmp);
10246 }
10247 break;
10248 case 0x08:
10249 case 0x09:
10250 {
10251 int j, n, loaded_base;
10252 bool exc_return = false;
10253 bool is_load = extract32(insn, 20, 1);
10254 bool user = false;
10255 TCGv_i32 loaded_var;
10256 /* load/store multiple words */
10257 /* XXX: store correct base if write back */
10258 if (insn & (1 << 22)) {
10259 /* LDM (user), LDM (exception return) and STM (user) */
10260 if (IS_USER(s))
10261 goto illegal_op; /* only usable in supervisor mode */
10262
10263 if (is_load && extract32(insn, 15, 1)) {
10264 exc_return = true;
10265 } else {
10266 user = true;
10267 }
10268 }
10269 rn = (insn >> 16) & 0xf;
10270 addr = load_reg(s, rn);
10271
10272 /* compute total size */
10273 loaded_base = 0;
10274 loaded_var = NULL;
10275 n = 0;
10276 for(i=0;i<16;i++) {
10277 if (insn & (1 << i))
10278 n++;
10279 }
10280 /* XXX: test invalid n == 0 case ? */
10281 if (insn & (1 << 23)) {
10282 if (insn & (1 << 24)) {
10283 /* pre increment */
10284 tcg_gen_addi_i32(addr, addr, 4);
10285 } else {
10286 /* post increment */
10287 }
10288 } else {
10289 if (insn & (1 << 24)) {
10290 /* pre decrement */
10291 tcg_gen_addi_i32(addr, addr, -(n * 4));
10292 } else {
10293 /* post decrement */
10294 if (n != 1)
10295 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10296 }
10297 }
10298 j = 0;
10299 for(i=0;i<16;i++) {
10300 if (insn & (1 << i)) {
10301 if (is_load) {
10302 /* load */
10303 tmp = tcg_temp_new_i32();
10304 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10305 if (user) {
10306 tmp2 = tcg_const_i32(i);
10307 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10308 tcg_temp_free_i32(tmp2);
10309 tcg_temp_free_i32(tmp);
10310 } else if (i == rn) {
10311 loaded_var = tmp;
10312 loaded_base = 1;
10313 } else if (i == 15 && exc_return) {
10314 store_pc_exc_ret(s, tmp);
10315 } else {
10316 store_reg_from_load(s, i, tmp);
10317 }
10318 } else {
10319 /* store */
10320 if (i == 15) {
10321 /* special case: r15 = PC + 8 */
10322 val = (long)s->pc + 4;
10323 tmp = tcg_temp_new_i32();
10324 tcg_gen_movi_i32(tmp, val);
10325 } else if (user) {
10326 tmp = tcg_temp_new_i32();
10327 tmp2 = tcg_const_i32(i);
10328 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10329 tcg_temp_free_i32(tmp2);
10330 } else {
10331 tmp = load_reg(s, i);
10332 }
10333 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10334 tcg_temp_free_i32(tmp);
10335 }
10336 j++;
10337 /* no need to add after the last transfer */
10338 if (j != n)
10339 tcg_gen_addi_i32(addr, addr, 4);
10340 }
10341 }
10342 if (insn & (1 << 21)) {
10343 /* write back */
10344 if (insn & (1 << 23)) {
10345 if (insn & (1 << 24)) {
10346 /* pre increment */
10347 } else {
10348 /* post increment */
10349 tcg_gen_addi_i32(addr, addr, 4);
10350 }
10351 } else {
10352 if (insn & (1 << 24)) {
10353 /* pre decrement */
10354 if (n != 1)
10355 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10356 } else {
10357 /* post decrement */
10358 tcg_gen_addi_i32(addr, addr, -(n * 4));
10359 }
10360 }
10361 store_reg(s, rn, addr);
10362 } else {
10363 tcg_temp_free_i32(addr);
10364 }
10365 if (loaded_base) {
10366 store_reg(s, rn, loaded_var);
10367 }
10368 if (exc_return) {
10369 /* Restore CPSR from SPSR. */
10370 tmp = load_cpu_field(spsr);
10371 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10372 gen_io_start();
10373 }
10374 gen_helper_cpsr_write_eret(cpu_env, tmp);
10375 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10376 gen_io_end();
10377 }
10378 tcg_temp_free_i32(tmp);
10379 /* Must exit loop to check un-masked IRQs */
10380 s->base.is_jmp = DISAS_EXIT;
10381 }
10382 }
10383 break;
10384 case 0xa:
10385 case 0xb:
10386 {
10387 int32_t offset;
10388
10389 /* branch (and link) */
10390 val = (int32_t)s->pc;
10391 if (insn & (1 << 24)) {
10392 tmp = tcg_temp_new_i32();
10393 tcg_gen_movi_i32(tmp, val);
10394 store_reg(s, 14, tmp);
10395 }
10396 offset = sextract32(insn << 2, 0, 26);
10397 val += offset + 4;
10398 gen_jmp(s, val);
10399 }
10400 break;
10401 case 0xc:
10402 case 0xd:
10403 case 0xe:
10404 if (((insn >> 8) & 0xe) == 10) {
10405 /* VFP. */
10406 if (disas_vfp_insn(s, insn)) {
10407 goto illegal_op;
10408 }
10409 } else if (disas_coproc_insn(s, insn)) {
10410 /* Coprocessor. */
10411 goto illegal_op;
10412 }
10413 break;
10414 case 0xf:
10415 /* swi */
10416 gen_set_pc_im(s, s->pc);
10417 s->svc_imm = extract32(insn, 0, 24);
10418 s->base.is_jmp = DISAS_SWI;
10419 break;
10420 default:
10421 illegal_op:
10422 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10423 default_exception_el(s));
10424 break;
10425 }
10426 }
10427 }
10428
10429 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10430 {
10431 /* Return true if this is a 16 bit instruction. We must be precise
10432 * about this (matching the decode). We assume that s->pc still
10433 * points to the first 16 bits of the insn.
10434 */
10435 if ((insn >> 11) < 0x1d) {
10436 /* Definitely a 16-bit instruction */
10437 return true;
10438 }
10439
10440 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10441 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10442 * end up actually treating this as two 16-bit insns, though,
10443 * if it's half of a bl/blx pair that might span a page boundary.
10444 */
10445 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10446 arm_dc_feature(s, ARM_FEATURE_M)) {
10447 /* Thumb2 cores (including all M profile ones) always treat
10448 * 32-bit insns as 32-bit.
10449 */
10450 return false;
10451 }
10452
10453 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10454 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10455 * is not on the next page; we merge this into a 32-bit
10456 * insn.
10457 */
10458 return false;
10459 }
10460 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10461 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10462 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10463 * -- handle as single 16 bit insn
10464 */
10465 return true;
10466 }
10467
10468 /* Return true if this is a Thumb-2 logical op. */
10469 static int
10470 thumb2_logic_op(int op)
10471 {
10472 return (op < 8);
10473 }
10474
10475 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10476 then set condition code flags based on the result of the operation.
10477 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10478 to the high bit of T1.
10479 Returns zero if the opcode is valid. */
10480
10481 static int
10482 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10483 TCGv_i32 t0, TCGv_i32 t1)
10484 {
10485 int logic_cc;
10486
10487 logic_cc = 0;
10488 switch (op) {
10489 case 0: /* and */
10490 tcg_gen_and_i32(t0, t0, t1);
10491 logic_cc = conds;
10492 break;
10493 case 1: /* bic */
10494 tcg_gen_andc_i32(t0, t0, t1);
10495 logic_cc = conds;
10496 break;
10497 case 2: /* orr */
10498 tcg_gen_or_i32(t0, t0, t1);
10499 logic_cc = conds;
10500 break;
10501 case 3: /* orn */
10502 tcg_gen_orc_i32(t0, t0, t1);
10503 logic_cc = conds;
10504 break;
10505 case 4: /* eor */
10506 tcg_gen_xor_i32(t0, t0, t1);
10507 logic_cc = conds;
10508 break;
10509 case 8: /* add */
10510 if (conds)
10511 gen_add_CC(t0, t0, t1);
10512 else
10513 tcg_gen_add_i32(t0, t0, t1);
10514 break;
10515 case 10: /* adc */
10516 if (conds)
10517 gen_adc_CC(t0, t0, t1);
10518 else
10519 gen_adc(t0, t1);
10520 break;
10521 case 11: /* sbc */
10522 if (conds) {
10523 gen_sbc_CC(t0, t0, t1);
10524 } else {
10525 gen_sub_carry(t0, t0, t1);
10526 }
10527 break;
10528 case 13: /* sub */
10529 if (conds)
10530 gen_sub_CC(t0, t0, t1);
10531 else
10532 tcg_gen_sub_i32(t0, t0, t1);
10533 break;
10534 case 14: /* rsb */
10535 if (conds)
10536 gen_sub_CC(t0, t1, t0);
10537 else
10538 tcg_gen_sub_i32(t0, t1, t0);
10539 break;
10540 default: /* 5, 6, 7, 9, 12, 15. */
10541 return 1;
10542 }
10543 if (logic_cc) {
10544 gen_logic_CC(t0);
10545 if (shifter_out)
10546 gen_set_CF_bit31(t1);
10547 }
10548 return 0;
10549 }
10550
10551 /* Translate a 32-bit thumb instruction. */
10552 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10553 {
10554 uint32_t imm, shift, offset;
10555 uint32_t rd, rn, rm, rs;
10556 TCGv_i32 tmp;
10557 TCGv_i32 tmp2;
10558 TCGv_i32 tmp3;
10559 TCGv_i32 addr;
10560 TCGv_i64 tmp64;
10561 int op;
10562 int shiftop;
10563 int conds;
10564 int logic_cc;
10565
10566 /*
10567 * ARMv6-M supports a limited subset of Thumb2 instructions.
10568 * Other Thumb1 architectures allow only 32-bit
10569 * combined BL/BLX prefix and suffix.
10570 */
10571 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10572 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10573 int i;
10574 bool found = false;
10575 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10576 0xf3b08040 /* dsb */,
10577 0xf3b08050 /* dmb */,
10578 0xf3b08060 /* isb */,
10579 0xf3e08000 /* mrs */,
10580 0xf000d000 /* bl */};
10581 static const uint32_t armv6m_mask[] = {0xffe0d000,
10582 0xfff0d0f0,
10583 0xfff0d0f0,
10584 0xfff0d0f0,
10585 0xffe0d000,
10586 0xf800d000};
10587
10588 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10589 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10590 found = true;
10591 break;
10592 }
10593 }
10594 if (!found) {
10595 goto illegal_op;
10596 }
10597 } else if ((insn & 0xf800e800) != 0xf000e800) {
10598 ARCH(6T2);
10599 }
10600
10601 rn = (insn >> 16) & 0xf;
10602 rs = (insn >> 12) & 0xf;
10603 rd = (insn >> 8) & 0xf;
10604 rm = insn & 0xf;
10605 switch ((insn >> 25) & 0xf) {
10606 case 0: case 1: case 2: case 3:
10607 /* 16-bit instructions. Should never happen. */
10608 abort();
10609 case 4:
10610 if (insn & (1 << 22)) {
10611 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10612 * - load/store doubleword, load/store exclusive, ldacq/strel,
10613 * table branch, TT.
10614 */
10615 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10616 arm_dc_feature(s, ARM_FEATURE_V8)) {
10617 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10618 * - SG (v8M only)
10619 * The bulk of the behaviour for this instruction is implemented
10620 * in v7m_handle_execute_nsc(), which deals with the insn when
10621 * it is executed by a CPU in non-secure state from memory
10622 * which is Secure & NonSecure-Callable.
10623 * Here we only need to handle the remaining cases:
10624 * * in NS memory (including the "security extension not
10625 * implemented" case) : NOP
10626 * * in S memory but CPU already secure (clear IT bits)
10627 * We know that the attribute for the memory this insn is
10628 * in must match the current CPU state, because otherwise
10629 * get_phys_addr_pmsav8 would have generated an exception.
10630 */
10631 if (s->v8m_secure) {
10632 /* Like the IT insn, we don't need to generate any code */
10633 s->condexec_cond = 0;
10634 s->condexec_mask = 0;
10635 }
10636 } else if (insn & 0x01200000) {
10637 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10638 * - load/store dual (post-indexed)
10639 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10640 * - load/store dual (literal and immediate)
10641 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10642 * - load/store dual (pre-indexed)
10643 */
10644 bool wback = extract32(insn, 21, 1);
10645
10646 if (rn == 15) {
10647 if (insn & (1 << 21)) {
10648 /* UNPREDICTABLE */
10649 goto illegal_op;
10650 }
10651 addr = tcg_temp_new_i32();
10652 tcg_gen_movi_i32(addr, s->pc & ~3);
10653 } else {
10654 addr = load_reg(s, rn);
10655 }
10656 offset = (insn & 0xff) * 4;
10657 if ((insn & (1 << 23)) == 0) {
10658 offset = -offset;
10659 }
10660
10661 if (s->v8m_stackcheck && rn == 13 && wback) {
10662 /*
10663 * Here 'addr' is the current SP; if offset is +ve we're
10664 * moving SP up, else down. It is UNKNOWN whether the limit
10665 * check triggers when SP starts below the limit and ends
10666 * up above it; check whichever of the current and final
10667 * SP is lower, so QEMU will trigger in that situation.
10668 */
10669 if ((int32_t)offset < 0) {
10670 TCGv_i32 newsp = tcg_temp_new_i32();
10671
10672 tcg_gen_addi_i32(newsp, addr, offset);
10673 gen_helper_v8m_stackcheck(cpu_env, newsp);
10674 tcg_temp_free_i32(newsp);
10675 } else {
10676 gen_helper_v8m_stackcheck(cpu_env, addr);
10677 }
10678 }
10679
10680 if (insn & (1 << 24)) {
10681 tcg_gen_addi_i32(addr, addr, offset);
10682 offset = 0;
10683 }
10684 if (insn & (1 << 20)) {
10685 /* ldrd */
10686 tmp = tcg_temp_new_i32();
10687 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10688 store_reg(s, rs, tmp);
10689 tcg_gen_addi_i32(addr, addr, 4);
10690 tmp = tcg_temp_new_i32();
10691 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10692 store_reg(s, rd, tmp);
10693 } else {
10694 /* strd */
10695 tmp = load_reg(s, rs);
10696 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10697 tcg_temp_free_i32(tmp);
10698 tcg_gen_addi_i32(addr, addr, 4);
10699 tmp = load_reg(s, rd);
10700 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10701 tcg_temp_free_i32(tmp);
10702 }
10703 if (wback) {
10704 /* Base writeback. */
10705 tcg_gen_addi_i32(addr, addr, offset - 4);
10706 store_reg(s, rn, addr);
10707 } else {
10708 tcg_temp_free_i32(addr);
10709 }
10710 } else if ((insn & (1 << 23)) == 0) {
10711 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10712 * - load/store exclusive word
10713 * - TT (v8M only)
10714 */
10715 if (rs == 15) {
10716 if (!(insn & (1 << 20)) &&
10717 arm_dc_feature(s, ARM_FEATURE_M) &&
10718 arm_dc_feature(s, ARM_FEATURE_V8)) {
10719 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10720 * - TT (v8M only)
10721 */
10722 bool alt = insn & (1 << 7);
10723 TCGv_i32 addr, op, ttresp;
10724
10725 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10726 /* we UNDEF for these UNPREDICTABLE cases */
10727 goto illegal_op;
10728 }
10729
10730 if (alt && !s->v8m_secure) {
10731 goto illegal_op;
10732 }
10733
10734 addr = load_reg(s, rn);
10735 op = tcg_const_i32(extract32(insn, 6, 2));
10736 ttresp = tcg_temp_new_i32();
10737 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10738 tcg_temp_free_i32(addr);
10739 tcg_temp_free_i32(op);
10740 store_reg(s, rd, ttresp);
10741 break;
10742 }
10743 goto illegal_op;
10744 }
10745 addr = tcg_temp_local_new_i32();
10746 load_reg_var(s, addr, rn);
10747 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10748 if (insn & (1 << 20)) {
10749 gen_load_exclusive(s, rs, 15, addr, 2);
10750 } else {
10751 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10752 }
10753 tcg_temp_free_i32(addr);
10754 } else if ((insn & (7 << 5)) == 0) {
10755 /* Table Branch. */
10756 if (rn == 15) {
10757 addr = tcg_temp_new_i32();
10758 tcg_gen_movi_i32(addr, s->pc);
10759 } else {
10760 addr = load_reg(s, rn);
10761 }
10762 tmp = load_reg(s, rm);
10763 tcg_gen_add_i32(addr, addr, tmp);
10764 if (insn & (1 << 4)) {
10765 /* tbh */
10766 tcg_gen_add_i32(addr, addr, tmp);
10767 tcg_temp_free_i32(tmp);
10768 tmp = tcg_temp_new_i32();
10769 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10770 } else { /* tbb */
10771 tcg_temp_free_i32(tmp);
10772 tmp = tcg_temp_new_i32();
10773 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10774 }
10775 tcg_temp_free_i32(addr);
10776 tcg_gen_shli_i32(tmp, tmp, 1);
10777 tcg_gen_addi_i32(tmp, tmp, s->pc);
10778 store_reg(s, 15, tmp);
10779 } else {
10780 bool is_lasr = false;
10781 bool is_ld = extract32(insn, 20, 1);
10782 int op2 = (insn >> 6) & 0x3;
10783 op = (insn >> 4) & 0x3;
10784 switch (op2) {
10785 case 0:
10786 goto illegal_op;
10787 case 1:
10788 /* Load/store exclusive byte/halfword/doubleword */
10789 if (op == 2) {
10790 goto illegal_op;
10791 }
10792 ARCH(7);
10793 break;
10794 case 2:
10795 /* Load-acquire/store-release */
10796 if (op == 3) {
10797 goto illegal_op;
10798 }
10799 /* Fall through */
10800 case 3:
10801 /* Load-acquire/store-release exclusive */
10802 ARCH(8);
10803 is_lasr = true;
10804 break;
10805 }
10806
10807 if (is_lasr && !is_ld) {
10808 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
10809 }
10810
10811 addr = tcg_temp_local_new_i32();
10812 load_reg_var(s, addr, rn);
10813 if (!(op2 & 1)) {
10814 if (is_ld) {
10815 tmp = tcg_temp_new_i32();
10816 switch (op) {
10817 case 0: /* ldab */
10818 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10819 rs | ISSIsAcqRel);
10820 break;
10821 case 1: /* ldah */
10822 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10823 rs | ISSIsAcqRel);
10824 break;
10825 case 2: /* lda */
10826 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10827 rs | ISSIsAcqRel);
10828 break;
10829 default:
10830 abort();
10831 }
10832 store_reg(s, rs, tmp);
10833 } else {
10834 tmp = load_reg(s, rs);
10835 switch (op) {
10836 case 0: /* stlb */
10837 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10838 rs | ISSIsAcqRel);
10839 break;
10840 case 1: /* stlh */
10841 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10842 rs | ISSIsAcqRel);
10843 break;
10844 case 2: /* stl */
10845 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10846 rs | ISSIsAcqRel);
10847 break;
10848 default:
10849 abort();
10850 }
10851 tcg_temp_free_i32(tmp);
10852 }
10853 } else if (is_ld) {
10854 gen_load_exclusive(s, rs, rd, addr, op);
10855 } else {
10856 gen_store_exclusive(s, rm, rs, rd, addr, op);
10857 }
10858 tcg_temp_free_i32(addr);
10859
10860 if (is_lasr && is_ld) {
10861 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
10862 }
10863 }
10864 } else {
10865 /* Load/store multiple, RFE, SRS. */
10866 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10867 /* RFE, SRS: not available in user mode or on M profile */
10868 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10869 goto illegal_op;
10870 }
10871 if (insn & (1 << 20)) {
10872 /* rfe */
10873 addr = load_reg(s, rn);
10874 if ((insn & (1 << 24)) == 0)
10875 tcg_gen_addi_i32(addr, addr, -8);
10876 /* Load PC into tmp and CPSR into tmp2. */
10877 tmp = tcg_temp_new_i32();
10878 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10879 tcg_gen_addi_i32(addr, addr, 4);
10880 tmp2 = tcg_temp_new_i32();
10881 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10882 if (insn & (1 << 21)) {
10883 /* Base writeback. */
10884 if (insn & (1 << 24)) {
10885 tcg_gen_addi_i32(addr, addr, 4);
10886 } else {
10887 tcg_gen_addi_i32(addr, addr, -4);
10888 }
10889 store_reg(s, rn, addr);
10890 } else {
10891 tcg_temp_free_i32(addr);
10892 }
10893 gen_rfe(s, tmp, tmp2);
10894 } else {
10895 /* srs */
10896 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10897 insn & (1 << 21));
10898 }
10899 } else {
10900 int i, loaded_base = 0;
10901 TCGv_i32 loaded_var;
10902 bool wback = extract32(insn, 21, 1);
10903 /* Load/store multiple. */
10904 addr = load_reg(s, rn);
10905 offset = 0;
10906 for (i = 0; i < 16; i++) {
10907 if (insn & (1 << i))
10908 offset += 4;
10909 }
10910
10911 if (insn & (1 << 24)) {
10912 tcg_gen_addi_i32(addr, addr, -offset);
10913 }
10914
10915 if (s->v8m_stackcheck && rn == 13 && wback) {
10916 /*
10917 * If the writeback is incrementing SP rather than
10918 * decrementing it, and the initial SP is below the
10919 * stack limit but the final written-back SP would
10920 * be above, then then we must not perform any memory
10921 * accesses, but it is IMPDEF whether we generate
10922 * an exception. We choose to do so in this case.
10923 * At this point 'addr' is the lowest address, so
10924 * either the original SP (if incrementing) or our
10925 * final SP (if decrementing), so that's what we check.
10926 */
10927 gen_helper_v8m_stackcheck(cpu_env, addr);
10928 }
10929
10930 loaded_var = NULL;
10931 for (i = 0; i < 16; i++) {
10932 if ((insn & (1 << i)) == 0)
10933 continue;
10934 if (insn & (1 << 20)) {
10935 /* Load. */
10936 tmp = tcg_temp_new_i32();
10937 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10938 if (i == 15) {
10939 gen_bx_excret(s, tmp);
10940 } else if (i == rn) {
10941 loaded_var = tmp;
10942 loaded_base = 1;
10943 } else {
10944 store_reg(s, i, tmp);
10945 }
10946 } else {
10947 /* Store. */
10948 tmp = load_reg(s, i);
10949 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10950 tcg_temp_free_i32(tmp);
10951 }
10952 tcg_gen_addi_i32(addr, addr, 4);
10953 }
10954 if (loaded_base) {
10955 store_reg(s, rn, loaded_var);
10956 }
10957 if (wback) {
10958 /* Base register writeback. */
10959 if (insn & (1 << 24)) {
10960 tcg_gen_addi_i32(addr, addr, -offset);
10961 }
10962 /* Fault if writeback register is in register list. */
10963 if (insn & (1 << rn))
10964 goto illegal_op;
10965 store_reg(s, rn, addr);
10966 } else {
10967 tcg_temp_free_i32(addr);
10968 }
10969 }
10970 }
10971 break;
10972 case 5:
10973
10974 op = (insn >> 21) & 0xf;
10975 if (op == 6) {
10976 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10977 goto illegal_op;
10978 }
10979 /* Halfword pack. */
10980 tmp = load_reg(s, rn);
10981 tmp2 = load_reg(s, rm);
10982 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10983 if (insn & (1 << 5)) {
10984 /* pkhtb */
10985 if (shift == 0)
10986 shift = 31;
10987 tcg_gen_sari_i32(tmp2, tmp2, shift);
10988 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10989 tcg_gen_ext16u_i32(tmp2, tmp2);
10990 } else {
10991 /* pkhbt */
10992 if (shift)
10993 tcg_gen_shli_i32(tmp2, tmp2, shift);
10994 tcg_gen_ext16u_i32(tmp, tmp);
10995 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10996 }
10997 tcg_gen_or_i32(tmp, tmp, tmp2);
10998 tcg_temp_free_i32(tmp2);
10999 store_reg(s, rd, tmp);
11000 } else {
11001 /* Data processing register constant shift. */
11002 if (rn == 15) {
11003 tmp = tcg_temp_new_i32();
11004 tcg_gen_movi_i32(tmp, 0);
11005 } else {
11006 tmp = load_reg(s, rn);
11007 }
11008 tmp2 = load_reg(s, rm);
11009
11010 shiftop = (insn >> 4) & 3;
11011 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11012 conds = (insn & (1 << 20)) != 0;
11013 logic_cc = (conds && thumb2_logic_op(op));
11014 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
11015 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
11016 goto illegal_op;
11017 tcg_temp_free_i32(tmp2);
11018 if (rd == 13 &&
11019 ((op == 2 && rn == 15) ||
11020 (op == 8 && rn == 13) ||
11021 (op == 13 && rn == 13))) {
11022 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11023 store_sp_checked(s, tmp);
11024 } else if (rd != 15) {
11025 store_reg(s, rd, tmp);
11026 } else {
11027 tcg_temp_free_i32(tmp);
11028 }
11029 }
11030 break;
11031 case 13: /* Misc data processing. */
11032 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
11033 if (op < 4 && (insn & 0xf000) != 0xf000)
11034 goto illegal_op;
11035 switch (op) {
11036 case 0: /* Register controlled shift. */
11037 tmp = load_reg(s, rn);
11038 tmp2 = load_reg(s, rm);
11039 if ((insn & 0x70) != 0)
11040 goto illegal_op;
11041 /*
11042 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11043 * - MOV, MOVS (register-shifted register), flagsetting
11044 */
11045 op = (insn >> 21) & 3;
11046 logic_cc = (insn & (1 << 20)) != 0;
11047 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
11048 if (logic_cc)
11049 gen_logic_CC(tmp);
11050 store_reg(s, rd, tmp);
11051 break;
11052 case 1: /* Sign/zero extend. */
11053 op = (insn >> 20) & 7;
11054 switch (op) {
11055 case 0: /* SXTAH, SXTH */
11056 case 1: /* UXTAH, UXTH */
11057 case 4: /* SXTAB, SXTB */
11058 case 5: /* UXTAB, UXTB */
11059 break;
11060 case 2: /* SXTAB16, SXTB16 */
11061 case 3: /* UXTAB16, UXTB16 */
11062 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11063 goto illegal_op;
11064 }
11065 break;
11066 default:
11067 goto illegal_op;
11068 }
11069 if (rn != 15) {
11070 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11071 goto illegal_op;
11072 }
11073 }
11074 tmp = load_reg(s, rm);
11075 shift = (insn >> 4) & 3;
11076 /* ??? In many cases it's not necessary to do a
11077 rotate, a shift is sufficient. */
11078 if (shift != 0)
11079 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
11080 op = (insn >> 20) & 7;
11081 switch (op) {
11082 case 0: gen_sxth(tmp); break;
11083 case 1: gen_uxth(tmp); break;
11084 case 2: gen_sxtb16(tmp); break;
11085 case 3: gen_uxtb16(tmp); break;
11086 case 4: gen_sxtb(tmp); break;
11087 case 5: gen_uxtb(tmp); break;
11088 default:
11089 g_assert_not_reached();
11090 }
11091 if (rn != 15) {
11092 tmp2 = load_reg(s, rn);
11093 if ((op >> 1) == 1) {
11094 gen_add16(tmp, tmp2);
11095 } else {
11096 tcg_gen_add_i32(tmp, tmp, tmp2);
11097 tcg_temp_free_i32(tmp2);
11098 }
11099 }
11100 store_reg(s, rd, tmp);
11101 break;
11102 case 2: /* SIMD add/subtract. */
11103 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11104 goto illegal_op;
11105 }
11106 op = (insn >> 20) & 7;
11107 shift = (insn >> 4) & 7;
11108 if ((op & 3) == 3 || (shift & 3) == 3)
11109 goto illegal_op;
11110 tmp = load_reg(s, rn);
11111 tmp2 = load_reg(s, rm);
11112 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
11113 tcg_temp_free_i32(tmp2);
11114 store_reg(s, rd, tmp);
11115 break;
11116 case 3: /* Other data processing. */
11117 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
11118 if (op < 4) {
11119 /* Saturating add/subtract. */
11120 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11121 goto illegal_op;
11122 }
11123 tmp = load_reg(s, rn);
11124 tmp2 = load_reg(s, rm);
11125 if (op & 1)
11126 gen_helper_double_saturate(tmp, cpu_env, tmp);
11127 if (op & 2)
11128 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
11129 else
11130 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
11131 tcg_temp_free_i32(tmp2);
11132 } else {
11133 switch (op) {
11134 case 0x0a: /* rbit */
11135 case 0x08: /* rev */
11136 case 0x09: /* rev16 */
11137 case 0x0b: /* revsh */
11138 case 0x18: /* clz */
11139 break;
11140 case 0x10: /* sel */
11141 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11142 goto illegal_op;
11143 }
11144 break;
11145 case 0x20: /* crc32/crc32c */
11146 case 0x21:
11147 case 0x22:
11148 case 0x28:
11149 case 0x29:
11150 case 0x2a:
11151 if (!dc_isar_feature(aa32_crc32, s)) {
11152 goto illegal_op;
11153 }
11154 break;
11155 default:
11156 goto illegal_op;
11157 }
11158 tmp = load_reg(s, rn);
11159 switch (op) {
11160 case 0x0a: /* rbit */
11161 gen_helper_rbit(tmp, tmp);
11162 break;
11163 case 0x08: /* rev */
11164 tcg_gen_bswap32_i32(tmp, tmp);
11165 break;
11166 case 0x09: /* rev16 */
11167 gen_rev16(tmp);
11168 break;
11169 case 0x0b: /* revsh */
11170 gen_revsh(tmp);
11171 break;
11172 case 0x10: /* sel */
11173 tmp2 = load_reg(s, rm);
11174 tmp3 = tcg_temp_new_i32();
11175 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
11176 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
11177 tcg_temp_free_i32(tmp3);
11178 tcg_temp_free_i32(tmp2);
11179 break;
11180 case 0x18: /* clz */
11181 tcg_gen_clzi_i32(tmp, tmp, 32);
11182 break;
11183 case 0x20:
11184 case 0x21:
11185 case 0x22:
11186 case 0x28:
11187 case 0x29:
11188 case 0x2a:
11189 {
11190 /* crc32/crc32c */
11191 uint32_t sz = op & 0x3;
11192 uint32_t c = op & 0x8;
11193
11194 tmp2 = load_reg(s, rm);
11195 if (sz == 0) {
11196 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
11197 } else if (sz == 1) {
11198 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
11199 }
11200 tmp3 = tcg_const_i32(1 << sz);
11201 if (c) {
11202 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
11203 } else {
11204 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
11205 }
11206 tcg_temp_free_i32(tmp2);
11207 tcg_temp_free_i32(tmp3);
11208 break;
11209 }
11210 default:
11211 g_assert_not_reached();
11212 }
11213 }
11214 store_reg(s, rd, tmp);
11215 break;
11216 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
11217 switch ((insn >> 20) & 7) {
11218 case 0: /* 32 x 32 -> 32 */
11219 case 7: /* Unsigned sum of absolute differences. */
11220 break;
11221 case 1: /* 16 x 16 -> 32 */
11222 case 2: /* Dual multiply add. */
11223 case 3: /* 32 * 16 -> 32msb */
11224 case 4: /* Dual multiply subtract. */
11225 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11226 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11227 goto illegal_op;
11228 }
11229 break;
11230 }
11231 op = (insn >> 4) & 0xf;
11232 tmp = load_reg(s, rn);
11233 tmp2 = load_reg(s, rm);
11234 switch ((insn >> 20) & 7) {
11235 case 0: /* 32 x 32 -> 32 */
11236 tcg_gen_mul_i32(tmp, tmp, tmp2);
11237 tcg_temp_free_i32(tmp2);
11238 if (rs != 15) {
11239 tmp2 = load_reg(s, rs);
11240 if (op)
11241 tcg_gen_sub_i32(tmp, tmp2, tmp);
11242 else
11243 tcg_gen_add_i32(tmp, tmp, tmp2);
11244 tcg_temp_free_i32(tmp2);
11245 }
11246 break;
11247 case 1: /* 16 x 16 -> 32 */
11248 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11249 tcg_temp_free_i32(tmp2);
11250 if (rs != 15) {
11251 tmp2 = load_reg(s, rs);
11252 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11253 tcg_temp_free_i32(tmp2);
11254 }
11255 break;
11256 case 2: /* Dual multiply add. */
11257 case 4: /* Dual multiply subtract. */
11258 if (op)
11259 gen_swap_half(tmp2);
11260 gen_smul_dual(tmp, tmp2);
11261 if (insn & (1 << 22)) {
11262 /* This subtraction cannot overflow. */
11263 tcg_gen_sub_i32(tmp, tmp, tmp2);
11264 } else {
11265 /* This addition cannot overflow 32 bits;
11266 * however it may overflow considered as a signed
11267 * operation, in which case we must set the Q flag.
11268 */
11269 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11270 }
11271 tcg_temp_free_i32(tmp2);
11272 if (rs != 15)
11273 {
11274 tmp2 = load_reg(s, rs);
11275 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11276 tcg_temp_free_i32(tmp2);
11277 }
11278 break;
11279 case 3: /* 32 * 16 -> 32msb */
11280 if (op)
11281 tcg_gen_sari_i32(tmp2, tmp2, 16);
11282 else
11283 gen_sxth(tmp2);
11284 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11285 tcg_gen_shri_i64(tmp64, tmp64, 16);
11286 tmp = tcg_temp_new_i32();
11287 tcg_gen_extrl_i64_i32(tmp, tmp64);
11288 tcg_temp_free_i64(tmp64);
11289 if (rs != 15)
11290 {
11291 tmp2 = load_reg(s, rs);
11292 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11293 tcg_temp_free_i32(tmp2);
11294 }
11295 break;
11296 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11297 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11298 if (rs != 15) {
11299 tmp = load_reg(s, rs);
11300 if (insn & (1 << 20)) {
11301 tmp64 = gen_addq_msw(tmp64, tmp);
11302 } else {
11303 tmp64 = gen_subq_msw(tmp64, tmp);
11304 }
11305 }
11306 if (insn & (1 << 4)) {
11307 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11308 }
11309 tcg_gen_shri_i64(tmp64, tmp64, 32);
11310 tmp = tcg_temp_new_i32();
11311 tcg_gen_extrl_i64_i32(tmp, tmp64);
11312 tcg_temp_free_i64(tmp64);
11313 break;
11314 case 7: /* Unsigned sum of absolute differences. */
11315 gen_helper_usad8(tmp, tmp, tmp2);
11316 tcg_temp_free_i32(tmp2);
11317 if (rs != 15) {
11318 tmp2 = load_reg(s, rs);
11319 tcg_gen_add_i32(tmp, tmp, tmp2);
11320 tcg_temp_free_i32(tmp2);
11321 }
11322 break;
11323 }
11324 store_reg(s, rd, tmp);
11325 break;
11326 case 6: case 7: /* 64-bit multiply, Divide. */
11327 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11328 tmp = load_reg(s, rn);
11329 tmp2 = load_reg(s, rm);
11330 if ((op & 0x50) == 0x10) {
11331 /* sdiv, udiv */
11332 if (!dc_isar_feature(thumb_div, s)) {
11333 goto illegal_op;
11334 }
11335 if (op & 0x20)
11336 gen_helper_udiv(tmp, tmp, tmp2);
11337 else
11338 gen_helper_sdiv(tmp, tmp, tmp2);
11339 tcg_temp_free_i32(tmp2);
11340 store_reg(s, rd, tmp);
11341 } else if ((op & 0xe) == 0xc) {
11342 /* Dual multiply accumulate long. */
11343 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11344 tcg_temp_free_i32(tmp);
11345 tcg_temp_free_i32(tmp2);
11346 goto illegal_op;
11347 }
11348 if (op & 1)
11349 gen_swap_half(tmp2);
11350 gen_smul_dual(tmp, tmp2);
11351 if (op & 0x10) {
11352 tcg_gen_sub_i32(tmp, tmp, tmp2);
11353 } else {
11354 tcg_gen_add_i32(tmp, tmp, tmp2);
11355 }
11356 tcg_temp_free_i32(tmp2);
11357 /* BUGFIX */
11358 tmp64 = tcg_temp_new_i64();
11359 tcg_gen_ext_i32_i64(tmp64, tmp);
11360 tcg_temp_free_i32(tmp);
11361 gen_addq(s, tmp64, rs, rd);
11362 gen_storeq_reg(s, rs, rd, tmp64);
11363 tcg_temp_free_i64(tmp64);
11364 } else {
11365 if (op & 0x20) {
11366 /* Unsigned 64-bit multiply */
11367 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11368 } else {
11369 if (op & 8) {
11370 /* smlalxy */
11371 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11372 tcg_temp_free_i32(tmp2);
11373 tcg_temp_free_i32(tmp);
11374 goto illegal_op;
11375 }
11376 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11377 tcg_temp_free_i32(tmp2);
11378 tmp64 = tcg_temp_new_i64();
11379 tcg_gen_ext_i32_i64(tmp64, tmp);
11380 tcg_temp_free_i32(tmp);
11381 } else {
11382 /* Signed 64-bit multiply */
11383 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11384 }
11385 }
11386 if (op & 4) {
11387 /* umaal */
11388 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11389 tcg_temp_free_i64(tmp64);
11390 goto illegal_op;
11391 }
11392 gen_addq_lo(s, tmp64, rs);
11393 gen_addq_lo(s, tmp64, rd);
11394 } else if (op & 0x40) {
11395 /* 64-bit accumulate. */
11396 gen_addq(s, tmp64, rs, rd);
11397 }
11398 gen_storeq_reg(s, rs, rd, tmp64);
11399 tcg_temp_free_i64(tmp64);
11400 }
11401 break;
11402 }
11403 break;
11404 case 6: case 7: case 14: case 15:
11405 /* Coprocessor. */
11406 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11407 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
11408 if (extract32(insn, 24, 2) == 3) {
11409 goto illegal_op; /* op0 = 0b11 : unallocated */
11410 }
11411
11412 /*
11413 * Decode VLLDM and VLSTM first: these are nonstandard because:
11414 * * if there is no FPU then these insns must NOP in
11415 * Secure state and UNDEF in Nonsecure state
11416 * * if there is an FPU then these insns do not have
11417 * the usual behaviour that disas_vfp_insn() provides of
11418 * being controlled by CPACR/NSACR enable bits or the
11419 * lazy-stacking logic.
11420 */
11421 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11422 (insn & 0xffa00f00) == 0xec200a00) {
11423 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11424 * - VLLDM, VLSTM
11425 * We choose to UNDEF if the RAZ bits are non-zero.
11426 */
11427 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11428 goto illegal_op;
11429 }
11430
11431 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
11432 TCGv_i32 fptr = load_reg(s, rn);
11433
11434 if (extract32(insn, 20, 1)) {
11435 gen_helper_v7m_vlldm(cpu_env, fptr);
11436 } else {
11437 gen_helper_v7m_vlstm(cpu_env, fptr);
11438 }
11439 tcg_temp_free_i32(fptr);
11440
11441 /* End the TB, because we have updated FP control bits */
11442 s->base.is_jmp = DISAS_UPDATE;
11443 }
11444 break;
11445 }
11446 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
11447 ((insn >> 8) & 0xe) == 10) {
11448 /* FP, and the CPU supports it */
11449 if (disas_vfp_insn(s, insn)) {
11450 goto illegal_op;
11451 }
11452 break;
11453 }
11454
11455 /* All other insns: NOCP */
11456 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11457 default_exception_el(s));
11458 break;
11459 }
11460 if ((insn & 0xfe000a00) == 0xfc000800
11461 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11462 /* The Thumb2 and ARM encodings are identical. */
11463 if (disas_neon_insn_3same_ext(s, insn)) {
11464 goto illegal_op;
11465 }
11466 } else if ((insn & 0xff000a00) == 0xfe000800
11467 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11468 /* The Thumb2 and ARM encodings are identical. */
11469 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11470 goto illegal_op;
11471 }
11472 } else if (((insn >> 24) & 3) == 3) {
11473 /* Translate into the equivalent ARM encoding. */
11474 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11475 if (disas_neon_data_insn(s, insn)) {
11476 goto illegal_op;
11477 }
11478 } else if (((insn >> 8) & 0xe) == 10) {
11479 if (disas_vfp_insn(s, insn)) {
11480 goto illegal_op;
11481 }
11482 } else {
11483 if (insn & (1 << 28))
11484 goto illegal_op;
11485 if (disas_coproc_insn(s, insn)) {
11486 goto illegal_op;
11487 }
11488 }
11489 break;
11490 case 8: case 9: case 10: case 11:
11491 if (insn & (1 << 15)) {
11492 /* Branches, misc control. */
11493 if (insn & 0x5000) {
11494 /* Unconditional branch. */
11495 /* signextend(hw1[10:0]) -> offset[:12]. */
11496 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11497 /* hw1[10:0] -> offset[11:1]. */
11498 offset |= (insn & 0x7ff) << 1;
11499 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11500 offset[24:22] already have the same value because of the
11501 sign extension above. */
11502 offset ^= ((~insn) & (1 << 13)) << 10;
11503 offset ^= ((~insn) & (1 << 11)) << 11;
11504
11505 if (insn & (1 << 14)) {
11506 /* Branch and link. */
11507 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11508 }
11509
11510 offset += s->pc;
11511 if (insn & (1 << 12)) {
11512 /* b/bl */
11513 gen_jmp(s, offset);
11514 } else {
11515 /* blx */
11516 offset &= ~(uint32_t)2;
11517 /* thumb2 bx, no need to check */
11518 gen_bx_im(s, offset);
11519 }
11520 } else if (((insn >> 23) & 7) == 7) {
11521 /* Misc control */
11522 if (insn & (1 << 13))
11523 goto illegal_op;
11524
11525 if (insn & (1 << 26)) {
11526 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11527 goto illegal_op;
11528 }
11529 if (!(insn & (1 << 20))) {
11530 /* Hypervisor call (v7) */
11531 int imm16 = extract32(insn, 16, 4) << 12
11532 | extract32(insn, 0, 12);
11533 ARCH(7);
11534 if (IS_USER(s)) {
11535 goto illegal_op;
11536 }
11537 gen_hvc(s, imm16);
11538 } else {
11539 /* Secure monitor call (v6+) */
11540 ARCH(6K);
11541 if (IS_USER(s)) {
11542 goto illegal_op;
11543 }
11544 gen_smc(s);
11545 }
11546 } else {
11547 op = (insn >> 20) & 7;
11548 switch (op) {
11549 case 0: /* msr cpsr. */
11550 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11551 tmp = load_reg(s, rn);
11552 /* the constant is the mask and SYSm fields */
11553 addr = tcg_const_i32(insn & 0xfff);
11554 gen_helper_v7m_msr(cpu_env, addr, tmp);
11555 tcg_temp_free_i32(addr);
11556 tcg_temp_free_i32(tmp);
11557 gen_lookup_tb(s);
11558 break;
11559 }
11560 /* fall through */
11561 case 1: /* msr spsr. */
11562 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11563 goto illegal_op;
11564 }
11565
11566 if (extract32(insn, 5, 1)) {
11567 /* MSR (banked) */
11568 int sysm = extract32(insn, 8, 4) |
11569 (extract32(insn, 4, 1) << 4);
11570 int r = op & 1;
11571
11572 gen_msr_banked(s, r, sysm, rm);
11573 break;
11574 }
11575
11576 /* MSR (for PSRs) */
11577 tmp = load_reg(s, rn);
11578 if (gen_set_psr(s,
11579 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11580 op == 1, tmp))
11581 goto illegal_op;
11582 break;
11583 case 2: /* cps, nop-hint. */
11584 if (((insn >> 8) & 7) == 0) {
11585 gen_nop_hint(s, insn & 0xff);
11586 }
11587 /* Implemented as NOP in user mode. */
11588 if (IS_USER(s))
11589 break;
11590 offset = 0;
11591 imm = 0;
11592 if (insn & (1 << 10)) {
11593 if (insn & (1 << 7))
11594 offset |= CPSR_A;
11595 if (insn & (1 << 6))
11596 offset |= CPSR_I;
11597 if (insn & (1 << 5))
11598 offset |= CPSR_F;
11599 if (insn & (1 << 9))
11600 imm = CPSR_A | CPSR_I | CPSR_F;
11601 }
11602 if (insn & (1 << 8)) {
11603 offset |= 0x1f;
11604 imm |= (insn & 0x1f);
11605 }
11606 if (offset) {
11607 gen_set_psr_im(s, offset, 0, imm);
11608 }
11609 break;
11610 case 3: /* Special control operations. */
11611 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11612 !arm_dc_feature(s, ARM_FEATURE_M)) {
11613 goto illegal_op;
11614 }
11615 op = (insn >> 4) & 0xf;
11616 switch (op) {
11617 case 2: /* clrex */
11618 gen_clrex(s);
11619 break;
11620 case 4: /* dsb */
11621 case 5: /* dmb */
11622 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11623 break;
11624 case 6: /* isb */
11625 /* We need to break the TB after this insn
11626 * to execute self-modifying code correctly
11627 * and also to take any pending interrupts
11628 * immediately.
11629 */
11630 gen_goto_tb(s, 0, s->pc & ~1);
11631 break;
11632 case 7: /* sb */
11633 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
11634 goto illegal_op;
11635 }
11636 /*
11637 * TODO: There is no speculation barrier opcode
11638 * for TCG; MB and end the TB instead.
11639 */
11640 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11641 gen_goto_tb(s, 0, s->pc & ~1);
11642 break;
11643 default:
11644 goto illegal_op;
11645 }
11646 break;
11647 case 4: /* bxj */
11648 /* Trivial implementation equivalent to bx.
11649 * This instruction doesn't exist at all for M-profile.
11650 */
11651 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11652 goto illegal_op;
11653 }
11654 tmp = load_reg(s, rn);
11655 gen_bx(s, tmp);
11656 break;
11657 case 5: /* Exception return. */
11658 if (IS_USER(s)) {
11659 goto illegal_op;
11660 }
11661 if (rn != 14 || rd != 15) {
11662 goto illegal_op;
11663 }
11664 if (s->current_el == 2) {
11665 /* ERET from Hyp uses ELR_Hyp, not LR */
11666 if (insn & 0xff) {
11667 goto illegal_op;
11668 }
11669 tmp = load_cpu_field(elr_el[2]);
11670 } else {
11671 tmp = load_reg(s, rn);
11672 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11673 }
11674 gen_exception_return(s, tmp);
11675 break;
11676 case 6: /* MRS */
11677 if (extract32(insn, 5, 1) &&
11678 !arm_dc_feature(s, ARM_FEATURE_M)) {
11679 /* MRS (banked) */
11680 int sysm = extract32(insn, 16, 4) |
11681 (extract32(insn, 4, 1) << 4);
11682
11683 gen_mrs_banked(s, 0, sysm, rd);
11684 break;
11685 }
11686
11687 if (extract32(insn, 16, 4) != 0xf) {
11688 goto illegal_op;
11689 }
11690 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11691 extract32(insn, 0, 8) != 0) {
11692 goto illegal_op;
11693 }
11694
11695 /* mrs cpsr */
11696 tmp = tcg_temp_new_i32();
11697 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11698 addr = tcg_const_i32(insn & 0xff);
11699 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11700 tcg_temp_free_i32(addr);
11701 } else {
11702 gen_helper_cpsr_read(tmp, cpu_env);
11703 }
11704 store_reg(s, rd, tmp);
11705 break;
11706 case 7: /* MRS */
11707 if (extract32(insn, 5, 1) &&
11708 !arm_dc_feature(s, ARM_FEATURE_M)) {
11709 /* MRS (banked) */
11710 int sysm = extract32(insn, 16, 4) |
11711 (extract32(insn, 4, 1) << 4);
11712
11713 gen_mrs_banked(s, 1, sysm, rd);
11714 break;
11715 }
11716
11717 /* mrs spsr. */
11718 /* Not accessible in user mode. */
11719 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11720 goto illegal_op;
11721 }
11722
11723 if (extract32(insn, 16, 4) != 0xf ||
11724 extract32(insn, 0, 8) != 0) {
11725 goto illegal_op;
11726 }
11727
11728 tmp = load_cpu_field(spsr);
11729 store_reg(s, rd, tmp);
11730 break;
11731 }
11732 }
11733 } else {
11734 /* Conditional branch. */
11735 op = (insn >> 22) & 0xf;
11736 /* Generate a conditional jump to next instruction. */
11737 arm_skip_unless(s, op);
11738
11739 /* offset[11:1] = insn[10:0] */
11740 offset = (insn & 0x7ff) << 1;
11741 /* offset[17:12] = insn[21:16]. */
11742 offset |= (insn & 0x003f0000) >> 4;
11743 /* offset[31:20] = insn[26]. */
11744 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11745 /* offset[18] = insn[13]. */
11746 offset |= (insn & (1 << 13)) << 5;
11747 /* offset[19] = insn[11]. */
11748 offset |= (insn & (1 << 11)) << 8;
11749
11750 /* jump to the offset */
11751 gen_jmp(s, s->pc + offset);
11752 }
11753 } else {
11754 /*
11755 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11756 * - Data-processing (modified immediate, plain binary immediate)
11757 */
11758 if (insn & (1 << 25)) {
11759 /*
11760 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11761 * - Data-processing (plain binary immediate)
11762 */
11763 if (insn & (1 << 24)) {
11764 if (insn & (1 << 20))
11765 goto illegal_op;
11766 /* Bitfield/Saturate. */
11767 op = (insn >> 21) & 7;
11768 imm = insn & 0x1f;
11769 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11770 if (rn == 15) {
11771 tmp = tcg_temp_new_i32();
11772 tcg_gen_movi_i32(tmp, 0);
11773 } else {
11774 tmp = load_reg(s, rn);
11775 }
11776 switch (op) {
11777 case 2: /* Signed bitfield extract. */
11778 imm++;
11779 if (shift + imm > 32)
11780 goto illegal_op;
11781 if (imm < 32) {
11782 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11783 }
11784 break;
11785 case 6: /* Unsigned bitfield extract. */
11786 imm++;
11787 if (shift + imm > 32)
11788 goto illegal_op;
11789 if (imm < 32) {
11790 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11791 }
11792 break;
11793 case 3: /* Bitfield insert/clear. */
11794 if (imm < shift)
11795 goto illegal_op;
11796 imm = imm + 1 - shift;
11797 if (imm != 32) {
11798 tmp2 = load_reg(s, rd);
11799 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11800 tcg_temp_free_i32(tmp2);
11801 }
11802 break;
11803 case 7:
11804 goto illegal_op;
11805 default: /* Saturate. */
11806 if (shift) {
11807 if (op & 1)
11808 tcg_gen_sari_i32(tmp, tmp, shift);
11809 else
11810 tcg_gen_shli_i32(tmp, tmp, shift);
11811 }
11812 tmp2 = tcg_const_i32(imm);
11813 if (op & 4) {
11814 /* Unsigned. */
11815 if ((op & 1) && shift == 0) {
11816 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11817 tcg_temp_free_i32(tmp);
11818 tcg_temp_free_i32(tmp2);
11819 goto illegal_op;
11820 }
11821 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11822 } else {
11823 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11824 }
11825 } else {
11826 /* Signed. */
11827 if ((op & 1) && shift == 0) {
11828 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11829 tcg_temp_free_i32(tmp);
11830 tcg_temp_free_i32(tmp2);
11831 goto illegal_op;
11832 }
11833 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11834 } else {
11835 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11836 }
11837 }
11838 tcg_temp_free_i32(tmp2);
11839 break;
11840 }
11841 store_reg(s, rd, tmp);
11842 } else {
11843 imm = ((insn & 0x04000000) >> 15)
11844 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11845 if (insn & (1 << 22)) {
11846 /* 16-bit immediate. */
11847 imm |= (insn >> 4) & 0xf000;
11848 if (insn & (1 << 23)) {
11849 /* movt */
11850 tmp = load_reg(s, rd);
11851 tcg_gen_ext16u_i32(tmp, tmp);
11852 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11853 } else {
11854 /* movw */
11855 tmp = tcg_temp_new_i32();
11856 tcg_gen_movi_i32(tmp, imm);
11857 }
11858 store_reg(s, rd, tmp);
11859 } else {
11860 /* Add/sub 12-bit immediate. */
11861 if (rn == 15) {
11862 offset = s->pc & ~(uint32_t)3;
11863 if (insn & (1 << 23))
11864 offset -= imm;
11865 else
11866 offset += imm;
11867 tmp = tcg_temp_new_i32();
11868 tcg_gen_movi_i32(tmp, offset);
11869 store_reg(s, rd, tmp);
11870 } else {
11871 tmp = load_reg(s, rn);
11872 if (insn & (1 << 23))
11873 tcg_gen_subi_i32(tmp, tmp, imm);
11874 else
11875 tcg_gen_addi_i32(tmp, tmp, imm);
11876 if (rn == 13 && rd == 13) {
11877 /* ADD SP, SP, imm or SUB SP, SP, imm */
11878 store_sp_checked(s, tmp);
11879 } else {
11880 store_reg(s, rd, tmp);
11881 }
11882 }
11883 }
11884 }
11885 } else {
11886 /*
11887 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11888 * - Data-processing (modified immediate)
11889 */
11890 int shifter_out = 0;
11891 /* modified 12-bit immediate. */
11892 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11893 imm = (insn & 0xff);
11894 switch (shift) {
11895 case 0: /* XY */
11896 /* Nothing to do. */
11897 break;
11898 case 1: /* 00XY00XY */
11899 imm |= imm << 16;
11900 break;
11901 case 2: /* XY00XY00 */
11902 imm |= imm << 16;
11903 imm <<= 8;
11904 break;
11905 case 3: /* XYXYXYXY */
11906 imm |= imm << 16;
11907 imm |= imm << 8;
11908 break;
11909 default: /* Rotated constant. */
11910 shift = (shift << 1) | (imm >> 7);
11911 imm |= 0x80;
11912 imm = imm << (32 - shift);
11913 shifter_out = 1;
11914 break;
11915 }
11916 tmp2 = tcg_temp_new_i32();
11917 tcg_gen_movi_i32(tmp2, imm);
11918 rn = (insn >> 16) & 0xf;
11919 if (rn == 15) {
11920 tmp = tcg_temp_new_i32();
11921 tcg_gen_movi_i32(tmp, 0);
11922 } else {
11923 tmp = load_reg(s, rn);
11924 }
11925 op = (insn >> 21) & 0xf;
11926 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11927 shifter_out, tmp, tmp2))
11928 goto illegal_op;
11929 tcg_temp_free_i32(tmp2);
11930 rd = (insn >> 8) & 0xf;
11931 if (rd == 13 && rn == 13
11932 && (op == 8 || op == 13)) {
11933 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11934 store_sp_checked(s, tmp);
11935 } else if (rd != 15) {
11936 store_reg(s, rd, tmp);
11937 } else {
11938 tcg_temp_free_i32(tmp);
11939 }
11940 }
11941 }
11942 break;
11943 case 12: /* Load/store single data item. */
11944 {
11945 int postinc = 0;
11946 int writeback = 0;
11947 int memidx;
11948 ISSInfo issinfo;
11949
11950 if ((insn & 0x01100000) == 0x01000000) {
11951 if (disas_neon_ls_insn(s, insn)) {
11952 goto illegal_op;
11953 }
11954 break;
11955 }
11956 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11957 if (rs == 15) {
11958 if (!(insn & (1 << 20))) {
11959 goto illegal_op;
11960 }
11961 if (op != 2) {
11962 /* Byte or halfword load space with dest == r15 : memory hints.
11963 * Catch them early so we don't emit pointless addressing code.
11964 * This space is a mix of:
11965 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11966 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11967 * cores)
11968 * unallocated hints, which must be treated as NOPs
11969 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11970 * which is easiest for the decoding logic
11971 * Some space which must UNDEF
11972 */
11973 int op1 = (insn >> 23) & 3;
11974 int op2 = (insn >> 6) & 0x3f;
11975 if (op & 2) {
11976 goto illegal_op;
11977 }
11978 if (rn == 15) {
11979 /* UNPREDICTABLE, unallocated hint or
11980 * PLD/PLDW/PLI (literal)
11981 */
11982 return;
11983 }
11984 if (op1 & 1) {
11985 return; /* PLD/PLDW/PLI or unallocated hint */
11986 }
11987 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11988 return; /* PLD/PLDW/PLI or unallocated hint */
11989 }
11990 /* UNDEF space, or an UNPREDICTABLE */
11991 goto illegal_op;
11992 }
11993 }
11994 memidx = get_mem_index(s);
11995 if (rn == 15) {
11996 addr = tcg_temp_new_i32();
11997 /* PC relative. */
11998 /* s->pc has already been incremented by 4. */
11999 imm = s->pc & 0xfffffffc;
12000 if (insn & (1 << 23))
12001 imm += insn & 0xfff;
12002 else
12003 imm -= insn & 0xfff;
12004 tcg_gen_movi_i32(addr, imm);
12005 } else {
12006 addr = load_reg(s, rn);
12007 if (insn & (1 << 23)) {
12008 /* Positive offset. */
12009 imm = insn & 0xfff;
12010 tcg_gen_addi_i32(addr, addr, imm);
12011 } else {
12012 imm = insn & 0xff;
12013 switch ((insn >> 8) & 0xf) {
12014 case 0x0: /* Shifted Register. */
12015 shift = (insn >> 4) & 0xf;
12016 if (shift > 3) {
12017 tcg_temp_free_i32(addr);
12018 goto illegal_op;
12019 }
12020 tmp = load_reg(s, rm);
12021 if (shift)
12022 tcg_gen_shli_i32(tmp, tmp, shift);
12023 tcg_gen_add_i32(addr, addr, tmp);
12024 tcg_temp_free_i32(tmp);
12025 break;
12026 case 0xc: /* Negative offset. */
12027 tcg_gen_addi_i32(addr, addr, -imm);
12028 break;
12029 case 0xe: /* User privilege. */
12030 tcg_gen_addi_i32(addr, addr, imm);
12031 memidx = get_a32_user_mem_index(s);
12032 break;
12033 case 0x9: /* Post-decrement. */
12034 imm = -imm;
12035 /* Fall through. */
12036 case 0xb: /* Post-increment. */
12037 postinc = 1;
12038 writeback = 1;
12039 break;
12040 case 0xd: /* Pre-decrement. */
12041 imm = -imm;
12042 /* Fall through. */
12043 case 0xf: /* Pre-increment. */
12044 writeback = 1;
12045 break;
12046 default:
12047 tcg_temp_free_i32(addr);
12048 goto illegal_op;
12049 }
12050 }
12051 }
12052
12053 issinfo = writeback ? ISSInvalid : rs;
12054
12055 if (s->v8m_stackcheck && rn == 13 && writeback) {
12056 /*
12057 * Stackcheck. Here we know 'addr' is the current SP;
12058 * if imm is +ve we're moving SP up, else down. It is
12059 * UNKNOWN whether the limit check triggers when SP starts
12060 * below the limit and ends up above it; we chose to do so.
12061 */
12062 if ((int32_t)imm < 0) {
12063 TCGv_i32 newsp = tcg_temp_new_i32();
12064
12065 tcg_gen_addi_i32(newsp, addr, imm);
12066 gen_helper_v8m_stackcheck(cpu_env, newsp);
12067 tcg_temp_free_i32(newsp);
12068 } else {
12069 gen_helper_v8m_stackcheck(cpu_env, addr);
12070 }
12071 }
12072
12073 if (writeback && !postinc) {
12074 tcg_gen_addi_i32(addr, addr, imm);
12075 }
12076
12077 if (insn & (1 << 20)) {
12078 /* Load. */
12079 tmp = tcg_temp_new_i32();
12080 switch (op) {
12081 case 0:
12082 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
12083 break;
12084 case 4:
12085 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
12086 break;
12087 case 1:
12088 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
12089 break;
12090 case 5:
12091 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
12092 break;
12093 case 2:
12094 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
12095 break;
12096 default:
12097 tcg_temp_free_i32(tmp);
12098 tcg_temp_free_i32(addr);
12099 goto illegal_op;
12100 }
12101 if (rs == 15) {
12102 gen_bx_excret(s, tmp);
12103 } else {
12104 store_reg(s, rs, tmp);
12105 }
12106 } else {
12107 /* Store. */
12108 tmp = load_reg(s, rs);
12109 switch (op) {
12110 case 0:
12111 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
12112 break;
12113 case 1:
12114 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
12115 break;
12116 case 2:
12117 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
12118 break;
12119 default:
12120 tcg_temp_free_i32(tmp);
12121 tcg_temp_free_i32(addr);
12122 goto illegal_op;
12123 }
12124 tcg_temp_free_i32(tmp);
12125 }
12126 if (postinc)
12127 tcg_gen_addi_i32(addr, addr, imm);
12128 if (writeback) {
12129 store_reg(s, rn, addr);
12130 } else {
12131 tcg_temp_free_i32(addr);
12132 }
12133 }
12134 break;
12135 default:
12136 goto illegal_op;
12137 }
12138 return;
12139 illegal_op:
12140 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
12141 default_exception_el(s));
12142 }
12143
12144 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
12145 {
12146 uint32_t val, op, rm, rn, rd, shift, cond;
12147 int32_t offset;
12148 int i;
12149 TCGv_i32 tmp;
12150 TCGv_i32 tmp2;
12151 TCGv_i32 addr;
12152
12153 switch (insn >> 12) {
12154 case 0: case 1:
12155
12156 rd = insn & 7;
12157 op = (insn >> 11) & 3;
12158 if (op == 3) {
12159 /*
12160 * 0b0001_1xxx_xxxx_xxxx
12161 * - Add, subtract (three low registers)
12162 * - Add, subtract (two low registers and immediate)
12163 */
12164 rn = (insn >> 3) & 7;
12165 tmp = load_reg(s, rn);
12166 if (insn & (1 << 10)) {
12167 /* immediate */
12168 tmp2 = tcg_temp_new_i32();
12169 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
12170 } else {
12171 /* reg */
12172 rm = (insn >> 6) & 7;
12173 tmp2 = load_reg(s, rm);
12174 }
12175 if (insn & (1 << 9)) {
12176 if (s->condexec_mask)
12177 tcg_gen_sub_i32(tmp, tmp, tmp2);
12178 else
12179 gen_sub_CC(tmp, tmp, tmp2);
12180 } else {
12181 if (s->condexec_mask)
12182 tcg_gen_add_i32(tmp, tmp, tmp2);
12183 else
12184 gen_add_CC(tmp, tmp, tmp2);
12185 }
12186 tcg_temp_free_i32(tmp2);
12187 store_reg(s, rd, tmp);
12188 } else {
12189 /* shift immediate */
12190 rm = (insn >> 3) & 7;
12191 shift = (insn >> 6) & 0x1f;
12192 tmp = load_reg(s, rm);
12193 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
12194 if (!s->condexec_mask)
12195 gen_logic_CC(tmp);
12196 store_reg(s, rd, tmp);
12197 }
12198 break;
12199 case 2: case 3:
12200 /*
12201 * 0b001x_xxxx_xxxx_xxxx
12202 * - Add, subtract, compare, move (one low register and immediate)
12203 */
12204 op = (insn >> 11) & 3;
12205 rd = (insn >> 8) & 0x7;
12206 if (op == 0) { /* mov */
12207 tmp = tcg_temp_new_i32();
12208 tcg_gen_movi_i32(tmp, insn & 0xff);
12209 if (!s->condexec_mask)
12210 gen_logic_CC(tmp);
12211 store_reg(s, rd, tmp);
12212 } else {
12213 tmp = load_reg(s, rd);
12214 tmp2 = tcg_temp_new_i32();
12215 tcg_gen_movi_i32(tmp2, insn & 0xff);
12216 switch (op) {
12217 case 1: /* cmp */
12218 gen_sub_CC(tmp, tmp, tmp2);
12219 tcg_temp_free_i32(tmp);
12220 tcg_temp_free_i32(tmp2);
12221 break;
12222 case 2: /* add */
12223 if (s->condexec_mask)
12224 tcg_gen_add_i32(tmp, tmp, tmp2);
12225 else
12226 gen_add_CC(tmp, tmp, tmp2);
12227 tcg_temp_free_i32(tmp2);
12228 store_reg(s, rd, tmp);
12229 break;
12230 case 3: /* sub */
12231 if (s->condexec_mask)
12232 tcg_gen_sub_i32(tmp, tmp, tmp2);
12233 else
12234 gen_sub_CC(tmp, tmp, tmp2);
12235 tcg_temp_free_i32(tmp2);
12236 store_reg(s, rd, tmp);
12237 break;
12238 }
12239 }
12240 break;
12241 case 4:
12242 if (insn & (1 << 11)) {
12243 rd = (insn >> 8) & 7;
12244 /* load pc-relative. Bit 1 of PC is ignored. */
12245 val = s->pc + 2 + ((insn & 0xff) * 4);
12246 val &= ~(uint32_t)2;
12247 addr = tcg_temp_new_i32();
12248 tcg_gen_movi_i32(addr, val);
12249 tmp = tcg_temp_new_i32();
12250 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
12251 rd | ISSIs16Bit);
12252 tcg_temp_free_i32(addr);
12253 store_reg(s, rd, tmp);
12254 break;
12255 }
12256 if (insn & (1 << 10)) {
12257 /* 0b0100_01xx_xxxx_xxxx
12258 * - data processing extended, branch and exchange
12259 */
12260 rd = (insn & 7) | ((insn >> 4) & 8);
12261 rm = (insn >> 3) & 0xf;
12262 op = (insn >> 8) & 3;
12263 switch (op) {
12264 case 0: /* add */
12265 tmp = load_reg(s, rd);
12266 tmp2 = load_reg(s, rm);
12267 tcg_gen_add_i32(tmp, tmp, tmp2);
12268 tcg_temp_free_i32(tmp2);
12269 if (rd == 13) {
12270 /* ADD SP, SP, reg */
12271 store_sp_checked(s, tmp);
12272 } else {
12273 store_reg(s, rd, tmp);
12274 }
12275 break;
12276 case 1: /* cmp */
12277 tmp = load_reg(s, rd);
12278 tmp2 = load_reg(s, rm);
12279 gen_sub_CC(tmp, tmp, tmp2);
12280 tcg_temp_free_i32(tmp2);
12281 tcg_temp_free_i32(tmp);
12282 break;
12283 case 2: /* mov/cpy */
12284 tmp = load_reg(s, rm);
12285 if (rd == 13) {
12286 /* MOV SP, reg */
12287 store_sp_checked(s, tmp);
12288 } else {
12289 store_reg(s, rd, tmp);
12290 }
12291 break;
12292 case 3:
12293 {
12294 /* 0b0100_0111_xxxx_xxxx
12295 * - branch [and link] exchange thumb register
12296 */
12297 bool link = insn & (1 << 7);
12298
12299 if (insn & 3) {
12300 goto undef;
12301 }
12302 if (link) {
12303 ARCH(5);
12304 }
12305 if ((insn & 4)) {
12306 /* BXNS/BLXNS: only exists for v8M with the
12307 * security extensions, and always UNDEF if NonSecure.
12308 * We don't implement these in the user-only mode
12309 * either (in theory you can use them from Secure User
12310 * mode but they are too tied in to system emulation.)
12311 */
12312 if (!s->v8m_secure || IS_USER_ONLY) {
12313 goto undef;
12314 }
12315 if (link) {
12316 gen_blxns(s, rm);
12317 } else {
12318 gen_bxns(s, rm);
12319 }
12320 break;
12321 }
12322 /* BLX/BX */
12323 tmp = load_reg(s, rm);
12324 if (link) {
12325 val = (uint32_t)s->pc | 1;
12326 tmp2 = tcg_temp_new_i32();
12327 tcg_gen_movi_i32(tmp2, val);
12328 store_reg(s, 14, tmp2);
12329 gen_bx(s, tmp);
12330 } else {
12331 /* Only BX works as exception-return, not BLX */
12332 gen_bx_excret(s, tmp);
12333 }
12334 break;
12335 }
12336 }
12337 break;
12338 }
12339
12340 /*
12341 * 0b0100_00xx_xxxx_xxxx
12342 * - Data-processing (two low registers)
12343 */
12344 rd = insn & 7;
12345 rm = (insn >> 3) & 7;
12346 op = (insn >> 6) & 0xf;
12347 if (op == 2 || op == 3 || op == 4 || op == 7) {
12348 /* the shift/rotate ops want the operands backwards */
12349 val = rm;
12350 rm = rd;
12351 rd = val;
12352 val = 1;
12353 } else {
12354 val = 0;
12355 }
12356
12357 if (op == 9) { /* neg */
12358 tmp = tcg_temp_new_i32();
12359 tcg_gen_movi_i32(tmp, 0);
12360 } else if (op != 0xf) { /* mvn doesn't read its first operand */
12361 tmp = load_reg(s, rd);
12362 } else {
12363 tmp = NULL;
12364 }
12365
12366 tmp2 = load_reg(s, rm);
12367 switch (op) {
12368 case 0x0: /* and */
12369 tcg_gen_and_i32(tmp, tmp, tmp2);
12370 if (!s->condexec_mask)
12371 gen_logic_CC(tmp);
12372 break;
12373 case 0x1: /* eor */
12374 tcg_gen_xor_i32(tmp, tmp, tmp2);
12375 if (!s->condexec_mask)
12376 gen_logic_CC(tmp);
12377 break;
12378 case 0x2: /* lsl */
12379 if (s->condexec_mask) {
12380 gen_shl(tmp2, tmp2, tmp);
12381 } else {
12382 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12383 gen_logic_CC(tmp2);
12384 }
12385 break;
12386 case 0x3: /* lsr */
12387 if (s->condexec_mask) {
12388 gen_shr(tmp2, tmp2, tmp);
12389 } else {
12390 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12391 gen_logic_CC(tmp2);
12392 }
12393 break;
12394 case 0x4: /* asr */
12395 if (s->condexec_mask) {
12396 gen_sar(tmp2, tmp2, tmp);
12397 } else {
12398 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12399 gen_logic_CC(tmp2);
12400 }
12401 break;
12402 case 0x5: /* adc */
12403 if (s->condexec_mask) {
12404 gen_adc(tmp, tmp2);
12405 } else {
12406 gen_adc_CC(tmp, tmp, tmp2);
12407 }
12408 break;
12409 case 0x6: /* sbc */
12410 if (s->condexec_mask) {
12411 gen_sub_carry(tmp, tmp, tmp2);
12412 } else {
12413 gen_sbc_CC(tmp, tmp, tmp2);
12414 }
12415 break;
12416 case 0x7: /* ror */
12417 if (s->condexec_mask) {
12418 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12419 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12420 } else {
12421 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12422 gen_logic_CC(tmp2);
12423 }
12424 break;
12425 case 0x8: /* tst */
12426 tcg_gen_and_i32(tmp, tmp, tmp2);
12427 gen_logic_CC(tmp);
12428 rd = 16;
12429 break;
12430 case 0x9: /* neg */
12431 if (s->condexec_mask)
12432 tcg_gen_neg_i32(tmp, tmp2);
12433 else
12434 gen_sub_CC(tmp, tmp, tmp2);
12435 break;
12436 case 0xa: /* cmp */
12437 gen_sub_CC(tmp, tmp, tmp2);
12438 rd = 16;
12439 break;
12440 case 0xb: /* cmn */
12441 gen_add_CC(tmp, tmp, tmp2);
12442 rd = 16;
12443 break;
12444 case 0xc: /* orr */
12445 tcg_gen_or_i32(tmp, tmp, tmp2);
12446 if (!s->condexec_mask)
12447 gen_logic_CC(tmp);
12448 break;
12449 case 0xd: /* mul */
12450 tcg_gen_mul_i32(tmp, tmp, tmp2);
12451 if (!s->condexec_mask)
12452 gen_logic_CC(tmp);
12453 break;
12454 case 0xe: /* bic */
12455 tcg_gen_andc_i32(tmp, tmp, tmp2);
12456 if (!s->condexec_mask)
12457 gen_logic_CC(tmp);
12458 break;
12459 case 0xf: /* mvn */
12460 tcg_gen_not_i32(tmp2, tmp2);
12461 if (!s->condexec_mask)
12462 gen_logic_CC(tmp2);
12463 val = 1;
12464 rm = rd;
12465 break;
12466 }
12467 if (rd != 16) {
12468 if (val) {
12469 store_reg(s, rm, tmp2);
12470 if (op != 0xf)
12471 tcg_temp_free_i32(tmp);
12472 } else {
12473 store_reg(s, rd, tmp);
12474 tcg_temp_free_i32(tmp2);
12475 }
12476 } else {
12477 tcg_temp_free_i32(tmp);
12478 tcg_temp_free_i32(tmp2);
12479 }
12480 break;
12481
12482 case 5:
12483 /* load/store register offset. */
12484 rd = insn & 7;
12485 rn = (insn >> 3) & 7;
12486 rm = (insn >> 6) & 7;
12487 op = (insn >> 9) & 7;
12488 addr = load_reg(s, rn);
12489 tmp = load_reg(s, rm);
12490 tcg_gen_add_i32(addr, addr, tmp);
12491 tcg_temp_free_i32(tmp);
12492
12493 if (op < 3) { /* store */
12494 tmp = load_reg(s, rd);
12495 } else {
12496 tmp = tcg_temp_new_i32();
12497 }
12498
12499 switch (op) {
12500 case 0: /* str */
12501 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12502 break;
12503 case 1: /* strh */
12504 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12505 break;
12506 case 2: /* strb */
12507 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12508 break;
12509 case 3: /* ldrsb */
12510 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12511 break;
12512 case 4: /* ldr */
12513 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12514 break;
12515 case 5: /* ldrh */
12516 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12517 break;
12518 case 6: /* ldrb */
12519 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12520 break;
12521 case 7: /* ldrsh */
12522 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12523 break;
12524 }
12525 if (op >= 3) { /* load */
12526 store_reg(s, rd, tmp);
12527 } else {
12528 tcg_temp_free_i32(tmp);
12529 }
12530 tcg_temp_free_i32(addr);
12531 break;
12532
12533 case 6:
12534 /* load/store word immediate offset */
12535 rd = insn & 7;
12536 rn = (insn >> 3) & 7;
12537 addr = load_reg(s, rn);
12538 val = (insn >> 4) & 0x7c;
12539 tcg_gen_addi_i32(addr, addr, val);
12540
12541 if (insn & (1 << 11)) {
12542 /* load */
12543 tmp = tcg_temp_new_i32();
12544 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12545 store_reg(s, rd, tmp);
12546 } else {
12547 /* store */
12548 tmp = load_reg(s, rd);
12549 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12550 tcg_temp_free_i32(tmp);
12551 }
12552 tcg_temp_free_i32(addr);
12553 break;
12554
12555 case 7:
12556 /* load/store byte immediate offset */
12557 rd = insn & 7;
12558 rn = (insn >> 3) & 7;
12559 addr = load_reg(s, rn);
12560 val = (insn >> 6) & 0x1f;
12561 tcg_gen_addi_i32(addr, addr, val);
12562
12563 if (insn & (1 << 11)) {
12564 /* load */
12565 tmp = tcg_temp_new_i32();
12566 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12567 store_reg(s, rd, tmp);
12568 } else {
12569 /* store */
12570 tmp = load_reg(s, rd);
12571 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12572 tcg_temp_free_i32(tmp);
12573 }
12574 tcg_temp_free_i32(addr);
12575 break;
12576
12577 case 8:
12578 /* load/store halfword immediate offset */
12579 rd = insn & 7;
12580 rn = (insn >> 3) & 7;
12581 addr = load_reg(s, rn);
12582 val = (insn >> 5) & 0x3e;
12583 tcg_gen_addi_i32(addr, addr, val);
12584
12585 if (insn & (1 << 11)) {
12586 /* load */
12587 tmp = tcg_temp_new_i32();
12588 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12589 store_reg(s, rd, tmp);
12590 } else {
12591 /* store */
12592 tmp = load_reg(s, rd);
12593 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12594 tcg_temp_free_i32(tmp);
12595 }
12596 tcg_temp_free_i32(addr);
12597 break;
12598
12599 case 9:
12600 /* load/store from stack */
12601 rd = (insn >> 8) & 7;
12602 addr = load_reg(s, 13);
12603 val = (insn & 0xff) * 4;
12604 tcg_gen_addi_i32(addr, addr, val);
12605
12606 if (insn & (1 << 11)) {
12607 /* load */
12608 tmp = tcg_temp_new_i32();
12609 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12610 store_reg(s, rd, tmp);
12611 } else {
12612 /* store */
12613 tmp = load_reg(s, rd);
12614 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12615 tcg_temp_free_i32(tmp);
12616 }
12617 tcg_temp_free_i32(addr);
12618 break;
12619
12620 case 10:
12621 /*
12622 * 0b1010_xxxx_xxxx_xxxx
12623 * - Add PC/SP (immediate)
12624 */
12625 rd = (insn >> 8) & 7;
12626 if (insn & (1 << 11)) {
12627 /* SP */
12628 tmp = load_reg(s, 13);
12629 } else {
12630 /* PC. bit 1 is ignored. */
12631 tmp = tcg_temp_new_i32();
12632 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12633 }
12634 val = (insn & 0xff) * 4;
12635 tcg_gen_addi_i32(tmp, tmp, val);
12636 store_reg(s, rd, tmp);
12637 break;
12638
12639 case 11:
12640 /* misc */
12641 op = (insn >> 8) & 0xf;
12642 switch (op) {
12643 case 0:
12644 /*
12645 * 0b1011_0000_xxxx_xxxx
12646 * - ADD (SP plus immediate)
12647 * - SUB (SP minus immediate)
12648 */
12649 tmp = load_reg(s, 13);
12650 val = (insn & 0x7f) * 4;
12651 if (insn & (1 << 7))
12652 val = -(int32_t)val;
12653 tcg_gen_addi_i32(tmp, tmp, val);
12654 store_sp_checked(s, tmp);
12655 break;
12656
12657 case 2: /* sign/zero extend. */
12658 ARCH(6);
12659 rd = insn & 7;
12660 rm = (insn >> 3) & 7;
12661 tmp = load_reg(s, rm);
12662 switch ((insn >> 6) & 3) {
12663 case 0: gen_sxth(tmp); break;
12664 case 1: gen_sxtb(tmp); break;
12665 case 2: gen_uxth(tmp); break;
12666 case 3: gen_uxtb(tmp); break;
12667 }
12668 store_reg(s, rd, tmp);
12669 break;
12670 case 4: case 5: case 0xc: case 0xd:
12671 /*
12672 * 0b1011_x10x_xxxx_xxxx
12673 * - push/pop
12674 */
12675 addr = load_reg(s, 13);
12676 if (insn & (1 << 8))
12677 offset = 4;
12678 else
12679 offset = 0;
12680 for (i = 0; i < 8; i++) {
12681 if (insn & (1 << i))
12682 offset += 4;
12683 }
12684 if ((insn & (1 << 11)) == 0) {
12685 tcg_gen_addi_i32(addr, addr, -offset);
12686 }
12687
12688 if (s->v8m_stackcheck) {
12689 /*
12690 * Here 'addr' is the lower of "old SP" and "new SP";
12691 * if this is a pop that starts below the limit and ends
12692 * above it, it is UNKNOWN whether the limit check triggers;
12693 * we choose to trigger.
12694 */
12695 gen_helper_v8m_stackcheck(cpu_env, addr);
12696 }
12697
12698 for (i = 0; i < 8; i++) {
12699 if (insn & (1 << i)) {
12700 if (insn & (1 << 11)) {
12701 /* pop */
12702 tmp = tcg_temp_new_i32();
12703 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12704 store_reg(s, i, tmp);
12705 } else {
12706 /* push */
12707 tmp = load_reg(s, i);
12708 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12709 tcg_temp_free_i32(tmp);
12710 }
12711 /* advance to the next address. */
12712 tcg_gen_addi_i32(addr, addr, 4);
12713 }
12714 }
12715 tmp = NULL;
12716 if (insn & (1 << 8)) {
12717 if (insn & (1 << 11)) {
12718 /* pop pc */
12719 tmp = tcg_temp_new_i32();
12720 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12721 /* don't set the pc until the rest of the instruction
12722 has completed */
12723 } else {
12724 /* push lr */
12725 tmp = load_reg(s, 14);
12726 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12727 tcg_temp_free_i32(tmp);
12728 }
12729 tcg_gen_addi_i32(addr, addr, 4);
12730 }
12731 if ((insn & (1 << 11)) == 0) {
12732 tcg_gen_addi_i32(addr, addr, -offset);
12733 }
12734 /* write back the new stack pointer */
12735 store_reg(s, 13, addr);
12736 /* set the new PC value */
12737 if ((insn & 0x0900) == 0x0900) {
12738 store_reg_from_load(s, 15, tmp);
12739 }
12740 break;
12741
12742 case 1: case 3: case 9: case 11: /* czb */
12743 rm = insn & 7;
12744 tmp = load_reg(s, rm);
12745 arm_gen_condlabel(s);
12746 if (insn & (1 << 11))
12747 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12748 else
12749 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12750 tcg_temp_free_i32(tmp);
12751 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12752 val = (uint32_t)s->pc + 2;
12753 val += offset;
12754 gen_jmp(s, val);
12755 break;
12756
12757 case 15: /* IT, nop-hint. */
12758 if ((insn & 0xf) == 0) {
12759 gen_nop_hint(s, (insn >> 4) & 0xf);
12760 break;
12761 }
12762 /* If Then. */
12763 s->condexec_cond = (insn >> 4) & 0xe;
12764 s->condexec_mask = insn & 0x1f;
12765 /* No actual code generated for this insn, just setup state. */
12766 break;
12767
12768 case 0xe: /* bkpt */
12769 {
12770 int imm8 = extract32(insn, 0, 8);
12771 ARCH(5);
12772 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12773 break;
12774 }
12775
12776 case 0xa: /* rev, and hlt */
12777 {
12778 int op1 = extract32(insn, 6, 2);
12779
12780 if (op1 == 2) {
12781 /* HLT */
12782 int imm6 = extract32(insn, 0, 6);
12783
12784 gen_hlt(s, imm6);
12785 break;
12786 }
12787
12788 /* Otherwise this is rev */
12789 ARCH(6);
12790 rn = (insn >> 3) & 0x7;
12791 rd = insn & 0x7;
12792 tmp = load_reg(s, rn);
12793 switch (op1) {
12794 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12795 case 1: gen_rev16(tmp); break;
12796 case 3: gen_revsh(tmp); break;
12797 default:
12798 g_assert_not_reached();
12799 }
12800 store_reg(s, rd, tmp);
12801 break;
12802 }
12803
12804 case 6:
12805 switch ((insn >> 5) & 7) {
12806 case 2:
12807 /* setend */
12808 ARCH(6);
12809 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12810 gen_helper_setend(cpu_env);
12811 s->base.is_jmp = DISAS_UPDATE;
12812 }
12813 break;
12814 case 3:
12815 /* cps */
12816 ARCH(6);
12817 if (IS_USER(s)) {
12818 break;
12819 }
12820 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12821 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12822 /* FAULTMASK */
12823 if (insn & 1) {
12824 addr = tcg_const_i32(19);
12825 gen_helper_v7m_msr(cpu_env, addr, tmp);
12826 tcg_temp_free_i32(addr);
12827 }
12828 /* PRIMASK */
12829 if (insn & 2) {
12830 addr = tcg_const_i32(16);
12831 gen_helper_v7m_msr(cpu_env, addr, tmp);
12832 tcg_temp_free_i32(addr);
12833 }
12834 tcg_temp_free_i32(tmp);
12835 gen_lookup_tb(s);
12836 } else {
12837 if (insn & (1 << 4)) {
12838 shift = CPSR_A | CPSR_I | CPSR_F;
12839 } else {
12840 shift = 0;
12841 }
12842 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12843 }
12844 break;
12845 default:
12846 goto undef;
12847 }
12848 break;
12849
12850 default:
12851 goto undef;
12852 }
12853 break;
12854
12855 case 12:
12856 {
12857 /* load/store multiple */
12858 TCGv_i32 loaded_var = NULL;
12859 rn = (insn >> 8) & 0x7;
12860 addr = load_reg(s, rn);
12861 for (i = 0; i < 8; i++) {
12862 if (insn & (1 << i)) {
12863 if (insn & (1 << 11)) {
12864 /* load */
12865 tmp = tcg_temp_new_i32();
12866 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12867 if (i == rn) {
12868 loaded_var = tmp;
12869 } else {
12870 store_reg(s, i, tmp);
12871 }
12872 } else {
12873 /* store */
12874 tmp = load_reg(s, i);
12875 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12876 tcg_temp_free_i32(tmp);
12877 }
12878 /* advance to the next address */
12879 tcg_gen_addi_i32(addr, addr, 4);
12880 }
12881 }
12882 if ((insn & (1 << rn)) == 0) {
12883 /* base reg not in list: base register writeback */
12884 store_reg(s, rn, addr);
12885 } else {
12886 /* base reg in list: if load, complete it now */
12887 if (insn & (1 << 11)) {
12888 store_reg(s, rn, loaded_var);
12889 }
12890 tcg_temp_free_i32(addr);
12891 }
12892 break;
12893 }
12894 case 13:
12895 /* conditional branch or swi */
12896 cond = (insn >> 8) & 0xf;
12897 if (cond == 0xe)
12898 goto undef;
12899
12900 if (cond == 0xf) {
12901 /* swi */
12902 gen_set_pc_im(s, s->pc);
12903 s->svc_imm = extract32(insn, 0, 8);
12904 s->base.is_jmp = DISAS_SWI;
12905 break;
12906 }
12907 /* generate a conditional jump to next instruction */
12908 arm_skip_unless(s, cond);
12909
12910 /* jump to the offset */
12911 val = (uint32_t)s->pc + 2;
12912 offset = ((int32_t)insn << 24) >> 24;
12913 val += offset << 1;
12914 gen_jmp(s, val);
12915 break;
12916
12917 case 14:
12918 if (insn & (1 << 11)) {
12919 /* thumb_insn_is_16bit() ensures we can't get here for
12920 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12921 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12922 */
12923 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12924 ARCH(5);
12925 offset = ((insn & 0x7ff) << 1);
12926 tmp = load_reg(s, 14);
12927 tcg_gen_addi_i32(tmp, tmp, offset);
12928 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12929
12930 tmp2 = tcg_temp_new_i32();
12931 tcg_gen_movi_i32(tmp2, s->pc | 1);
12932 store_reg(s, 14, tmp2);
12933 gen_bx(s, tmp);
12934 break;
12935 }
12936 /* unconditional branch */
12937 val = (uint32_t)s->pc;
12938 offset = ((int32_t)insn << 21) >> 21;
12939 val += (offset << 1) + 2;
12940 gen_jmp(s, val);
12941 break;
12942
12943 case 15:
12944 /* thumb_insn_is_16bit() ensures we can't get here for
12945 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12946 */
12947 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12948
12949 if (insn & (1 << 11)) {
12950 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12951 offset = ((insn & 0x7ff) << 1) | 1;
12952 tmp = load_reg(s, 14);
12953 tcg_gen_addi_i32(tmp, tmp, offset);
12954
12955 tmp2 = tcg_temp_new_i32();
12956 tcg_gen_movi_i32(tmp2, s->pc | 1);
12957 store_reg(s, 14, tmp2);
12958 gen_bx(s, tmp);
12959 } else {
12960 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12961 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12962
12963 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12964 }
12965 break;
12966 }
12967 return;
12968 illegal_op:
12969 undef:
12970 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12971 default_exception_el(s));
12972 }
12973
12974 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12975 {
12976 /* Return true if the insn at dc->pc might cross a page boundary.
12977 * (False positives are OK, false negatives are not.)
12978 * We know this is a Thumb insn, and our caller ensures we are
12979 * only called if dc->pc is less than 4 bytes from the page
12980 * boundary, so we cross the page if the first 16 bits indicate
12981 * that this is a 32 bit insn.
12982 */
12983 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12984
12985 return !thumb_insn_is_16bit(s, insn);
12986 }
12987
12988 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12989 {
12990 DisasContext *dc = container_of(dcbase, DisasContext, base);
12991 CPUARMState *env = cs->env_ptr;
12992 ARMCPU *cpu = env_archcpu(env);
12993 uint32_t tb_flags = dc->base.tb->flags;
12994 uint32_t condexec, core_mmu_idx;
12995
12996 dc->isar = &cpu->isar;
12997 dc->pc = dc->base.pc_first;
12998 dc->condjmp = 0;
12999
13000 dc->aarch64 = 0;
13001 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13002 * there is no secure EL1, so we route exceptions to EL3.
13003 */
13004 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
13005 !arm_el_is_aa64(env, 3);
13006 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
13007 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
13008 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
13009 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
13010 dc->condexec_mask = (condexec & 0xf) << 1;
13011 dc->condexec_cond = condexec >> 4;
13012 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
13013 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
13014 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
13015 #if !defined(CONFIG_USER_ONLY)
13016 dc->user = (dc->current_el == 0);
13017 #endif
13018 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
13019 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
13020 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
13021 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
13022 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
13023 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
13024 dc->vec_stride = 0;
13025 } else {
13026 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
13027 dc->c15_cpar = 0;
13028 }
13029 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
13030 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13031 regime_is_secure(env, dc->mmu_idx);
13032 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
13033 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
13034 dc->v7m_new_fp_ctxt_needed =
13035 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
13036 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
13037 dc->cp_regs = cpu->cp_regs;
13038 dc->features = env->features;
13039
13040 /* Single step state. The code-generation logic here is:
13041 * SS_ACTIVE == 0:
13042 * generate code with no special handling for single-stepping (except
13043 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13044 * this happens anyway because those changes are all system register or
13045 * PSTATE writes).
13046 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13047 * emit code for one insn
13048 * emit code to clear PSTATE.SS
13049 * emit code to generate software step exception for completed step
13050 * end TB (as usual for having generated an exception)
13051 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13052 * emit code to generate a software step exception
13053 * end the TB
13054 */
13055 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
13056 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
13057 dc->is_ldex = false;
13058 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
13059
13060 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
13061
13062 /* If architectural single step active, limit to 1. */
13063 if (is_singlestepping(dc)) {
13064 dc->base.max_insns = 1;
13065 }
13066
13067 /* ARM is a fixed-length ISA. Bound the number of insns to execute
13068 to those left on the page. */
13069 if (!dc->thumb) {
13070 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
13071 dc->base.max_insns = MIN(dc->base.max_insns, bound);
13072 }
13073
13074 cpu_F0s = tcg_temp_new_i32();
13075 cpu_F1s = tcg_temp_new_i32();
13076 cpu_F0d = tcg_temp_new_i64();
13077 cpu_F1d = tcg_temp_new_i64();
13078 cpu_V0 = cpu_F0d;
13079 cpu_V1 = cpu_F1d;
13080 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
13081 cpu_M0 = tcg_temp_new_i64();
13082 }
13083
13084 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
13085 {
13086 DisasContext *dc = container_of(dcbase, DisasContext, base);
13087
13088 /* A note on handling of the condexec (IT) bits:
13089 *
13090 * We want to avoid the overhead of having to write the updated condexec
13091 * bits back to the CPUARMState for every instruction in an IT block. So:
13092 * (1) if the condexec bits are not already zero then we write
13093 * zero back into the CPUARMState now. This avoids complications trying
13094 * to do it at the end of the block. (For example if we don't do this
13095 * it's hard to identify whether we can safely skip writing condexec
13096 * at the end of the TB, which we definitely want to do for the case
13097 * where a TB doesn't do anything with the IT state at all.)
13098 * (2) if we are going to leave the TB then we call gen_set_condexec()
13099 * which will write the correct value into CPUARMState if zero is wrong.
13100 * This is done both for leaving the TB at the end, and for leaving
13101 * it because of an exception we know will happen, which is done in
13102 * gen_exception_insn(). The latter is necessary because we need to
13103 * leave the TB with the PC/IT state just prior to execution of the
13104 * instruction which caused the exception.
13105 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13106 * then the CPUARMState will be wrong and we need to reset it.
13107 * This is handled in the same way as restoration of the
13108 * PC in these situations; we save the value of the condexec bits
13109 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13110 * then uses this to restore them after an exception.
13111 *
13112 * Note that there are no instructions which can read the condexec
13113 * bits, and none which can write non-static values to them, so
13114 * we don't need to care about whether CPUARMState is correct in the
13115 * middle of a TB.
13116 */
13117
13118 /* Reset the conditional execution bits immediately. This avoids
13119 complications trying to do it at the end of the block. */
13120 if (dc->condexec_mask || dc->condexec_cond) {
13121 TCGv_i32 tmp = tcg_temp_new_i32();
13122 tcg_gen_movi_i32(tmp, 0);
13123 store_cpu_field(tmp, condexec_bits);
13124 }
13125 }
13126
13127 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
13128 {
13129 DisasContext *dc = container_of(dcbase, DisasContext, base);
13130
13131 tcg_gen_insn_start(dc->pc,
13132 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
13133 0);
13134 dc->insn_start = tcg_last_op();
13135 }
13136
13137 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
13138 const CPUBreakpoint *bp)
13139 {
13140 DisasContext *dc = container_of(dcbase, DisasContext, base);
13141
13142 if (bp->flags & BP_CPU) {
13143 gen_set_condexec(dc);
13144 gen_set_pc_im(dc, dc->pc);
13145 gen_helper_check_breakpoints(cpu_env);
13146 /* End the TB early; it's likely not going to be executed */
13147 dc->base.is_jmp = DISAS_TOO_MANY;
13148 } else {
13149 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
13150 /* The address covered by the breakpoint must be
13151 included in [tb->pc, tb->pc + tb->size) in order
13152 to for it to be properly cleared -- thus we
13153 increment the PC here so that the logic setting
13154 tb->size below does the right thing. */
13155 /* TODO: Advance PC by correct instruction length to
13156 * avoid disassembler error messages */
13157 dc->pc += 2;
13158 dc->base.is_jmp = DISAS_NORETURN;
13159 }
13160
13161 return true;
13162 }
13163
13164 static bool arm_pre_translate_insn(DisasContext *dc)
13165 {
13166 #ifdef CONFIG_USER_ONLY
13167 /* Intercept jump to the magic kernel page. */
13168 if (dc->pc >= 0xffff0000) {
13169 /* We always get here via a jump, so know we are not in a
13170 conditional execution block. */
13171 gen_exception_internal(EXCP_KERNEL_TRAP);
13172 dc->base.is_jmp = DISAS_NORETURN;
13173 return true;
13174 }
13175 #endif
13176
13177 if (dc->ss_active && !dc->pstate_ss) {
13178 /* Singlestep state is Active-pending.
13179 * If we're in this state at the start of a TB then either
13180 * a) we just took an exception to an EL which is being debugged
13181 * and this is the first insn in the exception handler
13182 * b) debug exceptions were masked and we just unmasked them
13183 * without changing EL (eg by clearing PSTATE.D)
13184 * In either case we're going to take a swstep exception in the
13185 * "did not step an insn" case, and so the syndrome ISV and EX
13186 * bits should be zero.
13187 */
13188 assert(dc->base.num_insns == 1);
13189 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
13190 default_exception_el(dc));
13191 dc->base.is_jmp = DISAS_NORETURN;
13192 return true;
13193 }
13194
13195 return false;
13196 }
13197
13198 static void arm_post_translate_insn(DisasContext *dc)
13199 {
13200 if (dc->condjmp && !dc->base.is_jmp) {
13201 gen_set_label(dc->condlabel);
13202 dc->condjmp = 0;
13203 }
13204 dc->base.pc_next = dc->pc;
13205 translator_loop_temp_check(&dc->base);
13206 }
13207
13208 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13209 {
13210 DisasContext *dc = container_of(dcbase, DisasContext, base);
13211 CPUARMState *env = cpu->env_ptr;
13212 unsigned int insn;
13213
13214 if (arm_pre_translate_insn(dc)) {
13215 return;
13216 }
13217
13218 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
13219 dc->insn = insn;
13220 dc->pc += 4;
13221 disas_arm_insn(dc, insn);
13222
13223 arm_post_translate_insn(dc);
13224
13225 /* ARM is a fixed-length ISA. We performed the cross-page check
13226 in init_disas_context by adjusting max_insns. */
13227 }
13228
13229 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
13230 {
13231 /* Return true if this Thumb insn is always unconditional,
13232 * even inside an IT block. This is true of only a very few
13233 * instructions: BKPT, HLT, and SG.
13234 *
13235 * A larger class of instructions are UNPREDICTABLE if used
13236 * inside an IT block; we do not need to detect those here, because
13237 * what we do by default (perform the cc check and update the IT
13238 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13239 * choice for those situations.
13240 *
13241 * insn is either a 16-bit or a 32-bit instruction; the two are
13242 * distinguishable because for the 16-bit case the top 16 bits
13243 * are zeroes, and that isn't a valid 32-bit encoding.
13244 */
13245 if ((insn & 0xffffff00) == 0xbe00) {
13246 /* BKPT */
13247 return true;
13248 }
13249
13250 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
13251 !arm_dc_feature(s, ARM_FEATURE_M)) {
13252 /* HLT: v8A only. This is unconditional even when it is going to
13253 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13254 * For v7 cores this was a plain old undefined encoding and so
13255 * honours its cc check. (We might be using the encoding as
13256 * a semihosting trap, but we don't change the cc check behaviour
13257 * on that account, because a debugger connected to a real v7A
13258 * core and emulating semihosting traps by catching the UNDEF
13259 * exception would also only see cases where the cc check passed.
13260 * No guest code should be trying to do a HLT semihosting trap
13261 * in an IT block anyway.
13262 */
13263 return true;
13264 }
13265
13266 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
13267 arm_dc_feature(s, ARM_FEATURE_M)) {
13268 /* SG: v8M only */
13269 return true;
13270 }
13271
13272 return false;
13273 }
13274
13275 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13276 {
13277 DisasContext *dc = container_of(dcbase, DisasContext, base);
13278 CPUARMState *env = cpu->env_ptr;
13279 uint32_t insn;
13280 bool is_16bit;
13281
13282 if (arm_pre_translate_insn(dc)) {
13283 return;
13284 }
13285
13286 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13287 is_16bit = thumb_insn_is_16bit(dc, insn);
13288 dc->pc += 2;
13289 if (!is_16bit) {
13290 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13291
13292 insn = insn << 16 | insn2;
13293 dc->pc += 2;
13294 }
13295 dc->insn = insn;
13296
13297 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
13298 uint32_t cond = dc->condexec_cond;
13299
13300 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
13301 arm_skip_unless(dc, cond);
13302 }
13303 }
13304
13305 if (is_16bit) {
13306 disas_thumb_insn(dc, insn);
13307 } else {
13308 disas_thumb2_insn(dc, insn);
13309 }
13310
13311 /* Advance the Thumb condexec condition. */
13312 if (dc->condexec_mask) {
13313 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13314 ((dc->condexec_mask >> 4) & 1));
13315 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13316 if (dc->condexec_mask == 0) {
13317 dc->condexec_cond = 0;
13318 }
13319 }
13320
13321 arm_post_translate_insn(dc);
13322
13323 /* Thumb is a variable-length ISA. Stop translation when the next insn
13324 * will touch a new page. This ensures that prefetch aborts occur at
13325 * the right place.
13326 *
13327 * We want to stop the TB if the next insn starts in a new page,
13328 * or if it spans between this page and the next. This means that
13329 * if we're looking at the last halfword in the page we need to
13330 * see if it's a 16-bit Thumb insn (which will fit in this TB)
13331 * or a 32-bit Thumb insn (which won't).
13332 * This is to avoid generating a silly TB with a single 16-bit insn
13333 * in it at the end of this page (which would execute correctly
13334 * but isn't very efficient).
13335 */
13336 if (dc->base.is_jmp == DISAS_NEXT
13337 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13338 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13339 && insn_crosses_page(env, dc)))) {
13340 dc->base.is_jmp = DISAS_TOO_MANY;
13341 }
13342 }
13343
13344 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13345 {
13346 DisasContext *dc = container_of(dcbase, DisasContext, base);
13347
13348 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13349 /* FIXME: This can theoretically happen with self-modifying code. */
13350 cpu_abort(cpu, "IO on conditional branch instruction");
13351 }
13352
13353 /* At this stage dc->condjmp will only be set when the skipped
13354 instruction was a conditional branch or trap, and the PC has
13355 already been written. */
13356 gen_set_condexec(dc);
13357 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13358 /* Exception return branches need some special case code at the
13359 * end of the TB, which is complex enough that it has to
13360 * handle the single-step vs not and the condition-failed
13361 * insn codepath itself.
13362 */
13363 gen_bx_excret_final_code(dc);
13364 } else if (unlikely(is_singlestepping(dc))) {
13365 /* Unconditional and "condition passed" instruction codepath. */
13366 switch (dc->base.is_jmp) {
13367 case DISAS_SWI:
13368 gen_ss_advance(dc);
13369 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13370 default_exception_el(dc));
13371 break;
13372 case DISAS_HVC:
13373 gen_ss_advance(dc);
13374 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13375 break;
13376 case DISAS_SMC:
13377 gen_ss_advance(dc);
13378 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13379 break;
13380 case DISAS_NEXT:
13381 case DISAS_TOO_MANY:
13382 case DISAS_UPDATE:
13383 gen_set_pc_im(dc, dc->pc);
13384 /* fall through */
13385 default:
13386 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13387 gen_singlestep_exception(dc);
13388 break;
13389 case DISAS_NORETURN:
13390 break;
13391 }
13392 } else {
13393 /* While branches must always occur at the end of an IT block,
13394 there are a few other things that can cause us to terminate
13395 the TB in the middle of an IT block:
13396 - Exception generating instructions (bkpt, swi, undefined).
13397 - Page boundaries.
13398 - Hardware watchpoints.
13399 Hardware breakpoints have already been handled and skip this code.
13400 */
13401 switch(dc->base.is_jmp) {
13402 case DISAS_NEXT:
13403 case DISAS_TOO_MANY:
13404 gen_goto_tb(dc, 1, dc->pc);
13405 break;
13406 case DISAS_JUMP:
13407 gen_goto_ptr();
13408 break;
13409 case DISAS_UPDATE:
13410 gen_set_pc_im(dc, dc->pc);
13411 /* fall through */
13412 default:
13413 /* indicate that the hash table must be used to find the next TB */
13414 tcg_gen_exit_tb(NULL, 0);
13415 break;
13416 case DISAS_NORETURN:
13417 /* nothing more to generate */
13418 break;
13419 case DISAS_WFI:
13420 {
13421 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13422 !(dc->insn & (1U << 31))) ? 2 : 4);
13423
13424 gen_helper_wfi(cpu_env, tmp);
13425 tcg_temp_free_i32(tmp);
13426 /* The helper doesn't necessarily throw an exception, but we
13427 * must go back to the main loop to check for interrupts anyway.
13428 */
13429 tcg_gen_exit_tb(NULL, 0);
13430 break;
13431 }
13432 case DISAS_WFE:
13433 gen_helper_wfe(cpu_env);
13434 break;
13435 case DISAS_YIELD:
13436 gen_helper_yield(cpu_env);
13437 break;
13438 case DISAS_SWI:
13439 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13440 default_exception_el(dc));
13441 break;
13442 case DISAS_HVC:
13443 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13444 break;
13445 case DISAS_SMC:
13446 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13447 break;
13448 }
13449 }
13450
13451 if (dc->condjmp) {
13452 /* "Condition failed" instruction codepath for the branch/trap insn */
13453 gen_set_label(dc->condlabel);
13454 gen_set_condexec(dc);
13455 if (unlikely(is_singlestepping(dc))) {
13456 gen_set_pc_im(dc, dc->pc);
13457 gen_singlestep_exception(dc);
13458 } else {
13459 gen_goto_tb(dc, 1, dc->pc);
13460 }
13461 }
13462
13463 /* Functions above can change dc->pc, so re-align db->pc_next */
13464 dc->base.pc_next = dc->pc;
13465 }
13466
13467 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13468 {
13469 DisasContext *dc = container_of(dcbase, DisasContext, base);
13470
13471 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13472 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13473 }
13474
13475 static const TranslatorOps arm_translator_ops = {
13476 .init_disas_context = arm_tr_init_disas_context,
13477 .tb_start = arm_tr_tb_start,
13478 .insn_start = arm_tr_insn_start,
13479 .breakpoint_check = arm_tr_breakpoint_check,
13480 .translate_insn = arm_tr_translate_insn,
13481 .tb_stop = arm_tr_tb_stop,
13482 .disas_log = arm_tr_disas_log,
13483 };
13484
13485 static const TranslatorOps thumb_translator_ops = {
13486 .init_disas_context = arm_tr_init_disas_context,
13487 .tb_start = arm_tr_tb_start,
13488 .insn_start = arm_tr_insn_start,
13489 .breakpoint_check = arm_tr_breakpoint_check,
13490 .translate_insn = thumb_tr_translate_insn,
13491 .tb_stop = arm_tr_tb_stop,
13492 .disas_log = arm_tr_disas_log,
13493 };
13494
13495 /* generate intermediate code for basic block 'tb'. */
13496 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
13497 {
13498 DisasContext dc;
13499 const TranslatorOps *ops = &arm_translator_ops;
13500
13501 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
13502 ops = &thumb_translator_ops;
13503 }
13504 #ifdef TARGET_AARCH64
13505 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
13506 ops = &aarch64_translator_ops;
13507 }
13508 #endif
13509
13510 translator_loop(ops, &dc.base, cpu, tb, max_insns);
13511 }
13512
13513 void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
13514 {
13515 ARMCPU *cpu = ARM_CPU(cs);
13516 CPUARMState *env = &cpu->env;
13517 int i;
13518
13519 if (is_a64(env)) {
13520 aarch64_cpu_dump_state(cs, f, flags);
13521 return;
13522 }
13523
13524 for(i=0;i<16;i++) {
13525 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13526 if ((i % 4) == 3)
13527 qemu_fprintf(f, "\n");
13528 else
13529 qemu_fprintf(f, " ");
13530 }
13531
13532 if (arm_feature(env, ARM_FEATURE_M)) {
13533 uint32_t xpsr = xpsr_read(env);
13534 const char *mode;
13535 const char *ns_status = "";
13536
13537 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13538 ns_status = env->v7m.secure ? "S " : "NS ";
13539 }
13540
13541 if (xpsr & XPSR_EXCP) {
13542 mode = "handler";
13543 } else {
13544 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13545 mode = "unpriv-thread";
13546 } else {
13547 mode = "priv-thread";
13548 }
13549 }
13550
13551 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13552 xpsr,
13553 xpsr & XPSR_N ? 'N' : '-',
13554 xpsr & XPSR_Z ? 'Z' : '-',
13555 xpsr & XPSR_C ? 'C' : '-',
13556 xpsr & XPSR_V ? 'V' : '-',
13557 xpsr & XPSR_T ? 'T' : 'A',
13558 ns_status,
13559 mode);
13560 } else {
13561 uint32_t psr = cpsr_read(env);
13562 const char *ns_status = "";
13563
13564 if (arm_feature(env, ARM_FEATURE_EL3) &&
13565 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13566 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13567 }
13568
13569 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13570 psr,
13571 psr & CPSR_N ? 'N' : '-',
13572 psr & CPSR_Z ? 'Z' : '-',
13573 psr & CPSR_C ? 'C' : '-',
13574 psr & CPSR_V ? 'V' : '-',
13575 psr & CPSR_T ? 'T' : 'A',
13576 ns_status,
13577 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13578 }
13579
13580 if (flags & CPU_DUMP_FPU) {
13581 int numvfpregs = 0;
13582 if (arm_feature(env, ARM_FEATURE_VFP)) {
13583 numvfpregs += 16;
13584 }
13585 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13586 numvfpregs += 16;
13587 }
13588 for (i = 0; i < numvfpregs; i++) {
13589 uint64_t v = *aa32_vfp_dreg(env, i);
13590 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13591 i * 2, (uint32_t)v,
13592 i * 2 + 1, (uint32_t)(v >> 32),
13593 i, v);
13594 }
13595 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13596 }
13597 }
13598
13599 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13600 target_ulong *data)
13601 {
13602 if (is_a64(env)) {
13603 env->pc = data[0];
13604 env->condexec_bits = 0;
13605 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13606 } else {
13607 env->regs[15] = data[0];
13608 env->condexec_bits = data[1];
13609 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13610 }
13611 }