qemu

Форк
0
/
tci.c 
1334 строки · 40.5 Кб
1
/*
2
 * Tiny Code Interpreter for QEMU
3
 *
4
 * Copyright (c) 2009, 2011, 2016 Stefan Weil
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program 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
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
#include "qemu/osdep.h"
21
#include "tcg/tcg.h"
22
#include "tcg/helper-info.h"
23
#include "tcg/tcg-ldst.h"
24
#include <ffi.h>
25

26

27
/*
28
 * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
29
 * Without assertions, the interpreter runs much faster.
30
 */
31
#if defined(CONFIG_DEBUG_TCG)
32
# define tci_assert(cond) assert(cond)
33
#else
34
# define tci_assert(cond) ((void)(cond))
35
#endif
36

37
__thread uintptr_t tci_tb_ptr;
38

39
static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
40
                            uint32_t low_index, uint64_t value)
41
{
42
    regs[low_index] = (uint32_t)value;
43
    regs[high_index] = value >> 32;
44
}
45

46
/* Create a 64 bit value from two 32 bit values. */
47
static uint64_t tci_uint64(uint32_t high, uint32_t low)
48
{
49
    return ((uint64_t)high << 32) + low;
50
}
51

52
/*
53
 * Load sets of arguments all at once.  The naming convention is:
54
 *   tci_args_<arguments>
55
 * where arguments is a sequence of
56
 *
57
 *   b = immediate (bit position)
58
 *   c = condition (TCGCond)
59
 *   i = immediate (uint32_t)
60
 *   I = immediate (tcg_target_ulong)
61
 *   l = label or pointer
62
 *   m = immediate (MemOpIdx)
63
 *   n = immediate (call return length)
64
 *   r = register
65
 *   s = signed ldst offset
66
 */
67

68
static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
69
{
70
    int diff = sextract32(insn, 12, 20);
71
    *l0 = diff ? (void *)tb_ptr + diff : NULL;
72
}
73

74
static void tci_args_r(uint32_t insn, TCGReg *r0)
75
{
76
    *r0 = extract32(insn, 8, 4);
77
}
78

79
static void tci_args_nl(uint32_t insn, const void *tb_ptr,
80
                        uint8_t *n0, void **l1)
81
{
82
    *n0 = extract32(insn, 8, 4);
83
    *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
84
}
85

86
static void tci_args_rl(uint32_t insn, const void *tb_ptr,
87
                        TCGReg *r0, void **l1)
88
{
89
    *r0 = extract32(insn, 8, 4);
90
    *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
91
}
92

93
static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
94
{
95
    *r0 = extract32(insn, 8, 4);
96
    *r1 = extract32(insn, 12, 4);
97
}
98

99
static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
100
{
101
    *r0 = extract32(insn, 8, 4);
102
    *i1 = sextract32(insn, 12, 20);
103
}
104

105
static void tci_args_rrm(uint32_t insn, TCGReg *r0,
106
                         TCGReg *r1, MemOpIdx *m2)
107
{
108
    *r0 = extract32(insn, 8, 4);
109
    *r1 = extract32(insn, 12, 4);
110
    *m2 = extract32(insn, 16, 16);
111
}
112

113
static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
114
{
115
    *r0 = extract32(insn, 8, 4);
116
    *r1 = extract32(insn, 12, 4);
117
    *r2 = extract32(insn, 16, 4);
118
}
119

120
static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
121
{
122
    *r0 = extract32(insn, 8, 4);
123
    *r1 = extract32(insn, 12, 4);
124
    *i2 = sextract32(insn, 16, 16);
125
}
126

127
static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
128
                          uint8_t *i2, uint8_t *i3)
129
{
130
    *r0 = extract32(insn, 8, 4);
131
    *r1 = extract32(insn, 12, 4);
132
    *i2 = extract32(insn, 16, 6);
133
    *i3 = extract32(insn, 22, 6);
134
}
135

136
static void tci_args_rrrc(uint32_t insn,
137
                          TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
138
{
139
    *r0 = extract32(insn, 8, 4);
140
    *r1 = extract32(insn, 12, 4);
141
    *r2 = extract32(insn, 16, 4);
142
    *c3 = extract32(insn, 20, 4);
143
}
144

145
static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
146
                           TCGReg *r2, uint8_t *i3, uint8_t *i4)
147
{
148
    *r0 = extract32(insn, 8, 4);
149
    *r1 = extract32(insn, 12, 4);
150
    *r2 = extract32(insn, 16, 4);
151
    *i3 = extract32(insn, 20, 6);
152
    *i4 = extract32(insn, 26, 6);
153
}
154

155
static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
156
                           TCGReg *r2, TCGReg *r3, TCGReg *r4)
157
{
158
    *r0 = extract32(insn, 8, 4);
159
    *r1 = extract32(insn, 12, 4);
160
    *r2 = extract32(insn, 16, 4);
161
    *r3 = extract32(insn, 20, 4);
162
    *r4 = extract32(insn, 24, 4);
163
}
164

