Statistics
| Branch: | Revision:

root / target-arm / translate-a64.c @ fa2ef212

History | View | Annotate | Download (104.6 kB)

1
/*
2
 *  AArch64 translation
3
 *
4
 *  Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <stdarg.h>
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <inttypes.h>
24

    
25
#include "cpu.h"
26
#include "tcg-op.h"
27
#include "qemu/log.h"
28
#include "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

    
124
static int get_mem_index(DisasContext *s)
125
{
126
#ifdef CONFIG_USER_ONLY
127
    return 1;
128
#else
129
    return s->user;
130
#endif
131
}
132

    
133
void gen_a64_set_pc_im(uint64_t val)
134
{
135
    tcg_gen_movi_i64(cpu_pc, val);
136
}
137

    
138
static void gen_exception(int excp)
139
{
140
    TCGv_i32 tmp = tcg_temp_new_i32();
141
    tcg_gen_movi_i32(tmp, excp);
142
    gen_helper_exception(cpu_env, tmp);
143
    tcg_temp_free_i32(tmp);
144
}
145

    
146
static void gen_exception_insn(DisasContext *s, int offset, int excp)
147
{
148
    gen_a64_set_pc_im(s->pc - offset);
149
    gen_exception(excp);
150
    s->is_jmp = DISAS_EXC;
151
}
152

    
153
static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
154
{
155
    /* No direct tb linking with singlestep or deterministic io */
156
    if (s->singlestep_enabled || (s->tb->cflags & CF_LAST_IO)) {
157
        return false;
158
    }
159

    
160
    /* Only link tbs from inside the same guest page */
161
    if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
162
        return false;
163
    }
164

    
165
    return true;
166
}
167

    
168
static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
169
{
170
    TranslationBlock *tb;
171

    
172
    tb = s->tb;
173
    if (use_goto_tb(s, n, dest)) {
174
        tcg_gen_goto_tb(n);
175
        gen_a64_set_pc_im(dest);
176
        tcg_gen_exit_tb((tcg_target_long)tb + n);
177
        s->is_jmp = DISAS_TB_JUMP;
178
    } else {
179
        gen_a64_set_pc_im(dest);
180
        if (s->singlestep_enabled) {
181
            gen_exception(EXCP_DEBUG);
182
        }
183
        tcg_gen_exit_tb(0);
184
        s->is_jmp = DISAS_JUMP;
185
    }
186
}
187

    
188
static void unallocated_encoding(DisasContext *s)
189
{
190
    gen_exception_insn(s, 4, EXCP_UDEF);
191
}
192

    
193
#define unsupported_encoding(s, insn)                                    \
194
    do {                                                                 \
195
        qemu_log_mask(LOG_UNIMP,                                         \
196
                      "%s:%d: unsupported instruction encoding 0x%08x "  \
197
                      "at pc=%016" PRIx64 "\n",                          \
198
                      __FILE__, __LINE__, insn, s->pc - 4);              \
199
        unallocated_encoding(s);                                         \
200
    } while (0);
201

    
202
static void init_tmp_a64_array(DisasContext *s)
203
{
204
#ifdef CONFIG_DEBUG_TCG
205
    int i;
206
    for (i = 0; i < ARRAY_SIZE(s->tmp_a64); i++) {
207
        TCGV_UNUSED_I64(s->tmp_a64[i]);
208
    }
209
#endif
210
    s->tmp_a64_count = 0;
211
}
212

    
213
static void free_tmp_a64(DisasContext *s)
214
{
215
    int i;
216
    for (i = 0; i < s->tmp_a64_count; i++) {
217
        tcg_temp_free_i64(s->tmp_a64[i]);
218
    }
219
    init_tmp_a64_array(s);
220
}
221

    
222
static TCGv_i64 new_tmp_a64(DisasContext *s)
223
{
224
    assert(s->tmp_a64_count < TMP_A64_MAX);
225
    return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
226
}
227

    
228
static TCGv_i64 new_tmp_a64_zero(DisasContext *s)
229
{
230
    TCGv_i64 t = new_tmp_a64(s);
231
    tcg_gen_movi_i64(t, 0);
232
    return t;
233
}
234

    
235
/*
236
 * Register access functions
237
 *
238
 * These functions are used for directly accessing a register in where
239
 * changes to the final register value are likely to be made. If you
240
 * need to use a register for temporary calculation (e.g. index type
241
 * operations) use the read_* form.
242
 *
243
 * B1.2.1 Register mappings
244
 *
245
 * In instruction register encoding 31 can refer to ZR (zero register) or
246
 * the SP (stack pointer) depending on context. In QEMU's case we map SP
247
 * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
248
 * This is the point of the _sp forms.
249
 */
250
static TCGv_i64 cpu_reg(DisasContext *s, int reg)
251
{
252
    if (reg == 31) {
253
        return new_tmp_a64_zero(s);
254
    } else {
255
        return cpu_X[reg];
256
    }
257
}
258

    
259
/* register access for when 31 == SP */
260
static TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
261
{
262
    return cpu_X[reg];
263
}
264

    
265
/* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
266
 * representing the register contents. This TCGv is an auto-freed
267
 * temporary so it need not be explicitly freed, and may be modified.
268
 */
269
static TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
270
{
271
    TCGv_i64 v = new_tmp_a64(s);
272
    if (reg != 31) {
273
        if (sf) {
274
            tcg_gen_mov_i64(v, cpu_X[reg]);
275
        } else {
276
            tcg_gen_ext32u_i64(v, cpu_X[reg]);
277
        }
278
    } else {
279
        tcg_gen_movi_i64(v, 0);
280
    }
281
    return v;
282
}
283

    
284
static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
285
{
286
    TCGv_i64 v = new_tmp_a64(s);
287
    if (sf) {
288
        tcg_gen_mov_i64(v, cpu_X[reg]);
289
    } else {
290
        tcg_gen_ext32u_i64(v, cpu_X[reg]);
291
    }
292
    return v;
293
}
294

    
295
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
296
 * than the 32 bit equivalent.
297
 */
298
static inline void gen_set_NZ64(TCGv_i64 result)
299
{
300
    TCGv_i64 flag = tcg_temp_new_i64();
301

    
302
    tcg_gen_setcondi_i64(TCG_COND_NE, flag, result, 0);
303
    tcg_gen_trunc_i64_i32(cpu_ZF, flag);
304
    tcg_gen_shri_i64(flag, result, 32);
305
    tcg_gen_trunc_i64_i32(cpu_NF, flag);
306
    tcg_temp_free_i64(flag);
307
}
308

    
309
/* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
310
static inline void gen_logic_CC(int sf, TCGv_i64 result)
311
{
312
    if (sf) {
313
        gen_set_NZ64(result);
314
    } else {
315
        tcg_gen_trunc_i64_i32(cpu_ZF, result);
316
        tcg_gen_trunc_i64_i32(cpu_NF, result);
317
    }
318
    tcg_gen_movi_i32(cpu_CF, 0);
319
    tcg_gen_movi_i32(cpu_VF, 0);
320
}
321

    
322
/* dest = T0 + T1; compute C, N, V and Z flags */
323
static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
324
{
325
    if (sf) {
326
        TCGv_i64 result, flag, tmp;
327
        result = tcg_temp_new_i64();
328
        flag = tcg_temp_new_i64();
329
        tmp = tcg_temp_new_i64();
330

    
331
        tcg_gen_movi_i64(tmp, 0);
332
        tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
333

    
334
        tcg_gen_trunc_i64_i32(cpu_CF, flag);
335

    
336
        gen_set_NZ64(result);
337

    
338
        tcg_gen_xor_i64(flag, result, t0);
339
        tcg_gen_xor_i64(tmp, t0, t1);
340
        tcg_gen_andc_i64(flag, flag, tmp);
341
        tcg_temp_free_i64(tmp);
342
        tcg_gen_shri_i64(flag, flag, 32);
343
        tcg_gen_trunc_i64_i32(cpu_VF, flag);
344

    
345
        tcg_gen_mov_i64(dest, result);
346
        tcg_temp_free_i64(result);
347
        tcg_temp_free_i64(flag);
348
    } else {
349
        /* 32 bit arithmetic */
350
        TCGv_i32 t0_32 = tcg_temp_new_i32();
351
        TCGv_i32 t1_32 = tcg_temp_new_i32();
352
        TCGv_i32 tmp = tcg_temp_new_i32();
353

    
354
        tcg_gen_movi_i32(tmp, 0);
355
        tcg_gen_trunc_i64_i32(t0_32, t0);
356
        tcg_gen_trunc_i64_i32(t1_32, t1);
357
        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
358
        tcg_gen_mov_i32(cpu_ZF, cpu_NF);
359
        tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
360
        tcg_gen_xor_i32(tmp, t0_32, t1_32);
361
        tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
362
        tcg_gen_extu_i32_i64(dest, cpu_NF);
363

    
364
        tcg_temp_free_i32(tmp);
365
        tcg_temp_free_i32(t0_32);
366
        tcg_temp_free_i32(t1_32);
367
    }
368
}
369

    
370
/* dest = T0 - T1; compute C, N, V and Z flags */
371
static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
372
{
373
    if (sf) {
374
        /* 64 bit arithmetic */
375
        TCGv_i64 result, flag, tmp;
376

    
377
        result = tcg_temp_new_i64();
378
        flag = tcg_temp_new_i64();
379
        tcg_gen_sub_i64(result, t0, t1);
380

    
381
        gen_set_NZ64(result);
382

    
383
        tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
384
        tcg_gen_trunc_i64_i32(cpu_CF, flag);
385

    
386
        tcg_gen_xor_i64(flag, result, t0);
387
        tmp = tcg_temp_new_i64();
388
        tcg_gen_xor_i64(tmp, t0, t1);
389
        tcg_gen_and_i64(flag, flag, tmp);
390
        tcg_temp_free_i64(tmp);
391
        tcg_gen_shri_i64(flag, flag, 32);
392
        tcg_gen_trunc_i64_i32(cpu_VF, flag);
393
        tcg_gen_mov_i64(dest, result);
394
        tcg_temp_free_i64(flag);
395
        tcg_temp_free_i64(result);
396
    } else {
397
        /* 32 bit arithmetic */
398
        TCGv_i32 t0_32 = tcg_temp_new_i32();
399
        TCGv_i32 t1_32 = tcg_temp_new_i32();
400
        TCGv_i32 tmp;
401

    
402
        tcg_gen_trunc_i64_i32(t0_32, t0);
403
        tcg_gen_trunc_i64_i32(t1_32, t1);
404
        tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
405
        tcg_gen_mov_i32(cpu_ZF, cpu_NF);
406
        tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
407
        tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
408
        tmp = tcg_temp_new_i32();
409
        tcg_gen_xor_i32(tmp, t0_32, t1_32);
410
        tcg_temp_free_i32(t0_32);
411
        tcg_temp_free_i32(t1_32);
412
        tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
413
        tcg_temp_free_i32(tmp);
414
        tcg_gen_extu_i32_i64(dest, cpu_NF);
415
    }
416
}
417

    
418
/* dest = T0 + T1 + CF; do not compute flags. */
419
static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
420
{
421
    TCGv_i64 flag = tcg_temp_new_i64();
422
    tcg_gen_extu_i32_i64(flag, cpu_CF);
423
    tcg_gen_add_i64(dest, t0, t1);
424
    tcg_gen_add_i64(dest, dest, flag);
425
    tcg_temp_free_i64(flag);
426

    
427
    if (!sf) {
428
        tcg_gen_ext32u_i64(dest, dest);
429
    }
430
}
431

    
432
/* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
433
static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
434
{
435
    if (sf) {
436
        TCGv_i64 result, cf_64, vf_64, tmp;
437
        result = tcg_temp_new_i64();
438
        cf_64 = tcg_temp_new_i64();
439
        vf_64 = tcg_temp_new_i64();
440
        tmp = tcg_const_i64(0);
441

    
442
        tcg_gen_extu_i32_i64(cf_64, cpu_CF);
443
        tcg_gen_add2_i64(result, cf_64, t0, tmp, cf_64, tmp);
444
        tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, tmp);
445
        tcg_gen_trunc_i64_i32(cpu_CF, cf_64);
446
        gen_set_NZ64(result);
447

    
448
        tcg_gen_xor_i64(vf_64, result, t0);
449
        tcg_gen_xor_i64(tmp, t0, t1);
450
        tcg_gen_andc_i64(vf_64, vf_64, tmp);
451
        tcg_gen_shri_i64(vf_64, vf_64, 32);
452
        tcg_gen_trunc_i64_i32(cpu_VF, vf_64);
453

    
454
        tcg_gen_mov_i64(dest, result);
455

    
456
        tcg_temp_free_i64(tmp);
457
        tcg_temp_free_i64(vf_64);
458
        tcg_temp_free_i64(cf_64);
459
        tcg_temp_free_i64(result);
460
    } else {
461
        TCGv_i32 t0_32, t1_32, tmp;
462
        t0_32 = tcg_temp_new_i32();
463
        t1_32 = tcg_temp_new_i32();
464
        tmp = tcg_const_i32(0);
465

    
466
        tcg_gen_trunc_i64_i32(t0_32, t0);
467
        tcg_gen_trunc_i64_i32(t1_32, t1);
468
        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, cpu_CF, tmp);
469
        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, tmp);
470

    
471
        tcg_gen_mov_i32(cpu_ZF, cpu_NF);
472
        tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
473
        tcg_gen_xor_i32(tmp, t0_32, t1_32);
474
        tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
475
        tcg_gen_extu_i32_i64(dest, cpu_NF);
476

    
477
        tcg_temp_free_i32(tmp);
478
        tcg_temp_free_i32(t1_32);
479
        tcg_temp_free_i32(t0_32);
480
    }
481
}
482

    
483
/*
484
 * Load/Store generators
485
 */
486

    
487
/*
488
 * Store from GPR register to memory
489
 */
490
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
491
                      TCGv_i64 tcg_addr, int size)
492
{
493
    g_assert(size <= 3);
494
    tcg_gen_qemu_st_i64(source, tcg_addr, get_mem_index(s), MO_TE + size);
495
}
496

    
497
/*
498
 * Load from memory to GPR register
499
 */
500
static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
501
                      int size, bool is_signed, bool extend)
502
{
503
    TCGMemOp memop = MO_TE + size;
504

    
505
    g_assert(size <= 3);
506

    
507
    if (is_signed) {
508
        memop += MO_SIGN;
509
    }
510

    
511
    tcg_gen_qemu_ld_i64(dest, tcg_addr, get_mem_index(s), memop);
512

    
513
    if (extend && is_signed) {
514
        g_assert(size < 3);
515
        tcg_gen_ext32u_i64(dest, dest);
516
    }
517
}
518

    
519
/*
520
 * Store from FP register to memory
521
 */
522
static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
523
{
524
    /* This writes the bottom N bits of a 128 bit wide vector to memory */
525
    int freg_offs = offsetof(CPUARMState, vfp.regs[srcidx * 2]);
526
    TCGv_i64 tmp = tcg_temp_new_i64();
527

    
528
    if (size < 4) {
529
        switch (size) {
530
        case 0:
531
            tcg_gen_ld8u_i64(tmp, cpu_env, freg_offs);
532
            break;
533
        case 1:
534
            tcg_gen_ld16u_i64(tmp, cpu_env, freg_offs);
535
            break;
536
        case 2:
537
            tcg_gen_ld32u_i64(tmp, cpu_env, freg_offs);
538
            break;
539
        case 3:
540
            tcg_gen_ld_i64(tmp, cpu_env, freg_offs);
541
            break;
542
        }
543
        tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
544
    } else {
545
        TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
546
        tcg_gen_ld_i64(tmp, cpu_env, freg_offs);
547
        tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
548
        tcg_gen_qemu_st64(tmp, tcg_addr, get_mem_index(s));
549
        tcg_gen_ld_i64(tmp, cpu_env, freg_offs + sizeof(float64));
550
        tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
551
        tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
552
        tcg_temp_free_i64(tcg_hiaddr);
553
    }
554

    
555
    tcg_temp_free_i64(tmp);
556
}
557

    
558
/*
559
 * Load from memory to FP register
560
 */
