1 /*
2 * ARM translation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
7 * Copyright (c) 2015 Nguyen Anh Quynh (Unicorn engine)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 */
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "unicorn/platform.h"
27
28 #include "cpu.h"
29 #include "internals.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
33 #include "arm_ldst.h"
34
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
37
38 #include "exec/gen-icount.h"
39
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
50
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
52
53 #include "translate.h"
54
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
60
61 #ifdef CONFIG_USER_ONLY
62 static TCGv_i64 cpu_exclusive_test;
63 static TCGv_i32 cpu_exclusive_info;
64 #endif
65
66
67 static const char *regnames[] =
68 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
69 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
70
71 /* initialize TCG globals. */
arm_translate_init(struct uc_struct * uc)72 void arm_translate_init(struct uc_struct *uc)
73 {
74 int i;
75 TCGContext *tcg_ctx = uc->tcg_ctx;
76
77 tcg_ctx->cpu_env = tcg_global_reg_new_ptr(uc->tcg_ctx, TCG_AREG0, "env");
78
79 for (i = 0; i < 16; i++) {
80 tcg_ctx->cpu_R[i] = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0,
81 offsetof(CPUARMState, regs[i]),
82 regnames[i]);
83 }
84 tcg_ctx->cpu_CF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, CF), "CF");
85 tcg_ctx->cpu_NF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, NF), "NF");
86 tcg_ctx->cpu_VF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, VF), "VF");
87 tcg_ctx->cpu_ZF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
88
89 tcg_ctx->cpu_exclusive_addr = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
90 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
91 tcg_ctx->cpu_exclusive_val = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
92 offsetof(CPUARMState, exclusive_val), "exclusive_val");
93 #ifdef CONFIG_USER_ONLY
94 cpu_exclusive_test = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
95 offsetof(CPUARMState, exclusive_test), "exclusive_test");
96 cpu_exclusive_info = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0,
97 offsetof(CPUARMState, exclusive_info), "exclusive_info");
98 #endif
99
100 a64_translate_init(uc);
101 }
102
load_cpu_offset(struct uc_struct * uc,int offset)103 static inline TCGv_i32 load_cpu_offset(struct uc_struct *uc, int offset)
104 {
105 TCGContext *tcg_ctx = uc->tcg_ctx;
106 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
107 tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offset);
108 return tmp;
109 }
110
111 #define load_cpu_field(uc, name) load_cpu_offset(uc, offsetof(CPUARMState, name))
112
store_cpu_offset(TCGContext * tcg_ctx,TCGv_i32 var,int offset)113 static inline void store_cpu_offset(TCGContext *tcg_ctx, TCGv_i32 var, int offset)
114 {
115 tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offset);
116 tcg_temp_free_i32(tcg_ctx, var);
117 }
118
119 #define store_cpu_field(s, var, name) \
120 store_cpu_offset(s, var, offsetof(CPUARMState, name))
121
122 /* Set a variable to the value of a CPU register. */
load_reg_var(DisasContext * s,TCGv_i32 var,int reg)123 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
124 {
125 TCGContext *tcg_ctx = s->uc->tcg_ctx;
126 if (reg == 15) {
127 uint32_t addr;
128 /* normally, since we updated PC, we need only to add one insn */
129 if (s->thumb)
130 addr = (long)s->pc + 2;
131 else
132 addr = (long)s->pc + 4;
133 tcg_gen_movi_i32(tcg_ctx, var, addr);
134 } else {
135 tcg_gen_mov_i32(tcg_ctx, var, tcg_ctx->cpu_R[reg & 0x0f]);
136 }
137 }
138
139 /* Create a new temporary and set it to the value of a CPU register. */
load_reg(DisasContext * s,int reg)140 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
141 {
142 TCGContext *tcg_ctx = s->uc->tcg_ctx;
143 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
144 load_reg_var(s, tmp, reg);
145 return tmp;
146 }
147
148 /* Set a CPU register. The source must be a temporary and will be
149 marked as dead. */
store_reg(DisasContext * s,int reg,TCGv_i32 var)150 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
151 {
152 TCGContext *tcg_ctx = s->uc->tcg_ctx;
153 if (reg == 15) {
154 tcg_gen_andi_i32(tcg_ctx, var, var, ~1);
155 s->is_jmp = DISAS_JUMP;
156 }
157 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_R[reg & 0x0f], var);
158 tcg_temp_free_i32(tcg_ctx, var);
159 }
160
161 /* Value extensions. */
162 #define gen_uxtb(var) tcg_gen_ext8u_i32(tcg_ctx, var, var)
163 #define gen_uxth(var) tcg_gen_ext16u_i32(tcg_ctx, var, var)
164 #define gen_sxtb(var) tcg_gen_ext8s_i32(tcg_ctx, var, var)
165 #define gen_sxth(var) tcg_gen_ext16s_i32(tcg_ctx, var, var)
166
167 #define gen_sxtb16(var) gen_helper_sxtb16(tcg_ctx, var, var)
168 #define gen_uxtb16(var) gen_helper_uxtb16(tcg_ctx, var, var)
169
170
gen_set_cpsr(DisasContext * s,TCGv_i32 var,uint32_t mask)171 static inline void gen_set_cpsr(DisasContext *s, TCGv_i32 var, uint32_t mask)
172 {
173 TCGContext *tcg_ctx = s->uc->tcg_ctx;
174 TCGv_i32 tmp_mask = tcg_const_i32(tcg_ctx, mask);
175 gen_helper_cpsr_write(tcg_ctx, tcg_ctx->cpu_env, var, tmp_mask);
176 tcg_temp_free_i32(tcg_ctx, tmp_mask);
177 }
178 /* Set NZCV flags from the high 4 bits of var. */
179 #define gen_set_nzcv(s, var) gen_set_cpsr(s, var, CPSR_NZCV)
180
gen_exception_internal(DisasContext * s,int excp)181 static void gen_exception_internal(DisasContext *s, int excp)
182 {
183 TCGContext *tcg_ctx = s->uc->tcg_ctx;
184 TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
185
186 assert(excp_is_internal(excp));
187 gen_helper_exception_internal(tcg_ctx, tcg_ctx->cpu_env, tcg_excp);
188 tcg_temp_free_i32(tcg_ctx, tcg_excp);
189 }
190
gen_exception(DisasContext * s,int excp,uint32_t syndrome)191 static void gen_exception(DisasContext *s, int excp, uint32_t syndrome) // qq
192 {
193 TCGContext *tcg_ctx = s->uc->tcg_ctx;
194 TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
195 TCGv_i32 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
196
197 gen_helper_exception_with_syndrome(tcg_ctx, tcg_ctx->cpu_env, tcg_excp, tcg_syn);
198 tcg_temp_free_i32(tcg_ctx, tcg_syn);
199 tcg_temp_free_i32(tcg_ctx, tcg_excp);
200 }
201
gen_ss_advance(DisasContext * s)202 static void gen_ss_advance(DisasContext *s)
203 {
204 TCGContext *tcg_ctx = s->uc->tcg_ctx;
205 /* If the singlestep state is Active-not-pending, advance to
206 * Active-pending.
207 */
208 if (s->ss_active) {
209 s->pstate_ss = 0;
210 gen_helper_clear_pstate_ss(tcg_ctx, tcg_ctx->cpu_env);
211 }
212 }
213
gen_step_complete_exception(DisasContext * s)214 static void gen_step_complete_exception(DisasContext *s)
215 {
216 /* We just completed step of an insn. Move from Active-not-pending
217 * to Active-pending, and then also take the swstep exception.
218 * This corresponds to making the (IMPDEF) choice to prioritize
219 * swstep exceptions over asynchronous exceptions taken to an exception
220 * level where debug is disabled. This choice has the advantage that
221 * we do not need to maintain internal state corresponding to the
222 * ISV/EX syndrome bits between completion of the step and generation
223 * of the exception, and our syndrome information is always correct.
224 */
225 gen_ss_advance(s);
226 gen_exception(s, EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
227 s->is_jmp = DISAS_EXC;
228 }
229
gen_smul_dual(DisasContext * s,TCGv_i32 a,TCGv_i32 b)230 static void gen_smul_dual(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
231 {
232 TCGContext *tcg_ctx = s->uc->tcg_ctx;
233 TCGv_i32 tmp1 = tcg_temp_new_i32(tcg_ctx);
234 TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
235 tcg_gen_ext16s_i32(tcg_ctx, tmp1, a);
236 tcg_gen_ext16s_i32(tcg_ctx, tmp2, b);
237 tcg_gen_mul_i32(tcg_ctx, tmp1, tmp1, tmp2);
238 tcg_temp_free_i32(tcg_ctx, tmp2);
239 tcg_gen_sari_i32(tcg_ctx, a, a, 16);
240 tcg_gen_sari_i32(tcg_ctx, b, b, 16);
241 tcg_gen_mul_i32(tcg_ctx, b, b, a);
242 tcg_gen_mov_i32(tcg_ctx, a, tmp1);
243 tcg_temp_free_i32(tcg_ctx, tmp1);
244 }
245
246 /* Byteswap each halfword. */
gen_rev16(DisasContext * s,TCGv_i32 var)247 static void gen_rev16(DisasContext *s, TCGv_i32 var)
248 {
249 TCGContext *tcg_ctx = s->uc->tcg_ctx;
250 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
251 tcg_gen_shri_i32(tcg_ctx, tmp, var, 8);
252 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x00ff00ff);
253 tcg_gen_shli_i32(tcg_ctx, var, var, 8);
254 tcg_gen_andi_i32(tcg_ctx, var, var, 0xff00ff00);
255 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
256 tcg_temp_free_i32(tcg_ctx, tmp);
257 }
258
259 /* Byteswap low halfword and sign extend. */
gen_revsh(DisasContext * s,TCGv_i32 var)260 static void gen_revsh(DisasContext *s, TCGv_i32 var)
261 {
262 TCGContext *tcg_ctx = s->uc->tcg_ctx;
263 tcg_gen_ext16u_i32(tcg_ctx, var, var);
264 tcg_gen_bswap16_i32(tcg_ctx, var, var);
265 tcg_gen_ext16s_i32(tcg_ctx, var, var);
266 }
267
268 /* Unsigned bitfield extract. */
gen_ubfx(DisasContext * s,TCGv_i32 var,int shift,uint32_t mask)269 static void gen_ubfx(DisasContext *s, TCGv_i32 var, int shift, uint32_t mask)
270 {
271 TCGContext *tcg_ctx = s->uc->tcg_ctx;
272 if (shift)
273 tcg_gen_shri_i32(tcg_ctx, var, var, shift);
274 tcg_gen_andi_i32(tcg_ctx, var, var, mask);
275 }
276
277 /* Signed bitfield extract. */
gen_sbfx(DisasContext * s,TCGv_i32 var,int shift,int width)278 static void gen_sbfx(DisasContext *s, TCGv_i32 var, int shift, int width)
279 {
280 TCGContext *tcg_ctx = s->uc->tcg_ctx;
281 uint32_t signbit;
282
283 if (shift)
284 tcg_gen_sari_i32(tcg_ctx, var, var, shift);
285 if (shift + width < 32) {
286 signbit = 1u << (width - 1);
287 tcg_gen_andi_i32(tcg_ctx, var, var, (1u << width) - 1);
288 tcg_gen_xori_i32(tcg_ctx, var, var, signbit);
289 tcg_gen_subi_i32(tcg_ctx, var, var, signbit);
290 }
291 }
292
293 /* Return (b << 32) + a. Mark inputs as dead */
gen_addq_msw(DisasContext * s,TCGv_i64 a,TCGv_i32 b)294 static TCGv_i64 gen_addq_msw(DisasContext *s, TCGv_i64 a, TCGv_i32 b)
295 {
296 TCGContext *tcg_ctx = s->uc->tcg_ctx;
297 TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
298
299 tcg_gen_extu_i32_i64(tcg_ctx, tmp64, b);
300 tcg_temp_free_i32(tcg_ctx, b);
301 tcg_gen_shli_i64(tcg_ctx, tmp64, tmp64, 32);
302 tcg_gen_add_i64(tcg_ctx, a, tmp64, a);
303
304 tcg_temp_free_i64(tcg_ctx, tmp64);
305 return a;
306 }
307
308 /* Return (b << 32) - a. Mark inputs as dead. */
gen_subq_msw(DisasContext * s,TCGv_i64 a,TCGv_i32 b)309 static TCGv_i64 gen_subq_msw(DisasContext *s, TCGv_i64 a, TCGv_i32 b)
310 {
311 TCGContext *tcg_ctx = s->uc->tcg_ctx;
312 TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
313
314 tcg_gen_extu_i32_i64(tcg_ctx, tmp64, b);
315 tcg_temp_free_i32(tcg_ctx, b);
316 tcg_gen_shli_i64(tcg_ctx, tmp64, tmp64, 32);
317 tcg_gen_sub_i64(tcg_ctx, a, tmp64, a);
318
319 tcg_temp_free_i64(tcg_ctx, tmp64);
320 return a;
321 }
322
323 /* 32x32->64 multiply. Marks inputs as dead. */
gen_mulu_i64_i32(DisasContext * s,TCGv_i32 a,TCGv_i32 b)324 static TCGv_i64 gen_mulu_i64_i32(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
325 {
326 TCGContext *tcg_ctx = s->uc->tcg_ctx;
327 TCGv_i32 lo = tcg_temp_new_i32(tcg_ctx);
328 TCGv_i32 hi = tcg_temp_new_i32(tcg_ctx);
329 TCGv_i64 ret;
330
331 tcg_gen_mulu2_i32(tcg_ctx, lo, hi, a, b);
332 tcg_temp_free_i32(tcg_ctx, a);
333 tcg_temp_free_i32(tcg_ctx, b);
334
335 ret = tcg_temp_new_i64(tcg_ctx);
336 tcg_gen_concat_i32_i64(tcg_ctx, ret, lo, hi);
337 tcg_temp_free_i32(tcg_ctx, lo);
338 tcg_temp_free_i32(tcg_ctx, hi);
339
340 return ret;
341 }
342
gen_muls_i64_i32(DisasContext * s,TCGv_i32 a,TCGv_i32 b)343 static TCGv_i64 gen_muls_i64_i32(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
344 {
345 TCGContext *tcg_ctx = s->uc->tcg_ctx;
346 TCGv_i32 lo = tcg_temp_new_i32(tcg_ctx);
347 TCGv_i32 hi = tcg_temp_new_i32(tcg_ctx);
348 TCGv_i64 ret;
349
350 tcg_gen_muls2_i32(tcg_ctx, lo, hi, a, b);
351 tcg_temp_free_i32(tcg_ctx, a);
352 tcg_temp_free_i32(tcg_ctx, b);
353
354 ret = tcg_temp_new_i64(tcg_ctx);
355 tcg_gen_concat_i32_i64(tcg_ctx, ret, lo, hi);
356 tcg_temp_free_i32(tcg_ctx, lo);
357 tcg_temp_free_i32(tcg_ctx, hi);
358
359 return ret;
360 }
361
362 /* Swap low and high halfwords. */
gen_swap_half(DisasContext * s,TCGv_i32 var)363 static void gen_swap_half(DisasContext *s, TCGv_i32 var)
364 {
365 TCGContext *tcg_ctx = s->uc->tcg_ctx;
366 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
367 tcg_gen_shri_i32(tcg_ctx, tmp, var, 16);
368 tcg_gen_shli_i32(tcg_ctx, var, var, 16);
369 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
370 tcg_temp_free_i32(tcg_ctx, tmp);
371 }
372
373 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
374 tmp = (t0 ^ t1) & 0x8000;
375 t0 &= ~0x8000;
376 t1 &= ~0x8000;
377 t0 = (t0 + t1) ^ tmp;
378 */
379
gen_add16(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1)380 static void gen_add16(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1)
381 {
382 TCGContext *tcg_ctx = s->uc->tcg_ctx;
383 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
384 tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
385 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x8000);
386 tcg_gen_andi_i32(tcg_ctx, t0, t0, ~0x8000);
387 tcg_gen_andi_i32(tcg_ctx, t1, t1, ~0x8000);
388 tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
389 tcg_gen_xor_i32(tcg_ctx, t0, t0, tmp);
390 tcg_temp_free_i32(tcg_ctx, tmp);
391 tcg_temp_free_i32(tcg_ctx, t1);
392 }
393
394 /* Set CF to the top bit of var. */
gen_set_CF_bit31(DisasContext * s,TCGv_i32 var)395 static void gen_set_CF_bit31(DisasContext *s, TCGv_i32 var)
396 {
397 TCGContext *tcg_ctx = s->uc->tcg_ctx;
398 tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 31);
399 }
400
401 /* Set N and Z flags from var. */
gen_logic_CC(DisasContext * s,TCGv_i32 var)402 static inline void gen_logic_CC(DisasContext *s, TCGv_i32 var)
403 {
404 TCGContext *tcg_ctx = s->uc->tcg_ctx;
405 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_NF, var);
406 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, var);
407 }
408
409 /* T0 += T1 + CF. */
gen_adc(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1)410 static void gen_adc(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1)
411 {
412 TCGContext *tcg_ctx = s->uc->tcg_ctx;
413 tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
414 tcg_gen_add_i32(tcg_ctx, t0, t0, tcg_ctx->cpu_CF);
415 }
416
417 /* dest = T0 + T1 + CF. */
gen_add_carry(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)418 static void gen_add_carry(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
419 {
420 TCGContext *tcg_ctx = s->uc->tcg_ctx;
421 tcg_gen_add_i32(tcg_ctx, dest, t0, t1);
422 tcg_gen_add_i32(tcg_ctx, dest, dest, tcg_ctx->cpu_CF);
423 }
424
425 /* dest = T0 - T1 + CF - 1. */
gen_sub_carry(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)426 static void gen_sub_carry(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
427 {
428 TCGContext *tcg_ctx = s->uc->tcg_ctx;
429 tcg_gen_sub_i32(tcg_ctx, dest, t0, t1);
430 tcg_gen_add_i32(tcg_ctx, dest, dest, tcg_ctx->cpu_CF);
431 tcg_gen_subi_i32(tcg_ctx, dest, dest, 1);
432 }
433
434 /* dest = T0 + T1. Compute C, N, V and Z flags */
gen_add_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)435 static void gen_add_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
436 {
437 TCGContext *tcg_ctx = s->uc->tcg_ctx;
438 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
439 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
440 tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t0, tmp, t1, tmp);
441 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
442 tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
443 tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
444 tcg_gen_andc_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
445 tcg_temp_free_i32(tcg_ctx, tmp);
446 tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
447 }
448
449 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
gen_adc_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)450 static void gen_adc_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
451 {
452 TCGContext *tcg_ctx = s->uc->tcg_ctx;
453 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
454 if (TCG_TARGET_HAS_add2_i32) {
455 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
456 tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t0, tmp, tcg_ctx->cpu_CF, tmp);
457 tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t1, tmp);
458 } else {
459 TCGv_i64 q0 = tcg_temp_new_i64(tcg_ctx);
460 TCGv_i64 q1 = tcg_temp_new_i64(tcg_ctx);
461 tcg_gen_extu_i32_i64(tcg_ctx, q0, t0);
462 tcg_gen_extu_i32_i64(tcg_ctx, q1, t1);
463 tcg_gen_add_i64(tcg_ctx, q0, q0, q1);
464 tcg_gen_extu_i32_i64(tcg_ctx, q1, tcg_ctx->cpu_CF);
465 tcg_gen_add_i64(tcg_ctx, q0, q0, q1);
466 tcg_gen_extr_i64_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, q0);
467 tcg_temp_free_i64(tcg_ctx, q0);
468 tcg_temp_free_i64(tcg_ctx, q1);
469 }
470 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
471 tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
472 tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
473 tcg_gen_andc_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
474 tcg_temp_free_i32(tcg_ctx, tmp);
475 tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
476 }
477
478 /* dest = T0 - T1. Compute C, N, V and Z flags */
gen_sub_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)479 static void gen_sub_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 {
481 TCGContext *tcg_ctx = s->uc->tcg_ctx;
482 TCGv_i32 tmp;
483 tcg_gen_sub_i32(tcg_ctx, tcg_ctx->cpu_NF, t0, t1);
484 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
485 tcg_gen_setcond_i32(tcg_ctx, TCG_COND_GEU, tcg_ctx->cpu_CF, t0, t1);
486 tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
487 tmp = tcg_temp_new_i32(tcg_ctx);
488 tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
489 tcg_gen_and_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
490 tcg_temp_free_i32(tcg_ctx, tmp);
491 tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
492 }
493
494 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
gen_sbc_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)495 static void gen_sbc_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
496 {
497 TCGContext *tcg_ctx = s->uc->tcg_ctx;
498 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
499 tcg_gen_not_i32(tcg_ctx, tmp, t1);
500 gen_adc_CC(s, dest, t0, tmp);
501 tcg_temp_free_i32(tcg_ctx, tmp);
502 }
503
504 #define GEN_SHIFT(name) \
505 static void gen_##name(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
506 { \
507 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
508 TCGv_i32 tmp1, tmp2, tmp3; \
509 tmp1 = tcg_temp_new_i32(tcg_ctx); \
510 tcg_gen_andi_i32(tcg_ctx, tmp1, t1, 0xff); \
511 tmp2 = tcg_const_i32(tcg_ctx, 0); \
512 tmp3 = tcg_const_i32(tcg_ctx, 0x1f); \
513 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
514 tcg_temp_free_i32(tcg_ctx, tmp3); \
515 tcg_gen_andi_i32(tcg_ctx, tmp1, tmp1, 0x1f); \
516 tcg_gen_##name##_i32(tcg_ctx, dest, tmp2, tmp1); \
517 tcg_temp_free_i32(tcg_ctx, tmp2); \
518 tcg_temp_free_i32(tcg_ctx, tmp1); \
519 }
520 GEN_SHIFT(shl)
GEN_SHIFT(shr)521 GEN_SHIFT(shr)
522 #undef GEN_SHIFT
523
524 static void gen_sar(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
525 {
526 TCGContext *tcg_ctx = s->uc->tcg_ctx;
527 TCGv_i32 tmp1, tmp2;
528 tmp1 = tcg_temp_new_i32(tcg_ctx);
529 tcg_gen_andi_i32(tcg_ctx, tmp1, t1, 0xff);
530 tmp2 = tcg_const_i32(tcg_ctx, 0x1f);
531 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
532 tcg_temp_free_i32(tcg_ctx, tmp2);
533 tcg_gen_sar_i32(tcg_ctx, dest, t0, tmp1);
534 tcg_temp_free_i32(tcg_ctx, tmp1);
535 }
536
tcg_gen_abs_i32(DisasContext * s,TCGv_i32 dest,TCGv_i32 src)537 static void tcg_gen_abs_i32(DisasContext *s, TCGv_i32 dest, TCGv_i32 src)
538 {
539 TCGContext *tcg_ctx = s->uc->tcg_ctx;
540 TCGv_i32 c0 = tcg_const_i32(tcg_ctx, 0);
541 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
542 tcg_gen_neg_i32(tcg_ctx, tmp, src);
543 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GT, dest, src, c0, src, tmp);
544 tcg_temp_free_i32(tcg_ctx, c0);
545 tcg_temp_free_i32(tcg_ctx, tmp);
546 }
547
shifter_out_im(DisasContext * s,TCGv_i32 var,int shift)548 static void shifter_out_im(DisasContext *s, TCGv_i32 var, int shift)
549 {
550 TCGContext *tcg_ctx = s->uc->tcg_ctx;
551 if (shift == 0) {
552 tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 1);
553 } else {
554 tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, shift);
555 if (shift != 31) {
556 tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_CF, tcg_ctx->cpu_CF, 1);
557 }
558 }
559 }
560
561 /* Shift by immediate. Includes special handling for shift == 0. */
gen_arm_shift_im(DisasContext * s,TCGv_i32 var,int shiftop,int shift,int flags)562 static inline void gen_arm_shift_im(DisasContext *s, TCGv_i32 var, int shiftop,
563 int shift, int flags)
564 {
565 TCGContext *tcg_ctx = s->uc->tcg_ctx;
566 switch (shiftop) {
567 case 0: /* LSL */
568 if (shift != 0) {
569 if (flags)
570 shifter_out_im(s, var, 32 - shift);
571 tcg_gen_shli_i32(tcg_ctx, var, var, shift);
572 }
573 break;
574 case 1: /* LSR */
575 if (shift == 0) {
576 if (flags) {
577 tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 31);
578 }
579 tcg_gen_movi_i32(tcg_ctx, var, 0);
580 } else {
581 if (flags)
582 shifter_out_im(s, var, shift - 1);
583 tcg_gen_shri_i32(tcg_ctx, var, var, shift);
584 }
585 break;
586 case 2: /* ASR */
587 if (shift == 0)
588 shift = 32;
589 if (flags)
590 shifter_out_im(s, var, shift - 1);
591 if (shift == 32)
592 shift = 31;
593 tcg_gen_sari_i32(tcg_ctx, var, var, shift);
594 break;
595 case 3: /* ROR/RRX */
596 if (shift != 0) {
597 if (flags)
598 shifter_out_im(s, var, shift - 1);
599 tcg_gen_rotri_i32(tcg_ctx, var, var, shift); break;
600 } else {
601 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
602 tcg_gen_shli_i32(tcg_ctx, tmp, tcg_ctx->cpu_CF, 31);
603 if (flags)
604 shifter_out_im(s, var, 0);
605 tcg_gen_shri_i32(tcg_ctx, var, var, 1);
606 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
607 tcg_temp_free_i32(tcg_ctx, tmp);
608 }
609 }
610 }
611
gen_arm_shift_reg(DisasContext * s,TCGv_i32 var,int shiftop,TCGv_i32 shift,int flags)612 static inline void gen_arm_shift_reg(DisasContext *s, TCGv_i32 var, int shiftop,
613 TCGv_i32 shift, int flags)
614 {
615 TCGContext *tcg_ctx = s->uc->tcg_ctx;
616 if (flags) {
617 switch (shiftop) {
618 case 0: gen_helper_shl_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
619 case 1: gen_helper_shr_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
620 case 2: gen_helper_sar_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
621 case 3: gen_helper_ror_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
622 }
623 } else {
624 switch (shiftop) {
625 case 0:
626 gen_shl(s, var, var, shift);
627 break;
628 case 1:
629 gen_shr(s, var, var, shift);
630 break;
631 case 2:
632 gen_sar(s, var, var, shift);
633 break;
634 case 3: tcg_gen_andi_i32(tcg_ctx, shift, shift, 0x1f);
635 tcg_gen_rotr_i32(tcg_ctx, var, var, shift); break;
636 }
637 }
638 tcg_temp_free_i32(tcg_ctx, shift);
639 }
640
641 #define PAS_OP(pfx) \
642 switch (op2) { \
643 case 0: gen_pas_helper(glue(pfx,add16)); break; \
644 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
645 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
646 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
647 case 4: gen_pas_helper(glue(pfx,add8)); break; \
648 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
649 }
gen_arm_parallel_addsub(DisasContext * s,int op1,int op2,TCGv_i32 a,TCGv_i32 b)650 static void gen_arm_parallel_addsub(DisasContext *s, int op1, int op2, TCGv_i32 a, TCGv_i32 b)
651 {
652 TCGContext *tcg_ctx = s->uc->tcg_ctx;
653 TCGv_ptr tmp;
654
655 switch (op1) {
656 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b, tmp)
657 case 1:
658 tmp = tcg_temp_new_ptr(tcg_ctx);
659 tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
660 PAS_OP(s)
661 tcg_temp_free_ptr(tcg_ctx, tmp);
662 break;
663 case 5:
664 tmp = tcg_temp_new_ptr(tcg_ctx);
665 tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
666 PAS_OP(u)
667 tcg_temp_free_ptr(tcg_ctx, tmp);
668 break;
669 #undef gen_pas_helper
670 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b)
671 case 2:
672 PAS_OP(q);
673 break;
674 case 3:
675 PAS_OP(sh);
676 break;
677 case 6:
678 PAS_OP(uq);
679 break;
680 case 7:
681 PAS_OP(uh);
682 break;
683 #undef gen_pas_helper
684 }
685 }
686 #undef PAS_OP
687
688 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
689 #define PAS_OP(pfx) \
690 switch (op1) { \
691 case 0: gen_pas_helper(glue(pfx,add8)); break; \
692 case 1: gen_pas_helper(glue(pfx,add16)); break; \
693 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
694 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
695 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
696 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
697 }
gen_thumb2_parallel_addsub(DisasContext * s,int op1,int op2,TCGv_i32 a,TCGv_i32 b)698 static void gen_thumb2_parallel_addsub(DisasContext *s, int op1, int op2, TCGv_i32 a, TCGv_i32 b)
699 {
700 TCGContext *tcg_ctx = s->uc->tcg_ctx;
701 TCGv_ptr tmp;
702
703 switch (op2) {
704 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b, tmp)
705 case 0:
706 tmp = tcg_temp_new_ptr(tcg_ctx);
707 tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
708 PAS_OP(s)
709 tcg_temp_free_ptr(tcg_ctx, tmp);
710 break;
711 case 4:
712 tmp = tcg_temp_new_ptr(tcg_ctx);
713 tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
714 PAS_OP(u)
715 tcg_temp_free_ptr(tcg_ctx, tmp);
716 break;
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b)
719 case 1:
720 PAS_OP(q);
721 break;
722 case 2:
723 PAS_OP(sh);
724 break;
725 case 5:
726 PAS_OP(uq);
727 break;
728 case 6:
729 PAS_OP(uh);
730 break;
731 #undef gen_pas_helper
732 }
733 }
734 #undef PAS_OP
735
736 /*
737 * generate a conditional branch based on ARM condition code cc.
738 * This is common between ARM and Aarch64 targets.
739 */
arm_gen_test_cc(TCGContext * tcg_ctx,int cc,int label)740 void arm_gen_test_cc(TCGContext *tcg_ctx, int cc, int label)
741 {
742 TCGv_i32 tmp;
743 int inv;
744
745 switch (cc) {
746 case 0: /* eq: Z */
747 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
748 break;
749 case 1: /* ne: !Z */
750 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_ZF, 0, label);
751 break;
752 case 2: /* cs: C */
753 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_CF, 0, label);
754 break;
755 case 3: /* cc: !C */
756 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, label);
757 break;
758 case 4: /* mi: N */
759 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tcg_ctx->cpu_NF, 0, label);
760 break;
761 case 5: /* pl: !N */
762 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tcg_ctx->cpu_NF, 0, label);
763 break;
764 case 6: /* vs: V */
765 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tcg_ctx->cpu_VF, 0, label);
766 break;
767 case 7: /* vc: !V */
768 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tcg_ctx->cpu_VF, 0, label);
769 break;
770 case 8: /* hi: C && !Z */
771 inv = gen_new_label(tcg_ctx);
772 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, inv);
773 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_ZF, 0, label);
774 gen_set_label(tcg_ctx, inv);
775 break;
776 case 9: /* ls: !C || Z */
777 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, label);
778 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
779 break;
780 case 10: /* ge: N == V -> N ^ V == 0 */
781 tmp = tcg_temp_new_i32(tcg_ctx);
782 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
783 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tmp, 0, label);
784 tcg_temp_free_i32(tcg_ctx, tmp);
785 break;
786 case 11: /* lt: N != V -> N ^ V != 0 */
787 tmp = tcg_temp_new_i32(tcg_ctx);
788 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
789 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tmp, 0, label);
790 tcg_temp_free_i32(tcg_ctx, tmp);
791 break;
792 case 12: /* gt: !Z && N == V */
793 inv = gen_new_label(tcg_ctx);
794 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, inv);
795 tmp = tcg_temp_new_i32(tcg_ctx);
796 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
797 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tmp, 0, label);
798 tcg_temp_free_i32(tcg_ctx, tmp);
799 gen_set_label(tcg_ctx, inv);
800 break;
801 case 13: /* le: Z || N != V */
802 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
803 tmp = tcg_temp_new_i32(tcg_ctx);
804 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
805 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tmp, 0, label);
806 tcg_temp_free_i32(tcg_ctx, tmp);
807 break;
808 default:
809 /* fprintf(stderr, "Bad condition code 0x%x\n", cc); */
810 tmp = tcg_const_i32(tcg_ctx, EXCP_EXCEPTION_EXIT);
811 gen_helper_exception_internal(tcg_ctx, tcg_ctx->cpu_env, tmp);
812 tcg_temp_free_i32(tcg_ctx, tmp);
813 }
814 }
815
816 static const uint8_t table_logic_cc[16] = {
817 1, /* and */
818 1, /* xor */
819 0, /* sub */
820 0, /* rsb */
821 0, /* add */
822 0, /* adc */
823 0, /* sbc */
824 0, /* rsc */
825 1, /* andl */
826 1, /* xorl */
827 0, /* cmp */
828 0, /* cmn */
829 1, /* orr */
830 1, /* mov */
831 1, /* bic */
832 1, /* mvn */
833 };
834
835 /* Set PC and Thumb state from an immediate address. */
gen_bx_im(DisasContext * s,uint32_t addr)836 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
837 {
838 TCGv_i32 tmp;
839 TCGContext *tcg_ctx = s->uc->tcg_ctx;
840
841 s->is_jmp = DISAS_UPDATE;
842 if (s->thumb != (addr & 1)) {
843 tmp = tcg_temp_new_i32(tcg_ctx);
844 tcg_gen_movi_i32(tcg_ctx, tmp, addr & 1);
845 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, thumb));
846 tcg_temp_free_i32(tcg_ctx, tmp);
847 }
848 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], addr & ~1);
849 }
850
851 /* Set PC and Thumb state from var. var is marked as dead. */
gen_bx(DisasContext * s,TCGv_i32 var)852 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
853 {
854 TCGContext *tcg_ctx = s->uc->tcg_ctx;
855
856 s->is_jmp = DISAS_UPDATE;
857 tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_R[15], var, ~1);
858 tcg_gen_andi_i32(tcg_ctx, var, var, 1);
859 store_cpu_field(tcg_ctx, var, thumb);
860 }
861
862 /* Variant of store_reg which uses branch&exchange logic when storing
863 to r15 in ARM architecture v7 and above. The source must be a temporary
864 and will be marked as dead. */
store_reg_bx(DisasContext * s,int reg,TCGv_i32 var)865 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
866 {
867 if (reg == 15 && ENABLE_ARCH_7) {
868 gen_bx(s, var);
869 } else {
870 store_reg(s, reg, var);
871 }
872 }
873
874 /* Variant of store_reg which uses branch&exchange logic when storing
875 * to r15 in ARM architecture v5T and above. This is used for storing
876 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
877 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
store_reg_from_load(DisasContext * s,int reg,TCGv_i32 var)878 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
879 {
880 if (reg == 15 && ENABLE_ARCH_5) {
881 gen_bx(s, var);
882 } else {
883 store_reg(s, reg, var);
884 }
885 }
886
887 /* Abstractions of "generate code to do a guest load/store for
888 * AArch32", where a vaddr is always 32 bits (and is zero
889 * extended if we're a 64 bit core) and data is also
890 * 32 bits unless specifically doing a 64 bit access.
891 * These functions work like tcg_gen_qemu_{ld,st}* except
892 * that the address argument is TCGv_i32 rather than TCGv.
893 */
894 #if TARGET_LONG_BITS == 32
895
896 #define DO_GEN_LD(SUFF, OPC) \
897 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
898 { \
899 tcg_gen_qemu_ld_i32(s->uc, val, addr, index, OPC); \
900 }
901
902 #define DO_GEN_ST(SUFF, OPC) \
903 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
904 { \
905 tcg_gen_qemu_st_i32(s->uc, val, addr, index, OPC); \
906 }
907
gen_aa32_ld64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)908 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
909 {
910 tcg_gen_qemu_ld_i64(s->uc, val, addr, index, MO_TEQ);
911 }
912
gen_aa32_st64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)913 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
914 {
915 tcg_gen_qemu_st_i64(s->uc, val, addr, index, MO_TEQ);
916 }
917
918 #else
919
920 #define DO_GEN_LD(SUFF, OPC) \
921 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
922 { \
923 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
924 TCGv addr64 = tcg_temp_new(tcg_ctx); \
925 tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr); \
926 tcg_gen_qemu_ld_i32(s->uc, val, addr64, index, OPC); \
927 tcg_temp_free(tcg_ctx, addr64); \
928 }
929
930 #define DO_GEN_ST(SUFF, OPC) \
931 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
932 { \
933 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
934 TCGv addr64 = tcg_temp_new(tcg_ctx); \
935 tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr); \
936 tcg_gen_qemu_st_i32(s->uc, val, addr64, index, OPC); \
937 tcg_temp_free(tcg_ctx, addr64); \
938 }
939
gen_aa32_ld64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)940 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
941 {
942 TCGContext *tcg_ctx = s->uc->tcg_ctx;
943 TCGv addr64 = tcg_temp_new(tcg_ctx);
944 tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
945 tcg_gen_qemu_ld_i64(s->uc, val, addr64, index, MO_TEQ);
946 tcg_temp_free(tcg_ctx, addr64);
947 }
948
gen_aa32_st64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)949 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
950 {
951 TCGContext *tcg_ctx = s->uc->tcg_ctx;
952 TCGv addr64 = tcg_temp_new(tcg_ctx);
953 tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
954 tcg_gen_qemu_st_i64(s->uc, val, addr64, index, MO_TEQ);
955 tcg_temp_free(tcg_ctx, addr64);
956 }
957
958 #endif
959
960 DO_GEN_LD(8s, MO_SB)
961 DO_GEN_LD(8u, MO_UB)
962 DO_GEN_LD(16s, MO_TESW)
963 DO_GEN_LD(16u, MO_TEUW)
964 DO_GEN_LD(32u, MO_TEUL)
965 DO_GEN_ST(8, MO_UB)
966 DO_GEN_ST(16, MO_TEUW)
967 DO_GEN_ST(32, MO_TEUL)
968
gen_set_pc_im(DisasContext * s,target_ulong val)969 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
970 {
971 TCGContext *tcg_ctx = s->uc->tcg_ctx;
972 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], val);
973 }
974
gen_hvc(DisasContext * s,int imm16)975 static inline void gen_hvc(DisasContext *s, int imm16)
976 {
977 TCGContext *tcg_ctx = s->uc->tcg_ctx;
978 /* The pre HVC helper handles cases when HVC gets trapped
979 * as an undefined insn by runtime configuration (ie before
980 * the insn really executes).
981 */
982 gen_set_pc_im(s, s->pc - 4);
983 gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
984 /* Otherwise we will treat this as a real exception which
985 * happens after execution of the insn. (The distinction matters
986 * for the PC value reported to the exception handler and also
987 * for single stepping.)
988 */
989 s->svc_imm = imm16;
990 gen_set_pc_im(s, s->pc);
991 s->is_jmp = DISAS_HVC;
992 }
993
gen_smc(DisasContext * s)994 static inline void gen_smc(DisasContext *s)
995 {
996 /* As with HVC, we may take an exception either before or after
997 * the insn executes.
998 */
999 TCGv_i32 tmp;
1000 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1001
1002 gen_set_pc_im(s, s->pc - 4);
1003 tmp = tcg_const_i32(tcg_ctx, syn_aa32_smc());
1004 gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
1005 tcg_temp_free_i32(tcg_ctx, tmp);
1006 gen_set_pc_im(s, s->pc);
1007 s->is_jmp = DISAS_SMC;
1008 }
1009
1010 static inline void
gen_set_condexec(DisasContext * s)1011 gen_set_condexec (DisasContext *s)
1012 {
1013 if (s->condexec_mask) {
1014 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1015 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1016 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1017 tcg_gen_movi_i32(tcg_ctx, tmp, val);
1018 store_cpu_field(tcg_ctx, tmp, condexec_bits);
1019 }
1020 }
1021
gen_exception_internal_insn(DisasContext * s,int offset,int excp)1022 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1023 {
1024 gen_set_condexec(s);
1025 gen_set_pc_im(s, s->pc - offset);
1026 gen_exception_internal(s, excp);
1027 s->is_jmp = DISAS_JUMP;
1028 }
1029
gen_exception_insn(DisasContext * s,int offset,int excp,int syn)1030 static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
1031 {
1032 gen_set_condexec(s);
1033 gen_set_pc_im(s, s->pc - offset);
1034 gen_exception(s, excp, syn); // qq
1035 s->is_jmp = DISAS_JUMP;
1036 }
1037
1038 /* Force a TB lookup after an instruction that changes the CPU state. */
gen_lookup_tb(DisasContext * s)1039 static inline void gen_lookup_tb(DisasContext *s)
1040 {
1041 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1042 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], s->pc & ~1);
1043 s->is_jmp = DISAS_UPDATE;
1044 }
1045
gen_add_data_offset(DisasContext * s,unsigned int insn,TCGv_i32 var)1046 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1047 TCGv_i32 var)
1048 {
1049 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1050 int val, rm, shift, shiftop;
1051 TCGv_i32 offset;
1052
1053 if (!(insn & (1 << 25))) {
1054 /* immediate */
1055 val = insn & 0xfff;
1056 if (!(insn & (1 << 23)))
1057 val = -val;
1058 if (val != 0)
1059 tcg_gen_addi_i32(tcg_ctx, var, var, val);
1060 } else {
1061 /* shift/register */
1062 rm = (insn) & 0xf;
1063 shift = (insn >> 7) & 0x1f;
1064 shiftop = (insn >> 5) & 3;
1065 offset = load_reg(s, rm);
1066 gen_arm_shift_im(s, offset, shiftop, shift, 0);
1067 if (!(insn & (1 << 23)))
1068 tcg_gen_sub_i32(tcg_ctx, var, var, offset);
1069 else
1070 tcg_gen_add_i32(tcg_ctx, var, var, offset);
1071 tcg_temp_free_i32(tcg_ctx, offset);
1072 }
1073 }
1074
gen_add_datah_offset(DisasContext * s,unsigned int insn,int extra,TCGv_i32 var)1075 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1076 int extra, TCGv_i32 var)
1077 {
1078 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1079 int val, rm;
1080 TCGv_i32 offset;
1081
1082 if (insn & (1 << 22)) {
1083 /* immediate */
1084 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1085 if (!(insn & (1 << 23)))
1086 val = -val;
1087 val += extra;
1088 if (val != 0)
1089 tcg_gen_addi_i32(tcg_ctx, var, var, val);
1090 } else {
1091 /* register */
1092 if (extra)
1093 tcg_gen_addi_i32(tcg_ctx, var, var, extra);
1094 rm = (insn) & 0xf;
1095 offset = load_reg(s, rm);
1096 if (!(insn & (1 << 23)))
1097 tcg_gen_sub_i32(tcg_ctx, var, var, offset);
1098 else
1099 tcg_gen_add_i32(tcg_ctx, var, var, offset);
1100 tcg_temp_free_i32(tcg_ctx, offset);
1101 }
1102 }
1103
get_fpstatus_ptr(DisasContext * s,int neon)1104 static TCGv_ptr get_fpstatus_ptr(DisasContext *s, int neon)
1105 {
1106 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1107 TCGv_ptr statusptr = tcg_temp_new_ptr(tcg_ctx);
1108 int offset;
1109 if (neon) {
1110 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1111 } else {
1112 offset = offsetof(CPUARMState, vfp.fp_status);
1113 }
1114 tcg_gen_addi_ptr(tcg_ctx, statusptr, tcg_ctx->cpu_env, offset);
1115 return statusptr;
1116 }
1117
1118 #define VFP_OP2(name) \
1119 static inline void gen_vfp_##name(DisasContext *s, int dp) \
1120 { \
1121 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1122 TCGv_ptr fpst = get_fpstatus_ptr(s, 0); \
1123 if (dp) { \
1124 gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, fpst); \
1125 } else { \
1126 gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, fpst); \
1127 } \
1128 tcg_temp_free_ptr(tcg_ctx, fpst); \
1129 }
1130
1131 VFP_OP2(add)
VFP_OP2(sub)1132 VFP_OP2(sub)
1133 VFP_OP2(mul)
1134 VFP_OP2(div)
1135
1136 #undef VFP_OP2
1137
1138 static inline void gen_vfp_F1_mul(DisasContext *s, int dp)
1139 {
1140 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1141 /* Like gen_vfp_mul() but put result in F1 */
1142 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
1143 if (dp) {
1144 gen_helper_vfp_muld(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, fpst);
1145 } else {
1146 gen_helper_vfp_muls(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, fpst);
1147 }
1148 tcg_temp_free_ptr(tcg_ctx, fpst);
1149 }
1150
gen_vfp_F1_neg(DisasContext * s,int dp)1151 static inline void gen_vfp_F1_neg(DisasContext *s, int dp)
1152 {
1153 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1154 /* Like gen_vfp_neg() but put result in F1 */
1155 if (dp) {
1156 gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_F0d);
1157 } else {
1158 gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_F0s);
1159 }
1160 }
1161
gen_vfp_abs(DisasContext * s,int dp)1162 static inline void gen_vfp_abs(DisasContext *s, int dp)
1163 {
1164 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1165 if (dp)
1166 gen_helper_vfp_absd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
1167 else
1168 gen_helper_vfp_abss(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
1169 }
1170
gen_vfp_neg(DisasContext * s,int dp)1171 static inline void gen_vfp_neg(DisasContext *s, int dp)
1172 {
1173 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1174 if (dp)
1175 gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
1176 else
1177 gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
1178 }
1179
gen_vfp_sqrt(DisasContext * s,int dp)1180 static inline void gen_vfp_sqrt(DisasContext *s, int dp)
1181 {
1182 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1183 if (dp)
1184 gen_helper_vfp_sqrtd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env);
1185 else
1186 gen_helper_vfp_sqrts(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
1187 }
1188
gen_vfp_cmp(DisasContext * s,int dp)1189 static inline void gen_vfp_cmp(DisasContext *s, int dp)
1190 {
1191 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1192 if (dp)
1193 gen_helper_vfp_cmpd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env);
1194 else
1195 gen_helper_vfp_cmps(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env);
1196 }
1197
gen_vfp_cmpe(DisasContext * s,int dp)1198 static inline void gen_vfp_cmpe(DisasContext *s, int dp)
1199 {
1200 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1201 if (dp)
1202 gen_helper_vfp_cmped(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env);
1203 else
1204 gen_helper_vfp_cmpes(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env);
1205 }
1206
gen_vfp_F1_ld0(DisasContext * s,int dp)1207 static inline void gen_vfp_F1_ld0(DisasContext *s, int dp)
1208 {
1209 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1210 if (dp)
1211 tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_F1d, 0);
1212 else
1213 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_F1s, 0);
1214 }
1215
1216 #define VFP_GEN_ITOF(name) \
1217 static inline void gen_vfp_##name(DisasContext *s, int dp, int neon) \
1218 { \
1219 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1220 TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1221 if (dp) { \
1222 gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0s, statusptr); \
1223 } else { \
1224 gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, statusptr); \
1225 } \
1226 tcg_temp_free_ptr(tcg_ctx, statusptr); \
1227 }
1228
1229 VFP_GEN_ITOF(uito)
VFP_GEN_ITOF(sito)1230 VFP_GEN_ITOF(sito)
1231 #undef VFP_GEN_ITOF
1232
1233 #define VFP_GEN_FTOI(name) \
1234 static inline void gen_vfp_##name(DisasContext *s, int dp, int neon) \
1235 { \
1236 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1237 TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1238 if (dp) { \
1239 gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0d, statusptr); \
1240 } else { \
1241 gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, statusptr); \
1242 } \
1243 tcg_temp_free_ptr(tcg_ctx, statusptr); \
1244 }
1245
1246 VFP_GEN_FTOI(toui)
1247 VFP_GEN_FTOI(touiz)
1248 VFP_GEN_FTOI(tosi)
1249 VFP_GEN_FTOI(tosiz)
1250 #undef VFP_GEN_FTOI
1251
1252 #define VFP_GEN_FIX(name, round) \
1253 static inline void gen_vfp_##name(DisasContext *s, int dp, int shift, int neon) \
1254 { \
1255 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1256 TCGv_i32 tmp_shift = tcg_const_i32(tcg_ctx, shift); \
1257 TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1258 if (dp) { \
1259 gen_helper_vfp_##name##d##round(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tmp_shift, \
1260 statusptr); \
1261 } else { \
1262 gen_helper_vfp_##name##s##round(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tmp_shift, \
1263 statusptr); \
1264 } \
1265 tcg_temp_free_i32(tcg_ctx, tmp_shift); \
1266 tcg_temp_free_ptr(tcg_ctx, statusptr); \
1267 }
1268 VFP_GEN_FIX(tosh, _round_to_zero)
1269 VFP_GEN_FIX(tosl, _round_to_zero)
1270 VFP_GEN_FIX(touh, _round_to_zero)
1271 VFP_GEN_FIX(toul, _round_to_zero)
1272 VFP_GEN_FIX(shto, )
1273 VFP_GEN_FIX(slto, )
1274 VFP_GEN_FIX(uhto, )
1275 VFP_GEN_FIX(ulto, )
1276 #undef VFP_GEN_FIX
1277
1278 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1279 {
1280 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1281 if (dp) {
1282 gen_aa32_ld64(s, tcg_ctx->cpu_F0d, addr, get_mem_index(s));
1283 } else {
1284 gen_aa32_ld32u(s, tcg_ctx->cpu_F0s, addr, get_mem_index(s));
1285 }
1286 }
1287
gen_vfp_st(DisasContext * s,int dp,TCGv_i32 addr)1288 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1289 {
1290 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1291 if (dp) {
1292 gen_aa32_st64(s, tcg_ctx->cpu_F0d, addr, get_mem_index(s));
1293 } else {
1294 gen_aa32_st32(s, tcg_ctx->cpu_F0s, addr, get_mem_index(s));
1295 }
1296 }
1297
1298 static inline long
vfp_reg_offset(int dp,int reg)1299 vfp_reg_offset (int dp, int reg)
1300 {
1301 if (dp)
1302 return offsetof(CPUARMState, vfp.regs[reg]);
1303 else if (reg & 1) {
1304 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1305 + offsetof(CPU_DoubleU, l.upper);
1306 } else {
1307 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1308 + offsetof(CPU_DoubleU, l.lower);
1309 }
1310 }
1311
1312 /* Return the offset of a 32-bit piece of a NEON register.
1313 zero is the least significant end of the register. */
1314 static inline long
neon_reg_offset(int reg,int n)1315 neon_reg_offset (int reg, int n)
1316 {
1317 int sreg;
1318 sreg = reg * 2 + n;
1319 return vfp_reg_offset(0, sreg);
1320 }
1321
neon_load_reg(TCGContext * tcg_ctx,int reg,int pass)1322 static TCGv_i32 neon_load_reg(TCGContext *tcg_ctx, int reg, int pass)
1323 {
1324 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1325 tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(reg, pass));
1326 return tmp;
1327 }
1328
neon_store_reg(TCGContext * tcg_ctx,int reg,int pass,TCGv_i32 var)1329 static void neon_store_reg(TCGContext *tcg_ctx, int reg, int pass, TCGv_i32 var)
1330 {
1331 tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, neon_reg_offset(reg, pass));
1332 tcg_temp_free_i32(tcg_ctx, var);
1333 }
1334
neon_load_reg64(TCGContext * tcg_ctx,TCGv_i64 var,int reg)1335 static inline void neon_load_reg64(TCGContext *tcg_ctx, TCGv_i64 var, int reg)
1336 {
1337 tcg_gen_ld_i64(tcg_ctx, var, tcg_ctx->cpu_env, vfp_reg_offset(1, reg));
1338 }
1339
neon_store_reg64(TCGContext * tcg_ctx,TCGv_i64 var,int reg)1340 static inline void neon_store_reg64(TCGContext *tcg_ctx, TCGv_i64 var, int reg)
1341 {
1342 tcg_gen_st_i64(tcg_ctx, var, tcg_ctx->cpu_env, vfp_reg_offset(1, reg));
1343 }
1344
1345 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1346 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1347 #define tcg_gen_st_f32 tcg_gen_st_i32
1348 #define tcg_gen_st_f64 tcg_gen_st_i64
1349
gen_mov_F0_vreg(DisasContext * s,int dp,int reg)1350 static inline void gen_mov_F0_vreg(DisasContext *s, int dp, int reg)
1351 {
1352 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1353 if (dp)
1354 tcg_gen_ld_f64(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1355 else
1356 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1357 }
1358
gen_mov_F1_vreg(DisasContext * s,int dp,int reg)1359 static inline void gen_mov_F1_vreg(DisasContext *s, int dp, int reg)
1360 {
1361 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1362 if (dp)
1363 tcg_gen_ld_f64(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1364 else
1365 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1366 }
1367
gen_mov_vreg_F0(DisasContext * s,int dp,int reg)1368 static inline void gen_mov_vreg_F0(DisasContext *s, int dp, int reg)
1369 {
1370 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1371 if (dp)
1372 tcg_gen_st_f64(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1373 else
1374 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1375 }
1376
1377 #define ARM_CP_RW_BIT (1 << 20)
1378
iwmmxt_load_reg(DisasContext * s,TCGv_i64 var,int reg)1379 static inline void iwmmxt_load_reg(DisasContext *s, TCGv_i64 var, int reg)
1380 {
1381 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1382 tcg_gen_ld_i64(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1383 }
1384
iwmmxt_store_reg(DisasContext * s,TCGv_i64 var,int reg)1385 static inline void iwmmxt_store_reg(DisasContext *s, TCGv_i64 var, int reg)
1386 {
1387 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1388 tcg_gen_st_i64(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1389 }
1390
iwmmxt_load_creg(DisasContext * s,int reg)1391 static inline TCGv_i32 iwmmxt_load_creg(DisasContext *s, int reg)
1392 {
1393 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1394 TCGv_i32 var = tcg_temp_new_i32(tcg_ctx);
1395 tcg_gen_ld_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1396 return var;
1397 }
1398
iwmmxt_store_creg(DisasContext * s,int reg,TCGv_i32 var)1399 static inline void iwmmxt_store_creg(DisasContext *s, int reg, TCGv_i32 var)
1400 {
1401 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1402 tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1403 tcg_temp_free_i32(tcg_ctx, var);
1404 }
1405
gen_op_iwmmxt_movq_wRn_M0(DisasContext * s,int rn)1406 static inline void gen_op_iwmmxt_movq_wRn_M0(DisasContext *s, int rn)
1407 {
1408 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1409 iwmmxt_store_reg(s, tcg_ctx->cpu_M0, rn);
1410 }
1411
gen_op_iwmmxt_movq_M0_wRn(DisasContext * s,int rn)1412 static inline void gen_op_iwmmxt_movq_M0_wRn(DisasContext *s, int rn)
1413 {
1414 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1415 iwmmxt_load_reg(s, tcg_ctx->cpu_M0, rn);
1416 }
1417
gen_op_iwmmxt_orq_M0_wRn(DisasContext * s,int rn)1418 static inline void gen_op_iwmmxt_orq_M0_wRn(DisasContext *s, int rn)
1419 {
1420 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1421 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1422 tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1423 }
1424
gen_op_iwmmxt_andq_M0_wRn(DisasContext * s,int rn)1425 static inline void gen_op_iwmmxt_andq_M0_wRn(DisasContext *s, int rn)
1426 {
1427 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1428 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1429 tcg_gen_and_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1430 }
1431
gen_op_iwmmxt_xorq_M0_wRn(DisasContext * s,int rn)1432 static inline void gen_op_iwmmxt_xorq_M0_wRn(DisasContext *s, int rn)
1433 {
1434 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1435 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1436 tcg_gen_xor_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1437 }
1438
1439 #define IWMMXT_OP(name) \
1440 static inline void gen_op_iwmmxt_##name##_M0_wRn(DisasContext *s, int rn) \
1441 { \
1442 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1443 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn); \
1444 gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1); \
1445 }
1446
1447 #define IWMMXT_OP_ENV(name) \
1448 static inline void gen_op_iwmmxt_##name##_M0_wRn(DisasContext *s, int rn) \
1449 { \
1450 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1451 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn); \
1452 gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1); \
1453 }
1454
1455 #define IWMMXT_OP_ENV_SIZE(name) \
1456 IWMMXT_OP_ENV(name##b) \
1457 IWMMXT_OP_ENV(name##w) \
1458 IWMMXT_OP_ENV(name##l)
1459
1460 #define IWMMXT_OP_ENV1(name) \
1461 static inline void gen_op_iwmmxt_##name##_M0(DisasContext *s) \
1462 { \
1463 TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1464 gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0); \
1465 }
1466
1467 IWMMXT_OP(maddsq)
IWMMXT_OP(madduq)1468 IWMMXT_OP(madduq)
1469 IWMMXT_OP(sadb)
1470 IWMMXT_OP(sadw)
1471 IWMMXT_OP(mulslw)
1472 IWMMXT_OP(mulshw)
1473 IWMMXT_OP(mululw)
1474 IWMMXT_OP(muluhw)
1475 IWMMXT_OP(macsw)
1476 IWMMXT_OP(macuw)
1477
1478 IWMMXT_OP_ENV_SIZE(unpackl)
1479 IWMMXT_OP_ENV_SIZE(unpackh)
1480
1481 IWMMXT_OP_ENV1(unpacklub)
1482 IWMMXT_OP_ENV1(unpackluw)
1483 IWMMXT_OP_ENV1(unpacklul)
1484 IWMMXT_OP_ENV1(unpackhub)
1485 IWMMXT_OP_ENV1(unpackhuw)
1486 IWMMXT_OP_ENV1(unpackhul)
1487 IWMMXT_OP_ENV1(unpacklsb)
1488 IWMMXT_OP_ENV1(unpacklsw)
1489 IWMMXT_OP_ENV1(unpacklsl)
1490 IWMMXT_OP_ENV1(unpackhsb)
1491 IWMMXT_OP_ENV1(unpackhsw)
1492 IWMMXT_OP_ENV1(unpackhsl)
1493
1494 IWMMXT_OP_ENV_SIZE(cmpeq)
1495 IWMMXT_OP_ENV_SIZE(cmpgtu)
1496 IWMMXT_OP_ENV_SIZE(cmpgts)
1497
1498 IWMMXT_OP_ENV_SIZE(mins)
1499 IWMMXT_OP_ENV_SIZE(minu)
1500 IWMMXT_OP_ENV_SIZE(maxs)
1501 IWMMXT_OP_ENV_SIZE(maxu)
1502
1503 IWMMXT_OP_ENV_SIZE(subn)
1504 IWMMXT_OP_ENV_SIZE(addn)
1505 IWMMXT_OP_ENV_SIZE(subu)
1506 IWMMXT_OP_ENV_SIZE(addu)
1507 IWMMXT_OP_ENV_SIZE(subs)
1508 IWMMXT_OP_ENV_SIZE(adds)
1509
1510 IWMMXT_OP_ENV(avgb0)
1511 IWMMXT_OP_ENV(avgb1)
1512 IWMMXT_OP_ENV(avgw0)
1513 IWMMXT_OP_ENV(avgw1)
1514
1515 IWMMXT_OP_ENV(packuw)
1516 IWMMXT_OP_ENV(packul)
1517 IWMMXT_OP_ENV(packuq)
1518 IWMMXT_OP_ENV(packsw)
1519 IWMMXT_OP_ENV(packsl)
1520 IWMMXT_OP_ENV(packsq)
1521
1522 static void gen_op_iwmmxt_set_mup(DisasContext *s)
1523 {
1524 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1525 TCGv_i32 tmp;
1526 tmp = load_cpu_field(s->uc, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1527 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, 2);
1528 store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1529 }
1530
gen_op_iwmmxt_set_cup(DisasContext * s)1531 static void gen_op_iwmmxt_set_cup(DisasContext *s)
1532 {
1533 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1534 TCGv_i32 tmp;
1535 tmp = load_cpu_field(s->uc, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1536 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, 1);
1537 store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1538 }
1539
gen_op_iwmmxt_setpsr_nz(DisasContext * s)1540 static void gen_op_iwmmxt_setpsr_nz(DisasContext *s)
1541 {
1542 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1543 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1544 gen_helper_iwmmxt_setpsr_nz(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1545 store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1546 }
1547
gen_op_iwmmxt_addl_M0_wRn(DisasContext * s,int rn)1548 static inline void gen_op_iwmmxt_addl_M0_wRn(DisasContext *s, int rn)
1549 {
1550 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1551 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1552 tcg_gen_ext32u_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1);
1553 tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1554 }
1555
gen_iwmmxt_address(DisasContext * s,uint32_t insn,TCGv_i32 dest)1556 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1557 TCGv_i32 dest)
1558 {
1559 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1560 int rd;
1561 uint32_t offset;
1562 TCGv_i32 tmp;
1563
1564 rd = (insn >> 16) & 0xf;
1565 tmp = load_reg(s, rd);
1566
1567 offset = (insn & 0xff) << ((insn >> 7) & 2);
1568 if (insn & (1 << 24)) {
1569 /* Pre indexed */
1570 if (insn & (1 << 23))
1571 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
1572 else
1573 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, 0-offset);
1574 tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1575 if (insn & (1 << 21))
1576 store_reg(s, rd, tmp);
1577 else
1578 tcg_temp_free_i32(tcg_ctx, tmp);
1579 } else if (insn & (1 << 21)) {
1580 /* Post indexed */
1581 tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1582 if (insn & (1 << 23))
1583 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
1584 else
1585 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, 0-offset);
1586 store_reg(s, rd, tmp);
1587 } else if (!(insn & (1 << 23)))
1588 return 1;
1589 return 0;
1590 }
1591
gen_iwmmxt_shift(DisasContext * s,uint32_t insn,uint32_t mask,TCGv_i32 dest)1592 static inline int gen_iwmmxt_shift(DisasContext *s, uint32_t insn, uint32_t mask, TCGv_i32 dest)
1593 {
1594 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1595 int rd = (insn >> 0) & 0xf;
1596 TCGv_i32 tmp;
1597
1598 if (insn & (1 << 8)) {
1599 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1600 return 1;
1601 } else {
1602 tmp = iwmmxt_load_creg(s, rd);
1603 }
1604 } else {
1605 tmp = tcg_temp_new_i32(tcg_ctx);
1606 iwmmxt_load_reg(s, tcg_ctx->cpu_V0, rd);
1607 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
1608 }
1609 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, mask);
1610 tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1611 tcg_temp_free_i32(tcg_ctx, tmp);
1612 return 0;
1613 }
1614
1615 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1616 (ie. an undefined instruction). */
disas_iwmmxt_insn(DisasContext * s,uint32_t insn)1617 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1618 {
1619 TCGContext *tcg_ctx = s->uc->tcg_ctx;
1620 int rd, wrd;
1621 int rdhi, rdlo, rd0, rd1, i;
1622 TCGv_i32 addr;
1623 TCGv_i32 tmp, tmp2, tmp3;
1624
1625 if ((insn & 0x0e000e00) == 0x0c000000) {
1626 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1627 wrd = insn & 0xf;
1628 rdlo = (insn >> 12) & 0xf;
1629 rdhi = (insn >> 16) & 0xf;
1630 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1631 iwmmxt_load_reg(s, tcg_ctx->cpu_V0, wrd);
1632 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_V0);
1633 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
1634 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_V0);
1635 } else { /* TMCRR */
1636 tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_R[rdhi]);
1637 iwmmxt_store_reg(s, tcg_ctx->cpu_V0, wrd);
1638 gen_op_iwmmxt_set_mup(s);
1639 }
1640 return 0;
1641 }
1642
1643 wrd = (insn >> 12) & 0xf;
1644 addr = tcg_temp_new_i32(tcg_ctx);
1645 if (gen_iwmmxt_address(s, insn, addr)) {
1646 tcg_temp_free_i32(tcg_ctx, addr);
1647 return 1;
1648 }
1649 if (insn & ARM_CP_RW_BIT) {
1650 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1651 tmp = tcg_temp_new_i32(tcg_ctx);
1652 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1653 iwmmxt_store_creg(s, wrd, tmp);
1654 } else {
1655 i = 1;
1656 if (insn & (1 << 8)) {
1657 if (insn & (1 << 22)) { /* WLDRD */
1658 gen_aa32_ld64(s, tcg_ctx->cpu_M0, addr, get_mem_index(s));
1659 i = 0;
1660 } else { /* WLDRW wRd */
1661 tmp = tcg_temp_new_i32(tcg_ctx);
1662 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1663 }
1664 } else {
1665 tmp = tcg_temp_new_i32(tcg_ctx);
1666 if (insn & (1 << 22)) { /* WLDRH */
1667 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1668 } else { /* WLDRB */
1669 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1670 }
1671 }
1672 if (i) {
1673 tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_M0, tmp);
1674 tcg_temp_free_i32(tcg_ctx, tmp);
1675 }
1676 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1677 }
1678 } else {
1679 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1680 tmp = iwmmxt_load_creg(s, wrd);
1681 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1682 } else {
1683 gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1684 tmp = tcg_temp_new_i32(tcg_ctx);
1685 if (insn & (1 << 8)) {
1686 if (insn & (1 << 22)) { /* WSTRD */
1687 gen_aa32_st64(s, tcg_ctx->cpu_M0, addr, get_mem_index(s));
1688 } else { /* WSTRW wRd */
1689 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1690 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1691 }
1692 } else {
1693 if (insn & (1 << 22)) { /* WSTRH */
1694 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1695 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1696 } else { /* WSTRB */
1697 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1698 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1699 }
1700 }
1701 }
1702 tcg_temp_free_i32(tcg_ctx, tmp);
1703 }
1704 tcg_temp_free_i32(tcg_ctx, addr);
1705 return 0;
1706 }
1707
1708 if ((insn & 0x0f000000) != 0x0e000000)
1709 return 1;
1710
1711 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1712 case 0x000: /* WOR */
1713 wrd = (insn >> 12) & 0xf;
1714 rd0 = (insn >> 0) & 0xf;
1715 rd1 = (insn >> 16) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1717 gen_op_iwmmxt_orq_M0_wRn(s, rd1);
1718 gen_op_iwmmxt_setpsr_nz(s);
1719 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1720 gen_op_iwmmxt_set_mup(s);
1721 gen_op_iwmmxt_set_cup(s);
1722 break;
1723 case 0x011: /* TMCR */
1724 if (insn & 0xf)
1725 return 1;
1726 rd = (insn >> 12) & 0xf;
1727 wrd = (insn >> 16) & 0xf;
1728 switch (wrd) {
1729 case ARM_IWMMXT_wCID:
1730 case ARM_IWMMXT_wCASF:
1731 break;
1732 case ARM_IWMMXT_wCon:
1733 gen_op_iwmmxt_set_cup(s);
1734 /* Fall through. */
1735 case ARM_IWMMXT_wCSSF:
1736 tmp = iwmmxt_load_creg(s, wrd);
1737 tmp2 = load_reg(s, rd);
1738 tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
1739 tcg_temp_free_i32(tcg_ctx, tmp2);
1740 iwmmxt_store_creg(s, wrd, tmp);
1741 break;
1742 case ARM_IWMMXT_wCGR0:
1743 case ARM_IWMMXT_wCGR1:
1744 case ARM_IWMMXT_wCGR2:
1745 case ARM_IWMMXT_wCGR3:
1746 gen_op_iwmmxt_set_cup(s);
1747 tmp = load_reg(s, rd);
1748 iwmmxt_store_creg(s, wrd, tmp);
1749 break;
1750 default:
1751 return 1;
1752 }
1753 break;
1754 case 0x100: /* WXOR */
1755 wrd = (insn >> 12) & 0xf;
1756 rd0 = (insn >> 0) & 0xf;
1757 rd1 = (insn >> 16) & 0xf;
1758 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1759 gen_op_iwmmxt_xorq_M0_wRn(s, rd1);
1760 gen_op_iwmmxt_setpsr_nz(s);
1761 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1762 gen_op_iwmmxt_set_mup(s);
1763 gen_op_iwmmxt_set_cup(s);
1764 break;
1765 case 0x111: /* TMRC */
1766 if (insn & 0xf)
1767 return 1;
1768 rd = (insn >> 12) & 0xf;
1769 wrd = (insn >> 16) & 0xf;
1770 tmp = iwmmxt_load_creg(s, wrd);
1771 store_reg(s, rd, tmp);
1772 break;
1773 case 0x300: /* WANDN */
1774 wrd = (insn >> 12) & 0xf;
1775 rd0 = (insn >> 0) & 0xf;
1776 rd1 = (insn >> 16) & 0xf;
1777 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1778 tcg_gen_neg_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
1779 gen_op_iwmmxt_andq_M0_wRn(s, rd1);
1780 gen_op_iwmmxt_setpsr_nz(s);
1781 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1782 gen_op_iwmmxt_set_mup(s);
1783 gen_op_iwmmxt_set_cup(s);
1784 break;
1785 case 0x200: /* WAND */
1786 wrd = (insn >> 12) & 0xf;
1787 rd0 = (insn >> 0) & 0xf;
1788 rd1 = (insn >> 16) & 0xf;
1789 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1790 gen_op_iwmmxt_andq_M0_wRn(s, rd1);
1791 gen_op_iwmmxt_setpsr_nz(s);
1792 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1793 gen_op_iwmmxt_set_mup(s);
1794 gen_op_iwmmxt_set_cup(s);
1795 break;
1796 case 0x810: case 0xa10: /* WMADD */
1797 wrd = (insn >> 12) & 0xf;
1798 rd0 = (insn >> 0) & 0xf;
1799 rd1 = (insn >> 16) & 0xf;
1800 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1801 if (insn & (1 << 21))
1802 gen_op_iwmmxt_maddsq_M0_wRn(s, rd1);
1803 else
1804 gen_op_iwmmxt_madduq_M0_wRn(s, rd1);
1805 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1806 gen_op_iwmmxt_set_mup(s);
1807 break;
1808 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1809 wrd = (insn >> 12) & 0xf;
1810 rd0 = (insn >> 16) & 0xf;
1811 rd1 = (insn >> 0) & 0xf;
1812 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1813 switch ((insn >> 22) & 3) {
1814 case 0:
1815 gen_op_iwmmxt_unpacklb_M0_wRn(s, rd1);
1816 break;
1817 case 1:
1818 gen_op_iwmmxt_unpacklw_M0_wRn(s, rd1);
1819 break;
1820 case 2:
1821 gen_op_iwmmxt_unpackll_M0_wRn(s, rd1);
1822 break;
1823 case 3:
1824 return 1;
1825 }
1826 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1827 gen_op_iwmmxt_set_mup(s);
1828 gen_op_iwmmxt_set_cup(s);
1829 break;
1830 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1831 wrd = (insn >> 12) & 0xf;
1832 rd0 = (insn >> 16) & 0xf;
1833 rd1 = (insn >> 0) & 0xf;
1834 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1835 switch ((insn >> 22) & 3) {
1836 case 0:
1837 gen_op_iwmmxt_unpackhb_M0_wRn(s, rd1);
1838 break;
1839 case 1:
1840 gen_op_iwmmxt_unpackhw_M0_wRn(s, rd1);
1841 break;
1842 case 2:
1843 gen_op_iwmmxt_unpackhl_M0_wRn(s, rd1);
1844 break;
1845 case 3:
1846 return 1;
1847 }
1848 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1849 gen_op_iwmmxt_set_mup(s);
1850 gen_op_iwmmxt_set_cup(s);
1851 break;
1852 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1853 wrd = (insn >> 12) & 0xf;
1854 rd0 = (insn >> 16) & 0xf;
1855 rd1 = (insn >> 0) & 0xf;
1856 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1857 if (insn & (1 << 22))
1858 gen_op_iwmmxt_sadw_M0_wRn(s, rd1);
1859 else
1860 gen_op_iwmmxt_sadb_M0_wRn(s, rd1);
1861 if (!(insn & (1 << 20)))
1862 gen_op_iwmmxt_addl_M0_wRn(s, wrd);
1863 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1864 gen_op_iwmmxt_set_mup(s);
1865 break;
1866 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1867 wrd = (insn >> 12) & 0xf;
1868 rd0 = (insn >> 16) & 0xf;
1869 rd1 = (insn >> 0) & 0xf;
1870 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1871 if (insn & (1 << 21)) {
1872 if (insn & (1 << 20))
1873 gen_op_iwmmxt_mulshw_M0_wRn(s, rd1);
1874 else
1875 gen_op_iwmmxt_mulslw_M0_wRn(s, rd1);
1876 } else {
1877 if (insn & (1 << 20))
1878 gen_op_iwmmxt_muluhw_M0_wRn(s, rd1);
1879 else
1880 gen_op_iwmmxt_mululw_M0_wRn(s, rd1);
1881 }
1882 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1883 gen_op_iwmmxt_set_mup(s);
1884 break;
1885 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1886 wrd = (insn >> 12) & 0xf;
1887 rd0 = (insn >> 16) & 0xf;
1888 rd1 = (insn >> 0) & 0xf;
1889 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1890 if (insn & (1 << 21))
1891 gen_op_iwmmxt_macsw_M0_wRn(s, rd1);
1892 else
1893 gen_op_iwmmxt_macuw_M0_wRn(s, rd1);
1894 if (!(insn & (1 << 20))) {
1895 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, wrd);
1896 tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1897 }
1898 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1899 gen_op_iwmmxt_set_mup(s);
1900 break;
1901 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1902 wrd = (insn >> 12) & 0xf;
1903 rd0 = (insn >> 16) & 0xf;
1904 rd1 = (insn >> 0) & 0xf;
1905 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1906 switch ((insn >> 22) & 3) {
1907 case 0:
1908 gen_op_iwmmxt_cmpeqb_M0_wRn(s, rd1);
1909 break;
1910 case 1:
1911 gen_op_iwmmxt_cmpeqw_M0_wRn(s, rd1);
1912 break;
1913 case 2:
1914 gen_op_iwmmxt_cmpeql_M0_wRn(s, rd1);
1915 break;
1916 case 3:
1917 return 1;
1918 }
1919 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1920 gen_op_iwmmxt_set_mup(s);
1921 gen_op_iwmmxt_set_cup(s);
1922 break;
1923 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1924 wrd = (insn >> 12) & 0xf;
1925 rd0 = (insn >> 16) & 0xf;
1926 rd1 = (insn >> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1928 if (insn & (1 << 22)) {
1929 if (insn & (1 << 20))
1930 gen_op_iwmmxt_avgw1_M0_wRn(s, rd1);
1931 else
1932 gen_op_iwmmxt_avgw0_M0_wRn(s, rd1);
1933 } else {
1934 if (insn & (1 << 20))
1935 gen_op_iwmmxt_avgb1_M0_wRn(s, rd1);
1936 else
1937 gen_op_iwmmxt_avgb0_M0_wRn(s, rd1);
1938 }
1939 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1940 gen_op_iwmmxt_set_mup(s);
1941 gen_op_iwmmxt_set_cup(s);
1942 break;
1943 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1944 wrd = (insn >> 12) & 0xf;
1945 rd0 = (insn >> 16) & 0xf;
1946 rd1 = (insn >> 0) & 0xf;
1947 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1948 tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1949 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 7);
1950 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rd1);
1951 gen_helper_iwmmxt_align(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1, tmp);
1952 tcg_temp_free_i32(tcg_ctx, tmp);
1953 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1954 gen_op_iwmmxt_set_mup(s);
1955 break;
1956 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1957 if (((insn >> 6) & 3) == 3)
1958 return 1;
1959 rd = (insn >> 12) & 0xf;
1960 wrd = (insn >> 16) & 0xf;
1961 tmp = load_reg(s, rd);
1962 gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1963 switch ((insn >> 6) & 3) {
1964 case 0:
1965 tmp2 = tcg_const_i32(tcg_ctx, 0xff);
1966 tmp3 = tcg_const_i32(tcg_ctx, (insn & 7) << 3);
1967 break;
1968 case 1:
1969 tmp2 = tcg_const_i32(tcg_ctx, 0xffff);
1970 tmp3 = tcg_const_i32(tcg_ctx, (insn & 3) << 4);
1971 break;
1972 case 2:
1973 tmp2 = tcg_const_i32(tcg_ctx, 0xffffffff);
1974 tmp3 = tcg_const_i32(tcg_ctx, (insn & 1) << 5);
1975 break;
1976 default:
1977 TCGV_UNUSED_I32(tmp2);
1978 TCGV_UNUSED_I32(tmp3);
1979 }
1980 gen_helper_iwmmxt_insr(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2, tmp3);
1981 tcg_temp_free_i32(tcg_ctx, tmp3);
1982 tcg_temp_free_i32(tcg_ctx, tmp2);
1983 tcg_temp_free_i32(tcg_ctx, tmp);
1984 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1985 gen_op_iwmmxt_set_mup(s);
1986 break;
1987 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1988 rd = (insn >> 12) & 0xf;
1989 wrd = (insn >> 16) & 0xf;
1990 if (rd == 15 || ((insn >> 22) & 3) == 3)
1991 return 1;
1992 gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1993 tmp = tcg_temp_new_i32(tcg_ctx);
1994 switch ((insn >> 22) & 3) {
1995 case 0:
1996 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 7) << 3);
1997 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1998 if (insn & 8) {
1999 tcg_gen_ext8s_i32(tcg_ctx, tmp, tmp);
2000 } else {
2001 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xff);
2002 }
2003 break;
2004 case 1:
2005 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 3) << 4);
2006 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2007 if (insn & 8) {
2008 tcg_gen_ext16s_i32(tcg_ctx, tmp, tmp);
2009 } else {
2010 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff);
2011 }
2012 break;
2013 case 2:
2014 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 1) << 5);
2015 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2016 break;
2017 }
2018 store_reg(s, rd, tmp);
2019 break;
2020 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2021 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2022 return 1;
2023 tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2024 switch ((insn >> 22) & 3) {
2025 case 0:
2026 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 7) << 2) + 0);
2027 break;
2028 case 1:
2029 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 3) << 3) + 4);
2030 break;
2031 case 2:
2032 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 1) << 4) + 12);
2033 break;
2034 }
2035 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 28);
2036 gen_set_nzcv(s, tmp);
2037 tcg_temp_free_i32(tcg_ctx, tmp);
2038 break;
2039 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2040 if (((insn >> 6) & 3) == 3)
2041 return 1;
2042 rd = (insn >> 12) & 0xf;
2043 wrd = (insn >> 16) & 0xf;
2044 tmp = load_reg(s, rd);
2045 switch ((insn >> 6) & 3) {
2046 case 0:
2047 gen_helper_iwmmxt_bcstb(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2048 break;
2049 case 1:
2050 gen_helper_iwmmxt_bcstw(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2051 break;
2052 case 2:
2053 gen_helper_iwmmxt_bcstl(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2054 break;
2055 }
2056 tcg_temp_free_i32(tcg_ctx, tmp);
2057 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2058 gen_op_iwmmxt_set_mup(s);
2059 break;
2060 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2061 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2062 return 1;
2063 tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2064 tmp2 = tcg_temp_new_i32(tcg_ctx);
2065 tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
2066 switch ((insn >> 22) & 3) {
2067 case 0:
2068 for (i = 0; i < 7; i ++) {
2069 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 4);
2070 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2071 }
2072 break;
2073 case 1:
2074 for (i = 0; i < 3; i ++) {
2075 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 8);
2076 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2077 }
2078 break;
2079 case 2:
2080 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
2081 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2082 break;
2083 }
2084 gen_set_nzcv(s, tmp);
2085 tcg_temp_free_i32(tcg_ctx, tmp2);
2086 tcg_temp_free_i32(tcg_ctx, tmp);
2087 break;
2088 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2089 wrd = (insn >> 12) & 0xf;
2090 rd0 = (insn >> 16) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2092 switch ((insn >> 22) & 3) {
2093 case 0:
2094 gen_helper_iwmmxt_addcb(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2095 break;
2096 case 1:
2097 gen_helper_iwmmxt_addcw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2098 break;
2099 case 2:
2100 gen_helper_iwmmxt_addcl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2101 break;
2102 case 3:
2103 return 1;
2104 }
2105 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2106 gen_op_iwmmxt_set_mup(s);
2107 break;
2108 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2109 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2110 return 1;
2111 tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2112 tmp2 = tcg_temp_new_i32(tcg_ctx);
2113 tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
2114 switch ((insn >> 22) & 3) {
2115 case 0:
2116 for (i = 0; i < 7; i ++) {
2117 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 4);
2118 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2119 }
2120 break;
2121 case 1:
2122 for (i = 0; i < 3; i ++) {
2123 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 8);
2124 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2125 }
2126 break;
2127 case 2:
2128 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
2129 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2130 break;
2131 }
2132 gen_set_nzcv(s, tmp);
2133 tcg_temp_free_i32(tcg_ctx, tmp2);
2134 tcg_temp_free_i32(tcg_ctx, tmp);
2135 break;
2136 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2137 rd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2140 return 1;
2141 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2142 tmp = tcg_temp_new_i32(tcg_ctx);
2143 switch ((insn >> 22) & 3) {
2144 case 0:
2145 gen_helper_iwmmxt_msbb(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2146 break;
2147 case 1:
2148 gen_helper_iwmmxt_msbw(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2149 break;
2150 case 2:
2151 gen_helper_iwmmxt_msbl(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2152 break;
2153 }
2154 store_reg(s, rd, tmp);
2155 break;
2156 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2157 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2158 wrd = (insn >> 12) & 0xf;
2159 rd0 = (insn >> 16) & 0xf;
2160 rd1 = (insn >> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2162 switch ((insn >> 22) & 3) {
2163 case 0:
2164 if (insn & (1 << 21))
2165 gen_op_iwmmxt_cmpgtsb_M0_wRn(s, rd1);
2166 else
2167 gen_op_iwmmxt_cmpgtub_M0_wRn(s, rd1);
2168 break;
2169 case 1:
2170 if (insn & (1 << 21))
2171 gen_op_iwmmxt_cmpgtsw_M0_wRn(s, rd1);
2172 else
2173 gen_op_iwmmxt_cmpgtuw_M0_wRn(s, rd1);
2174 break;
2175 case 2:
2176 if (insn & (1 << 21))
2177 gen_op_iwmmxt_cmpgtsl_M0_wRn(s, rd1);
2178 else
2179 gen_op_iwmmxt_cmpgtul_M0_wRn(s, rd1);
2180 break;
2181 case 3:
2182 return 1;
2183 }
2184 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2185 gen_op_iwmmxt_set_mup(s);
2186 gen_op_iwmmxt_set_cup(s);
2187 break;
2188 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2189 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2190 wrd = (insn >> 12) & 0xf;
2191 rd0 = (insn >> 16) & 0xf;
2192 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2193 switch ((insn >> 22) & 3) {
2194 case 0:
2195 if (insn & (1 << 21))
2196 gen_op_iwmmxt_unpacklsb_M0(s);
2197 else
2198 gen_op_iwmmxt_unpacklub_M0(s);
2199 break;
2200 case 1:
2201 if (insn & (1 << 21))
2202 gen_op_iwmmxt_unpacklsw_M0(s);
2203 else
2204 gen_op_iwmmxt_unpackluw_M0(s);
2205 break;
2206 case 2:
2207 if (insn & (1 << 21))
2208 gen_op_iwmmxt_unpacklsl_M0(s);
2209 else
2210 gen_op_iwmmxt_unpacklul_M0(s);
2211 break;
2212 case 3:
2213 return 1;
2214 }
2215 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2216 gen_op_iwmmxt_set_mup(s);
2217 gen_op_iwmmxt_set_cup(s);
2218 break;
2219 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2220 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2221 wrd = (insn >> 12) & 0xf;
2222 rd0 = (insn >> 16) & 0xf;
2223 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2224 switch ((insn >> 22) & 3) {
2225 case 0:
2226 if (insn & (1 << 21))
2227 gen_op_iwmmxt_unpackhsb_M0(s);
2228 else
2229 gen_op_iwmmxt_unpackhub_M0(s);
2230 break;
2231 case 1:
2232 if (insn & (1 << 21))
2233 gen_op_iwmmxt_unpackhsw_M0(s);
2234 else
2235 gen_op_iwmmxt_unpackhuw_M0(s);
2236 break;
2237 case 2:
2238 if (insn & (1 << 21))
2239 gen_op_iwmmxt_unpackhsl_M0(s);
2240 else
2241 gen_op_iwmmxt_unpackhul_M0(s);
2242 break;
2243 case 3:
2244 return 1;
2245 }
2246 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2247 gen_op_iwmmxt_set_mup(s);
2248 gen_op_iwmmxt_set_cup(s);
2249 break;
2250 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2251 case 0x214: case 0x614: case 0xa14: case 0xe14:
2252 if (((insn >> 22) & 3) == 0)
2253 return 1;
2254 wrd = (insn >> 12) & 0xf;
2255 rd0 = (insn >> 16) & 0xf;
2256 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2257 tmp = tcg_temp_new_i32(tcg_ctx);
2258 if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2259 tcg_temp_free_i32(tcg_ctx, tmp);
2260 return 1;
2261 }
2262 switch ((insn >> 22) & 3) {
2263 case 1:
2264 gen_helper_iwmmxt_srlw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2265 break;
2266 case 2:
2267 gen_helper_iwmmxt_srll(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2268 break;
2269 case 3:
2270 gen_helper_iwmmxt_srlq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2271 break;
2272 }
2273 tcg_temp_free_i32(tcg_ctx, tmp);
2274 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2275 gen_op_iwmmxt_set_mup(s);
2276 gen_op_iwmmxt_set_cup(s);
2277 break;
2278 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2279 case 0x014: case 0x414: case 0x814: case 0xc14:
2280 if (((insn >> 22) & 3) == 0)
2281 return 1;
2282 wrd = (insn >> 12) & 0xf;
2283 rd0 = (insn >> 16) & 0xf;
2284 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2285 tmp = tcg_temp_new_i32(tcg_ctx);
2286 if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2287 tcg_temp_free_i32(tcg_ctx, tmp);
2288 return 1;
2289 }
2290 switch ((insn >> 22) & 3) {
2291 case 1:
2292 gen_helper_iwmmxt_sraw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2293 break;
2294 case 2:
2295 gen_helper_iwmmxt_sral(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2296 break;
2297 case 3:
2298 gen_helper_iwmmxt_sraq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2299 break;
2300 }
2301 tcg_temp_free_i32(tcg_ctx, tmp);
2302 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2303 gen_op_iwmmxt_set_mup(s);
2304 gen_op_iwmmxt_set_cup(s);
2305 break;
2306 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2307 case 0x114: case 0x514: case 0x914: case 0xd14:
2308 if (((insn >> 22) & 3) == 0)
2309 return 1;
2310 wrd = (insn >> 12) & 0xf;
2311 rd0 = (insn >> 16) & 0xf;
2312 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2313 tmp = tcg_temp_new_i32(tcg_ctx);
2314 if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2315 tcg_temp_free_i32(tcg_ctx, tmp);
2316 return 1;
2317 }
2318 switch ((insn >> 22) & 3) {
2319 case 1:
2320 gen_helper_iwmmxt_sllw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2321 break;
2322 case 2:
2323 gen_helper_iwmmxt_slll(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2324 break;
2325 case 3:
2326 gen_helper_iwmmxt_sllq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2327 break;
2328 }
2329 tcg_temp_free_i32(tcg_ctx, tmp);
2330 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2331 gen_op_iwmmxt_set_mup(s);
2332 gen_op_iwmmxt_set_cup(s);
2333 break;
2334 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2335 case 0x314: case 0x714: case 0xb14: case 0xf14:
2336 if (((insn >> 22) & 3) == 0)
2337 return 1;
2338 wrd = (insn >> 12) & 0xf;
2339 rd0 = (insn >> 16) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2341 tmp = tcg_temp_new_i32(tcg_ctx);
2342 switch ((insn >> 22) & 3) {
2343 case 1:
2344 if (gen_iwmmxt_shift(s, insn, 0xf, tmp)) {
2345 tcg_temp_free_i32(tcg_ctx, tmp);
2346 return 1;
2347 }
2348 gen_helper_iwmmxt_rorw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2349 break;
2350 case 2:
2351 if (gen_iwmmxt_shift(s, insn, 0x1f, tmp)) {
2352 tcg_temp_free_i32(tcg_ctx, tmp);
2353 return 1;
2354 }
2355 gen_helper_iwmmxt_rorl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2356 break;
2357 case 3:
2358 if (gen_iwmmxt_shift(s, insn, 0x3f, tmp)) {
2359 tcg_temp_free_i32(tcg_ctx, tmp);
2360 return 1;
2361 }
2362 gen_helper_iwmmxt_rorq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2363 break;
2364 }
2365 tcg_temp_free_i32(tcg_ctx, tmp);
2366 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2367 gen_op_iwmmxt_set_mup(s);
2368 gen_op_iwmmxt_set_cup(s);
2369 break;
2370 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2371 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2372 wrd = (insn >> 12) & 0xf;
2373 rd0 = (insn >> 16) & 0xf;
2374 rd1 = (insn >> 0) & 0xf;
2375 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2376 switch ((insn >> 22) & 3) {
2377 case 0:
2378 if (insn & (1 << 21))
2379 gen_op_iwmmxt_minsb_M0_wRn(s, rd1);
2380 else
2381 gen_op_iwmmxt_minub_M0_wRn(s, rd1);
2382 break;
2383 case 1:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_minsw_M0_wRn(s, rd1);
2386 else
2387 gen_op_iwmmxt_minuw_M0_wRn(s, rd1);
2388 break;
2389 case 2:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_minsl_M0_wRn(s, rd1);
2392 else
2393 gen_op_iwmmxt_minul_M0_wRn(s, rd1);
2394 break;
2395 case 3:
2396 return 1;
2397 }
2398 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2399 gen_op_iwmmxt_set_mup(s);
2400 break;
2401 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2402 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2403 wrd = (insn >> 12) & 0xf;
2404 rd0 = (insn >> 16) & 0xf;
2405 rd1 = (insn >> 0) & 0xf;
2406 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2407 switch ((insn >> 22) & 3) {
2408 case 0:
2409 if (insn & (1 << 21))
2410 gen_op_iwmmxt_maxsb_M0_wRn(s, rd1);
2411 else
2412 gen_op_iwmmxt_maxub_M0_wRn(s, rd1);
2413 break;
2414 case 1:
2415 if (insn & (1 << 21))
2416 gen_op_iwmmxt_maxsw_M0_wRn(s, rd1);
2417 else
2418 gen_op_iwmmxt_maxuw_M0_wRn(s, rd1);
2419 break;
2420 case 2:
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_maxsl_M0_wRn(s, rd1);
2423 else
2424 gen_op_iwmmxt_maxul_M0_wRn(s, rd1);
2425 break;
2426 case 3:
2427 return 1;
2428 }
2429 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2430 gen_op_iwmmxt_set_mup(s);
2431 break;
2432 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2433 case 0x402: case 0x502: case 0x602: case 0x702:
2434 wrd = (insn >> 12) & 0xf;
2435 rd0 = (insn >> 16) & 0xf;
2436 rd1 = (insn >> 0) & 0xf;
2437 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2438 tmp = tcg_const_i32(tcg_ctx, (insn >> 20) & 3);
2439 iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rd1);
2440 gen_helper_iwmmxt_align(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1, tmp);
2441 tcg_temp_free_i32(tcg_ctx, tmp);
2442 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2443 gen_op_iwmmxt_set_mup(s);
2444 break;
2445 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2446 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2447 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2448 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2449 wrd = (insn >> 12) & 0xf;
2450 rd0 = (insn >> 16) & 0xf;
2451 rd1 = (insn >> 0) & 0xf;
2452 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2453 switch ((insn >> 20) & 0xf) {
2454 case 0x0:
2455 gen_op_iwmmxt_subnb_M0_wRn(s, rd1);
2456 break;
2457 case 0x1:
2458 gen_op_iwmmxt_subub_M0_wRn(s, rd1);
2459 break;
2460 case 0x3:
2461 gen_op_iwmmxt_subsb_M0_wRn(s, rd1);
2462 break;
2463 case 0x4:
2464 gen_op_iwmmxt_subnw_M0_wRn(s, rd1);
2465 break;
2466 case 0x5:
2467 gen_op_iwmmxt_subuw_M0_wRn(s, rd1);
2468 break;
2469 case 0x7:
2470 gen_op_iwmmxt_subsw_M0_wRn(s, rd1);
2471 break;
2472 case 0x8:
2473 gen_op_iwmmxt_subnl_M0_wRn(s, rd1);
2474 break;
2475 case 0x9:
2476 gen_op_iwmmxt_subul_M0_wRn(s, rd1);
2477 break;
2478 case 0xb:
2479 gen_op_iwmmxt_subsl_M0_wRn(s, rd1);
2480 break;
2481 default:
2482 return 1;
2483 }
2484 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2485 gen_op_iwmmxt_set_mup(s);
2486 gen_op_iwmmxt_set_cup(s);
2487 break;
2488 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2489 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2490 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2491 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2492 wrd = (insn >> 12) & 0xf;
2493 rd0 = (insn >> 16) & 0xf;
2494 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2495 tmp = tcg_const_i32(tcg_ctx, ((insn >> 16) & 0xf0) | (insn & 0x0f));
2496 gen_helper_iwmmxt_shufh(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2497 tcg_temp_free_i32(tcg_ctx, tmp);
2498 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2499 gen_op_iwmmxt_set_mup(s);
2500 gen_op_iwmmxt_set_cup(s);
2501 break;
2502 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2503 case 0x418: case 0x518: case 0x618: case 0x718:
2504 case 0x818: case 0x918: case 0xa18: case 0xb18:
2505 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2506 wrd = (insn >> 12) & 0xf;
2507 rd0 = (insn >> 16) & 0xf;
2508 rd1 = (insn >> 0) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2510 switch ((insn >> 20) & 0xf) {
2511 case 0x0:
2512 gen_op_iwmmxt_addnb_M0_wRn(s, rd1);
2513 break;
2514 case 0x1:
2515 gen_op_iwmmxt_addub_M0_wRn(s, rd1);
2516 break;
2517 case 0x3:
2518 gen_op_iwmmxt_addsb_M0_wRn(s, rd1);
2519 break;
2520 case 0x4:
2521 gen_op_iwmmxt_addnw_M0_wRn(s, rd1);
2522 break;
2523 case 0x5:
2524 gen_op_iwmmxt_adduw_M0_wRn(s, rd1);
2525 break;
2526 case 0x7:
2527 gen_op_iwmmxt_addsw_M0_wRn(s, rd1);
2528 break;
2529 case 0x8:
2530 gen_op_iwmmxt_addnl_M0_wRn(s, rd1);
2531 break;
2532 case 0x9:
2533 gen_op_iwmmxt_addul_M0_wRn(s, rd1);
2534 break;
2535 case 0xb:
2536 gen_op_iwmmxt_addsl_M0_wRn(s, rd1);
2537 break;
2538 default:
2539 return 1;
2540 }
2541 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2542 gen_op_iwmmxt_set_mup(s);
2543 gen_op_iwmmxt_set_cup(s);
2544 break;
2545 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2546 case 0x408: case 0x508: case 0x608: case 0x708:
2547 case 0x808: case 0x908: case 0xa08: case 0xb08:
2548 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2549 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2550 return 1;
2551 wrd = (insn >> 12) & 0xf;
2552 rd0 = (insn >> 16) & 0xf;
2553 rd1 = (insn >> 0) & 0xf;
2554 gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2555 switch ((insn >> 22) & 3) {
2556 case 1:
2557 if (insn & (1 << 21))
2558 gen_op_iwmmxt_packsw_M0_wRn(s, rd1);
2559 else
2560 gen_op_iwmmxt_packuw_M0_wRn(s, rd1);
2561 break;
2562 case 2:
2563 if (insn & (1 << 21))
2564 gen_op_iwmmxt_packsl_M0_wRn(s, rd1);
2565 else
2566 gen_op_iwmmxt_packul_M0_wRn(s, rd1);
2567 break;
2568 case 3:
2569 if (insn & (1 << 21))
2570 gen_op_iwmmxt_packsq_M0_wRn(s, rd1);
2571 else
2572 gen_op_iwmmxt_packuq_M0_wRn(s, rd1);
2573 break;
2574 }
2575 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2576 gen_op_iwmmxt_set_mup(s);
2577 gen_op_iwmmxt_set_cup(s);
2578 break;
2579 case 0x201: case 0x203: case 0x205: case 0x207:
2580 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2581 case 0x211: case 0x213: case 0x215: case 0x217:
2582 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2583 wrd = (insn >> 5) & 0xf;
2584 rd0 = (insn >> 12) & 0xf;
2585 rd1 = (insn >> 0) & 0xf;
2586 if (rd0 == 0xf || rd1 == 0xf)
2587 return 1;
2588 gen_op_iwmmxt_movq_M0_wRn(s, wrd);
2589 tmp = load_reg(s, rd0);
2590 tmp2 = load_reg(s, rd1);
2591 switch ((insn >> 16) & 0xf) {
2592 case 0x0: /* TMIA */
2593 gen_helper_iwmmxt_muladdsl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2594 break;
2595 case 0x8: /* TMIAPH */
2596 gen_helper_iwmmxt_muladdsw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2597 break;
2598 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2599 if (insn & (1 << 16))
2600 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
2601 if (insn & (1 << 17))
2602 tcg_gen_shri_i32(tcg_ctx, tmp2, tmp2, 16);
2603 gen_helper_iwmmxt_muladdswl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2604 break;
2605 default:
2606 tcg_temp_free_i32(tcg_ctx, tmp2);
2607 tcg_temp_free_i32(tcg_ctx, tmp);
2608 return 1;
2609 }
2610 tcg_temp_free_i32(tcg_ctx, tmp2);
2611 tcg_temp_free_i32(tcg_ctx, tmp);
2612 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2613 gen_op_iwmmxt_set_mup(s);
2614 break;
2615 default:
2616 return 1;
2617 }
2618
2619 return 0;
2620 }
2621
2622 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2623 (ie. an undefined instruction). */
disas_dsp_insn(DisasContext * s,uint32_t insn)2624 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2625 {
2626 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2627 int acc, rd0, rd1, rdhi, rdlo;
2628 TCGv_i32 tmp, tmp2;
2629
2630 if ((insn & 0x0ff00f10) == 0x0e200010) {
2631 /* Multiply with Internal Accumulate Format */
2632 rd0 = (insn >> 12) & 0xf;
2633 rd1 = insn & 0xf;
2634 acc = (insn >> 5) & 7;
2635
2636 if (acc != 0)
2637 return 1;
2638
2639 tmp = load_reg(s, rd0);
2640 tmp2 = load_reg(s, rd1);
2641 switch ((insn >> 16) & 0xf) {
2642 case 0x0: /* MIA */
2643 gen_helper_iwmmxt_muladdsl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2644 break;
2645 case 0x8: /* MIAPH */
2646 gen_helper_iwmmxt_muladdsw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2647 break;
2648 case 0xc: /* MIABB */
2649 case 0xd: /* MIABT */
2650 case 0xe: /* MIATB */
2651 case 0xf: /* MIATT */
2652 if (insn & (1 << 16))
2653 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
2654 if (insn & (1 << 17))
2655 tcg_gen_shri_i32(tcg_ctx, tmp2, tmp2, 16);
2656 gen_helper_iwmmxt_muladdswl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2657 break;
2658 default:
2659 return 1;
2660 }
2661 tcg_temp_free_i32(tcg_ctx, tmp2);
2662 tcg_temp_free_i32(tcg_ctx, tmp);
2663
2664 gen_op_iwmmxt_movq_wRn_M0(s, acc);
2665 return 0;
2666 }
2667
2668 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2669 /* Internal Accumulator Access Format */
2670 rdhi = (insn >> 16) & 0xf;
2671 rdlo = (insn >> 12) & 0xf;
2672 acc = insn & 7;
2673
2674 if (acc != 0)
2675 return 1;
2676
2677 if (insn & ARM_CP_RW_BIT) { /* MRA */
2678 iwmmxt_load_reg(s, tcg_ctx->cpu_V0, acc);
2679 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_V0);
2680 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
2681 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_V0);
2682 tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_R[rdhi], (1 << (40 - 32)) - 1);
2683 } else { /* MAR */
2684 tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_R[rdhi]);
2685 iwmmxt_store_reg(s, tcg_ctx->cpu_V0, acc);
2686 }
2687 return 0;
2688 }
2689
2690 return 1;
2691 }
2692
2693 // this causes "warning C4293: shift count negative or too big, undefined behavior"
2694 // on msvc, so is replaced with separate versions for the shift to perform.
2695 //#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2696 #if 0
2697 #define VFP_SREG(insn, bigbit, smallbit) \
2698 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2699 #endif
2700
2701 #define VFP_REG_SHR_NEG(insn, n) ((insn) << -(n))
2702 #define VFP_SREG_NEG(insn, bigbit, smallbit) \
2703 ((VFP_REG_SHR_NEG(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2704
2705 #define VFP_REG_SHR_POS(x, n) ((insn) >> (n))
2706 #define VFP_SREG_POS(insn, bigbit, smallbit) \
2707 ((VFP_REG_SHR_POS(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2708
2709 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2710 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2711 reg = (((insn) >> (bigbit)) & 0x0f) \
2712 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2713 } else { \
2714 if (insn & (1 << (smallbit))) \
2715 return 1; \
2716 reg = ((insn) >> (bigbit)) & 0x0f; \
2717 }} while (0)
2718
2719 #define VFP_SREG_D(insn) VFP_SREG_POS(insn, 12, 22)
2720 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2721 #define VFP_SREG_N(insn) VFP_SREG_POS(insn, 16, 7)
2722 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2723 #define VFP_SREG_M(insn) VFP_SREG_NEG(insn, 0, 5)
2724 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2725
2726 /* Move between integer and VFP cores. */
gen_vfp_mrs(DisasContext * s)2727 static TCGv_i32 gen_vfp_mrs(DisasContext *s)
2728 {
2729 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2730 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2731 tcg_gen_mov_i32(tcg_ctx, tmp, tcg_ctx->cpu_F0s);
2732 return tmp;
2733 }
2734
gen_vfp_msr(DisasContext * s,TCGv_i32 tmp)2735 static void gen_vfp_msr(DisasContext *s, TCGv_i32 tmp)
2736 {
2737 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2738 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_F0s, tmp);
2739 tcg_temp_free_i32(tcg_ctx, tmp);
2740 }
2741
gen_neon_dup_u8(DisasContext * s,TCGv_i32 var,int shift)2742 static void gen_neon_dup_u8(DisasContext *s, TCGv_i32 var, int shift)
2743 {
2744 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2745 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2746 if (shift)
2747 tcg_gen_shri_i32(tcg_ctx, var, var, shift);
2748 tcg_gen_ext8u_i32(tcg_ctx, var, var);
2749 tcg_gen_shli_i32(tcg_ctx, tmp, var, 8);
2750 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2751 tcg_gen_shli_i32(tcg_ctx, tmp, var, 16);
2752 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2753 tcg_temp_free_i32(tcg_ctx, tmp);
2754 }
2755
gen_neon_dup_low16(DisasContext * s,TCGv_i32 var)2756 static void gen_neon_dup_low16(DisasContext *s, TCGv_i32 var)
2757 {
2758 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2759 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2760 tcg_gen_ext16u_i32(tcg_ctx, var, var);
2761 tcg_gen_shli_i32(tcg_ctx, tmp, var, 16);
2762 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2763 tcg_temp_free_i32(tcg_ctx, tmp);
2764 }
2765
gen_neon_dup_high16(DisasContext * s,TCGv_i32 var)2766 static void gen_neon_dup_high16(DisasContext *s, TCGv_i32 var)
2767 {
2768 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2769 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2770 tcg_gen_andi_i32(tcg_ctx, var, var, 0xffff0000);
2771 tcg_gen_shri_i32(tcg_ctx, tmp, var, 16);
2772 tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2773 tcg_temp_free_i32(tcg_ctx, tmp);
2774 }
2775
gen_load_and_replicate(DisasContext * s,TCGv_i32 addr,int size)2776 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2777 {
2778 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2779 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2780 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2781 switch (size) {
2782 case 0:
2783 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2784 gen_neon_dup_u8(s, tmp, 0);
2785 break;
2786 case 1:
2787 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2788 gen_neon_dup_low16(s, tmp);
2789 break;
2790 case 2:
2791 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2792 break;
2793 default: /* Avoid compiler warnings. */
2794 abort();
2795 }
2796 return tmp;
2797 }
2798
handle_vsel(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rn,uint32_t rm,uint32_t dp)2799 static int handle_vsel(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2800 uint32_t dp)
2801 {
2802 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2803 uint32_t cc = extract32(insn, 20, 2);
2804
2805 if (dp) {
2806 TCGv_i64 frn, frm, dest;
2807 TCGv_i64 tmp, zero, zf, nf, vf;
2808
2809 zero = tcg_const_i64(tcg_ctx, 0);
2810
2811 frn = tcg_temp_new_i64(tcg_ctx);
2812 frm = tcg_temp_new_i64(tcg_ctx);
2813 dest = tcg_temp_new_i64(tcg_ctx);
2814
2815 zf = tcg_temp_new_i64(tcg_ctx);
2816 nf = tcg_temp_new_i64(tcg_ctx);
2817 vf = tcg_temp_new_i64(tcg_ctx);
2818
2819 tcg_gen_extu_i32_i64(tcg_ctx, zf, tcg_ctx->cpu_ZF);
2820 tcg_gen_ext_i32_i64(tcg_ctx, nf, tcg_ctx->cpu_NF);
2821 tcg_gen_ext_i32_i64(tcg_ctx, vf, tcg_ctx->cpu_VF);
2822
2823 tcg_gen_ld_f64(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2824 tcg_gen_ld_f64(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2825 switch (cc) {
2826 case 0: /* eq: Z */
2827 tcg_gen_movcond_i64(tcg_ctx, TCG_COND_EQ, dest, zf, zero,
2828 frn, frm);
2829 break;
2830 case 1: /* vs: V */
2831 tcg_gen_movcond_i64(tcg_ctx, TCG_COND_LT, dest, vf, zero,
2832 frn, frm);
2833 break;
2834 case 2: /* ge: N == V -> N ^ V == 0 */
2835 tmp = tcg_temp_new_i64(tcg_ctx);
2836 tcg_gen_xor_i64(tcg_ctx, tmp, vf, nf);
2837 tcg_gen_movcond_i64(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2838 frn, frm);
2839 tcg_temp_free_i64(tcg_ctx, tmp);
2840 break;
2841 case 3: /* gt: !Z && N == V */
2842 tcg_gen_movcond_i64(tcg_ctx, TCG_COND_NE, dest, zf, zero,
2843 frn, frm);
2844 tmp = tcg_temp_new_i64(tcg_ctx);
2845 tcg_gen_xor_i64(tcg_ctx, tmp, vf, nf);
2846 tcg_gen_movcond_i64(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2847 dest, frm);
2848 tcg_temp_free_i64(tcg_ctx, tmp);
2849 break;
2850 }
2851 tcg_gen_st_f64(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2852 tcg_temp_free_i64(tcg_ctx, frn);
2853 tcg_temp_free_i64(tcg_ctx, frm);
2854 tcg_temp_free_i64(tcg_ctx, dest);
2855
2856 tcg_temp_free_i64(tcg_ctx, zf);
2857 tcg_temp_free_i64(tcg_ctx, nf);
2858 tcg_temp_free_i64(tcg_ctx, vf);
2859
2860 tcg_temp_free_i64(tcg_ctx, zero);
2861 } else {
2862 TCGv_i32 frn, frm, dest;
2863 TCGv_i32 tmp, zero;
2864
2865 zero = tcg_const_i32(tcg_ctx, 0);
2866
2867 frn = tcg_temp_new_i32(tcg_ctx);
2868 frm = tcg_temp_new_i32(tcg_ctx);
2869 dest = tcg_temp_new_i32(tcg_ctx);
2870 tcg_gen_ld_f32(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2871 tcg_gen_ld_f32(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2872 switch (cc) {
2873 case 0: /* eq: Z */
2874 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_EQ, dest, tcg_ctx->cpu_ZF, zero,
2875 frn, frm);
2876 break;
2877 case 1: /* vs: V */
2878 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_LT, dest, tcg_ctx->cpu_VF, zero,
2879 frn, frm);
2880 break;
2881 case 2: /* ge: N == V -> N ^ V == 0 */
2882 tmp = tcg_temp_new_i32(tcg_ctx);
2883 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
2884 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2885 frn, frm);
2886 tcg_temp_free_i32(tcg_ctx, tmp);
2887 break;
2888 case 3: /* gt: !Z && N == V */
2889 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_NE, dest, tcg_ctx->cpu_ZF, zero,
2890 frn, frm);
2891 tmp = tcg_temp_new_i32(tcg_ctx);
2892 tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
2893 tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2894 dest, frm);
2895 tcg_temp_free_i32(tcg_ctx, tmp);
2896 break;
2897 }
2898 tcg_gen_st_f32(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2899 tcg_temp_free_i32(tcg_ctx, frn);
2900 tcg_temp_free_i32(tcg_ctx, frm);
2901 tcg_temp_free_i32(tcg_ctx, dest);
2902
2903 tcg_temp_free_i32(tcg_ctx, zero);
2904 }
2905
2906 return 0;
2907 }
2908
handle_vminmaxnm(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rn,uint32_t rm,uint32_t dp)2909 static int handle_vminmaxnm(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rn,
2910 uint32_t rm, uint32_t dp)
2911 {
2912 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2913 uint32_t vmin = extract32(insn, 6, 1);
2914 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
2915
2916 if (dp) {
2917 TCGv_i64 frn, frm, dest;
2918
2919 frn = tcg_temp_new_i64(tcg_ctx);
2920 frm = tcg_temp_new_i64(tcg_ctx);
2921 dest = tcg_temp_new_i64(tcg_ctx);
2922
2923 tcg_gen_ld_f64(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2924 tcg_gen_ld_f64(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2925 if (vmin) {
2926 gen_helper_vfp_minnumd(tcg_ctx, dest, frn, frm, fpst);
2927 } else {
2928 gen_helper_vfp_maxnumd(tcg_ctx, dest, frn, frm, fpst);
2929 }
2930 tcg_gen_st_f64(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2931 tcg_temp_free_i64(tcg_ctx, frn);
2932 tcg_temp_free_i64(tcg_ctx, frm);
2933 tcg_temp_free_i64(tcg_ctx, dest);
2934 } else {
2935 TCGv_i32 frn, frm, dest;
2936
2937 frn = tcg_temp_new_i32(tcg_ctx);
2938 frm = tcg_temp_new_i32(tcg_ctx);
2939 dest = tcg_temp_new_i32(tcg_ctx);
2940
2941 tcg_gen_ld_f32(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2942 tcg_gen_ld_f32(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2943 if (vmin) {
2944 gen_helper_vfp_minnums(tcg_ctx, dest, frn, frm, fpst);
2945 } else {
2946 gen_helper_vfp_maxnums(tcg_ctx, dest, frn, frm, fpst);
2947 }
2948 tcg_gen_st_f32(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2949 tcg_temp_free_i32(tcg_ctx, frn);
2950 tcg_temp_free_i32(tcg_ctx, frm);
2951 tcg_temp_free_i32(tcg_ctx, dest);
2952 }
2953
2954 tcg_temp_free_ptr(tcg_ctx, fpst);
2955 return 0;
2956 }
2957
handle_vrint(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rm,uint32_t dp,int rounding)2958 static int handle_vrint(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2959 int rounding)
2960 {
2961 TCGContext *tcg_ctx = s->uc->tcg_ctx;
2962 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
2963 TCGv_i32 tcg_rmode;
2964
2965 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rounding));
2966 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
2967
2968 if (dp) {
2969 TCGv_i64 tcg_op;
2970 TCGv_i64 tcg_res;
2971 tcg_op = tcg_temp_new_i64(tcg_ctx);
2972 tcg_res = tcg_temp_new_i64(tcg_ctx);
2973 tcg_gen_ld_f64(tcg_ctx, tcg_op, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2974 gen_helper_rintd(tcg_ctx, tcg_res, tcg_op, fpst);
2975 tcg_gen_st_f64(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2976 tcg_temp_free_i64(tcg_ctx, tcg_op);
2977 tcg_temp_free_i64(tcg_ctx, tcg_res);
2978 } else {
2979 TCGv_i32 tcg_op;
2980 TCGv_i32 tcg_res;
2981 tcg_op = tcg_temp_new_i32(tcg_ctx);
2982 tcg_res = tcg_temp_new_i32(tcg_ctx);
2983 tcg_gen_ld_f32(tcg_ctx, tcg_op, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2984 gen_helper_rints(tcg_ctx, tcg_res, tcg_op, fpst);
2985 tcg_gen_st_f32(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2986 tcg_temp_free_i32(tcg_ctx, tcg_op);
2987 tcg_temp_free_i32(tcg_ctx, tcg_res);
2988 }
2989
2990 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
2991 tcg_temp_free_i32(tcg_ctx, tcg_rmode);
2992
2993 tcg_temp_free_ptr(tcg_ctx, fpst);
2994 return 0;
2995 }
2996
handle_vcvt(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rm,uint32_t dp,int rounding)2997 static int handle_vcvt(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2998 int rounding)
2999 {
3000 TCGContext *tcg_ctx = s->uc->tcg_ctx;
3001 bool is_signed = extract32(insn, 7, 1);
3002 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3003 TCGv_i32 tcg_rmode, tcg_shift;
3004
3005 tcg_shift = tcg_const_i32(tcg_ctx, 0);
3006
3007 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rounding));
3008 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3009
3010 if (dp) {
3011 TCGv_i64 tcg_double, tcg_res;
3012 TCGv_i32 tcg_tmp;
3013 /* Rd is encoded as a single precision register even when the source
3014 * is double precision.
3015 */
3016 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3017 tcg_double = tcg_temp_new_i64(tcg_ctx);
3018 tcg_res = tcg_temp_new_i64(tcg_ctx);
3019 tcg_tmp = tcg_temp_new_i32(tcg_ctx);
3020 tcg_gen_ld_f64(tcg_ctx, tcg_double, tcg_ctx->cpu_env, vfp_reg_offset(1, rm));
3021 if (is_signed) {
3022 gen_helper_vfp_tosld(tcg_ctx, tcg_res, tcg_double, tcg_shift, fpst);
3023 } else {
3024 gen_helper_vfp_tould(tcg_ctx, tcg_res, tcg_double, tcg_shift, fpst);
3025 }
3026 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_tmp, tcg_res);
3027 tcg_gen_st_f32(tcg_ctx, tcg_tmp, tcg_ctx->cpu_env, vfp_reg_offset(0, rd));
3028 tcg_temp_free_i32(tcg_ctx, tcg_tmp);
3029 tcg_temp_free_i64(tcg_ctx, tcg_res);
3030 tcg_temp_free_i64(tcg_ctx, tcg_double);
3031 } else {
3032 TCGv_i32 tcg_single, tcg_res;
3033 tcg_single = tcg_temp_new_i32(tcg_ctx);
3034 tcg_res = tcg_temp_new_i32(tcg_ctx);
3035 tcg_gen_ld_f32(tcg_ctx, tcg_single, tcg_ctx->cpu_env, vfp_reg_offset(0, rm));
3036 if (is_signed) {
3037 gen_helper_vfp_tosls(tcg_ctx, tcg_res, tcg_single, tcg_shift, fpst);
3038 } else {
3039 gen_helper_vfp_touls(tcg_ctx, tcg_res, tcg_single, tcg_shift, fpst);
3040 }
3041 tcg_gen_st_f32(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(0, rd));
3042 tcg_temp_free_i32(tcg_ctx, tcg_res);
3043 tcg_temp_free_i32(tcg_ctx, tcg_single);
3044 }
3045
3046 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3047 tcg_temp_free_i32(tcg_ctx, tcg_rmode);
3048
3049 tcg_temp_free_i32(tcg_ctx, tcg_shift);
3050
3051 tcg_temp_free_ptr(tcg_ctx, fpst);
3052
3053 return 0;
3054 }
3055
3056 /* Table for converting the most common AArch32 encoding of
3057 * rounding mode to arm_fprounding order (which matches the
3058 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3059 */
3060 static const uint8_t fp_decode_rm[] = {
3061 FPROUNDING_TIEAWAY,
3062 FPROUNDING_TIEEVEN,
3063 FPROUNDING_POSINF,
3064 FPROUNDING_NEGINF,
3065 };
3066
disas_vfp_v8_insn(DisasContext * s,uint32_t insn)3067 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3068 {
3069 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3070
3071 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3072 return 1;
3073 }
3074
3075 if (dp) {
3076 VFP_DREG_D(rd, insn);
3077 VFP_DREG_N(rn, insn);
3078 VFP_DREG_M(rm, insn);
3079 } else {
3080 rd = VFP_SREG_D(insn);
3081 rn = VFP_SREG_N(insn);
3082 rm = VFP_SREG_M(insn);
3083 }
3084
3085 if ((insn & 0x0f800e50) == 0x0e000a00) {
3086 return handle_vsel(s, insn, rd, rn, rm, dp);
3087 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3088 return handle_vminmaxnm(s, insn, rd, rn, rm, dp);
3089 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3090 /* VRINTA, VRINTN, VRINTP, VRINTM */
3091 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3092 return handle_vrint(s, insn, rd, rm, dp, rounding);
3093 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3094 /* VCVTA, VCVTN, VCVTP, VCVTM */
3095 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3096 return handle_vcvt(s, insn, rd, rm, dp, rounding);
3097 }
3098 return 1;
3099 }
3100
3101 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3102 (ie. an undefined instruction). */
disas_vfp_insn(DisasContext * s,uint32_t insn)3103 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3104 {
3105 TCGContext *tcg_ctx = s->uc->tcg_ctx;
3106 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3107 int dp, veclen;
3108 TCGv_i32 addr;
3109 TCGv_i32 tmp;
3110 TCGv_i32 tmp2;
3111
3112 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3113 return 1;
3114 }
3115
3116 /* FIXME: this access check should not take precedence over UNDEF
3117 * for invalid encodings; we will generate incorrect syndrome information
3118 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3119 */
3120 if (!s->cpacr_fpen) {
3121 gen_exception_insn(s, 4, EXCP_UDEF,
3122 syn_fp_access_trap(1, 0xe, s->thumb));
3123 return 0;
3124 }
3125
3126 if (!s->vfp_enabled) {
3127 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3128 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3129 return 1;
3130 rn = (insn >> 16) & 0xf;
3131 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3132 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3133 return 1;
3134 }
3135 }
3136
3137 if (extract32(insn, 28, 4) == 0xf) {
3138 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3139 * only used in v8 and above.
3140 */
3141 return disas_vfp_v8_insn(s, insn);
3142 }
3143
3144 dp = ((insn & 0xf00) == 0xb00);
3145 switch ((insn >> 24) & 0xf) {
3146 case 0xe:
3147 if (insn & (1 << 4)) {
3148 /* single register transfer */
3149 rd = (insn >> 12) & 0xf;
3150 if (dp) {
3151 int size;
3152 int pass;
3153
3154 VFP_DREG_N(rn, insn);
3155 if (insn & 0xf)
3156 return 1;
3157 if (insn & 0x00c00060
3158 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3159 return 1;
3160 }
3161
3162 pass = (insn >> 21) & 1;
3163 if (insn & (1 << 22)) {
3164 size = 0;
3165 offset = ((insn >> 5) & 3) * 8;
3166 } else if (insn & (1 << 5)) {
3167 size = 1;
3168 offset = (insn & (1 << 6)) ? 16 : 0;
3169 } else {
3170 size = 2;
3171 offset = 0;
3172 }
3173 if (insn & ARM_CP_RW_BIT) {
3174 /* vfp->arm */
3175 tmp = neon_load_reg(tcg_ctx, rn, pass);
3176 switch (size) {
3177 case 0:
3178 if (offset)
3179 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, offset);
3180 if (insn & (1 << 23))
3181 gen_uxtb(tmp);
3182 else
3183 gen_sxtb(tmp);
3184 break;
3185 case 1:
3186 if (insn & (1 << 23)) {
3187 if (offset) {
3188 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
3189 } else {
3190 gen_uxth(tmp);
3191 }
3192 } else {
3193 if (offset) {
3194 tcg_gen_sari_i32(tcg_ctx, tmp, tmp, 16);
3195 } else {
3196 gen_sxth(tmp);
3197 }
3198 }
3199 break;
3200 case 2:
3201 break;
3202 }
3203 store_reg(s, rd, tmp);
3204 } else {
3205 /* arm->vfp */
3206 tmp = load_reg(s, rd);
3207 if (insn & (1 << 23)) {
3208 /* VDUP */
3209 if (size == 0) {
3210 gen_neon_dup_u8(s, tmp, 0);
3211 } else if (size == 1) {
3212 gen_neon_dup_low16(s, tmp);
3213 }
3214 for (n = 0; n <= pass * 2; n++) {
3215 tmp2 = tcg_temp_new_i32(tcg_ctx);
3216 tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
3217 neon_store_reg(tcg_ctx, rn, n, tmp2);
3218 }
3219 neon_store_reg(tcg_ctx, rn, n, tmp);
3220 } else {
3221 /* VMOV */
3222 switch (size) {
3223 case 0:
3224 tmp2 = neon_load_reg(tcg_ctx, rn, pass);
3225 tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, offset, 8);
3226 tcg_temp_free_i32(tcg_ctx, tmp2);
3227 break;
3228 case 1:
3229 tmp2 = neon_load_reg(tcg_ctx, rn, pass);
3230 tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, offset, 16);
3231 tcg_temp_free_i32(tcg_ctx, tmp2);
3232 break;
3233 case 2:
3234 break;
3235 }
3236 neon_store_reg(tcg_ctx, rn, pass, tmp);
3237 }
3238 }
3239 } else { /* !dp */
3240 if ((insn & 0x6f) != 0x00)
3241 return 1;
3242 rn = VFP_SREG_N(insn);
3243 if (insn & ARM_CP_RW_BIT) {
3244 /* vfp->arm */
3245 if (insn & (1 << 21)) {
3246 /* system register */
3247 rn >>= 1;
3248
3249 switch (rn) {
3250 case ARM_VFP_FPSID:
3251 /* VFP2 allows access to FSID from userspace.
3252 VFP3 restricts all id registers to privileged
3253 accesses. */
3254 if (IS_USER(s)
3255 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3256 return 1;
3257 }
3258 tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3259 break;
3260 case ARM_VFP_FPEXC:
3261 if (IS_USER(s))
3262 return 1;
3263 tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3264 break;
3265 case ARM_VFP_FPINST:
3266 case ARM_VFP_FPINST2:
3267 /* Not present in VFP3. */
3268 if (IS_USER(s)
3269 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3270 return 1;
3271 }
3272 tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3273 break;
3274 case ARM_VFP_FPSCR:
3275 if (rd == 15) {
3276 tmp = load_cpu_field(s->uc, vfp.xregs[ARM_VFP_FPSCR]);
3277 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xf0000000);
3278 } else {
3279 tmp = tcg_temp_new_i32(tcg_ctx);
3280 gen_helper_vfp_get_fpscr(tcg_ctx, tmp, tcg_ctx->cpu_env);
3281 }
3282 break;
3283 case ARM_VFP_MVFR2:
3284 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3285 return 1;
3286 }
3287 /* fall through */
3288 case ARM_VFP_MVFR0:
3289 case ARM_VFP_MVFR1:
3290 if (IS_USER(s)
3291 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3292 return 1;
3293 }
3294 tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3295 break;
3296 default:
3297 return 1;
3298 }
3299 } else {
3300 gen_mov_F0_vreg(s, 0, rn);
3301 tmp = gen_vfp_mrs(s);
3302 }
3303 if (rd == 15) {
3304 /* Set the 4 flag bits in the CPSR. */
3305 gen_set_nzcv(s, tmp);
3306 tcg_temp_free_i32(tcg_ctx, tmp);
3307 } else {
3308 store_reg(s, rd, tmp);
3309 }
3310 } else {
3311 /* arm->vfp */
3312 if (insn & (1 << 21)) {
3313 rn >>= 1;
3314 /* system register */
3315 switch (rn) {
3316 case ARM_VFP_FPSID:
3317 case ARM_VFP_MVFR0:
3318 case ARM_VFP_MVFR1:
3319 /* Writes are ignored. */
3320 break;
3321 case ARM_VFP_FPSCR:
3322 tmp = load_reg(s, rd);
3323 gen_helper_vfp_set_fpscr(tcg_ctx, tcg_ctx->cpu_env, tmp);
3324 tcg_temp_free_i32(tcg_ctx, tmp);
3325 gen_lookup_tb(s);
3326 break;
3327 case ARM_VFP_FPEXC:
3328 if (IS_USER(s))
3329 return 1;
3330 /* TODO: VFP subarchitecture support.
3331 * For now, keep the EN bit only */
3332 tmp = load_reg(s, rd);
3333 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 1 << 30);
3334 store_cpu_field(tcg_ctx, tmp, vfp.xregs[rn]);
3335 gen_lookup_tb(s);
3336 break;
3337 case ARM_VFP_FPINST:
3338 case ARM_VFP_FPINST2:
3339 if (IS_USER(s)) {
3340 return 1;
3341 }
3342 tmp = load_reg(s, rd);
3343 store_cpu_field(tcg_ctx, tmp, vfp.xregs[rn]);
3344 break;
3345 default:
3346 return 1;
3347 }
3348 } else {
3349 tmp = load_reg(s, rd);
3350 gen_vfp_msr(s, tmp);
3351 gen_mov_vreg_F0(s, 0, rn);
3352 }
3353 }
3354 }
3355 } else {
3356 /* data processing */
3357 /* The opcode is in bits 23, 21, 20 and 6. */
3358 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3359 if (dp) {
3360 if (op == 15) {
3361 /* rn is opcode */
3362 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3363 } else {
3364 /* rn is register number */
3365 VFP_DREG_N(rn, insn);
3366 }
3367
3368 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3369 ((rn & 0x1e) == 0x6))) {
3370 /* Integer or single/half precision destination. */
3371 rd = VFP_SREG_D(insn);
3372 } else {
3373 VFP_DREG_D(rd, insn);
3374 }
3375 if (op == 15 &&
3376 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3377 ((rn & 0x1e) == 0x4))) {
3378 /* VCVT from int or half precision is always from S reg
3379 * regardless of dp bit. VCVT with immediate frac_bits
3380 * has same format as SREG_M.
3381 */
3382 rm = VFP_SREG_M(insn);
3383 } else {
3384 VFP_DREG_M(rm, insn);
3385 }
3386 } else {
3387 rn = VFP_SREG_N(insn);
3388 if (op == 15 && rn == 15) {
3389 /* Double precision destination. */
3390 VFP_DREG_D(rd, insn);
3391 } else {
3392 rd = VFP_SREG_D(insn);
3393 }
3394 /* NB that we implicitly rely on the encoding for the frac_bits
3395 * in VCVT of fixed to float being the same as that of an SREG_M
3396 */
3397 rm = VFP_SREG_M(insn);
3398 }
3399
3400 veclen = s->vec_len;
3401 if (op == 15 && rn > 3)
3402 veclen = 0;
3403
3404 /* Shut up compiler warnings. */
3405 delta_m = 0;
3406 delta_d = 0;
3407 bank_mask = 0;
3408
3409 if (veclen > 0) {
3410 if (dp)
3411 bank_mask = 0xc;
3412 else
3413 bank_mask = 0x18;
3414
3415 /* Figure out what type of vector operation this is. */
3416 if ((rd & bank_mask) == 0) {
3417 /* scalar */
3418 veclen = 0;
3419 } else {
3420 if (dp)
3421 delta_d = (s->vec_stride >> 1) + 1;
3422 else
3423 delta_d = s->vec_stride + 1;
3424
3425 if ((rm & bank_mask) == 0) {
3426 /* mixed scalar/vector */
3427 delta_m = 0;
3428 } else {
3429 /* vector */
3430 delta_m = delta_d;
3431 }
3432 }
3433 }
3434
3435 /* Load the initial operands. */
3436 if (op == 15) {
3437 switch (rn) {
3438 case 16:
3439 case 17:
3440 /* Integer source */
3441 gen_mov_F0_vreg(s, 0, rm);
3442 break;
3443 case 8:
3444 case 9:
3445 /* Compare */
3446 gen_mov_F0_vreg(s, dp, rd);
3447 gen_mov_F1_vreg(s, dp, rm);
3448 break;
3449 case 10:
3450 case 11:
3451 /* Compare with zero */
3452 gen_mov_F0_vreg(s, dp, rd);
3453 gen_vfp_F1_ld0(s, dp);
3454 break;
3455 case 20:
3456 case 21:
3457 case 22:
3458 case 23:
3459 case 28:
3460 case 29:
3461 case 30:
3462 case 31:
3463 /* Source and destination the same. */
3464 gen_mov_F0_vreg(s, dp, rd);
3465 break;
3466 case 4:
3467 case 5:
3468 case 6:
3469 case 7:
3470 /* VCVTB, VCVTT: only present with the halfprec extension
3471 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3472 * (we choose to UNDEF)
3473 */
3474 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3475 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3476 return 1;
3477 }
3478 if (!extract32(rn, 1, 1)) {
3479 /* Half precision source. */
3480 gen_mov_F0_vreg(s, 0, rm);
3481 break;
3482 }
3483 /* Otherwise fall through */
3484 default:
3485 /* One source operand. */
3486 gen_mov_F0_vreg(s, dp, rm);
3487 break;
3488 }
3489 } else {
3490 /* Two source operands. */
3491 gen_mov_F0_vreg(s, dp, rn);
3492 gen_mov_F1_vreg(s, dp, rm);
3493 }
3494
3495 for (;;) {
3496 /* Perform the calculation. */
3497 switch (op) {
3498 case 0: /* VMLA: fd + (fn * fm) */
3499 /* Note that order of inputs to the add matters for NaNs */
3500 gen_vfp_F1_mul(s, dp);
3501 gen_mov_F0_vreg(s, dp, rd);
3502 gen_vfp_add(s, dp);
3503 break;
3504 case 1: /* VMLS: fd + -(fn * fm) */
3505 gen_vfp_mul(s, dp);
3506 gen_vfp_F1_neg(s, dp);
3507 gen_mov_F0_vreg(s, dp, rd);
3508 gen_vfp_add(s, dp);
3509 break;
3510 case 2: /* VNMLS: -fd + (fn * fm) */
3511 /* Note that it isn't valid to replace (-A + B) with (B - A)
3512 * or similar plausible looking simplifications
3513 * because this will give wrong results for NaNs.
3514 */
3515 gen_vfp_F1_mul(s, dp);
3516 gen_mov_F0_vreg(s, dp, rd);
3517 gen_vfp_neg(s, dp);
3518 gen_vfp_add(s, dp);
3519 break;
3520 case 3: /* VNMLA: -fd + -(fn * fm) */
3521 gen_vfp_mul(s, dp);
3522 gen_vfp_F1_neg(s, dp);
3523 gen_mov_F0_vreg(s, dp, rd);
3524 gen_vfp_neg(s, dp);
3525 gen_vfp_add(s, dp);
3526 break;
3527 case 4: /* mul: fn * fm */
3528 gen_vfp_mul(s, dp);
3529 break;
3530 case 5: /* nmul: -(fn * fm) */
3531 gen_vfp_mul(s, dp);
3532 gen_vfp_neg(s, dp);
3533 break;
3534 case 6: /* add: fn + fm */
3535 gen_vfp_add(s, dp);
3536 break;
3537 case 7: /* sub: fn - fm */
3538 gen_vfp_sub(s, dp);
3539 break;
3540 case 8: /* div: fn / fm */
3541 gen_vfp_div(s, dp);
3542 break;
3543 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3544 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3545 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3546 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3547 /* These are fused multiply-add, and must be done as one
3548 * floating point operation with no rounding between the
3549 * multiplication and addition steps.
3550 * NB that doing the negations here as separate steps is
3551 * correct : an input NaN should come out with its sign bit
3552 * flipped if it is a negated-input.
3553 */
3554 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3555 return 1;
3556 }
3557 if (dp) {
3558 TCGv_ptr fpst;
3559 TCGv_i64 frd;
3560 if (op & 1) {
3561 /* VFNMS, VFMS */
3562 gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
3563 }
3564 frd = tcg_temp_new_i64(tcg_ctx);
3565 tcg_gen_ld_f64(tcg_ctx, frd, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
3566 if (op & 2) {
3567 /* VFNMA, VFNMS */
3568 gen_helper_vfp_negd(tcg_ctx, frd, frd);
3569 }
3570 fpst = get_fpstatus_ptr(s, 0);
3571 gen_helper_vfp_muladdd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d,
3572 tcg_ctx->cpu_F1d, frd, fpst);
3573 tcg_temp_free_ptr(tcg_ctx, fpst);
3574 tcg_temp_free_i64(tcg_ctx, frd);
3575 } else {
3576 TCGv_ptr fpst;
3577 TCGv_i32 frd;
3578 if (op & 1) {
3579 /* VFNMS, VFMS */
3580 gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
3581 }
3582 frd = tcg_temp_new_i32(tcg_ctx);
3583 tcg_gen_ld_f32(tcg_ctx, frd, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
3584 if (op & 2) {
3585 gen_helper_vfp_negs(tcg_ctx, frd, frd);
3586 }
3587 fpst = get_fpstatus_ptr(s, 0);
3588 gen_helper_vfp_muladds(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
3589 tcg_ctx->cpu_F1s, frd, fpst);
3590 tcg_temp_free_ptr(tcg_ctx, fpst);
3591 tcg_temp_free_i32(tcg_ctx, frd);
3592 }
3593 break;
3594 case 14: /* fconst */
3595 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3596 return 1;
3597 }
3598
3599 n = (insn << 12) & 0x80000000;
3600 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3601 if (dp) {
3602 if (i & 0x40)
3603 i |= 0x3f80;
3604 else
3605 i |= 0x4000;
3606 n |= i << 16;
3607 tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_F0d, ((uint64_t)n) << 32);
3608 } else {
3609 if (i & 0x40)
3610 i |= 0x780;
3611 else
3612 i |= 0x800;
3613 n |= i << 19;
3614 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_F0s, n);
3615 }
3616 break;
3617 case 15: /* extension space */
3618 switch (rn) {
3619 case 0: /* cpy */
3620 /* no-op */
3621 break;
3622 case 1: /* abs */
3623 gen_vfp_abs(s, dp);
3624 break;
3625 case 2: /* neg */
3626 gen_vfp_neg(s, dp);
3627 break;
3628 case 3: /* sqrt */
3629 gen_vfp_sqrt(s, dp);
3630 break;
3631 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3632 tmp = gen_vfp_mrs(s);
3633 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
3634 if (dp) {
3635 gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp,
3636 tcg_ctx->cpu_env);
3637 } else {
3638 gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp,
3639 tcg_ctx->cpu_env);
3640 }
3641 tcg_temp_free_i32(tcg_ctx, tmp);
3642 break;
3643 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3644 tmp = gen_vfp_mrs(s);
3645 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
3646 if (dp) {
3647 gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp,
3648 tcg_ctx->cpu_env);
3649 } else {
3650 gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp,
3651 tcg_ctx->cpu_env);
3652 }
3653 tcg_temp_free_i32(tcg_ctx, tmp);
3654 break;
3655 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3656 tmp = tcg_temp_new_i32(tcg_ctx);
3657 if (dp) {
3658 gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d,
3659 tcg_ctx->cpu_env);
3660 } else {
3661 gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s,
3662 tcg_ctx->cpu_env);
3663 }
3664 gen_mov_F0_vreg(s, 0, rd);
3665 tmp2 = gen_vfp_mrs(s);
3666 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
3667 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
3668 tcg_temp_free_i32(tcg_ctx, tmp2);
3669 gen_vfp_msr(s, tmp);
3670 break;
3671 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3672 tmp = tcg_temp_new_i32(tcg_ctx);
3673 if (dp) {
3674 gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d,
3675 tcg_ctx->cpu_env);
3676 } else {
3677 gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s,
3678 tcg_ctx->cpu_env);
3679 }
3680 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 16);
3681 gen_mov_F0_vreg(s, 0, rd);
3682 tmp2 = gen_vfp_mrs(s);
3683 tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
3684 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
3685 tcg_temp_free_i32(tcg_ctx, tmp2);
3686 gen_vfp_msr(s, tmp);
3687 break;
3688 case 8: /* cmp */
3689 gen_vfp_cmp(s, dp);
3690 break;
3691 case 9: /* cmpe */
3692 gen_vfp_cmpe(s, dp);
3693 break;
3694 case 10: /* cmpz */
3695 gen_vfp_cmp(s, dp);
3696 break;
3697 case 11: /* cmpez */
3698 gen_vfp_F1_ld0(s, dp);
3699 gen_vfp_cmpe(s, dp);
3700 break;
3701 case 12: /* vrintr */
3702 {
3703 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3704 if (dp) {
3705 gen_helper_rintd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3706 } else {
3707 gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3708 }
3709 tcg_temp_free_ptr(tcg_ctx, fpst);
3710 break;
3711 }
3712 case 13: /* vrintz */
3713 {
3714 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3715 TCGv_i32 tcg_rmode;
3716 tcg_rmode = tcg_const_i32(tcg_ctx, float_round_to_zero);
3717 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3718 if (dp) {
3719 gen_helper_rintd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3720 } else {
3721 gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3722 }
3723 gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3724 tcg_temp_free_i32(tcg_ctx, tcg_rmode);
3725 tcg_temp_free_ptr(tcg_ctx, fpst);
3726 break;
3727 }
3728 case 14: /* vrintx */
3729 {
3730 TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3731 if (dp) {
3732 gen_helper_rintd_exact(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3733 } else {
3734 gen_helper_rints_exact(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3735 }
3736 tcg_temp_free_ptr(tcg_ctx, fpst);
3737 break;
3738 }
3739 case 15: /* single<->double conversion */
3740 if (dp)
3741 gen_helper_vfp_fcvtsd(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env);
3742 else
3743 gen_helper_vfp_fcvtds(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
3744 break;
3745 case 16: /* fuito */
3746 gen_vfp_uito(s, dp, 0);
3747 break;
3748 case 17: /* fsito */
3749 gen_vfp_sito(s, dp, 0);
3750 break;
3751 case 20: /* fshto */
3752 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3753 return 1;
3754 }
3755 gen_vfp_shto(s, dp, 16 - rm, 0);
3756 break;
3757 case 21: /* fslto */
3758 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3759 return 1;
3760 }
3761 gen_vfp_slto(s, dp, 32 - rm, 0);
3762 break;
3763 case 22: /* fuhto */
3764 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3765 return 1;
3766 }
3767 gen_vfp_uhto(s, dp, 16 - rm, 0);
3768 break;
3769 case 23: /* fulto */
3770 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3771 return 1;
3772 }
3773 gen_vfp_ulto(s, dp, 32 - rm, 0);
3774 break;
3775 case 24: /* ftoui */
3776 gen_vfp_toui(s, dp, 0);
3777 break;
3778 case 25: /* ftouiz */
3779 gen_vfp_touiz(s, dp, 0);
3780 break;
3781 case 26: /* ftosi */
3782 gen_vfp_tosi(s, dp, 0);
3783 break;
3784 case 27: /* ftosiz */
3785 gen_vfp_tosiz(s, dp, 0);
3786 break;
3787 case 28: /* ftosh */
3788 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3789 return 1;
3790 }
3791 gen_vfp_tosh(s, dp, 16 - rm, 0);
3792 break;
3793 case 29: /* ftosl */
3794 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3795 return 1;
3796 }
3797 gen_vfp_tosl(s, dp, 32 - rm, 0);
3798 break;
3799 case 30: /* ftouh */
3800 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3801 return 1;
3802 }
3803 gen_vfp_touh(s, dp, 16 - rm, 0);
3804 break;
3805 case 31: /* ftoul */
3806 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3807 return 1;
3808 }
3809 gen_vfp_toul(s, dp, 32 - rm, 0);
3810 break;
3811 default: /* undefined */
3812 return 1;
3813 }
3814 break;
3815 default: /* undefined */
3816 return 1;
3817 }
3818
3819 /* Write back the result. */
3820 if (op == 15 && (rn >= 8 && rn <= 11)) {
3821 /* Comparison, do nothing. */
3822 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3823 (rn & 0x1e) == 0x6)) {
3824 /* VCVT double to int: always integer result.
3825 * VCVT double to half precision is always a single
3826 * precision result.
3827 */
3828 gen_mov_vreg_F0(s, 0, rd);
3829 } else if (op == 15 && rn == 15) {
3830 /* conversion */
3831 gen_mov_vreg_F0(s, !dp, rd);
3832 } else {
3833 gen_mov_vreg_F0(s, dp, rd);
3834 }
3835
3836 /* break out of the loop if we have finished */
3837 if (veclen == 0)
3838 break;
3839
3840 if (op == 15 && delta_m == 0) {
3841 /* single source one-many */
3842 while (veclen--) {
3843 rd = ((rd + delta_d) & (bank_mask - 1))
3844 | (rd & bank_mask);
3845 gen_mov_vreg_F0(s, dp, rd);
3846 }
3847 break;
3848 }
3849 /* Setup the next operands. */
3850 veclen--;
3851 rd = ((rd + delta_d) & (bank_mask - 1))
3852 | (rd & bank_mask);
3853
3854 if (op == 15) {
3855 /* One source operand. */
3856 rm = ((rm + delta_m) & (bank_mask - 1))
3857 | (rm & bank_mask);
3858 gen_mov_F0_vreg(s, dp, rm);
3859 } else {
3860 /* Two source operands. */
3861 rn = ((rn + delta_d) & (bank_mask - 1))
3862 | (rn & bank_mask);
3863 gen_mov_F0_vreg(s, dp, rn);
3864 if (delta_m) {
3865 rm = ((rm + delta_m) & (bank_mask - 1))
3866 | (rm & bank_mask);
3867 gen_mov_F1_vreg(s, dp, rm);
3868 }
3869 }
3870 }
3871 }
3872 break;
3873 case 0xc:
3874 case 0xd:
3875 if ((insn & 0x03e00000) == 0x00400000) {
3876 /* two-register transfer */
3877 rn = (insn >> 16) & 0xf;
3878 rd = (insn >> 12) & 0xf;
3879 if (dp) {
3880 VFP_DREG_M(rm, insn);
3881 } else {
3882 rm = VFP_SREG_M(insn);
3883 }
3884
3885 if (insn & ARM_CP_RW_BIT) {
3886 /* vfp->arm */
3887 if (dp) {
3888 gen_mov_F0_vreg(s, 0, rm * 2);
3889 tmp = gen_vfp_mrs(s);
3890 store_reg(s, rd, tmp);
3891 gen_mov_F0_vreg(s, 0, rm * 2 + 1);
3892 tmp = gen_vfp_mrs(s);
3893 store_reg(s, rn, tmp);
3894 } else {
3895 gen_mov_F0_vreg(s, 0, rm);
3896 tmp = gen_vfp_mrs(s);
3897 store_reg(s, rd, tmp);
3898 gen_mov_F0_vreg(s, 0, rm + 1);
3899 tmp = gen_vfp_mrs(s);
3900 store_reg(s, rn, tmp);
3901 }
3902 } else {
3903 /* arm->vfp */
3904 if (dp) {
3905 tmp = load_reg(s, rd);
3906 gen_vfp_msr(s, tmp);
3907 gen_mov_vreg_F0(s, 0, rm * 2);
3908 tmp = load_reg(s, rn);
3909 gen_vfp_msr(s, tmp);
3910 gen_mov_vreg_F0(s, 0, rm * 2 + 1);
3911 } else {
3912 tmp = load_reg(s, rd);
3913 gen_vfp_msr(s, tmp);
3914 gen_mov_vreg_F0(s, 0, rm);
3915 tmp = load_reg(s, rn);
3916 gen_vfp_msr(s, tmp);
3917 gen_mov_vreg_F0(s, 0, rm + 1);
3918 }
3919 }
3920 } else {
3921 /* Load/store */
3922 rn = (insn >> 16) & 0xf;
3923 if (dp)
3924 VFP_DREG_D(rd, insn);
3925 else
3926 rd = VFP_SREG_D(insn);
3927 if ((insn & 0x01200000) == 0x01000000) {
3928 /* Single load/store */
3929 offset = (insn & 0xff) << 2;
3930 if ((insn & (1 << 23)) == 0)
3931 offset = 0-offset;
3932 if (s->thumb && rn == 15) {
3933 /* This is actually UNPREDICTABLE */
3934 addr = tcg_temp_new_i32(tcg_ctx);
3935 tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~2);
3936 } else {
3937 addr = load_reg(s, rn);
3938 }
3939 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
3940 if (insn & (1 << 20)) {
3941 gen_vfp_ld(s, dp, addr);
3942 gen_mov_vreg_F0(s, dp, rd);
3943 } else {
3944 gen_mov_F0_vreg(s, dp, rd);
3945 gen_vfp_st(s, dp, addr);
3946 }
3947 tcg_temp_free_i32(tcg_ctx, addr);
3948 } else {
3949 /* load/store multiple */
3950 int w = insn & (1 << 21);
3951 if (dp)
3952 n = (insn >> 1) & 0x7f;
3953 else
3954 n = insn & 0xff;
3955
3956 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3957 /* P == U , W == 1 => UNDEF */
3958 return 1;
3959 }
3960 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3961 /* UNPREDICTABLE cases for bad immediates: we choose to
3962 * UNDEF to avoid generating huge numbers of TCG ops
3963 */
3964 return 1;
3965 }
3966 if (rn == 15 && w) {
3967 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3968 return 1;
3969 }
3970
3971 if (s->thumb && rn == 15) {
3972 /* This is actually UNPREDICTABLE */
3973 addr = tcg_temp_new_i32(tcg_ctx);
3974 tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~2);
3975 } else {
3976 addr = load_reg(s, rn);
3977 }
3978 if (insn & (1 << 24)) /* pre-decrement */
3979 tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-((insn & 0xff) << 2));
3980
3981 if (dp)
3982 offset = 8;
3983 else
3984 offset = 4;
3985 for (i = 0; i < n; i++) {
3986 if (insn & ARM_CP_RW_BIT) {
3987 /* load */
3988 gen_vfp_ld(s, dp, addr);
3989 gen_mov_vreg_F0(s, dp, rd + i);
3990 } else {
3991 /* store */
3992 gen_mov_F0_vreg(s, dp, rd + i);
3993 gen_vfp_st(s, dp, addr);
3994 }
3995 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
3996 }
3997 if (w) {
3998 /* writeback */
3999 if (insn & (1 << 24))
4000 offset = (0-offset) * n;
4001 else if (dp && (insn & 1))
4002 offset = 4;
4003 else
4004 offset = 0;
4005
4006 if (offset != 0)
4007 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
4008 store_reg(s, rn, addr);
4009 } else {
4010 tcg_temp_free_i32(tcg_ctx, addr);
4011 }
4012 }
4013 }
4014 break;
4015 default:
4016 /* Should never happen. */
4017 return 1;
4018 }
4019 return 0;
4020 }
4021
gen_goto_tb(DisasContext * s,int n,target_ulong dest)4022 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4023 {
4024 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4025 TranslationBlock *tb;
4026
4027 tb = s->tb;
4028 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
4029 tcg_gen_goto_tb(tcg_ctx, n);
4030 gen_set_pc_im(s, dest);
4031 tcg_gen_exit_tb(tcg_ctx, (uintptr_t)tb + n);
4032 } else {
4033 gen_set_pc_im(s, dest);
4034 tcg_gen_exit_tb(tcg_ctx, 0);
4035 }
4036 }
4037
gen_jmp(DisasContext * s,uint32_t dest)4038 static inline void gen_jmp(DisasContext *s, uint32_t dest)
4039 {
4040 if (unlikely(s->singlestep_enabled || s->ss_active)) {
4041 /* An indirect jump so that we still trigger the debug exception. */
4042 if (s->thumb)
4043 dest |= 1;
4044 gen_bx_im(s, dest);
4045 } else {
4046 gen_goto_tb(s, 0, dest);
4047 s->is_jmp = DISAS_TB_JUMP;
4048 }
4049 }
4050
gen_mulxy(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1,int x,int y)4051 static inline void gen_mulxy(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4052 {
4053 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4054 if (x)
4055 tcg_gen_sari_i32(tcg_ctx, t0, t0, 16);
4056 else
4057 gen_sxth(t0);
4058 if (y)
4059 tcg_gen_sari_i32(tcg_ctx, t1, t1, 16);
4060 else
4061 gen_sxth(t1);
4062 tcg_gen_mul_i32(tcg_ctx, t0, t0, t1);
4063 }
4064
4065 /* Return the mask of PSR bits set by a MSR instruction. */
msr_mask(DisasContext * s,int flags,int spsr)4066 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4067 {
4068 uint32_t mask;
4069
4070 mask = 0;
4071 if (flags & (1 << 0))
4072 mask |= 0xff;
4073 if (flags & (1 << 1))
4074 mask |= 0xff00;
4075 if (flags & (1 << 2))
4076 mask |= 0xff0000;
4077 if (flags & (1 << 3))
4078 mask |= 0xff000000;
4079
4080 /* Mask out undefined bits. */
4081 mask &= ~CPSR_RESERVED;
4082 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4083 mask &= ~CPSR_T;
4084 }
4085 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4086 mask &= ~CPSR_Q; /* V5TE in reality*/
4087 }
4088 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4089 mask &= ~(CPSR_E | CPSR_GE);
4090 }
4091 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4092 mask &= ~CPSR_IT;
4093 }
4094 /* Mask out execution state and reserved bits. */
4095 if (!spsr) {
4096 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4097 }
4098 /* Mask out privileged bits. */
4099 if (IS_USER(s))
4100 mask &= CPSR_USER;
4101 return mask;
4102 }
4103
4104 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
gen_set_psr(DisasContext * s,uint32_t mask,int spsr,TCGv_i32 t0)4105 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4106 {
4107 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4108 TCGv_i32 tmp;
4109 if (spsr) {
4110 /* ??? This is also undefined in system mode. */
4111 if (IS_USER(s))
4112 return 1;
4113
4114 tmp = load_cpu_field(s->uc, spsr);
4115 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, ~mask);
4116 tcg_gen_andi_i32(tcg_ctx, t0, t0, mask);
4117 tcg_gen_or_i32(tcg_ctx, tmp, tmp, t0);
4118 store_cpu_field(tcg_ctx, tmp, spsr);
4119 } else {
4120 gen_set_cpsr(s, t0, mask);
4121 }
4122 tcg_temp_free_i32(tcg_ctx, t0);
4123 gen_lookup_tb(s);
4124 return 0;
4125 }
4126
4127 /* Returns nonzero if access to the PSR is not permitted. */
gen_set_psr_im(DisasContext * s,uint32_t mask,int spsr,uint32_t val)4128 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4129 {
4130 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4131 TCGv_i32 tmp;
4132 tmp = tcg_temp_new_i32(tcg_ctx);
4133 tcg_gen_movi_i32(tcg_ctx, tmp, val);
4134 return gen_set_psr(s, mask, spsr, tmp);
4135 }
4136
4137 /* Generate an old-style exception return. Marks pc as dead. */
gen_exception_return(DisasContext * s,TCGv_i32 pc)4138 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4139 {
4140 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4141 TCGv_i32 tmp;
4142 store_reg(s, 15, pc);
4143 tmp = load_cpu_field(s->uc, spsr);
4144 gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
4145 tcg_temp_free_i32(tcg_ctx, tmp);
4146 s->is_jmp = DISAS_UPDATE;
4147 }
4148
4149 /* Generate a v6 exception return. Marks both values as dead. */
gen_rfe(DisasContext * s,TCGv_i32 pc,TCGv_i32 cpsr)4150 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4151 {
4152 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4153 gen_set_cpsr(s, cpsr, CPSR_ERET_MASK);
4154 tcg_temp_free_i32(tcg_ctx, cpsr);
4155 store_reg(s, 15, pc);
4156 s->is_jmp = DISAS_UPDATE;
4157 }
4158
gen_nop_hint(DisasContext * s,int val)4159 static void gen_nop_hint(DisasContext *s, int val)
4160 {
4161 switch (val) {
4162 case 3: /* wfi */
4163 gen_set_pc_im(s, s->pc);
4164 s->is_jmp = DISAS_WFI;
4165 break;
4166 case 2: /* wfe */
4167 gen_set_pc_im(s, s->pc);
4168 s->is_jmp = DISAS_WFE;
4169 break;
4170 case 4: /* sev */
4171 case 5: /* sevl */
4172 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4173 default: /* nop */
4174 break;
4175 }
4176 }
4177
4178 #define CPU_V001 tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1
4179
gen_neon_add(DisasContext * s,int size,TCGv_i32 t0,TCGv_i32 t1)4180 static inline void gen_neon_add(DisasContext *s, int size, TCGv_i32 t0, TCGv_i32 t1)
4181 {
4182 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4183 switch (size) {
4184 case 0: gen_helper_neon_add_u8(tcg_ctx, t0, t0, t1); break;
4185 case 1: gen_helper_neon_add_u16(tcg_ctx, t0, t0, t1); break;
4186 case 2: tcg_gen_add_i32(tcg_ctx, t0, t0, t1); break;
4187 default: abort();
4188 }
4189 }
4190
gen_neon_rsb(DisasContext * s,int size,TCGv_i32 t0,TCGv_i32 t1)4191 static inline void gen_neon_rsb(DisasContext *s, int size, TCGv_i32 t0, TCGv_i32 t1)
4192 {
4193 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4194 switch (size) {
4195 case 0: gen_helper_neon_sub_u8(tcg_ctx, t0, t1, t0); break;
4196 case 1: gen_helper_neon_sub_u16(tcg_ctx, t0, t1, t0); break;
4197 case 2: tcg_gen_sub_i32(tcg_ctx, t0, t1, t0); break;
4198 default: return;
4199 }
4200 }
4201
4202 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4203 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4204 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4205 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4206 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4207
4208 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4209 switch ((size << 1) | u) { \
4210 case 0: \
4211 gen_helper_neon_##name##_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4212 break; \
4213 case 1: \
4214 gen_helper_neon_##name##_u8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4215 break; \
4216 case 2: \
4217 gen_helper_neon_##name##_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4218 break; \
4219 case 3: \
4220 gen_helper_neon_##name##_u16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4221 break; \
4222 case 4: \
4223 gen_helper_neon_##name##_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4224 break; \
4225 case 5: \
4226 gen_helper_neon_##name##_u32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4227 break; \
4228 default: return 1; \
4229 }} while (0)
4230
4231 #define GEN_NEON_INTEGER_OP(name) do { \
4232 switch ((size << 1) | u) { \
4233 case 0: \
4234 gen_helper_neon_##name##_s8(tcg_ctx, tmp, tmp, tmp2); \
4235 break; \
4236 case 1: \
4237 gen_helper_neon_##name##_u8(tcg_ctx, tmp, tmp, tmp2); \
4238 break; \
4239 case 2: \
4240 gen_helper_neon_##name##_s16(tcg_ctx, tmp, tmp, tmp2); \
4241 break; \
4242 case 3: \
4243 gen_helper_neon_##name##_u16(tcg_ctx, tmp, tmp, tmp2); \
4244 break; \
4245 case 4: \
4246 gen_helper_neon_##name##_s32(tcg_ctx, tmp, tmp, tmp2); \
4247 break; \
4248 case 5: \
4249 gen_helper_neon_##name##_u32(tcg_ctx, tmp, tmp, tmp2); \
4250 break; \
4251 default: return 1; \
4252 }} while (0)
4253
neon_load_scratch(TCGContext * tcg_ctx,int scratch)4254 static TCGv_i32 neon_load_scratch(TCGContext *tcg_ctx, int scratch)
4255 {
4256 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
4257 tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4258 return tmp;
4259 }
4260
neon_store_scratch(TCGContext * tcg_ctx,int scratch,TCGv_i32 var)4261 static void neon_store_scratch(TCGContext *tcg_ctx, int scratch, TCGv_i32 var)
4262 {
4263 tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4264 tcg_temp_free_i32(tcg_ctx, var);
4265 }
4266
neon_get_scalar(DisasContext * s,int size,int reg)4267 static inline TCGv_i32 neon_get_scalar(DisasContext *s, int size, int reg)
4268 {
4269 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4270 TCGv_i32 tmp;
4271 if (size == 1) {
4272 tmp = neon_load_reg(tcg_ctx, reg & 7, reg >> 4);
4273 if (reg & 8) {
4274 gen_neon_dup_high16(s, tmp);
4275 } else {
4276 gen_neon_dup_low16(s, tmp);
4277 }
4278 } else {
4279 tmp = neon_load_reg(tcg_ctx, reg & 15, reg >> 4);
4280 }
4281 return tmp;
4282 }
4283
gen_neon_unzip(TCGContext * tcg_ctx,int rd,int rm,int size,int q)4284 static int gen_neon_unzip(TCGContext *tcg_ctx, int rd, int rm, int size, int q)
4285 {
4286 TCGv_i32 tmp, tmp2;
4287 if (!q && size == 2) {
4288 return 1;
4289 }
4290 tmp = tcg_const_i32(tcg_ctx, rd);
4291 tmp2 = tcg_const_i32(tcg_ctx, rm);
4292 if (q) {
4293 switch (size) {
4294 case 0:
4295 gen_helper_neon_qunzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4296 break;
4297 case 1:
4298 gen_helper_neon_qunzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4299 break;
4300 case 2:
4301 gen_helper_neon_qunzip32(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4302 break;
4303 default:
4304 abort();
4305 }
4306 } else {
4307 switch (size) {
4308 case 0:
4309 gen_helper_neon_unzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4310 break;
4311 case 1:
4312 gen_helper_neon_unzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4313 break;
4314 default:
4315 abort();
4316 }
4317 }
4318 tcg_temp_free_i32(tcg_ctx, tmp);
4319 tcg_temp_free_i32(tcg_ctx, tmp2);
4320 return 0;
4321 }
4322
gen_neon_zip(TCGContext * tcg_ctx,int rd,int rm,int size,int q)4323 static int gen_neon_zip(TCGContext *tcg_ctx, int rd, int rm, int size, int q)
4324 {
4325 TCGv_i32 tmp, tmp2;
4326 if (!q && size == 2) {
4327 return 1;
4328 }
4329 tmp = tcg_const_i32(tcg_ctx, rd);
4330 tmp2 = tcg_const_i32(tcg_ctx, rm);
4331 if (q) {
4332 switch (size) {
4333 case 0:
4334 gen_helper_neon_qzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4335 break;
4336 case 1:
4337 gen_helper_neon_qzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4338 break;
4339 case 2:
4340 gen_helper_neon_qzip32(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4341 break;
4342 default:
4343 abort();
4344 }
4345 } else {
4346 switch (size) {
4347 case 0:
4348 gen_helper_neon_zip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4349 break;
4350 case 1:
4351 gen_helper_neon_zip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4352 break;
4353 default:
4354 abort();
4355 }
4356 }
4357 tcg_temp_free_i32(tcg_ctx, tmp);
4358 tcg_temp_free_i32(tcg_ctx, tmp2);
4359 return 0;
4360 }
4361
gen_neon_trn_u8(TCGContext * tcg_ctx,TCGv_i32 t0,TCGv_i32 t1)4362 static void gen_neon_trn_u8(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
4363 {
4364 TCGv_i32 rd, tmp;
4365
4366 rd = tcg_temp_new_i32(tcg_ctx);
4367 tmp = tcg_temp_new_i32(tcg_ctx);
4368
4369 tcg_gen_shli_i32(tcg_ctx, rd, t0, 8);
4370 tcg_gen_andi_i32(tcg_ctx, rd, rd, 0xff00ff00);
4371 tcg_gen_andi_i32(tcg_ctx, tmp, t1, 0x00ff00ff);
4372 tcg_gen_or_i32(tcg_ctx, rd, rd, tmp);
4373
4374 tcg_gen_shri_i32(tcg_ctx, t1, t1, 8);
4375 tcg_gen_andi_i32(tcg_ctx, t1, t1, 0x00ff00ff);
4376 tcg_gen_andi_i32(tcg_ctx, tmp, t0, 0xff00ff00);
4377 tcg_gen_or_i32(tcg_ctx, t1, t1, tmp);
4378 tcg_gen_mov_i32(tcg_ctx, t0, rd);
4379
4380 tcg_temp_free_i32(tcg_ctx, tmp);
4381 tcg_temp_free_i32(tcg_ctx, rd);
4382 }
4383
gen_neon_trn_u16(TCGContext * tcg_ctx,TCGv_i32 t0,TCGv_i32 t1)4384 static void gen_neon_trn_u16(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
4385 {
4386 TCGv_i32 rd, tmp;
4387
4388 rd = tcg_temp_new_i32(tcg_ctx);
4389 tmp = tcg_temp_new_i32(tcg_ctx);
4390
4391 tcg_gen_shli_i32(tcg_ctx, rd, t0, 16);
4392 tcg_gen_andi_i32(tcg_ctx, tmp, t1, 0xffff);
4393 tcg_gen_or_i32(tcg_ctx, rd, rd, tmp);
4394 tcg_gen_shri_i32(tcg_ctx, t1, t1, 16);
4395 tcg_gen_andi_i32(tcg_ctx, tmp, t0, 0xffff0000);
4396 tcg_gen_or_i32(tcg_ctx, t1, t1, tmp);
4397 tcg_gen_mov_i32(tcg_ctx, t0, rd);
4398
4399 tcg_temp_free_i32(tcg_ctx, tmp);
4400 tcg_temp_free_i32(tcg_ctx, rd);
4401 }
4402
4403
4404 static struct {
4405 int nregs;
4406 int interleave;
4407 int spacing;
4408 } neon_ls_element_type[11] = {
4409 {4, 4, 1},
4410 {4, 4, 2},
4411 {4, 1, 1},
4412 {4, 2, 1},
4413 {3, 3, 1},
4414 {3, 3, 2},
4415 {3, 1, 1},
4416 {1, 1, 1},
4417 {2, 2, 1},
4418 {2, 2, 2},
4419 {2, 1, 1}
4420 };
4421
4422 /* Translate a NEON load/store element instruction. Return nonzero if the
4423 instruction is invalid. */
disas_neon_ls_insn(DisasContext * s,uint32_t insn)4424 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4425 {
4426 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4427 int rd, rn, rm;
4428 int op;
4429 int nregs;
4430 int interleave;
4431 int spacing;
4432 int stride;
4433 int size;
4434 int reg;
4435 int pass;
4436 int load;
4437 int shift;
4438 int n;
4439 TCGv_i32 addr;
4440 TCGv_i32 tmp;
4441 TCGv_i32 tmp2;
4442 TCGv_i64 tmp64;
4443
4444 /* FIXME: this access check should not take precedence over UNDEF
4445 * for invalid encodings; we will generate incorrect syndrome information
4446 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4447 */
4448 if (!s->cpacr_fpen) {
4449 gen_exception_insn(s, 4, EXCP_UDEF,
4450 syn_fp_access_trap(1, 0xe, s->thumb));
4451 return 0;
4452 }
4453
4454 if (!s->vfp_enabled)
4455 return 1;
4456 VFP_DREG_D(rd, insn);
4457 rn = (insn >> 16) & 0xf;
4458 rm = insn & 0xf;
4459 load = (insn & (1 << 21)) != 0;
4460 if ((insn & (1 << 23)) == 0) {
4461 /* Load store all elements. */
4462 op = (insn >> 8) & 0xf;
4463 size = (insn >> 6) & 3;
4464 if (op > 10)
4465 return 1;
4466 /* Catch UNDEF cases for bad values of align field */
4467 switch (op & 0xc) {
4468 case 4:
4469 if (((insn >> 5) & 1) == 1) {
4470 return 1;
4471 }
4472 break;
4473 case 8:
4474 if (((insn >> 4) & 3) == 3) {
4475 return 1;
4476 }
4477 break;
4478 default:
4479 break;
4480 }
4481 nregs = neon_ls_element_type[op].nregs;
4482 interleave = neon_ls_element_type[op].interleave;
4483 spacing = neon_ls_element_type[op].spacing;
4484 if (size == 3 && (interleave | spacing) != 1)
4485 return 1;
4486 addr = tcg_temp_new_i32(tcg_ctx);
4487 load_reg_var(s, addr, rn);
4488 stride = (1 << size) * interleave;
4489 for (reg = 0; reg < nregs; reg++) {
4490 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4491 load_reg_var(s, addr, rn);
4492 tcg_gen_addi_i32(tcg_ctx, addr, addr, (1 << size) * reg);
4493 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4494 load_reg_var(s, addr, rn);
4495 tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4496 }
4497 if (size == 3) {
4498 tmp64 = tcg_temp_new_i64(tcg_ctx);
4499 if (load) {
4500 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4501 neon_store_reg64(tcg_ctx, tmp64, rd);
4502 } else {
4503 neon_load_reg64(tcg_ctx, tmp64, rd);
4504 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4505 }
4506 tcg_temp_free_i64(tcg_ctx, tmp64);
4507 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4508 } else {
4509 for (pass = 0; pass < 2; pass++) {
4510 if (size == 2) {
4511 if (load) {
4512 tmp = tcg_temp_new_i32(tcg_ctx);
4513 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4514 neon_store_reg(tcg_ctx, rd, pass, tmp);
4515 } else {
4516 tmp = neon_load_reg(tcg_ctx, rd, pass);
4517 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4518 tcg_temp_free_i32(tcg_ctx, tmp);
4519 }
4520 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4521 } else if (size == 1) {
4522 if (load) {
4523 tmp = tcg_temp_new_i32(tcg_ctx);
4524 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4525 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4526 tmp2 = tcg_temp_new_i32(tcg_ctx);
4527 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4528 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4529 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
4530 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
4531 tcg_temp_free_i32(tcg_ctx, tmp2);
4532 neon_store_reg(tcg_ctx, rd, pass, tmp);
4533 } else {
4534 tmp = neon_load_reg(tcg_ctx, rd, pass);
4535 tmp2 = tcg_temp_new_i32(tcg_ctx);
4536 tcg_gen_shri_i32(tcg_ctx, tmp2, tmp, 16);
4537 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4538 tcg_temp_free_i32(tcg_ctx, tmp);
4539 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4540 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4541 tcg_temp_free_i32(tcg_ctx, tmp2);
4542 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4543 }
4544 } else /* size == 0 */ {
4545 if (load) {
4546 TCGV_UNUSED_I32(tmp2);
4547 for (n = 0; n < 4; n++) {
4548 tmp = tcg_temp_new_i32(tcg_ctx);
4549 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4550 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4551 if (n == 0) {
4552 tmp2 = tmp;
4553 } else {
4554 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, n * 8);
4555 tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
4556 tcg_temp_free_i32(tcg_ctx, tmp);
4557 }
4558 }
4559 neon_store_reg(tcg_ctx, rd, pass, tmp2);
4560 } else {
4561 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
4562 for (n = 0; n < 4; n++) {
4563 tmp = tcg_temp_new_i32(tcg_ctx);
4564 if (n == 0) {
4565 tcg_gen_mov_i32(tcg_ctx, tmp, tmp2);
4566 } else {
4567 tcg_gen_shri_i32(tcg_ctx, tmp, tmp2, n * 8);
4568 }
4569 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4570 tcg_temp_free_i32(tcg_ctx, tmp);
4571 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4572 }
4573 tcg_temp_free_i32(tcg_ctx, tmp2);
4574 }
4575 }
4576 }
4577 }
4578 rd += spacing;
4579 }
4580 tcg_temp_free_i32(tcg_ctx, addr);
4581 stride = nregs * 8;
4582 } else {
4583 size = (insn >> 10) & 3;
4584 if (size == 3) {
4585 /* Load single element to all lanes. */
4586 int a = (insn >> 4) & 1;
4587 if (!load) {
4588 return 1;
4589 }
4590 size = (insn >> 6) & 3;
4591 nregs = ((insn >> 8) & 3) + 1;
4592
4593 if (size == 3) {
4594 if (nregs != 4 || a == 0) {
4595 return 1;
4596 }
4597 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4598 size = 2;
4599 }
4600 if (nregs == 1 && a == 1 && size == 0) {
4601 return 1;
4602 }
4603 if (nregs == 3 && a == 1) {
4604 return 1;
4605 }
4606 addr = tcg_temp_new_i32(tcg_ctx);
4607 load_reg_var(s, addr, rn);
4608 if (nregs == 1) {
4609 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4610 tmp = gen_load_and_replicate(s, addr, size);
4611 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
4612 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
4613 if (insn & (1 << 5)) {
4614 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd + 1, 0));
4615 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd + 1, 1));
4616 }
4617 tcg_temp_free_i32(tcg_ctx, tmp);
4618 } else {
4619 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4620 stride = (insn & (1 << 5)) ? 2 : 1;
4621 for (reg = 0; reg < nregs; reg++) {
4622 tmp = gen_load_and_replicate(s, addr, size);
4623 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
4624 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
4625 tcg_temp_free_i32(tcg_ctx, tmp);
4626 tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4627 rd += stride;
4628 }
4629 }
4630 tcg_temp_free_i32(tcg_ctx, addr);
4631 stride = (1 << size) * nregs;
4632 } else {
4633 /* Single element. */
4634 int idx = (insn >> 4) & 0xf;
4635 pass = (insn >> 7) & 1;
4636 switch (size) {
4637 case 0:
4638 shift = ((insn >> 5) & 3) * 8;
4639 stride = 1;
4640 break;
4641 case 1:
4642 shift = ((insn >> 6) & 1) * 16;
4643 stride = (insn & (1 << 5)) ? 2 : 1;
4644 break;
4645 case 2:
4646 shift = 0;
4647 stride = (insn & (1 << 6)) ? 2 : 1;
4648 break;
4649 default:
4650 abort();
4651 }
4652 nregs = ((insn >> 8) & 3) + 1;
4653 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4654 switch (nregs) {
4655 case 1:
4656 if (((idx & (1 << size)) != 0) ||
4657 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4658 return 1;
4659 }
4660 break;
4661 case 3:
4662 if ((idx & 1) != 0) {
4663 return 1;
4664 }
4665 /* fall through */
4666 case 2:
4667 if (size == 2 && (idx & 2) != 0) {
4668 return 1;
4669 }
4670 break;
4671 case 4:
4672 if ((size == 2) && ((idx & 3) == 3)) {
4673 return 1;
4674 }
4675 break;
4676 default:
4677 abort();
4678 }
4679 if ((rd + stride * (nregs - 1)) > 31) {
4680 /* Attempts to write off the end of the register file
4681 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4682 * the neon_load_reg() would write off the end of the array.
4683 */
4684 return 1;
4685 }
4686 addr = tcg_temp_new_i32(tcg_ctx);
4687 load_reg_var(s, addr, rn);
4688 for (reg = 0; reg < nregs; reg++) {
4689 if (load) {
4690 tmp = tcg_temp_new_i32(tcg_ctx);
4691 switch (size) {
4692 case 0:
4693 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4694 break;
4695 case 1:
4696 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4697 break;
4698 case 2:
4699 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4700 break;
4701 default: /* Avoid compiler warnings. */
4702 abort();
4703 }
4704 if (size != 2) {
4705 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
4706 tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp,
4707 shift, size ? 16 : 8);
4708 tcg_temp_free_i32(tcg_ctx, tmp2);
4709 }
4710 neon_store_reg(tcg_ctx, rd, pass, tmp);
4711 } else { /* Store */
4712 tmp = neon_load_reg(tcg_ctx, rd, pass);
4713 if (shift)
4714 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, shift);
4715 switch (size) {
4716 case 0:
4717 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4718 break;
4719 case 1:
4720 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4721 break;
4722 case 2:
4723 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4724 break;
4725 }
4726 tcg_temp_free_i32(tcg_ctx, tmp);
4727 }
4728 rd += stride;
4729 tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4730 }
4731 tcg_temp_free_i32(tcg_ctx, addr);
4732 stride = nregs * (1 << size);
4733 }
4734 }
4735 if (rm != 15) {
4736 TCGv_i32 base;
4737
4738 base = load_reg(s, rn);
4739 if (rm == 13) {
4740 tcg_gen_addi_i32(tcg_ctx, base, base, stride);
4741 } else {
4742 TCGv_i32 index;
4743 index = load_reg(s, rm);
4744 tcg_gen_add_i32(tcg_ctx, base, base, index);
4745 tcg_temp_free_i32(tcg_ctx, index);
4746 }
4747 store_reg(s, rn, base);
4748 }
4749 return 0;
4750 }
4751
4752 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
gen_neon_bsl(DisasContext * s,TCGv_i32 dest,TCGv_i32 t,TCGv_i32 f,TCGv_i32 c)4753 static void gen_neon_bsl(DisasContext *s, TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4754 {
4755 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4756 tcg_gen_and_i32(tcg_ctx, t, t, c);
4757 tcg_gen_andc_i32(tcg_ctx, f, f, c);
4758 tcg_gen_or_i32(tcg_ctx, dest, t, f);
4759 }
4760
gen_neon_narrow(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4761 static inline void gen_neon_narrow(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4762 {
4763 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4764 switch (size) {
4765 case 0: gen_helper_neon_narrow_u8(tcg_ctx, dest, src); break;
4766 case 1: gen_helper_neon_narrow_u16(tcg_ctx, dest, src); break;
4767 case 2: tcg_gen_trunc_i64_i32(tcg_ctx, dest, src); break;
4768 default: abort();
4769 }
4770 }
4771
gen_neon_narrow_sats(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4772 static inline void gen_neon_narrow_sats(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4773 {
4774 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4775 switch (size) {
4776 case 0: gen_helper_neon_narrow_sat_s8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4777 case 1: gen_helper_neon_narrow_sat_s16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4778 case 2: gen_helper_neon_narrow_sat_s32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4779 default: abort();
4780 }
4781 }
4782
gen_neon_narrow_satu(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4783 static inline void gen_neon_narrow_satu(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4784 {
4785 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4786 switch (size) {
4787 case 0: gen_helper_neon_narrow_sat_u8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4788 case 1: gen_helper_neon_narrow_sat_u16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4789 case 2: gen_helper_neon_narrow_sat_u32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4790 default: abort();
4791 }
4792 }
4793
gen_neon_unarrow_sats(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4794 static inline void gen_neon_unarrow_sats(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4795 {
4796 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4797 switch (size) {
4798 case 0: gen_helper_neon_unarrow_sat8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4799 case 1: gen_helper_neon_unarrow_sat16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4800 case 2: gen_helper_neon_unarrow_sat32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4801 default: abort();
4802 }
4803 }
4804
gen_neon_shift_narrow(DisasContext * s,int size,TCGv_i32 var,TCGv_i32 shift,int q,int u)4805 static inline void gen_neon_shift_narrow(DisasContext *s, int size, TCGv_i32 var, TCGv_i32 shift,
4806 int q, int u)
4807 {
4808 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4809 if (q) {
4810 if (u) {
4811 switch (size) {
4812 case 1: gen_helper_neon_rshl_u16(tcg_ctx, var, var, shift); break;
4813 case 2: gen_helper_neon_rshl_u32(tcg_ctx, var, var, shift); break;
4814 default: abort();
4815 }
4816 } else {
4817 switch (size) {
4818 case 1: gen_helper_neon_rshl_s16(tcg_ctx, var, var, shift); break;
4819 case 2: gen_helper_neon_rshl_s32(tcg_ctx, var, var, shift); break;
4820 default: abort();
4821 }
4822 }
4823 } else {
4824 if (u) {
4825 switch (size) {
4826 case 1: gen_helper_neon_shl_u16(tcg_ctx, var, var, shift); break;
4827 case 2: gen_helper_neon_shl_u32(tcg_ctx, var, var, shift); break;
4828 default: abort();
4829 }
4830 } else {
4831 switch (size) {
4832 case 1: gen_helper_neon_shl_s16(tcg_ctx, var, var, shift); break;
4833 case 2: gen_helper_neon_shl_s32(tcg_ctx, var, var, shift); break;
4834 default: abort();
4835 }
4836 }
4837 }
4838 }
4839
gen_neon_widen(DisasContext * s,TCGv_i64 dest,TCGv_i32 src,int size,int u)4840 static inline void gen_neon_widen(DisasContext *s, TCGv_i64 dest, TCGv_i32 src, int size, int u)
4841 {
4842 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4843 if (u) {
4844 switch (size) {
4845 case 0: gen_helper_neon_widen_u8(tcg_ctx, dest, src); break;
4846 case 1: gen_helper_neon_widen_u16(tcg_ctx, dest, src); break;
4847 case 2: tcg_gen_extu_i32_i64(tcg_ctx, dest, src); break;
4848 default: abort();
4849 }
4850 } else {
4851 switch (size) {
4852 case 0: gen_helper_neon_widen_s8(tcg_ctx, dest, src); break;
4853 case 1: gen_helper_neon_widen_s16(tcg_ctx, dest, src); break;
4854 case 2: tcg_gen_ext_i32_i64(tcg_ctx, dest, src); break;
4855 default: abort();
4856 }
4857 }
4858 tcg_temp_free_i32(tcg_ctx, src);
4859 }
4860
gen_neon_addl(DisasContext * s,int size)4861 static inline void gen_neon_addl(DisasContext *s, int size)
4862 {
4863 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4864 switch (size) {
4865 case 0: gen_helper_neon_addl_u16(tcg_ctx, CPU_V001); break;
4866 case 1: gen_helper_neon_addl_u32(tcg_ctx, CPU_V001); break;
4867 case 2: tcg_gen_add_i64(tcg_ctx, CPU_V001); break;
4868 default: abort();
4869 }
4870 }
4871
gen_neon_subl(DisasContext * s,int size)4872 static inline void gen_neon_subl(DisasContext *s, int size)
4873 {
4874 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4875 switch (size) {
4876 case 0: gen_helper_neon_subl_u16(tcg_ctx, CPU_V001); break;
4877 case 1: gen_helper_neon_subl_u32(tcg_ctx, CPU_V001); break;
4878 case 2: tcg_gen_sub_i64(tcg_ctx, CPU_V001); break;
4879 default: abort();
4880 }
4881 }
4882
gen_neon_negl(DisasContext * s,TCGv_i64 var,int size)4883 static inline void gen_neon_negl(DisasContext *s, TCGv_i64 var, int size)
4884 {
4885 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4886 switch (size) {
4887 case 0: gen_helper_neon_negl_u16(tcg_ctx, var, var); break;
4888 case 1: gen_helper_neon_negl_u32(tcg_ctx, var, var); break;
4889 case 2:
4890 tcg_gen_neg_i64(tcg_ctx, var, var);
4891 break;
4892 default: abort();
4893 }
4894 }
4895
gen_neon_addl_saturate(DisasContext * s,TCGv_i64 op0,TCGv_i64 op1,int size)4896 static inline void gen_neon_addl_saturate(DisasContext *s, TCGv_i64 op0, TCGv_i64 op1, int size)
4897 {
4898 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4899 switch (size) {
4900 case 1: gen_helper_neon_addl_saturate_s32(tcg_ctx, op0, tcg_ctx->cpu_env, op0, op1); break;
4901 case 2: gen_helper_neon_addl_saturate_s64(tcg_ctx, op0, tcg_ctx->cpu_env, op0, op1); break;
4902 default: abort();
4903 }
4904 }
4905
gen_neon_mull(DisasContext * s,TCGv_i64 dest,TCGv_i32 a,TCGv_i32 b,int size,int u)4906 static inline void gen_neon_mull(DisasContext *s, TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4907 int size, int u)
4908 {
4909 TCGContext *tcg_ctx = s->uc->tcg_ctx;
4910 TCGv_i64 tmp;
4911
4912 switch ((size << 1) | u) {
4913 case 0: gen_helper_neon_mull_s8(tcg_ctx, dest, a, b); break;
4914 case 1: gen_helper_neon_mull_u8(tcg_ctx, dest, a, b); break;
4915 case 2: gen_helper_neon_mull_s16(tcg_ctx, dest, a, b); break;
4916 case 3: gen_helper_neon_mull_u16(tcg_ctx, dest, a, b); break;
4917 case 4:
4918 tmp = gen_muls_i64_i32(s, a, b);
4919 tcg_gen_mov_i64(tcg_ctx, dest, tmp);
4920 tcg_temp_free_i64(tcg_ctx, tmp);
4921 break;
4922 case 5:
4923 tmp = gen_mulu_i64_i32(s, a, b);
4924 tcg_gen_mov_i64(tcg_ctx, dest, tmp);
4925 tcg_temp_free_i64(tcg_ctx, tmp);
4926 break;
4927 default: abort();
4928 }
4929
4930 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4931 Don't forget to clean them now. */
4932 if (size < 2) {
4933 tcg_temp_free_i32(tcg_ctx, a);
4934 tcg_temp_free_i32(tcg_ctx, b);
4935 }
4936 }
4937
gen_neon_narrow_op(DisasContext * s,int op,int u,int size,TCGv_i32 dest,TCGv_i64 src)4938 static void gen_neon_narrow_op(DisasContext *s, int op, int u, int size,
4939 TCGv_i32 dest, TCGv_i64 src)
4940 {
4941 if (op) {
4942 if (u) {
4943 gen_neon_unarrow_sats(s, size, dest, src);
4944 } else {
4945 gen_neon_narrow(s, size, dest, src);
4946 }
4947 } else {
4948 if (u) {
4949 gen_neon_narrow_satu(s, size, dest, src);
4950 } else {
4951 gen_neon_narrow_sats(s, size, dest, src);
4952 }
4953 }
4954 }
4955
4956 /* Symbolic constants for op fields for Neon 3-register same-length.
4957 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4958 * table A7-9.
4959 */
4960 #define NEON_3R_VHADD 0
4961 #define NEON_3R_VQADD 1
4962 #define NEON_3R_VRHADD 2
4963 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4964 #define NEON_3R_VHSUB 4
4965 #define NEON_3R_VQSUB 5
4966 #define NEON_3R_VCGT 6
4967 #define NEON_3R_VCGE 7
4968 #define NEON_3R_VSHL 8
4969 #define NEON_3R_VQSHL 9
4970 #define NEON_3R_VRSHL 10
4971 #define NEON_3R_VQRSHL 11
4972 #define NEON_3R_VMAX 12
4973 #define NEON_3R_VMIN 13
4974 #define NEON_3R_VABD 14
4975 #define NEON_3R_VABA 15
4976 #define NEON_3R_VADD_VSUB 16
4977 #define NEON_3R_VTST_VCEQ 17
4978 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4979 #define NEON_3R_VMUL 19
4980 #define NEON_3R_VPMAX 20
4981 #define NEON_3R_VPMIN 21
4982 #define NEON_3R_VQDMULH_VQRDMULH 22
4983 #define NEON_3R_VPADD 23
4984 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4985 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4986 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4987 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4988 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4989 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4990 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4991 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4992
4993 static const uint8_t neon_3r_sizes[] = {
4994 /*NEON_3R_VHADD*/ 0x7,
4995 /*NEON_3R_VQADD*/ 0xf,
4996 /*NEON_3R_VRHADD*/ 0x7,
4997 /*NEON_3R_LOGIC*/ 0xf, /* size field encodes op type */
4998 /*NEON_3R_VHSUB*/ 0x7,
4999 /*NEON_3R_VQSUB*/ 0xf,
5000 /*NEON_3R_VCGT*/ 0x7,
5001 /*NEON_3R_VCGE*/ 0x7,
5002 /*NEON_3R_VSHL*/ 0xf,
5003 /*NEON_3R_VQSHL*/ 0xf,
5004 /*NEON_3R_VRSHL*/ 0xf,
5005 /*NEON_3R_VQRSHL*/ 0xf,
5006 /*NEON_3R_VMAX*/ 0x7,
5007 /*NEON_3R_VMIN*/ 0x7,
5008 /*NEON_3R_VABD*/ 0x7,
5009 /*NEON_3R_VABA*/ 0x7,
5010 /*NEON_3R_VADD_VSUB*/ 0xf,
5011 /*NEON_3R_VTST_VCEQ*/ 0x7,
5012 /*NEON_3R_VML*/ 0x7,
5013 /*NEON_3R_VMUL*/ 0x7,
5014 /*NEON_3R_VPMAX*/ 0x7,
5015 /*NEON_3R_VPMIN*/ 0x7,
5016 /*NEON_3R_VQDMULH_VQRDMULH*/ 0x6,
5017 /*NEON_3R_VPADD*/ 0x7,
5018 /*NEON_3R_SHA*/ 0xf, /* size field encodes op type */
5019 /*NEON_3R_VFM*/ 0x5, /* size bit 1 encodes op */
5020 /*NEON_3R_FLOAT_ARITH*/ 0x5, /* size bit 1 encodes op */
5021 /*NEON_3R_FLOAT_MULTIPLY*/ 0x5, /* size bit 1 encodes op */
5022 /*NEON_3R_FLOAT_CMP*/ 0x5, /* size bit 1 encodes op */
5023 /*NEON_3R_FLOAT_ACMP*/ 0x5, /* size bit 1 encodes op */
5024 /*NEON_3R_FLOAT_MINMAX*/ 0x5, /* size bit 1 encodes op */
5025 /*NEON_3R_FLOAT_MISC*/ 0x5, /* size bit 1 encodes op */
5026 };
5027
5028 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5029 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5030 * table A7-13.
5031 */
5032 #define NEON_2RM_VREV64 0
5033 #define NEON_2RM_VREV32 1
5034 #define NEON_2RM_VREV16 2
5035 #define NEON_2RM_VPADDL 4
5036 #define NEON_2RM_VPADDL_U 5
5037 #define NEON_2RM_AESE 6 /* Includes AESD */
5038 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5039 #define NEON_2RM_VCLS 8
5040 #define NEON_2RM_VCLZ 9
5041 #define NEON_2RM_VCNT 10
5042 #define NEON_2RM_VMVN 11
5043 #define NEON_2RM_VPADAL 12
5044 #define NEON_2RM_VPADAL_U 13
5045 #define NEON_2RM_VQABS 14
5046 #define NEON_2RM_VQNEG 15
5047 #define NEON_2RM_VCGT0 16
5048 #define NEON_2RM_VCGE0 17
5049 #define NEON_2RM_VCEQ0 18
5050 #define NEON_2RM_VCLE0 19
5051 #define NEON_2RM_VCLT0 20
5052 #define NEON_2RM_SHA1H 21
5053 #define NEON_2RM_VABS 22
5054 #define NEON_2RM_VNEG 23
5055 #define NEON_2RM_VCGT0_F 24
5056 #define NEON_2RM_VCGE0_F 25
5057 #define NEON_2RM_VCEQ0_F 26
5058 #define NEON_2RM_VCLE0_F 27
5059 #define NEON_2RM_VCLT0_F 28
5060 #define NEON_2RM_VABS_F 30
5061 #define NEON_2RM_VNEG_F 31
5062 #define NEON_2RM_VSWP 32
5063 #define NEON_2RM_VTRN 33
5064 #define NEON_2RM_VUZP 34
5065 #define NEON_2RM_VZIP 35
5066 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5067 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5068 #define NEON_2RM_VSHLL 38
5069 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5070 #define NEON_2RM_VRINTN 40
5071 #define NEON_2RM_VRINTX 41
5072 #define NEON_2RM_VRINTA 42
5073 #define NEON_2RM_VRINTZ 43
5074 #define NEON_2RM_VCVT_F16_F32 44
5075 #define NEON_2RM_VRINTM 45
5076 #define NEON_2RM_VCVT_F32_F16 46
5077 #define NEON_2RM_VRINTP 47
5078 #define NEON_2RM_VCVTAU 48
5079 #define NEON_2RM_VCVTAS 49
5080 #define NEON_2RM_VCVTNU 50
5081 #define NEON_2RM_VCVTNS 51
5082 #define NEON_2RM_VCVTPU 52
5083 #define NEON_2RM_VCVTPS 53
5084 #define NEON_2RM_VCVTMU 54
5085 #define NEON_2RM_VCVTMS 55
5086 #define NEON_2RM_VRECPE 56
5087 #define NEON_2RM_VRSQRTE 57
5088 #define NEON_2RM_VRECPE_F 58
5089 #define NEON_2RM_VRSQRTE_F 59
5090 #define NEON_2RM_VCVT_FS 60
5091 #define NEON_2RM_VCVT_FU 61
5092 #define NEON_2RM_VCVT_SF 62
5093 #define NEON_2RM_VCVT_UF 63
5094
neon_2rm_is_float_op(int op)5095 static int neon_2rm_is_float_op(int op)
5096 {
5097 /* Return true if this neon 2reg-misc op is float-to-float */
5098 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5099 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5100 op == NEON_2RM_VRINTM ||
5101 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5102 op >= NEON_2RM_VRECPE_F);
5103 }
5104
5105 /* Each entry in this array has bit n set if the insn allows
5106 * size value n (otherwise it will UNDEF). Since unallocated
5107 * op values will have no bits set they always UNDEF.
5108 */
5109 static const uint8_t neon_2rm_sizes[] = {
5110 /*NEON_2RM_VREV64*/ 0x7,
5111 /*NEON_2RM_VREV32*/ 0x3,
5112 /*NEON_2RM_VREV16*/ 0x1,
5113 0,
5114 /*NEON_2RM_VPADDL*/ 0x7,
5115 /*NEON_2RM_VPADDL_U*/ 0x7,
5116 /*NEON_2RM_AESE*/ 0x1,
5117 /*NEON_2RM_AESMC*/ 0x1,
5118 /*NEON_2RM_VCLS*/ 0x7,
5119 /*NEON_2RM_VCLZ*/ 0x7,
5120 /*NEON_2RM_VCNT*/ 0x1,
5121 /*NEON_2RM_VMVN*/ 0x1,
5122 /*NEON_2RM_VPADAL*/ 0x7,
5123 /*NEON_2RM_VPADAL_U*/ 0x7,
5124 /*NEON_2RM_VQABS*/ 0x7,
5125 /*NEON_2RM_VQNEG*/ 0x7,
5126 /*NEON_2RM_VCGT0*/ 0x7,
5127 /*NEON_2RM_VCGE0*/ 0x7,
5128 /*NEON_2RM_VCEQ0*/ 0x7,
5129 /*NEON_2RM_VCLE0*/ 0x7,
5130 /*NEON_2RM_VCLT0*/ 0x7,
5131 /*NEON_2RM_SHA1H*/ 0x4,
5132 /*NEON_2RM_VABS*/ 0x7,
5133 /*NEON_2RM_VNEG*/ 0x7,
5134 /*NEON_2RM_VCGT0_F*/ 0x4,
5135 /*NEON_2RM_VCGE0_F*/ 0x4,
5136 /*NEON_2RM_VCEQ0_F*/ 0x4,
5137 /*NEON_2RM_VCLE0_F*/ 0x4,
5138 /*NEON_2RM_VCLT0_F*/ 0x4,
5139 0,
5140 /*NEON_2RM_VABS_F*/ 0x4,
5141 /*NEON_2RM_VNEG_F*/ 0x4,
5142 /*NEON_2RM_VSWP*/ 0x1,
5143 /*NEON_2RM_VTRN*/ 0x7,
5144 /*NEON_2RM_VUZP*/ 0x7,
5145 /*NEON_2RM_VZIP*/ 0x7,
5146 /*NEON_2RM_VMOVN*/ 0x7,
5147 /*NEON_2RM_VQMOVN*/ 0x7,
5148 /*NEON_2RM_VSHLL*/ 0x7,
5149 /*NEON_2RM_SHA1SU1*/ 0x4,
5150 /*NEON_2RM_VRINTN*/ 0x4,
5151 /*NEON_2RM_VRINTX*/ 0x4,
5152 /*NEON_2RM_VRINTA*/ 0x4,
5153 /*NEON_2RM_VRINTZ*/ 0x4,
5154 /*NEON_2RM_VCVT_F16_F32*/ 0x2,
5155 /*NEON_2RM_VRINTM*/ 0x4,
5156 /*NEON_2RM_VCVT_F32_F16*/ 0x2,
5157 /*NEON_2RM_VRINTP*/ 0x4,
5158 /*NEON_2RM_VCVTAU*/ 0x4,
5159 /*NEON_2RM_VCVTAS*/ 0x4,
5160 /*NEON_2RM_VCVTNU*/ 0x4,
5161 /*NEON_2RM_VCVTNS*/ 0x4,
5162 /*NEON_2RM_VCVTPU*/ 0x4,
5163 /*NEON_2RM_VCVTPS*/ 0x4,
5164 /*NEON_2RM_VCVTMU*/ 0x4,
5165 /*NEON_2RM_VCVTMS*/ 0x4,
5166 /*NEON_2RM_VRECPE*/ 0x4,
5167 /*NEON_2RM_VRSQRTE*/ 0x4,
5168 /*NEON_2RM_VRECPE_F*/ 0x4,
5169 /*NEON_2RM_VRSQRTE_F*/ 0x4,
5170 /*NEON_2RM_VCVT_FS*/ 0x4,
5171 /*NEON_2RM_VCVT_FU*/ 0x4,
5172 /*NEON_2RM_VCVT_SF*/ 0x4,
5173 /*NEON_2RM_VCVT_UF*/ 0x4,
5174 };
5175
5176 /* Translate a NEON data processing instruction. Return nonzero if the
5177 instruction is invalid.
5178 We process data in a mixture of 32-bit and 64-bit chunks.
5179 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5180
disas_neon_data_insn(DisasContext * s,uint32_t insn)5181 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5182 {
5183 TCGContext *tcg_ctx = s->uc->tcg_ctx;
5184 int op;
5185 int q;
5186 int rd, rn, rm;
5187 int size;
5188 int shift;
5189 int pass;
5190 int count;
5191 int pairwise;
5192 int u;
5193 uint32_t imm, mask;
5194 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5195 TCGv_i64 tmp64;
5196
5197 /* FIXME: this access check should not take precedence over UNDEF
5198 * for invalid encodings; we will generate incorrect syndrome information
5199 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5200 */
5201 if (!s->cpacr_fpen) {
5202 gen_exception_insn(s, 4, EXCP_UDEF,
5203 syn_fp_access_trap(1, 0xe, s->thumb));
5204 return 0;
5205 }
5206
5207 if (!s->vfp_enabled)
5208 return 1;
5209 q = (insn & (1 << 6)) != 0;
5210 u = (insn >> 24) & 1;
5211 VFP_DREG_D(rd, insn);
5212 VFP_DREG_N(rn, insn);
5213 VFP_DREG_M(rm, insn);
5214 size = (insn >> 20) & 3;
5215 if ((insn & (1 << 23)) == 0) {
5216 /* Three register same length. */
5217 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5218 /* Catch invalid op and bad size combinations: UNDEF */
5219 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5220 return 1;
5221 }
5222 /* All insns of this form UNDEF for either this condition or the
5223 * superset of cases "Q==1"; we catch the latter later.
5224 */
5225 if (q && ((rd | rn | rm) & 1)) {
5226 return 1;
5227 }
5228 /*
5229 * The SHA-1/SHA-256 3-register instructions require special treatment
5230 * here, as their size field is overloaded as an op type selector, and
5231 * they all consume their input in a single pass.
5232 */
5233 if (op == NEON_3R_SHA) {
5234 if (!q) {
5235 return 1;
5236 }
5237 if (!u) { /* SHA-1 */
5238 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5239 return 1;
5240 }
5241 tmp = tcg_const_i32(tcg_ctx, rd);
5242 tmp2 = tcg_const_i32(tcg_ctx, rn);
5243 tmp3 = tcg_const_i32(tcg_ctx, rm);
5244 tmp4 = tcg_const_i32(tcg_ctx, size);
5245 gen_helper_crypto_sha1_3reg(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3, tmp4);
5246 tcg_temp_free_i32(tcg_ctx, tmp4);
5247 } else { /* SHA-256 */
5248 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5249 return 1;
5250 }
5251 tmp = tcg_const_i32(tcg_ctx, rd);
5252 tmp2 = tcg_const_i32(tcg_ctx, rn);
5253 tmp3 = tcg_const_i32(tcg_ctx, rm);
5254 switch (size) {
5255 case 0:
5256 gen_helper_crypto_sha256h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5257 break;
5258 case 1:
5259 gen_helper_crypto_sha256h2(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5260 break;
5261 case 2:
5262 gen_helper_crypto_sha256su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5263 break;
5264 }
5265 }
5266 tcg_temp_free_i32(tcg_ctx, tmp);
5267 tcg_temp_free_i32(tcg_ctx, tmp2);
5268 tcg_temp_free_i32(tcg_ctx, tmp3);
5269 return 0;
5270 }
5271 if (size == 3 && op != NEON_3R_LOGIC) {
5272 /* 64-bit element instructions. */
5273 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5274 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + pass);
5275 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + pass);
5276 switch (op) {
5277 case NEON_3R_VQADD:
5278 if (u) {
5279 gen_helper_neon_qadd_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5280 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5281 } else {
5282 gen_helper_neon_qadd_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5283 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5284 }
5285 break;
5286 case NEON_3R_VQSUB:
5287 if (u) {
5288 gen_helper_neon_qsub_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5289 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5290 } else {
5291 gen_helper_neon_qsub_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5292 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5293 }
5294 break;
5295 case NEON_3R_VSHL:
5296 if (u) {
5297 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5298 } else {
5299 gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5300 }
5301 break;
5302 case NEON_3R_VQSHL:
5303 if (u) {
5304 gen_helper_neon_qshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5305 tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5306 } else {
5307 gen_helper_neon_qshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5308 tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5309 }
5310 break;
5311 case NEON_3R_VRSHL:
5312 if (u) {
5313 gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5314 } else {
5315 gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5316 }
5317 break;
5318 case NEON_3R_VQRSHL:
5319 if (u) {
5320 gen_helper_neon_qrshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5321 tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5322 } else {
5323 gen_helper_neon_qrshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5324 tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5325 }
5326 break;
5327 case NEON_3R_VADD_VSUB:
5328 if (u) {
5329 tcg_gen_sub_i64(tcg_ctx, CPU_V001);
5330 } else {
5331 tcg_gen_add_i64(tcg_ctx, CPU_V001);
5332 }
5333 break;
5334 default:
5335 abort();
5336 }
5337 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
5338 }
5339 return 0;
5340 }
5341 pairwise = 0;
5342 switch (op) {
5343 case NEON_3R_VSHL:
5344 case NEON_3R_VQSHL:
5345 case NEON_3R_VRSHL:
5346 case NEON_3R_VQRSHL:
5347 {
5348 int rtmp;
5349 /* Shift instruction operands are reversed. */
5350 rtmp = rn;
5351 rn = rm;
5352 rm = rtmp;
5353 }
5354 break;
5355 case NEON_3R_VPADD:
5356 if (u) {
5357 return 1;
5358 }
5359 /* Fall through */
5360 case NEON_3R_VPMAX:
5361 case NEON_3R_VPMIN:
5362 pairwise = 1;
5363 break;
5364 case NEON_3R_FLOAT_ARITH:
5365 pairwise = (u && size < 2); /* if VPADD (float) */
5366 break;
5367 case NEON_3R_FLOAT_MINMAX:
5368 pairwise = u; /* if VPMIN/VPMAX (float) */
5369 break;
5370 case NEON_3R_FLOAT_CMP:
5371 if (!u && size) {
5372 /* no encoding for U=0 C=1x */
5373 return 1;
5374 }
5375 break;
5376 case NEON_3R_FLOAT_ACMP:
5377 if (!u) {
5378 return 1;
5379 }
5380 break;
5381 case NEON_3R_FLOAT_MISC:
5382 /* VMAXNM/VMINNM in ARMv8 */
5383 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5384 return 1;
5385 }
5386 break;
5387 case NEON_3R_VMUL:
5388 if (u && (size != 0)) {
5389 /* UNDEF on invalid size for polynomial subcase */
5390 return 1;
5391 }
5392 break;
5393 case NEON_3R_VFM:
5394 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5395 return 1;
5396 }
5397 break;
5398 default:
5399 break;
5400 }
5401
5402 if (pairwise && q) {
5403 /* All the pairwise insns UNDEF if Q is set */
5404 return 1;
5405 }
5406
5407 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5408
5409 if (pairwise) {
5410 /* Pairwise. */
5411 if (pass < 1) {
5412 tmp = neon_load_reg(tcg_ctx, rn, 0);
5413 tmp2 = neon_load_reg(tcg_ctx, rn, 1);
5414 } else {
5415 tmp = neon_load_reg(tcg_ctx, rm, 0);
5416 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
5417 }
5418 } else {
5419 /* Elementwise. */
5420 tmp = neon_load_reg(tcg_ctx, rn, pass);
5421 tmp2 = neon_load_reg(tcg_ctx, rm, pass);
5422 }
5423 switch (op) {
5424 case NEON_3R_VHADD:
5425 GEN_NEON_INTEGER_OP(hadd);
5426 break;
5427 case NEON_3R_VQADD:
5428 GEN_NEON_INTEGER_OP_ENV(qadd);
5429 break;
5430 case NEON_3R_VRHADD:
5431 GEN_NEON_INTEGER_OP(rhadd);
5432 break;
5433 case NEON_3R_LOGIC: /* Logic ops. */
5434 switch ((u << 2) | size) {
5435 case 0: /* VAND */
5436 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
5437 break;
5438 case 1: /* BIC */
5439 tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
5440 break;
5441 case 2: /* VORR */
5442 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
5443 break;
5444 case 3: /* VORN */
5445 tcg_gen_orc_i32(tcg_ctx, tmp, tmp, tmp2);
5446 break;
5447 case 4: /* VEOR */
5448 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
5449 break;
5450 case 5: /* VBSL */
5451 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5452 gen_neon_bsl(s, tmp, tmp, tmp2, tmp3);
5453 tcg_temp_free_i32(tcg_ctx, tmp3);
5454 break;
5455 case 6: /* VBIT */
5456 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5457 gen_neon_bsl(s, tmp, tmp, tmp3, tmp2);
5458 tcg_temp_free_i32(tcg_ctx, tmp3);
5459 break;
5460 case 7: /* VBIF */
5461 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5462 gen_neon_bsl(s, tmp, tmp3, tmp, tmp2);
5463 tcg_temp_free_i32(tcg_ctx, tmp3);
5464 break;
5465 }
5466 break;
5467 case NEON_3R_VHSUB:
5468 GEN_NEON_INTEGER_OP(hsub);
5469 break;
5470 case NEON_3R_VQSUB:
5471 GEN_NEON_INTEGER_OP_ENV(qsub);
5472 break;
5473 case NEON_3R_VCGT:
5474 GEN_NEON_INTEGER_OP(cgt);
5475 break;
5476 case NEON_3R_VCGE:
5477 GEN_NEON_INTEGER_OP(cge);
5478 break;
5479 case NEON_3R_VSHL:
5480 GEN_NEON_INTEGER_OP(shl);
5481 break;
5482 case NEON_3R_VQSHL:
5483 GEN_NEON_INTEGER_OP_ENV(qshl);
5484 break;
5485 case NEON_3R_VRSHL:
5486 GEN_NEON_INTEGER_OP(rshl);
5487 break;
5488 case NEON_3R_VQRSHL:
5489 GEN_NEON_INTEGER_OP_ENV(qrshl);
5490 break;
5491 case NEON_3R_VMAX:
5492 GEN_NEON_INTEGER_OP(max);
5493 break;
5494 case NEON_3R_VMIN:
5495 GEN_NEON_INTEGER_OP(min);
5496 break;
5497 case NEON_3R_VABD:
5498 GEN_NEON_INTEGER_OP(abd);
5499 break;
5500 case NEON_3R_VABA:
5501 GEN_NEON_INTEGER_OP(abd);
5502 tcg_temp_free_i32(tcg_ctx, tmp2);
5503 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5504 gen_neon_add(s, size, tmp, tmp2);
5505 break;
5506 case NEON_3R_VADD_VSUB:
5507 if (!u) { /* VADD */
5508 gen_neon_add(s, size, tmp, tmp2);
5509 } else { /* VSUB */
5510 switch (size) {
5511 case 0: gen_helper_neon_sub_u8(tcg_ctx, tmp, tmp, tmp2); break;
5512 case 1: gen_helper_neon_sub_u16(tcg_ctx, tmp, tmp, tmp2); break;
5513 case 2: tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); break;
5514 default: abort();
5515 }
5516 }
5517 break;
5518 case NEON_3R_VTST_VCEQ:
5519 if (!u) { /* VTST */
5520 switch (size) {
5521 case 0: gen_helper_neon_tst_u8(tcg_ctx, tmp, tmp, tmp2); break;
5522 case 1: gen_helper_neon_tst_u16(tcg_ctx, tmp, tmp, tmp2); break;
5523 case 2: gen_helper_neon_tst_u32(tcg_ctx, tmp, tmp, tmp2); break;
5524 default: abort();
5525 }
5526 } else { /* VCEQ */
5527 switch (size) {
5528 case 0: gen_helper_neon_ceq_u8(tcg_ctx, tmp, tmp, tmp2); break;
5529 case 1: gen_helper_neon_ceq_u16(tcg_ctx, tmp, tmp, tmp2); break;
5530 case 2: gen_helper_neon_ceq_u32(tcg_ctx, tmp, tmp, tmp2); break;
5531 default: abort();
5532 }
5533 }
5534 break;
5535 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5536 switch (size) {
5537 case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
5538 case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
5539 case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
5540 default: abort();
5541 }
5542 tcg_temp_free_i32(tcg_ctx, tmp2);
5543 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5544 if (u) { /* VMLS */
5545 gen_neon_rsb(s, size, tmp, tmp2);
5546 } else { /* VMLA */
5547 gen_neon_add(s, size, tmp, tmp2);
5548 }
5549 break;
5550 case NEON_3R_VMUL:
5551 if (u) { /* polynomial */
5552 gen_helper_neon_mul_p8(tcg_ctx, tmp, tmp, tmp2);
5553 } else { /* Integer */
5554 switch (size) {
5555 case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
5556 case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
5557 case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
5558 default: abort();
5559 }
5560 }
5561 break;
5562 case NEON_3R_VPMAX:
5563 GEN_NEON_INTEGER_OP(pmax);
5564 break;
5565 case NEON_3R_VPMIN:
5566 GEN_NEON_INTEGER_OP(pmin);
5567 break;
5568 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5569 if (!u) { /* VQDMULH */
5570 switch (size) {
5571 case 1:
5572 gen_helper_neon_qdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5573 break;
5574 case 2:
5575 gen_helper_neon_qdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5576 break;
5577 default: abort();
5578 }
5579 } else { /* VQRDMULH */
5580 switch (size) {
5581 case 1:
5582 gen_helper_neon_qrdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5583 break;
5584 case 2:
5585 gen_helper_neon_qrdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5586 break;
5587 default: abort();
5588 }
5589 }
5590 break;
5591 case NEON_3R_VPADD:
5592 switch (size) {
5593 case 0: gen_helper_neon_padd_u8(tcg_ctx, tmp, tmp, tmp2); break;
5594 case 1: gen_helper_neon_padd_u16(tcg_ctx, tmp, tmp, tmp2); break;
5595 case 2: tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2); break;
5596 default: abort();
5597 }
5598 break;
5599 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5600 {
5601 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5602 switch ((u << 2) | size) {
5603 case 0: /* VADD */
5604 case 4: /* VPADD */
5605 gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5606 break;
5607 case 2: /* VSUB */
5608 gen_helper_vfp_subs(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5609 break;
5610 case 6: /* VABD */
5611 gen_helper_neon_abd_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5612 break;
5613 default:
5614 abort();
5615 }
5616 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5617 break;
5618 }
5619 case NEON_3R_FLOAT_MULTIPLY:
5620 {
5621 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5622 gen_helper_vfp_muls(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5623 if (!u) {
5624 tcg_temp_free_i32(tcg_ctx, tmp2);
5625 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5626 if (size == 0) {
5627 gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5628 } else {
5629 gen_helper_vfp_subs(tcg_ctx, tmp, tmp2, tmp, fpstatus);
5630 }
5631 }
5632 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5633 break;
5634 }
5635 case NEON_3R_FLOAT_CMP:
5636 {
5637 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5638 if (!u) {
5639 gen_helper_neon_ceq_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5640 } else {
5641 if (size == 0) {
5642 gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5643 } else {
5644 gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5645 }
5646 }
5647 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5648 break;
5649 }
5650 case NEON_3R_FLOAT_ACMP:
5651 {
5652 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5653 if (size == 0) {
5654 gen_helper_neon_acge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5655 } else {
5656 gen_helper_neon_acgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5657 }
5658 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5659 break;
5660 }
5661 case NEON_3R_FLOAT_MINMAX:
5662 {
5663 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5664 if (size == 0) {
5665 gen_helper_vfp_maxs(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5666 } else {
5667 gen_helper_vfp_mins(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5668 }
5669 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5670 break;
5671 }
5672 case NEON_3R_FLOAT_MISC:
5673 if (u) {
5674 /* VMAXNM/VMINNM */
5675 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5676 if (size == 0) {
5677 gen_helper_vfp_maxnums(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5678 } else {
5679 gen_helper_vfp_minnums(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5680 }
5681 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5682 } else {
5683 if (size == 0) {
5684 gen_helper_recps_f32(tcg_ctx, tmp, tmp, tmp2, tcg_ctx->cpu_env);
5685 } else {
5686 gen_helper_rsqrts_f32(tcg_ctx, tmp, tmp, tmp2, tcg_ctx->cpu_env);
5687 }
5688 }
5689 break;
5690 case NEON_3R_VFM:
5691 {
5692 /* VFMA, VFMS: fused multiply-add */
5693 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5694 TCGv_i32 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5695 if (size) {
5696 /* VFMS */
5697 gen_helper_vfp_negs(tcg_ctx, tmp, tmp);
5698 }
5699 gen_helper_vfp_muladds(tcg_ctx, tmp, tmp, tmp2, tmp3, fpstatus);
5700 tcg_temp_free_i32(tcg_ctx, tmp3);
5701 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5702 break;
5703 }
5704 default:
5705 abort();
5706 }
5707 tcg_temp_free_i32(tcg_ctx, tmp2);
5708
5709 /* Save the result. For elementwise operations we can put it
5710 straight into the destination register. For pairwise operations
5711 we have to be careful to avoid clobbering the source operands. */
5712 if (pairwise && rd == rm) {
5713 neon_store_scratch(tcg_ctx, pass, tmp);
5714 } else {
5715 neon_store_reg(tcg_ctx, rd, pass, tmp);
5716 }
5717
5718 } /* for pass */
5719 if (pairwise && rd == rm) {
5720 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5721 tmp = neon_load_scratch(tcg_ctx, pass);
5722 neon_store_reg(tcg_ctx, rd, pass, tmp);
5723 }
5724 }
5725 /* End of 3 register same size operations. */
5726 } else if (insn & (1 << 4)) {
5727 if ((insn & 0x00380080) != 0) {
5728 /* Two registers and shift. */
5729 op = (insn >> 8) & 0xf;
5730 if (insn & (1 << 7)) {
5731 /* 64-bit shift. */
5732 if (op > 7) {
5733 return 1;
5734 }
5735 size = 3;
5736 } else {
5737 size = 2;
5738 while ((insn & (1 << (size + 19))) == 0)
5739 size--;
5740 }
5741 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5742 /* To avoid excessive duplication of ops we implement shift
5743 by immediate using the variable shift operations. */
5744 if (op < 8) {
5745 /* Shift by immediate:
5746 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5747 if (q && ((rd | rm) & 1)) {
5748 return 1;
5749 }
5750 if (!u && (op == 4 || op == 6)) {
5751 return 1;
5752 }
5753 /* Right shifts are encoded as N - shift, where N is the
5754 element size in bits. */
5755 if (op <= 4)
5756 shift = shift - (1 << (size + 3));
5757 if (size == 3) {
5758 count = q + 1;
5759 } else {
5760 count = q ? 4: 2;
5761 }
5762 switch (size) {
5763 case 0:
5764 imm = (uint8_t) shift;
5765 imm |= imm << 8;
5766 imm |= imm << 16;
5767 break;
5768 case 1:
5769 imm = (uint16_t) shift;
5770 imm |= imm << 16;
5771 break;
5772 case 2:
5773 case 3:
5774 imm = shift;
5775 break;
5776 default:
5777 abort();
5778 }
5779
5780 for (pass = 0; pass < count; pass++) {
5781 if (size == 3) {
5782 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm + pass);
5783 tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_V1, imm);
5784 switch (op) {
5785 case 0: /* VSHR */
5786 case 1: /* VSRA */
5787 if (u)
5788 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5789 else
5790 gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5791 break;
5792 case 2: /* VRSHR */
5793 case 3: /* VRSRA */
5794 if (u)
5795 gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5796 else
5797 gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5798 break;
5799 case 4: /* VSRI */
5800 case 5: /* VSHL, VSLI */
5801 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5802 break;
5803 case 6: /* VQSHLU */
5804 gen_helper_neon_qshlu_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5805 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5806 break;
5807 case 7: /* VQSHL */
5808 if (u) {
5809 gen_helper_neon_qshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5810 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5811 } else {
5812 gen_helper_neon_qshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5813 tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5814 }
5815 break;
5816 }
5817 if (op == 1 || op == 3) {
5818 /* Accumulate. */
5819 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
5820 tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5821 } else if (op == 4 || (op == 5 && u)) {
5822 /* Insert */
5823 uint64_t mask;
5824 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
5825 if (shift < -63 || shift > 63) {
5826 mask = 0;
5827 } else {
5828 if (op == 4) {
5829 mask = 0xffffffffffffffffull >> -shift;
5830 } else {
5831 mask = 0xffffffffffffffffull << shift;
5832 }
5833 }
5834 tcg_gen_andi_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, ~mask);
5835 tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5836 }
5837 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
5838 } else { /* size < 3 */
5839 /* Operands in T0 and T1. */
5840 tmp = neon_load_reg(tcg_ctx, rm, pass);
5841 tmp2 = tcg_temp_new_i32(tcg_ctx);
5842 tcg_gen_movi_i32(tcg_ctx, tmp2, imm);
5843 switch (op) {
5844 case 0: /* VSHR */
5845 case 1: /* VSRA */
5846 GEN_NEON_INTEGER_OP(shl);
5847 break;
5848 case 2: /* VRSHR */
5849 case 3: /* VRSRA */
5850 GEN_NEON_INTEGER_OP(rshl);
5851 break;
5852 case 4: /* VSRI */
5853 case 5: /* VSHL, VSLI */
5854 switch (size) {
5855 case 0: gen_helper_neon_shl_u8(tcg_ctx, tmp, tmp, tmp2); break;
5856 case 1: gen_helper_neon_shl_u16(tcg_ctx, tmp, tmp, tmp2); break;
5857 case 2: gen_helper_neon_shl_u32(tcg_ctx, tmp, tmp, tmp2); break;
5858 default: abort();
5859 }
5860 break;
5861 case 6: /* VQSHLU */
5862 switch (size) {
5863 case 0:
5864 gen_helper_neon_qshlu_s8(tcg_ctx, tmp, tcg_ctx->cpu_env,
5865 tmp, tmp2);
5866 break;
5867 case 1:
5868 gen_helper_neon_qshlu_s16(tcg_ctx, tmp, tcg_ctx->cpu_env,
5869 tmp, tmp2);
5870 break;
5871 case 2:
5872 gen_helper_neon_qshlu_s32(tcg_ctx, tmp, tcg_ctx->cpu_env,
5873 tmp, tmp2);
5874 break;
5875 default:
5876 abort();
5877 }
5878 break;
5879 case 7: /* VQSHL */
5880 GEN_NEON_INTEGER_OP_ENV(qshl);
5881 break;
5882 }
5883 tcg_temp_free_i32(tcg_ctx, tmp2);
5884
5885 if (op == 1 || op == 3) {
5886 /* Accumulate. */
5887 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5888 gen_neon_add(s, size, tmp, tmp2);
5889 tcg_temp_free_i32(tcg_ctx, tmp2);
5890 } else if (op == 4 || (op == 5 && u)) {
5891 /* Insert */
5892 switch (size) {
5893 case 0:
5894 if (op == 4)
5895 mask = 0xff >> -shift;
5896 else
5897 mask = (uint8_t)(0xff << shift);
5898 mask |= mask << 8;
5899 mask |= mask << 16;
5900 break;
5901 case 1:
5902 if (op == 4)
5903 mask = 0xffff >> -shift;
5904 else
5905 mask = (uint16_t)(0xffff << shift);
5906 mask |= mask << 16;
5907 break;
5908 case 2:
5909 if (shift < -31 || shift > 31) {
5910 mask = 0;
5911 } else {
5912 if (op == 4)
5913 mask = 0xffffffffu >> -shift;
5914 else
5915 mask = 0xffffffffu << shift;
5916 }
5917 break;
5918 default:
5919 abort();
5920 }
5921 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5922 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, mask);
5923 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, ~mask);
5924 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
5925 tcg_temp_free_i32(tcg_ctx, tmp2);
5926 }
5927 neon_store_reg(tcg_ctx, rd, pass, tmp);
5928 }
5929 } /* for pass */
5930 } else if (op < 10) {
5931 /* Shift by immediate and narrow:
5932 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5933 int input_unsigned = (op == 8) ? !u : u;
5934 if (rm & 1) {
5935 return 1;
5936 }
5937 shift = shift - (1 << (size + 3));
5938 size++;
5939 if (size == 3) {
5940 tmp64 = tcg_const_i64(tcg_ctx, shift);
5941 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm);
5942 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + 1);
5943 for (pass = 0; pass < 2; pass++) {
5944 TCGv_i64 in;
5945 if (pass == 0) {
5946 in = tcg_ctx->cpu_V0;
5947 } else {
5948 in = tcg_ctx->cpu_V1;
5949 }
5950 if (q) {
5951 if (input_unsigned) {
5952 gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5953 } else {
5954 gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5955 }
5956 } else {
5957 if (input_unsigned) {
5958 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5959 } else {
5960 gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5961 }
5962 }
5963 tmp = tcg_temp_new_i32(tcg_ctx);
5964 gen_neon_narrow_op(s, op == 8, u, size - 1, tmp, tcg_ctx->cpu_V0);
5965 neon_store_reg(tcg_ctx, rd, pass, tmp);
5966 } /* for pass */
5967 tcg_temp_free_i64(tcg_ctx, tmp64);
5968 } else {
5969 if (size == 1) {
5970 imm = (uint16_t)shift;
5971 imm |= imm << 16;
5972 } else {
5973 /* size == 2 */
5974 imm = (uint32_t)shift;
5975 }
5976 tmp2 = tcg_const_i32(tcg_ctx, imm);
5977 tmp4 = neon_load_reg(tcg_ctx, rm + 1, 0);
5978 tmp5 = neon_load_reg(tcg_ctx, rm + 1, 1);
5979 for (pass = 0; pass < 2; pass++) {
5980 if (pass == 0) {
5981 tmp = neon_load_reg(tcg_ctx, rm, 0);
5982 } else {
5983 tmp = tmp4;
5984 }
5985 gen_neon_shift_narrow(s, size, tmp, tmp2, q,
5986 input_unsigned);
5987 if (pass == 0) {
5988 tmp3 = neon_load_reg(tcg_ctx, rm, 1);
5989 } else {
5990 tmp3 = tmp5;
5991 }
5992 gen_neon_shift_narrow(s, size, tmp3, tmp2, q,
5993 input_unsigned);
5994 tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp3);
5995 tcg_temp_free_i32(tcg_ctx, tmp);
5996 tcg_temp_free_i32(tcg_ctx, tmp3);
5997 tmp = tcg_temp_new_i32(tcg_ctx);
5998 gen_neon_narrow_op(s, op == 8, u, size - 1, tmp, tcg_ctx->cpu_V0);
5999 neon_store_reg(tcg_ctx, rd, pass, tmp);
6000 } /* for pass */
6001 tcg_temp_free_i32(tcg_ctx, tmp2);
6002 }
6003 } else if (op == 10) {
6004 /* VSHLL, VMOVL */
6005 if (q || (rd & 1)) {
6006 return 1;
6007 }
6008 tmp = neon_load_reg(tcg_ctx, rm, 0);
6009 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6010 for (pass = 0; pass < 2; pass++) {
6011 if (pass == 1)
6012 tmp = tmp2;
6013
6014 gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, u);
6015
6016 if (shift != 0) {
6017 /* The shift is less than the width of the source
6018 type, so we can just shift the whole register. */
6019 tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, shift);
6020 /* Widen the result of shift: we need to clear
6021 * the potential overflow bits resulting from
6022 * left bits of the narrow input appearing as
6023 * right bits of left the neighbour narrow
6024 * input. */
6025 if (size < 2 || !u) {
6026 uint64_t imm64;
6027 if (size == 0) {
6028 imm = (0xffu >> (8 - shift));
6029 imm |= imm << 16;
6030 } else if (size == 1) {
6031 imm = 0xffff >> (16 - shift);
6032 } else {
6033 /* size == 2 */
6034 imm = 0xffffffff >> (32 - shift);
6035 }
6036 if (size < 2) {
6037 imm64 = imm | (((uint64_t)imm) << 32);
6038 } else {
6039 imm64 = imm;
6040 }
6041 tcg_gen_andi_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, ~imm64);
6042 }
6043 }
6044 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6045 }
6046 } else if (op >= 14) {
6047 /* VCVT fixed-point. */
6048 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6049 return 1;
6050 }
6051 /* We have already masked out the must-be-1 top bit of imm6,
6052 * hence this 32-shift where the ARM ARM has 64-imm6.
6053 */
6054 shift = 32 - shift;
6055 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6056 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, pass));
6057 if (!(op & 1)) {
6058 if (u)
6059 gen_vfp_ulto(s, 0, shift, 1);
6060 else
6061 gen_vfp_slto(s, 0, shift, 1);
6062 } else {
6063 if (u)
6064 gen_vfp_toul(s, 0, shift, 1);
6065 else
6066 gen_vfp_tosl(s, 0, shift, 1);
6067 }
6068 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, pass));
6069 }
6070 } else {
6071 return 1;
6072 }
6073 } else { /* (insn & 0x00380080) == 0 */
6074 int invert;
6075 if (q && (rd & 1)) {
6076 return 1;
6077 }
6078
6079 op = (insn >> 8) & 0xf;
6080 /* One register and immediate. */
6081 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6082 invert = (insn & (1 << 5)) != 0;
6083 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6084 * We choose to not special-case this and will behave as if a
6085 * valid constant encoding of 0 had been given.
6086 */
6087 switch (op) {
6088 case 0: case 1:
6089 /* no-op */
6090 break;
6091 case 2: case 3:
6092 imm <<= 8;
6093 break;
6094 case 4: case 5:
6095 imm <<= 16;
6096 break;
6097 case 6: case 7:
6098 imm <<= 24;
6099 break;
6100 case 8: case 9:
6101 imm |= imm << 16;
6102 break;
6103 case 10: case 11:
6104 imm = (imm << 8) | (imm << 24);
6105 break;
6106 case 12:
6107 imm = (imm << 8) | 0xff;
6108 break;
6109 case 13:
6110 imm = (imm << 16) | 0xffff;
6111 break;
6112 case 14:
6113 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6114 if (invert)
6115 imm = ~imm;
6116 break;
6117 case 15:
6118 if (invert) {
6119 return 1;
6120 }
6121 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6122 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6123 break;
6124 }
6125 if (invert)
6126 imm = ~imm;
6127
6128 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6129 if (op & 1 && op < 12) {
6130 tmp = neon_load_reg(tcg_ctx, rd, pass);
6131 if (invert) {
6132 /* The immediate value has already been inverted, so
6133 BIC becomes AND. */
6134 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, imm);
6135 } else {
6136 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, imm);
6137 }
6138 } else {
6139 /* VMOV, VMVN. */
6140 tmp = tcg_temp_new_i32(tcg_ctx);
6141 if (op == 14 && invert) {
6142 int n;
6143 uint32_t val;
6144 val = 0;
6145 for (n = 0; n < 4; n++) {
6146 if (imm & (1 << (n + (pass & 1) * 4)))
6147 val |= 0xffU << (n * 8);
6148 }
6149 tcg_gen_movi_i32(tcg_ctx, tmp, val);
6150 } else {
6151 tcg_gen_movi_i32(tcg_ctx, tmp, imm);
6152 }
6153 }
6154 neon_store_reg(tcg_ctx, rd, pass, tmp);
6155 }
6156 }
6157 } else { /* (insn & 0x00800010 == 0x00800000) */
6158 if (size != 3) {
6159 op = (insn >> 8) & 0xf;
6160 if ((insn & (1 << 6)) == 0) {
6161 /* Three registers of different lengths. */
6162 int src1_wide;
6163 int src2_wide;
6164 int prewiden;
6165 /* undefreq: bit 0 : UNDEF if size == 0
6166 * bit 1 : UNDEF if size == 1
6167 * bit 2 : UNDEF if size == 2
6168 * bit 3 : UNDEF if U == 1
6169 * Note that [2:0] set implies 'always UNDEF'
6170 */
6171 int undefreq;
6172 /* prewiden, src1_wide, src2_wide, undefreq */
6173 static const int neon_3reg_wide[16][4] = {
6174 {1, 0, 0, 0}, /* VADDL */
6175 {1, 1, 0, 0}, /* VADDW */
6176 {1, 0, 0, 0}, /* VSUBL */
6177 {1, 1, 0, 0}, /* VSUBW */
6178 {0, 1, 1, 0}, /* VADDHN */
6179 {0, 0, 0, 0}, /* VABAL */
6180 {0, 1, 1, 0}, /* VSUBHN */
6181 {0, 0, 0, 0}, /* VABDL */
6182 {0, 0, 0, 0}, /* VMLAL */
6183 {0, 0, 0, 9}, /* VQDMLAL */
6184 {0, 0, 0, 0}, /* VMLSL */
6185 {0, 0, 0, 9}, /* VQDMLSL */
6186 {0, 0, 0, 0}, /* Integer VMULL */
6187 {0, 0, 0, 1}, /* VQDMULL */
6188 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6189 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6190 };
6191
6192 prewiden = neon_3reg_wide[op][0];
6193 src1_wide = neon_3reg_wide[op][1];
6194 src2_wide = neon_3reg_wide[op][2];
6195 undefreq = neon_3reg_wide[op][3];
6196
6197 if ((undefreq & (1 << size)) ||
6198 ((undefreq & 8) && u)) {
6199 return 1;
6200 }
6201 if ((src1_wide && (rn & 1)) ||
6202 (src2_wide && (rm & 1)) ||
6203 (!src2_wide && (rd & 1))) {
6204 return 1;
6205 }
6206
6207 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6208 * outside the loop below as it only performs a single pass.
6209 */
6210 if (op == 14 && size == 2) {
6211 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6212
6213 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6214 return 1;
6215 }
6216 tcg_rn = tcg_temp_new_i64(tcg_ctx);
6217 tcg_rm = tcg_temp_new_i64(tcg_ctx);
6218 tcg_rd = tcg_temp_new_i64(tcg_ctx);
6219 neon_load_reg64(tcg_ctx, tcg_rn, rn);
6220 neon_load_reg64(tcg_ctx, tcg_rm, rm);
6221 gen_helper_neon_pmull_64_lo(tcg_ctx, tcg_rd, tcg_rn, tcg_rm);
6222 neon_store_reg64(tcg_ctx, tcg_rd, rd);
6223 gen_helper_neon_pmull_64_hi(tcg_ctx, tcg_rd, tcg_rn, tcg_rm);
6224 neon_store_reg64(tcg_ctx, tcg_rd, rd + 1);
6225 tcg_temp_free_i64(tcg_ctx, tcg_rn);
6226 tcg_temp_free_i64(tcg_ctx, tcg_rm);
6227 tcg_temp_free_i64(tcg_ctx, tcg_rd);
6228 return 0;
6229 }
6230
6231 /* Avoid overlapping operands. Wide source operands are
6232 always aligned so will never overlap with wide
6233 destinations in problematic ways. */
6234 if (rd == rm && !src2_wide) {
6235 tmp = neon_load_reg(tcg_ctx, rm, 1);
6236 neon_store_scratch(tcg_ctx, 2, tmp);
6237 } else if (rd == rn && !src1_wide) {
6238 tmp = neon_load_reg(tcg_ctx, rn, 1);
6239 neon_store_scratch(tcg_ctx, 2, tmp);
6240 }
6241 TCGV_UNUSED_I32(tmp3);
6242 for (pass = 0; pass < 2; pass++) {
6243 if (src1_wide) {
6244 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + pass);
6245 TCGV_UNUSED_I32(tmp);
6246 } else {
6247 if (pass == 1 && rd == rn) {
6248 tmp = neon_load_scratch(tcg_ctx, 2);
6249 } else {
6250 tmp = neon_load_reg(tcg_ctx, rn, pass);
6251 }
6252 if (prewiden) {
6253 gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, u);
6254 }
6255 }
6256 if (src2_wide) {
6257 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + pass);
6258 TCGV_UNUSED_I32(tmp2);
6259 } else {
6260 if (pass == 1 && rd == rm) {
6261 tmp2 = neon_load_scratch(tcg_ctx, 2);
6262 } else {
6263 tmp2 = neon_load_reg(tcg_ctx, rm, pass);
6264 }
6265 if (prewiden) {
6266 gen_neon_widen(s, tcg_ctx->cpu_V1, tmp2, size, u);
6267 }
6268 }
6269 switch (op) {
6270 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6271 gen_neon_addl(s, size);
6272 break;
6273 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6274 gen_neon_subl(s, size);
6275 break;
6276 case 5: case 7: /* VABAL, VABDL */
6277 switch ((size << 1) | u) {
6278 case 0:
6279 gen_helper_neon_abdl_s16(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6280 break;
6281 case 1:
6282 gen_helper_neon_abdl_u16(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6283 break;
6284 case 2:
6285 gen_helper_neon_abdl_s32(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6286 break;
6287 case 3:
6288 gen_helper_neon_abdl_u32(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6289 break;
6290 case 4:
6291 gen_helper_neon_abdl_s64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6292 break;
6293 case 5:
6294 gen_helper_neon_abdl_u64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6295 break;
6296 default: abort();
6297 }
6298 tcg_temp_free_i32(tcg_ctx, tmp2);
6299 tcg_temp_free_i32(tcg_ctx, tmp);
6300 break;
6301 case 8: case 9: case 10: case 11: case 12: case 13:
6302 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6303 gen_neon_mull(s, tcg_ctx->cpu_V0, tmp, tmp2, size, u);
6304 break;
6305 case 14: /* Polynomial VMULL */
6306 gen_helper_neon_mull_p8(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6307 tcg_temp_free_i32(tcg_ctx, tmp2);
6308 tcg_temp_free_i32(tcg_ctx, tmp);
6309 break;
6310 default: /* 15 is RESERVED: caught earlier */
6311 abort();
6312 }
6313 if (op == 13) {
6314 /* VQDMULL */
6315 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6316 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6317 } else if (op == 5 || (op >= 8 && op <= 11)) {
6318 /* Accumulate. */
6319 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6320 switch (op) {
6321 case 10: /* VMLSL */
6322 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6323 /* Fall through */
6324 case 5: case 8: /* VABAL, VMLAL */
6325 gen_neon_addl(s, size);
6326 break;
6327 case 9: case 11: /* VQDMLAL, VQDMLSL */
6328 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6329 if (op == 11) {
6330 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6331 }
6332 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, size);
6333 break;
6334 default:
6335 abort();
6336 }
6337 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6338 } else if (op == 4 || op == 6) {
6339 /* Narrowing operation. */
6340 tmp = tcg_temp_new_i32(tcg_ctx);
6341 if (!u) {
6342 switch (size) {
6343 case 0:
6344 gen_helper_neon_narrow_high_u8(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6345 break;
6346 case 1:
6347 gen_helper_neon_narrow_high_u16(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6348 break;
6349 case 2:
6350 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
6351 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6352 break;
6353 default: abort();
6354 }
6355 } else {
6356 switch (size) {
6357 case 0:
6358 gen_helper_neon_narrow_round_high_u8(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6359 break;
6360 case 1:
6361 gen_helper_neon_narrow_round_high_u16(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6362 break;
6363 case 2:
6364 tcg_gen_addi_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 1u << 31);
6365 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
6366 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6367 break;
6368 default: abort();
6369 }
6370 }
6371 if (pass == 0) {
6372 tmp3 = tmp;
6373 } else {
6374 neon_store_reg(tcg_ctx, rd, 0, tmp3);
6375 neon_store_reg(tcg_ctx, rd, 1, tmp);
6376 }
6377 } else {
6378 /* Write back the result. */
6379 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6380 }
6381 }
6382 } else {
6383 /* Two registers and a scalar. NB that for ops of this form
6384 * the ARM ARM labels bit 24 as Q, but it is in our variable
6385 * 'u', not 'q'.
6386 */
6387 if (size == 0) {
6388 return 1;
6389 }
6390 switch (op) {
6391 case 1: /* Float VMLA scalar */
6392 case 5: /* Floating point VMLS scalar */
6393 case 9: /* Floating point VMUL scalar */
6394 if (size == 1) {
6395 return 1;
6396 }
6397 /* fall through */
6398 case 0: /* Integer VMLA scalar */
6399 case 4: /* Integer VMLS scalar */
6400 case 8: /* Integer VMUL scalar */
6401 case 12: /* VQDMULH scalar */
6402 case 13: /* VQRDMULH scalar */
6403 if (u && ((rd | rn) & 1)) {
6404 return 1;
6405 }
6406 tmp = neon_get_scalar(s, size, rm);
6407 neon_store_scratch(tcg_ctx, 0, tmp);
6408 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6409 tmp = neon_load_scratch(tcg_ctx, 0);
6410 tmp2 = neon_load_reg(tcg_ctx, rn, pass);
6411 if (op == 12) {
6412 if (size == 1) {
6413 gen_helper_neon_qdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6414 } else {
6415 gen_helper_neon_qdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6416 }
6417 } else if (op == 13) {
6418 if (size == 1) {
6419 gen_helper_neon_qrdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6420 } else {
6421 gen_helper_neon_qrdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6422 }
6423 } else if (op & 1) {
6424 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6425 gen_helper_vfp_muls(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6426 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6427 } else {
6428 switch (size) {
6429 case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
6430 case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
6431 case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
6432 default: abort();
6433 }
6434 }
6435 tcg_temp_free_i32(tcg_ctx, tmp2);
6436 if (op < 8) {
6437 /* Accumulate. */
6438 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6439 switch (op) {
6440 case 0:
6441 gen_neon_add(s, size, tmp, tmp2);
6442 break;
6443 case 1:
6444 {
6445 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6446 gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6447 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6448 break;
6449 }
6450 case 4:
6451 gen_neon_rsb(s, size, tmp, tmp2);
6452 break;
6453 case 5:
6454 {
6455 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6456 gen_helper_vfp_subs(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6457 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6458 break;
6459 }
6460 default:
6461 abort();
6462 }
6463 tcg_temp_free_i32(tcg_ctx, tmp2);
6464 }
6465 neon_store_reg(tcg_ctx, rd, pass, tmp);
6466 }
6467 break;
6468 case 3: /* VQDMLAL scalar */
6469 case 7: /* VQDMLSL scalar */
6470 case 11: /* VQDMULL scalar */
6471 if (u == 1) {
6472 return 1;
6473 }
6474 /* fall through */
6475 case 2: /* VMLAL sclar */
6476 case 6: /* VMLSL scalar */
6477 case 10: /* VMULL scalar */
6478 if (rd & 1) {
6479 return 1;
6480 }
6481 tmp2 = neon_get_scalar(s, size, rm);
6482 /* We need a copy of tmp2 because gen_neon_mull
6483 * deletes it during pass 0. */
6484 tmp4 = tcg_temp_new_i32(tcg_ctx);
6485 tcg_gen_mov_i32(tcg_ctx, tmp4, tmp2);
6486 tmp3 = neon_load_reg(tcg_ctx, rn, 1);
6487
6488 for (pass = 0; pass < 2; pass++) {
6489 if (pass == 0) {
6490 tmp = neon_load_reg(tcg_ctx, rn, 0);
6491 } else {
6492 tmp = tmp3;
6493 tmp2 = tmp4;
6494 }
6495 gen_neon_mull(s, tcg_ctx->cpu_V0, tmp, tmp2, size, u);
6496 if (op != 11) {
6497 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6498 }
6499 switch (op) {
6500 case 6:
6501 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6502 /* Fall through */
6503 case 2:
6504 gen_neon_addl(s, size);
6505 break;
6506 case 3: case 7:
6507 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6508 if (op == 7) {
6509 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6510 }
6511 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, size);
6512 break;
6513 case 10:
6514 /* no-op */
6515 break;
6516 case 11:
6517 gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6518 break;
6519 default:
6520 abort();
6521 }
6522 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6523 }
6524
6525
6526 break;
6527 default: /* 14 and 15 are RESERVED */
6528 return 1;
6529 }
6530 }
6531 } else { /* size == 3 */
6532 if (!u) {
6533 /* Extract. */
6534 imm = (insn >> 8) & 0xf;
6535
6536 if (imm > 7 && !q)
6537 return 1;
6538
6539 if (q && ((rd | rn | rm) & 1)) {
6540 return 1;
6541 }
6542
6543 if (imm == 0) {
6544 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6545 if (q) {
6546 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rn + 1);
6547 }
6548 } else if (imm == 8) {
6549 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + 1);
6550 if (q) {
6551 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6552 }
6553 } else if (q) {
6554 tmp64 = tcg_temp_new_i64(tcg_ctx);
6555 if (imm < 8) {
6556 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6557 neon_load_reg64(tcg_ctx, tmp64, rn + 1);
6558 } else {
6559 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + 1);
6560 neon_load_reg64(tcg_ctx, tmp64, rm);
6561 }
6562 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, (imm & 7) * 8);
6563 tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6564 tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
6565 if (imm < 8) {
6566 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6567 } else {
6568 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + 1);
6569 imm -= 8;
6570 }
6571 tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, 64 - (imm * 8));
6572 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, imm * 8);
6573 tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, tmp64);
6574 tcg_temp_free_i64(tcg_ctx, tmp64);
6575 } else {
6576 /* BUGFIX */
6577 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6578 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, imm * 8);
6579 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6580 tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, 64 - (imm * 8));
6581 tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
6582 }
6583 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd);
6584 if (q) {
6585 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + 1);
6586 }
6587 } else if ((insn & (1 << 11)) == 0) {
6588 /* Two register misc. */
6589 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6590 size = (insn >> 18) & 3;
6591 /* UNDEF for unknown op values and bad op-size combinations */
6592 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6593 return 1;
6594 }
6595 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6596 q && ((rm | rd) & 1)) {
6597 return 1;
6598 }
6599 switch (op) {
6600 case NEON_2RM_VREV64:
6601 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6602 tmp = neon_load_reg(tcg_ctx, rm, pass * 2);
6603 tmp2 = neon_load_reg(tcg_ctx, rm, pass * 2 + 1);
6604 switch (size) {
6605 case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
6606 case 1: gen_swap_half(s, tmp); break;
6607 case 2: /* no-op */ break;
6608 default: abort();
6609 }
6610 neon_store_reg(tcg_ctx, rd, pass * 2 + 1, tmp);
6611 if (size == 2) {
6612 neon_store_reg(tcg_ctx, rd, pass * 2, tmp2);
6613 } else {
6614 switch (size) {
6615 case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp2, tmp2); break;
6616 case 1: gen_swap_half(s, tmp2); break;
6617 default: abort();
6618 }
6619 neon_store_reg(tcg_ctx, rd, pass * 2, tmp2);
6620 }
6621 }
6622 break;
6623 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6624 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6625 for (pass = 0; pass < q + 1; pass++) {
6626 tmp = neon_load_reg(tcg_ctx, rm, pass * 2);
6627 gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, op & 1);
6628 tmp = neon_load_reg(tcg_ctx, rm, pass * 2 + 1);
6629 gen_neon_widen(s, tcg_ctx->cpu_V1, tmp, size, op & 1);
6630 switch (size) {
6631 case 0: gen_helper_neon_paddl_u16(tcg_ctx, CPU_V001); break;
6632 case 1: gen_helper_neon_paddl_u32(tcg_ctx, CPU_V001); break;
6633 case 2: tcg_gen_add_i64(tcg_ctx, CPU_V001); break;
6634 default: abort();
6635 }
6636 if (op >= NEON_2RM_VPADAL) {
6637 /* Accumulate. */
6638 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6639 gen_neon_addl(s, size);
6640 }
6641 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6642 }
6643 break;
6644 case NEON_2RM_VTRN:
6645 if (size == 2) {
6646 int n;
6647 for (n = 0; n < (q ? 4 : 2); n += 2) {
6648 tmp = neon_load_reg(tcg_ctx, rm, n);
6649 tmp2 = neon_load_reg(tcg_ctx, rd, n + 1);
6650 neon_store_reg(tcg_ctx, rm, n, tmp2);
6651 neon_store_reg(tcg_ctx, rd, n + 1, tmp);
6652 }
6653 } else {
6654 goto elementwise;
6655 }
6656 break;
6657 case NEON_2RM_VUZP:
6658 if (gen_neon_unzip(tcg_ctx, rd, rm, size, q)) {
6659 return 1;
6660 }
6661 break;
6662 case NEON_2RM_VZIP:
6663 if (gen_neon_zip(tcg_ctx, rd, rm, size, q)) {
6664 return 1;
6665 }
6666 break;
6667 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6668 /* also VQMOVUN; op field and mnemonics don't line up */
6669 if (rm & 1) {
6670 return 1;
6671 }
6672 TCGV_UNUSED_I32(tmp2);
6673 for (pass = 0; pass < 2; pass++) {
6674 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm + pass);
6675 tmp = tcg_temp_new_i32(tcg_ctx);
6676 gen_neon_narrow_op(s, op == NEON_2RM_VMOVN, q, size,
6677 tmp, tcg_ctx->cpu_V0);
6678 if (pass == 0) {
6679 tmp2 = tmp;
6680 } else {
6681 neon_store_reg(tcg_ctx, rd, 0, tmp2);
6682 neon_store_reg(tcg_ctx, rd, 1, tmp);
6683 }
6684 }
6685 break;
6686 case NEON_2RM_VSHLL:
6687 if (q || (rd & 1)) {
6688 return 1;
6689 }
6690 tmp = neon_load_reg(tcg_ctx, rm, 0);
6691 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6692 for (pass = 0; pass < 2; pass++) {
6693 if (pass == 1)
6694 tmp = tmp2;
6695 gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, 1);
6696 tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 8 << size);
6697 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6698 }
6699 break;
6700 case NEON_2RM_VCVT_F16_F32:
6701 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6702 q || (rm & 1)) {
6703 return 1;
6704 }
6705 tmp = tcg_temp_new_i32(tcg_ctx);
6706 tmp2 = tcg_temp_new_i32(tcg_ctx);
6707 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 0));
6708 gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6709 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 1));
6710 gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6711 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
6712 tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
6713 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 2));
6714 gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6715 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 3));
6716 neon_store_reg(tcg_ctx, rd, 0, tmp2);
6717 tmp2 = tcg_temp_new_i32(tcg_ctx);
6718 gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6719 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
6720 tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
6721 neon_store_reg(tcg_ctx, rd, 1, tmp2);
6722 tcg_temp_free_i32(tcg_ctx, tmp);
6723 break;
6724 case NEON_2RM_VCVT_F32_F16:
6725 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6726 q || (rd & 1)) {
6727 return 1;
6728 }
6729 tmp3 = tcg_temp_new_i32(tcg_ctx);
6730 tmp = neon_load_reg(tcg_ctx, rm, 0);
6731 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6732 tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp);
6733 gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6734 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
6735 tcg_gen_shri_i32(tcg_ctx, tmp3, tmp, 16);
6736 gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6737 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
6738 tcg_temp_free_i32(tcg_ctx, tmp);
6739 tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp2);
6740 gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6741 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 2));
6742 tcg_gen_shri_i32(tcg_ctx, tmp3, tmp2, 16);
6743 gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6744 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 3));
6745 tcg_temp_free_i32(tcg_ctx, tmp2);
6746 tcg_temp_free_i32(tcg_ctx, tmp3);
6747 break;
6748 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6749 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6750 || ((rm | rd) & 1)) {
6751 return 1;
6752 }
6753 tmp = tcg_const_i32(tcg_ctx, rd);
6754 tmp2 = tcg_const_i32(tcg_ctx, rm);
6755
6756 /* Bit 6 is the lowest opcode bit; it distinguishes between
6757 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6758 */
6759 tmp3 = tcg_const_i32(tcg_ctx, extract32(insn, 6, 1));
6760
6761 if (op == NEON_2RM_AESE) {
6762 gen_helper_crypto_aese(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
6763 } else {
6764 gen_helper_crypto_aesmc(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
6765 }
6766 tcg_temp_free_i32(tcg_ctx, tmp);
6767 tcg_temp_free_i32(tcg_ctx, tmp2);
6768 tcg_temp_free_i32(tcg_ctx, tmp3);
6769 break;
6770 case NEON_2RM_SHA1H:
6771 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6772 || ((rm | rd) & 1)) {
6773 return 1;
6774 }
6775 tmp = tcg_const_i32(tcg_ctx, rd);
6776 tmp2 = tcg_const_i32(tcg_ctx, rm);
6777
6778 gen_helper_crypto_sha1h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6779
6780 tcg_temp_free_i32(tcg_ctx, tmp);
6781 tcg_temp_free_i32(tcg_ctx, tmp2);
6782 break;
6783 case NEON_2RM_SHA1SU1:
6784 if ((rm | rd) & 1) {
6785 return 1;
6786 }
6787 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6788 if (q) {
6789 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6790 return 1;
6791 }
6792 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6793 return 1;
6794 }
6795 tmp = tcg_const_i32(tcg_ctx, rd);
6796 tmp2 = tcg_const_i32(tcg_ctx, rm);
6797 if (q) {
6798 gen_helper_crypto_sha256su0(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6799 } else {
6800 gen_helper_crypto_sha1su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6801 }
6802 tcg_temp_free_i32(tcg_ctx, tmp);
6803 tcg_temp_free_i32(tcg_ctx, tmp2);
6804 break;
6805 default:
6806 elementwise:
6807 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6808 if (neon_2rm_is_float_op(op)) {
6809 tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env,
6810 neon_reg_offset(rm, pass));
6811 TCGV_UNUSED_I32(tmp);
6812 } else {
6813 tmp = neon_load_reg(tcg_ctx, rm, pass);
6814 }
6815 switch (op) {
6816 case NEON_2RM_VREV32:
6817 switch (size) {
6818 case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
6819 case 1: gen_swap_half(s, tmp); break;
6820 default: abort();
6821 }
6822 break;
6823 case NEON_2RM_VREV16:
6824 gen_rev16(s, tmp);
6825 break;
6826 case NEON_2RM_VCLS:
6827 switch (size) {
6828 case 0: gen_helper_neon_cls_s8(tcg_ctx, tmp, tmp); break;
6829 case 1: gen_helper_neon_cls_s16(tcg_ctx, tmp, tmp); break;
6830 case 2: gen_helper_neon_cls_s32(tcg_ctx, tmp, tmp); break;
6831 default: abort();
6832 }
6833 break;
6834 case NEON_2RM_VCLZ:
6835 switch (size) {
6836 case 0: gen_helper_neon_clz_u8(tcg_ctx, tmp, tmp); break;
6837 case 1: gen_helper_neon_clz_u16(tcg_ctx, tmp, tmp); break;
6838 case 2: gen_helper_clz(tcg_ctx, tmp, tmp); break;
6839 default: abort();
6840 }
6841 break;
6842 case NEON_2RM_VCNT:
6843 gen_helper_neon_cnt_u8(tcg_ctx, tmp, tmp);
6844 break;
6845 case NEON_2RM_VMVN:
6846 tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6847 break;
6848 case NEON_2RM_VQABS:
6849 switch (size) {
6850 case 0:
6851 gen_helper_neon_qabs_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6852 break;
6853 case 1:
6854 gen_helper_neon_qabs_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6855 break;
6856 case 2:
6857 gen_helper_neon_qabs_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6858 break;
6859 default: abort();
6860 }
6861 break;
6862 case NEON_2RM_VQNEG:
6863 switch (size) {
6864 case 0:
6865 gen_helper_neon_qneg_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6866 break;
6867 case 1:
6868 gen_helper_neon_qneg_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6869 break;
6870 case 2:
6871 gen_helper_neon_qneg_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6872 break;
6873 default: abort();
6874 }
6875 break;
6876 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6877 tmp2 = tcg_const_i32(tcg_ctx, 0);
6878 switch(size) {
6879 case 0: gen_helper_neon_cgt_s8(tcg_ctx, tmp, tmp, tmp2); break;
6880 case 1: gen_helper_neon_cgt_s16(tcg_ctx, tmp, tmp, tmp2); break;
6881 case 2: gen_helper_neon_cgt_s32(tcg_ctx, tmp, tmp, tmp2); break;
6882 default: abort();
6883 }
6884 tcg_temp_free_i32(tcg_ctx, tmp2);
6885 if (op == NEON_2RM_VCLE0) {
6886 tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6887 }
6888 break;
6889 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6890 tmp2 = tcg_const_i32(tcg_ctx, 0);
6891 switch(size) {
6892 case 0: gen_helper_neon_cge_s8(tcg_ctx, tmp, tmp, tmp2); break;
6893 case 1: gen_helper_neon_cge_s16(tcg_ctx, tmp, tmp, tmp2); break;
6894 case 2: gen_helper_neon_cge_s32(tcg_ctx, tmp, tmp, tmp2); break;
6895 default: abort();
6896 }
6897 tcg_temp_free_i32(tcg_ctx, tmp2);
6898 if (op == NEON_2RM_VCLT0) {
6899 tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6900 }
6901 break;
6902 case NEON_2RM_VCEQ0:
6903 tmp2 = tcg_const_i32(tcg_ctx, 0);
6904 switch(size) {
6905 case 0: gen_helper_neon_ceq_u8(tcg_ctx, tmp, tmp, tmp2); break;
6906 case 1: gen_helper_neon_ceq_u16(tcg_ctx, tmp, tmp, tmp2); break;
6907 case 2: gen_helper_neon_ceq_u32(tcg_ctx, tmp, tmp, tmp2); break;
6908 default: abort();
6909 }
6910 tcg_temp_free_i32(tcg_ctx, tmp2);
6911 break;
6912 case NEON_2RM_VABS:
6913 switch(size) {
6914 case 0: gen_helper_neon_abs_s8(tcg_ctx, tmp, tmp); break;
6915 case 1: gen_helper_neon_abs_s16(tcg_ctx, tmp, tmp); break;
6916 case 2: tcg_gen_abs_i32(s, tmp, tmp); break;
6917 default: abort();
6918 }
6919 break;
6920 case NEON_2RM_VNEG:
6921 tmp2 = tcg_const_i32(tcg_ctx, 0);
6922 gen_neon_rsb(s, size, tmp, tmp2);
6923 tcg_temp_free_i32(tcg_ctx, tmp2);
6924 break;
6925 case NEON_2RM_VCGT0_F:
6926 {
6927 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6928 tmp2 = tcg_const_i32(tcg_ctx, 0);
6929 gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6930 tcg_temp_free_i32(tcg_ctx, tmp2);
6931 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6932 break;
6933 }
6934 case NEON_2RM_VCGE0_F:
6935 {
6936 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6937 tmp2 = tcg_const_i32(tcg_ctx, 0);
6938 gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6939 tcg_temp_free_i32(tcg_ctx, tmp2);
6940 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6941 break;
6942 }
6943 case NEON_2RM_VCEQ0_F:
6944 {
6945 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6946 tmp2 = tcg_const_i32(tcg_ctx, 0);
6947 gen_helper_neon_ceq_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6948 tcg_temp_free_i32(tcg_ctx, tmp2);
6949 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6950 break;
6951 }
6952 case NEON_2RM_VCLE0_F:
6953 {
6954 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6955 tmp2 = tcg_const_i32(tcg_ctx, 0);
6956 gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6957 tcg_temp_free_i32(tcg_ctx, tmp2);
6958 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6959 break;
6960 }
6961 case NEON_2RM_VCLT0_F:
6962 {
6963 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6964 tmp2 = tcg_const_i32(tcg_ctx, 0);
6965 gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6966 tcg_temp_free_i32(tcg_ctx, tmp2);
6967 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6968 break;
6969 }
6970 case NEON_2RM_VABS_F:
6971 gen_vfp_abs(s, 0);
6972 break;
6973 case NEON_2RM_VNEG_F:
6974 gen_vfp_neg(s, 0);
6975 break;
6976 case NEON_2RM_VSWP:
6977 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6978 neon_store_reg(tcg_ctx, rm, pass, tmp2);
6979 break;
6980 case NEON_2RM_VTRN:
6981 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6982 switch (size) {
6983 case 0: gen_neon_trn_u8(tcg_ctx, tmp, tmp2); break;
6984 case 1: gen_neon_trn_u16(tcg_ctx, tmp, tmp2); break;
6985 default: abort();
6986 }
6987 neon_store_reg(tcg_ctx, rm, pass, tmp2);
6988 break;
6989 case NEON_2RM_VRINTN:
6990 case NEON_2RM_VRINTA:
6991 case NEON_2RM_VRINTM:
6992 case NEON_2RM_VRINTP:
6993 case NEON_2RM_VRINTZ:
6994 {
6995 TCGv_i32 tcg_rmode;
6996 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6997 int rmode;
6998
6999 if (op == NEON_2RM_VRINTZ) {
7000 rmode = FPROUNDING_ZERO;
7001 } else {
7002 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7003 }
7004
7005 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode));
7006 gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7007 tcg_ctx->cpu_env);
7008 gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7009 gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7010 tcg_ctx->cpu_env);
7011 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7012 tcg_temp_free_i32(tcg_ctx, tcg_rmode);
7013 break;
7014 }
7015 case NEON_2RM_VRINTX:
7016 {
7017 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7018 gen_helper_rints_exact(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7019 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7020 break;
7021 }
7022 case NEON_2RM_VCVTAU:
7023 case NEON_2RM_VCVTAS:
7024 case NEON_2RM_VCVTNU:
7025 case NEON_2RM_VCVTNS:
7026 case NEON_2RM_VCVTPU:
7027 case NEON_2RM_VCVTPS:
7028 case NEON_2RM_VCVTMU:
7029 case NEON_2RM_VCVTMS:
7030 {
7031 bool is_signed = !extract32(insn, 7, 1);
7032 TCGv_ptr fpst = get_fpstatus_ptr(s, 1);
7033 TCGv_i32 tcg_rmode, tcg_shift;
7034 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7035
7036 tcg_shift = tcg_const_i32(tcg_ctx, 0);
7037 tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode));
7038 gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7039 tcg_ctx->cpu_env);
7040
7041 if (is_signed) {
7042 gen_helper_vfp_tosls(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
7043 tcg_shift, fpst);
7044 } else {
7045 gen_helper_vfp_touls(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
7046 tcg_shift, fpst);
7047 }
7048
7049 gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7050 tcg_ctx->cpu_env);
7051 tcg_temp_free_i32(tcg_ctx, tcg_rmode);
7052 tcg_temp_free_i32(tcg_ctx, tcg_shift);
7053 tcg_temp_free_ptr(tcg_ctx, fpst);
7054 break;
7055 }
7056 case NEON_2RM_VRECPE:
7057 {
7058 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7059 gen_helper_recpe_u32(tcg_ctx, tmp, tmp, fpstatus);
7060 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7061 break;
7062 }
7063 case NEON_2RM_VRSQRTE:
7064 {
7065 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7066 gen_helper_rsqrte_u32(tcg_ctx, tmp, tmp, fpstatus);
7067 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7068 break;
7069 }
7070 case NEON_2RM_VRECPE_F:
7071 {
7072 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7073 gen_helper_recpe_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7074 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7075 break;
7076 }
7077 case NEON_2RM_VRSQRTE_F:
7078 {
7079 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7080 gen_helper_rsqrte_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7081 tcg_temp_free_ptr(tcg_ctx, fpstatus);
7082 break;
7083 }
7084 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7085 gen_vfp_sito(s, 0, 1);
7086 break;
7087 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7088 gen_vfp_uito(s, 0, 1);
7089 break;
7090 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7091 gen_vfp_tosiz(s, 0, 1);
7092 break;
7093 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7094 gen_vfp_touiz(s, 0, 1);
7095 break;
7096 default:
7097 /* Reserved op values were caught by the
7098 * neon_2rm_sizes[] check earlier.
7099 */
7100 abort();
7101 }
7102 if (neon_2rm_is_float_op(op)) {
7103 tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env,
7104 neon_reg_offset(rd, pass));
7105 } else {
7106 neon_store_reg(tcg_ctx, rd, pass, tmp);
7107 }
7108 }
7109 break;
7110 }
7111 } else if ((insn & (1 << 10)) == 0) {
7112 /* VTBL, VTBX. */
7113 int n = ((insn >> 8) & 3) + 1;
7114 if ((rn + n) > 32) {
7115 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7116 * helper function running off the end of the register file.
7117 */
7118 return 1;
7119 }
7120 n <<= 3;
7121 if (insn & (1 << 6)) {
7122 tmp = neon_load_reg(tcg_ctx, rd, 0);
7123 } else {
7124 tmp = tcg_temp_new_i32(tcg_ctx);
7125 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
7126 }
7127 tmp2 = neon_load_reg(tcg_ctx, rm, 0);
7128 tmp4 = tcg_const_i32(tcg_ctx, rn);
7129 tmp5 = tcg_const_i32(tcg_ctx, n);
7130 gen_helper_neon_tbl(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp, tmp4, tmp5);
7131 tcg_temp_free_i32(tcg_ctx, tmp);
7132 if (insn & (1 << 6)) {
7133 tmp = neon_load_reg(tcg_ctx, rd, 1);
7134 } else {
7135 tmp = tcg_temp_new_i32(tcg_ctx);
7136 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
7137 }
7138 tmp3 = neon_load_reg(tcg_ctx, rm, 1);
7139 gen_helper_neon_tbl(tcg_ctx, tmp3, tcg_ctx->cpu_env, tmp3, tmp, tmp4, tmp5);
7140 tcg_temp_free_i32(tcg_ctx, tmp5);
7141 tcg_temp_free_i32(tcg_ctx, tmp4);
7142 neon_store_reg(tcg_ctx, rd, 0, tmp2);
7143 neon_store_reg(tcg_ctx, rd, 1, tmp3);
7144 tcg_temp_free_i32(tcg_ctx, tmp);
7145 } else if ((insn & 0x380) == 0) {
7146 /* VDUP */
7147 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7148 return 1;
7149 }
7150 if (insn & (1 << 19)) {
7151 tmp = neon_load_reg(tcg_ctx, rm, 1);
7152 } else {
7153 tmp = neon_load_reg(tcg_ctx, rm, 0);
7154 }
7155 if (insn & (1 << 16)) {
7156 gen_neon_dup_u8(s, tmp, ((insn >> 17) & 3) * 8);
7157 } else if (insn & (1 << 17)) {
7158 if ((insn >> 18) & 1)
7159 gen_neon_dup_high16(s, tmp);
7160 else
7161 gen_neon_dup_low16(s, tmp);
7162 }
7163 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7164 tmp2 = tcg_temp_new_i32(tcg_ctx);
7165 tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
7166 neon_store_reg(tcg_ctx, rd, pass, tmp2);
7167 }
7168 tcg_temp_free_i32(tcg_ctx, tmp);
7169 } else {
7170 return 1;
7171 }
7172 }
7173 }
7174 return 0;
7175 }
7176
disas_coproc_insn(DisasContext * s,uint32_t insn)7177 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7178 {
7179 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7180 const ARMCPRegInfo *ri;
7181 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7182
7183 cpnum = (insn >> 8) & 0xf;
7184
7185 /* First check for coprocessor space used for XScale/iwMMXt insns */
7186 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7187 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7188 return 1;
7189 }
7190 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7191 return disas_iwmmxt_insn(s, insn);
7192 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7193 return disas_dsp_insn(s, insn);
7194 }
7195 return 1;
7196 }
7197
7198 /* Otherwise treat as a generic register access */
7199 is64 = (insn & (1 << 25)) == 0;
7200 if (!is64 && ((insn & (1 << 4)) == 0)) {
7201 /* cdp */
7202 return 1;
7203 }
7204
7205 crm = insn & 0xf;
7206 if (is64) {
7207 crn = 0;
7208 opc1 = (insn >> 4) & 0xf;
7209 opc2 = 0;
7210 rt2 = (insn >> 16) & 0xf;
7211 } else {
7212 crn = (insn >> 16) & 0xf;
7213 opc1 = (insn >> 21) & 7;
7214 opc2 = (insn >> 5) & 7;
7215 rt2 = 0;
7216 }
7217 isread = (insn >> 20) & 1;
7218 rt = (insn >> 12) & 0xf;
7219
7220 ri = get_arm_cp_reginfo(s->cp_regs,
7221 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
7222 if (ri) {
7223 /* Check access permissions */
7224 if (!cp_access_ok(s->current_el, ri, isread)) {
7225 return 1;
7226 }
7227
7228 if (ri->accessfn ||
7229 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7230 /* Emit code to perform further access permissions checks at
7231 * runtime; this may result in an exception.
7232 * Note that on XScale all cp0..c13 registers do an access check
7233 * call in order to handle c15_cpar.
7234 */
7235 TCGv_ptr tmpptr;
7236 TCGv_i32 tcg_syn;
7237 uint32_t syndrome;
7238
7239 /* Note that since we are an implementation which takes an
7240 * exception on a trapped conditional instruction only if the
7241 * instruction passes its condition code check, we can take
7242 * advantage of the clause in the ARM ARM that allows us to set
7243 * the COND field in the instruction to 0xE in all cases.
7244 * We could fish the actual condition out of the insn (ARM)
7245 * or the condexec bits (Thumb) but it isn't necessary.
7246 */
7247 switch (cpnum) {
7248 case 14:
7249 if (is64) {
7250 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7251 isread, s->thumb);
7252 } else {
7253 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7254 rt, isread, s->thumb);
7255 }
7256 break;
7257 case 15:
7258 if (is64) {
7259 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7260 isread, s->thumb);
7261 } else {
7262 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7263 rt, isread, s->thumb);
7264 }
7265 break;
7266 default:
7267 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7268 * so this can only happen if this is an ARMv7 or earlier CPU,
7269 * in which case the syndrome information won't actually be
7270 * guest visible.
7271 */
7272 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7273 syndrome = syn_uncategorized();
7274 break;
7275 }
7276
7277 gen_set_pc_im(s, s->pc);
7278 tmpptr = tcg_const_ptr(tcg_ctx, ri);
7279 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
7280 gen_helper_access_check_cp_reg(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tcg_syn);
7281 tcg_temp_free_ptr(tcg_ctx, tmpptr);
7282 tcg_temp_free_i32(tcg_ctx, tcg_syn);
7283 }
7284
7285 /* Handle special cases first */
7286 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7287 case ARM_CP_NOP:
7288 return 0;
7289 case ARM_CP_WFI:
7290 if (isread) {
7291 return 1;
7292 }
7293 gen_set_pc_im(s, s->pc);
7294 s->is_jmp = DISAS_WFI;
7295 return 0;
7296 default:
7297 break;
7298 }
7299
7300 if (isread) {
7301 /* Read */
7302 if (is64) {
7303 TCGv_i64 tmp64;
7304 TCGv_i32 tmp;
7305 if (ri->type & ARM_CP_CONST) {
7306 tmp64 = tcg_const_i64(tcg_ctx, ri->resetvalue);
7307 } else if (ri->readfn) {
7308 TCGv_ptr tmpptr;
7309 tmp64 = tcg_temp_new_i64(tcg_ctx);
7310 tmpptr = tcg_const_ptr(tcg_ctx, ri);
7311 gen_helper_get_cp_reg64(tcg_ctx, tmp64, tcg_ctx->cpu_env, tmpptr);
7312 tcg_temp_free_ptr(tcg_ctx, tmpptr);
7313 } else {
7314 tmp64 = tcg_temp_new_i64(tcg_ctx);
7315 tcg_gen_ld_i64(tcg_ctx, tmp64, tcg_ctx->cpu_env, ri->fieldoffset);
7316 }
7317 tmp = tcg_temp_new_i32(tcg_ctx);
7318 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
7319 store_reg(s, rt, tmp);
7320 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
7321 tmp = tcg_temp_new_i32(tcg_ctx);
7322 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
7323 tcg_temp_free_i64(tcg_ctx, tmp64);
7324 store_reg(s, rt2, tmp);
7325 } else {
7326 TCGv_i32 tmp;
7327 if (ri->type & ARM_CP_CONST) {
7328 tmp = tcg_const_i32(tcg_ctx, ri->resetvalue);
7329 } else if (ri->readfn) {
7330 TCGv_ptr tmpptr;
7331 tmp = tcg_temp_new_i32(tcg_ctx);
7332 tmpptr = tcg_const_ptr(tcg_ctx, ri);
7333 gen_helper_get_cp_reg(tcg_ctx, tmp, tcg_ctx->cpu_env, tmpptr);
7334 tcg_temp_free_ptr(tcg_ctx, tmpptr);
7335 } else {
7336 tmp = load_cpu_offset(s->uc, ri->fieldoffset);
7337 }
7338 if (rt == 15) {
7339 /* Destination register of r15 for 32 bit loads sets
7340 * the condition codes from the high 4 bits of the value
7341 */
7342 gen_set_nzcv(s, tmp);
7343 tcg_temp_free_i32(tcg_ctx, tmp);
7344 } else {
7345 store_reg(s, rt, tmp);
7346 }
7347 }
7348 } else {
7349 /* Write */
7350 if (ri->type & ARM_CP_CONST) {
7351 /* If not forbidden by access permissions, treat as WI */
7352 return 0;
7353 }
7354
7355 if (is64) {
7356 TCGv_i32 tmplo, tmphi;
7357 TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
7358 tmplo = load_reg(s, rt);
7359 tmphi = load_reg(s, rt2);
7360 tcg_gen_concat_i32_i64(tcg_ctx, tmp64, tmplo, tmphi);
7361 tcg_temp_free_i32(tcg_ctx, tmplo);
7362 tcg_temp_free_i32(tcg_ctx, tmphi);
7363 if (ri->writefn) {
7364 TCGv_ptr tmpptr = tcg_const_ptr(tcg_ctx, ri);
7365 gen_helper_set_cp_reg64(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tmp64);
7366 tcg_temp_free_ptr(tcg_ctx, tmpptr);
7367 } else {
7368 tcg_gen_st_i64(tcg_ctx, tmp64, tcg_ctx->cpu_env, ri->fieldoffset);
7369 }
7370 tcg_temp_free_i64(tcg_ctx, tmp64);
7371 } else {
7372 if (ri->writefn) {
7373 TCGv_i32 tmp;
7374 TCGv_ptr tmpptr;
7375 tmp = load_reg(s, rt);
7376 tmpptr = tcg_const_ptr(tcg_ctx, ri);
7377 gen_helper_set_cp_reg(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tmp);
7378 tcg_temp_free_ptr(tcg_ctx, tmpptr);
7379 tcg_temp_free_i32(tcg_ctx, tmp);
7380 } else {
7381 TCGv_i32 tmp = load_reg(s, rt);
7382 store_cpu_offset(tcg_ctx, tmp, ri->fieldoffset);
7383 }
7384 }
7385 }
7386
7387 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7388 /* We default to ending the TB on a coprocessor register write,
7389 * but allow this to be suppressed by the register definition
7390 * (usually only necessary to work around guest bugs).
7391 */
7392 gen_lookup_tb(s);
7393 }
7394
7395 return 0;
7396 }
7397
7398 /* Unknown register; this might be a guest error or a QEMU
7399 * unimplemented feature.
7400 */
7401 if (is64) {
7402 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7403 "64 bit system register cp:%d opc1: %d crm:%d\n",
7404 isread ? "read" : "write", cpnum, opc1, crm);
7405 } else {
7406 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7407 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7408 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7409 }
7410
7411 return 1;
7412 }
7413
7414
7415 /* Store a 64-bit value to a register pair. Clobbers val. */
gen_storeq_reg(DisasContext * s,int rlow,int rhigh,TCGv_i64 val)7416 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7417 {
7418 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7419 TCGv_i32 tmp;
7420 tmp = tcg_temp_new_i32(tcg_ctx);
7421 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, val);
7422 store_reg(s, rlow, tmp);
7423 tmp = tcg_temp_new_i32(tcg_ctx);
7424 tcg_gen_shri_i64(tcg_ctx, val, val, 32);
7425 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, val);
7426 store_reg(s, rhigh, tmp);
7427 }
7428
7429 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
gen_addq_lo(DisasContext * s,TCGv_i64 val,int rlow)7430 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7431 {
7432 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7433 TCGv_i64 tmp;
7434 TCGv_i32 tmp2;
7435
7436 /* Load value and extend to 64 bits. */
7437 tmp = tcg_temp_new_i64(tcg_ctx);
7438 tmp2 = load_reg(s, rlow);
7439 tcg_gen_extu_i32_i64(tcg_ctx, tmp, tmp2);
7440 tcg_temp_free_i32(tcg_ctx, tmp2);
7441 tcg_gen_add_i64(tcg_ctx, val, val, tmp);
7442 tcg_temp_free_i64(tcg_ctx, tmp);
7443 }
7444
7445 /* load and add a 64-bit value from a register pair. */
gen_addq(DisasContext * s,TCGv_i64 val,int rlow,int rhigh)7446 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7447 {
7448 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7449 TCGv_i64 tmp;
7450 TCGv_i32 tmpl;
7451 TCGv_i32 tmph;
7452
7453 /* Load 64-bit value rd:rn. */
7454 tmpl = load_reg(s, rlow);
7455 tmph = load_reg(s, rhigh);
7456 tmp = tcg_temp_new_i64(tcg_ctx);
7457 tcg_gen_concat_i32_i64(tcg_ctx, tmp, tmpl, tmph);
7458 tcg_temp_free_i32(tcg_ctx, tmpl);
7459 tcg_temp_free_i32(tcg_ctx, tmph);
7460 tcg_gen_add_i64(tcg_ctx, val, val, tmp);
7461 tcg_temp_free_i64(tcg_ctx, tmp);
7462 }
7463
7464 /* Set N and Z flags from hi|lo. */
gen_logicq_cc(DisasContext * s,TCGv_i32 lo,TCGv_i32 hi)7465 static void gen_logicq_cc(DisasContext *s, TCGv_i32 lo, TCGv_i32 hi)
7466 {
7467 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7468 tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_NF, hi);
7469 tcg_gen_or_i32(tcg_ctx, tcg_ctx->cpu_ZF, lo, hi);
7470 }
7471
7472 /* Load/Store exclusive instructions are implemented by remembering
7473 the value/address loaded, and seeing if these are the same
7474 when the store is performed. This should be sufficient to implement
7475 the architecturally mandated semantics, and avoids having to monitor
7476 regular stores.
7477
7478 In system emulation mode only one CPU will be running at once, so
7479 this sequence is effectively atomic. In user emulation mode we
7480 throw an exception and handle the atomic operation elsewhere. */
gen_load_exclusive(DisasContext * s,int rt,int rt2,TCGv_i32 addr,int size)7481 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7482 TCGv_i32 addr, int size)
7483 {
7484 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7485 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
7486
7487 s->is_ldex = true;
7488
7489 switch (size) {
7490 case 0:
7491 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7492 break;
7493 case 1:
7494 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7495 break;
7496 case 2:
7497 case 3:
7498 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7499 break;
7500 default:
7501 abort();
7502 }
7503
7504 if (size == 3) {
7505 TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
7506 TCGv_i32 tmp3 = tcg_temp_new_i32(tcg_ctx);
7507
7508 tcg_gen_addi_i32(tcg_ctx, tmp2, addr, 4);
7509 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7510 tcg_temp_free_i32(tcg_ctx, tmp2);
7511 tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_val, tmp, tmp3);
7512 store_reg(s, rt2, tmp3);
7513 } else {
7514 tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_val, tmp);
7515 }
7516
7517 store_reg(s, rt, tmp);
7518 tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, addr);
7519 }
7520
gen_clrex(DisasContext * s)7521 static void gen_clrex(DisasContext *s)
7522 {
7523 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7524 tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, -1);
7525 }
7526
7527 #ifdef CONFIG_USER_ONLY
gen_store_exclusive(DisasContext * s,int rd,int rt,int rt2,TCGv_i32 addr,int size)7528 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7529 TCGv_i32 addr, int size)
7530 {
7531 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7532 tcg_gen_extu_i32_i64(tcg_ctx, cpu_exclusive_test, addr);
7533 tcg_gen_movi_i32(tcg_ctx, cpu_exclusive_info,
7534 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7535 gen_exception_internal_insn(s, 4, EXCP_STREX);
7536 }
7537 #else
gen_store_exclusive(DisasContext * s,int rd,int rt,int rt2,TCGv_i32 addr,int size)7538 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7539 TCGv_i32 addr, int size)
7540 {
7541 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7542 TCGv_i32 tmp;
7543 TCGv_i64 val64, extaddr;
7544 int done_label;
7545 int fail_label;
7546
7547 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7548 [addr] = {Rt};
7549 {Rd} = 0;
7550 } else {
7551 {Rd} = 1;
7552 } */
7553 fail_label = gen_new_label(tcg_ctx);
7554 done_label = gen_new_label(tcg_ctx);
7555 extaddr = tcg_temp_new_i64(tcg_ctx);
7556 tcg_gen_extu_i32_i64(tcg_ctx, extaddr, addr);
7557 tcg_gen_brcond_i64(tcg_ctx, TCG_COND_NE, extaddr, tcg_ctx->cpu_exclusive_addr, fail_label);
7558 tcg_temp_free_i64(tcg_ctx, extaddr);
7559
7560 tmp = tcg_temp_new_i32(tcg_ctx);
7561 switch (size) {
7562 case 0:
7563 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7564 break;
7565 case 1:
7566 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7567 break;
7568 case 2:
7569 case 3:
7570 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7571 break;
7572 default:
7573 abort();
7574 }
7575
7576 val64 = tcg_temp_new_i64(tcg_ctx);
7577 if (size == 3) {
7578 TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
7579 TCGv_i32 tmp3 = tcg_temp_new_i32(tcg_ctx);
7580 tcg_gen_addi_i32(tcg_ctx, tmp2, addr, 4);
7581 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7582 tcg_temp_free_i32(tcg_ctx, tmp2);
7583 tcg_gen_concat_i32_i64(tcg_ctx, val64, tmp, tmp3);
7584 tcg_temp_free_i32(tcg_ctx, tmp3);
7585 } else {
7586 tcg_gen_extu_i32_i64(tcg_ctx, val64, tmp);
7587 }
7588 tcg_temp_free_i32(tcg_ctx, tmp);
7589
7590 tcg_gen_brcond_i64(tcg_ctx, TCG_COND_NE, val64, tcg_ctx->cpu_exclusive_val, fail_label);
7591 tcg_temp_free_i64(tcg_ctx, val64);
7592
7593 tmp = load_reg(s, rt);
7594 switch (size) {
7595 case 0:
7596 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
7597 break;
7598 case 1:
7599 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
7600 break;
7601 case 2:
7602 case 3:
7603 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7604 break;
7605 default:
7606 abort();
7607 }
7608 tcg_temp_free_i32(tcg_ctx, tmp);
7609 if (size == 3) {
7610 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7611 tmp = load_reg(s, rt2);
7612 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7613 tcg_temp_free_i32(tcg_ctx, tmp);
7614 }
7615 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[rd], 0);
7616 tcg_gen_br(tcg_ctx, done_label);
7617 gen_set_label(tcg_ctx, fail_label);
7618 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[rd], 1);
7619 gen_set_label(tcg_ctx, done_label);
7620 tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, -1);
7621 }
7622 #endif
7623
7624 /* gen_srs:
7625 * @env: CPUARMState
7626 * @s: DisasContext
7627 * @mode: mode field from insn (which stack to store to)
7628 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7629 * @writeback: true if writeback bit set
7630 *
7631 * Generate code for the SRS (Store Return State) insn.
7632 */
gen_srs(DisasContext * s,uint32_t mode,uint32_t amode,bool writeback)7633 static void gen_srs(DisasContext *s,
7634 uint32_t mode, uint32_t amode, bool writeback)
7635 {
7636 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7637 int32_t offset;
7638 TCGv_i32 addr = tcg_temp_new_i32(tcg_ctx);
7639 TCGv_i32 tmp = tcg_const_i32(tcg_ctx, mode);
7640 gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
7641 tcg_temp_free_i32(tcg_ctx, tmp);
7642 switch (amode) {
7643 case 0: /* DA */
7644 offset = -4;
7645 break;
7646 case 1: /* IA */
7647 offset = 0;
7648 break;
7649 case 2: /* DB */
7650 offset = -8;
7651 break;
7652 case 3: /* IB */
7653 offset = 4;
7654 break;
7655 default:
7656 abort();
7657 }
7658 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7659 tmp = load_reg(s, 14);
7660 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7661 tcg_temp_free_i32(tcg_ctx, tmp);
7662 tmp = load_cpu_field(s->uc, spsr);
7663 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7664 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7665 tcg_temp_free_i32(tcg_ctx, tmp);
7666 if (writeback) {
7667 switch (amode) {
7668 case 0:
7669 offset = -8;
7670 break;
7671 case 1:
7672 offset = 4;
7673 break;
7674 case 2:
7675 offset = -4;
7676 break;
7677 case 3:
7678 offset = 0;
7679 break;
7680 default:
7681 abort();
7682 }
7683 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7684 tmp = tcg_const_i32(tcg_ctx, mode);
7685 gen_helper_set_r13_banked(tcg_ctx, tcg_ctx->cpu_env, tmp, addr);
7686 tcg_temp_free_i32(tcg_ctx, tmp);
7687 }
7688 tcg_temp_free_i32(tcg_ctx, addr);
7689 }
7690
disas_arm_insn(DisasContext * s,unsigned int insn)7691 static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
7692 {
7693 TCGContext *tcg_ctx = s->uc->tcg_ctx;
7694 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7695 TCGv_i32 tmp;
7696 TCGv_i32 tmp2;
7697 TCGv_i32 tmp3;
7698 TCGv_i32 addr;
7699 TCGv_i64 tmp64;
7700
7701 /* M variants do not implement ARM mode. */
7702 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7703 goto illegal_op;
7704 }
7705
7706 // Unicorn: trace this instruction on request
7707 if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) {
7708 gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4);
7709 // the callback might want to stop emulation immediately
7710 check_exit_request(tcg_ctx);
7711 }
7712
7713 cond = insn >> 28;
7714 if (cond == 0xf){
7715 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7716 * choose to UNDEF. In ARMv5 and above the space is used
7717 * for miscellaneous unconditional instructions.
7718 */
7719 ARCH(5);
7720
7721 /* Unconditional instructions. */
7722 if (((insn >> 25) & 7) == 1) {
7723 /* NEON Data processing. */
7724 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7725 goto illegal_op;
7726 }
7727
7728 if (disas_neon_data_insn(s, insn)) {
7729 goto illegal_op;
7730 }
7731 return;
7732 }
7733 if ((insn & 0x0f100000) == 0x04000000) {
7734 /* NEON load/store. */
7735 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7736 goto illegal_op;
7737 }
7738
7739 if (disas_neon_ls_insn(s, insn)) {
7740 goto illegal_op;
7741 }
7742 return;
7743 }
7744 if ((insn & 0x0f000e10) == 0x0e000a00) {
7745 /* VFP. */
7746 if (disas_vfp_insn(s, insn)) {
7747 goto illegal_op;
7748 }
7749 return;
7750 }
7751 if (((insn & 0x0f30f000) == 0x0510f000) ||
7752 ((insn & 0x0f30f010) == 0x0710f000)) {
7753 if ((insn & (1 << 22)) == 0) {
7754 /* PLDW; v7MP */
7755 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7756 goto illegal_op;
7757 }
7758 }
7759 /* Otherwise PLD; v5TE+ */
7760 ARCH(5TE);
7761 return;
7762 }
7763 if (((insn & 0x0f70f000) == 0x0450f000) ||
7764 ((insn & 0x0f70f010) == 0x0650f000)) {
7765 ARCH(7);
7766 return; /* PLI; V7 */
7767 }
7768 if (((insn & 0x0f700000) == 0x04100000) ||
7769 ((insn & 0x0f700010) == 0x06100000)) {
7770 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7771 goto illegal_op;
7772 }
7773 return; /* v7MP: Unallocated memory hint: must NOP */
7774 }
7775
7776 if ((insn & 0x0ffffdff) == 0x01010000) {
7777 ARCH(6);
7778 /* setend */
7779 if (((insn >> 9) & 1) != s->bswap_code) {
7780 /* Dynamic endianness switching not implemented. */
7781 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7782 goto illegal_op;
7783 }
7784 return;
7785 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7786 switch ((insn >> 4) & 0xf) {
7787 case 1: /* clrex */
7788 ARCH(6K);
7789 gen_clrex(s);
7790 return;
7791 case 4: /* dsb */
7792 case 5: /* dmb */
7793 case 6: /* isb */
7794 ARCH(7);
7795 /* We don't emulate caches so these are a no-op. */
7796 return;
7797 default:
7798 goto illegal_op;
7799 }
7800 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7801 /* srs */
7802 if (IS_USER(s)) {
7803 goto illegal_op;
7804 }
7805 ARCH(6);
7806 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7807 return;
7808 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7809 /* rfe */
7810 int32_t offset;
7811 if (IS_USER(s))
7812 goto illegal_op;
7813 ARCH(6);
7814 rn = (insn >> 16) & 0xf;
7815 addr = load_reg(s, rn);
7816 i = (insn >> 23) & 3;
7817 switch (i) {
7818 case 0: offset = -4; break; /* DA */
7819 case 1: offset = 0; break; /* IA */
7820 case 2: offset = -8; break; /* DB */
7821 case 3: offset = 4; break; /* IB */
7822 default: abort();
7823 }
7824 if (offset)
7825 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7826 /* Load PC into tmp and CPSR into tmp2. */
7827 tmp = tcg_temp_new_i32(tcg_ctx);
7828 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7829 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7830 tmp2 = tcg_temp_new_i32(tcg_ctx);
7831 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7832 if (insn & (1 << 21)) {
7833 /* Base writeback. */
7834 switch (i) {
7835 case 0: offset = -8; break;
7836 case 1: offset = 4; break;
7837 case 2: offset = -4; break;
7838 case 3: offset = 0; break;
7839 default: abort();
7840 }
7841 if (offset)
7842 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7843 store_reg(s, rn, addr);
7844 } else {
7845 tcg_temp_free_i32(tcg_ctx, addr);
7846 }
7847 gen_rfe(s, tmp, tmp2);
7848 return;
7849 } else if ((insn & 0x0e000000) == 0x0a000000) {
7850 /* branch link and change to thumb (blx <offset>) */
7851 int32_t offset;
7852
7853 val = (uint32_t)s->pc;
7854 tmp = tcg_temp_new_i32(tcg_ctx);
7855 tcg_gen_movi_i32(tcg_ctx, tmp, val);
7856 store_reg(s, 14, tmp);
7857 /* Sign-extend the 24-bit offset */
7858 offset = ((int32_t)(insn << 8)) >> 8;
7859 /* offset * 4 + bit24 * 2 + (thumb bit) */
7860 val += (((uint32_t)offset) << 2) | ((insn >> 23) & 2) | 1;
7861 /* pipeline offset */
7862 val += 4;
7863 /* protected by ARCH(5); above, near the start of uncond block */
7864 gen_bx_im(s, val);
7865 return;
7866 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7867 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7868 /* iWMMXt register transfer. */
7869 if (extract32(s->c15_cpar, 1, 1)) {
7870 if (!disas_iwmmxt_insn(s, insn)) {
7871 return;
7872 }
7873 }
7874 }
7875 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7876 /* Coprocessor double register transfer. */
7877 ARCH(5TE);
7878 } else if ((insn & 0x0f000010) == 0x0e000010) {
7879 /* Additional coprocessor register transfer. */
7880 } else if ((insn & 0x0ff10020) == 0x01000000) {
7881 uint32_t mask;
7882 uint32_t val;
7883 /* cps (privileged) */
7884 if (IS_USER(s))
7885 return;
7886 mask = val = 0;
7887 if (insn & (1 << 19)) {
7888 if (insn & (1 << 8))
7889 mask |= CPSR_A;
7890 if (insn & (1 << 7))
7891 mask |= CPSR_I;
7892 if (insn & (1 << 6))
7893 mask |= CPSR_F;
7894 if (insn & (1 << 18))
7895 val |= mask;
7896 }
7897 if (insn & (1 << 17)) {
7898 mask |= CPSR_M;
7899 val |= (insn & 0x1f);
7900 }
7901 if (mask) {
7902 gen_set_psr_im(s, mask, 0, val);
7903 }
7904 return;
7905 }
7906 goto illegal_op;
7907 }
7908 if (cond != 0xe) {
7909 /* if not always execute, we generate a conditional jump to
7910 next instruction */
7911 s->condlabel = gen_new_label(tcg_ctx);
7912 arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
7913 s->condjmp = 1;
7914 }
7915 if ((insn & 0x0f900000) == 0x03000000) {
7916 if ((insn & (1 << 21)) == 0) {
7917 ARCH(6T2);
7918 rd = (insn >> 12) & 0xf;
7919 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7920 if ((insn & (1 << 22)) == 0) {
7921 /* MOVW */
7922 tmp = tcg_temp_new_i32(tcg_ctx);
7923 tcg_gen_movi_i32(tcg_ctx, tmp, val);
7924 } else {
7925 /* MOVT */
7926 tmp = load_reg(s, rd);
7927 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
7928 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, val << 16);
7929 }
7930 store_reg(s, rd, tmp);
7931 } else {
7932 if (((insn >> 12) & 0xf) != 0xf)
7933 goto illegal_op;
7934 if (((insn >> 16) & 0xf) == 0) {
7935 gen_nop_hint(s, insn & 0xff);
7936 } else {
7937 /* CPSR = immediate */
7938 val = insn & 0xff;
7939 shift = ((insn >> 8) & 0xf) * 2;
7940 if (shift)
7941 val = (val >> shift) | (val << (32 - shift));
7942 i = ((insn & (1 << 22)) != 0);
7943 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7944 i, val)) {
7945 goto illegal_op;
7946 }
7947 }
7948 }
7949 } else if ((insn & 0x0f900000) == 0x01000000
7950 && (insn & 0x00000090) != 0x00000090) {
7951 /* miscellaneous instructions */
7952 op1 = (insn >> 21) & 3;
7953 sh = (insn >> 4) & 0xf;
7954 rm = insn & 0xf;
7955 switch (sh) {
7956 case 0x0: /* move program status register */
7957 if (op1 & 1) {
7958 /* PSR = reg */
7959 tmp = load_reg(s, rm);
7960 i = ((op1 & 2) != 0);
7961 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7962 goto illegal_op;
7963 } else {
7964 /* reg = PSR */
7965 rd = (insn >> 12) & 0xf;
7966 if (op1 & 2) {
7967 if (IS_USER(s))
7968 goto illegal_op;
7969 tmp = load_cpu_field(s->uc, spsr);
7970 } else {
7971 tmp = tcg_temp_new_i32(tcg_ctx);
7972 gen_helper_cpsr_read(tcg_ctx, tmp, tcg_ctx->cpu_env);
7973 }
7974 store_reg(s, rd, tmp);
7975 }
7976 break;
7977 case 0x1:
7978 if (op1 == 1) {
7979 /* branch/exchange thumb (bx). */
7980 ARCH(4T);
7981 tmp = load_reg(s, rm);
7982 gen_bx(s, tmp);
7983 } else if (op1 == 3) {
7984 /* clz */
7985 ARCH(5);
7986 rd = (insn >> 12) & 0xf;
7987 tmp = load_reg(s, rm);
7988 gen_helper_clz(tcg_ctx, tmp, tmp);
7989 store_reg(s, rd, tmp);
7990 } else {
7991 goto illegal_op;
7992 }
7993 break;
7994 case 0x2:
7995 if (op1 == 1) {
7996 ARCH(5J); /* bxj */
7997 /* Trivial implementation equivalent to bx. */
7998 tmp = load_reg(s, rm);
7999 gen_bx(s, tmp);
8000 } else {
8001 goto illegal_op;
8002 }
8003 break;
8004 case 0x3:
8005 if (op1 != 1)
8006 goto illegal_op;
8007
8008 ARCH(5);
8009 /* branch link/exchange thumb (blx) */
8010 tmp = load_reg(s, rm);
8011 tmp2 = tcg_temp_new_i32(tcg_ctx);
8012 tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc);
8013 store_reg(s, 14, tmp2);
8014 gen_bx(s, tmp);
8015 break;
8016 case 0x4:
8017 {
8018 /* crc32/crc32c */
8019 uint32_t c = extract32(insn, 8, 4);
8020
8021 /* Check this CPU supports ARMv8 CRC instructions.
8022 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8023 * Bits 8, 10 and 11 should be zero.
8024 */
8025 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8026 (c & 0xd) != 0) {
8027 goto illegal_op;
8028 }
8029
8030 rn = extract32(insn, 16, 4);
8031 rd = extract32(insn, 12, 4);
8032
8033 tmp = load_reg(s, rn);
8034 tmp2 = load_reg(s, rm);
8035 if (op1 == 0) {
8036 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
8037 } else if (op1 == 1) {
8038 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff);
8039 }
8040 tmp3 = tcg_const_i32(tcg_ctx, 1 << op1);
8041 if (c & 0x2) {
8042 gen_helper_crc32c(tcg_ctx, tmp, tmp, tmp2, tmp3);
8043 } else {
8044 gen_helper_crc32(tcg_ctx, tmp, tmp, tmp2, tmp3);
8045 }
8046 tcg_temp_free_i32(tcg_ctx, tmp2);
8047 tcg_temp_free_i32(tcg_ctx, tmp3);
8048 store_reg(s, rd, tmp);
8049 break;
8050 }
8051 case 0x5: /* saturating add/subtract */
8052 ARCH(5TE);
8053 rd = (insn >> 12) & 0xf;
8054 rn = (insn >> 16) & 0xf;
8055 tmp = load_reg(s, rm);
8056 tmp2 = load_reg(s, rn);
8057 if (op1 & 2)
8058 gen_helper_double_saturate(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2);
8059 if (op1 & 1)
8060 gen_helper_sub_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8061 else
8062 gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8063 tcg_temp_free_i32(tcg_ctx, tmp2);
8064 store_reg(s, rd, tmp);
8065 break;
8066 case 7:
8067 {
8068 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8069 switch (op1) {
8070 case 1:
8071 /* bkpt */
8072 ARCH(5);
8073 gen_exception_insn(s, 4, EXCP_BKPT,
8074 syn_aa32_bkpt(imm16, false));
8075 break;
8076 case 2:
8077 /* Hypervisor call (v7) */
8078 ARCH(7);
8079 if (IS_USER(s)) {
8080 goto illegal_op;
8081 }
8082 gen_hvc(s, imm16);
8083 break;
8084 case 3:
8085 /* Secure monitor call (v6+) */
8086 ARCH(6K);
8087 if (IS_USER(s)) {
8088 goto illegal_op;
8089 }
8090 gen_smc(s);
8091 break;
8092 default:
8093 goto illegal_op;
8094 }
8095 break;
8096 }
8097 case 0x8: /* signed multiply */
8098 case 0xa:
8099 case 0xc:
8100 case 0xe:
8101 ARCH(5TE);
8102 rs = (insn >> 8) & 0xf;
8103 rn = (insn >> 12) & 0xf;
8104 rd = (insn >> 16) & 0xf;
8105 if (op1 == 1) {
8106 /* (32 * 16) >> 16 */
8107 tmp = load_reg(s, rm);
8108 tmp2 = load_reg(s, rs);
8109 if (sh & 4)
8110 tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, 16);
8111 else
8112 gen_sxth(tmp2);
8113 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
8114 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 16);
8115 tmp = tcg_temp_new_i32(tcg_ctx);
8116 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
8117 tcg_temp_free_i64(tcg_ctx, tmp64);
8118 if ((sh & 2) == 0) {
8119 tmp2 = load_reg(s, rn);
8120 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8121 tcg_temp_free_i32(tcg_ctx, tmp2);
8122 }
8123 store_reg(s, rd, tmp);
8124 } else {
8125 /* 16 * 16 */
8126 tmp = load_reg(s, rm);
8127 tmp2 = load_reg(s, rs);
8128 gen_mulxy(s, tmp, tmp2, sh & 2, sh & 4);
8129 tcg_temp_free_i32(tcg_ctx, tmp2);
8130 if (op1 == 2) {
8131 tmp64 = tcg_temp_new_i64(tcg_ctx);
8132 tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
8133 tcg_temp_free_i32(tcg_ctx, tmp);
8134 gen_addq(s, tmp64, rn, rd);
8135 gen_storeq_reg(s, rn, rd, tmp64);
8136 tcg_temp_free_i64(tcg_ctx, tmp64);
8137 } else {
8138 if (op1 == 0) {
8139 tmp2 = load_reg(s, rn);
8140 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8141 tcg_temp_free_i32(tcg_ctx, tmp2);
8142 }
8143 store_reg(s, rd, tmp);
8144 }
8145 }
8146 break;
8147 default:
8148 goto illegal_op;
8149 }
8150 } else if (((insn & 0x0e000000) == 0 &&
8151 (insn & 0x00000090) != 0x90) ||
8152 ((insn & 0x0e000000) == (1 << 25))) {
8153 int set_cc, logic_cc, shiftop;
8154
8155 op1 = (insn >> 21) & 0xf;
8156 set_cc = (insn >> 20) & 1;
8157 logic_cc = table_logic_cc[op1] & set_cc;
8158
8159 /* data processing instruction */
8160 if (insn & (1 << 25)) {
8161 /* immediate operand */
8162 val = insn & 0xff;
8163 shift = ((insn >> 8) & 0xf) * 2;
8164 if (shift) {
8165 val = (val >> shift) | (val << (32 - shift));
8166 }
8167 tmp2 = tcg_temp_new_i32(tcg_ctx);
8168 tcg_gen_movi_i32(tcg_ctx, tmp2, val);
8169 if (logic_cc && shift) {
8170 gen_set_CF_bit31(s, tmp2);
8171 }
8172 } else {
8173 /* register */
8174 rm = (insn) & 0xf;
8175 tmp2 = load_reg(s, rm);
8176 shiftop = (insn >> 5) & 3;
8177 if (!(insn & (1 << 4))) {
8178 shift = (insn >> 7) & 0x1f;
8179 gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
8180 } else {
8181 rs = (insn >> 8) & 0xf;
8182 tmp = load_reg(s, rs);
8183 gen_arm_shift_reg(s, tmp2, shiftop, tmp, logic_cc);
8184 }
8185 }
8186 if (op1 != 0x0f && op1 != 0x0d) {
8187 rn = (insn >> 16) & 0xf;
8188 tmp = load_reg(s, rn);
8189 } else {
8190 TCGV_UNUSED_I32(tmp);
8191 }
8192 rd = (insn >> 12) & 0xf;
8193 switch(op1) {
8194 case 0x00:
8195 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
8196 if (logic_cc) {
8197 gen_logic_CC(s, tmp);
8198 }
8199 store_reg_bx(s, rd, tmp);
8200 break;
8201 case 0x01:
8202 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
8203 if (logic_cc) {
8204 gen_logic_CC(s, tmp);
8205 }
8206 store_reg_bx(s, rd, tmp);
8207 break;
8208 case 0x02:
8209 if (set_cc && rd == 15) {
8210 /* SUBS r15, ... is used for exception return. */
8211 if (IS_USER(s)) {
8212 goto illegal_op;
8213 }
8214 gen_sub_CC(s, tmp, tmp, tmp2);
8215 gen_exception_return(s, tmp);
8216 } else {
8217 if (set_cc) {
8218 gen_sub_CC(s, tmp, tmp, tmp2);
8219 } else {
8220 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
8221 }
8222 store_reg_bx(s, rd, tmp);
8223 }
8224 break;
8225 case 0x03:
8226 if (set_cc) {
8227 gen_sub_CC(s, tmp, tmp2, tmp);
8228 } else {
8229 tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
8230 }
8231 store_reg_bx(s, rd, tmp);
8232 break;
8233 case 0x04:
8234 if (set_cc) {
8235 gen_add_CC(s, tmp, tmp, tmp2);
8236 } else {
8237 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8238 }
8239 store_reg_bx(s, rd, tmp);
8240 break;
8241 case 0x05:
8242 if (set_cc) {
8243 gen_adc_CC(s, tmp, tmp, tmp2);
8244 } else {
8245 gen_add_carry(s, tmp, tmp, tmp2);
8246 }
8247 store_reg_bx(s, rd, tmp);
8248 break;
8249 case 0x06:
8250 if (set_cc) {
8251 gen_sbc_CC(s, tmp, tmp, tmp2);
8252 } else {
8253 gen_sub_carry(s, tmp, tmp, tmp2);
8254 }
8255 store_reg_bx(s, rd, tmp);
8256 break;
8257 case 0x07:
8258 if (set_cc) {
8259 gen_sbc_CC(s, tmp, tmp2, tmp);
8260 } else {
8261 gen_sub_carry(s, tmp, tmp2, tmp);
8262 }
8263 store_reg_bx(s, rd, tmp);
8264 break;
8265 case 0x08:
8266 if (set_cc) {
8267 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
8268 gen_logic_CC(s, tmp);
8269 }
8270 tcg_temp_free_i32(tcg_ctx, tmp);
8271 break;
8272 case 0x09:
8273 if (set_cc) {
8274 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
8275 gen_logic_CC(s, tmp);
8276 }
8277 tcg_temp_free_i32(tcg_ctx, tmp);
8278 break;
8279 case 0x0a:
8280 if (set_cc) {
8281 gen_sub_CC(s, tmp, tmp, tmp2);
8282 }
8283 tcg_temp_free_i32(tcg_ctx, tmp);
8284 break;
8285 case 0x0b:
8286 if (set_cc) {
8287 gen_add_CC(s, tmp, tmp, tmp2);
8288 }
8289 tcg_temp_free_i32(tcg_ctx, tmp);
8290 break;
8291 case 0x0c:
8292 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
8293 if (logic_cc) {
8294 gen_logic_CC(s, tmp);
8295 }
8296 store_reg_bx(s, rd, tmp);
8297 break;
8298 case 0x0d:
8299 if (logic_cc && rd == 15) {
8300 /* MOVS r15, ... is used for exception return. */
8301 if (IS_USER(s)) {
8302 goto illegal_op;
8303 }
8304 gen_exception_return(s, tmp2);
8305 } else {
8306 if (logic_cc) {
8307 gen_logic_CC(s, tmp2);
8308 }
8309 store_reg_bx(s, rd, tmp2);
8310 }
8311 break;
8312 case 0x0e:
8313 tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
8314 if (logic_cc) {
8315 gen_logic_CC(s, tmp);
8316 }
8317 store_reg_bx(s, rd, tmp);
8318 break;
8319 default:
8320 case 0x0f:
8321 tcg_gen_not_i32(tcg_ctx, tmp2, tmp2);
8322 if (logic_cc) {
8323 gen_logic_CC(s, tmp2);
8324 }
8325 store_reg_bx(s, rd, tmp2);
8326 break;
8327 }
8328 if (op1 != 0x0f && op1 != 0x0d) {
8329 tcg_temp_free_i32(tcg_ctx, tmp2);
8330 }
8331 } else {
8332 /* other instructions */
8333 op1 = (insn >> 24) & 0xf;
8334 switch(op1) {
8335 case 0x0:
8336 case 0x1:
8337 /* multiplies, extra load/stores */
8338 sh = (insn >> 5) & 3;
8339 if (sh == 0) {
8340 if (op1 == 0x0) {
8341 rd = (insn >> 16) & 0xf;
8342 rn = (insn >> 12) & 0xf;
8343 rs = (insn >> 8) & 0xf;
8344 rm = (insn) & 0xf;
8345 op1 = (insn >> 20) & 0xf;
8346 switch (op1) {
8347 case 0: case 1: case 2: case 3: case 6:
8348 /* 32 bit mul */
8349 tmp = load_reg(s, rs);
8350 tmp2 = load_reg(s, rm);
8351 tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
8352 tcg_temp_free_i32(tcg_ctx, tmp2);
8353 if (insn & (1 << 22)) {
8354 /* Subtract (mls) */
8355 ARCH(6T2);
8356 tmp2 = load_reg(s, rn);
8357 tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
8358 tcg_temp_free_i32(tcg_ctx, tmp2);
8359 } else if (insn & (1 << 21)) {
8360 /* Add */
8361 tmp2 = load_reg(s, rn);
8362 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8363 tcg_temp_free_i32(tcg_ctx, tmp2);
8364 }
8365 if (insn & (1 << 20))
8366 gen_logic_CC(s, tmp);
8367 store_reg(s, rd, tmp);
8368 break;
8369 case 4:
8370 /* 64 bit mul double accumulate (UMAAL) */
8371 ARCH(6);
8372 tmp = load_reg(s, rs);
8373 tmp2 = load_reg(s, rm);
8374 tmp64 = gen_mulu_i64_i32(s, tmp, tmp2);
8375 gen_addq_lo(s, tmp64, rn);
8376 gen_addq_lo(s, tmp64, rd);
8377 gen_storeq_reg(s, rn, rd, tmp64);
8378 tcg_temp_free_i64(tcg_ctx, tmp64);
8379 break;
8380 case 8: case 9: case 10: case 11:
8381 case 12: case 13: case 14: case 15:
8382 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8383 tmp = load_reg(s, rs);
8384 tmp2 = load_reg(s, rm);
8385 if (insn & (1 << 22)) {
8386 tcg_gen_muls2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2);
8387 } else {
8388 tcg_gen_mulu2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2);
8389 }
8390 if (insn & (1 << 21)) { /* mult accumulate */
8391 TCGv_i32 al = load_reg(s, rn);
8392 TCGv_i32 ah = load_reg(s, rd);
8393 tcg_gen_add2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2, al, ah);
8394 tcg_temp_free_i32(tcg_ctx, al);
8395 tcg_temp_free_i32(tcg_ctx, ah);
8396 }
8397 if (insn & (1 << 20)) {
8398 gen_logicq_cc(s, tmp, tmp2);
8399 }
8400 store_reg(s, rn, tmp);
8401 store_reg(s, rd, tmp2);
8402 break;
8403 default:
8404 goto illegal_op;
8405 }
8406 } else {
8407 rn = (insn >> 16) & 0xf;
8408 rd = (insn >> 12) & 0xf;
8409 if (insn & (1 << 23)) {
8410 /* load/store exclusive */
8411 int op2 = (insn >> 8) & 3;
8412 op1 = (insn >> 21) & 0x3;
8413
8414 switch (op2) {
8415 case 0: /* lda/stl */
8416 if (op1 == 1) {
8417 goto illegal_op;
8418 }
8419 ARCH(8);
8420 break;
8421 case 1: /* reserved */
8422 goto illegal_op;
8423 case 2: /* ldaex/stlex */
8424 ARCH(8);
8425 break;
8426 case 3: /* ldrex/strex */
8427 if (op1) {
8428 ARCH(6K);
8429 } else {
8430 ARCH(6);
8431 }
8432 break;
8433 }
8434
8435 addr = tcg_temp_local_new_i32(tcg_ctx);
8436 load_reg_var(s, addr, rn);
8437
8438 /* Since the emulation does not have barriers,
8439 the acquire/release semantics need no special
8440 handling */
8441 if (op2 == 0) {
8442 if (insn & (1 << 20)) {
8443 tmp = tcg_temp_new_i32(tcg_ctx);
8444 switch (op1) {
8445 case 0: /* lda */
8446 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8447 break;
8448 case 2: /* ldab */
8449 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
8450 break;
8451 case 3: /* ldah */
8452 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8453 break;
8454 default:
8455 abort();
8456 }
8457 store_reg(s, rd, tmp);
8458 } else {
8459 rm = insn & 0xf;
8460 tmp = load_reg(s, rm);
8461 switch (op1) {
8462 case 0: /* stl */
8463 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8464 break;
8465 case 2: /* stlb */
8466 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8467 break;
8468 case 3: /* stlh */
8469 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8470 break;
8471 default:
8472 abort();
8473 }
8474 tcg_temp_free_i32(tcg_ctx, tmp);
8475 }
8476 } else if (insn & (1 << 20)) {
8477 switch (op1) {
8478 case 0: /* ldrex */
8479 gen_load_exclusive(s, rd, 15, addr, 2);
8480 break;
8481 case 1: /* ldrexd */
8482 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8483 break;
8484 case 2: /* ldrexb */
8485 gen_load_exclusive(s, rd, 15, addr, 0);
8486 break;
8487 case 3: /* ldrexh */
8488 gen_load_exclusive(s, rd, 15, addr, 1);
8489 break;
8490 default:
8491 abort();
8492 }
8493 } else {
8494 rm = insn & 0xf;
8495 switch (op1) {
8496 case 0: /* strex */
8497 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8498 break;
8499 case 1: /* strexd */
8500 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8501 break;
8502 case 2: /* strexb */
8503 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8504 break;
8505 case 3: /* strexh */
8506 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8507 break;
8508 default:
8509 abort();
8510 }
8511 }
8512 tcg_temp_free_i32(tcg_ctx, addr);
8513 } else {
8514 /* SWP instruction */
8515 rm = (insn) & 0xf;
8516
8517 /* ??? This is not really atomic. However we know
8518 we never have multiple CPUs running in parallel,
8519 so it is good enough. */
8520 addr = load_reg(s, rn);
8521 tmp = load_reg(s, rm);
8522 tmp2 = tcg_temp_new_i32(tcg_ctx);
8523 if (insn & (1 << 22)) {
8524 gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
8525 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8526 } else {
8527 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8528 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8529 }
8530 tcg_temp_free_i32(tcg_ctx, tmp);
8531 tcg_temp_free_i32(tcg_ctx, addr);
8532 store_reg(s, rd, tmp2);
8533 }
8534 }
8535 } else {
8536 int address_offset;
8537 int load = insn & (1 << 20);
8538 int wbit = insn & (1 << 21);
8539 int pbit = insn & (1 << 24);
8540 int doubleword = 0;
8541 /* Misc load/store */
8542 rn = (insn >> 16) & 0xf;
8543 rd = (insn >> 12) & 0xf;
8544 if (!load && (sh & 2)) {
8545 /* doubleword */
8546 ARCH(5TE);
8547 if (rd & 1) {
8548 /* UNPREDICTABLE; we choose to UNDEF */
8549 goto illegal_op;
8550 }
8551 load = (sh & 1) == 0;
8552 doubleword = 1;
8553 }
8554 addr = load_reg(s, rn);
8555 if (pbit)
8556 gen_add_datah_offset(s, insn, 0, addr);
8557 address_offset = 0;
8558 if (doubleword) {
8559 if (!load) {
8560 /* store */
8561 tmp = load_reg(s, rd);
8562 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8563 tcg_temp_free_i32(tcg_ctx, tmp);
8564 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
8565 tmp = load_reg(s, rd + 1);
8566 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8567 tcg_temp_free_i32(tcg_ctx, tmp);
8568 } else {
8569 /* load */
8570 tmp = tcg_temp_new_i32(tcg_ctx);
8571 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8572 store_reg(s, rd, tmp);
8573 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
8574 tmp = tcg_temp_new_i32(tcg_ctx);
8575 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8576 rd++;
8577 }
8578 address_offset = -4;
8579 } else if (load) {
8580 /* load */
8581 tmp = tcg_temp_new_i32(tcg_ctx);
8582 switch(sh) {
8583 case 1:
8584 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8585 break;
8586 case 2:
8587 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8588 break;
8589 default:
8590 case 3:
8591 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8592 break;
8593 }
8594 } else {
8595 /* store */
8596 tmp = load_reg(s, rd);
8597 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8598 tcg_temp_free_i32(tcg_ctx, tmp);
8599 }
8600 /* Perform base writeback before the loaded value to
8601 ensure correct behavior with overlapping index registers.
8602 ldrd with base writeback is is undefined if the
8603 destination and index registers overlap. */
8604 if (!pbit) {
8605 gen_add_datah_offset(s, insn, address_offset, addr);
8606 store_reg(s, rn, addr);
8607 } else if (wbit) {
8608 if (address_offset)
8609 tcg_gen_addi_i32(tcg_ctx, addr, addr, address_offset);
8610 store_reg(s, rn, addr);
8611 } else {
8612 tcg_temp_free_i32(tcg_ctx, addr);
8613 }
8614 if (load) {
8615 /* Complete the load. */
8616 store_reg(s, rd, tmp);
8617 }
8618 }
8619 break;
8620 case 0x4:
8621 case 0x5:
8622 goto do_ldst;
8623 case 0x6:
8624 case 0x7:
8625 if (insn & (1 << 4)) {
8626 ARCH(6);
8627 /* Armv6 Media instructions. */
8628 rm = insn & 0xf;
8629 rn = (insn >> 16) & 0xf;
8630 rd = (insn >> 12) & 0xf;
8631 rs = (insn >> 8) & 0xf;
8632 switch ((insn >> 23) & 3) {
8633 case 0: /* Parallel add/subtract. */
8634 op1 = (insn >> 20) & 7;
8635 tmp = load_reg(s, rn);
8636 tmp2 = load_reg(s, rm);
8637 sh = (insn >> 5) & 7;
8638 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8639 goto illegal_op;
8640 gen_arm_parallel_addsub(s, op1, sh, tmp, tmp2);
8641 tcg_temp_free_i32(tcg_ctx, tmp2);
8642 store_reg(s, rd, tmp);
8643 break;
8644 case 1:
8645 if ((insn & 0x00700020) == 0) {
8646 /* Halfword pack. */
8647 tmp = load_reg(s, rn);
8648 tmp2 = load_reg(s, rm);
8649 shift = (insn >> 7) & 0x1f;
8650 if (insn & (1 << 6)) {
8651 /* pkhtb */
8652 if (shift == 0)
8653 shift = 31;
8654 tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, shift);
8655 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff0000);
8656 tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
8657 } else {
8658 /* pkhbt */
8659 if (shift)
8660 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, shift);
8661 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
8662 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
8663 }
8664 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
8665 tcg_temp_free_i32(tcg_ctx, tmp2);
8666 store_reg(s, rd, tmp);
8667 } else if ((insn & 0x00200020) == 0x00200000) {
8668 /* [us]sat */
8669 tmp = load_reg(s, rm);
8670 shift = (insn >> 7) & 0x1f;
8671 if (insn & (1 << 6)) {
8672 if (shift == 0)
8673 shift = 31;
8674 tcg_gen_sari_i32(tcg_ctx, tmp, tmp, shift);
8675 } else {
8676 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
8677 }
8678 sh = (insn >> 16) & 0x1f;
8679 tmp2 = tcg_const_i32(tcg_ctx, sh);
8680 if (insn & (1 << 22))
8681 gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8682 else
8683 gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8684 tcg_temp_free_i32(tcg_ctx, tmp2);
8685 store_reg(s, rd, tmp);
8686 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8687 /* [us]sat16 */
8688 tmp = load_reg(s, rm);
8689 sh = (insn >> 16) & 0x1f;
8690 tmp2 = tcg_const_i32(tcg_ctx, sh);
8691 if (insn & (1 << 22))
8692 gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8693 else
8694 gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8695 tcg_temp_free_i32(tcg_ctx, tmp2);
8696 store_reg(s, rd, tmp);
8697 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8698 /* Select bytes. */
8699 tmp = load_reg(s, rn);
8700 tmp2 = load_reg(s, rm);
8701 tmp3 = tcg_temp_new_i32(tcg_ctx);
8702 tcg_gen_ld_i32(tcg_ctx, tmp3, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
8703 gen_helper_sel_flags(tcg_ctx, tmp, tmp3, tmp, tmp2);
8704 tcg_temp_free_i32(tcg_ctx, tmp3);
8705 tcg_temp_free_i32(tcg_ctx, tmp2);
8706 store_reg(s, rd, tmp);
8707 } else if ((insn & 0x000003e0) == 0x00000060) {
8708 tmp = load_reg(s, rm);
8709 shift = (insn >> 10) & 3;
8710 /* ??? In many cases it's not necessary to do a
8711 rotate, a shift is sufficient. */
8712 if (shift != 0)
8713 tcg_gen_rotri_i32(tcg_ctx, tmp, tmp, shift * 8);
8714 op1 = (insn >> 20) & 7;
8715 switch (op1) {
8716 case 0: gen_sxtb16(tmp); break;
8717 case 2: gen_sxtb(tmp); break;
8718 case 3: gen_sxth(tmp); break;
8719 case 4: gen_uxtb16(tmp); break;
8720 case 6: gen_uxtb(tmp); break;
8721 case 7: gen_uxth(tmp); break;
8722 default: goto illegal_op;
8723 }
8724 if (rn != 15) {
8725 tmp2 = load_reg(s, rn);
8726 if ((op1 & 3) == 0) {
8727 gen_add16(s, tmp, tmp2);
8728 } else {
8729 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8730 tcg_temp_free_i32(tcg_ctx, tmp2);
8731 }
8732 }
8733 store_reg(s, rd, tmp);
8734 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8735 /* rev */
8736 tmp = load_reg(s, rm);
8737 if (insn & (1 << 22)) {
8738 if (insn & (1 << 7)) {
8739 gen_revsh(s, tmp);
8740 } else {
8741 ARCH(6T2);
8742 gen_helper_rbit(tcg_ctx, tmp, tmp);
8743 }
8744 } else {
8745 if (insn & (1 << 7))
8746 gen_rev16(s, tmp);
8747 else
8748 tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp);
8749 }
8750 store_reg(s, rd, tmp);
8751 } else {
8752 goto illegal_op;
8753 }
8754 break;
8755 case 2: /* Multiplies (Type 3). */
8756 switch ((insn >> 20) & 0x7) {
8757 case 5:
8758 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8759 /* op2 not 00x or 11x : UNDEF */
8760 goto illegal_op;
8761 }
8762 /* Signed multiply most significant [accumulate].
8763 (SMMUL, SMMLA, SMMLS) */
8764 tmp = load_reg(s, rm);
8765 tmp2 = load_reg(s, rs);
8766 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
8767
8768 if (rd != 15) {
8769 tmp = load_reg(s, rd);
8770 if (insn & (1 << 6)) {
8771 tmp64 = gen_subq_msw(s, tmp64, tmp);
8772 } else {
8773 tmp64 = gen_addq_msw(s, tmp64, tmp);
8774 }
8775 }
8776 if (insn & (1 << 5)) {
8777 tcg_gen_addi_i64(tcg_ctx, tmp64, tmp64, 0x80000000u);
8778 }
8779 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
8780 tmp = tcg_temp_new_i32(tcg_ctx);
8781 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
8782 tcg_temp_free_i64(tcg_ctx, tmp64);
8783 store_reg(s, rn, tmp);
8784 break;
8785 case 0:
8786 case 4:
8787 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8788 if (insn & (1 << 7)) {
8789 goto illegal_op;
8790 }
8791 tmp = load_reg(s, rm);
8792 tmp2 = load_reg(s, rs);
8793 if (insn & (1 << 5))
8794 gen_swap_half(s, tmp2);
8795 gen_smul_dual(s, tmp, tmp2);
8796 if (insn & (1 << 22)) {
8797 /* smlald, smlsld */
8798 TCGv_i64 tmp64_2;
8799
8800 tmp64 = tcg_temp_new_i64(tcg_ctx);
8801 tmp64_2 = tcg_temp_new_i64(tcg_ctx);
8802 tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
8803 tcg_gen_ext_i32_i64(tcg_ctx, tmp64_2, tmp2);
8804 tcg_temp_free_i32(tcg_ctx, tmp);
8805 tcg_temp_free_i32(tcg_ctx, tmp2);
8806 if (insn & (1 << 6)) {
8807 tcg_gen_sub_i64(tcg_ctx, tmp64, tmp64, tmp64_2);
8808 } else {
8809 tcg_gen_add_i64(tcg_ctx, tmp64, tmp64, tmp64_2);
8810 }
8811 tcg_temp_free_i64(tcg_ctx, tmp64_2);
8812 gen_addq(s, tmp64, rd, rn);
8813 gen_storeq_reg(s, rd, rn, tmp64);
8814 tcg_temp_free_i64(tcg_ctx, tmp64);
8815 } else {
8816 /* smuad, smusd, smlad, smlsd */
8817 if (insn & (1 << 6)) {
8818 /* This subtraction cannot overflow. */
8819 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
8820 } else {
8821 /* This addition cannot overflow 32 bits;
8822 * however it may overflow considered as a
8823 * signed operation, in which case we must set
8824 * the Q flag.
8825 */
8826 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8827 }
8828 tcg_temp_free_i32(tcg_ctx, tmp2);
8829 if (rd != 15)
8830 {
8831 tmp2 = load_reg(s, rd);
8832 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8833 tcg_temp_free_i32(tcg_ctx, tmp2);
8834 }
8835 store_reg(s, rn, tmp);
8836 }
8837 break;
8838 case 1:
8839 case 3:
8840 /* SDIV, UDIV */
8841 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8842 goto illegal_op;
8843 }
8844 if (((insn >> 5) & 7) || (rd != 15)) {
8845 goto illegal_op;
8846 }
8847 tmp = load_reg(s, rm);
8848 tmp2 = load_reg(s, rs);
8849 if (insn & (1 << 21)) {
8850 gen_helper_udiv(tcg_ctx, tmp, tmp, tmp2);
8851 } else {
8852 gen_helper_sdiv(tcg_ctx, tmp, tmp, tmp2);
8853 }
8854 tcg_temp_free_i32(tcg_ctx, tmp2);
8855 store_reg(s, rn, tmp);
8856 break;
8857 default:
8858 goto illegal_op;
8859 }
8860 break;
8861 case 3:
8862 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8863 switch (op1) {
8864 case 0: /* Unsigned sum of absolute differences. */
8865 ARCH(6);
8866 tmp = load_reg(s, rm);
8867 tmp2 = load_reg(s, rs);
8868 gen_helper_usad8(tcg_ctx, tmp, tmp, tmp2);
8869 tcg_temp_free_i32(tcg_ctx, tmp2);
8870 if (rd != 15) {
8871 tmp2 = load_reg(s, rd);
8872 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8873 tcg_temp_free_i32(tcg_ctx, tmp2);
8874 }
8875 store_reg(s, rn, tmp);
8876 break;
8877 case 0x20: case 0x24: case 0x28: case 0x2c:
8878 /* Bitfield insert/clear. */
8879 ARCH(6T2);
8880 shift = (insn >> 7) & 0x1f;
8881 i = (insn >> 16) & 0x1f;
8882 i = i + 1 - shift;
8883 if (rm == 15) {
8884 tmp = tcg_temp_new_i32(tcg_ctx);
8885 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
8886 } else {
8887 tmp = load_reg(s, rm);
8888 }
8889 if (i != 32) {
8890 tmp2 = load_reg(s, rd);
8891 tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, shift, i);
8892 tcg_temp_free_i32(tcg_ctx, tmp2);
8893 }
8894 store_reg(s, rd, tmp);
8895 break;
8896 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8897 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8898 ARCH(6T2);
8899 tmp = load_reg(s, rm);
8900 shift = (insn >> 7) & 0x1f;
8901 i = ((insn >> 16) & 0x1f) + 1;
8902 if (shift + i > 32)
8903 goto illegal_op;
8904 if (i < 32) {
8905 if (op1 & 0x20) {
8906 gen_ubfx(s, tmp, shift, (1u << i) - 1);
8907 } else {
8908 gen_sbfx(s, tmp, shift, i);
8909 }
8910 }
8911 store_reg(s, rd, tmp);
8912 break;
8913 default:
8914 goto illegal_op;
8915 }
8916 break;
8917 }
8918 break;
8919 }
8920 do_ldst:
8921 /* Check for undefined extension instructions
8922 * per the ARM Bible IE:
8923 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8924 */
8925 sh = (0xf << 20) | (0xf << 4);
8926 if (op1 == 0x7 && ((insn & sh) == sh))
8927 {
8928 goto illegal_op;
8929 }
8930 /* load/store byte/word */
8931 rn = (insn >> 16) & 0xf;
8932 rd = (insn >> 12) & 0xf;
8933 tmp2 = load_reg(s, rn);
8934 if ((insn & 0x01200000) == 0x00200000) {
8935 /* ldrt/strt */
8936 i = MMU_USER_IDX;
8937 } else {
8938 i = get_mem_index(s);
8939 }
8940 if (insn & (1 << 24))
8941 gen_add_data_offset(s, insn, tmp2);
8942 if (insn & (1 << 20)) {
8943 /* load */
8944 tmp = tcg_temp_new_i32(tcg_ctx);
8945 if (insn & (1 << 22)) {
8946 gen_aa32_ld8u(s, tmp, tmp2, i);
8947 } else {
8948 gen_aa32_ld32u(s, tmp, tmp2, i);
8949 }
8950 } else {
8951 /* store */
8952 tmp = load_reg(s, rd);
8953 if (insn & (1 << 22)) {
8954 gen_aa32_st8(s, tmp, tmp2, i);
8955 } else {
8956 gen_aa32_st32(s, tmp, tmp2, i);
8957 }
8958 tcg_temp_free_i32(tcg_ctx, tmp);
8959 }
8960 if (!(insn & (1 << 24))) {
8961 gen_add_data_offset(s, insn, tmp2);
8962 store_reg(s, rn, tmp2);
8963 } else if (insn & (1 << 21)) {
8964 store_reg(s, rn, tmp2);
8965 } else {
8966 tcg_temp_free_i32(tcg_ctx, tmp2);
8967 }
8968 if (insn & (1 << 20)) {
8969 /* Complete the load. */
8970 store_reg_from_load(s, rd, tmp);
8971 }
8972 break;
8973 case 0x08:
8974 case 0x09:
8975 {
8976 int j, n, user, loaded_base;
8977 TCGv_i32 loaded_var;
8978 /* load/store multiple words */
8979 /* XXX: store correct base if write back */
8980 user = 0;
8981 if (insn & (1 << 22)) {
8982 if (IS_USER(s))
8983 goto illegal_op; /* only usable in supervisor mode */
8984
8985 if ((insn & (1 << 15)) == 0)
8986 user = 1;
8987 }
8988 rn = (insn >> 16) & 0xf;
8989 addr = load_reg(s, rn);
8990
8991 /* compute total size */
8992 loaded_base = 0;
8993 TCGV_UNUSED_I32(loaded_var);
8994 n = 0;
8995 for(i=0;i<16;i++) {
8996 if (insn & (1 << i))
8997 n++;
8998 }
8999 /* XXX: test invalid n == 0 case ? */
9000 if (insn & (1 << 23)) {
9001 if (insn & (1 << 24)) {
9002 /* pre increment */
9003 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9004 } else {
9005 /* post increment */
9006 }
9007 } else {
9008 if (insn & (1 << 24)) {
9009 /* pre decrement */
9010 tcg_gen_addi_i32(tcg_ctx, addr, addr, -(n * 4));
9011 } else {
9012 /* post decrement */
9013 if (n != 1)
9014 tcg_gen_addi_i32(tcg_ctx, addr, addr, -((n - 1) * 4));
9015 }
9016 }
9017 j = 0;
9018 for(i=0;i<16;i++) {
9019 if (insn & (1 << i)) {
9020 if (insn & (1 << 20)) {
9021 /* load */
9022 tmp = tcg_temp_new_i32(tcg_ctx);
9023 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9024 if (user) {
9025 tmp2 = tcg_const_i32(tcg_ctx, i);
9026 gen_helper_set_user_reg(tcg_ctx, tcg_ctx->cpu_env, tmp2, tmp);
9027 tcg_temp_free_i32(tcg_ctx, tmp2);
9028 tcg_temp_free_i32(tcg_ctx, tmp);
9029 } else if (i == rn) {
9030 loaded_var = tmp;
9031 loaded_base = 1;
9032 } else {
9033 store_reg_from_load(s, i, tmp);
9034 }
9035 } else {
9036 /* store */
9037 if (i == 15) {
9038 /* special case: r15 = PC + 8 */
9039 val = (long)s->pc + 4;
9040 tmp = tcg_temp_new_i32(tcg_ctx);
9041 tcg_gen_movi_i32(tcg_ctx, tmp, val);
9042 } else if (user) {
9043 tmp = tcg_temp_new_i32(tcg_ctx);
9044 tmp2 = tcg_const_i32(tcg_ctx, i);
9045 gen_helper_get_user_reg(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp2);
9046 tcg_temp_free_i32(tcg_ctx, tmp2);
9047 } else {
9048 tmp = load_reg(s, i);
9049 }
9050 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9051 tcg_temp_free_i32(tcg_ctx, tmp);
9052 }
9053 j++;
9054 /* no need to add after the last transfer */
9055 if (j != n)
9056 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9057 }
9058 }
9059 if (insn & (1 << 21)) {
9060 /* write back */
9061 if (insn & (1 << 23)) {
9062 if (insn & (1 << 24)) {
9063 /* pre increment */
9064 } else {
9065 /* post increment */
9066 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9067 }
9068 } else {
9069 if (insn & (1 << 24)) {
9070 /* pre decrement */
9071 if (n != 1)
9072 tcg_gen_addi_i32(tcg_ctx, addr, addr, -((n - 1) * 4));
9073 } else {
9074 /* post decrement */
9075 tcg_gen_addi_i32(tcg_ctx, addr, addr, -(n * 4));
9076 }
9077 }
9078 store_reg(s, rn, addr);
9079 } else {
9080 tcg_temp_free_i32(tcg_ctx, addr);
9081 }
9082 if (loaded_base) {
9083 store_reg(s, rn, loaded_var);
9084 }
9085 if ((insn & (1 << 22)) && !user) {
9086 /* Restore CPSR from SPSR. */
9087 tmp = load_cpu_field(s->uc, spsr);
9088 gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
9089 tcg_temp_free_i32(tcg_ctx, tmp);
9090 s->is_jmp = DISAS_UPDATE;
9091 }
9092 }
9093 break;
9094 case 0xa:
9095 case 0xb:
9096 {
9097 int32_t offset;
9098
9099 /* branch (and link) */
9100 val = (int32_t)s->pc;
9101 if (insn & (1 << 24)) {
9102 tmp = tcg_temp_new_i32(tcg_ctx);
9103 tcg_gen_movi_i32(tcg_ctx, tmp, val);
9104 store_reg(s, 14, tmp);
9105 }
9106 offset = sextract32(insn << 2, 0, 26);
9107 val += offset + 4;
9108 gen_jmp(s, val);
9109 }
9110 break;
9111 case 0xc:
9112 case 0xd:
9113 case 0xe:
9114 if (((insn >> 8) & 0xe) == 10) {
9115 /* VFP. */
9116 if (disas_vfp_insn(s, insn)) {
9117 goto illegal_op;
9118 }
9119 } else if (disas_coproc_insn(s, insn)) {
9120 /* Coprocessor. */
9121 goto illegal_op;
9122 }
9123 break;
9124 case 0xf: // qq
9125 /* swi */
9126 gen_set_pc_im(s, s->pc);
9127 s->svc_imm = extract32(insn, 0, 24);
9128 s->is_jmp = DISAS_SWI;
9129 break;
9130 default:
9131 illegal_op:
9132 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
9133 break;
9134 }
9135 }
9136 }
9137
9138 /* Return true if this is a Thumb-2 logical op. */
9139 static int
thumb2_logic_op(int op)9140 thumb2_logic_op(int op)
9141 {
9142 return (op < 8);
9143 }
9144
9145 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9146 then set condition code flags based on the result of the operation.
9147 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9148 to the high bit of T1.
9149 Returns zero if the opcode is valid. */
9150
9151 static int
gen_thumb2_data_op(DisasContext * s,int op,int conds,uint32_t shifter_out,TCGv_i32 t0,TCGv_i32 t1)9152 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9153 TCGv_i32 t0, TCGv_i32 t1)
9154 {
9155 TCGContext *tcg_ctx = s->uc->tcg_ctx;
9156 int logic_cc;
9157
9158 logic_cc = 0;
9159 switch (op) {
9160 case 0: /* and */
9161 tcg_gen_and_i32(tcg_ctx, t0, t0, t1);
9162 logic_cc = conds;
9163 break;
9164 case 1: /* bic */
9165 tcg_gen_andc_i32(tcg_ctx, t0, t0, t1);
9166 logic_cc = conds;
9167 break;
9168 case 2: /* orr */
9169 tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
9170 logic_cc = conds;
9171 break;
9172 case 3: /* orn */
9173 tcg_gen_orc_i32(tcg_ctx, t0, t0, t1);
9174 logic_cc = conds;
9175 break;
9176 case 4: /* eor */
9177 tcg_gen_xor_i32(tcg_ctx, t0, t0, t1);
9178 logic_cc = conds;
9179 break;
9180 case 8: /* add */
9181 if (conds)
9182 gen_add_CC(s, t0, t0, t1);
9183 else
9184 tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
9185 break;
9186 case 10: /* adc */
9187 if (conds)
9188 gen_adc_CC(s, t0, t0, t1);
9189 else
9190 gen_adc(s, t0, t1);
9191 break;
9192 case 11: /* sbc */
9193 if (conds) {
9194 gen_sbc_CC(s, t0, t0, t1);
9195 } else {
9196 gen_sub_carry(s, t0, t0, t1);
9197 }
9198 break;
9199 case 13: /* sub */
9200 if (conds)
9201 gen_sub_CC(s, t0, t0, t1);
9202 else
9203 tcg_gen_sub_i32(tcg_ctx, t0, t0, t1);
9204 break;
9205 case 14: /* rsb */
9206 if (conds)
9207 gen_sub_CC(s, t0, t1, t0);
9208 else
9209 tcg_gen_sub_i32(tcg_ctx, t0, t1, t0);
9210 break;
9211 default: /* 5, 6, 7, 9, 12, 15. */
9212 return 1;
9213 }
9214 if (logic_cc) {
9215 gen_logic_CC(s, t0);
9216 if (shifter_out)
9217 gen_set_CF_bit31(s, t1);
9218 }
9219 return 0;
9220 }
9221
9222 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9223 is not legal. */
disas_thumb2_insn(CPUARMState * env,DisasContext * s,uint16_t insn_hw1)9224 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9225 {
9226 TCGContext *tcg_ctx = s->uc->tcg_ctx;
9227 uint32_t insn, imm, shift, offset;
9228 uint32_t rd, rn, rm, rs;
9229 TCGv_i32 tmp;
9230 TCGv_i32 tmp2;
9231 TCGv_i32 tmp3;
9232 TCGv_i32 addr;
9233 TCGv_i64 tmp64;
9234 int op;
9235 int shiftop;
9236 int conds;
9237 int logic_cc;
9238
9239 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9240 || arm_dc_feature(s, ARM_FEATURE_M))) {
9241 /* Thumb-1 cores may need to treat bl and blx as a pair of
9242 16-bit instructions to get correct prefetch abort behavior. */
9243 insn = insn_hw1;
9244 if ((insn & (1 << 12)) == 0) {
9245 ARCH(5);
9246 /* Second half of blx. */
9247 offset = ((insn & 0x7ff) << 1);
9248 tmp = load_reg(s, 14);
9249 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
9250 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xfffffffc);
9251
9252 tmp2 = tcg_temp_new_i32(tcg_ctx);
9253 tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1);
9254 store_reg(s, 14, tmp2);
9255 gen_bx(s, tmp);
9256 return 0;
9257 }
9258 if (insn & (1 << 11)) {
9259 /* Second half of bl. */
9260 offset = ((insn & 0x7ff) << 1) | 1;
9261 tmp = load_reg(s, 14);
9262 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
9263
9264 tmp2 = tcg_temp_new_i32(tcg_ctx);
9265 tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1);
9266 store_reg(s, 14, tmp2);
9267 gen_bx(s, tmp);
9268 return 0;
9269 }
9270 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9271 /* Instruction spans a page boundary. Implement it as two
9272 16-bit instructions in case the second half causes an
9273 prefetch abort. */
9274 offset = ((int32_t)insn << 21) >> 9;
9275 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->pc + 2 + offset);
9276 return 0;
9277 }
9278 /* Fall through to 32-bit decode. */
9279 }
9280
9281 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9282 s->pc += 2;
9283 insn |= (uint32_t)insn_hw1 << 16;
9284
9285 if ((insn & 0xf800e800) != 0xf000e800) {
9286 ARCH(6T2);
9287 }
9288
9289 rn = (insn >> 16) & 0xf;
9290 rs = (insn >> 12) & 0xf;
9291 rd = (insn >> 8) & 0xf;
9292 rm = insn & 0xf;
9293 switch ((insn >> 25) & 0xf) {
9294 case 0: case 1: case 2: case 3:
9295 /* 16-bit instructions. Should never happen. */
9296 abort();
9297 case 4:
9298 if (insn & (1 << 22)) {
9299 /* Other load/store, table branch. */
9300 if (insn & 0x01200000) {
9301 /* Load/store doubleword. */
9302 if (rn == 15) {
9303 addr = tcg_temp_new_i32(tcg_ctx);
9304 tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~3);
9305 } else {
9306 addr = load_reg(s, rn);
9307 }
9308 offset = (insn & 0xff) * 4;
9309 if ((insn & (1 << 23)) == 0)
9310 offset = 0-offset;
9311 if (insn & (1 << 24)) {
9312 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
9313 offset = 0;
9314 }
9315 if (insn & (1 << 20)) {
9316 /* ldrd */
9317 tmp = tcg_temp_new_i32(tcg_ctx);
9318 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9319 store_reg(s, rs, tmp);
9320 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9321 tmp = tcg_temp_new_i32(tcg_ctx);
9322 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9323 store_reg(s, rd, tmp);
9324 } else {
9325 /* strd */
9326 tmp = load_reg(s, rs);
9327 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9328 tcg_temp_free_i32(tcg_ctx, tmp);
9329 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9330 tmp = load_reg(s, rd);
9331 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9332 tcg_temp_free_i32(tcg_ctx, tmp);
9333 }
9334 if (insn & (1 << 21)) {
9335 /* Base writeback. */
9336 if (rn == 15)
9337 goto illegal_op;
9338 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset - 4);
9339 store_reg(s, rn, addr);
9340 } else {
9341 tcg_temp_free_i32(tcg_ctx, addr);
9342 }
9343 } else if ((insn & (1 << 23)) == 0) {
9344 /* Load/store exclusive word. */
9345 addr = tcg_temp_local_new_i32(tcg_ctx);
9346 load_reg_var(s, addr, rn);
9347 tcg_gen_addi_i32(tcg_ctx, addr, addr, (insn & 0xff) << 2);
9348 if (insn & (1 << 20)) {
9349 gen_load_exclusive(s, rs, 15, addr, 2);
9350 } else {
9351 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9352 }
9353 tcg_temp_free_i32(tcg_ctx, addr);
9354 } else if ((insn & (7 << 5)) == 0) {
9355 /* Table Branch. */
9356 if (rn == 15) {
9357 addr = tcg_temp_new_i32(tcg_ctx);
9358 tcg_gen_movi_i32(tcg_ctx, addr, s->pc);
9359 } else {
9360 addr = load_reg(s, rn);
9361 }
9362 tmp = load_reg(s, rm);
9363 tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
9364 if (insn & (1 << 4)) {
9365 /* tbh */
9366 tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
9367 tcg_temp_free_i32(tcg_ctx, tmp);
9368 tmp = tcg_temp_new_i32(tcg_ctx);
9369 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9370 } else { /* tbb */
9371 tcg_temp_free_i32(tcg_ctx, tmp);
9372 tmp = tcg_temp_new_i32(tcg_ctx);
9373 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9374 }
9375 tcg_temp_free_i32(tcg_ctx, addr);
9376 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 1);
9377 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, s->pc);
9378 store_reg(s, 15, tmp);
9379 } else {
9380 int op2 = (insn >> 6) & 0x3;
9381 op = (insn >> 4) & 0x3;
9382 switch (op2) {
9383 case 0:
9384 goto illegal_op;
9385 case 1:
9386 /* Load/store exclusive byte/halfword/doubleword */
9387 if (op == 2) {
9388 goto illegal_op;
9389 }
9390 ARCH(7);
9391 break;
9392 case 2:
9393 /* Load-acquire/store-release */
9394 if (op == 3) {
9395 goto illegal_op;
9396 }
9397 /* Fall through */
9398 case 3:
9399 /* Load-acquire/store-release exclusive */
9400 ARCH(8);
9401 break;
9402 }
9403 addr = tcg_temp_local_new_i32(tcg_ctx);
9404 load_reg_var(s, addr, rn);
9405 if (!(op2 & 1)) {
9406 if (insn & (1 << 20)) {
9407 tmp = tcg_temp_new_i32(tcg_ctx);
9408 switch (op) {
9409 case 0: /* ldab */
9410 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9411 break;
9412 case 1: /* ldah */
9413 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9414 break;
9415 case 2: /* lda */
9416 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9417 break;
9418 default:
9419 abort();
9420 }
9421 store_reg(s, rs, tmp);
9422 } else {
9423 tmp = load_reg(s, rs);
9424 switch (op) {
9425 case 0: /* stlb */
9426 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9427 break;
9428 case 1: /* stlh */
9429 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9430 break;
9431 case 2: /* stl */
9432 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9433 break;
9434 default:
9435 abort();
9436 }
9437 tcg_temp_free_i32(tcg_ctx, tmp);
9438 }
9439 } else if (insn & (1 << 20)) {
9440 gen_load_exclusive(s, rs, rd, addr, op);
9441 } else {
9442 gen_store_exclusive(s, rm, rs, rd, addr, op);
9443 }
9444 tcg_temp_free_i32(tcg_ctx, addr);
9445 }
9446 } else {
9447 /* Load/store multiple, RFE, SRS. */
9448 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9449 /* RFE, SRS: not available in user mode or on M profile */
9450 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9451 goto illegal_op;
9452 }
9453 if (insn & (1 << 20)) {
9454 /* rfe */
9455 addr = load_reg(s, rn);
9456 if ((insn & (1 << 24)) == 0)
9457 tcg_gen_addi_i32(tcg_ctx, addr, addr, -8);
9458 /* Load PC into tmp and CPSR into tmp2. */
9459 tmp = tcg_temp_new_i32(tcg_ctx);
9460 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9461 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9462 tmp2 = tcg_temp_new_i32(tcg_ctx);
9463 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9464 if (insn & (1 << 21)) {
9465 /* Base writeback. */
9466 if (insn & (1 << 24)) {
9467 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9468 } else {
9469 tcg_gen_addi_i32(tcg_ctx, addr, addr, -4);
9470 }
9471 store_reg(s, rn, addr);
9472 } else {
9473 tcg_temp_free_i32(tcg_ctx, addr);
9474 }
9475 gen_rfe(s, tmp, tmp2);
9476 } else {
9477 /* srs */
9478 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9479 insn & (1 << 21));
9480 }
9481 } else {
9482 int i, loaded_base = 0;
9483 TCGv_i32 loaded_var;
9484 /* Load/store multiple. */
9485 addr = load_reg(s, rn);
9486 offset = 0;
9487 for (i = 0; i < 16; i++) {
9488 if (insn & (1 << i))
9489 offset += 4;
9490 }
9491 if (insn & (1 << 24)) {
9492 tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-offset);
9493 }
9494
9495 TCGV_UNUSED_I32(loaded_var);
9496 for (i = 0; i < 16; i++) {
9497 if ((insn & (1 << i)) == 0)
9498 continue;
9499 if (insn & (1 << 20)) {
9500 /* Load. */
9501 tmp = tcg_temp_new_i32(tcg_ctx);
9502 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9503 if (i == 15) {
9504 gen_bx(s, tmp);
9505 } else if (i == rn) {
9506 loaded_var = tmp;
9507 loaded_base = 1;
9508 } else {
9509 store_reg(s, i, tmp);
9510 }
9511 } else {
9512 /* Store. */
9513 tmp = load_reg(s, i);
9514 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9515 tcg_temp_free_i32(tcg_ctx, tmp);
9516 }
9517 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9518 }
9519 if (loaded_base) {
9520 store_reg(s, rn, loaded_var);
9521 }
9522 if (insn & (1 << 21)) {
9523 /* Base register writeback. */
9524 if (insn & (1 << 24)) {
9525 tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-offset);
9526 }
9527 /* Fault if writeback register is in register list. */
9528 if (insn & (1 << rn))
9529 goto illegal_op;
9530 store_reg(s, rn, addr);
9531 } else {
9532 tcg_temp_free_i32(tcg_ctx, addr);
9533 }
9534 }
9535 }
9536 break;
9537 case 5:
9538
9539 op = (insn >> 21) & 0xf;
9540 if (op == 6) {
9541 /* Halfword pack. */
9542 tmp = load_reg(s, rn);
9543 tmp2 = load_reg(s, rm);
9544 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9545 if (insn & (1 << 5)) {
9546 /* pkhtb */
9547 if (shift == 0)
9548 shift = 31;
9549 tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, shift);
9550 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff0000);
9551 tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
9552 } else {
9553 /* pkhbt */
9554 if (shift)
9555 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, shift);
9556 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
9557 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
9558 }
9559 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
9560 tcg_temp_free_i32(tcg_ctx, tmp2);
9561 store_reg(s, rd, tmp);
9562 } else {
9563 /* Data processing register constant shift. */
9564 if (rn == 15) {
9565 tmp = tcg_temp_new_i32(tcg_ctx);
9566 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
9567 } else {
9568 tmp = load_reg(s, rn);
9569 }
9570 tmp2 = load_reg(s, rm);
9571
9572 shiftop = (insn >> 4) & 3;
9573 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9574 conds = (insn & (1 << 20)) != 0;
9575 logic_cc = (conds && thumb2_logic_op(op));
9576 gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
9577 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9578 goto illegal_op;
9579 tcg_temp_free_i32(tcg_ctx, tmp2);
9580 if (rd != 15) {
9581 store_reg(s, rd, tmp);
9582 } else {
9583 tcg_temp_free_i32(tcg_ctx, tmp);
9584 }
9585 }
9586 break;
9587 case 13: /* Misc data processing. */
9588 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9589 if (op < 4 && (insn & 0xf000) != 0xf000)
9590 goto illegal_op;
9591 switch (op) {
9592 case 0: /* Register controlled shift. */
9593 tmp = load_reg(s, rn);
9594 tmp2 = load_reg(s, rm);
9595 if ((insn & 0x70) != 0)
9596 goto illegal_op;
9597 op = (insn >> 21) & 3;
9598 logic_cc = (insn & (1 << 20)) != 0;
9599 gen_arm_shift_reg(s, tmp, op, tmp2, logic_cc);
9600 if (logic_cc)
9601 gen_logic_CC(s, tmp);
9602 store_reg_bx(s, rd, tmp);
9603 break;
9604 case 1: /* Sign/zero extend. */
9605 tmp = load_reg(s, rm);
9606 shift = (insn >> 4) & 3;
9607 /* ??? In many cases it's not necessary to do a
9608 rotate, a shift is sufficient. */
9609 if (shift != 0)
9610 tcg_gen_rotri_i32(tcg_ctx, tmp, tmp, shift * 8);
9611 op = (insn >> 20) & 7;
9612 switch (op) {
9613 case 0: gen_sxth(tmp); break;
9614 case 1: gen_uxth(tmp); break;
9615 case 2: gen_sxtb16(tmp); break;
9616 case 3: gen_uxtb16(tmp); break;
9617 case 4: gen_sxtb(tmp); break;
9618 case 5: gen_uxtb(tmp); break;
9619 default: goto illegal_op;
9620 }
9621 if (rn != 15) {
9622 tmp2 = load_reg(s, rn);
9623 if ((op >> 1) == 1) {
9624 gen_add16(s, tmp, tmp2);
9625 } else {
9626 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9627 tcg_temp_free_i32(tcg_ctx, tmp2);
9628 }
9629 }
9630 store_reg(s, rd, tmp);
9631 break;
9632 case 2: /* SIMD add/subtract. */
9633 op = (insn >> 20) & 7;
9634 shift = (insn >> 4) & 7;
9635 if ((op & 3) == 3 || (shift & 3) == 3)
9636 goto illegal_op;
9637 tmp = load_reg(s, rn);
9638 tmp2 = load_reg(s, rm);
9639 gen_thumb2_parallel_addsub(s, op, shift, tmp, tmp2);
9640 tcg_temp_free_i32(tcg_ctx, tmp2);
9641 store_reg(s, rd, tmp);
9642 break;
9643 case 3: /* Other data processing. */
9644 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9645 if (op < 4) {
9646 /* Saturating add/subtract. */
9647 tmp = load_reg(s, rn);
9648 tmp2 = load_reg(s, rm);
9649 if (op & 1)
9650 gen_helper_double_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
9651 if (op & 2)
9652 gen_helper_sub_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp2, tmp);
9653 else
9654 gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9655 tcg_temp_free_i32(tcg_ctx, tmp2);
9656 } else {
9657 tmp = load_reg(s, rn);
9658 switch (op) {
9659 case 0x0a: /* rbit */
9660 gen_helper_rbit(tcg_ctx, tmp, tmp);
9661 break;
9662 case 0x08: /* rev */
9663 tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp);
9664 break;
9665 case 0x09: /* rev16 */
9666 gen_rev16(s, tmp);
9667 break;
9668 case 0x0b: /* revsh */
9669 gen_revsh(s, tmp);
9670 break;
9671 case 0x10: /* sel */
9672 tmp2 = load_reg(s, rm);
9673 tmp3 = tcg_temp_new_i32(tcg_ctx);
9674 tcg_gen_ld_i32(tcg_ctx, tmp3, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
9675 gen_helper_sel_flags(tcg_ctx, tmp, tmp3, tmp, tmp2);
9676 tcg_temp_free_i32(tcg_ctx, tmp3);
9677 tcg_temp_free_i32(tcg_ctx, tmp2);
9678 break;
9679 case 0x18: /* clz */
9680 gen_helper_clz(tcg_ctx, tmp, tmp);
9681 break;
9682 case 0x20:
9683 case 0x21:
9684 case 0x22:
9685 case 0x28:
9686 case 0x29:
9687 case 0x2a:
9688 {
9689 /* crc32/crc32c */
9690 uint32_t sz = op & 0x3;
9691 uint32_t c = op & 0x8;
9692
9693 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9694 goto illegal_op;
9695 }
9696
9697 tmp2 = load_reg(s, rm);
9698 if (sz == 0) {
9699 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
9700 } else if (sz == 1) {
9701 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff);
9702 }
9703 tmp3 = tcg_const_i32(tcg_ctx, 1 << sz);
9704 if (c) {
9705 gen_helper_crc32c(tcg_ctx, tmp, tmp, tmp2, tmp3);
9706 } else {
9707 gen_helper_crc32(tcg_ctx, tmp, tmp, tmp2, tmp3);
9708 }
9709 tcg_temp_free_i32(tcg_ctx, tmp2);
9710 tcg_temp_free_i32(tcg_ctx, tmp3);
9711 break;
9712 }
9713 default:
9714 goto illegal_op;
9715 }
9716 }
9717 store_reg(s, rd, tmp);
9718 break;
9719 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9720 op = (insn >> 4) & 0xf;
9721 tmp = load_reg(s, rn);
9722 tmp2 = load_reg(s, rm);
9723 switch ((insn >> 20) & 7) {
9724 case 0: /* 32 x 32 -> 32 */
9725 tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
9726 tcg_temp_free_i32(tcg_ctx, tmp2);
9727 if (rs != 15) {
9728 tmp2 = load_reg(s, rs);
9729 if (op)
9730 tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
9731 else
9732 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9733 tcg_temp_free_i32(tcg_ctx, tmp2);
9734 }
9735 break;
9736 case 1: /* 16 x 16 -> 32 */
9737 gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
9738 tcg_temp_free_i32(tcg_ctx, tmp2);
9739 if (rs != 15) {
9740 tmp2 = load_reg(s, rs);
9741 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9742 tcg_temp_free_i32(tcg_ctx, tmp2);
9743 }
9744 break;
9745 case 2: /* Dual multiply add. */
9746 case 4: /* Dual multiply subtract. */
9747 if (op)
9748 gen_swap_half(s, tmp2);
9749 gen_smul_dual(s, tmp, tmp2);
9750 if (insn & (1 << 22)) {
9751 /* This subtraction cannot overflow. */
9752 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
9753 } else {
9754 /* This addition cannot overflow 32 bits;
9755 * however it may overflow considered as a signed
9756 * operation, in which case we must set the Q flag.
9757 */
9758 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9759 }
9760 tcg_temp_free_i32(tcg_ctx, tmp2);
9761 if (rs != 15)
9762 {
9763 tmp2 = load_reg(s, rs);
9764 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9765 tcg_temp_free_i32(tcg_ctx, tmp2);
9766 }
9767 break;
9768 case 3: /* 32 * 16 -> 32msb */
9769 if (op)
9770 tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, 16);
9771 else
9772 gen_sxth(tmp2);
9773 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9774 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 16);
9775 tmp = tcg_temp_new_i32(tcg_ctx);
9776 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
9777 tcg_temp_free_i64(tcg_ctx, tmp64);
9778 if (rs != 15)
9779 {
9780 tmp2 = load_reg(s, rs);
9781 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9782 tcg_temp_free_i32(tcg_ctx, tmp2);
9783 }
9784 break;
9785 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9786 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9787 if (rs != 15) {
9788 tmp = load_reg(s, rs);
9789 if (insn & (1 << 20)) {
9790 tmp64 = gen_addq_msw(s, tmp64, tmp);
9791 } else {
9792 tmp64 = gen_subq_msw(s, tmp64, tmp);
9793 }
9794 }
9795 if (insn & (1 << 4)) {
9796 tcg_gen_addi_i64(tcg_ctx, tmp64, tmp64, 0x80000000u);
9797 }
9798 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
9799 tmp = tcg_temp_new_i32(tcg_ctx);
9800 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
9801 tcg_temp_free_i64(tcg_ctx, tmp64);
9802 break;
9803 case 7: /* Unsigned sum of absolute differences. */
9804 gen_helper_usad8(tcg_ctx, tmp, tmp, tmp2);
9805 tcg_temp_free_i32(tcg_ctx, tmp2);
9806 if (rs != 15) {
9807 tmp2 = load_reg(s, rs);
9808 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9809 tcg_temp_free_i32(tcg_ctx, tmp2);
9810 }
9811 break;
9812 }
9813 store_reg(s, rd, tmp);
9814 break;
9815 case 6: case 7: /* 64-bit multiply, Divide. */
9816 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9817 tmp = load_reg(s, rn);
9818 tmp2 = load_reg(s, rm);
9819 if ((op & 0x50) == 0x10) {
9820 /* sdiv, udiv */
9821 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9822 goto illegal_op;
9823 }
9824 if (op & 0x20)
9825 gen_helper_udiv(tcg_ctx, tmp, tmp, tmp2);
9826 else
9827 gen_helper_sdiv(tcg_ctx, tmp, tmp, tmp2);
9828 tcg_temp_free_i32(tcg_ctx, tmp2);
9829 store_reg(s, rd, tmp);
9830 } else if ((op & 0xe) == 0xc) {
9831 /* Dual multiply accumulate long. */
9832 if (op & 1)
9833 gen_swap_half(s, tmp2);
9834 gen_smul_dual(s, tmp, tmp2);
9835 if (op & 0x10) {
9836 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
9837 } else {
9838 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9839 }
9840 tcg_temp_free_i32(tcg_ctx, tmp2);
9841 /* BUGFIX */
9842 tmp64 = tcg_temp_new_i64(tcg_ctx);
9843 tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
9844 tcg_temp_free_i32(tcg_ctx, tmp);
9845 gen_addq(s, tmp64, rs, rd);
9846 gen_storeq_reg(s, rs, rd, tmp64);
9847 tcg_temp_free_i64(tcg_ctx, tmp64);
9848 } else {
9849 if (op & 0x20) {
9850 /* Unsigned 64-bit multiply */
9851 tmp64 = gen_mulu_i64_i32(s, tmp, tmp2);
9852 } else {
9853 if (op & 8) {
9854 /* smlalxy */
9855 gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
9856 tcg_temp_free_i32(tcg_ctx, tmp2);
9857 tmp64 = tcg_temp_new_i64(tcg_ctx);
9858 tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
9859 tcg_temp_free_i32(tcg_ctx, tmp);
9860 } else {
9861 /* Signed 64-bit multiply */
9862 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9863 }
9864 }
9865 if (op & 4) {
9866 /* umaal */
9867 gen_addq_lo(s, tmp64, rs);
9868 gen_addq_lo(s, tmp64, rd);
9869 } else if (op & 0x40) {
9870 /* 64-bit accumulate. */
9871 gen_addq(s, tmp64, rs, rd);
9872 }
9873 gen_storeq_reg(s, rs, rd, tmp64);
9874 tcg_temp_free_i64(tcg_ctx, tmp64);
9875 }
9876 break;
9877 }
9878 break;
9879 case 6: case 7: case 14: case 15:
9880 /* Coprocessor. */
9881 if (((insn >> 24) & 3) == 3) {
9882 /* Translate into the equivalent ARM encoding. */
9883 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9884 if (disas_neon_data_insn(s, insn)) {
9885 goto illegal_op;
9886 }
9887 } else if (((insn >> 8) & 0xe) == 10) {
9888 if (disas_vfp_insn(s, insn)) {
9889 goto illegal_op;
9890 }
9891 } else {
9892 if (insn & (1 << 28))
9893 goto illegal_op;
9894 if (disas_coproc_insn(s, insn)) {
9895 goto illegal_op;
9896 }
9897 }
9898 break;
9899 case 8: case 9: case 10: case 11:
9900 if (insn & (1 << 15)) {
9901 /* Branches, misc control. */
9902 if (insn & 0x5000) {
9903 /* Unconditional branch. */
9904 /* signextend(hw1[10:0]) -> offset[:12]. */
9905 offset = ((int32_t)(insn << 5)) >> 9 & ~(int32_t)0xfff;
9906 /* hw1[10:0] -> offset[11:1]. */
9907 offset |= (insn & 0x7ff) << 1;
9908 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9909 offset[24:22] already have the same value because of the
9910 sign extension above. */
9911 offset ^= ((~insn) & (1 << 13)) << 10;
9912 offset ^= ((~insn) & (1 << 11)) << 11;
9913
9914 if (insn & (1 << 14)) {
9915 /* Branch and link. */
9916 tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->pc | 1);
9917 }
9918
9919 offset += s->pc;
9920 if (insn & (1 << 12)) {
9921 /* b/bl */
9922 gen_jmp(s, offset);
9923 } else {
9924 /* blx */
9925 offset &= ~(uint32_t)2;
9926 /* thumb2 bx, no need to check */
9927 gen_bx_im(s, offset);
9928 }
9929 } else if (((insn >> 23) & 7) == 7) {
9930 /* Misc control */
9931 if (insn & (1 << 13))
9932 goto illegal_op;
9933
9934 if (insn & (1 << 26)) {
9935 if (!(insn & (1 << 20))) {
9936 /* Hypervisor call (v7) */
9937 int imm16 = extract32(insn, 16, 4) << 12
9938 | extract32(insn, 0, 12);
9939 ARCH(7);
9940 if (IS_USER(s)) {
9941 goto illegal_op;
9942 }
9943 gen_hvc(s, imm16);
9944 } else {
9945 /* Secure monitor call (v6+) */
9946 ARCH(6K);
9947 if (IS_USER(s)) {
9948 goto illegal_op;
9949 }
9950 gen_smc(s);
9951 }
9952 } else {
9953 op = (insn >> 20) & 7;
9954 switch (op) {
9955 case 0: /* msr cpsr. */
9956 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9957 tmp = load_reg(s, rn);
9958 addr = tcg_const_i32(tcg_ctx, insn & 0xff);
9959 gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
9960 tcg_temp_free_i32(tcg_ctx, addr);
9961 tcg_temp_free_i32(tcg_ctx, tmp);
9962 gen_lookup_tb(s);
9963 break;
9964 }
9965 /* fall through */
9966 case 1: /* msr spsr. */
9967 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9968 goto illegal_op;
9969 }
9970 tmp = load_reg(s, rn);
9971 if (gen_set_psr(s,
9972 msr_mask(s, (insn >> 8) & 0xf, op == 1),
9973 op == 1, tmp))
9974 goto illegal_op;
9975 break;
9976 case 2: /* cps, nop-hint. */
9977 if (((insn >> 8) & 7) == 0) {
9978 gen_nop_hint(s, insn & 0xff);
9979 }
9980 /* Implemented as NOP in user mode. */
9981 if (IS_USER(s))
9982 break;
9983 offset = 0;
9984 imm = 0;
9985 if (insn & (1 << 10)) {
9986 if (insn & (1 << 7))
9987 offset |= CPSR_A;
9988 if (insn & (1 << 6))
9989 offset |= CPSR_I;
9990 if (insn & (1 << 5))
9991 offset |= CPSR_F;
9992 if (insn & (1 << 9))
9993 imm = CPSR_A | CPSR_I | CPSR_F;
9994 }
9995 if (insn & (1 << 8)) {
9996 offset |= 0x1f;
9997 imm |= (insn & 0x1f);
9998 }
9999 if (offset) {
10000 gen_set_psr_im(s, offset, 0, imm);
10001 }
10002 break;
10003 case 3: /* Special control operations. */
10004 ARCH(7);
10005 op = (insn >> 4) & 0xf;
10006 switch (op) {
10007 case 2: /* clrex */
10008 gen_clrex(s);
10009 break;
10010 case 4: /* dsb */
10011 case 5: /* dmb */
10012 case 6: /* isb */
10013 /* These execute as NOPs. */
10014 break;
10015 default:
10016 goto illegal_op;
10017 }
10018 break;
10019 case 4: /* bxj */
10020 /* Trivial implementation equivalent to bx. */
10021 tmp = load_reg(s, rn);
10022 gen_bx(s, tmp);
10023 break;
10024 case 5: /* Exception return. */
10025 if (IS_USER(s)) {
10026 goto illegal_op;
10027 }
10028 if (rn != 14 || rd != 15) {
10029 goto illegal_op;
10030 }
10031 tmp = load_reg(s, rn);
10032 tcg_gen_subi_i32(tcg_ctx, tmp, tmp, insn & 0xff);
10033 gen_exception_return(s, tmp);
10034 break;
10035 case 6: /* mrs cpsr. */
10036 tmp = tcg_temp_new_i32(tcg_ctx);
10037 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10038 addr = tcg_const_i32(tcg_ctx, insn & 0xff);
10039 gen_helper_v7m_mrs(tcg_ctx, tmp, tcg_ctx->cpu_env, addr);
10040 tcg_temp_free_i32(tcg_ctx, addr);
10041 } else {
10042 gen_helper_cpsr_read(tcg_ctx, tmp, tcg_ctx->cpu_env);
10043 }
10044 store_reg(s, rd, tmp);
10045 break;
10046 case 7: /* mrs spsr. */
10047 /* Not accessible in user mode. */
10048 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10049 goto illegal_op;
10050 }
10051 tmp = load_cpu_field(s->uc, spsr);
10052 store_reg(s, rd, tmp);
10053 break;
10054 }
10055 }
10056 } else {
10057 /* Conditional branch. */
10058 op = (insn >> 22) & 0xf;
10059 /* Generate a conditional jump to next instruction. */
10060 s->condlabel = gen_new_label(tcg_ctx);
10061 arm_gen_test_cc(tcg_ctx, op ^ 1, s->condlabel);
10062 s->condjmp = 1;
10063
10064 /* offset[11:1] = insn[10:0] */
10065 offset = (insn & 0x7ff) << 1;
10066 /* offset[17:12] = insn[21:16]. */
10067 offset |= (insn & 0x003f0000) >> 4;
10068 /* offset[31:20] = insn[26]. */
10069 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10070 /* offset[18] = insn[13]. */
10071 offset |= (insn & (1 << 13)) << 5;
10072 /* offset[19] = insn[11]. */
10073 offset |= (insn & (1 << 11)) << 8;
10074
10075 /* jump to the offset */
10076 gen_jmp(s, s->pc + offset);
10077 }
10078 } else {
10079 /* Data processing immediate. */
10080 if (insn & (1 << 25)) {
10081 if (insn & (1 << 24)) {
10082 if (insn & (1 << 20))
10083 goto illegal_op;
10084 /* Bitfield/Saturate. */
10085 op = (insn >> 21) & 7;
10086 imm = insn & 0x1f;
10087 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10088 if (rn == 15) {
10089 tmp = tcg_temp_new_i32(tcg_ctx);
10090 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10091 } else {
10092 tmp = load_reg(s, rn);
10093 }
10094 switch (op) {
10095 case 2: /* Signed bitfield extract. */
10096 imm++;
10097 if (shift + imm > 32)
10098 goto illegal_op;
10099 if (imm < 32)
10100 gen_sbfx(s, tmp, shift, imm);
10101 break;
10102 case 6: /* Unsigned bitfield extract. */
10103 imm++;
10104 if (shift + imm > 32)
10105 goto illegal_op;
10106 if (imm < 32)
10107 gen_ubfx(s, tmp, shift, (1u << imm) - 1);
10108 break;
10109 case 3: /* Bitfield insert/clear. */
10110 if (imm < shift)
10111 goto illegal_op;
10112 imm = imm + 1 - shift;
10113 if (imm != 32) {
10114 tmp2 = load_reg(s, rd);
10115 tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, shift, imm);
10116 tcg_temp_free_i32(tcg_ctx, tmp2);
10117 }
10118 break;
10119 case 7:
10120 goto illegal_op;
10121 default: /* Saturate. */
10122 if (shift) {
10123 if (op & 1)
10124 tcg_gen_sari_i32(tcg_ctx, tmp, tmp, shift);
10125 else
10126 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
10127 }
10128 tmp2 = tcg_const_i32(tcg_ctx, imm);
10129 if (op & 4) {
10130 /* Unsigned. */
10131 if ((op & 1) && shift == 0)
10132 gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10133 else
10134 gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10135 } else {
10136 /* Signed. */
10137 if ((op & 1) && shift == 0)
10138 gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10139 else
10140 gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10141 }
10142 tcg_temp_free_i32(tcg_ctx, tmp2);
10143 break;
10144 }
10145 store_reg(s, rd, tmp);
10146 } else {
10147 imm = ((insn & 0x04000000) >> 15)
10148 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10149 if (insn & (1 << 22)) {
10150 /* 16-bit immediate. */
10151 imm |= (insn >> 4) & 0xf000;
10152 if (insn & (1 << 23)) {
10153 /* movt */
10154 tmp = load_reg(s, rd);
10155 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
10156 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, imm << 16);
10157 } else {
10158 /* movw */
10159 tmp = tcg_temp_new_i32(tcg_ctx);
10160 tcg_gen_movi_i32(tcg_ctx, tmp, imm);
10161 }
10162 } else {
10163 /* Add/sub 12-bit immediate. */
10164 if (rn == 15) {
10165 offset = s->pc & ~(uint32_t)3;
10166 if (insn & (1 << 23))
10167 offset -= imm;
10168 else
10169 offset += imm;
10170 tmp = tcg_temp_new_i32(tcg_ctx);
10171 tcg_gen_movi_i32(tcg_ctx, tmp, offset);
10172 } else {
10173 tmp = load_reg(s, rn);
10174 if (insn & (1 << 23))
10175 tcg_gen_subi_i32(tcg_ctx, tmp, tmp, imm);
10176 else
10177 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, imm);
10178 }
10179 }
10180 store_reg(s, rd, tmp);
10181 }
10182 } else {
10183 int shifter_out = 0;
10184 /* modified 12-bit immediate. */
10185 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10186 imm = (insn & 0xff);
10187 switch (shift) {
10188 case 0: /* XY */
10189 /* Nothing to do. */
10190 break;
10191 case 1: /* 00XY00XY */
10192 imm |= imm << 16;
10193 break;
10194 case 2: /* XY00XY00 */
10195 imm |= imm << 16;
10196 imm <<= 8;
10197 break;
10198 case 3: /* XYXYXYXY */
10199 imm |= imm << 16;
10200 imm |= imm << 8;
10201 break;
10202 default: /* Rotated constant. */
10203 shift = (shift << 1) | (imm >> 7);
10204 imm |= 0x80;
10205 imm = imm << (32 - shift);
10206 shifter_out = 1;
10207 break;
10208 }
10209 tmp2 = tcg_temp_new_i32(tcg_ctx);
10210 tcg_gen_movi_i32(tcg_ctx, tmp2, imm);
10211 rn = (insn >> 16) & 0xf;
10212 if (rn == 15) {
10213 tmp = tcg_temp_new_i32(tcg_ctx);
10214 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10215 } else {
10216 tmp = load_reg(s, rn);
10217 }
10218 op = (insn >> 21) & 0xf;
10219 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10220 shifter_out, tmp, tmp2))
10221 goto illegal_op;
10222 tcg_temp_free_i32(tcg_ctx, tmp2);
10223 rd = (insn >> 8) & 0xf;
10224 if (rd != 15) {
10225 store_reg(s, rd, tmp);
10226 } else {
10227 tcg_temp_free_i32(tcg_ctx, tmp);
10228 }
10229 }
10230 }
10231 break;
10232 case 12: /* Load/store single data item. */
10233 {
10234 int postinc = 0;
10235 int writeback = 0;
10236 int memidx;
10237 if ((insn & 0x01100000) == 0x01000000) {
10238 if (disas_neon_ls_insn(s, insn)) {
10239 goto illegal_op;
10240 }
10241 break;
10242 }
10243 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10244 if (rs == 15) {
10245 if (!(insn & (1 << 20))) {
10246 goto illegal_op;
10247 }
10248 if (op != 2) {
10249 /* Byte or halfword load space with dest == r15 : memory hints.
10250 * Catch them early so we don't emit pointless addressing code.
10251 * This space is a mix of:
10252 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10253 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10254 * cores)
10255 * unallocated hints, which must be treated as NOPs
10256 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10257 * which is easiest for the decoding logic
10258 * Some space which must UNDEF
10259 */
10260 int op1 = (insn >> 23) & 3;
10261 int op2 = (insn >> 6) & 0x3f;
10262 if (op & 2) {
10263 goto illegal_op;
10264 }
10265 if (rn == 15) {
10266 /* UNPREDICTABLE, unallocated hint or
10267 * PLD/PLDW/PLI (literal)
10268 */
10269 return 0;
10270 }
10271 if (op1 & 1) {
10272 return 0; /* PLD/PLDW/PLI or unallocated hint */
10273 }
10274 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10275 return 0; /* PLD/PLDW/PLI or unallocated hint */
10276 }
10277 /* UNDEF space, or an UNPREDICTABLE */
10278 return 1;
10279 }
10280 }
10281 memidx = get_mem_index(s);
10282 if (rn == 15) {
10283 addr = tcg_temp_new_i32(tcg_ctx);
10284 /* PC relative. */
10285 /* s->pc has already been incremented by 4. */
10286 imm = s->pc & 0xfffffffc;
10287 if (insn & (1 << 23))
10288 imm += insn & 0xfff;
10289 else
10290 imm -= insn & 0xfff;
10291 tcg_gen_movi_i32(tcg_ctx, addr, imm);
10292 } else {
10293 addr = load_reg(s, rn);
10294 if (insn & (1 << 23)) {
10295 /* Positive offset. */
10296 imm = insn & 0xfff;
10297 tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10298 } else {
10299 imm = insn & 0xff;
10300 switch ((insn >> 8) & 0xf) {
10301 case 0x0: /* Shifted Register. */
10302 shift = (insn >> 4) & 0xf;
10303 if (shift > 3) {
10304 tcg_temp_free_i32(tcg_ctx, addr);
10305 goto illegal_op;
10306 }
10307 tmp = load_reg(s, rm);
10308 if (shift)
10309 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
10310 tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
10311 tcg_temp_free_i32(tcg_ctx, tmp);
10312 break;
10313 case 0xc: /* Negative offset. */
10314 tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-imm);
10315 break;
10316 case 0xe: /* User privilege. */
10317 tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10318 memidx = MMU_USER_IDX;
10319 break;
10320 case 0x9: /* Post-decrement. */
10321 imm = 0-imm;
10322 /* Fall through. */
10323 case 0xb: /* Post-increment. */
10324 postinc = 1;
10325 writeback = 1;
10326 break;
10327 case 0xd: /* Pre-decrement. */
10328 imm = 0-imm;
10329 /* Fall through. */
10330 case 0xf: /* Pre-increment. */
10331 tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10332 writeback = 1;
10333 break;
10334 default:
10335 tcg_temp_free_i32(tcg_ctx, addr);
10336 goto illegal_op;
10337 }
10338 }
10339 }
10340 if (insn & (1 << 20)) {
10341 /* Load. */
10342 tmp = tcg_temp_new_i32(tcg_ctx);
10343 switch (op) {
10344 case 0:
10345 gen_aa32_ld8u(s, tmp, addr, memidx);
10346 break;
10347 case 4:
10348 gen_aa32_ld8s(s, tmp, addr, memidx);
10349 break;
10350 case 1:
10351 gen_aa32_ld16u(s, tmp, addr, memidx);
10352 break;
10353 case 5:
10354 gen_aa32_ld16s(s, tmp, addr, memidx);
10355 break;
10356 case 2:
10357 gen_aa32_ld32u(s, tmp, addr, memidx);
10358 break;
10359 default:
10360 tcg_temp_free_i32(tcg_ctx, tmp);
10361 tcg_temp_free_i32(tcg_ctx, addr);
10362 goto illegal_op;
10363 }
10364 if (rs == 15) {
10365 gen_bx(s, tmp);
10366 } else {
10367 store_reg(s, rs, tmp);
10368 }
10369 } else {
10370 /* Store. */
10371 tmp = load_reg(s, rs);
10372 switch (op) {
10373 case 0:
10374 gen_aa32_st8(s, tmp, addr, memidx);
10375 break;
10376 case 1:
10377 gen_aa32_st16(s, tmp, addr, memidx);
10378 break;
10379 case 2:
10380 gen_aa32_st32(s, tmp, addr, memidx);
10381 break;
10382 default:
10383 tcg_temp_free_i32(tcg_ctx, tmp);
10384 tcg_temp_free_i32(tcg_ctx, addr);
10385 goto illegal_op;
10386 }
10387 tcg_temp_free_i32(tcg_ctx, tmp);
10388 }
10389 if (postinc)
10390 tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10391 if (writeback) {
10392 store_reg(s, rn, addr);
10393 } else {
10394 tcg_temp_free_i32(tcg_ctx, addr);
10395 }
10396 }
10397 break;
10398 default:
10399 goto illegal_op;
10400 }
10401 return 0;
10402 illegal_op:
10403 return 1;
10404 }
10405
disas_thumb_insn(CPUARMState * env,DisasContext * s)10406 static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
10407 {
10408 TCGContext *tcg_ctx = s->uc->tcg_ctx;
10409 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10410 int32_t offset;
10411 int i;
10412 TCGv_i32 tmp;
10413 TCGv_i32 tmp2;
10414 TCGv_i32 addr;
10415
10416 // Unicorn: end address tells us to stop emulation
10417 if (s->pc == s->uc->addr_end) {
10418 // imitate WFI instruction to halt emulation
10419 s->is_jmp = DISAS_WFI;
10420 return;
10421 }
10422
10423 if (s->condexec_mask) {
10424 cond = s->condexec_cond;
10425 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10426 s->condlabel = gen_new_label(tcg_ctx);
10427 arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
10428 s->condjmp = 1;
10429 }
10430 }
10431
10432 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10433
10434 // Unicorn: trace this instruction on request
10435 if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc)) {
10436 // determine instruction size (Thumb/Thumb2)
10437 switch(insn & 0xf800) {
10438 // Thumb2: 32-bit
10439 case 0xe800:
10440 case 0xf000:
10441 case 0xf800:
10442 gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc);
10443 break;
10444 // Thumb: 16-bit
10445 default:
10446 gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, s->uc, s->pc);
10447 break;
10448 }
10449 // the callback might want to stop emulation immediately
10450 check_exit_request(tcg_ctx);
10451 }
10452
10453 s->pc += 2;
10454
10455 switch (insn >> 12) {
10456 case 0: case 1:
10457
10458 rd = insn & 7;
10459 op = (insn >> 11) & 3;
10460 if (op == 3) {
10461 /* add/subtract */
10462 rn = (insn >> 3) & 7;
10463 tmp = load_reg(s, rn);
10464 if (insn & (1 << 10)) {
10465 /* immediate */
10466 tmp2 = tcg_temp_new_i32(tcg_ctx);
10467 tcg_gen_movi_i32(tcg_ctx, tmp2, (insn >> 6) & 7);
10468 } else {
10469 /* reg */
10470 rm = (insn >> 6) & 7;
10471 tmp2 = load_reg(s, rm);
10472 }
10473 if (insn & (1 << 9)) {
10474 if (s->condexec_mask)
10475 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
10476 else
10477 gen_sub_CC(s, tmp, tmp, tmp2);
10478 } else {
10479 if (s->condexec_mask)
10480 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10481 else
10482 gen_add_CC(s, tmp, tmp, tmp2);
10483 }
10484 tcg_temp_free_i32(tcg_ctx, tmp2);
10485 store_reg(s, rd, tmp);
10486 } else {
10487 /* shift immediate */
10488 rm = (insn >> 3) & 7;
10489 shift = (insn >> 6) & 0x1f;
10490 tmp = load_reg(s, rm);
10491 gen_arm_shift_im(s, tmp, op, shift, s->condexec_mask == 0);
10492 if (!s->condexec_mask)
10493 gen_logic_CC(s, tmp);
10494 store_reg(s, rd, tmp);
10495 }
10496 break;
10497 case 2: case 3:
10498 /* arithmetic large immediate */
10499 op = (insn >> 11) & 3;
10500 rd = (insn >> 8) & 0x7;
10501 if (op == 0) { /* mov */
10502 tmp = tcg_temp_new_i32(tcg_ctx);
10503 tcg_gen_movi_i32(tcg_ctx, tmp, insn & 0xff);
10504 if (!s->condexec_mask)
10505 gen_logic_CC(s, tmp);
10506 store_reg(s, rd, tmp);
10507 } else {
10508 tmp = load_reg(s, rd);
10509 tmp2 = tcg_temp_new_i32(tcg_ctx);
10510 tcg_gen_movi_i32(tcg_ctx, tmp2, insn & 0xff);
10511 switch (op) {
10512 case 1: /* cmp */
10513 gen_sub_CC(s, tmp, tmp, tmp2);
10514 tcg_temp_free_i32(tcg_ctx, tmp);
10515 tcg_temp_free_i32(tcg_ctx, tmp2);
10516 break;
10517 case 2: /* add */
10518 if (s->condexec_mask)
10519 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10520 else
10521 gen_add_CC(s, tmp, tmp, tmp2);
10522 tcg_temp_free_i32(tcg_ctx, tmp2);
10523 store_reg(s, rd, tmp);
10524 break;
10525 case 3: /* sub */
10526 if (s->condexec_mask)
10527 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
10528 else
10529 gen_sub_CC(s, tmp, tmp, tmp2);
10530 tcg_temp_free_i32(tcg_ctx, tmp2);
10531 store_reg(s, rd, tmp);
10532 break;
10533 }
10534 }
10535 break;
10536 case 4:
10537 if (insn & (1 << 11)) {
10538 rd = (insn >> 8) & 7;
10539 /* load pc-relative. Bit 1 of PC is ignored. */
10540 val = s->pc + 2 + ((insn & 0xff) * 4);
10541 val &= ~(uint32_t)2;
10542 addr = tcg_temp_new_i32(tcg_ctx);
10543 tcg_gen_movi_i32(tcg_ctx, addr, val);
10544 tmp = tcg_temp_new_i32(tcg_ctx);
10545 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10546 tcg_temp_free_i32(tcg_ctx, addr);
10547 store_reg(s, rd, tmp);
10548 break;
10549 }
10550 if (insn & (1 << 10)) {
10551 /* data processing extended or blx */
10552 rd = (insn & 7) | ((insn >> 4) & 8);
10553 rm = (insn >> 3) & 0xf;
10554 op = (insn >> 8) & 3;
10555 switch (op) {
10556 case 0: /* add */
10557 tmp = load_reg(s, rd);
10558 tmp2 = load_reg(s, rm);
10559 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10560 tcg_temp_free_i32(tcg_ctx, tmp2);
10561 store_reg(s, rd, tmp);
10562 break;
10563 case 1: /* cmp */
10564 tmp = load_reg(s, rd);
10565 tmp2 = load_reg(s, rm);
10566 gen_sub_CC(s, tmp, tmp, tmp2);
10567 tcg_temp_free_i32(tcg_ctx, tmp2);
10568 tcg_temp_free_i32(tcg_ctx, tmp);
10569 break;
10570 case 2: /* mov/cpy */
10571 tmp = load_reg(s, rm);
10572 store_reg(s, rd, tmp);
10573 break;
10574 case 3:/* branch [and link] exchange thumb register */
10575 tmp = load_reg(s, rm);
10576 if (insn & (1 << 7)) {
10577 ARCH(5);
10578 val = (uint32_t)s->pc | 1;
10579 tmp2 = tcg_temp_new_i32(tcg_ctx);
10580 tcg_gen_movi_i32(tcg_ctx, tmp2, val);
10581 store_reg(s, 14, tmp2);
10582 }
10583 /* already thumb, no need to check */
10584 gen_bx(s, tmp);
10585 break;
10586 }
10587 break;
10588 }
10589
10590 /* data processing register */
10591 rd = insn & 7;
10592 rm = (insn >> 3) & 7;
10593 op = (insn >> 6) & 0xf;
10594 if (op == 2 || op == 3 || op == 4 || op == 7) {
10595 /* the shift/rotate ops want the operands backwards */
10596 val = rm;
10597 rm = rd;
10598 rd = val;
10599 val = 1;
10600 } else {
10601 val = 0;
10602 }
10603
10604 if (op == 9) { /* neg */
10605 tmp = tcg_temp_new_i32(tcg_ctx);
10606 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10607 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10608 tmp = load_reg(s, rd);
10609 } else {
10610 TCGV_UNUSED_I32(tmp);
10611 }
10612
10613 tmp2 = load_reg(s, rm);
10614 switch (op) {
10615 case 0x0: /* and */
10616 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
10617 if (!s->condexec_mask)
10618 gen_logic_CC(s, tmp);
10619 break;
10620 case 0x1: /* eor */
10621 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
10622 if (!s->condexec_mask)
10623 gen_logic_CC(s, tmp);
10624 break;
10625 case 0x2: /* lsl */
10626 if (s->condexec_mask) {
10627 gen_shl(s, tmp2, tmp2, tmp);
10628 } else {
10629 gen_helper_shl_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10630 gen_logic_CC(s, tmp2);
10631 }
10632 break;
10633 case 0x3: /* lsr */
10634 if (s->condexec_mask) {
10635 gen_shr(s, tmp2, tmp2, tmp);
10636 } else {
10637 gen_helper_shr_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10638 gen_logic_CC(s, tmp2);
10639 }
10640 break;
10641 case 0x4: /* asr */
10642 if (s->condexec_mask) {
10643 gen_sar(s, tmp2, tmp2, tmp);
10644 } else {
10645 gen_helper_sar_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10646 gen_logic_CC(s, tmp2);
10647 }
10648 break;
10649 case 0x5: /* adc */
10650 if (s->condexec_mask) {
10651 gen_adc(s, tmp, tmp2);
10652 } else {
10653 gen_adc_CC(s, tmp, tmp, tmp2);
10654 }
10655 break;
10656 case 0x6: /* sbc */
10657 if (s->condexec_mask) {
10658 gen_sub_carry(s, tmp, tmp, tmp2);
10659 } else {
10660 gen_sbc_CC(s, tmp, tmp, tmp2);
10661 }
10662 break;
10663 case 0x7: /* ror */
10664 if (s->condexec_mask) {
10665 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x1f);
10666 tcg_gen_rotr_i32(tcg_ctx, tmp2, tmp2, tmp);
10667 } else {
10668 gen_helper_ror_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10669 gen_logic_CC(s, tmp2);
10670 }
10671 break;
10672 case 0x8: /* tst */
10673 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
10674 gen_logic_CC(s, tmp);
10675 rd = 16;
10676 break;
10677 case 0x9: /* neg */
10678 if (s->condexec_mask)
10679 tcg_gen_neg_i32(tcg_ctx, tmp, tmp2);
10680 else
10681 gen_sub_CC(s, tmp, tmp, tmp2);
10682 break;
10683 case 0xa: /* cmp */
10684 gen_sub_CC(s, tmp, tmp, tmp2);
10685 rd = 16;
10686 break;
10687 case 0xb: /* cmn */
10688 gen_add_CC(s, tmp, tmp, tmp2);
10689 rd = 16;
10690 break;
10691 case 0xc: /* orr */
10692 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
10693 if (!s->condexec_mask)
10694 gen_logic_CC(s, tmp);
10695 break;
10696 case 0xd: /* mul */
10697 tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
10698 if (!s->condexec_mask)
10699 gen_logic_CC(s, tmp);
10700 break;
10701 case 0xe: /* bic */
10702 tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
10703 if (!s->condexec_mask)
10704 gen_logic_CC(s, tmp);
10705 break;
10706 case 0xf: /* mvn */
10707 tcg_gen_not_i32(tcg_ctx, tmp2, tmp2);
10708 if (!s->condexec_mask)
10709 gen_logic_CC(s, tmp2);
10710 val = 1;
10711 rm = rd;
10712 break;
10713 }
10714 if (rd != 16) {
10715 if (val) {
10716 store_reg(s, rm, tmp2);
10717 if (op != 0xf)
10718 tcg_temp_free_i32(tcg_ctx, tmp);
10719 } else {
10720 store_reg(s, rd, tmp);
10721 tcg_temp_free_i32(tcg_ctx, tmp2);
10722 }
10723 } else {
10724 tcg_temp_free_i32(tcg_ctx, tmp);
10725 tcg_temp_free_i32(tcg_ctx, tmp2);
10726 }
10727 break;
10728
10729 case 5:
10730 /* load/store register offset. */
10731 rd = insn & 7;
10732 rn = (insn >> 3) & 7;
10733 rm = (insn >> 6) & 7;
10734 op = (insn >> 9) & 7;
10735 addr = load_reg(s, rn);
10736 tmp = load_reg(s, rm);
10737 tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
10738 tcg_temp_free_i32(tcg_ctx, tmp);
10739
10740 if (op < 3) { /* store */
10741 tmp = load_reg(s, rd);
10742 } else {
10743 tmp = tcg_temp_new_i32(tcg_ctx);
10744 }
10745
10746 switch (op) {
10747 case 0: /* str */
10748 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10749 break;
10750 case 1: /* strh */
10751 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10752 break;
10753 case 2: /* strb */
10754 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10755 break;
10756 case 3: /* ldrsb */
10757 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
10758 break;
10759 case 4: /* ldr */
10760 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10761 break;
10762 case 5: /* ldrh */
10763 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10764 break;
10765 case 6: /* ldrb */
10766 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10767 break;
10768 case 7: /* ldrsh */
10769 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
10770 break;
10771 }
10772 if (op >= 3) { /* load */
10773 store_reg(s, rd, tmp);
10774 } else {
10775 tcg_temp_free_i32(tcg_ctx, tmp);
10776 }
10777 tcg_temp_free_i32(tcg_ctx, addr);
10778 break;
10779
10780 case 6:
10781 /* load/store word immediate offset */
10782 rd = insn & 7;
10783 rn = (insn >> 3) & 7;
10784 addr = load_reg(s, rn);
10785 val = (insn >> 4) & 0x7c;
10786 tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10787
10788 if (insn & (1 << 11)) {
10789 /* load */
10790 tmp = tcg_temp_new_i32(tcg_ctx);
10791 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10792 store_reg(s, rd, tmp);
10793 } else {
10794 /* store */
10795 tmp = load_reg(s, rd);
10796 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10797 tcg_temp_free_i32(tcg_ctx, tmp);
10798 }
10799 tcg_temp_free_i32(tcg_ctx, addr);
10800 break;
10801
10802 case 7:
10803 /* load/store byte immediate offset */
10804 rd = insn & 7;
10805 rn = (insn >> 3) & 7;
10806 addr = load_reg(s, rn);
10807 val = (insn >> 6) & 0x1f;
10808 tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10809
10810 if (insn & (1 << 11)) {
10811 /* load */
10812 tmp = tcg_temp_new_i32(tcg_ctx);
10813 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10814 store_reg(s, rd, tmp);
10815 } else {
10816 /* store */
10817 tmp = load_reg(s, rd);
10818 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10819 tcg_temp_free_i32(tcg_ctx, tmp);
10820 }
10821 tcg_temp_free_i32(tcg_ctx, addr);
10822 break;
10823
10824 case 8:
10825 /* load/store halfword immediate offset */
10826 rd = insn & 7;
10827 rn = (insn >> 3) & 7;
10828 addr = load_reg(s, rn);
10829 val = (insn >> 5) & 0x3e;
10830 tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10831
10832 if (insn & (1 << 11)) {
10833 /* load */
10834 tmp = tcg_temp_new_i32(tcg_ctx);
10835 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10836 store_reg(s, rd, tmp);
10837 } else {
10838 /* store */
10839 tmp = load_reg(s, rd);
10840 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10841 tcg_temp_free_i32(tcg_ctx, tmp);
10842 }
10843 tcg_temp_free_i32(tcg_ctx, addr);
10844 break;
10845
10846 case 9:
10847 /* load/store from stack */
10848 rd = (insn >> 8) & 7;
10849 addr = load_reg(s, 13);
10850 val = (insn & 0xff) * 4;
10851 tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10852
10853 if (insn & (1 << 11)) {
10854 /* load */
10855 tmp = tcg_temp_new_i32(tcg_ctx);
10856 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10857 store_reg(s, rd, tmp);
10858 } else {
10859 /* store */
10860 tmp = load_reg(s, rd);
10861 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10862 tcg_temp_free_i32(tcg_ctx, tmp);
10863 }
10864 tcg_temp_free_i32(tcg_ctx, addr);
10865 break;
10866
10867 case 10:
10868 /* add to high reg */
10869 rd = (insn >> 8) & 7;
10870 if (insn & (1 << 11)) {
10871 /* SP */
10872 tmp = load_reg(s, 13);
10873 } else {
10874 /* PC. bit 1 is ignored. */
10875 tmp = tcg_temp_new_i32(tcg_ctx);
10876 tcg_gen_movi_i32(tcg_ctx, tmp, (s->pc + 2) & ~(uint32_t)2);
10877 }
10878 val = (insn & 0xff) * 4;
10879 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, val);
10880 store_reg(s, rd, tmp);
10881 break;
10882
10883 case 11:
10884 /* misc */
10885 op = (insn >> 8) & 0xf;
10886 switch (op) {
10887 case 0:
10888 /* adjust stack pointer */
10889 tmp = load_reg(s, 13);
10890 val = (insn & 0x7f) * 4;
10891 if (insn & (1 << 7))
10892 val = -(int32_t)val;
10893 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, val);
10894 store_reg(s, 13, tmp);
10895 break;
10896
10897 case 2: /* sign/zero extend. */
10898 ARCH(6);
10899 rd = insn & 7;
10900 rm = (insn >> 3) & 7;
10901 tmp = load_reg(s, rm);
10902 switch ((insn >> 6) & 3) {
10903 case 0: gen_sxth(tmp); break;
10904 case 1: gen_sxtb(tmp); break;
10905 case 2: gen_uxth(tmp); break;
10906 case 3: gen_uxtb(tmp); break;
10907 }
10908 store_reg(s, rd, tmp);
10909 break;
10910 case 4: case 5: case 0xc: case 0xd:
10911 /* push/pop */
10912 addr = load_reg(s, 13);
10913 if (insn & (1 << 8))
10914 offset = 4;
10915 else
10916 offset = 0;
10917 for (i = 0; i < 8; i++) {
10918 if (insn & (1 << i))
10919 offset += 4;
10920 }
10921 if ((insn & (1 << 11)) == 0) {
10922 tcg_gen_addi_i32(tcg_ctx, addr, addr, -offset);
10923 }
10924 for (i = 0; i < 8; i++) {
10925 if (insn & (1 << i)) {
10926 if (insn & (1 << 11)) {
10927 /* pop */
10928 tmp = tcg_temp_new_i32(tcg_ctx);
10929 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10930 store_reg(s, i, tmp);
10931 } else {
10932 /* push */
10933 tmp = load_reg(s, i);
10934 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10935 tcg_temp_free_i32(tcg_ctx, tmp);
10936 }
10937 /* advance to the next address. */
10938 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
10939 }
10940 }
10941 TCGV_UNUSED_I32(tmp);
10942 if (insn & (1 << 8)) {
10943 if (insn & (1 << 11)) {
10944 /* pop pc */
10945 tmp = tcg_temp_new_i32(tcg_ctx);
10946 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10947 /* don't set the pc until the rest of the instruction
10948 has completed */
10949 } else {
10950 /* push lr */
10951 tmp = load_reg(s, 14);
10952 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10953 tcg_temp_free_i32(tcg_ctx, tmp);
10954 }
10955 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
10956 }
10957 if ((insn & (1 << 11)) == 0) {
10958 tcg_gen_addi_i32(tcg_ctx, addr, addr, -offset);
10959 }
10960 /* write back the new stack pointer */
10961 store_reg(s, 13, addr);
10962 /* set the new PC value */
10963 if ((insn & 0x0900) == 0x0900) {
10964 store_reg_from_load(s, 15, tmp);
10965 }
10966 break;
10967
10968 case 1: case 3: case 9: case 11: /* czb */
10969 rm = insn & 7;
10970 tmp = load_reg(s, rm);
10971 s->condlabel = gen_new_label(tcg_ctx);
10972 s->condjmp = 1;
10973 if (insn & (1 << 11))
10974 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tmp, 0, s->condlabel);
10975 else
10976 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tmp, 0, s->condlabel);
10977 tcg_temp_free_i32(tcg_ctx, tmp);
10978 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10979 val = (uint32_t)s->pc + 2;
10980 val += offset;
10981 gen_jmp(s, val);
10982 break;
10983
10984 case 15: /* IT, nop-hint. */
10985 if ((insn & 0xf) == 0) {
10986 gen_nop_hint(s, (insn >> 4) & 0xf);
10987 break;
10988 }
10989 /* If Then. */
10990 s->condexec_cond = (insn >> 4) & 0xe;
10991 s->condexec_mask = insn & 0x1f;
10992 /* No actual code generated for this insn, just setup state. */
10993 break;
10994
10995 case 0xe: /* bkpt */
10996 {
10997 int imm8 = extract32(insn, 0, 8);
10998 ARCH(5);
10999 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
11000 break;
11001 }
11002
11003 case 0xa: /* rev */
11004 ARCH(6);
11005 rn = (insn >> 3) & 0x7;
11006 rd = insn & 0x7;
11007 tmp = load_reg(s, rn);
11008 switch ((insn >> 6) & 3) {
11009 case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
11010 case 1: gen_rev16(s, tmp); break;
11011 case 3: gen_revsh(s, tmp); break;
11012 default: goto illegal_op;
11013 }
11014 store_reg(s, rd, tmp);
11015 break;
11016
11017 case 6:
11018 switch ((insn >> 5) & 7) {
11019 case 2:
11020 /* setend */
11021 ARCH(6);
11022 if (((insn >> 3) & 1) != s->bswap_code) {
11023 /* Dynamic endianness switching not implemented. */
11024 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
11025 goto illegal_op;
11026 }
11027 break;
11028 case 3:
11029 /* cps */
11030 ARCH(6);
11031 if (IS_USER(s)) {
11032 break;
11033 }
11034 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11035 tmp = tcg_const_i32(tcg_ctx, (insn & (1 << 4)) != 0);
11036 /* FAULTMASK */
11037 if (insn & 1) {
11038 addr = tcg_const_i32(tcg_ctx, 19);
11039 gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
11040 tcg_temp_free_i32(tcg_ctx, addr);
11041 }
11042 /* PRIMASK */
11043 if (insn & 2) {
11044 addr = tcg_const_i32(tcg_ctx, 16);
11045 gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
11046 tcg_temp_free_i32(tcg_ctx, addr);
11047 }
11048 tcg_temp_free_i32(tcg_ctx, tmp);
11049 gen_lookup_tb(s);
11050 } else {
11051 if (insn & (1 << 4)) {
11052 shift = CPSR_A | CPSR_I | CPSR_F;
11053 } else {
11054 shift = 0;
11055 }
11056 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11057 }
11058 break;
11059 default:
11060 goto undef;
11061 }
11062 break;
11063
11064 default:
11065 goto undef;
11066 }
11067 break;
11068
11069 case 12:
11070 {
11071 /* load/store multiple */
11072 TCGv_i32 loaded_var;
11073 TCGV_UNUSED_I32(loaded_var);
11074 rn = (insn >> 8) & 0x7;
11075 addr = load_reg(s, rn);
11076 for (i = 0; i < 8; i++) {
11077 if (insn & (1 << i)) {
11078 if (insn & (1 << 11)) {
11079 /* load */
11080 tmp = tcg_temp_new_i32(tcg_ctx);
11081 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11082 if (i == rn) {
11083 loaded_var = tmp;
11084 } else {
11085 store_reg(s, i, tmp);
11086 }
11087 } else {
11088 /* store */
11089 tmp = load_reg(s, i);
11090 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11091 tcg_temp_free_i32(tcg_ctx, tmp);
11092 }
11093 /* advance to the next address */
11094 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
11095 }
11096 }
11097 if ((insn & (1 << rn)) == 0) {
11098 /* base reg not in list: base register writeback */
11099 store_reg(s, rn, addr);
11100 } else {
11101 /* base reg in list: if load, complete it now */
11102 if (insn & (1 << 11)) {
11103 store_reg(s, rn, loaded_var);
11104 }
11105 tcg_temp_free_i32(tcg_ctx, addr);
11106 }
11107 break;
11108 }
11109 case 13:
11110 /* conditional branch or swi */
11111 cond = (insn >> 8) & 0xf;
11112 if (cond == 0xe)
11113 goto undef;
11114
11115 if (cond == 0xf) {
11116 /* swi */
11117 gen_set_pc_im(s, s->pc);
11118 s->svc_imm = extract32(insn, 0, 8);
11119 s->is_jmp = DISAS_SWI;
11120 break;
11121 }
11122 /* generate a conditional jump to next instruction */
11123 s->condlabel = gen_new_label(tcg_ctx);
11124 arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
11125 s->condjmp = 1;
11126
11127 /* jump to the offset */
11128 val = (uint32_t)s->pc + 2;
11129 offset = ((int32_t)((uint32_t)insn << 24)) >> 24;
11130 val += (int32_t)((uint32_t)offset << 1);
11131 gen_jmp(s, val);
11132 break;
11133
11134 case 14:
11135 if (insn & (1 << 11)) {
11136 if (disas_thumb2_insn(env, s, insn))
11137 goto undef32;
11138 break;
11139 }
11140 /* unconditional branch */
11141 val = (uint32_t)s->pc;
11142 offset = ((int32_t)((uint32_t)insn << 21)) >> 21;
11143 val += (int32_t)((uint32_t)offset << 1) + 2;
11144 gen_jmp(s, val);
11145 break;
11146
11147 case 15:
11148 if (disas_thumb2_insn(env, s, insn))
11149 goto undef32;
11150 break;
11151 }
11152
11153 return;
11154 undef32:
11155 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
11156 return;
11157 illegal_op:
11158 undef:
11159 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
11160 }
11161
11162 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11163 basic block 'tb'. If search_pc is TRUE, also generate PC
11164 information for each intermediate instruction. */
gen_intermediate_code_internal(ARMCPU * cpu,TranslationBlock * tb,bool search_pc)11165 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
11166 TranslationBlock *tb,
11167 bool search_pc)
11168 {
11169 CPUState *cs = CPU(cpu);
11170 CPUARMState *env = &cpu->env;
11171 DisasContext dc1, *dc = &dc1;
11172 CPUBreakpoint *bp;
11173 uint16_t *gen_opc_end;
11174 int j, lj;
11175 target_ulong pc_start;
11176 target_ulong next_page_start;
11177 int num_insns;
11178 int max_insns;
11179 TCGContext *tcg_ctx = env->uc->tcg_ctx;
11180 bool block_full = false;
11181
11182 /* generate intermediate code */
11183
11184 /* The A64 decoder has its own top level loop, because it doesn't need
11185 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11186 */
11187 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11188 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
11189 return;
11190 }
11191
11192 pc_start = tb->pc;
11193
11194 dc->uc = env->uc;
11195 dc->tb = tb;
11196
11197 gen_opc_end = tcg_ctx->gen_opc_buf + OPC_MAX_SIZE;
11198
11199 dc->is_jmp = DISAS_NEXT;
11200 dc->pc = pc_start;
11201
11202 dc->singlestep_enabled = cs->singlestep_enabled;
11203 dc->condjmp = 0;
11204
11205 dc->aarch64 = 0;
11206 dc->thumb = ARM_TBFLAG_THUMB(tb->flags); // qq
11207 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
11208 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11209 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11210 #if !defined(CONFIG_USER_ONLY)
11211 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
11212 #endif
11213 dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
11214 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11215 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11216 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11217 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11218 dc->cp_regs = cpu->cp_regs;
11219 dc->current_el = arm_current_el(env);
11220 dc->features = env->features;
11221
11222 /* Single step state. The code-generation logic here is:
11223 * SS_ACTIVE == 0:
11224 * generate code with no special handling for single-stepping (except
11225 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11226 * this happens anyway because those changes are all system register or
11227 * PSTATE writes).
11228 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11229 * emit code for one insn
11230 * emit code to clear PSTATE.SS
11231 * emit code to generate software step exception for completed step
11232 * end TB (as usual for having generated an exception)
11233 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11234 * emit code to generate a software step exception
11235 * end the TB
11236 */
11237 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11238 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11239 dc->is_ldex = false;
11240 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11241
11242 tcg_ctx->cpu_F0s = tcg_temp_new_i32(tcg_ctx);
11243 tcg_ctx->cpu_F1s = tcg_temp_new_i32(tcg_ctx);
11244 tcg_ctx->cpu_F0d = tcg_temp_new_i64(tcg_ctx);
11245 tcg_ctx->cpu_F1d = tcg_temp_new_i64(tcg_ctx);
11246 tcg_ctx->cpu_V0 = tcg_ctx->cpu_F0d;
11247 tcg_ctx->cpu_V1 = tcg_ctx->cpu_F1d;
11248 /* FIXME: tcg_ctx->cpu_M0 can probably be the same as tcg_ctx->cpu_V0. */
11249 tcg_ctx->cpu_M0 = tcg_temp_new_i64(tcg_ctx);
11250 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11251 lj = -1;
11252 num_insns = 0;
11253 max_insns = tb->cflags & CF_COUNT_MASK;
11254 if (max_insns == 0)
11255 max_insns = CF_COUNT_MASK;
11256
11257 tcg_clear_temp_count();
11258
11259 // Unicorn: early check to see if the address of this block is the until address
11260 if (tb->pc == env->uc->addr_end) {
11261 // imitate WFI instruction to halt emulation
11262 gen_tb_start(tcg_ctx);
11263 dc->is_jmp = DISAS_WFI;
11264 goto tb_end;
11265 }
11266
11267 // Unicorn: trace this block on request
11268 // Only hook this block if it is not broken from previous translation due to
11269 // full translation cache
11270 if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
11271 // save block address to see if we need to patch block size later
11272 env->uc->block_addr = pc_start;
11273 env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
11274 gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
11275 } else {
11276 env->uc->size_arg = -1;
11277 }
11278
11279 gen_tb_start(tcg_ctx);
11280
11281 /* A note on handling of the condexec (IT) bits:
11282 *
11283 * We want to avoid the overhead of having to write the updated condexec
11284 * bits back to the CPUARMState for every instruction in an IT block. So:
11285 * (1) if the condexec bits are not already zero then we write
11286 * zero back into the CPUARMState now. This avoids complications trying
11287 * to do it at the end of the block. (For example if we don't do this
11288 * it's hard to identify whether we can safely skip writing condexec
11289 * at the end of the TB, which we definitely want to do for the case
11290 * where a TB doesn't do anything with the IT state at all.)
11291 * (2) if we are going to leave the TB then we call gen_set_condexec()
11292 * which will write the correct value into CPUARMState if zero is wrong.
11293 * This is done both for leaving the TB at the end, and for leaving
11294 * it because of an exception we know will happen, which is done in
11295 * gen_exception_insn(). The latter is necessary because we need to
11296 * leave the TB with the PC/IT state just prior to execution of the
11297 * instruction which caused the exception.
11298 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11299 * then the CPUARMState will be wrong and we need to reset it.
11300 * This is handled in the same way as restoration of the
11301 * PC in these situations: we will be called again with search_pc=1
11302 * and generate a mapping of the condexec bits for each PC in
11303 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11304 * this to restore the condexec bits.
11305 *
11306 * Note that there are no instructions which can read the condexec
11307 * bits, and none which can write non-static values to them, so
11308 * we don't need to care about whether CPUARMState is correct in the
11309 * middle of a TB.
11310 */
11311
11312 /* Reset the conditional execution bits immediately. This avoids
11313 complications trying to do it at the end of the block. */
11314 if (dc->condexec_mask || dc->condexec_cond)
11315 {
11316 TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
11317 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
11318 store_cpu_field(tcg_ctx, tmp, condexec_bits);
11319 }
11320 do {
11321 //printf(">>> arm pc = %x\n", dc->pc);
11322 #ifdef CONFIG_USER_ONLY
11323 /* Intercept jump to the magic kernel page. */
11324 if (dc->pc >= 0xffff0000) {
11325 /* We always get here via a jump, so know we are not in a
11326 conditional execution block. */
11327 gen_exception_internal(dc, EXCP_KERNEL_TRAP);
11328 dc->is_jmp = DISAS_UPDATE;
11329 break;
11330 }
11331 #else
11332 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11333 /* We always get here via a jump, so know we are not in a
11334 conditional execution block. */
11335 gen_exception_internal(dc, EXCP_EXCEPTION_EXIT);
11336 dc->is_jmp = DISAS_UPDATE;
11337 break;
11338 }
11339 #endif
11340
11341 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11342 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11343 if (bp->pc == dc->pc) {
11344 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11345 /* Advance PC so that clearing the breakpoint will
11346 invalidate this TB. */
11347 dc->pc += 2;
11348 goto done_generating;
11349 }
11350 }
11351 }
11352 if (search_pc) {
11353 j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
11354 if (lj < j) {
11355 lj++;
11356 while (lj < j)
11357 tcg_ctx->gen_opc_instr_start[lj++] = 0;
11358 }
11359 tcg_ctx->gen_opc_pc[lj] = dc->pc;
11360 tcg_ctx->gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11361 tcg_ctx->gen_opc_instr_start[lj] = 1;
11362 //tcg_ctx->gen_opc_icount[lj] = num_insns;
11363 }
11364
11365 //if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11366 // gen_io_start();
11367
11368 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11369 tcg_gen_debug_insn_start(tcg_ctx, dc->pc);
11370 }
11371
11372 if (dc->ss_active && !dc->pstate_ss) {
11373 /* Singlestep state is Active-pending.
11374 * If we're in this state at the start of a TB then either
11375 * a) we just took an exception to an EL which is being debugged
11376 * and this is the first insn in the exception handler
11377 * b) debug exceptions were masked and we just unmasked them
11378 * without changing EL (eg by clearing PSTATE.D)
11379 * In either case we're going to take a swstep exception in the
11380 * "did not step an insn" case, and so the syndrome ISV and EX
11381 * bits should be zero.
11382 */
11383 assert(num_insns == 0);
11384 gen_exception(dc, EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
11385 goto done_generating;
11386 }
11387
11388 if (dc->thumb) { // qq
11389 disas_thumb_insn(env, dc);
11390 if (dc->condexec_mask) {
11391 dc->condexec_cond = (dc->condexec_cond & 0xe)
11392 | ((dc->condexec_mask >> 4) & 1);
11393 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11394 if (dc->condexec_mask == 0) {
11395 dc->condexec_cond = 0;
11396 }
11397 }
11398 } else {
11399 unsigned int insn;
11400
11401 // end address tells us to stop emulation
11402 if (dc->pc == dc->uc->addr_end) {
11403 // imitate WFI instruction to halt emulation
11404 dc->is_jmp = DISAS_WFI;
11405 } else {
11406 insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
11407 dc->pc += 4;
11408 disas_arm_insn(dc, insn);
11409 }
11410 }
11411
11412 if (dc->condjmp && !dc->is_jmp) {
11413 gen_set_label(tcg_ctx, dc->condlabel);
11414 dc->condjmp = 0;
11415 }
11416
11417 if (tcg_check_temp_count()) {
11418 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11419 dc->pc);
11420 }
11421
11422 /* Translation stops when a conditional branch is encountered.
11423 * Otherwise the subsequent code could get translated several times.
11424 * Also stop translation when a page boundary is reached. This
11425 * ensures prefetch aborts occur at the right place. */
11426 num_insns ++;
11427 } while (!dc->is_jmp && tcg_ctx->gen_opc_ptr < gen_opc_end &&
11428 !cs->singlestep_enabled &&
11429 !dc->ss_active &&
11430 dc->pc < next_page_start &&
11431 num_insns < max_insns);
11432
11433 if (tb->cflags & CF_LAST_IO) {
11434 if (dc->condjmp) {
11435 /* FIXME: This can theoretically happen with self-modifying
11436 code. */
11437 cpu_abort(cs, "IO on conditional branch instruction");
11438 }
11439 //gen_io_end();
11440 }
11441
11442 /* if too long translation, save this info */
11443 if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) {
11444 block_full = true;
11445 }
11446
11447 tb_end:
11448
11449 /* At this stage dc->condjmp will only be set when the skipped
11450 instruction was a conditional branch or trap, and the PC has
11451 already been written. */
11452 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11453 /* Make sure the pc is updated, and raise a debug exception. */
11454 if (dc->condjmp) {
11455 gen_set_condexec(dc);
11456 if (dc->is_jmp == DISAS_SWI) {
11457 gen_ss_advance(dc);
11458 gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11459 } else if (dc->is_jmp == DISAS_HVC) {
11460 gen_ss_advance(dc);
11461 gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11462 } else if (dc->is_jmp == DISAS_SMC) {
11463 gen_ss_advance(dc);
11464 gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11465 } else if (dc->ss_active) {
11466 gen_step_complete_exception(dc);
11467 } else {
11468 gen_exception_internal(dc, EXCP_DEBUG);
11469 }
11470 gen_set_label(tcg_ctx, dc->condlabel);
11471 }
11472 if (dc->condjmp || !dc->is_jmp) {
11473 gen_set_pc_im(dc, dc->pc);
11474 dc->condjmp = 0;
11475 }
11476 gen_set_condexec(dc);
11477 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11478 gen_ss_advance(dc);
11479 gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11480 } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11481 gen_ss_advance(dc);
11482 gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11483 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11484 gen_ss_advance(dc);
11485 gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11486 } else if (dc->ss_active) {
11487 gen_step_complete_exception(dc);
11488 } else {
11489 /* FIXME: Single stepping a WFI insn will not halt
11490 the CPU. */
11491 gen_exception_internal(dc, EXCP_DEBUG);
11492 }
11493 } else {
11494 /* While branches must always occur at the end of an IT block,
11495 there are a few other things that can cause us to terminate
11496 the TB in the middle of an IT block:
11497 - Exception generating instructions (bkpt, swi, undefined).
11498 - Page boundaries.
11499 - Hardware watchpoints.
11500 Hardware breakpoints have already been handled and skip this code.
11501 */
11502 gen_set_condexec(dc);
11503 switch(dc->is_jmp) {
11504 case DISAS_NEXT:
11505 gen_goto_tb(dc, 1, dc->pc);
11506 break;
11507 default:
11508 case DISAS_JUMP:
11509 case DISAS_UPDATE:
11510 /* indicate that the hash table must be used to find the next TB */
11511 tcg_gen_exit_tb(tcg_ctx, 0);
11512 break;
11513 case DISAS_TB_JUMP:
11514 /* nothing more to generate */
11515 break;
11516 case DISAS_WFI:
11517 gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
11518 break;
11519 case DISAS_WFE:
11520 gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env);
11521 break;
11522 case DISAS_SWI:
11523 gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11524 break;
11525 case DISAS_HVC:
11526 gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11527 break;
11528 case DISAS_SMC:
11529 gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11530 break;
11531 }
11532 if (dc->condjmp) {
11533 gen_set_label(tcg_ctx, dc->condlabel);
11534 gen_set_condexec(dc);
11535 gen_goto_tb(dc, 1, dc->pc);
11536 dc->condjmp = 0;
11537 }
11538 }
11539
11540 done_generating:
11541 gen_tb_end(tcg_ctx, tb, num_insns);
11542 *tcg_ctx->gen_opc_ptr = INDEX_op_end;
11543
11544 if (search_pc) {
11545 j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
11546 lj++;
11547 while (lj <= j)
11548 tcg_ctx->gen_opc_instr_start[lj++] = 0;
11549 } else {
11550 tb->size = dc->pc - pc_start;
11551 //tb->icount = num_insns;
11552 }
11553
11554 env->uc->block_full = block_full;
11555 }
11556
gen_intermediate_code(CPUARMState * env,TranslationBlock * tb)11557 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11558 {
11559 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11560 }
11561
gen_intermediate_code_pc(CPUARMState * env,TranslationBlock * tb)11562 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11563 {
11564 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11565 }
11566
11567 #if 0
11568 static const char *cpu_mode_names[16] = {
11569 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11570 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11571 };
11572
11573 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11574 int flags)
11575 {
11576 ARMCPU *cpu = ARM_CPU(cs);
11577 CPUARMState *env = &cpu->env;
11578 int i;
11579 uint32_t psr;
11580
11581 if (is_a64(env)) {
11582 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11583 return;
11584 }
11585
11586 for(i=0;i<16;i++) {
11587 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11588 if ((i % 4) == 3)
11589 cpu_fprintf(f, "\n");
11590 else
11591 cpu_fprintf(f, " ");
11592 }
11593 psr = cpsr_read(env);
11594 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11595 psr,
11596 psr & (1 << 31) ? 'N' : '-',
11597 psr & (1 << 30) ? 'Z' : '-',
11598 psr & (1 << 29) ? 'C' : '-',
11599 psr & (1 << 28) ? 'V' : '-',
11600 psr & CPSR_T ? 'T' : 'A',
11601 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11602
11603 if (flags & CPU_DUMP_FPU) {
11604 int numvfpregs = 0;
11605 if (arm_feature(env, ARM_FEATURE_VFP)) {
11606 numvfpregs += 16;
11607 }
11608 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11609 numvfpregs += 16;
11610 }
11611 for (i = 0; i < numvfpregs; i++) {
11612 uint64_t v = float64_val(env->vfp.regs[i]);
11613 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11614 i * 2, (uint32_t)v,
11615 i * 2 + 1, (uint32_t)(v >> 32),
11616 i, v);
11617 }
11618 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11619 }
11620 }
11621 #endif
11622
restore_state_to_opc(CPUARMState * env,TranslationBlock * tb,int pc_pos)11623 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11624 {
11625 TCGContext *tcg_ctx = env->uc->tcg_ctx;
11626 if (is_a64(env)) {
11627 env->pc = tcg_ctx->gen_opc_pc[pc_pos];
11628 env->condexec_bits = 0;
11629 } else {
11630 env->regs[15] = tcg_ctx->gen_opc_pc[pc_pos];
11631 env->condexec_bits = tcg_ctx->gen_opc_condexec_bits[pc_pos];
11632 }
11633 }
11634