165
static void tci_args_rrrr(uint32_t insn,
166
                          TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
167
{
168
    *r0 = extract32(insn, 8, 4);
169
    *r1 = extract32(insn, 12, 4);
170
    *r2 = extract32(insn, 16, 4);
171
    *r3 = extract32(insn, 20, 4);
172
}
173

174
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
175
                            TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
176
{
177
    *r0 = extract32(insn, 8, 4);
178
    *r1 = extract32(insn, 12, 4);
179
    *r2 = extract32(insn, 16, 4);
180
    *r3 = extract32(insn, 20, 4);
181
    *r4 = extract32(insn, 24, 4);
182
    *c5 = extract32(insn, 28, 4);
183
}
184

185
static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
186
                            TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
187
{
188
    *r0 = extract32(insn, 8, 4);
189
    *r1 = extract32(insn, 12, 4);
190
    *r2 = extract32(insn, 16, 4);
191
    *r3 = extract32(insn, 20, 4);
192
    *r4 = extract32(insn, 24, 4);
193
    *r5 = extract32(insn, 28, 4);
194
}
195

196
static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
197
{
198
    bool result = false;
199
    int32_t i0 = u0;
200
    int32_t i1 = u1;
201
    switch (condition) {
202
    case TCG_COND_EQ:
203
        result = (u0 == u1);
204
        break;
205
    case TCG_COND_NE:
206
        result = (u0 != u1);
207
        break;
208
    case TCG_COND_LT:
209
        result = (i0 < i1);
210
        break;
211
    case TCG_COND_GE:
212
        result = (i0 >= i1);
213
        break;
214
    case TCG_COND_LE:
215
        result = (i0 <= i1);
216
        break;
217
    case TCG_COND_GT:
218
        result = (i0 > i1);
219
        break;
220
    case TCG_COND_LTU:
221
        result = (u0 < u1);
222
        break;
223
    case TCG_COND_GEU:
224
        result = (u0 >= u1);
225
        break;
226
    case TCG_COND_LEU:
227
        result = (u0 <= u1);
228
        break;
229
    case TCG_COND_GTU:
230
        result = (u0 > u1);
231
        break;
232
    case TCG_COND_TSTEQ:
233
        result = (u0 & u1) == 0;
234
        break;
235
    case TCG_COND_TSTNE:
236
        result = (u0 & u1) != 0;
237
        break;
238
    default:
239
        g_assert_not_reached();
240
    }
241
    return result;
242
}
243

244
static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
245
{
246
    bool result = false;
247
    int64_t i0 = u0;
248
    int64_t i1 = u1;
249
    switch (condition) {
250
    case TCG_COND_EQ:
251
        result = (u0 == u1);
252
        break;
253
    case TCG_COND_NE:
254
        result = (u0 != u1);
255
        break;
256
    case TCG_COND_LT:
257
        result = (i0 < i1);
258
        break;
259
    case TCG_COND_GE:
260
        result = (i0 >= i1);
261
        break;
262
    case TCG_COND_LE:
263
        result = (i0 <= i1);
264
        break;
265
    case TCG_COND_GT:
266
        result = (i0 > i1);
267
        break;
268
    case TCG_COND_LTU:
269
        result = (u0 < u1);
270
        break;
271
    case TCG_COND_GEU:
272
        result = (u0 >= u1);
273
        break;
274
    case TCG_COND_LEU:
275
        result = (u0 <= u1);
276
        break;
277
    case TCG_COND_GTU:
278
        result = (u0 > u1);
279
        break;
280
    case TCG_COND_TSTEQ:
281
        result = (u0 & u1) == 0;
282
        break;
283
    case TCG_COND_TSTNE:
284
        result = (u0 & u1) != 0;
285
        break;
286
    default:
287
        g_assert_not_reached();
288
    }
289
    return result;
290
}
291

292
static uint64_t tci_qemu_ld(CPUArchState *env, uint64_t taddr,
293
                            MemOpIdx oi, const void *tb_ptr)
294
{
295
    MemOp mop = get_memop(oi);
296
    uintptr_t ra = (uintptr_t)tb_ptr;
297

298
    switch (mop & MO_SSIZE) {
299
    case MO_UB:
300
        return helper_ldub_mmu(env, taddr, oi, ra);
301
    case MO_SB:
302
        return helper_ldsb_mmu(env, taddr, oi, ra);
303
    case MO_UW:
304
        return helper_lduw_mmu(env, taddr, oi, ra);
305
    case MO_SW:
306
        return helper_ldsw_mmu(env, taddr, oi, ra);
307
    case MO_UL:
308
        return helper_ldul_mmu(env, taddr, oi, ra);
309
    case MO_SL:
310
        return helper_ldsl_mmu(env, taddr, oi, ra);
311
    case MO_UQ:
312
        return helper_ldq_mmu(env, taddr, oi, ra);
313
    default:
314
        g_assert_not_reached();
315
    }
316
}
317

318
static void tci_qemu_st(CPUArchState *env, uint64_t taddr, uint64_t val,
319
                        MemOpIdx oi, const void *tb_ptr)
320
{
321
    MemOp mop = get_memop(oi);
322
    uintptr_t ra = (uintptr_t)tb_ptr;
323

324
    switch (mop & MO_SIZE) {
325
    case MO_UB:
326
        helper_stb_mmu(env, taddr, val, oi, ra);
327
        break;
328
    case MO_UW:
329
        helper_stw_mmu(env, taddr, val, oi, ra);
330
        break;
331
    case MO_UL:
332
        helper_stl_mmu(env, taddr, val, oi, ra);
333
        break;
334
    case MO_UQ:
335
        helper_stq_mmu(env, taddr, val, oi, ra);
336
        break;
337
    default:
338
        g_assert_not_reached();
339
    }
340
}
341

342
#if TCG_TARGET_REG_BITS == 64
343
# define CASE_32_64(x) \
344
        case glue(glue(INDEX_op_, x), _i64): \
345
        case glue(glue(INDEX_op_, x), _i32):
346
# define CASE_64(x) \
347
        case glue(glue(INDEX_op_, x), _i64):
348
#else
349
# define CASE_32_64(x) \
350
        case glue(glue(INDEX_op_, x), _i32):
351
# define CASE_64(x)
352
#endif
353

354
/* Interpret pseudo code in tb. */
355
/*
356
 * Disable CFI checks.
357
 * One possible operation in the pseudo code is a call to binary code.
358
 * Therefore, disable CFI checks in the interpreter function
359
 */
360
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
361
                                            const void *v_tb_ptr)
362
{
363
    const uint32_t *tb_ptr = v_tb_ptr;
364
    tcg_target_ulong regs[TCG_TARGET_NB_REGS];
365
    uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
366
                   / sizeof(uint64_t)];
367

368
    regs[TCG_AREG0] = (tcg_target_ulong)env;
369
    regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
370
    tci_assert(tb_ptr);
371

