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