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