561
static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
562
{
563
    /* This always zero-extends and writes to a full 128 bit wide vector */
564
    int freg_offs = offsetof(CPUARMState, vfp.regs[destidx * 2]);
565
    TCGv_i64 tmplo = tcg_temp_new_i64();
566
    TCGv_i64 tmphi;
567

    
568
    if (size < 4) {
569
        TCGMemOp memop = MO_TE + size;
570
        tmphi = tcg_const_i64(0);
571
        tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
572
    } else {
573
        TCGv_i64 tcg_hiaddr;
574
        tmphi = tcg_temp_new_i64();
575
        tcg_hiaddr = tcg_temp_new_i64();
576

    
577
        tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
578
        tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
579
        tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
580
        tcg_temp_free_i64(tcg_hiaddr);
581
    }
582

    
583
    tcg_gen_st_i64(tmplo, cpu_env, freg_offs);
584
    tcg_gen_st_i64(tmphi, cpu_env, freg_offs + sizeof(float64));
585

    
586
    tcg_temp_free_i64(tmplo);
587
    tcg_temp_free_i64(tmphi);
588
}
589

    
590
/*
591
 * This utility function is for doing register extension with an
592
 * optional shift. You will likely want to pass a temporary for the
593
 * destination register. See DecodeRegExtend() in the ARM ARM.
594
 */
595
static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
596
                              int option, unsigned int shift)
597
{
598
    int extsize = extract32(option, 0, 2);
599
    bool is_signed = extract32(option, 2, 1);
600

    
601
    if (is_signed) {
602
        switch (extsize) {
603
        case 0:
604
            tcg_gen_ext8s_i64(tcg_out, tcg_in);
605
            break;
606
        case 1:
607
            tcg_gen_ext16s_i64(tcg_out, tcg_in);
608
            break;
609
        case 2:
610
            tcg_gen_ext32s_i64(tcg_out, tcg_in);
611
            break;
612
        case 3:
613
            tcg_gen_mov_i64(tcg_out, tcg_in);
614
            break;
615
        }
616
    } else {
617
        switch (extsize) {
618
        case 0:
619
            tcg_gen_ext8u_i64(tcg_out, tcg_in);
620
            break;
621
        case 1:
622
            tcg_gen_ext16u_i64(tcg_out, tcg_in);
623
            break;
624
        case 2:
625
            tcg_gen_ext32u_i64(tcg_out, tcg_in);
626
            break;
627
        case 3:
628
            tcg_gen_mov_i64(tcg_out, tcg_in);
629
            break;
630
        }
631
    }
632

    
633
    if (shift) {
634
        tcg_gen_shli_i64(tcg_out, tcg_out, shift);
635
    }
636
}
637

    
638
static inline void gen_check_sp_alignment(DisasContext *s)
639
{
640
    /* The AArch64 architecture mandates that (if enabled via PSTATE
641
     * or SCTLR bits) there is a check that SP is 16-aligned on every
642
     * SP-relative load or store (with an exception generated if it is not).
643
     * In line with general QEMU practice regarding misaligned accesses,
644
     * we omit these checks for the sake of guest program performance.
645
     * This function is provided as a hook so we can more easily add these
646
     * checks in future (possibly as a "favour catching guest program bugs
647
     * over speed" user selectable option).
648
     */
649
}
650

    
651
/*
652
 * the instruction disassembly implemented here matches
653
 * the instruction encoding classifications in chapter 3 (C3)
654
 * of the ARM Architecture Reference Manual (DDI0487A_a)
655
 */
656

    
657
/* C3.2.7 Unconditional branch (immediate)
658
 *   31  30       26 25                                  0
659
 * +----+-----------+-------------------------------------+
660
 * | op | 0 0 1 0 1 |                 imm26               |
661
 * +----+-----------+-------------------------------------+
662
 */
663
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
664
{
665
    uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
666

    
667
    if (insn & (1 << 31)) {
668
        /* C5.6.26 BL Branch with link */
669
        tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
670
    }
671

    
672
    /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
673
    gen_goto_tb(s, 0, addr);
674
}
675

    
676
/* C3.2.1 Compare & branch (immediate)
677
 *   31  30         25  24  23                  5 4      0
678
 * +----+-------------+----+---------------------+--------+
679
 * | sf | 0 1 1 0 1 0 | op |         imm19       |   Rt   |
680
 * +----+-------------+----+---------------------+--------+
681
 */
682
static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
683
{
684
    unsigned int sf, op, rt;
685
    uint64_t addr;
686
    int label_match;
687
    TCGv_i64 tcg_cmp;
688

    
689
    sf = extract32(insn, 31, 1);
690
    op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
691
    rt = extract32(insn, 0, 5);
692
    addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
693

    
694
    tcg_cmp = read_cpu_reg(s, rt, sf);
695
    label_match = gen_new_label();
696

    
697
    tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
698
                        tcg_cmp, 0, label_match);
699

    
700
    gen_goto_tb(s, 0, s->pc);
701
    gen_set_label(label_match);
702
    gen_goto_tb(s, 1, addr);
703
}
704

    
705
/* C3.2.5 Test & branch (immediate)
706
 *   31  30         25  24  23   19 18          5 4    0
707
 * +----+-------------+----+-------+-------------+------+
708
 * | b5 | 0 1 1 0 1 1 | op |  b40  |    imm14    |  Rt  |
709
 * +----+-------------+----+-------+-------------+------+
710
 */
711
static void disas_test_b_imm(DisasContext *s, uint32_t insn)
712
{
713
    unsigned int bit_pos, op, rt;
714
    uint64_t addr;
715
    int label_match;
716
    TCGv_i64 tcg_cmp;
717

    
718
    bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
719
    op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
720
    addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
721
    rt = extract32(insn, 0, 5);
722

    
723
    tcg_cmp = tcg_temp_new_i64();
724
    tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
725
    label_match = gen_new_label();
726
    tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
727
                        tcg_cmp, 0, label_match);
728
    tcg_temp_free_i64(tcg_cmp);
729
    gen_goto_tb(s, 0, s->pc);
730
    gen_set_label(label_match);
731
    gen_goto_tb(s, 1, addr);
732
}
733

    
734
/* C3.2.2 / C5.6.19 Conditional branch (immediate)
735
 *  31           25  24  23                  5   4  3    0
736
 * +---------------+----+---------------------+----+------+
737
 * | 0 1 0 1 0 1 0 | o1 |         imm19       | o0 | cond |
738
 * +---------------+----+---------------------+----+------+
739
 */
740
static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
741
{
742
    unsigned int cond;
743
    uint64_t addr;
744

    
745
    if ((insn & (1 << 4)) || (insn & (1 << 24))) {
746
        unallocated_encoding(s);
747
        return;
748
    }
749
    addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
750
    cond = extract32(insn, 0, 4);
751

    
752
    if (cond < 0x0e) {
753
        /* genuinely conditional branches */
754
        int label_match = gen_new_label();
755
        arm_gen_test_cc(cond, label_match);
756
        gen_goto_tb(s, 0, s->pc);
757
        gen_set_label(label_match);
758
        gen_goto_tb(s, 1, addr);
759
    } else {
760
        /* 0xe and 0xf are both "always" conditions */
761
        gen_goto_tb(s, 0, addr);
762
    }
763
}
764

    
765
/* C5.6.68 HINT */
766
static void handle_hint(DisasContext *s, uint32_t insn,
767
                        unsigned int op1, unsigned int op2, unsigned int crm)
768
{
769
    unsigned int selector = crm << 3 | op2;
770

    
771
    if (op1 != 3) {
772
        unallocated_encoding(s);
773
        return;
774
    }
775

    
776
    switch (selector) {
777
    case 0: /* NOP */
778
        return;
779
    case 1: /* YIELD */
780
    case 2: /* WFE */
781
    case 3: /* WFI */
782
    case 4: /* SEV */
783
    case 5: /* SEVL */
784
        /* we treat all as NOP at least for now */
785
        return;
786
    default:
787
        /* default specified as NOP equivalent */
788
        return;
789
    }
790
}
791

    
792
static void gen_clrex(DisasContext *s, uint32_t insn)
793
{
794
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
795
}
796

    
797
/* CLREX, DSB, DMB, ISB */
798
static void handle_sync(DisasContext *s, uint32_t insn,
799
                        unsigned int op1, unsigned int op2, unsigned int crm)
800
{
801
    if (op1 != 3) {
802
        unallocated_encoding(s);
803
        return;
804
    }
805

    
806
    switch (op2) {
807
    case 2: /* CLREX */
808
        gen_clrex(s, insn);
809
        return;
810
    case 4: /* DSB */
811
    case 5: /* DMB */
812
    case 6: /* ISB */
813
        /* We don't emulate caches so barriers are no-ops */
814
        return;
815
    default:
816
        unallocated_encoding(s);
817
        return;
818
    }
819
}
820

    
821
/* C5.6.130 MSR (immediate) - move immediate to processor state field */
822
static void handle_msr_i(DisasContext *s, uint32_t insn,
823
                         unsigned int op1, unsigned int op2, unsigned int crm)
824
{
825
    unsupported_encoding(s, insn);
826
}
827

    
828
static void gen_get_nzcv(TCGv_i64 tcg_rt)
829
{
830
    TCGv_i32 tmp = tcg_temp_new_i32();
831
    TCGv_i32 nzcv = tcg_temp_new_i32();
832

    
833
    /* build bit 31, N */
834
    tcg_gen_andi_i32(nzcv, cpu_NF, (1 << 31));
835
    /* build bit 30, Z */
836
    tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
837
    tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
838
    /* build bit 29, C */
839
    tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
840
    /* build bit 28, V */
841
    tcg_gen_shri_i32(tmp, cpu_VF, 31);
842
    tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
843
    /* generate result */
844
    tcg_gen_extu_i32_i64(tcg_rt, nzcv);
845

    
846
    tcg_temp_free_i32(nzcv);
847
    tcg_temp_free_i32(tmp);
848
}
849

    
850
static void gen_set_nzcv(TCGv_i64 tcg_rt)
851

    
852
{
853
    TCGv_i32 nzcv = tcg_temp_new_i32();
854

    
855
    /* take NZCV from R[t] */
856
    tcg_gen_trunc_i64_i32(nzcv, tcg_rt);
857

    
858
    /* bit 31, N */
859
    tcg_gen_andi_i32(cpu_NF, nzcv, (1 << 31));
860
    /* bit 30, Z */
861
    tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
862
    tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
863
    /* bit 29, C */
864
    tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
865
    tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
866
    /* bit 28, V */
867
    tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
868
    tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
869
    tcg_temp_free_i32(nzcv);
870
}
871

    
872
/* C5.6.129 MRS - move from system register
873
 * C5.6.131 MSR (register) - move to system register
874
 * C5.6.204 SYS
875
 * C5.6.205 SYSL
876
 * These are all essentially the same insn in 'read' and 'write'
877
 * versions, with varying op0 fields.
878
 */
879
static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
880
                       unsigned int op0, unsigned int op1, unsigned int op2,
881
                       unsigned int crn, unsigned int crm, unsigned int rt)
882
{
883
    const ARMCPRegInfo *ri;
884
    TCGv_i64 tcg_rt;
885

    
886
    ri = get_arm_cp_reginfo(s->cp_regs,
887
                            ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
888
                                               crn, crm, op0, op1, op2));
889

    
890
    if (!ri) {
891
        /* Unknown register */
892
        unallocated_encoding(s);
893
        return;
894
    }
895

    
896
    /* Check access permissions */
897
    if (!cp_access_ok(s->current_pl, ri, isread)) {
898
        unallocated_encoding(s);
899
        return;
900
    }
901

    
902
    /* Handle special cases first */
903
    switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
904
    case ARM_CP_NOP:
905
        return;
906
    case ARM_CP_NZCV:
907
        tcg_rt = cpu_reg(s, rt);
908
        if (isread) {
909
            gen_get_nzcv(tcg_rt);
910
        } else {
911
            gen_set_nzcv(tcg_rt);
912
        }
913
        return;
914
    default:
915
        break;
916
    }
917

    
918
    if (use_icount && (ri->type & ARM_CP_IO)) {
919
        gen_io_start();
920
    }
921

    
922
    tcg_rt = cpu_reg(s, rt);
923

    
924
    if (isread) {
925
        if (ri->type & ARM_CP_CONST) {
926
            tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
927
        } else if (ri->readfn) {
928
            TCGv_ptr tmpptr;
929
            gen_a64_set_pc_im(s->pc - 4);
930
            tmpptr = tcg_const_ptr(ri);
931
            gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
932
            tcg_temp_free_ptr(tmpptr);
933
        } else {
934
            tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
935
        }
936
    } else {
937
        if (ri->type & ARM_CP_CONST) {
938
            /* If not forbidden by access permissions, treat as WI */
939
            return;
940
        } else if (ri->writefn) {
941
            TCGv_ptr tmpptr;
942
            gen_a64_set_pc_im(s->pc - 4);
943
            tmpptr = tcg_const_ptr(ri);
944
            gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
945
            tcg_temp_free_ptr(tmpptr);
946
        } else {
947
            tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
948
        }
949
    }
950

    
951
    if (use_icount && (ri->type & ARM_CP_IO)) {
952
        /* I/O operations must end the TB here (whether read or write) */
953
        gen_io_end();
954
        s->is_jmp = DISAS_UPDATE;
955
    } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
956
        /* We default to ending the TB on a coprocessor register write,
957
         * but allow this to be suppressed by the register definition
958
         * (usually only necessary to work around guest bugs).
959
         */
960
        s->is_jmp = DISAS_UPDATE;
961
    }
962
}
963

    
964
/* C3.2.4 System
965
 *  31                 22 21  20 19 18 16 15   12 11    8 7   5 4    0
966
 * +---------------------+---+-----+-----+-------+-------+-----+------+
967
 * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 |  CRn  |  CRm  | op2 |  Rt  |
968
 * +---------------------+---+-----+-----+-------+-------+-----+------+
969
 */
970
static void disas_system(DisasContext *s, uint32_t insn)
971
{
972
    unsigned int l, op0, op1, crn, crm, op2, rt;
973
    l = extract32(insn, 21, 1);
974
    op0 = extract32(insn, 19, 2);
975
    op1 = extract32(insn, 16, 3);
976
    crn = extract32(insn, 12, 4);
977
    crm = extract32(insn, 8, 4);
978
    op2 = extract32(insn, 5, 3);
979
    rt = extract32(insn, 0, 5);
980

    
981
    if (op0 == 0) {
982
        if (l || rt != 31) {
983
            unallocated_encoding(s);
984
            return;
985
        }
986
        switch (crn) {
987
        case 2: /* C5.6.68 HINT */
988
            handle_hint(s, insn, op1, op2, crm);
989
            break;
990
        case 3: /* CLREX, DSB, DMB, ISB */
991
            handle_sync(s, insn, op1, op2, crm);
992
            break;
993
        case 4: /* C5.6.130 MSR (immediate) */
994
            handle_msr_i(s, insn, op1, op2, crm);
995
            break;
996
        default:
997
            unallocated_encoding(s);
998
            break;
999
        }
1000
        return;
1001
    }
1002
    handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
1003
}
1004

    
1005
/* C3.2.3 Exception generation
1006
 *
1007
 *  31             24 23 21 20                     5 4   2 1  0
1008
 * +-----------------+-----+------------------------+-----+----+
1009
 * | 1 1 0 1 0 1 0 0 | opc |          imm16         | op2 | LL |
1010
 * +-----------------------+------------------------+----------+
1011
 */
