]> Git Repo - qemu.git/blob - tcg/mips/tcg-target.inc.c
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20170913-pull-request' into...
[qemu.git] / tcg / mips / tcg-target.inc.c
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008-2009 Arnaud Patard <[email protected]>
5  * Copyright (c) 2009 Aurelien Jarno <[email protected]>
6  * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26
27 #ifdef HOST_WORDS_BIGENDIAN
28 # define MIPS_BE  1
29 #else
30 # define MIPS_BE  0
31 #endif
32
33 #if TCG_TARGET_REG_BITS == 32
34 # define LO_OFF  (MIPS_BE * 4)
35 # define HI_OFF  (4 - LO_OFF)
36 #else
37 /* To assert at compile-time that these values are never used
38    for TCG_TARGET_REG_BITS == 64.  */
39 /* extern */ int link_error(void);
40 # define LO_OFF  link_error()
41 # define HI_OFF  link_error()
42 #endif
43
44 #ifdef CONFIG_DEBUG_TCG
45 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
46     "zero",
47     "at",
48     "v0",
49     "v1",
50     "a0",
51     "a1",
52     "a2",
53     "a3",
54     "t0",
55     "t1",
56     "t2",
57     "t3",
58     "t4",
59     "t5",
60     "t6",
61     "t7",
62     "s0",
63     "s1",
64     "s2",
65     "s3",
66     "s4",
67     "s5",
68     "s6",
69     "s7",
70     "t8",
71     "t9",
72     "k0",
73     "k1",
74     "gp",
75     "sp",
76     "s8",
77     "ra",
78 };
79 #endif
80
81 #define TCG_TMP0  TCG_REG_AT
82 #define TCG_TMP1  TCG_REG_T9
83 #define TCG_TMP2  TCG_REG_T8
84 #define TCG_TMP3  TCG_REG_T7
85
86 #ifndef CONFIG_SOFTMMU
87 #define TCG_GUEST_BASE_REG TCG_REG_S1
88 #endif
89
90 /* check if we really need so many registers :P */
91 static const int tcg_target_reg_alloc_order[] = {
92     /* Call saved registers.  */
93     TCG_REG_S0,
94     TCG_REG_S1,
95     TCG_REG_S2,
96     TCG_REG_S3,
97     TCG_REG_S4,
98     TCG_REG_S5,
99     TCG_REG_S6,
100     TCG_REG_S7,
101     TCG_REG_S8,
102
103     /* Call clobbered registers.  */
104     TCG_REG_T4,
105     TCG_REG_T5,
106     TCG_REG_T6,
107     TCG_REG_T7,
108     TCG_REG_T8,
109     TCG_REG_T9,
110     TCG_REG_V1,
111     TCG_REG_V0,
112
113     /* Argument registers, opposite order of allocation.  */
114     TCG_REG_T3,
115     TCG_REG_T2,
116     TCG_REG_T1,
117     TCG_REG_T0,
118     TCG_REG_A3,
119     TCG_REG_A2,
120     TCG_REG_A1,
121     TCG_REG_A0,
122 };
123
124 static const TCGReg tcg_target_call_iarg_regs[] = {
125     TCG_REG_A0,
126     TCG_REG_A1,
127     TCG_REG_A2,
128     TCG_REG_A3,
129 #if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
130     TCG_REG_T0,
131     TCG_REG_T1,
132     TCG_REG_T2,
133     TCG_REG_T3,
134 #endif
135 };
136
137 static const TCGReg tcg_target_call_oarg_regs[2] = {
138     TCG_REG_V0,
139     TCG_REG_V1
140 };
141
142 static tcg_insn_unit *tb_ret_addr;
143 static tcg_insn_unit *bswap32_addr;
144 static tcg_insn_unit *bswap32u_addr;
145 static tcg_insn_unit *bswap64_addr;
146
147 static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
148 {
149     /* Let the compiler perform the right-shift as part of the arithmetic.  */
150     ptrdiff_t disp = target - (pc + 1);
151     tcg_debug_assert(disp == (int16_t)disp);
152     return disp & 0xffff;
153 }
154
155 static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
156 {
157     *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
158 }
159
160 static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
161 {
162     tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
163     return ((uintptr_t)target >> 2) & 0x3ffffff;
164 }
165
166 static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
167 {
168     *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
169 }
170
171 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
172                         intptr_t value, intptr_t addend)
173 {
174     tcg_debug_assert(type == R_MIPS_PC16);
175     tcg_debug_assert(addend == 0);
176     reloc_pc16(code_ptr, (tcg_insn_unit *)value);
177 }
178
179 #define TCG_CT_CONST_ZERO 0x100
180 #define TCG_CT_CONST_U16  0x200    /* Unsigned 16-bit: 0 - 0xffff.  */
181 #define TCG_CT_CONST_S16  0x400    /* Signed 16-bit: -32768 - 32767 */
182 #define TCG_CT_CONST_P2M1 0x800    /* Power of 2 minus 1.  */
183 #define TCG_CT_CONST_N16  0x1000   /* "Negatable" 16-bit: -32767 - 32767 */
184 #define TCG_CT_CONST_WSZ  0x2000   /* word size */
185
186 static inline bool is_p2m1(tcg_target_long val)
187 {
188     return val && ((val + 1) & val) == 0;
189 }
190
191 /* parse target specific constraints */
192 static const char *target_parse_constraint(TCGArgConstraint *ct,
193                                            const char *ct_str, TCGType type)
194 {
195     switch(*ct_str++) {
196     case 'r':
197         ct->ct |= TCG_CT_REG;
198         tcg_regset_set(ct->u.regs, 0xffffffff);
199         break;
200     case 'L': /* qemu_ld input arg constraint */
201         ct->ct |= TCG_CT_REG;
202         tcg_regset_set(ct->u.regs, 0xffffffff);
203         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
204 #if defined(CONFIG_SOFTMMU)
205         if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
206             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
207         }
208 #endif
209         break;
210     case 'S': /* qemu_st constraint */
211         ct->ct |= TCG_CT_REG;
212         tcg_regset_set(ct->u.regs, 0xffffffff);
213         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
214 #if defined(CONFIG_SOFTMMU)
215         if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
216             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
217             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
218         } else {
219             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
220         }
221 #endif
222         break;
223     case 'I':
224         ct->ct |= TCG_CT_CONST_U16;
225         break;
226     case 'J':
227         ct->ct |= TCG_CT_CONST_S16;
228         break;
229     case 'K':
230         ct->ct |= TCG_CT_CONST_P2M1;
231         break;
232     case 'N':
233         ct->ct |= TCG_CT_CONST_N16;
234         break;
235     case 'W':
236         ct->ct |= TCG_CT_CONST_WSZ;
237         break;
238     case 'Z':
239         /* We are cheating a bit here, using the fact that the register
240            ZERO is also the register number 0. Hence there is no need
241            to check for const_args in each instruction. */
242         ct->ct |= TCG_CT_CONST_ZERO;
243         break;
244     default:
245         return NULL;
246     }
247     return ct_str;
248 }
249
250 /* test if a constant matches the constraint */
251 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
252                                          const TCGArgConstraint *arg_ct)
253 {
254     int ct;
255     ct = arg_ct->ct;
256     if (ct & TCG_CT_CONST) {
257         return 1;
258     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
259         return 1;
260     } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
261         return 1;
262     } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
263         return 1;
264     } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) {
265         return 1;
266     } else if ((ct & TCG_CT_CONST_P2M1)
267                && use_mips32r2_instructions && is_p2m1(val)) {
268         return 1;
269     } else if ((ct & TCG_CT_CONST_WSZ)
270                && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
271         return 1;
272     }
273     return 0;
274 }
275
276 /* instruction opcodes */
277 typedef enum {
278     OPC_J        = 002 << 26,
279     OPC_JAL      = 003 << 26,
280     OPC_BEQ      = 004 << 26,
281     OPC_BNE      = 005 << 26,
282     OPC_BLEZ     = 006 << 26,
283     OPC_BGTZ     = 007 << 26,
284     OPC_ADDIU    = 011 << 26,
285     OPC_SLTI     = 012 << 26,
286     OPC_SLTIU    = 013 << 26,
287     OPC_ANDI     = 014 << 26,
288     OPC_ORI      = 015 << 26,
289     OPC_XORI     = 016 << 26,
290     OPC_LUI      = 017 << 26,
291     OPC_DADDIU   = 031 << 26,
292     OPC_LB       = 040 << 26,
293     OPC_LH       = 041 << 26,
294     OPC_LW       = 043 << 26,
295     OPC_LBU      = 044 << 26,
296     OPC_LHU      = 045 << 26,
297     OPC_LWU      = 047 << 26,
298     OPC_SB       = 050 << 26,
299     OPC_SH       = 051 << 26,
300     OPC_SW       = 053 << 26,
301     OPC_LD       = 067 << 26,
302     OPC_SD       = 077 << 26,
303
304     OPC_SPECIAL  = 000 << 26,
305     OPC_SLL      = OPC_SPECIAL | 000,
306     OPC_SRL      = OPC_SPECIAL | 002,
307     OPC_ROTR     = OPC_SPECIAL | 002 | (1 << 21),
308     OPC_SRA      = OPC_SPECIAL | 003,
309     OPC_SLLV     = OPC_SPECIAL | 004,
310     OPC_SRLV     = OPC_SPECIAL | 006,
311     OPC_ROTRV    = OPC_SPECIAL | 006 | 0100,
312     OPC_SRAV     = OPC_SPECIAL | 007,
313     OPC_JR_R5    = OPC_SPECIAL | 010,
314     OPC_JALR     = OPC_SPECIAL | 011,
315     OPC_MOVZ     = OPC_SPECIAL | 012,
316     OPC_MOVN     = OPC_SPECIAL | 013,
317     OPC_SYNC     = OPC_SPECIAL | 017,
318     OPC_MFHI     = OPC_SPECIAL | 020,
319     OPC_MFLO     = OPC_SPECIAL | 022,
320     OPC_DSLLV    = OPC_SPECIAL | 024,
321     OPC_DSRLV    = OPC_SPECIAL | 026,
322     OPC_DROTRV   = OPC_SPECIAL | 026 | 0100,
323     OPC_DSRAV    = OPC_SPECIAL | 027,
324     OPC_MULT     = OPC_SPECIAL | 030,
325     OPC_MUL_R6   = OPC_SPECIAL | 030 | 0200,
326     OPC_MUH      = OPC_SPECIAL | 030 | 0300,
327     OPC_MULTU    = OPC_SPECIAL | 031,
328     OPC_MULU     = OPC_SPECIAL | 031 | 0200,
329     OPC_MUHU     = OPC_SPECIAL | 031 | 0300,
330     OPC_DIV      = OPC_SPECIAL | 032,
331     OPC_DIV_R6   = OPC_SPECIAL | 032 | 0200,
332     OPC_MOD      = OPC_SPECIAL | 032 | 0300,
333     OPC_DIVU     = OPC_SPECIAL | 033,
334     OPC_DIVU_R6  = OPC_SPECIAL | 033 | 0200,
335     OPC_MODU     = OPC_SPECIAL | 033 | 0300,
336     OPC_DMULT    = OPC_SPECIAL | 034,
337     OPC_DMUL     = OPC_SPECIAL | 034 | 0200,
338     OPC_DMUH     = OPC_SPECIAL | 034 | 0300,
339     OPC_DMULTU   = OPC_SPECIAL | 035,
340     OPC_DMULU    = OPC_SPECIAL | 035 | 0200,
341     OPC_DMUHU    = OPC_SPECIAL | 035 | 0300,
342     OPC_DDIV     = OPC_SPECIAL | 036,
343     OPC_DDIV_R6  = OPC_SPECIAL | 036 | 0200,
344     OPC_DMOD     = OPC_SPECIAL | 036 | 0300,
345     OPC_DDIVU    = OPC_SPECIAL | 037,
346     OPC_DDIVU_R6 = OPC_SPECIAL | 037 | 0200,
347     OPC_DMODU    = OPC_SPECIAL | 037 | 0300,
348     OPC_ADDU     = OPC_SPECIAL | 041,
349     OPC_SUBU     = OPC_SPECIAL | 043,
350     OPC_AND      = OPC_SPECIAL | 044,
351     OPC_OR       = OPC_SPECIAL | 045,
352     OPC_XOR      = OPC_SPECIAL | 046,
353     OPC_NOR      = OPC_SPECIAL | 047,
354     OPC_SLT      = OPC_SPECIAL | 052,
355     OPC_SLTU     = OPC_SPECIAL | 053,
356     OPC_DADDU    = OPC_SPECIAL | 055,
357     OPC_DSUBU    = OPC_SPECIAL | 057,
358     OPC_SELEQZ   = OPC_SPECIAL | 065,
359     OPC_SELNEZ   = OPC_SPECIAL | 067,
360     OPC_DSLL     = OPC_SPECIAL | 070,
361     OPC_DSRL     = OPC_SPECIAL | 072,
362     OPC_DROTR    = OPC_SPECIAL | 072 | (1 << 21),
363     OPC_DSRA     = OPC_SPECIAL | 073,
364     OPC_DSLL32   = OPC_SPECIAL | 074,
365     OPC_DSRL32   = OPC_SPECIAL | 076,
366     OPC_DROTR32  = OPC_SPECIAL | 076 | (1 << 21),
367     OPC_DSRA32   = OPC_SPECIAL | 077,
368     OPC_CLZ_R6   = OPC_SPECIAL | 0120,
369     OPC_DCLZ_R6  = OPC_SPECIAL | 0122,
370
371     OPC_REGIMM   = 001 << 26,
372     OPC_BLTZ     = OPC_REGIMM | (000 << 16),
373     OPC_BGEZ     = OPC_REGIMM | (001 << 16),
374
375     OPC_SPECIAL2 = 034 << 26,
376     OPC_MUL_R5   = OPC_SPECIAL2 | 002,
377     OPC_CLZ      = OPC_SPECIAL2 | 040,
378     OPC_DCLZ     = OPC_SPECIAL2 | 044,
379
380     OPC_SPECIAL3 = 037 << 26,
381     OPC_EXT      = OPC_SPECIAL3 | 000,
382     OPC_DEXTM    = OPC_SPECIAL3 | 001,
383     OPC_DEXTU    = OPC_SPECIAL3 | 002,
384     OPC_DEXT     = OPC_SPECIAL3 | 003,
385     OPC_INS      = OPC_SPECIAL3 | 004,
386     OPC_DINSM    = OPC_SPECIAL3 | 005,
387     OPC_DINSU    = OPC_SPECIAL3 | 006,
388     OPC_DINS     = OPC_SPECIAL3 | 007,
389     OPC_WSBH     = OPC_SPECIAL3 | 00240,
390     OPC_DSBH     = OPC_SPECIAL3 | 00244,
391     OPC_DSHD     = OPC_SPECIAL3 | 00544,
392     OPC_SEB      = OPC_SPECIAL3 | 02040,
393     OPC_SEH      = OPC_SPECIAL3 | 03040,
394
395     /* MIPS r6 doesn't have JR, JALR should be used instead */
396     OPC_JR       = use_mips32r6_instructions ? OPC_JALR : OPC_JR_R5,
397
398     /*
399      * MIPS r6 replaces MUL with an alternative encoding which is
400      * backwards-compatible at the assembly level.
401      */
402     OPC_MUL      = use_mips32r6_instructions ? OPC_MUL_R6 : OPC_MUL_R5,
403
404     /* MIPS r6 introduced names for weaker variants of SYNC.  These are
405        backward compatible to previous architecture revisions.  */
406     OPC_SYNC_WMB     = OPC_SYNC | 0x04 << 5,
407     OPC_SYNC_MB      = OPC_SYNC | 0x10 << 5,
408     OPC_SYNC_ACQUIRE = OPC_SYNC | 0x11 << 5,
409     OPC_SYNC_RELEASE = OPC_SYNC | 0x12 << 5,
410     OPC_SYNC_RMB     = OPC_SYNC | 0x13 << 5,
411
412     /* Aliases for convenience.  */
413     ALIAS_PADD     = sizeof(void *) == 4 ? OPC_ADDU : OPC_DADDU,
414     ALIAS_PADDI    = sizeof(void *) == 4 ? OPC_ADDIU : OPC_DADDIU,
415     ALIAS_TSRL     = TARGET_LONG_BITS == 32 || TCG_TARGET_REG_BITS == 32
416                      ? OPC_SRL : OPC_DSRL,
417 } MIPSInsn;
418
419 /*
420  * Type reg
421  */
422 static inline void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
423                                    TCGReg rd, TCGReg rs, TCGReg rt)
424 {
425     int32_t inst;
426
427     inst = opc;
428     inst |= (rs & 0x1F) << 21;
429     inst |= (rt & 0x1F) << 16;
430     inst |= (rd & 0x1F) << 11;
431     tcg_out32(s, inst);
432 }
433
434 /*
435  * Type immediate
436  */
437 static inline void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
438                                    TCGReg rt, TCGReg rs, TCGArg imm)
439 {
440     int32_t inst;
441
442     inst = opc;
443     inst |= (rs & 0x1F) << 21;
444     inst |= (rt & 0x1F) << 16;
445     inst |= (imm & 0xffff);
446     tcg_out32(s, inst);
447 }
448
449 /*
450  * Type bitfield
451  */
452 static inline void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
453                                   TCGReg rs, int msb, int lsb)
454 {
455     int32_t inst;
456
457     inst = opc;
458     inst |= (rs & 0x1F) << 21;
459     inst |= (rt & 0x1F) << 16;
460     inst |= (msb & 0x1F) << 11;
461     inst |= (lsb & 0x1F) << 6;
462     tcg_out32(s, inst);
463 }
464
465 static inline void tcg_out_opc_bf64(TCGContext *s, MIPSInsn opc, MIPSInsn opm,
466                                     MIPSInsn oph, TCGReg rt, TCGReg rs,
467                                     int msb, int lsb)
468 {
469     if (lsb >= 32) {
470         opc = oph;
471         msb -= 32;
472         lsb -= 32;
473     } else if (msb >= 32) {
474         opc = opm;
475         msb -= 32;
476     }
477     tcg_out_opc_bf(s, opc, rt, rs, msb, lsb);
478 }
479
480 /*
481  * Type branch
482  */
483 static inline void tcg_out_opc_br(TCGContext *s, MIPSInsn opc,
484                                   TCGReg rt, TCGReg rs)
485 {
486     /* We pay attention here to not modify the branch target by reading
487        the existing value and using it again. This ensure that caches and
488        memory are kept coherent during retranslation. */
489     uint16_t offset = (uint16_t)*s->code_ptr;
490
491     tcg_out_opc_imm(s, opc, rt, rs, offset);
492 }
493
494 /*
495  * Type sa
496  */
497 static inline void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
498                                   TCGReg rd, TCGReg rt, TCGArg sa)
499 {
500     int32_t inst;
501
502     inst = opc;
503     inst |= (rt & 0x1F) << 16;
504     inst |= (rd & 0x1F) << 11;
505     inst |= (sa & 0x1F) <<  6;
506     tcg_out32(s, inst);
507
508 }
509
510 static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn opc1, MIPSInsn opc2,
511                              TCGReg rd, TCGReg rt, TCGArg sa)
512 {
513     int32_t inst;
514
515     inst = (sa & 32 ? opc2 : opc1);
516     inst |= (rt & 0x1F) << 16;
517     inst |= (rd & 0x1F) << 11;
518     inst |= (sa & 0x1F) <<  6;
519     tcg_out32(s, inst);
520 }
521
522 /*
523  * Type jump.
524  * Returns true if the branch was in range and the insn was emitted.
525  */
526 static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
527 {
528     uintptr_t dest = (uintptr_t)target;
529     uintptr_t from = (uintptr_t)s->code_ptr + 4;
530     int32_t inst;
531
532     /* The pc-region branch happens within the 256MB region of
533        the delay slot (thus the +4).  */
534     if ((from ^ dest) & -(1 << 28)) {
535         return false;
536     }
537     tcg_debug_assert((dest & 3) == 0);
538
539     inst = opc;
540     inst |= (dest >> 2) & 0x3ffffff;
541     tcg_out32(s, inst);
542     return true;
543 }
544
545 static inline void tcg_out_nop(TCGContext *s)
546 {
547     tcg_out32(s, 0);
548 }
549
550 static inline void tcg_out_dsll(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
551 {
552     tcg_out_opc_sa64(s, OPC_DSLL, OPC_DSLL32, rd, rt, sa);
553 }
554
555 static inline void tcg_out_dsrl(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
556 {
557     tcg_out_opc_sa64(s, OPC_DSRL, OPC_DSRL32, rd, rt, sa);
558 }
559
560 static inline void tcg_out_dsra(TCGContext *s, TCGReg rd, TCGReg rt, TCGArg sa)
561 {
562     tcg_out_opc_sa64(s, OPC_DSRA, OPC_DSRA32, rd, rt, sa);
563 }
564
565 static inline void tcg_out_mov(TCGContext *s, TCGType type,
566                                TCGReg ret, TCGReg arg)
567 {
568     /* Simple reg-reg move, optimising out the 'do nothing' case */
569     if (ret != arg) {
570         tcg_out_opc_reg(s, OPC_OR, ret, arg, TCG_REG_ZERO);
571     }
572 }
573
574 static void tcg_out_movi(TCGContext *s, TCGType type,
575                          TCGReg ret, tcg_target_long arg)
576 {
577     if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
578         arg = (int32_t)arg;
579     }
580     if (arg == (int16_t)arg) {
581         tcg_out_opc_imm(s, OPC_ADDIU, ret, TCG_REG_ZERO, arg);
582         return;
583     }
584     if (arg == (uint16_t)arg) {
585         tcg_out_opc_imm(s, OPC_ORI, ret, TCG_REG_ZERO, arg);
586         return;
587     }
588     if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {
589         tcg_out_opc_imm(s, OPC_LUI, ret, TCG_REG_ZERO, arg >> 16);
590     } else {
591         tcg_out_movi(s, TCG_TYPE_I32, ret, arg >> 31 >> 1);
592         if (arg & 0xffff0000ull) {
593             tcg_out_dsll(s, ret, ret, 16);
594             tcg_out_opc_imm(s, OPC_ORI, ret, ret, arg >> 16);
595             tcg_out_dsll(s, ret, ret, 16);
596         } else {
597             tcg_out_dsll(s, ret, ret, 32);
598         }
599     }
600     if (arg & 0xffff) {
601         tcg_out_opc_imm(s, OPC_ORI, ret, ret, arg & 0xffff);
602     }
603 }
604
605 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
606 {
607     if (use_mips32r2_instructions) {
608         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
609     } else {
610         /* ret and arg can't be register at */
611         if (ret == TCG_TMP0 || arg == TCG_TMP0) {
612             tcg_abort();
613         }
614
615         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
616         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
617         tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
618         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
619     }
620 }
621
622 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
623 {
624     if (use_mips32r2_instructions) {
625         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
626         tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
627     } else {
628         /* ret and arg can't be register at */
629         if (ret == TCG_TMP0 || arg == TCG_TMP0) {
630             tcg_abort();
631         }
632
633         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
634         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
635         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
636         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
637     }
638 }
639
640 static void tcg_out_bswap_subr(TCGContext *s, tcg_insn_unit *sub)
641 {
642     bool ok = tcg_out_opc_jmp(s, OPC_JAL, sub);
643     tcg_debug_assert(ok);
644 }
645
646 static void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
647 {
648     if (use_mips32r2_instructions) {
649         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
650         tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
651     } else {
652         tcg_out_bswap_subr(s, bswap32_addr);
653         /* delay slot -- never omit the insn, like tcg_out_mov might.  */
654         tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
655         tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
656     }
657 }
658
659 static void tcg_out_bswap32u(TCGContext *s, TCGReg ret, TCGReg arg)
660 {
661     if (use_mips32r2_instructions) {
662         tcg_out_opc_reg(s, OPC_DSBH, ret, 0, arg);
663         tcg_out_opc_reg(s, OPC_DSHD, ret, 0, ret);
664         tcg_out_dsrl(s, ret, ret, 32);
665     } else {
666         tcg_out_bswap_subr(s, bswap32u_addr);
667         /* delay slot -- never omit the insn, like tcg_out_mov might.  */
668         tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
669         tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
670     }
671 }
672
673 static void tcg_out_bswap64(TCGContext *s, TCGReg ret, TCGReg arg)
674 {
675     if (use_mips32r2_instructions) {
676         tcg_out_opc_reg(s, OPC_DSBH, ret, 0, arg);
677         tcg_out_opc_reg(s, OPC_DSHD, ret, 0, ret);
678     } else {
679         tcg_out_bswap_subr(s, bswap64_addr);
680         /* delay slot -- never omit the insn, like tcg_out_mov might.  */
681         tcg_out_opc_reg(s, OPC_OR, TCG_TMP0, arg, TCG_REG_ZERO);
682         tcg_out_mov(s, TCG_TYPE_I32, ret, TCG_TMP3);
683     }
684 }
685
686 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
687 {
688     if (use_mips32r2_instructions) {
689         tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
690     } else {
691         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
692         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
693     }
694 }
695
696 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
697 {
698     if (use_mips32r2_instructions) {
699         tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
700     } else {
701         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
702         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
703     }
704 }
705
706 static inline void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
707 {
708     if (use_mips32r2_instructions) {
709         tcg_out_opc_bf(s, OPC_DEXT, ret, arg, 31, 0);
710     } else {
711         tcg_out_dsll(s, ret, arg, 32);
712         tcg_out_dsrl(s, ret, ret, 32);
713     }
714 }
715
716 static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
717                          TCGReg addr, intptr_t ofs)
718 {
719     int16_t lo = ofs;
720     if (ofs != lo) {
721         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
722         if (addr != TCG_REG_ZERO) {
723             tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP0, TCG_TMP0, addr);
724         }
725         addr = TCG_TMP0;
726     }
727     tcg_out_opc_imm(s, opc, data, addr, lo);
728 }
729
730 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
731                               TCGReg arg1, intptr_t arg2)
732 {
733     MIPSInsn opc = OPC_LD;
734     if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
735         opc = OPC_LW;
736     }
737     tcg_out_ldst(s, opc, arg, arg1, arg2);
738 }
739
740 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
741                               TCGReg arg1, intptr_t arg2)
742 {
743     MIPSInsn opc = OPC_SD;
744     if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
745         opc = OPC_SW;
746     }
747     tcg_out_ldst(s, opc, arg, arg1, arg2);
748 }
749
750 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
751                                TCGReg base, intptr_t ofs)
752 {
753     if (val == 0) {
754         tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
755         return true;
756     }
757     return false;
758 }
759
760 static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
761                             TCGReg ah, TCGArg bl, TCGArg bh, bool cbl,
762                             bool cbh, bool is_sub)
763 {
764     TCGReg th = TCG_TMP1;
765
766     /* If we have a negative constant such that negating it would
767        make the high part zero, we can (usually) eliminate one insn.  */
768     if (cbl && cbh && bh == -1 && bl != 0) {
769         bl = -bl;
770         bh = 0;
771         is_sub = !is_sub;
772     }
773
774     /* By operating on the high part first, we get to use the final
775        carry operation to move back from the temporary.  */
776     if (!cbh) {
777         tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh);
778     } else if (bh != 0 || ah == rl) {
779         tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh));
780     } else {
781         th = ah;
782     }
783
784     /* Note that tcg optimization should eliminate the bl == 0 case.  */
785     if (is_sub) {
786         if (cbl) {
787             tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl);
788             tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl);
789         } else {
790             tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl);
791             tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl);
792         }
793         tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0);
794     } else {
795         if (cbl) {
796             tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
797             tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
798         } else if (rl == al && rl == bl) {
799             tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
800             tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
801         } else {
802             tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
803             tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
804         }
805         tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0);
806     }
807 }
808
809 /* Bit 0 set if inversion required; bit 1 set if swapping required.  */
810 #define MIPS_CMP_INV  1
811 #define MIPS_CMP_SWAP 2
812
813 static const uint8_t mips_cmp_map[16] = {
814     [TCG_COND_LT]  = 0,
815     [TCG_COND_LTU] = 0,
816     [TCG_COND_GE]  = MIPS_CMP_INV,
817     [TCG_COND_GEU] = MIPS_CMP_INV,
818     [TCG_COND_LE]  = MIPS_CMP_INV | MIPS_CMP_SWAP,
819     [TCG_COND_LEU] = MIPS_CMP_INV | MIPS_CMP_SWAP,
820     [TCG_COND_GT]  = MIPS_CMP_SWAP,
821     [TCG_COND_GTU] = MIPS_CMP_SWAP,
822 };
823
824 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
825                             TCGReg arg1, TCGReg arg2)
826 {
827     MIPSInsn s_opc = OPC_SLTU;
828     int cmp_map;
829
830     switch (cond) {
831     case TCG_COND_EQ:
832         if (arg2 != 0) {
833             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
834             arg1 = ret;
835         }
836         tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
837         break;
838
839     case TCG_COND_NE:
840         if (arg2 != 0) {
841             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
842             arg1 = ret;
843         }
844         tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
845         break;
846
847     case TCG_COND_LT:
848     case TCG_COND_GE:
849     case TCG_COND_LE:
850     case TCG_COND_GT:
851         s_opc = OPC_SLT;
852         /* FALLTHRU */
853
854     case TCG_COND_LTU:
855     case TCG_COND_GEU:
856     case TCG_COND_LEU:
857     case TCG_COND_GTU:
858         cmp_map = mips_cmp_map[cond];
859         if (cmp_map & MIPS_CMP_SWAP) {
860             TCGReg t = arg1;
861             arg1 = arg2;
862             arg2 = t;
863         }
864         tcg_out_opc_reg(s, s_opc, ret, arg1, arg2);
865         if (cmp_map & MIPS_CMP_INV) {
866             tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
867         }
868         break;
869
870      default:
871          tcg_abort();
872          break;
873      }
874 }
875
876 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
877                            TCGReg arg2, TCGLabel *l)
878 {
879     static const MIPSInsn b_zero[16] = {
880         [TCG_COND_LT] = OPC_BLTZ,
881         [TCG_COND_GT] = OPC_BGTZ,
882         [TCG_COND_LE] = OPC_BLEZ,
883         [TCG_COND_GE] = OPC_BGEZ,
884     };
885
886     MIPSInsn s_opc = OPC_SLTU;
887     MIPSInsn b_opc;
888     int cmp_map;
889
890     switch (cond) {
891     case TCG_COND_EQ:
892         b_opc = OPC_BEQ;
893         break;
894     case TCG_COND_NE:
895         b_opc = OPC_BNE;
896         break;
897
898     case TCG_COND_LT:
899     case TCG_COND_GT:
900     case TCG_COND_LE:
901     case TCG_COND_GE:
902         if (arg2 == 0) {
903             b_opc = b_zero[cond];
904             arg2 = arg1;
905             arg1 = 0;
906             break;
907         }
908         s_opc = OPC_SLT;
909         /* FALLTHRU */
910
911     case TCG_COND_LTU:
912     case TCG_COND_GTU:
913     case TCG_COND_LEU:
914     case TCG_COND_GEU:
915         cmp_map = mips_cmp_map[cond];
916         if (cmp_map & MIPS_CMP_SWAP) {
917             TCGReg t = arg1;
918             arg1 = arg2;
919             arg2 = t;
920         }
921         tcg_out_opc_reg(s, s_opc, TCG_TMP0, arg1, arg2);
922         b_opc = (cmp_map & MIPS_CMP_INV ? OPC_BEQ : OPC_BNE);
923         arg1 = TCG_TMP0;
924         arg2 = TCG_REG_ZERO;
925         break;
926
927     default:
928         tcg_abort();
929         break;
930     }
931
932     tcg_out_opc_br(s, b_opc, arg1, arg2);
933     if (l->has_value) {
934         reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
935     } else {
936         tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
937     }
938     tcg_out_nop(s);
939 }
940
941 static TCGReg tcg_out_reduce_eq2(TCGContext *s, TCGReg tmp0, TCGReg tmp1,
942                                  TCGReg al, TCGReg ah,
943                                  TCGReg bl, TCGReg bh)
944 {
945     /* Merge highpart comparison into AH.  */
946     if (bh != 0) {
947         if (ah != 0) {
948             tcg_out_opc_reg(s, OPC_XOR, tmp0, ah, bh);
949             ah = tmp0;
950         } else {
951             ah = bh;
952         }
953     }
954     /* Merge lowpart comparison into AL.  */
955     if (bl != 0) {
956         if (al != 0) {
957             tcg_out_opc_reg(s, OPC_XOR, tmp1, al, bl);
958             al = tmp1;
959         } else {
960             al = bl;
961         }
962     }
963     /* Merge high and low part comparisons into AL.  */
964     if (ah != 0) {
965         if (al != 0) {
966             tcg_out_opc_reg(s, OPC_OR, tmp0, ah, al);
967             al = tmp0;
968         } else {
969             al = ah;
970         }
971     }
972     return al;
973 }
974
975 static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
976                              TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
977 {
978     TCGReg tmp0 = TCG_TMP0;
979     TCGReg tmp1 = ret;
980
981     tcg_debug_assert(ret != TCG_TMP0);
982     if (ret == ah || ret == bh) {
983         tcg_debug_assert(ret != TCG_TMP1);
984         tmp1 = TCG_TMP1;
985     }
986
987     switch (cond) {
988     case TCG_COND_EQ:
989     case TCG_COND_NE:
990         tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);
991         tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
992         break;
993
994     default:
995         tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
996         tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
997         tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);
998         tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);
999         tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);
1000         break;
1001     }
1002 }
1003
1004 static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
1005                             TCGReg bl, TCGReg bh, TCGLabel *l)
1006 {
1007     TCGCond b_cond = TCG_COND_NE;
1008     TCGReg tmp = TCG_TMP1;
1009
1010     /* With branches, we emit between 4 and 9 insns with 2 or 3 branches.
1011        With setcond, we emit between 3 and 10 insns and only 1 branch,
1012        which ought to get better branch prediction.  */
1013      switch (cond) {
1014      case TCG_COND_EQ:
1015      case TCG_COND_NE:
1016         b_cond = cond;
1017         tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
1018         break;
1019
1020     default:
1021         /* Minimize code size by preferring a compare not requiring INV.  */
1022         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
1023             cond = tcg_invert_cond(cond);
1024             b_cond = TCG_COND_EQ;
1025         }
1026         tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh);
1027         break;
1028     }
1029
1030     tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
1031 }
1032
1033 static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
1034                             TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
1035 {
1036     bool eqz = false;
1037
1038     /* If one of the values is zero, put it last to match SEL*Z instructions */
1039     if (use_mips32r6_instructions && v1 == 0) {
1040         v1 = v2;
1041         v2 = 0;
1042         cond = tcg_invert_cond(cond);
1043     }
1044
1045     switch (cond) {
1046     case TCG_COND_EQ:
1047         eqz = true;
1048         /* FALLTHRU */
1049     case TCG_COND_NE:
1050         if (c2 != 0) {
1051             tcg_out_opc_reg(s, OPC_XOR, TCG_TMP0, c1, c2);
1052             c1 = TCG_TMP0;
1053         }
1054         break;
1055
1056     default:
1057         /* Minimize code size by preferring a compare not requiring INV.  */
1058         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
1059             cond = tcg_invert_cond(cond);
1060             eqz = true;
1061         }
1062         tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
1063         c1 = TCG_TMP0;
1064         break;
1065     }
1066
1067     if (use_mips32r6_instructions) {
1068         MIPSInsn m_opc_t = eqz ? OPC_SELEQZ : OPC_SELNEZ;
1069         MIPSInsn m_opc_f = eqz ? OPC_SELNEZ : OPC_SELEQZ;
1070
1071         if (v2 != 0) {
1072             tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
1073         }
1074         tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
1075         if (v2 != 0) {
1076             tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
1077         }
1078     } else {
1079         MIPSInsn m_opc = eqz ? OPC_MOVZ : OPC_MOVN;
1080
1081         tcg_out_opc_reg(s, m_opc, ret, v1, c1);
1082
1083         /* This should be guaranteed via constraints */
1084         tcg_debug_assert(v2 == ret);
1085     }
1086 }
1087
1088 static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
1089 {
1090     /* Note that the ABI requires the called function's address to be
1091        loaded into T9, even if a direct branch is in range.  */
1092     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T9, (uintptr_t)arg);
1093
1094     /* But do try a direct branch, allowing the cpu better insn prefetch.  */
1095     if (tail) {
1096         if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
1097             tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
1098         }
1099     } else {
1100         if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
1101             tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1102         }
1103     }
1104 }
1105
1106 static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
1107 {
1108     tcg_out_call_int(s, arg, false);
1109     tcg_out_nop(s);
1110 }
1111
1112 #if defined(CONFIG_SOFTMMU)
1113 #include "tcg-ldst.inc.c"
1114
1115 static void * const qemu_ld_helpers[16] = {
1116     [MO_UB]   = helper_ret_ldub_mmu,
1117     [MO_SB]   = helper_ret_ldsb_mmu,
1118     [MO_LEUW] = helper_le_lduw_mmu,
1119     [MO_LESW] = helper_le_ldsw_mmu,
1120     [MO_LEUL] = helper_le_ldul_mmu,
1121     [MO_LEQ]  = helper_le_ldq_mmu,
1122     [MO_BEUW] = helper_be_lduw_mmu,
1123     [MO_BESW] = helper_be_ldsw_mmu,
1124     [MO_BEUL] = helper_be_ldul_mmu,
1125     [MO_BEQ]  = helper_be_ldq_mmu,
1126 #if TCG_TARGET_REG_BITS == 64
1127     [MO_LESL] = helper_le_ldsl_mmu,
1128     [MO_BESL] = helper_be_ldsl_mmu,
1129 #endif
1130 };
1131
1132 static void * const qemu_st_helpers[16] = {
1133     [MO_UB]   = helper_ret_stb_mmu,
1134     [MO_LEUW] = helper_le_stw_mmu,
1135     [MO_LEUL] = helper_le_stl_mmu,
1136     [MO_LEQ]  = helper_le_stq_mmu,
1137     [MO_BEUW] = helper_be_stw_mmu,
1138     [MO_BEUL] = helper_be_stl_mmu,
1139     [MO_BEQ]  = helper_be_stq_mmu,
1140 };
1141
1142 /* Helper routines for marshalling helper function arguments into
1143  * the correct registers and stack.
1144  * I is where we want to put this argument, and is updated and returned
1145  * for the next call. ARG is the argument itself.
1146  *
1147  * We provide routines for arguments which are: immediate, 32 bit
1148  * value in register, 16 and 8 bit values in register (which must be zero
1149  * extended before use) and 64 bit value in a lo:hi register pair.
1150  */
1151
1152 static int tcg_out_call_iarg_reg(TCGContext *s, int i, TCGReg arg)
1153 {
1154     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1155         tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[i], arg);
1156     } else {
1157         /* For N32 and N64, the initial offset is different.  But there
1158            we also have 8 argument register so we don't run out here.  */
1159         tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
1160         tcg_out_st(s, TCG_TYPE_REG, arg, TCG_REG_SP, 4 * i);
1161     }
1162     return i + 1;
1163 }
1164
1165 static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
1166 {
1167     TCGReg tmp = TCG_TMP0;
1168     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1169         tmp = tcg_target_call_iarg_regs[i];
1170     }
1171     tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
1172     return tcg_out_call_iarg_reg(s, i, tmp);
1173 }
1174
1175 static int tcg_out_call_iarg_reg16(TCGContext *s, int i, TCGReg arg)
1176 {
1177     TCGReg tmp = TCG_TMP0;
1178     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1179         tmp = tcg_target_call_iarg_regs[i];
1180     }
1181     tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xffff);
1182     return tcg_out_call_iarg_reg(s, i, tmp);
1183 }
1184
1185 static int tcg_out_call_iarg_imm(TCGContext *s, int i, TCGArg arg)
1186 {
1187     TCGReg tmp = TCG_TMP0;
1188     if (arg == 0) {
1189         tmp = TCG_REG_ZERO;
1190     } else {
1191         if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
1192             tmp = tcg_target_call_iarg_regs[i];
1193         }
1194         tcg_out_movi(s, TCG_TYPE_REG, tmp, arg);
1195     }
1196     return tcg_out_call_iarg_reg(s, i, tmp);
1197 }
1198
1199 static int tcg_out_call_iarg_reg2(TCGContext *s, int i, TCGReg al, TCGReg ah)
1200 {
1201     tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
1202     i = (i + 1) & ~1;
1203     i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? ah : al));
1204     i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? al : ah));
1205     return i;
1206 }
1207
1208 /* Perform the tlb comparison operation.  The complete host address is
1209    placed in BASE.  Clobbers TMP0, TMP1, TMP2, A0.  */
1210 static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
1211                              TCGReg addrh, TCGMemOpIdx oi,
1212                              tcg_insn_unit *label_ptr[2], bool is_load)
1213 {
1214     TCGMemOp opc = get_memop(oi);
1215     unsigned s_bits = opc & MO_SIZE;
1216     unsigned a_bits = get_alignment_bits(opc);
1217     target_ulong mask;
1218     int mem_index = get_mmuidx(oi);
1219     int cmp_off
1220         = (is_load
1221            ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1222            : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1223     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1224
1225     tcg_out_opc_sa(s, ALIAS_TSRL, TCG_REG_A0, addrl,
1226                    TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1227     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0,
1228                     (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1229     tcg_out_opc_reg(s, ALIAS_PADD, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1230
1231     /* Compensate for very large offsets.  */
1232     if (add_off >= 0x8000) {
1233         /* Most target env are smaller than 32k; none are larger than 64k.
1234            Simplify the logic here merely to offset by 0x7ff0, giving us a
1235            range just shy of 64k.  Check this assumption.  */
1236         QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
1237                                    tlb_table[NB_MMU_MODES - 1][1])
1238                           > 0x7ff0 + 0x7fff);
1239         tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_A0, TCG_REG_A0, 0x7ff0);
1240         cmp_off -= 0x7ff0;
1241         add_off -= 0x7ff0;
1242     }
1243
1244     /* We don't currently support unaligned accesses.
1245        We could do so with mips32r6.  */
1246     if (a_bits < s_bits) {
1247         a_bits = s_bits;
1248     }
1249
1250     mask = (target_ulong)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
1251
1252     /* Load the (low half) tlb comparator.  Mask the page bits, keeping the
1253        alignment bits to compare against.  */
1254     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1255         tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_REG_A0, cmp_off + LO_OFF);
1256         tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1, mask);
1257     } else {
1258         tcg_out_ldst(s,
1259                     (TARGET_LONG_BITS == 64 ? OPC_LD
1260                     : TCG_TARGET_REG_BITS == 64 ? OPC_LWU : OPC_LW),
1261                     TCG_TMP0, TCG_REG_A0, cmp_off);
1262         tcg_out_movi(s, TCG_TYPE_TL, TCG_TMP1, mask);
1263         /* No second compare is required here;
1264            load the tlb addend for the fast path.  */
1265         tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_REG_A0, add_off);
1266     }
1267     tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl);
1268
1269     /* Zero extend a 32-bit guest address for a 64-bit host. */
1270     if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1271         tcg_out_ext32u(s, base, addrl);
1272         addrl = base;
1273     }
1274
1275     label_ptr[0] = s->code_ptr;
1276     tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
1277
1278     /* Load and test the high half tlb comparator.  */
1279     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1280         /* delay slot */
1281         tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_REG_A0, cmp_off + HI_OFF);
1282
1283         /* Load the tlb addend for the fast path.  */
1284         tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP2, TCG_REG_A0, add_off);
1285
1286         label_ptr[1] = s->code_ptr;
1287         tcg_out_opc_br(s, OPC_BNE, addrh, TCG_TMP0);
1288     }
1289
1290     /* delay slot */
1291     tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP2, addrl);
1292 }
1293
1294 static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
1295                                 TCGType ext,
1296                                 TCGReg datalo, TCGReg datahi,
1297                                 TCGReg addrlo, TCGReg addrhi,
1298                                 void *raddr, tcg_insn_unit *label_ptr[2])
1299 {
1300     TCGLabelQemuLdst *label = new_ldst_label(s);
1301
1302     label->is_ld = is_ld;
1303     label->oi = oi;
1304     label->type = ext;
1305     label->datalo_reg = datalo;
1306     label->datahi_reg = datahi;
1307     label->addrlo_reg = addrlo;
1308     label->addrhi_reg = addrhi;
1309     label->raddr = raddr;
1310     label->label_ptr[0] = label_ptr[0];
1311     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1312         label->label_ptr[1] = label_ptr[1];
1313     }
1314 }
1315
1316 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1317 {
1318     TCGMemOpIdx oi = l->oi;
1319     TCGMemOp opc = get_memop(oi);
1320     TCGReg v0;
1321     int i;
1322
1323     /* resolve label address */
1324     reloc_pc16(l->label_ptr[0], s->code_ptr);
1325     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1326         reloc_pc16(l->label_ptr[1], s->code_ptr);
1327     }
1328
1329     i = 1;
1330     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1331         i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1332     } else {
1333         i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1334     }
1335     i = tcg_out_call_iarg_imm(s, i, oi);
1336     i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr);
1337     tcg_out_call_int(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)], false);
1338     /* delay slot */
1339     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1340
1341     v0 = l->datalo_reg;
1342     if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1343         /* We eliminated V0 from the possible output registers, so it
1344            cannot be clobbered here.  So we must move V1 first.  */
1345         if (MIPS_BE) {
1346             tcg_out_mov(s, TCG_TYPE_I32, v0, TCG_REG_V1);
1347             v0 = l->datahi_reg;
1348         } else {
1349             tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_V1);
1350         }
1351     }
1352
1353     reloc_pc16(s->code_ptr, l->raddr);
1354     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1355     /* delay slot */
1356     if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) {
1357         /* we always sign-extend 32-bit loads */
1358         tcg_out_opc_sa(s, OPC_SLL, v0, TCG_REG_V0, 0);
1359     } else {
1360         tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO);
1361     }
1362 }
1363
1364 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1365 {
1366     TCGMemOpIdx oi = l->oi;
1367     TCGMemOp opc = get_memop(oi);
1368     TCGMemOp s_bits = opc & MO_SIZE;
1369     int i;
1370
1371     /* resolve label address */
1372     reloc_pc16(l->label_ptr[0], s->code_ptr);
1373     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1374         reloc_pc16(l->label_ptr[1], s->code_ptr);
1375     }
1376
1377     i = 1;
1378     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1379         i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1380     } else {
1381         i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1382     }
1383     switch (s_bits) {
1384     case MO_8:
1385         i = tcg_out_call_iarg_reg8(s, i, l->datalo_reg);
1386         break;
1387     case MO_16:
1388         i = tcg_out_call_iarg_reg16(s, i, l->datalo_reg);
1389         break;
1390     case MO_32:
1391         i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1392         break;
1393     case MO_64:
1394         if (TCG_TARGET_REG_BITS == 32) {
1395             i = tcg_out_call_iarg_reg2(s, i, l->datalo_reg, l->datahi_reg);
1396         } else {
1397             i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1398         }
1399         break;
1400     default:
1401         tcg_abort();
1402     }
1403     i = tcg_out_call_iarg_imm(s, i, oi);
1404
1405     /* Tail call to the store helper.  Thus force the return address
1406        computation to take place in the return address register.  */
1407     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)l->raddr);
1408     i = tcg_out_call_iarg_reg(s, i, TCG_REG_RA);
1409     tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
1410     /* delay slot */
1411     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1412 }
1413 #endif
1414
1415 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1416                                    TCGReg base, TCGMemOp opc, bool is_64)
1417 {
1418     switch (opc & (MO_SSIZE | MO_BSWAP)) {
1419     case MO_UB:
1420         tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
1421         break;
1422     case MO_SB:
1423         tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
1424         break;
1425     case MO_UW | MO_BSWAP:
1426         tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1427         tcg_out_bswap16(s, lo, TCG_TMP1);
1428         break;
1429     case MO_UW:
1430         tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
1431         break;
1432     case MO_SW | MO_BSWAP:
1433         tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1434         tcg_out_bswap16s(s, lo, TCG_TMP1);
1435         break;
1436     case MO_SW:
1437         tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
1438         break;
1439     case MO_UL | MO_BSWAP:
1440         if (TCG_TARGET_REG_BITS == 64 && is_64) {
1441             if (use_mips32r2_instructions) {
1442                 tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
1443                 tcg_out_bswap32u(s, lo, lo);
1444             } else {
1445                 tcg_out_bswap_subr(s, bswap32u_addr);
1446                 /* delay slot */
1447                 tcg_out_opc_imm(s, OPC_LWU, TCG_TMP0, base, 0);
1448                 tcg_out_mov(s, TCG_TYPE_I64, lo, TCG_TMP3);
1449             }
1450             break;
1451         }
1452         /* FALLTHRU */
1453     case MO_SL | MO_BSWAP:
1454         if (use_mips32r2_instructions) {
1455             tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1456             tcg_out_bswap32(s, lo, lo);
1457         } else {
1458             tcg_out_bswap_subr(s, bswap32_addr);
1459             /* delay slot */
1460             tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1461             tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_TMP3);
1462         }
1463         break;
1464     case MO_UL:
1465         if (TCG_TARGET_REG_BITS == 64 && is_64) {
1466             tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
1467             break;
1468         }
1469         /* FALLTHRU */
1470     case MO_SL:
1471         tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
1472         break;
1473     case MO_Q | MO_BSWAP:
1474         if (TCG_TARGET_REG_BITS == 64) {
1475             if (use_mips32r2_instructions) {
1476                 tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
1477                 tcg_out_bswap64(s, lo, lo);
1478             } else {
1479                 tcg_out_bswap_subr(s, bswap64_addr);
1480                 /* delay slot */
1481                 tcg_out_opc_imm(s, OPC_LD, TCG_TMP0, base, 0);
1482                 tcg_out_mov(s, TCG_TYPE_I64, lo, TCG_TMP3);
1483             }
1484         } else if (use_mips32r2_instructions) {
1485             tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1486             tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, 4);
1487             tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, TCG_TMP0);
1488             tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, TCG_TMP1);
1489             tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? lo : hi, TCG_TMP0, 16);
1490             tcg_out_opc_sa(s, OPC_ROTR, MIPS_BE ? hi : lo, TCG_TMP1, 16);
1491         } else {
1492             tcg_out_bswap_subr(s, bswap32_addr);
1493             /* delay slot */
1494             tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 0);
1495             tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, base, 4);
1496             tcg_out_bswap_subr(s, bswap32_addr);
1497             /* delay slot */
1498             tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? lo : hi, TCG_TMP3);
1499             tcg_out_mov(s, TCG_TYPE_I32, MIPS_BE ? hi : lo, TCG_TMP3);
1500         }
1501         break;
1502     case MO_Q:
1503         /* Prefer to load from offset 0 first, but allow for overlap.  */
1504         if (TCG_TARGET_REG_BITS == 64) {
1505             tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
1506         } else if (MIPS_BE ? hi != base : lo == base) {
1507             tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1508             tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1509         } else {
1510             tcg_out_opc_imm(s, OPC_LW, lo, base, LO_OFF);
1511             tcg_out_opc_imm(s, OPC_LW, hi, base, HI_OFF);
1512         }
1513         break;
1514     default:
1515         tcg_abort();
1516     }
1517 }
1518
1519 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1520 {
1521     TCGReg addr_regl, addr_regh __attribute__((unused));
1522     TCGReg data_regl, data_regh;
1523     TCGMemOpIdx oi;
1524     TCGMemOp opc;
1525 #if defined(CONFIG_SOFTMMU)
1526     tcg_insn_unit *label_ptr[2];
1527 #endif
1528     TCGReg base = TCG_REG_A0;
1529
1530     data_regl = *args++;
1531     data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1532     addr_regl = *args++;
1533     addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1534     oi = *args++;
1535     opc = get_memop(oi);
1536
1537 #if defined(CONFIG_SOFTMMU)
1538     tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 1);
1539     tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
1540     add_qemu_ldst_label(s, 1, oi,
1541                         (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1542                         data_regl, data_regh, addr_regl, addr_regh,
1543                         s->code_ptr, label_ptr);
1544 #else
1545     if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1546         tcg_out_ext32u(s, base, addr_regl);
1547         addr_regl = base;
1548     }
1549     if (guest_base == 0 && data_regl != addr_regl) {
1550         base = addr_regl;
1551     } else if (guest_base == (int16_t)guest_base) {
1552         tcg_out_opc_imm(s, ALIAS_PADDI, base, addr_regl, guest_base);
1553     } else {
1554         tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl);
1555     }
1556     tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
1557 #endif
1558 }
1559
1560 static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
1561                                    TCGReg base, TCGMemOp opc)
1562 {
1563     /* Don't clutter the code below with checks to avoid bswapping ZERO.  */
1564     if ((lo | hi) == 0) {
1565         opc &= ~MO_BSWAP;
1566     }
1567
1568     switch (opc & (MO_SIZE | MO_BSWAP)) {
1569     case MO_8:
1570         tcg_out_opc_imm(s, OPC_SB, lo, base, 0);
1571         break;
1572
1573     case MO_16 | MO_BSWAP:
1574         tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, lo, 0xffff);
1575         tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1);
1576         lo = TCG_TMP1;
1577         /* FALLTHRU */
1578     case MO_16:
1579         tcg_out_opc_imm(s, OPC_SH, lo, base, 0);
1580         break;
1581
1582     case MO_32 | MO_BSWAP:
1583         tcg_out_bswap32(s, TCG_TMP3, lo);
1584         lo = TCG_TMP3;
1585         /* FALLTHRU */
1586     case MO_32:
1587         tcg_out_opc_imm(s, OPC_SW, lo, base, 0);
1588         break;
1589
1590     case MO_64 | MO_BSWAP:
1591         if (TCG_TARGET_REG_BITS == 64) {
1592             tcg_out_bswap64(s, TCG_TMP3, lo);
1593             tcg_out_opc_imm(s, OPC_SD, TCG_TMP3, base, 0);
1594         } else if (use_mips32r2_instructions) {
1595             tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP0, 0, MIPS_BE ? lo : hi);
1596             tcg_out_opc_reg(s, OPC_WSBH, TCG_TMP1, 0, MIPS_BE ? hi : lo);
1597             tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP0, TCG_TMP0, 16);
1598             tcg_out_opc_sa(s, OPC_ROTR, TCG_TMP1, TCG_TMP1, 16);
1599             tcg_out_opc_imm(s, OPC_SW, TCG_TMP0, base, 0);
1600             tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, 4);
1601         } else {
1602             tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? lo : hi);
1603             tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 0);
1604             tcg_out_bswap32(s, TCG_TMP3, MIPS_BE ? hi : lo);
1605             tcg_out_opc_imm(s, OPC_SW, TCG_TMP3, base, 4);
1606         }
1607         break;
1608     case MO_64:
1609         if (TCG_TARGET_REG_BITS == 64) {
1610             tcg_out_opc_imm(s, OPC_SD, lo, base, 0);
1611         } else {
1612             tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? hi : lo, base, 0);
1613             tcg_out_opc_imm(s, OPC_SW, MIPS_BE ? lo : hi, base, 4);
1614         }
1615         break;
1616
1617     default:
1618         tcg_abort();
1619     }
1620 }
1621
1622 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1623 {
1624     TCGReg addr_regl, addr_regh __attribute__((unused));
1625     TCGReg data_regl, data_regh;
1626     TCGMemOpIdx oi;
1627     TCGMemOp opc;
1628 #if defined(CONFIG_SOFTMMU)
1629     tcg_insn_unit *label_ptr[2];
1630 #endif
1631     TCGReg base = TCG_REG_A0;
1632
1633     data_regl = *args++;
1634     data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1635     addr_regl = *args++;
1636     addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1637     oi = *args++;
1638     opc = get_memop(oi);
1639
1640 #if defined(CONFIG_SOFTMMU)
1641     tcg_out_tlb_load(s, base, addr_regl, addr_regh, oi, label_ptr, 0);
1642     tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1643     add_qemu_ldst_label(s, 0, oi,
1644                         (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1645                         data_regl, data_regh, addr_regl, addr_regh,
1646                         s->code_ptr, label_ptr);
1647 #else
1648     base = TCG_REG_A0;
1649     if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1650         tcg_out_ext32u(s, base, addr_regl);
1651         addr_regl = base;
1652     }
1653     if (guest_base == 0) {
1654         base = addr_regl;
1655     } else if (guest_base == (int16_t)guest_base) {
1656         tcg_out_opc_imm(s, ALIAS_PADDI, base, addr_regl, guest_base);
1657     } else {
1658         tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_GUEST_BASE_REG, addr_regl);
1659     }
1660     tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1661 #endif
1662 }
1663
1664 static void tcg_out_mb(TCGContext *s, TCGArg a0)
1665 {
1666     static const MIPSInsn sync[] = {
1667         /* Note that SYNC_MB is a slightly weaker than SYNC 0,
1668            as the former is an ordering barrier and the latter
1669            is a completion barrier.  */
1670         [0 ... TCG_MO_ALL]            = OPC_SYNC_MB,
1671         [TCG_MO_LD_LD]                = OPC_SYNC_RMB,
1672         [TCG_MO_ST_ST]                = OPC_SYNC_WMB,
1673         [TCG_MO_LD_ST]                = OPC_SYNC_RELEASE,
1674         [TCG_MO_LD_ST | TCG_MO_ST_ST] = OPC_SYNC_RELEASE,
1675         [TCG_MO_LD_ST | TCG_MO_LD_LD] = OPC_SYNC_ACQUIRE,
1676     };
1677     tcg_out32(s, sync[a0 & TCG_MO_ALL]);
1678 }
1679
1680 static void tcg_out_clz(TCGContext *s, MIPSInsn opcv2, MIPSInsn opcv6,
1681                         int width, TCGReg a0, TCGReg a1, TCGArg a2)
1682 {
1683     if (use_mips32r6_instructions) {
1684         if (a2 == width) {
1685             tcg_out_opc_reg(s, opcv6, a0, a1, 0);
1686         } else {
1687             tcg_out_opc_reg(s, opcv6, TCG_TMP0, a1, 0);
1688             tcg_out_movcond(s, TCG_COND_EQ, a0, a1, 0, a2, TCG_TMP0);
1689         }
1690     } else {
1691         if (a2 == width) {
1692             tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1693         } else if (a0 == a2) {
1694             tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1695             tcg_out_opc_reg(s, OPC_MOVN, a0, TCG_TMP0, a1);
1696         } else if (a0 != a1) {
1697             tcg_out_opc_reg(s, opcv2, a0, a1, a1);
1698             tcg_out_opc_reg(s, OPC_MOVZ, a0, a2, a1);
1699         } else {
1700             tcg_out_opc_reg(s, opcv2, TCG_TMP0, a1, a1);
1701             tcg_out_opc_reg(s, OPC_MOVZ, TCG_TMP0, a2, a1);
1702             tcg_out_mov(s, TCG_TYPE_REG, a0, TCG_TMP0);
1703         }
1704     }
1705 }
1706
1707 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1708                               const TCGArg *args, const int *const_args)
1709 {
1710     MIPSInsn i1, i2;
1711     TCGArg a0, a1, a2;
1712     int c2;
1713
1714     a0 = args[0];
1715     a1 = args[1];
1716     a2 = args[2];
1717     c2 = const_args[2];
1718
1719     switch (opc) {
1720     case INDEX_op_exit_tb:
1721         {
1722             TCGReg b0 = TCG_REG_ZERO;
1723
1724             a0 = (intptr_t)a0;
1725             if (a0 & ~0xffff) {
1726                 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, a0 & ~0xffff);
1727                 b0 = TCG_REG_V0;
1728             }
1729             if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1730                 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0,
1731                              (uintptr_t)tb_ret_addr);
1732                 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1733             }
1734             tcg_out_opc_imm(s, OPC_ORI, TCG_REG_V0, b0, a0 & 0xffff);
1735         }
1736         break;
1737     case INDEX_op_goto_tb:
1738         if (s->tb_jmp_insn_offset) {
1739             /* direct jump method */
1740             s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1741             /* Avoid clobbering the address during retranslation.  */
1742             tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
1743         } else {
1744             /* indirect jump method */
1745             tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
1746                        (uintptr_t)(s->tb_jmp_target_addr + a0));
1747             tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1748         }
1749         tcg_out_nop(s);
1750         s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
1751         break;
1752     case INDEX_op_goto_ptr:
1753         /* jmp to the given host address (could be epilogue) */
1754         tcg_out_opc_reg(s, OPC_JR, 0, a0, 0);
1755         tcg_out_nop(s);
1756         break;
1757     case INDEX_op_br:
1758         tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
1759                        arg_label(a0));
1760         break;
1761
1762     case INDEX_op_ld8u_i32:
1763     case INDEX_op_ld8u_i64:
1764         i1 = OPC_LBU;
1765         goto do_ldst;
1766     case INDEX_op_ld8s_i32:
1767     case INDEX_op_ld8s_i64:
1768         i1 = OPC_LB;
1769         goto do_ldst;
1770     case INDEX_op_ld16u_i32:
1771     case INDEX_op_ld16u_i64:
1772         i1 = OPC_LHU;
1773         goto do_ldst;
1774     case INDEX_op_ld16s_i32:
1775     case INDEX_op_ld16s_i64:
1776         i1 = OPC_LH;
1777         goto do_ldst;
1778     case INDEX_op_ld_i32:
1779     case INDEX_op_ld32s_i64:
1780         i1 = OPC_LW;
1781         goto do_ldst;
1782     case INDEX_op_ld32u_i64:
1783         i1 = OPC_LWU;
1784         goto do_ldst;
1785     case INDEX_op_ld_i64:
1786         i1 = OPC_LD;
1787         goto do_ldst;
1788     case INDEX_op_st8_i32:
1789     case INDEX_op_st8_i64:
1790         i1 = OPC_SB;
1791         goto do_ldst;
1792     case INDEX_op_st16_i32:
1793     case INDEX_op_st16_i64:
1794         i1 = OPC_SH;
1795         goto do_ldst;
1796     case INDEX_op_st_i32:
1797     case INDEX_op_st32_i64:
1798         i1 = OPC_SW;
1799         goto do_ldst;
1800     case INDEX_op_st_i64:
1801         i1 = OPC_SD;
1802     do_ldst:
1803         tcg_out_ldst(s, i1, a0, a1, a2);
1804         break;
1805
1806     case INDEX_op_add_i32:
1807         i1 = OPC_ADDU, i2 = OPC_ADDIU;
1808         goto do_binary;
1809     case INDEX_op_add_i64:
1810         i1 = OPC_DADDU, i2 = OPC_DADDIU;
1811         goto do_binary;
1812     case INDEX_op_or_i32:
1813     case INDEX_op_or_i64:
1814         i1 = OPC_OR, i2 = OPC_ORI;
1815         goto do_binary;
1816     case INDEX_op_xor_i32:
1817     case INDEX_op_xor_i64:
1818         i1 = OPC_XOR, i2 = OPC_XORI;
1819     do_binary:
1820         if (c2) {
1821             tcg_out_opc_imm(s, i2, a0, a1, a2);
1822             break;
1823         }
1824     do_binaryv:
1825         tcg_out_opc_reg(s, i1, a0, a1, a2);
1826         break;
1827
1828     case INDEX_op_sub_i32:
1829         i1 = OPC_SUBU, i2 = OPC_ADDIU;
1830         goto do_subtract;
1831     case INDEX_op_sub_i64:
1832         i1 = OPC_DSUBU, i2 = OPC_DADDIU;
1833     do_subtract:
1834         if (c2) {
1835             tcg_out_opc_imm(s, i2, a0, a1, -a2);
1836             break;
1837         }
1838         goto do_binaryv;
1839     case INDEX_op_and_i32:
1840         if (c2 && a2 != (uint16_t)a2) {
1841             int msb = ctz32(~a2) - 1;
1842             tcg_debug_assert(use_mips32r2_instructions);
1843             tcg_debug_assert(is_p2m1(a2));
1844             tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1845             break;
1846         }
1847         i1 = OPC_AND, i2 = OPC_ANDI;
1848         goto do_binary;
1849     case INDEX_op_and_i64:
1850         if (c2 && a2 != (uint16_t)a2) {
1851             int msb = ctz64(~a2) - 1;
1852             tcg_debug_assert(use_mips32r2_instructions);
1853             tcg_debug_assert(is_p2m1(a2));
1854             tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1, msb, 0);
1855             break;
1856         }
1857         i1 = OPC_AND, i2 = OPC_ANDI;
1858         goto do_binary;
1859     case INDEX_op_nor_i32:
1860     case INDEX_op_nor_i64:
1861         i1 = OPC_NOR;
1862         goto do_binaryv;
1863
1864     case INDEX_op_mul_i32:
1865         if (use_mips32_instructions) {
1866             tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1867             break;
1868         }
1869         i1 = OPC_MULT, i2 = OPC_MFLO;
1870         goto do_hilo1;
1871     case INDEX_op_mulsh_i32:
1872         if (use_mips32r6_instructions) {
1873             tcg_out_opc_reg(s, OPC_MUH, a0, a1, a2);
1874             break;
1875         }
1876         i1 = OPC_MULT, i2 = OPC_MFHI;
1877         goto do_hilo1;
1878     case INDEX_op_muluh_i32:
1879         if (use_mips32r6_instructions) {
1880             tcg_out_opc_reg(s, OPC_MUHU, a0, a1, a2);
1881             break;
1882         }
1883         i1 = OPC_MULTU, i2 = OPC_MFHI;
1884         goto do_hilo1;
1885     case INDEX_op_div_i32:
1886         if (use_mips32r6_instructions) {
1887             tcg_out_opc_reg(s, OPC_DIV_R6, a0, a1, a2);
1888             break;
1889         }
1890         i1 = OPC_DIV, i2 = OPC_MFLO;
1891         goto do_hilo1;
1892     case INDEX_op_divu_i32:
1893         if (use_mips32r6_instructions) {
1894             tcg_out_opc_reg(s, OPC_DIVU_R6, a0, a1, a2);
1895             break;
1896         }
1897         i1 = OPC_DIVU, i2 = OPC_MFLO;
1898         goto do_hilo1;
1899     case INDEX_op_rem_i32:
1900         if (use_mips32r6_instructions) {
1901             tcg_out_opc_reg(s, OPC_MOD, a0, a1, a2);
1902             break;
1903         }
1904         i1 = OPC_DIV, i2 = OPC_MFHI;
1905         goto do_hilo1;
1906     case INDEX_op_remu_i32:
1907         if (use_mips32r6_instructions) {
1908             tcg_out_opc_reg(s, OPC_MODU, a0, a1, a2);
1909             break;
1910         }
1911         i1 = OPC_DIVU, i2 = OPC_MFHI;
1912         goto do_hilo1;
1913     case INDEX_op_mul_i64:
1914         if (use_mips32r6_instructions) {
1915             tcg_out_opc_reg(s, OPC_DMUL, a0, a1, a2);
1916             break;
1917         }
1918         i1 = OPC_DMULT, i2 = OPC_MFLO;
1919         goto do_hilo1;
1920     case INDEX_op_mulsh_i64:
1921         if (use_mips32r6_instructions) {
1922             tcg_out_opc_reg(s, OPC_DMUH, a0, a1, a2);
1923             break;
1924         }
1925         i1 = OPC_DMULT, i2 = OPC_MFHI;
1926         goto do_hilo1;
1927     case INDEX_op_muluh_i64:
1928         if (use_mips32r6_instructions) {
1929             tcg_out_opc_reg(s, OPC_DMUHU, a0, a1, a2);
1930             break;
1931         }
1932         i1 = OPC_DMULTU, i2 = OPC_MFHI;
1933         goto do_hilo1;
1934     case INDEX_op_div_i64:
1935         if (use_mips32r6_instructions) {
1936             tcg_out_opc_reg(s, OPC_DDIV_R6, a0, a1, a2);
1937             break;
1938         }
1939         i1 = OPC_DDIV, i2 = OPC_MFLO;
1940         goto do_hilo1;
1941     case INDEX_op_divu_i64:
1942         if (use_mips32r6_instructions) {
1943             tcg_out_opc_reg(s, OPC_DDIVU_R6, a0, a1, a2);
1944             break;
1945         }
1946         i1 = OPC_DDIVU, i2 = OPC_MFLO;
1947         goto do_hilo1;
1948     case INDEX_op_rem_i64:
1949         if (use_mips32r6_instructions) {
1950             tcg_out_opc_reg(s, OPC_DMOD, a0, a1, a2);
1951             break;
1952         }
1953         i1 = OPC_DDIV, i2 = OPC_MFHI;
1954         goto do_hilo1;
1955     case INDEX_op_remu_i64:
1956         if (use_mips32r6_instructions) {
1957             tcg_out_opc_reg(s, OPC_DMODU, a0, a1, a2);
1958             break;
1959         }
1960         i1 = OPC_DDIVU, i2 = OPC_MFHI;
1961     do_hilo1:
1962         tcg_out_opc_reg(s, i1, 0, a1, a2);
1963         tcg_out_opc_reg(s, i2, a0, 0, 0);
1964         break;
1965
1966     case INDEX_op_muls2_i32:
1967         i1 = OPC_MULT;
1968         goto do_hilo2;
1969     case INDEX_op_mulu2_i32:
1970         i1 = OPC_MULTU;
1971         goto do_hilo2;
1972     case INDEX_op_muls2_i64:
1973         i1 = OPC_DMULT;
1974         goto do_hilo2;
1975     case INDEX_op_mulu2_i64:
1976         i1 = OPC_DMULTU;
1977     do_hilo2:
1978         tcg_out_opc_reg(s, i1, 0, a2, args[3]);
1979         tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1980         tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1981         break;
1982
1983     case INDEX_op_not_i32:
1984     case INDEX_op_not_i64:
1985         i1 = OPC_NOR;
1986         goto do_unary;
1987     case INDEX_op_bswap16_i32:
1988     case INDEX_op_bswap16_i64:
1989         i1 = OPC_WSBH;
1990         goto do_unary;
1991     case INDEX_op_ext8s_i32:
1992     case INDEX_op_ext8s_i64:
1993         i1 = OPC_SEB;
1994         goto do_unary;
1995     case INDEX_op_ext16s_i32:
1996     case INDEX_op_ext16s_i64:
1997         i1 = OPC_SEH;
1998     do_unary:
1999         tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
2000         break;
2001
2002     case INDEX_op_bswap32_i32:
2003         tcg_out_bswap32(s, a0, a1);
2004         break;
2005     case INDEX_op_bswap32_i64:
2006         tcg_out_bswap32u(s, a0, a1);
2007         break;
2008     case INDEX_op_bswap64_i64:
2009         tcg_out_bswap64(s, a0, a1);
2010         break;
2011     case INDEX_op_extrh_i64_i32:
2012         tcg_out_dsra(s, a0, a1, 32);
2013         break;
2014     case INDEX_op_ext32s_i64:
2015     case INDEX_op_ext_i32_i64:
2016     case INDEX_op_extrl_i64_i32:
2017         tcg_out_opc_sa(s, OPC_SLL, a0, a1, 0);
2018         break;
2019     case INDEX_op_ext32u_i64:
2020     case INDEX_op_extu_i32_i64:
2021         tcg_out_ext32u(s, a0, a1);
2022         break;
2023
2024     case INDEX_op_sar_i32:
2025         i1 = OPC_SRAV, i2 = OPC_SRA;
2026         goto do_shift;
2027     case INDEX_op_shl_i32:
2028         i1 = OPC_SLLV, i2 = OPC_SLL;
2029         goto do_shift;
2030     case INDEX_op_shr_i32:
2031         i1 = OPC_SRLV, i2 = OPC_SRL;
2032         goto do_shift;
2033     case INDEX_op_rotr_i32:
2034         i1 = OPC_ROTRV, i2 = OPC_ROTR;
2035     do_shift:
2036         if (c2) {
2037             tcg_out_opc_sa(s, i2, a0, a1, a2);
2038             break;
2039         }
2040     do_shiftv:
2041         tcg_out_opc_reg(s, i1, a0, a2, a1);
2042         break;
2043     case INDEX_op_rotl_i32:
2044         if (c2) {
2045             tcg_out_opc_sa(s, OPC_ROTR, a0, a1, 32 - a2);
2046         } else {
2047             tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, TCG_REG_ZERO, a2);
2048             tcg_out_opc_reg(s, OPC_ROTRV, a0, TCG_TMP0, a1);
2049         }
2050         break;
2051     case INDEX_op_sar_i64:
2052         if (c2) {
2053             tcg_out_dsra(s, a0, a1, a2);
2054             break;
2055         }
2056         i1 = OPC_DSRAV;
2057         goto do_shiftv;
2058     case INDEX_op_shl_i64:
2059         if (c2) {
2060             tcg_out_dsll(s, a0, a1, a2);
2061             break;
2062         }
2063         i1 = OPC_DSLLV;
2064         goto do_shiftv;
2065     case INDEX_op_shr_i64:
2066         if (c2) {
2067             tcg_out_dsrl(s, a0, a1, a2);
2068             break;
2069         }
2070         i1 = OPC_DSRLV;
2071         goto do_shiftv;
2072     case INDEX_op_rotr_i64:
2073         if (c2) {
2074             tcg_out_opc_sa64(s, OPC_DROTR, OPC_DROTR32, a0, a1, a2);
2075             break;
2076         }
2077         i1 = OPC_DROTRV;
2078         goto do_shiftv;
2079     case INDEX_op_rotl_i64:
2080         if (c2) {
2081             tcg_out_opc_sa64(s, OPC_DROTR, OPC_DROTR32, a0, a1, 64 - a2);
2082         } else {
2083             tcg_out_opc_reg(s, OPC_DSUBU, TCG_TMP0, TCG_REG_ZERO, a2);
2084             tcg_out_opc_reg(s, OPC_DROTRV, a0, TCG_TMP0, a1);
2085         }
2086         break;
2087
2088     case INDEX_op_clz_i32:
2089         tcg_out_clz(s, OPC_CLZ, OPC_CLZ_R6, 32, a0, a1, a2);
2090         break;
2091     case INDEX_op_clz_i64:
2092         tcg_out_clz(s, OPC_DCLZ, OPC_DCLZ_R6, 64, a0, a1, a2);
2093         break;
2094
2095     case INDEX_op_deposit_i32:
2096         tcg_out_opc_bf(s, OPC_INS, a0, a2, args[3] + args[4] - 1, args[3]);
2097         break;
2098     case INDEX_op_deposit_i64:
2099         tcg_out_opc_bf64(s, OPC_DINS, OPC_DINSM, OPC_DINSU, a0, a2,
2100                          args[3] + args[4] - 1, args[3]);
2101         break;
2102     case INDEX_op_extract_i32:
2103         tcg_out_opc_bf(s, OPC_EXT, a0, a1, args[3] - 1, a2);
2104         break;
2105     case INDEX_op_extract_i64:
2106         tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1,
2107                          args[3] - 1, a2);
2108         break;
2109
2110     case INDEX_op_brcond_i32:
2111     case INDEX_op_brcond_i64:
2112         tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
2113         break;
2114     case INDEX_op_brcond2_i32:
2115         tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
2116         break;
2117
2118     case INDEX_op_movcond_i32:
2119     case INDEX_op_movcond_i64:
2120         tcg_out_movcond(s, args[5], a0, a1, a2, args[3], args[4]);
2121         break;
2122
2123     case INDEX_op_setcond_i32:
2124     case INDEX_op_setcond_i64:
2125         tcg_out_setcond(s, args[3], a0, a1, a2);
2126         break;
2127     case INDEX_op_setcond2_i32:
2128         tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
2129         break;
2130
2131     case INDEX_op_qemu_ld_i32:
2132         tcg_out_qemu_ld(s, args, false);
2133         break;
2134     case INDEX_op_qemu_ld_i64:
2135         tcg_out_qemu_ld(s, args, true);
2136         break;
2137     case INDEX_op_qemu_st_i32:
2138         tcg_out_qemu_st(s, args, false);
2139         break;
2140     case INDEX_op_qemu_st_i64:
2141         tcg_out_qemu_st(s, args, true);
2142         break;
2143
2144     case INDEX_op_add2_i32:
2145         tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
2146                         const_args[4], const_args[5], false);
2147         break;
2148     case INDEX_op_sub2_i32:
2149         tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
2150                         const_args[4], const_args[5], true);
2151         break;
2152
2153     case INDEX_op_mb:
2154         tcg_out_mb(s, a0);
2155         break;
2156     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
2157     case INDEX_op_mov_i64:
2158     case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
2159     case INDEX_op_movi_i64:
2160     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
2161     default:
2162         tcg_abort();
2163     }
2164 }
2165
2166 static const TCGTargetOpDef mips_op_defs[] = {
2167     { INDEX_op_exit_tb, { } },
2168     { INDEX_op_goto_tb, { } },
2169     { INDEX_op_br, { } },
2170     { INDEX_op_goto_ptr, { "r" } },
2171
2172     { INDEX_op_ld8u_i32, { "r", "r" } },
2173     { INDEX_op_ld8s_i32, { "r", "r" } },
2174     { INDEX_op_ld16u_i32, { "r", "r" } },
2175     { INDEX_op_ld16s_i32, { "r", "r" } },
2176     { INDEX_op_ld_i32, { "r", "r" } },
2177     { INDEX_op_st8_i32, { "rZ", "r" } },
2178     { INDEX_op_st16_i32, { "rZ", "r" } },
2179     { INDEX_op_st_i32, { "rZ", "r" } },
2180
2181     { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
2182     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
2183 #if !use_mips32r6_instructions
2184     { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
2185     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
2186 #endif
2187     { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
2188     { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
2189     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
2190     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
2191     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
2192     { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
2193     { INDEX_op_sub_i32, { "r", "rZ", "rN" } },
2194
2195     { INDEX_op_and_i32, { "r", "rZ", "rIK" } },
2196     { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
2197     { INDEX_op_not_i32, { "r", "rZ" } },
2198     { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
2199     { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
2200
2201     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
2202     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
2203     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
2204     { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
2205     { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
2206     { INDEX_op_clz_i32,  { "r", "r", "rWZ" } },
2207
2208     { INDEX_op_bswap16_i32, { "r", "r" } },
2209     { INDEX_op_bswap32_i32, { "r", "r" } },
2210
2211     { INDEX_op_ext8s_i32, { "r", "rZ" } },
2212     { INDEX_op_ext16s_i32, { "r", "rZ" } },
2213
2214     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2215     { INDEX_op_extract_i32, { "r", "r" } },
2216
2217     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
2218 #if use_mips32r6_instructions
2219     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
2220 #else
2221     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
2222 #endif
2223     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
2224
2225 #if TCG_TARGET_REG_BITS == 32
2226     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
2227     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
2228     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
2229     { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
2230 #endif
2231
2232 #if TCG_TARGET_REG_BITS == 64
2233     { INDEX_op_ld8u_i64, { "r", "r" } },
2234     { INDEX_op_ld8s_i64, { "r", "r" } },
2235     { INDEX_op_ld16u_i64, { "r", "r" } },
2236     { INDEX_op_ld16s_i64, { "r", "r" } },
2237     { INDEX_op_ld32s_i64, { "r", "r" } },
2238     { INDEX_op_ld32u_i64, { "r", "r" } },
2239     { INDEX_op_ld_i64, { "r", "r" } },
2240     { INDEX_op_st8_i64, { "rZ", "r" } },
2241     { INDEX_op_st16_i64, { "rZ", "r" } },
2242     { INDEX_op_st32_i64, { "rZ", "r" } },
2243     { INDEX_op_st_i64, { "rZ", "r" } },
2244
2245     { INDEX_op_add_i64, { "r", "rZ", "rJ" } },
2246     { INDEX_op_mul_i64, { "r", "rZ", "rZ" } },
2247 #if !use_mips32r6_instructions
2248     { INDEX_op_muls2_i64, { "r", "r", "rZ", "rZ" } },
2249     { INDEX_op_mulu2_i64, { "r", "r", "rZ", "rZ" } },
2250 #endif
2251     { INDEX_op_mulsh_i64, { "r", "rZ", "rZ" } },
2252     { INDEX_op_muluh_i64, { "r", "rZ", "rZ" } },
2253     { INDEX_op_div_i64, { "r", "rZ", "rZ" } },
2254     { INDEX_op_divu_i64, { "r", "rZ", "rZ" } },
2255     { INDEX_op_rem_i64, { "r", "rZ", "rZ" } },
2256     { INDEX_op_remu_i64, { "r", "rZ", "rZ" } },
2257     { INDEX_op_sub_i64, { "r", "rZ", "rN" } },
2258
2259     { INDEX_op_and_i64, { "r", "rZ", "rIK" } },
2260     { INDEX_op_nor_i64, { "r", "rZ", "rZ" } },
2261     { INDEX_op_not_i64, { "r", "rZ" } },
2262     { INDEX_op_or_i64, { "r", "rZ", "rI" } },
2263     { INDEX_op_xor_i64, { "r", "rZ", "rI" } },
2264
2265     { INDEX_op_shl_i64, { "r", "rZ", "ri" } },
2266     { INDEX_op_shr_i64, { "r", "rZ", "ri" } },
2267     { INDEX_op_sar_i64, { "r", "rZ", "ri" } },
2268     { INDEX_op_rotr_i64, { "r", "rZ", "ri" } },
2269     { INDEX_op_rotl_i64, { "r", "rZ", "ri" } },
2270     { INDEX_op_clz_i64,  { "r", "r", "rWZ" } },
2271
2272     { INDEX_op_bswap16_i64, { "r", "r" } },
2273     { INDEX_op_bswap32_i64, { "r", "r" } },
2274     { INDEX_op_bswap64_i64, { "r", "r" } },
2275
2276     { INDEX_op_ext8s_i64, { "r", "rZ" } },
2277     { INDEX_op_ext16s_i64, { "r", "rZ" } },
2278     { INDEX_op_ext32s_i64, { "r", "rZ" } },
2279     { INDEX_op_ext32u_i64, { "r", "rZ" } },
2280     { INDEX_op_ext_i32_i64, { "r", "rZ" } },
2281     { INDEX_op_extu_i32_i64, { "r", "rZ" } },
2282     { INDEX_op_extrl_i64_i32, { "r", "rZ" } },
2283     { INDEX_op_extrh_i64_i32, { "r", "rZ" } },
2284
2285     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
2286     { INDEX_op_extract_i64, { "r", "r" } },
2287
2288     { INDEX_op_brcond_i64, { "rZ", "rZ" } },
2289 #if use_mips32r6_instructions
2290     { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rZ", "rZ" } },
2291 #else
2292     { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rZ", "0" } },
2293 #endif
2294     { INDEX_op_setcond_i64, { "r", "rZ", "rZ" } },
2295
2296     { INDEX_op_qemu_ld_i32, { "r", "LZ" } },
2297     { INDEX_op_qemu_st_i32, { "SZ", "SZ" } },
2298     { INDEX_op_qemu_ld_i64, { "r", "LZ" } },
2299     { INDEX_op_qemu_st_i64, { "SZ", "SZ" } },
2300 #elif TARGET_LONG_BITS == 32
2301     { INDEX_op_qemu_ld_i32, { "r", "LZ" } },
2302     { INDEX_op_qemu_st_i32, { "SZ", "SZ" } },
2303     { INDEX_op_qemu_ld_i64, { "r", "r", "LZ" } },
2304     { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ" } },
2305 #else
2306     { INDEX_op_qemu_ld_i32, { "r", "LZ", "LZ" } },
2307     { INDEX_op_qemu_st_i32, { "SZ", "SZ", "SZ" } },
2308     { INDEX_op_qemu_ld_i64, { "r", "r", "LZ", "LZ" } },
2309     { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ", "SZ" } },
2310 #endif
2311
2312     { INDEX_op_mb, { } },
2313     { -1 },
2314 };
2315
2316 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2317 {
2318     int i, n = ARRAY_SIZE(mips_op_defs);
2319
2320     for (i = 0; i < n; ++i) {
2321         if (mips_op_defs[i].op == op) {
2322             return &mips_op_defs[i];
2323         }
2324     }
2325     return NULL;
2326 }
2327
2328 static int tcg_target_callee_save_regs[] = {
2329     TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
2330     TCG_REG_S1,
2331     TCG_REG_S2,
2332     TCG_REG_S3,
2333     TCG_REG_S4,
2334     TCG_REG_S5,
2335     TCG_REG_S6,
2336     TCG_REG_S7,
2337     TCG_REG_S8,
2338     TCG_REG_RA,       /* should be last for ABI compliance */
2339 };
2340
2341 /* The Linux kernel doesn't provide any information about the available
2342    instruction set. Probe it using a signal handler. */
2343
2344
2345 #ifndef use_movnz_instructions
2346 bool use_movnz_instructions = false;
2347 #endif
2348
2349 #ifndef use_mips32_instructions
2350 bool use_mips32_instructions = false;
2351 #endif
2352
2353 #ifndef use_mips32r2_instructions
2354 bool use_mips32r2_instructions = false;
2355 #endif
2356
2357 static volatile sig_atomic_t got_sigill;
2358
2359 static void sigill_handler(int signo, siginfo_t *si, void *data)
2360 {
2361     /* Skip the faulty instruction */
2362     ucontext_t *uc = (ucontext_t *)data;
2363     uc->uc_mcontext.pc += 4;
2364
2365     got_sigill = 1;
2366 }
2367
2368 static void tcg_target_detect_isa(void)
2369 {
2370     struct sigaction sa_old, sa_new;
2371
2372     memset(&sa_new, 0, sizeof(sa_new));
2373     sa_new.sa_flags = SA_SIGINFO;
2374     sa_new.sa_sigaction = sigill_handler;
2375     sigaction(SIGILL, &sa_new, &sa_old);
2376
2377     /* Probe for movn/movz, necessary to implement movcond. */
2378 #ifndef use_movnz_instructions
2379     got_sigill = 0;
2380     asm volatile(".set push\n"
2381                  ".set mips32\n"
2382                  "movn $zero, $zero, $zero\n"
2383                  "movz $zero, $zero, $zero\n"
2384                  ".set pop\n"
2385                  : : : );
2386     use_movnz_instructions = !got_sigill;
2387 #endif
2388
2389     /* Probe for MIPS32 instructions. As no subsetting is allowed
2390        by the specification, it is only necessary to probe for one
2391        of the instructions. */
2392 #ifndef use_mips32_instructions
2393     got_sigill = 0;
2394     asm volatile(".set push\n"
2395                  ".set mips32\n"
2396                  "mul $zero, $zero\n"
2397                  ".set pop\n"
2398                  : : : );
2399     use_mips32_instructions = !got_sigill;
2400 #endif
2401
2402     /* Probe for MIPS32r2 instructions if MIPS32 instructions are
2403        available. As no subsetting is allowed by the specification,
2404        it is only necessary to probe for one of the instructions. */
2405 #ifndef use_mips32r2_instructions
2406     if (use_mips32_instructions) {
2407         got_sigill = 0;
2408         asm volatile(".set push\n"
2409                      ".set mips32r2\n"
2410                      "seb $zero, $zero\n"
2411                      ".set pop\n"
2412                      : : : );
2413         use_mips32r2_instructions = !got_sigill;
2414     }
2415 #endif
2416
2417     sigaction(SIGILL, &sa_old, NULL);
2418 }
2419
2420 static tcg_insn_unit *align_code_ptr(TCGContext *s)
2421 {
2422     uintptr_t p = (uintptr_t)s->code_ptr;
2423     if (p & 15) {
2424         p = (p + 15) & -16;
2425         s->code_ptr = (void *)p;
2426     }
2427     return s->code_ptr;
2428 }
2429
2430 /* Stack frame parameters.  */
2431 #define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
2432 #define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
2433 #define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
2434
2435 #define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
2436                      + TCG_TARGET_STACK_ALIGN - 1) \
2437                     & -TCG_TARGET_STACK_ALIGN)
2438 #define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
2439
2440 /* We're expecting to be able to use an immediate for frame allocation.  */
2441 QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7fff);
2442
2443 /* Generate global QEMU prologue and epilogue code */
2444 static void tcg_target_qemu_prologue(TCGContext *s)
2445 {
2446     int i;
2447
2448     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
2449
2450     /* TB prologue */
2451     tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
2452     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2453         tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2454                    TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2455     }
2456
2457 #ifndef CONFIG_SOFTMMU
2458     if (guest_base) {
2459         tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
2460         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2461     }
2462 #endif
2463
2464     /* Call generated code */
2465     tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
2466     /* delay slot */
2467     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2468
2469     /*
2470      * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2471      * and fall through to the rest of the epilogue.
2472      */
2473     s->code_gen_epilogue = s->code_ptr;
2474     tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
2475
2476     /* TB epilogue */
2477     tb_ret_addr = s->code_ptr;
2478     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2479         tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2480                    TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
2481     }
2482
2483     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2484     /* delay slot */
2485     tcg_out_opc_imm(s, ALIAS_PADDI, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
2486
2487     if (use_mips32r2_instructions) {
2488         return;
2489     }
2490
2491     /* Bswap subroutines: Input in TCG_TMP0, output in TCG_TMP3;
2492        clobbers TCG_TMP1, TCG_TMP2.  */
2493
2494     /*
2495      * bswap32 -- 32-bit swap (signed result for mips64).  a0 = abcd.
2496      */
2497     bswap32_addr = align_code_ptr(s);
2498     /* t3 = (ssss)d000 */
2499     tcg_out_opc_sa(s, OPC_SLL, TCG_TMP3, TCG_TMP0, 24);
2500     /* t1 = 000a */
2501     tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 24);
2502     /* t2 = 00c0 */
2503     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2504     /* t3 = d00a */
2505     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2506     /* t1 = 0abc */
2507     tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2508     /* t2 = 0c00 */
2509     tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2510     /* t1 = 00b0 */
2511     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2512     /* t3 = dc0a */
2513     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2514     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2515     /* t3 = dcba -- delay slot */
2516     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2517
2518     if (TCG_TARGET_REG_BITS == 32) {
2519         return;
2520     }
2521
2522     /*
2523      * bswap32u -- unsigned 32-bit swap.  a0 = ....abcd.
2524      */
2525     bswap32u_addr = align_code_ptr(s);
2526     /* t1 = (0000)000d */
2527     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP0, 0xff);
2528     /* t3 = 000a */
2529     tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, TCG_TMP0, 24);
2530     /* t1 = (0000)d000 */
2531     tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2532     /* t2 = 00c0 */
2533     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2534     /* t3 = d00a */
2535     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2536     /* t1 = 0abc */
2537     tcg_out_opc_sa(s, OPC_SRL, TCG_TMP1, TCG_TMP0, 8);
2538     /* t2 = 0c00 */
2539     tcg_out_opc_sa(s, OPC_SLL, TCG_TMP2, TCG_TMP2, 8);
2540     /* t1 = 00b0 */
2541     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2542     /* t3 = dc0a */
2543     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2544     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2545     /* t3 = dcba -- delay slot */
2546     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2547
2548     /*
2549      * bswap64 -- 64-bit swap.  a0 = abcdefgh
2550      */
2551     bswap64_addr = align_code_ptr(s);
2552     /* t3 = h0000000 */
2553     tcg_out_dsll(s, TCG_TMP3, TCG_TMP0, 56);
2554     /* t1 = 0000000a */
2555     tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 56);
2556
2557     /* t2 = 000000g0 */
2558     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP0, 0xff00);
2559     /* t3 = h000000a */
2560     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2561     /* t1 = 00000abc */
2562     tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 40);
2563     /* t2 = 0g000000 */
2564     tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2565     /* t1 = 000000b0 */
2566     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2567
2568     /* t3 = hg00000a */
2569     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2570     /* t2 = 0000abcd */
2571     tcg_out_dsrl(s, TCG_TMP2, TCG_TMP0, 32);
2572     /* t3 = hg0000ba */
2573     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2574
2575     /* t1 = 000000c0 */
2576     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP2, 0xff00);
2577     /* t2 = 0000000d */
2578     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP2, 0x00ff);
2579     /* t1 = 00000c00 */
2580     tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 8);
2581     /* t2 = 0000d000 */
2582     tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 24);
2583
2584     /* t3 = hg000cba */
2585     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2586     /* t1 = 00abcdef */
2587     tcg_out_dsrl(s, TCG_TMP1, TCG_TMP0, 16);
2588     /* t3 = hg00dcba */
2589     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2590
2591     /* t2 = 0000000f */
2592     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP2, TCG_TMP1, 0x00ff);
2593     /* t1 = 000000e0 */
2594     tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP1, 0xff00);
2595     /* t2 = 00f00000 */
2596     tcg_out_dsll(s, TCG_TMP2, TCG_TMP2, 40);
2597     /* t1 = 000e0000 */
2598     tcg_out_dsll(s, TCG_TMP1, TCG_TMP1, 24);
2599
2600     /* t3 = hgf0dcba */
2601     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP2);
2602     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
2603     /* t3 = hgfedcba -- delay slot */
2604     tcg_out_opc_reg(s, OPC_OR, TCG_TMP3, TCG_TMP3, TCG_TMP1);
2605 }
2606
2607 static void tcg_target_init(TCGContext *s)
2608 {
2609     tcg_target_detect_isa();
2610     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
2611     if (TCG_TARGET_REG_BITS == 64) {
2612         tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64], 0xffffffff);
2613     }
2614     tcg_regset_set(tcg_target_call_clobber_regs,
2615                    (1 << TCG_REG_V0) |
2616                    (1 << TCG_REG_V1) |
2617                    (1 << TCG_REG_A0) |
2618                    (1 << TCG_REG_A1) |
2619                    (1 << TCG_REG_A2) |
2620                    (1 << TCG_REG_A3) |
2621                    (1 << TCG_REG_T0) |
2622                    (1 << TCG_REG_T1) |
2623                    (1 << TCG_REG_T2) |
2624                    (1 << TCG_REG_T3) |
2625                    (1 << TCG_REG_T4) |
2626                    (1 << TCG_REG_T5) |
2627                    (1 << TCG_REG_T6) |
2628                    (1 << TCG_REG_T7) |
2629                    (1 << TCG_REG_T8) |
2630                    (1 << TCG_REG_T9));
2631
2632     tcg_regset_clear(s->reserved_regs);
2633     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
2634     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
2635     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
2636     tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);     /* internal use */
2637     tcg_regset_set_reg(s->reserved_regs, TCG_TMP1);     /* internal use */
2638     tcg_regset_set_reg(s->reserved_regs, TCG_TMP2);     /* internal use */
2639     tcg_regset_set_reg(s->reserved_regs, TCG_TMP3);     /* internal use */
2640     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
2641     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
2642     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
2643 }
2644
2645 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
2646                               uintptr_t addr)
2647 {
2648     atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
2649     flush_icache_range(jmp_addr, jmp_addr + 4);
2650 }
2651
2652 typedef struct {
2653     DebugFrameHeader h;
2654     uint8_t fde_def_cfa[4];
2655     uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
2656 } DebugFrame;
2657
2658 #define ELF_HOST_MACHINE EM_MIPS
2659 /* GDB doesn't appear to require proper setting of ELF_HOST_FLAGS,
2660    which is good because they're really quite complicated for MIPS.  */
2661
2662 static const DebugFrame debug_frame = {
2663     .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
2664     .h.cie.id = -1,
2665     .h.cie.version = 1,
2666     .h.cie.code_align = 1,
2667     .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
2668     .h.cie.return_column = TCG_REG_RA,
2669
2670     /* Total FDE size does not include the "len" member.  */
2671     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2672
2673     .fde_def_cfa = {
2674         12, TCG_REG_SP,                 /* DW_CFA_def_cfa sp, ... */
2675         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2676         (FRAME_SIZE >> 7)
2677     },
2678     .fde_reg_ofs = {
2679         0x80 + 16, 9,                   /* DW_CFA_offset, s0, -72 */
2680         0x80 + 17, 8,                   /* DW_CFA_offset, s2, -64 */
2681         0x80 + 18, 7,                   /* DW_CFA_offset, s3, -56 */
2682         0x80 + 19, 6,                   /* DW_CFA_offset, s4, -48 */
2683         0x80 + 20, 5,                   /* DW_CFA_offset, s5, -40 */
2684         0x80 + 21, 4,                   /* DW_CFA_offset, s6, -32 */
2685         0x80 + 22, 3,                   /* DW_CFA_offset, s7, -24 */
2686         0x80 + 30, 2,                   /* DW_CFA_offset, s8, -16 */
2687         0x80 + 31, 1,                   /* DW_CFA_offset, ra,  -8 */
2688     }
2689 };
2690
2691 void tcg_register_jit(void *buf, size_t buf_size)
2692 {
2693     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2694 }
This page took 0.170175 seconds and 4 git commands to generate.