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