1012
static void disas_exc(DisasContext *s, uint32_t insn)
1013
{
1014
    int opc = extract32(insn, 21, 3);
1015
    int op2_ll = extract32(insn, 0, 5);
1016

    
1017
    switch (opc) {
1018
    case 0:
1019
        /* SVC, HVC, SMC; since we don't support the Virtualization
1020
         * or TrustZone extensions these all UNDEF except SVC.
1021
         */
1022
        if (op2_ll != 1) {
1023
            unallocated_encoding(s);
1024
            break;
1025
        }
1026
        gen_exception_insn(s, 0, EXCP_SWI);
1027
        break;
1028
    case 1:
1029
        if (op2_ll != 0) {
1030
            unallocated_encoding(s);
1031
            break;
1032
        }
1033
        /* BRK */
1034
        gen_exception_insn(s, 0, EXCP_BKPT);
1035
        break;
1036
    case 2:
1037
        if (op2_ll != 0) {
1038
            unallocated_encoding(s);
1039
            break;
1040
        }
1041
        /* HLT */
1042
        unsupported_encoding(s, insn);
1043
        break;
1044
    case 5:
1045
        if (op2_ll < 1 || op2_ll > 3) {
1046
            unallocated_encoding(s);
1047
            break;
1048
        }
1049
        /* DCPS1, DCPS2, DCPS3 */
1050
        unsupported_encoding(s, insn);
1051
        break;
1052
    default:
1053
        unallocated_encoding(s);
1054
        break;
1055
    }
1056
}
1057

    
1058
/* C3.2.7 Unconditional branch (register)
1059
 *  31           25 24   21 20   16 15   10 9    5 4     0
1060
 * +---------------+-------+-------+-------+------+-------+
1061
 * | 1 1 0 1 0 1 1 |  opc  |  op2  |  op3  |  Rn  |  op4  |
1062
 * +---------------+-------+-------+-------+------+-------+
1063
 */
1064
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
1065
{
1066
    unsigned int opc, op2, op3, rn, op4;
1067

    
1068
    opc = extract32(insn, 21, 4);
1069
    op2 = extract32(insn, 16, 5);
1070
    op3 = extract32(insn, 10, 6);
1071
    rn = extract32(insn, 5, 5);
1072
    op4 = extract32(insn, 0, 5);
1073

    
1074
    if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
1075
        unallocated_encoding(s);
1076
        return;
1077
    }
1078

    
1079
    switch (opc) {
1080
    case 0: /* BR */
1081
    case 2: /* RET */
1082
        break;
1083
    case 1: /* BLR */
1084
        tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1085
        break;
1086
    case 4: /* ERET */
1087
    case 5: /* DRPS */
1088
        if (rn != 0x1f) {
1089
            unallocated_encoding(s);
1090
        } else {
1091
            unsupported_encoding(s, insn);
1092
        }
1093
        return;
1094
    default:
1095
        unallocated_encoding(s);
1096
        return;
1097
    }
1098

    
1099
    tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1100
    s->is_jmp = DISAS_JUMP;
1101
}
1102

    
1103
/* C3.2 Branches, exception generating and system instructions */
1104
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
1105
{
1106
    switch (extract32(insn, 25, 7)) {
1107
    case 0x0a: case 0x0b:
1108
    case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1109
        disas_uncond_b_imm(s, insn);
1110
        break;
1111
    case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1112
        disas_comp_b_imm(s, insn);
1113
        break;
1114
    case 0x1b: case 0x5b: /* Test & branch (immediate) */
1115
        disas_test_b_imm(s, insn);
1116
        break;
1117
    case 0x2a: /* Conditional branch (immediate) */
1118
        disas_cond_b_imm(s, insn);
1119
        break;
1120
    case 0x6a: /* Exception generation / System */
1121
        if (insn & (1 << 24)) {
1122
            disas_system(s, insn);
1123
        } else {
1124
            disas_exc(s, insn);
1125
        }
1126
        break;
1127
    case 0x6b: /* Unconditional branch (register) */
1128
        disas_uncond_b_reg(s, insn);
1129
        break;
1130
    default:
1131
        unallocated_encoding(s);
1132
        break;
1133
    }
1134
}
1135

    
1136
/*
1137
 * Load/Store exclusive instructions are implemented by remembering
1138
 * the value/address loaded, and seeing if these are the same
1139
 * when the store is performed. This is not actually the architecturally
1140
 * mandated semantics, but it works for typical guest code sequences
1141
 * and avoids having to monitor regular stores.
1142
 *
1143
 * In system emulation mode only one CPU will be running at once, so
1144
 * this sequence is effectively atomic.  In user emulation mode we
1145
 * throw an exception and handle the atomic operation elsewhere.
1146
 */
1147
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
1148
                               TCGv_i64 addr, int size, bool is_pair)
1149
{
1150
    TCGv_i64 tmp = tcg_temp_new_i64();
1151
    TCGMemOp memop = MO_TE + size;
1152

    
1153
    g_assert(size <= 3);
1154
    tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
1155

    
1156
    if (is_pair) {
1157
        TCGv_i64 addr2 = tcg_temp_new_i64();
1158
        TCGv_i64 hitmp = tcg_temp_new_i64();
1159

    
1160
        g_assert(size >= 2);
1161
        tcg_gen_addi_i64(addr2, addr, 1 << size);
1162
        tcg_gen_qemu_ld_i64(hitmp, addr2, get_mem_index(s), memop);
1163
        tcg_temp_free_i64(addr2);
1164
        tcg_gen_mov_i64(cpu_exclusive_high, hitmp);
1165
        tcg_gen_mov_i64(cpu_reg(s, rt2), hitmp);
1166
        tcg_temp_free_i64(hitmp);
1167
    }
1168

    
1169
    tcg_gen_mov_i64(cpu_exclusive_val, tmp);
1170
    tcg_gen_mov_i64(cpu_reg(s, rt), tmp);
1171

    
1172
    tcg_temp_free_i64(tmp);
1173
    tcg_gen_mov_i64(cpu_exclusive_addr, addr);
1174
}
1175

    
1176
#ifdef CONFIG_USER_ONLY
1177
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1178
                                TCGv_i64 addr, int size, int is_pair)
1179
{
1180
    tcg_gen_mov_i64(cpu_exclusive_test, addr);
1181
    tcg_gen_movi_i32(cpu_exclusive_info,
1182
                     size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
1183
    gen_exception_insn(s, 4, EXCP_STREX);
1184
}
1185
#else
1186
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1187
                                TCGv_i64 addr, int size, int is_pair)
1188
{
1189
    qemu_log_mask(LOG_UNIMP,
1190
                  "%s:%d: system mode store_exclusive unsupported "
1191
                  "at pc=%016" PRIx64 "\n",
1192
                  __FILE__, __LINE__, s->pc - 4);
1193
}
1194
#endif
1195

    
1196
/* C3.3.6 Load/store exclusive
1197
 *
1198
 *  31 30 29         24  23  22   21  20  16  15  14   10 9    5 4    0
1199
 * +-----+-------------+----+---+----+------+----+-------+------+------+
1200
 * | sz  | 0 0 1 0 0 0 | o2 | L | o1 |  Rs  | o0 |  Rt2  |  Rn  | Rt   |
1201
 * +-----+-------------+----+---+----+------+----+-------+------+------+
1202
 *
1203
 *  sz: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64 bit
1204
 *   L: 0 -> store, 1 -> load
1205
 *  o2: 0 -> exclusive, 1 -> not
1206
 *  o1: 0 -> single register, 1 -> register pair
1207
 *  o0: 1 -> load-acquire/store-release, 0 -> not
1208
 *
1209
 *  o0 == 0 AND o2 == 1 is un-allocated
1210
 *  o1 == 1 is un-allocated except for 32 and 64 bit sizes
1211
 */
1212
static void disas_ldst_excl(DisasContext *s, uint32_t insn)
1213
{
1214
    int rt = extract32(insn, 0, 5);
1215
    int rn = extract32(insn, 5, 5);
1216
    int rt2 = extract32(insn, 10, 5);
1217
    int is_lasr = extract32(insn, 15, 1);
1218
    int rs = extract32(insn, 16, 5);
1219
    int is_pair = extract32(insn, 21, 1);
1220
    int is_store = !extract32(insn, 22, 1);
1221
    int is_excl = !extract32(insn, 23, 1);
1222
    int size = extract32(insn, 30, 2);
1223
    TCGv_i64 tcg_addr;
1224

    
1225
    if ((!is_excl && !is_lasr) ||
1226
        (is_pair && size < 2)) {
1227
        unallocated_encoding(s);
1228
        return;
1229
    }
1230

    
1231
    if (rn == 31) {
1232
        gen_check_sp_alignment(s);
1233
    }
1234
    tcg_addr = read_cpu_reg_sp(s, rn, 1);
1235

    
1236
    /* Note that since TCG is single threaded load-acquire/store-release
1237
     * semantics require no extra if (is_lasr) { ... } handling.
1238
     */
1239

    
1240
    if (is_excl) {
1241
        if (!is_store) {
1242
            gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
1243
        } else {
1244
            gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
1245
        }
1246
    } else {
1247
        TCGv_i64 tcg_rt = cpu_reg(s, rt);
1248
        if (is_store) {
1249
            do_gpr_st(s, tcg_rt, tcg_addr, size);
1250
        } else {
1251
            do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);
1252
        }
1253
        if (is_pair) {
1254
            TCGv_i64 tcg_rt2 = cpu_reg(s, rt);
1255
            tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1256
            if (is_store) {
1257
                do_gpr_st(s, tcg_rt2, tcg_addr, size);
1258
            } else {
1259
                do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false);
1260
            }
1261
        }
1262
    }
1263
}
1264

    
1265
/*
1266
 * C3.3.5 Load register (literal)
1267
 *
1268
 *  31 30 29   27  26 25 24 23                5 4     0
1269
 * +-----+-------+---+-----+-------------------+-------+
1270
 * | opc | 0 1 1 | V | 0 0 |     imm19         |  Rt   |
1271
 * +-----+-------+---+-----+-------------------+-------+
1272
 *
1273
 * V: 1 -> vector (simd/fp)
1274
 * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
1275
 *                   10-> 32 bit signed, 11 -> prefetch
1276
 * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
1277
 */
1278
static void disas_ld_lit(DisasContext *s, uint32_t insn)
1279
{
1280
    int rt = extract32(insn, 0, 5);
1281
    int64_t imm = sextract32(insn, 5, 19) << 2;
1282
    bool is_vector = extract32(insn, 26, 1);
1283
    int opc = extract32(insn, 30, 2);
1284
    bool is_signed = false;
1285
    int size = 2;
1286
    TCGv_i64 tcg_rt, tcg_addr;
1287

    
1288
    if (is_vector) {
1289
        if (opc == 3) {
1290
            unallocated_encoding(s);
1291
            return;
1292
        }
1293
        size = 2 + opc;
1294
    } else {
1295
        if (opc == 3) {
1296
            /* PRFM (literal) : prefetch */
1297
            return;
1298
        }
1299
        size = 2 + extract32(opc, 0, 1);
1300
        is_signed = extract32(opc, 1, 1);
1301
    }
1302

    
1303
    tcg_rt = cpu_reg(s, rt);
1304

    
1305
    tcg_addr = tcg_const_i64((s->pc - 4) + imm);
1306
    if (is_vector) {
1307
        do_fp_ld(s, rt, tcg_addr, size);
1308
    } else {
1309
        do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1310
    }
1311
    tcg_temp_free_i64(tcg_addr);
1312
}
1313

    
1314
/*
1315
 * C5.6.80 LDNP (Load Pair - non-temporal hint)
1316
 * C5.6.81 LDP (Load Pair - non vector)
1317
 * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
1318
 * C5.6.176 STNP (Store Pair - non-temporal hint)
1319
 * C5.6.177 STP (Store Pair - non vector)
1320
 * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
1321
 * C6.3.165 LDP (Load Pair of SIMD&FP)
1322
 * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
1323
 * C6.3.284 STP (Store Pair of SIMD&FP)
1324
 *
1325
 *  31 30 29   27  26  25 24   23  22 21   15 14   10 9    5 4    0
1326
 * +-----+-------+---+---+-------+---+-----------------------------+
1327
 * | opc | 1 0 1 | V | 0 | index | L |  imm7 |  Rt2  |  Rn  | Rt   |
1328
 * +-----+-------+---+---+-------+---+-------+-------+------+------+
1329
 *
1330
 * opc: LDP/STP/LDNP/STNP        00 -> 32 bit, 10 -> 64 bit
1331
 *      LDPSW                    01
1332
 *      LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
1333
 *   V: 0 -> GPR, 1 -> Vector
1334
 * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
1335
 *      10 -> signed offset, 11 -> pre-index
1336
 *   L: 0 -> Store 1 -> Load
1337
 *
1338
 * Rt, Rt2 = GPR or SIMD registers to be stored
1339
 * Rn = general purpose register containing address
1340
 * imm7 = signed offset (multiple of 4 or 8 depending on size)
1341
 */
