Merge tag 'pull-ppc-20230205' of https://gitlab.com/danielhb/qemu into staging
[qemu.git] / tcg / loongarch64 / tcg-target.c.inc
blobc5f55afd682846b95be8d0d1409f38f1bd45991e
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
5  *
6  * Based on tcg/riscv/tcg-target.c.inc
7  *
8  * Copyright (c) 2018 SiFive, Inc
9  * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
10  * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
11  * Copyright (c) 2008 Fabrice Bellard
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a copy
14  * of this software and associated documentation files (the "Software"), to deal
15  * in the Software without restriction, including without limitation the rights
16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17  * copies of the Software, and to permit persons to whom the Software is
18  * furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29  * THE SOFTWARE.
30  */
32 #include "../tcg-ldst.c.inc"
34 #ifdef CONFIG_DEBUG_TCG
35 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
36     "zero",
37     "ra",
38     "tp",
39     "sp",
40     "a0",
41     "a1",
42     "a2",
43     "a3",
44     "a4",
45     "a5",
46     "a6",
47     "a7",
48     "t0",
49     "t1",
50     "t2",
51     "t3",
52     "t4",
53     "t5",
54     "t6",
55     "t7",
56     "t8",
57     "r21", /* reserved in the LP64* ABI, hence no ABI name */
58     "s9",
59     "s0",
60     "s1",
61     "s2",
62     "s3",
63     "s4",
64     "s5",
65     "s6",
66     "s7",
67     "s8"
69 #endif
71 static const int tcg_target_reg_alloc_order[] = {
72     /* Registers preserved across calls */
73     /* TCG_REG_S0 reserved for TCG_AREG0 */
74     TCG_REG_S1,
75     TCG_REG_S2,
76     TCG_REG_S3,
77     TCG_REG_S4,
78     TCG_REG_S5,
79     TCG_REG_S6,
80     TCG_REG_S7,
81     TCG_REG_S8,
82     TCG_REG_S9,
84     /* Registers (potentially) clobbered across calls */
85     TCG_REG_T0,
86     TCG_REG_T1,
87     TCG_REG_T2,
88     TCG_REG_T3,
89     TCG_REG_T4,
90     TCG_REG_T5,
91     TCG_REG_T6,
92     TCG_REG_T7,
93     TCG_REG_T8,
95     /* Argument registers, opposite order of allocation.  */
96     TCG_REG_A7,
97     TCG_REG_A6,
98     TCG_REG_A5,
99     TCG_REG_A4,
100     TCG_REG_A3,
101     TCG_REG_A2,
102     TCG_REG_A1,
103     TCG_REG_A0,
106 static const int tcg_target_call_iarg_regs[] = {
107     TCG_REG_A0,
108     TCG_REG_A1,
109     TCG_REG_A2,
110     TCG_REG_A3,
111     TCG_REG_A4,
112     TCG_REG_A5,
113     TCG_REG_A6,
114     TCG_REG_A7,
117 static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
119     tcg_debug_assert(kind == TCG_CALL_RET_NORMAL);
120     tcg_debug_assert(slot >= 0 && slot <= 1);
121     return TCG_REG_A0 + slot;
124 #ifndef CONFIG_SOFTMMU
125 #define USE_GUEST_BASE     (guest_base != 0)
126 #define TCG_GUEST_BASE_REG TCG_REG_S1
127 #endif
129 #define TCG_CT_CONST_ZERO  0x100
130 #define TCG_CT_CONST_S12   0x200
131 #define TCG_CT_CONST_S32   0x400
132 #define TCG_CT_CONST_U12   0x800
133 #define TCG_CT_CONST_C12   0x1000
134 #define TCG_CT_CONST_WSZ   0x2000
136 #define ALL_GENERAL_REGS      MAKE_64BIT_MASK(0, 32)
138  * For softmmu, we need to avoid conflicts with the first 5
139  * argument registers to call the helper.  Some of these are
140  * also used for the tlb lookup.
141  */
142 #ifdef CONFIG_SOFTMMU
143 #define SOFTMMU_RESERVE_REGS  MAKE_64BIT_MASK(TCG_REG_A0, 5)
144 #else
145 #define SOFTMMU_RESERVE_REGS  0
146 #endif
149 static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
151     return sextract64(val, pos, len);
154 /* test if a constant matches the constraint */
155 static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
157     if (ct & TCG_CT_CONST) {
158         return true;
159     }
160     if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
161         return true;
162     }
163     if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
164         return true;
165     }
166     if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
167         return true;
168     }
169     if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) {
170         return true;
171     }
172     if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) {
173         return true;
174     }
175     if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
176         return true;
177     }
178     return false;
182  * Relocations
183  */
186  * Relocation records defined in LoongArch ELF psABI v1.00 is way too
187  * complicated; a whopping stack machine is needed to stuff the fields, at
188  * the very least one SOP_PUSH and one SOP_POP (of the correct format) are
189  * needed.
191  * Hence, define our own simpler relocation types. Numbers are chosen as to
192  * not collide with potential future additions to the true ELF relocation
193  * type enum.
194  */
196 /* Field Sk16, shifted right by 2; suitable for conditional jumps */
197 #define R_LOONGARCH_BR_SK16     256
198 /* Field Sd10k16, shifted right by 2; suitable for B and BL */
199 #define R_LOONGARCH_BR_SD10K16  257
201 static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
203     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
204     intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
206     tcg_debug_assert((offset & 3) == 0);
207     offset >>= 2;
208     if (offset == sextreg(offset, 0, 16)) {
209         *src_rw = deposit64(*src_rw, 10, 16, offset);
210         return true;
211     }
213     return false;
216 static bool reloc_br_sd10k16(tcg_insn_unit *src_rw,
217                              const tcg_insn_unit *target)
219     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
220     intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
222     tcg_debug_assert((offset & 3) == 0);
223     offset >>= 2;
224     if (offset == sextreg(offset, 0, 26)) {
225         *src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */
226         *src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */
227         return true;
228     }
230     return false;
233 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
234                         intptr_t value, intptr_t addend)
236     tcg_debug_assert(addend == 0);
237     switch (type) {
238     case R_LOONGARCH_BR_SK16:
239         return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value);
240     case R_LOONGARCH_BR_SD10K16:
241         return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value);
242     default:
243         g_assert_not_reached();
244     }
247 #include "tcg-insn-defs.c.inc"
250  * TCG intrinsics
251  */
253 static void tcg_out_mb(TCGContext *s, TCGArg a0)
255     /* Baseline LoongArch only has the full barrier, unfortunately.  */
256     tcg_out_opc_dbar(s, 0);
259 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
261     if (ret == arg) {
262         return true;
263     }
264     switch (type) {
265     case TCG_TYPE_I32:
266     case TCG_TYPE_I64:
267         /*
268          * Conventional register-register move used in LoongArch is
269          * `or dst, src, zero`.
270          */
271         tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO);
272         break;
273     default:
274         g_assert_not_reached();
275     }
276     return true;
279 /* Loads a 32-bit immediate into rd, sign-extended.  */
280 static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val)
282     tcg_target_long lo = sextreg(val, 0, 12);
283     tcg_target_long hi12 = sextreg(val, 12, 20);
285     /* Single-instruction cases.  */
286     if (hi12 == 0) {
287         /* val fits in uimm12: ori rd, zero, val */
288         tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val);
289         return;
290     }
291     if (hi12 == sextreg(lo, 12, 20)) {
292         /* val fits in simm12: addi.w rd, zero, val */
293         tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
294         return;
295     }
297     /* High bits must be set; load with lu12i.w + optional ori.  */
298     tcg_out_opc_lu12i_w(s, rd, hi12);
299     if (lo != 0) {
300         tcg_out_opc_ori(s, rd, rd, lo & 0xfff);
301     }
304 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
305                          tcg_target_long val)
307     /*
308      * LoongArch conventionally loads 64-bit immediates in at most 4 steps,
309      * with dedicated instructions for filling the respective bitfields
310      * below:
311      *
312      *        6                   5                   4               3
313      *  3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2
314      * +-----------------------+---------------------------------------+...
315      * |          hi52         |                  hi32                 |
316      * +-----------------------+---------------------------------------+...
317      *       3                   2                   1
318      *     1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
319      * ...+-------------------------------------+-------------------------+
320      *    |                 hi12                |            lo           |
321      * ...+-------------------------------------+-------------------------+
322      *
323      * Check if val belong to one of the several fast cases, before falling
324      * back to the slow path.
325      */
327     intptr_t pc_offset;
328     tcg_target_long val_lo, val_hi, pc_hi, offset_hi;
329     tcg_target_long hi12, hi32, hi52;
331     /* Value fits in signed i32.  */
332     if (type == TCG_TYPE_I32 || val == (int32_t)val) {
333         tcg_out_movi_i32(s, rd, val);
334         return;
335     }
337     /* PC-relative cases.  */
338     pc_offset = tcg_pcrel_diff(s, (void *)val);
339     if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) {
340         /* Single pcaddu2i.  */
341         tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2);
342         return;
343     }
345     if (pc_offset == (int32_t)pc_offset) {
346         /* Offset within 32 bits; load with pcalau12i + ori.  */
347         val_lo = sextreg(val, 0, 12);
348         val_hi = val >> 12;
349         pc_hi = (val - pc_offset) >> 12;
350         offset_hi = val_hi - pc_hi;
352         tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20));
353         tcg_out_opc_pcalau12i(s, rd, offset_hi);
354         if (val_lo != 0) {
355             tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff);
356         }
357         return;
358     }
360     hi12 = sextreg(val, 12, 20);
361     hi32 = sextreg(val, 32, 20);
362     hi52 = sextreg(val, 52, 12);
364     /* Single cu52i.d case.  */
365     if ((hi52 != 0) && (ctz64(val) >= 52)) {
366         tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52);
367         return;
368     }
370     /* Slow path.  Initialize the low 32 bits, then concat high bits.  */
371     tcg_out_movi_i32(s, rd, val);
373     /* Load hi32 and hi52 explicitly when they are unexpected values. */
374     if (hi32 != sextreg(hi12, 20, 20)) {
375         tcg_out_opc_cu32i_d(s, rd, hi32);
376     }
378     if (hi52 != sextreg(hi32, 20, 12)) {
379         tcg_out_opc_cu52i_d(s, rd, rd, hi52);
380     }
383 static void tcg_out_addi(TCGContext *s, TCGType type, TCGReg rd,
384                          TCGReg rs, tcg_target_long imm)
386     tcg_target_long lo12 = sextreg(imm, 0, 12);
387     tcg_target_long hi16 = sextreg(imm - lo12, 16, 16);
389     /*
390      * Note that there's a hole in between hi16 and lo12:
391      *
392      *       3                   2                   1                   0
393      *     1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
394      * ...+-------------------------------+-------+-----------------------+
395      *    |             hi16              |       |          lo12         |
396      * ...+-------------------------------+-------+-----------------------+
397      *
398      * For bits within that hole, it's more efficient to use LU12I and ADD.
399      */
400     if (imm == (hi16 << 16) + lo12) {
401         if (hi16) {
402             tcg_out_opc_addu16i_d(s, rd, rs, hi16);
403             rs = rd;
404         }
405         if (type == TCG_TYPE_I32) {
406             tcg_out_opc_addi_w(s, rd, rs, lo12);
407         } else if (lo12) {
408             tcg_out_opc_addi_d(s, rd, rs, lo12);
409         } else {
410             tcg_out_mov(s, type, rd, rs);
411         }
412     } else {
413         tcg_out_movi(s, type, TCG_REG_TMP0, imm);
414         if (type == TCG_TYPE_I32) {
415             tcg_out_opc_add_w(s, rd, rs, TCG_REG_TMP0);
416         } else {
417             tcg_out_opc_add_d(s, rd, rs, TCG_REG_TMP0);
418         }
419     }
422 static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
423                              tcg_target_long imm)
425     /* This function is only used for passing structs by reference. */
426     g_assert_not_reached();
429 static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
431     tcg_out_opc_andi(s, ret, arg, 0xff);
434 static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
436     tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15);
439 static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
441     tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31);
444 static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
446     tcg_out_opc_sext_b(s, ret, arg);
449 static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
451     tcg_out_opc_sext_h(s, ret, arg);
454 static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
456     tcg_out_opc_addi_w(s, ret, arg, 0);
459 static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
460                            TCGReg a0, TCGReg a1, TCGReg a2,
461                            bool c2, bool is_32bit)
463     if (c2) {
464         /*
465          * Fast path: semantics already satisfied due to constraint and
466          * insn behavior, single instruction is enough.
467          */
468         tcg_debug_assert(a2 == (is_32bit ? 32 : 64));
469         /* all clz/ctz insns belong to DJ-format */
470         tcg_out32(s, encode_dj_insn(opc, a0, a1));
471         return;
472     }
474     tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1));
475     /* a0 = a1 ? REG_TMP0 : a2 */
476     tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1);
477     tcg_out_opc_masknez(s, a0, a2, a1);
478     tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
481 #define SETCOND_INV    TCG_TARGET_NB_REGS
482 #define SETCOND_NEZ    (SETCOND_INV << 1)
483 #define SETCOND_FLAGS  (SETCOND_INV | SETCOND_NEZ)
485 static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
486                                TCGReg arg1, tcg_target_long arg2, bool c2)
488     int flags = 0;
490     switch (cond) {
491     case TCG_COND_EQ:    /* -> NE  */
492     case TCG_COND_GE:    /* -> LT  */
493     case TCG_COND_GEU:   /* -> LTU */
494     case TCG_COND_GT:    /* -> LE  */
495     case TCG_COND_GTU:   /* -> LEU */
496         cond = tcg_invert_cond(cond);
497         flags ^= SETCOND_INV;
498         break;
499     default:
500         break;
501     }
503     switch (cond) {
504     case TCG_COND_LE:
505     case TCG_COND_LEU:
506         /*
507          * If we have a constant input, the most efficient way to implement
508          * LE is by adding 1 and using LT.  Watch out for wrap around for LEU.
509          * We don't need to care for this for LE because the constant input
510          * is still constrained to int32_t, and INT32_MAX+1 is representable
511          * in the 64-bit temporary register.
512          */
513         if (c2) {
514             if (cond == TCG_COND_LEU) {
515                 /* unsigned <= -1 is true */
516                 if (arg2 == -1) {
517                     tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
518                     return ret;
519                 }
520                 cond = TCG_COND_LTU;
521             } else {
522                 cond = TCG_COND_LT;
523             }
524             arg2 += 1;
525         } else {
526             TCGReg tmp = arg2;
527             arg2 = arg1;
528             arg1 = tmp;
529             cond = tcg_swap_cond(cond);    /* LE -> GE */
530             cond = tcg_invert_cond(cond);  /* GE -> LT */
531             flags ^= SETCOND_INV;
532         }
533         break;
534     default:
535         break;
536     }
538     switch (cond) {
539     case TCG_COND_NE:
540         flags |= SETCOND_NEZ;
541         if (!c2) {
542             tcg_out_opc_xor(s, ret, arg1, arg2);
543         } else if (arg2 == 0) {
544             ret = arg1;
545         } else if (arg2 >= 0 && arg2 <= 0xfff) {
546             tcg_out_opc_xori(s, ret, arg1, arg2);
547         } else {
548             tcg_out_addi(s, TCG_TYPE_REG, ret, arg1, -arg2);
549         }
550         break;
552     case TCG_COND_LT:
553     case TCG_COND_LTU:
554         if (c2) {
555             if (arg2 >= -0x800 && arg2 <= 0x7ff) {
556                 if (cond == TCG_COND_LT) {
557                     tcg_out_opc_slti(s, ret, arg1, arg2);
558                 } else {
559                     tcg_out_opc_sltui(s, ret, arg1, arg2);
560                 }
561                 break;
562             }
563             tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
564             arg2 = TCG_REG_TMP0;
565         }
566         if (cond == TCG_COND_LT) {
567             tcg_out_opc_slt(s, ret, arg1, arg2);
568         } else {
569             tcg_out_opc_sltu(s, ret, arg1, arg2);
570         }
571         break;
573     default:
574         g_assert_not_reached();
575         break;
576     }
578     return ret | flags;
581 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
582                             TCGReg arg1, tcg_target_long arg2, bool c2)
584     int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
586     if (tmpflags != ret) {
587         TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
589         switch (tmpflags & SETCOND_FLAGS) {
590         case SETCOND_INV:
591             /* Intermediate result is boolean: simply invert. */
592             tcg_out_opc_xori(s, ret, tmp, 1);
593             break;
594         case SETCOND_NEZ:
595             /* Intermediate result is zero/non-zero: test != 0. */
596             tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
597             break;
598         case SETCOND_NEZ | SETCOND_INV:
599             /* Intermediate result is zero/non-zero: test == 0. */
600             tcg_out_opc_sltui(s, ret, tmp, 1);
601             break;
602         default:
603             g_assert_not_reached();
604         }
605     }
608 static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
609                             TCGReg c1, tcg_target_long c2, bool const2,
610                             TCGReg v1, TCGReg v2)
612     int tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, c1, c2, const2);
613     TCGReg t;
615     /* Standardize the test below to t != 0. */
616     if (tmpflags & SETCOND_INV) {
617         t = v1, v1 = v2, v2 = t;
618     }
620     t = tmpflags & ~SETCOND_FLAGS;
621     if (v1 == TCG_REG_ZERO) {
622         tcg_out_opc_masknez(s, ret, v2, t);
623     } else if (v2 == TCG_REG_ZERO) {
624         tcg_out_opc_maskeqz(s, ret, v1, t);
625     } else {
626         tcg_out_opc_masknez(s, TCG_REG_TMP2, v2, t); /* t ? 0 : v2 */
627         tcg_out_opc_maskeqz(s, TCG_REG_TMP1, v1, t); /* t ? v1 : 0 */
628         tcg_out_opc_or(s, ret, TCG_REG_TMP1, TCG_REG_TMP2);
629     }
633  * Branch helpers
634  */
636 static const struct {
637     LoongArchInsn op;
638     bool swap;
639 } tcg_brcond_to_loongarch[] = {
640     [TCG_COND_EQ] =  { OPC_BEQ,  false },
641     [TCG_COND_NE] =  { OPC_BNE,  false },
642     [TCG_COND_LT] =  { OPC_BGT,  true  },
643     [TCG_COND_GE] =  { OPC_BLE,  true  },
644     [TCG_COND_LE] =  { OPC_BLE,  false },
645     [TCG_COND_GT] =  { OPC_BGT,  false },
646     [TCG_COND_LTU] = { OPC_BGTU, true  },
647     [TCG_COND_GEU] = { OPC_BLEU, true  },
648     [TCG_COND_LEU] = { OPC_BLEU, false },
649     [TCG_COND_GTU] = { OPC_BGTU, false }
652 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
653                            TCGReg arg2, TCGLabel *l)
655     LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
657     tcg_debug_assert(op != 0);
659     if (tcg_brcond_to_loongarch[cond].swap) {
660         TCGReg t = arg1;
661         arg1 = arg2;
662         arg2 = t;
663     }
665     /* all conditional branch insns belong to DJSk16-format */
666     tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0);
667     tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
670 static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
672     TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
673     ptrdiff_t offset = tcg_pcrel_diff(s, arg);
675     tcg_debug_assert((offset & 3) == 0);
676     if (offset == sextreg(offset, 0, 28)) {
677         /* short jump: +/- 256MiB */
678         if (tail) {
679             tcg_out_opc_b(s, offset >> 2);
680         } else {
681             tcg_out_opc_bl(s, offset >> 2);
682         }
683     } else if (offset == sextreg(offset, 0, 38)) {
684         /* long jump: +/- 256GiB */
685         tcg_target_long lo = sextreg(offset, 0, 18);
686         tcg_target_long hi = offset - lo;
687         tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18);
688         tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
689     } else {
690         /* far jump: 64-bit */
691         tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18);
692         tcg_target_long hi = (tcg_target_long)arg - lo;
693         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi);
694         tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
695     }
698 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg,
699                          const TCGHelperInfo *info)
701     tcg_out_call_int(s, arg, false);
705  * Load/store helpers
706  */
708 static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
709                          TCGReg addr, intptr_t offset)
711     intptr_t imm12 = sextreg(offset, 0, 12);
713     if (offset != imm12) {
714         intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
716         if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
717             imm12 = sextreg(diff, 0, 12);
718             tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12);
719         } else {
720             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
721             if (addr != TCG_REG_ZERO) {
722                 tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr);
723             }
724         }
725         addr = TCG_REG_TMP2;
726     }
728     switch (opc) {
729     case OPC_LD_B:
730     case OPC_LD_BU:
731     case OPC_LD_H:
732     case OPC_LD_HU:
733     case OPC_LD_W:
734     case OPC_LD_WU:
735     case OPC_LD_D:
736     case OPC_ST_B:
737     case OPC_ST_H:
738     case OPC_ST_W:
739     case OPC_ST_D:
740         tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12));
741         break;
742     default:
743         g_assert_not_reached();
744     }
747 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
748                        TCGReg arg1, intptr_t arg2)
750     bool is_32bit = type == TCG_TYPE_I32;
751     tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2);
754 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
755                        TCGReg arg1, intptr_t arg2)
757     bool is_32bit = type == TCG_TYPE_I32;
758     tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2);
761 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
762                         TCGReg base, intptr_t ofs)
764     if (val == 0) {
765         tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
766         return true;
767     }
768     return false;
772  * Load/store helpers for SoftMMU, and qemu_ld/st implementations
773  */
775 #if defined(CONFIG_SOFTMMU)
777  * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
778  *                                     MemOpIdx oi, uintptr_t ra)
779  */
780 static void * const qemu_ld_helpers[4] = {
781     [MO_8]  = helper_ret_ldub_mmu,
782     [MO_16] = helper_le_lduw_mmu,
783     [MO_32] = helper_le_ldul_mmu,
784     [MO_64] = helper_le_ldq_mmu,
788  * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
789  *                                     uintxx_t val, MemOpIdx oi,
790  *                                     uintptr_t ra)
791  */
792 static void * const qemu_st_helpers[4] = {
793     [MO_8]  = helper_ret_stb_mmu,
794     [MO_16] = helper_le_stw_mmu,
795     [MO_32] = helper_le_stl_mmu,
796     [MO_64] = helper_le_stq_mmu,
799 /* We expect to use a 12-bit negative offset from ENV.  */
800 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
801 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
803 static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
805     tcg_out_opc_b(s, 0);
806     return reloc_br_sd10k16(s->code_ptr - 1, target);
810  * Emits common code for TLB addend lookup, that eventually loads the
811  * addend in TCG_REG_TMP2.
812  */
813 static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi,
814                              tcg_insn_unit **label_ptr, bool is_load)
816     MemOp opc = get_memop(oi);
817     unsigned s_bits = opc & MO_SIZE;
818     unsigned a_bits = get_alignment_bits(opc);
819     tcg_target_long compare_mask;
820     int mem_index = get_mmuidx(oi);
821     int fast_ofs = TLB_MASK_TABLE_OFS(mem_index);
822     int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask);
823     int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table);
825     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
826     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
828     tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl,
829                     TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
830     tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0);
831     tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1);
833     /* Load the tlb comparator and the addend.  */
834     tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2,
835                is_load ? offsetof(CPUTLBEntry, addr_read)
836                : offsetof(CPUTLBEntry, addr_write));
837     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2,
838                offsetof(CPUTLBEntry, addend));
840     /* We don't support unaligned accesses.  */
841     if (a_bits < s_bits) {
842         a_bits = s_bits;
843     }
844     /* Clear the non-page, non-alignment bits from the address.  */
845     compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
846     tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask);
847     tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl);
849     /* Compare masked address with the TLB entry.  */
850     label_ptr[0] = s->code_ptr;
851     tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0);
853     /* TLB Hit - addend in TCG_REG_TMP2, ready for use.  */
856 static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
857                                 TCGType type,
858                                 TCGReg datalo, TCGReg addrlo,
859                                 void *raddr, tcg_insn_unit **label_ptr)
861     TCGLabelQemuLdst *label = new_ldst_label(s);
863     label->is_ld = is_ld;
864     label->oi = oi;
865     label->type = type;
866     label->datalo_reg = datalo;
867     label->datahi_reg = 0; /* unused */
868     label->addrlo_reg = addrlo;
869     label->addrhi_reg = 0; /* unused */
870     label->raddr = tcg_splitwx_to_rx(raddr);
871     label->label_ptr[0] = label_ptr[0];
874 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
876     MemOpIdx oi = l->oi;
877     MemOp opc = get_memop(oi);
878     MemOp size = opc & MO_SIZE;
879     TCGType type = l->type;
881     /* resolve label address */
882     if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
883         return false;
884     }
886     /* call load helper */
887     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
888     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg);
889     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A2, oi);
890     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, (tcg_target_long)l->raddr);
892     tcg_out_call_int(s, qemu_ld_helpers[size], false);
894     switch (opc & MO_SSIZE) {
895     case MO_SB:
896         tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0);
897         break;
898     case MO_SW:
899         tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0);
900         break;
901     case MO_SL:
902         tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
903         break;
904     case MO_UL:
905         if (type == TCG_TYPE_I32) {
906             /* MO_UL loads of i32 should be sign-extended too */
907             tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
908             break;
909         }
910         /* fallthrough */
911     default:
912         tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0);
913         break;
914     }
916     return tcg_out_goto(s, l->raddr);
919 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
921     MemOpIdx oi = l->oi;
922     MemOp opc = get_memop(oi);
923     MemOp size = opc & MO_SIZE;
925     /* resolve label address */
926     if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
927         return false;
928     }
930     /* call store helper */
931     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
932     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg);
933     switch (size) {
934     case MO_8:
935         tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg);
936         break;
937     case MO_16:
938         tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg);
939         break;
940     case MO_32:
941         tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg);
942         break;
943     case MO_64:
944         tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg);
945         break;
946     default:
947         g_assert_not_reached();
948         break;
949     }
950     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi);
951     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr);
953     tcg_out_call_int(s, qemu_st_helpers[size], false);
955     return tcg_out_goto(s, l->raddr);
957 #else
960  * Alignment helpers for user-mode emulation
961  */
963 static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
964                                    unsigned a_bits)
966     TCGLabelQemuLdst *l = new_ldst_label(s);
968     l->is_ld = is_ld;
969     l->addrlo_reg = addr_reg;
971     /*
972      * Without micro-architecture details, we don't know which of bstrpick or
973      * andi is faster, so use bstrpick as it's not constrained by imm field
974      * width. (Not to say alignments >= 2^12 are going to happen any time
975      * soon, though)
976      */
977     tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1);
979     l->label_ptr[0] = s->code_ptr;
980     tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0);
982     l->raddr = tcg_splitwx_to_rx(s->code_ptr);
985 static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
987     /* resolve label address */
988     if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
989         return false;
990     }
992     tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg);
993     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
995     /* tail call, with the return address back inline. */
996     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr);
997     tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld
998                                        : helper_unaligned_st), true);
999     return true;
1002 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1004     return tcg_out_fail_alignment(s, l);
1007 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1009     return tcg_out_fail_alignment(s, l);
1012 #endif /* CONFIG_SOFTMMU */
1015  * `ext32u` the address register into the temp register given,
1016  * if target is 32-bit, no-op otherwise.
1018  * Returns the address register ready for use with TLB addend.
1019  */
1020 static TCGReg tcg_out_zext_addr_if_32_bit(TCGContext *s,
1021                                           TCGReg addr, TCGReg tmp)
1023     if (TARGET_LONG_BITS == 32) {
1024         tcg_out_ext32u(s, tmp, addr);
1025         return tmp;
1026     }
1027     return addr;
1030 static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg rd, TCGReg rj,
1031                                    TCGReg rk, MemOp opc, TCGType type)
1033     /* Byte swapping is left to middle-end expansion.  */
1034     tcg_debug_assert((opc & MO_BSWAP) == 0);
1036     switch (opc & MO_SSIZE) {
1037     case MO_UB:
1038         tcg_out_opc_ldx_bu(s, rd, rj, rk);
1039         break;
1040     case MO_SB:
1041         tcg_out_opc_ldx_b(s, rd, rj, rk);
1042         break;
1043     case MO_UW:
1044         tcg_out_opc_ldx_hu(s, rd, rj, rk);
1045         break;
1046     case MO_SW:
1047         tcg_out_opc_ldx_h(s, rd, rj, rk);
1048         break;
1049     case MO_UL:
1050         if (type == TCG_TYPE_I64) {
1051             tcg_out_opc_ldx_wu(s, rd, rj, rk);
1052             break;
1053         }
1054         /* fallthrough */
1055     case MO_SL:
1056         tcg_out_opc_ldx_w(s, rd, rj, rk);
1057         break;
1058     case MO_UQ:
1059         tcg_out_opc_ldx_d(s, rd, rj, rk);
1060         break;
1061     default:
1062         g_assert_not_reached();
1063     }
1066 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGType type)
1068     TCGReg addr_regl;
1069     TCGReg data_regl;
1070     MemOpIdx oi;
1071     MemOp opc;
1072 #if defined(CONFIG_SOFTMMU)
1073     tcg_insn_unit *label_ptr[1];
1074 #else
1075     unsigned a_bits;
1076 #endif
1077     TCGReg base;
1079     data_regl = *args++;
1080     addr_regl = *args++;
1081     oi = *args++;
1082     opc = get_memop(oi);
1084 #if defined(CONFIG_SOFTMMU)
1085     tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 1);
1086     base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
1087     tcg_out_qemu_ld_indexed(s, data_regl, base, TCG_REG_TMP2, opc, type);
1088     add_qemu_ldst_label(s, 1, oi, type,
1089                         data_regl, addr_regl,
1090                         s->code_ptr, label_ptr);
1091 #else
1092     a_bits = get_alignment_bits(opc);
1093     if (a_bits) {
1094         tcg_out_test_alignment(s, true, addr_regl, a_bits);
1095     }
1096     base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
1097     TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
1098     tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type);
1099 #endif
1102 static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data,
1103                                    TCGReg rj, TCGReg rk, MemOp opc)
1105     /* Byte swapping is left to middle-end expansion.  */
1106     tcg_debug_assert((opc & MO_BSWAP) == 0);
1108     switch (opc & MO_SIZE) {
1109     case MO_8:
1110         tcg_out_opc_stx_b(s, data, rj, rk);
1111         break;
1112     case MO_16:
1113         tcg_out_opc_stx_h(s, data, rj, rk);
1114         break;
1115     case MO_32:
1116         tcg_out_opc_stx_w(s, data, rj, rk);
1117         break;
1118     case MO_64:
1119         tcg_out_opc_stx_d(s, data, rj, rk);
1120         break;
1121     default:
1122         g_assert_not_reached();
1123     }
1126 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args)
1128     TCGReg addr_regl;
1129     TCGReg data_regl;
1130     MemOpIdx oi;
1131     MemOp opc;
1132 #if defined(CONFIG_SOFTMMU)
1133     tcg_insn_unit *label_ptr[1];
1134 #else
1135     unsigned a_bits;
1136 #endif
1137     TCGReg base;
1139     data_regl = *args++;
1140     addr_regl = *args++;
1141     oi = *args++;
1142     opc = get_memop(oi);
1144 #if defined(CONFIG_SOFTMMU)
1145     tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0);
1146     base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
1147     tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc);
1148     add_qemu_ldst_label(s, 0, oi,
1149                         0, /* type param is unused for stores */
1150                         data_regl, addr_regl,
1151                         s->code_ptr, label_ptr);
1152 #else
1153     a_bits = get_alignment_bits(opc);
1154     if (a_bits) {
1155         tcg_out_test_alignment(s, false, addr_regl, a_bits);
1156     }
1157     base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
1158     TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO;
1159     tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc);
1160 #endif
1164  * Entry-points
1165  */
1167 static const tcg_insn_unit *tb_ret_addr;
1169 static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
1171     /* Reuse the zeroing that exists for goto_ptr.  */
1172     if (a0 == 0) {
1173         tcg_out_call_int(s, tcg_code_gen_epilogue, true);
1174     } else {
1175         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
1176         tcg_out_call_int(s, tb_ret_addr, true);
1177     }
1180 static void tcg_out_goto_tb(TCGContext *s, int which)
1182     /*
1183      * Direct branch, or load indirect address, to be patched
1184      * by tb_target_set_jmp_target.  Check indirect load offset
1185      * in range early, regardless of direct branch distance,
1186      * via assert within tcg_out_opc_pcaddu2i.
1187      */
1188     uintptr_t i_addr = get_jmp_target_addr(s, which);
1189     intptr_t i_disp = tcg_pcrel_diff(s, (void *)i_addr);
1191     set_jmp_insn_offset(s, which);
1192     tcg_out_opc_pcaddu2i(s, TCG_REG_TMP0, i_disp >> 2);
1194     /* Finish the load and indirect branch. */
1195     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_TMP0, 0);
1196     tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
1197     set_jmp_reset_offset(s, which);
1200 void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
1201                               uintptr_t jmp_rx, uintptr_t jmp_rw)
1203     uintptr_t d_addr = tb->jmp_target_addr[n];
1204     ptrdiff_t d_disp = (ptrdiff_t)(d_addr - jmp_rx) >> 2;
1205     tcg_insn_unit insn;
1207     /* Either directly branch, or load slot address for indirect branch. */
1208     if (d_disp == sextreg(d_disp, 0, 26)) {
1209         insn = encode_sd10k16_insn(OPC_B, d_disp);
1210     } else {
1211         uintptr_t i_addr = (uintptr_t)&tb->jmp_target_addr[n];
1212         intptr_t i_disp = i_addr - jmp_rx;
1213         insn = encode_dsj20_insn(OPC_PCADDU2I, TCG_REG_TMP0, i_disp >> 2);
1214     }
1216     qatomic_set((tcg_insn_unit *)jmp_rw, insn);
1217     flush_idcache_range(jmp_rx, jmp_rw, 4);
1220 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1221                        const TCGArg args[TCG_MAX_OP_ARGS],
1222                        const int const_args[TCG_MAX_OP_ARGS])
1224     TCGArg a0 = args[0];
1225     TCGArg a1 = args[1];
1226     TCGArg a2 = args[2];
1227     int c2 = const_args[2];
1229     switch (opc) {
1230     case INDEX_op_mb:
1231         tcg_out_mb(s, a0);
1232         break;
1234     case INDEX_op_goto_ptr:
1235         tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
1236         break;
1238     case INDEX_op_br:
1239         tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0),
1240                       0);
1241         tcg_out_opc_b(s, 0);
1242         break;
1244     case INDEX_op_brcond_i32:
1245     case INDEX_op_brcond_i64:
1246         tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
1247         break;
1249     case INDEX_op_ext8s_i32:
1250     case INDEX_op_ext8s_i64:
1251         tcg_out_ext8s(s, a0, a1);
1252         break;
1254     case INDEX_op_ext8u_i32:
1255     case INDEX_op_ext8u_i64:
1256         tcg_out_ext8u(s, a0, a1);
1257         break;
1259     case INDEX_op_ext16s_i32:
1260     case INDEX_op_ext16s_i64:
1261         tcg_out_ext16s(s, a0, a1);
1262         break;
1264     case INDEX_op_ext16u_i32:
1265     case INDEX_op_ext16u_i64:
1266         tcg_out_ext16u(s, a0, a1);
1267         break;
1269     case INDEX_op_ext32u_i64:
1270     case INDEX_op_extu_i32_i64:
1271         tcg_out_ext32u(s, a0, a1);
1272         break;
1274     case INDEX_op_ext32s_i64:
1275     case INDEX_op_extrl_i64_i32:
1276     case INDEX_op_ext_i32_i64:
1277         tcg_out_ext32s(s, a0, a1);
1278         break;
1280     case INDEX_op_extrh_i64_i32:
1281         tcg_out_opc_srai_d(s, a0, a1, 32);
1282         break;
1284     case INDEX_op_not_i32:
1285     case INDEX_op_not_i64:
1286         tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO);
1287         break;
1289     case INDEX_op_nor_i32:
1290     case INDEX_op_nor_i64:
1291         if (c2) {
1292             tcg_out_opc_ori(s, a0, a1, a2);
1293             tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO);
1294         } else {
1295             tcg_out_opc_nor(s, a0, a1, a2);
1296         }
1297         break;
1299     case INDEX_op_andc_i32:
1300     case INDEX_op_andc_i64:
1301         if (c2) {
1302             /* guaranteed to fit due to constraint */
1303             tcg_out_opc_andi(s, a0, a1, ~a2);
1304         } else {
1305             tcg_out_opc_andn(s, a0, a1, a2);
1306         }
1307         break;
1309     case INDEX_op_orc_i32:
1310     case INDEX_op_orc_i64:
1311         if (c2) {
1312             /* guaranteed to fit due to constraint */
1313             tcg_out_opc_ori(s, a0, a1, ~a2);
1314         } else {
1315             tcg_out_opc_orn(s, a0, a1, a2);
1316         }
1317         break;
1319     case INDEX_op_and_i32:
1320     case INDEX_op_and_i64:
1321         if (c2) {
1322             tcg_out_opc_andi(s, a0, a1, a2);
1323         } else {
1324             tcg_out_opc_and(s, a0, a1, a2);
1325         }
1326         break;
1328     case INDEX_op_or_i32:
1329     case INDEX_op_or_i64:
1330         if (c2) {
1331             tcg_out_opc_ori(s, a0, a1, a2);
1332         } else {
1333             tcg_out_opc_or(s, a0, a1, a2);
1334         }
1335         break;
1337     case INDEX_op_xor_i32:
1338     case INDEX_op_xor_i64:
1339         if (c2) {
1340             tcg_out_opc_xori(s, a0, a1, a2);
1341         } else {
1342             tcg_out_opc_xor(s, a0, a1, a2);
1343         }
1344         break;
1346     case INDEX_op_extract_i32:
1347         tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1);
1348         break;
1349     case INDEX_op_extract_i64:
1350         tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1);
1351         break;
1353     case INDEX_op_deposit_i32:
1354         tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1);
1355         break;
1356     case INDEX_op_deposit_i64:
1357         tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1);
1358         break;
1360     case INDEX_op_bswap16_i32:
1361     case INDEX_op_bswap16_i64:
1362         tcg_out_opc_revb_2h(s, a0, a1);
1363         if (a2 & TCG_BSWAP_OS) {
1364             tcg_out_ext16s(s, a0, a0);
1365         } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
1366             tcg_out_ext16u(s, a0, a0);
1367         }
1368         break;
1370     case INDEX_op_bswap32_i32:
1371         /* All 32-bit values are computed sign-extended in the register.  */
1372         a2 = TCG_BSWAP_OS;
1373         /* fallthrough */
1374     case INDEX_op_bswap32_i64:
1375         tcg_out_opc_revb_2w(s, a0, a1);
1376         if (a2 & TCG_BSWAP_OS) {
1377             tcg_out_ext32s(s, a0, a0);
1378         } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
1379             tcg_out_ext32u(s, a0, a0);
1380         }
1381         break;
1383     case INDEX_op_bswap64_i64:
1384         tcg_out_opc_revb_d(s, a0, a1);
1385         break;
1387     case INDEX_op_clz_i32:
1388         tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true);
1389         break;
1390     case INDEX_op_clz_i64:
1391         tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false);
1392         break;
1394     case INDEX_op_ctz_i32:
1395         tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true);
1396         break;
1397     case INDEX_op_ctz_i64:
1398         tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false);
1399         break;
1401     case INDEX_op_shl_i32:
1402         if (c2) {
1403             tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f);
1404         } else {
1405             tcg_out_opc_sll_w(s, a0, a1, a2);
1406         }
1407         break;
1408     case INDEX_op_shl_i64:
1409         if (c2) {
1410             tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f);
1411         } else {
1412             tcg_out_opc_sll_d(s, a0, a1, a2);
1413         }
1414         break;
1416     case INDEX_op_shr_i32:
1417         if (c2) {
1418             tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f);
1419         } else {
1420             tcg_out_opc_srl_w(s, a0, a1, a2);
1421         }
1422         break;
1423     case INDEX_op_shr_i64:
1424         if (c2) {
1425             tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f);
1426         } else {
1427             tcg_out_opc_srl_d(s, a0, a1, a2);
1428         }
1429         break;
1431     case INDEX_op_sar_i32:
1432         if (c2) {
1433             tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f);
1434         } else {
1435             tcg_out_opc_sra_w(s, a0, a1, a2);
1436         }
1437         break;
1438     case INDEX_op_sar_i64:
1439         if (c2) {
1440             tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f);
1441         } else {
1442             tcg_out_opc_sra_d(s, a0, a1, a2);
1443         }
1444         break;
1446     case INDEX_op_rotl_i32:
1447         /* transform into equivalent rotr/rotri */
1448         if (c2) {
1449             tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f);
1450         } else {
1451             tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
1452             tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0);
1453         }
1454         break;
1455     case INDEX_op_rotl_i64:
1456         /* transform into equivalent rotr/rotri */
1457         if (c2) {
1458             tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f);
1459         } else {
1460             tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
1461             tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0);
1462         }
1463         break;
1465     case INDEX_op_rotr_i32:
1466         if (c2) {
1467             tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f);
1468         } else {
1469             tcg_out_opc_rotr_w(s, a0, a1, a2);
1470         }
1471         break;
1472     case INDEX_op_rotr_i64:
1473         if (c2) {
1474             tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f);
1475         } else {
1476             tcg_out_opc_rotr_d(s, a0, a1, a2);
1477         }
1478         break;
1480     case INDEX_op_add_i32:
1481         if (c2) {
1482             tcg_out_addi(s, TCG_TYPE_I32, a0, a1, a2);
1483         } else {
1484             tcg_out_opc_add_w(s, a0, a1, a2);
1485         }
1486         break;
1487     case INDEX_op_add_i64:
1488         if (c2) {
1489             tcg_out_addi(s, TCG_TYPE_I64, a0, a1, a2);
1490         } else {
1491             tcg_out_opc_add_d(s, a0, a1, a2);
1492         }
1493         break;
1495     case INDEX_op_sub_i32:
1496         if (c2) {
1497             tcg_out_addi(s, TCG_TYPE_I32, a0, a1, -a2);
1498         } else {
1499             tcg_out_opc_sub_w(s, a0, a1, a2);
1500         }
1501         break;
1502     case INDEX_op_sub_i64:
1503         if (c2) {
1504             tcg_out_addi(s, TCG_TYPE_I64, a0, a1, -a2);
1505         } else {
1506             tcg_out_opc_sub_d(s, a0, a1, a2);
1507         }
1508         break;
1510     case INDEX_op_mul_i32:
1511         tcg_out_opc_mul_w(s, a0, a1, a2);
1512         break;
1513     case INDEX_op_mul_i64:
1514         tcg_out_opc_mul_d(s, a0, a1, a2);
1515         break;
1517     case INDEX_op_mulsh_i32:
1518         tcg_out_opc_mulh_w(s, a0, a1, a2);
1519         break;
1520     case INDEX_op_mulsh_i64:
1521         tcg_out_opc_mulh_d(s, a0, a1, a2);
1522         break;
1524     case INDEX_op_muluh_i32:
1525         tcg_out_opc_mulh_wu(s, a0, a1, a2);
1526         break;
1527     case INDEX_op_muluh_i64:
1528         tcg_out_opc_mulh_du(s, a0, a1, a2);
1529         break;
1531     case INDEX_op_div_i32:
1532         tcg_out_opc_div_w(s, a0, a1, a2);
1533         break;
1534     case INDEX_op_div_i64:
1535         tcg_out_opc_div_d(s, a0, a1, a2);
1536         break;
1538     case INDEX_op_divu_i32:
1539         tcg_out_opc_div_wu(s, a0, a1, a2);
1540         break;
1541     case INDEX_op_divu_i64:
1542         tcg_out_opc_div_du(s, a0, a1, a2);
1543         break;
1545     case INDEX_op_rem_i32:
1546         tcg_out_opc_mod_w(s, a0, a1, a2);
1547         break;
1548     case INDEX_op_rem_i64:
1549         tcg_out_opc_mod_d(s, a0, a1, a2);
1550         break;
1552     case INDEX_op_remu_i32:
1553         tcg_out_opc_mod_wu(s, a0, a1, a2);
1554         break;
1555     case INDEX_op_remu_i64:
1556         tcg_out_opc_mod_du(s, a0, a1, a2);
1557         break;
1559     case INDEX_op_setcond_i32:
1560     case INDEX_op_setcond_i64:
1561         tcg_out_setcond(s, args[3], a0, a1, a2, c2);
1562         break;
1564     case INDEX_op_movcond_i32:
1565     case INDEX_op_movcond_i64:
1566         tcg_out_movcond(s, args[5], a0, a1, a2, c2, args[3], args[4]);
1567         break;
1569     case INDEX_op_ld8s_i32:
1570     case INDEX_op_ld8s_i64:
1571         tcg_out_ldst(s, OPC_LD_B, a0, a1, a2);
1572         break;
1573     case INDEX_op_ld8u_i32:
1574     case INDEX_op_ld8u_i64:
1575         tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2);
1576         break;
1577     case INDEX_op_ld16s_i32:
1578     case INDEX_op_ld16s_i64:
1579         tcg_out_ldst(s, OPC_LD_H, a0, a1, a2);
1580         break;
1581     case INDEX_op_ld16u_i32:
1582     case INDEX_op_ld16u_i64:
1583         tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2);
1584         break;
1585     case INDEX_op_ld_i32:
1586     case INDEX_op_ld32s_i64:
1587         tcg_out_ldst(s, OPC_LD_W, a0, a1, a2);
1588         break;
1589     case INDEX_op_ld32u_i64:
1590         tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2);
1591         break;
1592     case INDEX_op_ld_i64:
1593         tcg_out_ldst(s, OPC_LD_D, a0, a1, a2);
1594         break;
1596     case INDEX_op_st8_i32:
1597     case INDEX_op_st8_i64:
1598         tcg_out_ldst(s, OPC_ST_B, a0, a1, a2);
1599         break;
1600     case INDEX_op_st16_i32:
1601     case INDEX_op_st16_i64:
1602         tcg_out_ldst(s, OPC_ST_H, a0, a1, a2);
1603         break;
1604     case INDEX_op_st_i32:
1605     case INDEX_op_st32_i64:
1606         tcg_out_ldst(s, OPC_ST_W, a0, a1, a2);
1607         break;
1608     case INDEX_op_st_i64:
1609         tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
1610         break;
1612     case INDEX_op_qemu_ld_i32:
1613         tcg_out_qemu_ld(s, args, TCG_TYPE_I32);
1614         break;
1615     case INDEX_op_qemu_ld_i64:
1616         tcg_out_qemu_ld(s, args, TCG_TYPE_I64);
1617         break;
1618     case INDEX_op_qemu_st_i32:
1619         tcg_out_qemu_st(s, args);
1620         break;
1621     case INDEX_op_qemu_st_i64:
1622         tcg_out_qemu_st(s, args);
1623         break;
1625     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1626     case INDEX_op_mov_i64:
1627     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1628     case INDEX_op_exit_tb:  /* Always emitted via tcg_out_exit_tb.  */
1629     case INDEX_op_goto_tb:  /* Always emitted via tcg_out_goto_tb.  */
1630     default:
1631         g_assert_not_reached();
1632     }
1635 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
1637     switch (op) {
1638     case INDEX_op_goto_ptr:
1639         return C_O0_I1(r);
1641     case INDEX_op_st8_i32:
1642     case INDEX_op_st8_i64:
1643     case INDEX_op_st16_i32:
1644     case INDEX_op_st16_i64:
1645     case INDEX_op_st32_i64:
1646     case INDEX_op_st_i32:
1647     case INDEX_op_st_i64:
1648         return C_O0_I2(rZ, r);
1650     case INDEX_op_brcond_i32:
1651     case INDEX_op_brcond_i64:
1652         return C_O0_I2(rZ, rZ);
1654     case INDEX_op_qemu_st_i32:
1655     case INDEX_op_qemu_st_i64:
1656         return C_O0_I2(LZ, L);
1658     case INDEX_op_ext8s_i32:
1659     case INDEX_op_ext8s_i64:
1660     case INDEX_op_ext8u_i32:
1661     case INDEX_op_ext8u_i64:
1662     case INDEX_op_ext16s_i32:
1663     case INDEX_op_ext16s_i64:
1664     case INDEX_op_ext16u_i32:
1665     case INDEX_op_ext16u_i64:
1666     case INDEX_op_ext32s_i64:
1667     case INDEX_op_ext32u_i64:
1668     case INDEX_op_extu_i32_i64:
1669     case INDEX_op_extrl_i64_i32:
1670     case INDEX_op_extrh_i64_i32:
1671     case INDEX_op_ext_i32_i64:
1672     case INDEX_op_not_i32:
1673     case INDEX_op_not_i64:
1674     case INDEX_op_extract_i32:
1675     case INDEX_op_extract_i64:
1676     case INDEX_op_bswap16_i32:
1677     case INDEX_op_bswap16_i64:
1678     case INDEX_op_bswap32_i32:
1679     case INDEX_op_bswap32_i64:
1680     case INDEX_op_bswap64_i64:
1681     case INDEX_op_ld8s_i32:
1682     case INDEX_op_ld8s_i64:
1683     case INDEX_op_ld8u_i32:
1684     case INDEX_op_ld8u_i64:
1685     case INDEX_op_ld16s_i32:
1686     case INDEX_op_ld16s_i64:
1687     case INDEX_op_ld16u_i32:
1688     case INDEX_op_ld16u_i64:
1689     case INDEX_op_ld32s_i64:
1690     case INDEX_op_ld32u_i64:
1691     case INDEX_op_ld_i32:
1692     case INDEX_op_ld_i64:
1693         return C_O1_I1(r, r);
1695     case INDEX_op_qemu_ld_i32:
1696     case INDEX_op_qemu_ld_i64:
1697         return C_O1_I1(r, L);
1699     case INDEX_op_andc_i32:
1700     case INDEX_op_andc_i64:
1701     case INDEX_op_orc_i32:
1702     case INDEX_op_orc_i64:
1703         /*
1704          * LoongArch insns for these ops don't have reg-imm forms, but we
1705          * can express using andi/ori if ~constant satisfies
1706          * TCG_CT_CONST_U12.
1707          */
1708         return C_O1_I2(r, r, rC);
1710     case INDEX_op_shl_i32:
1711     case INDEX_op_shl_i64:
1712     case INDEX_op_shr_i32:
1713     case INDEX_op_shr_i64:
1714     case INDEX_op_sar_i32:
1715     case INDEX_op_sar_i64:
1716     case INDEX_op_rotl_i32:
1717     case INDEX_op_rotl_i64:
1718     case INDEX_op_rotr_i32:
1719     case INDEX_op_rotr_i64:
1720         return C_O1_I2(r, r, ri);
1722     case INDEX_op_add_i32:
1723         return C_O1_I2(r, r, ri);
1724     case INDEX_op_add_i64:
1725         return C_O1_I2(r, r, rJ);
1727     case INDEX_op_and_i32:
1728     case INDEX_op_and_i64:
1729     case INDEX_op_nor_i32:
1730     case INDEX_op_nor_i64:
1731     case INDEX_op_or_i32:
1732     case INDEX_op_or_i64:
1733     case INDEX_op_xor_i32:
1734     case INDEX_op_xor_i64:
1735         /* LoongArch reg-imm bitops have their imms ZERO-extended */
1736         return C_O1_I2(r, r, rU);
1738     case INDEX_op_clz_i32:
1739     case INDEX_op_clz_i64:
1740     case INDEX_op_ctz_i32:
1741     case INDEX_op_ctz_i64:
1742         return C_O1_I2(r, r, rW);
1744     case INDEX_op_deposit_i32:
1745     case INDEX_op_deposit_i64:
1746         /* Must deposit into the same register as input */
1747         return C_O1_I2(r, 0, rZ);
1749     case INDEX_op_sub_i32:
1750     case INDEX_op_setcond_i32:
1751         return C_O1_I2(r, rZ, ri);
1752     case INDEX_op_sub_i64:
1753     case INDEX_op_setcond_i64:
1754         return C_O1_I2(r, rZ, rJ);
1756     case INDEX_op_mul_i32:
1757     case INDEX_op_mul_i64:
1758     case INDEX_op_mulsh_i32:
1759     case INDEX_op_mulsh_i64:
1760     case INDEX_op_muluh_i32:
1761     case INDEX_op_muluh_i64:
1762     case INDEX_op_div_i32:
1763     case INDEX_op_div_i64:
1764     case INDEX_op_divu_i32:
1765     case INDEX_op_divu_i64:
1766     case INDEX_op_rem_i32:
1767     case INDEX_op_rem_i64:
1768     case INDEX_op_remu_i32:
1769     case INDEX_op_remu_i64:
1770         return C_O1_I2(r, rZ, rZ);
1772     case INDEX_op_movcond_i32:
1773     case INDEX_op_movcond_i64:
1774         return C_O1_I4(r, rZ, rJ, rZ, rZ);
1776     default:
1777         g_assert_not_reached();
1778     }
1781 static const int tcg_target_callee_save_regs[] = {
1782     TCG_REG_S0,     /* used for the global env (TCG_AREG0) */
1783     TCG_REG_S1,
1784     TCG_REG_S2,
1785     TCG_REG_S3,
1786     TCG_REG_S4,
1787     TCG_REG_S5,
1788     TCG_REG_S6,
1789     TCG_REG_S7,
1790     TCG_REG_S8,
1791     TCG_REG_S9,
1792     TCG_REG_RA,     /* should be last for ABI compliance */
1795 /* Stack frame parameters.  */
1796 #define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
1797 #define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
1798 #define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
1799 #define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
1800                      + TCG_TARGET_STACK_ALIGN - 1) \
1801                     & -TCG_TARGET_STACK_ALIGN)
1802 #define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
1804 /* We're expecting to be able to use an immediate for frame allocation.  */
1805 QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff);
1807 /* Generate global QEMU prologue and epilogue code */
1808 static void tcg_target_qemu_prologue(TCGContext *s)
1810     int i;
1812     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
1814     /* TB prologue */
1815     tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
1816     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1817         tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1818                    TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
1819     }
1821 #if !defined(CONFIG_SOFTMMU)
1822     if (USE_GUEST_BASE) {
1823         tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
1824         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1825     }
1826 #endif
1828     /* Call generated code */
1829     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1830     tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
1832     /* Return path for goto_ptr. Set return value to 0 */
1833     tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
1834     tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
1836     /* TB epilogue */
1837     tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
1838     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1839         tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1840                    TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
1841     }
1843     tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
1844     tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0);
1847 static void tcg_target_init(TCGContext *s)
1849     tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
1850     tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
1852     tcg_target_call_clobber_regs = ALL_GENERAL_REGS;
1853     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
1854     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
1855     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
1856     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3);
1857     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4);
1858     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5);
1859     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6);
1860     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7);
1861     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8);
1862     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9);
1864     s->reserved_regs = 0;
1865     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
1866     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0);
1867     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
1868     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2);
1869     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
1870     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
1871     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
1874 typedef struct {
1875     DebugFrameHeader h;
1876     uint8_t fde_def_cfa[4];
1877     uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
1878 } DebugFrame;
1880 #define ELF_HOST_MACHINE EM_LOONGARCH
1882 static const DebugFrame debug_frame = {
1883     .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
1884     .h.cie.id = -1,
1885     .h.cie.version = 1,
1886     .h.cie.code_align = 1,
1887     .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
1888     .h.cie.return_column = TCG_REG_RA,
1890     /* Total FDE size does not include the "len" member.  */
1891     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
1893     .fde_def_cfa = {
1894         12, TCG_REG_SP,                 /* DW_CFA_def_cfa sp, ...  */
1895         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
1896         (FRAME_SIZE >> 7)
1897     },
1898     .fde_reg_ofs = {
1899         0x80 + 23, 11,                  /* DW_CFA_offset, s0, -88 */
1900         0x80 + 24, 10,                  /* DW_CFA_offset, s1, -80 */
1901         0x80 + 25, 9,                   /* DW_CFA_offset, s2, -72 */
1902         0x80 + 26, 8,                   /* DW_CFA_offset, s3, -64 */
1903         0x80 + 27, 7,                   /* DW_CFA_offset, s4, -56 */
1904         0x80 + 28, 6,                   /* DW_CFA_offset, s5, -48 */
1905         0x80 + 29, 5,                   /* DW_CFA_offset, s6, -40 */
1906         0x80 + 30, 4,                   /* DW_CFA_offset, s7, -32 */
1907         0x80 + 31, 3,                   /* DW_CFA_offset, s8, -24 */
1908         0x80 + 22, 2,                   /* DW_CFA_offset, s9, -16 */
1909         0x80 + 1 , 1,                   /* DW_CFA_offset, ra, -8 */
1910     }
1913 void tcg_register_jit(const void *buf, size_t buf_size)
1915     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));