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