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