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