372
    for (;;) {
373
        uint32_t insn;
374
        TCGOpcode opc;
375
        TCGReg r0, r1, r2, r3, r4, r5;
376
        tcg_target_ulong t1;
377
        TCGCond condition;
378
        uint8_t pos, len;
379
        uint32_t tmp32;
380
        uint64_t tmp64, taddr;
381
        uint64_t T1, T2;
382
        MemOpIdx oi;
383
        int32_t ofs;
384
        void *ptr;
385

386
        insn = *tb_ptr++;
387
        opc = extract32(insn, 0, 8);
388

389
        switch (opc) {
390
        case INDEX_op_call:
391
            {
392
                void *call_slots[MAX_CALL_IARGS];
393
                ffi_cif *cif;
394
                void *func;
395
                unsigned i, s, n;
396

397
                tci_args_nl(insn, tb_ptr, &len, &ptr);
398
                func = ((void **)ptr)[0];
399
                cif = ((void **)ptr)[1];
400

401
                n = cif->nargs;
402
                for (i = s = 0; i < n; ++i) {
403
                    ffi_type *t = cif->arg_types[i];
404
                    call_slots[i] = &stack[s];
405
                    s += DIV_ROUND_UP(t->size, 8);
406
                }
407

408
                /* Helper functions may need to access the "return address" */
409
                tci_tb_ptr = (uintptr_t)tb_ptr;
410
                ffi_call(cif, func, stack, call_slots);
411
            }
412

413
            switch (len) {
414
            case 0: /* void */
415
                break;
416
            case 1: /* uint32_t */
417
                /*
418
                 * The result winds up "left-aligned" in the stack[0] slot.
419
                 * Note that libffi has an odd special case in that it will
420
                 * always widen an integral result to ffi_arg.
421
                 */
422
                if (sizeof(ffi_arg) == 8) {
423
                    regs[TCG_REG_R0] = (uint32_t)stack[0];
424
                } else {
425
                    regs[TCG_REG_R0] = *(uint32_t *)stack;
426
                }
427
                break;
428
            case 2: /* uint64_t */
429
                /*
430
                 * For TCG_TARGET_REG_BITS == 32, the register pair
431
                 * must stay in host memory order.
432
                 */
433
                memcpy(&regs[TCG_REG_R0], stack, 8);
434
                break;
435
            case 3: /* Int128 */
436
                memcpy(&regs[TCG_REG_R0], stack, 16);
437
                break;
438
            default:
439
                g_assert_not_reached();
440
            }
441
            break;
442

443
        case INDEX_op_br:
444
            tci_args_l(insn, tb_ptr, &ptr);
445
            tb_ptr = ptr;
446
            continue;
447
        case INDEX_op_setcond_i32:
448
            tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
449
            regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
450
            break;
451
        case INDEX_op_movcond_i32:
452
            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
453
            tmp32 = tci_compare32(regs[r1], regs[r2], condition);
454
            regs[r0] = regs[tmp32 ? r3 : r4];
455
            break;
456
#if TCG_TARGET_REG_BITS == 32
457
        case INDEX_op_setcond2_i32:
458
            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
459
            T1 = tci_uint64(regs[r2], regs[r1]);
460
            T2 = tci_uint64(regs[r4], regs[r3]);
461
            regs[r0] = tci_compare64(T1, T2, condition);
462
            break;
463
#elif TCG_TARGET_REG_BITS == 64
464
        case INDEX_op_setcond_i64:
465
            tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
466
            regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
467
            break;
468
        case INDEX_op_movcond_i64:
469
            tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
470
            tmp32 = tci_compare64(regs[r1], regs[r2], condition);
471
            regs[r0] = regs[tmp32 ? r3 : r4];
472
            break;
473
#endif
474
        CASE_32_64(mov)
475
            tci_args_rr(insn, &r0, &r1);
476
            regs[r0] = regs[r1];
477
            break;
478
        case INDEX_op_tci_movi:
479
            tci_args_ri(insn, &r0, &t1);
480
            regs[r0] = t1;
481
            break;
482
        case INDEX_op_tci_movl:
483
            tci_args_rl(insn, tb_ptr, &r0, &ptr);
484
            regs[r0] = *(tcg_target_ulong *)ptr;
485
            break;
486

487
            /* Load/store operations (32 bit). */
488

489
        CASE_32_64(ld8u)
490
            tci_args_rrs(insn, &r0, &r1, &ofs);
491
            ptr = (void *)(regs[r1] + ofs);
492
            regs[r0] = *(uint8_t *)ptr;
493
            break;
494
        CASE_32_64(ld8s)
495
            tci_args_rrs(insn, &r0, &r1, &ofs);
496
            ptr = (void *)(regs[r1] + ofs);
497
            regs[r0] = *(int8_t *)ptr;
498
            break;
499
        CASE_32_64(ld16u)
500
            tci_args_rrs(insn, &r0, &r1, &ofs);
501
            ptr = (void *)(regs[r1] + ofs);
502
            regs[r0] = *(uint16_t *)ptr;
503
            break;
504
        CASE_32_64(ld16s)
505
            tci_args_rrs(insn, &r0, &r1, &ofs);
506
            ptr = (void *)(regs[r1] + ofs);
507
            regs[r0] = *(int16_t *)ptr;
508
            break;
509
        case INDEX_op_ld_i32:
510
        CASE_64(ld32u)
511
            tci_args_rrs(insn, &r0, &r1, &ofs);
512
            ptr = (void *)(regs[r1] + ofs);
513
            regs[r0] = *(uint32_t *)ptr;
514
            break;
515
        CASE_32_64(st8)
516
            tci_args_rrs(insn, &r0, &r1, &ofs);
517
            ptr = (void *)(regs[r1] + ofs);
518
            *(uint8_t *)ptr = regs[r0];
519
            break;
520
        CASE_32_64(st16)
521
            tci_args_rrs(insn, &r0, &r1, &ofs);
522
            ptr = (void *)(regs[r1] + ofs);
523
            *(uint16_t *)ptr = regs[r0];
524
            break;
525
        case INDEX_op_st_i32:
526
        CASE_64(st32)
527
            tci_args_rrs(insn, &r0, &r1, &ofs);
528
            ptr = (void *)(regs[r1] + ofs);
529
            *(uint32_t *)ptr = regs[r0];
530
            break;
531

532
            /* Arithmetic operations (mixed 32/64 bit). */
533

534
        CASE_32_64(add)
535
            tci_args_rrr(insn, &r0, &r1, &r2);
536
            regs[r0] = regs[r1] + regs[r2];
537
            break;
538
        CASE_32_64(sub)
539
            tci_args_rrr(insn, &r0, &r1, &r2);
540
            regs[r0] = regs[r1] - regs[r2];
541
            break;
542
        CASE_32_64(mul)
543
            tci_args_rrr(insn, &r0, &r1, &r2);
544
            regs[r0] = regs[r1] * regs[r2];
545
            break;
546
        CASE_32_64(and)
547
            tci_args_rrr(insn, &r0, &r1, &r2);
548
            regs[r0] = regs[r1] & regs[r2];
549
            break;
550
        CASE_32_64(or)
551
            tci_args_rrr(insn, &r0, &r1, &r2);
552
            regs[r0] = regs[r1] | regs[r2];
553
            break;
554
        CASE_32_64(xor)
555
            tci_args_rrr(insn, &r0, &r1, &r2);
556
            regs[r0] = regs[r1] ^ regs[r2];
557
            break;
558
#if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
559
        CASE_32_64(andc)
560
            tci_args_rrr(insn, &r0, &r1, &r2);
561
            regs[r0] = regs[r1] & ~regs[r2];
562
            break;
563
#endif
564
#if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
565
        CASE_32_64(orc)
566
            tci_args_rrr(insn, &r0, &r1, &r2);
567
            regs[r0] = regs[r1] | ~regs[r2];
568
            break;
569
#endif
570
#if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
571
        CASE_32_64(eqv)
572
            tci_args_rrr(insn, &r0, &r1, &r2);
573
            regs[r0] = ~(regs[r1] ^ regs[r2]);
574
            break;
575
#endif
576
#if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
577
        CASE_32_64(nand)
578
            tci_args_rrr(insn, &r0, &r1, &r2);
579
            regs[r0] = ~(regs[r1] & regs[r2]);
580
            break;
581
#endif
582
#if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
583
        CASE_32_64(nor)
584
            tci_args_rrr(insn, &r0, &r1, &r2);
585
            regs[r0] = ~(regs[r1] | regs[r2]);
586
            break;
587
#endif
588

589
            /* Arithmetic operations (32 bit). */
590

591
        case INDEX_op_div_i32:
592
            tci_args_rrr(insn, &r0, &r1, &r2);
593
            regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
594
            break;
595
        case INDEX_op_divu_i32:
596
            tci_args_rrr(insn, &r0, &r1, &r2);
597
            regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
598
            break;
599
        case INDEX_op_rem_i32:
600
            tci_args_rrr(insn, &r0, &r1, &r2);
601
            regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
602
            break;
603
        case INDEX_op_remu_i32:
604
            tci_args_rrr(insn, &r0, &r1, &r2);
605
            regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
606
            break;
607
#if TCG_TARGET_HAS_clz_i32
608
        case INDEX_op_clz_i32:
609
            tci_args_rrr(insn, &r0, &r1, &r2);
610
            tmp32 = regs[r1];
611
            regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
612
            break;
613
#endif
614
#if TCG_TARGET_HAS_ctz_i32
615
        case INDEX_op_ctz_i32:
616
            tci_args_rrr(insn, &r0, &r1, &r2);
617
            tmp32 = regs[r1];
618
            regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
619
            break;
620
#endif
621
#if TCG_TARGET_HAS_ctpop_i32
622
        case INDEX_op_ctpop_i32:
623
            tci_args_rr(insn, &r0, &r1);
624
            regs[r0] = ctpop32(regs[r1]);
625
            break;
626
#endif
627

628
            /* Shift/rotate operations (32 bit). */
629

630
        case INDEX_op_shl_i32:
631
            tci_args_rrr(insn, &r0, &r1, &r2);
632
            regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
633
            break;
634
        case INDEX_op_shr_i32:
635
            tci_args_rrr(insn, &r0, &r1, &r2);
636
            regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
637
            break;
638
        case INDEX_op_sar_i32:
639
            tci_args_rrr(insn, &r0, &r1, &r2);
640
            regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
641
            break;
642
#if TCG_TARGET_HAS_rot_i32
643
        case INDEX_op_rotl_i32:
644
            tci_args_rrr(insn, &r0, &r1, &r2);
645
            regs[r0] = rol32(regs[r1], regs[r2] & 31);
646
            break;
647
        case INDEX_op_rotr_i32:
648
            tci_args_rrr(insn, &r0, &r1, &r2);
649
            regs[r0] = ror32(regs[r1], regs[r2] & 31);
650
            break;
651
#endif
652
#if TCG_TARGET_HAS_deposit_i32
653
        case INDEX_op_deposit_i32:
654
            tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
655
            regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
656
            break;
657
#endif
658
#if TCG_TARGET_HAS_extract_i32
659
        case INDEX_op_extract_i32:
660
            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
661
            regs[r0] = extract32(regs[r1], pos, len);
662
            break;
663
#endif
664
#if TCG_TARGET_HAS_sextract_i32
665
        case INDEX_op_sextract_i32:
666
            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
667
            regs[r0] = sextract32(regs[r1], pos, len);
668
            break;
669
#endif
670
        case INDEX_op_brcond_i32:
671
            tci_args_rl(insn, tb_ptr, &r0, &ptr);
672
            if ((uint32_t)regs[r0]) {
673
                tb_ptr = ptr;
674
            }
675
            break;
676
#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
677
        case INDEX_op_add2_i32:
678
            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
679
            T1 = tci_uint64(regs[r3], regs[r2]);
680
            T2 = tci_uint64(regs[r5], regs[r4]);
681
            tci_write_reg64(regs, r1, r0, T1 + T2);
682
            break;
683
#endif
684
#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
685
        case INDEX_op_sub2_i32:
686
            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
687
            T1 = tci_uint64(regs[r3], regs[r2]);
688
            T2 = tci_uint64(regs[r5], regs[r4]);
689
            tci_write_reg64(regs, r1, r0, T1 - T2);
690
            break;
691
#endif
692
#if TCG_TARGET_HAS_mulu2_i32
693
        case INDEX_op_mulu2_i32:
694
            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
695
            tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
696
            tci_write_reg64(regs, r1, r0, tmp64);
697
            break;
698
#endif
699
#if TCG_TARGET_HAS_muls2_i32
700
        case INDEX_op_muls2_i32:
701
            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
702
            tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
703
            tci_write_reg64(regs, r1, r0, tmp64);
704
            break;
705
#endif
706
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
707
        CASE_32_64(ext8s)
708
            tci_args_rr(insn, &r0, &r1);
709
            regs[r0] = (int8_t)regs[r1];
710
            break;
711
#endif
712
#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64 || \
713
    TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
714
        CASE_32_64(ext16s)
715
            tci_args_rr(insn, &r0, &r1);
716
            regs[r0] = (int16_t)regs[r1];
717
            break;
718
#endif
719
#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
720
        CASE_32_64(ext8u)
721
            tci_args_rr(insn, &r0, &r1);
722
            regs[r0] = (uint8_t)regs[r1];
723
            break;
724
#endif
725
#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
726
        CASE_32_64(ext16u)
727
            tci_args_rr(insn, &r0, &r1);
728
            regs[r0] = (uint16_t)regs[r1];
729
            break;
730
#endif
731
#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
732
        CASE_32_64(bswap16)
733
            tci_args_rr(insn, &r0, &r1);
734
            regs[r0] = bswap16(regs[r1]);
735
            break;
736
#endif
737
#if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
738
        CASE_32_64(bswap32)
739
            tci_args_rr(insn, &r0, &r1);
740
            regs[r0] = bswap32(regs[r1]);
741
            break;
742
#endif
743
#if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
744
        CASE_32_64(not)
745
            tci_args_rr(insn, &r0, &r1);
746
            regs[r0] = ~regs[r1];
747
            break;
748
#endif
749
        CASE_32_64(neg)
750
            tci_args_rr(insn, &r0, &r1);
751
            regs[r0] = -regs[r1];
752
            break;
753
#if TCG_TARGET_REG_BITS == 64
754
            /* Load/store operations (64 bit). */
755

756
        case INDEX_op_ld32s_i64:
757
            tci_args_rrs(insn, &r0, &r1, &ofs);
758
            ptr = (void *)(regs[r1] + ofs);
759
            regs[r0] = *(int32_t *)ptr;
760
            break;
761
        case INDEX_op_ld_i64:
762
            tci_args_rrs(insn, &r0, &r1, &ofs);
763
            ptr = (void *)(regs[r1] + ofs);
764
            regs[r0] = *(uint64_t *)ptr;
765
            break;
766
        case INDEX_op_st_i64:
767
            tci_args_rrs(insn, &r0, &r1, &ofs);
768
            ptr = (void *)(regs[r1] + ofs);
769
            *(uint64_t *)ptr = regs[r0];
770
            break;
771

772
            /* Arithmetic operations (64 bit). */
773

774
        case INDEX_op_div_i64:
775
            tci_args_rrr(insn, &r0, &r1, &r2);
776
            regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
777
            break;
778
        case INDEX_op_divu_i64:
779
            tci_args_rrr(insn, &r0, &r1, &r2);
780
            regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
781
            break;
782
        case INDEX_op_rem_i64:
783
            tci_args_rrr(insn, &r0, &r1, &r2);
784
            regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
785
            break;
786
        case INDEX_op_remu_i64:
787
            tci_args_rrr(insn, &r0, &r1, &r2);
788
            regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
789
            break;
790
#if TCG_TARGET_HAS_clz_i64
791
        case INDEX_op_clz_i64:
792
            tci_args_rrr(insn, &r0, &r1, &r2);
793
            regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
794
            break;
795
#endif
796
#if TCG_TARGET_HAS_ctz_i64
797
        case INDEX_op_ctz_i64:
798
            tci_args_rrr(insn, &r0, &r1, &r2);
799
            regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
800
            break;
801
#endif
802
#if TCG_TARGET_HAS_ctpop_i64
803
        case INDEX_op_ctpop_i64:
804
            tci_args_rr(insn, &r0, &r1);
805
            regs[r0] = ctpop64(regs[r1]);
806
            break;
807
#endif
808
#if TCG_TARGET_HAS_mulu2_i64
809
        case INDEX_op_mulu2_i64:
810
            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
811
            mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
812
            break;
813
#endif
814
#if TCG_TARGET_HAS_muls2_i64
815
        case INDEX_op_muls2_i64:
816
            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
817
            muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
818
            break;
819
#endif
820
#if TCG_TARGET_HAS_add2_i64
821
        case INDEX_op_add2_i64:
822
            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
823
            T1 = regs[r2] + regs[r4];
824
            T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
825
            regs[r0] = T1;
826
            regs[r1] = T2;
827
            break;
828
#endif
829
#if TCG_TARGET_HAS_add2_i64
830
        case INDEX_op_sub2_i64:
831
            tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
832
            T1 = regs[r2] - regs[r4];
833
            T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
834
            regs[r0] = T1;
835
            regs[r1] = T2;
836
            break;
837
#endif
838

839
            /* Shift/rotate operations (64 bit). */
840

841
        case INDEX_op_shl_i64:
842
            tci_args_rrr(insn, &r0, &r1, &r2);
843
            regs[r0] = regs[r1] << (regs[r2] & 63);
844
            break;
845
        case INDEX_op_shr_i64:
846
            tci_args_rrr(insn, &r0, &r1, &r2);
847
            regs[r0] = regs[r1] >> (regs[r2] & 63);
848
            break;
849
        case INDEX_op_sar_i64:
850
            tci_args_rrr(insn, &r0, &r1, &r2);
851
            regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
852
            break;
853
#if TCG_TARGET_HAS_rot_i64
854
        case INDEX_op_rotl_i64:
855
            tci_args_rrr(insn, &r0, &r1, &r2);
856
            regs[r0] = rol64(regs[r1], regs[r2] & 63);
857
            break;
858
        case INDEX_op_rotr_i64:
859
            tci_args_rrr(insn, &r0, &r1, &r2);
860
            regs[r0] = ror64(regs[r1], regs[r2] & 63);
861
            break;
862
#endif
863
#if TCG_TARGET_HAS_deposit_i64
864
        case INDEX_op_deposit_i64:
865
            tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
866
            regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
867
            break;
868
#endif
869
#if TCG_TARGET_HAS_extract_i64
870
        case INDEX_op_extract_i64:
871
            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
872
            regs[r0] = extract64(regs[r1], pos, len);
873
            break;
874
#endif
875
#if TCG_TARGET_HAS_sextract_i64
876
        case INDEX_op_sextract_i64:
877
            tci_args_rrbb(insn, &r0, &r1, &pos, &len);
878
            regs[r0] = sextract64(regs[r1], pos, len);
879
            break;
880
#endif
881
        case INDEX_op_brcond_i64:
882
            tci_args_rl(insn, tb_ptr, &r0, &ptr);
883
            if (regs[r0]) {
884
                tb_ptr = ptr;
885
            }
886
            break;
887
        case INDEX_op_ext32s_i64:
888
        case INDEX_op_ext_i32_i64:
889
            tci_args_rr(insn, &r0, &r1);
890
            regs[r0] = (int32_t)regs[r1];
891
            break;
892
        case INDEX_op_ext32u_i64:
893
        case INDEX_op_extu_i32_i64:
894
            tci_args_rr(insn, &r0, &r1);
895
            regs[r0] = (uint32_t)regs[r1];
896
            break;
897
#if TCG_TARGET_HAS_bswap64_i64
898
        case INDEX_op_bswap64_i64:
899
            tci_args_rr(insn, &r0, &r1);
900
            regs[r0] = bswap64(regs[r1]);
901
            break;
902
#endif
903
#endif /* TCG_TARGET_REG_BITS == 64 */
904

905
            /* QEMU specific operations. */
906

907
        case INDEX_op_exit_tb:
908
            tci_args_l(insn, tb_ptr, &ptr);
909
            return (uintptr_t)ptr;
910

911
        case INDEX_op_goto_tb:
912
            tci_args_l(insn, tb_ptr, &ptr);
913
            tb_ptr = *(void **)ptr;
914
            break;
915

916
        case INDEX_op_goto_ptr:
917
            tci_args_r(insn, &r0);
918
            ptr = (void *)regs[r0];
919
            if (!ptr) {
920
                return 0;
921
            }
922
            tb_ptr = ptr;
923
            break;
924

925
        case INDEX_op_qemu_ld_a32_i32:
926
            tci_args_rrm(insn, &r0, &r1, &oi);
927
            taddr = (uint32_t)regs[r1];
928
            goto do_ld_i32;
929
        case INDEX_op_qemu_ld_a64_i32:
930
            if (TCG_TARGET_REG_BITS == 64) {
931
                tci_args_rrm(insn, &r0, &r1, &oi);
932
                taddr = regs[r1];
933
            } else {
934
                tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
935
                taddr = tci_uint64(regs[r2], regs[r1]);
936
                oi = regs[r3];
937
            }
938
        do_ld_i32:
939
            regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
940
            break;
941

942
        case INDEX_op_qemu_ld_a32_i64:
943
            if (TCG_TARGET_REG_BITS == 64) {
944
                tci_args_rrm(insn, &r0, &r1, &oi);
945
                taddr = (uint32_t)regs[r1];
946
            } else {
947
                tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
948
                taddr = (uint32_t)regs[r2];
949
                oi = regs[r3];
950
            }
951
            goto do_ld_i64;
952
        case INDEX_op_qemu_ld_a64_i64:
953
            if (TCG_TARGET_REG_BITS == 64) {
954
                tci_args_rrm(insn, &r0, &r1, &oi);
955
                taddr = regs[r1];
956
            } else {
957
                tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
958
                taddr = tci_uint64(regs[r3], regs[r2]);
959
                oi = regs[r4];
960
            }
961
        do_ld_i64:
962
            tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
963
            if (TCG_TARGET_REG_BITS == 32) {
964
                tci_write_reg64(regs, r1, r0, tmp64);
965
            } else {
966
                regs[r0] = tmp64;
967
            }
968
            break;
969

970
        case INDEX_op_qemu_st_a32_i32:
971
            tci_args_rrm(insn, &r0, &r1, &oi);
972
            taddr = (uint32_t)regs[r1];
973
            goto do_st_i32;
974
        case INDEX_op_qemu_st_a64_i32:
975
            if (TCG_TARGET_REG_BITS == 64) {
976
                tci_args_rrm(insn, &r0, &r1, &oi);
977
                taddr = regs[r1];
978
            } else {
979
                tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
980
                taddr = tci_uint64(regs[r2], regs[r1]);
981
                oi = regs[r3];
982
            }
983
        do_st_i32:
984
            tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
985
            break;
986

987
        case INDEX_op_qemu_st_a32_i64:
988
            if (TCG_TARGET_REG_BITS == 64) {
989
                tci_args_rrm(insn, &r0, &r1, &oi);
990
                tmp64 = regs[r0];
991
                taddr = (uint32_t)regs[r1];
992
            } else {
993
                tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
994
                tmp64 = tci_uint64(regs[r1], regs[r0]);
995
                taddr = (uint32_t)regs[r2];
996
                oi = regs[r3];
997
            }
998
            goto do_st_i64;
999
        case INDEX_op_qemu_st_a64_i64:
1000
            if (TCG_TARGET_REG_BITS == 64) {
1001
                tci_args_rrm(insn, &r0, &r1, &oi);
1002
                tmp64 = regs[r0];
1003
                taddr = regs[r1];
1004
            } else {
1005
                tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1006
                tmp64 = tci_uint64(regs[r1], regs[r0]);
1007
                taddr = tci_uint64(regs[r3], regs[r2]);
1008
                oi = regs[r4];
1009
            }
1010
        do_st_i64:
1011
            tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
1012
            break;
1013

1014
        case INDEX_op_mb:
1015
            /* Ensure ordering for all kinds */
1016
            smp_mb();
1017
            break;
1018
        default:
1019
            g_assert_not_reached();
1020
        }
1021
    }