1342
static void disas_ldst_pair(DisasContext *s, uint32_t insn)
1343
{
1344
    int rt = extract32(insn, 0, 5);
1345
    int rn = extract32(insn, 5, 5);
1346
    int rt2 = extract32(insn, 10, 5);
1347
    int64_t offset = sextract32(insn, 15, 7);
1348
    int index = extract32(insn, 23, 2);
1349
    bool is_vector = extract32(insn, 26, 1);
1350
    bool is_load = extract32(insn, 22, 1);
1351
    int opc = extract32(insn, 30, 2);
1352

    
1353
    bool is_signed = false;
1354
    bool postindex = false;
1355
    bool wback = false;
1356

    
1357
    TCGv_i64 tcg_addr; /* calculated address */
1358
    int size;
1359

    
1360
    if (opc == 3) {
1361
        unallocated_encoding(s);
1362
        return;
1363
    }
1364

    
1365
    if (is_vector) {
1366
        size = 2 + opc;
1367
    } else {
1368
        size = 2 + extract32(opc, 1, 1);
1369
        is_signed = extract32(opc, 0, 1);
1370
        if (!is_load && is_signed) {
1371
            unallocated_encoding(s);
1372
            return;
1373
        }
1374
    }
1375

    
1376
    switch (index) {
1377
    case 1: /* post-index */
1378
        postindex = true;
1379
        wback = true;
1380
        break;
1381
    case 0:
1382
        /* signed offset with "non-temporal" hint. Since we don't emulate
1383
         * caches we don't care about hints to the cache system about
1384
         * data access patterns, and handle this identically to plain
1385
         * signed offset.
1386
         */
1387
        if (is_signed) {
1388
            /* There is no non-temporal-hint version of LDPSW */
1389
            unallocated_encoding(s);
1390
            return;
1391
        }
1392
        postindex = false;
1393
        break;
1394
    case 2: /* signed offset, rn not updated */
1395
        postindex = false;
1396
        break;
1397
    case 3: /* pre-index */
1398
        postindex = false;
1399
        wback = true;
1400
        break;
1401
    }
1402

    
1403
    offset <<= size;
1404

    
1405
    if (rn == 31) {
1406
        gen_check_sp_alignment(s);
1407
    }
1408

    
1409
    tcg_addr = read_cpu_reg_sp(s, rn, 1);
1410

    
1411
    if (!postindex) {
1412
        tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1413
    }
1414

    
1415
    if (is_vector) {
1416
        if (is_load) {
1417
            do_fp_ld(s, rt, tcg_addr, size);
1418
        } else {
1419
            do_fp_st(s, rt, tcg_addr, size);
1420
        }
1421
    } else {
1422
        TCGv_i64 tcg_rt = cpu_reg(s, rt);
1423
        if (is_load) {
1424
            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1425
        } else {
1426
            do_gpr_st(s, tcg_rt, tcg_addr, size);
1427
        }
1428
    }
1429
    tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1430
    if (is_vector) {
1431
        if (is_load) {
1432
            do_fp_ld(s, rt2, tcg_addr, size);
1433
        } else {
1434
            do_fp_st(s, rt2, tcg_addr, size);
1435
        }
1436
    } else {
1437
        TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
1438
        if (is_load) {
1439
            do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
1440
        } else {
1441
            do_gpr_st(s, tcg_rt2, tcg_addr, size);
1442
        }
1443
    }
1444

    
1445
    if (wback) {
1446
        if (postindex) {
1447
            tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
1448
        } else {
1449
            tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
1450
        }
1451
        tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
1452
    }
1453
}
1454

    
1455
/*
1456
 * C3.3.8 Load/store (immediate post-indexed)
1457
 * C3.3.9 Load/store (immediate pre-indexed)
1458
 * C3.3.12 Load/store (unscaled immediate)
1459
 *
1460
 * 31 30 29   27  26 25 24 23 22 21  20    12 11 10 9    5 4    0
1461
 * +----+-------+---+-----+-----+---+--------+-----+------+------+
1462
 * |size| 1 1 1 | V | 0 0 | opc | 0 |  imm9  | idx |  Rn  |  Rt  |
1463
 * +----+-------+---+-----+-----+---+--------+-----+------+------+
1464
 *
1465
 * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
1466
 * V = 0 -> non-vector
1467
 * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
1468
 * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1469
 */
1470
static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
1471
{
1472
    int rt = extract32(insn, 0, 5);
1473
    int rn = extract32(insn, 5, 5);
1474
    int imm9 = sextract32(insn, 12, 9);
1475
    int opc = extract32(insn, 22, 2);
1476
    int size = extract32(insn, 30, 2);
1477
    int idx = extract32(insn, 10, 2);
1478
    bool is_signed = false;
1479
    bool is_store = false;
1480
    bool is_extended = false;
1481
    bool is_vector = extract32(insn, 26, 1);
1482
    bool post_index;
1483
    bool writeback;
1484

    
1485
    TCGv_i64 tcg_addr;
1486

    
1487
    if (is_vector) {
1488
        size |= (opc & 2) << 1;
1489
        if (size > 4) {
1490
            unallocated_encoding(s);
1491
            return;
1492
        }
1493
        is_store = ((opc & 1) == 0);
1494
    } else {
1495
        if (size == 3 && opc == 2) {
1496
            /* PRFM - prefetch */
1497
            return;
1498
        }
1499
        if (opc == 3 && size > 1) {
1500
            unallocated_encoding(s);
1501
            return;
1502
        }
1503
        is_store = (opc == 0);
1504
        is_signed = opc & (1<<1);
1505
        is_extended = (size < 3) && (opc & 1);
1506
    }
1507

    
1508
    switch (idx) {
1509
    case 0:
1510
        post_index = false;
1511
        writeback = false;
1512
        break;
1513
    case 1:
1514
        post_index = true;
1515
        writeback = true;
1516
        break;
1517
    case 3:
1518
        post_index = false;
1519
        writeback = true;
1520
        break;
1521
    case 2:
1522
        g_assert(false);
1523
        break;
1524
    }
1525

    
1526
    if (rn == 31) {
1527
        gen_check_sp_alignment(s);
1528
    }
1529
    tcg_addr = read_cpu_reg_sp(s, rn, 1);
1530

    
1531
    if (!post_index) {
1532
        tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1533
    }
1534

    
1535
    if (is_vector) {
1536
        if (is_store) {
1537
            do_fp_st(s, rt, tcg_addr, size);
1538
        } else {
1539
            do_fp_ld(s, rt, tcg_addr, size);
1540
        }
1541
    } else {
1542
        TCGv_i64 tcg_rt = cpu_reg(s, rt);
1543
        if (is_store) {
1544
            do_gpr_st(s, tcg_rt, tcg_addr, size);
1545
        } else {
1546
            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1547
        }
1548
    }
1549

    
1550
    if (writeback) {
1551
        TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
1552
        if (post_index) {
1553
            tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1554
        }
1555
        tcg_gen_mov_i64(tcg_rn, tcg_addr);
1556
    }
1557
}
1558

    
1559
/*
1560
 * C3.3.10 Load/store (register offset)
1561
 *
1562
 * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
1563
 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1564
 * |size| 1 1 1 | V | 0 0 | opc | 1 |  Rm  | opt | S| 1 0 | Rn | Rt |
1565
 * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1566
 *
1567
 * For non-vector:
1568
 *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1569
 *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1570
 * For vector:
1571
 *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1572
 *   opc<0>: 0 -> store, 1 -> load
1573
 * V: 1 -> vector/simd
1574
 * opt: extend encoding (see DecodeRegExtend)
1575
 * S: if S=1 then scale (essentially index by sizeof(size))
1576
 * Rt: register to transfer into/out of
1577
 * Rn: address register or SP for base
1578
 * Rm: offset register or ZR for offset
1579
 */
1580
static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
1581
{
1582
    int rt = extract32(insn, 0, 5);
1583
    int rn = extract32(insn, 5, 5);
1584
    int shift = extract32(insn, 12, 1);
1585
    int rm = extract32(insn, 16, 5);
1586
    int opc = extract32(insn, 22, 2);
1587
    int opt = extract32(insn, 13, 3);
1588
    int size = extract32(insn, 30, 2);
1589
    bool is_signed = false;
1590
    bool is_store = false;
1591
    bool is_extended = false;
1592
    bool is_vector = extract32(insn, 26, 1);
1593

    
1594
    TCGv_i64 tcg_rm;
1595
    TCGv_i64 tcg_addr;
1596

    
1597
    if (extract32(opt, 1, 1) == 0) {
1598
        unallocated_encoding(s);
1599
        return;
1600
    }
1601

    
1602
    if (is_vector) {
1603
        size |= (opc & 2) << 1;
1604
        if (size > 4) {
1605
            unallocated_encoding(s);
1606
            return;
1607
        }
1608
        is_store = !extract32(opc, 0, 1);
1609
    } else {
1610
        if (size == 3 && opc == 2) {
1611
            /* PRFM - prefetch */
1612
            return;
1613
        }
1614
        if (opc == 3 && size > 1) {
1615
            unallocated_encoding(s);
1616
            return;
1617
        }
1618
        is_store = (opc == 0);
1619
        is_signed = extract32(opc, 1, 1);
1620
        is_extended = (size < 3) && extract32(opc, 0, 1);
1621
    }
1622

    
1623
    if (rn == 31) {
1624
        gen_check_sp_alignment(s);
1625
    }
1626
    tcg_addr = read_cpu_reg_sp(s, rn, 1);
1627

    
1628
    tcg_rm = read_cpu_reg(s, rm, 1);
1629
    ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
1630

    
1631
    tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
1632

    
1633
    if (is_vector) {
1634
        if (is_store) {
1635
            do_fp_st(s, rt, tcg_addr, size);
1636
        } else {
1637
            do_fp_ld(s, rt, tcg_addr, size);
1638
        }
1639
    } else {
1640
        TCGv_i64 tcg_rt = cpu_reg(s, rt);
1641
        if (is_store) {
1642
            do_gpr_st(s, tcg_rt, tcg_addr, size);
1643
        } else {
1644
            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1645
        }
1646
    }
1647
}
1648

    
1649
/*
1650
 * C3.3.13 Load/store (unsigned immediate)
1651
 *
1652
 * 31 30 29   27  26 25 24 23 22 21        10 9     5
1653
 * +----+-------+---+-----+-----+------------+-------+------+
1654
 * |size| 1 1 1 | V | 0 1 | opc |   imm12    |  Rn   |  Rt  |
1655
 * +----+-------+---+-----+-----+------------+-------+------+
1656
 *
1657
 * For non-vector:
1658
 *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1659
 *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1660
 * For vector:
1661
 *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1662
 *   opc<0>: 0 -> store, 1 -> load
1663
 * Rn: base address register (inc SP)
1664
 * Rt: target register
1665
 */
1666
static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
1667
{
1668
    int rt = extract32(insn, 0, 5);
1669
    int rn = extract32(insn, 5, 5);
1670
    unsigned int imm12 = extract32(insn, 10, 12);
1671
    bool is_vector = extract32(insn, 26, 1);
1672
    int size = extract32(insn, 30, 2);
1673
    int opc = extract32(insn, 22, 2);
1674
    unsigned int offset;
1675

    
1676
    TCGv_i64 tcg_addr;
1677

    
1678
    bool is_store;
1679
    bool is_signed = false;
1680
    bool is_extended = false;
1681

    
1682
    if (is_vector) {
1683
        size |= (opc & 2) << 1;
1684
        if (size > 4) {
1685
            unallocated_encoding(s);
1686
            return;
1687
        }
1688
        is_store = !extract32(opc, 0, 1);
1689
    } else {
1690
        if (size == 3 && opc == 2) {
1691
            /* PRFM - prefetch */
1692
            return;
1693
        }
1694
        if (opc == 3 && size > 1) {
1695
            unallocated_encoding(s);
1696
            return;
1697
        }
1698
        is_store = (opc == 0);
1699
        is_signed = extract32(opc, 1, 1);
1700
        is_extended = (size < 3) && extract32(opc, 0, 1);
1701
    }
1702

    
1703
    if (rn == 31) {
1704
        gen_check_sp_alignment(s);
1705
    }
1706
    tcg_addr = read_cpu_reg_sp(s, rn, 1);
1707
    offset = imm12 << size;
1708
    tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1709

    
1710
    if (is_vector) {
1711
        if (is_store) {
1712
            do_fp_st(s, rt, tcg_addr, size);
1713
        } else {
1714
            do_fp_ld(s, rt, tcg_addr, size);
1715
        }
1716
    } else {
1717
        TCGv_i64 tcg_rt = cpu_reg(s, rt);
1718
        if (is_store) {
1719
            do_gpr_st(s, tcg_rt, tcg_addr, size);
1720
        } else {
1721
            do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1722
        }
1723
    }
1724
}
1725

    
1726
/* Load/store register (immediate forms) */
1727
static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn)
1728
{
1729
    switch (extract32(insn, 10, 2)) {
1730
    case 0: case 1: case 3:
1731
        /* Load/store register (unscaled immediate) */
1732
        /* Load/store immediate pre/post-indexed */
1733
        disas_ldst_reg_imm9(s, insn);
1734
        break;
1735
    case 2:
1736
        /* Load/store register unprivileged */
1737
        unsupported_encoding(s, insn);
1738
        break;
1739
    default:
1740
        unallocated_encoding(s);
1741
        break;
1742
    }
1743
}
1744

    
1745
/* Load/store register (all forms) */
1746
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
1747
{
1748
    switch (extract32(insn, 24, 2)) {
1749
    case 0:
1750
        if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
1751
            disas_ldst_reg_roffset(s, insn);
1752
        } else {
1753
            disas_ldst_reg_imm(s, insn);
1754
        }
1755
        break;
1756
    case 1:
1757
        disas_ldst_reg_unsigned_imm(s, insn);
1758
        break;
1759
    default:
1760
        unallocated_encoding(s);
1761
        break;
1762
    }
1763
}
1764

    
1765
/* AdvSIMD load/store multiple structures */
1766
static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
1767
{
1768
    unsupported_encoding(s, insn);
1769
}
1770

    
1771
/* AdvSIMD load/store single structure */
1772
static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
1773
{
1774
    unsupported_encoding(s, insn);
1775
}
1776

    
1777
/* C3.3 Loads and stores */
1778
static void disas_ldst(DisasContext *s, uint32_t insn)
1779
{
1780
    switch (extract32(insn, 24, 6)) {
1781
    case 0x08: /* Load/store exclusive */
1782
        disas_ldst_excl(s, insn);
1783
        break;
1784
    case 0x18: case 0x1c: /* Load register (literal) */
1785
        disas_ld_lit(s, insn);
1786
        break;
1787
    case 0x28: case 0x29:
1788
    case 0x2c: case 0x2d: /* Load/store pair (all forms) */
1789
        disas_ldst_pair(s, insn);
1790
        break;
1791
    case 0x38: case 0x39:
1792
    case 0x3c: case 0x3d: /* Load/store register (all forms) */
1793
        disas_ldst_reg(s, insn);
1794
        break;
1795
    case 0x0c: /* AdvSIMD load/store multiple structures */
1796
        disas_ldst_multiple_struct(s, insn);
1797
        break;
1798
    case 0x0d: /* AdvSIMD load/store single structure */
1799
        disas_ldst_single_struct(s, insn);
1800
        break;
1801
    default:
1802
        unallocated_encoding(s);
1803
        break;
1804
    }
1805
}
1806

    
1807
/* C3.4.6 PC-rel. addressing
1808
 *   31  30   29 28       24 23                5 4    0
1809
 * +----+-------+-----------+-------------------+------+
1810
 * | op | immlo | 1 0 0 0 0 |       immhi       |  Rd  |
1811
 * +----+-------+-----------+-------------------+------+
1812
 */
1813
static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
1814
{
1815
    unsigned int page, rd;
1816
    uint64_t base;
1817
    int64_t offset;
1818

    
1819
    page = extract32(insn, 31, 1);
1820
    /* SignExtend(immhi:immlo) -> offset */
1821
    offset = ((int64_t)sextract32(insn, 5, 19) << 2) | extract32(insn, 29, 2);
1822
    rd = extract32(insn, 0, 5);
1823
    base = s->pc - 4;
1824

    
1825
    if (page) {
1826
        /* ADRP (page based) */
1827
        base &= ~0xfff;
1828
        offset <<= 12;
1829
    }
1830

    
1831
    tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
1832
}
1833

    
1834
/*
1835
 * C3.4.1 Add/subtract (immediate)
1836
 *
1837
 *  31 30 29 28       24 23 22 21         10 9   5 4   0
1838
 * +--+--+--+-----------+-----+-------------+-----+-----+
1839
 * |sf|op| S| 1 0 0 0 1 |shift|    imm12    |  Rn | Rd  |
1840
 * +--+--+--+-----------+-----+-------------+-----+-----+
1841
 *
1842
 *    sf: 0 -> 32bit, 1 -> 64bit
1843
 *    op: 0 -> add  , 1 -> sub
1844
 *     S: 1 -> set flags
1845
 * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
1846
 */
