qemu-img: Omit error_report() after img_open()
[qemu.git] / target-arm / translate-a64.c
1 /*
2 * AArch64 translation
3 *
4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24
25 #include "cpu.h"
26 #include "tcg-op.h"
27 #include "qemu/log.h"
28 #include "arm_ldst.h"
29 #include "translate.h"
30 #include "internals.h"
31 #include "qemu/host-utils.h"
32
33 #include "exec/gen-icount.h"
34
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
37
38 #include "trace-tcg.h"
39
40 static TCGv_i64 cpu_X[32];
41 static TCGv_i64 cpu_pc;
42 static TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
43
44 /* Load/store exclusive handling */
45 static TCGv_i64 cpu_exclusive_addr;
46 static TCGv_i64 cpu_exclusive_val;
47 static TCGv_i64 cpu_exclusive_high;
48 #ifdef CONFIG_USER_ONLY
49 static TCGv_i64 cpu_exclusive_test;
50 static TCGv_i32 cpu_exclusive_info;
51 #endif
52
53 static const char *regnames[] = {
54 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
55 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
56 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
57 "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
58 };
59
60 enum a64_shift_type {
61 A64_SHIFT_TYPE_LSL = 0,
62 A64_SHIFT_TYPE_LSR = 1,
63 A64_SHIFT_TYPE_ASR = 2,
64 A64_SHIFT_TYPE_ROR = 3
65 };
66
67 /* Table based decoder typedefs - used when the relevant bits for decode
68 * are too awkwardly scattered across the instruction (eg SIMD).
69 */
70 typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn);
71
72 typedef struct AArch64DecodeTable {
73 uint32_t pattern;
74 uint32_t mask;
75 AArch64DecodeFn *disas_fn;
76 } AArch64DecodeTable;
77
78 /* Function prototype for gen_ functions for calling Neon helpers */
79 typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
80 typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
81 typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
82 typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
83 typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
84 typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
85 typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
86 typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
87 typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
88 typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
89 typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
90 typedef void CryptoTwoOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32);
91 typedef void CryptoThreeOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
92
93 /* initialize TCG globals. */
94 void a64_translate_init(void)
95 {
96 int i;
97
98 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
99 offsetof(CPUARMState, pc),
100 "pc");
101 for (i = 0; i < 32; i++) {
102 cpu_X[i] = tcg_global_mem_new_i64(TCG_AREG0,
103 offsetof(CPUARMState, xregs[i]),
104 regnames[i]);
105 }
106
107 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
108 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
109 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
110 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
111
112 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
113 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
114 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
115 offsetof(CPUARMState, exclusive_val), "exclusive_val");
116 cpu_exclusive_high = tcg_global_mem_new_i64(TCG_AREG0,
117 offsetof(CPUARMState, exclusive_high), "exclusive_high");
118 #ifdef CONFIG_USER_ONLY
119 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
120 offsetof(CPUARMState, exclusive_test), "exclusive_test");
121 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
122 offsetof(CPUARMState, exclusive_info), "exclusive_info");
123 #endif
124 }
125
126 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
127 fprintf_function cpu_fprintf, int flags)
128 {
129 ARMCPU *cpu = ARM_CPU(cs);
130 CPUARMState *env = &cpu->env;
131 uint32_t psr = pstate_read(env);
132 int i;
133
134 cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
135 env->pc, env->xregs[31]);
136 for (i = 0; i < 31; i++) {
137 cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
138 if ((i % 4) == 3) {
139 cpu_fprintf(f, "\n");
140 } else {
141 cpu_fprintf(f, " ");
142 }
143 }
144 cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
145 psr,
146 psr & PSTATE_N ? 'N' : '-',
147 psr & PSTATE_Z ? 'Z' : '-',
148 psr & PSTATE_C ? 'C' : '-',
149 psr & PSTATE_V ? 'V' : '-');
150 cpu_fprintf(f, "\n");
151
152 if (flags & CPU_DUMP_FPU) {
153 int numvfpregs = 32;
154 for (i = 0; i < numvfpregs; i += 2) {
155 uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
156 uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
157 cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
158 i, vhi, vlo);
159 vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
160 vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
161 cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
162 i + 1, vhi, vlo);
163 }
164 cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
165 vfp_get_fpcr(env), vfp_get_fpsr(env));
166 }
167 }
168
169 void gen_a64_set_pc_im(uint64_t val)
170 {
171 tcg_gen_movi_i64(cpu_pc, val);
172 }
173
174 static void gen_exception_internal(int excp)
175 {
176 TCGv_i32 tcg_excp = tcg_const_i32(excp);
177
178 assert(excp_is_internal(excp));
179 gen_helper_exception_internal(cpu_env, tcg_excp);
180 tcg_temp_free_i32(tcg_excp);
181 }
182
183 static void gen_exception(int excp, uint32_t syndrome)
184 {
185 TCGv_i32 tcg_excp = tcg_const_i32(excp);
186 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
187
188 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn);
189 tcg_temp_free_i32(tcg_syn);
190 tcg_temp_free_i32(tcg_excp);
191 }
192
193 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
194 {
195 gen_a64_set_pc_im(s->pc - offset);
196 gen_exception_internal(excp);
197 s->is_jmp = DISAS_EXC;
198 }
199
200 static void gen_exception_insn(DisasContext *s, int offset, int excp,
201 uint32_t syndrome)
202 {
203 gen_a64_set_pc_im(s->pc - offset);
204 gen_exception(excp, syndrome);
205 s->is_jmp = DISAS_EXC;
206 }
207
208 static void gen_ss_advance(DisasContext *s)
209 {
210 /* If the singlestep state is Active-not-pending, advance to
211 * Active-pending.
212 */
213 if (s->ss_active) {
214 s->pstate_ss = 0;
215 gen_helper_clear_pstate_ss(cpu_env);
216 }
217 }
218
219 static void gen_step_complete_exception(DisasContext *s)
220 {
221 /* We just completed step of an insn. Move from Active-not-pending
222 * to Active-pending, and then also take the swstep exception.
223 * This corresponds to making the (IMPDEF) choice to prioritize
224 * swstep exceptions over asynchronous exceptions taken to an exception
225 * level where debug is disabled. This choice has the advantage that
226 * we do not need to maintain internal state corresponding to the
227 * ISV/EX syndrome bits between completion of the step and generation
228 * of the exception, and our syndrome information is always correct.
229 */
230 gen_ss_advance(s);
231 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
232 s->is_jmp = DISAS_EXC;
233 }
234
235 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
236 {
237 /* No direct tb linking with singlestep (either QEMU's or the ARM
238 * debug architecture kind) or deterministic io
239 */
240 if (s->singlestep_enabled || s->ss_active || (s->tb->cflags & CF_LAST_IO)) {
241 return false;
242 }
243
244 /* Only link tbs from inside the same guest page */
245 if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
246 return false;
247 }
248
249 return true;
250 }
251
252 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
253 {
254 TranslationBlock *tb;
255
256 tb = s->tb;
257 if (use_goto_tb(s, n, dest)) {
258 tcg_gen_goto_tb(n);
259 gen_a64_set_pc_im(dest);
260 tcg_gen_exit_tb((intptr_t)tb + n);
261 s->is_jmp = DISAS_TB_JUMP;
262 } else {
263 gen_a64_set_pc_im(dest);
264 if (s->ss_active) {
265 gen_step_complete_exception(s);
266 } else if (s->singlestep_enabled) {
267 gen_exception_internal(EXCP_DEBUG);
268 } else {
269 tcg_gen_exit_tb(0);
270 s->is_jmp = DISAS_TB_JUMP;
271 }
272 }
273 }
274
275 static void unallocated_encoding(DisasContext *s)
276 {
277 /* Unallocated and reserved encodings are uncategorized */
278 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
279 }
280
281 #define unsupported_encoding(s, insn) \
282 do { \
283 qemu_log_mask(LOG_UNIMP, \
284 "%s:%d: unsupported instruction encoding 0x%08x " \
285 "at pc=%016" PRIx64 "\n", \
286 __FILE__, __LINE__, insn, s->pc - 4); \
287 unallocated_encoding(s); \
288 } while (0);
289
290 static void init_tmp_a64_array(DisasContext *s)
291 {
292 #ifdef CONFIG_DEBUG_TCG
293 int i;
294 for (i = 0; i < ARRAY_SIZE(s->tmp_a64); i++) {
295 TCGV_UNUSED_I64(s->tmp_a64[i]);
296 }
297 #endif
298 s->tmp_a64_count = 0;
299 }
300
301 static void free_tmp_a64(DisasContext *s)
302 {
303 int i;
304 for (i = 0; i < s->tmp_a64_count; i++) {
305 tcg_temp_free_i64(s->tmp_a64[i]);
306 }
307 init_tmp_a64_array(s);
308 }
309
310 static TCGv_i64 new_tmp_a64(DisasContext *s)
311 {
312 assert(s->tmp_a64_count < TMP_A64_MAX);
313 return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
314 }
315
316 static TCGv_i64 new_tmp_a64_zero(DisasContext *s)
317 {
318 TCGv_i64 t = new_tmp_a64(s);
319 tcg_gen_movi_i64(t, 0);
320 return t;
321 }
322
323 /*
324 * Register access functions
325 *
326 * These functions are used for directly accessing a register in where
327 * changes to the final register value are likely to be made. If you
328 * need to use a register for temporary calculation (e.g. index type
329 * operations) use the read_* form.
330 *
331 * B1.2.1 Register mappings
332 *
333 * In instruction register encoding 31 can refer to ZR (zero register) or
334 * the SP (stack pointer) depending on context. In QEMU's case we map SP
335 * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
336 * This is the point of the _sp forms.
337 */
338 static TCGv_i64 cpu_reg(DisasContext *s, int reg)
339 {
340 if (reg == 31) {
341 return new_tmp_a64_zero(s);
342 } else {
343 return cpu_X[reg];
344 }
345 }
346
347 /* register access for when 31 == SP */
348 static TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
349 {
350 return cpu_X[reg];
351 }
352
353 /* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
354 * representing the register contents. This TCGv is an auto-freed
355 * temporary so it need not be explicitly freed, and may be modified.
356 */
357 static TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
358 {
359 TCGv_i64 v = new_tmp_a64(s);
360 if (reg != 31) {
361 if (sf) {
362 tcg_gen_mov_i64(v, cpu_X[reg]);
363 } else {
364 tcg_gen_ext32u_i64(v, cpu_X[reg]);
365 }
366 } else {
367 tcg_gen_movi_i64(v, 0);
368 }
369 return v;
370 }
371
372 static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
373 {
374 TCGv_i64 v = new_tmp_a64(s);
375 if (sf) {
376 tcg_gen_mov_i64(v, cpu_X[reg]);
377 } else {
378 tcg_gen_ext32u_i64(v, cpu_X[reg]);
379 }
380 return v;
381 }
382
383 /* We should have at some point before trying to access an FP register
384 * done the necessary access check, so assert that
385 * (a) we did the check and
386 * (b) we didn't then just plough ahead anyway if it failed.
387 * Print the instruction pattern in the abort message so we can figure
388 * out what we need to fix if a user encounters this problem in the wild.
389 */
390 static inline void assert_fp_access_checked(DisasContext *s)
391 {
392 #ifdef CONFIG_DEBUG_TCG
393 if (unlikely(!s->fp_access_checked || !s->cpacr_fpen)) {
394 fprintf(stderr, "target-arm: FP access check missing for "
395 "instruction 0x%08x\n", s->insn);
396 abort();
397 }
398 #endif
399 }
400
401 /* Return the offset into CPUARMState of an element of specified
402 * size, 'element' places in from the least significant end of
403 * the FP/vector register Qn.
404 */
405 static inline int vec_reg_offset(DisasContext *s, int regno,
406 int element, TCGMemOp size)
407 {
408 int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
409 #ifdef HOST_WORDS_BIGENDIAN
410 /* This is complicated slightly because vfp.regs[2n] is
411 * still the low half and vfp.regs[2n+1] the high half
412 * of the 128 bit vector, even on big endian systems.
413 * Calculate the offset assuming a fully bigendian 128 bits,
414 * then XOR to account for the order of the two 64 bit halves.
415 */
416 offs += (16 - ((element + 1) * (1 << size)));
417 offs ^= 8;
418 #else
419 offs += element * (1 << size);
420 #endif
421 assert_fp_access_checked(s);
422 return offs;
423 }
424
425 /* Return the offset into CPUARMState of a slice (from
426 * the least significant end) of FP register Qn (ie
427 * Dn, Sn, Hn or Bn).
428 * (Note that this is not the same mapping as for A32; see cpu.h)
429 */
430 static inline int fp_reg_offset(DisasContext *s, int regno, TCGMemOp size)
431 {
432 int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
433 #ifdef HOST_WORDS_BIGENDIAN
434 offs += (8 - (1 << size));
435 #endif
436 assert_fp_access_checked(s);
437 return offs;
438 }
439
440 /* Offset of the high half of the 128 bit vector Qn */
441 static inline int fp_reg_hi_offset(DisasContext *s, int regno)
442 {
443 assert_fp_access_checked(s);
444 return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
445 }
446
447 /* Convenience accessors for reading and writing single and double
448 * FP registers. Writing clears the upper parts of the associated
449 * 128 bit vector register, as required by the architecture.
450 * Note that unlike the GP register accessors, the values returned
451 * by the read functions must be manually freed.
452 */
453 static TCGv_i64 read_fp_dreg(DisasContext *s, int reg)
454 {
455 TCGv_i64 v = tcg_temp_new_i64();
456
457 tcg_gen_ld_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
458 return v;
459 }
460
461 static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
462 {
463 TCGv_i32 v = tcg_temp_new_i32();
464
465 tcg_gen_ld_i32(v, cpu_env, fp_reg_offset(s, reg, MO_32));
466 return v;
467 }
468
469 static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
470 {
471 TCGv_i64 tcg_zero = tcg_const_i64(0);
472
473 tcg_gen_st_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
474 tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(s, reg));
475 tcg_temp_free_i64(tcg_zero);
476 }
477
478 static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
479 {
480 TCGv_i64 tmp = tcg_temp_new_i64();
481
482 tcg_gen_extu_i32_i64(tmp, v);
483 write_fp_dreg(s, reg, tmp);
484 tcg_temp_free_i64(tmp);
485 }
486
487 static TCGv_ptr get_fpstatus_ptr(void)
488 {
489 TCGv_ptr statusptr = tcg_temp_new_ptr();
490 int offset;
491
492 /* In A64 all instructions (both FP and Neon) use the FPCR;
493 * there is no equivalent of the A32 Neon "standard FPSCR value"
494 * and all operations use vfp.fp_status.
495 */
496 offset = offsetof(CPUARMState, vfp.fp_status);
497 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
498 return statusptr;
499 }
500
501 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
502 * than the 32 bit equivalent.
503 */
504 static inline void gen_set_NZ64(TCGv_i64 result)
505 {
506 TCGv_i64 flag = tcg_temp_new_i64();
507
508 tcg_gen_setcondi_i64(TCG_COND_NE, flag, result, 0);
509 tcg_gen_trunc_i64_i32(cpu_ZF, flag);
510 tcg_gen_shri_i64(flag, result, 32);
511 tcg_gen_trunc_i64_i32(cpu_NF, flag);
512 tcg_temp_free_i64(flag);
513 }
514
515 /* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
516 static inline void gen_logic_CC(int sf, TCGv_i64 result)
517 {
518 if (sf) {
519 gen_set_NZ64(result);
520 } else {
521 tcg_gen_trunc_i64_i32(cpu_ZF, result);
522 tcg_gen_trunc_i64_i32(cpu_NF, result);
523 }
524 tcg_gen_movi_i32(cpu_CF, 0);
525 tcg_gen_movi_i32(cpu_VF, 0);
526 }
527
528 /* dest = T0 + T1; compute C, N, V and Z flags */
529 static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
530 {
531 if (sf) {
532 TCGv_i64 result, flag, tmp;
533 result = tcg_temp_new_i64();
534 flag = tcg_temp_new_i64();
535 tmp = tcg_temp_new_i64();
536
537 tcg_gen_movi_i64(tmp, 0);
538 tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
539
540 tcg_gen_trunc_i64_i32(cpu_CF, flag);
541
542 gen_set_NZ64(result);
543
544 tcg_gen_xor_i64(flag, result, t0);
545 tcg_gen_xor_i64(tmp, t0, t1);
546 tcg_gen_andc_i64(flag, flag, tmp);
547 tcg_temp_free_i64(tmp);
548 tcg_gen_shri_i64(flag, flag, 32);
549 tcg_gen_trunc_i64_i32(cpu_VF, flag);
550
551 tcg_gen_mov_i64(dest, result);
552 tcg_temp_free_i64(result);
553 tcg_temp_free_i64(flag);
554 } else {
555 /* 32 bit arithmetic */
556 TCGv_i32 t0_32 = tcg_temp_new_i32();
557 TCGv_i32 t1_32 = tcg_temp_new_i32();
558 TCGv_i32 tmp = tcg_temp_new_i32();
559
560 tcg_gen_movi_i32(tmp, 0);
561 tcg_gen_trunc_i64_i32(t0_32, t0);
562 tcg_gen_trunc_i64_i32(t1_32, t1);
563 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
564 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
565 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
566 tcg_gen_xor_i32(tmp, t0_32, t1_32);
567 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
568 tcg_gen_extu_i32_i64(dest, cpu_NF);
569
570 tcg_temp_free_i32(tmp);
571 tcg_temp_free_i32(t0_32);
572 tcg_temp_free_i32(t1_32);
573 }
574 }
575
576 /* dest = T0 - T1; compute C, N, V and Z flags */
577 static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
578 {
579 if (sf) {
580 /* 64 bit arithmetic */
581 TCGv_i64 result, flag, tmp;
582
583 result = tcg_temp_new_i64();
584 flag = tcg_temp_new_i64();
585 tcg_gen_sub_i64(result, t0, t1);
586
587 gen_set_NZ64(result);
588
589 tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
590 tcg_gen_trunc_i64_i32(cpu_CF, flag);
591
592 tcg_gen_xor_i64(flag, result, t0);
593 tmp = tcg_temp_new_i64();
594 tcg_gen_xor_i64(tmp, t0, t1);
595 tcg_gen_and_i64(flag, flag, tmp);
596 tcg_temp_free_i64(tmp);
597 tcg_gen_shri_i64(flag, flag, 32);
598 tcg_gen_trunc_i64_i32(cpu_VF, flag);
599 tcg_gen_mov_i64(dest, result);
600 tcg_temp_free_i64(flag);
601 tcg_temp_free_i64(result);
602 } else {
603 /* 32 bit arithmetic */
604 TCGv_i32 t0_32 = tcg_temp_new_i32();
605 TCGv_i32 t1_32 = tcg_temp_new_i32();
606 TCGv_i32 tmp;
607
608 tcg_gen_trunc_i64_i32(t0_32, t0);
609 tcg_gen_trunc_i64_i32(t1_32, t1);
610 tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
611 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
612 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
613 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
614 tmp = tcg_temp_new_i32();
615 tcg_gen_xor_i32(tmp, t0_32, t1_32);
616 tcg_temp_free_i32(t0_32);
617 tcg_temp_free_i32(t1_32);
618 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
619 tcg_temp_free_i32(tmp);
620 tcg_gen_extu_i32_i64(dest, cpu_NF);
621 }
622 }
623
624 /* dest = T0 + T1 + CF; do not compute flags. */
625 static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
626 {
627 TCGv_i64 flag = tcg_temp_new_i64();
628 tcg_gen_extu_i32_i64(flag, cpu_CF);
629 tcg_gen_add_i64(dest, t0, t1);
630 tcg_gen_add_i64(dest, dest, flag);
631 tcg_temp_free_i64(flag);
632
633 if (!sf) {
634 tcg_gen_ext32u_i64(dest, dest);
635 }
636 }
637
638 /* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
639 static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
640 {
641 if (sf) {
642 TCGv_i64 result, cf_64, vf_64, tmp;
643 result = tcg_temp_new_i64();
644 cf_64 = tcg_temp_new_i64();
645 vf_64 = tcg_temp_new_i64();
646 tmp = tcg_const_i64(0);
647
648 tcg_gen_extu_i32_i64(cf_64, cpu_CF);
649 tcg_gen_add2_i64(result, cf_64, t0, tmp, cf_64, tmp);
650 tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, tmp);
651 tcg_gen_trunc_i64_i32(cpu_CF, cf_64);
652 gen_set_NZ64(result);
653
654 tcg_gen_xor_i64(vf_64, result, t0);
655 tcg_gen_xor_i64(tmp, t0, t1);
656 tcg_gen_andc_i64(vf_64, vf_64, tmp);
657 tcg_gen_shri_i64(vf_64, vf_64, 32);
658 tcg_gen_trunc_i64_i32(cpu_VF, vf_64);
659
660 tcg_gen_mov_i64(dest, result);
661
662 tcg_temp_free_i64(tmp);
663 tcg_temp_free_i64(vf_64);
664 tcg_temp_free_i64(cf_64);
665 tcg_temp_free_i64(result);
666 } else {
667 TCGv_i32 t0_32, t1_32, tmp;
668 t0_32 = tcg_temp_new_i32();
669 t1_32 = tcg_temp_new_i32();
670 tmp = tcg_const_i32(0);
671
672 tcg_gen_trunc_i64_i32(t0_32, t0);
673 tcg_gen_trunc_i64_i32(t1_32, t1);
674 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, cpu_CF, tmp);
675 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, tmp);
676
677 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
678 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
679 tcg_gen_xor_i32(tmp, t0_32, t1_32);
680 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
681 tcg_gen_extu_i32_i64(dest, cpu_NF);
682
683 tcg_temp_free_i32(tmp);
684 tcg_temp_free_i32(t1_32);
685 tcg_temp_free_i32(t0_32);
686 }
687 }
688
689 /*
690 * Load/Store generators
691 */
692
693 /*
694 * Store from GPR register to memory.
695 */
696 static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
697 TCGv_i64 tcg_addr, int size, int memidx)
698 {
699 g_assert(size <= 3);
700 tcg_gen_qemu_st_i64(source, tcg_addr, memidx, MO_TE + size);
701 }
702
703 static void do_gpr_st(DisasContext *s, TCGv_i64 source,
704 TCGv_i64 tcg_addr, int size)
705 {
706 do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s));
707 }
708
709 /*
710 * Load from memory to GPR register
711 */
712 static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
713 int size, bool is_signed, bool extend, int memidx)
714 {
715 TCGMemOp memop = MO_TE + size;
716
717 g_assert(size <= 3);
718
719 if (is_signed) {
720 memop += MO_SIGN;
721 }
722
723 tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
724
725 if (extend && is_signed) {
726 g_assert(size < 3);
727 tcg_gen_ext32u_i64(dest, dest);
728 }
729 }
730
731 static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
732 int size, bool is_signed, bool extend)
733 {
734 do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
735 get_mem_index(s));
736 }
737
738 /*
739 * Store from FP register to memory
740 */
741 static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
742 {
743 /* This writes the bottom N bits of a 128 bit wide vector to memory */
744 TCGv_i64 tmp = tcg_temp_new_i64();
745 tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
746 if (size < 4) {
747 tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
748 } else {
749 TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
750 tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
751 tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
752 tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
753 tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
754 tcg_temp_free_i64(tcg_hiaddr);
755 }
756
757 tcg_temp_free_i64(tmp);
758 }
759
760 /*
761 * Load from memory to FP register
762 */
763 static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
764 {
765 /* This always zero-extends and writes to a full 128 bit wide vector */
766 TCGv_i64 tmplo = tcg_temp_new_i64();
767 TCGv_i64 tmphi;
768
769 if (size < 4) {
770 TCGMemOp memop = MO_TE + size;
771 tmphi = tcg_const_i64(0);
772 tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
773 } else {
774 TCGv_i64 tcg_hiaddr;
775 tmphi = tcg_temp_new_i64();
776 tcg_hiaddr = tcg_temp_new_i64();
777
778 tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
779 tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
780 tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
781 tcg_temp_free_i64(tcg_hiaddr);
782 }
783
784 tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(s, destidx, MO_64));
785 tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(s, destidx));
786
787 tcg_temp_free_i64(tmplo);
788 tcg_temp_free_i64(tmphi);
789 }
790
791 /*
792 * Vector load/store helpers.
793 *
794 * The principal difference between this and a FP load is that we don't
795 * zero extend as we are filling a partial chunk of the vector register.
796 * These functions don't support 128 bit loads/stores, which would be
797 * normal load/store operations.
798 *
799 * The _i32 versions are useful when operating on 32 bit quantities
800 * (eg for floating point single or using Neon helper functions).
801 */
802
803 /* Get value of an element within a vector register */
804 static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx,
805 int element, TCGMemOp memop)
806 {
807 int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
808 switch (memop) {
809 case MO_8:
810 tcg_gen_ld8u_i64(tcg_dest, cpu_env, vect_off);
811 break;
812 case MO_16:
813 tcg_gen_ld16u_i64(tcg_dest, cpu_env, vect_off);
814 break;
815 case MO_32:
816 tcg_gen_ld32u_i64(tcg_dest, cpu_env, vect_off);
817 break;
818 case MO_8|MO_SIGN:
819 tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off);
820 break;
821 case MO_16|MO_SIGN:
822 tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off);
823 break;
824 case MO_32|MO_SIGN:
825 tcg_gen_ld32s_i64(tcg_dest, cpu_env, vect_off);
826 break;
827 case MO_64:
828 case MO_64|MO_SIGN:
829 tcg_gen_ld_i64(tcg_dest, cpu_env, vect_off);
830 break;
831 default:
832 g_assert_not_reached();
833 }
834 }
835
836 static void read_vec_element_i32(DisasContext *s, TCGv_i32 tcg_dest, int srcidx,
837 int element, TCGMemOp memop)
838 {
839 int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
840 switch (memop) {
841 case MO_8:
842 tcg_gen_ld8u_i32(tcg_dest, cpu_env, vect_off);
843 break;
844 case MO_16:
845 tcg_gen_ld16u_i32(tcg_dest, cpu_env, vect_off);
846 break;
847 case MO_8|MO_SIGN:
848 tcg_gen_ld8s_i32(tcg_dest, cpu_env, vect_off);
849 break;
850 case MO_16|MO_SIGN:
851 tcg_gen_ld16s_i32(tcg_dest, cpu_env, vect_off);
852 break;
853 case MO_32:
854 case MO_32|MO_SIGN:
855 tcg_gen_ld_i32(tcg_dest, cpu_env, vect_off);
856 break;
857 default:
858 g_assert_not_reached();
859 }
860 }
861
862 /* Set value of an element within a vector register */
863 static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx,
864 int element, TCGMemOp memop)
865 {
866 int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
867 switch (memop) {
868 case MO_8:
869 tcg_gen_st8_i64(tcg_src, cpu_env, vect_off);
870 break;
871 case MO_16:
872 tcg_gen_st16_i64(tcg_src, cpu_env, vect_off);
873 break;
874 case MO_32:
875 tcg_gen_st32_i64(tcg_src, cpu_env, vect_off);
876 break;
877 case MO_64:
878 tcg_gen_st_i64(tcg_src, cpu_env, vect_off);
879 break;
880 default:
881 g_assert_not_reached();
882 }
883 }
884
885 static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
886 int destidx, int element, TCGMemOp memop)
887 {
888 int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
889 switch (memop) {
890 case MO_8:
891 tcg_gen_st8_i32(tcg_src, cpu_env, vect_off);
892 break;
893 case MO_16:
894 tcg_gen_st16_i32(tcg_src, cpu_env, vect_off);
895 break;
896 case MO_32:
897 tcg_gen_st_i32(tcg_src, cpu_env, vect_off);
898 break;
899 default:
900 g_assert_not_reached();
901 }
902 }
903
904 /* Clear the high 64 bits of a 128 bit vector (in general non-quad
905 * vector ops all need to do this).
906 */
907 static void clear_vec_high(DisasContext *s, int rd)
908 {
909 TCGv_i64 tcg_zero = tcg_const_i64(0);
910
911 write_vec_element(s, tcg_zero, rd, 1, MO_64);
912 tcg_temp_free_i64(tcg_zero);
913 }
914
915 /* Store from vector register to memory */
916 static void do_vec_st(DisasContext *s, int srcidx, int element,
917 TCGv_i64 tcg_addr, int size)
918 {
919 TCGMemOp memop = MO_TE + size;
920 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
921
922 read_vec_element(s, tcg_tmp, srcidx, element, size);
923 tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
924
925 tcg_temp_free_i64(tcg_tmp);
926 }
927
928 /* Load from memory to vector register */
929 static void do_vec_ld(DisasContext *s, int destidx, int element,
930 TCGv_i64 tcg_addr, int size)
931 {
932 TCGMemOp memop = MO_TE + size;
933 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
934
935 tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
936 write_vec_element(s, tcg_tmp, destidx, element, size);
937
938 tcg_temp_free_i64(tcg_tmp);
939 }
940
941 /* Check that FP/Neon access is enabled. If it is, return
942 * true. If not, emit code to generate an appropriate exception,
943 * and return false; the caller should not emit any code for
944 * the instruction. Note that this check must happen after all
945 * unallocated-encoding checks (otherwise the syndrome information
946 * for the resulting exception will be incorrect).
947 */
948 static inline bool fp_access_check(DisasContext *s)
949 {
950 assert(!s->fp_access_checked);
951 s->fp_access_checked = true;
952
953 if (s->cpacr_fpen) {
954 return true;
955 }
956
957 gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false));
958 return false;
959 }
960
961 /*
962 * This utility function is for doing register extension with an
963 * optional shift. You will likely want to pass a temporary for the
964 * destination register. See DecodeRegExtend() in the ARM ARM.
965 */
966 static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
967 int option, unsigned int shift)
968 {
969 int extsize = extract32(option, 0, 2);
970 bool is_signed = extract32(option, 2, 1);
971
972 if (is_signed) {
973 switch (extsize) {
974 case 0:
975 tcg_gen_ext8s_i64(tcg_out, tcg_in);
976 break;
977 case 1:
978 tcg_gen_ext16s_i64(tcg_out, tcg_in);
979 break;
980 case 2:
981 tcg_gen_ext32s_i64(tcg_out, tcg_in);
982 break;
983 case 3:
984 tcg_gen_mov_i64(tcg_out, tcg_in);
985 break;
986 }
987 } else {
988 switch (extsize) {
989 case 0:
990 tcg_gen_ext8u_i64(tcg_out, tcg_in);
991 break;
992 case 1:
993 tcg_gen_ext16u_i64(tcg_out, tcg_in);
994 break;
995 case 2:
996 tcg_gen_ext32u_i64(tcg_out, tcg_in);
997 break;
998 case 3:
999 tcg_gen_mov_i64(tcg_out, tcg_in);
1000 break;
1001 }
1002 }
1003
1004 if (shift) {
1005 tcg_gen_shli_i64(tcg_out, tcg_out, shift);
1006 }
1007 }
1008
1009 static inline void gen_check_sp_alignment(DisasContext *s)
1010 {
1011 /* The AArch64 architecture mandates that (if enabled via PSTATE
1012 * or SCTLR bits) there is a check that SP is 16-aligned on every
1013 * SP-relative load or store (with an exception generated if it is not).
1014 * In line with general QEMU practice regarding misaligned accesses,
1015 * we omit these checks for the sake of guest program performance.
1016 * This function is provided as a hook so we can more easily add these
1017 * checks in future (possibly as a "favour catching guest program bugs
1018 * over speed" user selectable option).
1019 */
1020 }
1021
1022 /*
1023 * This provides a simple table based table lookup decoder. It is
1024 * intended to be used when the relevant bits for decode are too
1025 * awkwardly placed and switch/if based logic would be confusing and
1026 * deeply nested. Since it's a linear search through the table, tables
1027 * should be kept small.
1028 *
1029 * It returns the first handler where insn & mask == pattern, or
1030 * NULL if there is no match.
1031 * The table is terminated by an empty mask (i.e. 0)
1032 */
1033 static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
1034 uint32_t insn)
1035 {
1036 const AArch64DecodeTable *tptr = table;
1037
1038 while (tptr->mask) {
1039 if ((insn & tptr->mask) == tptr->pattern) {
1040 return tptr->disas_fn;
1041 }
1042 tptr++;
1043 }
1044 return NULL;
1045 }
1046
1047 /*
1048 * the instruction disassembly implemented here matches
1049 * the instruction encoding classifications in chapter 3 (C3)
1050 * of the ARM Architecture Reference Manual (DDI0487A_a)
1051 */
1052
1053 /* C3.2.7 Unconditional branch (immediate)
1054 * 31 30 26 25 0
1055 * +----+-----------+-------------------------------------+
1056 * | op | 0 0 1 0 1 | imm26 |
1057 * +----+-----------+-------------------------------------+
1058 */
1059 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
1060 {
1061 uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
1062
1063 if (insn & (1 << 31)) {
1064 /* C5.6.26 BL Branch with link */
1065 tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1066 }
1067
1068 /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
1069 gen_goto_tb(s, 0, addr);
1070 }
1071
1072 /* C3.2.1 Compare & branch (immediate)
1073 * 31 30 25 24 23 5 4 0
1074 * +----+-------------+----+---------------------+--------+
1075 * | sf | 0 1 1 0 1 0 | op | imm19 | Rt |
1076 * +----+-------------+----+---------------------+--------+
1077 */
1078 static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
1079 {
1080 unsigned int sf, op, rt;
1081 uint64_t addr;
1082 int label_match;
1083 TCGv_i64 tcg_cmp;
1084
1085 sf = extract32(insn, 31, 1);
1086 op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
1087 rt = extract32(insn, 0, 5);
1088 addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
1089
1090 tcg_cmp = read_cpu_reg(s, rt, sf);
1091 label_match = gen_new_label();
1092
1093 tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
1094 tcg_cmp, 0, label_match);
1095
1096 gen_goto_tb(s, 0, s->pc);
1097 gen_set_label(label_match);
1098 gen_goto_tb(s, 1, addr);
1099 }
1100
1101 /* C3.2.5 Test & branch (immediate)
1102 * 31 30 25 24 23 19 18 5 4 0
1103 * +----+-------------+----+-------+-------------+------+
1104 * | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
1105 * +----+-------------+----+-------+-------------+------+
1106 */
1107 static void disas_test_b_imm(DisasContext *s, uint32_t insn)
1108 {
1109 unsigned int bit_pos, op, rt;
1110 uint64_t addr;
1111 int label_match;
1112 TCGv_i64 tcg_cmp;
1113
1114 bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
1115 op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
1116 addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
1117 rt = extract32(insn, 0, 5);
1118
1119 tcg_cmp = tcg_temp_new_i64();
1120 tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
1121 label_match = gen_new_label();
1122 tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
1123 tcg_cmp, 0, label_match);
1124 tcg_temp_free_i64(tcg_cmp);
1125 gen_goto_tb(s, 0, s->pc);
1126 gen_set_label(label_match);
1127 gen_goto_tb(s, 1, addr);
1128 }
1129
1130 /* C3.2.2 / C5.6.19 Conditional branch (immediate)
1131 * 31 25 24 23 5 4 3 0
1132 * +---------------+----+---------------------+----+------+
1133 * | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
1134 * +---------------+----+---------------------+----+------+
1135 */
1136 static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
1137 {
1138 unsigned int cond;
1139 uint64_t addr;
1140
1141 if ((insn & (1 << 4)) || (insn & (1 << 24))) {
1142 unallocated_encoding(s);
1143 return;
1144 }
1145 addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
1146 cond = extract32(insn, 0, 4);
1147
1148 if (cond < 0x0e) {
1149 /* genuinely conditional branches */
1150 int label_match = gen_new_label();
1151 arm_gen_test_cc(cond, label_match);
1152 gen_goto_tb(s, 0, s->pc);
1153 gen_set_label(label_match);
1154 gen_goto_tb(s, 1, addr);
1155 } else {
1156 /* 0xe and 0xf are both "always" conditions */
1157 gen_goto_tb(s, 0, addr);
1158 }
1159 }
1160
1161 /* C5.6.68 HINT */
1162 static void handle_hint(DisasContext *s, uint32_t insn,
1163 unsigned int op1, unsigned int op2, unsigned int crm)
1164 {
1165 unsigned int selector = crm << 3 | op2;
1166
1167 if (op1 != 3) {
1168 unallocated_encoding(s);
1169 return;
1170 }
1171
1172 switch (selector) {
1173 case 0: /* NOP */
1174 return;
1175 case 3: /* WFI */
1176 s->is_jmp = DISAS_WFI;
1177 return;
1178 case 1: /* YIELD */
1179 case 2: /* WFE */
1180 s->is_jmp = DISAS_WFE;
1181 return;
1182 case 4: /* SEV */
1183 case 5: /* SEVL */
1184 /* we treat all as NOP at least for now */
1185 return;
1186 default:
1187 /* default specified as NOP equivalent */
1188 return;
1189 }
1190 }
1191
1192 static void gen_clrex(DisasContext *s, uint32_t insn)
1193 {
1194 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
1195 }
1196
1197 /* CLREX, DSB, DMB, ISB */
1198 static void handle_sync(DisasContext *s, uint32_t insn,
1199 unsigned int op1, unsigned int op2, unsigned int crm)
1200 {
1201 if (op1 != 3) {
1202 unallocated_encoding(s);
1203 return;
1204 }
1205
1206 switch (op2) {
1207 case 2: /* CLREX */
1208 gen_clrex(s, insn);
1209 return;
1210 case 4: /* DSB */
1211 case 5: /* DMB */
1212 case 6: /* ISB */
1213 /* We don't emulate caches so barriers are no-ops */
1214 return;
1215 default:
1216 unallocated_encoding(s);
1217 return;
1218 }
1219 }
1220
1221 /* C5.6.130 MSR (immediate) - move immediate to processor state field */
1222 static void handle_msr_i(DisasContext *s, uint32_t insn,
1223 unsigned int op1, unsigned int op2, unsigned int crm)
1224 {
1225 int op = op1 << 3 | op2;
1226 switch (op) {
1227 case 0x05: /* SPSel */
1228 if (s->current_el == 0) {
1229 unallocated_encoding(s);
1230 return;
1231 }
1232 /* fall through */
1233 case 0x1e: /* DAIFSet */
1234 case 0x1f: /* DAIFClear */
1235 {
1236 TCGv_i32 tcg_imm = tcg_const_i32(crm);
1237 TCGv_i32 tcg_op = tcg_const_i32(op);
1238 gen_a64_set_pc_im(s->pc - 4);
1239 gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
1240 tcg_temp_free_i32(tcg_imm);
1241 tcg_temp_free_i32(tcg_op);
1242 s->is_jmp = DISAS_UPDATE;
1243 break;
1244 }
1245 default:
1246 unallocated_encoding(s);
1247 return;
1248 }
1249 }
1250
1251 static void gen_get_nzcv(TCGv_i64 tcg_rt)
1252 {
1253 TCGv_i32 tmp = tcg_temp_new_i32();
1254 TCGv_i32 nzcv = tcg_temp_new_i32();
1255
1256 /* build bit 31, N */
1257 tcg_gen_andi_i32(nzcv, cpu_NF, (1 << 31));
1258 /* build bit 30, Z */
1259 tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
1260 tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
1261 /* build bit 29, C */
1262 tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
1263 /* build bit 28, V */
1264 tcg_gen_shri_i32(tmp, cpu_VF, 31);
1265 tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
1266 /* generate result */
1267 tcg_gen_extu_i32_i64(tcg_rt, nzcv);
1268
1269 tcg_temp_free_i32(nzcv);
1270 tcg_temp_free_i32(tmp);
1271 }
1272
1273 static void gen_set_nzcv(TCGv_i64 tcg_rt)
1274
1275 {
1276 TCGv_i32 nzcv = tcg_temp_new_i32();
1277
1278 /* take NZCV from R[t] */
1279 tcg_gen_trunc_i64_i32(nzcv, tcg_rt);
1280
1281 /* bit 31, N */
1282 tcg_gen_andi_i32(cpu_NF, nzcv, (1 << 31));
1283 /* bit 30, Z */
1284 tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
1285 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
1286 /* bit 29, C */
1287 tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
1288 tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
1289 /* bit 28, V */
1290 tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
1291 tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
1292 tcg_temp_free_i32(nzcv);
1293 }
1294
1295 /* C5.6.129 MRS - move from system register
1296 * C5.6.131 MSR (register) - move to system register
1297 * C5.6.204 SYS
1298 * C5.6.205 SYSL
1299 * These are all essentially the same insn in 'read' and 'write'
1300 * versions, with varying op0 fields.
1301 */
1302 static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
1303 unsigned int op0, unsigned int op1, unsigned int op2,
1304 unsigned int crn, unsigned int crm, unsigned int rt)
1305 {
1306 const ARMCPRegInfo *ri;
1307 TCGv_i64 tcg_rt;
1308
1309 ri = get_arm_cp_reginfo(s->cp_regs,
1310 ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
1311 crn, crm, op0, op1, op2));
1312
1313 if (!ri) {
1314 /* Unknown register; this might be a guest error or a QEMU
1315 * unimplemented feature.
1316 */
1317 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
1318 "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
1319 isread ? "read" : "write", op0, op1, crn, crm, op2);
1320 unallocated_encoding(s);
1321 return;
1322 }
1323
1324 /* Check access permissions */
1325 if (!cp_access_ok(s->current_el, ri, isread)) {
1326 unallocated_encoding(s);
1327 return;
1328 }
1329
1330 if (ri->accessfn) {
1331 /* Emit code to perform further access permissions checks at
1332 * runtime; this may result in an exception.
1333 */
1334 TCGv_ptr tmpptr;
1335 TCGv_i32 tcg_syn;
1336 uint32_t syndrome;
1337
1338 gen_a64_set_pc_im(s->pc - 4);
1339 tmpptr = tcg_const_ptr(ri);
1340 syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
1341 tcg_syn = tcg_const_i32(syndrome);
1342 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
1343 tcg_temp_free_ptr(tmpptr);
1344 tcg_temp_free_i32(tcg_syn);
1345 }
1346
1347 /* Handle special cases first */
1348 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
1349 case ARM_CP_NOP:
1350 return;
1351 case ARM_CP_NZCV:
1352 tcg_rt = cpu_reg(s, rt);
1353 if (isread) {
1354 gen_get_nzcv(tcg_rt);
1355 } else {
1356 gen_set_nzcv(tcg_rt);
1357 }
1358 return;
1359 case ARM_CP_CURRENTEL:
1360 /* Reads as current EL value from pstate, which is
1361 * guaranteed to be constant by the tb flags.
1362 */
1363 tcg_rt = cpu_reg(s, rt);
1364 tcg_gen_movi_i64(tcg_rt, s->current_el << 2);
1365 return;
1366 case ARM_CP_DC_ZVA:
1367 /* Writes clear the aligned block of memory which rt points into. */
1368 tcg_rt = cpu_reg(s, rt);
1369 gen_helper_dc_zva(cpu_env, tcg_rt);
1370 return;
1371 default:
1372 break;
1373 }
1374
1375 if (use_icount && (ri->type & ARM_CP_IO)) {
1376 gen_io_start();
1377 }
1378
1379 tcg_rt = cpu_reg(s, rt);
1380
1381 if (isread) {
1382 if (ri->type & ARM_CP_CONST) {
1383 tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
1384 } else if (ri->readfn) {
1385 TCGv_ptr tmpptr;
1386 tmpptr = tcg_const_ptr(ri);
1387 gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
1388 tcg_temp_free_ptr(tmpptr);
1389 } else {
1390 tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
1391 }
1392 } else {
1393 if (ri->type & ARM_CP_CONST) {
1394 /* If not forbidden by access permissions, treat as WI */
1395 return;
1396 } else if (ri->writefn) {
1397 TCGv_ptr tmpptr;
1398 tmpptr = tcg_const_ptr(ri);
1399 gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
1400 tcg_temp_free_ptr(tmpptr);
1401 } else {
1402 tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
1403 }
1404 }
1405
1406 if (use_icount && (ri->type & ARM_CP_IO)) {
1407 /* I/O operations must end the TB here (whether read or write) */
1408 gen_io_end();
1409 s->is_jmp = DISAS_UPDATE;
1410 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
1411 /* We default to ending the TB on a coprocessor register write,
1412 * but allow this to be suppressed by the register definition
1413 * (usually only necessary to work around guest bugs).
1414 */
1415 s->is_jmp = DISAS_UPDATE;
1416 }
1417 }
1418
1419 /* C3.2.4 System
1420 * 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
1421 * +---------------------+---+-----+-----+-------+-------+-----+------+
1422 * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 | CRn | CRm | op2 | Rt |
1423 * +---------------------+---+-----+-----+-------+-------+-----+------+
1424 */
1425 static void disas_system(DisasContext *s, uint32_t insn)
1426 {
1427 unsigned int l, op0, op1, crn, crm, op2, rt;
1428 l = extract32(insn, 21, 1);
1429 op0 = extract32(insn, 19, 2);
1430 op1 = extract32(insn, 16, 3);
1431 crn = extract32(insn, 12, 4);
1432 crm = extract32(insn, 8, 4);
1433 op2 = extract32(insn, 5, 3);
1434 rt = extract32(insn, 0, 5);
1435
1436 if (op0 == 0) {
1437 if (l || rt != 31) {
1438 unallocated_encoding(s);
1439 return;
1440 }
1441 switch (crn) {
1442 case 2: /* C5.6.68 HINT */
1443 handle_hint(s, insn, op1, op2, crm);
1444 break;
1445 case 3: /* CLREX, DSB, DMB, ISB */
1446 handle_sync(s, insn, op1, op2, crm);
1447 break;
1448 case 4: /* C5.6.130 MSR (immediate) */
1449 handle_msr_i(s, insn, op1, op2, crm);
1450 break;
1451 default:
1452 unallocated_encoding(s);
1453 break;
1454 }
1455 return;
1456 }
1457 handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
1458 }
1459
1460 /* C3.2.3 Exception generation
1461 *
1462 * 31 24 23 21 20 5 4 2 1 0
1463 * +-----------------+-----+------------------------+-----+----+
1464 * | 1 1 0 1 0 1 0 0 | opc | imm16 | op2 | LL |
1465 * +-----------------------+------------------------+----------+
1466 */
1467 static void disas_exc(DisasContext *s, uint32_t insn)
1468 {
1469 int opc = extract32(insn, 21, 3);
1470 int op2_ll = extract32(insn, 0, 5);
1471 int imm16 = extract32(insn, 5, 16);
1472 TCGv_i32 tmp;
1473
1474 switch (opc) {
1475 case 0:
1476 /* For SVC, HVC and SMC we advance the single-step state
1477 * machine before taking the exception. This is architecturally
1478 * mandated, to ensure that single-stepping a system call
1479 * instruction works properly.
1480 */
1481 switch (op2_ll) {
1482 case 1:
1483 gen_ss_advance(s);
1484 gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
1485 break;
1486 case 2:
1487 if (s->current_el == 0) {
1488 unallocated_encoding(s);
1489 break;
1490 }
1491 /* The pre HVC helper handles cases when HVC gets trapped
1492 * as an undefined insn by runtime configuration.
1493 */
1494 gen_a64_set_pc_im(s->pc - 4);
1495 gen_helper_pre_hvc(cpu_env);
1496 gen_ss_advance(s);
1497 gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
1498 break;
1499 case 3:
1500 if (s->current_el == 0) {
1501 unallocated_encoding(s);
1502 break;
1503 }
1504 gen_a64_set_pc_im(s->pc - 4);
1505 tmp = tcg_const_i32(syn_aa64_smc(imm16));
1506 gen_helper_pre_smc(cpu_env, tmp);
1507 tcg_temp_free_i32(tmp);
1508 gen_ss_advance(s);
1509 gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16));
1510 break;
1511 default:
1512 unallocated_encoding(s);
1513 break;
1514 }
1515 break;
1516 case 1:
1517 if (op2_ll != 0) {
1518 unallocated_encoding(s);
1519 break;
1520 }
1521 /* BRK */
1522 gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16));
1523 break;
1524 case 2:
1525 if (op2_ll != 0) {
1526 unallocated_encoding(s);
1527 break;
1528 }
1529 /* HLT */
1530 unsupported_encoding(s, insn);
1531 break;
1532 case 5:
1533 if (op2_ll < 1 || op2_ll > 3) {
1534 unallocated_encoding(s);
1535 break;
1536 }
1537 /* DCPS1, DCPS2, DCPS3 */
1538 unsupported_encoding(s, insn);
1539 break;
1540 default:
1541 unallocated_encoding(s);
1542 break;
1543 }
1544 }
1545
1546 /* C3.2.7 Unconditional branch (register)
1547 * 31 25 24 21 20 16 15 10 9 5 4 0
1548 * +---------------+-------+-------+-------+------+-------+
1549 * | 1 1 0 1 0 1 1 | opc | op2 | op3 | Rn | op4 |
1550 * +---------------+-------+-------+-------+------+-------+
1551 */
1552 static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
1553 {
1554 unsigned int opc, op2, op3, rn, op4;
1555
1556 opc = extract32(insn, 21, 4);
1557 op2 = extract32(insn, 16, 5);
1558 op3 = extract32(insn, 10, 6);
1559 rn = extract32(insn, 5, 5);
1560 op4 = extract32(insn, 0, 5);
1561
1562 if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
1563 unallocated_encoding(s);
1564 return;
1565 }
1566
1567 switch (opc) {
1568 case 0: /* BR */
1569 case 2: /* RET */
1570 tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1571 break;
1572 case 1: /* BLR */
1573 tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1574 tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1575 break;
1576 case 4: /* ERET */
1577 if (s->current_el == 0) {
1578 unallocated_encoding(s);
1579 return;
1580 }
1581 gen_helper_exception_return(cpu_env);
1582 s->is_jmp = DISAS_JUMP;
1583 return;
1584 case 5: /* DRPS */
1585 if (rn != 0x1f) {
1586 unallocated_encoding(s);
1587 } else {
1588 unsupported_encoding(s, insn);
1589 }
1590 return;
1591 default:
1592 unallocated_encoding(s);
1593 return;
1594 }
1595
1596 s->is_jmp = DISAS_JUMP;
1597 }
1598
1599 /* C3.2 Branches, exception generating and system instructions */
1600 static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
1601 {
1602 switch (extract32(insn, 25, 7)) {
1603 case 0x0a: case 0x0b:
1604 case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1605 disas_uncond_b_imm(s, insn);
1606 break;
1607 case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1608 disas_comp_b_imm(s, insn);
1609 break;
1610 case 0x1b: case 0x5b: /* Test & branch (immediate) */
1611 disas_test_b_imm(s, insn);
1612 break;
1613 case 0x2a: /* Conditional branch (immediate) */
1614 disas_cond_b_imm(s, insn);
1615 break;
1616 case 0x6a: /* Exception generation / System */
1617 if (insn & (1 << 24)) {
1618 disas_system(s, insn);
1619 } else {
1620 disas_exc(s, insn);
1621 }
1622 break;
1623 case 0x6b: /* Unconditional branch (register) */
1624 disas_uncond_b_reg(s, insn);
1625 break;
1626 default:
1627 unallocated_encoding(s);
1628 break;
1629 }
1630 }
1631
1632 /*
1633 * Load/Store exclusive instructions are implemented by remembering
1634 * the value/address loaded, and seeing if these are the same
1635 * when the store is performed. This is not actually the architecturally
1636 * mandated semantics, but it works for typical guest code sequences
1637 * and avoids having to monitor regular stores.
1638 *
1639 * In system emulation mode only one CPU will be running at once, so
1640 * this sequence is effectively atomic. In user emulation mode we
1641 * throw an exception and handle the atomic operation elsewhere.
1642 */
1643 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
1644 TCGv_i64 addr, int size, bool is_pair)
1645 {
1646 TCGv_i64 tmp = tcg_temp_new_i64();
1647 TCGMemOp memop = MO_TE + size;
1648
1649 g_assert(size <= 3);
1650 tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
1651
1652 if (is_pair) {
1653 TCGv_i64 addr2 = tcg_temp_new_i64();
1654 TCGv_i64 hitmp = tcg_temp_new_i64();
1655
1656 g_assert(size >= 2);
1657 tcg_gen_addi_i64(addr2, addr, 1 << size);
1658 tcg_gen_qemu_ld_i64(hitmp, addr2, get_mem_index(s), memop);
1659 tcg_temp_free_i64(addr2);
1660 tcg_gen_mov_i64(cpu_exclusive_high, hitmp);
1661 tcg_gen_mov_i64(cpu_reg(s, rt2), hitmp);
1662 tcg_temp_free_i64(hitmp);
1663 }
1664
1665 tcg_gen_mov_i64(cpu_exclusive_val, tmp);
1666 tcg_gen_mov_i64(cpu_reg(s, rt), tmp);
1667
1668 tcg_temp_free_i64(tmp);
1669 tcg_gen_mov_i64(cpu_exclusive_addr, addr);
1670 }
1671
1672 #ifdef CONFIG_USER_ONLY
1673 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1674 TCGv_i64 addr, int size, int is_pair)
1675 {
1676 tcg_gen_mov_i64(cpu_exclusive_test, addr);
1677 tcg_gen_movi_i32(cpu_exclusive_info,
1678 size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
1679 gen_exception_internal_insn(s, 4, EXCP_STREX);
1680 }
1681 #else
1682 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1683 TCGv_i64 inaddr, int size, int is_pair)
1684 {
1685 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
1686 * && (!is_pair || env->exclusive_high == [addr + datasize])) {
1687 * [addr] = {Rt};
1688 * if (is_pair) {
1689 * [addr + datasize] = {Rt2};
1690 * }
1691 * {Rd} = 0;
1692 * } else {
1693 * {Rd} = 1;
1694 * }
1695 * env->exclusive_addr = -1;
1696 */
1697 int fail_label = gen_new_label();
1698 int done_label = gen_new_label();
1699 TCGv_i64 addr = tcg_temp_local_new_i64();
1700 TCGv_i64 tmp;
1701
1702 /* Copy input into a local temp so it is not trashed when the
1703 * basic block ends at the branch insn.
1704 */
1705 tcg_gen_mov_i64(addr, inaddr);
1706 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
1707
1708 tmp = tcg_temp_new_i64();
1709 tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size);
1710 tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
1711 tcg_temp_free_i64(tmp);
1712
1713 if (is_pair) {
1714 TCGv_i64 addrhi = tcg_temp_new_i64();
1715 TCGv_i64 tmphi = tcg_temp_new_i64();
1716
1717 tcg_gen_addi_i64(addrhi, addr, 1 << size);
1718 tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size);
1719 tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
1720
1721 tcg_temp_free_i64(tmphi);
1722 tcg_temp_free_i64(addrhi);
1723 }
1724
1725 /* We seem to still have the exclusive monitor, so do the store */
1726 tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size);
1727 if (is_pair) {
1728 TCGv_i64 addrhi = tcg_temp_new_i64();
1729
1730 tcg_gen_addi_i64(addrhi, addr, 1 << size);
1731 tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
1732 get_mem_index(s), MO_TE + size);
1733 tcg_temp_free_i64(addrhi);
1734 }
1735
1736 tcg_temp_free_i64(addr);
1737
1738 tcg_gen_movi_i64(cpu_reg(s, rd), 0);
1739 tcg_gen_br(done_label);
1740 gen_set_label(fail_label);
1741 tcg_gen_movi_i64(cpu_reg(s, rd), 1);
1742 gen_set_label(done_label);
1743 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
1744
1745 }
1746 #endif
1747
1748 /* C3.3.6 Load/store exclusive
1749 *
1750 * 31 30 29 24 23 22 21 20 16 15 14 10 9 5 4 0
1751 * +-----+-------------+----+---+----+------+----+-------+------+------+
1752 * | sz | 0 0 1 0 0 0 | o2 | L | o1 | Rs | o0 | Rt2 | Rn | Rt |
1753 * +-----+-------------+----+---+----+------+----+-------+------+------+
1754 *
1755 * sz: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64 bit
1756 * L: 0 -> store, 1 -> load
1757 * o2: 0 -> exclusive, 1 -> not
1758 * o1: 0 -> single register, 1 -> register pair
1759 * o0: 1 -> load-acquire/store-release, 0 -> not
1760 *
1761 * o0 == 0 AND o2 == 1 is un-allocated
1762 * o1 == 1 is un-allocated except for 32 and 64 bit sizes
1763 */
1764 static void disas_ldst_excl(DisasContext *s, uint32_t insn)
1765 {
1766 int rt = extract32(insn, 0, 5);
1767 int rn = extract32(insn, 5, 5);
1768 int rt2 = extract32(insn, 10, 5);
1769 int is_lasr = extract32(insn, 15, 1);
1770 int rs = extract32(insn, 16, 5);
1771 int is_pair = extract32(insn, 21, 1);
1772 int is_store = !extract32(insn, 22, 1);
1773 int is_excl = !extract32(insn, 23, 1);
1774 int size = extract32(insn, 30, 2);
1775 TCGv_i64 tcg_addr;
1776
1777 if ((!is_excl && !is_lasr) ||
1778 (is_pair && size < 2)) {
1779 unallocated_encoding(s);
1780 return;
1781 }
1782
1783 if (rn == 31) {
1784 gen_check_sp_alignment(s);
1785 }
1786 tcg_addr = read_cpu_reg_sp(s, rn, 1);
1787
1788 /* Note that since TCG is single threaded load-acquire/store-release
1789 * semantics require no extra if (is_lasr) { ... } handling.
1790 */
1791
1792 if (is_excl) {
1793 if (!is_store) {
1794 s->is_ldex = true;
1795 gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
1796 } else {
1797 gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
1798 }
1799 } else {
1800 TCGv_i64 tcg_rt = cpu_reg(s, rt);
1801 if (is_store) {
1802 do_gpr_st(s, tcg_rt, tcg_addr, size);
1803 } else {
1804 do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);
1805 }
1806 if (is_pair) {
1807 TCGv_i64 tcg_rt2 = cpu_reg(s, rt);
1808 tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1809 if (is_store) {
1810 do_gpr_st(s, tcg_rt2, tcg_addr, size);
1811 } else {
1812 do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false);
1813 }
1814 }
1815 }
1816 }
1817
1818 /*
1819 * C3.3.5 Load register (literal)
1820 *
1821 * 31 30 29 27 26 25 24 23 5 4 0
1822 * +-----+-------+---+-----+-------------------+-------+
1823 * | opc | 0 1 1 | V | 0 0 | imm19 | Rt |
1824 * +-----+-------+---+-----+-------------------+-------+
1825 *
1826 * V: 1 -> vector (simd/fp)
1827 * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
1828 * 10-> 32 bit signed, 11 -> prefetch
1829 * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
1830 */
1831 static void disas_ld_lit(DisasContext *s, uint32_t insn)
1832 {
1833 int rt = extract32(insn, 0, 5);
1834 int64_t imm = sextract32(insn, 5, 19) << 2;
1835 bool is_vector = extract32(insn, 26, 1);
1836 int opc = extract32(insn, 30, 2);
1837 bool is_signed = false;
1838 int size = 2;
1839 TCGv_i64 tcg_rt, tcg_addr;
1840
1841 if (is_vector) {
1842 if (opc == 3) {
1843 unallocated_encoding(s);
1844 return;
1845 }
1846 size = 2 + opc;
1847 if (!fp_access_check(s)) {
1848 return;
1849 }
1850 } else {
1851 if (opc == 3) {
1852 /* PRFM (literal) : prefetch */
1853 return;
1854 }
1855 size = 2 + extract32(opc, 0, 1);
1856 is_signed = extract32(opc, 1, 1);
1857 }
1858
1859 tcg_rt = cpu_reg(s, rt);
1860
1861 tcg_addr = tcg_const_i64((s->pc - 4) + imm);
1862 if (is_vector) {
1863 do_fp_ld(s, rt, tcg_addr, size);
1864 } else {
1865 do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1866 }
1867 tcg_temp_free_i64(tcg_addr);
1868 }
1869
1870 /*
1871 * C5.6.80 LDNP (Load Pair - non-temporal hint)
1872 * C5.6.81 LDP (Load Pair - non vector)
1873 * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
1874 * C5.6.176 STNP (Store Pair - non-temporal hint)
1875 * C5.6.177 STP (Store Pair - non vector)
1876 * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
1877 * C6.3.165 LDP (Load Pair of SIMD&FP)
1878 * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
1879 * C6.3.284 STP (Store Pair of SIMD&FP)
1880 *
1881 * 31 30 29 27 26 25 24 23 22 21 15 14 10 9 5 4 0
1882 * +-----+-------+---+---+-------+---+-----------------------------+
1883 * | opc | 1 0 1 | V | 0 | index | L | imm7 | Rt2 | Rn | Rt |
1884 * +-----+-------+---+---+-------+---+-------+-------+------+------+
1885 *
1886 * opc: LDP/STP/LDNP/STNP 00 -> 32 bit, 10 -> 64 bit
1887 * LDPSW 01
1888 * LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
1889 * V: 0 -> GPR, 1 -> Vector
1890 * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
1891 * 10 -> signed offset, 11 -> pre-index
1892 * L: 0 -> Store 1 -> Load
1893 *
1894 * Rt, Rt2 = GPR or SIMD registers to be stored
1895 * Rn = general purpose register containing address
1896 * imm7 = signed offset (multiple of 4 or 8 depending on size)
1897 */
1898 static void disas_ldst_pair(DisasContext *s, uint32_t insn)
1899 {
1900 int rt = extract32(insn, 0, 5);
1901 int rn = extract32(insn, 5, 5);
1902 int rt2 = extract32(insn, 10, 5);
1903 int64_t offset = sextract32(insn, 15, 7);
1904 int index = extract32(insn, 23, 2);
1905 bool is_vector = extract32(insn, 26, 1);
1906 bool is_load = extract32(insn, 22, 1);
1907 int opc = extract32(insn, 30, 2);
1908
1909 bool is_signed = false;
1910 bool postindex = false;
1911 bool wback = false;
1912
1913 TCGv_i64 tcg_addr; /* calculated address */
1914 int size;
1915
1916 if (opc == 3) {
1917 unallocated_encoding(s);
1918 return;
1919 }
1920
1921 if (is_vector) {
1922 size = 2 + opc;
1923 } else {
1924 size = 2 + extract32(opc, 1, 1);
1925 is_signed = extract32(opc, 0, 1);
1926 if (!is_load && is_signed) {
1927 unallocated_encoding(s);
1928 return;
1929 }
1930 }
1931
1932 switch (index) {
1933 case 1: /* post-index */
1934 postindex = true;
1935 wback = true;
1936 break;
1937 case 0:
1938 /* signed offset with "non-temporal" hint. Since we don't emulate
1939 * caches we don't care about hints to the cache system about
1940 * data access patterns, and handle this identically to plain
1941 * signed offset.
1942 */
1943 if (is_signed) {
1944 /* There is no non-temporal-hint version of LDPSW */
1945 unallocated_encoding(s);
1946 return;
1947 }
1948 postindex = false;
1949 break;
1950 case 2: /* signed offset, rn not updated */
1951 postindex = false;
1952 break;
1953 case 3: /* pre-index */
1954 postindex = false;
1955 wback = true;
1956 break;
1957 }
1958
1959 if (is_vector && !fp_access_check(s)) {
1960 return;
1961 }
1962
1963 offset <<= size;
1964
1965 if (rn == 31) {
1966 gen_check_sp_alignment(s);
1967 }
1968
1969 tcg_addr = read_cpu_reg_sp(s, rn, 1);
1970
1971 if (!postindex) {
1972 tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1973 }
1974
1975 if (is_vector) {
1976 if (is_load) {
1977 do_fp_ld(s, rt, tcg_addr, size);
1978 } else {
1979 do_fp_st(s, rt, tcg_addr, size);
1980 }
1981 } else {
1982 TCGv_i64 tcg_rt = cpu_reg(s, rt);
1983 if (is_load) {
1984 do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1985 } else {
1986 do_gpr_st(s, tcg_rt, tcg_addr, size);
1987 }
1988 }
1989 tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1990 if (is_vector) {
1991 if (is_load) {
1992 do_fp_ld(s, rt2, tcg_addr, size);
1993 } else {
1994 do_fp_st(s, rt2, tcg_addr, size);
1995 }
1996 } else {
1997 TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
1998 if (is_load) {
1999 do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
2000 } else {
2001 do_gpr_st(s, tcg_rt2, tcg_addr, size);
2002 }
2003 }
2004
2005 if (wback) {
2006 if (postindex) {
2007 tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
2008 } else {
2009 tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
2010 }
2011 tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
2012 }
2013 }
2014
2015 /*
2016 * C3.3.8 Load/store (immediate post-indexed)
2017 * C3.3.9 Load/store (immediate pre-indexed)
2018 * C3.3.12 Load/store (unscaled immediate)
2019 *
2020 * 31 30 29 27 26 25 24 23 22 21 20 12 11 10 9 5 4 0
2021 * +----+-------+---+-----+-----+---+--------+-----+------+------+
2022 * |size| 1 1 1 | V | 0 0 | opc | 0 | imm9 | idx | Rn | Rt |
2023 * +----+-------+---+-----+-----+---+--------+-----+------+------+
2024 *
2025 * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
2026 10 -> unprivileged
2027 * V = 0 -> non-vector
2028 * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
2029 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2030 */
2031 static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
2032 {
2033 int rt = extract32(insn, 0, 5);
2034 int rn = extract32(insn, 5, 5);
2035 int imm9 = sextract32(insn, 12, 9);
2036 int opc = extract32(insn, 22, 2);
2037 int size = extract32(insn, 30, 2);
2038 int idx = extract32(insn, 10, 2);
2039 bool is_signed = false;
2040 bool is_store = false;
2041 bool is_extended = false;
2042 bool is_unpriv = (idx == 2);
2043 bool is_vector = extract32(insn, 26, 1);
2044 bool post_index;
2045 bool writeback;
2046
2047 TCGv_i64 tcg_addr;
2048
2049 if (is_vector) {
2050 size |= (opc & 2) << 1;
2051 if (size > 4 || is_unpriv) {
2052 unallocated_encoding(s);
2053 return;
2054 }
2055 is_store = ((opc & 1) == 0);
2056 if (!fp_access_check(s)) {
2057 return;
2058 }
2059 } else {
2060 if (size == 3 && opc == 2) {
2061 /* PRFM - prefetch */
2062 if (is_unpriv) {
2063 unallocated_encoding(s);
2064 return;
2065 }
2066 return;
2067 }
2068 if (opc == 3 && size > 1) {
2069 unallocated_encoding(s);
2070 return;
2071 }
2072 is_store = (opc == 0);
2073 is_signed = opc & (1<<1);
2074 is_extended = (size < 3) && (opc & 1);
2075 }
2076
2077 switch (idx) {
2078 case 0:
2079 case 2:
2080 post_index = false;
2081 writeback = false;
2082 break;
2083 case 1:
2084 post_index = true;
2085 writeback = true;
2086 break;
2087 case 3:
2088 post_index = false;
2089 writeback = true;
2090 break;
2091 }
2092
2093 if (rn == 31) {
2094 gen_check_sp_alignment(s);
2095 }
2096 tcg_addr = read_cpu_reg_sp(s, rn, 1);
2097
2098 if (!post_index) {
2099 tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
2100 }
2101
2102 if (is_vector) {
2103 if (is_store) {
2104 do_fp_st(s, rt, tcg_addr, size);
2105 } else {
2106 do_fp_ld(s, rt, tcg_addr, size);
2107 }
2108 } else {
2109 TCGv_i64 tcg_rt = cpu_reg(s, rt);
2110 int memidx = is_unpriv ? 1 : get_mem_index(s);
2111
2112 if (is_store) {
2113 do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx);
2114 } else {
2115 do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
2116 is_signed, is_extended, memidx);
2117 }
2118 }
2119
2120 if (writeback) {
2121 TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
2122 if (post_index) {
2123 tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
2124 }
2125 tcg_gen_mov_i64(tcg_rn, tcg_addr);
2126 }
2127 }
2128
2129 /*
2130 * C3.3.10 Load/store (register offset)
2131 *
2132 * 31 30 29 27 26 25 24 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2133 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2134 * |size| 1 1 1 | V | 0 0 | opc | 1 | Rm | opt | S| 1 0 | Rn | Rt |
2135 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2136 *
2137 * For non-vector:
2138 * size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2139 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2140 * For vector:
2141 * size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2142 * opc<0>: 0 -> store, 1 -> load
2143 * V: 1 -> vector/simd
2144 * opt: extend encoding (see DecodeRegExtend)
2145 * S: if S=1 then scale (essentially index by sizeof(size))
2146 * Rt: register to transfer into/out of
2147 * Rn: address register or SP for base
2148 * Rm: offset register or ZR for offset
2149 */
2150 static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
2151 {
2152 int rt = extract32(insn, 0, 5);
2153 int rn = extract32(insn, 5, 5);
2154 int shift = extract32(insn, 12, 1);
2155 int rm = extract32(insn, 16, 5);
2156 int opc = extract32(insn, 22, 2);
2157 int opt = extract32(insn, 13, 3);
2158 int size = extract32(insn, 30, 2);
2159 bool is_signed = false;
2160 bool is_store = false;
2161 bool is_extended = false;
2162 bool is_vector = extract32(insn, 26, 1);
2163
2164 TCGv_i64 tcg_rm;
2165 TCGv_i64 tcg_addr;
2166
2167 if (extract32(opt, 1, 1) == 0) {
2168 unallocated_encoding(s);
2169 return;
2170 }
2171
2172 if (is_vector) {
2173 size |= (opc & 2) << 1;
2174 if (size > 4) {
2175 unallocated_encoding(s);
2176 return;
2177 }
2178 is_store = !extract32(opc, 0, 1);
2179 if (!fp_access_check(s)) {
2180 return;
2181 }
2182 } else {
2183 if (size == 3 && opc == 2) {
2184 /* PRFM - prefetch */
2185 return;
2186 }
2187 if (opc == 3 && size > 1) {
2188 unallocated_encoding(s);
2189 return;
2190 }
2191 is_store = (opc == 0);
2192 is_signed = extract32(opc, 1, 1);
2193 is_extended = (size < 3) && extract32(opc, 0, 1);
2194 }
2195
2196 if (rn == 31) {
2197 gen_check_sp_alignment(s);
2198 }
2199 tcg_addr = read_cpu_reg_sp(s, rn, 1);
2200
2201 tcg_rm = read_cpu_reg(s, rm, 1);
2202 ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
2203
2204 tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
2205
2206 if (is_vector) {
2207 if (is_store) {
2208 do_fp_st(s, rt, tcg_addr, size);
2209 } else {
2210 do_fp_ld(s, rt, tcg_addr, size);
2211 }
2212 } else {
2213 TCGv_i64 tcg_rt = cpu_reg(s, rt);
2214 if (is_store) {
2215 do_gpr_st(s, tcg_rt, tcg_addr, size);
2216 } else {
2217 do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
2218 }
2219 }
2220 }
2221
2222 /*
2223 * C3.3.13 Load/store (unsigned immediate)
2224 *
2225 * 31 30 29 27 26 25 24 23 22 21 10 9 5
2226 * +----+-------+---+-----+-----+------------+-------+------+
2227 * |size| 1 1 1 | V | 0 1 | opc | imm12 | Rn | Rt |
2228 * +----+-------+---+-----+-----+------------+-------+------+
2229 *
2230 * For non-vector:
2231 * size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2232 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2233 * For vector:
2234 * size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2235 * opc<0>: 0 -> store, 1 -> load
2236 * Rn: base address register (inc SP)
2237 * Rt: target register
2238 */
2239 static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
2240 {
2241 int rt = extract32(insn, 0, 5);
2242 int rn = extract32(insn, 5, 5);
2243 unsigned int imm12 = extract32(insn, 10, 12);
2244 bool is_vector = extract32(insn, 26, 1);
2245 int size = extract32(insn, 30, 2);
2246 int opc = extract32(insn, 22, 2);
2247 unsigned int offset;
2248
2249 TCGv_i64 tcg_addr;
2250
2251 bool is_store;
2252 bool is_signed = false;
2253 bool is_extended = false;
2254
2255 if (is_vector) {
2256 size |= (opc & 2) << 1;
2257 if (size > 4) {
2258 unallocated_encoding(s);
2259 return;
2260 }
2261 is_store = !extract32(opc, 0, 1);
2262 if (!fp_access_check(s)) {
2263 return;
2264 }
2265 } else {
2266 if (size == 3 && opc == 2) {
2267 /* PRFM - prefetch */
2268 return;
2269 }
2270 if (opc == 3 && size > 1) {
2271 unallocated_encoding(s);
2272 return;
2273 }
2274 is_store = (opc == 0);
2275 is_signed = extract32(opc, 1, 1);
2276 is_extended = (size < 3) && extract32(opc, 0, 1);
2277 }
2278
2279 if (rn == 31) {
2280 gen_check_sp_alignment(s);
2281 }
2282 tcg_addr = read_cpu_reg_sp(s, rn, 1);
2283 offset = imm12 << size;
2284 tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
2285
2286 if (is_vector) {
2287 if (is_store) {
2288 do_fp_st(s, rt, tcg_addr, size);
2289 } else {
2290 do_fp_ld(s, rt, tcg_addr, size);
2291 }
2292 } else {
2293 TCGv_i64 tcg_rt = cpu_reg(s, rt);
2294 if (is_store) {
2295 do_gpr_st(s, tcg_rt, tcg_addr, size);
2296 } else {
2297 do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
2298 }
2299 }
2300 }
2301
2302 /* Load/store register (all forms) */
2303 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
2304 {
2305 switch (extract32(insn, 24, 2)) {
2306 case 0:
2307 if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
2308 disas_ldst_reg_roffset(s, insn);
2309 } else {
2310 /* Load/store register (unscaled immediate)
2311 * Load/store immediate pre/post-indexed
2312 * Load/store register unprivileged
2313 */
2314 disas_ldst_reg_imm9(s, insn);
2315 }
2316 break;
2317 case 1:
2318 disas_ldst_reg_unsigned_imm(s, insn);
2319 break;
2320 default:
2321 unallocated_encoding(s);
2322 break;
2323 }
2324 }
2325
2326 /* C3.3.1 AdvSIMD load/store multiple structures
2327 *
2328 * 31 30 29 23 22 21 16 15 12 11 10 9 5 4 0
2329 * +---+---+---------------+---+-------------+--------+------+------+------+
2330 * | 0 | Q | 0 0 1 1 0 0 0 | L | 0 0 0 0 0 0 | opcode | size | Rn | Rt |
2331 * +---+---+---------------+---+-------------+--------+------+------+------+
2332 *
2333 * C3.3.2 AdvSIMD load/store multiple structures (post-indexed)
2334 *
2335 * 31 30 29 23 22 21 20 16 15 12 11 10 9 5 4 0
2336 * +---+---+---------------+---+---+---------+--------+------+------+------+
2337 * | 0 | Q | 0 0 1 1 0 0 1 | L | 0 | Rm | opcode | size | Rn | Rt |
2338 * +---+---+---------------+---+---+---------+--------+------+------+------+
2339 *
2340 * Rt: first (or only) SIMD&FP register to be transferred
2341 * Rn: base address or SP
2342 * Rm (post-index only): post-index register (when !31) or size dependent #imm
2343 */
2344 static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
2345 {
2346 int rt = extract32(insn, 0, 5);
2347 int rn = extract32(insn, 5, 5);
2348 int size = extract32(insn, 10, 2);
2349 int opcode = extract32(insn, 12, 4);
2350 bool is_store = !extract32(insn, 22, 1);
2351 bool is_postidx = extract32(insn, 23, 1);
2352 bool is_q = extract32(insn, 30, 1);
2353 TCGv_i64 tcg_addr, tcg_rn;
2354
2355 int ebytes = 1 << size;
2356 int elements = (is_q ? 128 : 64) / (8 << size);
2357 int rpt; /* num iterations */
2358 int selem; /* structure elements */
2359 int r;
2360
2361 if (extract32(insn, 31, 1) || extract32(insn, 21, 1)) {
2362 unallocated_encoding(s);
2363 return;
2364 }
2365
2366 /* From the shared decode logic */
2367 switch (opcode) {
2368 case 0x0:
2369 rpt = 1;
2370 selem = 4;
2371 break;
2372 case 0x2:
2373 rpt = 4;
2374 selem = 1;
2375 break;
2376 case 0x4:
2377 rpt = 1;
2378 selem = 3;
2379 break;
2380 case 0x6:
2381 rpt = 3;
2382 selem = 1;
2383 break;
2384 case 0x7:
2385 rpt = 1;
2386 selem = 1;
2387 break;
2388 case 0x8:
2389 rpt = 1;
2390 selem = 2;
2391 break;
2392 case 0xa:
2393 rpt = 2;
2394 selem = 1;
2395 break;
2396 default:
2397 unallocated_encoding(s);
2398 return;
2399 }
2400
2401 if (size == 3 && !is_q && selem != 1) {
2402 /* reserved */
2403 unallocated_encoding(s);
2404 return;
2405 }
2406
2407 if (!fp_access_check(s)) {
2408 return;
2409 }
2410
2411 if (rn == 31) {
2412 gen_check_sp_alignment(s);
2413 }
2414
2415 tcg_rn = cpu_reg_sp(s, rn);
2416 tcg_addr = tcg_temp_new_i64();
2417 tcg_gen_mov_i64(tcg_addr, tcg_rn);
2418
2419 for (r = 0; r < rpt; r++) {
2420 int e;
2421 for (e = 0; e < elements; e++) {
2422 int tt = (rt + r) % 32;
2423 int xs;
2424 for (xs = 0; xs < selem; xs++) {
2425 if (is_store) {
2426 do_vec_st(s, tt, e, tcg_addr, size);
2427 } else {
2428 do_vec_ld(s, tt, e, tcg_addr, size);
2429
2430 /* For non-quad operations, setting a slice of the low
2431 * 64 bits of the register clears the high 64 bits (in
2432 * the ARM ARM pseudocode this is implicit in the fact
2433 * that 'rval' is a 64 bit wide variable). We optimize
2434 * by noticing that we only need to do this the first
2435 * time we touch a register.
2436 */
2437 if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
2438 clear_vec_high(s, tt);
2439 }
2440 }
2441 tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2442 tt = (tt + 1) % 32;
2443 }
2444 }
2445 }
2446
2447 if (is_postidx) {
2448 int rm = extract32(insn, 16, 5);
2449 if (rm == 31) {
2450 tcg_gen_mov_i64(tcg_rn, tcg_addr);
2451 } else {
2452 tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2453 }
2454 }
2455 tcg_temp_free_i64(tcg_addr);
2456 }
2457
2458 /* C3.3.3 AdvSIMD load/store single structure
2459 *
2460 * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2461 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2462 * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size | Rn | Rt |
2463 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2464 *
2465 * C3.3.4 AdvSIMD load/store single structure (post-indexed)
2466 *
2467 * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
2468 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2469 * | 0 | Q | 0 0 1 1 0 1 1 | L R | Rm | opc | S | size | Rn | Rt |
2470 * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2471 *
2472 * Rt: first (or only) SIMD&FP register to be transferred
2473 * Rn: base address or SP
2474 * Rm (post-index only): post-index register (when !31) or size dependent #imm
2475 * index = encoded in Q:S:size dependent on size
2476 *
2477 * lane_size = encoded in R, opc
2478 * transfer width = encoded in opc, S, size
2479 */
2480 static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
2481 {
2482 int rt = extract32(insn, 0, 5);
2483 int rn = extract32(insn, 5, 5);
2484 int size = extract32(insn, 10, 2);
2485 int S = extract32(insn, 12, 1);
2486 int opc = extract32(insn, 13, 3);
2487 int R = extract32(insn, 21, 1);
2488 int is_load = extract32(insn, 22, 1);
2489 int is_postidx = extract32(insn, 23, 1);
2490 int is_q = extract32(insn, 30, 1);
2491
2492 int scale = extract32(opc, 1, 2);
2493 int selem = (extract32(opc, 0, 1) << 1 | R) + 1;
2494 bool replicate = false;
2495 int index = is_q << 3 | S << 2 | size;
2496 int ebytes, xs;
2497 TCGv_i64 tcg_addr, tcg_rn;
2498
2499 switch (scale) {
2500 case 3:
2501 if (!is_load || S) {
2502 unallocated_encoding(s);
2503 return;
2504 }
2505 scale = size;
2506 replicate = true;
2507 break;
2508 case 0:
2509 break;
2510 case 1:
2511 if (extract32(size, 0, 1)) {
2512 unallocated_encoding(s);
2513 return;
2514 }
2515 index >>= 1;
2516 break;
2517 case 2:
2518 if (extract32(size, 1, 1)) {
2519 unallocated_encoding(s);
2520 return;
2521 }
2522 if (!extract32(size, 0, 1)) {
2523 index >>= 2;
2524 } else {
2525 if (S) {
2526 unallocated_encoding(s);
2527 return;
2528 }
2529 index >>= 3;
2530 scale = 3;
2531 }
2532 break;
2533 default:
2534 g_assert_not_reached();
2535 }
2536
2537 if (!fp_access_check(s)) {
2538 return;
2539 }
2540
2541 ebytes = 1 << scale;
2542
2543 if (rn == 31) {
2544 gen_check_sp_alignment(s);
2545 }
2546
2547 tcg_rn = cpu_reg_sp(s, rn);
2548 tcg_addr = tcg_temp_new_i64();
2549 tcg_gen_mov_i64(tcg_addr, tcg_rn);
2550
2551 for (xs = 0; xs < selem; xs++) {
2552 if (replicate) {
2553 /* Load and replicate to all elements */
2554 uint64_t mulconst;
2555 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2556
2557 tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
2558 get_mem_index(s), MO_TE + scale);
2559 switch (scale) {
2560 case 0:
2561 mulconst = 0x0101010101010101ULL;
2562 break;
2563 case 1:
2564 mulconst = 0x0001000100010001ULL;
2565 break;
2566 case 2:
2567 mulconst = 0x0000000100000001ULL;
2568 break;
2569 case 3:
2570 mulconst = 0;
2571 break;
2572 default:
2573 g_assert_not_reached();
2574 }
2575 if (mulconst) {
2576 tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
2577 }
2578 write_vec_element(s, tcg_tmp, rt, 0, MO_64);
2579 if (is_q) {
2580 write_vec_element(s, tcg_tmp, rt, 1, MO_64);
2581 } else {
2582 clear_vec_high(s, rt);
2583 }
2584 tcg_temp_free_i64(tcg_tmp);
2585 } else {
2586 /* Load/store one element per register */
2587 if (is_load) {
2588 do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
2589 } else {
2590 do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
2591 }
2592 }
2593 tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2594 rt = (rt + 1) % 32;
2595 }
2596
2597 if (is_postidx) {
2598 int rm = extract32(insn, 16, 5);
2599 if (rm == 31) {
2600 tcg_gen_mov_i64(tcg_rn, tcg_addr);
2601 } else {
2602 tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2603 }
2604 }
2605 tcg_temp_free_i64(tcg_addr);
2606 }
2607
2608 /* C3.3 Loads and stores */
2609 static void disas_ldst(DisasContext *s, uint32_t insn)
2610 {
2611 switch (extract32(insn, 24, 6)) {
2612 case 0x08: /* Load/store exclusive */
2613 disas_ldst_excl(s, insn);
2614 break;
2615 case 0x18: case 0x1c: /* Load register (literal) */
2616 disas_ld_lit(s, insn);
2617 break;
2618 case 0x28: case 0x29:
2619 case 0x2c: case 0x2d: /* Load/store pair (all forms) */
2620 disas_ldst_pair(s, insn);
2621 break;
2622 case 0x38: case 0x39:
2623 case 0x3c: case 0x3d: /* Load/store register (all forms) */
2624 disas_ldst_reg(s, insn);
2625 break;
2626 case 0x0c: /* AdvSIMD load/store multiple structures */
2627 disas_ldst_multiple_struct(s, insn);
2628 break;
2629 case 0x0d: /* AdvSIMD load/store single structure */
2630 disas_ldst_single_struct(s, insn);
2631 break;
2632 default:
2633 unallocated_encoding(s);
2634 break;
2635 }
2636 }
2637
2638 /* C3.4.6 PC-rel. addressing
2639 * 31 30 29 28 24 23 5 4 0
2640 * +----+-------+-----------+-------------------+------+
2641 * | op | immlo | 1 0 0 0 0 | immhi | Rd |
2642 * +----+-------+-----------+-------------------+------+
2643 */
2644 static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
2645 {
2646 unsigned int page, rd;
2647 uint64_t base;
2648 int64_t offset;
2649
2650 page = extract32(insn, 31, 1);
2651 /* SignExtend(immhi:immlo) -> offset */
2652 offset = ((int64_t)sextract32(insn, 5, 19) << 2) | extract32(insn, 29, 2);
2653 rd = extract32(insn, 0, 5);
2654 base = s->pc - 4;
2655
2656 if (page) {
2657 /* ADRP (page based) */
2658 base &= ~0xfff;
2659 offset <<= 12;
2660 }
2661
2662 tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
2663 }
2664
2665 /*
2666 * C3.4.1 Add/subtract (immediate)
2667 *
2668 * 31 30 29 28 24 23 22 21 10 9 5 4 0
2669 * +--+--+--+-----------+-----+-------------+-----+-----+
2670 * |sf|op| S| 1 0 0 0 1 |shift| imm12 | Rn | Rd |
2671 * +--+--+--+-----------+-----+-------------+-----+-----+
2672 *
2673 * sf: 0 -> 32bit, 1 -> 64bit
2674 * op: 0 -> add , 1 -> sub
2675 * S: 1 -> set flags
2676 * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
2677 */
2678 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
2679 {
2680 int rd = extract32(insn, 0, 5);
2681 int rn = extract32(insn, 5, 5);
2682 uint64_t imm = extract32(insn, 10, 12);
2683 int shift = extract32(insn, 22, 2);
2684 bool setflags = extract32(insn, 29, 1);
2685 bool sub_op = extract32(insn, 30, 1);
2686 bool is_64bit = extract32(insn, 31, 1);
2687
2688 TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
2689 TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
2690 TCGv_i64 tcg_result;
2691
2692 switch (shift) {
2693 case 0x0:
2694 break;
2695 case 0x1:
2696 imm <<= 12;
2697 break;
2698 default:
2699 unallocated_encoding(s);
2700 return;
2701 }
2702
2703 tcg_result = tcg_temp_new_i64();
2704 if (!setflags) {
2705 if (sub_op) {
2706 tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
2707 } else {
2708 tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
2709 }
2710 } else {
2711 TCGv_i64 tcg_imm = tcg_const_i64(imm);
2712 if (sub_op) {
2713 gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2714 } else {
2715 gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2716 }
2717 tcg_temp_free_i64(tcg_imm);
2718 }
2719
2720 if (is_64bit) {
2721 tcg_gen_mov_i64(tcg_rd, tcg_result);
2722 } else {
2723 tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2724 }
2725
2726 tcg_temp_free_i64(tcg_result);
2727 }
2728
2729 /* The input should be a value in the bottom e bits (with higher
2730 * bits zero); returns that value replicated into every element
2731 * of size e in a 64 bit integer.
2732 */
2733 static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
2734 {
2735 assert(e != 0);
2736 while (e < 64) {
2737 mask |= mask << e;
2738 e *= 2;
2739 }
2740 return mask;
2741 }
2742
2743 /* Return a value with the bottom len bits set (where 0 < len <= 64) */
2744 static inline uint64_t bitmask64(unsigned int length)
2745 {
2746 assert(length > 0 && length <= 64);
2747 return ~0ULL >> (64 - length);
2748 }
2749
2750 /* Simplified variant of pseudocode DecodeBitMasks() for the case where we
2751 * only require the wmask. Returns false if the imms/immr/immn are a reserved
2752 * value (ie should cause a guest UNDEF exception), and true if they are
2753 * valid, in which case the decoded bit pattern is written to result.
2754 */
2755 static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
2756 unsigned int imms, unsigned int immr)
2757 {
2758 uint64_t mask;
2759 unsigned e, levels, s, r;
2760 int len;
2761
2762 assert(immn < 2 && imms < 64 && immr < 64);
2763
2764 /* The bit patterns we create here are 64 bit patterns which
2765 * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
2766 * 64 bits each. Each element contains the same value: a run
2767 * of between 1 and e-1 non-zero bits, rotated within the
2768 * element by between 0 and e-1 bits.
2769 *
2770 * The element size and run length are encoded into immn (1 bit)
2771 * and imms (6 bits) as follows:
2772 * 64 bit elements: immn = 1, imms = <length of run - 1>
2773 * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
2774 * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
2775 * 8 bit elements: immn = 0, imms = 110 : <length of run - 1>
2776 * 4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
2777 * 2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
2778 * Notice that immn = 0, imms = 11111x is the only combination
2779 * not covered by one of the above options; this is reserved.
2780 * Further, <length of run - 1> all-ones is a reserved pattern.
2781 *
2782 * In all cases the rotation is by immr % e (and immr is 6 bits).
2783 */
2784
2785 /* First determine the element size */
2786 len = 31 - clz32((immn << 6) | (~imms & 0x3f));
2787 if (len < 1) {
2788 /* This is the immn == 0, imms == 0x11111x case */
2789 return false;
2790 }
2791 e = 1 << len;
2792
2793 levels = e - 1;
2794 s = imms & levels;
2795 r = immr & levels;
2796
2797 if (s == levels) {
2798 /* <length of run - 1> mustn't be all-ones. */
2799 return false;
2800 }
2801
2802 /* Create the value of one element: s+1 set bits rotated
2803 * by r within the element (which is e bits wide)...
2804 */
2805 mask = bitmask64(s + 1);
2806 mask = (mask >> r) | (mask << (e - r));
2807 /* ...then replicate the element over the whole 64 bit value */
2808 mask = bitfield_replicate(mask, e);
2809 *result = mask;
2810 return true;
2811 }
2812
2813 /* C3.4.4 Logical (immediate)
2814 * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
2815 * +----+-----+-------------+---+------+------+------+------+
2816 * | sf | opc | 1 0 0 1 0 0 | N | immr | imms | Rn | Rd |
2817 * +----+-----+-------------+---+------+------+------+------+
2818 */
2819 static void disas_logic_imm(DisasContext *s, uint32_t insn)
2820 {
2821 unsigned int sf, opc, is_n, immr, imms, rn, rd;
2822 TCGv_i64 tcg_rd, tcg_rn;
2823 uint64_t wmask;
2824 bool is_and = false;
2825
2826 sf = extract32(insn, 31, 1);
2827 opc = extract32(insn, 29, 2);
2828 is_n = extract32(insn, 22, 1);
2829 immr = extract32(insn, 16, 6);
2830 imms = extract32(insn, 10, 6);
2831 rn = extract32(insn, 5, 5);
2832 rd = extract32(insn, 0, 5);
2833
2834 if (!sf && is_n) {
2835 unallocated_encoding(s);
2836 return;
2837 }
2838
2839 if (opc == 0x3) { /* ANDS */
2840 tcg_rd = cpu_reg(s, rd);
2841 } else {
2842 tcg_rd = cpu_reg_sp(s, rd);
2843 }
2844 tcg_rn = cpu_reg(s, rn);
2845
2846 if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
2847 /* some immediate field values are reserved */
2848 unallocated_encoding(s);
2849 return;
2850 }
2851
2852 if (!sf) {
2853 wmask &= 0xffffffff;
2854 }
2855
2856 switch (opc) {
2857 case 0x3: /* ANDS */
2858 case 0x0: /* AND */
2859 tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
2860 is_and = true;
2861 break;
2862 case 0x1: /* ORR */
2863 tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
2864 break;
2865 case 0x2: /* EOR */
2866 tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
2867 break;
2868 default:
2869 assert(FALSE); /* must handle all above */
2870 break;
2871 }
2872
2873 if (!sf && !is_and) {
2874 /* zero extend final result; we know we can skip this for AND
2875 * since the immediate had the high 32 bits clear.
2876 */
2877 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2878 }
2879
2880 if (opc == 3) { /* ANDS */
2881 gen_logic_CC(sf, tcg_rd);
2882 }
2883 }
2884
2885 /*
2886 * C3.4.5 Move wide (immediate)
2887 *
2888 * 31 30 29 28 23 22 21 20 5 4 0
2889 * +--+-----+-------------+-----+----------------+------+
2890 * |sf| opc | 1 0 0 1 0 1 | hw | imm16 | Rd |
2891 * +--+-----+-------------+-----+----------------+------+
2892 *
2893 * sf: 0 -> 32 bit, 1 -> 64 bit
2894 * opc: 00 -> N, 10 -> Z, 11 -> K
2895 * hw: shift/16 (0,16, and sf only 32, 48)
2896 */
2897 static void disas_movw_imm(DisasContext *s, uint32_t insn)
2898 {
2899 int rd = extract32(insn, 0, 5);
2900 uint64_t imm = extract32(insn, 5, 16);
2901 int sf = extract32(insn, 31, 1);
2902 int opc = extract32(insn, 29, 2);
2903 int pos = extract32(insn, 21, 2) << 4;
2904 TCGv_i64 tcg_rd = cpu_reg(s, rd);
2905 TCGv_i64 tcg_imm;
2906
2907 if (!sf && (pos >= 32)) {
2908 unallocated_encoding(s);
2909 return;
2910 }
2911
2912 switch (opc) {
2913 case 0: /* MOVN */
2914 case 2: /* MOVZ */
2915 imm <<= pos;
2916 if (opc == 0) {
2917 imm = ~imm;
2918 }
2919 if (!sf) {
2920 imm &= 0xffffffffu;
2921 }
2922 tcg_gen_movi_i64(tcg_rd, imm);
2923 break;
2924 case 3: /* MOVK */
2925 tcg_imm = tcg_const_i64(imm);
2926 tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
2927 tcg_temp_free_i64(tcg_imm);
2928 if (!sf) {
2929 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2930 }
2931 break;
2932 default:
2933 unallocated_encoding(s);
2934 break;
2935 }
2936 }
2937
2938 /* C3.4.2 Bitfield
2939 * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
2940 * +----+-----+-------------+---+------+------+------+------+
2941 * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
2942 * +----+-----+-------------+---+------+------+------+------+
2943 */
2944 static void disas_bitfield(DisasContext *s, uint32_t insn)
2945 {
2946 unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
2947 TCGv_i64 tcg_rd, tcg_tmp;
2948
2949 sf = extract32(insn, 31, 1);
2950 opc = extract32(insn, 29, 2);
2951 n = extract32(insn, 22, 1);
2952 ri = extract32(insn, 16, 6);
2953 si = extract32(insn, 10, 6);
2954 rn = extract32(insn, 5, 5);
2955 rd = extract32(insn, 0, 5);
2956 bitsize = sf ? 64 : 32;
2957
2958 if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
2959 unallocated_encoding(s);
2960 return;
2961 }
2962
2963 tcg_rd = cpu_reg(s, rd);
2964 tcg_tmp = read_cpu_reg(s, rn, sf);
2965
2966 /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
2967
2968 if (opc != 1) { /* SBFM or UBFM */
2969 tcg_gen_movi_i64(tcg_rd, 0);
2970 }
2971
2972 /* do the bit move operation */
2973 if (si >= ri) {
2974 /* Wd<s-r:0> = Wn<s:r> */
2975 tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
2976 pos = 0;
2977 len = (si - ri) + 1;
2978 } else {
2979 /* Wd<32+s-r,32-r> = Wn<s:0> */
2980 pos = bitsize - ri;
2981 len = si + 1;
2982 }
2983
2984 tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
2985
2986 if (opc == 0) { /* SBFM - sign extend the destination field */
2987 tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2988 tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2989 }
2990
2991 if (!sf) { /* zero extend final result */
2992 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2993 }
2994 }
2995
2996 /* C3.4.3 Extract
2997 * 31 30 29 28 23 22 21 20 16 15 10 9 5 4 0
2998 * +----+------+-------------+---+----+------+--------+------+------+
2999 * | sf | op21 | 1 0 0 1 1 1 | N | o0 | Rm | imms | Rn | Rd |
3000 * +----+------+-------------+---+----+------+--------+------+------+
3001 */
3002 static void disas_extract(DisasContext *s, uint32_t insn)
3003 {
3004 unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
3005
3006 sf = extract32(insn, 31, 1);
3007 n = extract32(insn, 22, 1);
3008 rm = extract32(insn, 16, 5);
3009 imm = extract32(insn, 10, 6);
3010 rn = extract32(insn, 5, 5);
3011 rd = extract32(insn, 0, 5);
3012 op21 = extract32(insn, 29, 2);
3013 op0 = extract32(insn, 21, 1);
3014 bitsize = sf ? 64 : 32;
3015
3016 if (sf != n || op21 || op0 || imm >= bitsize) {
3017 unallocated_encoding(s);
3018 } else {
3019 TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
3020
3021 tcg_rd = cpu_reg(s, rd);
3022
3023 if (imm) {
3024 /* OPTME: we can special case rm==rn as a rotate */
3025 tcg_rm = read_cpu_reg(s, rm, sf);
3026 tcg_rn = read_cpu_reg(s, rn, sf);
3027 tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
3028 tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
3029 tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
3030 if (!sf) {
3031 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3032 }
3033 } else {
3034 /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
3035 * so an extract from bit 0 is a special case.
3036 */
3037 if (sf) {
3038 tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
3039 } else {
3040 tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
3041 }
3042 }
3043
3044 }
3045 }
3046
3047 /* C3.4 Data processing - immediate */
3048 static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
3049 {
3050 switch (extract32(insn, 23, 6)) {
3051 case 0x20: case 0x21: /* PC-rel. addressing */
3052 disas_pc_rel_adr(s, insn);
3053 break;
3054 case 0x22: case 0x23: /* Add/subtract (immediate) */
3055 disas_add_sub_imm(s, insn);
3056 break;
3057 case 0x24: /* Logical (immediate) */
3058 disas_logic_imm(s, insn);
3059 break;
3060 case 0x25: /* Move wide (immediate) */
3061 disas_movw_imm(s, insn);
3062 break;
3063 case 0x26: /* Bitfield */
3064 disas_bitfield(s, insn);
3065 break;
3066 case 0x27: /* Extract */
3067 disas_extract(s, insn);
3068 break;
3069 default:
3070 unallocated_encoding(s);
3071 break;
3072 }
3073 }
3074
3075 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
3076 * Note that it is the caller's responsibility to ensure that the
3077 * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
3078 * mandated semantics for out of range shifts.
3079 */
3080 static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
3081 enum a64_shift_type shift_type, TCGv_i64 shift_amount)
3082 {
3083 switch (shift_type) {
3084 case A64_SHIFT_TYPE_LSL:
3085 tcg_gen_shl_i64(dst, src, shift_amount);
3086 break;
3087 case A64_SHIFT_TYPE_LSR:
3088 tcg_gen_shr_i64(dst, src, shift_amount);
3089 break;
3090 case A64_SHIFT_TYPE_ASR:
3091 if (!sf) {
3092 tcg_gen_ext32s_i64(dst, src);
3093 }
3094 tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
3095 break;
3096 case A64_SHIFT_TYPE_ROR:
3097 if (sf) {
3098 tcg_gen_rotr_i64(dst, src, shift_amount);
3099 } else {
3100 TCGv_i32 t0, t1;
3101 t0 = tcg_temp_new_i32();
3102 t1 = tcg_temp_new_i32();
3103 tcg_gen_trunc_i64_i32(t0, src);
3104 tcg_gen_trunc_i64_i32(t1, shift_amount);
3105 tcg_gen_rotr_i32(t0, t0, t1);
3106 tcg_gen_extu_i32_i64(dst, t0);
3107 tcg_temp_free_i32(t0);
3108 tcg_temp_free_i32(t1);
3109 }
3110 break;
3111 default:
3112 assert(FALSE); /* all shift types should be handled */
3113 break;
3114 }
3115
3116 if (!sf) { /* zero extend final result */
3117 tcg_gen_ext32u_i64(dst, dst);
3118 }
3119 }
3120
3121 /* Shift a TCGv src by immediate, put result in dst.
3122 * The shift amount must be in range (this should always be true as the
3123 * relevant instructions will UNDEF on bad shift immediates).
3124 */
3125 static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
3126 enum a64_shift_type shift_type, unsigned int shift_i)
3127 {
3128 assert(shift_i < (sf ? 64 : 32));
3129
3130 if (shift_i == 0) {
3131 tcg_gen_mov_i64(dst, src);
3132 } else {
3133 TCGv_i64 shift_const;
3134
3135 shift_const = tcg_const_i64(shift_i);
3136 shift_reg(dst, src, sf, shift_type, shift_const);
3137 tcg_temp_free_i64(shift_const);
3138 }
3139 }
3140
3141 /* C3.5.10 Logical (shifted register)
3142 * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0
3143 * +----+-----+-----------+-------+---+------+--------+------+------+
3144 * | sf | opc | 0 1 0 1 0 | shift | N | Rm | imm6 | Rn | Rd |
3145 * +----+-----+-----------+-------+---+------+--------+------+------+
3146 */
3147 static void disas_logic_reg(DisasContext *s, uint32_t insn)
3148 {
3149 TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
3150 unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;
3151
3152 sf = extract32(insn, 31, 1);
3153 opc = extract32(insn, 29, 2);
3154 shift_type = extract32(insn, 22, 2);
3155 invert = extract32(insn, 21, 1);
3156 rm = extract32(insn, 16, 5);
3157 shift_amount = extract32(insn, 10, 6);
3158 rn = extract32(insn, 5, 5);
3159 rd = extract32(insn, 0, 5);
3160
3161 if (!sf && (shift_amount & (1 << 5))) {
3162 unallocated_encoding(s);
3163 return;
3164 }
3165
3166 tcg_rd = cpu_reg(s, rd);
3167
3168 if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
3169 /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
3170 * register-register MOV and MVN, so it is worth special casing.
3171 */
3172 tcg_rm = cpu_reg(s, rm);
3173 if (invert) {
3174 tcg_gen_not_i64(tcg_rd, tcg_rm);
3175 if (!sf) {
3176 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3177 }
3178 } else {
3179 if (sf) {
3180 tcg_gen_mov_i64(tcg_rd, tcg_rm);
3181 } else {
3182 tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
3183 }
3184 }
3185 return;
3186 }
3187
3188 tcg_rm = read_cpu_reg(s, rm, sf);
3189
3190 if (shift_amount) {
3191 shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
3192 }
3193
3194 tcg_rn = cpu_reg(s, rn);
3195
3196 switch (opc | (invert << 2)) {
3197 case 0: /* AND */
3198 case 3: /* ANDS */
3199 tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
3200 break;
3201 case 1: /* ORR */
3202 tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
3203 break;
3204 case 2: /* EOR */
3205 tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
3206 break;
3207 case 4: /* BIC */
3208 case 7: /* BICS */
3209 tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
3210 break;