1022
}
1023

1024
/*
1025
 * Disassembler that matches the interpreter
1026
 */
1027

1028
static const char *str_r(TCGReg r)
1029
{
1030
    static const char regs[TCG_TARGET_NB_REGS][4] = {
1031
        "r0", "r1", "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
1032
        "r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
1033
    };
1034

1035
    QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
1036
    QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
1037

1038
    assert((unsigned)r < TCG_TARGET_NB_REGS);
1039
    return regs[r];
1040
}
1041

1042
static const char *str_c(TCGCond c)
1043
{
1044
    static const char cond[16][8] = {
1045
        [TCG_COND_NEVER] = "never",
1046
        [TCG_COND_ALWAYS] = "always",
1047
        [TCG_COND_EQ] = "eq",
1048
        [TCG_COND_NE] = "ne",
1049
        [TCG_COND_LT] = "lt",
1050
        [TCG_COND_GE] = "ge",
1051
        [TCG_COND_LE] = "le",
1052
        [TCG_COND_GT] = "gt",
1053
        [TCG_COND_LTU] = "ltu",
1054
        [TCG_COND_GEU] = "geu",
1055
        [TCG_COND_LEU] = "leu",
1056
        [TCG_COND_GTU] = "gtu",
1057
        [TCG_COND_TSTEQ] = "tsteq",
1058
        [TCG_COND_TSTNE] = "tstne",
1059
    };
1060

1061
    assert((unsigned)c < ARRAY_SIZE(cond));
1062
    assert(cond[c][0] != 0);
1063
    return cond[c];
1064
}
1065