1847
static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
1848
{
1849
    int rd = extract32(insn, 0, 5);
1850
    int rn = extract32(insn, 5, 5);
1851
    uint64_t imm = extract32(insn, 10, 12);
1852
    int shift = extract32(insn, 22, 2);
1853
    bool setflags = extract32(insn, 29, 1);
1854
    bool sub_op = extract32(insn, 30, 1);
1855
    bool is_64bit = extract32(insn, 31, 1);
1856

    
1857
    TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
1858
    TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
1859
    TCGv_i64 tcg_result;
1860

    
1861
    switch (shift) {
1862
    case 0x0:
1863
        break;
1864
    case 0x1:
1865
        imm <<= 12;
1866
        break;
1867
    default:
1868
        unallocated_encoding(s);
1869
        return;
1870
    }
1871

    
1872
    tcg_result = tcg_temp_new_i64();
1873
    if (!setflags) {
1874
        if (sub_op) {
1875
            tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
1876
        } else {
1877
            tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
1878
        }
1879
    } else {
1880
        TCGv_i64 tcg_imm = tcg_const_i64(imm);
1881
        if (sub_op) {
1882
            gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
1883
        } else {
1884
            gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
1885
        }
1886
        tcg_temp_free_i64(tcg_imm);
1887
    }
1888

    
1889
    if (is_64bit) {
1890
        tcg_gen_mov_i64(tcg_rd, tcg_result);
1891
    } else {
1892
        tcg_gen_ext32u_i64(tcg_rd, tcg_result);
1893
    }
1894

    
1895
    tcg_temp_free_i64(tcg_result);
1896
}
1897

    
1898
/* The input should be a value in the bottom e bits (with higher
1899
 * bits zero); returns that value replicated into every element
1900
 * of size e in a 64 bit integer.
1901
 */
1902
static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
1903
{
1904
    assert(e != 0);
1905
    while (e < 64) {
1906
        mask |= mask << e;
1907
        e *= 2;
1908
    }
1909
    return mask;
1910
}
1911

    
1912
/* Return a value with the bottom len bits set (where 0 < len <= 64) */
1913
static inline uint64_t bitmask64(unsigned int length)
1914
{
1915
    assert(length > 0 && length <= 64);
1916
    return ~0ULL >> (64 - length);
1917
}
1918

    
1919
/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
1920
 * only require the wmask. Returns false if the imms/immr/immn are a reserved
1921
 * value (ie should cause a guest UNDEF exception), and true if they are
1922
 * valid, in which case the decoded bit pattern is written to result.
1923
 */
1924
static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
1925
                                   unsigned int imms, unsigned int immr)
1926
{
1927
    uint64_t mask;
1928
    unsigned e, levels, s, r;
1929
    int len;
1930

    
1931
    assert(immn < 2 && imms < 64 && immr < 64);
1932

    
1933
    /* The bit patterns we create here are 64 bit patterns which
1934
     * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
1935
     * 64 bits each. Each element contains the same value: a run
1936
     * of between 1 and e-1 non-zero bits, rotated within the
1937
     * element by between 0 and e-1 bits.
1938
     *
1939
     * The element size and run length are encoded into immn (1 bit)
1940
     * and imms (6 bits) as follows:
1941
     * 64 bit elements: immn = 1, imms = <length of run - 1>
1942
     * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
1943
     * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
1944
     *  8 bit elements: immn = 0, imms = 110 : <length of run - 1>
1945
     *  4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
1946
     *  2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
1947
     * Notice that immn = 0, imms = 11111x is the only combination
1948
     * not covered by one of the above options; this is reserved.
1949
     * Further, <length of run - 1> all-ones is a reserved pattern.
1950
     *
1951
     * In all cases the rotation is by immr % e (and immr is 6 bits).
1952
     */
1953

    
1954
    /* First determine the element size */
1955
    len = 31 - clz32((immn << 6) | (~imms & 0x3f));
1956
    if (len < 1) {
1957
        /* This is the immn == 0, imms == 0x11111x case */
1958
        return false;
1959
    }
1960
    e = 1 << len;
1961

    
1962
    levels = e - 1;
1963
    s = imms & levels;
1964
    r = immr & levels;
1965

    
1966
    if (s == levels) {
1967
        /* <length of run - 1> mustn't be all-ones. */
1968
        return false;
1969
    }
1970

    
1971
    /* Create the value of one element: s+1 set bits rotated
1972
     * by r within the element (which is e bits wide)...
1973
     */
1974
    mask = bitmask64(s + 1);
1975
    mask = (mask >> r) | (mask << (e - r));
1976
    /* ...then replicate the element over the whole 64 bit value */
1977
    mask = bitfield_replicate(mask, e);
1978
    *result = mask;
1979
    return true;
1980
}
1981

    
1982
/* C3.4.4 Logical (immediate)
1983
 *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
1984
 * +----+-----+-------------+---+------+------+------+------+
1985
 * | sf | opc | 1 0 0 1 0 0 | N | immr | imms |  Rn  |  Rd  |
1986
 * +----+-----+-------------+---+------+------+------+------+
1987
 */
1988
static void disas_logic_imm(DisasContext *s, uint32_t insn)
1989
{
1990
    unsigned int sf, opc, is_n, immr, imms, rn, rd;
1991
    TCGv_i64 tcg_rd, tcg_rn;
1992
    uint64_t wmask;
1993
    bool is_and = false;
1994

    
1995
    sf = extract32(insn, 31, 1);
1996
    opc = extract32(insn, 29, 2);
1997
    is_n = extract32(insn, 22, 1);
1998
    immr = extract32(insn, 16, 6);
1999
    imms = extract32(insn, 10, 6);
2000
    rn = extract32(insn, 5, 5);
2001
    rd = extract32(insn, 0, 5);
2002

    
2003
    if (!sf && is_n) {
2004
        unallocated_encoding(s);
2005
        return;
2006
    }
2007

    
2008
    if (opc == 0x3) { /* ANDS */
2009
        tcg_rd = cpu_reg(s, rd);
2010
    } else {
2011
        tcg_rd = cpu_reg_sp(s, rd);
2012
    }
2013
    tcg_rn = cpu_reg(s, rn);
2014

    
2015
    if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
2016
        /* some immediate field values are reserved */
2017
        unallocated_encoding(s);
2018
        return;
2019
    }
2020

    
2021
    if (!sf) {
2022
        wmask &= 0xffffffff;
2023
    }
2024

    
2025
    switch (opc) {
2026
    case 0x3: /* ANDS */
2027
    case 0x0: /* AND */
2028
        tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
2029
        is_and = true;
2030
        break;
2031
    case 0x1: /* ORR */
2032
        tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
2033
        break;
2034
    case 0x2: /* EOR */
2035
        tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
2036
        break;
2037
    default:
2038
        assert(FALSE); /* must handle all above */
2039
        break;
2040
    }
2041

    
2042
    if (!sf && !is_and) {
2043
        /* zero extend final result; we know we can skip this for AND
2044
         * since the immediate had the high 32 bits clear.
2045
         */
2046
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2047
    }
2048

    
2049
    if (opc == 3) { /* ANDS */
2050
        gen_logic_CC(sf, tcg_rd);
2051
    }
2052
}
2053

    
2054
/*
2055
 * C3.4.5 Move wide (immediate)
2056
 *
2057
 *  31 30 29 28         23 22 21 20             5 4    0
2058
 * +--+-----+-------------+-----+----------------+------+
2059
 * |sf| opc | 1 0 0 1 0 1 |  hw |  imm16         |  Rd  |
2060
 * +--+-----+-------------+-----+----------------+------+
2061
 *
2062
 * sf: 0 -> 32 bit, 1 -> 64 bit
2063
 * opc: 00 -> N, 10 -> Z, 11 -> K
2064
 * hw: shift/16 (0,16, and sf only 32, 48)
2065
 */
2066
static void disas_movw_imm(DisasContext *s, uint32_t insn)
2067
{
2068
    int rd = extract32(insn, 0, 5);
2069
    uint64_t imm = extract32(insn, 5, 16);
2070
    int sf = extract32(insn, 31, 1);
2071
    int opc = extract32(insn, 29, 2);
2072
    int pos = extract32(insn, 21, 2) << 4;
2073
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
2074
    TCGv_i64 tcg_imm;
2075

    
2076
    if (!sf && (pos >= 32)) {
2077
        unallocated_encoding(s);
2078
        return;
2079
    }
2080

    
2081
    switch (opc) {
2082
    case 0: /* MOVN */
2083
    case 2: /* MOVZ */
2084
        imm <<= pos;
2085
        if (opc == 0) {
2086
            imm = ~imm;
2087
        }
2088
        if (!sf) {
2089
            imm &= 0xffffffffu;
2090
        }
2091
        tcg_gen_movi_i64(tcg_rd, imm);
2092
        break;
2093
    case 3: /* MOVK */
2094
        tcg_imm = tcg_const_i64(imm);
2095
        tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
2096
        tcg_temp_free_i64(tcg_imm);
2097
        if (!sf) {
2098
            tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2099
        }
2100
        break;
2101
    default:
2102
        unallocated_encoding(s);
2103
        break;
2104
    }
2105
}
2106

    
2107
/* C3.4.2 Bitfield
2108
 *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
2109
 * +----+-----+-------------+---+------+------+------+------+
2110
 * | sf | opc | 1 0 0 1 1 0 | N | immr | imms |  Rn  |  Rd  |
2111
 * +----+-----+-------------+---+------+------+------+------+
2112
 */
2113
static void disas_bitfield(DisasContext *s, uint32_t insn)
2114
{
2115
    unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
2116
    TCGv_i64 tcg_rd, tcg_tmp;
2117

    
2118
    sf = extract32(insn, 31, 1);
2119
    opc = extract32(insn, 29, 2);
2120
    n = extract32(insn, 22, 1);
2121
    ri = extract32(insn, 16, 6);
2122
    si = extract32(insn, 10, 6);
2123
    rn = extract32(insn, 5, 5);
2124
    rd = extract32(insn, 0, 5);
2125
    bitsize = sf ? 64 : 32;
2126

    
2127
    if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
2128
        unallocated_encoding(s);
2129
        return;
2130
    }
2131

    
2132
    tcg_rd = cpu_reg(s, rd);
2133
    tcg_tmp = read_cpu_reg(s, rn, sf);
2134

    
2135
    /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
2136

    
2137
    if (opc != 1) { /* SBFM or UBFM */
2138
        tcg_gen_movi_i64(tcg_rd, 0);
2139
    }
2140

    
2141
    /* do the bit move operation */
2142
    if (si >= ri) {
2143
        /* Wd<s-r:0> = Wn<s:r> */
2144
        tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
2145
        pos = 0;
2146
        len = (si - ri) + 1;
2147
    } else {
2148
        /* Wd<32+s-r,32-r> = Wn<s:0> */
2149
        pos = bitsize - ri;
2150
        len = si + 1;
2151
    }
2152

    
2153
    tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
2154

    
2155
    if (opc == 0) { /* SBFM - sign extend the destination field */
2156
        tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2157
        tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2158
    }
2159

    
2160
    if (!sf) { /* zero extend final result */
2161
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2162
    }
2163
}
2164

    
2165
/* C3.4.3 Extract
2166
 *   31  30  29 28         23 22   21  20  16 15    10 9    5 4    0
2167
 * +----+------+-------------+---+----+------+--------+------+------+
2168
 * | sf | op21 | 1 0 0 1 1 1 | N | o0 |  Rm  |  imms  |  Rn  |  Rd  |
2169
 * +----+------+-------------+---+----+------+--------+------+------+
2170
 */
2171
static void disas_extract(DisasContext *s, uint32_t insn)
2172
{
2173
    unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
2174

    
2175
    sf = extract32(insn, 31, 1);
2176
    n = extract32(insn, 22, 1);
2177
    rm = extract32(insn, 16, 5);
2178
    imm = extract32(insn, 10, 6);
2179
    rn = extract32(insn, 5, 5);
2180
    rd = extract32(insn, 0, 5);
2181
    op21 = extract32(insn, 29, 2);
2182
    op0 = extract32(insn, 21, 1);
2183
    bitsize = sf ? 64 : 32;
2184

    
2185
    if (sf != n || op21 || op0 || imm >= bitsize) {
2186
        unallocated_encoding(s);
2187
    } else {
2188
        TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
2189

    
2190
        tcg_rd = cpu_reg(s, rd);
2191

    
2192
        if (imm) {
2193
            /* OPTME: we can special case rm==rn as a rotate */
2194
            tcg_rm = read_cpu_reg(s, rm, sf);
2195
            tcg_rn = read_cpu_reg(s, rn, sf);
2196
            tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
2197
            tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
2198
            tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
2199
            if (!sf) {
2200
                tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2201
            }
2202
        } else {
2203
            /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
2204
             * so an extract from bit 0 is a special case.
2205
             */
2206
            if (sf) {
2207
                tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
2208
            } else {
2209
                tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
2210
            }
2211
        }
2212

    
2213
    }
2214
}
2215

    
2216
/* C3.4 Data processing - immediate */
2217
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
2218
{
2219
    switch (extract32(insn, 23, 6)) {
2220
    case 0x20: case 0x21: /* PC-rel. addressing */
2221
        disas_pc_rel_adr(s, insn);
2222
        break;
2223
    case 0x22: case 0x23: /* Add/subtract (immediate) */
2224
        disas_add_sub_imm(s, insn);
2225
        break;
2226
    case 0x24: /* Logical (immediate) */
2227
        disas_logic_imm(s, insn);
2228
        break;
2229
    case 0x25: /* Move wide (immediate) */
2230
        disas_movw_imm(s, insn);
2231
        break;
2232
    case 0x26: /* Bitfield */
2233
        disas_bitfield(s, insn);
2234
        break;
2235
    case 0x27: /* Extract */
2236
        disas_extract(s, insn);
2237
        break;
2238
    default:
2239
        unallocated_encoding(s);
2240
        break;
2241
    }
2242
}
2243

    
2244
/* Shift a TCGv src by TCGv shift_amount, put result in dst.
2245
 * Note that it is the caller's responsibility to ensure that the
2246
 * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
2247
 * mandated semantics for out of range shifts.
2248
 */
2249
static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
2250
                      enum a64_shift_type shift_type, TCGv_i64 shift_amount)
2251
{
2252
    switch (shift_type) {
2253
    case A64_SHIFT_TYPE_LSL:
2254
        tcg_gen_shl_i64(dst, src, shift_amount);
2255
        break;
2256
    case A64_SHIFT_TYPE_LSR:
2257
        tcg_gen_shr_i64(dst, src, shift_amount);
2258
        break;
2259
    case A64_SHIFT_TYPE_ASR:
2260
        if (!sf) {
2261
            tcg_gen_ext32s_i64(dst, src);
2262
        }
2263
        tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
2264
        break;
2265
    case A64_SHIFT_TYPE_ROR:
2266
        if (sf) {
2267
            tcg_gen_rotr_i64(dst, src, shift_amount);
2268
        } else {
2269
            TCGv_i32 t0, t1;
2270
            t0 = tcg_temp_new_i32();
2271
            t1 = tcg_temp_new_i32();
2272
            tcg_gen_trunc_i64_i32(t0, src);
2273
            tcg_gen_trunc_i64_i32(t1, shift_amount);
2274
            tcg_gen_rotr_i32(t0, t0, t1);
2275
            tcg_gen_extu_i32_i64(dst, t0);
2276
            tcg_temp_free_i32(t0);
2277
            tcg_temp_free_i32(t1);
2278
        }
2279
        break;
2280
    default:
2281
        assert(FALSE); /* all shift types should be handled */
2282
        break;
2283
    }
2284

    
2285
    if (!sf) { /* zero extend final result */
2286
        tcg_gen_ext32u_i64(dst, dst);
2287
    }
2288
}
2289

    
2290
/* Shift a TCGv src by immediate, put result in dst.
2291
 * The shift amount must be in range (this should always be true as the
2292
 * relevant instructions will UNDEF on bad shift immediates).
2293
 */
2294
static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
2295
                          enum a64_shift_type shift_type, unsigned int shift_i)
