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