1066
/* Disassemble TCI bytecode. */
1067
int print_insn_tci(bfd_vma addr, disassemble_info *info)
1068
{
1069
    const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
1070
    const TCGOpDef *def;
1071
    const char *op_name;
1072
    uint32_t insn;
1073
    TCGOpcode op;
1074
    TCGReg r0, r1, r2, r3, r4, r5;
1075
    tcg_target_ulong i1;
1076
    int32_t s2;
1077
    TCGCond c;
1078
    MemOpIdx oi;
1079
    uint8_t pos, len;
1080
    void *ptr;
1081

1082
    /* TCI is always the host, so we don't need to load indirect. */
1083
    insn = *tb_ptr++;
1084

1085
    info->fprintf_func(info->stream, "%08x  ", insn);
1086

1087
    op = extract32(insn, 0, 8);
1088
    def = &tcg_op_defs[op];
1089
    op_name = def->name;
1090

1091
    switch (op) {
1092
    case INDEX_op_br:
1093
    case INDEX_op_exit_tb:
1094
    case INDEX_op_goto_tb:
1095
        tci_args_l(insn, tb_ptr, &ptr);
1096
        info->fprintf_func(info->stream, "%-12s  %p", op_name, ptr);
1097
        break;
1098

1099
    case INDEX_op_goto_ptr:
1100
        tci_args_r(insn, &r0);
1101
        info->fprintf_func(info->stream, "%-12s  %s", op_name, str_r(r0));
1102
        break;
1103

1104
    case INDEX_op_call:
1105
        tci_args_nl(insn, tb_ptr, &len, &ptr);
1106
        info->fprintf_func(info->stream, "%-12s  %d, %p", op_name, len, ptr);
1107
        break;
1108

1109
    case INDEX_op_brcond_i32:
1110
    case INDEX_op_brcond_i64:
1111
        tci_args_rl(insn, tb_ptr, &r0, &ptr);
1112
        info->fprintf_func(info->stream, "%-12s  %s, 0, ne, %p",
1113
                           op_name, str_r(r0), ptr);
1114
        break;
1115

1116
    case INDEX_op_setcond_i32:
1117
    case INDEX_op_setcond_i64:
1118
        tci_args_rrrc(insn, &r0, &r1, &r2, &c);
1119
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1120
                           op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1121
        break;
1122

1123
    case INDEX_op_tci_movi:
1124
        tci_args_ri(insn, &r0, &i1);
1125
        info->fprintf_func(info->stream, "%-12s  %s, 0x%" TCG_PRIlx,
1126
                           op_name, str_r(r0), i1);
1127
        break;
1128

1129
    case INDEX_op_tci_movl:
1130
        tci_args_rl(insn, tb_ptr, &r0, &ptr);
1131
        info->fprintf_func(info->stream, "%-12s  %s, %p",
1132
                           op_name, str_r(r0), ptr);
1133
        break;
1134

1135
    case INDEX_op_ld8u_i32:
1136
    case INDEX_op_ld8u_i64:
1137
    case INDEX_op_ld8s_i32:
1138
    case INDEX_op_ld8s_i64:
1139
    case INDEX_op_ld16u_i32:
1140
    case INDEX_op_ld16u_i64:
1141
    case INDEX_op_ld16s_i32:
1142
    case INDEX_op_ld16s_i64:
1143
    case INDEX_op_ld32u_i64:
1144
    case INDEX_op_ld32s_i64:
1145
    case INDEX_op_ld_i32:
1146
    case INDEX_op_ld_i64:
1147
    case INDEX_op_st8_i32:
1148
    case INDEX_op_st8_i64:
1149
    case INDEX_op_st16_i32:
1150
    case INDEX_op_st16_i64:
1151
    case INDEX_op_st32_i64:
1152
    case INDEX_op_st_i32:
1153
    case INDEX_op_st_i64:
1154
        tci_args_rrs(insn, &r0, &r1, &s2);
1155
        info->fprintf_func(info->stream, "%-12s  %s, %s, %d",
1156
                           op_name, str_r(r0), str_r(r1), s2);
1157
        break;
1158

1159
    case INDEX_op_mov_i32:
1160
    case INDEX_op_mov_i64:
1161
    case INDEX_op_ext8s_i32:
1162
    case INDEX_op_ext8s_i64:
1163
    case INDEX_op_ext8u_i32:
1164
    case INDEX_op_ext8u_i64:
1165
    case INDEX_op_ext16s_i32:
1166
    case INDEX_op_ext16s_i64:
1167
    case INDEX_op_ext16u_i32:
1168
    case INDEX_op_ext32s_i64:
1169
    case INDEX_op_ext32u_i64:
1170
    case INDEX_op_ext_i32_i64:
1171
    case INDEX_op_extu_i32_i64:
1172
    case INDEX_op_bswap16_i32:
1173
    case INDEX_op_bswap16_i64:
1174
    case INDEX_op_bswap32_i32:
1175
    case INDEX_op_bswap32_i64:
1176
    case INDEX_op_bswap64_i64:
1177
    case INDEX_op_not_i32:
1178
    case INDEX_op_not_i64:
1179
    case INDEX_op_neg_i32:
1180
    case INDEX_op_neg_i64:
1181
    case INDEX_op_ctpop_i32:
1182
    case INDEX_op_ctpop_i64:
1183
        tci_args_rr(insn, &r0, &r1);
1184
        info->fprintf_func(info->stream, "%-12s  %s, %s",
1185
                           op_name, str_r(r0), str_r(r1));
1186
        break;
1187

1188
    case INDEX_op_add_i32:
1189
    case INDEX_op_add_i64:
1190
    case INDEX_op_sub_i32:
1191
    case INDEX_op_sub_i64:
1192
    case INDEX_op_mul_i32:
1193
    case INDEX_op_mul_i64:
1194
    case INDEX_op_and_i32:
1195
    case INDEX_op_and_i64:
1196
    case INDEX_op_or_i32:
1197
    case INDEX_op_or_i64:
1198
    case INDEX_op_xor_i32:
1199
    case INDEX_op_xor_i64:
1200
    case INDEX_op_andc_i32:
1201
    case INDEX_op_andc_i64:
1202
    case INDEX_op_orc_i32:
1203
    case INDEX_op_orc_i64:
1204
    case INDEX_op_eqv_i32:
1205
    case INDEX_op_eqv_i64:
1206
    case INDEX_op_nand_i32:
1207
    case INDEX_op_nand_i64:
1208
    case INDEX_op_nor_i32:
1209
    case INDEX_op_nor_i64:
1210
    case INDEX_op_div_i32:
1211
    case INDEX_op_div_i64:
1212
    case INDEX_op_rem_i32:
1213
    case INDEX_op_rem_i64:
1214
    case INDEX_op_divu_i32:
1215
    case INDEX_op_divu_i64:
1216
    case INDEX_op_remu_i32:
1217
    case INDEX_op_remu_i64:
1218
    case INDEX_op_shl_i32:
1219
    case INDEX_op_shl_i64:
1220
    case INDEX_op_shr_i32:
1221
    case INDEX_op_shr_i64:
1222
    case INDEX_op_sar_i32:
1223
    case INDEX_op_sar_i64:
1224
    case INDEX_op_rotl_i32:
1225
    case INDEX_op_rotl_i64:
1226
    case INDEX_op_rotr_i32:
1227
    case INDEX_op_rotr_i64:
1228
    case INDEX_op_clz_i32:
1229
    case INDEX_op_clz_i64:
1230
    case INDEX_op_ctz_i32:
1231
    case INDEX_op_ctz_i64:
1232
        tci_args_rrr(insn, &r0, &r1, &r2);
1233
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s",
1234
                           op_name, str_r(r0), str_r(r1), str_r(r2));
1235
        break;
1236

1237
    case INDEX_op_deposit_i32:
1238
    case INDEX_op_deposit_i64:
1239
        tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1240
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %d, %d",
1241
                           op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1242
        break;
1243

1244
    case INDEX_op_extract_i32:
1245
    case INDEX_op_extract_i64:
1246
    case INDEX_op_sextract_i32:
1247
    case INDEX_op_sextract_i64:
1248
        tci_args_rrbb(insn, &r0, &r1, &pos, &len);
1249
        info->fprintf_func(info->stream, "%-12s  %s,%s,%d,%d",
1250
                           op_name, str_r(r0), str_r(r1), pos, len);
1251
        break;
1252

1253
    case INDEX_op_movcond_i32:
1254
    case INDEX_op_movcond_i64:
1255
    case INDEX_op_setcond2_i32:
1256
        tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1257
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1258
                           op_name, str_r(r0), str_r(r1), str_r(r2),
1259
                           str_r(r3), str_r(r4), str_c(c));