2296
{
2297
    assert(shift_i < (sf ? 64 : 32));
2298

    
2299
    if (shift_i == 0) {
2300
        tcg_gen_mov_i64(dst, src);
2301
    } else {
2302
        TCGv_i64 shift_const;
2303

    
2304
        shift_const = tcg_const_i64(shift_i);
2305
        shift_reg(dst, src, sf, shift_type, shift_const);
2306
        tcg_temp_free_i64(shift_const);
2307
    }
2308
}
2309

    
2310
/* C3.5.10 Logical (shifted register)
2311
 *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
2312
 * +----+-----+-----------+-------+---+------+--------+------+------+
2313
 * | sf | opc | 0 1 0 1 0 | shift | N |  Rm  |  imm6  |  Rn  |  Rd  |
2314
 * +----+-----+-----------+-------+---+------+--------+------+------+
2315
 */
2316
static void disas_logic_reg(DisasContext *s, uint32_t insn)
2317
{
2318
    TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
2319
    unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;
2320

    
2321
    sf = extract32(insn, 31, 1);
2322
    opc = extract32(insn, 29, 2);
2323
    shift_type = extract32(insn, 22, 2);
2324
    invert = extract32(insn, 21, 1);
2325
    rm = extract32(insn, 16, 5);
2326
    shift_amount = extract32(insn, 10, 6);
2327
    rn = extract32(insn, 5, 5);
2328
    rd = extract32(insn, 0, 5);
2329

    
2330
    if (!sf && (shift_amount & (1 << 5))) {
2331
        unallocated_encoding(s);
2332
        return;
2333
    }
2334

    
2335
    tcg_rd = cpu_reg(s, rd);
2336

    
2337
    if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
2338
        /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
2339
         * register-register MOV and MVN, so it is worth special casing.
2340
         */
2341
        tcg_rm = cpu_reg(s, rm);
2342
        if (invert) {
2343
            tcg_gen_not_i64(tcg_rd, tcg_rm);
2344
            if (!sf) {
2345
                tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2346
            }
2347
        } else {
2348
            if (sf) {
2349
                tcg_gen_mov_i64(tcg_rd, tcg_rm);
2350
            } else {
2351
                tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
2352
            }
2353
        }
2354
        return;
2355
    }
2356

    
2357
    tcg_rm = read_cpu_reg(s, rm, sf);
2358

    
2359
    if (shift_amount) {
2360
        shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
2361
    }
2362

    
2363
    tcg_rn = cpu_reg(s, rn);
2364

    
2365
    switch (opc | (invert << 2)) {
2366
    case 0: /* AND */
2367
    case 3: /* ANDS */
2368
        tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
2369
        break;
2370
    case 1: /* ORR */
2371
        tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
2372
        break;
2373
    case 2: /* EOR */
2374
        tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
2375
        break;
2376
    case 4: /* BIC */
2377
    case 7: /* BICS */
2378
        tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
2379
        break;
2380
    case 5: /* ORN */
2381
        tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm);
2382
        break;
2383
    case 6: /* EON */
2384
        tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm);
2385
        break;
2386
    default:
2387
        assert(FALSE);
2388
        break;
2389
    }
2390

    
2391
    if (!sf) {
2392
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2393
    }
2394

    
2395
    if (opc == 3) {
2396
        gen_logic_CC(sf, tcg_rd);
2397
    }
2398
}
2399

    
2400
/*
2401
 * C3.5.1 Add/subtract (extended register)
2402
 *
2403
 *  31|30|29|28       24|23 22|21|20   16|15  13|12  10|9  5|4  0|
2404
 * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2405
 * |sf|op| S| 0 1 0 1 1 | opt | 1|  Rm   |option| imm3 | Rn | Rd |
2406
 * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2407
 *
2408
 *  sf: 0 -> 32bit, 1 -> 64bit
2409
 *  op: 0 -> add  , 1 -> sub
2410
 *   S: 1 -> set flags
2411
 * opt: 00
2412
 * option: extension type (see DecodeRegExtend)
2413
 * imm3: optional shift to Rm
2414
 *
2415
 * Rd = Rn + LSL(extend(Rm), amount)
2416
 */
2417
static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
2418
{
2419
    int rd = extract32(insn, 0, 5);
2420
    int rn = extract32(insn, 5, 5);
2421
    int imm3 = extract32(insn, 10, 3);
2422
    int option = extract32(insn, 13, 3);
2423
    int rm = extract32(insn, 16, 5);
2424
    bool setflags = extract32(insn, 29, 1);
2425
    bool sub_op = extract32(insn, 30, 1);
2426
    bool sf = extract32(insn, 31, 1);
2427

    
2428
    TCGv_i64 tcg_rm, tcg_rn; /* temps */
2429
    TCGv_i64 tcg_rd;
2430
    TCGv_i64 tcg_result;
2431

    
2432
    if (imm3 > 4) {
2433
        unallocated_encoding(s);
2434
        return;
2435
    }
2436

    
2437
    /* non-flag setting ops may use SP */
2438
    if (!setflags) {
2439
        tcg_rn = read_cpu_reg_sp(s, rn, sf);
2440
        tcg_rd = cpu_reg_sp(s, rd);
2441
    } else {
2442
        tcg_rn = read_cpu_reg(s, rn, sf);
2443
        tcg_rd = cpu_reg(s, rd);
2444
    }
2445

    
2446
    tcg_rm = read_cpu_reg(s, rm, sf);
2447
    ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3);
2448

    
2449
    tcg_result = tcg_temp_new_i64();
2450

    
2451
    if (!setflags) {
2452
        if (sub_op) {
2453
            tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
2454
        } else {
2455
            tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
2456
        }
2457
    } else {
2458
        if (sub_op) {
2459
            gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
2460
        } else {
2461
            gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
2462
        }
2463
    }
2464

    
2465
    if (sf) {
2466
        tcg_gen_mov_i64(tcg_rd, tcg_result);
2467
    } else {
2468
        tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2469
    }
2470

    
2471
    tcg_temp_free_i64(tcg_result);
2472
}
2473

    
2474
/*
2475
 * C3.5.2 Add/subtract (shifted register)
2476
 *
2477
 *  31 30 29 28       24 23 22 21 20   16 15     10 9    5 4    0
2478
 * +--+--+--+-----------+-----+--+-------+---------+------+------+
2479
 * |sf|op| S| 0 1 0 1 1 |shift| 0|  Rm   |  imm6   |  Rn  |  Rd  |
2480
 * +--+--+--+-----------+-----+--+-------+---------+------+------+
2481
 *
2482
 *    sf: 0 -> 32bit, 1 -> 64bit
2483
 *    op: 0 -> add  , 1 -> sub
2484
 *     S: 1 -> set flags
2485
 * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED
2486
 *  imm6: Shift amount to apply to Rm before the add/sub
2487
 */
2488
static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
2489
{
2490
    int rd = extract32(insn, 0, 5);
2491
    int rn = extract32(insn, 5, 5);
2492
    int imm6 = extract32(insn, 10, 6);
2493
    int rm = extract32(insn, 16, 5);
2494
    int shift_type = extract32(insn, 22, 2);
2495
    bool setflags = extract32(insn, 29, 1);
2496
    bool sub_op = extract32(insn, 30, 1);
2497
    bool sf = extract32(insn, 31, 1);
2498

    
2499
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
2500
    TCGv_i64 tcg_rn, tcg_rm;
2501
    TCGv_i64 tcg_result;
2502

    
2503
    if ((shift_type == 3) || (!sf && (imm6 > 31))) {
2504
        unallocated_encoding(s);
2505
        return;
2506
    }
2507

    
2508
    tcg_rn = read_cpu_reg(s, rn, sf);
2509
    tcg_rm = read_cpu_reg(s, rm, sf);
2510

    
2511
    shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6);
2512

    
2513
    tcg_result = tcg_temp_new_i64();
2514

    
2515
    if (!setflags) {
2516
        if (sub_op) {
2517
            tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
2518
        } else {
2519
            tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
2520
        }
2521
    } else {
2522
        if (sub_op) {
2523
            gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
2524
        } else {
2525
            gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
2526
        }
2527
    }
2528

    
2529
    if (sf) {
2530
        tcg_gen_mov_i64(tcg_rd, tcg_result);
2531
    } else {
2532
        tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2533
    }
2534

    
2535
    tcg_temp_free_i64(tcg_result);
2536
}
2537

    
2538
/* C3.5.9 Data-processing (3 source)
2539

2540
   31 30  29 28       24 23 21  20  16  15  14  10 9    5 4    0
2541
  +--+------+-----------+------+------+----+------+------+------+
2542
  |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
2543
  +--+------+-----------+------+------+----+------+------+------+
2544

2545
 */
2546
static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
2547
{
2548
    int rd = extract32(insn, 0, 5);
2549
    int rn = extract32(insn, 5, 5);
2550
    int ra = extract32(insn, 10, 5);
2551
    int rm = extract32(insn, 16, 5);
2552
    int op_id = (extract32(insn, 29, 3) << 4) |
2553
        (extract32(insn, 21, 3) << 1) |
2554
        extract32(insn, 15, 1);
2555
    bool sf = extract32(insn, 31, 1);
2556
    bool is_sub = extract32(op_id, 0, 1);
2557
    bool is_high = extract32(op_id, 2, 1);
2558
    bool is_signed = false;
2559
    TCGv_i64 tcg_op1;
2560
    TCGv_i64 tcg_op2;
2561
    TCGv_i64 tcg_tmp;
2562

    
2563
    /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
2564
    switch (op_id) {
2565
    case 0x42: /* SMADDL */
2566
    case 0x43: /* SMSUBL */
2567
    case 0x44: /* SMULH */
2568
        is_signed = true;
2569
        break;
2570
    case 0x0: /* MADD (32bit) */
2571
    case 0x1: /* MSUB (32bit) */
2572
    case 0x40: /* MADD (64bit) */
2573
    case 0x41: /* MSUB (64bit) */
2574
    case 0x4a: /* UMADDL */
2575
    case 0x4b: /* UMSUBL */
2576
    case 0x4c: /* UMULH */
2577
        break;
2578
    default:
2579
        unallocated_encoding(s);
2580
        return;
2581
    }
2582

    
2583
    if (is_high) {
2584
        TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
2585
        TCGv_i64 tcg_rd = cpu_reg(s, rd);
2586
        TCGv_i64 tcg_rn = cpu_reg(s, rn);
2587
        TCGv_i64 tcg_rm = cpu_reg(s, rm);
2588

    
2589
        if (is_signed) {
2590
            tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
2591
        } else {
2592
            tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
2593
        }
2594

    
2595
        tcg_temp_free_i64(low_bits);
2596
        return;
2597
    }
2598

    
2599
    tcg_op1 = tcg_temp_new_i64();
2600
    tcg_op2 = tcg_temp_new_i64();
2601
    tcg_tmp = tcg_temp_new_i64();
2602

    
2603
    if (op_id < 0x42) {
2604
        tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
2605
        tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
2606
    } else {
2607
        if (is_signed) {
2608
            tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
2609
            tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
2610
        } else {
2611
            tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
2612
            tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
2613
        }
2614
    }
2615

    
2616
    if (ra == 31 && !is_sub) {
2617
        /* Special-case MADD with rA == XZR; it is the standard MUL alias */
2618
        tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
2619
    } else {
2620
        tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
2621
        if (is_sub) {
2622
            tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
2623
        } else {
2624
            tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
2625
        }
2626
    }
2627

    
2628
    if (!sf) {
2629
        tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
2630
    }
2631

    
2632
    tcg_temp_free_i64(tcg_op1);
2633
    tcg_temp_free_i64(tcg_op2);
2634
    tcg_temp_free_i64(tcg_tmp);
2635
}
2636

    
2637
/* C3.5.3 - Add/subtract (with carry)
2638
 *  31 30 29 28 27 26 25 24 23 22 21  20  16  15   10  9    5 4   0
2639
 * +--+--+--+------------------------+------+---------+------+-----+
2640
 * |sf|op| S| 1  1  0  1  0  0  0  0 |  rm  | opcode2 |  Rn  |  Rd |
2641
 * +--+--+--+------------------------+------+---------+------+-----+
2642
 *                                            [000000]
2643
 */
2644

    
2645
static void disas_adc_sbc(DisasContext *s, uint32_t insn)
2646
{
2647
    unsigned int sf, op, setflags, rm, rn, rd;
2648
    TCGv_i64 tcg_y, tcg_rn, tcg_rd;
2649

    
2650
    if (extract32(insn, 10, 6) != 0) {
2651
        unallocated_encoding(s);
2652
        return;
2653
    }
2654

    
2655
    sf = extract32(insn, 31, 1);
2656
    op = extract32(insn, 30, 1);
2657
    setflags = extract32(insn, 29, 1);
2658
    rm = extract32(insn, 16, 5);
2659
    rn = extract32(insn, 5, 5);
2660
    rd = extract32(insn, 0, 5);
2661

    
2662
    tcg_rd = cpu_reg(s, rd);
2663
    tcg_rn = cpu_reg(s, rn);
2664

    
2665
    if (op) {
2666
        tcg_y = new_tmp_a64(s);
2667
        tcg_gen_not_i64(tcg_y, cpu_reg(s, rm));
2668
    } else {
2669
        tcg_y = cpu_reg(s, rm);
2670
    }
2671

    
2672
    if (setflags) {
2673
        gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y);
2674
    } else {
2675
        gen_adc(sf, tcg_rd, tcg_rn, tcg_y);
2676
    }
2677
}
2678

    
2679
/* C3.5.4 - C3.5.5 Conditional compare (immediate / register)
2680
 *  31 30 29 28 27 26 25 24 23 22 21  20    16 15  12  11  10  9   5  4 3   0
2681
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
2682
 * |sf|op| S| 1  1  0  1  0  0  1  0 |imm5/rm | cond |i/r |o2|  Rn  |o3|nzcv |
2683
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
2684
 *        [1]                             y                [0]       [0]
2685
 */
2686
static void disas_cc(DisasContext *s, uint32_t insn)
2687
{
2688
    unsigned int sf, op, y, cond, rn, nzcv, is_imm;
2689
    int label_continue = -1;
2690
    TCGv_i64 tcg_tmp, tcg_y, tcg_rn;
2691

    
2692
    if (!extract32(insn, 29, 1)) {
2693
        unallocated_encoding(s);
2694
        return;
2695
    }
2696
    if (insn & (1 << 10 | 1 << 4)) {
2697
        unallocated_encoding(s);
2698
        return;
2699
    }
2700
    sf = extract32(insn, 31, 1);
2701
    op = extract32(insn, 30, 1);
2702
    is_imm = extract32(insn, 11, 1);
2703
    y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */
2704
    cond = extract32(insn, 12, 4);
2705
    rn = extract32(insn, 5, 5);
2706
    nzcv = extract32(insn, 0, 4);
2707

    
2708
    if (cond < 0x0e) { /* not always */
2709
        int label_match = gen_new_label();
2710
        label_continue = gen_new_label();
2711
        arm_gen_test_cc(cond, label_match);
2712
        /* nomatch: */
2713
        tcg_tmp = tcg_temp_new_i64();
2714
        tcg_gen_movi_i64(tcg_tmp, nzcv << 28);
2715
        gen_set_nzcv(tcg_tmp);
2716
        tcg_temp_free_i64(tcg_tmp);
2717
        tcg_gen_br(label_continue);
2718
        gen_set_label(label_match);
2719
    }
2720
    /* match, or condition is always */
2721
    if (is_imm) {
2722
        tcg_y = new_tmp_a64(s);
2723
        tcg_gen_movi_i64(tcg_y, y);
2724
    } else {
2725
        tcg_y = cpu_reg(s, y);
2726
    }
2727
    tcg_rn = cpu_reg(s, rn);
2728

    
2729
    tcg_tmp = tcg_temp_new_i64();
2730
    if (op) {
2731
        gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y);
2732
    } else {
2733
        gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y);
