xref: /openbmc/qemu/tcg/tci/tcg-target.c.inc (revision 33aba058c8fcc9b1581b03a1fbac45d8d91baac6)
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2009, 2011 Stefan Weil
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25/* Used for function call generation. */
26#define TCG_TARGET_CALL_STACK_OFFSET    0
27#define TCG_TARGET_STACK_ALIGN          8
28#if TCG_TARGET_REG_BITS == 32
29# define TCG_TARGET_CALL_ARG_I32        TCG_CALL_ARG_EVEN
30# define TCG_TARGET_CALL_ARG_I64        TCG_CALL_ARG_EVEN
31# define TCG_TARGET_CALL_ARG_I128       TCG_CALL_ARG_EVEN
32#else
33# define TCG_TARGET_CALL_ARG_I32        TCG_CALL_ARG_NORMAL
34# define TCG_TARGET_CALL_ARG_I64        TCG_CALL_ARG_NORMAL
35# define TCG_TARGET_CALL_ARG_I128       TCG_CALL_ARG_NORMAL
36#endif
37#define TCG_TARGET_CALL_RET_I128        TCG_CALL_RET_NORMAL
38
39static TCGConstraintSetIndex
40tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
41{
42    switch (op) {
43    case INDEX_op_qemu_ld_i32:
44        return C_O1_I1(r, r);
45    case INDEX_op_qemu_ld_i64:
46        return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
47    case INDEX_op_qemu_st_i32:
48        return C_O0_I2(r, r);
49    case INDEX_op_qemu_st_i64:
50        return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
51
52    default:
53        return C_NotImplemented;
54    }
55}
56
57static const int tcg_target_reg_alloc_order[] = {
58    TCG_REG_R4,
59    TCG_REG_R5,
60    TCG_REG_R6,
61    TCG_REG_R7,
62    TCG_REG_R8,
63    TCG_REG_R9,
64    TCG_REG_R10,
65    TCG_REG_R11,
66    TCG_REG_R12,
67    TCG_REG_R13,
68    TCG_REG_R14,
69    TCG_REG_R15,
70    /* Either 2 or 4 of these are call clobbered, so use them last. */
71    TCG_REG_R3,
72    TCG_REG_R2,
73    TCG_REG_R1,
74    TCG_REG_R0,
75};
76
77/* No call arguments via registers.  All will be stored on the "stack". */
78static const int tcg_target_call_iarg_regs[] = { };
79
80static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
81{
82    tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
83    tcg_debug_assert(slot >= 0 && slot < 128 / TCG_TARGET_REG_BITS);
84    return TCG_REG_R0 + slot;
85}
86
87#ifdef CONFIG_DEBUG_TCG
88static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
89    "r00",
90    "r01",
91    "r02",
92    "r03",
93    "r04",
94    "r05",
95    "r06",
96    "r07",
97    "r08",
98    "r09",
99    "r10",
100    "r11",
101    "r12",
102    "r13",
103    "r14",
104    "r15",
105};
106#endif
107
108static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
109                        intptr_t value, intptr_t addend)
110{
111    intptr_t diff = value - (intptr_t)(code_ptr + 1);
112
113    tcg_debug_assert(addend == 0);
114    tcg_debug_assert(type == 20);
115
116    if (diff == sextract32(diff, 0, type)) {
117        tcg_patch32(code_ptr, deposit32(*code_ptr, 32 - type, type, diff));
118        return true;
119    }
120    return false;
121}
122
123static void stack_bounds_check(TCGReg base, intptr_t offset)
124{
125    if (base == TCG_REG_CALL_STACK) {
126        tcg_debug_assert(offset >= 0);
127        tcg_debug_assert(offset < (TCG_STATIC_CALL_ARGS_SIZE +
128                                   TCG_STATIC_FRAME_SIZE));
129    }
130}
131
132static void tcg_out_op_l(TCGContext *s, TCGOpcode op, TCGLabel *l0)
133{
134    tcg_insn_unit insn = 0;
135
136    tcg_out_reloc(s, s->code_ptr, 20, l0, 0);
137    insn = deposit32(insn, 0, 8, op);
138    tcg_out32(s, insn);
139}
140
141static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0)
142{
143    tcg_insn_unit insn = 0;
144    intptr_t diff;
145
146    /* Special case for exit_tb: map null -> 0. */
147    if (p0 == NULL) {
148        diff = 0;
149    } else {
150        diff = p0 - (void *)(s->code_ptr + 1);
151        tcg_debug_assert(diff != 0);
152        if (diff != sextract32(diff, 0, 20)) {
153            tcg_raise_tb_overflow(s);
154        }
155    }
156    insn = deposit32(insn, 0, 8, op);
157    insn = deposit32(insn, 12, 20, diff);
158    tcg_out32(s, insn);
159}
160
161static void tcg_out_op_r(TCGContext *s, TCGOpcode op, TCGReg r0)
162{
163    tcg_insn_unit insn = 0;
164
165    insn = deposit32(insn, 0, 8, op);
166    insn = deposit32(insn, 8, 4, r0);
167    tcg_out32(s, insn);
168}
169
170static void tcg_out_op_v(TCGContext *s, TCGOpcode op)
171{
172    tcg_out32(s, (uint8_t)op);
173}
174
175static void tcg_out_op_ri(TCGContext *s, TCGOpcode op, TCGReg r0, int32_t i1)
176{
177    tcg_insn_unit insn = 0;
178
179    tcg_debug_assert(i1 == sextract32(i1, 0, 20));
180    insn = deposit32(insn, 0, 8, op);
181    insn = deposit32(insn, 8, 4, r0);
182    insn = deposit32(insn, 12, 20, i1);
183    tcg_out32(s, insn);
184}
185
186static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1)
187{
188    tcg_insn_unit insn = 0;
189
190    tcg_out_reloc(s, s->code_ptr, 20, l1, 0);
191    insn = deposit32(insn, 0, 8, op);
192    insn = deposit32(insn, 8, 4, r0);
193    tcg_out32(s, insn);
194}
195
196static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1)
197{
198    tcg_insn_unit insn = 0;
199
200    insn = deposit32(insn, 0, 8, op);
201    insn = deposit32(insn, 8, 4, r0);
202    insn = deposit32(insn, 12, 4, r1);
203    tcg_out32(s, insn);
204}
205
206static void tcg_out_op_rrm(TCGContext *s, TCGOpcode op,
207                           TCGReg r0, TCGReg r1, TCGArg m2)
208{
209    tcg_insn_unit insn = 0;
210
211    tcg_debug_assert(m2 == extract32(m2, 0, 16));
212    insn = deposit32(insn, 0, 8, op);
213    insn = deposit32(insn, 8, 4, r0);
214    insn = deposit32(insn, 12, 4, r1);
215    insn = deposit32(insn, 16, 16, m2);
216    tcg_out32(s, insn);
217}
218
219static void tcg_out_op_rrr(TCGContext *s, TCGOpcode op,
220                           TCGReg r0, TCGReg r1, TCGReg r2)
221{
222    tcg_insn_unit insn = 0;
223
224    insn = deposit32(insn, 0, 8, op);
225    insn = deposit32(insn, 8, 4, r0);
226    insn = deposit32(insn, 12, 4, r1);
227    insn = deposit32(insn, 16, 4, r2);
228    tcg_out32(s, insn);
229}
230
231static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
232                           TCGReg r0, TCGReg r1, intptr_t i2)
233{
234    tcg_insn_unit insn = 0;
235
236    tcg_debug_assert(i2 == sextract32(i2, 0, 16));
237    insn = deposit32(insn, 0, 8, op);
238    insn = deposit32(insn, 8, 4, r0);
239    insn = deposit32(insn, 12, 4, r1);
240    insn = deposit32(insn, 16, 16, i2);
241    tcg_out32(s, insn);
242}
243
244static void tcg_out_op_rrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
245                            TCGReg r1, uint8_t b2, uint8_t b3)
246{
247    tcg_insn_unit insn = 0;
248
249    tcg_debug_assert(b2 == extract32(b2, 0, 6));
250    tcg_debug_assert(b3 == extract32(b3, 0, 6));
251    insn = deposit32(insn, 0, 8, op);
252    insn = deposit32(insn, 8, 4, r0);
253    insn = deposit32(insn, 12, 4, r1);
254    insn = deposit32(insn, 16, 6, b2);
255    insn = deposit32(insn, 22, 6, b3);
256    tcg_out32(s, insn);
257}
258
259static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
260                            TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
261{
262    tcg_insn_unit insn = 0;
263
264    insn = deposit32(insn, 0, 8, op);
265    insn = deposit32(insn, 8, 4, r0);
266    insn = deposit32(insn, 12, 4, r1);
267    insn = deposit32(insn, 16, 4, r2);
268    insn = deposit32(insn, 20, 4, c3);
269    tcg_out32(s, insn);
270}
271
272static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
273                             TCGReg r1, TCGReg r2, uint8_t b3, uint8_t b4)
274{
275    tcg_insn_unit insn = 0;
276
277    tcg_debug_assert(b3 == extract32(b3, 0, 6));
278    tcg_debug_assert(b4 == extract32(b4, 0, 6));
279    insn = deposit32(insn, 0, 8, op);
280    insn = deposit32(insn, 8, 4, r0);
281    insn = deposit32(insn, 12, 4, r1);
282    insn = deposit32(insn, 16, 4, r2);
283    insn = deposit32(insn, 20, 6, b3);
284    insn = deposit32(insn, 26, 6, b4);
285    tcg_out32(s, insn);
286}
287
288static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
289                            TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
290{
291    tcg_insn_unit insn = 0;
292
293    insn = deposit32(insn, 0, 8, op);
294    insn = deposit32(insn, 8, 4, r0);
295    insn = deposit32(insn, 12, 4, r1);
296    insn = deposit32(insn, 16, 4, r2);
297    insn = deposit32(insn, 20, 4, r3);
298    tcg_out32(s, insn);
299}
300
301static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
302                              TCGReg r0, TCGReg r1, TCGReg r2,
303                              TCGReg r3, TCGReg r4, TCGCond c5)
304{
305    tcg_insn_unit insn = 0;
306
307    insn = deposit32(insn, 0, 8, op);
308    insn = deposit32(insn, 8, 4, r0);
309    insn = deposit32(insn, 12, 4, r1);
310    insn = deposit32(insn, 16, 4, r2);
311    insn = deposit32(insn, 20, 4, r3);
312    insn = deposit32(insn, 24, 4, r4);
313    insn = deposit32(insn, 28, 4, c5);
314    tcg_out32(s, insn);
315}
316
317static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
318                         TCGReg base, intptr_t offset)
319{
320    stack_bounds_check(base, offset);
321    if (offset != sextract32(offset, 0, 16)) {
322        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
323        tcg_out_op_rrr(s, INDEX_op_add, TCG_REG_TMP, TCG_REG_TMP, base);
324        base = TCG_REG_TMP;
325        offset = 0;
326    }
327    tcg_out_op_rrs(s, op, val, base, offset);
328}
329
330static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
331                       intptr_t offset)
332{
333    TCGOpcode op = INDEX_op_ld;
334
335    if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
336        op = INDEX_op_ld32u;
337    }
338    tcg_out_ldst(s, op, val, base, offset);
339}
340
341static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
342{
343    tcg_out_op_rr(s, INDEX_op_mov, ret, arg);
344    return true;
345}
346
347static void tcg_out_movi(TCGContext *s, TCGType type,
348                         TCGReg ret, tcg_target_long arg)
349{
350    switch (type) {
351    case TCG_TYPE_I32:
352#if TCG_TARGET_REG_BITS == 64
353        arg = (int32_t)arg;
354        /* fall through */
355    case TCG_TYPE_I64:
356#endif
357        break;
358    default:
359        g_assert_not_reached();
360    }
361
362    if (arg == sextract32(arg, 0, 20)) {
363        tcg_out_op_ri(s, INDEX_op_tci_movi, ret, arg);
364    } else {
365        tcg_insn_unit insn = 0;
366
367        new_pool_label(s, arg, 20, s->code_ptr, 0);
368        insn = deposit32(insn, 0, 8, INDEX_op_tci_movl);
369        insn = deposit32(insn, 8, 4, ret);
370        tcg_out32(s, insn);
371    }
372}
373
374static void tcg_out_extract(TCGContext *s, TCGType type, TCGReg rd,
375                            TCGReg rs, unsigned pos, unsigned len)
376{
377    tcg_out_op_rrbb(s, INDEX_op_extract, rd, rs, pos, len);
378}
379
380static const TCGOutOpExtract outop_extract = {
381    .base.static_constraint = C_O1_I1(r, r),
382    .out_rr = tcg_out_extract,
383};
384
385static void tcg_out_sextract(TCGContext *s, TCGType type, TCGReg rd,
386                             TCGReg rs, unsigned pos, unsigned len)
387{
388    tcg_out_op_rrbb(s, INDEX_op_sextract, rd, rs, pos, len);
389}
390
391static const TCGOutOpExtract outop_sextract = {
392    .base.static_constraint = C_O1_I1(r, r),
393    .out_rr = tcg_out_sextract,
394};
395
396static const TCGOutOpExtract2 outop_extract2 = {
397    .base.static_constraint = C_NotImplemented,
398};
399
400static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
401{
402    tcg_out_sextract(s, type, rd, rs, 0, 8);
403}
404
405static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
406{
407    tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 8);
408}
409
410static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
411{
412    tcg_out_sextract(s, type, rd, rs, 0, 16);
413}
414
415static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
416{
417    tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 16);
418}
419
420static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
421{
422    tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
423    tcg_out_sextract(s, TCG_TYPE_I64, rd, rs, 0, 32);
424}
425
426static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
427{
428    tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
429    tcg_out_extract(s, TCG_TYPE_I64, rd, rs, 0, 32);
430}
431
432static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
433{
434    tcg_out_ext32s(s, rd, rs);
435}
436
437static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
438{
439    tcg_out_ext32u(s, rd, rs);
440}
441
442static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
443{
444    tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
445    tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
446}
447
448static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
449{
450    return false;
451}
452
453static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
454                             tcg_target_long imm)
455{
456    /* This function is only used for passing structs by reference. */
457    g_assert_not_reached();
458}
459
460static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
461                         const TCGHelperInfo *info)
462{
463    ffi_cif *cif = info->cif;
464    tcg_insn_unit insn = 0;
465    uint8_t which;
466
467    if (cif->rtype == &ffi_type_void) {
468        which = 0;
469    } else {
470        tcg_debug_assert(cif->rtype->size == 4 ||
471                         cif->rtype->size == 8 ||
472                         cif->rtype->size == 16);
473        which = ctz32(cif->rtype->size) - 1;
474    }
475    new_pool_l2(s, 20, s->code_ptr, 0, (uintptr_t)func, (uintptr_t)cif);
476    insn = deposit32(insn, 0, 8, INDEX_op_call);
477    insn = deposit32(insn, 8, 4, which);
478    tcg_out32(s, insn);
479}
480
481static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg)
482{
483    tcg_out_op_p(s, INDEX_op_exit_tb, (void *)arg);
484}
485
486static void tcg_out_goto_tb(TCGContext *s, int which)
487{
488    /* indirect jump method. */
489    tcg_out_op_p(s, INDEX_op_goto_tb, (void *)get_jmp_target_addr(s, which));
490    set_jmp_reset_offset(s, which);
491}
492
493static void tcg_out_goto_ptr(TCGContext *s, TCGReg a0)
494{
495    tcg_out_op_r(s, INDEX_op_goto_ptr, a0);
496}
497
498void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
499                              uintptr_t jmp_rx, uintptr_t jmp_rw)
500{
501    /* Always indirect, nothing to do */
502}
503
504static void tgen_add(TCGContext *s, TCGType type,
505                     TCGReg a0, TCGReg a1, TCGReg a2)
506{
507    tcg_out_op_rrr(s, INDEX_op_add, a0, a1, a2);
508}
509
510static const TCGOutOpBinary outop_add = {
511    .base.static_constraint = C_O1_I2(r, r, r),
512    .out_rrr = tgen_add,
513};
514
515static TCGConstraintSetIndex cset_addsubcarry(TCGType type, unsigned flags)
516{
517    return type == TCG_TYPE_REG ? C_O1_I2(r, r, r) : C_NotImplemented;
518}
519
520static void tgen_addco(TCGContext *s, TCGType type,
521                       TCGReg a0, TCGReg a1, TCGReg a2)
522{
523    tcg_out_op_rrr(s, INDEX_op_addco, a0, a1, a2);
524}
525
526static const TCGOutOpBinary outop_addco = {
527    .base.static_constraint = C_Dynamic,
528    .base.dynamic_constraint = cset_addsubcarry,
529    .out_rrr = tgen_addco,
530};
531
532static void tgen_addci(TCGContext *s, TCGType type,
533                       TCGReg a0, TCGReg a1, TCGReg a2)
534{
535    tcg_out_op_rrr(s, INDEX_op_addci, a0, a1, a2);
536}
537
538static const TCGOutOpAddSubCarry outop_addci = {
539    .base.static_constraint = C_Dynamic,
540    .base.dynamic_constraint = cset_addsubcarry,
541    .out_rrr = tgen_addci,
542};
543
544static void tgen_addcio(TCGContext *s, TCGType type,
545                        TCGReg a0, TCGReg a1, TCGReg a2)
546{
547    tcg_out_op_rrr(s, INDEX_op_addcio, a0, a1, a2);
548}
549
550static const TCGOutOpBinary outop_addcio = {
551    .base.static_constraint = C_Dynamic,
552    .base.dynamic_constraint = cset_addsubcarry,
553    .out_rrr = tgen_addcio,
554};
555
556static void tcg_out_set_carry(TCGContext *s)
557{
558    tcg_out_op_v(s, INDEX_op_tci_setcarry);
559}
560
561static void tgen_and(TCGContext *s, TCGType type,
562                     TCGReg a0, TCGReg a1, TCGReg a2)
563{
564    tcg_out_op_rrr(s, INDEX_op_and, a0, a1, a2);
565}
566
567static const TCGOutOpBinary outop_and = {
568    .base.static_constraint = C_O1_I2(r, r, r),
569    .out_rrr = tgen_and,
570};
571
572static void tgen_andc(TCGContext *s, TCGType type,
573                      TCGReg a0, TCGReg a1, TCGReg a2)
574{
575    tcg_out_op_rrr(s, INDEX_op_andc, a0, a1, a2);
576}
577
578static const TCGOutOpBinary outop_andc = {
579    .base.static_constraint = C_O1_I2(r, r, r),
580    .out_rrr = tgen_andc,
581};
582
583static void tgen_clz(TCGContext *s, TCGType type,
584                      TCGReg a0, TCGReg a1, TCGReg a2)
585{
586    TCGOpcode opc = (type == TCG_TYPE_I32
587                     ? INDEX_op_tci_clz32
588                     : INDEX_op_clz);
589    tcg_out_op_rrr(s, opc, a0, a1, a2);
590}
591
592static const TCGOutOpBinary outop_clz = {
593    .base.static_constraint = C_O1_I2(r, r, r),
594    .out_rrr = tgen_clz,
595};
596
597static void tgen_ctz(TCGContext *s, TCGType type,
598                      TCGReg a0, TCGReg a1, TCGReg a2)
599{
600    TCGOpcode opc = (type == TCG_TYPE_I32
601                     ? INDEX_op_tci_ctz32
602                     : INDEX_op_ctz);
603    tcg_out_op_rrr(s, opc, a0, a1, a2);
604}
605
606static const TCGOutOpBinary outop_ctz = {
607    .base.static_constraint = C_O1_I2(r, r, r),
608    .out_rrr = tgen_ctz,
609};
610
611static void tgen_deposit(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
612                         TCGReg a2, unsigned ofs, unsigned len)
613{
614    tcg_out_op_rrrbb(s, INDEX_op_deposit, a0, a1, a2, ofs, len);
615}
616
617static const TCGOutOpDeposit outop_deposit = {
618    .base.static_constraint = C_O1_I2(r, r, r),
619    .out_rrr = tgen_deposit,
620};
621
622static void tgen_divs(TCGContext *s, TCGType type,
623                      TCGReg a0, TCGReg a1, TCGReg a2)
624{
625    TCGOpcode opc = (type == TCG_TYPE_I32
626                     ? INDEX_op_tci_divs32
627                     : INDEX_op_divs);
628    tcg_out_op_rrr(s, opc, a0, a1, a2);
629}
630
631static const TCGOutOpBinary outop_divs = {
632    .base.static_constraint = C_O1_I2(r, r, r),
633    .out_rrr = tgen_divs,
634};
635
636static const TCGOutOpDivRem outop_divs2 = {
637    .base.static_constraint = C_NotImplemented,
638};
639
640static void tgen_divu(TCGContext *s, TCGType type,
641                      TCGReg a0, TCGReg a1, TCGReg a2)
642{
643    TCGOpcode opc = (type == TCG_TYPE_I32
644                     ? INDEX_op_tci_divu32
645                     : INDEX_op_divu);
646    tcg_out_op_rrr(s, opc, a0, a1, a2);
647}
648
649static const TCGOutOpBinary outop_divu = {
650    .base.static_constraint = C_O1_I2(r, r, r),
651    .out_rrr = tgen_divu,
652};
653
654static const TCGOutOpDivRem outop_divu2 = {
655    .base.static_constraint = C_NotImplemented,
656};
657
658static void tgen_eqv(TCGContext *s, TCGType type,
659                     TCGReg a0, TCGReg a1, TCGReg a2)
660{
661    tcg_out_op_rrr(s, INDEX_op_eqv, a0, a1, a2);
662}
663
664static const TCGOutOpBinary outop_eqv = {
665    .base.static_constraint = C_O1_I2(r, r, r),
666    .out_rrr = tgen_eqv,
667};
668
669#if TCG_TARGET_REG_BITS == 64
670static void tgen_extrh_i64_i32(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1)
671{
672    tcg_out_extract(s, TCG_TYPE_I64, a0, a1, 32, 32);
673}
674
675static const TCGOutOpUnary outop_extrh_i64_i32 = {
676    .base.static_constraint = C_O1_I1(r, r),
677    .out_rr = tgen_extrh_i64_i32,
678};
679#endif
680
681static void tgen_mul(TCGContext *s, TCGType type,
682                     TCGReg a0, TCGReg a1, TCGReg a2)
683{
684    tcg_out_op_rrr(s, INDEX_op_mul, a0, a1, a2);
685}
686
687static const TCGOutOpBinary outop_mul = {
688    .base.static_constraint = C_O1_I2(r, r, r),
689    .out_rrr = tgen_mul,
690};
691
692static TCGConstraintSetIndex cset_mul2(TCGType type, unsigned flags)
693{
694    return type == TCG_TYPE_REG ? C_O2_I2(r, r, r, r) : C_NotImplemented;
695}
696
697static void tgen_muls2(TCGContext *s, TCGType type,
698                       TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
699{
700    tcg_out_op_rrrr(s, INDEX_op_muls2, a0, a1, a2, a3);
701}
702
703static const TCGOutOpMul2 outop_muls2 = {
704    .base.static_constraint = C_Dynamic,
705    .base.dynamic_constraint = cset_mul2,
706    .out_rrrr = tgen_muls2,
707};
708
709static const TCGOutOpBinary outop_mulsh = {
710    .base.static_constraint = C_NotImplemented,
711};
712
713static void tgen_mulu2(TCGContext *s, TCGType type,
714                       TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
715{
716    tcg_out_op_rrrr(s, INDEX_op_mulu2, a0, a1, a2, a3);
717}
718
719static const TCGOutOpMul2 outop_mulu2 = {
720    .base.static_constraint = C_Dynamic,
721    .base.dynamic_constraint = cset_mul2,
722    .out_rrrr = tgen_mulu2,
723};
724
725static const TCGOutOpBinary outop_muluh = {
726    .base.static_constraint = C_NotImplemented,
727};
728
729static void tgen_nand(TCGContext *s, TCGType type,
730                     TCGReg a0, TCGReg a1, TCGReg a2)
731{
732    tcg_out_op_rrr(s, INDEX_op_nand, a0, a1, a2);
733}
734
735static const TCGOutOpBinary outop_nand = {
736    .base.static_constraint = C_O1_I2(r, r, r),
737    .out_rrr = tgen_nand,
738};
739
740static void tgen_nor(TCGContext *s, TCGType type,
741                     TCGReg a0, TCGReg a1, TCGReg a2)
742{
743    tcg_out_op_rrr(s, INDEX_op_nor, a0, a1, a2);
744}
745
746static const TCGOutOpBinary outop_nor = {
747    .base.static_constraint = C_O1_I2(r, r, r),
748    .out_rrr = tgen_nor,
749};
750
751static void tgen_or(TCGContext *s, TCGType type,
752                     TCGReg a0, TCGReg a1, TCGReg a2)
753{
754    tcg_out_op_rrr(s, INDEX_op_or, a0, a1, a2);
755}
756
757static const TCGOutOpBinary outop_or = {
758    .base.static_constraint = C_O1_I2(r, r, r),
759    .out_rrr = tgen_or,
760};
761
762static void tgen_orc(TCGContext *s, TCGType type,
763                     TCGReg a0, TCGReg a1, TCGReg a2)
764{
765    tcg_out_op_rrr(s, INDEX_op_orc, a0, a1, a2);
766}
767
768static const TCGOutOpBinary outop_orc = {
769    .base.static_constraint = C_O1_I2(r, r, r),
770    .out_rrr = tgen_orc,
771};
772
773static void tgen_rems(TCGContext *s, TCGType type,
774                      TCGReg a0, TCGReg a1, TCGReg a2)
775{
776    TCGOpcode opc = (type == TCG_TYPE_I32
777                     ? INDEX_op_tci_rems32
778                     : INDEX_op_rems);
779    tcg_out_op_rrr(s, opc, a0, a1, a2);
780}
781
782static const TCGOutOpBinary outop_rems = {
783    .base.static_constraint = C_O1_I2(r, r, r),
784    .out_rrr = tgen_rems,
785};
786
787static void tgen_remu(TCGContext *s, TCGType type,
788                      TCGReg a0, TCGReg a1, TCGReg a2)
789{
790    TCGOpcode opc = (type == TCG_TYPE_I32
791                     ? INDEX_op_tci_remu32
792                     : INDEX_op_remu);
793    tcg_out_op_rrr(s, opc, a0, a1, a2);
794}
795
796static const TCGOutOpBinary outop_remu = {
797    .base.static_constraint = C_O1_I2(r, r, r),
798    .out_rrr = tgen_remu,
799};
800
801static void tgen_rotl(TCGContext *s, TCGType type,
802                     TCGReg a0, TCGReg a1, TCGReg a2)
803{
804    TCGOpcode opc = (type == TCG_TYPE_I32
805                     ? INDEX_op_tci_rotl32
806                     : INDEX_op_rotl);
807    tcg_out_op_rrr(s, opc, a0, a1, a2);
808}
809
810static const TCGOutOpBinary outop_rotl = {
811    .base.static_constraint = C_O1_I2(r, r, r),
812    .out_rrr = tgen_rotl,
813};
814
815static void tgen_rotr(TCGContext *s, TCGType type,
816                     TCGReg a0, TCGReg a1, TCGReg a2)
817{
818    TCGOpcode opc = (type == TCG_TYPE_I32
819                     ? INDEX_op_tci_rotr32
820                     : INDEX_op_rotr);
821    tcg_out_op_rrr(s, opc, a0, a1, a2);
822}
823
824static const TCGOutOpBinary outop_rotr = {
825    .base.static_constraint = C_O1_I2(r, r, r),
826    .out_rrr = tgen_rotr,
827};
828
829static void tgen_sar(TCGContext *s, TCGType type,
830                     TCGReg a0, TCGReg a1, TCGReg a2)
831{
832    if (type < TCG_TYPE_REG) {
833        tcg_out_ext32s(s, TCG_REG_TMP, a1);
834        a1 = TCG_REG_TMP;
835    }
836    tcg_out_op_rrr(s, INDEX_op_sar, a0, a1, a2);
837}
838
839static const TCGOutOpBinary outop_sar = {
840    .base.static_constraint = C_O1_I2(r, r, r),
841    .out_rrr = tgen_sar,
842};
843
844static void tgen_shl(TCGContext *s, TCGType type,
845                     TCGReg a0, TCGReg a1, TCGReg a2)
846{
847    tcg_out_op_rrr(s, INDEX_op_shl, a0, a1, a2);
848}
849
850static const TCGOutOpBinary outop_shl = {
851    .base.static_constraint = C_O1_I2(r, r, r),
852    .out_rrr = tgen_shl,
853};
854
855static void tgen_shr(TCGContext *s, TCGType type,
856                     TCGReg a0, TCGReg a1, TCGReg a2)
857{
858    if (type < TCG_TYPE_REG) {
859        tcg_out_ext32u(s, TCG_REG_TMP, a1);
860        a1 = TCG_REG_TMP;
861    }
862    tcg_out_op_rrr(s, INDEX_op_shr, a0, a1, a2);
863}
864
865static const TCGOutOpBinary outop_shr = {
866    .base.static_constraint = C_O1_I2(r, r, r),
867    .out_rrr = tgen_shr,
868};
869
870static void tgen_sub(TCGContext *s, TCGType type,
871                     TCGReg a0, TCGReg a1, TCGReg a2)
872{
873    tcg_out_op_rrr(s, INDEX_op_sub, a0, a1, a2);
874}
875
876static const TCGOutOpSubtract outop_sub = {
877    .base.static_constraint = C_O1_I2(r, r, r),
878    .out_rrr = tgen_sub,
879};
880
881static void tgen_subbo(TCGContext *s, TCGType type,
882                       TCGReg a0, TCGReg a1, TCGReg a2)
883{
884    tcg_out_op_rrr(s, INDEX_op_subbo, a0, a1, a2);
885}
886
887static const TCGOutOpAddSubCarry outop_subbo = {
888    .base.static_constraint = C_Dynamic,
889    .base.dynamic_constraint = cset_addsubcarry,
890    .out_rrr = tgen_subbo,
891};
892
893static void tgen_subbi(TCGContext *s, TCGType type,
894                       TCGReg a0, TCGReg a1, TCGReg a2)
895{
896    tcg_out_op_rrr(s, INDEX_op_subbi, a0, a1, a2);
897}
898
899static const TCGOutOpAddSubCarry outop_subbi = {
900    .base.static_constraint = C_Dynamic,
901    .base.dynamic_constraint = cset_addsubcarry,
902    .out_rrr = tgen_subbi,
903};
904
905static void tgen_subbio(TCGContext *s, TCGType type,
906                        TCGReg a0, TCGReg a1, TCGReg a2)
907{
908    tcg_out_op_rrr(s, INDEX_op_subbio, a0, a1, a2);
909}
910
911static const TCGOutOpAddSubCarry outop_subbio = {
912    .base.static_constraint = C_Dynamic,
913    .base.dynamic_constraint = cset_addsubcarry,
914    .out_rrr = tgen_subbio,
915};
916
917static void tcg_out_set_borrow(TCGContext *s)
918{
919    tcg_out_op_v(s, INDEX_op_tci_setcarry);  /* borrow == carry */
920}
921
922static void tgen_xor(TCGContext *s, TCGType type,
923                     TCGReg a0, TCGReg a1, TCGReg a2)
924{
925    tcg_out_op_rrr(s, INDEX_op_xor, a0, a1, a2);
926}
927
928static const TCGOutOpBinary outop_xor = {
929    .base.static_constraint = C_O1_I2(r, r, r),
930    .out_rrr = tgen_xor,
931};
932
933static void tgen_ctpop(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
934{
935    tcg_out_op_rr(s, INDEX_op_ctpop, a0, a1);
936}
937
938static TCGConstraintSetIndex cset_ctpop(TCGType type, unsigned flags)
939{
940    return type == TCG_TYPE_REG ? C_O1_I1(r, r) : C_NotImplemented;
941}
942
943static const TCGOutOpUnary outop_ctpop = {
944    .base.static_constraint = C_Dynamic,
945    .base.dynamic_constraint = cset_ctpop,
946    .out_rr = tgen_ctpop,
947};
948
949static void tgen_bswap16(TCGContext *s, TCGType type,
950                         TCGReg a0, TCGReg a1, unsigned flags)
951{
952    tcg_out_op_rr(s, INDEX_op_bswap16, a0, a1);
953    if (flags & TCG_BSWAP_OS) {
954        tcg_out_sextract(s, TCG_TYPE_REG, a0, a0, 0, 16);
955    }
956}
957
958static const TCGOutOpBswap outop_bswap16 = {
959    .base.static_constraint = C_O1_I1(r, r),
960    .out_rr = tgen_bswap16,
961};
962
963static void tgen_bswap32(TCGContext *s, TCGType type,
964                         TCGReg a0, TCGReg a1, unsigned flags)
965{
966    tcg_out_op_rr(s, INDEX_op_bswap32, a0, a1);
967    if (flags & TCG_BSWAP_OS) {
968        tcg_out_sextract(s, TCG_TYPE_REG, a0, a0, 0, 32);
969    }
970}
971
972static const TCGOutOpBswap outop_bswap32 = {
973    .base.static_constraint = C_O1_I1(r, r),
974    .out_rr = tgen_bswap32,
975};
976
977#if TCG_TARGET_REG_BITS == 64
978static void tgen_bswap64(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
979{
980    tcg_out_op_rr(s, INDEX_op_bswap64, a0, a1);
981}
982
983static const TCGOutOpUnary outop_bswap64 = {
984    .base.static_constraint = C_O1_I1(r, r),
985    .out_rr = tgen_bswap64,
986};
987#endif
988
989static void tgen_neg(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
990{
991    tcg_out_op_rr(s, INDEX_op_neg, a0, a1);
992}
993
994static const TCGOutOpUnary outop_neg = {
995    .base.static_constraint = C_O1_I1(r, r),
996    .out_rr = tgen_neg,
997};
998
999static void tgen_not(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
1000{
1001    tcg_out_op_rr(s, INDEX_op_not, a0, a1);
1002}
1003
1004static const TCGOutOpUnary outop_not = {
1005    .base.static_constraint = C_O1_I1(r, r),
1006    .out_rr = tgen_not,
1007};
1008
1009static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
1010                         TCGReg dest, TCGReg arg1, TCGReg arg2)
1011{
1012    TCGOpcode opc = (type == TCG_TYPE_I32
1013                     ? INDEX_op_tci_setcond32
1014                     : INDEX_op_setcond);
1015    tcg_out_op_rrrc(s, opc, dest, arg1, arg2, cond);
1016}
1017
1018static const TCGOutOpSetcond outop_setcond = {
1019    .base.static_constraint = C_O1_I2(r, r, r),
1020    .out_rrr = tgen_setcond,
1021};
1022
1023static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
1024                            TCGReg dest, TCGReg arg1, TCGReg arg2)
1025{
1026    tgen_setcond(s, type, cond, dest, arg1, arg2);
1027    tgen_neg(s, type, dest, dest);
1028}
1029
1030static const TCGOutOpSetcond outop_negsetcond = {
1031    .base.static_constraint = C_O1_I2(r, r, r),
1032    .out_rrr = tgen_negsetcond,
1033};
1034
1035static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
1036                        TCGReg arg0, TCGReg arg1, TCGLabel *l)
1037{
1038    tgen_setcond(s, type, cond, TCG_REG_TMP, arg0, arg1);
1039    tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, l);
1040}
1041
1042static const TCGOutOpBrcond outop_brcond = {
1043    .base.static_constraint = C_O0_I2(r, r),
1044    .out_rr = tgen_brcond,
1045};
1046
1047static void tgen_movcond(TCGContext *s, TCGType type, TCGCond cond,
1048                         TCGReg ret, TCGReg c1, TCGArg c2, bool const_c2,
1049                         TCGArg vt, bool const_vt, TCGArg vf, bool consf_vf)
1050{
1051    TCGOpcode opc = (type == TCG_TYPE_I32
1052                     ? INDEX_op_tci_movcond32
1053                     : INDEX_op_movcond);
1054    tcg_out_op_rrrrrc(s, opc, ret, c1, c2, vt, vf, cond);
1055}
1056
1057static const TCGOutOpMovcond outop_movcond = {
1058    .base.static_constraint = C_O1_I4(r, r, r, r, r),
1059    .out = tgen_movcond,
1060};
1061
1062static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
1063                         TCGArg bl, bool const_bl,
1064                         TCGArg bh, bool const_bh, TCGLabel *l)
1065{
1066    tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
1067                      al, ah, bl, bh, cond);
1068    tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, l);
1069}
1070
1071#if TCG_TARGET_REG_BITS != 32
1072__attribute__((unused))
1073#endif
1074static const TCGOutOpBrcond2 outop_brcond2 = {
1075    .base.static_constraint = C_O0_I4(r, r, r, r),
1076    .out = tgen_brcond2,
1077};
1078
1079static void tgen_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
1080                          TCGReg al, TCGReg ah,
1081                          TCGArg bl, bool const_bl,
1082                          TCGArg bh, bool const_bh)
1083{
1084    tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, ret, al, ah, bl, bh, cond);
1085}
1086
1087#if TCG_TARGET_REG_BITS != 32
1088__attribute__((unused))
1089#endif
1090static const TCGOutOpSetcond2 outop_setcond2 = {
1091    .base.static_constraint = C_O1_I4(r, r, r, r, r),
1092    .out = tgen_setcond2,
1093};
1094
1095static void tcg_out_mb(TCGContext *s, unsigned a0)
1096{
1097    tcg_out_op_v(s, INDEX_op_mb);
1098}
1099
1100static void tcg_out_br(TCGContext *s, TCGLabel *l)
1101{
1102    tcg_out_op_l(s, INDEX_op_br, l);
1103}
1104
1105static void tgen_ld8u(TCGContext *s, TCGType type, TCGReg dest,
1106                      TCGReg base, ptrdiff_t offset)
1107{
1108    tcg_out_ldst(s, INDEX_op_ld8u, dest, base, offset);
1109}
1110
1111static const TCGOutOpLoad outop_ld8u = {
1112    .base.static_constraint = C_O1_I1(r, r),
1113    .out = tgen_ld8u,
1114};
1115
1116static void tgen_ld8s(TCGContext *s, TCGType type, TCGReg dest,
1117                      TCGReg base, ptrdiff_t offset)
1118{
1119    tcg_out_ldst(s, INDEX_op_ld8s, dest, base, offset);
1120}
1121
1122static const TCGOutOpLoad outop_ld8s = {
1123    .base.static_constraint = C_O1_I1(r, r),
1124    .out = tgen_ld8s,
1125};
1126
1127static void tgen_ld16u(TCGContext *s, TCGType type, TCGReg dest,
1128                       TCGReg base, ptrdiff_t offset)
1129{
1130    tcg_out_ldst(s, INDEX_op_ld16u, dest, base, offset);
1131}
1132
1133static const TCGOutOpLoad outop_ld16u = {
1134    .base.static_constraint = C_O1_I1(r, r),
1135    .out = tgen_ld16u,
1136};
1137
1138static void tgen_ld16s(TCGContext *s, TCGType type, TCGReg dest,
1139                       TCGReg base, ptrdiff_t offset)
1140{
1141    tcg_out_ldst(s, INDEX_op_ld16s, dest, base, offset);
1142}
1143
1144static const TCGOutOpLoad outop_ld16s = {
1145    .base.static_constraint = C_O1_I1(r, r),
1146    .out = tgen_ld16s,
1147};
1148
1149#if TCG_TARGET_REG_BITS == 64
1150static void tgen_ld32u(TCGContext *s, TCGType type, TCGReg dest,
1151                       TCGReg base, ptrdiff_t offset)
1152{
1153    tcg_out_ldst(s, INDEX_op_ld32u, dest, base, offset);
1154}
1155
1156static const TCGOutOpLoad outop_ld32u = {
1157    .base.static_constraint = C_O1_I1(r, r),
1158    .out = tgen_ld32u,
1159};
1160
1161static void tgen_ld32s(TCGContext *s, TCGType type, TCGReg dest,
1162                       TCGReg base, ptrdiff_t offset)
1163{
1164    tcg_out_ldst(s, INDEX_op_ld32s, dest, base, offset);
1165}
1166
1167static const TCGOutOpLoad outop_ld32s = {
1168    .base.static_constraint = C_O1_I1(r, r),
1169    .out = tgen_ld32s,
1170};
1171#endif
1172
1173static void tgen_st8(TCGContext *s, TCGType type, TCGReg data,
1174                     TCGReg base, ptrdiff_t offset)
1175{
1176    tcg_out_ldst(s, INDEX_op_st8, data, base, offset);
1177}
1178
1179static const TCGOutOpStore outop_st8 = {
1180    .base.static_constraint = C_O0_I2(r, r),
1181    .out_r = tgen_st8,
1182};
1183
1184static void tgen_st16(TCGContext *s, TCGType type, TCGReg data,
1185                      TCGReg base, ptrdiff_t offset)
1186{
1187    tcg_out_ldst(s, INDEX_op_st16, data, base, offset);
1188}
1189
1190static const TCGOutOpStore outop_st16 = {
1191    .base.static_constraint = C_O0_I2(r, r),
1192    .out_r = tgen_st16,
1193};
1194
1195static const TCGOutOpStore outop_st = {
1196    .base.static_constraint = C_O0_I2(r, r),
1197    .out_r = tcg_out_st,
1198};
1199
1200
1201static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1202                       const TCGArg args[TCG_MAX_OP_ARGS],
1203                       const int const_args[TCG_MAX_OP_ARGS])
1204{
1205    switch (opc) {
1206    case INDEX_op_qemu_ld_i64:
1207    case INDEX_op_qemu_st_i64:
1208        if (TCG_TARGET_REG_BITS == 32) {
1209            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[3]);
1210            tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], TCG_REG_TMP);
1211            break;
1212        }
1213        /* fall through */
1214    case INDEX_op_qemu_ld_i32:
1215    case INDEX_op_qemu_st_i32:
1216        if (TCG_TARGET_REG_BITS == 64 && s->addr_type == TCG_TYPE_I32) {
1217            tcg_out_ext32u(s, TCG_REG_TMP, args[1]);
1218            tcg_out_op_rrm(s, opc, args[0], TCG_REG_TMP, args[2]);
1219        } else {
1220            tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
1221        }
1222        break;
1223
1224    case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1225    case INDEX_op_exit_tb:  /* Always emitted via tcg_out_exit_tb.  */
1226    case INDEX_op_goto_tb:  /* Always emitted via tcg_out_goto_tb.  */
1227    default:
1228        g_assert_not_reached();
1229    }
1230}
1231
1232static void tcg_out_st(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
1233                       intptr_t offset)
1234{
1235    TCGOpcode op = INDEX_op_st;
1236
1237    if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1238        op = INDEX_op_st32;
1239    }
1240    tcg_out_ldst(s, op, val, base, offset);
1241}
1242
1243static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
1244                               TCGReg base, intptr_t ofs)
1245{
1246    return false;
1247}
1248
1249/* Test if a constant matches the constraint. */
1250static bool tcg_target_const_match(int64_t val, int ct,
1251                                   TCGType type, TCGCond cond, int vece)
1252{
1253    return ct & TCG_CT_CONST;
1254}
1255
1256static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1257{
1258    memset(p, 0, sizeof(*p) * count);
1259}
1260
1261static void tcg_target_init(TCGContext *s)
1262{
1263    /* The current code uses uint8_t for tcg operations. */
1264    tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX);
1265
1266    /* Registers available for 32 bit operations. */
1267    tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1;
1268    /* Registers available for 64 bit operations. */
1269    tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1;
1270    /*
1271     * The interpreter "registers" are in the local stack frame and
1272     * cannot be clobbered by the called helper functions.  However,
1273     * the interpreter assumes a 128-bit return value and assigns to
1274     * the return value registers.
1275     */
1276    tcg_target_call_clobber_regs =
1277        MAKE_64BIT_MASK(TCG_REG_R0, 128 / TCG_TARGET_REG_BITS);
1278
1279    s->reserved_regs = 0;
1280    tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
1281    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
1282
1283    /* The call arguments come first, followed by the temp storage. */
1284    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
1285                  TCG_STATIC_FRAME_SIZE);
1286}
1287
1288/* Generate global QEMU prologue and epilogue code. */
1289static inline void tcg_target_qemu_prologue(TCGContext *s)
1290{
1291}
1292
1293static void tcg_out_tb_start(TCGContext *s)
1294{
1295    /* nothing to do */
1296}
1297
1298bool tcg_target_has_memory_bswap(MemOp memop)
1299{
1300    return true;
1301}
1302
1303static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1304{
1305    g_assert_not_reached();
1306}
1307
1308static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1309{
1310    g_assert_not_reached();
1311}
1312