1260
        break;
1261

1262
    case INDEX_op_mulu2_i32:
1263
    case INDEX_op_mulu2_i64:
1264
    case INDEX_op_muls2_i32:
1265
    case INDEX_op_muls2_i64:
1266
        tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1267
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1268
                           op_name, str_r(r0), str_r(r1),
1269
                           str_r(r2), str_r(r3));
1270
        break;
1271

1272
    case INDEX_op_add2_i32:
1273
    case INDEX_op_add2_i64:
1274
    case INDEX_op_sub2_i32:
1275
    case INDEX_op_sub2_i64:
1276
        tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1277
        info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s, %s",
1278
                           op_name, str_r(r0), str_r(r1), str_r(r2),
1279
                           str_r(r3), str_r(r4), str_r(r5));
1280
        break;
1281

1282
    case INDEX_op_qemu_ld_a32_i32:
1283
    case INDEX_op_qemu_st_a32_i32:
1284
        len = 1 + 1;
1285
        goto do_qemu_ldst;
1286
    case INDEX_op_qemu_ld_a32_i64:
1287
    case INDEX_op_qemu_st_a32_i64:
1288
    case INDEX_op_qemu_ld_a64_i32:
1289
    case INDEX_op_qemu_st_a64_i32:
1290
        len = 1 + DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1291
        goto do_qemu_ldst;