2734
    }
2735
    tcg_temp_free_i64(tcg_tmp);
2736

    
2737
    if (cond < 0x0e) { /* continue */
2738
        gen_set_label(label_continue);
2739
    }
2740
}
2741

    
2742
/* C3.5.6 Conditional select
2743
 *   31   30  29  28             21 20  16 15  12 11 10 9    5 4    0
2744
 * +----+----+---+-----------------+------+------+-----+------+------+
2745
 * | sf | op | S | 1 1 0 1 0 1 0 0 |  Rm  | cond | op2 |  Rn  |  Rd  |
2746
 * +----+----+---+-----------------+------+------+-----+------+------+
2747
 */
2748
static void disas_cond_select(DisasContext *s, uint32_t insn)
2749
{
2750
    unsigned int sf, else_inv, rm, cond, else_inc, rn, rd;
2751
    TCGv_i64 tcg_rd, tcg_src;
2752

    
2753
    if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) {
2754
        /* S == 1 or op2<1> == 1 */
2755
        unallocated_encoding(s);
2756
        return;
2757
    }
2758
    sf = extract32(insn, 31, 1);
2759
    else_inv = extract32(insn, 30, 1);
2760
    rm = extract32(insn, 16, 5);
2761
    cond = extract32(insn, 12, 4);
2762
    else_inc = extract32(insn, 10, 1);
2763
    rn = extract32(insn, 5, 5);
2764
    rd = extract32(insn, 0, 5);
2765

    
2766
    if (rd == 31) {
2767
        /* silly no-op write; until we use movcond we must special-case
2768
         * this to avoid a dead temporary across basic blocks.
2769
         */
2770
        return;
2771
    }
2772

    
2773
    tcg_rd = cpu_reg(s, rd);
2774

    
2775
    if (cond >= 0x0e) { /* condition "always" */
2776
        tcg_src = read_cpu_reg(s, rn, sf);
2777
        tcg_gen_mov_i64(tcg_rd, tcg_src);
2778
    } else {
2779
        /* OPTME: we could use movcond here, at the cost of duplicating
2780
         * a lot of the arm_gen_test_cc() logic.
2781
         */
2782
        int label_match = gen_new_label();
2783
        int label_continue = gen_new_label();
2784

    
2785
        arm_gen_test_cc(cond, label_match);
2786
        /* nomatch: */
2787
        tcg_src = cpu_reg(s, rm);
2788

    
2789
        if (else_inv && else_inc) {
2790
            tcg_gen_neg_i64(tcg_rd, tcg_src);
2791
        } else if (else_inv) {
2792
            tcg_gen_not_i64(tcg_rd, tcg_src);
2793
        } else if (else_inc) {
2794
            tcg_gen_addi_i64(tcg_rd, tcg_src, 1);
2795
        } else {
2796
            tcg_gen_mov_i64(tcg_rd, tcg_src);
2797
        }
2798
        if (!sf) {
2799
            tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2800
        }
2801
        tcg_gen_br(label_continue);
2802
        /* match: */
2803
        gen_set_label(label_match);
2804
        tcg_src = read_cpu_reg(s, rn, sf);
2805
        tcg_gen_mov_i64(tcg_rd, tcg_src);
2806
        /* continue: */
2807
        gen_set_label(label_continue);
2808
    }
2809
}
2810

    
2811
static void handle_clz(DisasContext *s, unsigned int sf,
2812
                       unsigned int rn, unsigned int rd)
2813
{
2814
    TCGv_i64 tcg_rd, tcg_rn;
2815
    tcg_rd = cpu_reg(s, rd);
2816
    tcg_rn = cpu_reg(s, rn);
2817

    
2818
    if (sf) {
2819
        gen_helper_clz64(tcg_rd, tcg_rn);
2820
    } else {
2821
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2822
        tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2823
        gen_helper_clz(tcg_tmp32, tcg_tmp32);
2824
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2825
        tcg_temp_free_i32(tcg_tmp32);
2826
    }
2827
}
2828

    
2829
static void handle_cls(DisasContext *s, unsigned int sf,
2830
                       unsigned int rn, unsigned int rd)
2831
{
2832
    TCGv_i64 tcg_rd, tcg_rn;
2833
    tcg_rd = cpu_reg(s, rd);
2834
    tcg_rn = cpu_reg(s, rn);
2835

    
2836
    if (sf) {
2837
        gen_helper_cls64(tcg_rd, tcg_rn);
2838
    } else {
2839
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2840
        tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2841
        gen_helper_cls32(tcg_tmp32, tcg_tmp32);
2842
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2843
        tcg_temp_free_i32(tcg_tmp32);
2844
    }
2845
}
2846

    
2847
static void handle_rbit(DisasContext *s, unsigned int sf,
2848
                        unsigned int rn, unsigned int rd)
2849
{
2850
    TCGv_i64 tcg_rd, tcg_rn;
2851
    tcg_rd = cpu_reg(s, rd);
2852
    tcg_rn = cpu_reg(s, rn);
2853

    
2854
    if (sf) {
2855
        gen_helper_rbit64(tcg_rd, tcg_rn);
2856
    } else {
2857
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2858
        tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2859
        gen_helper_rbit(tcg_tmp32, tcg_tmp32);
2860
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2861
        tcg_temp_free_i32(tcg_tmp32);
2862
    }
2863
}
2864

    
2865
/* C5.6.149 REV with sf==1, opcode==3 ("REV64") */
2866
static void handle_rev64(DisasContext *s, unsigned int sf,
2867
                         unsigned int rn, unsigned int rd)
2868
{
2869
    if (!sf) {
2870
        unallocated_encoding(s);
2871
        return;
2872
    }
2873
    tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
2874
}
2875

    
2876
/* C5.6.149 REV with sf==0, opcode==2
2877
 * C5.6.151 REV32 (sf==1, opcode==2)
2878
 */
2879
static void handle_rev32(DisasContext *s, unsigned int sf,
2880
                         unsigned int rn, unsigned int rd)
2881
{
2882
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
2883

    
2884
    if (sf) {
2885
        TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2886
        TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
2887

    
2888
        /* bswap32_i64 requires zero high word */
2889
        tcg_gen_ext32u_i64(tcg_tmp, tcg_rn);
2890
        tcg_gen_bswap32_i64(tcg_rd, tcg_tmp);
2891
        tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
2892
        tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp);
2893
        tcg_gen_concat32_i64(tcg_rd, tcg_rd, tcg_tmp);
2894

    
2895
        tcg_temp_free_i64(tcg_tmp);
2896
    } else {
2897
        tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rn));
2898
        tcg_gen_bswap32_i64(tcg_rd, tcg_rd);
2899
    }
2900
}
2901

    
2902
/* C5.6.150 REV16 (opcode==1) */
2903
static void handle_rev16(DisasContext *s, unsigned int sf,
2904
                         unsigned int rn, unsigned int rd)
2905
{
2906
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
2907
    TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2908
    TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
2909

    
2910
    tcg_gen_andi_i64(tcg_tmp, tcg_rn, 0xffff);
2911
    tcg_gen_bswap16_i64(tcg_rd, tcg_tmp);
2912

    
2913
    tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16);
2914
    tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
2915
    tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2916
    tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 16, 16);
2917

    
2918
    if (sf) {
2919
        tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
2920
        tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
2921
        tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2922
        tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 32, 16);
2923

    
2924
        tcg_gen_shri_i64(tcg_tmp, tcg_rn, 48);
2925
        tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2926
        tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 48, 16);
2927
    }
2928

    
2929
    tcg_temp_free_i64(tcg_tmp);
2930
}
2931

    
2932
/* C3.5.7 Data-processing (1 source)
2933
 *   31  30  29  28             21 20     16 15    10 9    5 4    0
2934
 * +----+---+---+-----------------+---------+--------+------+------+
2935
 * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode |  Rn  |  Rd  |
2936
 * +----+---+---+-----------------+---------+--------+------+------+
2937
 */
2938
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
2939
{
2940
    unsigned int sf, opcode, rn, rd;
2941

    
2942
    if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
2943
        unallocated_encoding(s);
2944
        return;
2945
    }
2946

    
2947
    sf = extract32(insn, 31, 1);
2948
    opcode = extract32(insn, 10, 6);
2949
    rn = extract32(insn, 5, 5);
2950
    rd = extract32(insn, 0, 5);
2951

    
2952
    switch (opcode) {
2953
    case 0: /* RBIT */
2954
        handle_rbit(s, sf, rn, rd);
2955
        break;
2956
    case 1: /* REV16 */
2957
        handle_rev16(s, sf, rn, rd);
2958
        break;
2959
    case 2: /* REV32 */
2960
        handle_rev32(s, sf, rn, rd);
2961
        break;
2962
    case 3: /* REV64 */
2963
        handle_rev64(s, sf, rn, rd);
2964
        break;
2965
    case 4: /* CLZ */
2966
        handle_clz(s, sf, rn, rd);
2967
        break;
2968
    case 5: /* CLS */
2969
        handle_cls(s, sf, rn, rd);
2970
        break;
2971
    }
2972
}
2973

    
2974
static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
2975
                       unsigned int rm, unsigned int rn, unsigned int rd)
2976
{
2977
    TCGv_i64 tcg_n, tcg_m, tcg_rd;
2978
    tcg_rd = cpu_reg(s, rd);
2979

    
2980
    if (!sf && is_signed) {
2981
        tcg_n = new_tmp_a64(s);
2982
        tcg_m = new_tmp_a64(s);
2983
        tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn));
2984
        tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm));
2985
    } else {
2986
        tcg_n = read_cpu_reg(s, rn, sf);
2987
        tcg_m = read_cpu_reg(s, rm, sf);
2988
    }
2989

    
2990
    if (is_signed) {
2991
        gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m);
2992
    } else {
2993
        gen_helper_udiv64(tcg_rd, tcg_n, tcg_m);
2994
    }
2995

    
2996
    if (!sf) { /* zero extend final result */
2997
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2998
    }
2999
}
3000

    
3001
/* C5.6.115 LSLV, C5.6.118 LSRV, C5.6.17 ASRV, C5.6.154 RORV */
3002
static void handle_shift_reg(DisasContext *s,
3003
                             enum a64_shift_type shift_type, unsigned int sf,
3004
                             unsigned int rm, unsigned int rn, unsigned int rd)
3005
{
3006
    TCGv_i64 tcg_shift = tcg_temp_new_i64();
3007
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
3008
    TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3009

    
3010
    tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31);
3011
    shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift);
3012
    tcg_temp_free_i64(tcg_shift);
3013
}
3014

    
3015
/* C3.5.8 Data-processing (2 source)
3016
 *   31   30  29 28             21 20  16 15    10 9    5 4    0
3017
 * +----+---+---+-----------------+------+--------+------+------+
3018
 * | sf | 0 | S | 1 1 0 1 0 1 1 0 |  Rm  | opcode |  Rn  |  Rd  |
3019
 * +----+---+---+-----------------+------+--------+------+------+
3020
 */
3021
static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
3022
{
3023
    unsigned int sf, rm, opcode, rn, rd;
3024
    sf = extract32(insn, 31, 1);
3025
    rm = extract32(insn, 16, 5);
3026
    opcode = extract32(insn, 10, 6);
3027
    rn = extract32(insn, 5, 5);
3028
    rd = extract32(insn, 0, 5);
3029

    
3030
    if (extract32(insn, 29, 1)) {
3031
        unallocated_encoding(s);
3032
        return;
3033
    }
3034

    
3035
    switch (opcode) {
3036
    case 2: /* UDIV */
3037
        handle_div(s, false, sf, rm, rn, rd);
3038
        break;
3039
    case 3: /* SDIV */
3040
        handle_div(s, true, sf, rm, rn, rd);
3041
        break;
3042
    case 8: /* LSLV */
3043
        handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
3044
        break;
3045
    case 9: /* LSRV */
3046
        handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd);
3047
        break;
3048
    case 10: /* ASRV */
3049
        handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd);
3050
        break;
3051
    case 11: /* RORV */
3052
        handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
3053
        break;
3054
    case 16:
3055
    case 17:
3056
    case 18:
3057
    case 19:
3058
    case 20:
3059
    case 21:
3060
    case 22:
3061
    case 23: /* CRC32 */
3062
        unsupported_encoding(s, insn);
3063
        break;
3064
    default:
3065
        unallocated_encoding(s);
3066
        break;
3067
    }
3068
}
3069

    
3070
/* C3.5 Data processing - register */
3071
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
3072
{
3073
    switch (extract32(insn, 24, 5)) {
3074
    case 0x0a: /* Logical (shifted register) */
3075
        disas_logic_reg(s, insn);
3076
        break;
3077
    case 0x0b: /* Add/subtract */
3078
        if (insn & (1 << 21)) { /* (extended register) */
3079
            disas_add_sub_ext_reg(s, insn);
3080
        } else {
3081
            disas_add_sub_reg(s, insn);
3082
        }
3083
        break;
3084
    case 0x1b: /* Data-processing (3 source) */
3085
        disas_data_proc_3src(s, insn);
3086
        break;
3087
    case 0x1a:
3088
        switch (extract32(insn, 21, 3)) {
3089
        case 0x0: /* Add/subtract (with carry) */
3090
            disas_adc_sbc(s, insn);
3091
            break;
3092
        case 0x2: /* Conditional compare */
3093
            disas_cc(s, insn); /* both imm and reg forms */
3094
            break;
3095
        case 0x4: /* Conditional select */
3096
            disas_cond_select(s, insn);
3097
            break;
3098
        case 0x6: /* Data-processing */
3099
            if (insn & (1 << 30)) { /* (1 source) */
3100
                disas_data_proc_1src(s, insn);
3101
            } else {            /* (2 source) */
3102
                disas_data_proc_2src(s, insn);
3103
            }
3104
            break;
3105
        default:
3106
            unallocated_encoding(s);
3107
            break;
3108
        }
3109
        break;
3110
    default:
3111
        unallocated_encoding(s);
3112
        break;
3113
    }
3114
}
3115

    
3116
/* C3.6.22 Floating point compare
3117
 *   31  30  29 28       24 23  22  21 20  16 15 14 13  10    9    5 4     0
3118
 * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
3119
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
3120
 * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
3121
 */
3122
static void disas_fp_compare(DisasContext *s, uint32_t insn)
3123
{
3124
    unsupported_encoding(s, insn);
3125
}
3126

    
3127
/* C3.6.23 Floating point conditional compare
3128
 *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5  4   3    0
3129
 * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
3130
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
3131
 * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
3132
 */
3133
static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
3134
{
3135
    unsupported_encoding(s, insn);
3136
}
3137

    
3138
/* C3.6.24 Floating point conditional select
3139
 *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5 4    0
3140
 * +---+---+---+-----------+------+---+------+------+-----+------+------+
3141
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
3142
 * +---+---+---+-----------+------+---+------+------+-----+------+------+
3143
 */
3144
static void disas_fp_csel(DisasContext *s, uint32_t insn)
3145
{
3146
    unsupported_encoding(s, insn);
3147
}
3148

    
3149
/* C3.6.25 Floating point data-processing (1 source)
3150
 *   31  30  29 28       24 23  22  21 20    15 14       10 9    5 4    0
3151
 * +---+---+---+-----------+------+---+--------+-----------+------+------+
3152
 * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
3153
 * +---+---+---+-----------+------+---+--------+-----------+------+------+
3154
 */
