meson: target
[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 dest, TCGv_i32 var)
382 {
383 tcg_gen_rotri_i32(dest, 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 static TCGv_i32 neon_load_reg(int reg, int pass)
1137 {
1138 TCGv_i32 tmp = tcg_temp_new_i32();
1139 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1140 return tmp;
1141 }
1142
1143 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1144 {
1145 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1146 tcg_temp_free_i32(var);
1147 }
1148
1149 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1150 {
1151 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1152 }
1153
1154 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1155 {
1156 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1157 }
1158
1159 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1160 {
1161 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1162 }
1163
1164 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1165 {
1166 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1167 }
1168
1169 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1170 {
1171 TCGv_ptr ret = tcg_temp_new_ptr();
1172 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1173 return ret;
1174 }
1175
1176 #define ARM_CP_RW_BIT (1 << 20)
1177
1178 /* Include the VFP and Neon decoders */
1179 #include "translate-vfp.c.inc"
1180 #include "translate-neon.c.inc"
1181
1182 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1183 {
1184 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1185 }
1186
1187 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1188 {
1189 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1190 }
1191
1192 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1193 {
1194 TCGv_i32 var = tcg_temp_new_i32();
1195 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1196 return var;
1197 }
1198
1199 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1200 {
1201 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1202 tcg_temp_free_i32(var);
1203 }
1204
1205 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1206 {
1207 iwmmxt_store_reg(cpu_M0, rn);
1208 }
1209
1210 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1211 {
1212 iwmmxt_load_reg(cpu_M0, rn);
1213 }
1214
1215 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1216 {
1217 iwmmxt_load_reg(cpu_V1, rn);
1218 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1219 }
1220
1221 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1222 {
1223 iwmmxt_load_reg(cpu_V1, rn);
1224 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1225 }
1226
1227 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1228 {
1229 iwmmxt_load_reg(cpu_V1, rn);
1230 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1231 }
1232
1233 #define IWMMXT_OP(name) \
1234 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1235 { \
1236 iwmmxt_load_reg(cpu_V1, rn); \
1237 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1238 }
1239
1240 #define IWMMXT_OP_ENV(name) \
1241 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1242 { \
1243 iwmmxt_load_reg(cpu_V1, rn); \
1244 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1245 }
1246
1247 #define IWMMXT_OP_ENV_SIZE(name) \
1248 IWMMXT_OP_ENV(name##b) \
1249 IWMMXT_OP_ENV(name##w) \
1250 IWMMXT_OP_ENV(name##l)
1251
1252 #define IWMMXT_OP_ENV1(name) \
1253 static inline void gen_op_iwmmxt_##name##_M0(void) \
1254 { \
1255 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1256 }
1257
1258 IWMMXT_OP(maddsq)
1259 IWMMXT_OP(madduq)
1260 IWMMXT_OP(sadb)
1261 IWMMXT_OP(sadw)
1262 IWMMXT_OP(mulslw)
1263 IWMMXT_OP(mulshw)
1264 IWMMXT_OP(mululw)
1265 IWMMXT_OP(muluhw)
1266 IWMMXT_OP(macsw)
1267 IWMMXT_OP(macuw)
1268
1269 IWMMXT_OP_ENV_SIZE(unpackl)
1270 IWMMXT_OP_ENV_SIZE(unpackh)
1271
1272 IWMMXT_OP_ENV1(unpacklub)
1273 IWMMXT_OP_ENV1(unpackluw)
1274 IWMMXT_OP_ENV1(unpacklul)
1275 IWMMXT_OP_ENV1(unpackhub)
1276 IWMMXT_OP_ENV1(unpackhuw)
1277 IWMMXT_OP_ENV1(unpackhul)
1278 IWMMXT_OP_ENV1(unpacklsb)
1279 IWMMXT_OP_ENV1(unpacklsw)
1280 IWMMXT_OP_ENV1(unpacklsl)
1281 IWMMXT_OP_ENV1(unpackhsb)
1282 IWMMXT_OP_ENV1(unpackhsw)
1283 IWMMXT_OP_ENV1(unpackhsl)
1284
1285 IWMMXT_OP_ENV_SIZE(cmpeq)
1286 IWMMXT_OP_ENV_SIZE(cmpgtu)
1287 IWMMXT_OP_ENV_SIZE(cmpgts)
1288
1289 IWMMXT_OP_ENV_SIZE(mins)
1290 IWMMXT_OP_ENV_SIZE(minu)
1291 IWMMXT_OP_ENV_SIZE(maxs)
1292 IWMMXT_OP_ENV_SIZE(maxu)
1293
1294 IWMMXT_OP_ENV_SIZE(subn)
1295 IWMMXT_OP_ENV_SIZE(addn)
1296 IWMMXT_OP_ENV_SIZE(subu)
1297 IWMMXT_OP_ENV_SIZE(addu)
1298 IWMMXT_OP_ENV_SIZE(subs)
1299 IWMMXT_OP_ENV_SIZE(adds)
1300
1301 IWMMXT_OP_ENV(avgb0)
1302 IWMMXT_OP_ENV(avgb1)
1303 IWMMXT_OP_ENV(avgw0)
1304 IWMMXT_OP_ENV(avgw1)
1305
1306 IWMMXT_OP_ENV(packuw)
1307 IWMMXT_OP_ENV(packul)
1308 IWMMXT_OP_ENV(packuq)
1309 IWMMXT_OP_ENV(packsw)
1310 IWMMXT_OP_ENV(packsl)
1311 IWMMXT_OP_ENV(packsq)
1312
1313 static void gen_op_iwmmxt_set_mup(void)
1314 {
1315 TCGv_i32 tmp;
1316 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1317 tcg_gen_ori_i32(tmp, tmp, 2);
1318 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1319 }
1320
1321 static void gen_op_iwmmxt_set_cup(void)
1322 {
1323 TCGv_i32 tmp;
1324 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1325 tcg_gen_ori_i32(tmp, tmp, 1);
1326 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1327 }
1328
1329 static void gen_op_iwmmxt_setpsr_nz(void)
1330 {
1331 TCGv_i32 tmp = tcg_temp_new_i32();
1332 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1333 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1334 }
1335
1336 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1337 {
1338 iwmmxt_load_reg(cpu_V1, rn);
1339 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1340 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1341 }
1342
1343 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1344 TCGv_i32 dest)
1345 {
1346 int rd;
1347 uint32_t offset;
1348 TCGv_i32 tmp;
1349
1350 rd = (insn >> 16) & 0xf;
1351 tmp = load_reg(s, rd);
1352
1353 offset = (insn & 0xff) << ((insn >> 7) & 2);
1354 if (insn & (1 << 24)) {
1355 /* Pre indexed */
1356 if (insn & (1 << 23))
1357 tcg_gen_addi_i32(tmp, tmp, offset);
1358 else
1359 tcg_gen_addi_i32(tmp, tmp, -offset);
1360 tcg_gen_mov_i32(dest, tmp);
1361 if (insn & (1 << 21))
1362 store_reg(s, rd, tmp);
1363 else
1364 tcg_temp_free_i32(tmp);
1365 } else if (insn & (1 << 21)) {
1366 /* Post indexed */
1367 tcg_gen_mov_i32(dest, tmp);
1368 if (insn & (1 << 23))
1369 tcg_gen_addi_i32(tmp, tmp, offset);
1370 else
1371 tcg_gen_addi_i32(tmp, tmp, -offset);
1372 store_reg(s, rd, tmp);
1373 } else if (!(insn & (1 << 23)))
1374 return 1;
1375 return 0;
1376 }
1377
1378 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1379 {
1380 int rd = (insn >> 0) & 0xf;
1381 TCGv_i32 tmp;
1382
1383 if (insn & (1 << 8)) {
1384 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1385 return 1;
1386 } else {
1387 tmp = iwmmxt_load_creg(rd);
1388 }
1389 } else {
1390 tmp = tcg_temp_new_i32();
1391 iwmmxt_load_reg(cpu_V0, rd);
1392 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1393 }
1394 tcg_gen_andi_i32(tmp, tmp, mask);
1395 tcg_gen_mov_i32(dest, tmp);
1396 tcg_temp_free_i32(tmp);
1397 return 0;
1398 }
1399
1400 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1401 (ie. an undefined instruction). */
1402 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1403 {
1404 int rd, wrd;
1405 int rdhi, rdlo, rd0, rd1, i;
1406 TCGv_i32 addr;
1407 TCGv_i32 tmp, tmp2, tmp3;
1408
1409 if ((insn & 0x0e000e00) == 0x0c000000) {
1410 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1411 wrd = insn & 0xf;
1412 rdlo = (insn >> 12) & 0xf;
1413 rdhi = (insn >> 16) & 0xf;
1414 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1415 iwmmxt_load_reg(cpu_V0, wrd);
1416 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1417 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1418 } else { /* TMCRR */
1419 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1420 iwmmxt_store_reg(cpu_V0, wrd);
1421 gen_op_iwmmxt_set_mup();
1422 }
1423 return 0;
1424 }
1425
1426 wrd = (insn >> 12) & 0xf;
1427 addr = tcg_temp_new_i32();
1428 if (gen_iwmmxt_address(s, insn, addr)) {
1429 tcg_temp_free_i32(addr);
1430 return 1;
1431 }
1432 if (insn & ARM_CP_RW_BIT) {
1433 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1434 tmp = tcg_temp_new_i32();
1435 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1436 iwmmxt_store_creg(wrd, tmp);
1437 } else {
1438 i = 1;
1439 if (insn & (1 << 8)) {
1440 if (insn & (1 << 22)) { /* WLDRD */
1441 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1442 i = 0;
1443 } else { /* WLDRW wRd */
1444 tmp = tcg_temp_new_i32();
1445 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1446 }
1447 } else {
1448 tmp = tcg_temp_new_i32();
1449 if (insn & (1 << 22)) { /* WLDRH */
1450 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1451 } else { /* WLDRB */
1452 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1453 }
1454 }
1455 if (i) {
1456 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1457 tcg_temp_free_i32(tmp);
1458 }
1459 gen_op_iwmmxt_movq_wRn_M0(wrd);
1460 }
1461 } else {
1462 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1463 tmp = iwmmxt_load_creg(wrd);
1464 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1465 } else {
1466 gen_op_iwmmxt_movq_M0_wRn(wrd);
1467 tmp = tcg_temp_new_i32();
1468 if (insn & (1 << 8)) {
1469 if (insn & (1 << 22)) { /* WSTRD */
1470 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1471 } else { /* WSTRW wRd */
1472 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1473 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1474 }
1475 } else {
1476 if (insn & (1 << 22)) { /* WSTRH */
1477 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1478 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1479 } else { /* WSTRB */
1480 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1481 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1482 }
1483 }
1484 }
1485 tcg_temp_free_i32(tmp);
1486 }
1487 tcg_temp_free_i32(addr);
1488 return 0;
1489 }
1490
1491 if ((insn & 0x0f000000) != 0x0e000000)
1492 return 1;
1493
1494 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1495 case 0x000: /* WOR */
1496 wrd = (insn >> 12) & 0xf;
1497 rd0 = (insn >> 0) & 0xf;
1498 rd1 = (insn >> 16) & 0xf;
1499 gen_op_iwmmxt_movq_M0_wRn(rd0);
1500 gen_op_iwmmxt_orq_M0_wRn(rd1);
1501 gen_op_iwmmxt_setpsr_nz();
1502 gen_op_iwmmxt_movq_wRn_M0(wrd);
1503 gen_op_iwmmxt_set_mup();
1504 gen_op_iwmmxt_set_cup();
1505 break;
1506 case 0x011: /* TMCR */
1507 if (insn & 0xf)
1508 return 1;
1509 rd = (insn >> 12) & 0xf;
1510 wrd = (insn >> 16) & 0xf;
1511 switch (wrd) {
1512 case ARM_IWMMXT_wCID:
1513 case ARM_IWMMXT_wCASF:
1514 break;
1515 case ARM_IWMMXT_wCon:
1516 gen_op_iwmmxt_set_cup();
1517 /* Fall through. */
1518 case ARM_IWMMXT_wCSSF:
1519 tmp = iwmmxt_load_creg(wrd);
1520 tmp2 = load_reg(s, rd);
1521 tcg_gen_andc_i32(tmp, tmp, tmp2);
1522 tcg_temp_free_i32(tmp2);
1523 iwmmxt_store_creg(wrd, tmp);
1524 break;
1525 case ARM_IWMMXT_wCGR0:
1526 case ARM_IWMMXT_wCGR1:
1527 case ARM_IWMMXT_wCGR2:
1528 case ARM_IWMMXT_wCGR3:
1529 gen_op_iwmmxt_set_cup();
1530 tmp = load_reg(s, rd);
1531 iwmmxt_store_creg(wrd, tmp);
1532 break;
1533 default:
1534 return 1;
1535 }
1536 break;
1537 case 0x100: /* WXOR */
1538 wrd = (insn >> 12) & 0xf;
1539 rd0 = (insn >> 0) & 0xf;
1540 rd1 = (insn >> 16) & 0xf;
1541 gen_op_iwmmxt_movq_M0_wRn(rd0);
1542 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1543 gen_op_iwmmxt_setpsr_nz();
1544 gen_op_iwmmxt_movq_wRn_M0(wrd);
1545 gen_op_iwmmxt_set_mup();
1546 gen_op_iwmmxt_set_cup();
1547 break;
1548 case 0x111: /* TMRC */
1549 if (insn & 0xf)
1550 return 1;
1551 rd = (insn >> 12) & 0xf;
1552 wrd = (insn >> 16) & 0xf;
1553 tmp = iwmmxt_load_creg(wrd);
1554 store_reg(s, rd, tmp);
1555 break;
1556 case 0x300: /* WANDN */
1557 wrd = (insn >> 12) & 0xf;
1558 rd0 = (insn >> 0) & 0xf;
1559 rd1 = (insn >> 16) & 0xf;
1560 gen_op_iwmmxt_movq_M0_wRn(rd0);
1561 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1562 gen_op_iwmmxt_andq_M0_wRn(rd1);
1563 gen_op_iwmmxt_setpsr_nz();
1564 gen_op_iwmmxt_movq_wRn_M0(wrd);
1565 gen_op_iwmmxt_set_mup();
1566 gen_op_iwmmxt_set_cup();
1567 break;
1568 case 0x200: /* WAND */
1569 wrd = (insn >> 12) & 0xf;
1570 rd0 = (insn >> 0) & 0xf;
1571 rd1 = (insn >> 16) & 0xf;
1572 gen_op_iwmmxt_movq_M0_wRn(rd0);
1573 gen_op_iwmmxt_andq_M0_wRn(rd1);
1574 gen_op_iwmmxt_setpsr_nz();
1575 gen_op_iwmmxt_movq_wRn_M0(wrd);
1576 gen_op_iwmmxt_set_mup();
1577 gen_op_iwmmxt_set_cup();
1578 break;
1579 case 0x810: case 0xa10: /* WMADD */
1580 wrd = (insn >> 12) & 0xf;
1581 rd0 = (insn >> 0) & 0xf;
1582 rd1 = (insn >> 16) & 0xf;
1583 gen_op_iwmmxt_movq_M0_wRn(rd0);
1584 if (insn & (1 << 21))
1585 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1586 else
1587 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1588 gen_op_iwmmxt_movq_wRn_M0(wrd);
1589 gen_op_iwmmxt_set_mup();
1590 break;
1591 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1592 wrd = (insn >> 12) & 0xf;
1593 rd0 = (insn >> 16) & 0xf;
1594 rd1 = (insn >> 0) & 0xf;
1595 gen_op_iwmmxt_movq_M0_wRn(rd0);
1596 switch ((insn >> 22) & 3) {
1597 case 0:
1598 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1599 break;
1600 case 1:
1601 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1602 break;
1603 case 2:
1604 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1605 break;
1606 case 3:
1607 return 1;
1608 }
1609 gen_op_iwmmxt_movq_wRn_M0(wrd);
1610 gen_op_iwmmxt_set_mup();
1611 gen_op_iwmmxt_set_cup();
1612 break;
1613 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1614 wrd = (insn >> 12) & 0xf;
1615 rd0 = (insn >> 16) & 0xf;
1616 rd1 = (insn >> 0) & 0xf;
1617 gen_op_iwmmxt_movq_M0_wRn(rd0);
1618 switch ((insn >> 22) & 3) {
1619 case 0:
1620 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1621 break;
1622 case 1:
1623 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1624 break;
1625 case 2:
1626 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1627 break;
1628 case 3:
1629 return 1;
1630 }
1631 gen_op_iwmmxt_movq_wRn_M0(wrd);
1632 gen_op_iwmmxt_set_mup();
1633 gen_op_iwmmxt_set_cup();
1634 break;
1635 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1636 wrd = (insn >> 12) & 0xf;
1637 rd0 = (insn >> 16) & 0xf;
1638 rd1 = (insn >> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0);
1640 if (insn & (1 << 22))
1641 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1642 else
1643 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1644 if (!(insn & (1 << 20)))
1645 gen_op_iwmmxt_addl_M0_wRn(wrd);
1646 gen_op_iwmmxt_movq_wRn_M0(wrd);
1647 gen_op_iwmmxt_set_mup();
1648 break;
1649 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1650 wrd = (insn >> 12) & 0xf;
1651 rd0 = (insn >> 16) & 0xf;
1652 rd1 = (insn >> 0) & 0xf;
1653 gen_op_iwmmxt_movq_M0_wRn(rd0);
1654 if (insn & (1 << 21)) {
1655 if (insn & (1 << 20))
1656 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1657 else
1658 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1659 } else {
1660 if (insn & (1 << 20))
1661 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1662 else
1663 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1664 }
1665 gen_op_iwmmxt_movq_wRn_M0(wrd);
1666 gen_op_iwmmxt_set_mup();
1667 break;
1668 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1669 wrd = (insn >> 12) & 0xf;
1670 rd0 = (insn >> 16) & 0xf;
1671 rd1 = (insn >> 0) & 0xf;
1672 gen_op_iwmmxt_movq_M0_wRn(rd0);
1673 if (insn & (1 << 21))
1674 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1675 else
1676 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1677 if (!(insn & (1 << 20))) {
1678 iwmmxt_load_reg(cpu_V1, wrd);
1679 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1680 }
1681 gen_op_iwmmxt_movq_wRn_M0(wrd);
1682 gen_op_iwmmxt_set_mup();
1683 break;
1684 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1685 wrd = (insn >> 12) & 0xf;
1686 rd0 = (insn >> 16) & 0xf;
1687 rd1 = (insn >> 0) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0);
1689 switch ((insn >> 22) & 3) {
1690 case 0:
1691 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1692 break;
1693 case 1:
1694 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1695 break;
1696 case 2:
1697 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1698 break;
1699 case 3:
1700 return 1;
1701 }
1702 gen_op_iwmmxt_movq_wRn_M0(wrd);
1703 gen_op_iwmmxt_set_mup();
1704 gen_op_iwmmxt_set_cup();
1705 break;
1706 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1707 wrd = (insn >> 12) & 0xf;
1708 rd0 = (insn >> 16) & 0xf;
1709 rd1 = (insn >> 0) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0);
1711 if (insn & (1 << 22)) {
1712 if (insn & (1 << 20))
1713 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1714 else
1715 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1716 } else {
1717 if (insn & (1 << 20))
1718 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1719 else
1720 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1721 }
1722 gen_op_iwmmxt_movq_wRn_M0(wrd);
1723 gen_op_iwmmxt_set_mup();
1724 gen_op_iwmmxt_set_cup();
1725 break;
1726 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1727 wrd = (insn >> 12) & 0xf;
1728 rd0 = (insn >> 16) & 0xf;
1729 rd1 = (insn >> 0) & 0xf;
1730 gen_op_iwmmxt_movq_M0_wRn(rd0);
1731 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1732 tcg_gen_andi_i32(tmp, tmp, 7);
1733 iwmmxt_load_reg(cpu_V1, rd1);
1734 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1735 tcg_temp_free_i32(tmp);
1736 gen_op_iwmmxt_movq_wRn_M0(wrd);
1737 gen_op_iwmmxt_set_mup();
1738 break;
1739 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1740 if (((insn >> 6) & 3) == 3)
1741 return 1;
1742 rd = (insn >> 12) & 0xf;
1743 wrd = (insn >> 16) & 0xf;
1744 tmp = load_reg(s, rd);
1745 gen_op_iwmmxt_movq_M0_wRn(wrd);
1746 switch ((insn >> 6) & 3) {
1747 case 0:
1748 tmp2 = tcg_const_i32(0xff);
1749 tmp3 = tcg_const_i32((insn & 7) << 3);
1750 break;
1751 case 1:
1752 tmp2 = tcg_const_i32(0xffff);
1753 tmp3 = tcg_const_i32((insn & 3) << 4);
1754 break;
1755 case 2:
1756 tmp2 = tcg_const_i32(0xffffffff);
1757 tmp3 = tcg_const_i32((insn & 1) << 5);
1758 break;
1759 default:
1760 tmp2 = NULL;
1761 tmp3 = NULL;
1762 }
1763 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1764 tcg_temp_free_i32(tmp3);
1765 tcg_temp_free_i32(tmp2);
1766 tcg_temp_free_i32(tmp);
1767 gen_op_iwmmxt_movq_wRn_M0(wrd);
1768 gen_op_iwmmxt_set_mup();
1769 break;
1770 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1771 rd = (insn >> 12) & 0xf;
1772 wrd = (insn >> 16) & 0xf;
1773 if (rd == 15 || ((insn >> 22) & 3) == 3)
1774 return 1;
1775 gen_op_iwmmxt_movq_M0_wRn(wrd);
1776 tmp = tcg_temp_new_i32();
1777 switch ((insn >> 22) & 3) {
1778 case 0:
1779 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1780 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1781 if (insn & 8) {
1782 tcg_gen_ext8s_i32(tmp, tmp);
1783 } else {
1784 tcg_gen_andi_i32(tmp, tmp, 0xff);
1785 }
1786 break;
1787 case 1:
1788 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1789 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1790 if (insn & 8) {
1791 tcg_gen_ext16s_i32(tmp, tmp);
1792 } else {
1793 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1794 }
1795 break;
1796 case 2:
1797 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1798 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1799 break;
1800 }
1801 store_reg(s, rd, tmp);
1802 break;
1803 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1804 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1805 return 1;
1806 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1807 switch ((insn >> 22) & 3) {
1808 case 0:
1809 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1810 break;
1811 case 1:
1812 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1813 break;
1814 case 2:
1815 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1816 break;
1817 }
1818 tcg_gen_shli_i32(tmp, tmp, 28);
1819 gen_set_nzcv(tmp);
1820 tcg_temp_free_i32(tmp);
1821 break;
1822 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1823 if (((insn >> 6) & 3) == 3)
1824 return 1;
1825 rd = (insn >> 12) & 0xf;
1826 wrd = (insn >> 16) & 0xf;
1827 tmp = load_reg(s, rd);
1828 switch ((insn >> 6) & 3) {
1829 case 0:
1830 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1831 break;
1832 case 1:
1833 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1834 break;
1835 case 2:
1836 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1837 break;
1838 }
1839 tcg_temp_free_i32(tmp);
1840 gen_op_iwmmxt_movq_wRn_M0(wrd);
1841 gen_op_iwmmxt_set_mup();
1842 break;
1843 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1844 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1845 return 1;
1846 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1847 tmp2 = tcg_temp_new_i32();
1848 tcg_gen_mov_i32(tmp2, tmp);
1849 switch ((insn >> 22) & 3) {
1850 case 0:
1851 for (i = 0; i < 7; i ++) {
1852 tcg_gen_shli_i32(tmp2, tmp2, 4);
1853 tcg_gen_and_i32(tmp, tmp, tmp2);
1854 }
1855 break;
1856 case 1:
1857 for (i = 0; i < 3; i ++) {
1858 tcg_gen_shli_i32(tmp2, tmp2, 8);
1859 tcg_gen_and_i32(tmp, tmp, tmp2);
1860 }
1861 break;
1862 case 2:
1863 tcg_gen_shli_i32(tmp2, tmp2, 16);
1864 tcg_gen_and_i32(tmp, tmp, tmp2);
1865 break;
1866 }
1867 gen_set_nzcv(tmp);
1868 tcg_temp_free_i32(tmp2);
1869 tcg_temp_free_i32(tmp);
1870 break;
1871 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1872 wrd = (insn >> 12) & 0xf;
1873 rd0 = (insn >> 16) & 0xf;
1874 gen_op_iwmmxt_movq_M0_wRn(rd0);
1875 switch ((insn >> 22) & 3) {
1876 case 0:
1877 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1878 break;
1879 case 1:
1880 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1881 break;
1882 case 2:
1883 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1884 break;
1885 case 3:
1886 return 1;
1887 }
1888 gen_op_iwmmxt_movq_wRn_M0(wrd);
1889 gen_op_iwmmxt_set_mup();
1890 break;
1891 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1892 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1893 return 1;
1894 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1895 tmp2 = tcg_temp_new_i32();
1896 tcg_gen_mov_i32(tmp2, tmp);
1897 switch ((insn >> 22) & 3) {
1898 case 0:
1899 for (i = 0; i < 7; i ++) {
1900 tcg_gen_shli_i32(tmp2, tmp2, 4);
1901 tcg_gen_or_i32(tmp, tmp, tmp2);
1902 }
1903 break;
1904 case 1:
1905 for (i = 0; i < 3; i ++) {
1906 tcg_gen_shli_i32(tmp2, tmp2, 8);
1907 tcg_gen_or_i32(tmp, tmp, tmp2);
1908 }
1909 break;
1910 case 2:
1911 tcg_gen_shli_i32(tmp2, tmp2, 16);
1912 tcg_gen_or_i32(tmp, tmp, tmp2);
1913 break;
1914 }
1915 gen_set_nzcv(tmp);
1916 tcg_temp_free_i32(tmp2);
1917 tcg_temp_free_i32(tmp);
1918 break;
1919 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1920 rd = (insn >> 12) & 0xf;
1921 rd0 = (insn >> 16) & 0xf;
1922 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1923 return 1;
1924 gen_op_iwmmxt_movq_M0_wRn(rd0);
1925 tmp = tcg_temp_new_i32();
1926 switch ((insn >> 22) & 3) {
1927 case 0:
1928 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1929 break;
1930 case 1:
1931 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1932 break;
1933 case 2:
1934 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1935 break;
1936 }
1937 store_reg(s, rd, tmp);
1938 break;
1939 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1940 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1941 wrd = (insn >> 12) & 0xf;
1942 rd0 = (insn >> 16) & 0xf;
1943 rd1 = (insn >> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0);
1945 switch ((insn >> 22) & 3) {
1946 case 0:
1947 if (insn & (1 << 21))
1948 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1949 else
1950 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1951 break;
1952 case 1:
1953 if (insn & (1 << 21))
1954 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1955 else
1956 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1957 break;
1958 case 2:
1959 if (insn & (1 << 21))
1960 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1961 else
1962 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1963 break;
1964 case 3:
1965 return 1;
1966 }
1967 gen_op_iwmmxt_movq_wRn_M0(wrd);
1968 gen_op_iwmmxt_set_mup();
1969 gen_op_iwmmxt_set_cup();
1970 break;
1971 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1972 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
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 if (insn & (1 << 21))
1979 gen_op_iwmmxt_unpacklsb_M0();
1980 else
1981 gen_op_iwmmxt_unpacklub_M0();
1982 break;
1983 case 1:
1984 if (insn & (1 << 21))
1985 gen_op_iwmmxt_unpacklsw_M0();
1986 else
1987 gen_op_iwmmxt_unpackluw_M0();
1988 break;
1989 case 2:
1990 if (insn & (1 << 21))
1991 gen_op_iwmmxt_unpacklsl_M0();
1992 else
1993 gen_op_iwmmxt_unpacklul_M0();
1994 break;
1995 case 3:
1996 return 1;
1997 }
1998 gen_op_iwmmxt_movq_wRn_M0(wrd);
1999 gen_op_iwmmxt_set_mup();
2000 gen_op_iwmmxt_set_cup();
2001 break;
2002 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2003 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2004 wrd = (insn >> 12) & 0xf;
2005 rd0 = (insn >> 16) & 0xf;
2006 gen_op_iwmmxt_movq_M0_wRn(rd0);
2007 switch ((insn >> 22) & 3) {
2008 case 0:
2009 if (insn & (1 << 21))
2010 gen_op_iwmmxt_unpackhsb_M0();
2011 else
2012 gen_op_iwmmxt_unpackhub_M0();
2013 break;
2014 case 1:
2015 if (insn & (1 << 21))
2016 gen_op_iwmmxt_unpackhsw_M0();
2017 else
2018 gen_op_iwmmxt_unpackhuw_M0();
2019 break;
2020 case 2:
2021 if (insn & (1 << 21))
2022 gen_op_iwmmxt_unpackhsl_M0();
2023 else
2024 gen_op_iwmmxt_unpackhul_M0();
2025 break;
2026 case 3:
2027 return 1;
2028 }
2029 gen_op_iwmmxt_movq_wRn_M0(wrd);
2030 gen_op_iwmmxt_set_mup();
2031 gen_op_iwmmxt_set_cup();
2032 break;
2033 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2034 case 0x214: case 0x614: case 0xa14: case 0xe14:
2035 if (((insn >> 22) & 3) == 0)
2036 return 1;
2037 wrd = (insn >> 12) & 0xf;
2038 rd0 = (insn >> 16) & 0xf;
2039 gen_op_iwmmxt_movq_M0_wRn(rd0);
2040 tmp = tcg_temp_new_i32();
2041 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2042 tcg_temp_free_i32(tmp);
2043 return 1;
2044 }
2045 switch ((insn >> 22) & 3) {
2046 case 1:
2047 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2048 break;
2049 case 2:
2050 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2051 break;
2052 case 3:
2053 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2054 break;
2055 }
2056 tcg_temp_free_i32(tmp);
2057 gen_op_iwmmxt_movq_wRn_M0(wrd);
2058 gen_op_iwmmxt_set_mup();
2059 gen_op_iwmmxt_set_cup();
2060 break;
2061 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2062 case 0x014: case 0x414: case 0x814: case 0xc14:
2063 if (((insn >> 22) & 3) == 0)
2064 return 1;
2065 wrd = (insn >> 12) & 0xf;
2066 rd0 = (insn >> 16) & 0xf;
2067 gen_op_iwmmxt_movq_M0_wRn(rd0);
2068 tmp = tcg_temp_new_i32();
2069 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2070 tcg_temp_free_i32(tmp);
2071 return 1;
2072 }
2073 switch ((insn >> 22) & 3) {
2074 case 1:
2075 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2076 break;
2077 case 2:
2078 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2079 break;
2080 case 3:
2081 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2082 break;
2083 }
2084 tcg_temp_free_i32(tmp);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd);
2086 gen_op_iwmmxt_set_mup();
2087 gen_op_iwmmxt_set_cup();
2088 break;
2089 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2090 case 0x114: case 0x514: case 0x914: case 0xd14:
2091 if (((insn >> 22) & 3) == 0)
2092 return 1;
2093 wrd = (insn >> 12) & 0xf;
2094 rd0 = (insn >> 16) & 0xf;
2095 gen_op_iwmmxt_movq_M0_wRn(rd0);
2096 tmp = tcg_temp_new_i32();
2097 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2098 tcg_temp_free_i32(tmp);
2099 return 1;
2100 }
2101 switch ((insn >> 22) & 3) {
2102 case 1:
2103 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2104 break;
2105 case 2:
2106 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2107 break;
2108 case 3:
2109 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2110 break;
2111 }
2112 tcg_temp_free_i32(tmp);
2113 gen_op_iwmmxt_movq_wRn_M0(wrd);
2114 gen_op_iwmmxt_set_mup();
2115 gen_op_iwmmxt_set_cup();
2116 break;
2117 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2118 case 0x314: case 0x714: case 0xb14: case 0xf14:
2119 if (((insn >> 22) & 3) == 0)
2120 return 1;
2121 wrd = (insn >> 12) & 0xf;
2122 rd0 = (insn >> 16) & 0xf;
2123 gen_op_iwmmxt_movq_M0_wRn(rd0);
2124 tmp = tcg_temp_new_i32();
2125 switch ((insn >> 22) & 3) {
2126 case 1:
2127 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2128 tcg_temp_free_i32(tmp);
2129 return 1;
2130 }
2131 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2132 break;
2133 case 2:
2134 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2135 tcg_temp_free_i32(tmp);
2136 return 1;
2137 }
2138 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2139 break;
2140 case 3:
2141 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2142 tcg_temp_free_i32(tmp);
2143 return 1;
2144 }
2145 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2146 break;
2147 }
2148 tcg_temp_free_i32(tmp);
2149 gen_op_iwmmxt_movq_wRn_M0(wrd);
2150 gen_op_iwmmxt_set_mup();
2151 gen_op_iwmmxt_set_cup();
2152 break;
2153 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2154 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2155 wrd = (insn >> 12) & 0xf;
2156 rd0 = (insn >> 16) & 0xf;
2157 rd1 = (insn >> 0) & 0xf;
2158 gen_op_iwmmxt_movq_M0_wRn(rd0);
2159 switch ((insn >> 22) & 3) {
2160 case 0:
2161 if (insn & (1 << 21))
2162 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2163 else
2164 gen_op_iwmmxt_minub_M0_wRn(rd1);
2165 break;
2166 case 1:
2167 if (insn & (1 << 21))
2168 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2169 else
2170 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2171 break;
2172 case 2:
2173 if (insn & (1 << 21))
2174 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2175 else
2176 gen_op_iwmmxt_minul_M0_wRn(rd1);
2177 break;
2178 case 3:
2179 return 1;
2180 }
2181 gen_op_iwmmxt_movq_wRn_M0(wrd);
2182 gen_op_iwmmxt_set_mup();
2183 break;
2184 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2185 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2186 wrd = (insn >> 12) & 0xf;
2187 rd0 = (insn >> 16) & 0xf;
2188 rd1 = (insn >> 0) & 0xf;
2189 gen_op_iwmmxt_movq_M0_wRn(rd0);
2190 switch ((insn >> 22) & 3) {
2191 case 0:
2192 if (insn & (1 << 21))
2193 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2194 else
2195 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2196 break;
2197 case 1:
2198 if (insn & (1 << 21))
2199 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2200 else
2201 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2202 break;
2203 case 2:
2204 if (insn & (1 << 21))
2205 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2206 else
2207 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2208 break;
2209 case 3:
2210 return 1;
2211 }
2212 gen_op_iwmmxt_movq_wRn_M0(wrd);
2213 gen_op_iwmmxt_set_mup();
2214 break;
2215 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2216 case 0x402: case 0x502: case 0x602: case 0x702:
2217 wrd = (insn >> 12) & 0xf;
2218 rd0 = (insn >> 16) & 0xf;
2219 rd1 = (insn >> 0) & 0xf;
2220 gen_op_iwmmxt_movq_M0_wRn(rd0);
2221 tmp = tcg_const_i32((insn >> 20) & 3);
2222 iwmmxt_load_reg(cpu_V1, rd1);
2223 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2224 tcg_temp_free_i32(tmp);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2227 break;
2228 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2229 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2230 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2231 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2232 wrd = (insn >> 12) & 0xf;
2233 rd0 = (insn >> 16) & 0xf;
2234 rd1 = (insn >> 0) & 0xf;
2235 gen_op_iwmmxt_movq_M0_wRn(rd0);
2236 switch ((insn >> 20) & 0xf) {
2237 case 0x0:
2238 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2239 break;
2240 case 0x1:
2241 gen_op_iwmmxt_subub_M0_wRn(rd1);
2242 break;
2243 case 0x3:
2244 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2245 break;
2246 case 0x4:
2247 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2248 break;
2249 case 0x5:
2250 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2251 break;
2252 case 0x7:
2253 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2254 break;
2255 case 0x8:
2256 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2257 break;
2258 case 0x9:
2259 gen_op_iwmmxt_subul_M0_wRn(rd1);
2260 break;
2261 case 0xb:
2262 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2263 break;
2264 default:
2265 return 1;
2266 }
2267 gen_op_iwmmxt_movq_wRn_M0(wrd);
2268 gen_op_iwmmxt_set_mup();
2269 gen_op_iwmmxt_set_cup();
2270 break;
2271 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2272 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2273 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2274 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2275 wrd = (insn >> 12) & 0xf;
2276 rd0 = (insn >> 16) & 0xf;
2277 gen_op_iwmmxt_movq_M0_wRn(rd0);
2278 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2279 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2280 tcg_temp_free_i32(tmp);
2281 gen_op_iwmmxt_movq_wRn_M0(wrd);
2282 gen_op_iwmmxt_set_mup();
2283 gen_op_iwmmxt_set_cup();
2284 break;
2285 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2286 case 0x418: case 0x518: case 0x618: case 0x718:
2287 case 0x818: case 0x918: case 0xa18: case 0xb18:
2288 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2289 wrd = (insn >> 12) & 0xf;
2290 rd0 = (insn >> 16) & 0xf;
2291 rd1 = (insn >> 0) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0);
2293 switch ((insn >> 20) & 0xf) {
2294 case 0x0:
2295 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2296 break;
2297 case 0x1:
2298 gen_op_iwmmxt_addub_M0_wRn(rd1);
2299 break;
2300 case 0x3:
2301 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2302 break;
2303 case 0x4:
2304 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2305 break;
2306 case 0x5:
2307 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2308 break;
2309 case 0x7:
2310 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2311 break;
2312 case 0x8:
2313 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2314 break;
2315 case 0x9:
2316 gen_op_iwmmxt_addul_M0_wRn(rd1);
2317 break;
2318 case 0xb:
2319 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2320 break;
2321 default:
2322 return 1;
2323 }
2324 gen_op_iwmmxt_movq_wRn_M0(wrd);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2327 break;
2328 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2329 case 0x408: case 0x508: case 0x608: case 0x708:
2330 case 0x808: case 0x908: case 0xa08: case 0xb08:
2331 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2332 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2333 return 1;
2334 wrd = (insn >> 12) & 0xf;
2335 rd0 = (insn >> 16) & 0xf;
2336 rd1 = (insn >> 0) & 0xf;
2337 gen_op_iwmmxt_movq_M0_wRn(rd0);
2338 switch ((insn >> 22) & 3) {
2339 case 1:
2340 if (insn & (1 << 21))
2341 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2342 else
2343 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2344 break;
2345 case 2:
2346 if (insn & (1 << 21))
2347 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2348 else
2349 gen_op_iwmmxt_packul_M0_wRn(rd1);
2350 break;
2351 case 3:
2352 if (insn & (1 << 21))
2353 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2354 else
2355 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2356 break;
2357 }
2358 gen_op_iwmmxt_movq_wRn_M0(wrd);
2359 gen_op_iwmmxt_set_mup();
2360 gen_op_iwmmxt_set_cup();
2361 break;
2362 case 0x201: case 0x203: case 0x205: case 0x207:
2363 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2364 case 0x211: case 0x213: case 0x215: case 0x217:
2365 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2366 wrd = (insn >> 5) & 0xf;
2367 rd0 = (insn >> 12) & 0xf;
2368 rd1 = (insn >> 0) & 0xf;
2369 if (rd0 == 0xf || rd1 == 0xf)
2370 return 1;
2371 gen_op_iwmmxt_movq_M0_wRn(wrd);
2372 tmp = load_reg(s, rd0);
2373 tmp2 = load_reg(s, rd1);
2374 switch ((insn >> 16) & 0xf) {
2375 case 0x0: /* TMIA */
2376 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2377 break;
2378 case 0x8: /* TMIAPH */
2379 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2380 break;
2381 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2382 if (insn & (1 << 16))
2383 tcg_gen_shri_i32(tmp, tmp, 16);
2384 if (insn & (1 << 17))
2385 tcg_gen_shri_i32(tmp2, tmp2, 16);
2386 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2387 break;
2388 default:
2389 tcg_temp_free_i32(tmp2);
2390 tcg_temp_free_i32(tmp);
2391 return 1;
2392 }
2393 tcg_temp_free_i32(tmp2);
2394 tcg_temp_free_i32(tmp);
2395 gen_op_iwmmxt_movq_wRn_M0(wrd);
2396 gen_op_iwmmxt_set_mup();
2397 break;
2398 default:
2399 return 1;
2400 }
2401
2402 return 0;
2403 }
2404
2405 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2406 (ie. an undefined instruction). */
2407 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2408 {
2409 int acc, rd0, rd1, rdhi, rdlo;
2410 TCGv_i32 tmp, tmp2;
2411
2412 if ((insn & 0x0ff00f10) == 0x0e200010) {
2413 /* Multiply with Internal Accumulate Format */
2414 rd0 = (insn >> 12) & 0xf;
2415 rd1 = insn & 0xf;
2416 acc = (insn >> 5) & 7;
2417
2418 if (acc != 0)
2419 return 1;
2420
2421 tmp = load_reg(s, rd0);
2422 tmp2 = load_reg(s, rd1);
2423 switch ((insn >> 16) & 0xf) {
2424 case 0x0: /* MIA */
2425 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2426 break;
2427 case 0x8: /* MIAPH */
2428 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2429 break;
2430 case 0xc: /* MIABB */
2431 case 0xd: /* MIABT */
2432 case 0xe: /* MIATB */
2433 case 0xf: /* MIATT */
2434 if (insn & (1 << 16))
2435 tcg_gen_shri_i32(tmp, tmp, 16);
2436 if (insn & (1 << 17))
2437 tcg_gen_shri_i32(tmp2, tmp2, 16);
2438 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2439 break;
2440 default:
2441 return 1;
2442 }
2443 tcg_temp_free_i32(tmp2);
2444 tcg_temp_free_i32(tmp);
2445
2446 gen_op_iwmmxt_movq_wRn_M0(acc);
2447 return 0;
2448 }
2449
2450 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2451 /* Internal Accumulator Access Format */
2452 rdhi = (insn >> 16) & 0xf;
2453 rdlo = (insn >> 12) & 0xf;
2454 acc = insn & 7;
2455
2456 if (acc != 0)
2457 return 1;
2458
2459 if (insn & ARM_CP_RW_BIT) { /* MRA */
2460 iwmmxt_load_reg(cpu_V0, acc);
2461 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2462 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2463 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2464 } else { /* MAR */
2465 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2466 iwmmxt_store_reg(cpu_V0, acc);
2467 }
2468 return 0;
2469 }
2470
2471 return 1;
2472 }
2473
2474 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2475 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2476 if (dc_isar_feature(aa32_simd_r32, s)) { \
2477 reg = (((insn) >> (bigbit)) & 0x0f) \
2478 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2479 } else { \
2480 if (insn & (1 << (smallbit))) \
2481 return 1; \
2482 reg = ((insn) >> (bigbit)) & 0x0f; \
2483 }} while (0)
2484
2485 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2486 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2487 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2488
2489 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2490 {
2491 #ifndef CONFIG_USER_ONLY
2492 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2493 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2494 #else
2495 return true;
2496 #endif
2497 }
2498
2499 static void gen_goto_ptr(void)
2500 {
2501 tcg_gen_lookup_and_goto_ptr();
2502 }
2503
2504 /* This will end the TB but doesn't guarantee we'll return to
2505 * cpu_loop_exec. Any live exit_requests will be processed as we
2506 * enter the next TB.
2507 */
2508 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2509 {
2510 if (use_goto_tb(s, dest)) {
2511 tcg_gen_goto_tb(n);
2512 gen_set_pc_im(s, dest);
2513 tcg_gen_exit_tb(s->base.tb, n);
2514 } else {
2515 gen_set_pc_im(s, dest);
2516 gen_goto_ptr();
2517 }
2518 s->base.is_jmp = DISAS_NORETURN;
2519 }
2520
2521 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2522 {
2523 if (unlikely(is_singlestepping(s))) {
2524 /* An indirect jump so that we still trigger the debug exception. */
2525 gen_set_pc_im(s, dest);
2526 s->base.is_jmp = DISAS_JUMP;
2527 } else {
2528 gen_goto_tb(s, 0, dest);
2529 }
2530 }
2531
2532 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2533 {
2534 if (x)
2535 tcg_gen_sari_i32(t0, t0, 16);
2536 else
2537 gen_sxth(t0);
2538 if (y)
2539 tcg_gen_sari_i32(t1, t1, 16);
2540 else
2541 gen_sxth(t1);
2542 tcg_gen_mul_i32(t0, t0, t1);
2543 }
2544
2545 /* Return the mask of PSR bits set by a MSR instruction. */
2546 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2547 {
2548 uint32_t mask = 0;
2549
2550 if (flags & (1 << 0)) {
2551 mask |= 0xff;
2552 }
2553 if (flags & (1 << 1)) {
2554 mask |= 0xff00;
2555 }
2556 if (flags & (1 << 2)) {
2557 mask |= 0xff0000;
2558 }
2559 if (flags & (1 << 3)) {
2560 mask |= 0xff000000;
2561 }
2562
2563 /* Mask out undefined and reserved bits. */
2564 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2565
2566 /* Mask out execution state. */
2567 if (!spsr) {
2568 mask &= ~CPSR_EXEC;
2569 }
2570
2571 /* Mask out privileged bits. */
2572 if (IS_USER(s)) {
2573 mask &= CPSR_USER;
2574 }
2575 return mask;
2576 }
2577
2578 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2579 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2580 {
2581 TCGv_i32 tmp;
2582 if (spsr) {
2583 /* ??? This is also undefined in system mode. */
2584 if (IS_USER(s))
2585 return 1;
2586
2587 tmp = load_cpu_field(spsr);
2588 tcg_gen_andi_i32(tmp, tmp, ~mask);
2589 tcg_gen_andi_i32(t0, t0, mask);
2590 tcg_gen_or_i32(tmp, tmp, t0);
2591 store_cpu_field(tmp, spsr);
2592 } else {
2593 gen_set_cpsr(t0, mask);
2594 }
2595 tcg_temp_free_i32(t0);
2596 gen_lookup_tb(s);
2597 return 0;
2598 }
2599
2600 /* Returns nonzero if access to the PSR is not permitted. */
2601 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2602 {
2603 TCGv_i32 tmp;
2604 tmp = tcg_temp_new_i32();
2605 tcg_gen_movi_i32(tmp, val);
2606 return gen_set_psr(s, mask, spsr, tmp);
2607 }
2608
2609 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2610 int *tgtmode, int *regno)
2611 {
2612 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2613 * the target mode and register number, and identify the various
2614 * unpredictable cases.
2615 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2616 * + executed in user mode
2617 * + using R15 as the src/dest register
2618 * + accessing an unimplemented register
2619 * + accessing a register that's inaccessible at current PL/security state*
2620 * + accessing a register that you could access with a different insn
2621 * We choose to UNDEF in all these cases.
2622 * Since we don't know which of the various AArch32 modes we are in
2623 * we have to defer some checks to runtime.
2624 * Accesses to Monitor mode registers from Secure EL1 (which implies
2625 * that EL3 is AArch64) must trap to EL3.
2626 *
2627 * If the access checks fail this function will emit code to take
2628 * an exception and return false. Otherwise it will return true,
2629 * and set *tgtmode and *regno appropriately.
2630 */
2631 int exc_target = default_exception_el(s);
2632
2633 /* These instructions are present only in ARMv8, or in ARMv7 with the
2634 * Virtualization Extensions.
2635 */
2636 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2637 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2638 goto undef;
2639 }
2640
2641 if (IS_USER(s) || rn == 15) {
2642 goto undef;
2643 }
2644
2645 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2646 * of registers into (r, sysm).
2647 */
2648 if (r) {
2649 /* SPSRs for other modes */
2650 switch (sysm) {
2651 case 0xe: /* SPSR_fiq */
2652 *tgtmode = ARM_CPU_MODE_FIQ;
2653 break;
2654 case 0x10: /* SPSR_irq */
2655 *tgtmode = ARM_CPU_MODE_IRQ;
2656 break;
2657 case 0x12: /* SPSR_svc */
2658 *tgtmode = ARM_CPU_MODE_SVC;
2659 break;
2660 case 0x14: /* SPSR_abt */
2661 *tgtmode = ARM_CPU_MODE_ABT;
2662 break;
2663 case 0x16: /* SPSR_und */
2664 *tgtmode = ARM_CPU_MODE_UND;
2665 break;
2666 case 0x1c: /* SPSR_mon */
2667 *tgtmode = ARM_CPU_MODE_MON;
2668 break;
2669 case 0x1e: /* SPSR_hyp */
2670 *tgtmode = ARM_CPU_MODE_HYP;
2671 break;
2672 default: /* unallocated */
2673 goto undef;
2674 }
2675 /* We arbitrarily assign SPSR a register number of 16. */
2676 *regno = 16;
2677 } else {
2678 /* general purpose registers for other modes */
2679 switch (sysm) {
2680 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2681 *tgtmode = ARM_CPU_MODE_USR;
2682 *regno = sysm + 8;
2683 break;
2684 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2685 *tgtmode = ARM_CPU_MODE_FIQ;
2686 *regno = sysm;
2687 break;
2688 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2689 *tgtmode = ARM_CPU_MODE_IRQ;
2690 *regno = sysm & 1 ? 13 : 14;
2691 break;
2692 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2693 *tgtmode = ARM_CPU_MODE_SVC;
2694 *regno = sysm & 1 ? 13 : 14;
2695 break;
2696 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2697 *tgtmode = ARM_CPU_MODE_ABT;
2698 *regno = sysm & 1 ? 13 : 14;
2699 break;
2700 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2701 *tgtmode = ARM_CPU_MODE_UND;
2702 *regno = sysm & 1 ? 13 : 14;
2703 break;
2704 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2705 *tgtmode = ARM_CPU_MODE_MON;
2706 *regno = sysm & 1 ? 13 : 14;
2707 break;
2708 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2709 *tgtmode = ARM_CPU_MODE_HYP;
2710 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2711 *regno = sysm & 1 ? 13 : 17;
2712 break;
2713 default: /* unallocated */
2714 goto undef;
2715 }
2716 }
2717
2718 /* Catch the 'accessing inaccessible register' cases we can detect
2719 * at translate time.
2720 */
2721 switch (*tgtmode) {
2722 case ARM_CPU_MODE_MON:
2723 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2724 goto undef;
2725 }
2726 if (s->current_el == 1) {
2727 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2728 * then accesses to Mon registers trap to EL3
2729 */
2730 exc_target = 3;
2731 goto undef;
2732 }
2733 break;
2734 case ARM_CPU_MODE_HYP:
2735 /*
2736 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2737 * (and so we can forbid accesses from EL2 or below). elr_hyp
2738 * can be accessed also from Hyp mode, so forbid accesses from
2739 * EL0 or EL1.
2740 */
2741 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2742 (s->current_el < 3 && *regno != 17)) {
2743 goto undef;
2744 }
2745 break;
2746 default:
2747 break;
2748 }
2749
2750 return true;
2751
2752 undef:
2753 /* If we get here then some access check did not pass */
2754 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2755 syn_uncategorized(), exc_target);
2756 return false;
2757 }
2758
2759 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2760 {
2761 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2762 int tgtmode = 0, regno = 0;
2763
2764 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2765 return;
2766 }
2767
2768 /* Sync state because msr_banked() can raise exceptions */
2769 gen_set_condexec(s);
2770 gen_set_pc_im(s, s->pc_curr);
2771 tcg_reg = load_reg(s, rn);
2772 tcg_tgtmode = tcg_const_i32(tgtmode);
2773 tcg_regno = tcg_const_i32(regno);
2774 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2775 tcg_temp_free_i32(tcg_tgtmode);
2776 tcg_temp_free_i32(tcg_regno);
2777 tcg_temp_free_i32(tcg_reg);
2778 s->base.is_jmp = DISAS_UPDATE_EXIT;
2779 }
2780
2781 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2782 {
2783 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2784 int tgtmode = 0, regno = 0;
2785
2786 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2787 return;
2788 }
2789
2790 /* Sync state because mrs_banked() can raise exceptions */
2791 gen_set_condexec(s);
2792 gen_set_pc_im(s, s->pc_curr);
2793 tcg_reg = tcg_temp_new_i32();
2794 tcg_tgtmode = tcg_const_i32(tgtmode);
2795 tcg_regno = tcg_const_i32(regno);
2796 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2797 tcg_temp_free_i32(tcg_tgtmode);
2798 tcg_temp_free_i32(tcg_regno);
2799 store_reg(s, rn, tcg_reg);
2800 s->base.is_jmp = DISAS_UPDATE_EXIT;
2801 }
2802
2803 /* Store value to PC as for an exception return (ie don't
2804 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2805 * will do the masking based on the new value of the Thumb bit.
2806 */
2807 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2808 {
2809 tcg_gen_mov_i32(cpu_R[15], pc);
2810 tcg_temp_free_i32(pc);
2811 }
2812
2813 /* Generate a v6 exception return. Marks both values as dead. */
2814 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2815 {
2816 store_pc_exc_ret(s, pc);
2817 /* The cpsr_write_eret helper will mask the low bits of PC
2818 * appropriately depending on the new Thumb bit, so it must
2819 * be called after storing the new PC.
2820 */
2821 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2822 gen_io_start();
2823 }
2824 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2825 tcg_temp_free_i32(cpsr);
2826 /* Must exit loop to check un-masked IRQs */
2827 s->base.is_jmp = DISAS_EXIT;
2828 }
2829
2830 /* Generate an old-style exception return. Marks pc as dead. */
2831 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2832 {
2833 gen_rfe(s, pc, load_cpu_field(spsr));
2834 }
2835
2836 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
2837 uint32_t opr_sz, uint32_t max_sz,
2838 gen_helper_gvec_3_ptr *fn)
2839 {
2840 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
2841
2842 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
2843 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
2844 opr_sz, max_sz, 0, fn);
2845 tcg_temp_free_ptr(qc_ptr);
2846 }
2847
2848 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2849 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2850 {
2851 static gen_helper_gvec_3_ptr * const fns[2] = {
2852 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
2853 };
2854 tcg_debug_assert(vece >= 1 && vece <= 2);
2855 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2856 }
2857
2858 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2859 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2860 {
2861 static gen_helper_gvec_3_ptr * const fns[2] = {
2862 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
2863 };
2864 tcg_debug_assert(vece >= 1 && vece <= 2);
2865 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2866 }
2867
2868 #define GEN_CMP0(NAME, COND) \
2869 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
2870 { \
2871 tcg_gen_setcondi_i32(COND, d, a, 0); \
2872 tcg_gen_neg_i32(d, d); \
2873 } \
2874 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
2875 { \
2876 tcg_gen_setcondi_i64(COND, d, a, 0); \
2877 tcg_gen_neg_i64(d, d); \
2878 } \
2879 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
2880 { \
2881 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
2882 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
2883 tcg_temp_free_vec(zero); \
2884 } \
2885 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
2886 uint32_t opr_sz, uint32_t max_sz) \
2887 { \
2888 const GVecGen2 op[4] = { \
2889 { .fno = gen_helper_gvec_##NAME##0_b, \
2890 .fniv = gen_##NAME##0_vec, \
2891 .opt_opc = vecop_list_cmp, \
2892 .vece = MO_8 }, \
2893 { .fno = gen_helper_gvec_##NAME##0_h, \
2894 .fniv = gen_##NAME##0_vec, \
2895 .opt_opc = vecop_list_cmp, \
2896 .vece = MO_16 }, \
2897 { .fni4 = gen_##NAME##0_i32, \
2898 .fniv = gen_##NAME##0_vec, \
2899 .opt_opc = vecop_list_cmp, \
2900 .vece = MO_32 }, \
2901 { .fni8 = gen_##NAME##0_i64, \
2902 .fniv = gen_##NAME##0_vec, \
2903 .opt_opc = vecop_list_cmp, \
2904 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
2905 .vece = MO_64 }, \
2906 }; \
2907 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
2908 }
2909
2910 static const TCGOpcode vecop_list_cmp[] = {
2911 INDEX_op_cmp_vec, 0
2912 };
2913
2914 GEN_CMP0(ceq, TCG_COND_EQ)
2915 GEN_CMP0(cle, TCG_COND_LE)
2916 GEN_CMP0(cge, TCG_COND_GE)
2917 GEN_CMP0(clt, TCG_COND_LT)
2918 GEN_CMP0(cgt, TCG_COND_GT)
2919
2920 #undef GEN_CMP0
2921
2922 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2923 {
2924 tcg_gen_vec_sar8i_i64(a, a, shift);
2925 tcg_gen_vec_add8_i64(d, d, a);
2926 }
2927
2928 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2929 {
2930 tcg_gen_vec_sar16i_i64(a, a, shift);
2931 tcg_gen_vec_add16_i64(d, d, a);
2932 }
2933
2934 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
2935 {
2936 tcg_gen_sari_i32(a, a, shift);
2937 tcg_gen_add_i32(d, d, a);
2938 }
2939
2940 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2941 {
2942 tcg_gen_sari_i64(a, a, shift);
2943 tcg_gen_add_i64(d, d, a);
2944 }
2945
2946 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
2947 {
2948 tcg_gen_sari_vec(vece, a, a, sh);
2949 tcg_gen_add_vec(vece, d, d, a);
2950 }
2951
2952 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
2953 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
2954 {
2955 static const TCGOpcode vecop_list[] = {
2956 INDEX_op_sari_vec, INDEX_op_add_vec, 0
2957 };
2958 static const GVecGen2i ops[4] = {
2959 { .fni8 = gen_ssra8_i64,
2960 .fniv = gen_ssra_vec,
2961 .fno = gen_helper_gvec_ssra_b,
2962 .load_dest = true,
2963 .opt_opc = vecop_list,
2964 .vece = MO_8 },
2965 { .fni8 = gen_ssra16_i64,
2966 .fniv = gen_ssra_vec,
2967 .fno = gen_helper_gvec_ssra_h,
2968 .load_dest = true,
2969 .opt_opc = vecop_list,
2970 .vece = MO_16 },
2971 { .fni4 = gen_ssra32_i32,
2972 .fniv = gen_ssra_vec,
2973 .fno = gen_helper_gvec_ssra_s,
2974 .load_dest = true,
2975 .opt_opc = vecop_list,
2976 .vece = MO_32 },
2977 { .fni8 = gen_ssra64_i64,
2978 .fniv = gen_ssra_vec,
2979 .fno = gen_helper_gvec_ssra_b,
2980 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
2981 .opt_opc = vecop_list,
2982 .load_dest = true,
2983 .vece = MO_64 },
2984 };
2985
2986 /* tszimm encoding produces immediates in the range [1..esize]. */
2987 tcg_debug_assert(shift > 0);
2988 tcg_debug_assert(shift <= (8 << vece));
2989
2990 /*
2991 * Shifts larger than the element size are architecturally valid.
2992 * Signed results in all sign bits.
2993 */
2994 shift = MIN(shift, (8 << vece) - 1);
2995 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
2996 }
2997
2998 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2999 {
3000 tcg_gen_vec_shr8i_i64(a, a, shift);
3001 tcg_gen_vec_add8_i64(d, d, a);
3002 }
3003
3004 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3005 {
3006 tcg_gen_vec_shr16i_i64(a, a, shift);
3007 tcg_gen_vec_add16_i64(d, d, a);
3008 }
3009
3010 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3011 {
3012 tcg_gen_shri_i32(a, a, shift);
3013 tcg_gen_add_i32(d, d, a);
3014 }
3015
3016 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3017 {
3018 tcg_gen_shri_i64(a, a, shift);
3019 tcg_gen_add_i64(d, d, a);
3020 }
3021
3022 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3023 {
3024 tcg_gen_shri_vec(vece, a, a, sh);
3025 tcg_gen_add_vec(vece, d, d, a);
3026 }
3027
3028 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3029 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3030 {
3031 static const TCGOpcode vecop_list[] = {
3032 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3033 };
3034 static const GVecGen2i ops[4] = {
3035 { .fni8 = gen_usra8_i64,
3036 .fniv = gen_usra_vec,
3037 .fno = gen_helper_gvec_usra_b,
3038 .load_dest = true,
3039 .opt_opc = vecop_list,
3040 .vece = MO_8, },
3041 { .fni8 = gen_usra16_i64,
3042 .fniv = gen_usra_vec,
3043 .fno = gen_helper_gvec_usra_h,
3044 .load_dest = true,
3045 .opt_opc = vecop_list,
3046 .vece = MO_16, },
3047 { .fni4 = gen_usra32_i32,
3048 .fniv = gen_usra_vec,
3049 .fno = gen_helper_gvec_usra_s,
3050 .load_dest = true,
3051 .opt_opc = vecop_list,
3052 .vece = MO_32, },
3053 { .fni8 = gen_usra64_i64,
3054 .fniv = gen_usra_vec,
3055 .fno = gen_helper_gvec_usra_d,
3056 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3057 .load_dest = true,
3058 .opt_opc = vecop_list,
3059 .vece = MO_64, },
3060 };
3061
3062 /* tszimm encoding produces immediates in the range [1..esize]. */
3063 tcg_debug_assert(shift > 0);
3064 tcg_debug_assert(shift <= (8 << vece));
3065
3066 /*
3067 * Shifts larger than the element size are architecturally valid.
3068 * Unsigned results in all zeros as input to accumulate: nop.
3069 */
3070 if (shift < (8 << vece)) {
3071 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3072 } else {
3073 /* Nop, but we do need to clear the tail. */
3074 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3075 }
3076 }
3077
3078 /*
3079 * Shift one less than the requested amount, and the low bit is
3080 * the rounding bit. For the 8 and 16-bit operations, because we
3081 * mask the low bit, we can perform a normal integer shift instead
3082 * of a vector shift.
3083 */
3084 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3085 {
3086 TCGv_i64 t = tcg_temp_new_i64();
3087
3088 tcg_gen_shri_i64(t, a, sh - 1);
3089 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3090 tcg_gen_vec_sar8i_i64(d, a, sh);
3091 tcg_gen_vec_add8_i64(d, d, t);
3092 tcg_temp_free_i64(t);
3093 }
3094
3095 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3096 {
3097 TCGv_i64 t = tcg_temp_new_i64();
3098
3099 tcg_gen_shri_i64(t, a, sh - 1);
3100 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3101 tcg_gen_vec_sar16i_i64(d, a, sh);
3102 tcg_gen_vec_add16_i64(d, d, t);
3103 tcg_temp_free_i64(t);
3104 }
3105
3106 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3107 {
3108 TCGv_i32 t = tcg_temp_new_i32();
3109
3110 tcg_gen_extract_i32(t, a, sh - 1, 1);
3111 tcg_gen_sari_i32(d, a, sh);
3112 tcg_gen_add_i32(d, d, t);
3113 tcg_temp_free_i32(t);
3114 }
3115
3116 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3117 {
3118 TCGv_i64 t = tcg_temp_new_i64();
3119
3120 tcg_gen_extract_i64(t, a, sh - 1, 1);
3121 tcg_gen_sari_i64(d, a, sh);
3122 tcg_gen_add_i64(d, d, t);
3123 tcg_temp_free_i64(t);
3124 }
3125
3126 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3127 {
3128 TCGv_vec t = tcg_temp_new_vec_matching(d);
3129 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3130
3131 tcg_gen_shri_vec(vece, t, a, sh - 1);
3132 tcg_gen_dupi_vec(vece, ones, 1);
3133 tcg_gen_and_vec(vece, t, t, ones);
3134 tcg_gen_sari_vec(vece, d, a, sh);
3135 tcg_gen_add_vec(vece, d, d, t);
3136
3137 tcg_temp_free_vec(t);
3138 tcg_temp_free_vec(ones);
3139 }
3140
3141 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3142 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3143 {
3144 static const TCGOpcode vecop_list[] = {
3145 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3146 };
3147 static const GVecGen2i ops[4] = {
3148 { .fni8 = gen_srshr8_i64,
3149 .fniv = gen_srshr_vec,
3150 .fno = gen_helper_gvec_srshr_b,
3151 .opt_opc = vecop_list,
3152 .vece = MO_8 },
3153 { .fni8 = gen_srshr16_i64,
3154 .fniv = gen_srshr_vec,
3155 .fno = gen_helper_gvec_srshr_h,
3156 .opt_opc = vecop_list,
3157 .vece = MO_16 },
3158 { .fni4 = gen_srshr32_i32,
3159 .fniv = gen_srshr_vec,
3160 .fno = gen_helper_gvec_srshr_s,
3161 .opt_opc = vecop_list,
3162 .vece = MO_32 },
3163 { .fni8 = gen_srshr64_i64,
3164 .fniv = gen_srshr_vec,
3165 .fno = gen_helper_gvec_srshr_d,
3166 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3167 .opt_opc = vecop_list,
3168 .vece = MO_64 },
3169 };