1292
    case INDEX_op_qemu_ld_a64_i64:
1293
    case INDEX_op_qemu_st_a64_i64:
1294
        len = 2 * DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
1295
        goto do_qemu_ldst;
1296
    do_qemu_ldst:
1297
        switch (len) {
1298
        case 2:
1299
            tci_args_rrm(insn, &r0, &r1, &oi);
1300
            info->fprintf_func(info->stream, "%-12s  %s, %s, %x",
1301
                               op_name, str_r(r0), str_r(r1), oi);
1302
            break;
1303
        case 3:
1304
            tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1305
            info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s",
1306
                               op_name, str_r(r0), str_r(r1),
1307
                               str_r(r2), str_r(r3));
1308
            break;
1309
        case 4:
1310
            tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1311
            info->fprintf_func(info->stream, "%-12s  %s, %s, %s, %s, %s",
1312
                               op_name, str_r(r0), str_r(r1),
1313
                               str_r(r2), str_r(r3), str_r(r4));
1314
            break;
1315
        default:
1316
            g_assert_not_reached();
1317
        }
1318
        break;
1319

1320
    case 0:
1321
        /* tcg_out_nop_fill uses zeros */
1322
        if (insn == 0) {
1323
            info->fprintf_func(info->stream, "align");
1324
            break;
1325
        }
1326
        /* fall through */
1327

1328
    default:
1329
        info->fprintf_func(info->stream, "illegal opcode %d", op);
1330
        break;
1331
    }
1332

1333
    return sizeof(insn);
1334
}
1335

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.