3155
static void disas_fp_1src(DisasContext *s, uint32_t insn)
3156
{
3157
    unsupported_encoding(s, insn);
3158
}
3159

    
3160
/* C3.6.26 Floating point data-processing (2 source)
3161
 *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
3162
 * +---+---+---+-----------+------+---+------+--------+-----+------+------+
3163
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | opcode | 1 0 |  Rn  |  Rd  |
3164
 * +---+---+---+-----------+------+---+------+--------+-----+------+------+
3165
 */
3166
static void disas_fp_2src(DisasContext *s, uint32_t insn)
3167
{
3168
    unsupported_encoding(s, insn);
3169
}
3170

    
3171
/* C3.6.27 Floating point data-processing (3 source)
3172
 *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
3173
 * +---+---+---+-----------+------+----+------+----+------+------+------+
3174
 * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
3175
 * +---+---+---+-----------+------+----+------+----+------+------+------+
3176
 */
3177
static void disas_fp_3src(DisasContext *s, uint32_t insn)
3178
{
3179
    unsupported_encoding(s, insn);
3180
}
3181

    
3182
/* C3.6.28 Floating point immediate
3183
 *   31  30  29 28       24 23  22  21 20        13 12   10 9    5 4    0
3184
 * +---+---+---+-----------+------+---+------------+-------+------+------+
3185
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |    imm8    | 1 0 0 | imm5 |  Rd  |
3186
 * +---+---+---+-----------+------+---+------------+-------+------+------+
3187
 */
3188
static void disas_fp_imm(DisasContext *s, uint32_t insn)
3189
{
3190
    unsupported_encoding(s, insn);
3191
}
3192

    
3193
/* C3.6.29 Floating point <-> fixed point conversions
3194
 *   31   30  29 28       24 23  22  21 20   19 18    16 15   10 9    5 4    0
3195
 * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
3196
 * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
3197
 * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
3198
 */
3199
static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
3200
{
3201
    unsupported_encoding(s, insn);
3202
}
3203

    
3204
static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
3205
{
3206
    /* FMOV: gpr to or from float, double, or top half of quad fp reg,
3207
     * without conversion.
3208
     */
3209

    
3210
    if (itof) {
3211
        int freg_offs = offsetof(CPUARMState, vfp.regs[rd * 2]);
3212
        TCGv_i64 tcg_rn = cpu_reg(s, rn);
3213

    
3214
        switch (type) {
3215
        case 0:
3216
        {
3217
            /* 32 bit */
3218
            TCGv_i64 tmp = tcg_temp_new_i64();
3219
            tcg_gen_ext32u_i64(tmp, tcg_rn);
3220
            tcg_gen_st_i64(tmp, cpu_env, freg_offs);
3221
            tcg_gen_movi_i64(tmp, 0);
3222
            tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
3223
            tcg_temp_free_i64(tmp);
3224
            break;
3225
        }
3226
        case 1:
3227
        {
3228
            /* 64 bit */
3229
            TCGv_i64 tmp = tcg_const_i64(0);
3230
            tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs);
3231
            tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
3232
            tcg_temp_free_i64(tmp);
3233
            break;
3234
        }
3235
        case 2:
3236
            /* 64 bit to top half. */
3237
            tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs + sizeof(float64));
3238
            break;
3239
        }
3240
    } else {
3241
        int freg_offs = offsetof(CPUARMState, vfp.regs[rn * 2]);
3242
        TCGv_i64 tcg_rd = cpu_reg(s, rd);
3243

    
3244
        switch (type) {
3245
        case 0:
3246
            /* 32 bit */
3247
            tcg_gen_ld32u_i64(tcg_rd, cpu_env, freg_offs);
3248
            break;
3249
        case 2:
3250
            /* 64 bits from top half */
3251
            freg_offs += sizeof(float64);
3252
            /* fall through */
3253
        case 1:
3254
            /* 64 bit */
3255
            tcg_gen_ld_i64(tcg_rd, cpu_env, freg_offs);
3256
            break;
3257
        }
3258
    }
3259
}
3260

    
3261
/* C3.6.30 Floating point <-> integer conversions
3262
 *   31   30  29 28       24 23  22  21 20   19 18 16 15         10 9  5 4  0
3263
 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
3264
 * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
3265
 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
3266
 */
3267
static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
3268
{
3269
    int rd = extract32(insn, 0, 5);
3270
    int rn = extract32(insn, 5, 5);
3271
    int opcode = extract32(insn, 16, 3);
3272
    int rmode = extract32(insn, 19, 2);
3273
    int type = extract32(insn, 22, 2);
3274
    bool sbit = extract32(insn, 29, 1);
3275
    bool sf = extract32(insn, 31, 1);
3276

    
3277
    if (!sbit && (rmode < 2) && (opcode > 5)) {
3278
        /* FMOV */
3279
        bool itof = opcode & 1;
3280

    
3281
        switch (sf << 3 | type << 1 | rmode) {
3282
        case 0x0: /* 32 bit */
3283
        case 0xa: /* 64 bit */
3284
        case 0xd: /* 64 bit to top half of quad */
3285
            break;
3286
        default:
3287
            /* all other sf/type/rmode combinations are invalid */
3288
            unallocated_encoding(s);
3289
            break;
3290
        }
3291

    
3292
        handle_fmov(s, rd, rn, type, itof);
3293
    } else {
3294
        /* actual FP conversions */
3295
        unsupported_encoding(s, insn);
3296
    }
3297
}
3298

    
3299
/* FP-specific subcases of table C3-6 (SIMD and FP data processing)
3300
 *   31  30  29 28     25 24                          0
3301
 * +---+---+---+---------+-----------------------------+
3302
 * |   | 0 |   | 1 1 1 1 |                             |
3303
 * +---+---+---+---------+-----------------------------+
3304
 */
3305
static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
3306
{
3307
    if (extract32(insn, 24, 1)) {
3308
        /* Floating point data-processing (3 source) */
3309
        disas_fp_3src(s, insn);
3310
    } else if (extract32(insn, 21, 1) == 0) {
3311
        /* Floating point to fixed point conversions */
3312
        disas_fp_fixed_conv(s, insn);
3313
    } else {
3314
        switch (extract32(insn, 10, 2)) {
3315
        case 1:
3316
            /* Floating point conditional compare */
3317
            disas_fp_ccomp(s, insn);
3318
            break;
3319
        case 2:
3320
            /* Floating point data-processing (2 source) */
3321
            disas_fp_2src(s, insn);
3322
            break;
3323
        case 3:
3324
            /* Floating point conditional select */
3325
            disas_fp_csel(s, insn);
3326
            break;
3327
        case 0:
3328
            switch (ctz32(extract32(insn, 12, 4))) {
3329
            case 0: /* [15:12] == xxx1 */
3330
                /* Floating point immediate */
3331
                disas_fp_imm(s, insn);
3332
                break;
3333
            case 1: /* [15:12] == xx10 */
3334
                /* Floating point compare */
3335
                disas_fp_compare(s, insn);
3336
                break;
3337
            case 2: /* [15:12] == x100 */
3338
                /* Floating point data-processing (1 source) */
3339
                disas_fp_1src(s, insn);
3340
                break;
3341
            case 3: /* [15:12] == 1000 */
3342
                unallocated_encoding(s);
3343
                break;
3344
            default: /* [15:12] == 0000 */
3345
                /* Floating point <-> integer conversions */
3346
                disas_fp_int_conv(s, insn);
3347
                break;
3348
            }
3349
            break;
3350
        }
3351
    }
3352
}
3353

    
3354
static void disas_data_proc_simd(DisasContext *s, uint32_t insn)
3355
{
3356
    /* Note that this is called with all non-FP cases from
3357
     * table C3-6 so it must UNDEF for entries not specifically
3358
     * allocated to instructions in that table.
3359
     */
3360
    unsupported_encoding(s, insn);
3361
}
3362

    
3363
/* C3.6 Data processing - SIMD and floating point */
3364
static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
3365
{
3366
    if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) {
3367
        disas_data_proc_fp(s, insn);
3368
    } else {
3369
        /* SIMD, including crypto */
3370
        disas_data_proc_simd(s, insn);
3371
    }
3372
}
3373

    
3374
/* C3.1 A64 instruction index by encoding */
3375
static void disas_a64_insn(CPUARMState *env, DisasContext *s)
3376
{
3377
    uint32_t insn;
3378

    
3379
    insn = arm_ldl_code(env, s->pc, s->bswap_code);
3380
    s->insn = insn;
3381
    s->pc += 4;
3382

    
3383
    switch (extract32(insn, 25, 4)) {
3384
    case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
3385
        unallocated_encoding(s);
3386
        break;
3387
    case 0x8: case 0x9: /* Data processing - immediate */
3388
        disas_data_proc_imm(s, insn);
3389
        break;
3390
    case 0xa: case 0xb: /* Branch, exception generation and system insns */
3391
        disas_b_exc_sys(s, insn);
3392
        break;
3393
    case 0x4:
3394
    case 0x6:
3395
    case 0xc:
3396
    case 0xe:      /* Loads and stores */
3397
        disas_ldst(s, insn);
3398
        break;
3399
    case 0x5:
3400
    case 0xd:      /* Data processing - register */
3401
        disas_data_proc_reg(s, insn);
3402
        break;
3403
    case 0x7:
3404
    case 0xf:      /* Data processing - SIMD and floating point */
3405
        disas_data_proc_simd_fp(s, insn);
3406
        break;
3407
    default:
3408
        assert(FALSE); /* all 15 cases should be handled above */
3409
        break;
3410
    }
3411

    
3412
    /* if we allocated any temporaries, free them here */
3413
    free_tmp_a64(s);
3414
}
3415

    
3416
void gen_intermediate_code_internal_a64(ARMCPU *cpu,
3417
                                        TranslationBlock *tb,
3418
                                        bool search_pc)
3419
{
3420
    CPUState *cs = CPU(cpu);
3421
    CPUARMState *env = &cpu->env;
3422
    DisasContext dc1, *dc = &dc1;
3423
    CPUBreakpoint *bp;
3424
    uint16_t *gen_opc_end;
3425
    int j, lj;
3426
    target_ulong pc_start;
3427
    target_ulong next_page_start;
3428
    int num_insns;
3429
    int max_insns;
3430

    
3431
    pc_start = tb->pc;
3432

    
3433
    dc->tb = tb;
3434

    
3435
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3436

    
3437
    dc->is_jmp = DISAS_NEXT;
3438
    dc->pc = pc_start;
3439
    dc->singlestep_enabled = cs->singlestep_enabled;
3440
    dc->condjmp = 0;
3441

    
3442
    dc->aarch64 = 1;
3443
    dc->thumb = 0;
3444
    dc->bswap_code = 0;
3445
    dc->condexec_mask = 0;
3446
    dc->condexec_cond = 0;
3447
#if !defined(CONFIG_USER_ONLY)
3448
    dc->user = 0;
3449
#endif
3450
    dc->vfp_enabled = 0;
3451
    dc->vec_len = 0;
3452
    dc->vec_stride = 0;
3453
    dc->cp_regs = cpu->cp_regs;
3454
    dc->current_pl = arm_current_pl(env);
3455

    
3456
    init_tmp_a64_array(dc);
3457

    
3458
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3459
    lj = -1;
3460
    num_insns = 0;
3461
    max_insns = tb->cflags & CF_COUNT_MASK;
3462
    if (max_insns == 0) {
3463
        max_insns = CF_COUNT_MASK;
3464
    }
3465

    
3466
    gen_tb_start();
3467

    
3468
    tcg_clear_temp_count();
3469

    
3470
    do {
3471
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3472
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3473
                if (bp->pc == dc->pc) {
3474
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
3475
                    /* Advance PC so that clearing the breakpoint will
3476
                       invalidate this TB.  */
3477
                    dc->pc += 2;
3478
                    goto done_generating;
3479
                }
3480
            }
3481
        }
3482

    
3483
        if (search_pc) {
3484
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3485
            if (lj < j) {
3486
                lj++;
3487
                while (lj < j) {
3488
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
3489
                }
3490
            }
3491
            tcg_ctx.gen_opc_pc[lj] = dc->pc;
3492
            tcg_ctx.gen_opc_instr_start[lj] = 1;
3493
            tcg_ctx.gen_opc_icount[lj] = num_insns;
3494
        }
3495

    
3496
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3497
            gen_io_start();
3498
        }
3499

    
3500
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3501
            tcg_gen_debug_insn_start(dc->pc);
3502
        }
3503

    
3504
        disas_a64_insn(env, dc);
3505

    
3506
        if (tcg_check_temp_count()) {
3507
            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
3508
                    dc->pc);
3509
        }
3510

    
3511
        /* Translation stops when a conditional branch is encountered.
3512
         * Otherwise the subsequent code could get translated several times.
3513
         * Also stop translation when a page boundary is reached.  This
3514
         * ensures prefetch aborts occur at the right place.
3515
         */
3516
        num_insns++;
3517
    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
3518
             !cs->singlestep_enabled &&
3519
             !singlestep &&
3520
             dc->pc < next_page_start &&
3521
             num_insns < max_insns);
3522

    
3523
    if (tb->cflags & CF_LAST_IO) {
3524
        gen_io_end();
3525
    }
3526

    
3527
    if (unlikely(cs->singlestep_enabled) && dc->is_jmp != DISAS_EXC) {
3528
        /* Note that this means single stepping WFI doesn't halt the CPU.
3529
         * For conditional branch insns this is harmless unreachable code as
3530
         * gen_goto_tb() has already handled emitting the debug exception
3531
         * (and thus a tb-jump is not possible when singlestepping).
3532
         */
3533
        assert(dc->is_jmp != DISAS_TB_JUMP);
3534
        if (dc->is_jmp != DISAS_JUMP) {
3535
            gen_a64_set_pc_im(dc->pc);
3536
        }
3537
        gen_exception(EXCP_DEBUG);
3538
    } else {
3539
        switch (dc->is_jmp) {
3540
        case DISAS_NEXT:
3541
            gen_goto_tb(dc, 1, dc->pc);
3542
            break;
3543
        default:
3544
        case DISAS_UPDATE:
3545
            gen_a64_set_pc_im(dc->pc);
3546
            /* fall through */
3547
        case DISAS_JUMP:
3548
            /* indicate that the hash table must be used to find the next TB */
3549
            tcg_gen_exit_tb(0);
3550
            break;
3551
        case DISAS_TB_JUMP:
3552
        case DISAS_EXC:
3553
        case DISAS_SWI:
3554
            break;
3555
        case DISAS_WFI:
3556
            /* This is a special case because we don't want to just halt the CPU
3557
             * if trying to debug across a WFI.
3558
             */
3559
            gen_helper_wfi(cpu_env);
3560
            break;
3561
        }
3562
    }
3563

    
3564
done_generating:
3565
    gen_tb_end(tb, num_insns);
3566
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3567

    
3568
#ifdef DEBUG_DISAS
3569
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3570
        qemu_log("----------------\n");
3571
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
3572
        log_target_disas(env, pc_start, dc->pc - pc_start,
3573
                         dc->thumb | (dc->bswap_code << 1));
3574
        qemu_log("\n");
3575
    }
3576
#endif
3577
    if (search_pc) {
3578
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3579
        lj++;
3580
        while (lj <= j) {
3581
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
3582
        }
3583
    } else {
3584
        tb->size = dc->pc - pc_start;
3585
        tb->icount = num_insns;
3586
    }
3587
}