migration: increase max-bandwidth to 128 MiB/s (1 Gib/s)
[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 #include "translate.h"
53
54 #if defined(CONFIG_USER_ONLY)
55 #define IS_USER(s) 1
56 #else
57 #define IS_USER(s) (s->user)
58 #endif
59
60 /* These are TCG temporaries used only by the legacy iwMMXt decoder */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 /* These are TCG globals which alias CPUARMState fields */
63 static TCGv_i32 cpu_R[16];
64 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
65 TCGv_i64 cpu_exclusive_addr;
66 TCGv_i64 cpu_exclusive_val;
67
68 #include "exec/gen-icount.h"
69
70 static const char * const regnames[] =
71 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
72 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
73
74 /* Function prototypes for gen_ functions calling Neon helpers. */
75 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
76 TCGv_i32, TCGv_i32);
77 /* Function prototypes for gen_ functions for fix point conversions */
78 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
79
80 /* initialize TCG globals. */
81 void arm_translate_init(void)
82 {
83 int i;
84
85 for (i = 0; i < 16; i++) {
86 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
87 offsetof(CPUARMState, regs[i]),
88 regnames[i]);
89 }
90 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
91 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
92 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
93 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
94
95 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
96 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
97 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
98 offsetof(CPUARMState, exclusive_val), "exclusive_val");
99
100 a64_translate_init();
101 }
102
103 /* Flags for the disas_set_da_iss info argument:
104 * lower bits hold the Rt register number, higher bits are flags.
105 */
106 typedef enum ISSInfo {
107 ISSNone = 0,
108 ISSRegMask = 0x1f,
109 ISSInvalid = (1 << 5),
110 ISSIsAcqRel = (1 << 6),
111 ISSIsWrite = (1 << 7),
112 ISSIs16Bit = (1 << 8),
113 } ISSInfo;
114
115 /* Save the syndrome information for a Data Abort */
116 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
117 {
118 uint32_t syn;
119 int sas = memop & MO_SIZE;
120 bool sse = memop & MO_SIGN;
121 bool is_acqrel = issinfo & ISSIsAcqRel;
122 bool is_write = issinfo & ISSIsWrite;
123 bool is_16bit = issinfo & ISSIs16Bit;
124 int srt = issinfo & ISSRegMask;
125
126 if (issinfo & ISSInvalid) {
127 /* Some callsites want to conditionally provide ISS info,
128 * eg "only if this was not a writeback"
129 */
130 return;
131 }
132
133 if (srt == 15) {
134 /* For AArch32, insns where the src/dest is R15 never generate
135 * ISS information. Catching that here saves checking at all
136 * the call sites.
137 */
138 return;
139 }
140
141 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
142 0, 0, 0, is_write, 0, is_16bit);
143 disas_set_insn_syndrome(s, syn);
144 }
145
146 static inline int get_a32_user_mem_index(DisasContext *s)
147 {
148 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
149 * insns:
150 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
151 * otherwise, access as if at PL0.
152 */
153 switch (s->mmu_idx) {
154 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
155 case ARMMMUIdx_E10_0:
156 case ARMMMUIdx_E10_1:
157 case ARMMMUIdx_E10_1_PAN:
158 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
159 case ARMMMUIdx_SE3:
160 case ARMMMUIdx_SE10_0:
161 case ARMMMUIdx_SE10_1:
162 case ARMMMUIdx_SE10_1_PAN:
163 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
164 case ARMMMUIdx_MUser:
165 case ARMMMUIdx_MPriv:
166 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
167 case ARMMMUIdx_MUserNegPri:
168 case ARMMMUIdx_MPrivNegPri:
169 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
170 case ARMMMUIdx_MSUser:
171 case ARMMMUIdx_MSPriv:
172 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
173 case ARMMMUIdx_MSUserNegPri:
174 case ARMMMUIdx_MSPrivNegPri:
175 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
176 default:
177 g_assert_not_reached();
178 }
179 }
180
181 static inline TCGv_i32 load_cpu_offset(int offset)
182 {
183 TCGv_i32 tmp = tcg_temp_new_i32();
184 tcg_gen_ld_i32(tmp, cpu_env, offset);
185 return tmp;
186 }
187
188 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
189
190 static inline void store_cpu_offset(TCGv_i32 var, int offset)
191 {
192 tcg_gen_st_i32(var, cpu_env, offset);
193 tcg_temp_free_i32(var);
194 }
195
196 #define store_cpu_field(var, name) \
197 store_cpu_offset(var, offsetof(CPUARMState, name))
198
199 /* The architectural value of PC. */
200 static uint32_t read_pc(DisasContext *s)
201 {
202 return s->pc_curr + (s->thumb ? 4 : 8);
203 }
204
205 /* Set a variable to the value of a CPU register. */
206 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
207 {
208 if (reg == 15) {
209 tcg_gen_movi_i32(var, read_pc(s));
210 } else {
211 tcg_gen_mov_i32(var, cpu_R[reg]);
212 }
213 }
214
215 /* Create a new temporary and set it to the value of a CPU register. */
216 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
217 {
218 TCGv_i32 tmp = tcg_temp_new_i32();
219 load_reg_var(s, tmp, reg);
220 return tmp;
221 }
222
223 /*
224 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
225 * This is used for load/store for which use of PC implies (literal),
226 * or ADD that implies ADR.
227 */
228 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
229 {
230 TCGv_i32 tmp = tcg_temp_new_i32();
231
232 if (reg == 15) {
233 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
234 } else {
235 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
236 }
237 return tmp;
238 }
239
240 /* Set a CPU register. The source must be a temporary and will be
241 marked as dead. */
242 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
243 {
244 if (reg == 15) {
245 /* In Thumb mode, we must ignore bit 0.
246 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
247 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
248 * We choose to ignore [1:0] in ARM mode for all architecture versions.
249 */
250 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
251 s->base.is_jmp = DISAS_JUMP;
252 }
253 tcg_gen_mov_i32(cpu_R[reg], var);
254 tcg_temp_free_i32(var);
255 }
256
257 /*
258 * Variant of store_reg which applies v8M stack-limit checks before updating
259 * SP. If the check fails this will result in an exception being taken.
260 * We disable the stack checks for CONFIG_USER_ONLY because we have
261 * no idea what the stack limits should be in that case.
262 * If stack checking is not being done this just acts like store_reg().
263 */
264 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
265 {
266 #ifndef CONFIG_USER_ONLY
267 if (s->v8m_stackcheck) {
268 gen_helper_v8m_stackcheck(cpu_env, var);
269 }
270 #endif
271 store_reg(s, 13, var);
272 }
273
274 /* Value extensions. */
275 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
276 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
277 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
278 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
279
280 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
281 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
282
283
284 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
285 {
286 TCGv_i32 tmp_mask = tcg_const_i32(mask);
287 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
288 tcg_temp_free_i32(tmp_mask);
289 }
290 /* Set NZCV flags from the high 4 bits of var. */
291 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
292
293 static void gen_exception_internal(int excp)
294 {
295 TCGv_i32 tcg_excp = tcg_const_i32(excp);
296
297 assert(excp_is_internal(excp));
298 gen_helper_exception_internal(cpu_env, tcg_excp);
299 tcg_temp_free_i32(tcg_excp);
300 }
301
302 static void gen_step_complete_exception(DisasContext *s)
303 {
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
312 */
313 gen_ss_advance(s);
314 gen_swstep_exception(s, 1, s->is_ldex);
315 s->base.is_jmp = DISAS_NORETURN;
316 }
317
318 static void gen_singlestep_exception(DisasContext *s)
319 {
320 /* Generate the right kind of exception for singlestep, which is
321 * either the architectural singlestep or EXCP_DEBUG for QEMU's
322 * gdb singlestepping.
323 */
324 if (s->ss_active) {
325 gen_step_complete_exception(s);
326 } else {
327 gen_exception_internal(EXCP_DEBUG);
328 }
329 }
330
331 static inline bool is_singlestepping(DisasContext *s)
332 {
333 /* Return true if we are singlestepping either because of
334 * architectural singlestep or QEMU gdbstub singlestep. This does
335 * not include the command line '-singlestep' mode which is rather
336 * misnamed as it only means "one instruction per TB" and doesn't
337 * affect the code we generate.
338 */
339 return s->base.singlestep_enabled || s->ss_active;
340 }
341
342 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
343 {
344 TCGv_i32 tmp1 = tcg_temp_new_i32();
345 TCGv_i32 tmp2 = tcg_temp_new_i32();
346 tcg_gen_ext16s_i32(tmp1, a);
347 tcg_gen_ext16s_i32(tmp2, b);
348 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
349 tcg_temp_free_i32(tmp2);
350 tcg_gen_sari_i32(a, a, 16);
351 tcg_gen_sari_i32(b, b, 16);
352 tcg_gen_mul_i32(b, b, a);
353 tcg_gen_mov_i32(a, tmp1);
354 tcg_temp_free_i32(tmp1);
355 }
356
357 /* Byteswap each halfword. */
358 static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
359 {
360 TCGv_i32 tmp = tcg_temp_new_i32();
361 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
362 tcg_gen_shri_i32(tmp, var, 8);
363 tcg_gen_and_i32(tmp, tmp, mask);
364 tcg_gen_and_i32(var, var, mask);
365 tcg_gen_shli_i32(var, var, 8);
366 tcg_gen_or_i32(dest, var, tmp);
367 tcg_temp_free_i32(mask);
368 tcg_temp_free_i32(tmp);
369 }
370
371 /* Byteswap low halfword and sign extend. */
372 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
373 {
374 tcg_gen_ext16u_i32(var, var);
375 tcg_gen_bswap16_i32(var, var);
376 tcg_gen_ext16s_i32(dest, var);
377 }
378
379 /* Swap low and high halfwords. */
380 static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
381 {
382 tcg_gen_rotri_i32(dest, var, 16);
383 }
384
385 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
386 tmp = (t0 ^ t1) & 0x8000;
387 t0 &= ~0x8000;
388 t1 &= ~0x8000;
389 t0 = (t0 + t1) ^ tmp;
390 */
391
392 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
393 {
394 TCGv_i32 tmp = tcg_temp_new_i32();
395 tcg_gen_xor_i32(tmp, t0, t1);
396 tcg_gen_andi_i32(tmp, tmp, 0x8000);
397 tcg_gen_andi_i32(t0, t0, ~0x8000);
398 tcg_gen_andi_i32(t1, t1, ~0x8000);
399 tcg_gen_add_i32(t0, t0, t1);
400 tcg_gen_xor_i32(dest, t0, tmp);
401 tcg_temp_free_i32(tmp);
402 }
403
404 /* Set N and Z flags from var. */
405 static inline void gen_logic_CC(TCGv_i32 var)
406 {
407 tcg_gen_mov_i32(cpu_NF, var);
408 tcg_gen_mov_i32(cpu_ZF, var);
409 }
410
411 /* dest = T0 + T1 + CF. */
412 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
413 {
414 tcg_gen_add_i32(dest, t0, t1);
415 tcg_gen_add_i32(dest, dest, cpu_CF);
416 }
417
418 /* dest = T0 - T1 + CF - 1. */
419 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
420 {
421 tcg_gen_sub_i32(dest, t0, t1);
422 tcg_gen_add_i32(dest, dest, cpu_CF);
423 tcg_gen_subi_i32(dest, dest, 1);
424 }
425
426 /* dest = T0 + T1. Compute C, N, V and Z flags */
427 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
428 {
429 TCGv_i32 tmp = tcg_temp_new_i32();
430 tcg_gen_movi_i32(tmp, 0);
431 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
432 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
433 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
434 tcg_gen_xor_i32(tmp, t0, t1);
435 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
436 tcg_temp_free_i32(tmp);
437 tcg_gen_mov_i32(dest, cpu_NF);
438 }
439
440 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
441 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
442 {
443 TCGv_i32 tmp = tcg_temp_new_i32();
444 if (TCG_TARGET_HAS_add2_i32) {
445 tcg_gen_movi_i32(tmp, 0);
446 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
447 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
448 } else {
449 TCGv_i64 q0 = tcg_temp_new_i64();
450 TCGv_i64 q1 = tcg_temp_new_i64();
451 tcg_gen_extu_i32_i64(q0, t0);
452 tcg_gen_extu_i32_i64(q1, t1);
453 tcg_gen_add_i64(q0, q0, q1);
454 tcg_gen_extu_i32_i64(q1, cpu_CF);
455 tcg_gen_add_i64(q0, q0, q1);
456 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
457 tcg_temp_free_i64(q0);
458 tcg_temp_free_i64(q1);
459 }
460 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
461 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
462 tcg_gen_xor_i32(tmp, t0, t1);
463 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
464 tcg_temp_free_i32(tmp);
465 tcg_gen_mov_i32(dest, cpu_NF);
466 }
467
468 /* dest = T0 - T1. Compute C, N, V and Z flags */
469 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
470 {
471 TCGv_i32 tmp;
472 tcg_gen_sub_i32(cpu_NF, t0, t1);
473 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
474 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
475 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
476 tmp = tcg_temp_new_i32();
477 tcg_gen_xor_i32(tmp, t0, t1);
478 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
479 tcg_temp_free_i32(tmp);
480 tcg_gen_mov_i32(dest, cpu_NF);
481 }
482
483 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
484 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
485 {
486 TCGv_i32 tmp = tcg_temp_new_i32();
487 tcg_gen_not_i32(tmp, t1);
488 gen_adc_CC(dest, t0, tmp);
489 tcg_temp_free_i32(tmp);
490 }
491
492 #define GEN_SHIFT(name) \
493 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
494 { \
495 TCGv_i32 tmp1, tmp2, tmp3; \
496 tmp1 = tcg_temp_new_i32(); \
497 tcg_gen_andi_i32(tmp1, t1, 0xff); \
498 tmp2 = tcg_const_i32(0); \
499 tmp3 = tcg_const_i32(0x1f); \
500 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
501 tcg_temp_free_i32(tmp3); \
502 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
503 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
504 tcg_temp_free_i32(tmp2); \
505 tcg_temp_free_i32(tmp1); \
506 }
507 GEN_SHIFT(shl)
508 GEN_SHIFT(shr)
509 #undef GEN_SHIFT
510
511 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
512 {
513 TCGv_i32 tmp1, tmp2;
514 tmp1 = tcg_temp_new_i32();
515 tcg_gen_andi_i32(tmp1, t1, 0xff);
516 tmp2 = tcg_const_i32(0x1f);
517 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
518 tcg_temp_free_i32(tmp2);
519 tcg_gen_sar_i32(dest, t0, tmp1);
520 tcg_temp_free_i32(tmp1);
521 }
522
523 static void shifter_out_im(TCGv_i32 var, int shift)
524 {
525 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
526 }
527
528 /* Shift by immediate. Includes special handling for shift == 0. */
529 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
530 int shift, int flags)
531 {
532 switch (shiftop) {
533 case 0: /* LSL */
534 if (shift != 0) {
535 if (flags)
536 shifter_out_im(var, 32 - shift);
537 tcg_gen_shli_i32(var, var, shift);
538 }
539 break;
540 case 1: /* LSR */
541 if (shift == 0) {
542 if (flags) {
543 tcg_gen_shri_i32(cpu_CF, var, 31);
544 }
545 tcg_gen_movi_i32(var, 0);
546 } else {
547 if (flags)
548 shifter_out_im(var, shift - 1);
549 tcg_gen_shri_i32(var, var, shift);
550 }
551 break;
552 case 2: /* ASR */
553 if (shift == 0)
554 shift = 32;
555 if (flags)
556 shifter_out_im(var, shift - 1);
557 if (shift == 32)
558 shift = 31;
559 tcg_gen_sari_i32(var, var, shift);
560 break;
561 case 3: /* ROR/RRX */
562 if (shift != 0) {
563 if (flags)
564 shifter_out_im(var, shift - 1);
565 tcg_gen_rotri_i32(var, var, shift); break;
566 } else {
567 TCGv_i32 tmp = tcg_temp_new_i32();
568 tcg_gen_shli_i32(tmp, cpu_CF, 31);
569 if (flags)
570 shifter_out_im(var, 0);
571 tcg_gen_shri_i32(var, var, 1);
572 tcg_gen_or_i32(var, var, tmp);
573 tcg_temp_free_i32(tmp);
574 }
575 }
576 };
577
578 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
579 TCGv_i32 shift, int flags)
580 {
581 if (flags) {
582 switch (shiftop) {
583 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
584 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
585 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
586 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
587 }
588 } else {
589 switch (shiftop) {
590 case 0:
591 gen_shl(var, var, shift);
592 break;
593 case 1:
594 gen_shr(var, var, shift);
595 break;
596 case 2:
597 gen_sar(var, var, shift);
598 break;
599 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
600 tcg_gen_rotr_i32(var, var, shift); break;
601 }
602 }
603 tcg_temp_free_i32(shift);
604 }
605
606 /*
607 * Generate a conditional based on ARM condition code cc.
608 * This is common between ARM and Aarch64 targets.
609 */
610 void arm_test_cc(DisasCompare *cmp, int cc)
611 {
612 TCGv_i32 value;
613 TCGCond cond;
614 bool global = true;
615
616 switch (cc) {
617 case 0: /* eq: Z */
618 case 1: /* ne: !Z */
619 cond = TCG_COND_EQ;
620 value = cpu_ZF;
621 break;
622
623 case 2: /* cs: C */
624 case 3: /* cc: !C */
625 cond = TCG_COND_NE;
626 value = cpu_CF;
627 break;
628
629 case 4: /* mi: N */
630 case 5: /* pl: !N */
631 cond = TCG_COND_LT;
632 value = cpu_NF;
633 break;
634
635 case 6: /* vs: V */
636 case 7: /* vc: !V */
637 cond = TCG_COND_LT;
638 value = cpu_VF;
639 break;
640
641 case 8: /* hi: C && !Z */
642 case 9: /* ls: !C || Z -> !(C && !Z) */
643 cond = TCG_COND_NE;
644 value = tcg_temp_new_i32();
645 global = false;
646 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
647 ZF is non-zero for !Z; so AND the two subexpressions. */
648 tcg_gen_neg_i32(value, cpu_CF);
649 tcg_gen_and_i32(value, value, cpu_ZF);
650 break;
651
652 case 10: /* ge: N == V -> N ^ V == 0 */
653 case 11: /* lt: N != V -> N ^ V != 0 */
654 /* Since we're only interested in the sign bit, == 0 is >= 0. */
655 cond = TCG_COND_GE;
656 value = tcg_temp_new_i32();
657 global = false;
658 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
659 break;
660
661 case 12: /* gt: !Z && N == V */
662 case 13: /* le: Z || N != V */
663 cond = TCG_COND_NE;
664 value = tcg_temp_new_i32();
665 global = false;
666 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
667 * the sign bit then AND with ZF to yield the result. */
668 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
669 tcg_gen_sari_i32(value, value, 31);
670 tcg_gen_andc_i32(value, cpu_ZF, value);
671 break;
672
673 case 14: /* always */
674 case 15: /* always */
675 /* Use the ALWAYS condition, which will fold early.
676 * It doesn't matter what we use for the value. */
677 cond = TCG_COND_ALWAYS;
678 value = cpu_ZF;
679 goto no_invert;
680
681 default:
682 fprintf(stderr, "Bad condition code 0x%x\n", cc);
683 abort();
684 }
685
686 if (cc & 1) {
687 cond = tcg_invert_cond(cond);
688 }
689
690 no_invert:
691 cmp->cond = cond;
692 cmp->value = value;
693 cmp->value_global = global;
694 }
695
696 void arm_free_cc(DisasCompare *cmp)
697 {
698 if (!cmp->value_global) {
699 tcg_temp_free_i32(cmp->value);
700 }
701 }
702
703 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
704 {
705 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
706 }
707
708 void arm_gen_test_cc(int cc, TCGLabel *label)
709 {
710 DisasCompare cmp;
711 arm_test_cc(&cmp, cc);
712 arm_jump_cc(&cmp, label);
713 arm_free_cc(&cmp);
714 }
715
716 static inline void gen_set_condexec(DisasContext *s)
717 {
718 if (s->condexec_mask) {
719 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
720 TCGv_i32 tmp = tcg_temp_new_i32();
721 tcg_gen_movi_i32(tmp, val);
722 store_cpu_field(tmp, condexec_bits);
723 }
724 }
725
726 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
727 {
728 tcg_gen_movi_i32(cpu_R[15], val);
729 }
730
731 /* Set PC and Thumb state from var. var is marked as dead. */
732 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
733 {
734 s->base.is_jmp = DISAS_JUMP;
735 tcg_gen_andi_i32(cpu_R[15], var, ~1);
736 tcg_gen_andi_i32(var, var, 1);
737 store_cpu_field(var, thumb);
738 }
739
740 /*
741 * Set PC and Thumb state from var. var is marked as dead.
742 * For M-profile CPUs, include logic to detect exception-return
743 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
744 * and BX reg, and no others, and happens only for code in Handler mode.
745 * The Security Extension also requires us to check for the FNC_RETURN
746 * which signals a function return from non-secure state; this can happen
747 * in both Handler and Thread mode.
748 * To avoid having to do multiple comparisons in inline generated code,
749 * we make the check we do here loose, so it will match for EXC_RETURN
750 * in Thread mode. For system emulation do_v7m_exception_exit() checks
751 * for these spurious cases and returns without doing anything (giving
752 * the same behaviour as for a branch to a non-magic address).
753 *
754 * In linux-user mode it is unclear what the right behaviour for an
755 * attempted FNC_RETURN should be, because in real hardware this will go
756 * directly to Secure code (ie not the Linux kernel) which will then treat
757 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
758 * attempt behave the way it would on a CPU without the security extension,
759 * which is to say "like a normal branch". That means we can simply treat
760 * all branches as normal with no magic address behaviour.
761 */
762 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
763 {
764 /* Generate the same code here as for a simple bx, but flag via
765 * s->base.is_jmp that we need to do the rest of the work later.
766 */
767 gen_bx(s, var);
768 #ifndef CONFIG_USER_ONLY
769 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
770 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
771 s->base.is_jmp = DISAS_BX_EXCRET;
772 }
773 #endif
774 }
775
776 static inline void gen_bx_excret_final_code(DisasContext *s)
777 {
778 /* Generate the code to finish possible exception return and end the TB */
779 TCGLabel *excret_label = gen_new_label();
780 uint32_t min_magic;
781
782 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
783 /* Covers FNC_RETURN and EXC_RETURN magic */
784 min_magic = FNC_RETURN_MIN_MAGIC;
785 } else {
786 /* EXC_RETURN magic only */
787 min_magic = EXC_RETURN_MIN_MAGIC;
788 }
789
790 /* Is the new PC value in the magic range indicating exception return? */
791 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
792 /* No: end the TB as we would for a DISAS_JMP */
793 if (is_singlestepping(s)) {
794 gen_singlestep_exception(s);
795 } else {
796 tcg_gen_exit_tb(NULL, 0);
797 }
798 gen_set_label(excret_label);
799 /* Yes: this is an exception return.
800 * At this point in runtime env->regs[15] and env->thumb will hold
801 * the exception-return magic number, which do_v7m_exception_exit()
802 * will read. Nothing else will be able to see those values because
803 * the cpu-exec main loop guarantees that we will always go straight
804 * from raising the exception to the exception-handling code.
805 *
806 * gen_ss_advance(s) does nothing on M profile currently but
807 * calling it is conceptually the right thing as we have executed
808 * this instruction (compare SWI, HVC, SMC handling).
809 */
810 gen_ss_advance(s);
811 gen_exception_internal(EXCP_EXCEPTION_EXIT);
812 }
813
814 static inline void gen_bxns(DisasContext *s, int rm)
815 {
816 TCGv_i32 var = load_reg(s, rm);
817
818 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
819 * we need to sync state before calling it, but:
820 * - we don't need to do gen_set_pc_im() because the bxns helper will
821 * always set the PC itself
822 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
823 * unless it's outside an IT block or the last insn in an IT block,
824 * so we know that condexec == 0 (already set at the top of the TB)
825 * is correct in the non-UNPREDICTABLE cases, and we can choose
826 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
827 */
828 gen_helper_v7m_bxns(cpu_env, var);
829 tcg_temp_free_i32(var);
830 s->base.is_jmp = DISAS_EXIT;
831 }
832
833 static inline void gen_blxns(DisasContext *s, int rm)
834 {
835 TCGv_i32 var = load_reg(s, rm);
836
837 /* We don't need to sync condexec state, for the same reason as bxns.
838 * We do however need to set the PC, because the blxns helper reads it.
839 * The blxns helper may throw an exception.
840 */
841 gen_set_pc_im(s, s->base.pc_next);
842 gen_helper_v7m_blxns(cpu_env, var);
843 tcg_temp_free_i32(var);
844 s->base.is_jmp = DISAS_EXIT;
845 }
846
847 /* Variant of store_reg which uses branch&exchange logic when storing
848 to r15 in ARM architecture v7 and above. The source must be a temporary
849 and will be marked as dead. */
850 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
851 {
852 if (reg == 15 && ENABLE_ARCH_7) {
853 gen_bx(s, var);
854 } else {
855 store_reg(s, reg, var);
856 }
857 }
858
859 /* Variant of store_reg which uses branch&exchange logic when storing
860 * to r15 in ARM architecture v5T and above. This is used for storing
861 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
862 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
863 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
864 {
865 if (reg == 15 && ENABLE_ARCH_5) {
866 gen_bx_excret(s, var);
867 } else {
868 store_reg(s, reg, var);
869 }
870 }
871
872 #ifdef CONFIG_USER_ONLY
873 #define IS_USER_ONLY 1
874 #else
875 #define IS_USER_ONLY 0
876 #endif
877
878 /* Abstractions of "generate code to do a guest load/store for
879 * AArch32", where a vaddr is always 32 bits (and is zero
880 * extended if we're a 64 bit core) and data is also
881 * 32 bits unless specifically doing a 64 bit access.
882 * These functions work like tcg_gen_qemu_{ld,st}* except
883 * that the address argument is TCGv_i32 rather than TCGv.
884 */
885
886 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
887 {
888 TCGv addr = tcg_temp_new();
889 tcg_gen_extu_i32_tl(addr, a32);
890
891 /* Not needed for user-mode BE32, where we use MO_BE instead. */
892 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
893 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
894 }
895 return addr;
896 }
897
898 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
899 int index, MemOp opc)
900 {
901 TCGv addr;
902
903 if (arm_dc_feature(s, ARM_FEATURE_M) &&
904 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
905 opc |= MO_ALIGN;
906 }
907
908 addr = gen_aa32_addr(s, a32, opc);
909 tcg_gen_qemu_ld_i32(val, addr, index, opc);
910 tcg_temp_free(addr);
911 }
912
913 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
914 int index, MemOp opc)
915 {
916 TCGv addr;
917
918 if (arm_dc_feature(s, ARM_FEATURE_M) &&
919 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
920 opc |= MO_ALIGN;
921 }
922
923 addr = gen_aa32_addr(s, a32, opc);
924 tcg_gen_qemu_st_i32(val, addr, index, opc);
925 tcg_temp_free(addr);
926 }
927
928 #define DO_GEN_LD(SUFF, OPC) \
929 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
930 TCGv_i32 a32, int index) \
931 { \
932 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
933 }
934
935 #define DO_GEN_ST(SUFF, OPC) \
936 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
937 TCGv_i32 a32, int index) \
938 { \
939 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
940 }
941
942 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
943 {
944 /* Not needed for user-mode BE32, where we use MO_BE instead. */
945 if (!IS_USER_ONLY && s->sctlr_b) {
946 tcg_gen_rotri_i64(val, val, 32);
947 }
948 }
949
950 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
951 int index, MemOp opc)
952 {
953 TCGv addr = gen_aa32_addr(s, a32, opc);
954 tcg_gen_qemu_ld_i64(val, addr, index, opc);
955 gen_aa32_frob64(s, val);
956 tcg_temp_free(addr);
957 }
958
959 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
960 TCGv_i32 a32, int index)
961 {
962 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
963 }
964
965 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
966 int index, MemOp opc)
967 {
968 TCGv addr = gen_aa32_addr(s, a32, opc);
969
970 /* Not needed for user-mode BE32, where we use MO_BE instead. */
971 if (!IS_USER_ONLY && s->sctlr_b) {
972 TCGv_i64 tmp = tcg_temp_new_i64();
973 tcg_gen_rotri_i64(tmp, val, 32);
974 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
975 tcg_temp_free_i64(tmp);
976 } else {
977 tcg_gen_qemu_st_i64(val, addr, index, opc);
978 }
979 tcg_temp_free(addr);
980 }
981
982 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
983 TCGv_i32 a32, int index)
984 {
985 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
986 }
987
988 DO_GEN_LD(8u, MO_UB)
989 DO_GEN_LD(16u, MO_UW)
990 DO_GEN_LD(32u, MO_UL)
991 DO_GEN_ST(8, MO_UB)
992 DO_GEN_ST(16, MO_UW)
993 DO_GEN_ST(32, MO_UL)
994
995 static inline void gen_hvc(DisasContext *s, int imm16)
996 {
997 /* The pre HVC helper handles cases when HVC gets trapped
998 * as an undefined insn by runtime configuration (ie before
999 * the insn really executes).
1000 */
1001 gen_set_pc_im(s, s->pc_curr);
1002 gen_helper_pre_hvc(cpu_env);
1003 /* Otherwise we will treat this as a real exception which
1004 * happens after execution of the insn. (The distinction matters
1005 * for the PC value reported to the exception handler and also
1006 * for single stepping.)
1007 */
1008 s->svc_imm = imm16;
1009 gen_set_pc_im(s, s->base.pc_next);
1010 s->base.is_jmp = DISAS_HVC;
1011 }
1012
1013 static inline void gen_smc(DisasContext *s)
1014 {
1015 /* As with HVC, we may take an exception either before or after
1016 * the insn executes.
1017 */
1018 TCGv_i32 tmp;
1019
1020 gen_set_pc_im(s, s->pc_curr);
1021 tmp = tcg_const_i32(syn_aa32_smc());
1022 gen_helper_pre_smc(cpu_env, tmp);
1023 tcg_temp_free_i32(tmp);
1024 gen_set_pc_im(s, s->base.pc_next);
1025 s->base.is_jmp = DISAS_SMC;
1026 }
1027
1028 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1029 {
1030 gen_set_condexec(s);
1031 gen_set_pc_im(s, pc);
1032 gen_exception_internal(excp);
1033 s->base.is_jmp = DISAS_NORETURN;
1034 }
1035
1036 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1037 int syn, uint32_t target_el)
1038 {
1039 gen_set_condexec(s);
1040 gen_set_pc_im(s, pc);
1041 gen_exception(excp, syn, target_el);
1042 s->base.is_jmp = DISAS_NORETURN;
1043 }
1044
1045 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1046 {
1047 TCGv_i32 tcg_syn;
1048
1049 gen_set_condexec(s);
1050 gen_set_pc_im(s, s->pc_curr);
1051 tcg_syn = tcg_const_i32(syn);
1052 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1053 tcg_temp_free_i32(tcg_syn);
1054 s->base.is_jmp = DISAS_NORETURN;
1055 }
1056
1057 static void unallocated_encoding(DisasContext *s)
1058 {
1059 /* Unallocated and reserved encodings are uncategorized */
1060 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1061 default_exception_el(s));
1062 }
1063
1064 /* Force a TB lookup after an instruction that changes the CPU state. */
1065 static inline void gen_lookup_tb(DisasContext *s)
1066 {
1067 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1068 s->base.is_jmp = DISAS_EXIT;
1069 }
1070
1071 static inline void gen_hlt(DisasContext *s, int imm)
1072 {
1073 /* HLT. This has two purposes.
1074 * Architecturally, it is an external halting debug instruction.
1075 * Since QEMU doesn't implement external debug, we treat this as
1076 * it is required for halting debug disabled: it will UNDEF.
1077 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1078 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1079 * must trigger semihosting even for ARMv7 and earlier, where
1080 * HLT was an undefined encoding.
1081 * In system mode, we don't allow userspace access to
1082 * semihosting, to provide some semblance of security
1083 * (and for consistency with our 32-bit semihosting).
1084 */
1085 if (semihosting_enabled() &&
1086 #ifndef CONFIG_USER_ONLY
1087 s->current_el != 0 &&
1088 #endif
1089 (imm == (s->thumb ? 0x3c : 0xf000))) {
1090 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1091 return;
1092 }
1093
1094 unallocated_encoding(s);
1095 }
1096
1097 static inline long vfp_reg_offset(bool dp, unsigned reg)
1098 {
1099 if (dp) {
1100 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1101 } else {
1102 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1103 if (reg & 1) {
1104 ofs += offsetof(CPU_DoubleU, l.upper);
1105 } else {
1106 ofs += offsetof(CPU_DoubleU, l.lower);
1107 }
1108 return ofs;
1109 }
1110 }
1111
1112 /* Return the offset of a 32-bit piece of a NEON register.
1113 zero is the least significant end of the register. */
1114 static inline long
1115 neon_reg_offset (int reg, int n)
1116 {
1117 int sreg;
1118 sreg = reg * 2 + n;
1119 return vfp_reg_offset(0, sreg);
1120 }
1121
1122 static TCGv_i32 neon_load_reg(int reg, int pass)
1123 {
1124 TCGv_i32 tmp = tcg_temp_new_i32();
1125 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1126 return tmp;
1127 }
1128
1129 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1130 {
1131 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1132 tcg_temp_free_i32(var);
1133 }
1134
1135 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1136 {
1137 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1138 }
1139
1140 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1141 {
1142 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1143 }
1144
1145 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1146 {
1147 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1148 }
1149
1150 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1151 {
1152 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1153 }
1154
1155 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1156 {
1157 TCGv_ptr ret = tcg_temp_new_ptr();
1158 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1159 return ret;
1160 }
1161
1162 #define ARM_CP_RW_BIT (1 << 20)
1163
1164 /* Include the VFP and Neon decoders */
1165 #include "decode-m-nocp.c.inc"
1166 #include "translate-vfp.c.inc"
1167 #include "translate-neon.c.inc"
1168
1169 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1170 {
1171 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1172 }
1173
1174 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1175 {
1176 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1177 }
1178
1179 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1180 {
1181 TCGv_i32 var = tcg_temp_new_i32();
1182 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1183 return var;
1184 }
1185
1186 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1187 {
1188 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1189 tcg_temp_free_i32(var);
1190 }
1191
1192 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1193 {
1194 iwmmxt_store_reg(cpu_M0, rn);
1195 }
1196
1197 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1198 {
1199 iwmmxt_load_reg(cpu_M0, rn);
1200 }
1201
1202 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1203 {
1204 iwmmxt_load_reg(cpu_V1, rn);
1205 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1206 }
1207
1208 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1209 {
1210 iwmmxt_load_reg(cpu_V1, rn);
1211 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1212 }
1213
1214 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1215 {
1216 iwmmxt_load_reg(cpu_V1, rn);
1217 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1218 }
1219
1220 #define IWMMXT_OP(name) \
1221 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1222 { \
1223 iwmmxt_load_reg(cpu_V1, rn); \
1224 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1225 }
1226
1227 #define IWMMXT_OP_ENV(name) \
1228 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1229 { \
1230 iwmmxt_load_reg(cpu_V1, rn); \
1231 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1232 }
1233
1234 #define IWMMXT_OP_ENV_SIZE(name) \
1235 IWMMXT_OP_ENV(name##b) \
1236 IWMMXT_OP_ENV(name##w) \
1237 IWMMXT_OP_ENV(name##l)
1238
1239 #define IWMMXT_OP_ENV1(name) \
1240 static inline void gen_op_iwmmxt_##name##_M0(void) \
1241 { \
1242 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1243 }
1244
1245 IWMMXT_OP(maddsq)
1246 IWMMXT_OP(madduq)
1247 IWMMXT_OP(sadb)
1248 IWMMXT_OP(sadw)
1249 IWMMXT_OP(mulslw)
1250 IWMMXT_OP(mulshw)
1251 IWMMXT_OP(mululw)
1252 IWMMXT_OP(muluhw)
1253 IWMMXT_OP(macsw)
1254 IWMMXT_OP(macuw)
1255
1256 IWMMXT_OP_ENV_SIZE(unpackl)
1257 IWMMXT_OP_ENV_SIZE(unpackh)
1258
1259 IWMMXT_OP_ENV1(unpacklub)
1260 IWMMXT_OP_ENV1(unpackluw)
1261 IWMMXT_OP_ENV1(unpacklul)
1262 IWMMXT_OP_ENV1(unpackhub)
1263 IWMMXT_OP_ENV1(unpackhuw)
1264 IWMMXT_OP_ENV1(unpackhul)
1265 IWMMXT_OP_ENV1(unpacklsb)
1266 IWMMXT_OP_ENV1(unpacklsw)
1267 IWMMXT_OP_ENV1(unpacklsl)
1268 IWMMXT_OP_ENV1(unpackhsb)
1269 IWMMXT_OP_ENV1(unpackhsw)
1270 IWMMXT_OP_ENV1(unpackhsl)
1271
1272 IWMMXT_OP_ENV_SIZE(cmpeq)
1273 IWMMXT_OP_ENV_SIZE(cmpgtu)
1274 IWMMXT_OP_ENV_SIZE(cmpgts)
1275
1276 IWMMXT_OP_ENV_SIZE(mins)
1277 IWMMXT_OP_ENV_SIZE(minu)
1278 IWMMXT_OP_ENV_SIZE(maxs)
1279 IWMMXT_OP_ENV_SIZE(maxu)
1280
1281 IWMMXT_OP_ENV_SIZE(subn)
1282 IWMMXT_OP_ENV_SIZE(addn)
1283 IWMMXT_OP_ENV_SIZE(subu)
1284 IWMMXT_OP_ENV_SIZE(addu)
1285 IWMMXT_OP_ENV_SIZE(subs)
1286 IWMMXT_OP_ENV_SIZE(adds)
1287
1288 IWMMXT_OP_ENV(avgb0)
1289 IWMMXT_OP_ENV(avgb1)
1290 IWMMXT_OP_ENV(avgw0)
1291 IWMMXT_OP_ENV(avgw1)
1292
1293 IWMMXT_OP_ENV(packuw)
1294 IWMMXT_OP_ENV(packul)
1295 IWMMXT_OP_ENV(packuq)
1296 IWMMXT_OP_ENV(packsw)
1297 IWMMXT_OP_ENV(packsl)
1298 IWMMXT_OP_ENV(packsq)
1299
1300 static void gen_op_iwmmxt_set_mup(void)
1301 {
1302 TCGv_i32 tmp;
1303 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1304 tcg_gen_ori_i32(tmp, tmp, 2);
1305 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1306 }
1307
1308 static void gen_op_iwmmxt_set_cup(void)
1309 {
1310 TCGv_i32 tmp;
1311 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1312 tcg_gen_ori_i32(tmp, tmp, 1);
1313 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1314 }
1315
1316 static void gen_op_iwmmxt_setpsr_nz(void)
1317 {
1318 TCGv_i32 tmp = tcg_temp_new_i32();
1319 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1320 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1321 }
1322
1323 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1324 {
1325 iwmmxt_load_reg(cpu_V1, rn);
1326 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1327 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1328 }
1329
1330 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1331 TCGv_i32 dest)
1332 {
1333 int rd;
1334 uint32_t offset;
1335 TCGv_i32 tmp;
1336
1337 rd = (insn >> 16) & 0xf;
1338 tmp = load_reg(s, rd);
1339
1340 offset = (insn & 0xff) << ((insn >> 7) & 2);
1341 if (insn & (1 << 24)) {
1342 /* Pre indexed */
1343 if (insn & (1 << 23))
1344 tcg_gen_addi_i32(tmp, tmp, offset);
1345 else
1346 tcg_gen_addi_i32(tmp, tmp, -offset);
1347 tcg_gen_mov_i32(dest, tmp);
1348 if (insn & (1 << 21))
1349 store_reg(s, rd, tmp);
1350 else
1351 tcg_temp_free_i32(tmp);
1352 } else if (insn & (1 << 21)) {
1353 /* Post indexed */
1354 tcg_gen_mov_i32(dest, tmp);
1355 if (insn & (1 << 23))
1356 tcg_gen_addi_i32(tmp, tmp, offset);
1357 else
1358 tcg_gen_addi_i32(tmp, tmp, -offset);
1359 store_reg(s, rd, tmp);
1360 } else if (!(insn & (1 << 23)))
1361 return 1;
1362 return 0;
1363 }
1364
1365 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1366 {
1367 int rd = (insn >> 0) & 0xf;
1368 TCGv_i32 tmp;
1369
1370 if (insn & (1 << 8)) {
1371 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1372 return 1;
1373 } else {
1374 tmp = iwmmxt_load_creg(rd);
1375 }
1376 } else {
1377 tmp = tcg_temp_new_i32();
1378 iwmmxt_load_reg(cpu_V0, rd);
1379 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1380 }
1381 tcg_gen_andi_i32(tmp, tmp, mask);
1382 tcg_gen_mov_i32(dest, tmp);
1383 tcg_temp_free_i32(tmp);
1384 return 0;
1385 }
1386
1387 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1388 (ie. an undefined instruction). */
1389 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1390 {
1391 int rd, wrd;
1392 int rdhi, rdlo, rd0, rd1, i;
1393 TCGv_i32 addr;
1394 TCGv_i32 tmp, tmp2, tmp3;
1395
1396 if ((insn & 0x0e000e00) == 0x0c000000) {
1397 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1398 wrd = insn & 0xf;
1399 rdlo = (insn >> 12) & 0xf;
1400 rdhi = (insn >> 16) & 0xf;
1401 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1402 iwmmxt_load_reg(cpu_V0, wrd);
1403 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1404 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1405 } else { /* TMCRR */
1406 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1407 iwmmxt_store_reg(cpu_V0, wrd);
1408 gen_op_iwmmxt_set_mup();
1409 }
1410 return 0;
1411 }
1412
1413 wrd = (insn >> 12) & 0xf;
1414 addr = tcg_temp_new_i32();
1415 if (gen_iwmmxt_address(s, insn, addr)) {
1416 tcg_temp_free_i32(addr);
1417 return 1;
1418 }
1419 if (insn & ARM_CP_RW_BIT) {
1420 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1421 tmp = tcg_temp_new_i32();
1422 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1423 iwmmxt_store_creg(wrd, tmp);
1424 } else {
1425 i = 1;
1426 if (insn & (1 << 8)) {
1427 if (insn & (1 << 22)) { /* WLDRD */
1428 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1429 i = 0;
1430 } else { /* WLDRW wRd */
1431 tmp = tcg_temp_new_i32();
1432 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1433 }
1434 } else {
1435 tmp = tcg_temp_new_i32();
1436 if (insn & (1 << 22)) { /* WLDRH */
1437 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1438 } else { /* WLDRB */
1439 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1440 }
1441 }
1442 if (i) {
1443 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1444 tcg_temp_free_i32(tmp);
1445 }
1446 gen_op_iwmmxt_movq_wRn_M0(wrd);
1447 }
1448 } else {
1449 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1450 tmp = iwmmxt_load_creg(wrd);
1451 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1452 } else {
1453 gen_op_iwmmxt_movq_M0_wRn(wrd);
1454 tmp = tcg_temp_new_i32();
1455 if (insn & (1 << 8)) {
1456 if (insn & (1 << 22)) { /* WSTRD */
1457 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1458 } else { /* WSTRW wRd */
1459 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1460 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1461 }
1462 } else {
1463 if (insn & (1 << 22)) { /* WSTRH */
1464 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1465 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1466 } else { /* WSTRB */
1467 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1468 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1469 }
1470 }
1471 }
1472 tcg_temp_free_i32(tmp);
1473 }
1474 tcg_temp_free_i32(addr);
1475 return 0;
1476 }
1477
1478 if ((insn & 0x0f000000) != 0x0e000000)
1479 return 1;
1480
1481 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1482 case 0x000: /* WOR */
1483 wrd = (insn >> 12) & 0xf;
1484 rd0 = (insn >> 0) & 0xf;
1485 rd1 = (insn >> 16) & 0xf;
1486 gen_op_iwmmxt_movq_M0_wRn(rd0);
1487 gen_op_iwmmxt_orq_M0_wRn(rd1);
1488 gen_op_iwmmxt_setpsr_nz();
1489 gen_op_iwmmxt_movq_wRn_M0(wrd);
1490 gen_op_iwmmxt_set_mup();
1491 gen_op_iwmmxt_set_cup();
1492 break;
1493 case 0x011: /* TMCR */
1494 if (insn & 0xf)
1495 return 1;
1496 rd = (insn >> 12) & 0xf;
1497 wrd = (insn >> 16) & 0xf;
1498 switch (wrd) {
1499 case ARM_IWMMXT_wCID:
1500 case ARM_IWMMXT_wCASF:
1501 break;
1502 case ARM_IWMMXT_wCon:
1503 gen_op_iwmmxt_set_cup();
1504 /* Fall through. */
1505 case ARM_IWMMXT_wCSSF:
1506 tmp = iwmmxt_load_creg(wrd);
1507 tmp2 = load_reg(s, rd);
1508 tcg_gen_andc_i32(tmp, tmp, tmp2);
1509 tcg_temp_free_i32(tmp2);
1510 iwmmxt_store_creg(wrd, tmp);
1511 break;
1512 case ARM_IWMMXT_wCGR0:
1513 case ARM_IWMMXT_wCGR1:
1514 case ARM_IWMMXT_wCGR2:
1515 case ARM_IWMMXT_wCGR3:
1516 gen_op_iwmmxt_set_cup();
1517 tmp = load_reg(s, rd);
1518 iwmmxt_store_creg(wrd, tmp);
1519 break;
1520 default:
1521 return 1;
1522 }
1523 break;
1524 case 0x100: /* WXOR */
1525 wrd = (insn >> 12) & 0xf;
1526 rd0 = (insn >> 0) & 0xf;
1527 rd1 = (insn >> 16) & 0xf;
1528 gen_op_iwmmxt_movq_M0_wRn(rd0);
1529 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1530 gen_op_iwmmxt_setpsr_nz();
1531 gen_op_iwmmxt_movq_wRn_M0(wrd);
1532 gen_op_iwmmxt_set_mup();
1533 gen_op_iwmmxt_set_cup();
1534 break;
1535 case 0x111: /* TMRC */
1536 if (insn & 0xf)
1537 return 1;
1538 rd = (insn >> 12) & 0xf;
1539 wrd = (insn >> 16) & 0xf;
1540 tmp = iwmmxt_load_creg(wrd);
1541 store_reg(s, rd, tmp);
1542 break;
1543 case 0x300: /* WANDN */
1544 wrd = (insn >> 12) & 0xf;
1545 rd0 = (insn >> 0) & 0xf;
1546 rd1 = (insn >> 16) & 0xf;
1547 gen_op_iwmmxt_movq_M0_wRn(rd0);
1548 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1549 gen_op_iwmmxt_andq_M0_wRn(rd1);
1550 gen_op_iwmmxt_setpsr_nz();
1551 gen_op_iwmmxt_movq_wRn_M0(wrd);
1552 gen_op_iwmmxt_set_mup();
1553 gen_op_iwmmxt_set_cup();
1554 break;
1555 case 0x200: /* WAND */
1556 wrd = (insn >> 12) & 0xf;
1557 rd0 = (insn >> 0) & 0xf;
1558 rd1 = (insn >> 16) & 0xf;
1559 gen_op_iwmmxt_movq_M0_wRn(rd0);
1560 gen_op_iwmmxt_andq_M0_wRn(rd1);
1561 gen_op_iwmmxt_setpsr_nz();
1562 gen_op_iwmmxt_movq_wRn_M0(wrd);
1563 gen_op_iwmmxt_set_mup();
1564 gen_op_iwmmxt_set_cup();
1565 break;
1566 case 0x810: case 0xa10: /* WMADD */
1567 wrd = (insn >> 12) & 0xf;
1568 rd0 = (insn >> 0) & 0xf;
1569 rd1 = (insn >> 16) & 0xf;
1570 gen_op_iwmmxt_movq_M0_wRn(rd0);
1571 if (insn & (1 << 21))
1572 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1573 else
1574 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1575 gen_op_iwmmxt_movq_wRn_M0(wrd);
1576 gen_op_iwmmxt_set_mup();
1577 break;
1578 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1579 wrd = (insn >> 12) & 0xf;
1580 rd0 = (insn >> 16) & 0xf;
1581 rd1 = (insn >> 0) & 0xf;
1582 gen_op_iwmmxt_movq_M0_wRn(rd0);
1583 switch ((insn >> 22) & 3) {
1584 case 0:
1585 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1586 break;
1587 case 1:
1588 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1589 break;
1590 case 2:
1591 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1592 break;
1593 case 3:
1594 return 1;
1595 }
1596 gen_op_iwmmxt_movq_wRn_M0(wrd);
1597 gen_op_iwmmxt_set_mup();
1598 gen_op_iwmmxt_set_cup();
1599 break;
1600 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1601 wrd = (insn >> 12) & 0xf;
1602 rd0 = (insn >> 16) & 0xf;
1603 rd1 = (insn >> 0) & 0xf;
1604 gen_op_iwmmxt_movq_M0_wRn(rd0);
1605 switch ((insn >> 22) & 3) {
1606 case 0:
1607 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1608 break;
1609 case 1:
1610 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1611 break;
1612 case 2:
1613 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1614 break;
1615 case 3:
1616 return 1;
1617 }
1618 gen_op_iwmmxt_movq_wRn_M0(wrd);
1619 gen_op_iwmmxt_set_mup();
1620 gen_op_iwmmxt_set_cup();
1621 break;
1622 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1623 wrd = (insn >> 12) & 0xf;
1624 rd0 = (insn >> 16) & 0xf;
1625 rd1 = (insn >> 0) & 0xf;
1626 gen_op_iwmmxt_movq_M0_wRn(rd0);
1627 if (insn & (1 << 22))
1628 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1629 else
1630 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1631 if (!(insn & (1 << 20)))
1632 gen_op_iwmmxt_addl_M0_wRn(wrd);
1633 gen_op_iwmmxt_movq_wRn_M0(wrd);
1634 gen_op_iwmmxt_set_mup();
1635 break;
1636 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1637 wrd = (insn >> 12) & 0xf;
1638 rd0 = (insn >> 16) & 0xf;
1639 rd1 = (insn >> 0) & 0xf;
1640 gen_op_iwmmxt_movq_M0_wRn(rd0);
1641 if (insn & (1 << 21)) {
1642 if (insn & (1 << 20))
1643 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1644 else
1645 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1646 } else {
1647 if (insn & (1 << 20))
1648 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1649 else
1650 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1651 }
1652 gen_op_iwmmxt_movq_wRn_M0(wrd);
1653 gen_op_iwmmxt_set_mup();
1654 break;
1655 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1656 wrd = (insn >> 12) & 0xf;
1657 rd0 = (insn >> 16) & 0xf;
1658 rd1 = (insn >> 0) & 0xf;
1659 gen_op_iwmmxt_movq_M0_wRn(rd0);
1660 if (insn & (1 << 21))
1661 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1662 else
1663 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1664 if (!(insn & (1 << 20))) {
1665 iwmmxt_load_reg(cpu_V1, wrd);
1666 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1667 }
1668 gen_op_iwmmxt_movq_wRn_M0(wrd);
1669 gen_op_iwmmxt_set_mup();
1670 break;
1671 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1672 wrd = (insn >> 12) & 0xf;
1673 rd0 = (insn >> 16) & 0xf;
1674 rd1 = (insn >> 0) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0);
1676 switch ((insn >> 22) & 3) {
1677 case 0:
1678 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1679 break;
1680 case 1:
1681 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1682 break;
1683 case 2:
1684 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1685 break;
1686 case 3:
1687 return 1;
1688 }
1689 gen_op_iwmmxt_movq_wRn_M0(wrd);
1690 gen_op_iwmmxt_set_mup();
1691 gen_op_iwmmxt_set_cup();
1692 break;
1693 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1694 wrd = (insn >> 12) & 0xf;
1695 rd0 = (insn >> 16) & 0xf;
1696 rd1 = (insn >> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0);
1698 if (insn & (1 << 22)) {
1699 if (insn & (1 << 20))
1700 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1701 else
1702 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1703 } else {
1704 if (insn & (1 << 20))
1705 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1706 else
1707 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1708 }
1709 gen_op_iwmmxt_movq_wRn_M0(wrd);
1710 gen_op_iwmmxt_set_mup();
1711 gen_op_iwmmxt_set_cup();
1712 break;
1713 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1714 wrd = (insn >> 12) & 0xf;
1715 rd0 = (insn >> 16) & 0xf;
1716 rd1 = (insn >> 0) & 0xf;
1717 gen_op_iwmmxt_movq_M0_wRn(rd0);
1718 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1719 tcg_gen_andi_i32(tmp, tmp, 7);
1720 iwmmxt_load_reg(cpu_V1, rd1);
1721 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1722 tcg_temp_free_i32(tmp);
1723 gen_op_iwmmxt_movq_wRn_M0(wrd);
1724 gen_op_iwmmxt_set_mup();
1725 break;
1726 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1727 if (((insn >> 6) & 3) == 3)
1728 return 1;
1729 rd = (insn >> 12) & 0xf;
1730 wrd = (insn >> 16) & 0xf;
1731 tmp = load_reg(s, rd);
1732 gen_op_iwmmxt_movq_M0_wRn(wrd);
1733 switch ((insn >> 6) & 3) {
1734 case 0:
1735 tmp2 = tcg_const_i32(0xff);
1736 tmp3 = tcg_const_i32((insn & 7) << 3);
1737 break;
1738 case 1:
1739 tmp2 = tcg_const_i32(0xffff);
1740 tmp3 = tcg_const_i32((insn & 3) << 4);
1741 break;
1742 case 2:
1743 tmp2 = tcg_const_i32(0xffffffff);
1744 tmp3 = tcg_const_i32((insn & 1) << 5);
1745 break;
1746 default:
1747 tmp2 = NULL;
1748 tmp3 = NULL;
1749 }
1750 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1751 tcg_temp_free_i32(tmp3);
1752 tcg_temp_free_i32(tmp2);
1753 tcg_temp_free_i32(tmp);
1754 gen_op_iwmmxt_movq_wRn_M0(wrd);
1755 gen_op_iwmmxt_set_mup();
1756 break;
1757 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1758 rd = (insn >> 12) & 0xf;
1759 wrd = (insn >> 16) & 0xf;
1760 if (rd == 15 || ((insn >> 22) & 3) == 3)
1761 return 1;
1762 gen_op_iwmmxt_movq_M0_wRn(wrd);
1763 tmp = tcg_temp_new_i32();
1764 switch ((insn >> 22) & 3) {
1765 case 0:
1766 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1767 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1768 if (insn & 8) {
1769 tcg_gen_ext8s_i32(tmp, tmp);
1770 } else {
1771 tcg_gen_andi_i32(tmp, tmp, 0xff);
1772 }
1773 break;
1774 case 1:
1775 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1776 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1777 if (insn & 8) {
1778 tcg_gen_ext16s_i32(tmp, tmp);
1779 } else {
1780 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1781 }
1782 break;
1783 case 2:
1784 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1785 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1786 break;
1787 }
1788 store_reg(s, rd, tmp);
1789 break;
1790 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1791 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1792 return 1;
1793 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1794 switch ((insn >> 22) & 3) {
1795 case 0:
1796 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1797 break;
1798 case 1:
1799 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1800 break;
1801 case 2:
1802 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1803 break;
1804 }
1805 tcg_gen_shli_i32(tmp, tmp, 28);
1806 gen_set_nzcv(tmp);
1807 tcg_temp_free_i32(tmp);
1808 break;
1809 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1810 if (((insn >> 6) & 3) == 3)
1811 return 1;
1812 rd = (insn >> 12) & 0xf;
1813 wrd = (insn >> 16) & 0xf;
1814 tmp = load_reg(s, rd);
1815 switch ((insn >> 6) & 3) {
1816 case 0:
1817 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1818 break;
1819 case 1:
1820 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1821 break;
1822 case 2:
1823 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1824 break;
1825 }
1826 tcg_temp_free_i32(tmp);
1827 gen_op_iwmmxt_movq_wRn_M0(wrd);
1828 gen_op_iwmmxt_set_mup();
1829 break;
1830 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1831 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1832 return 1;
1833 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1834 tmp2 = tcg_temp_new_i32();
1835 tcg_gen_mov_i32(tmp2, tmp);
1836 switch ((insn >> 22) & 3) {
1837 case 0:
1838 for (i = 0; i < 7; i ++) {
1839 tcg_gen_shli_i32(tmp2, tmp2, 4);
1840 tcg_gen_and_i32(tmp, tmp, tmp2);
1841 }
1842 break;
1843 case 1:
1844 for (i = 0; i < 3; i ++) {
1845 tcg_gen_shli_i32(tmp2, tmp2, 8);
1846 tcg_gen_and_i32(tmp, tmp, tmp2);
1847 }
1848 break;
1849 case 2:
1850 tcg_gen_shli_i32(tmp2, tmp2, 16);
1851 tcg_gen_and_i32(tmp, tmp, tmp2);
1852 break;
1853 }
1854 gen_set_nzcv(tmp);
1855 tcg_temp_free_i32(tmp2);
1856 tcg_temp_free_i32(tmp);
1857 break;
1858 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1859 wrd = (insn >> 12) & 0xf;
1860 rd0 = (insn >> 16) & 0xf;
1861 gen_op_iwmmxt_movq_M0_wRn(rd0);
1862 switch ((insn >> 22) & 3) {
1863 case 0:
1864 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1865 break;
1866 case 1:
1867 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1868 break;
1869 case 2:
1870 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1871 break;
1872 case 3:
1873 return 1;
1874 }
1875 gen_op_iwmmxt_movq_wRn_M0(wrd);
1876 gen_op_iwmmxt_set_mup();
1877 break;
1878 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1879 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1880 return 1;
1881 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1882 tmp2 = tcg_temp_new_i32();
1883 tcg_gen_mov_i32(tmp2, tmp);
1884 switch ((insn >> 22) & 3) {
1885 case 0:
1886 for (i = 0; i < 7; i ++) {
1887 tcg_gen_shli_i32(tmp2, tmp2, 4);
1888 tcg_gen_or_i32(tmp, tmp, tmp2);
1889 }
1890 break;
1891 case 1:
1892 for (i = 0; i < 3; i ++) {
1893 tcg_gen_shli_i32(tmp2, tmp2, 8);
1894 tcg_gen_or_i32(tmp, tmp, tmp2);
1895 }
1896 break;
1897 case 2:
1898 tcg_gen_shli_i32(tmp2, tmp2, 16);
1899 tcg_gen_or_i32(tmp, tmp, tmp2);
1900 break;
1901 }
1902 gen_set_nzcv(tmp);
1903 tcg_temp_free_i32(tmp2);
1904 tcg_temp_free_i32(tmp);
1905 break;
1906 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1907 rd = (insn >> 12) & 0xf;
1908 rd0 = (insn >> 16) & 0xf;
1909 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1910 return 1;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0);
1912 tmp = tcg_temp_new_i32();
1913 switch ((insn >> 22) & 3) {
1914 case 0:
1915 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1916 break;
1917 case 1:
1918 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1919 break;
1920 case 2:
1921 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1922 break;
1923 }
1924 store_reg(s, rd, tmp);
1925 break;
1926 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1927 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1928 wrd = (insn >> 12) & 0xf;
1929 rd0 = (insn >> 16) & 0xf;
1930 rd1 = (insn >> 0) & 0xf;
1931 gen_op_iwmmxt_movq_M0_wRn(rd0);
1932 switch ((insn >> 22) & 3) {
1933 case 0:
1934 if (insn & (1 << 21))
1935 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1936 else
1937 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1938 break;
1939 case 1:
1940 if (insn & (1 << 21))
1941 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1942 else
1943 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1944 break;
1945 case 2:
1946 if (insn & (1 << 21))
1947 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1948 else
1949 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1950 break;
1951 case 3:
1952 return 1;
1953 }
1954 gen_op_iwmmxt_movq_wRn_M0(wrd);
1955 gen_op_iwmmxt_set_mup();
1956 gen_op_iwmmxt_set_cup();
1957 break;
1958 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1959 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1960 wrd = (insn >> 12) & 0xf;
1961 rd0 = (insn >> 16) & 0xf;
1962 gen_op_iwmmxt_movq_M0_wRn(rd0);
1963 switch ((insn >> 22) & 3) {
1964 case 0:
1965 if (insn & (1 << 21))
1966 gen_op_iwmmxt_unpacklsb_M0();
1967 else
1968 gen_op_iwmmxt_unpacklub_M0();
1969 break;
1970 case 1:
1971 if (insn & (1 << 21))
1972 gen_op_iwmmxt_unpacklsw_M0();
1973 else
1974 gen_op_iwmmxt_unpackluw_M0();
1975 break;
1976 case 2:
1977 if (insn & (1 << 21))
1978 gen_op_iwmmxt_unpacklsl_M0();
1979 else
1980 gen_op_iwmmxt_unpacklul_M0();
1981 break;
1982 case 3:
1983 return 1;
1984 }
1985 gen_op_iwmmxt_movq_wRn_M0(wrd);
1986 gen_op_iwmmxt_set_mup();
1987 gen_op_iwmmxt_set_cup();
1988 break;
1989 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1990 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1991 wrd = (insn >> 12) & 0xf;
1992 rd0 = (insn >> 16) & 0xf;
1993 gen_op_iwmmxt_movq_M0_wRn(rd0);
1994 switch ((insn >> 22) & 3) {
1995 case 0:
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_unpackhsb_M0();
1998 else
1999 gen_op_iwmmxt_unpackhub_M0();
2000 break;
2001 case 1:
2002 if (insn & (1 << 21))
2003 gen_op_iwmmxt_unpackhsw_M0();
2004 else
2005 gen_op_iwmmxt_unpackhuw_M0();
2006 break;
2007 case 2:
2008 if (insn & (1 << 21))
2009 gen_op_iwmmxt_unpackhsl_M0();
2010 else
2011 gen_op_iwmmxt_unpackhul_M0();
2012 break;
2013 case 3:
2014 return 1;
2015 }
2016 gen_op_iwmmxt_movq_wRn_M0(wrd);
2017 gen_op_iwmmxt_set_mup();
2018 gen_op_iwmmxt_set_cup();
2019 break;
2020 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2021 case 0x214: case 0x614: case 0xa14: case 0xe14:
2022 if (((insn >> 22) & 3) == 0)
2023 return 1;
2024 wrd = (insn >> 12) & 0xf;
2025 rd0 = (insn >> 16) & 0xf;
2026 gen_op_iwmmxt_movq_M0_wRn(rd0);
2027 tmp = tcg_temp_new_i32();
2028 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2029 tcg_temp_free_i32(tmp);
2030 return 1;
2031 }
2032 switch ((insn >> 22) & 3) {
2033 case 1:
2034 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2035 break;
2036 case 2:
2037 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2038 break;
2039 case 3:
2040 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2041 break;
2042 }
2043 tcg_temp_free_i32(tmp);
2044 gen_op_iwmmxt_movq_wRn_M0(wrd);
2045 gen_op_iwmmxt_set_mup();
2046 gen_op_iwmmxt_set_cup();
2047 break;
2048 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2049 case 0x014: case 0x414: case 0x814: case 0xc14:
2050 if (((insn >> 22) & 3) == 0)
2051 return 1;
2052 wrd = (insn >> 12) & 0xf;
2053 rd0 = (insn >> 16) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0);
2055 tmp = tcg_temp_new_i32();
2056 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2057 tcg_temp_free_i32(tmp);
2058 return 1;
2059 }
2060 switch ((insn >> 22) & 3) {
2061 case 1:
2062 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2063 break;
2064 case 2:
2065 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2066 break;
2067 case 3:
2068 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2069 break;
2070 }
2071 tcg_temp_free_i32(tmp);
2072 gen_op_iwmmxt_movq_wRn_M0(wrd);
2073 gen_op_iwmmxt_set_mup();
2074 gen_op_iwmmxt_set_cup();
2075 break;
2076 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2077 case 0x114: case 0x514: case 0x914: case 0xd14:
2078 if (((insn >> 22) & 3) == 0)
2079 return 1;
2080 wrd = (insn >> 12) & 0xf;
2081 rd0 = (insn >> 16) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 tmp = tcg_temp_new_i32();
2084 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2085 tcg_temp_free_i32(tmp);
2086 return 1;
2087 }
2088 switch ((insn >> 22) & 3) {
2089 case 1:
2090 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2091 break;
2092 case 2:
2093 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2094 break;
2095 case 3:
2096 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2097 break;
2098 }
2099 tcg_temp_free_i32(tmp);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd);
2101 gen_op_iwmmxt_set_mup();
2102 gen_op_iwmmxt_set_cup();
2103 break;
2104 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2105 case 0x314: case 0x714: case 0xb14: case 0xf14:
2106 if (((insn >> 22) & 3) == 0)
2107 return 1;
2108 wrd = (insn >> 12) & 0xf;
2109 rd0 = (insn >> 16) & 0xf;
2110 gen_op_iwmmxt_movq_M0_wRn(rd0);
2111 tmp = tcg_temp_new_i32();
2112 switch ((insn >> 22) & 3) {
2113 case 1:
2114 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2115 tcg_temp_free_i32(tmp);
2116 return 1;
2117 }
2118 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2119 break;
2120 case 2:
2121 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2122 tcg_temp_free_i32(tmp);
2123 return 1;
2124 }
2125 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2126 break;
2127 case 3:
2128 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2129 tcg_temp_free_i32(tmp);
2130 return 1;
2131 }
2132 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2133 break;
2134 }
2135 tcg_temp_free_i32(tmp);
2136 gen_op_iwmmxt_movq_wRn_M0(wrd);
2137 gen_op_iwmmxt_set_mup();
2138 gen_op_iwmmxt_set_cup();
2139 break;
2140 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2141 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2142 wrd = (insn >> 12) & 0xf;
2143 rd0 = (insn >> 16) & 0xf;
2144 rd1 = (insn >> 0) & 0xf;
2145 gen_op_iwmmxt_movq_M0_wRn(rd0);
2146 switch ((insn >> 22) & 3) {
2147 case 0:
2148 if (insn & (1 << 21))
2149 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2150 else
2151 gen_op_iwmmxt_minub_M0_wRn(rd1);
2152 break;
2153 case 1:
2154 if (insn & (1 << 21))
2155 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2156 else
2157 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2158 break;
2159 case 2:
2160 if (insn & (1 << 21))
2161 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2162 else
2163 gen_op_iwmmxt_minul_M0_wRn(rd1);
2164 break;
2165 case 3:
2166 return 1;
2167 }
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2170 break;
2171 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2172 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2173 wrd = (insn >> 12) & 0xf;
2174 rd0 = (insn >> 16) & 0xf;
2175 rd1 = (insn >> 0) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0);
2177 switch ((insn >> 22) & 3) {
2178 case 0:
2179 if (insn & (1 << 21))
2180 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2181 else
2182 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2183 break;
2184 case 1:
2185 if (insn & (1 << 21))
2186 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2187 else
2188 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2189 break;
2190 case 2:
2191 if (insn & (1 << 21))
2192 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2193 else
2194 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2195 break;
2196 case 3:
2197 return 1;
2198 }
2199 gen_op_iwmmxt_movq_wRn_M0(wrd);
2200 gen_op_iwmmxt_set_mup();
2201 break;
2202 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2203 case 0x402: case 0x502: case 0x602: case 0x702:
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 rd1 = (insn >> 0) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0);
2208 tmp = tcg_const_i32((insn >> 20) & 3);
2209 iwmmxt_load_reg(cpu_V1, rd1);
2210 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2211 tcg_temp_free_i32(tmp);
2212 gen_op_iwmmxt_movq_wRn_M0(wrd);
2213 gen_op_iwmmxt_set_mup();
2214 break;
2215 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2216 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2217 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2218 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2219 wrd = (insn >> 12) & 0xf;
2220 rd0 = (insn >> 16) & 0xf;
2221 rd1 = (insn >> 0) & 0xf;
2222 gen_op_iwmmxt_movq_M0_wRn(rd0);
2223 switch ((insn >> 20) & 0xf) {
2224 case 0x0:
2225 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2226 break;
2227 case 0x1:
2228 gen_op_iwmmxt_subub_M0_wRn(rd1);
2229 break;
2230 case 0x3:
2231 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2232 break;
2233 case 0x4:
2234 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2235 break;
2236 case 0x5:
2237 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2238 break;
2239 case 0x7:
2240 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2241 break;
2242 case 0x8:
2243 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2244 break;
2245 case 0x9:
2246 gen_op_iwmmxt_subul_M0_wRn(rd1);
2247 break;
2248 case 0xb:
2249 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2250 break;
2251 default:
2252 return 1;
2253 }
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2257 break;
2258 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2259 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2260 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2261 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2262 wrd = (insn >> 12) & 0xf;
2263 rd0 = (insn >> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0);
2265 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2266 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2267 tcg_temp_free_i32(tmp);
2268 gen_op_iwmmxt_movq_wRn_M0(wrd);
2269 gen_op_iwmmxt_set_mup();
2270 gen_op_iwmmxt_set_cup();
2271 break;
2272 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2273 case 0x418: case 0x518: case 0x618: case 0x718:
2274 case 0x818: case 0x918: case 0xa18: case 0xb18:
2275 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2276 wrd = (insn >> 12) & 0xf;
2277 rd0 = (insn >> 16) & 0xf;
2278 rd1 = (insn >> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0);
2280 switch ((insn >> 20) & 0xf) {
2281 case 0x0:
2282 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2283 break;
2284 case 0x1:
2285 gen_op_iwmmxt_addub_M0_wRn(rd1);
2286 break;
2287 case 0x3:
2288 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2289 break;
2290 case 0x4:
2291 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2292 break;
2293 case 0x5:
2294 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2295 break;
2296 case 0x7:
2297 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2298 break;
2299 case 0x8:
2300 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2301 break;
2302 case 0x9:
2303 gen_op_iwmmxt_addul_M0_wRn(rd1);
2304 break;
2305 case 0xb:
2306 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2307 break;
2308 default:
2309 return 1;
2310 }
2311 gen_op_iwmmxt_movq_wRn_M0(wrd);
2312 gen_op_iwmmxt_set_mup();
2313 gen_op_iwmmxt_set_cup();
2314 break;
2315 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2316 case 0x408: case 0x508: case 0x608: case 0x708:
2317 case 0x808: case 0x908: case 0xa08: case 0xb08:
2318 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2319 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2320 return 1;
2321 wrd = (insn >> 12) & 0xf;
2322 rd0 = (insn >> 16) & 0xf;
2323 rd1 = (insn >> 0) & 0xf;
2324 gen_op_iwmmxt_movq_M0_wRn(rd0);
2325 switch ((insn >> 22) & 3) {
2326 case 1:
2327 if (insn & (1 << 21))
2328 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2329 else
2330 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2331 break;
2332 case 2:
2333 if (insn & (1 << 21))
2334 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2335 else
2336 gen_op_iwmmxt_packul_M0_wRn(rd1);
2337 break;
2338 case 3:
2339 if (insn & (1 << 21))
2340 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2341 else
2342 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2343 break;
2344 }
2345 gen_op_iwmmxt_movq_wRn_M0(wrd);
2346 gen_op_iwmmxt_set_mup();
2347 gen_op_iwmmxt_set_cup();
2348 break;
2349 case 0x201: case 0x203: case 0x205: case 0x207:
2350 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2351 case 0x211: case 0x213: case 0x215: case 0x217:
2352 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2353 wrd = (insn >> 5) & 0xf;
2354 rd0 = (insn >> 12) & 0xf;
2355 rd1 = (insn >> 0) & 0xf;
2356 if (rd0 == 0xf || rd1 == 0xf)
2357 return 1;
2358 gen_op_iwmmxt_movq_M0_wRn(wrd);
2359 tmp = load_reg(s, rd0);
2360 tmp2 = load_reg(s, rd1);
2361 switch ((insn >> 16) & 0xf) {
2362 case 0x0: /* TMIA */
2363 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2364 break;
2365 case 0x8: /* TMIAPH */
2366 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2367 break;
2368 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2369 if (insn & (1 << 16))
2370 tcg_gen_shri_i32(tmp, tmp, 16);
2371 if (insn & (1 << 17))
2372 tcg_gen_shri_i32(tmp2, tmp2, 16);
2373 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2374 break;
2375 default:
2376 tcg_temp_free_i32(tmp2);
2377 tcg_temp_free_i32(tmp);
2378 return 1;
2379 }
2380 tcg_temp_free_i32(tmp2);
2381 tcg_temp_free_i32(tmp);
2382 gen_op_iwmmxt_movq_wRn_M0(wrd);
2383 gen_op_iwmmxt_set_mup();
2384 break;
2385 default:
2386 return 1;
2387 }
2388
2389 return 0;
2390 }
2391
2392 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2393 (ie. an undefined instruction). */
2394 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2395 {
2396 int acc, rd0, rd1, rdhi, rdlo;
2397 TCGv_i32 tmp, tmp2;
2398
2399 if ((insn & 0x0ff00f10) == 0x0e200010) {
2400 /* Multiply with Internal Accumulate Format */
2401 rd0 = (insn >> 12) & 0xf;
2402 rd1 = insn & 0xf;
2403 acc = (insn >> 5) & 7;
2404
2405 if (acc != 0)
2406 return 1;
2407
2408 tmp = load_reg(s, rd0);
2409 tmp2 = load_reg(s, rd1);
2410 switch ((insn >> 16) & 0xf) {
2411 case 0x0: /* MIA */
2412 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2413 break;
2414 case 0x8: /* MIAPH */
2415 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2416 break;
2417 case 0xc: /* MIABB */
2418 case 0xd: /* MIABT */
2419 case 0xe: /* MIATB */
2420 case 0xf: /* MIATT */
2421 if (insn & (1 << 16))
2422 tcg_gen_shri_i32(tmp, tmp, 16);
2423 if (insn & (1 << 17))
2424 tcg_gen_shri_i32(tmp2, tmp2, 16);
2425 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2426 break;
2427 default:
2428 return 1;
2429 }
2430 tcg_temp_free_i32(tmp2);
2431 tcg_temp_free_i32(tmp);
2432
2433 gen_op_iwmmxt_movq_wRn_M0(acc);
2434 return 0;
2435 }
2436
2437 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2438 /* Internal Accumulator Access Format */
2439 rdhi = (insn >> 16) & 0xf;
2440 rdlo = (insn >> 12) & 0xf;
2441 acc = insn & 7;
2442
2443 if (acc != 0)
2444 return 1;
2445
2446 if (insn & ARM_CP_RW_BIT) { /* MRA */
2447 iwmmxt_load_reg(cpu_V0, acc);
2448 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2449 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2450 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2451 } else { /* MAR */
2452 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2453 iwmmxt_store_reg(cpu_V0, acc);
2454 }
2455 return 0;
2456 }
2457
2458 return 1;
2459 }
2460
2461 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2462 {
2463 #ifndef CONFIG_USER_ONLY
2464 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2465 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2466 #else
2467 return true;
2468 #endif
2469 }
2470
2471 static void gen_goto_ptr(void)
2472 {
2473 tcg_gen_lookup_and_goto_ptr();
2474 }
2475
2476 /* This will end the TB but doesn't guarantee we'll return to
2477 * cpu_loop_exec. Any live exit_requests will be processed as we
2478 * enter the next TB.
2479 */
2480 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2481 {
2482 if (use_goto_tb(s, dest)) {
2483 tcg_gen_goto_tb(n);
2484 gen_set_pc_im(s, dest);
2485 tcg_gen_exit_tb(s->base.tb, n);
2486 } else {
2487 gen_set_pc_im(s, dest);
2488 gen_goto_ptr();
2489 }
2490 s->base.is_jmp = DISAS_NORETURN;
2491 }
2492
2493 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2494 {
2495 if (unlikely(is_singlestepping(s))) {
2496 /* An indirect jump so that we still trigger the debug exception. */
2497 gen_set_pc_im(s, dest);
2498 s->base.is_jmp = DISAS_JUMP;
2499 } else {
2500 gen_goto_tb(s, 0, dest);
2501 }
2502 }
2503
2504 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2505 {
2506 if (x)
2507 tcg_gen_sari_i32(t0, t0, 16);
2508 else
2509 gen_sxth(t0);
2510 if (y)
2511 tcg_gen_sari_i32(t1, t1, 16);
2512 else
2513 gen_sxth(t1);
2514 tcg_gen_mul_i32(t0, t0, t1);
2515 }
2516
2517 /* Return the mask of PSR bits set by a MSR instruction. */
2518 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2519 {
2520 uint32_t mask = 0;
2521
2522 if (flags & (1 << 0)) {
2523 mask |= 0xff;
2524 }
2525 if (flags & (1 << 1)) {
2526 mask |= 0xff00;
2527 }
2528 if (flags & (1 << 2)) {
2529 mask |= 0xff0000;
2530 }
2531 if (flags & (1 << 3)) {
2532 mask |= 0xff000000;
2533 }
2534
2535 /* Mask out undefined and reserved bits. */
2536 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2537
2538 /* Mask out execution state. */
2539 if (!spsr) {
2540 mask &= ~CPSR_EXEC;
2541 }
2542
2543 /* Mask out privileged bits. */
2544 if (IS_USER(s)) {
2545 mask &= CPSR_USER;
2546 }
2547 return mask;
2548 }
2549
2550 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2551 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2552 {
2553 TCGv_i32 tmp;
2554 if (spsr) {
2555 /* ??? This is also undefined in system mode. */
2556 if (IS_USER(s))
2557 return 1;
2558
2559 tmp = load_cpu_field(spsr);
2560 tcg_gen_andi_i32(tmp, tmp, ~mask);
2561 tcg_gen_andi_i32(t0, t0, mask);
2562 tcg_gen_or_i32(tmp, tmp, t0);
2563 store_cpu_field(tmp, spsr);
2564 } else {
2565 gen_set_cpsr(t0, mask);
2566 }
2567 tcg_temp_free_i32(t0);
2568 gen_lookup_tb(s);
2569 return 0;
2570 }
2571
2572 /* Returns nonzero if access to the PSR is not permitted. */
2573 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2574 {
2575 TCGv_i32 tmp;
2576 tmp = tcg_temp_new_i32();
2577 tcg_gen_movi_i32(tmp, val);
2578 return gen_set_psr(s, mask, spsr, tmp);
2579 }
2580
2581 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2582 int *tgtmode, int *regno)
2583 {
2584 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2585 * the target mode and register number, and identify the various
2586 * unpredictable cases.
2587 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2588 * + executed in user mode
2589 * + using R15 as the src/dest register
2590 * + accessing an unimplemented register
2591 * + accessing a register that's inaccessible at current PL/security state*
2592 * + accessing a register that you could access with a different insn
2593 * We choose to UNDEF in all these cases.
2594 * Since we don't know which of the various AArch32 modes we are in
2595 * we have to defer some checks to runtime.
2596 * Accesses to Monitor mode registers from Secure EL1 (which implies
2597 * that EL3 is AArch64) must trap to EL3.
2598 *
2599 * If the access checks fail this function will emit code to take
2600 * an exception and return false. Otherwise it will return true,
2601 * and set *tgtmode and *regno appropriately.
2602 */
2603 int exc_target = default_exception_el(s);
2604
2605 /* These instructions are present only in ARMv8, or in ARMv7 with the
2606 * Virtualization Extensions.
2607 */
2608 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2609 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2610 goto undef;
2611 }
2612
2613 if (IS_USER(s) || rn == 15) {
2614 goto undef;
2615 }
2616
2617 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2618 * of registers into (r, sysm).
2619 */
2620 if (r) {
2621 /* SPSRs for other modes */
2622 switch (sysm) {
2623 case 0xe: /* SPSR_fiq */
2624 *tgtmode = ARM_CPU_MODE_FIQ;
2625 break;
2626 case 0x10: /* SPSR_irq */
2627 *tgtmode = ARM_CPU_MODE_IRQ;
2628 break;
2629 case 0x12: /* SPSR_svc */
2630 *tgtmode = ARM_CPU_MODE_SVC;
2631 break;
2632 case 0x14: /* SPSR_abt */
2633 *tgtmode = ARM_CPU_MODE_ABT;
2634 break;
2635 case 0x16: /* SPSR_und */
2636 *tgtmode = ARM_CPU_MODE_UND;
2637 break;
2638 case 0x1c: /* SPSR_mon */
2639 *tgtmode = ARM_CPU_MODE_MON;
2640 break;
2641 case 0x1e: /* SPSR_hyp */
2642 *tgtmode = ARM_CPU_MODE_HYP;
2643 break;
2644 default: /* unallocated */
2645 goto undef;
2646 }
2647 /* We arbitrarily assign SPSR a register number of 16. */
2648 *regno = 16;
2649 } else {
2650 /* general purpose registers for other modes */
2651 switch (sysm) {
2652 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2653 *tgtmode = ARM_CPU_MODE_USR;
2654 *regno = sysm + 8;
2655 break;
2656 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2657 *tgtmode = ARM_CPU_MODE_FIQ;
2658 *regno = sysm;
2659 break;
2660 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2661 *tgtmode = ARM_CPU_MODE_IRQ;
2662 *regno = sysm & 1 ? 13 : 14;
2663 break;
2664 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2665 *tgtmode = ARM_CPU_MODE_SVC;
2666 *regno = sysm & 1 ? 13 : 14;
2667 break;
2668 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2669 *tgtmode = ARM_CPU_MODE_ABT;
2670 *regno = sysm & 1 ? 13 : 14;
2671 break;
2672 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2673 *tgtmode = ARM_CPU_MODE_UND;
2674 *regno = sysm & 1 ? 13 : 14;
2675 break;
2676 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2677 *tgtmode = ARM_CPU_MODE_MON;
2678 *regno = sysm & 1 ? 13 : 14;
2679 break;
2680 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2681 *tgtmode = ARM_CPU_MODE_HYP;
2682 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2683 *regno = sysm & 1 ? 13 : 17;
2684 break;
2685 default: /* unallocated */
2686 goto undef;
2687 }
2688 }
2689
2690 /* Catch the 'accessing inaccessible register' cases we can detect
2691 * at translate time.
2692 */
2693 switch (*tgtmode) {
2694 case ARM_CPU_MODE_MON:
2695 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2696 goto undef;
2697 }
2698 if (s->current_el == 1) {
2699 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2700 * then accesses to Mon registers trap to EL3
2701 */
2702 exc_target = 3;
2703 goto undef;
2704 }
2705 break;
2706 case ARM_CPU_MODE_HYP:
2707 /*
2708 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2709 * (and so we can forbid accesses from EL2 or below). elr_hyp
2710 * can be accessed also from Hyp mode, so forbid accesses from
2711 * EL0 or EL1.
2712 */
2713 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2714 (s->current_el < 3 && *regno != 17)) {
2715 goto undef;
2716 }
2717 break;
2718 default:
2719 break;
2720 }
2721
2722 return true;
2723
2724 undef:
2725 /* If we get here then some access check did not pass */
2726 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2727 syn_uncategorized(), exc_target);
2728 return false;
2729 }
2730
2731 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2732 {
2733 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2734 int tgtmode = 0, regno = 0;
2735
2736 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2737 return;
2738 }
2739
2740 /* Sync state because msr_banked() can raise exceptions */
2741 gen_set_condexec(s);
2742 gen_set_pc_im(s, s->pc_curr);
2743 tcg_reg = load_reg(s, rn);
2744 tcg_tgtmode = tcg_const_i32(tgtmode);
2745 tcg_regno = tcg_const_i32(regno);
2746 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2747 tcg_temp_free_i32(tcg_tgtmode);
2748 tcg_temp_free_i32(tcg_regno);
2749 tcg_temp_free_i32(tcg_reg);
2750 s->base.is_jmp = DISAS_UPDATE_EXIT;
2751 }
2752
2753 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2754 {
2755 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2756 int tgtmode = 0, regno = 0;
2757
2758 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2759 return;
2760 }
2761
2762 /* Sync state because mrs_banked() can raise exceptions */
2763 gen_set_condexec(s);
2764 gen_set_pc_im(s, s->pc_curr);
2765 tcg_reg = tcg_temp_new_i32();
2766 tcg_tgtmode = tcg_const_i32(tgtmode);
2767 tcg_regno = tcg_const_i32(regno);
2768 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2769 tcg_temp_free_i32(tcg_tgtmode);
2770 tcg_temp_free_i32(tcg_regno);
2771 store_reg(s, rn, tcg_reg);
2772 s->base.is_jmp = DISAS_UPDATE_EXIT;
2773 }
2774
2775 /* Store value to PC as for an exception return (ie don't
2776 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2777 * will do the masking based on the new value of the Thumb bit.
2778 */
2779 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2780 {
2781 tcg_gen_mov_i32(cpu_R[15], pc);
2782 tcg_temp_free_i32(pc);
2783 }
2784
2785 /* Generate a v6 exception return. Marks both values as dead. */
2786 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2787 {
2788 store_pc_exc_ret(s, pc);
2789 /* The cpsr_write_eret helper will mask the low bits of PC
2790 * appropriately depending on the new Thumb bit, so it must
2791 * be called after storing the new PC.
2792 */
2793 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2794 gen_io_start();
2795 }
2796 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2797 tcg_temp_free_i32(cpsr);
2798 /* Must exit loop to check un-masked IRQs */
2799 s->base.is_jmp = DISAS_EXIT;
2800 }
2801
2802 /* Generate an old-style exception return. Marks pc as dead. */
2803 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2804 {
2805 gen_rfe(s, pc, load_cpu_field(spsr));
2806 }
2807
2808 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
2809 uint32_t opr_sz, uint32_t max_sz,
2810 gen_helper_gvec_3_ptr *fn)
2811 {
2812 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
2813
2814 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
2815 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
2816 opr_sz, max_sz, 0, fn);
2817 tcg_temp_free_ptr(qc_ptr);
2818 }
2819
2820 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2821 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2822 {
2823 static gen_helper_gvec_3_ptr * const fns[2] = {
2824 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
2825 };
2826 tcg_debug_assert(vece >= 1 && vece <= 2);
2827 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2828 }
2829
2830 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2831 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2832 {
2833 static gen_helper_gvec_3_ptr * const fns[2] = {
2834 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
2835 };
2836 tcg_debug_assert(vece >= 1 && vece <= 2);
2837 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2838 }
2839
2840 #define GEN_CMP0(NAME, COND) \
2841 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
2842 { \
2843 tcg_gen_setcondi_i32(COND, d, a, 0); \
2844 tcg_gen_neg_i32(d, d); \
2845 } \
2846 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
2847 { \
2848 tcg_gen_setcondi_i64(COND, d, a, 0); \
2849 tcg_gen_neg_i64(d, d); \
2850 } \
2851 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
2852 { \
2853 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
2854 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
2855 tcg_temp_free_vec(zero); \
2856 } \
2857 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
2858 uint32_t opr_sz, uint32_t max_sz) \
2859 { \
2860 const GVecGen2 op[4] = { \
2861 { .fno = gen_helper_gvec_##NAME##0_b, \
2862 .fniv = gen_##NAME##0_vec, \
2863 .opt_opc = vecop_list_cmp, \
2864 .vece = MO_8 }, \
2865 { .fno = gen_helper_gvec_##NAME##0_h, \
2866 .fniv = gen_##NAME##0_vec, \
2867 .opt_opc = vecop_list_cmp, \
2868 .vece = MO_16 }, \
2869 { .fni4 = gen_##NAME##0_i32, \
2870 .fniv = gen_##NAME##0_vec, \
2871 .opt_opc = vecop_list_cmp, \
2872 .vece = MO_32 }, \
2873 { .fni8 = gen_##NAME##0_i64, \
2874 .fniv = gen_##NAME##0_vec, \
2875 .opt_opc = vecop_list_cmp, \
2876 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
2877 .vece = MO_64 }, \
2878 }; \
2879 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
2880 }
2881
2882 static const TCGOpcode vecop_list_cmp[] = {
2883 INDEX_op_cmp_vec, 0
2884 };
2885
2886 GEN_CMP0(ceq, TCG_COND_EQ)
2887 GEN_CMP0(cle, TCG_COND_LE)
2888 GEN_CMP0(cge, TCG_COND_GE)
2889 GEN_CMP0(clt, TCG_COND_LT)
2890 GEN_CMP0(cgt, TCG_COND_GT)
2891
2892 #undef GEN_CMP0
2893
2894 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2895 {
2896 tcg_gen_vec_sar8i_i64(a, a, shift);
2897 tcg_gen_vec_add8_i64(d, d, a);
2898 }
2899
2900 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2901 {
2902 tcg_gen_vec_sar16i_i64(a, a, shift);
2903 tcg_gen_vec_add16_i64(d, d, a);
2904 }
2905
2906 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
2907 {
2908 tcg_gen_sari_i32(a, a, shift);
2909 tcg_gen_add_i32(d, d, a);
2910 }
2911
2912 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2913 {
2914 tcg_gen_sari_i64(a, a, shift);
2915 tcg_gen_add_i64(d, d, a);
2916 }
2917
2918 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
2919 {
2920 tcg_gen_sari_vec(vece, a, a, sh);
2921 tcg_gen_add_vec(vece, d, d, a);
2922 }
2923
2924 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
2925 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
2926 {
2927 static const TCGOpcode vecop_list[] = {
2928 INDEX_op_sari_vec, INDEX_op_add_vec, 0
2929 };
2930 static const GVecGen2i ops[4] = {
2931 { .fni8 = gen_ssra8_i64,
2932 .fniv = gen_ssra_vec,
2933 .fno = gen_helper_gvec_ssra_b,
2934 .load_dest = true,
2935 .opt_opc = vecop_list,
2936 .vece = MO_8 },
2937 { .fni8 = gen_ssra16_i64,
2938 .fniv = gen_ssra_vec,
2939 .fno = gen_helper_gvec_ssra_h,
2940 .load_dest = true,
2941 .opt_opc = vecop_list,
2942 .vece = MO_16 },
2943 { .fni4 = gen_ssra32_i32,
2944 .fniv = gen_ssra_vec,
2945 .fno = gen_helper_gvec_ssra_s,
2946 .load_dest = true,
2947 .opt_opc = vecop_list,
2948 .vece = MO_32 },
2949 { .fni8 = gen_ssra64_i64,
2950 .fniv = gen_ssra_vec,
2951 .fno = gen_helper_gvec_ssra_b,
2952 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
2953 .opt_opc = vecop_list,
2954 .load_dest = true,
2955 .vece = MO_64 },
2956 };
2957
2958 /* tszimm encoding produces immediates in the range [1..esize]. */
2959 tcg_debug_assert(shift > 0);
2960 tcg_debug_assert(shift <= (8 << vece));
2961
2962 /*
2963 * Shifts larger than the element size are architecturally valid.
2964 * Signed results in all sign bits.
2965 */
2966 shift = MIN(shift, (8 << vece) - 1);
2967 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
2968 }
2969
2970 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2971 {
2972 tcg_gen_vec_shr8i_i64(a, a, shift);
2973 tcg_gen_vec_add8_i64(d, d, a);
2974 }
2975
2976 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2977 {
2978 tcg_gen_vec_shr16i_i64(a, a, shift);
2979 tcg_gen_vec_add16_i64(d, d, a);
2980 }
2981
2982 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
2983 {
2984 tcg_gen_shri_i32(a, a, shift);
2985 tcg_gen_add_i32(d, d, a);
2986 }
2987
2988 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
2989 {
2990 tcg_gen_shri_i64(a, a, shift);
2991 tcg_gen_add_i64(d, d, a);
2992 }
2993
2994 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
2995 {
2996 tcg_gen_shri_vec(vece, a, a, sh);
2997 tcg_gen_add_vec(vece, d, d, a);
2998 }
2999
3000 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3001 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3002 {
3003 static const TCGOpcode vecop_list[] = {
3004 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3005 };
3006 static const GVecGen2i ops[4] = {
3007 { .fni8 = gen_usra8_i64,
3008 .fniv = gen_usra_vec,
3009 .fno = gen_helper_gvec_usra_b,
3010 .load_dest = true,
3011 .opt_opc = vecop_list,
3012 .vece = MO_8, },
3013 { .fni8 = gen_usra16_i64,
3014 .fniv = gen_usra_vec,
3015 .fno = gen_helper_gvec_usra_h,
3016 .load_dest = true,
3017 .opt_opc = vecop_list,
3018 .vece = MO_16, },
3019 { .fni4 = gen_usra32_i32,
3020 .fniv = gen_usra_vec,
3021 .fno = gen_helper_gvec_usra_s,
3022 .load_dest = true,
3023 .opt_opc = vecop_list,
3024 .vece = MO_32, },
3025 { .fni8 = gen_usra64_i64,
3026 .fniv = gen_usra_vec,
3027 .fno = gen_helper_gvec_usra_d,
3028 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3029 .load_dest = true,
3030 .opt_opc = vecop_list,
3031 .vece = MO_64, },
3032 };
3033
3034 /* tszimm encoding produces immediates in the range [1..esize]. */
3035 tcg_debug_assert(shift > 0);
3036 tcg_debug_assert(shift <= (8 << vece));
3037
3038 /*
3039 * Shifts larger than the element size are architecturally valid.
3040 * Unsigned results in all zeros as input to accumulate: nop.
3041 */
3042 if (shift < (8 << vece)) {
3043 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3044 } else {
3045 /* Nop, but we do need to clear the tail. */
3046 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3047 }
3048 }
3049
3050 /*
3051 * Shift one less than the requested amount, and the low bit is
3052 * the rounding bit. For the 8 and 16-bit operations, because we
3053 * mask the low bit, we can perform a normal integer shift instead
3054 * of a vector shift.
3055 */
3056 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3057 {
3058 TCGv_i64 t = tcg_temp_new_i64();
3059
3060 tcg_gen_shri_i64(t, a, sh - 1);
3061 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3062 tcg_gen_vec_sar8i_i64(d, a, sh);
3063 tcg_gen_vec_add8_i64(d, d, t);
3064 tcg_temp_free_i64(t);
3065 }
3066
3067 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3068 {
3069 TCGv_i64 t = tcg_temp_new_i64();
3070
3071 tcg_gen_shri_i64(t, a, sh - 1);
3072 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3073 tcg_gen_vec_sar16i_i64(d, a, sh);
3074 tcg_gen_vec_add16_i64(d, d, t);
3075 tcg_temp_free_i64(t);
3076 }
3077
3078 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3079 {
3080 TCGv_i32 t = tcg_temp_new_i32();
3081
3082 tcg_gen_extract_i32(t, a, sh - 1, 1);
3083 tcg_gen_sari_i32(d, a, sh);
3084 tcg_gen_add_i32(d, d, t);
3085 tcg_temp_free_i32(t);
3086 }
3087
3088 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3089 {
3090 TCGv_i64 t = tcg_temp_new_i64();
3091
3092 tcg_gen_extract_i64(t, a, sh - 1, 1);
3093 tcg_gen_sari_i64(d, a, sh);
3094 tcg_gen_add_i64(d, d, t);
3095 tcg_temp_free_i64(t);
3096 }
3097
3098 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3099 {
3100 TCGv_vec t = tcg_temp_new_vec_matching(d);
3101 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3102
3103 tcg_gen_shri_vec(vece, t, a, sh - 1);
3104 tcg_gen_dupi_vec(vece, ones, 1);
3105 tcg_gen_and_vec(vece, t, t, ones);
3106 tcg_gen_sari_vec(vece, d, a, sh);
3107 tcg_gen_add_vec(vece, d, d, t);
3108
3109 tcg_temp_free_vec(t);
3110 tcg_temp_free_vec(ones);
3111 }
3112
3113 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3114 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3115 {
3116 static const TCGOpcode vecop_list[] = {
3117 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3118 };
3119 static const GVecGen2i ops[4] = {
3120 { .fni8 = gen_srshr8_i64,
3121 .fniv = gen_srshr_vec,
3122 .fno = gen_helper_gvec_srshr_b,
3123 .opt_opc = vecop_list,
3124 .vece = MO_8 },
3125 { .fni8 = gen_srshr16_i64,
3126 .fniv = gen_srshr_vec,
3127 .fno = gen_helper_gvec_srshr_h,
3128 .opt_opc = vecop_list,
3129 .vece = MO_16 },
3130 { .fni4 = gen_srshr32_i32,
3131 .fniv = gen_srshr_vec,
3132 .fno = gen_helper_gvec_srshr_s,
3133 .opt_opc = vecop_list,
3134 .vece = MO_32 },
3135 { .fni8 = gen_srshr64_i64,
3136 .fniv = gen_srshr_vec,
3137 .fno = gen_helper_gvec_srshr_d,
3138 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3139 .opt_opc = vecop_list,
3140 .vece = MO_64 },
3141 };
3142
3143 /* tszimm encoding produces immediates in the range [1..esize] */
3144 tcg_debug_assert(shift > 0);
3145 tcg_debug_assert(shift <= (8 << vece));
3146
3147 if (shift == (8 << vece)) {
3148 /*
3149 * Shifts larger than the element size are architecturally valid.
3150 * Signed results in all sign bits. With rounding, this produces
3151 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3152 * I.e. always zero.
3153 */
3154 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3155 } else {
3156 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3157 }
3158 }
3159
3160 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3161 {
3162 TCGv_i64 t = tcg_temp_new_i64();
3163
3164 gen_srshr8_i64(t, a, sh);
3165 tcg_gen_vec_add8_i64(d, d, t);
3166 tcg_temp_free_i64(t);
3167 }