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