]> git.proxmox.com Git - mirror_qemu.git/blob - target/arm/translate.c
57d61c4aa57b8d56df3c192a15253a20d388d4ec
[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/tcg-op.h"
28 #include "tcg/tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "hw/semihosting/semihost.h"
33
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
36
37 #include "trace-tcg.h"
38 #include "exec/log.h"
39
40
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53
54 #include "translate.h"
55
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
61
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
68
69 #include "exec/gen-icount.h"
70
71 static const char * const regnames[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
74
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
77 TCGv_i32, TCGv_i32);
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
80
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
83 {
84 int i;
85
86 for (i = 0; i < 16; i++) {
87 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
88 offsetof(CPUARMState, regs[i]),
89 regnames[i]);
90 }
91 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
92 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
93 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
94 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
95
96 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
97 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
98 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_val), "exclusive_val");
100
101 a64_translate_init();
102 }
103
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
106 */
107 typedef enum ISSInfo {
108 ISSNone = 0,
109 ISSRegMask = 0x1f,
110 ISSInvalid = (1 << 5),
111 ISSIsAcqRel = (1 << 6),
112 ISSIsWrite = (1 << 7),
113 ISSIs16Bit = (1 << 8),
114 } ISSInfo;
115
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
118 {
119 uint32_t syn;
120 int sas = memop & MO_SIZE;
121 bool sse = memop & MO_SIGN;
122 bool is_acqrel = issinfo & ISSIsAcqRel;
123 bool is_write = issinfo & ISSIsWrite;
124 bool is_16bit = issinfo & ISSIs16Bit;
125 int srt = issinfo & ISSRegMask;
126
127 if (issinfo & ISSInvalid) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
130 */
131 return;
132 }
133
134 if (srt == 15) {
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
137 * the call sites.
138 */
139 return;
140 }
141
142 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
143 0, 0, 0, is_write, 0, is_16bit);
144 disas_set_insn_syndrome(s, syn);
145 }
146
147 static inline int get_a32_user_mem_index(DisasContext *s)
148 {
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
150 * insns:
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
153 */
154 switch (s->mmu_idx) {
155 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_E10_0:
157 case ARMMMUIdx_E10_1:
158 case ARMMMUIdx_E10_1_PAN:
159 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
160 case ARMMMUIdx_SE3:
161 case ARMMMUIdx_SE10_0:
162 case ARMMMUIdx_SE10_1:
163 case ARMMMUIdx_SE10_1_PAN:
164 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 default:
178 g_assert_not_reached();
179 }
180 }
181
182 static inline TCGv_i32 load_cpu_offset(int offset)
183 {
184 TCGv_i32 tmp = tcg_temp_new_i32();
185 tcg_gen_ld_i32(tmp, cpu_env, offset);
186 return tmp;
187 }
188
189 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
190
191 static inline void store_cpu_offset(TCGv_i32 var, int offset)
192 {
193 tcg_gen_st_i32(var, cpu_env, offset);
194 tcg_temp_free_i32(var);
195 }
196
197 #define store_cpu_field(var, name) \
198 store_cpu_offset(var, offsetof(CPUARMState, name))
199
200 /* The architectural value of PC. */
201 static uint32_t read_pc(DisasContext *s)
202 {
203 return s->pc_curr + (s->thumb ? 4 : 8);
204 }
205
206 /* Set a variable to the value of a CPU register. */
207 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
208 {
209 if (reg == 15) {
210 tcg_gen_movi_i32(var, read_pc(s));
211 } else {
212 tcg_gen_mov_i32(var, cpu_R[reg]);
213 }
214 }
215
216 /* Create a new temporary and set it to the value of a CPU register. */
217 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
218 {
219 TCGv_i32 tmp = tcg_temp_new_i32();
220 load_reg_var(s, tmp, reg);
221 return tmp;
222 }
223
224 /*
225 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
226 * This is used for load/store for which use of PC implies (literal),
227 * or ADD that implies ADR.
228 */
229 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
230 {
231 TCGv_i32 tmp = tcg_temp_new_i32();
232
233 if (reg == 15) {
234 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
235 } else {
236 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
237 }
238 return tmp;
239 }
240
241 /* Set a CPU register. The source must be a temporary and will be
242 marked as dead. */
243 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
244 {
245 if (reg == 15) {
246 /* In Thumb mode, we must ignore bit 0.
247 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
248 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
249 * We choose to ignore [1:0] in ARM mode for all architecture versions.
250 */
251 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
252 s->base.is_jmp = DISAS_JUMP;
253 }
254 tcg_gen_mov_i32(cpu_R[reg], var);
255 tcg_temp_free_i32(var);
256 }
257
258 /*
259 * Variant of store_reg which applies v8M stack-limit checks before updating
260 * SP. If the check fails this will result in an exception being taken.
261 * We disable the stack checks for CONFIG_USER_ONLY because we have
262 * no idea what the stack limits should be in that case.
263 * If stack checking is not being done this just acts like store_reg().
264 */
265 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
266 {
267 #ifndef CONFIG_USER_ONLY
268 if (s->v8m_stackcheck) {
269 gen_helper_v8m_stackcheck(cpu_env, var);
270 }
271 #endif
272 store_reg(s, 13, var);
273 }
274
275 /* Value extensions. */
276 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
277 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
278 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
279 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
280
281 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
282 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
283
284
285 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
286 {
287 TCGv_i32 tmp_mask = tcg_const_i32(mask);
288 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
289 tcg_temp_free_i32(tmp_mask);
290 }
291 /* Set NZCV flags from the high 4 bits of var. */
292 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
293
294 static void gen_exception_internal(int excp)
295 {
296 TCGv_i32 tcg_excp = tcg_const_i32(excp);
297
298 assert(excp_is_internal(excp));
299 gen_helper_exception_internal(cpu_env, tcg_excp);
300 tcg_temp_free_i32(tcg_excp);
301 }
302
303 static void gen_step_complete_exception(DisasContext *s)
304 {
305 /* We just completed step of an insn. Move from Active-not-pending
306 * to Active-pending, and then also take the swstep exception.
307 * This corresponds to making the (IMPDEF) choice to prioritize
308 * swstep exceptions over asynchronous exceptions taken to an exception
309 * level where debug is disabled. This choice has the advantage that
310 * we do not need to maintain internal state corresponding to the
311 * ISV/EX syndrome bits between completion of the step and generation
312 * of the exception, and our syndrome information is always correct.
313 */
314 gen_ss_advance(s);
315 gen_swstep_exception(s, 1, s->is_ldex);
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 dest, 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(dest, 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 dest, TCGv_i32 var)
374 {
375 tcg_gen_ext16u_i32(var, var);
376 tcg_gen_bswap16_i32(var, var);
377 tcg_gen_ext16s_i32(dest, var);
378 }
379
380 /* 32x32->64 multiply. Marks inputs as dead. */
381 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
382 {
383 TCGv_i32 lo = tcg_temp_new_i32();
384 TCGv_i32 hi = tcg_temp_new_i32();
385 TCGv_i64 ret;
386
387 tcg_gen_mulu2_i32(lo, hi, a, b);
388 tcg_temp_free_i32(a);
389 tcg_temp_free_i32(b);
390
391 ret = tcg_temp_new_i64();
392 tcg_gen_concat_i32_i64(ret, lo, hi);
393 tcg_temp_free_i32(lo);
394 tcg_temp_free_i32(hi);
395
396 return ret;
397 }
398
399 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
400 {
401 TCGv_i32 lo = tcg_temp_new_i32();
402 TCGv_i32 hi = tcg_temp_new_i32();
403 TCGv_i64 ret;
404
405 tcg_gen_muls2_i32(lo, hi, a, b);
406 tcg_temp_free_i32(a);
407 tcg_temp_free_i32(b);
408
409 ret = tcg_temp_new_i64();
410 tcg_gen_concat_i32_i64(ret, lo, hi);
411 tcg_temp_free_i32(lo);
412 tcg_temp_free_i32(hi);
413
414 return ret;
415 }
416
417 /* Swap low and high halfwords. */
418 static void gen_swap_half(TCGv_i32 var)
419 {
420 tcg_gen_rotri_i32(var, var, 16);
421 }
422
423 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
424 tmp = (t0 ^ t1) & 0x8000;
425 t0 &= ~0x8000;
426 t1 &= ~0x8000;
427 t0 = (t0 + t1) ^ tmp;
428 */
429
430 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
431 {
432 TCGv_i32 tmp = tcg_temp_new_i32();
433 tcg_gen_xor_i32(tmp, t0, t1);
434 tcg_gen_andi_i32(tmp, tmp, 0x8000);
435 tcg_gen_andi_i32(t0, t0, ~0x8000);
436 tcg_gen_andi_i32(t1, t1, ~0x8000);
437 tcg_gen_add_i32(t0, t0, t1);
438 tcg_gen_xor_i32(dest, t0, tmp);
439 tcg_temp_free_i32(tmp);
440 }
441
442 /* Set N and Z flags from var. */
443 static inline void gen_logic_CC(TCGv_i32 var)
444 {
445 tcg_gen_mov_i32(cpu_NF, var);
446 tcg_gen_mov_i32(cpu_ZF, var);
447 }
448
449 /* dest = T0 + T1 + CF. */
450 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
451 {
452 tcg_gen_add_i32(dest, t0, t1);
453 tcg_gen_add_i32(dest, dest, cpu_CF);
454 }
455
456 /* dest = T0 - T1 + CF - 1. */
457 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
458 {
459 tcg_gen_sub_i32(dest, t0, t1);
460 tcg_gen_add_i32(dest, dest, cpu_CF);
461 tcg_gen_subi_i32(dest, dest, 1);
462 }
463
464 /* dest = T0 + T1. Compute C, N, V and Z flags */
465 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
466 {
467 TCGv_i32 tmp = tcg_temp_new_i32();
468 tcg_gen_movi_i32(tmp, 0);
469 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
470 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
471 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
472 tcg_gen_xor_i32(tmp, t0, t1);
473 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
474 tcg_temp_free_i32(tmp);
475 tcg_gen_mov_i32(dest, cpu_NF);
476 }
477
478 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
479 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 {
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 if (TCG_TARGET_HAS_add2_i32) {
483 tcg_gen_movi_i32(tmp, 0);
484 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
485 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
486 } else {
487 TCGv_i64 q0 = tcg_temp_new_i64();
488 TCGv_i64 q1 = tcg_temp_new_i64();
489 tcg_gen_extu_i32_i64(q0, t0);
490 tcg_gen_extu_i32_i64(q1, t1);
491 tcg_gen_add_i64(q0, q0, q1);
492 tcg_gen_extu_i32_i64(q1, cpu_CF);
493 tcg_gen_add_i64(q0, q0, q1);
494 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
495 tcg_temp_free_i64(q0);
496 tcg_temp_free_i64(q1);
497 }
498 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
499 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
500 tcg_gen_xor_i32(tmp, t0, t1);
501 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
502 tcg_temp_free_i32(tmp);
503 tcg_gen_mov_i32(dest, cpu_NF);
504 }
505
506 /* dest = T0 - T1. Compute C, N, V and Z flags */
507 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
508 {
509 TCGv_i32 tmp;
510 tcg_gen_sub_i32(cpu_NF, t0, t1);
511 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
512 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
513 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
514 tmp = tcg_temp_new_i32();
515 tcg_gen_xor_i32(tmp, t0, t1);
516 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
517 tcg_temp_free_i32(tmp);
518 tcg_gen_mov_i32(dest, cpu_NF);
519 }
520
521 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
522 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
523 {
524 TCGv_i32 tmp = tcg_temp_new_i32();
525 tcg_gen_not_i32(tmp, t1);
526 gen_adc_CC(dest, t0, tmp);
527 tcg_temp_free_i32(tmp);
528 }
529
530 #define GEN_SHIFT(name) \
531 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
532 { \
533 TCGv_i32 tmp1, tmp2, tmp3; \
534 tmp1 = tcg_temp_new_i32(); \
535 tcg_gen_andi_i32(tmp1, t1, 0xff); \
536 tmp2 = tcg_const_i32(0); \
537 tmp3 = tcg_const_i32(0x1f); \
538 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
539 tcg_temp_free_i32(tmp3); \
540 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
541 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
542 tcg_temp_free_i32(tmp2); \
543 tcg_temp_free_i32(tmp1); \
544 }
545 GEN_SHIFT(shl)
546 GEN_SHIFT(shr)
547 #undef GEN_SHIFT
548
549 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
550 {
551 TCGv_i32 tmp1, tmp2;
552 tmp1 = tcg_temp_new_i32();
553 tcg_gen_andi_i32(tmp1, t1, 0xff);
554 tmp2 = tcg_const_i32(0x1f);
555 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
556 tcg_temp_free_i32(tmp2);
557 tcg_gen_sar_i32(dest, t0, tmp1);
558 tcg_temp_free_i32(tmp1);
559 }
560
561 static void shifter_out_im(TCGv_i32 var, int shift)
562 {
563 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
564 }
565
566 /* Shift by immediate. Includes special handling for shift == 0. */
567 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
568 int shift, int flags)
569 {
570 switch (shiftop) {
571 case 0: /* LSL */
572 if (shift != 0) {
573 if (flags)
574 shifter_out_im(var, 32 - shift);
575 tcg_gen_shli_i32(var, var, shift);
576 }
577 break;
578 case 1: /* LSR */
579 if (shift == 0) {
580 if (flags) {
581 tcg_gen_shri_i32(cpu_CF, var, 31);
582 }
583 tcg_gen_movi_i32(var, 0);
584 } else {
585 if (flags)
586 shifter_out_im(var, shift - 1);
587 tcg_gen_shri_i32(var, var, shift);
588 }
589 break;
590 case 2: /* ASR */
591 if (shift == 0)
592 shift = 32;
593 if (flags)
594 shifter_out_im(var, shift - 1);
595 if (shift == 32)
596 shift = 31;
597 tcg_gen_sari_i32(var, var, shift);
598 break;
599 case 3: /* ROR/RRX */
600 if (shift != 0) {
601 if (flags)
602 shifter_out_im(var, shift - 1);
603 tcg_gen_rotri_i32(var, var, shift); break;
604 } else {
605 TCGv_i32 tmp = tcg_temp_new_i32();
606 tcg_gen_shli_i32(tmp, cpu_CF, 31);
607 if (flags)
608 shifter_out_im(var, 0);
609 tcg_gen_shri_i32(var, var, 1);
610 tcg_gen_or_i32(var, var, tmp);
611 tcg_temp_free_i32(tmp);
612 }
613 }
614 };
615
616 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
617 TCGv_i32 shift, int flags)
618 {
619 if (flags) {
620 switch (shiftop) {
621 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
622 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
623 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
624 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
625 }
626 } else {
627 switch (shiftop) {
628 case 0:
629 gen_shl(var, var, shift);
630 break;
631 case 1:
632 gen_shr(var, var, shift);
633 break;
634 case 2:
635 gen_sar(var, var, shift);
636 break;
637 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
638 tcg_gen_rotr_i32(var, var, shift); break;
639 }
640 }
641 tcg_temp_free_i32(shift);
642 }
643
644 /*
645 * Generate a conditional based on ARM condition code cc.
646 * This is common between ARM and Aarch64 targets.
647 */
648 void arm_test_cc(DisasCompare *cmp, int cc)
649 {
650 TCGv_i32 value;
651 TCGCond cond;
652 bool global = true;
653
654 switch (cc) {
655 case 0: /* eq: Z */
656 case 1: /* ne: !Z */
657 cond = TCG_COND_EQ;
658 value = cpu_ZF;
659 break;
660
661 case 2: /* cs: C */
662 case 3: /* cc: !C */
663 cond = TCG_COND_NE;
664 value = cpu_CF;
665 break;
666
667 case 4: /* mi: N */
668 case 5: /* pl: !N */
669 cond = TCG_COND_LT;
670 value = cpu_NF;
671 break;
672
673 case 6: /* vs: V */
674 case 7: /* vc: !V */
675 cond = TCG_COND_LT;
676 value = cpu_VF;
677 break;
678
679 case 8: /* hi: C && !Z */
680 case 9: /* ls: !C || Z -> !(C && !Z) */
681 cond = TCG_COND_NE;
682 value = tcg_temp_new_i32();
683 global = false;
684 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
685 ZF is non-zero for !Z; so AND the two subexpressions. */
686 tcg_gen_neg_i32(value, cpu_CF);
687 tcg_gen_and_i32(value, value, cpu_ZF);
688 break;
689
690 case 10: /* ge: N == V -> N ^ V == 0 */
691 case 11: /* lt: N != V -> N ^ V != 0 */
692 /* Since we're only interested in the sign bit, == 0 is >= 0. */
693 cond = TCG_COND_GE;
694 value = tcg_temp_new_i32();
695 global = false;
696 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
697 break;
698
699 case 12: /* gt: !Z && N == V */
700 case 13: /* le: Z || N != V */
701 cond = TCG_COND_NE;
702 value = tcg_temp_new_i32();
703 global = false;
704 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
705 * the sign bit then AND with ZF to yield the result. */
706 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
707 tcg_gen_sari_i32(value, value, 31);
708 tcg_gen_andc_i32(value, cpu_ZF, value);
709 break;
710
711 case 14: /* always */
712 case 15: /* always */
713 /* Use the ALWAYS condition, which will fold early.
714 * It doesn't matter what we use for the value. */
715 cond = TCG_COND_ALWAYS;
716 value = cpu_ZF;
717 goto no_invert;
718
719 default:
720 fprintf(stderr, "Bad condition code 0x%x\n", cc);
721 abort();
722 }
723
724 if (cc & 1) {
725 cond = tcg_invert_cond(cond);
726 }
727
728 no_invert:
729 cmp->cond = cond;
730 cmp->value = value;
731 cmp->value_global = global;
732 }
733
734 void arm_free_cc(DisasCompare *cmp)
735 {
736 if (!cmp->value_global) {
737 tcg_temp_free_i32(cmp->value);
738 }
739 }
740
741 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
742 {
743 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
744 }
745
746 void arm_gen_test_cc(int cc, TCGLabel *label)
747 {
748 DisasCompare cmp;
749 arm_test_cc(&cmp, cc);
750 arm_jump_cc(&cmp, label);
751 arm_free_cc(&cmp);
752 }
753
754 static inline void gen_set_condexec(DisasContext *s)
755 {
756 if (s->condexec_mask) {
757 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
758 TCGv_i32 tmp = tcg_temp_new_i32();
759 tcg_gen_movi_i32(tmp, val);
760 store_cpu_field(tmp, condexec_bits);
761 }
762 }
763
764 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
765 {
766 tcg_gen_movi_i32(cpu_R[15], val);
767 }
768
769 /* Set PC and Thumb state from var. var is marked as dead. */
770 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
771 {
772 s->base.is_jmp = DISAS_JUMP;
773 tcg_gen_andi_i32(cpu_R[15], var, ~1);
774 tcg_gen_andi_i32(var, var, 1);
775 store_cpu_field(var, thumb);
776 }
777
778 /*
779 * Set PC and Thumb state from var. var is marked as dead.
780 * For M-profile CPUs, include logic to detect exception-return
781 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
782 * and BX reg, and no others, and happens only for code in Handler mode.
783 * The Security Extension also requires us to check for the FNC_RETURN
784 * which signals a function return from non-secure state; this can happen
785 * in both Handler and Thread mode.
786 * To avoid having to do multiple comparisons in inline generated code,
787 * we make the check we do here loose, so it will match for EXC_RETURN
788 * in Thread mode. For system emulation do_v7m_exception_exit() checks
789 * for these spurious cases and returns without doing anything (giving
790 * the same behaviour as for a branch to a non-magic address).
791 *
792 * In linux-user mode it is unclear what the right behaviour for an
793 * attempted FNC_RETURN should be, because in real hardware this will go
794 * directly to Secure code (ie not the Linux kernel) which will then treat
795 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
796 * attempt behave the way it would on a CPU without the security extension,
797 * which is to say "like a normal branch". That means we can simply treat
798 * all branches as normal with no magic address behaviour.
799 */
800 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
801 {
802 /* Generate the same code here as for a simple bx, but flag via
803 * s->base.is_jmp that we need to do the rest of the work later.
804 */
805 gen_bx(s, var);
806 #ifndef CONFIG_USER_ONLY
807 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
808 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
809 s->base.is_jmp = DISAS_BX_EXCRET;
810 }
811 #endif
812 }
813
814 static inline void gen_bx_excret_final_code(DisasContext *s)
815 {
816 /* Generate the code to finish possible exception return and end the TB */
817 TCGLabel *excret_label = gen_new_label();
818 uint32_t min_magic;
819
820 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
821 /* Covers FNC_RETURN and EXC_RETURN magic */
822 min_magic = FNC_RETURN_MIN_MAGIC;
823 } else {
824 /* EXC_RETURN magic only */
825 min_magic = EXC_RETURN_MIN_MAGIC;
826 }
827
828 /* Is the new PC value in the magic range indicating exception return? */
829 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
830 /* No: end the TB as we would for a DISAS_JMP */
831 if (is_singlestepping(s)) {
832 gen_singlestep_exception(s);
833 } else {
834 tcg_gen_exit_tb(NULL, 0);
835 }
836 gen_set_label(excret_label);
837 /* Yes: this is an exception return.
838 * At this point in runtime env->regs[15] and env->thumb will hold
839 * the exception-return magic number, which do_v7m_exception_exit()
840 * will read. Nothing else will be able to see those values because
841 * the cpu-exec main loop guarantees that we will always go straight
842 * from raising the exception to the exception-handling code.
843 *
844 * gen_ss_advance(s) does nothing on M profile currently but
845 * calling it is conceptually the right thing as we have executed
846 * this instruction (compare SWI, HVC, SMC handling).
847 */
848 gen_ss_advance(s);
849 gen_exception_internal(EXCP_EXCEPTION_EXIT);
850 }
851
852 static inline void gen_bxns(DisasContext *s, int rm)
853 {
854 TCGv_i32 var = load_reg(s, rm);
855
856 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
857 * we need to sync state before calling it, but:
858 * - we don't need to do gen_set_pc_im() because the bxns helper will
859 * always set the PC itself
860 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
861 * unless it's outside an IT block or the last insn in an IT block,
862 * so we know that condexec == 0 (already set at the top of the TB)
863 * is correct in the non-UNPREDICTABLE cases, and we can choose
864 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
865 */
866 gen_helper_v7m_bxns(cpu_env, var);
867 tcg_temp_free_i32(var);
868 s->base.is_jmp = DISAS_EXIT;
869 }
870
871 static inline void gen_blxns(DisasContext *s, int rm)
872 {
873 TCGv_i32 var = load_reg(s, rm);
874
875 /* We don't need to sync condexec state, for the same reason as bxns.
876 * We do however need to set the PC, because the blxns helper reads it.
877 * The blxns helper may throw an exception.
878 */
879 gen_set_pc_im(s, s->base.pc_next);
880 gen_helper_v7m_blxns(cpu_env, var);
881 tcg_temp_free_i32(var);
882 s->base.is_jmp = DISAS_EXIT;
883 }
884
885 /* Variant of store_reg which uses branch&exchange logic when storing
886 to r15 in ARM architecture v7 and above. The source must be a temporary
887 and will be marked as dead. */
888 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
889 {
890 if (reg == 15 && ENABLE_ARCH_7) {
891 gen_bx(s, var);
892 } else {
893 store_reg(s, reg, var);
894 }
895 }
896
897 /* Variant of store_reg which uses branch&exchange logic when storing
898 * to r15 in ARM architecture v5T and above. This is used for storing
899 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
900 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
901 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
902 {
903 if (reg == 15 && ENABLE_ARCH_5) {
904 gen_bx_excret(s, var);
905 } else {
906 store_reg(s, reg, var);
907 }
908 }
909
910 #ifdef CONFIG_USER_ONLY
911 #define IS_USER_ONLY 1
912 #else
913 #define IS_USER_ONLY 0
914 #endif
915
916 /* Abstractions of "generate code to do a guest load/store for
917 * AArch32", where a vaddr is always 32 bits (and is zero
918 * extended if we're a 64 bit core) and data is also
919 * 32 bits unless specifically doing a 64 bit access.
920 * These functions work like tcg_gen_qemu_{ld,st}* except
921 * that the address argument is TCGv_i32 rather than TCGv.
922 */
923
924 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
925 {
926 TCGv addr = tcg_temp_new();
927 tcg_gen_extu_i32_tl(addr, a32);
928
929 /* Not needed for user-mode BE32, where we use MO_BE instead. */
930 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
931 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
932 }
933 return addr;
934 }
935
936 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
937 int index, MemOp opc)
938 {
939 TCGv addr;
940
941 if (arm_dc_feature(s, ARM_FEATURE_M) &&
942 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
943 opc |= MO_ALIGN;
944 }
945
946 addr = gen_aa32_addr(s, a32, opc);
947 tcg_gen_qemu_ld_i32(val, addr, index, opc);
948 tcg_temp_free(addr);
949 }
950
951 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
952 int index, MemOp opc)
953 {
954 TCGv addr;
955
956 if (arm_dc_feature(s, ARM_FEATURE_M) &&
957 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
958 opc |= MO_ALIGN;
959 }
960
961 addr = gen_aa32_addr(s, a32, opc);
962 tcg_gen_qemu_st_i32(val, addr, index, opc);
963 tcg_temp_free(addr);
964 }
965
966 #define DO_GEN_LD(SUFF, OPC) \
967 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
968 TCGv_i32 a32, int index) \
969 { \
970 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
971 }
972
973 #define DO_GEN_ST(SUFF, OPC) \
974 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
975 TCGv_i32 a32, int index) \
976 { \
977 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
978 }
979
980 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
981 {
982 /* Not needed for user-mode BE32, where we use MO_BE instead. */
983 if (!IS_USER_ONLY && s->sctlr_b) {
984 tcg_gen_rotri_i64(val, val, 32);
985 }
986 }
987
988 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
989 int index, MemOp opc)
990 {
991 TCGv addr = gen_aa32_addr(s, a32, opc);
992 tcg_gen_qemu_ld_i64(val, addr, index, opc);
993 gen_aa32_frob64(s, val);
994 tcg_temp_free(addr);
995 }
996
997 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
998 TCGv_i32 a32, int index)
999 {
1000 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1001 }
1002
1003 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1004 int index, MemOp opc)
1005 {
1006 TCGv addr = gen_aa32_addr(s, a32, opc);
1007
1008 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1009 if (!IS_USER_ONLY && s->sctlr_b) {
1010 TCGv_i64 tmp = tcg_temp_new_i64();
1011 tcg_gen_rotri_i64(tmp, val, 32);
1012 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1013 tcg_temp_free_i64(tmp);
1014 } else {
1015 tcg_gen_qemu_st_i64(val, addr, index, opc);
1016 }
1017 tcg_temp_free(addr);
1018 }
1019
1020 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1021 TCGv_i32 a32, int index)
1022 {
1023 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1024 }
1025
1026 DO_GEN_LD(8u, MO_UB)
1027 DO_GEN_LD(16u, MO_UW)
1028 DO_GEN_LD(32u, MO_UL)
1029 DO_GEN_ST(8, MO_UB)
1030 DO_GEN_ST(16, MO_UW)
1031 DO_GEN_ST(32, MO_UL)
1032
1033 static inline void gen_hvc(DisasContext *s, int imm16)
1034 {
1035 /* The pre HVC helper handles cases when HVC gets trapped
1036 * as an undefined insn by runtime configuration (ie before
1037 * the insn really executes).
1038 */
1039 gen_set_pc_im(s, s->pc_curr);
1040 gen_helper_pre_hvc(cpu_env);
1041 /* Otherwise we will treat this as a real exception which
1042 * happens after execution of the insn. (The distinction matters
1043 * for the PC value reported to the exception handler and also
1044 * for single stepping.)
1045 */
1046 s->svc_imm = imm16;
1047 gen_set_pc_im(s, s->base.pc_next);
1048 s->base.is_jmp = DISAS_HVC;
1049 }
1050
1051 static inline void gen_smc(DisasContext *s)
1052 {
1053 /* As with HVC, we may take an exception either before or after
1054 * the insn executes.
1055 */
1056 TCGv_i32 tmp;
1057
1058 gen_set_pc_im(s, s->pc_curr);
1059 tmp = tcg_const_i32(syn_aa32_smc());
1060 gen_helper_pre_smc(cpu_env, tmp);
1061 tcg_temp_free_i32(tmp);
1062 gen_set_pc_im(s, s->base.pc_next);
1063 s->base.is_jmp = DISAS_SMC;
1064 }
1065
1066 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1067 {
1068 gen_set_condexec(s);
1069 gen_set_pc_im(s, pc);
1070 gen_exception_internal(excp);
1071 s->base.is_jmp = DISAS_NORETURN;
1072 }
1073
1074 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1075 int syn, uint32_t target_el)
1076 {
1077 gen_set_condexec(s);
1078 gen_set_pc_im(s, pc);
1079 gen_exception(excp, syn, target_el);
1080 s->base.is_jmp = DISAS_NORETURN;
1081 }
1082
1083 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1084 {
1085 TCGv_i32 tcg_syn;
1086
1087 gen_set_condexec(s);
1088 gen_set_pc_im(s, s->pc_curr);
1089 tcg_syn = tcg_const_i32(syn);
1090 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1091 tcg_temp_free_i32(tcg_syn);
1092 s->base.is_jmp = DISAS_NORETURN;
1093 }
1094
1095 static void unallocated_encoding(DisasContext *s)
1096 {
1097 /* Unallocated and reserved encodings are uncategorized */
1098 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1099 default_exception_el(s));
1100 }
1101
1102 /* Force a TB lookup after an instruction that changes the CPU state. */
1103 static inline void gen_lookup_tb(DisasContext *s)
1104 {
1105 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1106 s->base.is_jmp = DISAS_EXIT;
1107 }
1108
1109 static inline void gen_hlt(DisasContext *s, int imm)
1110 {
1111 /* HLT. This has two purposes.
1112 * Architecturally, it is an external halting debug instruction.
1113 * Since QEMU doesn't implement external debug, we treat this as
1114 * it is required for halting debug disabled: it will UNDEF.
1115 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1116 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1117 * must trigger semihosting even for ARMv7 and earlier, where
1118 * HLT was an undefined encoding.
1119 * In system mode, we don't allow userspace access to
1120 * semihosting, to provide some semblance of security
1121 * (and for consistency with our 32-bit semihosting).
1122 */
1123 if (semihosting_enabled() &&
1124 #ifndef CONFIG_USER_ONLY
1125 s->current_el != 0 &&
1126 #endif
1127 (imm == (s->thumb ? 0x3c : 0xf000))) {
1128 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1129 return;
1130 }
1131
1132 unallocated_encoding(s);
1133 }
1134
1135 static TCGv_ptr get_fpstatus_ptr(int neon)
1136 {
1137 TCGv_ptr statusptr = tcg_temp_new_ptr();
1138 int offset;
1139 if (neon) {
1140 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1141 } else {
1142 offset = offsetof(CPUARMState, vfp.fp_status);
1143 }
1144 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1145 return statusptr;
1146 }
1147
1148 static inline long vfp_reg_offset(bool dp, unsigned reg)
1149 {
1150 if (dp) {
1151 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1152 } else {
1153 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1154 if (reg & 1) {
1155 ofs += offsetof(CPU_DoubleU, l.upper);
1156 } else {
1157 ofs += offsetof(CPU_DoubleU, l.lower);
1158 }
1159 return ofs;
1160 }
1161 }
1162
1163 /* Return the offset of a 32-bit piece of a NEON register.
1164 zero is the least significant end of the register. */
1165 static inline long
1166 neon_reg_offset (int reg, int n)
1167 {
1168 int sreg;
1169 sreg = reg * 2 + n;
1170 return vfp_reg_offset(0, sreg);
1171 }
1172
1173 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1174 * where 0 is the least significant end of the register.
1175 */
1176 static inline long
1177 neon_element_offset(int reg, int element, MemOp size)
1178 {
1179 int element_size = 1 << size;
1180 int ofs = element * element_size;
1181 #ifdef HOST_WORDS_BIGENDIAN
1182 /* Calculate the offset assuming fully little-endian,
1183 * then XOR to account for the order of the 8-byte units.
1184 */
1185 if (element_size < 8) {
1186 ofs ^= 8 - element_size;
1187 }
1188 #endif
1189 return neon_reg_offset(reg, 0) + ofs;
1190 }
1191
1192 static TCGv_i32 neon_load_reg(int reg, int pass)
1193 {
1194 TCGv_i32 tmp = tcg_temp_new_i32();
1195 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1196 return tmp;
1197 }
1198
1199 static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
1200 {
1201 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1202
1203 switch (mop) {
1204 case MO_UB:
1205 tcg_gen_ld8u_i32(var, cpu_env, offset);
1206 break;
1207 case MO_UW:
1208 tcg_gen_ld16u_i32(var, cpu_env, offset);
1209 break;
1210 case MO_UL:
1211 tcg_gen_ld_i32(var, cpu_env, offset);
1212 break;
1213 default:
1214 g_assert_not_reached();
1215 }
1216 }
1217
1218 static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
1219 {
1220 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1221
1222 switch (mop) {
1223 case MO_UB:
1224 tcg_gen_ld8u_i64(var, cpu_env, offset);
1225 break;
1226 case MO_UW:
1227 tcg_gen_ld16u_i64(var, cpu_env, offset);
1228 break;
1229 case MO_UL:
1230 tcg_gen_ld32u_i64(var, cpu_env, offset);
1231 break;
1232 case MO_Q:
1233 tcg_gen_ld_i64(var, cpu_env, offset);
1234 break;
1235 default:
1236 g_assert_not_reached();
1237 }
1238 }
1239
1240 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1241 {
1242 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1243 tcg_temp_free_i32(var);
1244 }
1245
1246 static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
1247 {
1248 long offset = neon_element_offset(reg, ele, size);
1249
1250 switch (size) {
1251 case MO_8:
1252 tcg_gen_st8_i32(var, cpu_env, offset);
1253 break;
1254 case MO_16:
1255 tcg_gen_st16_i32(var, cpu_env, offset);
1256 break;
1257 case MO_32:
1258 tcg_gen_st_i32(var, cpu_env, offset);
1259 break;
1260 default:
1261 g_assert_not_reached();
1262 }
1263 }
1264
1265 static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
1266 {
1267 long offset = neon_element_offset(reg, ele, size);
1268
1269 switch (size) {
1270 case MO_8:
1271 tcg_gen_st8_i64(var, cpu_env, offset);
1272 break;
1273 case MO_16:
1274 tcg_gen_st16_i64(var, cpu_env, offset);
1275 break;
1276 case MO_32:
1277 tcg_gen_st32_i64(var, cpu_env, offset);
1278 break;
1279 case MO_64:
1280 tcg_gen_st_i64(var, cpu_env, offset);
1281 break;
1282 default:
1283 g_assert_not_reached();
1284 }
1285 }
1286
1287 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1288 {
1289 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1290 }
1291
1292 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1293 {
1294 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1295 }
1296
1297 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1298 {
1299 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1300 }
1301
1302 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1303 {
1304 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1305 }
1306
1307 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1308 {
1309 TCGv_ptr ret = tcg_temp_new_ptr();
1310 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1311 return ret;
1312 }
1313
1314 #define ARM_CP_RW_BIT (1 << 20)
1315
1316 /* Include the VFP decoder */
1317 #include "translate-vfp.inc.c"
1318
1319 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1320 {
1321 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1322 }
1323
1324 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1325 {
1326 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1327 }
1328
1329 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1330 {
1331 TCGv_i32 var = tcg_temp_new_i32();
1332 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1333 return var;
1334 }
1335
1336 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1337 {
1338 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1339 tcg_temp_free_i32(var);
1340 }
1341
1342 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1343 {
1344 iwmmxt_store_reg(cpu_M0, rn);
1345 }
1346
1347 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1348 {
1349 iwmmxt_load_reg(cpu_M0, rn);
1350 }
1351
1352 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1353 {
1354 iwmmxt_load_reg(cpu_V1, rn);
1355 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1356 }
1357
1358 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1359 {
1360 iwmmxt_load_reg(cpu_V1, rn);
1361 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1362 }
1363
1364 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1365 {
1366 iwmmxt_load_reg(cpu_V1, rn);
1367 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1368 }
1369
1370 #define IWMMXT_OP(name) \
1371 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1372 { \
1373 iwmmxt_load_reg(cpu_V1, rn); \
1374 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1375 }
1376
1377 #define IWMMXT_OP_ENV(name) \
1378 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1379 { \
1380 iwmmxt_load_reg(cpu_V1, rn); \
1381 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1382 }
1383
1384 #define IWMMXT_OP_ENV_SIZE(name) \
1385 IWMMXT_OP_ENV(name##b) \
1386 IWMMXT_OP_ENV(name##w) \
1387 IWMMXT_OP_ENV(name##l)
1388
1389 #define IWMMXT_OP_ENV1(name) \
1390 static inline void gen_op_iwmmxt_##name##_M0(void) \
1391 { \
1392 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1393 }
1394
1395 IWMMXT_OP(maddsq)
1396 IWMMXT_OP(madduq)
1397 IWMMXT_OP(sadb)
1398 IWMMXT_OP(sadw)
1399 IWMMXT_OP(mulslw)
1400 IWMMXT_OP(mulshw)
1401 IWMMXT_OP(mululw)
1402 IWMMXT_OP(muluhw)
1403 IWMMXT_OP(macsw)
1404 IWMMXT_OP(macuw)
1405
1406 IWMMXT_OP_ENV_SIZE(unpackl)
1407 IWMMXT_OP_ENV_SIZE(unpackh)
1408
1409 IWMMXT_OP_ENV1(unpacklub)
1410 IWMMXT_OP_ENV1(unpackluw)
1411 IWMMXT_OP_ENV1(unpacklul)
1412 IWMMXT_OP_ENV1(unpackhub)
1413 IWMMXT_OP_ENV1(unpackhuw)
1414 IWMMXT_OP_ENV1(unpackhul)
1415 IWMMXT_OP_ENV1(unpacklsb)
1416 IWMMXT_OP_ENV1(unpacklsw)
1417 IWMMXT_OP_ENV1(unpacklsl)
1418 IWMMXT_OP_ENV1(unpackhsb)
1419 IWMMXT_OP_ENV1(unpackhsw)
1420 IWMMXT_OP_ENV1(unpackhsl)
1421
1422 IWMMXT_OP_ENV_SIZE(cmpeq)
1423 IWMMXT_OP_ENV_SIZE(cmpgtu)
1424 IWMMXT_OP_ENV_SIZE(cmpgts)
1425
1426 IWMMXT_OP_ENV_SIZE(mins)
1427 IWMMXT_OP_ENV_SIZE(minu)
1428 IWMMXT_OP_ENV_SIZE(maxs)
1429 IWMMXT_OP_ENV_SIZE(maxu)
1430
1431 IWMMXT_OP_ENV_SIZE(subn)
1432 IWMMXT_OP_ENV_SIZE(addn)
1433 IWMMXT_OP_ENV_SIZE(subu)
1434 IWMMXT_OP_ENV_SIZE(addu)
1435 IWMMXT_OP_ENV_SIZE(subs)
1436 IWMMXT_OP_ENV_SIZE(adds)
1437
1438 IWMMXT_OP_ENV(avgb0)
1439 IWMMXT_OP_ENV(avgb1)
1440 IWMMXT_OP_ENV(avgw0)
1441 IWMMXT_OP_ENV(avgw1)
1442
1443 IWMMXT_OP_ENV(packuw)
1444 IWMMXT_OP_ENV(packul)
1445 IWMMXT_OP_ENV(packuq)
1446 IWMMXT_OP_ENV(packsw)
1447 IWMMXT_OP_ENV(packsl)
1448 IWMMXT_OP_ENV(packsq)
1449
1450 static void gen_op_iwmmxt_set_mup(void)
1451 {
1452 TCGv_i32 tmp;
1453 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1454 tcg_gen_ori_i32(tmp, tmp, 2);
1455 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1456 }
1457
1458 static void gen_op_iwmmxt_set_cup(void)
1459 {
1460 TCGv_i32 tmp;
1461 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1462 tcg_gen_ori_i32(tmp, tmp, 1);
1463 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1464 }
1465
1466 static void gen_op_iwmmxt_setpsr_nz(void)
1467 {
1468 TCGv_i32 tmp = tcg_temp_new_i32();
1469 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1470 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1471 }
1472
1473 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1474 {
1475 iwmmxt_load_reg(cpu_V1, rn);
1476 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1477 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1478 }
1479
1480 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1481 TCGv_i32 dest)
1482 {
1483 int rd;
1484 uint32_t offset;
1485 TCGv_i32 tmp;
1486
1487 rd = (insn >> 16) & 0xf;
1488 tmp = load_reg(s, rd);
1489
1490 offset = (insn & 0xff) << ((insn >> 7) & 2);
1491 if (insn & (1 << 24)) {
1492 /* Pre indexed */
1493 if (insn & (1 << 23))
1494 tcg_gen_addi_i32(tmp, tmp, offset);
1495 else
1496 tcg_gen_addi_i32(tmp, tmp, -offset);
1497 tcg_gen_mov_i32(dest, tmp);
1498 if (insn & (1 << 21))
1499 store_reg(s, rd, tmp);
1500 else
1501 tcg_temp_free_i32(tmp);
1502 } else if (insn & (1 << 21)) {
1503 /* Post indexed */
1504 tcg_gen_mov_i32(dest, tmp);
1505 if (insn & (1 << 23))
1506 tcg_gen_addi_i32(tmp, tmp, offset);
1507 else
1508 tcg_gen_addi_i32(tmp, tmp, -offset);
1509 store_reg(s, rd, tmp);
1510 } else if (!(insn & (1 << 23)))
1511 return 1;
1512 return 0;
1513 }
1514
1515 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1516 {
1517 int rd = (insn >> 0) & 0xf;
1518 TCGv_i32 tmp;
1519
1520 if (insn & (1 << 8)) {
1521 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1522 return 1;
1523 } else {
1524 tmp = iwmmxt_load_creg(rd);
1525 }
1526 } else {
1527 tmp = tcg_temp_new_i32();
1528 iwmmxt_load_reg(cpu_V0, rd);
1529 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1530 }
1531 tcg_gen_andi_i32(tmp, tmp, mask);
1532 tcg_gen_mov_i32(dest, tmp);
1533 tcg_temp_free_i32(tmp);
1534 return 0;
1535 }
1536
1537 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1538 (ie. an undefined instruction). */
1539 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1540 {
1541 int rd, wrd;
1542 int rdhi, rdlo, rd0, rd1, i;
1543 TCGv_i32 addr;
1544 TCGv_i32 tmp, tmp2, tmp3;
1545
1546 if ((insn & 0x0e000e00) == 0x0c000000) {
1547 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1548 wrd = insn & 0xf;
1549 rdlo = (insn >> 12) & 0xf;
1550 rdhi = (insn >> 16) & 0xf;
1551 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1552 iwmmxt_load_reg(cpu_V0, wrd);
1553 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1554 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1555 } else { /* TMCRR */
1556 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1557 iwmmxt_store_reg(cpu_V0, wrd);
1558 gen_op_iwmmxt_set_mup();
1559 }
1560 return 0;
1561 }
1562
1563 wrd = (insn >> 12) & 0xf;
1564 addr = tcg_temp_new_i32();
1565 if (gen_iwmmxt_address(s, insn, addr)) {
1566 tcg_temp_free_i32(addr);
1567 return 1;
1568 }
1569 if (insn & ARM_CP_RW_BIT) {
1570 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1571 tmp = tcg_temp_new_i32();
1572 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1573 iwmmxt_store_creg(wrd, tmp);
1574 } else {
1575 i = 1;
1576 if (insn & (1 << 8)) {
1577 if (insn & (1 << 22)) { /* WLDRD */
1578 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1579 i = 0;
1580 } else { /* WLDRW wRd */
1581 tmp = tcg_temp_new_i32();
1582 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1583 }
1584 } else {
1585 tmp = tcg_temp_new_i32();
1586 if (insn & (1 << 22)) { /* WLDRH */
1587 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1588 } else { /* WLDRB */
1589 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1590 }
1591 }
1592 if (i) {
1593 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1594 tcg_temp_free_i32(tmp);
1595 }
1596 gen_op_iwmmxt_movq_wRn_M0(wrd);
1597 }
1598 } else {
1599 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1600 tmp = iwmmxt_load_creg(wrd);
1601 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1602 } else {
1603 gen_op_iwmmxt_movq_M0_wRn(wrd);
1604 tmp = tcg_temp_new_i32();
1605 if (insn & (1 << 8)) {
1606 if (insn & (1 << 22)) { /* WSTRD */
1607 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1608 } else { /* WSTRW wRd */
1609 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1610 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1611 }
1612 } else {
1613 if (insn & (1 << 22)) { /* WSTRH */
1614 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1615 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1616 } else { /* WSTRB */
1617 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1618 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1619 }
1620 }
1621 }
1622 tcg_temp_free_i32(tmp);
1623 }
1624 tcg_temp_free_i32(addr);
1625 return 0;
1626 }
1627
1628 if ((insn & 0x0f000000) != 0x0e000000)
1629 return 1;
1630
1631 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1632 case 0x000: /* WOR */
1633 wrd = (insn >> 12) & 0xf;
1634 rd0 = (insn >> 0) & 0xf;
1635 rd1 = (insn >> 16) & 0xf;
1636 gen_op_iwmmxt_movq_M0_wRn(rd0);
1637 gen_op_iwmmxt_orq_M0_wRn(rd1);
1638 gen_op_iwmmxt_setpsr_nz();
1639 gen_op_iwmmxt_movq_wRn_M0(wrd);
1640 gen_op_iwmmxt_set_mup();
1641 gen_op_iwmmxt_set_cup();
1642 break;
1643 case 0x011: /* TMCR */
1644 if (insn & 0xf)
1645 return 1;
1646 rd = (insn >> 12) & 0xf;
1647 wrd = (insn >> 16) & 0xf;
1648 switch (wrd) {
1649 case ARM_IWMMXT_wCID:
1650 case ARM_IWMMXT_wCASF:
1651 break;
1652 case ARM_IWMMXT_wCon:
1653 gen_op_iwmmxt_set_cup();
1654 /* Fall through. */
1655 case ARM_IWMMXT_wCSSF:
1656 tmp = iwmmxt_load_creg(wrd);
1657 tmp2 = load_reg(s, rd);
1658 tcg_gen_andc_i32(tmp, tmp, tmp2);
1659 tcg_temp_free_i32(tmp2);
1660 iwmmxt_store_creg(wrd, tmp);
1661 break;
1662 case ARM_IWMMXT_wCGR0:
1663 case ARM_IWMMXT_wCGR1:
1664 case ARM_IWMMXT_wCGR2:
1665 case ARM_IWMMXT_wCGR3:
1666 gen_op_iwmmxt_set_cup();
1667 tmp = load_reg(s, rd);
1668 iwmmxt_store_creg(wrd, tmp);
1669 break;
1670 default:
1671 return 1;
1672 }
1673 break;
1674 case 0x100: /* WXOR */
1675 wrd = (insn >> 12) & 0xf;
1676 rd0 = (insn >> 0) & 0xf;
1677 rd1 = (insn >> 16) & 0xf;
1678 gen_op_iwmmxt_movq_M0_wRn(rd0);
1679 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1680 gen_op_iwmmxt_setpsr_nz();
1681 gen_op_iwmmxt_movq_wRn_M0(wrd);
1682 gen_op_iwmmxt_set_mup();
1683 gen_op_iwmmxt_set_cup();
1684 break;
1685 case 0x111: /* TMRC */
1686 if (insn & 0xf)
1687 return 1;
1688 rd = (insn >> 12) & 0xf;
1689 wrd = (insn >> 16) & 0xf;
1690 tmp = iwmmxt_load_creg(wrd);
1691 store_reg(s, rd, tmp);
1692 break;
1693 case 0x300: /* WANDN */
1694 wrd = (insn >> 12) & 0xf;
1695 rd0 = (insn >> 0) & 0xf;
1696 rd1 = (insn >> 16) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0);
1698 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1699 gen_op_iwmmxt_andq_M0_wRn(rd1);
1700 gen_op_iwmmxt_setpsr_nz();
1701 gen_op_iwmmxt_movq_wRn_M0(wrd);
1702 gen_op_iwmmxt_set_mup();
1703 gen_op_iwmmxt_set_cup();
1704 break;
1705 case 0x200: /* WAND */
1706 wrd = (insn >> 12) & 0xf;
1707 rd0 = (insn >> 0) & 0xf;
1708 rd1 = (insn >> 16) & 0xf;
1709 gen_op_iwmmxt_movq_M0_wRn(rd0);
1710 gen_op_iwmmxt_andq_M0_wRn(rd1);
1711 gen_op_iwmmxt_setpsr_nz();
1712 gen_op_iwmmxt_movq_wRn_M0(wrd);
1713 gen_op_iwmmxt_set_mup();
1714 gen_op_iwmmxt_set_cup();
1715 break;
1716 case 0x810: case 0xa10: /* WMADD */
1717 wrd = (insn >> 12) & 0xf;
1718 rd0 = (insn >> 0) & 0xf;
1719 rd1 = (insn >> 16) & 0xf;
1720 gen_op_iwmmxt_movq_M0_wRn(rd0);
1721 if (insn & (1 << 21))
1722 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1723 else
1724 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd);
1726 gen_op_iwmmxt_set_mup();
1727 break;
1728 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1729 wrd = (insn >> 12) & 0xf;
1730 rd0 = (insn >> 16) & 0xf;
1731 rd1 = (insn >> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0);
1733 switch ((insn >> 22) & 3) {
1734 case 0:
1735 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1736 break;
1737 case 1:
1738 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1739 break;
1740 case 2:
1741 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1742 break;
1743 case 3:
1744 return 1;
1745 }
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1749 break;
1750 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1751 wrd = (insn >> 12) & 0xf;
1752 rd0 = (insn >> 16) & 0xf;
1753 rd1 = (insn >> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0);
1755 switch ((insn >> 22) & 3) {
1756 case 0:
1757 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1758 break;
1759 case 1:
1760 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1761 break;
1762 case 2:
1763 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1764 break;
1765 case 3:
1766 return 1;
1767 }
1768 gen_op_iwmmxt_movq_wRn_M0(wrd);
1769 gen_op_iwmmxt_set_mup();
1770 gen_op_iwmmxt_set_cup();
1771 break;
1772 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1773 wrd = (insn >> 12) & 0xf;
1774 rd0 = (insn >> 16) & 0xf;
1775 rd1 = (insn >> 0) & 0xf;
1776 gen_op_iwmmxt_movq_M0_wRn(rd0);
1777 if (insn & (1 << 22))
1778 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1779 else
1780 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1781 if (!(insn & (1 << 20)))
1782 gen_op_iwmmxt_addl_M0_wRn(wrd);
1783 gen_op_iwmmxt_movq_wRn_M0(wrd);
1784 gen_op_iwmmxt_set_mup();
1785 break;
1786 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1787 wrd = (insn >> 12) & 0xf;
1788 rd0 = (insn >> 16) & 0xf;
1789 rd1 = (insn >> 0) & 0xf;
1790 gen_op_iwmmxt_movq_M0_wRn(rd0);
1791 if (insn & (1 << 21)) {
1792 if (insn & (1 << 20))
1793 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1794 else
1795 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1796 } else {
1797 if (insn & (1 << 20))
1798 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1799 else
1800 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1801 }
1802 gen_op_iwmmxt_movq_wRn_M0(wrd);
1803 gen_op_iwmmxt_set_mup();
1804 break;
1805 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1806 wrd = (insn >> 12) & 0xf;
1807 rd0 = (insn >> 16) & 0xf;
1808 rd1 = (insn >> 0) & 0xf;
1809 gen_op_iwmmxt_movq_M0_wRn(rd0);
1810 if (insn & (1 << 21))
1811 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1812 else
1813 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1814 if (!(insn & (1 << 20))) {
1815 iwmmxt_load_reg(cpu_V1, wrd);
1816 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1817 }
1818 gen_op_iwmmxt_movq_wRn_M0(wrd);
1819 gen_op_iwmmxt_set_mup();
1820 break;
1821 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1822 wrd = (insn >> 12) & 0xf;
1823 rd0 = (insn >> 16) & 0xf;
1824 rd1 = (insn >> 0) & 0xf;
1825 gen_op_iwmmxt_movq_M0_wRn(rd0);
1826 switch ((insn >> 22) & 3) {
1827 case 0:
1828 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1829 break;
1830 case 1:
1831 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1832 break;
1833 case 2:
1834 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1835 break;
1836 case 3:
1837 return 1;
1838 }
1839 gen_op_iwmmxt_movq_wRn_M0(wrd);
1840 gen_op_iwmmxt_set_mup();
1841 gen_op_iwmmxt_set_cup();
1842 break;
1843 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1844 wrd = (insn >> 12) & 0xf;
1845 rd0 = (insn >> 16) & 0xf;
1846 rd1 = (insn >> 0) & 0xf;
1847 gen_op_iwmmxt_movq_M0_wRn(rd0);
1848 if (insn & (1 << 22)) {
1849 if (insn & (1 << 20))
1850 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1851 else
1852 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1853 } else {
1854 if (insn & (1 << 20))
1855 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1856 else
1857 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1858 }
1859 gen_op_iwmmxt_movq_wRn_M0(wrd);
1860 gen_op_iwmmxt_set_mup();
1861 gen_op_iwmmxt_set_cup();
1862 break;
1863 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1864 wrd = (insn >> 12) & 0xf;
1865 rd0 = (insn >> 16) & 0xf;
1866 rd1 = (insn >> 0) & 0xf;
1867 gen_op_iwmmxt_movq_M0_wRn(rd0);
1868 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1869 tcg_gen_andi_i32(tmp, tmp, 7);
1870 iwmmxt_load_reg(cpu_V1, rd1);
1871 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1872 tcg_temp_free_i32(tmp);
1873 gen_op_iwmmxt_movq_wRn_M0(wrd);
1874 gen_op_iwmmxt_set_mup();
1875 break;
1876 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1877 if (((insn >> 6) & 3) == 3)
1878 return 1;
1879 rd = (insn >> 12) & 0xf;
1880 wrd = (insn >> 16) & 0xf;
1881 tmp = load_reg(s, rd);
1882 gen_op_iwmmxt_movq_M0_wRn(wrd);
1883 switch ((insn >> 6) & 3) {
1884 case 0:
1885 tmp2 = tcg_const_i32(0xff);
1886 tmp3 = tcg_const_i32((insn & 7) << 3);
1887 break;
1888 case 1:
1889 tmp2 = tcg_const_i32(0xffff);
1890 tmp3 = tcg_const_i32((insn & 3) << 4);
1891 break;
1892 case 2:
1893 tmp2 = tcg_const_i32(0xffffffff);
1894 tmp3 = tcg_const_i32((insn & 1) << 5);
1895 break;
1896 default:
1897 tmp2 = NULL;
1898 tmp3 = NULL;
1899 }
1900 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1901 tcg_temp_free_i32(tmp3);
1902 tcg_temp_free_i32(tmp2);
1903 tcg_temp_free_i32(tmp);
1904 gen_op_iwmmxt_movq_wRn_M0(wrd);
1905 gen_op_iwmmxt_set_mup();
1906 break;
1907 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1908 rd = (insn >> 12) & 0xf;
1909 wrd = (insn >> 16) & 0xf;
1910 if (rd == 15 || ((insn >> 22) & 3) == 3)
1911 return 1;
1912 gen_op_iwmmxt_movq_M0_wRn(wrd);
1913 tmp = tcg_temp_new_i32();
1914 switch ((insn >> 22) & 3) {
1915 case 0:
1916 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1917 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1918 if (insn & 8) {
1919 tcg_gen_ext8s_i32(tmp, tmp);
1920 } else {
1921 tcg_gen_andi_i32(tmp, tmp, 0xff);
1922 }
1923 break;
1924 case 1:
1925 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1926 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1927 if (insn & 8) {
1928 tcg_gen_ext16s_i32(tmp, tmp);
1929 } else {
1930 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1931 }
1932 break;
1933 case 2:
1934 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1935 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1936 break;
1937 }
1938 store_reg(s, rd, tmp);
1939 break;
1940 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1941 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1942 return 1;
1943 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1944 switch ((insn >> 22) & 3) {
1945 case 0:
1946 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1947 break;
1948 case 1:
1949 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1950 break;
1951 case 2:
1952 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1953 break;
1954 }
1955 tcg_gen_shli_i32(tmp, tmp, 28);
1956 gen_set_nzcv(tmp);
1957 tcg_temp_free_i32(tmp);
1958 break;
1959 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1960 if (((insn >> 6) & 3) == 3)
1961 return 1;
1962 rd = (insn >> 12) & 0xf;
1963 wrd = (insn >> 16) & 0xf;
1964 tmp = load_reg(s, rd);
1965 switch ((insn >> 6) & 3) {
1966 case 0:
1967 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1968 break;
1969 case 1:
1970 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1971 break;
1972 case 2:
1973 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1974 break;
1975 }
1976 tcg_temp_free_i32(tmp);
1977 gen_op_iwmmxt_movq_wRn_M0(wrd);
1978 gen_op_iwmmxt_set_mup();
1979 break;
1980 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1981 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1982 return 1;
1983 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1984 tmp2 = tcg_temp_new_i32();
1985 tcg_gen_mov_i32(tmp2, tmp);
1986 switch ((insn >> 22) & 3) {
1987 case 0:
1988 for (i = 0; i < 7; i ++) {
1989 tcg_gen_shli_i32(tmp2, tmp2, 4);
1990 tcg_gen_and_i32(tmp, tmp, tmp2);
1991 }
1992 break;
1993 case 1:
1994 for (i = 0; i < 3; i ++) {
1995 tcg_gen_shli_i32(tmp2, tmp2, 8);
1996 tcg_gen_and_i32(tmp, tmp, tmp2);
1997 }
1998 break;
1999 case 2:
2000 tcg_gen_shli_i32(tmp2, tmp2, 16);
2001 tcg_gen_and_i32(tmp, tmp, tmp2);
2002 break;
2003 }
2004 gen_set_nzcv(tmp);
2005 tcg_temp_free_i32(tmp2);
2006 tcg_temp_free_i32(tmp);
2007 break;
2008 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2009 wrd = (insn >> 12) & 0xf;
2010 rd0 = (insn >> 16) & 0xf;
2011 gen_op_iwmmxt_movq_M0_wRn(rd0);
2012 switch ((insn >> 22) & 3) {
2013 case 0:
2014 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2015 break;
2016 case 1:
2017 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2018 break;
2019 case 2:
2020 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2021 break;
2022 case 3:
2023 return 1;
2024 }
2025 gen_op_iwmmxt_movq_wRn_M0(wrd);
2026 gen_op_iwmmxt_set_mup();
2027 break;
2028 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2029 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2030 return 1;
2031 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2032 tmp2 = tcg_temp_new_i32();
2033 tcg_gen_mov_i32(tmp2, tmp);
2034 switch ((insn >> 22) & 3) {
2035 case 0:
2036 for (i = 0; i < 7; i ++) {
2037 tcg_gen_shli_i32(tmp2, tmp2, 4);
2038 tcg_gen_or_i32(tmp, tmp, tmp2);
2039 }
2040 break;
2041 case 1:
2042 for (i = 0; i < 3; i ++) {
2043 tcg_gen_shli_i32(tmp2, tmp2, 8);
2044 tcg_gen_or_i32(tmp, tmp, tmp2);
2045 }
2046 break;
2047 case 2:
2048 tcg_gen_shli_i32(tmp2, tmp2, 16);
2049 tcg_gen_or_i32(tmp, tmp, tmp2);
2050 break;
2051 }
2052 gen_set_nzcv(tmp);
2053 tcg_temp_free_i32(tmp2);
2054 tcg_temp_free_i32(tmp);
2055 break;
2056 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2057 rd = (insn >> 12) & 0xf;
2058 rd0 = (insn >> 16) & 0xf;
2059 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2060 return 1;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0);
2062 tmp = tcg_temp_new_i32();
2063 switch ((insn >> 22) & 3) {
2064 case 0:
2065 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2066 break;
2067 case 1:
2068 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2069 break;
2070 case 2:
2071 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2072 break;
2073 }
2074 store_reg(s, rd, tmp);
2075 break;
2076 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2077 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2078 wrd = (insn >> 12) & 0xf;
2079 rd0 = (insn >> 16) & 0xf;
2080 rd1 = (insn >> 0) & 0xf;
2081 gen_op_iwmmxt_movq_M0_wRn(rd0);
2082 switch ((insn >> 22) & 3) {
2083 case 0:
2084 if (insn & (1 << 21))
2085 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2086 else
2087 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2088 break;
2089 case 1:
2090 if (insn & (1 << 21))
2091 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2092 else
2093 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2094 break;
2095 case 2:
2096 if (insn & (1 << 21))
2097 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2098 else
2099 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2100 break;
2101 case 3:
2102 return 1;
2103 }
2104 gen_op_iwmmxt_movq_wRn_M0(wrd);
2105 gen_op_iwmmxt_set_mup();
2106 gen_op_iwmmxt_set_cup();
2107 break;
2108 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2109 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2110 wrd = (insn >> 12) & 0xf;
2111 rd0 = (insn >> 16) & 0xf;
2112 gen_op_iwmmxt_movq_M0_wRn(rd0);
2113 switch ((insn >> 22) & 3) {
2114 case 0:
2115 if (insn & (1 << 21))
2116 gen_op_iwmmxt_unpacklsb_M0();
2117 else
2118 gen_op_iwmmxt_unpacklub_M0();
2119 break;
2120 case 1:
2121 if (insn & (1 << 21))
2122 gen_op_iwmmxt_unpacklsw_M0();
2123 else
2124 gen_op_iwmmxt_unpackluw_M0();
2125 break;
2126 case 2:
2127 if (insn & (1 << 21))
2128 gen_op_iwmmxt_unpacklsl_M0();
2129 else
2130 gen_op_iwmmxt_unpacklul_M0();
2131 break;
2132 case 3:
2133 return 1;
2134 }
2135 gen_op_iwmmxt_movq_wRn_M0(wrd);
2136 gen_op_iwmmxt_set_mup();
2137 gen_op_iwmmxt_set_cup();
2138 break;
2139 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2140 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2141 wrd = (insn >> 12) & 0xf;
2142 rd0 = (insn >> 16) & 0xf;
2143 gen_op_iwmmxt_movq_M0_wRn(rd0);
2144 switch ((insn >> 22) & 3) {
2145 case 0:
2146 if (insn & (1 << 21))
2147 gen_op_iwmmxt_unpackhsb_M0();
2148 else
2149 gen_op_iwmmxt_unpackhub_M0();
2150 break;
2151 case 1:
2152 if (insn & (1 << 21))
2153 gen_op_iwmmxt_unpackhsw_M0();
2154 else
2155 gen_op_iwmmxt_unpackhuw_M0();
2156 break;
2157 case 2:
2158 if (insn & (1 << 21))
2159 gen_op_iwmmxt_unpackhsl_M0();
2160 else
2161 gen_op_iwmmxt_unpackhul_M0();
2162 break;
2163 case 3:
2164 return 1;
2165 }
2166 gen_op_iwmmxt_movq_wRn_M0(wrd);
2167 gen_op_iwmmxt_set_mup();
2168 gen_op_iwmmxt_set_cup();
2169 break;
2170 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2171 case 0x214: case 0x614: case 0xa14: case 0xe14:
2172 if (((insn >> 22) & 3) == 0)
2173 return 1;
2174 wrd = (insn >> 12) & 0xf;
2175 rd0 = (insn >> 16) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0);
2177 tmp = tcg_temp_new_i32();
2178 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2179 tcg_temp_free_i32(tmp);
2180 return 1;
2181 }
2182 switch ((insn >> 22) & 3) {
2183 case 1:
2184 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2185 break;
2186 case 2:
2187 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2188 break;
2189 case 3:
2190 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2191 break;
2192 }
2193 tcg_temp_free_i32(tmp);
2194 gen_op_iwmmxt_movq_wRn_M0(wrd);
2195 gen_op_iwmmxt_set_mup();
2196 gen_op_iwmmxt_set_cup();
2197 break;
2198 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2199 case 0x014: case 0x414: case 0x814: case 0xc14:
2200 if (((insn >> 22) & 3) == 0)
2201 return 1;
2202 wrd = (insn >> 12) & 0xf;
2203 rd0 = (insn >> 16) & 0xf;
2204 gen_op_iwmmxt_movq_M0_wRn(rd0);
2205 tmp = tcg_temp_new_i32();
2206 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2207 tcg_temp_free_i32(tmp);
2208 return 1;
2209 }
2210 switch ((insn >> 22) & 3) {
2211 case 1:
2212 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2213 break;
2214 case 2:
2215 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2216 break;
2217 case 3:
2218 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2219 break;
2220 }
2221 tcg_temp_free_i32(tmp);
2222 gen_op_iwmmxt_movq_wRn_M0(wrd);
2223 gen_op_iwmmxt_set_mup();
2224 gen_op_iwmmxt_set_cup();
2225 break;
2226 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2227 case 0x114: case 0x514: case 0x914: case 0xd14:
2228 if (((insn >> 22) & 3) == 0)
2229 return 1;
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 tmp = tcg_temp_new_i32();
2234 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2235 tcg_temp_free_i32(tmp);
2236 return 1;
2237 }
2238 switch ((insn >> 22) & 3) {
2239 case 1:
2240 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2241 break;
2242 case 2:
2243 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2244 break;
2245 case 3:
2246 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2247 break;
2248 }
2249 tcg_temp_free_i32(tmp);
2250 gen_op_iwmmxt_movq_wRn_M0(wrd);
2251 gen_op_iwmmxt_set_mup();
2252 gen_op_iwmmxt_set_cup();
2253 break;
2254 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2255 case 0x314: case 0x714: case 0xb14: case 0xf14:
2256 if (((insn >> 22) & 3) == 0)
2257 return 1;
2258 wrd = (insn >> 12) & 0xf;
2259 rd0 = (insn >> 16) & 0xf;
2260 gen_op_iwmmxt_movq_M0_wRn(rd0);
2261 tmp = tcg_temp_new_i32();
2262 switch ((insn >> 22) & 3) {
2263 case 1:
2264 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2265 tcg_temp_free_i32(tmp);
2266 return 1;
2267 }
2268 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2269 break;
2270 case 2:
2271 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2272 tcg_temp_free_i32(tmp);
2273 return 1;
2274 }
2275 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2276 break;
2277 case 3:
2278 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2279 tcg_temp_free_i32(tmp);
2280 return 1;
2281 }
2282 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2283 break;
2284 }
2285 tcg_temp_free_i32(tmp);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd);
2287 gen_op_iwmmxt_set_mup();
2288 gen_op_iwmmxt_set_cup();
2289 break;
2290 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2291 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2292 wrd = (insn >> 12) & 0xf;
2293 rd0 = (insn >> 16) & 0xf;
2294 rd1 = (insn >> 0) & 0xf;
2295 gen_op_iwmmxt_movq_M0_wRn(rd0);
2296 switch ((insn >> 22) & 3) {
2297 case 0:
2298 if (insn & (1 << 21))
2299 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2300 else
2301 gen_op_iwmmxt_minub_M0_wRn(rd1);
2302 break;
2303 case 1:
2304 if (insn & (1 << 21))
2305 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2306 else
2307 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2308 break;
2309 case 2:
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2312 else
2313 gen_op_iwmmxt_minul_M0_wRn(rd1);
2314 break;
2315 case 3:
2316 return 1;
2317 }
2318 gen_op_iwmmxt_movq_wRn_M0(wrd);
2319 gen_op_iwmmxt_set_mup();
2320 break;
2321 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2322 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2323 wrd = (insn >> 12) & 0xf;
2324 rd0 = (insn >> 16) & 0xf;
2325 rd1 = (insn >> 0) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0);
2327 switch ((insn >> 22) & 3) {
2328 case 0:
2329 if (insn & (1 << 21))
2330 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2331 else
2332 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2333 break;
2334 case 1:
2335 if (insn & (1 << 21))
2336 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2337 else
2338 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2339 break;
2340 case 2:
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2343 else
2344 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2345 break;
2346 case 3:
2347 return 1;
2348 }
2349 gen_op_iwmmxt_movq_wRn_M0(wrd);
2350 gen_op_iwmmxt_set_mup();
2351 break;
2352 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2353 case 0x402: case 0x502: case 0x602: case 0x702:
2354 wrd = (insn >> 12) & 0xf;
2355 rd0 = (insn >> 16) & 0xf;
2356 rd1 = (insn >> 0) & 0xf;
2357 gen_op_iwmmxt_movq_M0_wRn(rd0);
2358 tmp = tcg_const_i32((insn >> 20) & 3);
2359 iwmmxt_load_reg(cpu_V1, rd1);
2360 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2361 tcg_temp_free_i32(tmp);
2362 gen_op_iwmmxt_movq_wRn_M0(wrd);
2363 gen_op_iwmmxt_set_mup();
2364 break;
2365 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2366 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2367 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2368 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2369 wrd = (insn >> 12) & 0xf;
2370 rd0 = (insn >> 16) & 0xf;
2371 rd1 = (insn >> 0) & 0xf;
2372 gen_op_iwmmxt_movq_M0_wRn(rd0);
2373 switch ((insn >> 20) & 0xf) {
2374 case 0x0:
2375 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2376 break;
2377 case 0x1:
2378 gen_op_iwmmxt_subub_M0_wRn(rd1);
2379 break;
2380 case 0x3:
2381 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2382 break;
2383 case 0x4:
2384 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2385 break;
2386 case 0x5:
2387 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2388 break;
2389 case 0x7:
2390 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2391 break;
2392 case 0x8:
2393 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2394 break;
2395 case 0x9:
2396 gen_op_iwmmxt_subul_M0_wRn(rd1);
2397 break;
2398 case 0xb:
2399 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2400 break;
2401 default:
2402 return 1;
2403 }
2404 gen_op_iwmmxt_movq_wRn_M0(wrd);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2407 break;
2408 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2409 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2410 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2411 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2412 wrd = (insn >> 12) & 0xf;
2413 rd0 = (insn >> 16) & 0xf;
2414 gen_op_iwmmxt_movq_M0_wRn(rd0);
2415 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2416 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2417 tcg_temp_free_i32(tmp);
2418 gen_op_iwmmxt_movq_wRn_M0(wrd);
2419 gen_op_iwmmxt_set_mup();
2420 gen_op_iwmmxt_set_cup();
2421 break;
2422 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2423 case 0x418: case 0x518: case 0x618: case 0x718:
2424 case 0x818: case 0x918: case 0xa18: case 0xb18:
2425 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2426 wrd = (insn >> 12) & 0xf;
2427 rd0 = (insn >> 16) & 0xf;
2428 rd1 = (insn >> 0) & 0xf;
2429 gen_op_iwmmxt_movq_M0_wRn(rd0);
2430 switch ((insn >> 20) & 0xf) {
2431 case 0x0:
2432 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2433 break;
2434 case 0x1:
2435 gen_op_iwmmxt_addub_M0_wRn(rd1);
2436 break;
2437 case 0x3:
2438 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2439 break;
2440 case 0x4:
2441 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2442 break;
2443 case 0x5:
2444 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2445 break;
2446 case 0x7:
2447 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2448 break;
2449 case 0x8:
2450 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2451 break;
2452 case 0x9:
2453 gen_op_iwmmxt_addul_M0_wRn(rd1);
2454 break;
2455 case 0xb:
2456 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2457 break;
2458 default:
2459 return 1;
2460 }
2461 gen_op_iwmmxt_movq_wRn_M0(wrd);
2462 gen_op_iwmmxt_set_mup();
2463 gen_op_iwmmxt_set_cup();
2464 break;
2465 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2466 case 0x408: case 0x508: case 0x608: case 0x708:
2467 case 0x808: case 0x908: case 0xa08: case 0xb08:
2468 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2469 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2470 return 1;
2471 wrd = (insn >> 12) & 0xf;
2472 rd0 = (insn >> 16) & 0xf;
2473 rd1 = (insn >> 0) & 0xf;
2474 gen_op_iwmmxt_movq_M0_wRn(rd0);
2475 switch ((insn >> 22) & 3) {
2476 case 1:
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2479 else
2480 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2481 break;
2482 case 2:
2483 if (insn & (1 << 21))
2484 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2485 else
2486 gen_op_iwmmxt_packul_M0_wRn(rd1);
2487 break;
2488 case 3:
2489 if (insn & (1 << 21))
2490 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2491 else
2492 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2493 break;
2494 }
2495 gen_op_iwmmxt_movq_wRn_M0(wrd);
2496 gen_op_iwmmxt_set_mup();
2497 gen_op_iwmmxt_set_cup();
2498 break;
2499 case 0x201: case 0x203: case 0x205: case 0x207:
2500 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2501 case 0x211: case 0x213: case 0x215: case 0x217:
2502 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2503 wrd = (insn >> 5) & 0xf;
2504 rd0 = (insn >> 12) & 0xf;
2505 rd1 = (insn >> 0) & 0xf;
2506 if (rd0 == 0xf || rd1 == 0xf)
2507 return 1;
2508 gen_op_iwmmxt_movq_M0_wRn(wrd);
2509 tmp = load_reg(s, rd0);
2510 tmp2 = load_reg(s, rd1);
2511 switch ((insn >> 16) & 0xf) {
2512 case 0x0: /* TMIA */
2513 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2514 break;
2515 case 0x8: /* TMIAPH */
2516 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2517 break;
2518 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2519 if (insn & (1 << 16))
2520 tcg_gen_shri_i32(tmp, tmp, 16);
2521 if (insn & (1 << 17))
2522 tcg_gen_shri_i32(tmp2, tmp2, 16);
2523 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2524 break;
2525 default:
2526 tcg_temp_free_i32(tmp2);
2527 tcg_temp_free_i32(tmp);
2528 return 1;
2529 }
2530 tcg_temp_free_i32(tmp2);
2531 tcg_temp_free_i32(tmp);
2532 gen_op_iwmmxt_movq_wRn_M0(wrd);
2533 gen_op_iwmmxt_set_mup();
2534 break;
2535 default:
2536 return 1;
2537 }
2538
2539 return 0;
2540 }
2541
2542 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2543 (ie. an undefined instruction). */
2544 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2545 {
2546 int acc, rd0, rd1, rdhi, rdlo;
2547 TCGv_i32 tmp, tmp2;
2548
2549 if ((insn & 0x0ff00f10) == 0x0e200010) {
2550 /* Multiply with Internal Accumulate Format */
2551 rd0 = (insn >> 12) & 0xf;
2552 rd1 = insn & 0xf;
2553 acc = (insn >> 5) & 7;
2554
2555 if (acc != 0)
2556 return 1;
2557
2558 tmp = load_reg(s, rd0);
2559 tmp2 = load_reg(s, rd1);
2560 switch ((insn >> 16) & 0xf) {
2561 case 0x0: /* MIA */
2562 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2563 break;
2564 case 0x8: /* MIAPH */
2565 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2566 break;
2567 case 0xc: /* MIABB */
2568 case 0xd: /* MIABT */
2569 case 0xe: /* MIATB */
2570 case 0xf: /* MIATT */
2571 if (insn & (1 << 16))
2572 tcg_gen_shri_i32(tmp, tmp, 16);
2573 if (insn & (1 << 17))
2574 tcg_gen_shri_i32(tmp2, tmp2, 16);
2575 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2576 break;
2577 default:
2578 return 1;
2579 }
2580 tcg_temp_free_i32(tmp2);
2581 tcg_temp_free_i32(tmp);
2582
2583 gen_op_iwmmxt_movq_wRn_M0(acc);
2584 return 0;
2585 }
2586
2587 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2588 /* Internal Accumulator Access Format */
2589 rdhi = (insn >> 16) & 0xf;
2590 rdlo = (insn >> 12) & 0xf;
2591 acc = insn & 7;
2592
2593 if (acc != 0)
2594 return 1;
2595
2596 if (insn & ARM_CP_RW_BIT) { /* MRA */
2597 iwmmxt_load_reg(cpu_V0, acc);
2598 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2599 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2600 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2601 } else { /* MAR */
2602 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2603 iwmmxt_store_reg(cpu_V0, acc);
2604 }
2605 return 0;
2606 }
2607
2608 return 1;
2609 }
2610
2611 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2612 #define VFP_SREG(insn, bigbit, smallbit) \
2613 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2614 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2615 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2616 reg = (((insn) >> (bigbit)) & 0x0f) \
2617 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2618 } else { \
2619 if (insn & (1 << (smallbit))) \
2620 return 1; \
2621 reg = ((insn) >> (bigbit)) & 0x0f; \
2622 }} while (0)
2623
2624 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2625 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2626 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2627 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2628 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2629 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2630
2631 static void gen_neon_dup_low16(TCGv_i32 var)
2632 {
2633 TCGv_i32 tmp = tcg_temp_new_i32();
2634 tcg_gen_ext16u_i32(var, var);
2635 tcg_gen_shli_i32(tmp, var, 16);
2636 tcg_gen_or_i32(var, var, tmp);
2637 tcg_temp_free_i32(tmp);
2638 }
2639
2640 static void gen_neon_dup_high16(TCGv_i32 var)
2641 {
2642 TCGv_i32 tmp = tcg_temp_new_i32();
2643 tcg_gen_andi_i32(var, var, 0xffff0000);
2644 tcg_gen_shri_i32(tmp, var, 16);
2645 tcg_gen_or_i32(var, var, tmp);
2646 tcg_temp_free_i32(tmp);
2647 }
2648
2649 /*
2650 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2651 * (ie. an undefined instruction).
2652 */
2653 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2654 {
2655 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2656 return 1;
2657 }
2658
2659 /*
2660 * If the decodetree decoder handles this insn it will always
2661 * emit code to either execute the insn or generate an appropriate
2662 * exception; so we don't need to ever return non-zero to tell
2663 * the calling code to emit an UNDEF exception.
2664 */
2665 if (extract32(insn, 28, 4) == 0xf) {
2666 if (disas_vfp_uncond(s, insn)) {
2667 return 0;
2668 }
2669 } else {
2670 if (disas_vfp(s, insn)) {
2671 return 0;
2672 }
2673 }
2674 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2675 return 1;
2676 }
2677
2678 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2679 {
2680 #ifndef CONFIG_USER_ONLY
2681 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2682 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2683 #else
2684 return true;
2685 #endif
2686 }
2687
2688 static void gen_goto_ptr(void)
2689 {
2690 tcg_gen_lookup_and_goto_ptr();
2691 }
2692
2693 /* This will end the TB but doesn't guarantee we'll return to
2694 * cpu_loop_exec. Any live exit_requests will be processed as we
2695 * enter the next TB.
2696 */
2697 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2698 {
2699 if (use_goto_tb(s, dest)) {
2700 tcg_gen_goto_tb(n);
2701 gen_set_pc_im(s, dest);
2702 tcg_gen_exit_tb(s->base.tb, n);
2703 } else {
2704 gen_set_pc_im(s, dest);
2705 gen_goto_ptr();
2706 }
2707 s->base.is_jmp = DISAS_NORETURN;
2708 }
2709
2710 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2711 {
2712 if (unlikely(is_singlestepping(s))) {
2713 /* An indirect jump so that we still trigger the debug exception. */
2714 gen_set_pc_im(s, dest);
2715 s->base.is_jmp = DISAS_JUMP;
2716 } else {
2717 gen_goto_tb(s, 0, dest);
2718 }
2719 }
2720
2721 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2722 {
2723 if (x)
2724 tcg_gen_sari_i32(t0, t0, 16);
2725 else
2726 gen_sxth(t0);
2727 if (y)
2728 tcg_gen_sari_i32(t1, t1, 16);
2729 else
2730 gen_sxth(t1);
2731 tcg_gen_mul_i32(t0, t0, t1);
2732 }
2733
2734 /* Return the mask of PSR bits set by a MSR instruction. */
2735 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2736 {
2737 uint32_t mask = 0;
2738
2739 if (flags & (1 << 0)) {
2740 mask |= 0xff;
2741 }
2742 if (flags & (1 << 1)) {
2743 mask |= 0xff00;
2744 }
2745 if (flags & (1 << 2)) {
2746 mask |= 0xff0000;
2747 }
2748 if (flags & (1 << 3)) {
2749 mask |= 0xff000000;
2750 }
2751
2752 /* Mask out undefined and reserved bits. */
2753 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2754
2755 /* Mask out execution state. */
2756 if (!spsr) {
2757 mask &= ~CPSR_EXEC;
2758 }
2759
2760 /* Mask out privileged bits. */
2761 if (IS_USER(s)) {
2762 mask &= CPSR_USER;
2763 }
2764 return mask;
2765 }
2766
2767 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2768 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2769 {
2770 TCGv_i32 tmp;
2771 if (spsr) {
2772 /* ??? This is also undefined in system mode. */
2773 if (IS_USER(s))
2774 return 1;
2775
2776 tmp = load_cpu_field(spsr);
2777 tcg_gen_andi_i32(tmp, tmp, ~mask);
2778 tcg_gen_andi_i32(t0, t0, mask);
2779 tcg_gen_or_i32(tmp, tmp, t0);
2780 store_cpu_field(tmp, spsr);
2781 } else {
2782 gen_set_cpsr(t0, mask);
2783 }
2784 tcg_temp_free_i32(t0);
2785 gen_lookup_tb(s);
2786 return 0;
2787 }
2788
2789 /* Returns nonzero if access to the PSR is not permitted. */
2790 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2791 {
2792 TCGv_i32 tmp;
2793 tmp = tcg_temp_new_i32();
2794 tcg_gen_movi_i32(tmp, val);
2795 return gen_set_psr(s, mask, spsr, tmp);
2796 }
2797
2798 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2799 int *tgtmode, int *regno)
2800 {
2801 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2802 * the target mode and register number, and identify the various
2803 * unpredictable cases.
2804 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2805 * + executed in user mode
2806 * + using R15 as the src/dest register
2807 * + accessing an unimplemented register
2808 * + accessing a register that's inaccessible at current PL/security state*
2809 * + accessing a register that you could access with a different insn
2810 * We choose to UNDEF in all these cases.
2811 * Since we don't know which of the various AArch32 modes we are in
2812 * we have to defer some checks to runtime.
2813 * Accesses to Monitor mode registers from Secure EL1 (which implies
2814 * that EL3 is AArch64) must trap to EL3.
2815 *
2816 * If the access checks fail this function will emit code to take
2817 * an exception and return false. Otherwise it will return true,
2818 * and set *tgtmode and *regno appropriately.
2819 */
2820 int exc_target = default_exception_el(s);
2821
2822 /* These instructions are present only in ARMv8, or in ARMv7 with the
2823 * Virtualization Extensions.
2824 */
2825 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2826 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2827 goto undef;
2828 }
2829
2830 if (IS_USER(s) || rn == 15) {
2831 goto undef;
2832 }
2833
2834 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2835 * of registers into (r, sysm).
2836 */
2837 if (r) {
2838 /* SPSRs for other modes */
2839 switch (sysm) {
2840 case 0xe: /* SPSR_fiq */
2841 *tgtmode = ARM_CPU_MODE_FIQ;
2842 break;
2843 case 0x10: /* SPSR_irq */
2844 *tgtmode = ARM_CPU_MODE_IRQ;
2845 break;
2846 case 0x12: /* SPSR_svc */
2847 *tgtmode = ARM_CPU_MODE_SVC;
2848 break;
2849 case 0x14: /* SPSR_abt */
2850 *tgtmode = ARM_CPU_MODE_ABT;
2851 break;
2852 case 0x16: /* SPSR_und */
2853 *tgtmode = ARM_CPU_MODE_UND;
2854 break;
2855 case 0x1c: /* SPSR_mon */
2856 *tgtmode = ARM_CPU_MODE_MON;
2857 break;
2858 case 0x1e: /* SPSR_hyp */
2859 *tgtmode = ARM_CPU_MODE_HYP;
2860 break;
2861 default: /* unallocated */
2862 goto undef;
2863 }
2864 /* We arbitrarily assign SPSR a register number of 16. */
2865 *regno = 16;
2866 } else {
2867 /* general purpose registers for other modes */
2868 switch (sysm) {
2869 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2870 *tgtmode = ARM_CPU_MODE_USR;
2871 *regno = sysm + 8;
2872 break;
2873 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2874 *tgtmode = ARM_CPU_MODE_FIQ;
2875 *regno = sysm;
2876 break;
2877 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2878 *tgtmode = ARM_CPU_MODE_IRQ;
2879 *regno = sysm & 1 ? 13 : 14;
2880 break;
2881 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2882 *tgtmode = ARM_CPU_MODE_SVC;
2883 *regno = sysm & 1 ? 13 : 14;
2884 break;
2885 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2886 *tgtmode = ARM_CPU_MODE_ABT;
2887 *regno = sysm & 1 ? 13 : 14;
2888 break;
2889 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2890 *tgtmode = ARM_CPU_MODE_UND;
2891 *regno = sysm & 1 ? 13 : 14;
2892 break;
2893 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2894 *tgtmode = ARM_CPU_MODE_MON;
2895 *regno = sysm & 1 ? 13 : 14;
2896 break;
2897 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2898 *tgtmode = ARM_CPU_MODE_HYP;
2899 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2900 *regno = sysm & 1 ? 13 : 17;
2901 break;
2902 default: /* unallocated */
2903 goto undef;
2904 }
2905 }
2906
2907 /* Catch the 'accessing inaccessible register' cases we can detect
2908 * at translate time.
2909 */
2910 switch (*tgtmode) {
2911 case ARM_CPU_MODE_MON:
2912 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2913 goto undef;
2914 }
2915 if (s->current_el == 1) {
2916 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2917 * then accesses to Mon registers trap to EL3
2918 */
2919 exc_target = 3;
2920 goto undef;
2921 }
2922 break;
2923 case ARM_CPU_MODE_HYP:
2924 /*
2925 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2926 * (and so we can forbid accesses from EL2 or below). elr_hyp
2927 * can be accessed also from Hyp mode, so forbid accesses from
2928 * EL0 or EL1.
2929 */
2930 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2931 (s->current_el < 3 && *regno != 17)) {
2932 goto undef;
2933 }
2934 break;
2935 default:
2936 break;
2937 }
2938
2939 return true;
2940
2941 undef:
2942 /* If we get here then some access check did not pass */
2943 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2944 syn_uncategorized(), exc_target);
2945 return false;
2946 }
2947
2948 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2949 {
2950 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2951 int tgtmode = 0, regno = 0;
2952
2953 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2954 return;
2955 }
2956
2957 /* Sync state because msr_banked() can raise exceptions */
2958 gen_set_condexec(s);
2959 gen_set_pc_im(s, s->pc_curr);
2960 tcg_reg = load_reg(s, rn);
2961 tcg_tgtmode = tcg_const_i32(tgtmode);
2962 tcg_regno = tcg_const_i32(regno);
2963 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2964 tcg_temp_free_i32(tcg_tgtmode);
2965 tcg_temp_free_i32(tcg_regno);
2966 tcg_temp_free_i32(tcg_reg);
2967 s->base.is_jmp = DISAS_UPDATE;
2968 }
2969
2970 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2971 {
2972 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2973 int tgtmode = 0, regno = 0;
2974
2975 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2976 return;
2977 }
2978
2979 /* Sync state because mrs_banked() can raise exceptions */
2980 gen_set_condexec(s);
2981 gen_set_pc_im(s, s->pc_curr);
2982 tcg_reg = tcg_temp_new_i32();
2983 tcg_tgtmode = tcg_const_i32(tgtmode);
2984 tcg_regno = tcg_const_i32(regno);
2985 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2986 tcg_temp_free_i32(tcg_tgtmode);
2987 tcg_temp_free_i32(tcg_regno);
2988 store_reg(s, rn, tcg_reg);
2989 s->base.is_jmp = DISAS_UPDATE;
2990 }
2991
2992 /* Store value to PC as for an exception return (ie don't
2993 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2994 * will do the masking based on the new value of the Thumb bit.
2995 */
2996 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2997 {
2998 tcg_gen_mov_i32(cpu_R[15], pc);
2999 tcg_temp_free_i32(pc);
3000 }
3001
3002 /* Generate a v6 exception return. Marks both values as dead. */
3003 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3004 {
3005 store_pc_exc_ret(s, pc);
3006 /* The cpsr_write_eret helper will mask the low bits of PC
3007 * appropriately depending on the new Thumb bit, so it must
3008 * be called after storing the new PC.
3009 */
3010 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3011 gen_io_start();
3012 }
3013 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3014 tcg_temp_free_i32(cpsr);
3015 /* Must exit loop to check un-masked IRQs */
3016 s->base.is_jmp = DISAS_EXIT;
3017 }
3018
3019 /* Generate an old-style exception return. Marks pc as dead. */
3020 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3021 {
3022 gen_rfe(s, pc, load_cpu_field(spsr));
3023 }
3024
3025 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3026
3027 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3028 {
3029 switch (size) {
3030 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3031 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3032 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3033 default: abort();
3034 }
3035 }
3036
3037 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3038 {
3039 switch (size) {
3040 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3041 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3042 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3043 default: return;
3044 }
3045 }
3046
3047 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3048 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3049 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3050 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3051 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3052
3053 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3054 switch ((size << 1) | u) { \
3055 case 0: \
3056 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3057 break; \
3058 case 1: \
3059 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3060 break; \
3061 case 2: \
3062 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3063 break; \
3064 case 3: \
3065 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3066 break; \
3067 case 4: \
3068 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3069 break; \
3070 case 5: \
3071 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3072 break; \
3073 default: return 1; \
3074 }} while (0)
3075
3076 #define GEN_NEON_INTEGER_OP(name) do { \
3077 switch ((size << 1) | u) { \
3078 case 0: \
3079 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3080 break; \
3081 case 1: \
3082 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3083 break; \
3084 case 2: \
3085 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3086 break; \
3087 case 3: \
3088 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3089 break; \
3090 case 4: \
3091 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3092 break; \
3093 case 5: \
3094 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3095 break; \
3096 default: return 1; \
3097 }} while (0)
3098
3099 static TCGv_i32 neon_load_scratch(int scratch)
3100 {
3101 TCGv_i32 tmp = tcg_temp_new_i32();
3102 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3103 return tmp;
3104 }
3105
3106 static void neon_store_scratch(int scratch, TCGv_i32 var)
3107 {
3108 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3109 tcg_temp_free_i32(var);
3110 }
3111
3112 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3113 {
3114 TCGv_i32 tmp;
3115 if (size == 1) {
3116 tmp = neon_load_reg(reg & 7, reg >> 4);
3117 if (reg & 8) {
3118 gen_neon_dup_high16(tmp);
3119 } else {
3120 gen_neon_dup_low16(tmp);
3121 }
3122 } else {
3123 tmp = neon_load_reg(reg & 15, reg >> 4);
3124 }
3125 return tmp;
3126 }
3127
3128 static int gen_neon_unzip(int rd, int rm, int size, int q)
3129 {
3130 TCGv_ptr pd, pm;
3131
3132 if (!q && size == 2) {
3133 return 1;
3134 }
3135 pd = vfp_reg_ptr(true, rd);
3136 pm = vfp_reg_ptr(true, rm);
3137 if (q) {
3138 switch (size) {
3139 case 0:
3140 gen_helper_neon_qunzip8(pd, pm);
3141 break;
3142 case 1:
3143 gen_helper_neon_qunzip16(pd, pm);
3144 break;
3145 case 2:
3146 gen_helper_neon_qunzip32(pd, pm);
3147 break;
3148 default:
3149 abort();
3150 }
3151 } else {
3152 switch (size) {
3153 case 0:
3154 gen_helper_neon_unzip8(pd, pm);
3155 break;
3156 case 1:
3157 gen_helper_neon_unzip16(pd, pm);
3158 break;
3159 default:
3160 abort();
3161 }
3162 }
3163 tcg_temp_free_ptr(pd);
3164 tcg_temp_free_ptr(pm);
3165 return 0;
3166 }
3167
3168 static int gen_neon_zip(int rd, int rm, int size, int q)
3169 {
3170 TCGv_ptr pd, pm;
3171
3172 if (!q && size == 2) {
3173 return 1;
3174 }
3175 pd = vfp_reg_ptr(true, rd);
3176 pm = vfp_reg_ptr(true, rm);
3177 if (q) {
3178 switch (size) {
3179 case 0:
3180 gen_helper_neon_qzip8(pd, pm);
3181 break;
3182 case 1:
3183 gen_helper_neon_qzip16(pd, pm);
3184 break;
3185 case 2:
3186 gen_helper_neon_qzip32(pd, pm);
3187 break;
3188 default:
3189 abort();
3190 }
3191 } else {
3192 switch (size) {
3193 case 0:
3194 gen_helper_neon_zip8(pd, pm);
3195 break;
3196 case 1:
3197 gen_helper_neon_zip16(pd, pm);
3198 break;
3199 default:
3200 abort();
3201 }
3202 }
3203 tcg_temp_free_ptr(pd);
3204 tcg_temp_free_ptr(pm);
3205 return 0;
3206 }
3207
3208 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3209 {
3210 TCGv_i32 rd, tmp;
3211
3212 rd = tcg_temp_new_i32();
3213 tmp = tcg_temp_new_i32();
3214
3215 tcg_gen_shli_i32(rd, t0, 8);
3216 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3217 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3218 tcg_gen_or_i32(rd, rd, tmp);
3219
3220 tcg_gen_shri_i32(t1, t1, 8);
3221 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3222 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3223 tcg_gen_or_i32(t1, t1, tmp);
3224 tcg_gen_mov_i32(t0, rd);
3225
3226 tcg_temp_free_i32(tmp);
3227 tcg_temp_free_i32(rd);
3228 }
3229
3230 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3231 {
3232 TCGv_i32 rd, tmp;
3233
3234 rd = tcg_temp_new_i32();
3235 tmp = tcg_temp_new_i32();
3236
3237 tcg_gen_shli_i32(rd, t0, 16);
3238 tcg_gen_andi_i32(tmp, t1, 0xffff);
3239 tcg_gen_or_i32(rd, rd, tmp);
3240 tcg_gen_shri_i32(t1, t1, 16);
3241 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3242 tcg_gen_or_i32(t1, t1, tmp);
3243 tcg_gen_mov_i32(t0, rd);
3244
3245 tcg_temp_free_i32(tmp);
3246 tcg_temp_free_i32(rd);
3247 }
3248
3249
3250 static struct {
3251 int nregs;
3252 int interleave;
3253 int spacing;
3254 } const neon_ls_element_type[11] = {
3255 {1, 4, 1},
3256 {1, 4, 2},
3257 {4, 1, 1},
3258 {2, 2, 2},
3259 {1, 3, 1},
3260 {1, 3, 2},
3261 {3, 1, 1},
3262 {1, 1, 1},
3263 {1, 2, 1},
3264 {1, 2, 2},
3265 {2, 1, 1}
3266 };
3267
3268 /* Translate a NEON load/store element instruction. Return nonzero if the
3269 instruction is invalid. */
3270 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3271 {
3272 int rd, rn, rm;
3273 int op;
3274 int nregs;
3275 int interleave;
3276 int spacing;
3277 int stride;
3278 int size;
3279 int reg;
3280 int load;
3281 int n;
3282 int vec_size;
3283 int mmu_idx;
3284 MemOp endian;
3285 TCGv_i32 addr;
3286 TCGv_i32 tmp;
3287 TCGv_i32 tmp2;
3288 TCGv_i64 tmp64;
3289
3290 /* FIXME: this access check should not take precedence over UNDEF
3291 * for invalid encodings; we will generate incorrect syndrome information
3292 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3293 */
3294 if (s->fp_excp_el) {
3295 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3296 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3297 return 0;
3298 }
3299
3300 if (!s->vfp_enabled)
3301 return 1;
3302 VFP_DREG_D(rd, insn);
3303 rn = (insn >> 16) & 0xf;
3304 rm = insn & 0xf;
3305 load = (insn & (1 << 21)) != 0;
3306 endian = s->be_data;
3307 mmu_idx = get_mem_index(s);
3308 if ((insn & (1 << 23)) == 0) {
3309 /* Load store all elements. */
3310 op = (insn >> 8) & 0xf;
3311 size = (insn >> 6) & 3;
3312 if (op > 10)
3313 return 1;
3314 /* Catch UNDEF cases for bad values of align field */
3315 switch (op & 0xc) {
3316 case 4:
3317 if (((insn >> 5) & 1) == 1) {
3318 return 1;
3319 }
3320 break;
3321 case 8:
3322 if (((insn >> 4) & 3) == 3) {
3323 return 1;
3324 }
3325 break;
3326 default:
3327 break;
3328 }
3329 nregs = neon_ls_element_type[op].nregs;
3330 interleave = neon_ls_element_type[op].interleave;
3331 spacing = neon_ls_element_type[op].spacing;
3332 if (size == 3 && (interleave | spacing) != 1) {
3333 return 1;
3334 }
3335 /* For our purposes, bytes are always little-endian. */
3336 if (size == 0) {
3337 endian = MO_LE;
3338 }
3339 /* Consecutive little-endian elements from a single register
3340 * can be promoted to a larger little-endian operation.
3341 */
3342 if (interleave == 1 && endian == MO_LE) {
3343 size = 3;
3344 }
3345 tmp64 = tcg_temp_new_i64();
3346 addr = tcg_temp_new_i32();
3347 tmp2 = tcg_const_i32(1 << size);
3348 load_reg_var(s, addr, rn);
3349 for (reg = 0; reg < nregs; reg++) {
3350 for (n = 0; n < 8 >> size; n++) {
3351 int xs;
3352 for (xs = 0; xs < interleave; xs++) {
3353 int tt = rd + reg + spacing * xs;
3354
3355 if (load) {
3356 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3357 neon_store_element64(tt, n, size, tmp64);
3358 } else {
3359 neon_load_element64(tmp64, tt, n, size);
3360 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3361 }
3362 tcg_gen_add_i32(addr, addr, tmp2);
3363 }
3364 }
3365 }
3366 tcg_temp_free_i32(addr);
3367 tcg_temp_free_i32(tmp2);
3368 tcg_temp_free_i64(tmp64);
3369 stride = nregs * interleave * 8;
3370 } else {
3371 size = (insn >> 10) & 3;
3372 if (size == 3) {
3373 /* Load single element to all lanes. */
3374 int a = (insn >> 4) & 1;
3375 if (!load) {
3376 return 1;
3377 }
3378 size = (insn >> 6) & 3;
3379 nregs = ((insn >> 8) & 3) + 1;
3380
3381 if (size == 3) {
3382 if (nregs != 4 || a == 0) {
3383 return 1;
3384 }
3385 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3386 size = 2;
3387 }
3388 if (nregs == 1 && a == 1 && size == 0) {
3389 return 1;
3390 }
3391 if (nregs == 3 && a == 1) {
3392 return 1;
3393 }
3394 addr = tcg_temp_new_i32();
3395 load_reg_var(s, addr, rn);
3396
3397 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3398 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3399 */
3400 stride = (insn & (1 << 5)) ? 2 : 1;
3401 vec_size = nregs == 1 ? stride * 8 : 8;
3402
3403 tmp = tcg_temp_new_i32();
3404 for (reg = 0; reg < nregs; reg++) {
3405 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3406 s->be_data | size);
3407 if ((rd & 1) && vec_size == 16) {
3408 /* We cannot write 16 bytes at once because the
3409 * destination is unaligned.
3410 */
3411 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3412 8, 8, tmp);
3413 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3414 neon_reg_offset(rd, 0), 8, 8);
3415 } else {
3416 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3417 vec_size, vec_size, tmp);
3418 }
3419 tcg_gen_addi_i32(addr, addr, 1 << size);
3420 rd += stride;
3421 }
3422 tcg_temp_free_i32(tmp);
3423 tcg_temp_free_i32(addr);
3424 stride = (1 << size) * nregs;
3425 } else {
3426 /* Single element. */
3427 int idx = (insn >> 4) & 0xf;
3428 int reg_idx;
3429 switch (size) {
3430 case 0:
3431 reg_idx = (insn >> 5) & 7;
3432 stride = 1;
3433 break;
3434 case 1:
3435 reg_idx = (insn >> 6) & 3;
3436 stride = (insn & (1 << 5)) ? 2 : 1;
3437 break;
3438 case 2:
3439 reg_idx = (insn >> 7) & 1;
3440 stride = (insn & (1 << 6)) ? 2 : 1;
3441 break;
3442 default:
3443 abort();
3444 }
3445 nregs = ((insn >> 8) & 3) + 1;
3446 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3447 switch (nregs) {
3448 case 1:
3449 if (((idx & (1 << size)) != 0) ||
3450 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3451 return 1;
3452 }
3453 break;
3454 case 3:
3455 if ((idx & 1) != 0) {
3456 return 1;
3457 }
3458 /* fall through */
3459 case 2:
3460 if (size == 2 && (idx & 2) != 0) {
3461 return 1;
3462 }
3463 break;
3464 case 4:
3465 if ((size == 2) && ((idx & 3) == 3)) {
3466 return 1;
3467 }
3468 break;
3469 default:
3470 abort();
3471 }
3472 if ((rd + stride * (nregs - 1)) > 31) {
3473 /* Attempts to write off the end of the register file
3474 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3475 * the neon_load_reg() would write off the end of the array.
3476 */
3477 return 1;
3478 }
3479 tmp = tcg_temp_new_i32();
3480 addr = tcg_temp_new_i32();
3481 load_reg_var(s, addr, rn);
3482 for (reg = 0; reg < nregs; reg++) {
3483 if (load) {
3484 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3485 s->be_data | size);
3486 neon_store_element(rd, reg_idx, size, tmp);
3487 } else { /* Store */
3488 neon_load_element(tmp, rd, reg_idx, size);
3489 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3490 s->be_data | size);
3491 }
3492 rd += stride;
3493 tcg_gen_addi_i32(addr, addr, 1 << size);
3494 }
3495 tcg_temp_free_i32(addr);
3496 tcg_temp_free_i32(tmp);
3497 stride = nregs * (1 << size);
3498 }
3499 }
3500 if (rm != 15) {
3501 TCGv_i32 base;
3502
3503 base = load_reg(s, rn);
3504 if (rm == 13) {
3505 tcg_gen_addi_i32(base, base, stride);
3506 } else {
3507 TCGv_i32 index;
3508 index = load_reg(s, rm);
3509 tcg_gen_add_i32(base, base, index);
3510 tcg_temp_free_i32(index);
3511 }
3512 store_reg(s, rn, base);
3513 }
3514 return 0;
3515 }
3516
3517 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3518 {
3519 switch (size) {
3520 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3521 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3522 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3523 default: abort();
3524 }
3525 }
3526
3527 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3528 {
3529 switch (size) {
3530 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3531 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3532 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3533 default: abort();
3534 }
3535 }
3536
3537 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3538 {
3539 switch (size) {
3540 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3541 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3542 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3543 default: abort();
3544 }
3545 }
3546
3547 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3548 {
3549 switch (size) {
3550 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3551 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3552 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3553 default: abort();
3554 }
3555 }
3556
3557 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3558 int q, int u)
3559 {
3560 if (q) {
3561 if (u) {
3562 switch (size) {
3563 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3564 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3565 default: abort();
3566 }
3567 } else {
3568 switch (size) {
3569 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3570 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3571 default: abort();
3572 }
3573 }
3574 } else {
3575 if (u) {
3576 switch (size) {
3577 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3578 case 2: gen_ushl_i32(var, var, shift); break;
3579 default: abort();
3580 }
3581 } else {
3582 switch (size) {
3583 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3584 case 2: gen_sshl_i32(var, var, shift); break;
3585 default: abort();
3586 }
3587 }
3588 }
3589 }
3590
3591 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3592 {
3593 if (u) {
3594 switch (size) {
3595 case 0: gen_helper_neon_widen_u8(dest, src); break;
3596 case 1: gen_helper_neon_widen_u16(dest, src); break;
3597 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3598 default: abort();
3599 }
3600 } else {
3601 switch (size) {
3602 case 0: gen_helper_neon_widen_s8(dest, src); break;
3603 case 1: gen_helper_neon_widen_s16(dest, src); break;
3604 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3605 default: abort();
3606 }
3607 }
3608 tcg_temp_free_i32(src);
3609 }
3610
3611 static inline void gen_neon_addl(int size)
3612 {
3613 switch (size) {
3614 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3615 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3616 case 2: tcg_gen_add_i64(CPU_V001); break;
3617 default: abort();
3618 }
3619 }
3620
3621 static inline void gen_neon_subl(int size)
3622 {
3623 switch (size) {
3624 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3625 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3626 case 2: tcg_gen_sub_i64(CPU_V001); break;
3627 default: abort();
3628 }
3629 }
3630
3631 static inline void gen_neon_negl(TCGv_i64 var, int size)
3632 {
3633 switch (size) {
3634 case 0: gen_helper_neon_negl_u16(var, var); break;
3635 case 1: gen_helper_neon_negl_u32(var, var); break;
3636 case 2:
3637 tcg_gen_neg_i64(var, var);
3638 break;
3639 default: abort();
3640 }
3641 }
3642
3643 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3644 {
3645 switch (size) {
3646 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3647 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3648 default: abort();
3649 }
3650 }
3651
3652 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3653 int size, int u)
3654 {
3655 TCGv_i64 tmp;
3656
3657 switch ((size << 1) | u) {
3658 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3659 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3660 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3661 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3662 case 4:
3663 tmp = gen_muls_i64_i32(a, b);
3664 tcg_gen_mov_i64(dest, tmp);
3665 tcg_temp_free_i64(tmp);
3666 break;
3667 case 5:
3668 tmp = gen_mulu_i64_i32(a, b);
3669 tcg_gen_mov_i64(dest, tmp);
3670 tcg_temp_free_i64(tmp);
3671 break;
3672 default: abort();
3673 }
3674
3675 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3676 Don't forget to clean them now. */
3677 if (size < 2) {
3678 tcg_temp_free_i32(a);
3679 tcg_temp_free_i32(b);
3680 }
3681 }
3682
3683 static void gen_neon_narrow_op(int op, int u, int size,
3684 TCGv_i32 dest, TCGv_i64 src)
3685 {
3686 if (op) {
3687 if (u) {
3688 gen_neon_unarrow_sats(size, dest, src);
3689 } else {
3690 gen_neon_narrow(size, dest, src);
3691 }
3692 } else {
3693 if (u) {
3694 gen_neon_narrow_satu(size, dest, src);
3695 } else {
3696 gen_neon_narrow_sats(size, dest, src);
3697 }
3698 }
3699 }
3700
3701 /* Symbolic constants for op fields for Neon 3-register same-length.
3702 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3703 * table A7-9.
3704 */
3705 #define NEON_3R_VHADD 0
3706 #define NEON_3R_VQADD 1
3707 #define NEON_3R_VRHADD 2
3708 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3709 #define NEON_3R_VHSUB 4
3710 #define NEON_3R_VQSUB 5
3711 #define NEON_3R_VCGT 6
3712 #define NEON_3R_VCGE 7
3713 #define NEON_3R_VSHL 8
3714 #define NEON_3R_VQSHL 9
3715 #define NEON_3R_VRSHL 10
3716 #define NEON_3R_VQRSHL 11
3717 #define NEON_3R_VMAX 12
3718 #define NEON_3R_VMIN 13
3719 #define NEON_3R_VABD 14
3720 #define NEON_3R_VABA 15
3721 #define NEON_3R_VADD_VSUB 16
3722 #define NEON_3R_VTST_VCEQ 17
3723 #define NEON_3R_VML 18 /* VMLA, VMLS */
3724 #define NEON_3R_VMUL 19
3725 #define NEON_3R_VPMAX 20
3726 #define NEON_3R_VPMIN 21
3727 #define NEON_3R_VQDMULH_VQRDMULH 22
3728 #define NEON_3R_VPADD_VQRDMLAH 23
3729 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3730 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3731 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3732 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3733 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3734 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3735 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3736 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3737
3738 static const uint8_t neon_3r_sizes[] = {
3739 [NEON_3R_VHADD] = 0x7,
3740 [NEON_3R_VQADD] = 0xf,
3741 [NEON_3R_VRHADD] = 0x7,
3742 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3743 [NEON_3R_VHSUB] = 0x7,
3744 [NEON_3R_VQSUB] = 0xf,
3745 [NEON_3R_VCGT] = 0x7,
3746 [NEON_3R_VCGE] = 0x7,
3747 [NEON_3R_VSHL] = 0xf,
3748 [NEON_3R_VQSHL] = 0xf,
3749 [NEON_3R_VRSHL] = 0xf,
3750 [NEON_3R_VQRSHL] = 0xf,
3751 [NEON_3R_VMAX] = 0x7,
3752 [NEON_3R_VMIN] = 0x7,
3753 [NEON_3R_VABD] = 0x7,
3754 [NEON_3R_VABA] = 0x7,
3755 [NEON_3R_VADD_VSUB] = 0xf,
3756 [NEON_3R_VTST_VCEQ] = 0x7,
3757 [NEON_3R_VML] = 0x7,
3758 [NEON_3R_VMUL] = 0x7,
3759 [NEON_3R_VPMAX] = 0x7,
3760 [NEON_3R_VPMIN] = 0x7,
3761 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
3762 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
3763 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
3764 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
3765 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
3766 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
3767 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
3768 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
3769 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
3770 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
3771 };
3772
3773 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3774 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3775 * table A7-13.
3776 */
3777 #define NEON_2RM_VREV64 0
3778 #define NEON_2RM_VREV32 1
3779 #define NEON_2RM_VREV16 2
3780 #define NEON_2RM_VPADDL 4
3781 #define NEON_2RM_VPADDL_U 5
3782 #define NEON_2RM_AESE 6 /* Includes AESD */
3783 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3784 #define NEON_2RM_VCLS 8
3785 #define NEON_2RM_VCLZ 9
3786 #define NEON_2RM_VCNT 10
3787 #define NEON_2RM_VMVN 11
3788 #define NEON_2RM_VPADAL 12
3789 #define NEON_2RM_VPADAL_U 13
3790 #define NEON_2RM_VQABS 14
3791 #define NEON_2RM_VQNEG 15
3792 #define NEON_2RM_VCGT0 16
3793 #define NEON_2RM_VCGE0 17
3794 #define NEON_2RM_VCEQ0 18
3795 #define NEON_2RM_VCLE0 19
3796 #define NEON_2RM_VCLT0 20
3797 #define NEON_2RM_SHA1H 21
3798 #define NEON_2RM_VABS 22
3799 #define NEON_2RM_VNEG 23
3800 #define NEON_2RM_VCGT0_F 24
3801 #define NEON_2RM_VCGE0_F 25
3802 #define NEON_2RM_VCEQ0_F 26
3803 #define NEON_2RM_VCLE0_F 27
3804 #define NEON_2RM_VCLT0_F 28
3805 #define NEON_2RM_VABS_F 30
3806 #define NEON_2RM_VNEG_F 31
3807 #define NEON_2RM_VSWP 32
3808 #define NEON_2RM_VTRN 33
3809 #define NEON_2RM_VUZP 34
3810 #define NEON_2RM_VZIP 35
3811 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3812 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3813 #define NEON_2RM_VSHLL 38
3814 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3815 #define NEON_2RM_VRINTN 40
3816 #define NEON_2RM_VRINTX 41
3817 #define NEON_2RM_VRINTA 42
3818 #define NEON_2RM_VRINTZ 43
3819 #define NEON_2RM_VCVT_F16_F32 44
3820 #define NEON_2RM_VRINTM 45
3821 #define NEON_2RM_VCVT_F32_F16 46
3822 #define NEON_2RM_VRINTP 47
3823 #define NEON_2RM_VCVTAU 48
3824 #define NEON_2RM_VCVTAS 49
3825 #define NEON_2RM_VCVTNU 50
3826 #define NEON_2RM_VCVTNS 51
3827 #define NEON_2RM_VCVTPU 52
3828 #define NEON_2RM_VCVTPS 53
3829 #define NEON_2RM_VCVTMU 54
3830 #define NEON_2RM_VCVTMS 55
3831 #define NEON_2RM_VRECPE 56
3832 #define NEON_2RM_VRSQRTE 57
3833 #define NEON_2RM_VRECPE_F 58
3834 #define NEON_2RM_VRSQRTE_F 59
3835 #define NEON_2RM_VCVT_FS 60
3836 #define NEON_2RM_VCVT_FU 61
3837 #define NEON_2RM_VCVT_SF 62
3838 #define NEON_2RM_VCVT_UF 63
3839
3840 static bool neon_2rm_is_v8_op(int op)
3841 {
3842 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3843 switch (op) {
3844 case NEON_2RM_VRINTN:
3845 case NEON_2RM_VRINTA:
3846 case NEON_2RM_VRINTM:
3847 case NEON_2RM_VRINTP:
3848 case NEON_2RM_VRINTZ:
3849 case NEON_2RM_VRINTX:
3850 case NEON_2RM_VCVTAU:
3851 case NEON_2RM_VCVTAS:
3852 case NEON_2RM_VCVTNU:
3853 case NEON_2RM_VCVTNS:
3854 case NEON_2RM_VCVTPU:
3855 case NEON_2RM_VCVTPS:
3856 case NEON_2RM_VCVTMU:
3857 case NEON_2RM_VCVTMS:
3858 return true;
3859 default:
3860 return false;
3861 }
3862 }
3863
3864 /* Each entry in this array has bit n set if the insn allows
3865 * size value n (otherwise it will UNDEF). Since unallocated
3866 * op values will have no bits set they always UNDEF.
3867 */
3868 static const uint8_t neon_2rm_sizes[] = {
3869 [NEON_2RM_VREV64] = 0x7,
3870 [NEON_2RM_VREV32] = 0x3,
3871 [NEON_2RM_VREV16] = 0x1,
3872 [NEON_2RM_VPADDL] = 0x7,
3873 [NEON_2RM_VPADDL_U] = 0x7,
3874 [NEON_2RM_AESE] = 0x1,
3875 [NEON_2RM_AESMC] = 0x1,
3876 [NEON_2RM_VCLS] = 0x7,
3877 [NEON_2RM_VCLZ] = 0x7,
3878 [NEON_2RM_VCNT] = 0x1,
3879 [NEON_2RM_VMVN] = 0x1,
3880 [NEON_2RM_VPADAL] = 0x7,
3881 [NEON_2RM_VPADAL_U] = 0x7,
3882 [NEON_2RM_VQABS] = 0x7,
3883 [NEON_2RM_VQNEG] = 0x7,
3884 [NEON_2RM_VCGT0] = 0x7,
3885 [NEON_2RM_VCGE0] = 0x7,
3886 [NEON_2RM_VCEQ0] = 0x7,
3887 [NEON_2RM_VCLE0] = 0x7,
3888 [NEON_2RM_VCLT0] = 0x7,
3889 [NEON_2RM_SHA1H] = 0x4,
3890 [NEON_2RM_VABS] = 0x7,
3891 [NEON_2RM_VNEG] = 0x7,
3892 [NEON_2RM_VCGT0_F] = 0x4,
3893 [NEON_2RM_VCGE0_F] = 0x4,
3894 [NEON_2RM_VCEQ0_F] = 0x4,
3895 [NEON_2RM_VCLE0_F] = 0x4,
3896 [NEON_2RM_VCLT0_F] = 0x4,
3897 [NEON_2RM_VABS_F] = 0x4,
3898 [NEON_2RM_VNEG_F] = 0x4,
3899 [NEON_2RM_VSWP] = 0x1,
3900 [NEON_2RM_VTRN] = 0x7,
3901 [NEON_2RM_VUZP] = 0x7,
3902 [NEON_2RM_VZIP] = 0x7,
3903 [NEON_2RM_VMOVN] = 0x7,
3904 [NEON_2RM_VQMOVN] = 0x7,
3905 [NEON_2RM_VSHLL] = 0x7,
3906 [NEON_2RM_SHA1SU1] = 0x4,
3907 [NEON_2RM_VRINTN] = 0x4,
3908 [NEON_2RM_VRINTX] = 0x4,
3909 [NEON_2RM_VRINTA] = 0x4,
3910 [NEON_2RM_VRINTZ] = 0x4,
3911 [NEON_2RM_VCVT_F16_F32] = 0x2,
3912 [NEON_2RM_VRINTM] = 0x4,
3913 [NEON_2RM_VCVT_F32_F16] = 0x2,
3914 [NEON_2RM_VRINTP] = 0x4,
3915 [NEON_2RM_VCVTAU] = 0x4,
3916 [NEON_2RM_VCVTAS] = 0x4,
3917 [NEON_2RM_VCVTNU] = 0x4,
3918 [NEON_2RM_VCVTNS] = 0x4,
3919 [NEON_2RM_VCVTPU] = 0x4,
3920 [NEON_2RM_VCVTPS] = 0x4,
3921 [NEON_2RM_VCVTMU] = 0x4,
3922 [NEON_2RM_VCVTMS] = 0x4,
3923 [NEON_2RM_VRECPE] = 0x4,
3924 [NEON_2RM_VRSQRTE] = 0x4,
3925 [NEON_2RM_VRECPE_F] = 0x4,
3926 [NEON_2RM_VRSQRTE_F] = 0x4,
3927 [NEON_2RM_VCVT_FS] = 0x4,
3928 [NEON_2RM_VCVT_FU] = 0x4,
3929 [NEON_2RM_VCVT_SF] = 0x4,
3930 [NEON_2RM_VCVT_UF] = 0x4,
3931 };
3932
3933
3934 /* Expand v8.1 simd helper. */
3935 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
3936 int q, int rd, int rn, int rm)
3937 {
3938 if (dc_isar_feature(aa32_rdm, s)) {
3939 int opr_sz = (1 + q) * 8;
3940 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
3941 vfp_reg_offset(1, rn),
3942 vfp_reg_offset(1, rm), cpu_env,
3943 opr_sz, opr_sz, 0, fn);
3944 return 0;
3945 }
3946 return 1;
3947 }
3948
3949 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3950 {
3951 tcg_gen_vec_sar8i_i64(a, a, shift);
3952 tcg_gen_vec_add8_i64(d, d, a);
3953 }
3954
3955 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3956 {
3957 tcg_gen_vec_sar16i_i64(a, a, shift);
3958 tcg_gen_vec_add16_i64(d, d, a);
3959 }
3960
3961 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3962 {
3963 tcg_gen_sari_i32(a, a, shift);
3964 tcg_gen_add_i32(d, d, a);
3965 }
3966
3967 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3968 {
3969 tcg_gen_sari_i64(a, a, shift);
3970 tcg_gen_add_i64(d, d, a);
3971 }
3972
3973 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3974 {
3975 tcg_gen_sari_vec(vece, a, a, sh);
3976 tcg_gen_add_vec(vece, d, d, a);
3977 }
3978
3979 static const TCGOpcode vecop_list_ssra[] = {
3980 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3981 };
3982
3983 const GVecGen2i ssra_op[4] = {
3984 { .fni8 = gen_ssra8_i64,
3985 .fniv = gen_ssra_vec,
3986 .load_dest = true,
3987 .opt_opc = vecop_list_ssra,
3988 .vece = MO_8 },
3989 { .fni8 = gen_ssra16_i64,
3990 .fniv = gen_ssra_vec,
3991 .load_dest = true,
3992 .opt_opc = vecop_list_ssra,
3993 .vece = MO_16 },
3994 { .fni4 = gen_ssra32_i32,
3995 .fniv = gen_ssra_vec,
3996 .load_dest = true,
3997 .opt_opc = vecop_list_ssra,
3998 .vece = MO_32 },
3999 { .fni8 = gen_ssra64_i64,
4000 .fniv = gen_ssra_vec,
4001 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4002 .opt_opc = vecop_list_ssra,
4003 .load_dest = true,
4004 .vece = MO_64 },
4005 };
4006
4007 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4008 {
4009 tcg_gen_vec_shr8i_i64(a, a, shift);
4010 tcg_gen_vec_add8_i64(d, d, a);
4011 }
4012
4013 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4014 {
4015 tcg_gen_vec_shr16i_i64(a, a, shift);
4016 tcg_gen_vec_add16_i64(d, d, a);
4017 }
4018
4019 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4020 {
4021 tcg_gen_shri_i32(a, a, shift);
4022 tcg_gen_add_i32(d, d, a);
4023 }
4024
4025 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4026 {
4027 tcg_gen_shri_i64(a, a, shift);
4028 tcg_gen_add_i64(d, d, a);
4029 }
4030
4031 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4032 {
4033 tcg_gen_shri_vec(vece, a, a, sh);
4034 tcg_gen_add_vec(vece, d, d, a);
4035 }
4036
4037 static const TCGOpcode vecop_list_usra[] = {
4038 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4039 };
4040
4041 const GVecGen2i usra_op[4] = {
4042 { .fni8 = gen_usra8_i64,
4043 .fniv = gen_usra_vec,
4044 .load_dest = true,
4045 .opt_opc = vecop_list_usra,
4046 .vece = MO_8, },
4047 { .fni8 = gen_usra16_i64,
4048 .fniv = gen_usra_vec,
4049 .load_dest = true,
4050 .opt_opc = vecop_list_usra,
4051 .vece = MO_16, },
4052 { .fni4 = gen_usra32_i32,
4053 .fniv = gen_usra_vec,
4054 .load_dest = true,
4055 .opt_opc = vecop_list_usra,
4056 .vece = MO_32, },
4057 { .fni8 = gen_usra64_i64,
4058 .fniv = gen_usra_vec,
4059 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4060 .load_dest = true,
4061 .opt_opc = vecop_list_usra,
4062 .vece = MO_64, },
4063 };
4064
4065 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4066 {
4067 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4068 TCGv_i64 t = tcg_temp_new_i64();
4069
4070 tcg_gen_shri_i64(t, a, shift);
4071 tcg_gen_andi_i64(t, t, mask);
4072 tcg_gen_andi_i64(d, d, ~mask);
4073 tcg_gen_or_i64(d, d, t);
4074 tcg_temp_free_i64(t);
4075 }
4076
4077 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4078 {
4079 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4080 TCGv_i64 t = tcg_temp_new_i64();
4081
4082 tcg_gen_shri_i64(t, a, shift);
4083 tcg_gen_andi_i64(t, t, mask);
4084 tcg_gen_andi_i64(d, d, ~mask);
4085 tcg_gen_or_i64(d, d, t);
4086 tcg_temp_free_i64(t);
4087 }
4088
4089 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4090 {
4091 tcg_gen_shri_i32(a, a, shift);
4092 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4093 }
4094
4095 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4096 {
4097 tcg_gen_shri_i64(a, a, shift);
4098 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4099 }
4100
4101 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4102 {
4103 if (sh == 0) {
4104 tcg_gen_mov_vec(d, a);
4105 } else {
4106 TCGv_vec t = tcg_temp_new_vec_matching(d);
4107 TCGv_vec m = tcg_temp_new_vec_matching(d);
4108
4109 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4110 tcg_gen_shri_vec(vece, t, a, sh);
4111 tcg_gen_and_vec(vece, d, d, m);
4112 tcg_gen_or_vec(vece, d, d, t);
4113
4114 tcg_temp_free_vec(t);
4115 tcg_temp_free_vec(m);
4116 }
4117 }
4118
4119 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4120
4121 const GVecGen2i sri_op[4] = {
4122 { .fni8 = gen_shr8_ins_i64,
4123 .fniv = gen_shr_ins_vec,
4124 .load_dest = true,
4125 .opt_opc = vecop_list_sri,
4126 .vece = MO_8 },
4127 { .fni8 = gen_shr16_ins_i64,
4128 .fniv = gen_shr_ins_vec,
4129 .load_dest = true,
4130 .opt_opc = vecop_list_sri,
4131 .vece = MO_16 },
4132 { .fni4 = gen_shr32_ins_i32,
4133 .fniv = gen_shr_ins_vec,
4134 .load_dest = true,
4135 .opt_opc = vecop_list_sri,
4136 .vece = MO_32 },
4137 { .fni8 = gen_shr64_ins_i64,
4138 .fniv = gen_shr_ins_vec,
4139 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4140 .load_dest = true,
4141 .opt_opc = vecop_list_sri,
4142 .vece = MO_64 },
4143 };
4144
4145 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4146 {
4147 uint64_t mask = dup_const(MO_8, 0xff << shift);
4148 TCGv_i64 t = tcg_temp_new_i64();
4149
4150 tcg_gen_shli_i64(t, a, shift);
4151 tcg_gen_andi_i64(t, t, mask);
4152 tcg_gen_andi_i64(d, d, ~mask);
4153 tcg_gen_or_i64(d, d, t);
4154 tcg_temp_free_i64(t);
4155 }
4156
4157 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4158 {
4159 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4160 TCGv_i64 t = tcg_temp_new_i64();
4161
4162 tcg_gen_shli_i64(t, a, shift);
4163 tcg_gen_andi_i64(t, t, mask);
4164 tcg_gen_andi_i64(d, d, ~mask);
4165 tcg_gen_or_i64(d, d, t);
4166 tcg_temp_free_i64(t);
4167 }
4168
4169 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4170 {
4171 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4172 }
4173
4174 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4175 {
4176 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4177 }
4178
4179 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4180 {
4181 if (sh == 0) {
4182 tcg_gen_mov_vec(d, a);
4183 } else {
4184 TCGv_vec t = tcg_temp_new_vec_matching(d);
4185 TCGv_vec m = tcg_temp_new_vec_matching(d);
4186
4187 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4188 tcg_gen_shli_vec(vece, t, a, sh);
4189 tcg_gen_and_vec(vece, d, d, m);
4190 tcg_gen_or_vec(vece, d, d, t);
4191
4192 tcg_temp_free_vec(t);
4193 tcg_temp_free_vec(m);
4194 }
4195 }
4196
4197 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4198
4199 const GVecGen2i sli_op[4] = {
4200 { .fni8 = gen_shl8_ins_i64,
4201 .fniv = gen_shl_ins_vec,
4202 .load_dest = true,
4203 .opt_opc = vecop_list_sli,
4204 .vece = MO_8 },
4205 { .fni8 = gen_shl16_ins_i64,
4206 .fniv = gen_shl_ins_vec,
4207 .load_dest = true,
4208 .opt_opc = vecop_list_sli,
4209 .vece = MO_16 },
4210 { .fni4 = gen_shl32_ins_i32,
4211 .fniv = gen_shl_ins_vec,
4212 .load_dest = true,
4213 .opt_opc = vecop_list_sli,
4214 .vece = MO_32 },
4215 { .fni8 = gen_shl64_ins_i64,
4216 .fniv = gen_shl_ins_vec,
4217 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4218 .load_dest = true,
4219 .opt_opc = vecop_list_sli,
4220 .vece = MO_64 },
4221 };
4222
4223 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4224 {
4225 gen_helper_neon_mul_u8(a, a, b);
4226 gen_helper_neon_add_u8(d, d, a);
4227 }
4228
4229 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4230 {
4231 gen_helper_neon_mul_u8(a, a, b);
4232 gen_helper_neon_sub_u8(d, d, a);
4233 }
4234
4235 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4236 {
4237 gen_helper_neon_mul_u16(a, a, b);
4238 gen_helper_neon_add_u16(d, d, a);
4239 }
4240
4241 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4242 {
4243 gen_helper_neon_mul_u16(a, a, b);
4244 gen_helper_neon_sub_u16(d, d, a);
4245 }
4246
4247 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4248 {
4249 tcg_gen_mul_i32(a, a, b);
4250 tcg_gen_add_i32(d, d, a);
4251 }
4252
4253 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4254 {
4255 tcg_gen_mul_i32(a, a, b);
4256 tcg_gen_sub_i32(d, d, a);
4257 }
4258
4259 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4260 {
4261 tcg_gen_mul_i64(a, a, b);
4262 tcg_gen_add_i64(d, d, a);
4263 }
4264
4265 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4266 {
4267 tcg_gen_mul_i64(a, a, b);
4268 tcg_gen_sub_i64(d, d, a);
4269 }
4270
4271 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4272 {
4273 tcg_gen_mul_vec(vece, a, a, b);
4274 tcg_gen_add_vec(vece, d, d, a);
4275 }
4276
4277 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4278 {
4279 tcg_gen_mul_vec(vece, a, a, b);
4280 tcg_gen_sub_vec(vece, d, d, a);
4281 }
4282
4283 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4284 * these tables are shared with AArch64 which does support them.
4285 */
4286
4287 static const TCGOpcode vecop_list_mla[] = {
4288 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4289 };
4290
4291 static const TCGOpcode vecop_list_mls[] = {
4292 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4293 };
4294
4295 const GVecGen3 mla_op[4] = {
4296 { .fni4 = gen_mla8_i32,
4297 .fniv = gen_mla_vec,
4298 .load_dest = true,
4299 .opt_opc = vecop_list_mla,
4300 .vece = MO_8 },
4301 { .fni4 = gen_mla16_i32,
4302 .fniv = gen_mla_vec,
4303 .load_dest = true,
4304 .opt_opc = vecop_list_mla,
4305 .vece = MO_16 },
4306 { .fni4 = gen_mla32_i32,
4307 .fniv = gen_mla_vec,
4308 .load_dest = true,
4309 .opt_opc = vecop_list_mla,
4310 .vece = MO_32 },
4311 { .fni8 = gen_mla64_i64,
4312 .fniv = gen_mla_vec,
4313 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4314 .load_dest = true,
4315 .opt_opc = vecop_list_mla,
4316 .vece = MO_64 },
4317 };
4318
4319 const GVecGen3 mls_op[4] = {
4320 { .fni4 = gen_mls8_i32,
4321 .fniv = gen_mls_vec,
4322 .load_dest = true,
4323 .opt_opc = vecop_list_mls,
4324 .vece = MO_8 },
4325 { .fni4 = gen_mls16_i32,
4326 .fniv = gen_mls_vec,
4327 .load_dest = true,
4328 .opt_opc = vecop_list_mls,
4329 .vece = MO_16 },
4330 { .fni4 = gen_mls32_i32,
4331 .fniv = gen_mls_vec,
4332 .load_dest = true,
4333 .opt_opc = vecop_list_mls,
4334 .vece = MO_32 },
4335 { .fni8 = gen_mls64_i64,
4336 .fniv = gen_mls_vec,
4337 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4338 .load_dest = true,
4339 .opt_opc = vecop_list_mls,
4340 .vece = MO_64 },
4341 };
4342
4343 /* CMTST : test is "if (X & Y != 0)". */
4344 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4345 {
4346 tcg_gen_and_i32(d, a, b);
4347 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4348 tcg_gen_neg_i32(d, d);
4349 }
4350
4351 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4352 {
4353 tcg_gen_and_i64(d, a, b);
4354 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4355 tcg_gen_neg_i64(d, d);
4356 }
4357
4358 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4359 {
4360 tcg_gen_and_vec(vece, d, a, b);
4361 tcg_gen_dupi_vec(vece, a, 0);
4362 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4363 }
4364
4365 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4366
4367 const GVecGen3 cmtst_op[4] = {
4368 { .fni4 = gen_helper_neon_tst_u8,
4369 .fniv = gen_cmtst_vec,
4370 .opt_opc = vecop_list_cmtst,
4371 .vece = MO_8 },
4372 { .fni4 = gen_helper_neon_tst_u16,
4373 .fniv = gen_cmtst_vec,
4374 .opt_opc = vecop_list_cmtst,
4375 .vece = MO_16 },
4376 { .fni4 = gen_cmtst_i32,
4377 .fniv = gen_cmtst_vec,
4378 .opt_opc = vecop_list_cmtst,
4379 .vece = MO_32 },
4380 { .fni8 = gen_cmtst_i64,
4381 .fniv = gen_cmtst_vec,
4382 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4383 .opt_opc = vecop_list_cmtst,
4384 .vece = MO_64 },
4385 };
4386
4387 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4388 {
4389 TCGv_i32 lval = tcg_temp_new_i32();
4390 TCGv_i32 rval = tcg_temp_new_i32();
4391 TCGv_i32 lsh = tcg_temp_new_i32();
4392 TCGv_i32 rsh = tcg_temp_new_i32();
4393 TCGv_i32 zero = tcg_const_i32(0);
4394 TCGv_i32 max = tcg_const_i32(32);
4395
4396 /*
4397 * Rely on the TCG guarantee that out of range shifts produce
4398 * unspecified results, not undefined behaviour (i.e. no trap).
4399 * Discard out-of-range results after the fact.
4400 */
4401 tcg_gen_ext8s_i32(lsh, shift);
4402 tcg_gen_neg_i32(rsh, lsh);
4403 tcg_gen_shl_i32(lval, src, lsh);
4404 tcg_gen_shr_i32(rval, src, rsh);
4405 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4406 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4407
4408 tcg_temp_free_i32(lval);
4409 tcg_temp_free_i32(rval);
4410 tcg_temp_free_i32(lsh);
4411 tcg_temp_free_i32(rsh);
4412 tcg_temp_free_i32(zero);
4413 tcg_temp_free_i32(max);
4414 }
4415
4416 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4417 {
4418 TCGv_i64 lval = tcg_temp_new_i64();
4419 TCGv_i64 rval = tcg_temp_new_i64();
4420 TCGv_i64 lsh = tcg_temp_new_i64();
4421 TCGv_i64 rsh = tcg_temp_new_i64();
4422 TCGv_i64 zero = tcg_const_i64(0);
4423 TCGv_i64 max = tcg_const_i64(64);
4424
4425 /*
4426 * Rely on the TCG guarantee that out of range shifts produce
4427 * unspecified results, not undefined behaviour (i.e. no trap).
4428 * Discard out-of-range results after the fact.
4429 */
4430 tcg_gen_ext8s_i64(lsh, shift);
4431 tcg_gen_neg_i64(rsh, lsh);
4432 tcg_gen_shl_i64(lval, src, lsh);
4433 tcg_gen_shr_i64(rval, src, rsh);
4434 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4435 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4436
4437 tcg_temp_free_i64(lval);
4438 tcg_temp_free_i64(rval);
4439 tcg_temp_free_i64(lsh);
4440 tcg_temp_free_i64(rsh);
4441 tcg_temp_free_i64(zero);
4442 tcg_temp_free_i64(max);
4443 }
4444
4445 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4446 TCGv_vec src, TCGv_vec shift)
4447 {
4448 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4449 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4450 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4451 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4452 TCGv_vec msk, max;
4453
4454 tcg_gen_neg_vec(vece, rsh, shift);
4455 if (vece == MO_8) {
4456 tcg_gen_mov_vec(lsh, shift);
4457 } else {
4458 msk = tcg_temp_new_vec_matching(dst);
4459 tcg_gen_dupi_vec(vece, msk, 0xff);
4460 tcg_gen_and_vec(vece, lsh, shift, msk);
4461 tcg_gen_and_vec(vece, rsh, rsh, msk);
4462 tcg_temp_free_vec(msk);
4463 }
4464
4465 /*
4466 * Rely on the TCG guarantee that out of range shifts produce
4467 * unspecified results, not undefined behaviour (i.e. no trap).
4468 * Discard out-of-range results after the fact.
4469 */
4470 tcg_gen_shlv_vec(vece, lval, src, lsh);
4471 tcg_gen_shrv_vec(vece, rval, src, rsh);
4472
4473 max = tcg_temp_new_vec_matching(dst);
4474 tcg_gen_dupi_vec(vece, max, 8 << vece);
4475
4476 /*
4477 * The choice of LT (signed) and GEU (unsigned) are biased toward
4478 * the instructions of the x86_64 host. For MO_8, the whole byte
4479 * is significant so we must use an unsigned compare; otherwise we
4480 * have already masked to a byte and so a signed compare works.
4481 * Other tcg hosts have a full set of comparisons and do not care.
4482 */
4483 if (vece == MO_8) {
4484 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4485 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4486 tcg_gen_andc_vec(vece, lval, lval, lsh);
4487 tcg_gen_andc_vec(vece, rval, rval, rsh);
4488 } else {
4489 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4490 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4491 tcg_gen_and_vec(vece, lval, lval, lsh);
4492 tcg_gen_and_vec(vece, rval, rval, rsh);
4493 }
4494 tcg_gen_or_vec(vece, dst, lval, rval);
4495
4496 tcg_temp_free_vec(max);
4497 tcg_temp_free_vec(lval);
4498 tcg_temp_free_vec(rval);
4499 tcg_temp_free_vec(lsh);
4500 tcg_temp_free_vec(rsh);
4501 }
4502
4503 static const TCGOpcode ushl_list[] = {
4504 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4505 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4506 };
4507
4508 const GVecGen3 ushl_op[4] = {
4509 { .fniv = gen_ushl_vec,
4510 .fno = gen_helper_gvec_ushl_b,
4511 .opt_opc = ushl_list,
4512 .vece = MO_8 },
4513 { .fniv = gen_ushl_vec,
4514 .fno = gen_helper_gvec_ushl_h,
4515 .opt_opc = ushl_list,
4516 .vece = MO_16 },
4517 { .fni4 = gen_ushl_i32,
4518 .fniv = gen_ushl_vec,
4519 .opt_opc = ushl_list,
4520 .vece = MO_32 },
4521 { .fni8 = gen_ushl_i64,
4522 .fniv = gen_ushl_vec,
4523 .opt_opc = ushl_list,
4524 .vece = MO_64 },
4525 };
4526
4527 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4528 {
4529 TCGv_i32 lval = tcg_temp_new_i32();
4530 TCGv_i32 rval = tcg_temp_new_i32();
4531 TCGv_i32 lsh = tcg_temp_new_i32();
4532 TCGv_i32 rsh = tcg_temp_new_i32();
4533 TCGv_i32 zero = tcg_const_i32(0);
4534 TCGv_i32 max = tcg_const_i32(31);
4535
4536 /*
4537 * Rely on the TCG guarantee that out of range shifts produce
4538 * unspecified results, not undefined behaviour (i.e. no trap).
4539 * Discard out-of-range results after the fact.
4540 */
4541 tcg_gen_ext8s_i32(lsh, shift);
4542 tcg_gen_neg_i32(rsh, lsh);
4543 tcg_gen_shl_i32(lval, src, lsh);
4544 tcg_gen_umin_i32(rsh, rsh, max);
4545 tcg_gen_sar_i32(rval, src, rsh);
4546 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4547 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4548
4549 tcg_temp_free_i32(lval);
4550 tcg_temp_free_i32(rval);
4551 tcg_temp_free_i32(lsh);
4552 tcg_temp_free_i32(rsh);
4553 tcg_temp_free_i32(zero);
4554 tcg_temp_free_i32(max);
4555 }
4556
4557 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4558 {
4559 TCGv_i64 lval = tcg_temp_new_i64();
4560 TCGv_i64 rval = tcg_temp_new_i64();
4561 TCGv_i64 lsh = tcg_temp_new_i64();
4562 TCGv_i64 rsh = tcg_temp_new_i64();
4563 TCGv_i64 zero = tcg_const_i64(0);
4564 TCGv_i64 max = tcg_const_i64(63);
4565
4566 /*
4567 * Rely on the TCG guarantee that out of range shifts produce
4568 * unspecified results, not undefined behaviour (i.e. no trap).
4569 * Discard out-of-range results after the fact.
4570 */
4571 tcg_gen_ext8s_i64(lsh, shift);
4572 tcg_gen_neg_i64(rsh, lsh);
4573 tcg_gen_shl_i64(lval, src, lsh);
4574 tcg_gen_umin_i64(rsh, rsh, max);
4575 tcg_gen_sar_i64(rval, src, rsh);
4576 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4577 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4578
4579 tcg_temp_free_i64(lval);
4580 tcg_temp_free_i64(rval);
4581 tcg_temp_free_i64(lsh);
4582 tcg_temp_free_i64(rsh);
4583 tcg_temp_free_i64(zero);
4584 tcg_temp_free_i64(max);
4585 }
4586
4587 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4588 TCGv_vec src, TCGv_vec shift)
4589 {
4590 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4591 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4592 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4593 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4594 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4595
4596 /*
4597 * Rely on the TCG guarantee that out of range shifts produce
4598 * unspecified results, not undefined behaviour (i.e. no trap).
4599 * Discard out-of-range results after the fact.
4600 */
4601 tcg_gen_neg_vec(vece, rsh, shift);
4602 if (vece == MO_8) {
4603 tcg_gen_mov_vec(lsh, shift);
4604 } else {
4605 tcg_gen_dupi_vec(vece, tmp, 0xff);
4606 tcg_gen_and_vec(vece, lsh, shift, tmp);
4607 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4608 }
4609
4610 /* Bound rsh so out of bound right shift gets -1. */
4611 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4612 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4613 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4614
4615 tcg_gen_shlv_vec(vece, lval, src, lsh);
4616 tcg_gen_sarv_vec(vece, rval, src, rsh);
4617
4618 /* Select in-bound left shift. */
4619 tcg_gen_andc_vec(vece, lval, lval, tmp);
4620
4621 /* Select between left and right shift. */
4622 if (vece == MO_8) {
4623 tcg_gen_dupi_vec(vece, tmp, 0);
4624 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4625 } else {
4626 tcg_gen_dupi_vec(vece, tmp, 0x80);
4627 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4628 }
4629
4630 tcg_temp_free_vec(lval);
4631 tcg_temp_free_vec(rval);
4632 tcg_temp_free_vec(lsh);
4633 tcg_temp_free_vec(rsh);
4634 tcg_temp_free_vec(tmp);
4635 }
4636
4637 static const TCGOpcode sshl_list[] = {
4638 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4639 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4640 };
4641
4642 const GVecGen3 sshl_op[4] = {
4643 { .fniv = gen_sshl_vec,
4644 .fno = gen_helper_gvec_sshl_b,
4645 .opt_opc = sshl_list,
4646 .vece = MO_8 },
4647 { .fniv = gen_sshl_vec,
4648 .fno = gen_helper_gvec_sshl_h,
4649 .opt_opc = sshl_list,
4650 .vece = MO_16 },
4651 { .fni4 = gen_sshl_i32,
4652 .fniv = gen_sshl_vec,
4653 .opt_opc = sshl_list,
4654 .vece = MO_32 },
4655 { .fni8 = gen_sshl_i64,
4656 .fniv = gen_sshl_vec,
4657 .opt_opc = sshl_list,
4658 .vece = MO_64 },
4659 };
4660
4661 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4662 TCGv_vec a, TCGv_vec b)
4663 {
4664 TCGv_vec x = tcg_temp_new_vec_matching(t);
4665 tcg_gen_add_vec(vece, x, a, b);
4666 tcg_gen_usadd_vec(vece, t, a, b);
4667 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4668 tcg_gen_or_vec(vece, sat, sat, x);
4669 tcg_temp_free_vec(x);
4670 }
4671
4672 static const TCGOpcode vecop_list_uqadd[] = {
4673 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4674 };
4675
4676 const GVecGen4 uqadd_op[4] = {
4677 { .fniv = gen_uqadd_vec,
4678 .fno = gen_helper_gvec_uqadd_b,
4679 .write_aofs = true,
4680 .opt_opc = vecop_list_uqadd,
4681 .vece = MO_8 },
4682 { .fniv = gen_uqadd_vec,
4683 .fno = gen_helper_gvec_uqadd_h,
4684 .write_aofs = true,
4685 .opt_opc = vecop_list_uqadd,
4686 .vece = MO_16 },
4687 { .fniv = gen_uqadd_vec,
4688 .fno = gen_helper_gvec_uqadd_s,
4689 .write_aofs = true,
4690 .opt_opc = vecop_list_uqadd,
4691 .vece = MO_32 },
4692 { .fniv = gen_uqadd_vec,
4693 .fno = gen_helper_gvec_uqadd_d,
4694 .write_aofs = true,
4695 .opt_opc = vecop_list_uqadd,
4696 .vece = MO_64 },
4697 };
4698
4699 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4700 TCGv_vec a, TCGv_vec b)
4701 {
4702 TCGv_vec x = tcg_temp_new_vec_matching(t);
4703 tcg_gen_add_vec(vece, x, a, b);
4704 tcg_gen_ssadd_vec(vece, t, a, b);
4705 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4706 tcg_gen_or_vec(vece, sat, sat, x);
4707 tcg_temp_free_vec(x);
4708 }
4709
4710 static const TCGOpcode vecop_list_sqadd[] = {
4711 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4712 };
4713
4714 const GVecGen4 sqadd_op[4] = {
4715 { .fniv = gen_sqadd_vec,
4716 .fno = gen_helper_gvec_sqadd_b,
4717 .opt_opc = vecop_list_sqadd,
4718 .write_aofs = true,
4719 .vece = MO_8 },
4720 { .fniv = gen_sqadd_vec,
4721 .fno = gen_helper_gvec_sqadd_h,
4722 .opt_opc = vecop_list_sqadd,
4723 .write_aofs = true,
4724 .vece = MO_16 },
4725 { .fniv = gen_sqadd_vec,
4726 .fno = gen_helper_gvec_sqadd_s,
4727 .opt_opc = vecop_list_sqadd,
4728 .write_aofs = true,
4729 .vece = MO_32 },
4730 { .fniv = gen_sqadd_vec,
4731 .fno = gen_helper_gvec_sqadd_d,
4732 .opt_opc = vecop_list_sqadd,
4733 .write_aofs = true,
4734 .vece = MO_64 },
4735 };
4736
4737 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4738 TCGv_vec a, TCGv_vec b)
4739 {
4740 TCGv_vec x = tcg_temp_new_vec_matching(t);
4741 tcg_gen_sub_vec(vece, x, a, b);
4742 tcg_gen_ussub_vec(vece, t, a, b);
4743 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4744 tcg_gen_or_vec(vece, sat, sat, x);
4745 tcg_temp_free_vec(x);
4746 }
4747
4748 static const TCGOpcode vecop_list_uqsub[] = {
4749 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4750 };
4751
4752 const GVecGen4 uqsub_op[4] = {
4753 { .fniv = gen_uqsub_vec,
4754 .fno = gen_helper_gvec_uqsub_b,
4755 .opt_opc = vecop_list_uqsub,
4756 .write_aofs = true,
4757 .vece = MO_8 },
4758 { .fniv = gen_uqsub_vec,
4759 .fno = gen_helper_gvec_uqsub_h,
4760 .opt_opc = vecop_list_uqsub,
4761 .write_aofs = true,
4762 .vece = MO_16 },
4763 { .fniv = gen_uqsub_vec,
4764 .fno = gen_helper_gvec_uqsub_s,
4765 .opt_opc = vecop_list_uqsub,
4766 .write_aofs = true,
4767 .vece = MO_32 },
4768 { .fniv = gen_uqsub_vec,
4769 .fno = gen_helper_gvec_uqsub_d,
4770 .opt_opc = vecop_list_uqsub,
4771 .write_aofs = true,
4772 .vece = MO_64 },
4773 };
4774
4775 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4776 TCGv_vec a, TCGv_vec b)
4777 {
4778 TCGv_vec x = tcg_temp_new_vec_matching(t);
4779 tcg_gen_sub_vec(vece, x, a, b);
4780 tcg_gen_sssub_vec(vece, t, a, b);
4781 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4782 tcg_gen_or_vec(vece, sat, sat, x);
4783 tcg_temp_free_vec(x);
4784 }
4785
4786 static const TCGOpcode vecop_list_sqsub[] = {
4787 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4788 };
4789
4790 const GVecGen4 sqsub_op[4] = {
4791 { .fniv = gen_sqsub_vec,
4792 .fno = gen_helper_gvec_sqsub_b,
4793 .opt_opc = vecop_list_sqsub,
4794 .write_aofs = true,
4795 .vece = MO_8 },
4796 { .fniv = gen_sqsub_vec,
4797 .fno = gen_helper_gvec_sqsub_h,
4798 .opt_opc = vecop_list_sqsub,
4799 .write_aofs = true,
4800 .vece = MO_16 },
4801 { .fniv = gen_sqsub_vec,
4802 .fno = gen_helper_gvec_sqsub_s,
4803 .opt_opc = vecop_list_sqsub,
4804 .write_aofs = true,
4805 .vece = MO_32 },
4806 { .fniv = gen_sqsub_vec,
4807 .fno = gen_helper_gvec_sqsub_d,
4808 .opt_opc = vecop_list_sqsub,
4809 .write_aofs = true,
4810 .vece = MO_64 },
4811 };
4812
4813 /* Translate a NEON data processing instruction. Return nonzero if the
4814 instruction is invalid.
4815 We process data in a mixture of 32-bit and 64-bit chunks.
4816 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4817
4818 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4819 {
4820 int op;
4821 int q;
4822 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4823 int size;
4824 int shift;
4825 int pass;
4826 int count;
4827 int pairwise;
4828 int u;
4829 int vec_size;
4830 uint32_t imm;
4831 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4832 TCGv_ptr ptr1, ptr2, ptr3;
4833 TCGv_i64 tmp64;
4834
4835 /* FIXME: this access check should not take precedence over UNDEF
4836 * for invalid encodings; we will generate incorrect syndrome information
4837 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4838 */
4839 if (s->fp_excp_el) {
4840 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4841 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4842 return 0;
4843 }
4844
4845 if (!s->vfp_enabled)
4846 return 1;
4847 q = (insn & (1 << 6)) != 0;
4848 u = (insn >> 24) & 1;
4849 VFP_DREG_D(rd, insn);
4850 VFP_DREG_N(rn, insn);
4851 VFP_DREG_M(rm, insn);
4852 size = (insn >> 20) & 3;
4853 vec_size = q ? 16 : 8;
4854 rd_ofs = neon_reg_offset(rd, 0);
4855 rn_ofs = neon_reg_offset(rn, 0);
4856 rm_ofs = neon_reg_offset(rm, 0);
4857
4858 if ((insn & (1 << 23)) == 0) {
4859 /* Three register same length. */
4860 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4861 /* Catch invalid op and bad size combinations: UNDEF */
4862 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4863 return 1;
4864 }
4865 /* All insns of this form UNDEF for either this condition or the
4866 * superset of cases "Q==1"; we catch the latter later.
4867 */
4868 if (q && ((rd | rn | rm) & 1)) {
4869 return 1;
4870 }
4871 switch (op) {
4872 case NEON_3R_SHA:
4873 /* The SHA-1/SHA-256 3-register instructions require special
4874 * treatment here, as their size field is overloaded as an
4875 * op type selector, and they all consume their input in a
4876 * single pass.
4877 */
4878 if (!q) {
4879 return 1;
4880 }
4881 if (!u) { /* SHA-1 */
4882 if (!dc_isar_feature(aa32_sha1, s)) {
4883 return 1;
4884 }
4885 ptr1 = vfp_reg_ptr(true, rd);
4886 ptr2 = vfp_reg_ptr(true, rn);
4887 ptr3 = vfp_reg_ptr(true, rm);
4888 tmp4 = tcg_const_i32(size);
4889 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4890 tcg_temp_free_i32(tmp4);
4891 } else { /* SHA-256 */
4892 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4893 return 1;
4894 }
4895 ptr1 = vfp_reg_ptr(true, rd);
4896 ptr2 = vfp_reg_ptr(true, rn);
4897 ptr3 = vfp_reg_ptr(true, rm);
4898 switch (size) {
4899 case 0:
4900 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4901 break;
4902 case 1:
4903 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4904 break;
4905 case 2:
4906 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4907 break;
4908 }
4909 }
4910 tcg_temp_free_ptr(ptr1);
4911 tcg_temp_free_ptr(ptr2);
4912 tcg_temp_free_ptr(ptr3);
4913 return 0;
4914
4915 case NEON_3R_VPADD_VQRDMLAH:
4916 if (!u) {
4917 break; /* VPADD */
4918 }
4919 /* VQRDMLAH */
4920 switch (size) {
4921 case 1:
4922 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4923 q, rd, rn, rm);
4924 case 2:
4925 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4926 q, rd, rn, rm);
4927 }
4928 return 1;
4929
4930 case NEON_3R_VFM_VQRDMLSH:
4931 if (!u) {
4932 /* VFM, VFMS */
4933 if (size == 1) {
4934 return 1;
4935 }
4936 break;
4937 }
4938 /* VQRDMLSH */
4939 switch (size) {
4940 case 1:
4941 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4942 q, rd, rn, rm);
4943 case 2:
4944 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4945 q, rd, rn, rm);
4946 }
4947 return 1;
4948
4949 case NEON_3R_LOGIC: /* Logic ops. */
4950 switch ((u << 2) | size) {
4951 case 0: /* VAND */
4952 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4953 vec_size, vec_size);
4954 break;
4955 case 1: /* VBIC */
4956 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4957 vec_size, vec_size);
4958 break;
4959 case 2: /* VORR */
4960 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4961 vec_size, vec_size);
4962 break;
4963 case 3: /* VORN */
4964 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4965 vec_size, vec_size);
4966 break;
4967 case 4: /* VEOR */
4968 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4969 vec_size, vec_size);
4970 break;
4971 case 5: /* VBSL */
4972 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4973 vec_size, vec_size);
4974 break;
4975 case 6: /* VBIT */
4976 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4977 vec_size, vec_size);
4978 break;
4979 case 7: /* VBIF */
4980 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4981 vec_size, vec_size);
4982 break;
4983 }
4984 return 0;
4985
4986 case NEON_3R_VADD_VSUB:
4987 if (u) {
4988 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4989 vec_size, vec_size);
4990 } else {
4991 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4992 vec_size, vec_size);
4993 }
4994 return 0;
4995
4996 case NEON_3R_VQADD:
4997 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4998 rn_ofs, rm_ofs, vec_size, vec_size,
4999 (u ? uqadd_op : sqadd_op) + size);
5000 return 0;
5001
5002 case NEON_3R_VQSUB:
5003 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5004 rn_ofs, rm_ofs, vec_size, vec_size,
5005 (u ? uqsub_op : sqsub_op) + size);
5006 return 0;
5007
5008 case NEON_3R_VMUL: /* VMUL */
5009 if (u) {
5010 /* Polynomial case allows only P8. */
5011 if (size != 0) {
5012 return 1;
5013 }
5014 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5015 0, gen_helper_gvec_pmul_b);
5016 } else {
5017 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5018 vec_size, vec_size);
5019 }
5020 return 0;
5021
5022 case NEON_3R_VML: /* VMLA, VMLS */
5023 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5024 u ? &mls_op[size] : &mla_op[size]);
5025 return 0;
5026
5027 case NEON_3R_VTST_VCEQ:
5028 if (u) { /* VCEQ */
5029 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5030 vec_size, vec_size);
5031 } else { /* VTST */
5032 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5033 vec_size, vec_size, &cmtst_op[size]);
5034 }
5035 return 0;
5036
5037 case NEON_3R_VCGT:
5038 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5039 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5040 return 0;
5041
5042 case NEON_3R_VCGE:
5043 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5044 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5045 return 0;
5046
5047 case NEON_3R_VMAX:
5048 if (u) {
5049 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5050 vec_size, vec_size);
5051 } else {
5052 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5053 vec_size, vec_size);
5054 }
5055 return 0;
5056 case NEON_3R_VMIN:
5057 if (u) {
5058 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5059 vec_size, vec_size);
5060 } else {
5061 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5062 vec_size, vec_size);
5063 }
5064 return 0;
5065
5066 case NEON_3R_VSHL:
5067 /* Note the operation is vshl vd,vm,vn */
5068 tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
5069 u ? &ushl_op[size] : &sshl_op[size]);
5070 return 0;
5071 }
5072
5073 if (size == 3) {
5074 /* 64-bit element instructions. */
5075 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5076 neon_load_reg64(cpu_V0, rn + pass);
5077 neon_load_reg64(cpu_V1, rm + pass);
5078 switch (op) {
5079 case NEON_3R_VQSHL:
5080 if (u) {
5081 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5082 cpu_V1, cpu_V0);
5083 } else {
5084 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5085 cpu_V1, cpu_V0);
5086 }
5087 break;
5088 case NEON_3R_VRSHL:
5089 if (u) {
5090 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5091 } else {
5092 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5093 }
5094 break;
5095 case NEON_3R_VQRSHL:
5096 if (u) {
5097 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5098 cpu_V1, cpu_V0);
5099 } else {
5100 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5101 cpu_V1, cpu_V0);
5102 }
5103 break;
5104 default:
5105 abort();
5106 }
5107 neon_store_reg64(cpu_V0, rd + pass);
5108 }
5109 return 0;
5110 }
5111 pairwise = 0;
5112 switch (op) {
5113 case NEON_3R_VQSHL:
5114 case NEON_3R_VRSHL:
5115 case NEON_3R_VQRSHL:
5116 {
5117 int rtmp;
5118 /* Shift instruction operands are reversed. */
5119 rtmp = rn;
5120 rn = rm;
5121 rm = rtmp;
5122 }
5123 break;
5124 case NEON_3R_VPADD_VQRDMLAH:
5125 case NEON_3R_VPMAX:
5126 case NEON_3R_VPMIN:
5127 pairwise = 1;
5128 break;
5129 case NEON_3R_FLOAT_ARITH:
5130 pairwise = (u && size < 2); /* if VPADD (float) */
5131 break;
5132 case NEON_3R_FLOAT_MINMAX:
5133 pairwise = u; /* if VPMIN/VPMAX (float) */
5134 break;
5135 case NEON_3R_FLOAT_CMP:
5136 if (!u && size) {
5137 /* no encoding for U=0 C=1x */
5138 return 1;
5139 }
5140 break;
5141 case NEON_3R_FLOAT_ACMP:
5142 if (!u) {
5143 return 1;
5144 }
5145 break;
5146 case NEON_3R_FLOAT_MISC:
5147 /* VMAXNM/VMINNM in ARMv8 */
5148 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5149 return 1;
5150 }
5151 break;
5152 case NEON_3R_VFM_VQRDMLSH:
5153 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5154 return 1;
5155 }
5156 break;
5157 default:
5158 break;
5159 }
5160
5161 if (pairwise && q) {
5162 /* All the pairwise insns UNDEF if Q is set */
5163 return 1;
5164 }
5165
5166 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5167
5168 if (pairwise) {
5169 /* Pairwise. */
5170 if (pass < 1) {
5171 tmp = neon_load_reg(rn, 0);
5172 tmp2 = neon_load_reg(rn, 1);
5173 } else {
5174 tmp = neon_load_reg(rm, 0);
5175 tmp2 = neon_load_reg(rm, 1);
5176 }
5177 } else {
5178 /* Elementwise. */
5179 tmp = neon_load_reg(rn, pass);
5180 tmp2 = neon_load_reg(rm, pass);
5181 }
5182 switch (op) {
5183 case NEON_3R_VHADD:
5184 GEN_NEON_INTEGER_OP(hadd);
5185 break;
5186 case NEON_3R_VRHADD:
5187 GEN_NEON_INTEGER_OP(rhadd);
5188 break;
5189 case NEON_3R_VHSUB:
5190 GEN_NEON_INTEGER_OP(hsub);
5191 break;
5192 case NEON_3R_VQSHL:
5193 GEN_NEON_INTEGER_OP_ENV(qshl);
5194 break;
5195 case NEON_3R_VRSHL:
5196 GEN_NEON_INTEGER_OP(rshl);
5197 break;
5198 case NEON_3R_VQRSHL:
5199 GEN_NEON_INTEGER_OP_ENV(qrshl);
5200 break;
5201 case NEON_3R_VABD:
5202 GEN_NEON_INTEGER_OP(abd);
5203 break;
5204 case NEON_3R_VABA:
5205 GEN_NEON_INTEGER_OP(abd);
5206 tcg_temp_free_i32(tmp2);
5207 tmp2 = neon_load_reg(rd, pass);
5208 gen_neon_add(size, tmp, tmp2);
5209 break;
5210 case NEON_3R_VPMAX:
5211 GEN_NEON_INTEGER_OP(pmax);
5212 break;
5213 case NEON_3R_VPMIN:
5214 GEN_NEON_INTEGER_OP(pmin);
5215 break;
5216 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5217 if (!u) { /* VQDMULH */
5218 switch (size) {
5219 case 1:
5220 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5221 break;
5222 case 2:
5223 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5224 break;
5225 default: abort();
5226 }
5227 } else { /* VQRDMULH */
5228 switch (size) {
5229 case 1:
5230 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5231 break;
5232 case 2:
5233 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5234 break;
5235 default: abort();
5236 }
5237 }
5238 break;
5239 case NEON_3R_VPADD_VQRDMLAH:
5240 switch (size) {
5241 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5242 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5243 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5244 default: abort();
5245 }
5246 break;
5247 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5248 {
5249 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5250 switch ((u << 2) | size) {
5251 case 0: /* VADD */
5252 case 4: /* VPADD */
5253 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5254 break;
5255 case 2: /* VSUB */
5256 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5257 break;
5258 case 6: /* VABD */
5259 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5260 break;
5261 default:
5262 abort();
5263 }
5264 tcg_temp_free_ptr(fpstatus);
5265 break;
5266 }
5267 case NEON_3R_FLOAT_MULTIPLY:
5268 {
5269 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5270 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5271 if (!u) {
5272 tcg_temp_free_i32(tmp2);
5273 tmp2 = neon_load_reg(rd, pass);
5274 if (size == 0) {
5275 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5276 } else {
5277 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5278 }
5279 }
5280 tcg_temp_free_ptr(fpstatus);
5281 break;
5282 }
5283 case NEON_3R_FLOAT_CMP:
5284 {
5285 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5286 if (!u) {
5287 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5288 } else {
5289 if (size == 0) {
5290 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5291 } else {
5292 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5293 }
5294 }
5295 tcg_temp_free_ptr(fpstatus);
5296 break;
5297 }
5298 case NEON_3R_FLOAT_ACMP:
5299 {
5300 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5301 if (size == 0) {
5302 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5303 } else {
5304 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5305 }
5306 tcg_temp_free_ptr(fpstatus);
5307 break;
5308 }
5309 case NEON_3R_FLOAT_MINMAX:
5310 {
5311 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5312 if (size == 0) {
5313 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5314 } else {
5315 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5316 }
5317 tcg_temp_free_ptr(fpstatus);
5318 break;
5319 }
5320 case NEON_3R_FLOAT_MISC:
5321 if (u) {
5322 /* VMAXNM/VMINNM */
5323 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5324 if (size == 0) {
5325 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5326 } else {
5327 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5328 }
5329 tcg_temp_free_ptr(fpstatus);
5330 } else {
5331 if (size == 0) {
5332 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5333 } else {
5334 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5335 }
5336 }
5337 break;
5338 case NEON_3R_VFM_VQRDMLSH:
5339 {
5340 /* VFMA, VFMS: fused multiply-add */
5341 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5342 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5343 if (size) {
5344 /* VFMS */
5345 gen_helper_vfp_negs(tmp, tmp);
5346 }
5347 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5348 tcg_temp_free_i32(tmp3);
5349 tcg_temp_free_ptr(fpstatus);
5350 break;
5351 }
5352 default:
5353 abort();
5354 }
5355 tcg_temp_free_i32(tmp2);
5356
5357 /* Save the result. For elementwise operations we can put it
5358 straight into the destination register. For pairwise operations
5359 we have to be careful to avoid clobbering the source operands. */
5360 if (pairwise && rd == rm) {
5361 neon_store_scratch(pass, tmp);
5362 } else {
5363 neon_store_reg(rd, pass, tmp);
5364 }
5365
5366 } /* for pass */
5367 if (pairwise && rd == rm) {
5368 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5369 tmp = neon_load_scratch(pass);
5370 neon_store_reg(rd, pass, tmp);
5371 }
5372 }
5373 /* End of 3 register same size operations. */
5374 } else if (insn & (1 << 4)) {
5375 if ((insn & 0x00380080) != 0) {
5376 /* Two registers and shift. */
5377 op = (insn >> 8) & 0xf;
5378 if (insn & (1 << 7)) {
5379 /* 64-bit shift. */
5380 if (op > 7) {
5381 return 1;
5382 }
5383 size = 3;
5384 } else {
5385 size = 2;
5386 while ((insn & (1 << (size + 19))) == 0)
5387 size--;
5388 }
5389 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5390 if (op < 8) {
5391 /* Shift by immediate:
5392 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5393 if (q && ((rd | rm) & 1)) {
5394 return 1;
5395 }
5396 if (!u && (op == 4 || op == 6)) {
5397 return 1;
5398 }
5399 /* Right shifts are encoded as N - shift, where N is the
5400 element size in bits. */
5401 if (op <= 4) {
5402 shift = shift - (1 << (size + 3));
5403 }
5404
5405 switch (op) {
5406 case 0: /* VSHR */
5407 /* Right shift comes here negative. */
5408 shift = -shift;
5409 /* Shifts larger than the element size are architecturally
5410 * valid. Unsigned results in all zeros; signed results
5411 * in all sign bits.
5412 */
5413 if (!u) {
5414 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5415 MIN(shift, (8 << size) - 1),
5416 vec_size, vec_size);
5417 } else if (shift >= 8 << size) {
5418 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5419 } else {
5420 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5421 vec_size, vec_size);
5422 }
5423 return 0;
5424
5425 case 1: /* VSRA */
5426 /* Right shift comes here negative. */
5427 shift = -shift;
5428 /* Shifts larger than the element size are architecturally
5429 * valid. Unsigned results in all zeros; signed results
5430 * in all sign bits.
5431 */
5432 if (!u) {
5433 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5434 MIN(shift, (8 << size) - 1),
5435 &ssra_op[size]);
5436 } else if (shift >= 8 << size) {
5437 /* rd += 0 */
5438 } else {
5439 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5440 shift, &usra_op[size]);
5441 }
5442 return 0;
5443
5444 case 4: /* VSRI */
5445 if (!u) {
5446 return 1;
5447 }
5448 /* Right shift comes here negative. */
5449 shift = -shift;
5450 /* Shift out of range leaves destination unchanged. */
5451 if (shift < 8 << size) {
5452 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5453 shift, &sri_op[size]);
5454 }
5455 return 0;
5456
5457 case 5: /* VSHL, VSLI */
5458 if (u) { /* VSLI */
5459 /* Shift out of range leaves destination unchanged. */
5460 if (shift < 8 << size) {
5461 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5462 vec_size, shift, &sli_op[size]);
5463 }
5464 } else { /* VSHL */
5465 /* Shifts larger than the element size are
5466 * architecturally valid and results in zero.
5467 */
5468 if (shift >= 8 << size) {
5469 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5470 } else {
5471 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5472 vec_size, vec_size);
5473 }
5474 }
5475 return 0;
5476 }
5477
5478 if (size == 3) {
5479 count = q + 1;
5480 } else {
5481 count = q ? 4: 2;
5482 }
5483
5484 /* To avoid excessive duplication of ops we implement shift
5485 * by immediate using the variable shift operations.
5486 */
5487 imm = dup_const(size, shift);
5488
5489 for (pass = 0; pass < count; pass++) {
5490 if (size == 3) {
5491 neon_load_reg64(cpu_V0, rm + pass);
5492 tcg_gen_movi_i64(cpu_V1, imm);
5493 switch (op) {
5494 case 2: /* VRSHR */
5495 case 3: /* VRSRA */
5496 if (u)
5497 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5498 else
5499 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5500 break;
5501 case 6: /* VQSHLU */
5502 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5503 cpu_V0, cpu_V1);
5504 break;
5505 case 7: /* VQSHL */
5506 if (u) {
5507 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5508 cpu_V0, cpu_V1);
5509 } else {
5510 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5511 cpu_V0, cpu_V1);
5512 }
5513 break;
5514 default:
5515 g_assert_not_reached();
5516 }
5517 if (op == 3) {
5518 /* Accumulate. */
5519 neon_load_reg64(cpu_V1, rd + pass);
5520 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5521 }
5522 neon_store_reg64(cpu_V0, rd + pass);
5523 } else { /* size < 3 */
5524 /* Operands in T0 and T1. */
5525 tmp = neon_load_reg(rm, pass);
5526 tmp2 = tcg_temp_new_i32();
5527 tcg_gen_movi_i32(tmp2, imm);
5528 switch (op) {
5529 case 2: /* VRSHR */
5530 case 3: /* VRSRA */
5531 GEN_NEON_INTEGER_OP(rshl);
5532 break;
5533 case 6: /* VQSHLU */
5534 switch (size) {
5535 case 0:
5536 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5537 tmp, tmp2);
5538 break;
5539 case 1:
5540 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5541 tmp, tmp2);
5542 break;
5543 case 2:
5544 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5545 tmp, tmp2);
5546 break;
5547 default:
5548 abort();
5549 }
5550 break;
5551 case 7: /* VQSHL */
5552 GEN_NEON_INTEGER_OP_ENV(qshl);
5553 break;
5554 default:
5555 g_assert_not_reached();
5556 }
5557 tcg_temp_free_i32(tmp2);
5558
5559 if (op == 3) {
5560 /* Accumulate. */
5561 tmp2 = neon_load_reg(rd, pass);
5562 gen_neon_add(size, tmp, tmp2);
5563 tcg_temp_free_i32(tmp2);
5564 }
5565 neon_store_reg(rd, pass, tmp);
5566 }
5567 } /* for pass */
5568 } else if (op < 10) {
5569 /* Shift by immediate and narrow:
5570 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5571 int input_unsigned = (op == 8) ? !u : u;
5572 if (rm & 1) {
5573 return 1;
5574 }
5575 shift = shift - (1 << (size + 3));
5576 size++;
5577 if (size == 3) {
5578 tmp64 = tcg_const_i64(shift);
5579 neon_load_reg64(cpu_V0, rm);
5580 neon_load_reg64(cpu_V1, rm + 1);
5581 for (pass = 0; pass < 2; pass++) {
5582 TCGv_i64 in;
5583 if (pass == 0) {
5584 in = cpu_V0;
5585 } else {
5586 in = cpu_V1;
5587 }
5588 if (q) {
5589 if (input_unsigned) {
5590 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5591 } else {
5592 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5593 }
5594 } else {
5595 if (input_unsigned) {
5596 gen_ushl_i64(cpu_V0, in, tmp64);
5597 } else {
5598 gen_sshl_i64(cpu_V0, in, tmp64);
5599 }
5600 }
5601 tmp = tcg_temp_new_i32();
5602 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5603 neon_store_reg(rd, pass, tmp);
5604 } /* for pass */
5605 tcg_temp_free_i64(tmp64);
5606 } else {
5607 if (size == 1) {
5608 imm = (uint16_t)shift;
5609 imm |= imm << 16;
5610 } else {
5611 /* size == 2 */
5612 imm = (uint32_t)shift;
5613 }
5614 tmp2 = tcg_const_i32(imm);
5615 tmp4 = neon_load_reg(rm + 1, 0);
5616 tmp5 = neon_load_reg(rm + 1, 1);
5617 for (pass = 0; pass < 2; pass++) {
5618 if (pass == 0) {
5619 tmp = neon_load_reg(rm, 0);
5620 } else {
5621 tmp = tmp4;
5622 }
5623 gen_neon_shift_narrow(size, tmp, tmp2, q,
5624 input_unsigned);
5625 if (pass == 0) {
5626 tmp3 = neon_load_reg(rm, 1);
5627 } else {
5628 tmp3 = tmp5;
5629 }
5630 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5631 input_unsigned);
5632 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5633 tcg_temp_free_i32(tmp);
5634 tcg_temp_free_i32(tmp3);
5635 tmp = tcg_temp_new_i32();
5636 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5637 neon_store_reg(rd, pass, tmp);
5638 } /* for pass */
5639 tcg_temp_free_i32(tmp2);
5640 }
5641 } else if (op == 10) {
5642 /* VSHLL, VMOVL */
5643 if (q || (rd & 1)) {
5644 return 1;
5645 }
5646 tmp = neon_load_reg(rm, 0);
5647 tmp2 = neon_load_reg(rm, 1);
5648 for (pass = 0; pass < 2; pass++) {
5649 if (pass == 1)
5650 tmp = tmp2;
5651
5652 gen_neon_widen(cpu_V0, tmp, size, u);
5653
5654 if (shift != 0) {
5655 /* The shift is less than the width of the source
5656 type, so we can just shift the whole register. */
5657 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5658 /* Widen the result of shift: we need to clear
5659 * the potential overflow bits resulting from
5660 * left bits of the narrow input appearing as
5661 * right bits of left the neighbour narrow
5662 * input. */
5663 if (size < 2 || !u) {
5664 uint64_t imm64;
5665 if (size == 0) {
5666 imm = (0xffu >> (8 - shift));
5667 imm |= imm << 16;
5668 } else if (size == 1) {
5669 imm = 0xffff >> (16 - shift);
5670 } else {
5671 /* size == 2 */
5672 imm = 0xffffffff >> (32 - shift);
5673 }
5674 if (size < 2) {
5675 imm64 = imm | (((uint64_t)imm) << 32);
5676 } else {
5677 imm64 = imm;
5678 }
5679 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5680 }
5681 }
5682 neon_store_reg64(cpu_V0, rd + pass);
5683 }
5684 } else if (op >= 14) {
5685 /* VCVT fixed-point. */
5686 TCGv_ptr fpst;
5687 TCGv_i32 shiftv;
5688 VFPGenFixPointFn *fn;
5689
5690 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5691 return 1;
5692 }
5693
5694 if (!(op & 1)) {
5695 if (u) {
5696 fn = gen_helper_vfp_ultos;
5697 } else {
5698 fn = gen_helper_vfp_sltos;
5699 }
5700 } else {
5701 if (u) {
5702 fn = gen_helper_vfp_touls_round_to_zero;
5703 } else {
5704 fn = gen_helper_vfp_tosls_round_to_zero;
5705 }
5706 }
5707
5708 /* We have already masked out the must-be-1 top bit of imm6,
5709 * hence this 32-shift where the ARM ARM has 64-imm6.
5710 */
5711 shift = 32 - shift;
5712 fpst = get_fpstatus_ptr(1);
5713 shiftv = tcg_const_i32(shift);
5714 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5715 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5716 fn(tmpf, tmpf, shiftv, fpst);
5717 neon_store_reg(rd, pass, tmpf);
5718 }
5719 tcg_temp_free_ptr(fpst);
5720 tcg_temp_free_i32(shiftv);
5721 } else {
5722 return 1;
5723 }
5724 } else { /* (insn & 0x00380080) == 0 */
5725 int invert, reg_ofs, vec_size;
5726
5727 if (q && (rd & 1)) {
5728 return 1;
5729 }
5730
5731 op = (insn >> 8) & 0xf;
5732 /* One register and immediate. */
5733 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5734 invert = (insn & (1 << 5)) != 0;
5735 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5736 * We choose to not special-case this and will behave as if a
5737 * valid constant encoding of 0 had been given.
5738 */
5739 switch (op) {
5740 case 0: case 1:
5741 /* no-op */
5742 break;
5743 case 2: case 3:
5744 imm <<= 8;
5745 break;
5746 case 4: case 5:
5747 imm <<= 16;
5748 break;
5749 case 6: case 7:
5750 imm <<= 24;
5751 break;
5752 case 8: case 9:
5753 imm |= imm << 16;
5754 break;
5755 case 10: case 11:
5756 imm = (imm << 8) | (imm << 24);
5757 break;
5758 case 12:
5759 imm = (imm << 8) | 0xff;
5760 break;
5761 case 13:
5762 imm = (imm << 16) | 0xffff;
5763 break;
5764 case 14:
5765 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5766 if (invert) {
5767 imm = ~imm;
5768 }
5769 break;
5770 case 15:
5771 if (invert) {
5772 return 1;
5773 }
5774 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5775 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5776 break;
5777 }
5778 if (invert) {
5779 imm = ~imm;
5780 }
5781
5782 reg_ofs = neon_reg_offset(rd, 0);
5783 vec_size = q ? 16 : 8;
5784
5785 if (op & 1 && op < 12) {
5786 if (invert) {
5787 /* The immediate value has already been inverted,
5788 * so BIC becomes AND.
5789 */
5790 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5791 vec_size, vec_size);
5792 } else {
5793 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5794 vec_size, vec_size);
5795 }
5796 } else {
5797 /* VMOV, VMVN. */
5798 if (op == 14 && invert) {
5799 TCGv_i64 t64 = tcg_temp_new_i64();
5800
5801 for (pass = 0; pass <= q; ++pass) {
5802 uint64_t val = 0;
5803 int n;
5804
5805 for (n = 0; n < 8; n++) {
5806 if (imm & (1 << (n + pass * 8))) {
5807 val |= 0xffull << (n * 8);
5808 }
5809 }
5810 tcg_gen_movi_i64(t64, val);
5811 neon_store_reg64(t64, rd + pass);
5812 }
5813 tcg_temp_free_i64(t64);
5814 } else {
5815 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5816 }
5817 }
5818 }
5819 } else { /* (insn & 0x00800010 == 0x00800000) */
5820 if (size != 3) {
5821 op = (insn >> 8) & 0xf;
5822 if ((insn & (1 << 6)) == 0) {
5823 /* Three registers of different lengths. */
5824 int src1_wide;
5825 int src2_wide;
5826 int prewiden;
5827 /* undefreq: bit 0 : UNDEF if size == 0
5828 * bit 1 : UNDEF if size == 1
5829 * bit 2 : UNDEF if size == 2
5830 * bit 3 : UNDEF if U == 1
5831 * Note that [2:0] set implies 'always UNDEF'
5832 */
5833 int undefreq;
5834 /* prewiden, src1_wide, src2_wide, undefreq */
5835 static const int neon_3reg_wide[16][4] = {
5836 {1, 0, 0, 0}, /* VADDL */
5837 {1, 1, 0, 0}, /* VADDW */
5838 {1, 0, 0, 0}, /* VSUBL */
5839 {1, 1, 0, 0}, /* VSUBW */
5840 {0, 1, 1, 0}, /* VADDHN */
5841 {0, 0, 0, 0}, /* VABAL */
5842 {0, 1, 1, 0}, /* VSUBHN */
5843 {0, 0, 0, 0}, /* VABDL */
5844 {0, 0, 0, 0}, /* VMLAL */
5845 {0, 0, 0, 9}, /* VQDMLAL */
5846 {0, 0, 0, 0}, /* VMLSL */
5847 {0, 0, 0, 9}, /* VQDMLSL */
5848 {0, 0, 0, 0}, /* Integer VMULL */
5849 {0, 0, 0, 1}, /* VQDMULL */
5850 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5851 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5852 };
5853
5854 prewiden = neon_3reg_wide[op][0];
5855 src1_wide = neon_3reg_wide[op][1];
5856 src2_wide = neon_3reg_wide[op][2];
5857 undefreq = neon_3reg_wide[op][3];
5858
5859 if ((undefreq & (1 << size)) ||
5860 ((undefreq & 8) && u)) {
5861 return 1;
5862 }
5863 if ((src1_wide && (rn & 1)) ||
5864 (src2_wide && (rm & 1)) ||
5865 (!src2_wide && (rd & 1))) {
5866 return 1;
5867 }
5868
5869 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5870 * outside the loop below as it only performs a single pass.
5871 */
5872 if (op == 14 && size == 2) {
5873 if (!dc_isar_feature(aa32_pmull, s)) {
5874 return 1;
5875 }
5876 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
5877 0, gen_helper_gvec_pmull_q);
5878 return 0;
5879 }
5880
5881 /* Avoid overlapping operands. Wide source operands are
5882 always aligned so will never overlap with wide
5883 destinations in problematic ways. */
5884 if (rd == rm && !src2_wide) {
5885 tmp = neon_load_reg(rm, 1);
5886 neon_store_scratch(2, tmp);
5887 } else if (rd == rn && !src1_wide) {
5888 tmp = neon_load_reg(rn, 1);
5889 neon_store_scratch(2, tmp);
5890 }
5891 tmp3 = NULL;
5892 for (pass = 0; pass < 2; pass++) {
5893 if (src1_wide) {
5894 neon_load_reg64(cpu_V0, rn + pass);
5895 tmp = NULL;
5896 } else {
5897 if (pass == 1 && rd == rn) {
5898 tmp = neon_load_scratch(2);
5899 } else {
5900 tmp = neon_load_reg(rn, pass);
5901 }
5902 if (prewiden) {
5903 gen_neon_widen(cpu_V0, tmp, size, u);
5904 }
5905 }
5906 if (src2_wide) {
5907 neon_load_reg64(cpu_V1, rm + pass);
5908 tmp2 = NULL;
5909 } else {
5910 if (pass == 1 && rd == rm) {
5911 tmp2 = neon_load_scratch(2);
5912 } else {
5913 tmp2 = neon_load_reg(rm, pass);
5914 }
5915 if (prewiden) {
5916 gen_neon_widen(cpu_V1, tmp2, size, u);
5917 }
5918 }
5919 switch (op) {
5920 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5921 gen_neon_addl(size);
5922 break;
5923 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5924 gen_neon_subl(size);
5925 break;
5926 case 5: case 7: /* VABAL, VABDL */
5927 switch ((size << 1) | u) {
5928 case 0:
5929 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5930 break;
5931 case 1:
5932 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5933 break;
5934 case 2:
5935 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5936 break;
5937 case 3:
5938 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5939 break;
5940 case 4:
5941 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5942 break;
5943 case 5:
5944 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5945 break;
5946 default: abort();
5947 }
5948 tcg_temp_free_i32(tmp2);
5949 tcg_temp_free_i32(tmp);
5950 break;
5951 case 8: case 9: case 10: case 11: case 12: case 13:
5952 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5953 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5954 break;
5955 case 14: /* Polynomial VMULL */
5956 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5957 tcg_temp_free_i32(tmp2);
5958 tcg_temp_free_i32(tmp);
5959 break;
5960 default: /* 15 is RESERVED: caught earlier */
5961 abort();
5962 }
5963 if (op == 13) {
5964 /* VQDMULL */
5965 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5966 neon_store_reg64(cpu_V0, rd + pass);
5967 } else if (op == 5 || (op >= 8 && op <= 11)) {
5968 /* Accumulate. */
5969 neon_load_reg64(cpu_V1, rd + pass);
5970 switch (op) {
5971 case 10: /* VMLSL */
5972 gen_neon_negl(cpu_V0, size);
5973 /* Fall through */
5974 case 5: case 8: /* VABAL, VMLAL */
5975 gen_neon_addl(size);
5976 break;
5977 case 9: case 11: /* VQDMLAL, VQDMLSL */
5978 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5979 if (op == 11) {
5980 gen_neon_negl(cpu_V0, size);
5981 }
5982 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5983 break;
5984 default:
5985 abort();
5986 }
5987 neon_store_reg64(cpu_V0, rd + pass);
5988 } else if (op == 4 || op == 6) {
5989 /* Narrowing operation. */
5990 tmp = tcg_temp_new_i32();
5991 if (!u) {
5992 switch (size) {
5993 case 0:
5994 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5995 break;
5996 case 1:
5997 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5998 break;
5999 case 2:
6000 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6001 break;
6002 default: abort();
6003 }
6004 } else {
6005 switch (size) {
6006 case 0:
6007 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6008 break;
6009 case 1:
6010 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6011 break;
6012 case 2:
6013 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6014 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6015 break;
6016 default: abort();
6017 }
6018 }
6019 if (pass == 0) {
6020 tmp3 = tmp;
6021 } else {
6022 neon_store_reg(rd, 0, tmp3);
6023 neon_store_reg(rd, 1, tmp);
6024 }
6025 } else {
6026 /* Write back the result. */
6027 neon_store_reg64(cpu_V0, rd + pass);
6028 }
6029 }
6030 } else {
6031 /* Two registers and a scalar. NB that for ops of this form
6032 * the ARM ARM labels bit 24 as Q, but it is in our variable
6033 * 'u', not 'q'.
6034 */
6035 if (size == 0) {
6036 return 1;
6037 }
6038 switch (op) {
6039 case 1: /* Float VMLA scalar */
6040 case 5: /* Floating point VMLS scalar */
6041 case 9: /* Floating point VMUL scalar */
6042 if (size == 1) {
6043 return 1;
6044 }
6045 /* fall through */
6046 case 0: /* Integer VMLA scalar */
6047 case 4: /* Integer VMLS scalar */
6048 case 8: /* Integer VMUL scalar */
6049 case 12: /* VQDMULH scalar */
6050 case 13: /* VQRDMULH scalar */
6051 if (u && ((rd | rn) & 1)) {
6052 return 1;
6053 }
6054 tmp = neon_get_scalar(size, rm);
6055 neon_store_scratch(0, tmp);
6056 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6057 tmp = neon_load_scratch(0);
6058 tmp2 = neon_load_reg(rn, pass);
6059 if (op == 12) {
6060 if (size == 1) {
6061 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6062 } else {
6063 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6064 }
6065 } else if (op == 13) {
6066 if (size == 1) {
6067 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6068 } else {
6069 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6070 }
6071 } else if (op & 1) {
6072 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6073 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6074 tcg_temp_free_ptr(fpstatus);
6075 } else {
6076 switch (size) {
6077 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6078 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6079 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6080 default: abort();
6081 }
6082 }
6083 tcg_temp_free_i32(tmp2);
6084 if (op < 8) {
6085 /* Accumulate. */
6086 tmp2 = neon_load_reg(rd, pass);
6087 switch (op) {
6088 case 0:
6089 gen_neon_add(size, tmp, tmp2);
6090 break;
6091 case 1:
6092 {
6093 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6094 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6095 tcg_temp_free_ptr(fpstatus);
6096 break;
6097 }
6098 case 4:
6099 gen_neon_rsb(size, tmp, tmp2);
6100 break;
6101 case 5:
6102 {
6103 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6104 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6105 tcg_temp_free_ptr(fpstatus);
6106 break;
6107 }
6108 default:
6109 abort();
6110 }
6111 tcg_temp_free_i32(tmp2);
6112 }
6113 neon_store_reg(rd, pass, tmp);
6114 }
6115 break;
6116 case 3: /* VQDMLAL scalar */
6117 case 7: /* VQDMLSL scalar */
6118 case 11: /* VQDMULL scalar */
6119 if (u == 1) {
6120 return 1;
6121 }
6122 /* fall through */
6123 case 2: /* VMLAL sclar */
6124 case 6: /* VMLSL scalar */
6125 case 10: /* VMULL scalar */
6126 if (rd & 1) {
6127 return 1;
6128 }
6129 tmp2 = neon_get_scalar(size, rm);
6130 /* We need a copy of tmp2 because gen_neon_mull
6131 * deletes it during pass 0. */
6132 tmp4 = tcg_temp_new_i32();
6133 tcg_gen_mov_i32(tmp4, tmp2);
6134 tmp3 = neon_load_reg(rn, 1);
6135
6136 for (pass = 0; pass < 2; pass++) {
6137 if (pass == 0) {
6138 tmp = neon_load_reg(rn, 0);
6139 } else {
6140 tmp = tmp3;
6141 tmp2 = tmp4;
6142 }
6143 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6144 if (op != 11) {
6145 neon_load_reg64(cpu_V1, rd + pass);
6146 }
6147 switch (op) {
6148 case 6:
6149 gen_neon_negl(cpu_V0, size);
6150 /* Fall through */
6151 case 2:
6152 gen_neon_addl(size);
6153 break;
6154 case 3: case 7:
6155 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6156 if (op == 7) {
6157 gen_neon_negl(cpu_V0, size);
6158 }
6159 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6160 break;
6161 case 10:
6162 /* no-op */
6163 break;
6164 case 11:
6165 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6166 break;
6167 default:
6168 abort();
6169 }
6170 neon_store_reg64(cpu_V0, rd + pass);
6171 }
6172 break;
6173 case 14: /* VQRDMLAH scalar */
6174 case 15: /* VQRDMLSH scalar */
6175 {
6176 NeonGenThreeOpEnvFn *fn;
6177
6178 if (!dc_isar_feature(aa32_rdm, s)) {
6179 return 1;
6180 }
6181 if (u && ((rd | rn) & 1)) {
6182 return 1;
6183 }
6184 if (op == 14) {
6185 if (size == 1) {
6186 fn = gen_helper_neon_qrdmlah_s16;
6187 } else {
6188 fn = gen_helper_neon_qrdmlah_s32;
6189 }
6190 } else {
6191 if (size == 1) {
6192 fn = gen_helper_neon_qrdmlsh_s16;
6193 } else {
6194 fn = gen_helper_neon_qrdmlsh_s32;
6195 }
6196 }
6197
6198 tmp2 = neon_get_scalar(size, rm);
6199 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6200 tmp = neon_load_reg(rn, pass);
6201 tmp3 = neon_load_reg(rd, pass);
6202 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6203 tcg_temp_free_i32(tmp3);
6204 neon_store_reg(rd, pass, tmp);
6205 }
6206 tcg_temp_free_i32(tmp2);
6207 }
6208 break;
6209 default:
6210 g_assert_not_reached();
6211 }
6212 }
6213 } else { /* size == 3 */
6214 if (!u) {
6215 /* Extract. */
6216 imm = (insn >> 8) & 0xf;
6217
6218 if (imm > 7 && !q)
6219 return 1;
6220
6221 if (q && ((rd | rn | rm) & 1)) {
6222 return 1;
6223 }
6224
6225 if (imm == 0) {
6226 neon_load_reg64(cpu_V0, rn);
6227 if (q) {
6228 neon_load_reg64(cpu_V1, rn + 1);
6229 }
6230 } else if (imm == 8) {
6231 neon_load_reg64(cpu_V0, rn + 1);
6232 if (q) {
6233 neon_load_reg64(cpu_V1, rm);
6234 }
6235 } else if (q) {
6236 tmp64 = tcg_temp_new_i64();
6237 if (imm < 8) {
6238 neon_load_reg64(cpu_V0, rn);
6239 neon_load_reg64(tmp64, rn + 1);
6240 } else {
6241 neon_load_reg64(cpu_V0, rn + 1);
6242 neon_load_reg64(tmp64, rm);
6243 }
6244 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6245 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6246 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6247 if (imm < 8) {
6248 neon_load_reg64(cpu_V1, rm);
6249 } else {
6250 neon_load_reg64(cpu_V1, rm + 1);
6251 imm -= 8;
6252 }
6253 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6254 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6255 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6256 tcg_temp_free_i64(tmp64);
6257 } else {
6258 /* BUGFIX */
6259 neon_load_reg64(cpu_V0, rn);
6260 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6261 neon_load_reg64(cpu_V1, rm);
6262 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6263 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6264 }
6265 neon_store_reg64(cpu_V0, rd);
6266 if (q) {
6267 neon_store_reg64(cpu_V1, rd + 1);
6268 }
6269 } else if ((insn & (1 << 11)) == 0) {
6270 /* Two register misc. */
6271 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6272 size = (insn >> 18) & 3;
6273 /* UNDEF for unknown op values and bad op-size combinations */
6274 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6275 return 1;
6276 }
6277 if (neon_2rm_is_v8_op(op) &&
6278 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6279 return 1;
6280 }
6281 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6282 q && ((rm | rd) & 1)) {
6283 return 1;
6284 }
6285 switch (op) {
6286 case NEON_2RM_VREV64:
6287 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6288 tmp = neon_load_reg(rm, pass * 2);
6289 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6290 switch (size) {
6291 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6292 case 1: gen_swap_half(tmp); break;
6293 case 2: /* no-op */ break;
6294 default: abort();
6295 }
6296 neon_store_reg(rd, pass * 2 + 1, tmp);
6297 if (size == 2) {
6298 neon_store_reg(rd, pass * 2, tmp2);
6299 } else {
6300 switch (size) {
6301 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6302 case 1: gen_swap_half(tmp2); break;
6303 default: abort();
6304 }
6305 neon_store_reg(rd, pass * 2, tmp2);
6306 }
6307 }
6308 break;
6309 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6310 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6311 for (pass = 0; pass < q + 1; pass++) {
6312 tmp = neon_load_reg(rm, pass * 2);
6313 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6314 tmp = neon_load_reg(rm, pass * 2 + 1);
6315 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6316 switch (size) {
6317 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6318 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6319 case 2: tcg_gen_add_i64(CPU_V001); break;
6320 default: abort();
6321 }
6322 if (op >= NEON_2RM_VPADAL) {
6323 /* Accumulate. */
6324 neon_load_reg64(cpu_V1, rd + pass);
6325 gen_neon_addl(size);
6326 }
6327 neon_store_reg64(cpu_V0, rd + pass);
6328 }
6329 break;
6330 case NEON_2RM_VTRN:
6331 if (size == 2) {
6332 int n;
6333 for (n = 0; n < (q ? 4 : 2); n += 2) {
6334 tmp = neon_load_reg(rm, n);
6335 tmp2 = neon_load_reg(rd, n + 1);
6336 neon_store_reg(rm, n, tmp2);
6337 neon_store_reg(rd, n + 1, tmp);
6338 }
6339 } else {
6340 goto elementwise;
6341 }
6342 break;
6343 case NEON_2RM_VUZP:
6344 if (gen_neon_unzip(rd, rm, size, q)) {
6345 return 1;
6346 }
6347 break;
6348 case NEON_2RM_VZIP:
6349 if (gen_neon_zip(rd, rm, size, q)) {
6350 return 1;
6351 }
6352 break;
6353 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6354 /* also VQMOVUN; op field and mnemonics don't line up */
6355 if (rm & 1) {
6356 return 1;
6357 }
6358 tmp2 = NULL;
6359 for (pass = 0; pass < 2; pass++) {
6360 neon_load_reg64(cpu_V0, rm + pass);
6361 tmp = tcg_temp_new_i32();
6362 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6363 tmp, cpu_V0);
6364 if (pass == 0) {
6365 tmp2 = tmp;
6366 } else {
6367 neon_store_reg(rd, 0, tmp2);
6368 neon_store_reg(rd, 1, tmp);
6369 }
6370 }
6371 break;
6372 case NEON_2RM_VSHLL:
6373 if (q || (rd & 1)) {
6374 return 1;
6375 }
6376 tmp = neon_load_reg(rm, 0);
6377 tmp2 = neon_load_reg(rm, 1);
6378 for (pass = 0; pass < 2; pass++) {
6379 if (pass == 1)
6380 tmp = tmp2;
6381 gen_neon_widen(cpu_V0, tmp, size, 1);
6382 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6383 neon_store_reg64(cpu_V0, rd + pass);
6384 }
6385 break;
6386 case NEON_2RM_VCVT_F16_F32:
6387 {
6388 TCGv_ptr fpst;
6389 TCGv_i32 ahp;
6390
6391 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6392 q || (rm & 1)) {
6393 return 1;
6394 }
6395 fpst = get_fpstatus_ptr(true);
6396 ahp = get_ahp_flag();
6397 tmp = neon_load_reg(rm, 0);
6398 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6399 tmp2 = neon_load_reg(rm, 1);
6400 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6401 tcg_gen_shli_i32(tmp2, tmp2, 16);
6402 tcg_gen_or_i32(tmp2, tmp2, tmp);
6403 tcg_temp_free_i32(tmp);
6404 tmp = neon_load_reg(rm, 2);
6405 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6406 tmp3 = neon_load_reg(rm, 3);
6407 neon_store_reg(rd, 0, tmp2);
6408 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6409 tcg_gen_shli_i32(tmp3, tmp3, 16);
6410 tcg_gen_or_i32(tmp3, tmp3, tmp);
6411 neon_store_reg(rd, 1, tmp3);
6412 tcg_temp_free_i32(tmp);
6413 tcg_temp_free_i32(ahp);
6414 tcg_temp_free_ptr(fpst);
6415 break;
6416 }
6417 case NEON_2RM_VCVT_F32_F16:
6418 {
6419 TCGv_ptr fpst;
6420 TCGv_i32 ahp;
6421 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6422 q || (rd & 1)) {
6423 return 1;
6424 }
6425 fpst = get_fpstatus_ptr(true);
6426 ahp = get_ahp_flag();
6427 tmp3 = tcg_temp_new_i32();
6428 tmp = neon_load_reg(rm, 0);
6429 tmp2 = neon_load_reg(rm, 1);
6430 tcg_gen_ext16u_i32(tmp3, tmp);
6431 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6432 neon_store_reg(rd, 0, tmp3);
6433 tcg_gen_shri_i32(tmp, tmp, 16);
6434 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6435 neon_store_reg(rd, 1, tmp);
6436 tmp3 = tcg_temp_new_i32();
6437 tcg_gen_ext16u_i32(tmp3, tmp2);
6438 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6439 neon_store_reg(rd, 2, tmp3);
6440 tcg_gen_shri_i32(tmp2, tmp2, 16);
6441 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6442 neon_store_reg(rd, 3, tmp2);
6443 tcg_temp_free_i32(ahp);
6444 tcg_temp_free_ptr(fpst);
6445 break;
6446 }
6447 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6448 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6449 return 1;
6450 }
6451 ptr1 = vfp_reg_ptr(true, rd);
6452 ptr2 = vfp_reg_ptr(true, rm);
6453
6454 /* Bit 6 is the lowest opcode bit; it distinguishes between
6455 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6456 */
6457 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6458
6459 if (op == NEON_2RM_AESE) {
6460 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6461 } else {
6462 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6463 }
6464 tcg_temp_free_ptr(ptr1);
6465 tcg_temp_free_ptr(ptr2);
6466 tcg_temp_free_i32(tmp3);
6467 break;
6468 case NEON_2RM_SHA1H:
6469 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6470 return 1;
6471 }
6472 ptr1 = vfp_reg_ptr(true, rd);
6473 ptr2 = vfp_reg_ptr(true, rm);
6474
6475 gen_helper_crypto_sha1h(ptr1, ptr2);
6476
6477 tcg_temp_free_ptr(ptr1);
6478 tcg_temp_free_ptr(ptr2);
6479 break;
6480 case NEON_2RM_SHA1SU1:
6481 if ((rm | rd) & 1) {
6482 return 1;
6483 }
6484 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6485 if (q) {
6486 if (!dc_isar_feature(aa32_sha2, s)) {
6487 return 1;
6488 }
6489 } else if (!dc_isar_feature(aa32_sha1, s)) {
6490 return 1;
6491 }
6492 ptr1 = vfp_reg_ptr(true, rd);
6493 ptr2 = vfp_reg_ptr(true, rm);
6494 if (q) {
6495 gen_helper_crypto_sha256su0(ptr1, ptr2);
6496 } else {
6497 gen_helper_crypto_sha1su1(ptr1, ptr2);
6498 }
6499 tcg_temp_free_ptr(ptr1);
6500 tcg_temp_free_ptr(ptr2);
6501 break;
6502
6503 case NEON_2RM_VMVN:
6504 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6505 break;
6506 case NEON_2RM_VNEG:
6507 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6508 break;
6509 case NEON_2RM_VABS:
6510 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6511 break;
6512
6513 default:
6514 elementwise:
6515 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6516 tmp = neon_load_reg(rm, pass);
6517 switch (op) {
6518 case NEON_2RM_VREV32:
6519 switch (size) {
6520 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6521 case 1: gen_swap_half(tmp); break;
6522 default: abort();
6523 }
6524 break;
6525 case NEON_2RM_VREV16:
6526 gen_rev16(tmp, tmp);
6527 break;
6528 case NEON_2RM_VCLS:
6529 switch (size) {
6530 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6531 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6532 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6533 default: abort();
6534 }
6535 break;
6536 case NEON_2RM_VCLZ:
6537 switch (size) {
6538 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6539 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6540 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6541 default: abort();
6542 }
6543 break;
6544 case NEON_2RM_VCNT:
6545 gen_helper_neon_cnt_u8(tmp, tmp);
6546 break;
6547 case NEON_2RM_VQABS:
6548 switch (size) {
6549 case 0:
6550 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6551 break;
6552 case 1:
6553 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6554 break;
6555 case 2:
6556 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6557 break;
6558 default: abort();
6559 }
6560 break;
6561 case NEON_2RM_VQNEG:
6562 switch (size) {
6563 case 0:
6564 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6565 break;
6566 case 1:
6567 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6568 break;
6569 case 2:
6570 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6571 break;
6572 default: abort();
6573 }
6574 break;
6575 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6576 tmp2 = tcg_const_i32(0);
6577 switch(size) {
6578 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6579 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6580 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6581 default: abort();
6582 }
6583 tcg_temp_free_i32(tmp2);
6584 if (op == NEON_2RM_VCLE0) {
6585 tcg_gen_not_i32(tmp, tmp);
6586 }
6587 break;
6588 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6589 tmp2 = tcg_const_i32(0);
6590 switch(size) {
6591 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6592 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6593 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6594 default: abort();
6595 }
6596 tcg_temp_free_i32(tmp2);
6597 if (op == NEON_2RM_VCLT0) {
6598 tcg_gen_not_i32(tmp, tmp);
6599 }
6600 break;
6601 case NEON_2RM_VCEQ0:
6602 tmp2 = tcg_const_i32(0);
6603 switch(size) {
6604 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6605 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6606 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6607 default: abort();
6608 }
6609 tcg_temp_free_i32(tmp2);
6610 break;
6611 case NEON_2RM_VCGT0_F:
6612 {
6613 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6614 tmp2 = tcg_const_i32(0);
6615 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6616 tcg_temp_free_i32(tmp2);
6617 tcg_temp_free_ptr(fpstatus);
6618 break;
6619 }
6620 case NEON_2RM_VCGE0_F:
6621 {
6622 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6623 tmp2 = tcg_const_i32(0);
6624 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6625 tcg_temp_free_i32(tmp2);
6626 tcg_temp_free_ptr(fpstatus);
6627 break;
6628 }
6629 case NEON_2RM_VCEQ0_F:
6630 {
6631 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6632 tmp2 = tcg_const_i32(0);
6633 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6634 tcg_temp_free_i32(tmp2);
6635 tcg_temp_free_ptr(fpstatus);
6636 break;
6637 }
6638 case NEON_2RM_VCLE0_F:
6639 {
6640 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6641 tmp2 = tcg_const_i32(0);
6642 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6643 tcg_temp_free_i32(tmp2);
6644 tcg_temp_free_ptr(fpstatus);
6645 break;
6646 }
6647 case NEON_2RM_VCLT0_F:
6648 {
6649 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6650 tmp2 = tcg_const_i32(0);
6651 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6652 tcg_temp_free_i32(tmp2);
6653 tcg_temp_free_ptr(fpstatus);
6654 break;
6655 }
6656 case NEON_2RM_VABS_F:
6657 gen_helper_vfp_abss(tmp, tmp);
6658 break;
6659 case NEON_2RM_VNEG_F:
6660 gen_helper_vfp_negs(tmp, tmp);
6661 break;
6662 case NEON_2RM_VSWP:
6663 tmp2 = neon_load_reg(rd, pass);
6664 neon_store_reg(rm, pass, tmp2);
6665 break;
6666 case NEON_2RM_VTRN:
6667 tmp2 = neon_load_reg(rd, pass);
6668 switch (size) {
6669 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6670 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6671 default: abort();
6672 }
6673 neon_store_reg(rm, pass, tmp2);
6674 break;
6675 case NEON_2RM_VRINTN:
6676 case NEON_2RM_VRINTA:
6677 case NEON_2RM_VRINTM:
6678 case NEON_2RM_VRINTP:
6679 case NEON_2RM_VRINTZ:
6680 {
6681 TCGv_i32 tcg_rmode;
6682 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6683 int rmode;
6684
6685 if (op == NEON_2RM_VRINTZ) {
6686 rmode = FPROUNDING_ZERO;
6687 } else {
6688 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6689 }
6690
6691 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6692 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6693 cpu_env);
6694 gen_helper_rints(tmp, tmp, fpstatus);
6695 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6696 cpu_env);
6697 tcg_temp_free_ptr(fpstatus);
6698 tcg_temp_free_i32(tcg_rmode);
6699 break;
6700 }
6701 case NEON_2RM_VRINTX:
6702 {
6703 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6704 gen_helper_rints_exact(tmp, tmp, fpstatus);
6705 tcg_temp_free_ptr(fpstatus);
6706 break;
6707 }
6708 case NEON_2RM_VCVTAU:
6709 case NEON_2RM_VCVTAS:
6710 case NEON_2RM_VCVTNU:
6711 case NEON_2RM_VCVTNS:
6712 case NEON_2RM_VCVTPU:
6713 case NEON_2RM_VCVTPS:
6714 case NEON_2RM_VCVTMU:
6715 case NEON_2RM_VCVTMS:
6716 {
6717 bool is_signed = !extract32(insn, 7, 1);
6718 TCGv_ptr fpst = get_fpstatus_ptr(1);
6719 TCGv_i32 tcg_rmode, tcg_shift;
6720 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6721
6722 tcg_shift = tcg_const_i32(0);
6723 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6724 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6725 cpu_env);
6726
6727 if (is_signed) {
6728 gen_helper_vfp_tosls(tmp, tmp,
6729 tcg_shift, fpst);
6730 } else {
6731 gen_helper_vfp_touls(tmp, tmp,
6732 tcg_shift, fpst);
6733 }
6734
6735 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6736 cpu_env);
6737 tcg_temp_free_i32(tcg_rmode);
6738 tcg_temp_free_i32(tcg_shift);
6739 tcg_temp_free_ptr(fpst);
6740 break;
6741 }
6742 case NEON_2RM_VRECPE:
6743 {
6744 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6745 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6746 tcg_temp_free_ptr(fpstatus);
6747 break;
6748 }
6749 case NEON_2RM_VRSQRTE:
6750 {
6751 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6752 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6753 tcg_temp_free_ptr(fpstatus);
6754 break;
6755 }
6756 case NEON_2RM_VRECPE_F:
6757 {
6758 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6759 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6760 tcg_temp_free_ptr(fpstatus);
6761 break;
6762 }
6763 case NEON_2RM_VRSQRTE_F:
6764 {
6765 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6766 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6767 tcg_temp_free_ptr(fpstatus);
6768 break;
6769 }
6770 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6771 {
6772 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6773 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6774 tcg_temp_free_ptr(fpstatus);
6775 break;
6776 }
6777 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6778 {
6779 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6780 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6781 tcg_temp_free_ptr(fpstatus);
6782 break;
6783 }
6784 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6785 {
6786 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6787 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6788 tcg_temp_free_ptr(fpstatus);
6789 break;
6790 }
6791 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6792 {
6793 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6794 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6795 tcg_temp_free_ptr(fpstatus);
6796 break;
6797 }
6798 default:
6799 /* Reserved op values were caught by the
6800 * neon_2rm_sizes[] check earlier.
6801 */
6802 abort();
6803 }
6804 neon_store_reg(rd, pass, tmp);
6805 }
6806 break;
6807 }
6808 } else if ((insn & (1 << 10)) == 0) {
6809 /* VTBL, VTBX. */
6810 int n = ((insn >> 8) & 3) + 1;
6811 if ((rn + n) > 32) {
6812 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6813 * helper function running off the end of the register file.
6814 */
6815 return 1;
6816 }
6817 n <<= 3;
6818 if (insn & (1 << 6)) {
6819 tmp = neon_load_reg(rd, 0);
6820 } else {
6821 tmp = tcg_temp_new_i32();
6822 tcg_gen_movi_i32(tmp, 0);
6823 }
6824 tmp2 = neon_load_reg(rm, 0);
6825 ptr1 = vfp_reg_ptr(true, rn);
6826 tmp5 = tcg_const_i32(n);
6827 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6828 tcg_temp_free_i32(tmp);
6829 if (insn & (1 << 6)) {
6830 tmp = neon_load_reg(rd, 1);
6831 } else {
6832 tmp = tcg_temp_new_i32();
6833 tcg_gen_movi_i32(tmp, 0);
6834 }
6835 tmp3 = neon_load_reg(rm, 1);
6836 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6837 tcg_temp_free_i32(tmp5);
6838 tcg_temp_free_ptr(ptr1);
6839 neon_store_reg(rd, 0, tmp2);
6840 neon_store_reg(rd, 1, tmp3);
6841 tcg_temp_free_i32(tmp);
6842 } else if ((insn & 0x380) == 0) {
6843 /* VDUP */
6844 int element;
6845 MemOp size;
6846
6847 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6848 return 1;
6849 }
6850 if (insn & (1 << 16)) {
6851 size = MO_8;
6852 element = (insn >> 17) & 7;
6853 } else if (insn & (1 << 17)) {
6854 size = MO_16;
6855 element = (insn >> 18) & 3;
6856 } else {
6857 size = MO_32;
6858 element = (insn >> 19) & 1;
6859 }
6860 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6861 neon_element_offset(rm, element, size),
6862 q ? 16 : 8, q ? 16 : 8);
6863 } else {
6864 return 1;
6865 }
6866 }
6867 }
6868 return 0;
6869 }
6870
6871 /* Advanced SIMD three registers of the same length extension.
6872 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6873 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6874 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6875 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6876 */
6877 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6878 {
6879 gen_helper_gvec_3 *fn_gvec = NULL;
6880 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6881 int rd, rn, rm, opr_sz;
6882 int data = 0;
6883 int off_rn, off_rm;
6884 bool is_long = false, q = extract32(insn, 6, 1);
6885 bool ptr_is_env = false;
6886
6887 if ((insn & 0xfe200f10) == 0xfc200800) {
6888 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6889 int size = extract32(insn, 20, 1);
6890 data = extract32(insn, 23, 2); /* rot */
6891 if (!dc_isar_feature(aa32_vcma, s)
6892 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6893 return 1;
6894 }
6895 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6896 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6897 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6898 int size = extract32(insn, 20, 1);
6899 data = extract32(insn, 24, 1); /* rot */
6900 if (!dc_isar_feature(aa32_vcma, s)
6901 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6902 return 1;
6903 }
6904 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6905 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6906 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6907 bool u = extract32(insn, 4, 1);
6908 if (!dc_isar_feature(aa32_dp, s)) {
6909 return 1;
6910 }
6911 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6912 } else if ((insn & 0xff300f10) == 0xfc200810) {
6913 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6914 int is_s = extract32(insn, 23, 1);
6915 if (!dc_isar_feature(aa32_fhm, s)) {
6916 return 1;
6917 }
6918 is_long = true;
6919 data = is_s; /* is_2 == 0 */
6920 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6921 ptr_is_env = true;
6922 } else {
6923 return 1;
6924 }
6925
6926 VFP_DREG_D(rd, insn);
6927 if (rd & q) {
6928 return 1;
6929 }
6930 if (q || !is_long) {
6931 VFP_DREG_N(rn, insn);
6932 VFP_DREG_M(rm, insn);
6933 if ((rn | rm) & q & !is_long) {
6934 return 1;
6935 }
6936 off_rn = vfp_reg_offset(1, rn);
6937 off_rm = vfp_reg_offset(1, rm);
6938 } else {
6939 rn = VFP_SREG_N(insn);
6940 rm = VFP_SREG_M(insn);
6941 off_rn = vfp_reg_offset(0, rn);
6942 off_rm = vfp_reg_offset(0, rm);
6943 }
6944
6945 if (s->fp_excp_el) {
6946 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6947 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6948 return 0;
6949 }
6950 if (!s->vfp_enabled) {
6951 return 1;
6952 }
6953
6954 opr_sz = (1 + q) * 8;
6955 if (fn_gvec_ptr) {
6956 TCGv_ptr ptr;
6957 if (ptr_is_env) {
6958 ptr = cpu_env;
6959 } else {
6960 ptr = get_fpstatus_ptr(1);
6961 }
6962 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6963 opr_sz, opr_sz, data, fn_gvec_ptr);
6964 if (!ptr_is_env) {
6965 tcg_temp_free_ptr(ptr);
6966 }
6967 } else {
6968 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6969 opr_sz, opr_sz, data, fn_gvec);
6970 }
6971 return 0;
6972 }
6973
6974 /* Advanced SIMD two registers and a scalar extension.
6975 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6976 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6977 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6978 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6979 *
6980 */
6981
6982 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6983 {
6984 gen_helper_gvec_3 *fn_gvec = NULL;
6985 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6986 int rd, rn, rm, opr_sz, data;
6987 int off_rn, off_rm;
6988 bool is_long = false, q = extract32(insn, 6, 1);
6989 bool ptr_is_env = false;
6990
6991 if ((insn & 0xff000f10) == 0xfe000800) {
6992 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6993 int rot = extract32(insn, 20, 2);
6994 int size = extract32(insn, 23, 1);
6995 int index;
6996
6997 if (!dc_isar_feature(aa32_vcma, s)) {
6998 return 1;
6999 }
7000 if (size == 0) {
7001 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7002 return 1;
7003 }
7004 /* For fp16, rm is just Vm, and index is M. */
7005 rm = extract32(insn, 0, 4);
7006 index = extract32(insn, 5, 1);
7007 } else {
7008 /* For fp32, rm is the usual M:Vm, and index is 0. */
7009 VFP_DREG_M(rm, insn);
7010 index = 0;
7011 }
7012 data = (index << 2) | rot;
7013 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7014 : gen_helper_gvec_fcmlah_idx);
7015 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7016 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7017 int u = extract32(insn, 4, 1);
7018
7019 if (!dc_isar_feature(aa32_dp, s)) {
7020 return 1;
7021 }
7022 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7023 /* rm is just Vm, and index is M. */
7024 data = extract32(insn, 5, 1); /* index */
7025 rm = extract32(insn, 0, 4);
7026 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7027 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7028 int is_s = extract32(insn, 20, 1);
7029 int vm20 = extract32(insn, 0, 3);
7030 int vm3 = extract32(insn, 3, 1);
7031 int m = extract32(insn, 5, 1);
7032 int index;
7033
7034 if (!dc_isar_feature(aa32_fhm, s)) {
7035 return 1;
7036 }
7037 if (q) {
7038 rm = vm20;
7039 index = m * 2 + vm3;
7040 } else {
7041 rm = vm20 * 2 + m;
7042 index = vm3;
7043 }
7044 is_long = true;
7045 data = (index << 2) | is_s; /* is_2 == 0 */
7046 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7047 ptr_is_env = true;
7048 } else {
7049 return 1;
7050 }
7051
7052 VFP_DREG_D(rd, insn);
7053 if (rd & q) {
7054 return 1;
7055 }
7056 if (q || !is_long) {
7057 VFP_DREG_N(rn, insn);
7058 if (rn & q & !is_long) {
7059 return 1;
7060 }
7061 off_rn = vfp_reg_offset(1, rn);
7062 off_rm = vfp_reg_offset(1, rm);
7063 } else {
7064 rn = VFP_SREG_N(insn);
7065 off_rn = vfp_reg_offset(0, rn);
7066 off_rm = vfp_reg_offset(0, rm);
7067 }
7068 if (s->fp_excp_el) {
7069 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7070 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7071 return 0;
7072 }
7073 if (!s->vfp_enabled) {
7074 return 1;
7075 }
7076
7077 opr_sz = (1 + q) * 8;
7078 if (fn_gvec_ptr) {
7079 TCGv_ptr ptr;
7080 if (ptr_is_env) {
7081 ptr = cpu_env;
7082 } else {
7083 ptr = get_fpstatus_ptr(1);
7084 }
7085 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7086 opr_sz, opr_sz, data, fn_gvec_ptr);
7087 if (!ptr_is_env) {
7088 tcg_temp_free_ptr(ptr);
7089 }
7090 } else {
7091 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7092 opr_sz, opr_sz, data, fn_gvec);
7093 }
7094 return 0;
7095 }
7096
7097 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7098 {
7099 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7100 const ARMCPRegInfo *ri;
7101
7102 cpnum = (insn >> 8) & 0xf;
7103
7104 /* First check for coprocessor space used for XScale/iwMMXt insns */
7105 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7106 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7107 return 1;
7108 }
7109 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7110 return disas_iwmmxt_insn(s, insn);
7111 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7112 return disas_dsp_insn(s, insn);
7113 }
7114 return 1;
7115 }
7116
7117 /* Otherwise treat as a generic register access */
7118 is64 = (insn & (1 << 25)) == 0;
7119 if (!is64 && ((insn & (1 << 4)) == 0)) {
7120 /* cdp */
7121 return 1;
7122 }
7123
7124 crm = insn & 0xf;
7125 if (is64) {
7126 crn = 0;
7127 opc1 = (insn >> 4) & 0xf;
7128 opc2 = 0;
7129 rt2 = (insn >> 16) & 0xf;
7130 } else {
7131 crn = (insn >> 16) & 0xf;
7132 opc1 = (insn >> 21) & 7;
7133 opc2 = (insn >> 5) & 7;
7134 rt2 = 0;
7135 }
7136 isread = (insn >> 20) & 1;
7137 rt = (insn >> 12) & 0xf;
7138
7139 ri = get_arm_cp_reginfo(s->cp_regs,
7140 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7141 if (ri) {
7142 bool need_exit_tb;
7143
7144 /* Check access permissions */
7145 if (!cp_access_ok(s->current_el, ri, isread)) {
7146 return 1;
7147 }
7148
7149 if (s->hstr_active || ri->accessfn ||
7150 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7151 /* Emit code to perform further access permissions checks at
7152 * runtime; this may result in an exception.
7153 * Note that on XScale all cp0..c13 registers do an access check
7154 * call in order to handle c15_cpar.
7155 */
7156 TCGv_ptr tmpptr;
7157 TCGv_i32 tcg_syn, tcg_isread;
7158 uint32_t syndrome;
7159
7160 /* Note that since we are an implementation which takes an
7161 * exception on a trapped conditional instruction only if the
7162 * instruction passes its condition code check, we can take
7163 * advantage of the clause in the ARM ARM that allows us to set
7164 * the COND field in the instruction to 0xE in all cases.
7165 * We could fish the actual condition out of the insn (ARM)
7166 * or the condexec bits (Thumb) but it isn't necessary.
7167 */
7168 switch (cpnum) {
7169 case 14:
7170 if (is64) {
7171 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7172 isread, false);
7173 } else {
7174 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7175 rt, isread, false);
7176 }
7177 break;
7178 case 15:
7179 if (is64) {
7180 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7181 isread, false);
7182 } else {
7183 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7184 rt, isread, false);
7185 }
7186 break;
7187 default:
7188 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7189 * so this can only happen if this is an ARMv7 or earlier CPU,
7190 * in which case the syndrome information won't actually be
7191 * guest visible.
7192 */
7193 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7194 syndrome = syn_uncategorized();
7195 break;
7196 }
7197
7198 gen_set_condexec(s);
7199 gen_set_pc_im(s, s->pc_curr);
7200 tmpptr = tcg_const_ptr(ri);
7201 tcg_syn = tcg_const_i32(syndrome);
7202 tcg_isread = tcg_const_i32(isread);
7203 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7204 tcg_isread);
7205 tcg_temp_free_ptr(tmpptr);
7206 tcg_temp_free_i32(tcg_syn);
7207 tcg_temp_free_i32(tcg_isread);
7208 } else if (ri->type & ARM_CP_RAISES_EXC) {
7209 /*
7210 * The readfn or writefn might raise an exception;
7211 * synchronize the CPU state in case it does.
7212 */
7213 gen_set_condexec(s);
7214 gen_set_pc_im(s, s->pc_curr);
7215 }
7216
7217 /* Handle special cases first */
7218 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7219 case ARM_CP_NOP:
7220 return 0;
7221 case ARM_CP_WFI:
7222 if (isread) {
7223 return 1;
7224 }
7225 gen_set_pc_im(s, s->base.pc_next);
7226 s->base.is_jmp = DISAS_WFI;
7227 return 0;
7228 default:
7229 break;
7230 }
7231
7232 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7233 gen_io_start();
7234 }
7235
7236 if (isread) {
7237 /* Read */
7238 if (is64) {
7239 TCGv_i64 tmp64;
7240 TCGv_i32 tmp;
7241 if (ri->type & ARM_CP_CONST) {
7242 tmp64 = tcg_const_i64(ri->resetvalue);
7243 } else if (ri->readfn) {
7244 TCGv_ptr tmpptr;
7245 tmp64 = tcg_temp_new_i64();
7246 tmpptr = tcg_const_ptr(ri);
7247 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7248 tcg_temp_free_ptr(tmpptr);
7249 } else {
7250 tmp64 = tcg_temp_new_i64();
7251 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7252 }
7253 tmp = tcg_temp_new_i32();
7254 tcg_gen_extrl_i64_i32(tmp, tmp64);
7255 store_reg(s, rt, tmp);
7256 tmp = tcg_temp_new_i32();
7257 tcg_gen_extrh_i64_i32(tmp, tmp64);
7258 tcg_temp_free_i64(tmp64);
7259 store_reg(s, rt2, tmp);
7260 } else {
7261 TCGv_i32 tmp;
7262 if (ri->type & ARM_CP_CONST) {
7263 tmp = tcg_const_i32(ri->resetvalue);
7264 } else if (ri->readfn) {
7265 TCGv_ptr tmpptr;
7266 tmp = tcg_temp_new_i32();
7267 tmpptr = tcg_const_ptr(ri);
7268 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7269 tcg_temp_free_ptr(tmpptr);
7270 } else {
7271 tmp = load_cpu_offset(ri->fieldoffset);
7272 }
7273 if (rt == 15) {
7274 /* Destination register of r15 for 32 bit loads sets
7275 * the condition codes from the high 4 bits of the value
7276 */
7277 gen_set_nzcv(tmp);
7278 tcg_temp_free_i32(tmp);
7279 } else {
7280 store_reg(s, rt, tmp);
7281 }
7282 }
7283 } else {
7284 /* Write */
7285 if (ri->type & ARM_CP_CONST) {
7286 /* If not forbidden by access permissions, treat as WI */
7287 return 0;
7288 }
7289
7290 if (is64) {
7291 TCGv_i32 tmplo, tmphi;
7292 TCGv_i64 tmp64 = tcg_temp_new_i64();
7293 tmplo = load_reg(s, rt);
7294 tmphi = load_reg(s, rt2);
7295 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7296 tcg_temp_free_i32(tmplo);
7297 tcg_temp_free_i32(tmphi);
7298 if (ri->writefn) {
7299 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7300 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7301 tcg_temp_free_ptr(tmpptr);
7302 } else {
7303 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7304 }
7305 tcg_temp_free_i64(tmp64);
7306 } else {
7307 if (ri->writefn) {
7308 TCGv_i32 tmp;
7309 TCGv_ptr tmpptr;
7310 tmp = load_reg(s, rt);
7311 tmpptr = tcg_const_ptr(ri);
7312 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7313 tcg_temp_free_ptr(tmpptr);
7314 tcg_temp_free_i32(tmp);
7315 } else {
7316 TCGv_i32 tmp = load_reg(s, rt);
7317 store_cpu_offset(tmp, ri->fieldoffset);
7318 }
7319 }
7320 }
7321
7322 /* I/O operations must end the TB here (whether read or write) */
7323 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
7324 (ri->type & ARM_CP_IO));
7325
7326 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7327 /*
7328 * A write to any coprocessor regiser that ends a TB
7329 * must rebuild the hflags for the next TB.
7330 */
7331 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
7332 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7333 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
7334 } else {
7335 if (ri->type & ARM_CP_NEWEL) {
7336 gen_helper_rebuild_hflags_a32_newel(cpu_env);
7337 } else {
7338 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
7339 }
7340 }
7341 tcg_temp_free_i32(tcg_el);
7342 /*
7343 * We default to ending the TB on a coprocessor register write,
7344 * but allow this to be suppressed by the register definition
7345 * (usually only necessary to work around guest bugs).
7346 */
7347 need_exit_tb = true;
7348 }
7349 if (need_exit_tb) {
7350 gen_lookup_tb(s);
7351 }
7352
7353 return 0;
7354 }
7355
7356 /* Unknown register; this might be a guest error or a QEMU
7357 * unimplemented feature.
7358 */
7359 if (is64) {
7360 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7361 "64 bit system register cp:%d opc1: %d crm:%d "
7362 "(%s)\n",
7363 isread ? "read" : "write", cpnum, opc1, crm,
7364 s->ns ? "non-secure" : "secure");
7365 } else {
7366 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7367 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7368 "(%s)\n",
7369 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7370 s->ns ? "non-secure" : "secure");
7371 }
7372
7373 return 1;
7374 }
7375
7376
7377 /* Store a 64-bit value to a register pair. Clobbers val. */
7378 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7379 {
7380 TCGv_i32 tmp;
7381 tmp = tcg_temp_new_i32();
7382 tcg_gen_extrl_i64_i32(tmp, val);
7383 store_reg(s, rlow, tmp);
7384 tmp = tcg_temp_new_i32();
7385 tcg_gen_extrh_i64_i32(tmp, val);
7386 store_reg(s, rhigh, tmp);
7387 }
7388
7389 /* load and add a 64-bit value from a register pair. */
7390 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7391 {
7392 TCGv_i64 tmp;
7393 TCGv_i32 tmpl;
7394 TCGv_i32 tmph;
7395
7396 /* Load 64-bit value rd:rn. */
7397 tmpl = load_reg(s, rlow);
7398 tmph = load_reg(s, rhigh);
7399 tmp = tcg_temp_new_i64();
7400 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7401 tcg_temp_free_i32(tmpl);
7402 tcg_temp_free_i32(tmph);
7403 tcg_gen_add_i64(val, val, tmp);
7404 tcg_temp_free_i64(tmp);
7405 }
7406
7407 /* Set N and Z flags from hi|lo. */
7408 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7409 {
7410 tcg_gen_mov_i32(cpu_NF, hi);
7411 tcg_gen_or_i32(cpu_ZF, lo, hi);
7412 }
7413
7414 /* Load/Store exclusive instructions are implemented by remembering
7415 the value/address loaded, and seeing if these are the same
7416 when the store is performed. This should be sufficient to implement
7417 the architecturally mandated semantics, and avoids having to monitor
7418 regular stores. The compare vs the remembered value is done during
7419 the cmpxchg operation, but we must compare the addresses manually. */
7420 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7421 TCGv_i32 addr, int size)
7422 {
7423 TCGv_i32 tmp = tcg_temp_new_i32();
7424 MemOp opc = size | MO_ALIGN | s->be_data;
7425
7426 s->is_ldex = true;
7427
7428 if (size == 3) {
7429 TCGv_i32 tmp2 = tcg_temp_new_i32();
7430 TCGv_i64 t64 = tcg_temp_new_i64();
7431
7432 /* For AArch32, architecturally the 32-bit word at the lowest
7433 * address is always Rt and the one at addr+4 is Rt2, even if
7434 * the CPU is big-endian. That means we don't want to do a
7435 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7436 * for an architecturally 64-bit access, but instead do a
7437 * 64-bit access using MO_BE if appropriate and then split
7438 * the two halves.
7439 * This only makes a difference for BE32 user-mode, where
7440 * frob64() must not flip the two halves of the 64-bit data
7441 * but this code must treat BE32 user-mode like BE32 system.
7442 */
7443 TCGv taddr = gen_aa32_addr(s, addr, opc);
7444
7445 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7446 tcg_temp_free(taddr);
7447 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7448 if (s->be_data == MO_BE) {
7449 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7450 } else {
7451 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7452 }
7453 tcg_temp_free_i64(t64);
7454
7455 store_reg(s, rt2, tmp2);
7456 } else {
7457 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7458 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7459 }
7460
7461 store_reg(s, rt, tmp);
7462 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7463 }
7464
7465 static void gen_clrex(DisasContext *s)
7466 {
7467 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7468 }
7469
7470 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7471 TCGv_i32 addr, int size)
7472 {
7473 TCGv_i32 t0, t1, t2;
7474 TCGv_i64 extaddr;
7475 TCGv taddr;
7476 TCGLabel *done_label;
7477 TCGLabel *fail_label;
7478 MemOp opc = size | MO_ALIGN | s->be_data;
7479
7480 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7481 [addr] = {Rt};
7482 {Rd} = 0;
7483 } else {
7484 {Rd} = 1;
7485 } */
7486 fail_label = gen_new_label();
7487 done_label = gen_new_label();
7488 extaddr = tcg_temp_new_i64();
7489 tcg_gen_extu_i32_i64(extaddr, addr);
7490 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7491 tcg_temp_free_i64(extaddr);
7492
7493 taddr = gen_aa32_addr(s, addr, opc);
7494 t0 = tcg_temp_new_i32();
7495 t1 = load_reg(s, rt);
7496 if (size == 3) {
7497 TCGv_i64 o64 = tcg_temp_new_i64();
7498 TCGv_i64 n64 = tcg_temp_new_i64();
7499
7500 t2 = load_reg(s, rt2);
7501 /* For AArch32, architecturally the 32-bit word at the lowest
7502 * address is always Rt and the one at addr+4 is Rt2, even if
7503 * the CPU is big-endian. Since we're going to treat this as a
7504 * single 64-bit BE store, we need to put the two halves in the
7505 * opposite order for BE to LE, so that they end up in the right
7506 * places.
7507 * We don't want gen_aa32_frob64() because that does the wrong
7508 * thing for BE32 usermode.
7509 */
7510 if (s->be_data == MO_BE) {
7511 tcg_gen_concat_i32_i64(n64, t2, t1);
7512 } else {
7513 tcg_gen_concat_i32_i64(n64, t1, t2);
7514 }
7515 tcg_temp_free_i32(t2);
7516
7517 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7518 get_mem_index(s), opc);
7519 tcg_temp_free_i64(n64);
7520
7521 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7522 tcg_gen_extrl_i64_i32(t0, o64);
7523
7524 tcg_temp_free_i64(o64);
7525 } else {
7526 t2 = tcg_temp_new_i32();
7527 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7528 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7529 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7530 tcg_temp_free_i32(t2);
7531 }
7532 tcg_temp_free_i32(t1);
7533 tcg_temp_free(taddr);
7534 tcg_gen_mov_i32(cpu_R[rd], t0);
7535 tcg_temp_free_i32(t0);
7536 tcg_gen_br(done_label);
7537
7538 gen_set_label(fail_label);
7539 tcg_gen_movi_i32(cpu_R[rd], 1);
7540 gen_set_label(done_label);
7541 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7542 }
7543
7544 /* gen_srs:
7545 * @env: CPUARMState
7546 * @s: DisasContext
7547 * @mode: mode field from insn (which stack to store to)
7548 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7549 * @writeback: true if writeback bit set
7550 *
7551 * Generate code for the SRS (Store Return State) insn.
7552 */
7553 static void gen_srs(DisasContext *s,
7554 uint32_t mode, uint32_t amode, bool writeback)
7555 {
7556 int32_t offset;
7557 TCGv_i32 addr, tmp;
7558 bool undef = false;
7559
7560 /* SRS is:
7561 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7562 * and specified mode is monitor mode
7563 * - UNDEFINED in Hyp mode
7564 * - UNPREDICTABLE in User or System mode
7565 * - UNPREDICTABLE if the specified mode is:
7566 * -- not implemented
7567 * -- not a valid mode number
7568 * -- a mode that's at a higher exception level
7569 * -- Monitor, if we are Non-secure
7570 * For the UNPREDICTABLE cases we choose to UNDEF.
7571 */
7572 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7573 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7574 return;
7575 }
7576
7577 if (s->current_el == 0 || s->current_el == 2) {
7578 undef = true;
7579 }
7580
7581 switch (mode) {
7582 case ARM_CPU_MODE_USR:
7583 case ARM_CPU_MODE_FIQ:
7584 case ARM_CPU_MODE_IRQ:
7585 case ARM_CPU_MODE_SVC:
7586 case ARM_CPU_MODE_ABT:
7587 case ARM_CPU_MODE_UND:
7588 case ARM_CPU_MODE_SYS:
7589 break;
7590 case ARM_CPU_MODE_HYP:
7591 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7592 undef = true;
7593 }
7594 break;
7595 case ARM_CPU_MODE_MON:
7596 /* No need to check specifically for "are we non-secure" because
7597 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7598 * so if this isn't EL3 then we must be non-secure.
7599 */
7600 if (s->current_el != 3) {
7601 undef = true;
7602 }
7603 break;
7604 default:
7605 undef = true;
7606 }
7607
7608 if (undef) {
7609 unallocated_encoding(s);
7610 return;
7611 }
7612
7613 addr = tcg_temp_new_i32();
7614 tmp = tcg_const_i32(mode);
7615 /* get_r13_banked() will raise an exception if called from System mode */
7616 gen_set_condexec(s);
7617 gen_set_pc_im(s, s->pc_curr);
7618 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7619 tcg_temp_free_i32(tmp);
7620 switch (amode) {
7621 case 0: /* DA */
7622 offset = -4;
7623 break;
7624 case 1: /* IA */
7625 offset = 0;
7626 break;
7627 case 2: /* DB */
7628 offset = -8;
7629 break;
7630 case 3: /* IB */
7631 offset = 4;
7632 break;
7633 default:
7634 abort();
7635 }
7636 tcg_gen_addi_i32(addr, addr, offset);
7637 tmp = load_reg(s, 14);
7638 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7639 tcg_temp_free_i32(tmp);
7640 tmp = load_cpu_field(spsr);
7641 tcg_gen_addi_i32(addr, addr, 4);
7642 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7643 tcg_temp_free_i32(tmp);
7644 if (writeback) {
7645 switch (amode) {
7646 case 0:
7647 offset = -8;
7648 break;
7649 case 1:
7650 offset = 4;
7651 break;
7652 case 2:
7653 offset = -4;
7654 break;
7655 case 3:
7656 offset = 0;
7657 break;
7658 default:
7659 abort();
7660 }
7661 tcg_gen_addi_i32(addr, addr, offset);
7662 tmp = tcg_const_i32(mode);
7663 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7664 tcg_temp_free_i32(tmp);
7665 }
7666 tcg_temp_free_i32(addr);
7667 s->base.is_jmp = DISAS_UPDATE;
7668 }
7669
7670 /* Generate a label used for skipping this instruction */
7671 static void arm_gen_condlabel(DisasContext *s)
7672 {
7673 if (!s->condjmp) {
7674 s->condlabel = gen_new_label();
7675 s->condjmp = 1;
7676 }
7677 }
7678
7679 /* Skip this instruction if the ARM condition is false */
7680 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7681 {
7682 arm_gen_condlabel(s);
7683 arm_gen_test_cc(cond ^ 1, s->condlabel);
7684 }
7685
7686
7687 /*
7688 * Constant expanders for the decoders.
7689 */
7690
7691 static int negate(DisasContext *s, int x)
7692 {
7693 return -x;
7694 }
7695
7696 static int plus_2(DisasContext *s, int x)
7697 {
7698 return x + 2;
7699 }
7700
7701 static int times_2(DisasContext *s, int x)
7702 {
7703 return x * 2;
7704 }
7705
7706 static int times_4(DisasContext *s, int x)
7707 {
7708 return x * 4;
7709 }
7710
7711 /* Return only the rotation part of T32ExpandImm. */
7712 static int t32_expandimm_rot(DisasContext *s, int x)
7713 {
7714 return x & 0xc00 ? extract32(x, 7, 5) : 0;
7715 }
7716
7717 /* Return the unrotated immediate from T32ExpandImm. */
7718 static int t32_expandimm_imm(DisasContext *s, int x)
7719 {
7720 int imm = extract32(x, 0, 8);
7721
7722 switch (extract32(x, 8, 4)) {
7723 case 0: /* XY */
7724 /* Nothing to do. */
7725 break;
7726 case 1: /* 00XY00XY */
7727 imm *= 0x00010001;
7728 break;
7729 case 2: /* XY00XY00 */
7730 imm *= 0x01000100;
7731 break;
7732 case 3: /* XYXYXYXY */
7733 imm *= 0x01010101;
7734 break;
7735 default:
7736 /* Rotated constant. */
7737 imm |= 0x80;
7738 break;
7739 }
7740 return imm;
7741 }
7742
7743 static int t32_branch24(DisasContext *s, int x)
7744 {
7745 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
7746 x ^= !(x < 0) * (3 << 21);
7747 /* Append the final zero. */
7748 return x << 1;
7749 }
7750
7751 static int t16_setflags(DisasContext *s)
7752 {
7753 return s->condexec_mask == 0;
7754 }
7755
7756 static int t16_push_list(DisasContext *s, int x)
7757 {
7758 return (x & 0xff) | (x & 0x100) << (14 - 8);
7759 }
7760
7761 static int t16_pop_list(DisasContext *s, int x)
7762 {
7763 return (x & 0xff) | (x & 0x100) << (15 - 8);
7764 }
7765
7766 /*
7767 * Include the generated decoders.
7768 */
7769
7770 #include "decode-a32.inc.c"
7771 #include "decode-a32-uncond.inc.c"
7772 #include "decode-t32.inc.c"
7773 #include "decode-t16.inc.c"
7774
7775 /* Helpers to swap operands for reverse-subtract. */
7776 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7777 {
7778 tcg_gen_sub_i32(dst, b, a);
7779 }
7780
7781 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7782 {
7783 gen_sub_CC(dst, b, a);
7784 }
7785
7786 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7787 {
7788 gen_sub_carry(dest, b, a);
7789 }
7790
7791 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7792 {
7793 gen_sbc_CC(dest, b, a);
7794 }
7795
7796 /*
7797 * Helpers for the data processing routines.
7798 *
7799 * After the computation store the results back.
7800 * This may be suppressed altogether (STREG_NONE), require a runtime
7801 * check against the stack limits (STREG_SP_CHECK), or generate an
7802 * exception return. Oh, or store into a register.
7803 *
7804 * Always return true, indicating success for a trans_* function.
7805 */
7806 typedef enum {
7807 STREG_NONE,
7808 STREG_NORMAL,
7809 STREG_SP_CHECK,
7810 STREG_EXC_RET,
7811 } StoreRegKind;
7812
7813 static bool store_reg_kind(DisasContext *s, int rd,
7814 TCGv_i32 val, StoreRegKind kind)
7815 {
7816 switch (kind) {
7817 case STREG_NONE:
7818 tcg_temp_free_i32(val);
7819 return true;
7820 case STREG_NORMAL:
7821 /* See ALUWritePC: Interworking only from a32 mode. */
7822 if (s->thumb) {
7823 store_reg(s, rd, val);
7824 } else {
7825 store_reg_bx(s, rd, val);
7826 }
7827 return true;
7828 case STREG_SP_CHECK:
7829 store_sp_checked(s, val);
7830 return true;
7831 case STREG_EXC_RET:
7832 gen_exception_return(s, val);
7833 return true;
7834 }
7835 g_assert_not_reached();
7836 }
7837
7838 /*
7839 * Data Processing (register)
7840 *
7841 * Operate, with set flags, one register source,
7842 * one immediate shifted register source, and a destination.
7843 */
7844 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
7845 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7846 int logic_cc, StoreRegKind kind)
7847 {
7848 TCGv_i32 tmp1, tmp2;
7849
7850 tmp2 = load_reg(s, a->rm);
7851 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
7852 tmp1 = load_reg(s, a->rn);
7853
7854 gen(tmp1, tmp1, tmp2);
7855 tcg_temp_free_i32(tmp2);
7856
7857 if (logic_cc) {
7858 gen_logic_CC(tmp1);
7859 }
7860 return store_reg_kind(s, a->rd, tmp1, kind);
7861 }
7862
7863 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
7864 void (*gen)(TCGv_i32, TCGv_i32),
7865 int logic_cc, StoreRegKind kind)
7866 {
7867 TCGv_i32 tmp;
7868
7869 tmp = load_reg(s, a->rm);
7870 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
7871
7872 gen(tmp, tmp);
7873 if (logic_cc) {
7874 gen_logic_CC(tmp);
7875 }
7876 return store_reg_kind(s, a->rd, tmp, kind);
7877 }
7878
7879 /*
7880 * Data-processing (register-shifted register)
7881 *
7882 * Operate, with set flags, one register source,
7883 * one register shifted register source, and a destination.
7884 */
7885 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
7886 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7887 int logic_cc, StoreRegKind kind)
7888 {
7889 TCGv_i32 tmp1, tmp2;
7890
7891 tmp1 = load_reg(s, a->rs);
7892 tmp2 = load_reg(s, a->rm);
7893 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7894 tmp1 = load_reg(s, a->rn);
7895
7896 gen(tmp1, tmp1, tmp2);
7897 tcg_temp_free_i32(tmp2);
7898
7899 if (logic_cc) {
7900 gen_logic_CC(tmp1);
7901 }
7902 return store_reg_kind(s, a->rd, tmp1, kind);
7903 }
7904
7905 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
7906 void (*gen)(TCGv_i32, TCGv_i32),
7907 int logic_cc, StoreRegKind kind)
7908 {
7909 TCGv_i32 tmp1, tmp2;
7910
7911 tmp1 = load_reg(s, a->rs);
7912 tmp2 = load_reg(s, a->rm);
7913 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7914
7915 gen(tmp2, tmp2);
7916 if (logic_cc) {
7917 gen_logic_CC(tmp2);
7918 }
7919 return store_reg_kind(s, a->rd, tmp2, kind);
7920 }
7921
7922 /*
7923 * Data-processing (immediate)
7924 *
7925 * Operate, with set flags, one register source,
7926 * one rotated immediate, and a destination.
7927 *
7928 * Note that logic_cc && a->rot setting CF based on the msb of the
7929 * immediate is the reason why we must pass in the unrotated form
7930 * of the immediate.
7931 */
7932 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
7933 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7934 int logic_cc, StoreRegKind kind)
7935 {
7936 TCGv_i32 tmp1, tmp2;
7937 uint32_t imm;
7938
7939 imm = ror32(a->imm, a->rot);
7940 if (logic_cc && a->rot) {
7941 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7942 }
7943 tmp2 = tcg_const_i32(imm);
7944 tmp1 = load_reg(s, a->rn);
7945
7946 gen(tmp1, tmp1, tmp2);
7947 tcg_temp_free_i32(tmp2);
7948
7949 if (logic_cc) {
7950 gen_logic_CC(tmp1);
7951 }
7952 return store_reg_kind(s, a->rd, tmp1, kind);
7953 }
7954
7955 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
7956 void (*gen)(TCGv_i32, TCGv_i32),
7957 int logic_cc, StoreRegKind kind)
7958 {
7959 TCGv_i32 tmp;
7960 uint32_t imm;
7961
7962 imm = ror32(a->imm, a->rot);
7963 if (logic_cc && a->rot) {
7964 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7965 }
7966 tmp = tcg_const_i32(imm);
7967
7968 gen(tmp, tmp);
7969 if (logic_cc) {
7970 gen_logic_CC(tmp);
7971 }
7972 return store_reg_kind(s, a->rd, tmp, kind);
7973 }
7974
7975 #define DO_ANY3(NAME, OP, L, K) \
7976 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7977 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7978 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7979 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7980 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7981 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7982
7983 #define DO_ANY2(NAME, OP, L, K) \
7984 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7985 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7986 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7987 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7988 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7989 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7990
7991 #define DO_CMP2(NAME, OP, L) \
7992 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7993 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7994 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7995 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7996 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7997 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7998
7999 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
8000 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
8001 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
8002 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
8003
8004 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
8005 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
8006 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
8007 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
8008
8009 DO_CMP2(TST, tcg_gen_and_i32, true)
8010 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
8011 DO_CMP2(CMN, gen_add_CC, false)
8012 DO_CMP2(CMP, gen_sub_CC, false)
8013
8014 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
8015 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
8016
8017 /*
8018 * Note for the computation of StoreRegKind we return out of the
8019 * middle of the functions that are expanded by DO_ANY3, and that
8020 * we modify a->s via that parameter before it is used by OP.
8021 */
8022 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
8023 ({
8024 StoreRegKind ret = STREG_NORMAL;
8025 if (a->rd == 15 && a->s) {
8026 /*
8027 * See ALUExceptionReturn:
8028 * In User mode, UNPREDICTABLE; we choose UNDEF.
8029 * In Hyp mode, UNDEFINED.
8030 */
8031 if (IS_USER(s) || s->current_el == 2) {
8032 unallocated_encoding(s);
8033 return true;
8034 }
8035 /* There is no writeback of nzcv to PSTATE. */
8036 a->s = 0;
8037 ret = STREG_EXC_RET;
8038 } else if (a->rd == 13 && a->rn == 13) {
8039 ret = STREG_SP_CHECK;
8040 }
8041 ret;
8042 }))
8043
8044 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
8045 ({
8046 StoreRegKind ret = STREG_NORMAL;
8047 if (a->rd == 15 && a->s) {
8048 /*
8049 * See ALUExceptionReturn:
8050 * In User mode, UNPREDICTABLE; we choose UNDEF.
8051 * In Hyp mode, UNDEFINED.
8052 */
8053 if (IS_USER(s) || s->current_el == 2) {
8054 unallocated_encoding(s);
8055 return true;
8056 }
8057 /* There is no writeback of nzcv to PSTATE. */
8058 a->s = 0;
8059 ret = STREG_EXC_RET;
8060 } else if (a->rd == 13) {
8061 ret = STREG_SP_CHECK;
8062 }
8063 ret;
8064 }))
8065
8066 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
8067
8068 /*
8069 * ORN is only available with T32, so there is no register-shifted-register
8070 * form of the insn. Using the DO_ANY3 macro would create an unused function.
8071 */
8072 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
8073 {
8074 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
8075 }
8076
8077 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
8078 {
8079 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
8080 }
8081
8082 #undef DO_ANY3
8083 #undef DO_ANY2
8084 #undef DO_CMP2
8085
8086 static bool trans_ADR(DisasContext *s, arg_ri *a)
8087 {
8088 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
8089 return true;
8090 }
8091
8092 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
8093 {
8094 TCGv_i32 tmp;
8095
8096 if (!ENABLE_ARCH_6T2) {
8097 return false;
8098 }
8099
8100 tmp = tcg_const_i32(a->imm);
8101 store_reg(s, a->rd, tmp);
8102 return true;
8103 }
8104
8105 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
8106 {
8107 TCGv_i32 tmp;
8108
8109 if (!ENABLE_ARCH_6T2) {
8110 return false;
8111 }
8112
8113 tmp = load_reg(s, a->rd);
8114 tcg_gen_ext16u_i32(tmp, tmp);
8115 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
8116 store_reg(s, a->rd, tmp);
8117 return true;
8118 }
8119
8120 /*
8121 * Multiply and multiply accumulate
8122 */
8123
8124 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
8125 {
8126 TCGv_i32 t1, t2;
8127
8128 t1 = load_reg(s, a->rn);
8129 t2 = load_reg(s, a->rm);
8130 tcg_gen_mul_i32(t1, t1, t2);
8131 tcg_temp_free_i32(t2);
8132 if (add) {
8133 t2 = load_reg(s, a->ra);
8134 tcg_gen_add_i32(t1, t1, t2);
8135 tcg_temp_free_i32(t2);
8136 }
8137 if (a->s) {
8138 gen_logic_CC(t1);
8139 }
8140 store_reg(s, a->rd, t1);
8141 return true;
8142 }
8143
8144 static bool trans_MUL(DisasContext *s, arg_MUL *a)
8145 {
8146 return op_mla(s, a, false);
8147 }
8148
8149 static bool trans_MLA(DisasContext *s, arg_MLA *a)
8150 {
8151 return op_mla(s, a, true);
8152 }
8153
8154 static bool trans_MLS(DisasContext *s, arg_MLS *a)
8155 {
8156 TCGv_i32 t1, t2;
8157
8158 if (!ENABLE_ARCH_6T2) {
8159 return false;
8160 }
8161 t1 = load_reg(s, a->rn);
8162 t2 = load_reg(s, a->rm);
8163 tcg_gen_mul_i32(t1, t1, t2);
8164 tcg_temp_free_i32(t2);
8165 t2 = load_reg(s, a->ra);
8166 tcg_gen_sub_i32(t1, t2, t1);
8167 tcg_temp_free_i32(t2);
8168 store_reg(s, a->rd, t1);
8169 return true;
8170 }
8171
8172 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
8173 {
8174 TCGv_i32 t0, t1, t2, t3;
8175
8176 t0 = load_reg(s, a->rm);
8177 t1 = load_reg(s, a->rn);
8178 if (uns) {
8179 tcg_gen_mulu2_i32(t0, t1, t0, t1);
8180 } else {
8181 tcg_gen_muls2_i32(t0, t1, t0, t1);
8182 }
8183 if (add) {
8184 t2 = load_reg(s, a->ra);
8185 t3 = load_reg(s, a->rd);
8186 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
8187 tcg_temp_free_i32(t2);
8188 tcg_temp_free_i32(t3);
8189 }
8190 if (a->s) {
8191 gen_logicq_cc(t0, t1);
8192 }
8193 store_reg(s, a->ra, t0);
8194 store_reg(s, a->rd, t1);
8195 return true;
8196 }
8197
8198 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
8199 {
8200 return op_mlal(s, a, true, false);
8201 }
8202
8203 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
8204 {
8205 return op_mlal(s, a, false, false);
8206 }
8207
8208 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
8209 {
8210 return op_mlal(s, a, true, true);
8211 }
8212
8213 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
8214 {
8215 return op_mlal(s, a, false, true);
8216 }
8217
8218 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
8219 {
8220 TCGv_i32 t0, t1, t2, zero;
8221
8222 if (s->thumb
8223 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8224 : !ENABLE_ARCH_6) {
8225 return false;
8226 }
8227
8228 t0 = load_reg(s, a->rm);
8229 t1 = load_reg(s, a->rn);
8230 tcg_gen_mulu2_i32(t0, t1, t0, t1);
8231 zero = tcg_const_i32(0);
8232 t2 = load_reg(s, a->ra);
8233 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8234 tcg_temp_free_i32(t2);
8235 t2 = load_reg(s, a->rd);
8236 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8237 tcg_temp_free_i32(t2);
8238 tcg_temp_free_i32(zero);
8239 store_reg(s, a->ra, t0);
8240 store_reg(s, a->rd, t1);
8241 return true;
8242 }
8243
8244 /*
8245 * Saturating addition and subtraction
8246 */
8247
8248 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
8249 {
8250 TCGv_i32 t0, t1;
8251
8252 if (s->thumb
8253 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8254 : !ENABLE_ARCH_5TE) {
8255 return false;
8256 }
8257
8258 t0 = load_reg(s, a->rm);
8259 t1 = load_reg(s, a->rn);
8260 if (doub) {
8261 gen_helper_add_saturate(t1, cpu_env, t1, t1);
8262 }
8263 if (add) {
8264 gen_helper_add_saturate(t0, cpu_env, t0, t1);
8265 } else {
8266 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
8267 }
8268 tcg_temp_free_i32(t1);
8269 store_reg(s, a->rd, t0);
8270 return true;
8271 }
8272
8273 #define DO_QADDSUB(NAME, ADD, DOUB) \
8274 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8275 { \
8276 return op_qaddsub(s, a, ADD, DOUB); \
8277 }
8278
8279 DO_QADDSUB(QADD, true, false)
8280 DO_QADDSUB(QSUB, false, false)
8281 DO_QADDSUB(QDADD, true, true)
8282 DO_QADDSUB(QDSUB, false, true)
8283
8284 #undef DO_QADDSUB
8285
8286 /*
8287 * Halfword multiply and multiply accumulate
8288 */
8289
8290 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
8291 int add_long, bool nt, bool mt)
8292 {
8293 TCGv_i32 t0, t1, tl, th;
8294
8295 if (s->thumb
8296 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8297 : !ENABLE_ARCH_5TE) {
8298 return false;
8299 }
8300
8301 t0 = load_reg(s, a->rn);
8302 t1 = load_reg(s, a->rm);
8303 gen_mulxy(t0, t1, nt, mt);
8304 tcg_temp_free_i32(t1);
8305
8306 switch (add_long) {
8307 case 0:
8308 store_reg(s, a->rd, t0);
8309 break;
8310 case 1:
8311 t1 = load_reg(s, a->ra);
8312 gen_helper_add_setq(t0, cpu_env, t0, t1);
8313 tcg_temp_free_i32(t1);
8314 store_reg(s, a->rd, t0);
8315 break;
8316 case 2:
8317 tl = load_reg(s, a->ra);
8318 th = load_reg(s, a->rd);
8319 /* Sign-extend the 32-bit product to 64 bits. */
8320 t1 = tcg_temp_new_i32();
8321 tcg_gen_sari_i32(t1, t0, 31);
8322 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
8323 tcg_temp_free_i32(t0);
8324 tcg_temp_free_i32(t1);
8325 store_reg(s, a->ra, tl);
8326 store_reg(s, a->rd, th);
8327 break;
8328 default:
8329 g_assert_not_reached();
8330 }
8331 return true;
8332 }
8333
8334 #define DO_SMLAX(NAME, add, nt, mt) \
8335 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8336 { \
8337 return op_smlaxxx(s, a, add, nt, mt); \
8338 }
8339
8340 DO_SMLAX(SMULBB, 0, 0, 0)
8341 DO_SMLAX(SMULBT, 0, 0, 1)
8342 DO_SMLAX(SMULTB, 0, 1, 0)
8343 DO_SMLAX(SMULTT, 0, 1, 1)
8344
8345 DO_SMLAX(SMLABB, 1, 0, 0)
8346 DO_SMLAX(SMLABT, 1, 0, 1)
8347 DO_SMLAX(SMLATB, 1, 1, 0)
8348 DO_SMLAX(SMLATT, 1, 1, 1)
8349
8350 DO_SMLAX(SMLALBB, 2, 0, 0)
8351 DO_SMLAX(SMLALBT, 2, 0, 1)
8352 DO_SMLAX(SMLALTB, 2, 1, 0)
8353 DO_SMLAX(SMLALTT, 2, 1, 1)
8354
8355 #undef DO_SMLAX
8356
8357 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
8358 {
8359 TCGv_i32 t0, t1;
8360
8361 if (!ENABLE_ARCH_5TE) {
8362 return false;
8363 }
8364
8365 t0 = load_reg(s, a->rn);
8366 t1 = load_reg(s, a->rm);
8367 /*
8368 * Since the nominal result is product<47:16>, shift the 16-bit
8369 * input up by 16 bits, so that the result is at product<63:32>.
8370 */
8371 if (mt) {
8372 tcg_gen_andi_i32(t1, t1, 0xffff0000);
8373 } else {
8374 tcg_gen_shli_i32(t1, t1, 16);
8375 }
8376 tcg_gen_muls2_i32(t0, t1, t0, t1);
8377 tcg_temp_free_i32(t0);
8378 if (add) {
8379 t0 = load_reg(s, a->ra);
8380 gen_helper_add_setq(t1, cpu_env, t1, t0);
8381 tcg_temp_free_i32(t0);
8382 }
8383 store_reg(s, a->rd, t1);
8384 return true;
8385 }
8386
8387 #define DO_SMLAWX(NAME, add, mt) \
8388 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8389 { \
8390 return op_smlawx(s, a, add, mt); \
8391 }
8392
8393 DO_SMLAWX(SMULWB, 0, 0)
8394 DO_SMLAWX(SMULWT, 0, 1)
8395 DO_SMLAWX(SMLAWB, 1, 0)
8396 DO_SMLAWX(SMLAWT, 1, 1)
8397
8398 #undef DO_SMLAWX
8399
8400 /*
8401 * MSR (immediate) and hints
8402 */
8403
8404 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
8405 {
8406 /*
8407 * When running single-threaded TCG code, use the helper to ensure that
8408 * the next round-robin scheduled vCPU gets a crack. When running in
8409 * MTTCG we don't generate jumps to the helper as it won't affect the
8410 * scheduling of other vCPUs.
8411 */
8412 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8413 gen_set_pc_im(s, s->base.pc_next);
8414 s->base.is_jmp = DISAS_YIELD;
8415 }
8416 return true;
8417 }
8418
8419 static bool trans_WFE(DisasContext *s, arg_WFE *a)
8420 {
8421 /*
8422 * When running single-threaded TCG code, use the helper to ensure that
8423 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
8424 * just skip this instruction. Currently the SEV/SEVL instructions,
8425 * which are *one* of many ways to wake the CPU from WFE, are not
8426 * implemented so we can't sleep like WFI does.
8427 */
8428 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8429 gen_set_pc_im(s, s->base.pc_next);
8430 s->base.is_jmp = DISAS_WFE;
8431 }
8432 return true;
8433 }
8434
8435 static bool trans_WFI(DisasContext *s, arg_WFI *a)
8436 {
8437 /* For WFI, halt the vCPU until an IRQ. */
8438 gen_set_pc_im(s, s->base.pc_next);
8439 s->base.is_jmp = DISAS_WFI;
8440 return true;
8441 }
8442
8443 static bool trans_NOP(DisasContext *s, arg_NOP *a)
8444 {
8445 return true;
8446 }
8447
8448 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
8449 {
8450 uint32_t val = ror32(a->imm, a->rot * 2);
8451 uint32_t mask = msr_mask(s, a->mask, a->r);
8452
8453 if (gen_set_psr_im(s, mask, a->r, val)) {
8454 unallocated_encoding(s);
8455 }
8456 return true;
8457 }
8458
8459 /*
8460 * Cyclic Redundancy Check
8461 */
8462
8463 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
8464 {
8465 TCGv_i32 t1, t2, t3;
8466
8467 if (!dc_isar_feature(aa32_crc32, s)) {
8468 return false;
8469 }
8470
8471 t1 = load_reg(s, a->rn);
8472 t2 = load_reg(s, a->rm);
8473 switch (sz) {
8474 case MO_8:
8475 gen_uxtb(t2);
8476 break;
8477 case MO_16:
8478 gen_uxth(t2);
8479 break;
8480 case MO_32:
8481 break;
8482 default:
8483 g_assert_not_reached();
8484 }
8485 t3 = tcg_const_i32(1 << sz);
8486 if (c) {
8487 gen_helper_crc32c(t1, t1, t2, t3);
8488 } else {
8489 gen_helper_crc32(t1, t1, t2, t3);
8490 }
8491 tcg_temp_free_i32(t2);
8492 tcg_temp_free_i32(t3);
8493 store_reg(s, a->rd, t1);
8494 return true;
8495 }
8496
8497 #define DO_CRC32(NAME, c, sz) \
8498 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8499 { return op_crc32(s, a, c, sz); }
8500
8501 DO_CRC32(CRC32B, false, MO_8)
8502 DO_CRC32(CRC32H, false, MO_16)
8503 DO_CRC32(CRC32W, false, MO_32)
8504 DO_CRC32(CRC32CB, true, MO_8)
8505 DO_CRC32(CRC32CH, true, MO_16)
8506 DO_CRC32(CRC32CW, true, MO_32)
8507
8508 #undef DO_CRC32
8509
8510 /*
8511 * Miscellaneous instructions
8512 */
8513
8514 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
8515 {
8516 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8517 return false;
8518 }
8519 gen_mrs_banked(s, a->r, a->sysm, a->rd);
8520 return true;
8521 }
8522
8523 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
8524 {
8525 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8526 return false;
8527 }
8528 gen_msr_banked(s, a->r, a->sysm, a->rn);
8529 return true;
8530 }
8531
8532 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
8533 {
8534 TCGv_i32 tmp;
8535
8536 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8537 return false;
8538 }
8539 if (a->r) {
8540 if (IS_USER(s)) {
8541 unallocated_encoding(s);
8542 return true;
8543 }
8544 tmp = load_cpu_field(spsr);
8545 } else {
8546 tmp = tcg_temp_new_i32();
8547 gen_helper_cpsr_read(tmp, cpu_env);
8548 }
8549 store_reg(s, a->rd, tmp);
8550 return true;
8551 }
8552
8553 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
8554 {
8555 TCGv_i32 tmp;
8556 uint32_t mask = msr_mask(s, a->mask, a->r);
8557
8558 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8559 return false;
8560 }
8561 tmp = load_reg(s, a->rn);
8562 if (gen_set_psr(s, mask, a->r, tmp)) {
8563 unallocated_encoding(s);
8564 }
8565 return true;
8566 }
8567
8568 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
8569 {
8570 TCGv_i32 tmp;
8571
8572 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8573 return false;
8574 }
8575 tmp = tcg_const_i32(a->sysm);
8576 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
8577 store_reg(s, a->rd, tmp);
8578 return true;
8579 }
8580
8581 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
8582 {
8583 TCGv_i32 addr, reg, el;
8584
8585 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8586 return false;
8587 }
8588 addr = tcg_const_i32((a->mask << 10) | a->sysm);
8589 reg = load_reg(s, a->rn);
8590 gen_helper_v7m_msr(cpu_env, addr, reg);
8591 tcg_temp_free_i32(addr);
8592 tcg_temp_free_i32(reg);
8593 el = tcg_const_i32(s->current_el);
8594 gen_helper_rebuild_hflags_m32(cpu_env, el);
8595 tcg_temp_free_i32(el);
8596 gen_lookup_tb(s);
8597 return true;
8598 }
8599
8600 static bool trans_BX(DisasContext *s, arg_BX *a)
8601 {
8602 if (!ENABLE_ARCH_4T) {
8603 return false;
8604 }
8605 gen_bx_excret(s, load_reg(s, a->rm));
8606 return true;
8607 }
8608
8609 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
8610 {
8611 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
8612 return false;
8613 }
8614 /* Trivial implementation equivalent to bx. */
8615 gen_bx(s, load_reg(s, a->rm));
8616 return true;
8617 }
8618
8619 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
8620 {
8621 TCGv_i32 tmp;
8622
8623 if (!ENABLE_ARCH_5) {
8624 return false;
8625 }
8626 tmp = load_reg(s, a->rm);
8627 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8628 gen_bx(s, tmp);
8629 return true;
8630 }
8631
8632 /*
8633 * BXNS/BLXNS: only exist for v8M with the security extensions,
8634 * and always UNDEF if NonSecure. We don't implement these in
8635 * the user-only mode either (in theory you can use them from
8636 * Secure User mode but they are too tied in to system emulation).
8637 */
8638 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
8639 {
8640 if (!s->v8m_secure || IS_USER_ONLY) {
8641 unallocated_encoding(s);
8642 } else {
8643 gen_bxns(s, a->rm);
8644 }
8645 return true;
8646 }
8647
8648 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
8649 {
8650 if (!s->v8m_secure || IS_USER_ONLY) {
8651 unallocated_encoding(s);
8652 } else {
8653 gen_blxns(s, a->rm);
8654 }
8655 return true;
8656 }
8657
8658 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
8659 {
8660 TCGv_i32 tmp;
8661
8662 if (!ENABLE_ARCH_5) {
8663 return false;
8664 }
8665 tmp = load_reg(s, a->rm);
8666 tcg_gen_clzi_i32(tmp, tmp, 32);
8667 store_reg(s, a->rd, tmp);
8668 return true;
8669 }
8670
8671 static bool trans_ERET(DisasContext *s, arg_ERET *a)
8672 {
8673 TCGv_i32 tmp;
8674
8675 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8676 return false;
8677 }
8678 if (IS_USER(s)) {
8679 unallocated_encoding(s);
8680 return true;
8681 }
8682 if (s->current_el == 2) {
8683 /* ERET from Hyp uses ELR_Hyp, not LR */
8684 tmp = load_cpu_field(elr_el[2]);
8685 } else {
8686 tmp = load_reg(s, 14);
8687 }
8688 gen_exception_return(s, tmp);
8689 return true;
8690 }
8691
8692 static bool trans_HLT(DisasContext *s, arg_HLT *a)
8693 {
8694 gen_hlt(s, a->imm);
8695 return true;
8696 }
8697
8698 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
8699 {
8700 if (!ENABLE_ARCH_5) {
8701 return false;
8702 }
8703 if (arm_dc_feature(s, ARM_FEATURE_M) &&
8704 semihosting_enabled() &&
8705 #ifndef CONFIG_USER_ONLY
8706 !IS_USER(s) &&
8707 #endif
8708 (a->imm == 0xab)) {
8709 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8710 } else {
8711 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
8712 }
8713 return true;
8714 }
8715
8716 static bool trans_HVC(DisasContext *s, arg_HVC *a)
8717 {
8718 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
8719 return false;
8720 }
8721 if (IS_USER(s)) {
8722 unallocated_encoding(s);
8723 } else {
8724 gen_hvc(s, a->imm);
8725 }
8726 return true;
8727 }
8728
8729 static bool trans_SMC(DisasContext *s, arg_SMC *a)
8730 {
8731 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
8732 return false;
8733 }
8734 if (IS_USER(s)) {
8735 unallocated_encoding(s);
8736 } else {
8737 gen_smc(s);
8738 }
8739 return true;
8740 }
8741
8742 static bool trans_SG(DisasContext *s, arg_SG *a)
8743 {
8744 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8745 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8746 return false;
8747 }
8748 /*
8749 * SG (v8M only)
8750 * The bulk of the behaviour for this instruction is implemented
8751 * in v7m_handle_execute_nsc(), which deals with the insn when
8752 * it is executed by a CPU in non-secure state from memory
8753 * which is Secure & NonSecure-Callable.
8754 * Here we only need to handle the remaining cases:
8755 * * in NS memory (including the "security extension not
8756 * implemented" case) : NOP
8757 * * in S memory but CPU already secure (clear IT bits)
8758 * We know that the attribute for the memory this insn is
8759 * in must match the current CPU state, because otherwise
8760 * get_phys_addr_pmsav8 would have generated an exception.
8761 */
8762 if (s->v8m_secure) {
8763 /* Like the IT insn, we don't need to generate any code */
8764 s->condexec_cond = 0;
8765 s->condexec_mask = 0;
8766 }
8767 return true;
8768 }
8769
8770 static bool trans_TT(DisasContext *s, arg_TT *a)
8771 {
8772 TCGv_i32 addr, tmp;
8773
8774 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8775 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8776 return false;
8777 }
8778 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
8779 /* We UNDEF for these UNPREDICTABLE cases */
8780 unallocated_encoding(s);
8781 return true;
8782 }
8783 if (a->A && !s->v8m_secure) {
8784 /* This case is UNDEFINED. */
8785 unallocated_encoding(s);
8786 return true;
8787 }
8788
8789 addr = load_reg(s, a->rn);
8790 tmp = tcg_const_i32((a->A << 1) | a->T);
8791 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
8792 tcg_temp_free_i32(addr);
8793 store_reg(s, a->rd, tmp);
8794 return true;
8795 }
8796
8797 /*
8798 * Load/store register index
8799 */
8800
8801 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
8802 {
8803 ISSInfo ret;
8804
8805 /* ISS not valid if writeback */
8806 if (p && !w) {
8807 ret = rd;
8808 if (s->base.pc_next - s->pc_curr == 2) {
8809 ret |= ISSIs16Bit;
8810 }
8811 } else {
8812 ret = ISSInvalid;
8813 }
8814 return ret;
8815 }
8816
8817 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
8818 {
8819 TCGv_i32 addr = load_reg(s, a->rn);
8820
8821 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8822 gen_helper_v8m_stackcheck(cpu_env, addr);
8823 }
8824
8825 if (a->p) {
8826 TCGv_i32 ofs = load_reg(s, a->rm);
8827 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8828 if (a->u) {
8829 tcg_gen_add_i32(addr, addr, ofs);
8830 } else {
8831 tcg_gen_sub_i32(addr, addr, ofs);
8832 }
8833 tcg_temp_free_i32(ofs);
8834 }
8835 return addr;
8836 }
8837
8838 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
8839 TCGv_i32 addr, int address_offset)
8840 {
8841 if (!a->p) {
8842 TCGv_i32 ofs = load_reg(s, a->rm);
8843 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8844 if (a->u) {
8845 tcg_gen_add_i32(addr, addr, ofs);
8846 } else {
8847 tcg_gen_sub_i32(addr, addr, ofs);
8848 }
8849 tcg_temp_free_i32(ofs);
8850 } else if (!a->w) {
8851 tcg_temp_free_i32(addr);
8852 return;
8853 }
8854 tcg_gen_addi_i32(addr, addr, address_offset);
8855 store_reg(s, a->rn, addr);
8856 }
8857
8858 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
8859 MemOp mop, int mem_idx)
8860 {
8861 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8862 TCGv_i32 addr, tmp;
8863
8864 addr = op_addr_rr_pre(s, a);
8865
8866 tmp = tcg_temp_new_i32();
8867 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8868 disas_set_da_iss(s, mop, issinfo);
8869
8870 /*
8871 * Perform base writeback before the loaded value to
8872 * ensure correct behavior with overlapping index registers.
8873 */
8874 op_addr_rr_post(s, a, addr, 0);
8875 store_reg_from_load(s, a->rt, tmp);
8876 return true;
8877 }
8878
8879 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
8880 MemOp mop, int mem_idx)
8881 {
8882 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8883 TCGv_i32 addr, tmp;
8884
8885 addr = op_addr_rr_pre(s, a);
8886
8887 tmp = load_reg(s, a->rt);
8888 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8889 disas_set_da_iss(s, mop, issinfo);
8890 tcg_temp_free_i32(tmp);
8891
8892 op_addr_rr_post(s, a, addr, 0);
8893 return true;
8894 }
8895
8896 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
8897 {
8898 int mem_idx = get_mem_index(s);
8899 TCGv_i32 addr, tmp;
8900
8901 if (!ENABLE_ARCH_5TE) {
8902 return false;
8903 }
8904 if (a->rt & 1) {
8905 unallocated_encoding(s);
8906 return true;
8907 }
8908 addr = op_addr_rr_pre(s, a);
8909
8910 tmp = tcg_temp_new_i32();
8911 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8912 store_reg(s, a->rt, tmp);
8913
8914 tcg_gen_addi_i32(addr, addr, 4);
8915
8916 tmp = tcg_temp_new_i32();
8917 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8918 store_reg(s, a->rt + 1, tmp);
8919
8920 /* LDRD w/ base writeback is undefined if the registers overlap. */
8921 op_addr_rr_post(s, a, addr, -4);
8922 return true;
8923 }
8924
8925 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
8926 {
8927 int mem_idx = get_mem_index(s);
8928 TCGv_i32 addr, tmp;
8929
8930 if (!ENABLE_ARCH_5TE) {
8931 return false;
8932 }
8933 if (a->rt & 1) {
8934 unallocated_encoding(s);
8935 return true;
8936 }
8937 addr = op_addr_rr_pre(s, a);
8938
8939 tmp = load_reg(s, a->rt);
8940 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8941 tcg_temp_free_i32(tmp);
8942
8943 tcg_gen_addi_i32(addr, addr, 4);
8944
8945 tmp = load_reg(s, a->rt + 1);
8946 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8947 tcg_temp_free_i32(tmp);
8948
8949 op_addr_rr_post(s, a, addr, -4);
8950 return true;
8951 }
8952
8953 /*
8954 * Load/store immediate index
8955 */
8956
8957 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
8958 {
8959 int ofs = a->imm;
8960
8961 if (!a->u) {
8962 ofs = -ofs;
8963 }
8964
8965 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8966 /*
8967 * Stackcheck. Here we know 'addr' is the current SP;
8968 * U is set if we're moving SP up, else down. It is
8969 * UNKNOWN whether the limit check triggers when SP starts
8970 * below the limit and ends up above it; we chose to do so.
8971 */
8972 if (!a->u) {
8973 TCGv_i32 newsp = tcg_temp_new_i32();
8974 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
8975 gen_helper_v8m_stackcheck(cpu_env, newsp);
8976 tcg_temp_free_i32(newsp);
8977 } else {
8978 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
8979 }
8980 }
8981
8982 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
8983 }
8984
8985 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
8986 TCGv_i32 addr, int address_offset)
8987 {
8988 if (!a->p) {
8989 if (a->u) {
8990 address_offset += a->imm;
8991 } else {
8992 address_offset -= a->imm;
8993 }
8994 } else if (!a->w) {
8995 tcg_temp_free_i32(addr);
8996 return;
8997 }
8998 tcg_gen_addi_i32(addr, addr, address_offset);
8999 store_reg(s, a->rn, addr);
9000 }
9001
9002 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
9003 MemOp mop, int mem_idx)
9004 {
9005 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
9006 TCGv_i32 addr, tmp;
9007
9008 addr = op_addr_ri_pre(s, a);
9009
9010 tmp = tcg_temp_new_i32();
9011 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
9012 disas_set_da_iss(s, mop, issinfo);
9013
9014 /*
9015 * Perform base writeback before the loaded value to
9016 * ensure correct behavior with overlapping index registers.
9017 */
9018 op_addr_ri_post(s, a, addr, 0);
9019 store_reg_from_load(s, a->rt, tmp);
9020 return true;
9021 }
9022
9023 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
9024 MemOp mop, int mem_idx)
9025 {
9026 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
9027 TCGv_i32 addr, tmp;
9028
9029 addr = op_addr_ri_pre(s, a);
9030
9031 tmp = load_reg(s, a->rt);
9032 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
9033 disas_set_da_iss(s, mop, issinfo);
9034 tcg_temp_free_i32(tmp);
9035
9036 op_addr_ri_post(s, a, addr, 0);
9037 return true;
9038 }
9039
9040 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
9041 {
9042 int mem_idx = get_mem_index(s);
9043 TCGv_i32 addr, tmp;
9044
9045 addr = op_addr_ri_pre(s, a);
9046
9047 tmp = tcg_temp_new_i32();
9048 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9049 store_reg(s, a->rt, tmp);
9050
9051 tcg_gen_addi_i32(addr, addr, 4);
9052
9053 tmp = tcg_temp_new_i32();
9054 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9055 store_reg(s, rt2, tmp);
9056
9057 /* LDRD w/ base writeback is undefined if the registers overlap. */
9058 op_addr_ri_post(s, a, addr, -4);
9059 return true;
9060 }
9061
9062 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
9063 {
9064 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
9065 return false;
9066 }
9067 return op_ldrd_ri(s, a, a->rt + 1);
9068 }
9069
9070 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
9071 {
9072 arg_ldst_ri b = {
9073 .u = a->u, .w = a->w, .p = a->p,
9074 .rn = a->rn, .rt = a->rt, .imm = a->imm
9075 };
9076 return op_ldrd_ri(s, &b, a->rt2);
9077 }
9078
9079 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
9080 {
9081 int mem_idx = get_mem_index(s);
9082 TCGv_i32 addr, tmp;
9083
9084 addr = op_addr_ri_pre(s, a);
9085
9086 tmp = load_reg(s, a->rt);
9087 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9088 tcg_temp_free_i32(tmp);
9089
9090 tcg_gen_addi_i32(addr, addr, 4);
9091
9092 tmp = load_reg(s, rt2);
9093 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9094 tcg_temp_free_i32(tmp);
9095
9096 op_addr_ri_post(s, a, addr, -4);
9097 return true;
9098 }
9099
9100 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
9101 {
9102 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
9103 return false;
9104 }
9105 return op_strd_ri(s, a, a->rt + 1);
9106 }
9107
9108 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
9109 {
9110 arg_ldst_ri b = {
9111 .u = a->u, .w = a->w, .p = a->p,
9112 .rn = a->rn, .rt = a->rt, .imm = a->imm
9113 };
9114 return op_strd_ri(s, &b, a->rt2);
9115 }
9116
9117 #define DO_LDST(NAME, WHICH, MEMOP) \
9118 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
9119 { \
9120 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
9121 } \
9122 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
9123 { \
9124 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
9125 } \
9126 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
9127 { \
9128 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
9129 } \
9130 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
9131 { \
9132 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
9133 }
9134
9135 DO_LDST(LDR, load, MO_UL)
9136 DO_LDST(LDRB, load, MO_UB)
9137 DO_LDST(LDRH, load, MO_UW)
9138 DO_LDST(LDRSB, load, MO_SB)
9139 DO_LDST(LDRSH, load, MO_SW)
9140
9141 DO_LDST(STR, store, MO_UL)
9142 DO_LDST(STRB, store, MO_UB)
9143 DO_LDST(STRH, store, MO_UW)
9144
9145 #undef DO_LDST
9146
9147 /*
9148 * Synchronization primitives
9149 */
9150
9151 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
9152 {
9153 TCGv_i32 addr, tmp;
9154 TCGv taddr;
9155
9156 opc |= s->be_data;
9157 addr = load_reg(s, a->rn);
9158 taddr = gen_aa32_addr(s, addr, opc);
9159 tcg_temp_free_i32(addr);
9160
9161 tmp = load_reg(s, a->rt2);
9162 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
9163 tcg_temp_free(taddr);
9164
9165 store_reg(s, a->rt, tmp);
9166 return true;
9167 }
9168
9169 static bool trans_SWP(DisasContext *s, arg_SWP *a)
9170 {
9171 return op_swp(s, a, MO_UL | MO_ALIGN);
9172 }
9173
9174 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
9175 {
9176 return op_swp(s, a, MO_UB);
9177 }
9178
9179 /*
9180 * Load/Store Exclusive and Load-Acquire/Store-Release
9181 */
9182
9183 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
9184 {
9185 TCGv_i32 addr;
9186 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
9187 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
9188
9189 /* We UNDEF for these UNPREDICTABLE cases. */
9190 if (a->rd == 15 || a->rn == 15 || a->rt == 15
9191 || a->rd == a->rn || a->rd == a->rt
9192 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
9193 || (mop == MO_64
9194 && (a->rt2 == 15
9195 || a->rd == a->rt2
9196 || (!v8a && s->thumb && a->rt2 == 13)))) {
9197 unallocated_encoding(s);
9198 return true;
9199 }
9200
9201 if (rel) {
9202 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9203 }
9204
9205 addr = tcg_temp_local_new_i32();
9206 load_reg_var(s, addr, a->rn);
9207 tcg_gen_addi_i32(addr, addr, a->imm);
9208
9209 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
9210 tcg_temp_free_i32(addr);
9211 return true;
9212 }
9213
9214 static bool trans_STREX(DisasContext *s, arg_STREX *a)
9215 {
9216 if (!ENABLE_ARCH_6) {
9217 return false;
9218 }
9219 return op_strex(s, a, MO_32, false);
9220 }
9221
9222 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
9223 {
9224 if (!ENABLE_ARCH_6K) {
9225 return false;
9226 }
9227 /* We UNDEF for these UNPREDICTABLE cases. */
9228 if (a->rt & 1) {
9229 unallocated_encoding(s);
9230 return true;
9231 }
9232 a->rt2 = a->rt + 1;
9233 return op_strex(s, a, MO_64, false);
9234 }
9235
9236 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
9237 {
9238 return op_strex(s, a, MO_64, false);
9239 }
9240
9241 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
9242 {
9243 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9244 return false;
9245 }
9246 return op_strex(s, a, MO_8, false);
9247 }
9248
9249 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
9250 {
9251 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9252 return false;
9253 }
9254 return op_strex(s, a, MO_16, false);
9255 }
9256
9257 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
9258 {
9259 if (!ENABLE_ARCH_8) {
9260 return false;
9261 }
9262 return op_strex(s, a, MO_32, true);
9263 }
9264
9265 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
9266 {
9267 if (!ENABLE_ARCH_8) {
9268 return false;
9269 }
9270 /* We UNDEF for these UNPREDICTABLE cases. */
9271 if (a->rt & 1) {
9272 unallocated_encoding(s);
9273 return true;
9274 }
9275 a->rt2 = a->rt + 1;
9276 return op_strex(s, a, MO_64, true);
9277 }
9278
9279 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
9280 {
9281 if (!ENABLE_ARCH_8) {
9282 return false;
9283 }
9284 return op_strex(s, a, MO_64, true);
9285 }
9286
9287 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
9288 {
9289 if (!ENABLE_ARCH_8) {
9290 return false;
9291 }
9292 return op_strex(s, a, MO_8, true);
9293 }
9294
9295 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
9296 {
9297 if (!ENABLE_ARCH_8) {
9298 return false;
9299 }
9300 return op_strex(s, a, MO_16, true);
9301 }
9302
9303 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
9304 {
9305 TCGv_i32 addr, tmp;
9306
9307 if (!ENABLE_ARCH_8) {
9308 return false;
9309 }
9310 /* We UNDEF for these UNPREDICTABLE cases. */
9311 if (a->rn == 15 || a->rt == 15) {
9312 unallocated_encoding(s);
9313 return true;
9314 }
9315
9316 addr = load_reg(s, a->rn);
9317 tmp = load_reg(s, a->rt);
9318 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9319 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9320 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
9321
9322 tcg_temp_free_i32(tmp);
9323 tcg_temp_free_i32(addr);
9324 return true;
9325 }
9326
9327 static bool trans_STL(DisasContext *s, arg_STL *a)
9328 {
9329 return op_stl(s, a, MO_UL);
9330 }
9331
9332 static bool trans_STLB(DisasContext *s, arg_STL *a)
9333 {
9334 return op_stl(s, a, MO_UB);
9335 }
9336
9337 static bool trans_STLH(DisasContext *s, arg_STL *a)
9338 {
9339 return op_stl(s, a, MO_UW);
9340 }
9341
9342 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
9343 {
9344 TCGv_i32 addr;
9345 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
9346 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
9347
9348 /* We UNDEF for these UNPREDICTABLE cases. */
9349 if (a->rn == 15 || a->rt == 15
9350 || (!v8a && s->thumb && a->rt == 13)
9351 || (mop == MO_64
9352 && (a->rt2 == 15 || a->rt == a->rt2
9353 || (!v8a && s->thumb && a->rt2 == 13)))) {
9354 unallocated_encoding(s);
9355 return true;
9356 }
9357
9358 addr = tcg_temp_local_new_i32();
9359 load_reg_var(s, addr, a->rn);
9360 tcg_gen_addi_i32(addr, addr, a->imm);
9361
9362 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
9363 tcg_temp_free_i32(addr);
9364
9365 if (acq) {
9366 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9367 }
9368 return true;
9369 }
9370
9371 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
9372 {
9373 if (!ENABLE_ARCH_6) {
9374 return false;
9375 }
9376 return op_ldrex(s, a, MO_32, false);
9377 }
9378
9379 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
9380 {
9381 if (!ENABLE_ARCH_6K) {
9382 return false;
9383 }
9384 /* We UNDEF for these UNPREDICTABLE cases. */
9385 if (a->rt & 1) {
9386 unallocated_encoding(s);
9387 return true;
9388 }
9389 a->rt2 = a->rt + 1;
9390 return op_ldrex(s, a, MO_64, false);
9391 }
9392
9393 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
9394 {
9395 return op_ldrex(s, a, MO_64, false);
9396 }
9397
9398 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
9399 {
9400 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9401 return false;
9402 }
9403 return op_ldrex(s, a, MO_8, false);
9404 }
9405
9406 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
9407 {
9408 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9409 return false;
9410 }
9411 return op_ldrex(s, a, MO_16, false);
9412 }
9413
9414 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
9415 {
9416 if (!ENABLE_ARCH_8) {
9417 return false;
9418 }
9419 return op_ldrex(s, a, MO_32, true);
9420 }
9421
9422 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
9423 {
9424 if (!ENABLE_ARCH_8) {
9425 return false;
9426 }
9427 /* We UNDEF for these UNPREDICTABLE cases. */
9428 if (a->rt & 1) {
9429 unallocated_encoding(s);
9430 return true;
9431 }
9432 a->rt2 = a->rt + 1;
9433 return op_ldrex(s, a, MO_64, true);
9434 }
9435
9436 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
9437 {
9438 if (!ENABLE_ARCH_8) {
9439 return false;
9440 }
9441 return op_ldrex(s, a, MO_64, true);
9442 }
9443
9444 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
9445 {
9446 if (!ENABLE_ARCH_8) {
9447 return false;
9448 }
9449 return op_ldrex(s, a, MO_8, true);
9450 }
9451
9452 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
9453 {
9454 if (!ENABLE_ARCH_8) {
9455 return false;
9456 }
9457 return op_ldrex(s, a, MO_16, true);
9458 }
9459
9460 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
9461 {
9462 TCGv_i32 addr, tmp;
9463
9464 if (!ENABLE_ARCH_8) {
9465 return false;
9466 }
9467 /* We UNDEF for these UNPREDICTABLE cases. */
9468 if (a->rn == 15 || a->rt == 15) {
9469 unallocated_encoding(s);
9470 return true;
9471 }
9472
9473 addr = load_reg(s, a->rn);
9474 tmp = tcg_temp_new_i32();
9475 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9476 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
9477 tcg_temp_free_i32(addr);
9478
9479 store_reg(s, a->rt, tmp);
9480 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9481 return true;
9482 }
9483
9484 static bool trans_LDA(DisasContext *s, arg_LDA *a)
9485 {
9486 return op_lda(s, a, MO_UL);
9487 }
9488
9489 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
9490 {
9491 return op_lda(s, a, MO_UB);
9492 }
9493
9494 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
9495 {
9496 return op_lda(s, a, MO_UW);
9497 }
9498
9499 /*
9500 * Media instructions
9501 */
9502
9503 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
9504 {
9505 TCGv_i32 t1, t2;
9506
9507 if (!ENABLE_ARCH_6) {
9508 return false;
9509 }
9510
9511 t1 = load_reg(s, a->rn);
9512 t2 = load_reg(s, a->rm);
9513 gen_helper_usad8(t1, t1, t2);
9514 tcg_temp_free_i32(t2);
9515 if (a->ra != 15) {
9516 t2 = load_reg(s, a->ra);
9517 tcg_gen_add_i32(t1, t1, t2);
9518 tcg_temp_free_i32(t2);
9519 }
9520 store_reg(s, a->rd, t1);
9521 return true;
9522 }
9523
9524 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
9525 {
9526 TCGv_i32 tmp;
9527 int width = a->widthm1 + 1;
9528 int shift = a->lsb;
9529
9530 if (!ENABLE_ARCH_6T2) {
9531 return false;
9532 }
9533 if (shift + width > 32) {
9534 /* UNPREDICTABLE; we choose to UNDEF */
9535 unallocated_encoding(s);
9536 return true;
9537 }
9538
9539 tmp = load_reg(s, a->rn);
9540 if (u) {
9541 tcg_gen_extract_i32(tmp, tmp, shift, width);
9542 } else {
9543 tcg_gen_sextract_i32(tmp, tmp, shift, width);
9544 }
9545 store_reg(s, a->rd, tmp);
9546 return true;
9547 }
9548
9549 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
9550 {
9551 return op_bfx(s, a, false);
9552 }
9553
9554 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
9555 {
9556 return op_bfx(s, a, true);
9557 }
9558
9559 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
9560 {
9561 TCGv_i32 tmp;
9562 int msb = a->msb, lsb = a->lsb;
9563 int width;
9564
9565 if (!ENABLE_ARCH_6T2) {
9566 return false;
9567 }
9568 if (msb < lsb) {
9569 /* UNPREDICTABLE; we choose to UNDEF */
9570 unallocated_encoding(s);
9571 return true;
9572 }
9573
9574 width = msb + 1 - lsb;
9575 if (a->rn == 15) {
9576 /* BFC */
9577 tmp = tcg_const_i32(0);
9578 } else {
9579 /* BFI */
9580 tmp = load_reg(s, a->rn);
9581 }
9582 if (width != 32) {
9583 TCGv_i32 tmp2 = load_reg(s, a->rd);
9584 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
9585 tcg_temp_free_i32(tmp2);
9586 }
9587 store_reg(s, a->rd, tmp);
9588 return true;
9589 }
9590
9591 static bool trans_UDF(DisasContext *s, arg_UDF *a)
9592 {
9593 unallocated_encoding(s);
9594 return true;
9595 }
9596
9597 /*
9598 * Parallel addition and subtraction
9599 */
9600
9601 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
9602 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
9603 {
9604 TCGv_i32 t0, t1;
9605
9606 if (s->thumb
9607 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9608 : !ENABLE_ARCH_6) {
9609 return false;
9610 }
9611
9612 t0 = load_reg(s, a->rn);
9613 t1 = load_reg(s, a->rm);
9614
9615 gen(t0, t0, t1);
9616
9617 tcg_temp_free_i32(t1);
9618 store_reg(s, a->rd, t0);
9619 return true;
9620 }
9621
9622 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
9623 void (*gen)(TCGv_i32, TCGv_i32,
9624 TCGv_i32, TCGv_ptr))
9625 {
9626 TCGv_i32 t0, t1;
9627 TCGv_ptr ge;
9628
9629 if (s->thumb
9630 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9631 : !ENABLE_ARCH_6) {
9632 return false;
9633 }
9634
9635 t0 = load_reg(s, a->rn);
9636 t1 = load_reg(s, a->rm);
9637
9638 ge = tcg_temp_new_ptr();
9639 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
9640 gen(t0, t0, t1, ge);
9641
9642 tcg_temp_free_ptr(ge);
9643 tcg_temp_free_i32(t1);
9644 store_reg(s, a->rd, t0);
9645 return true;
9646 }
9647
9648 #define DO_PAR_ADDSUB(NAME, helper) \
9649 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9650 { \
9651 return op_par_addsub(s, a, helper); \
9652 }
9653
9654 #define DO_PAR_ADDSUB_GE(NAME, helper) \
9655 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9656 { \
9657 return op_par_addsub_ge(s, a, helper); \
9658 }
9659
9660 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
9661 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
9662 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
9663 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
9664 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
9665 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
9666
9667 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
9668 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
9669 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
9670 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
9671 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
9672 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
9673
9674 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
9675 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
9676 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
9677 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
9678 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
9679 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
9680
9681 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
9682 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
9683 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
9684 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
9685 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
9686 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
9687
9688 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
9689 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
9690 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
9691 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
9692 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
9693 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
9694
9695 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
9696 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
9697 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
9698 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
9699 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
9700 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
9701
9702 #undef DO_PAR_ADDSUB
9703 #undef DO_PAR_ADDSUB_GE
9704
9705 /*
9706 * Packing, unpacking, saturation, and reversal
9707 */
9708
9709 static bool trans_PKH(DisasContext *s, arg_PKH *a)
9710 {
9711 TCGv_i32 tn, tm;
9712 int shift = a->imm;
9713
9714 if (s->thumb
9715 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9716 : !ENABLE_ARCH_6) {
9717 return false;
9718 }
9719
9720 tn = load_reg(s, a->rn);
9721 tm = load_reg(s, a->rm);
9722 if (a->tb) {
9723 /* PKHTB */
9724 if (shift == 0) {
9725 shift = 31;
9726 }
9727 tcg_gen_sari_i32(tm, tm, shift);
9728 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
9729 } else {
9730 /* PKHBT */
9731 tcg_gen_shli_i32(tm, tm, shift);
9732 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
9733 }
9734 tcg_temp_free_i32(tm);
9735 store_reg(s, a->rd, tn);
9736 return true;
9737 }
9738
9739 static bool op_sat(DisasContext *s, arg_sat *a,
9740 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
9741 {
9742 TCGv_i32 tmp, satimm;
9743 int shift = a->imm;
9744
9745 if (!ENABLE_ARCH_6) {
9746 return false;
9747 }
9748
9749 tmp = load_reg(s, a->rn);
9750 if (a->sh) {
9751 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
9752 } else {
9753 tcg_gen_shli_i32(tmp, tmp, shift);
9754 }
9755
9756 satimm = tcg_const_i32(a->satimm);
9757 gen(tmp, cpu_env, tmp, satimm);
9758 tcg_temp_free_i32(satimm);
9759
9760 store_reg(s, a->rd, tmp);
9761 return true;
9762 }
9763
9764 static bool trans_SSAT(DisasContext *s, arg_sat *a)
9765 {
9766 return op_sat(s, a, gen_helper_ssat);
9767 }
9768
9769 static bool trans_USAT(DisasContext *s, arg_sat *a)
9770 {
9771 return op_sat(s, a, gen_helper_usat);
9772 }
9773
9774 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
9775 {
9776 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9777 return false;
9778 }
9779 return op_sat(s, a, gen_helper_ssat16);
9780 }
9781
9782 static bool trans_USAT16(DisasContext *s, arg_sat *a)
9783 {
9784 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9785 return false;
9786 }
9787 return op_sat(s, a, gen_helper_usat16);
9788 }
9789
9790 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
9791 void (*gen_extract)(TCGv_i32, TCGv_i32),
9792 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
9793 {
9794 TCGv_i32 tmp;
9795
9796 if (!ENABLE_ARCH_6) {
9797 return false;
9798 }
9799
9800 tmp = load_reg(s, a->rm);
9801 /*
9802 * TODO: In many cases we could do a shift instead of a rotate.
9803 * Combined with a simple extend, that becomes an extract.
9804 */
9805 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
9806 gen_extract(tmp, tmp);
9807
9808 if (a->rn != 15) {
9809 TCGv_i32 tmp2 = load_reg(s, a->rn);
9810 gen_add(tmp, tmp, tmp2);
9811 tcg_temp_free_i32(tmp2);
9812 }
9813 store_reg(s, a->rd, tmp);
9814 return true;
9815 }
9816
9817 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
9818 {
9819 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
9820 }
9821
9822 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
9823 {
9824 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
9825 }
9826
9827 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
9828 {
9829 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9830 return false;
9831 }
9832 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
9833 }
9834
9835 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
9836 {
9837 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
9838 }
9839
9840 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
9841 {
9842 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
9843 }
9844
9845 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
9846 {
9847 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9848 return false;
9849 }
9850 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
9851 }
9852
9853 static bool trans_SEL(DisasContext *s, arg_rrr *a)
9854 {
9855 TCGv_i32 t1, t2, t3;
9856
9857 if (s->thumb
9858 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9859 : !ENABLE_ARCH_6) {
9860 return false;
9861 }
9862
9863 t1 = load_reg(s, a->rn);
9864 t2 = load_reg(s, a->rm);
9865 t3 = tcg_temp_new_i32();
9866 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
9867 gen_helper_sel_flags(t1, t3, t1, t2);
9868 tcg_temp_free_i32(t3);
9869 tcg_temp_free_i32(t2);
9870 store_reg(s, a->rd, t1);
9871 return true;
9872 }
9873
9874 static bool op_rr(DisasContext *s, arg_rr *a,
9875 void (*gen)(TCGv_i32, TCGv_i32))
9876 {
9877 TCGv_i32 tmp;
9878
9879 tmp = load_reg(s, a->rm);
9880 gen(tmp, tmp);
9881 store_reg(s, a->rd, tmp);
9882 return true;
9883 }
9884
9885 static bool trans_REV(DisasContext *s, arg_rr *a)
9886 {
9887 if (!ENABLE_ARCH_6) {
9888 return false;
9889 }
9890 return op_rr(s, a, tcg_gen_bswap32_i32);
9891 }
9892
9893 static bool trans_REV16(DisasContext *s, arg_rr *a)
9894 {
9895 if (!ENABLE_ARCH_6) {
9896 return false;
9897 }
9898 return op_rr(s, a, gen_rev16);
9899 }
9900
9901 static bool trans_REVSH(DisasContext *s, arg_rr *a)
9902 {
9903 if (!ENABLE_ARCH_6) {
9904 return false;
9905 }
9906 return op_rr(s, a, gen_revsh);
9907 }
9908
9909 static bool trans_RBIT(DisasContext *s, arg_rr *a)
9910 {
9911 if (!ENABLE_ARCH_6T2) {
9912 return false;
9913 }
9914 return op_rr(s, a, gen_helper_rbit);
9915 }
9916
9917 /*
9918 * Signed multiply, signed and unsigned divide
9919 */
9920
9921 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9922 {
9923 TCGv_i32 t1, t2;
9924
9925 if (!ENABLE_ARCH_6) {
9926 return false;
9927 }
9928
9929 t1 = load_reg(s, a->rn);
9930 t2 = load_reg(s, a->rm);
9931 if (m_swap) {
9932 gen_swap_half(t2);
9933 }
9934 gen_smul_dual(t1, t2);
9935
9936 if (sub) {
9937 /* This subtraction cannot overflow. */
9938 tcg_gen_sub_i32(t1, t1, t2);
9939 } else {
9940 /*
9941 * This addition cannot overflow 32 bits; however it may
9942 * overflow considered as a signed operation, in which case
9943 * we must set the Q flag.
9944 */
9945 gen_helper_add_setq(t1, cpu_env, t1, t2);
9946 }
9947 tcg_temp_free_i32(t2);
9948
9949 if (a->ra != 15) {
9950 t2 = load_reg(s, a->ra);
9951 gen_helper_add_setq(t1, cpu_env, t1, t2);
9952 tcg_temp_free_i32(t2);
9953 }
9954 store_reg(s, a->rd, t1);
9955 return true;
9956 }
9957
9958 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
9959 {
9960 return op_smlad(s, a, false, false);
9961 }
9962
9963 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
9964 {
9965 return op_smlad(s, a, true, false);
9966 }
9967
9968 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
9969 {
9970 return op_smlad(s, a, false, true);
9971 }
9972
9973 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
9974 {
9975 return op_smlad(s, a, true, true);
9976 }
9977
9978 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9979 {
9980 TCGv_i32 t1, t2;
9981 TCGv_i64 l1, l2;
9982
9983 if (!ENABLE_ARCH_6) {
9984 return false;
9985 }
9986
9987 t1 = load_reg(s, a->rn);
9988 t2 = load_reg(s, a->rm);
9989 if (m_swap) {
9990 gen_swap_half(t2);
9991 }
9992 gen_smul_dual(t1, t2);
9993
9994 l1 = tcg_temp_new_i64();
9995 l2 = tcg_temp_new_i64();
9996 tcg_gen_ext_i32_i64(l1, t1);
9997 tcg_gen_ext_i32_i64(l2, t2);
9998 tcg_temp_free_i32(t1);
9999 tcg_temp_free_i32(t2);
10000
10001 if (sub) {
10002 tcg_gen_sub_i64(l1, l1, l2);
10003 } else {
10004 tcg_gen_add_i64(l1, l1, l2);
10005 }
10006 tcg_temp_free_i64(l2);
10007
10008 gen_addq(s, l1, a->ra, a->rd);
10009 gen_storeq_reg(s, a->ra, a->rd, l1);
10010 tcg_temp_free_i64(l1);
10011 return true;
10012 }
10013
10014 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
10015 {
10016 return op_smlald(s, a, false, false);
10017 }
10018
10019 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
10020 {
10021 return op_smlald(s, a, true, false);
10022 }
10023
10024 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
10025 {
10026 return op_smlald(s, a, false, true);
10027 }
10028
10029 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
10030 {
10031 return op_smlald(s, a, true, true);
10032 }
10033
10034 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
10035 {
10036 TCGv_i32 t1, t2;
10037
10038 if (s->thumb
10039 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
10040 : !ENABLE_ARCH_6) {
10041 return false;
10042 }
10043
10044 t1 = load_reg(s, a->rn);
10045 t2 = load_reg(s, a->rm);
10046 tcg_gen_muls2_i32(t2, t1, t1, t2);
10047
10048 if (a->ra != 15) {
10049 TCGv_i32 t3 = load_reg(s, a->ra);
10050 if (sub) {
10051 /*
10052 * For SMMLS, we need a 64-bit subtract. Borrow caused by
10053 * a non-zero multiplicand lowpart, and the correct result
10054 * lowpart for rounding.
10055 */
10056 TCGv_i32 zero = tcg_const_i32(0);
10057 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
10058 tcg_temp_free_i32(zero);
10059 } else {
10060 tcg_gen_add_i32(t1, t1, t3);
10061 }
10062 tcg_temp_free_i32(t3);
10063 }
10064 if (round) {
10065 /*
10066 * Adding 0x80000000 to the 64-bit quantity means that we have
10067 * carry in to the high word when the low word has the msb set.
10068 */
10069 tcg_gen_shri_i32(t2, t2, 31);
10070 tcg_gen_add_i32(t1, t1, t2);
10071 }
10072 tcg_temp_free_i32(t2);
10073 store_reg(s, a->rd, t1);
10074 return true;
10075 }
10076
10077 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
10078 {
10079 return op_smmla(s, a, false, false);
10080 }
10081
10082 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
10083 {
10084 return op_smmla(s, a, true, false);
10085 }
10086
10087 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
10088 {
10089 return op_smmla(s, a, false, true);
10090 }
10091
10092 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
10093 {
10094 return op_smmla(s, a, true, true);
10095 }
10096
10097 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
10098 {
10099 TCGv_i32 t1, t2;
10100
10101 if (s->thumb
10102 ? !dc_isar_feature(aa32_thumb_div, s)
10103 : !dc_isar_feature(aa32_arm_div, s)) {
10104 return false;
10105 }
10106
10107 t1 = load_reg(s, a->rn);
10108 t2 = load_reg(s, a->rm);
10109 if (u) {
10110 gen_helper_udiv(t1, t1, t2);
10111 } else {
10112 gen_helper_sdiv(t1, t1, t2);
10113 }
10114 tcg_temp_free_i32(t2);
10115 store_reg(s, a->rd, t1);
10116 return true;
10117 }
10118
10119 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
10120 {
10121 return op_div(s, a, false);
10122 }
10123
10124 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
10125 {
10126 return op_div(s, a, true);
10127 }
10128
10129 /*
10130 * Block data transfer
10131 */
10132
10133 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
10134 {
10135 TCGv_i32 addr = load_reg(s, a->rn);
10136
10137 if (a->b) {
10138 if (a->i) {
10139 /* pre increment */
10140 tcg_gen_addi_i32(addr, addr, 4);
10141 } else {
10142 /* pre decrement */
10143 tcg_gen_addi_i32(addr, addr, -(n * 4));
10144 }
10145 } else if (!a->i && n != 1) {
10146 /* post decrement */
10147 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10148 }
10149
10150 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
10151 /*
10152 * If the writeback is incrementing SP rather than
10153 * decrementing it, and the initial SP is below the
10154 * stack limit but the final written-back SP would
10155 * be above, then then we must not perform any memory
10156 * accesses, but it is IMPDEF whether we generate
10157 * an exception. We choose to do so in this case.
10158 * At this point 'addr' is the lowest address, so
10159 * either the original SP (if incrementing) or our
10160 * final SP (if decrementing), so that's what we check.
10161 */
10162 gen_helper_v8m_stackcheck(cpu_env, addr);
10163 }
10164
10165 return addr;
10166 }
10167
10168 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
10169 TCGv_i32 addr, int n)
10170 {
10171 if (a->w) {
10172 /* write back */
10173 if (!a->b) {
10174 if (a->i) {
10175 /* post increment */
10176 tcg_gen_addi_i32(addr, addr, 4);
10177 } else {
10178 /* post decrement */
10179 tcg_gen_addi_i32(addr, addr, -(n * 4));
10180 }
10181 } else if (!a->i && n != 1) {
10182 /* pre decrement */
10183 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10184 }
10185 store_reg(s, a->rn, addr);
10186 } else {
10187 tcg_temp_free_i32(addr);
10188 }
10189 }
10190
10191 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
10192 {
10193 int i, j, n, list, mem_idx;
10194 bool user = a->u;
10195 TCGv_i32 addr, tmp, tmp2;
10196
10197 if (user) {
10198 /* STM (user) */
10199 if (IS_USER(s)) {
10200 /* Only usable in supervisor mode. */
10201 unallocated_encoding(s);
10202 return true;
10203 }
10204 }
10205
10206 list = a->list;
10207 n = ctpop16(list);
10208 if (n < min_n || a->rn == 15) {
10209 unallocated_encoding(s);
10210 return true;
10211 }
10212
10213 addr = op_addr_block_pre(s, a, n);
10214 mem_idx = get_mem_index(s);
10215
10216 for (i = j = 0; i < 16; i++) {
10217 if (!(list & (1 << i))) {
10218 continue;
10219 }
10220
10221 if (user && i != 15) {
10222 tmp = tcg_temp_new_i32();
10223 tmp2 = tcg_const_i32(i);
10224 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10225 tcg_temp_free_i32(tmp2);
10226 } else {
10227 tmp = load_reg(s, i);
10228 }
10229 gen_aa32_st32(s, tmp, addr, mem_idx);
10230 tcg_temp_free_i32(tmp);
10231
10232 /* No need to add after the last transfer. */
10233 if (++j != n) {
10234 tcg_gen_addi_i32(addr, addr, 4);
10235 }
10236 }
10237
10238 op_addr_block_post(s, a, addr, n);
10239 return true;
10240 }
10241
10242 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
10243 {
10244 /* BitCount(list) < 1 is UNPREDICTABLE */
10245 return op_stm(s, a, 1);
10246 }
10247
10248 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
10249 {
10250 /* Writeback register in register list is UNPREDICTABLE for T32. */
10251 if (a->w && (a->list & (1 << a->rn))) {
10252 unallocated_encoding(s);
10253 return true;
10254 }
10255 /* BitCount(list) < 2 is UNPREDICTABLE */
10256 return op_stm(s, a, 2);
10257 }
10258
10259 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
10260 {
10261 int i, j, n, list, mem_idx;
10262 bool loaded_base;
10263 bool user = a->u;
10264 bool exc_return = false;
10265 TCGv_i32 addr, tmp, tmp2, loaded_var;
10266
10267 if (user) {
10268 /* LDM (user), LDM (exception return) */
10269 if (IS_USER(s)) {
10270 /* Only usable in supervisor mode. */
10271 unallocated_encoding(s);
10272 return true;
10273 }
10274 if (extract32(a->list, 15, 1)) {
10275 exc_return = true;
10276 user = false;
10277 } else {
10278 /* LDM (user) does not allow writeback. */
10279 if (a->w) {
10280 unallocated_encoding(s);
10281 return true;
10282 }
10283 }
10284 }
10285
10286 list = a->list;
10287 n = ctpop16(list);
10288 if (n < min_n || a->rn == 15) {
10289 unallocated_encoding(s);
10290 return true;
10291 }
10292
10293 addr = op_addr_block_pre(s, a, n);
10294 mem_idx = get_mem_index(s);
10295 loaded_base = false;
10296 loaded_var = NULL;
10297
10298 for (i = j = 0; i < 16; i++) {
10299 if (!(list & (1 << i))) {
10300 continue;
10301 }
10302
10303 tmp = tcg_temp_new_i32();
10304 gen_aa32_ld32u(s, tmp, addr, mem_idx);
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 == a->rn) {
10311 loaded_var = tmp;
10312 loaded_base = true;
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
10319 /* No need to add after the last transfer. */
10320 if (++j != n) {
10321 tcg_gen_addi_i32(addr, addr, 4);
10322 }
10323 }
10324
10325 op_addr_block_post(s, a, addr, n);
10326
10327 if (loaded_base) {
10328 /* Note that we reject base == pc above. */
10329 store_reg(s, a->rn, loaded_var);
10330 }
10331
10332 if (exc_return) {
10333 /* Restore CPSR from SPSR. */
10334 tmp = load_cpu_field(spsr);
10335 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10336 gen_io_start();
10337 }
10338 gen_helper_cpsr_write_eret(cpu_env, tmp);
10339 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10340 gen_io_end();
10341 }
10342 tcg_temp_free_i32(tmp);
10343 /* Must exit loop to check un-masked IRQs */
10344 s->base.is_jmp = DISAS_EXIT;
10345 }
10346 return true;
10347 }
10348
10349 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
10350 {
10351 /*
10352 * Writeback register in register list is UNPREDICTABLE
10353 * for ArchVersion() >= 7. Prior to v7, A32 would write
10354 * an UNKNOWN value to the base register.
10355 */
10356 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
10357 unallocated_encoding(s);
10358 return true;
10359 }
10360 /* BitCount(list) < 1 is UNPREDICTABLE */
10361 return do_ldm(s, a, 1);
10362 }
10363
10364 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
10365 {
10366 /* Writeback register in register list is UNPREDICTABLE for T32. */
10367 if (a->w && (a->list & (1 << a->rn))) {
10368 unallocated_encoding(s);
10369 return true;
10370 }
10371 /* BitCount(list) < 2 is UNPREDICTABLE */
10372 return do_ldm(s, a, 2);
10373 }
10374
10375 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
10376 {
10377 /* Writeback is conditional on the base register not being loaded. */
10378 a->w = !(a->list & (1 << a->rn));
10379 /* BitCount(list) < 1 is UNPREDICTABLE */
10380 return do_ldm(s, a, 1);
10381 }
10382
10383 /*
10384 * Branch, branch with link
10385 */
10386
10387 static bool trans_B(DisasContext *s, arg_i *a)
10388 {
10389 gen_jmp(s, read_pc(s) + a->imm);
10390 return true;
10391 }
10392
10393 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
10394 {
10395 /* This has cond from encoding, required to be outside IT block. */
10396 if (a->cond >= 0xe) {
10397 return false;
10398 }
10399 if (s->condexec_mask) {
10400 unallocated_encoding(s);
10401 return true;
10402 }
10403 arm_skip_unless(s, a->cond);
10404 gen_jmp(s, read_pc(s) + a->imm);
10405 return true;
10406 }
10407
10408 static bool trans_BL(DisasContext *s, arg_i *a)
10409 {
10410 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10411 gen_jmp(s, read_pc(s) + a->imm);
10412 return true;
10413 }
10414
10415 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
10416 {
10417 TCGv_i32 tmp;
10418
10419 /* For A32, ARCH(5) is checked near the start of the uncond block. */
10420 if (s->thumb && (a->imm & 2)) {
10421 return false;
10422 }
10423 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10424 tmp = tcg_const_i32(!s->thumb);
10425 store_cpu_field(tmp, thumb);
10426 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
10427 return true;
10428 }
10429
10430 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
10431 {
10432 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10433 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
10434 return true;
10435 }
10436
10437 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
10438 {
10439 TCGv_i32 tmp = tcg_temp_new_i32();
10440
10441 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10442 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
10443 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10444 gen_bx(s, tmp);
10445 return true;
10446 }
10447
10448 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
10449 {
10450 TCGv_i32 tmp;
10451
10452 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10453 if (!ENABLE_ARCH_5) {
10454 return false;
10455 }
10456 tmp = tcg_temp_new_i32();
10457 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
10458 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
10459 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10460 gen_bx(s, tmp);
10461 return true;
10462 }
10463
10464 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
10465 {
10466 TCGv_i32 addr, tmp;
10467
10468 tmp = load_reg(s, a->rm);
10469 if (half) {
10470 tcg_gen_add_i32(tmp, tmp, tmp);
10471 }
10472 addr = load_reg(s, a->rn);
10473 tcg_gen_add_i32(addr, addr, tmp);
10474
10475 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
10476 half ? MO_UW | s->be_data : MO_UB);
10477 tcg_temp_free_i32(addr);
10478
10479 tcg_gen_add_i32(tmp, tmp, tmp);
10480 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
10481 store_reg(s, 15, tmp);
10482 return true;
10483 }
10484
10485 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
10486 {
10487 return op_tbranch(s, a, false);
10488 }
10489
10490 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
10491 {
10492 return op_tbranch(s, a, true);
10493 }
10494
10495 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
10496 {
10497 TCGv_i32 tmp = load_reg(s, a->rn);
10498
10499 arm_gen_condlabel(s);
10500 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
10501 tmp, 0, s->condlabel);
10502 tcg_temp_free_i32(tmp);
10503 gen_jmp(s, read_pc(s) + a->imm);
10504 return true;
10505 }
10506
10507 /*
10508 * Supervisor call - both T32 & A32 come here so we need to check
10509 * which mode we are in when checking for semihosting.
10510 */
10511
10512 static bool trans_SVC(DisasContext *s, arg_SVC *a)
10513 {
10514 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
10515
10516 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
10517 #ifndef CONFIG_USER_ONLY
10518 !IS_USER(s) &&
10519 #endif
10520 (a->imm == semihost_imm)) {
10521 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
10522 } else {
10523 gen_set_pc_im(s, s->base.pc_next);
10524 s->svc_imm = a->imm;
10525 s->base.is_jmp = DISAS_SWI;
10526 }
10527 return true;
10528 }
10529
10530 /*
10531 * Unconditional system instructions
10532 */
10533
10534 static bool trans_RFE(DisasContext *s, arg_RFE *a)
10535 {
10536 static const int8_t pre_offset[4] = {
10537 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
10538 };
10539 static const int8_t post_offset[4] = {
10540 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
10541 };
10542 TCGv_i32 addr, t1, t2;
10543
10544 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10545 return false;
10546 }
10547 if (IS_USER(s)) {
10548 unallocated_encoding(s);
10549 return true;
10550 }
10551
10552 addr = load_reg(s, a->rn);
10553 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
10554
10555 /* Load PC into tmp and CPSR into tmp2. */
10556 t1 = tcg_temp_new_i32();
10557 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
10558 tcg_gen_addi_i32(addr, addr, 4);
10559 t2 = tcg_temp_new_i32();
10560 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
10561
10562 if (a->w) {
10563 /* Base writeback. */
10564 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
10565 store_reg(s, a->rn, addr);
10566 } else {
10567 tcg_temp_free_i32(addr);
10568 }
10569 gen_rfe(s, t1, t2);
10570 return true;
10571 }
10572
10573 static bool trans_SRS(DisasContext *s, arg_SRS *a)
10574 {
10575 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10576 return false;
10577 }
10578 gen_srs(s, a->mode, a->pu, a->w);
10579 return true;
10580 }
10581
10582 static bool trans_CPS(DisasContext *s, arg_CPS *a)
10583 {
10584 uint32_t mask, val;
10585
10586 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10587 return false;
10588 }
10589 if (IS_USER(s)) {
10590 /* Implemented as NOP in user mode. */
10591 return true;
10592 }
10593 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
10594
10595 mask = val = 0;
10596 if (a->imod & 2) {
10597 if (a->A) {
10598 mask |= CPSR_A;
10599 }
10600 if (a->I) {
10601 mask |= CPSR_I;
10602 }
10603 if (a->F) {
10604 mask |= CPSR_F;
10605 }
10606 if (a->imod & 1) {
10607 val |= mask;
10608 }
10609 }
10610 if (a->M) {
10611 mask |= CPSR_M;
10612 val |= a->mode;
10613 }
10614 if (mask) {
10615 gen_set_psr_im(s, mask, 0, val);
10616 }
10617 return true;
10618 }
10619
10620 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
10621 {
10622 TCGv_i32 tmp, addr;
10623
10624 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
10625 return false;
10626 }
10627 if (IS_USER(s)) {
10628 /* Implemented as NOP in user mode. */
10629 return true;
10630 }
10631
10632 tmp = tcg_const_i32(a->im);
10633 /* FAULTMASK */
10634 if (a->F) {
10635 addr = tcg_const_i32(19);
10636 gen_helper_v7m_msr(cpu_env, addr, tmp);
10637 tcg_temp_free_i32(addr);
10638 }
10639 /* PRIMASK */
10640 if (a->I) {
10641 addr = tcg_const_i32(16);
10642 gen_helper_v7m_msr(cpu_env, addr, tmp);
10643 tcg_temp_free_i32(addr);
10644 }
10645 tcg_temp_free_i32(tmp);
10646 gen_lookup_tb(s);
10647 return true;
10648 }
10649
10650 /*
10651 * Clear-Exclusive, Barriers
10652 */
10653
10654 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
10655 {
10656 if (s->thumb
10657 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
10658 : !ENABLE_ARCH_6K) {
10659 return false;
10660 }
10661 gen_clrex(s);
10662 return true;
10663 }
10664
10665 static bool trans_DSB(DisasContext *s, arg_DSB *a)
10666 {
10667 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10668 return false;
10669 }
10670 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10671 return true;
10672 }
10673
10674 static bool trans_DMB(DisasContext *s, arg_DMB *a)
10675 {
10676 return trans_DSB(s, NULL);
10677 }
10678
10679 static bool trans_ISB(DisasContext *s, arg_ISB *a)
10680 {
10681 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10682 return false;
10683 }
10684 /*
10685 * We need to break the TB after this insn to execute
10686 * self-modifying code correctly and also to take
10687 * any pending interrupts immediately.
10688 */
10689 gen_goto_tb(s, 0, s->base.pc_next);
10690 return true;
10691 }
10692
10693 static bool trans_SB(DisasContext *s, arg_SB *a)
10694 {
10695 if (!dc_isar_feature(aa32_sb, s)) {
10696 return false;
10697 }
10698 /*
10699 * TODO: There is no speculation barrier opcode
10700 * for TCG; MB and end the TB instead.
10701 */
10702 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10703 gen_goto_tb(s, 0, s->base.pc_next);
10704 return true;
10705 }
10706
10707 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
10708 {
10709 if (!ENABLE_ARCH_6) {
10710 return false;
10711 }
10712 if (a->E != (s->be_data == MO_BE)) {
10713 gen_helper_setend(cpu_env);
10714 s->base.is_jmp = DISAS_UPDATE;
10715 }
10716 return true;
10717 }
10718
10719 /*
10720 * Preload instructions
10721 * All are nops, contingent on the appropriate arch level.
10722 */
10723
10724 static bool trans_PLD(DisasContext *s, arg_PLD *a)
10725 {
10726 return ENABLE_ARCH_5TE;
10727 }
10728
10729 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
10730 {
10731 return arm_dc_feature(s, ARM_FEATURE_V7MP);
10732 }
10733
10734 static bool trans_PLI(DisasContext *s, arg_PLD *a)
10735 {
10736 return ENABLE_ARCH_7;
10737 }
10738
10739 /*
10740 * If-then
10741 */
10742
10743 static bool trans_IT(DisasContext *s, arg_IT *a)
10744 {
10745 int cond_mask = a->cond_mask;
10746
10747 /*
10748 * No actual code generated for this insn, just setup state.
10749 *
10750 * Combinations of firstcond and mask which set up an 0b1111
10751 * condition are UNPREDICTABLE; we take the CONSTRAINED
10752 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
10753 * i.e. both meaning "execute always".
10754 */
10755 s->condexec_cond = (cond_mask >> 4) & 0xe;
10756 s->condexec_mask = cond_mask & 0x1f;
10757 return true;
10758 }
10759
10760 /*
10761 * Legacy decoder.
10762 */
10763
10764 static void disas_arm_insn(DisasContext *s, unsigned int insn)
10765 {
10766 unsigned int cond = insn >> 28;
10767
10768 /* M variants do not implement ARM mode; this must raise the INVSTATE
10769 * UsageFault exception.
10770 */
10771 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10772 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
10773 default_exception_el(s));
10774 return;
10775 }
10776
10777 if (cond == 0xf) {
10778 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10779 * choose to UNDEF. In ARMv5 and above the space is used
10780 * for miscellaneous unconditional instructions.
10781 */
10782 ARCH(5);
10783
10784 /* Unconditional instructions. */
10785 if (disas_a32_uncond(s, insn)) {
10786 return;
10787 }
10788 /* fall back to legacy decoder */
10789
10790 if (((insn >> 25) & 7) == 1) {
10791 /* NEON Data processing. */
10792 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10793 goto illegal_op;
10794 }
10795
10796 if (disas_neon_data_insn(s, insn)) {
10797 goto illegal_op;
10798 }
10799 return;
10800 }
10801 if ((insn & 0x0f100000) == 0x04000000) {
10802 /* NEON load/store. */
10803 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10804 goto illegal_op;
10805 }
10806
10807 if (disas_neon_ls_insn(s, insn)) {
10808 goto illegal_op;
10809 }
10810 return;
10811 }
10812 if ((insn & 0x0f000e10) == 0x0e000a00) {
10813 /* VFP. */
10814 if (disas_vfp_insn(s, insn)) {
10815 goto illegal_op;
10816 }
10817 return;
10818 }
10819 if ((insn & 0x0e000f00) == 0x0c000100) {
10820 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
10821 /* iWMMXt register transfer. */
10822 if (extract32(s->c15_cpar, 1, 1)) {
10823 if (!disas_iwmmxt_insn(s, insn)) {
10824 return;
10825 }
10826 }
10827 }
10828 } else if ((insn & 0x0e000a00) == 0x0c000800
10829 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10830 if (disas_neon_insn_3same_ext(s, insn)) {
10831 goto illegal_op;
10832 }
10833 return;
10834 } else if ((insn & 0x0f000a00) == 0x0e000800
10835 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10836 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10837 goto illegal_op;
10838 }
10839 return;
10840 }
10841 goto illegal_op;
10842 }
10843 if (cond != 0xe) {
10844 /* if not always execute, we generate a conditional jump to
10845 next instruction */
10846 arm_skip_unless(s, cond);
10847 }
10848
10849 if (disas_a32(s, insn)) {
10850 return;
10851 }
10852 /* fall back to legacy decoder */
10853
10854 switch ((insn >> 24) & 0xf) {
10855 case 0xc:
10856 case 0xd:
10857 case 0xe:
10858 if (((insn >> 8) & 0xe) == 10) {
10859 /* VFP. */
10860 if (disas_vfp_insn(s, insn)) {
10861 goto illegal_op;
10862 }
10863 } else if (disas_coproc_insn(s, insn)) {
10864 /* Coprocessor. */
10865 goto illegal_op;
10866 }
10867 break;
10868 default:
10869 illegal_op:
10870 unallocated_encoding(s);
10871 break;
10872 }
10873 }
10874
10875 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
10876 {
10877 /*
10878 * Return true if this is a 16 bit instruction. We must be precise
10879 * about this (matching the decode).
10880 */
10881 if ((insn >> 11) < 0x1d) {
10882 /* Definitely a 16-bit instruction */
10883 return true;
10884 }
10885
10886 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10887 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10888 * end up actually treating this as two 16-bit insns, though,
10889 * if it's half of a bl/blx pair that might span a page boundary.
10890 */
10891 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10892 arm_dc_feature(s, ARM_FEATURE_M)) {
10893 /* Thumb2 cores (including all M profile ones) always treat
10894 * 32-bit insns as 32-bit.
10895 */
10896 return false;
10897 }
10898
10899 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10900 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10901 * is not on the next page; we merge this into a 32-bit
10902 * insn.
10903 */
10904 return false;
10905 }
10906 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10907 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10908 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10909 * -- handle as single 16 bit insn
10910 */
10911 return true;
10912 }
10913
10914 /* Translate a 32-bit thumb instruction. */
10915 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10916 {
10917 /*
10918 * ARMv6-M supports a limited subset of Thumb2 instructions.
10919 * Other Thumb1 architectures allow only 32-bit
10920 * combined BL/BLX prefix and suffix.
10921 */
10922 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10923 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10924 int i;
10925 bool found = false;
10926 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10927 0xf3b08040 /* dsb */,
10928 0xf3b08050 /* dmb */,
10929 0xf3b08060 /* isb */,
10930 0xf3e08000 /* mrs */,
10931 0xf000d000 /* bl */};
10932 static const uint32_t armv6m_mask[] = {0xffe0d000,
10933 0xfff0d0f0,
10934 0xfff0d0f0,
10935 0xfff0d0f0,
10936 0xffe0d000,
10937 0xf800d000};
10938
10939 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10940 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10941 found = true;
10942 break;
10943 }
10944 }
10945 if (!found) {
10946 goto illegal_op;
10947 }
10948 } else if ((insn & 0xf800e800) != 0xf000e800) {
10949 ARCH(6T2);
10950 }
10951
10952 if (disas_t32(s, insn)) {
10953 return;
10954 }
10955 /* fall back to legacy decoder */
10956
10957 switch ((insn >> 25) & 0xf) {
10958 case 0: case 1: case 2: case 3:
10959 /* 16-bit instructions. Should never happen. */
10960 abort();
10961 case 6: case 7: case 14: case 15:
10962 /* Coprocessor. */
10963 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10964 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10965 if (extract32(insn, 24, 2) == 3) {
10966 goto illegal_op; /* op0 = 0b11 : unallocated */
10967 }
10968
10969 /*
10970 * Decode VLLDM and VLSTM first: these are nonstandard because:
10971 * * if there is no FPU then these insns must NOP in
10972 * Secure state and UNDEF in Nonsecure state
10973 * * if there is an FPU then these insns do not have
10974 * the usual behaviour that disas_vfp_insn() provides of
10975 * being controlled by CPACR/NSACR enable bits or the
10976 * lazy-stacking logic.
10977 */
10978 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10979 (insn & 0xffa00f00) == 0xec200a00) {
10980 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10981 * - VLLDM, VLSTM
10982 * We choose to UNDEF if the RAZ bits are non-zero.
10983 */
10984 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10985 goto illegal_op;
10986 }
10987
10988 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10989 uint32_t rn = (insn >> 16) & 0xf;
10990 TCGv_i32 fptr = load_reg(s, rn);
10991
10992 if (extract32(insn, 20, 1)) {
10993 gen_helper_v7m_vlldm(cpu_env, fptr);
10994 } else {
10995 gen_helper_v7m_vlstm(cpu_env, fptr);
10996 }
10997 tcg_temp_free_i32(fptr);
10998
10999 /* End the TB, because we have updated FP control bits */
11000 s->base.is_jmp = DISAS_UPDATE;
11001 }
11002 break;
11003 }
11004 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
11005 ((insn >> 8) & 0xe) == 10) {
11006 /* FP, and the CPU supports it */
11007 if (disas_vfp_insn(s, insn)) {
11008 goto illegal_op;
11009 }
11010 break;
11011 }
11012
11013 /* All other insns: NOCP */
11014 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
11015 default_exception_el(s));
11016 break;
11017 }
11018 if ((insn & 0xfe000a00) == 0xfc000800
11019 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11020 /* The Thumb2 and ARM encodings are identical. */
11021 if (disas_neon_insn_3same_ext(s, insn)) {
11022 goto illegal_op;
11023 }
11024 } else if ((insn & 0xff000a00) == 0xfe000800
11025 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11026 /* The Thumb2 and ARM encodings are identical. */
11027 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11028 goto illegal_op;
11029 }
11030 } else if (((insn >> 24) & 3) == 3) {
11031 /* Translate into the equivalent ARM encoding. */
11032 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11033 if (disas_neon_data_insn(s, insn)) {
11034 goto illegal_op;
11035 }
11036 } else if (((insn >> 8) & 0xe) == 10) {
11037 if (disas_vfp_insn(s, insn)) {
11038 goto illegal_op;
11039 }
11040 } else {
11041 if (insn & (1 << 28))
11042 goto illegal_op;
11043 if (disas_coproc_insn(s, insn)) {
11044 goto illegal_op;
11045 }
11046 }
11047 break;
11048 case 12:
11049 if ((insn & 0x01100000) == 0x01000000) {
11050 if (disas_neon_ls_insn(s, insn)) {
11051 goto illegal_op;
11052 }
11053 break;
11054 }
11055 goto illegal_op;
11056 default:
11057 illegal_op:
11058 unallocated_encoding(s);
11059 }
11060 }
11061
11062 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11063 {
11064 if (!disas_t16(s, insn)) {
11065 unallocated_encoding(s);
11066 }
11067 }
11068
11069 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11070 {
11071 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11072 * (False positives are OK, false negatives are not.)
11073 * We know this is a Thumb insn, and our caller ensures we are
11074 * only called if dc->base.pc_next is less than 4 bytes from the page
11075 * boundary, so we cross the page if the first 16 bits indicate
11076 * that this is a 32 bit insn.
11077 */
11078 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11079
11080 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11081 }
11082
11083 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11084 {
11085 DisasContext *dc = container_of(dcbase, DisasContext, base);
11086 CPUARMState *env = cs->env_ptr;
11087 ARMCPU *cpu = env_archcpu(env);
11088 uint32_t tb_flags = dc->base.tb->flags;
11089 uint32_t condexec, core_mmu_idx;
11090
11091 dc->isar = &cpu->isar;
11092 dc->condjmp = 0;
11093
11094 dc->aarch64 = 0;
11095 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11096 * there is no secure EL1, so we route exceptions to EL3.
11097 */
11098 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11099 !arm_el_is_aa64(env, 3);
11100 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
11101 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11102 condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
11103 dc->condexec_mask = (condexec & 0xf) << 1;
11104 dc->condexec_cond = condexec >> 4;
11105
11106 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11107 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11108 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11109 #if !defined(CONFIG_USER_ONLY)
11110 dc->user = (dc->current_el == 0);
11111 #endif
11112 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11113
11114 if (arm_feature(env, ARM_FEATURE_M)) {
11115 dc->vfp_enabled = 1;
11116 dc->be_data = MO_TE;
11117 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
11118 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11119 regime_is_secure(env, dc->mmu_idx);
11120 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
11121 dc->v8m_fpccr_s_wrong =
11122 FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
11123 dc->v7m_new_fp_ctxt_needed =
11124 FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
11125 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
11126 } else {
11127 dc->be_data =
11128 FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11129 dc->debug_target_el =
11130 FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11131 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11132 dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
11133 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11134 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11135 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11136 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11137 } else {
11138 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11139 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11140 }
11141 }
11142 dc->cp_regs = cpu->cp_regs;
11143 dc->features = env->features;
11144
11145 /* Single step state. The code-generation logic here is:
11146 * SS_ACTIVE == 0:
11147 * generate code with no special handling for single-stepping (except
11148 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11149 * this happens anyway because those changes are all system register or
11150 * PSTATE writes).
11151 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11152 * emit code for one insn
11153 * emit code to clear PSTATE.SS
11154 * emit code to generate software step exception for completed step
11155 * end TB (as usual for having generated an exception)
11156 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11157 * emit code to generate a software step exception
11158 * end the TB
11159 */
11160 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11161 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11162 dc->is_ldex = false;
11163
11164 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11165
11166 /* If architectural single step active, limit to 1. */
11167 if (is_singlestepping(dc)) {
11168 dc->base.max_insns = 1;
11169 }
11170
11171 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11172 to those left on the page. */
11173 if (!dc->thumb) {
11174 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11175 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11176 }
11177
11178 cpu_V0 = tcg_temp_new_i64();
11179 cpu_V1 = tcg_temp_new_i64();
11180 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11181 cpu_M0 = tcg_temp_new_i64();
11182 }
11183
11184 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11185 {
11186 DisasContext *dc = container_of(dcbase, DisasContext, base);
11187
11188 /* A note on handling of the condexec (IT) bits:
11189 *
11190 * We want to avoid the overhead of having to write the updated condexec
11191 * bits back to the CPUARMState for every instruction in an IT block. So:
11192 * (1) if the condexec bits are not already zero then we write
11193 * zero back into the CPUARMState now. This avoids complications trying
11194 * to do it at the end of the block. (For example if we don't do this
11195 * it's hard to identify whether we can safely skip writing condexec
11196 * at the end of the TB, which we definitely want to do for the case
11197 * where a TB doesn't do anything with the IT state at all.)
11198 * (2) if we are going to leave the TB then we call gen_set_condexec()
11199 * which will write the correct value into CPUARMState if zero is wrong.
11200 * This is done both for leaving the TB at the end, and for leaving
11201 * it because of an exception we know will happen, which is done in
11202 * gen_exception_insn(). The latter is necessary because we need to
11203 * leave the TB with the PC/IT state just prior to execution of the
11204 * instruction which caused the exception.
11205 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11206 * then the CPUARMState will be wrong and we need to reset it.
11207 * This is handled in the same way as restoration of the
11208 * PC in these situations; we save the value of the condexec bits
11209 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11210 * then uses this to restore them after an exception.
11211 *
11212 * Note that there are no instructions which can read the condexec
11213 * bits, and none which can write non-static values to them, so
11214 * we don't need to care about whether CPUARMState is correct in the
11215 * middle of a TB.
11216 */
11217
11218 /* Reset the conditional execution bits immediately. This avoids
11219 complications trying to do it at the end of the block. */
11220 if (dc->condexec_mask || dc->condexec_cond) {
11221 TCGv_i32 tmp = tcg_temp_new_i32();
11222 tcg_gen_movi_i32(tmp, 0);
11223 store_cpu_field(tmp, condexec_bits);
11224 }
11225 }
11226
11227 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11228 {
11229 DisasContext *dc = container_of(dcbase, DisasContext, base);
11230
11231 tcg_gen_insn_start(dc->base.pc_next,
11232 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11233 0);
11234 dc->insn_start = tcg_last_op();
11235 }
11236
11237 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11238 const CPUBreakpoint *bp)
11239 {
11240 DisasContext *dc = container_of(dcbase, DisasContext, base);
11241
11242 if (bp->flags & BP_CPU) {
11243 gen_set_condexec(dc);
11244 gen_set_pc_im(dc, dc->base.pc_next);
11245 gen_helper_check_breakpoints(cpu_env);
11246 /* End the TB early; it's likely not going to be executed */
11247 dc->base.is_jmp = DISAS_TOO_MANY;
11248 } else {
11249 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11250 /* The address covered by the breakpoint must be
11251 included in [tb->pc, tb->pc + tb->size) in order
11252 to for it to be properly cleared -- thus we
11253 increment the PC here so that the logic setting
11254 tb->size below does the right thing. */
11255 /* TODO: Advance PC by correct instruction length to
11256 * avoid disassembler error messages */
11257 dc->base.pc_next += 2;
11258 dc->base.is_jmp = DISAS_NORETURN;
11259 }
11260
11261 return true;
11262 }
11263
11264 static bool arm_pre_translate_insn(DisasContext *dc)
11265 {
11266 #ifdef CONFIG_USER_ONLY
11267 /* Intercept jump to the magic kernel page. */
11268 if (dc->base.pc_next >= 0xffff0000) {
11269 /* We always get here via a jump, so know we are not in a
11270 conditional execution block. */
11271 gen_exception_internal(EXCP_KERNEL_TRAP);
11272 dc->base.is_jmp = DISAS_NORETURN;
11273 return true;
11274 }
11275 #endif
11276
11277 if (dc->ss_active && !dc->pstate_ss) {
11278 /* Singlestep state is Active-pending.
11279 * If we're in this state at the start of a TB then either
11280 * a) we just took an exception to an EL which is being debugged
11281 * and this is the first insn in the exception handler
11282 * b) debug exceptions were masked and we just unmasked them
11283 * without changing EL (eg by clearing PSTATE.D)
11284 * In either case we're going to take a swstep exception in the
11285 * "did not step an insn" case, and so the syndrome ISV and EX
11286 * bits should be zero.
11287 */
11288 assert(dc->base.num_insns == 1);
11289 gen_swstep_exception(dc, 0, 0);
11290 dc->base.is_jmp = DISAS_NORETURN;
11291 return true;
11292 }
11293
11294 return false;
11295 }
11296
11297 static void arm_post_translate_insn(DisasContext *dc)
11298 {
11299 if (dc->condjmp && !dc->base.is_jmp) {
11300 gen_set_label(dc->condlabel);
11301 dc->condjmp = 0;
11302 }
11303 translator_loop_temp_check(&dc->base);
11304 }
11305
11306 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11307 {
11308 DisasContext *dc = container_of(dcbase, DisasContext, base);
11309 CPUARMState *env = cpu->env_ptr;
11310 unsigned int insn;
11311
11312 if (arm_pre_translate_insn(dc)) {
11313 return;
11314 }
11315
11316 dc->pc_curr = dc->base.pc_next;
11317 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11318 dc->insn = insn;
11319 dc->base.pc_next += 4;
11320 disas_arm_insn(dc, insn);
11321
11322 arm_post_translate_insn(dc);
11323
11324 /* ARM is a fixed-length ISA. We performed the cross-page check
11325 in init_disas_context by adjusting max_insns. */
11326 }
11327
11328 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11329 {
11330 /* Return true if this Thumb insn is always unconditional,
11331 * even inside an IT block. This is true of only a very few
11332 * instructions: BKPT, HLT, and SG.
11333 *
11334 * A larger class of instructions are UNPREDICTABLE if used
11335 * inside an IT block; we do not need to detect those here, because
11336 * what we do by default (perform the cc check and update the IT
11337 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11338 * choice for those situations.
11339 *
11340 * insn is either a 16-bit or a 32-bit instruction; the two are
11341 * distinguishable because for the 16-bit case the top 16 bits
11342 * are zeroes, and that isn't a valid 32-bit encoding.
11343 */
11344 if ((insn & 0xffffff00) == 0xbe00) {
11345 /* BKPT */
11346 return true;
11347 }
11348
11349 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11350 !arm_dc_feature(s, ARM_FEATURE_M)) {
11351 /* HLT: v8A only. This is unconditional even when it is going to
11352 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11353 * For v7 cores this was a plain old undefined encoding and so
11354 * honours its cc check. (We might be using the encoding as
11355 * a semihosting trap, but we don't change the cc check behaviour
11356 * on that account, because a debugger connected to a real v7A
11357 * core and emulating semihosting traps by catching the UNDEF
11358 * exception would also only see cases where the cc check passed.
11359 * No guest code should be trying to do a HLT semihosting trap
11360 * in an IT block anyway.
11361 */
11362 return true;
11363 }
11364
11365 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
11366 arm_dc_feature(s, ARM_FEATURE_M)) {
11367 /* SG: v8M only */
11368 return true;
11369 }
11370
11371 return false;
11372 }
11373
11374 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11375 {
11376 DisasContext *dc = container_of(dcbase, DisasContext, base);
11377 CPUARMState *env = cpu->env_ptr;
11378 uint32_t insn;
11379 bool is_16bit;
11380
11381 if (arm_pre_translate_insn(dc)) {
11382 return;
11383 }
11384
11385 dc->pc_curr = dc->base.pc_next;
11386 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11387 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
11388 dc->base.pc_next += 2;
11389 if (!is_16bit) {
11390 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11391
11392 insn = insn << 16 | insn2;
11393 dc->base.pc_next += 2;
11394 }
11395 dc->insn = insn;
11396
11397 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
11398 uint32_t cond = dc->condexec_cond;
11399
11400 /*
11401 * Conditionally skip the insn. Note that both 0xe and 0xf mean
11402 * "always"; 0xf is not "never".
11403 */
11404 if (cond < 0x0e) {
11405 arm_skip_unless(dc, cond);
11406 }
11407 }
11408
11409 if (is_16bit) {
11410 disas_thumb_insn(dc, insn);
11411 } else {
11412 disas_thumb2_insn(dc, insn);
11413 }
11414
11415 /* Advance the Thumb condexec condition. */
11416 if (dc->condexec_mask) {
11417 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
11418 ((dc->condexec_mask >> 4) & 1));
11419 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11420 if (dc->condexec_mask == 0) {
11421 dc->condexec_cond = 0;
11422 }
11423 }
11424
11425 arm_post_translate_insn(dc);
11426
11427 /* Thumb is a variable-length ISA. Stop translation when the next insn
11428 * will touch a new page. This ensures that prefetch aborts occur at
11429 * the right place.
11430 *
11431 * We want to stop the TB if the next insn starts in a new page,
11432 * or if it spans between this page and the next. This means that
11433 * if we're looking at the last halfword in the page we need to
11434 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11435 * or a 32-bit Thumb insn (which won't).
11436 * This is to avoid generating a silly TB with a single 16-bit insn
11437 * in it at the end of this page (which would execute correctly
11438 * but isn't very efficient).
11439 */
11440 if (dc->base.is_jmp == DISAS_NEXT
11441 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
11442 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
11443 && insn_crosses_page(env, dc)))) {
11444 dc->base.is_jmp = DISAS_TOO_MANY;
11445 }
11446 }
11447
11448 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
11449 {
11450 DisasContext *dc = container_of(dcbase, DisasContext, base);
11451
11452 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
11453 /* FIXME: This can theoretically happen with self-modifying code. */
11454 cpu_abort(cpu, "IO on conditional branch instruction");
11455 }
11456
11457 /* At this stage dc->condjmp will only be set when the skipped
11458 instruction was a conditional branch or trap, and the PC has
11459 already been written. */
11460 gen_set_condexec(dc);
11461 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
11462 /* Exception return branches need some special case code at the
11463 * end of the TB, which is complex enough that it has to
11464 * handle the single-step vs not and the condition-failed
11465 * insn codepath itself.
11466 */
11467 gen_bx_excret_final_code(dc);
11468 } else if (unlikely(is_singlestepping(dc))) {
11469 /* Unconditional and "condition passed" instruction codepath. */
11470 switch (dc->base.is_jmp) {
11471 case DISAS_SWI:
11472 gen_ss_advance(dc);
11473 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11474 default_exception_el(dc));
11475 break;
11476 case DISAS_HVC:
11477 gen_ss_advance(dc);
11478 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11479 break;
11480 case DISAS_SMC:
11481 gen_ss_advance(dc);
11482 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11483 break;
11484 case DISAS_NEXT:
11485 case DISAS_TOO_MANY:
11486 case DISAS_UPDATE:
11487 gen_set_pc_im(dc, dc->base.pc_next);
11488 /* fall through */
11489 default:
11490 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
11491 gen_singlestep_exception(dc);
11492 break;
11493 case DISAS_NORETURN:
11494 break;
11495 }
11496 } else {
11497 /* While branches must always occur at the end of an IT block,
11498 there are a few other things that can cause us to terminate
11499 the TB in the middle of an IT block:
11500 - Exception generating instructions (bkpt, swi, undefined).
11501 - Page boundaries.
11502 - Hardware watchpoints.
11503 Hardware breakpoints have already been handled and skip this code.
11504 */
11505 switch(dc->base.is_jmp) {
11506 case DISAS_NEXT:
11507 case DISAS_TOO_MANY:
11508 gen_goto_tb(dc, 1, dc->base.pc_next);
11509 break;
11510 case DISAS_JUMP:
11511 gen_goto_ptr();
11512 break;
11513 case DISAS_UPDATE:
11514 gen_set_pc_im(dc, dc->base.pc_next);
11515 /* fall through */
11516 default:
11517 /* indicate that the hash table must be used to find the next TB */
11518 tcg_gen_exit_tb(NULL, 0);
11519 break;
11520 case DISAS_NORETURN:
11521 /* nothing more to generate */
11522 break;
11523 case DISAS_WFI:
11524 {
11525 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
11526 !(dc->insn & (1U << 31))) ? 2 : 4);
11527
11528 gen_helper_wfi(cpu_env, tmp);
11529 tcg_temp_free_i32(tmp);
11530 /* The helper doesn't necessarily throw an exception, but we
11531 * must go back to the main loop to check for interrupts anyway.
11532 */
11533 tcg_gen_exit_tb(NULL, 0);
11534 break;
11535 }
11536 case DISAS_WFE:
11537 gen_helper_wfe(cpu_env);
11538 break;
11539 case DISAS_YIELD:
11540 gen_helper_yield(cpu_env);
11541 break;
11542 case DISAS_SWI:
11543 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11544 default_exception_el(dc));
11545 break;
11546 case DISAS_HVC:
11547 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11548 break;
11549 case DISAS_SMC:
11550 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11551 break;
11552 }
11553 }
11554
11555 if (dc->condjmp) {
11556 /* "Condition failed" instruction codepath for the branch/trap insn */
11557 gen_set_label(dc->condlabel);
11558 gen_set_condexec(dc);
11559 if (unlikely(is_singlestepping(dc))) {
11560 gen_set_pc_im(dc, dc->base.pc_next);
11561 gen_singlestep_exception(dc);
11562 } else {
11563 gen_goto_tb(dc, 1, dc->base.pc_next);
11564 }
11565 }
11566 }
11567
11568 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
11569 {
11570 DisasContext *dc = container_of(dcbase, DisasContext, base);
11571
11572 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
11573 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
11574 }
11575
11576 static const TranslatorOps arm_translator_ops = {
11577 .init_disas_context = arm_tr_init_disas_context,
11578 .tb_start = arm_tr_tb_start,
11579 .insn_start = arm_tr_insn_start,
11580 .breakpoint_check = arm_tr_breakpoint_check,
11581 .translate_insn = arm_tr_translate_insn,
11582 .tb_stop = arm_tr_tb_stop,
11583 .disas_log = arm_tr_disas_log,
11584 };
11585
11586 static const TranslatorOps thumb_translator_ops = {
11587 .init_disas_context = arm_tr_init_disas_context,
11588 .tb_start = arm_tr_tb_start,
11589 .insn_start = arm_tr_insn_start,
11590 .breakpoint_check = arm_tr_breakpoint_check,
11591 .translate_insn = thumb_tr_translate_insn,
11592 .tb_stop = arm_tr_tb_stop,
11593 .disas_log = arm_tr_disas_log,
11594 };
11595
11596 /* generate intermediate code for basic block 'tb'. */
11597 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
11598 {
11599 DisasContext dc = { };
11600 const TranslatorOps *ops = &arm_translator_ops;
11601
11602 if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
11603 ops = &thumb_translator_ops;
11604 }
11605 #ifdef TARGET_AARCH64
11606 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
11607 ops = &aarch64_translator_ops;
11608 }
11609 #endif
11610
11611 translator_loop(ops, &dc.base, cpu, tb, max_insns);
11612 }
11613
11614 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
11615 target_ulong *data)
11616 {
11617 if (is_a64(env)) {
11618 env->pc = data[0];
11619 env->condexec_bits = 0;
11620 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
11621 } else {
11622 env->regs[15] = data[0];
11623 env->condexec_bits = data[1];
11624 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
11625 }
11626 }