Add qemu 2.4.0
[kvmfornfv.git] / qemu / tcg / mips / tcg-target.c
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5  * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
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 #include "tcg-be-ldst.h"
28
29 #ifdef HOST_WORDS_BIGENDIAN
30 # define MIPS_BE  1
31 #else
32 # define MIPS_BE  0
33 #endif
34
35 #define LO_OFF    (MIPS_BE * 4)
36 #define HI_OFF    (4 - LO_OFF)
37
38 #ifndef NDEBUG
39 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
40     "zero",
41     "at",
42     "v0",
43     "v1",
44     "a0",
45     "a1",
46     "a2",
47     "a3",
48     "t0",
49     "t1",
50     "t2",
51     "t3",
52     "t4",
53     "t5",
54     "t6",
55     "t7",
56     "s0",
57     "s1",
58     "s2",
59     "s3",
60     "s4",
61     "s5",
62     "s6",
63     "s7",
64     "t8",
65     "t9",
66     "k0",
67     "k1",
68     "gp",
69     "sp",
70     "s8",
71     "ra",
72 };
73 #endif
74
75 #define TCG_TMP0  TCG_REG_AT
76 #define TCG_TMP1  TCG_REG_T9
77
78 /* check if we really need so many registers :P */
79 static const TCGReg tcg_target_reg_alloc_order[] = {
80     /* Call saved registers.  */
81     TCG_REG_S0,
82     TCG_REG_S1,
83     TCG_REG_S2,
84     TCG_REG_S3,
85     TCG_REG_S4,
86     TCG_REG_S5,
87     TCG_REG_S6,
88     TCG_REG_S7,
89     TCG_REG_S8,
90
91     /* Call clobbered registers.  */
92     TCG_REG_T0,
93     TCG_REG_T1,
94     TCG_REG_T2,
95     TCG_REG_T3,
96     TCG_REG_T4,
97     TCG_REG_T5,
98     TCG_REG_T6,
99     TCG_REG_T7,
100     TCG_REG_T8,
101     TCG_REG_T9,
102     TCG_REG_V1,
103     TCG_REG_V0,
104
105     /* Argument registers, opposite order of allocation.  */
106     TCG_REG_A3,
107     TCG_REG_A2,
108     TCG_REG_A1,
109     TCG_REG_A0,
110 };
111
112 static const TCGReg tcg_target_call_iarg_regs[4] = {
113     TCG_REG_A0,
114     TCG_REG_A1,
115     TCG_REG_A2,
116     TCG_REG_A3
117 };
118
119 static const TCGReg tcg_target_call_oarg_regs[2] = {
120     TCG_REG_V0,
121     TCG_REG_V1
122 };
123
124 static tcg_insn_unit *tb_ret_addr;
125
126 static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
127 {
128     /* Let the compiler perform the right-shift as part of the arithmetic.  */
129     ptrdiff_t disp = target - (pc + 1);
130     assert(disp == (int16_t)disp);
131     return disp & 0xffff;
132 }
133
134 static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
135 {
136     *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
137 }
138
139 static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
140 {
141     assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
142     return ((uintptr_t)target >> 2) & 0x3ffffff;
143 }
144
145 static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
146 {
147     *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
148 }
149
150 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
151                         intptr_t value, intptr_t addend)
152 {
153     assert(type == R_MIPS_PC16);
154     assert(addend == 0);
155     reloc_pc16(code_ptr, (tcg_insn_unit *)value);
156 }
157
158 #define TCG_CT_CONST_ZERO 0x100
159 #define TCG_CT_CONST_U16  0x200    /* Unsigned 16-bit: 0 - 0xffff.  */
160 #define TCG_CT_CONST_S16  0x400    /* Signed 16-bit: -32768 - 32767 */
161 #define TCG_CT_CONST_P2M1 0x800    /* Power of 2 minus 1.  */
162 #define TCG_CT_CONST_N16  0x1000   /* "Negatable" 16-bit: -32767 - 32767 */
163
164 static inline bool is_p2m1(tcg_target_long val)
165 {
166     return val && ((val + 1) & val) == 0;
167 }
168
169 /* parse target specific constraints */
170 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
171 {
172     const char *ct_str;
173
174     ct_str = *pct_str;
175     switch(ct_str[0]) {
176     case 'r':
177         ct->ct |= TCG_CT_REG;
178         tcg_regset_set(ct->u.regs, 0xffffffff);
179         break;
180     case 'L': /* qemu_ld output arg constraint */
181         ct->ct |= TCG_CT_REG;
182         tcg_regset_set(ct->u.regs, 0xffffffff);
183         tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
184         break;
185     case 'l': /* qemu_ld input arg constraint */
186         ct->ct |= TCG_CT_REG;
187         tcg_regset_set(ct->u.regs, 0xffffffff);
188         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
189 #if defined(CONFIG_SOFTMMU)
190         if (TARGET_LONG_BITS == 64) {
191             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
192         }
193 #endif
194         break;
195     case 'S': /* qemu_st constraint */
196         ct->ct |= TCG_CT_REG;
197         tcg_regset_set(ct->u.regs, 0xffffffff);
198         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
199 #if defined(CONFIG_SOFTMMU)
200         if (TARGET_LONG_BITS == 32) {
201             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
202         } else {
203             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
204             tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
205         }
206 #endif
207         break;
208     case 'I':
209         ct->ct |= TCG_CT_CONST_U16;
210         break;
211     case 'J':
212         ct->ct |= TCG_CT_CONST_S16;
213         break;
214     case 'K':
215         ct->ct |= TCG_CT_CONST_P2M1;
216         break;
217     case 'N':
218         ct->ct |= TCG_CT_CONST_N16;
219         break;
220     case 'Z':
221         /* We are cheating a bit here, using the fact that the register
222            ZERO is also the register number 0. Hence there is no need
223            to check for const_args in each instruction. */
224         ct->ct |= TCG_CT_CONST_ZERO;
225         break;
226     default:
227         return -1;
228     }
229     ct_str++;
230     *pct_str = ct_str;
231     return 0;
232 }
233
234 /* test if a constant matches the constraint */
235 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
236                                          const TCGArgConstraint *arg_ct)
237 {
238     int ct;
239     ct = arg_ct->ct;
240     if (ct & TCG_CT_CONST) {
241         return 1;
242     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
243         return 1;
244     } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
245         return 1;
246     } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
247         return 1;
248     } else if ((ct & TCG_CT_CONST_N16) && val >= -32767 && val <= 32767) {
249         return 1;
250     } else if ((ct & TCG_CT_CONST_P2M1)
251                && use_mips32r2_instructions && is_p2m1(val)) {
252         return 1;
253     }
254     return 0;
255 }
256
257 /* instruction opcodes */
258 typedef enum {
259     OPC_J        = 0x02 << 26,
260     OPC_JAL      = 0x03 << 26,
261     OPC_BEQ      = 0x04 << 26,
262     OPC_BNE      = 0x05 << 26,
263     OPC_BLEZ     = 0x06 << 26,
264     OPC_BGTZ     = 0x07 << 26,
265     OPC_ADDIU    = 0x09 << 26,
266     OPC_SLTI     = 0x0A << 26,
267     OPC_SLTIU    = 0x0B << 26,
268     OPC_ANDI     = 0x0C << 26,
269     OPC_ORI      = 0x0D << 26,
270     OPC_XORI     = 0x0E << 26,
271     OPC_LUI      = 0x0F << 26,
272     OPC_LB       = 0x20 << 26,
273     OPC_LH       = 0x21 << 26,
274     OPC_LW       = 0x23 << 26,
275     OPC_LBU      = 0x24 << 26,
276     OPC_LHU      = 0x25 << 26,
277     OPC_LWU      = 0x27 << 26,
278     OPC_SB       = 0x28 << 26,
279     OPC_SH       = 0x29 << 26,
280     OPC_SW       = 0x2B << 26,
281
282     OPC_SPECIAL  = 0x00 << 26,
283     OPC_SLL      = OPC_SPECIAL | 0x00,
284     OPC_SRL      = OPC_SPECIAL | 0x02,
285     OPC_ROTR     = OPC_SPECIAL | (0x01 << 21) | 0x02,
286     OPC_SRA      = OPC_SPECIAL | 0x03,
287     OPC_SLLV     = OPC_SPECIAL | 0x04,
288     OPC_SRLV     = OPC_SPECIAL | 0x06,
289     OPC_ROTRV    = OPC_SPECIAL | (0x01 <<  6) | 0x06,
290     OPC_SRAV     = OPC_SPECIAL | 0x07,
291     OPC_JR       = OPC_SPECIAL | 0x08,
292     OPC_JALR     = OPC_SPECIAL | 0x09,
293     OPC_MOVZ     = OPC_SPECIAL | 0x0A,
294     OPC_MOVN     = OPC_SPECIAL | 0x0B,
295     OPC_MFHI     = OPC_SPECIAL | 0x10,
296     OPC_MFLO     = OPC_SPECIAL | 0x12,
297     OPC_MULT     = OPC_SPECIAL | 0x18,
298     OPC_MULTU    = OPC_SPECIAL | 0x19,
299     OPC_DIV      = OPC_SPECIAL | 0x1A,
300     OPC_DIVU     = OPC_SPECIAL | 0x1B,
301     OPC_ADDU     = OPC_SPECIAL | 0x21,
302     OPC_SUBU     = OPC_SPECIAL | 0x23,
303     OPC_AND      = OPC_SPECIAL | 0x24,
304     OPC_OR       = OPC_SPECIAL | 0x25,
305     OPC_XOR      = OPC_SPECIAL | 0x26,
306     OPC_NOR      = OPC_SPECIAL | 0x27,
307     OPC_SLT      = OPC_SPECIAL | 0x2A,
308     OPC_SLTU     = OPC_SPECIAL | 0x2B,
309
310     OPC_REGIMM   = 0x01 << 26,
311     OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
312     OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
313
314     OPC_SPECIAL2 = 0x1c << 26,
315     OPC_MUL      = OPC_SPECIAL2 | 0x002,
316
317     OPC_SPECIAL3 = 0x1f << 26,
318     OPC_EXT      = OPC_SPECIAL3 | 0x000,
319     OPC_INS      = OPC_SPECIAL3 | 0x004,
320     OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
321     OPC_SEB      = OPC_SPECIAL3 | 0x420,
322     OPC_SEH      = OPC_SPECIAL3 | 0x620,
323 } MIPSInsn;
324
325 /*
326  * Type reg
327  */
328 static inline void tcg_out_opc_reg(TCGContext *s, MIPSInsn opc,
329                                    TCGReg rd, TCGReg rs, TCGReg rt)
330 {
331     int32_t inst;
332
333     inst = opc;
334     inst |= (rs & 0x1F) << 21;
335     inst |= (rt & 0x1F) << 16;
336     inst |= (rd & 0x1F) << 11;
337     tcg_out32(s, inst);
338 }
339
340 /*
341  * Type immediate
342  */
343 static inline void tcg_out_opc_imm(TCGContext *s, MIPSInsn opc,
344                                    TCGReg rt, TCGReg rs, TCGArg imm)
345 {
346     int32_t inst;
347
348     inst = opc;
349     inst |= (rs & 0x1F) << 21;
350     inst |= (rt & 0x1F) << 16;
351     inst |= (imm & 0xffff);
352     tcg_out32(s, inst);
353 }
354
355 /*
356  * Type bitfield
357  */
358 static inline void tcg_out_opc_bf(TCGContext *s, MIPSInsn opc, TCGReg rt,
359                                   TCGReg rs, int msb, int lsb)
360 {
361     int32_t inst;
362
363     inst = opc;
364     inst |= (rs & 0x1F) << 21;
365     inst |= (rt & 0x1F) << 16;
366     inst |= (msb & 0x1F) << 11;
367     inst |= (lsb & 0x1F) << 6;
368     tcg_out32(s, inst);
369 }
370
371 /*
372  * Type branch
373  */
374 static inline void tcg_out_opc_br(TCGContext *s, MIPSInsn opc,
375                                   TCGReg rt, TCGReg rs)
376 {
377     /* We pay attention here to not modify the branch target by reading
378        the existing value and using it again. This ensure that caches and
379        memory are kept coherent during retranslation. */
380     uint16_t offset = (uint16_t)*s->code_ptr;
381
382     tcg_out_opc_imm(s, opc, rt, rs, offset);
383 }
384
385 /*
386  * Type sa
387  */
388 static inline void tcg_out_opc_sa(TCGContext *s, MIPSInsn opc,
389                                   TCGReg rd, TCGReg rt, TCGArg sa)
390 {
391     int32_t inst;
392
393     inst = opc;
394     inst |= (rt & 0x1F) << 16;
395     inst |= (rd & 0x1F) << 11;
396     inst |= (sa & 0x1F) <<  6;
397     tcg_out32(s, inst);
398
399 }
400
401 /*
402  * Type jump.
403  * Returns true if the branch was in range and the insn was emitted.
404  */
405 static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
406 {
407     uintptr_t dest = (uintptr_t)target;
408     uintptr_t from = (uintptr_t)s->code_ptr + 4;
409     int32_t inst;
410
411     /* The pc-region branch happens within the 256MB region of
412        the delay slot (thus the +4).  */
413     if ((from ^ dest) & -(1 << 28)) {
414         return false;
415     }
416     assert((dest & 3) == 0);
417
418     inst = opc;
419     inst |= (dest >> 2) & 0x3ffffff;
420     tcg_out32(s, inst);
421     return true;
422 }
423
424 static inline void tcg_out_nop(TCGContext *s)
425 {
426     tcg_out32(s, 0);
427 }
428
429 static inline void tcg_out_mov(TCGContext *s, TCGType type,
430                                TCGReg ret, TCGReg arg)
431 {
432     /* Simple reg-reg move, optimising out the 'do nothing' case */
433     if (ret != arg) {
434         tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
435     }
436 }
437
438 static inline void tcg_out_movi(TCGContext *s, TCGType type,
439                                 TCGReg reg, tcg_target_long arg)
440 {
441     if (arg == (int16_t)arg) {
442         tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
443     } else if (arg == (uint16_t)arg) {
444         tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
445     } else {
446         tcg_out_opc_imm(s, OPC_LUI, reg, TCG_REG_ZERO, arg >> 16);
447         if (arg & 0xffff) {
448             tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
449         }
450     }
451 }
452
453 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
454 {
455     if (use_mips32r2_instructions) {
456         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
457     } else {
458         /* ret and arg can't be register at */
459         if (ret == TCG_TMP0 || arg == TCG_TMP0) {
460             tcg_abort();
461         }
462
463         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
464         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
465         tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
466         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
467     }
468 }
469
470 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
471 {
472     if (use_mips32r2_instructions) {
473         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
474         tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
475     } else {
476         /* ret and arg can't be register at */
477         if (ret == TCG_TMP0 || arg == TCG_TMP0) {
478             tcg_abort();
479         }
480
481         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
482         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
483         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
484         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
485     }
486 }
487
488 static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
489 {
490     if (use_mips32r2_instructions) {
491         tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
492         tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
493     } else {
494         /* ret and arg must be different and can't be register at */
495         if (ret == arg || ret == TCG_TMP0 || arg == TCG_TMP0) {
496             tcg_abort();
497         }
498
499         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
500
501         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 24);
502         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
503
504         tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, arg, 0xff00);
505         tcg_out_opc_sa(s, OPC_SLL, TCG_TMP0, TCG_TMP0, 8);
506         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
507
508         tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8);
509         tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0xff00);
510         tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0);
511     }
512 }
513
514 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
515 {
516     if (use_mips32r2_instructions) {
517         tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
518     } else {
519         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
520         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
521     }
522 }
523
524 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
525 {
526     if (use_mips32r2_instructions) {
527         tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
528     } else {
529         tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
530         tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
531     }
532 }
533
534 static void tcg_out_ldst(TCGContext *s, MIPSInsn opc, TCGReg data,
535                          TCGReg addr, intptr_t ofs)
536 {
537     int16_t lo = ofs;
538     if (ofs != lo) {
539         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs - lo);
540         if (addr != TCG_REG_ZERO) {
541             tcg_out_opc_reg(s, OPC_ADDU, TCG_TMP0, TCG_TMP0, addr);
542         }
543         addr = TCG_TMP0;
544     }
545     tcg_out_opc_imm(s, opc, data, addr, lo);
546 }
547
548 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
549                               TCGReg arg1, intptr_t arg2)
550 {
551     tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
552 }
553
554 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
555                               TCGReg arg1, intptr_t arg2)
556 {
557     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
558 }
559
560 static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
561 {
562     if (val == (int16_t)val) {
563         tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
564     } else {
565         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, val);
566         tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_TMP0);
567     }
568 }
569
570 /* Bit 0 set if inversion required; bit 1 set if swapping required.  */
571 #define MIPS_CMP_INV  1
572 #define MIPS_CMP_SWAP 2
573
574 static const uint8_t mips_cmp_map[16] = {
575     [TCG_COND_LT]  = 0,
576     [TCG_COND_LTU] = 0,
577     [TCG_COND_GE]  = MIPS_CMP_INV,
578     [TCG_COND_GEU] = MIPS_CMP_INV,
579     [TCG_COND_LE]  = MIPS_CMP_INV | MIPS_CMP_SWAP,
580     [TCG_COND_LEU] = MIPS_CMP_INV | MIPS_CMP_SWAP,
581     [TCG_COND_GT]  = MIPS_CMP_SWAP,
582     [TCG_COND_GTU] = MIPS_CMP_SWAP,
583 };
584
585 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
586                             TCGReg arg1, TCGReg arg2)
587 {
588     MIPSInsn s_opc = OPC_SLTU;
589     int cmp_map;
590
591     switch (cond) {
592     case TCG_COND_EQ:
593         if (arg2 != 0) {
594             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
595             arg1 = ret;
596         }
597         tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
598         break;
599
600     case TCG_COND_NE:
601         if (arg2 != 0) {
602             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
603             arg1 = ret;
604         }
605         tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
606         break;
607
608     case TCG_COND_LT:
609     case TCG_COND_GE:
610     case TCG_COND_LE:
611     case TCG_COND_GT:
612         s_opc = OPC_SLT;
613         /* FALLTHRU */
614
615     case TCG_COND_LTU:
616     case TCG_COND_GEU:
617     case TCG_COND_LEU:
618     case TCG_COND_GTU:
619         cmp_map = mips_cmp_map[cond];
620         if (cmp_map & MIPS_CMP_SWAP) {
621             TCGReg t = arg1;
622             arg1 = arg2;
623             arg2 = t;
624         }
625         tcg_out_opc_reg(s, s_opc, ret, arg1, arg2);
626         if (cmp_map & MIPS_CMP_INV) {
627             tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
628         }
629         break;
630
631      default:
632          tcg_abort();
633          break;
634      }
635 }
636
637 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
638                            TCGReg arg2, TCGLabel *l)
639 {
640     static const MIPSInsn b_zero[16] = {
641         [TCG_COND_LT] = OPC_BLTZ,
642         [TCG_COND_GT] = OPC_BGTZ,
643         [TCG_COND_LE] = OPC_BLEZ,
644         [TCG_COND_GE] = OPC_BGEZ,
645     };
646
647     MIPSInsn s_opc = OPC_SLTU;
648     MIPSInsn b_opc;
649     int cmp_map;
650
651     switch (cond) {
652     case TCG_COND_EQ:
653         b_opc = OPC_BEQ;
654         break;
655     case TCG_COND_NE:
656         b_opc = OPC_BNE;
657         break;
658
659     case TCG_COND_LT:
660     case TCG_COND_GT:
661     case TCG_COND_LE:
662     case TCG_COND_GE:
663         if (arg2 == 0) {
664             b_opc = b_zero[cond];
665             arg2 = arg1;
666             arg1 = 0;
667             break;
668         }
669         s_opc = OPC_SLT;
670         /* FALLTHRU */
671
672     case TCG_COND_LTU:
673     case TCG_COND_GTU:
674     case TCG_COND_LEU:
675     case TCG_COND_GEU:
676         cmp_map = mips_cmp_map[cond];
677         if (cmp_map & MIPS_CMP_SWAP) {
678             TCGReg t = arg1;
679             arg1 = arg2;
680             arg2 = t;
681         }
682         tcg_out_opc_reg(s, s_opc, TCG_TMP0, arg1, arg2);
683         b_opc = (cmp_map & MIPS_CMP_INV ? OPC_BEQ : OPC_BNE);
684         arg1 = TCG_TMP0;
685         arg2 = TCG_REG_ZERO;
686         break;
687
688     default:
689         tcg_abort();
690         break;
691     }
692
693     tcg_out_opc_br(s, b_opc, arg1, arg2);
694     if (l->has_value) {
695         reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
696     } else {
697         tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
698     }
699     tcg_out_nop(s);
700 }
701
702 static TCGReg tcg_out_reduce_eq2(TCGContext *s, TCGReg tmp0, TCGReg tmp1,
703                                  TCGReg al, TCGReg ah,
704                                  TCGReg bl, TCGReg bh)
705 {
706     /* Merge highpart comparison into AH.  */
707     if (bh != 0) {
708         if (ah != 0) {
709             tcg_out_opc_reg(s, OPC_XOR, tmp0, ah, bh);
710             ah = tmp0;
711         } else {
712             ah = bh;
713         }
714     }
715     /* Merge lowpart comparison into AL.  */
716     if (bl != 0) {
717         if (al != 0) {
718             tcg_out_opc_reg(s, OPC_XOR, tmp1, al, bl);
719             al = tmp1;
720         } else {
721             al = bl;
722         }
723     }
724     /* Merge high and low part comparisons into AL.  */
725     if (ah != 0) {
726         if (al != 0) {
727             tcg_out_opc_reg(s, OPC_OR, tmp0, ah, al);
728             al = tmp0;
729         } else {
730             al = ah;
731         }
732     }
733     return al;
734 }
735
736 static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
737                              TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
738 {
739     TCGReg tmp0 = TCG_TMP0;
740     TCGReg tmp1 = ret;
741
742     assert(ret != TCG_TMP0);
743     if (ret == ah || ret == bh) {
744         assert(ret != TCG_TMP1);
745         tmp1 = TCG_TMP1;
746     }
747
748     switch (cond) {
749     case TCG_COND_EQ:
750     case TCG_COND_NE:
751         tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);
752         tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
753         break;
754
755     default:
756         tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
757         tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
758         tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);
759         tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);
760         tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);
761         break;
762     }
763 }
764
765 static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
766                             TCGReg bl, TCGReg bh, TCGLabel *l)
767 {
768     TCGCond b_cond = TCG_COND_NE;
769     TCGReg tmp = TCG_TMP1;
770
771     /* With branches, we emit between 4 and 9 insns with 2 or 3 branches.
772        With setcond, we emit between 3 and 10 insns and only 1 branch,
773        which ought to get better branch prediction.  */
774      switch (cond) {
775      case TCG_COND_EQ:
776      case TCG_COND_NE:
777         b_cond = cond;
778         tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
779         break;
780
781     default:
782         /* Minimize code size by preferring a compare not requiring INV.  */
783         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
784             cond = tcg_invert_cond(cond);
785             b_cond = TCG_COND_EQ;
786         }
787         tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh);
788         break;
789     }
790
791     tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
792 }
793
794 static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
795                             TCGReg c1, TCGReg c2, TCGReg v)
796 {
797     MIPSInsn m_opc = OPC_MOVN;
798
799     switch (cond) {
800     case TCG_COND_EQ:
801         m_opc = OPC_MOVZ;
802         /* FALLTHRU */
803     case TCG_COND_NE:
804         if (c2 != 0) {
805             tcg_out_opc_reg(s, OPC_XOR, TCG_TMP0, c1, c2);
806             c1 = TCG_TMP0;
807         }
808         break;
809
810     default:
811         /* Minimize code size by preferring a compare not requiring INV.  */
812         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
813             cond = tcg_invert_cond(cond);
814             m_opc = OPC_MOVZ;
815         }
816         tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
817         c1 = TCG_TMP0;
818         break;
819     }
820
821     tcg_out_opc_reg(s, m_opc, ret, v, c1);
822 }
823
824 static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
825 {
826     /* Note that the ABI requires the called function's address to be
827        loaded into T9, even if a direct branch is in range.  */
828     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T9, (uintptr_t)arg);
829
830     /* But do try a direct branch, allowing the cpu better insn prefetch.  */
831     if (tail) {
832         if (!tcg_out_opc_jmp(s, OPC_J, arg)) {
833             tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_T9, 0);
834         }
835     } else {
836         if (!tcg_out_opc_jmp(s, OPC_JAL, arg)) {
837             tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
838         }
839     }
840 }
841
842 static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
843 {
844     tcg_out_call_int(s, arg, false);
845     tcg_out_nop(s);
846 }
847
848 #if defined(CONFIG_SOFTMMU)
849 static void * const qemu_ld_helpers[16] = {
850     [MO_UB]   = helper_ret_ldub_mmu,
851     [MO_SB]   = helper_ret_ldsb_mmu,
852     [MO_LEUW] = helper_le_lduw_mmu,
853     [MO_LESW] = helper_le_ldsw_mmu,
854     [MO_LEUL] = helper_le_ldul_mmu,
855     [MO_LEQ]  = helper_le_ldq_mmu,
856     [MO_BEUW] = helper_be_lduw_mmu,
857     [MO_BESW] = helper_be_ldsw_mmu,
858     [MO_BEUL] = helper_be_ldul_mmu,
859     [MO_BEQ]  = helper_be_ldq_mmu,
860 };
861
862 static void * const qemu_st_helpers[16] = {
863     [MO_UB]   = helper_ret_stb_mmu,
864     [MO_LEUW] = helper_le_stw_mmu,
865     [MO_LEUL] = helper_le_stl_mmu,
866     [MO_LEQ]  = helper_le_stq_mmu,
867     [MO_BEUW] = helper_be_stw_mmu,
868     [MO_BEUL] = helper_be_stl_mmu,
869     [MO_BEQ]  = helper_be_stq_mmu,
870 };
871
872 /* Helper routines for marshalling helper function arguments into
873  * the correct registers and stack.
874  * I is where we want to put this argument, and is updated and returned
875  * for the next call. ARG is the argument itself.
876  *
877  * We provide routines for arguments which are: immediate, 32 bit
878  * value in register, 16 and 8 bit values in register (which must be zero
879  * extended before use) and 64 bit value in a lo:hi register pair.
880  */
881
882 static int tcg_out_call_iarg_reg(TCGContext *s, int i, TCGReg arg)
883 {
884     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
885         tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[i], arg);
886     } else {
887         tcg_out_st(s, TCG_TYPE_REG, arg, TCG_REG_SP, 4 * i);
888     }
889     return i + 1;
890 }
891
892 static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
893 {
894     TCGReg tmp = TCG_TMP0;
895     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
896         tmp = tcg_target_call_iarg_regs[i];
897     }
898     tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
899     return tcg_out_call_iarg_reg(s, i, tmp);
900 }
901
902 static int tcg_out_call_iarg_reg16(TCGContext *s, int i, TCGReg arg)
903 {
904     TCGReg tmp = TCG_TMP0;
905     if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
906         tmp = tcg_target_call_iarg_regs[i];
907     }
908     tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xffff);
909     return tcg_out_call_iarg_reg(s, i, tmp);
910 }
911
912 static int tcg_out_call_iarg_imm(TCGContext *s, int i, TCGArg arg)
913 {
914     TCGReg tmp = TCG_TMP0;
915     if (arg == 0) {
916         tmp = TCG_REG_ZERO;
917     } else {
918         if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
919             tmp = tcg_target_call_iarg_regs[i];
920         }
921         tcg_out_movi(s, TCG_TYPE_REG, tmp, arg);
922     }
923     return tcg_out_call_iarg_reg(s, i, tmp);
924 }
925
926 static int tcg_out_call_iarg_reg2(TCGContext *s, int i, TCGReg al, TCGReg ah)
927 {
928     i = (i + 1) & ~1;
929     i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? ah : al));
930     i = tcg_out_call_iarg_reg(s, i, (MIPS_BE ? al : ah));
931     return i;
932 }
933
934 /* Perform the tlb comparison operation.  The complete host address is
935    placed in BASE.  Clobbers AT, T0, A0.  */
936 static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl,
937                              TCGReg addrh, int mem_index, TCGMemOp s_bits,
938                              tcg_insn_unit *label_ptr[2], bool is_load)
939 {
940     int cmp_off
941         = (is_load
942            ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
943            : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
944     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
945
946     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addrl,
947                    TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
948     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0,
949                     (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
950     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
951
952     /* Compensate for very large offsets.  */
953     if (add_off >= 0x8000) {
954         /* Most target env are smaller than 32k; none are larger than 64k.
955            Simplify the logic here merely to offset by 0x7ff0, giving us a
956            range just shy of 64k.  Check this assumption.  */
957         QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
958                                    tlb_table[NB_MMU_MODES - 1][1])
959                           > 0x7ff0 + 0x7fff);
960         tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, TCG_REG_A0, 0x7ff0);
961         cmp_off -= 0x7ff0;
962         add_off -= 0x7ff0;
963     }
964
965     /* Load the tlb comparator.  */
966     if (TARGET_LONG_BITS == 64) {
967         tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + LO_OFF);
968         tcg_out_opc_imm(s, OPC_LW, base, TCG_REG_A0, cmp_off + HI_OFF);
969     } else {
970         tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off);
971     }
972
973     /* Mask the page bits, keeping the alignment bits to compare against.
974        In between, load the tlb addend for the fast path.  */
975     tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1,
976                  TARGET_PAGE_MASK | ((1 << s_bits) - 1));
977     tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off);
978     tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrl);
979
980     label_ptr[0] = s->code_ptr;
981     tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
982
983     if (TARGET_LONG_BITS == 64) {
984         /* delay slot */
985         tcg_out_nop(s);
986
987         label_ptr[1] = s->code_ptr;
988         tcg_out_opc_br(s, OPC_BNE, addrh, base);
989     }
990
991     /* delay slot */
992     tcg_out_opc_reg(s, OPC_ADDU, base, TCG_REG_A0, addrl);
993 }
994
995 static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
996                                 TCGReg datalo, TCGReg datahi,
997                                 TCGReg addrlo, TCGReg addrhi,
998                                 void *raddr, tcg_insn_unit *label_ptr[2])
999 {
1000     TCGLabelQemuLdst *label = new_ldst_label(s);
1001
1002     label->is_ld = is_ld;
1003     label->oi = oi;
1004     label->datalo_reg = datalo;
1005     label->datahi_reg = datahi;
1006     label->addrlo_reg = addrlo;
1007     label->addrhi_reg = addrhi;
1008     label->raddr = raddr;
1009     label->label_ptr[0] = label_ptr[0];
1010     if (TARGET_LONG_BITS == 64) {
1011         label->label_ptr[1] = label_ptr[1];
1012     }
1013 }
1014
1015 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1016 {
1017     TCGMemOpIdx oi = l->oi;
1018     TCGMemOp opc = get_memop(oi);
1019     TCGReg v0;
1020     int i;
1021
1022     /* resolve label address */
1023     reloc_pc16(l->label_ptr[0], s->code_ptr);
1024     if (TARGET_LONG_BITS == 64) {
1025         reloc_pc16(l->label_ptr[1], s->code_ptr);
1026     }
1027
1028     i = 1;
1029     if (TARGET_LONG_BITS == 64) {
1030         i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1031     } else {
1032         i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1033     }
1034     i = tcg_out_call_iarg_imm(s, i, oi);
1035     i = tcg_out_call_iarg_imm(s, i, (intptr_t)l->raddr);
1036     tcg_out_call_int(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)], false);
1037     /* delay slot */
1038     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1039
1040     v0 = l->datalo_reg;
1041     if ((opc & MO_SIZE) == MO_64) {
1042         /* We eliminated V0 from the possible output registers, so it
1043            cannot be clobbered here.  So we must move V1 first.  */
1044         if (MIPS_BE) {
1045             tcg_out_mov(s, TCG_TYPE_I32, v0, TCG_REG_V1);
1046             v0 = l->datahi_reg;
1047         } else {
1048             tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_V1);
1049         }
1050     }
1051
1052     reloc_pc16(s->code_ptr, l->raddr);
1053     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1054     /* delay slot */
1055     tcg_out_mov(s, TCG_TYPE_REG, v0, TCG_REG_V0);
1056 }
1057
1058 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1059 {
1060     TCGMemOpIdx oi = l->oi;
1061     TCGMemOp opc = get_memop(oi);
1062     TCGMemOp s_bits = opc & MO_SIZE;
1063     int i;
1064
1065     /* resolve label address */
1066     reloc_pc16(l->label_ptr[0], s->code_ptr);
1067     if (TARGET_LONG_BITS == 64) {
1068         reloc_pc16(l->label_ptr[1], s->code_ptr);
1069     }
1070
1071     i = 1;
1072     if (TARGET_LONG_BITS == 64) {
1073         i = tcg_out_call_iarg_reg2(s, i, l->addrlo_reg, l->addrhi_reg);
1074     } else {
1075         i = tcg_out_call_iarg_reg(s, i, l->addrlo_reg);
1076     }
1077     switch (s_bits) {
1078     case MO_8:
1079         i = tcg_out_call_iarg_reg8(s, i, l->datalo_reg);
1080         break;
1081     case MO_16:
1082         i = tcg_out_call_iarg_reg16(s, i, l->datalo_reg);
1083         break;
1084     case MO_32:
1085         i = tcg_out_call_iarg_reg(s, i, l->datalo_reg);
1086         break;
1087     case MO_64:
1088         i = tcg_out_call_iarg_reg2(s, i, l->datalo_reg, l->datahi_reg);
1089         break;
1090     default:
1091         tcg_abort();
1092     }
1093     i = tcg_out_call_iarg_imm(s, i, oi);
1094
1095     /* Tail call to the store helper.  Thus force the return address
1096        computation to take place in the return address register.  */
1097     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)l->raddr);
1098     i = tcg_out_call_iarg_reg(s, i, TCG_REG_RA);
1099     tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
1100     /* delay slot */
1101     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1102 }
1103 #endif
1104
1105 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1106                                    TCGReg base, TCGMemOp opc)
1107 {
1108     switch (opc & (MO_SSIZE | MO_BSWAP)) {
1109     case MO_UB:
1110         tcg_out_opc_imm(s, OPC_LBU, datalo, base, 0);
1111         break;
1112     case MO_SB:
1113         tcg_out_opc_imm(s, OPC_LB, datalo, base, 0);
1114         break;
1115     case MO_UW | MO_BSWAP:
1116         tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1117         tcg_out_bswap16(s, datalo, TCG_TMP1);
1118         break;
1119     case MO_UW:
1120         tcg_out_opc_imm(s, OPC_LHU, datalo, base, 0);
1121         break;
1122     case MO_SW | MO_BSWAP:
1123         tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0);
1124         tcg_out_bswap16s(s, datalo, TCG_TMP1);
1125         break;
1126     case MO_SW:
1127         tcg_out_opc_imm(s, OPC_LH, datalo, base, 0);
1128         break;
1129     case MO_UL | MO_BSWAP:
1130         tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, 0);
1131         tcg_out_bswap32(s, datalo, TCG_TMP1);
1132         break;
1133     case MO_UL:
1134         tcg_out_opc_imm(s, OPC_LW, datalo, base, 0);
1135         break;
1136     case MO_Q | MO_BSWAP:
1137         tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, HI_OFF);
1138         tcg_out_bswap32(s, datalo, TCG_TMP1);
1139         tcg_out_opc_imm(s, OPC_LW, TCG_TMP1, base, LO_OFF);
1140         tcg_out_bswap32(s, datahi, TCG_TMP1);
1141         break;
1142     case MO_Q:
1143         tcg_out_opc_imm(s, OPC_LW, datalo, base, LO_OFF);
1144         tcg_out_opc_imm(s, OPC_LW, datahi, base, HI_OFF);
1145         break;
1146     default:
1147         tcg_abort();
1148     }
1149 }
1150
1151 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1152 {
1153     TCGReg addr_regl, addr_regh __attribute__((unused));
1154     TCGReg data_regl, data_regh;
1155     TCGMemOpIdx oi;
1156     TCGMemOp opc;
1157 #if defined(CONFIG_SOFTMMU)
1158     tcg_insn_unit *label_ptr[2];
1159     int mem_index;
1160     TCGMemOp s_bits;
1161 #endif
1162     /* Note that we've eliminated V0 from the output registers,
1163        so we won't overwrite the base register during loading.  */
1164     TCGReg base = TCG_REG_V0;
1165
1166     data_regl = *args++;
1167     data_regh = (is_64 ? *args++ : 0);
1168     addr_regl = *args++;
1169     addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1170     oi = *args++;
1171     opc = get_memop(oi);
1172
1173 #if defined(CONFIG_SOFTMMU)
1174     mem_index = get_mmuidx(oi);
1175     s_bits = opc & MO_SIZE;
1176
1177     tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index,
1178                      s_bits, label_ptr, 1);
1179     tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1180     add_qemu_ldst_label(s, 1, oi, data_regl, data_regh, addr_regl, addr_regh,
1181                         s->code_ptr, label_ptr);
1182 #else
1183     if (GUEST_BASE == 0 && data_regl != addr_regl) {
1184         base = addr_regl;
1185     } else if (GUEST_BASE == (int16_t)GUEST_BASE) {
1186         tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, GUEST_BASE);
1187     } else {
1188         tcg_out_movi(s, TCG_TYPE_PTR, base, GUEST_BASE);
1189         tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1190     }
1191     tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc);
1192 #endif
1193 }
1194
1195 static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1196                                    TCGReg base, TCGMemOp opc)
1197 {
1198     switch (opc & (MO_SIZE | MO_BSWAP)) {
1199     case MO_8:
1200         tcg_out_opc_imm(s, OPC_SB, datalo, base, 0);
1201         break;
1202
1203     case MO_16 | MO_BSWAP:
1204         tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, datalo, 0xffff);
1205         tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1);
1206         datalo = TCG_TMP1;
1207         /* FALLTHRU */
1208     case MO_16:
1209         tcg_out_opc_imm(s, OPC_SH, datalo, base, 0);
1210         break;
1211
1212     case MO_32 | MO_BSWAP:
1213         tcg_out_bswap32(s, TCG_TMP1, datalo);
1214         datalo = TCG_TMP1;
1215         /* FALLTHRU */
1216     case MO_32:
1217         tcg_out_opc_imm(s, OPC_SW, datalo, base, 0);
1218         break;
1219
1220     case MO_64 | MO_BSWAP:
1221         tcg_out_bswap32(s, TCG_TMP1, datalo);
1222         tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, HI_OFF);
1223         tcg_out_bswap32(s, TCG_TMP1, datahi);
1224         tcg_out_opc_imm(s, OPC_SW, TCG_TMP1, base, LO_OFF);
1225         break;
1226     case MO_64:
1227         tcg_out_opc_imm(s, OPC_SW, datalo, base, LO_OFF);
1228         tcg_out_opc_imm(s, OPC_SW, datahi, base, HI_OFF);
1229         break;
1230
1231     default:
1232         tcg_abort();
1233     }
1234 }
1235
1236 static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al,
1237                             TCGReg ah, TCGArg bl, TCGArg bh, bool cbl,
1238                             bool cbh, bool is_sub)
1239 {
1240     TCGReg th = TCG_TMP1;
1241
1242     /* If we have a negative constant such that negating it would
1243        make the high part zero, we can (usually) eliminate one insn.  */
1244     if (cbl && cbh && bh == -1 && bl != 0) {
1245         bl = -bl;
1246         bh = 0;
1247         is_sub = !is_sub;
1248     }
1249
1250     /* By operating on the high part first, we get to use the final
1251        carry operation to move back from the temporary.  */
1252     if (!cbh) {
1253         tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh);
1254     } else if (bh != 0 || ah == rl) {
1255         tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh));
1256     } else {
1257         th = ah;
1258     }
1259
1260     /* Note that tcg optimization should eliminate the bl == 0 case.  */
1261     if (is_sub) {
1262         if (cbl) {
1263             tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl);
1264             tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl);
1265         } else {
1266             tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl);
1267             tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl);
1268         }
1269         tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0);
1270     } else {
1271         if (cbl) {
1272             tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl);
1273             tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl);
1274         } else if (rl == al && rl == bl) {
1275             tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, al, 31);
1276             tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
1277         } else {
1278             tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl);
1279             tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl));
1280         }
1281         tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0);
1282     }
1283 }
1284
1285 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1286 {
1287     TCGReg addr_regl, addr_regh __attribute__((unused));
1288     TCGReg data_regl, data_regh, base;
1289     TCGMemOpIdx oi;
1290     TCGMemOp opc;
1291 #if defined(CONFIG_SOFTMMU)
1292     tcg_insn_unit *label_ptr[2];
1293     int mem_index;
1294     TCGMemOp s_bits;
1295 #endif
1296
1297     data_regl = *args++;
1298     data_regh = (is_64 ? *args++ : 0);
1299     addr_regl = *args++;
1300     addr_regh = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1301     oi = *args++;
1302     opc = get_memop(oi);
1303
1304 #if defined(CONFIG_SOFTMMU)
1305     mem_index = get_mmuidx(oi);
1306     s_bits = opc & 3;
1307
1308     /* Note that we eliminated the helper's address argument,
1309        so we can reuse that for the base.  */
1310     base = (TARGET_LONG_BITS == 32 ? TCG_REG_A1 : TCG_REG_A2);
1311     tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index,
1312                      s_bits, label_ptr, 0);
1313     tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1314     add_qemu_ldst_label(s, 0, oi, data_regl, data_regh, addr_regl, addr_regh,
1315                         s->code_ptr, label_ptr);
1316 #else
1317     if (GUEST_BASE == 0) {
1318         base = addr_regl;
1319     } else {
1320         base = TCG_REG_A0;
1321         if (GUEST_BASE == (int16_t)GUEST_BASE) {
1322             tcg_out_opc_imm(s, OPC_ADDIU, base, addr_regl, GUEST_BASE);
1323         } else {
1324             tcg_out_movi(s, TCG_TYPE_PTR, base, GUEST_BASE);
1325             tcg_out_opc_reg(s, OPC_ADDU, base, base, addr_regl);
1326         }
1327     }
1328     tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
1329 #endif
1330 }
1331
1332 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1333                               const TCGArg *args, const int *const_args)
1334 {
1335     MIPSInsn i1, i2;
1336     TCGArg a0, a1, a2;
1337     int c2;
1338
1339     a0 = args[0];
1340     a1 = args[1];
1341     a2 = args[2];
1342     c2 = const_args[2];
1343
1344     switch (opc) {
1345     case INDEX_op_exit_tb:
1346         {
1347             TCGReg b0 = TCG_REG_ZERO;
1348
1349             if (a0 & ~0xffff) {
1350                 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, a0 & ~0xffff);
1351                 b0 = TCG_REG_V0;
1352             }
1353             if (!tcg_out_opc_jmp(s, OPC_J, tb_ret_addr)) {
1354                 tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0,
1355                              (uintptr_t)tb_ret_addr);
1356                 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1357             }
1358             tcg_out_opc_imm(s, OPC_ORI, TCG_REG_V0, b0, a0 & 0xffff);
1359         }
1360         break;
1361     case INDEX_op_goto_tb:
1362         if (s->tb_jmp_offset) {
1363             /* direct jump method */
1364             s->tb_jmp_offset[a0] = tcg_current_code_size(s);
1365             /* Avoid clobbering the address during retranslation.  */
1366             tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff));
1367         } else {
1368             /* indirect jump method */
1369             tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
1370                        (uintptr_t)(s->tb_next + a0));
1371             tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
1372         }
1373         tcg_out_nop(s);
1374         s->tb_next_offset[a0] = tcg_current_code_size(s);
1375         break;
1376     case INDEX_op_br:
1377         tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
1378                        arg_label(a0));
1379         break;
1380
1381     case INDEX_op_ld8u_i32:
1382         i1 = OPC_LBU;
1383         goto do_ldst;
1384     case INDEX_op_ld8s_i32:
1385         i1 = OPC_LB;
1386         goto do_ldst;
1387     case INDEX_op_ld16u_i32:
1388         i1 = OPC_LHU;
1389         goto do_ldst;
1390     case INDEX_op_ld16s_i32:
1391         i1 = OPC_LH;
1392         goto do_ldst;
1393     case INDEX_op_ld_i32:
1394         i1 = OPC_LW;
1395         goto do_ldst;
1396     case INDEX_op_st8_i32:
1397         i1 = OPC_SB;
1398         goto do_ldst;
1399     case INDEX_op_st16_i32:
1400         i1 = OPC_SH;
1401         goto do_ldst;
1402     case INDEX_op_st_i32:
1403         i1 = OPC_SW;
1404     do_ldst:
1405         tcg_out_ldst(s, i1, a0, a1, a2);
1406         break;
1407
1408     case INDEX_op_add_i32:
1409         i1 = OPC_ADDU, i2 = OPC_ADDIU;
1410         goto do_binary;
1411     case INDEX_op_or_i32:
1412         i1 = OPC_OR, i2 = OPC_ORI;
1413         goto do_binary;
1414     case INDEX_op_xor_i32:
1415         i1 = OPC_XOR, i2 = OPC_XORI;
1416     do_binary:
1417         if (c2) {
1418             tcg_out_opc_imm(s, i2, a0, a1, a2);
1419             break;
1420         }
1421     do_binaryv:
1422         tcg_out_opc_reg(s, i1, a0, a1, a2);
1423         break;
1424
1425     case INDEX_op_sub_i32:
1426         if (c2) {
1427             tcg_out_opc_imm(s, OPC_ADDIU, a0, a1, -a2);
1428             break;
1429         }
1430         i1 = OPC_SUBU;
1431         goto do_binary;
1432     case INDEX_op_and_i32:
1433         if (c2 && a2 != (uint16_t)a2) {
1434             int msb = ctz32(~a2) - 1;
1435             assert(use_mips32r2_instructions);
1436             assert(is_p2m1(a2));
1437             tcg_out_opc_bf(s, OPC_EXT, a0, a1, msb, 0);
1438             break;
1439         }
1440         i1 = OPC_AND, i2 = OPC_ANDI;
1441         goto do_binary;
1442     case INDEX_op_nor_i32:
1443         i1 = OPC_NOR;
1444         goto do_binaryv;
1445
1446     case INDEX_op_mul_i32:
1447         if (use_mips32_instructions) {
1448             tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2);
1449             break;
1450         }
1451         i1 = OPC_MULT, i2 = OPC_MFLO;
1452         goto do_hilo1;
1453     case INDEX_op_mulsh_i32:
1454         i1 = OPC_MULT, i2 = OPC_MFHI;
1455         goto do_hilo1;
1456     case INDEX_op_muluh_i32:
1457         i1 = OPC_MULTU, i2 = OPC_MFHI;
1458         goto do_hilo1;
1459     case INDEX_op_div_i32:
1460         i1 = OPC_DIV, i2 = OPC_MFLO;
1461         goto do_hilo1;
1462     case INDEX_op_divu_i32:
1463         i1 = OPC_DIVU, i2 = OPC_MFLO;
1464         goto do_hilo1;
1465     case INDEX_op_rem_i32:
1466         i1 = OPC_DIV, i2 = OPC_MFHI;
1467         goto do_hilo1;
1468     case INDEX_op_remu_i32:
1469         i1 = OPC_DIVU, i2 = OPC_MFHI;
1470     do_hilo1:
1471         tcg_out_opc_reg(s, i1, 0, a1, a2);
1472         tcg_out_opc_reg(s, i2, a0, 0, 0);
1473         break;
1474
1475     case INDEX_op_muls2_i32:
1476         i1 = OPC_MULT;
1477         goto do_hilo2;
1478     case INDEX_op_mulu2_i32:
1479         i1 = OPC_MULTU;
1480     do_hilo2:
1481         tcg_out_opc_reg(s, i1, 0, a2, args[3]);
1482         tcg_out_opc_reg(s, OPC_MFLO, a0, 0, 0);
1483         tcg_out_opc_reg(s, OPC_MFHI, a1, 0, 0);
1484         break;
1485
1486     case INDEX_op_not_i32:
1487         i1 = OPC_NOR;
1488         goto do_unary;
1489     case INDEX_op_bswap16_i32:
1490         i1 = OPC_WSBH;
1491         goto do_unary;
1492     case INDEX_op_ext8s_i32:
1493         i1 = OPC_SEB;
1494         goto do_unary;
1495     case INDEX_op_ext16s_i32:
1496         i1 = OPC_SEH;
1497     do_unary:
1498         tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
1499         break;
1500
1501     case INDEX_op_sar_i32:
1502         i1 = OPC_SRAV, i2 = OPC_SRA;
1503         goto do_shift;
1504     case INDEX_op_shl_i32:
1505         i1 = OPC_SLLV, i2 = OPC_SLL;
1506         goto do_shift;
1507     case INDEX_op_shr_i32:
1508         i1 = OPC_SRLV, i2 = OPC_SRL;
1509         goto do_shift;
1510     case INDEX_op_rotr_i32:
1511         i1 = OPC_ROTRV, i2 = OPC_ROTR;
1512     do_shift:
1513         if (c2) {
1514             tcg_out_opc_sa(s, i2, a0, a1, a2);
1515         } else {
1516             tcg_out_opc_reg(s, i1, a0, a2, a1);
1517         }
1518         break;
1519     case INDEX_op_rotl_i32:
1520         if (c2) {
1521             tcg_out_opc_sa(s, OPC_ROTR, a0, a1, 32 - a2);
1522         } else {
1523             tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, TCG_REG_ZERO, a2);
1524             tcg_out_opc_reg(s, OPC_ROTRV, a0, TCG_TMP0, a1);
1525         }
1526         break;
1527
1528     case INDEX_op_bswap32_i32:
1529         tcg_out_opc_reg(s, OPC_WSBH, a0, 0, a1);
1530         tcg_out_opc_sa(s, OPC_ROTR, a0, a0, 16);
1531         break;
1532
1533     case INDEX_op_deposit_i32:
1534         tcg_out_opc_bf(s, OPC_INS, a0, a2, args[3] + args[4] - 1, args[3]);
1535         break;
1536
1537     case INDEX_op_brcond_i32:
1538         tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
1539         break;
1540     case INDEX_op_brcond2_i32:
1541         tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(args[5]));
1542         break;
1543
1544     case INDEX_op_movcond_i32:
1545         tcg_out_movcond(s, args[5], a0, a1, a2, args[3]);
1546         break;
1547
1548     case INDEX_op_setcond_i32:
1549         tcg_out_setcond(s, args[3], a0, a1, a2);
1550         break;
1551     case INDEX_op_setcond2_i32:
1552         tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
1553         break;
1554
1555     case INDEX_op_qemu_ld_i32:
1556         tcg_out_qemu_ld(s, args, false);
1557         break;
1558     case INDEX_op_qemu_ld_i64:
1559         tcg_out_qemu_ld(s, args, true);
1560         break;
1561     case INDEX_op_qemu_st_i32:
1562         tcg_out_qemu_st(s, args, false);
1563         break;
1564     case INDEX_op_qemu_st_i64:
1565         tcg_out_qemu_st(s, args, true);
1566         break;
1567
1568     case INDEX_op_add2_i32:
1569         tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1570                         const_args[4], const_args[5], false);
1571         break;
1572     case INDEX_op_sub2_i32:
1573         tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
1574                         const_args[4], const_args[5], true);
1575         break;
1576
1577     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1578     case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
1579     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1580     default:
1581         tcg_abort();
1582     }
1583 }
1584
1585 static const TCGTargetOpDef mips_op_defs[] = {
1586     { INDEX_op_exit_tb, { } },
1587     { INDEX_op_goto_tb, { } },
1588     { INDEX_op_br, { } },
1589
1590     { INDEX_op_ld8u_i32, { "r", "r" } },
1591     { INDEX_op_ld8s_i32, { "r", "r" } },
1592     { INDEX_op_ld16u_i32, { "r", "r" } },
1593     { INDEX_op_ld16s_i32, { "r", "r" } },
1594     { INDEX_op_ld_i32, { "r", "r" } },
1595     { INDEX_op_st8_i32, { "rZ", "r" } },
1596     { INDEX_op_st16_i32, { "rZ", "r" } },
1597     { INDEX_op_st_i32, { "rZ", "r" } },
1598
1599     { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1600     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1601     { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
1602     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1603     { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
1604     { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
1605     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1606     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1607     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1608     { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1609     { INDEX_op_sub_i32, { "r", "rZ", "rN" } },
1610
1611     { INDEX_op_and_i32, { "r", "rZ", "rIK" } },
1612     { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1613     { INDEX_op_not_i32, { "r", "rZ" } },
1614     { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1615     { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1616
1617     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1618     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1619     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1620     { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1621     { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1622
1623     { INDEX_op_bswap16_i32, { "r", "r" } },
1624     { INDEX_op_bswap32_i32, { "r", "r" } },
1625
1626     { INDEX_op_ext8s_i32, { "r", "rZ" } },
1627     { INDEX_op_ext16s_i32, { "r", "rZ" } },
1628
1629     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1630
1631     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1632     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1633     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1634     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1635
1636     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1637     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } },
1638     { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1639
1640 #if TARGET_LONG_BITS == 32
1641     { INDEX_op_qemu_ld_i32, { "L", "lZ" } },
1642     { INDEX_op_qemu_st_i32, { "SZ", "SZ" } },
1643     { INDEX_op_qemu_ld_i64, { "L", "L", "lZ" } },
1644     { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ" } },
1645 #else
1646     { INDEX_op_qemu_ld_i32, { "L", "lZ", "lZ" } },
1647     { INDEX_op_qemu_st_i32, { "SZ", "SZ", "SZ" } },
1648     { INDEX_op_qemu_ld_i64, { "L", "L", "lZ", "lZ" } },
1649     { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ", "SZ" } },
1650 #endif
1651     { -1 },
1652 };
1653
1654 static int tcg_target_callee_save_regs[] = {
1655     TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1656     TCG_REG_S1,
1657     TCG_REG_S2,
1658     TCG_REG_S3,
1659     TCG_REG_S4,
1660     TCG_REG_S5,
1661     TCG_REG_S6,
1662     TCG_REG_S7,
1663     TCG_REG_S8,
1664     TCG_REG_RA,       /* should be last for ABI compliance */
1665 };
1666
1667 /* The Linux kernel doesn't provide any information about the available
1668    instruction set. Probe it using a signal handler. */
1669
1670 #include <signal.h>
1671
1672 #ifndef use_movnz_instructions
1673 bool use_movnz_instructions = false;
1674 #endif
1675
1676 #ifndef use_mips32_instructions
1677 bool use_mips32_instructions = false;
1678 #endif
1679
1680 #ifndef use_mips32r2_instructions
1681 bool use_mips32r2_instructions = false;
1682 #endif
1683
1684 static volatile sig_atomic_t got_sigill;
1685
1686 static void sigill_handler(int signo, siginfo_t *si, void *data)
1687 {
1688     /* Skip the faulty instruction */
1689     ucontext_t *uc = (ucontext_t *)data;
1690     uc->uc_mcontext.pc += 4;
1691
1692     got_sigill = 1;
1693 }
1694
1695 static void tcg_target_detect_isa(void)
1696 {
1697     struct sigaction sa_old, sa_new;
1698
1699     memset(&sa_new, 0, sizeof(sa_new));
1700     sa_new.sa_flags = SA_SIGINFO;
1701     sa_new.sa_sigaction = sigill_handler;
1702     sigaction(SIGILL, &sa_new, &sa_old);
1703
1704     /* Probe for movn/movz, necessary to implement movcond. */
1705 #ifndef use_movnz_instructions
1706     got_sigill = 0;
1707     asm volatile(".set push\n"
1708                  ".set mips32\n"
1709                  "movn $zero, $zero, $zero\n"
1710                  "movz $zero, $zero, $zero\n"
1711                  ".set pop\n"
1712                  : : : );
1713     use_movnz_instructions = !got_sigill;
1714 #endif
1715
1716     /* Probe for MIPS32 instructions. As no subsetting is allowed
1717        by the specification, it is only necessary to probe for one
1718        of the instructions. */
1719 #ifndef use_mips32_instructions
1720     got_sigill = 0;
1721     asm volatile(".set push\n"
1722                  ".set mips32\n"
1723                  "mul $zero, $zero\n"
1724                  ".set pop\n"
1725                  : : : );
1726     use_mips32_instructions = !got_sigill;
1727 #endif
1728
1729     /* Probe for MIPS32r2 instructions if MIPS32 instructions are
1730        available. As no subsetting is allowed by the specification,
1731        it is only necessary to probe for one of the instructions. */
1732 #ifndef use_mips32r2_instructions
1733     if (use_mips32_instructions) {
1734         got_sigill = 0;
1735         asm volatile(".set push\n"
1736                      ".set mips32r2\n"
1737                      "seb $zero, $zero\n"
1738                      ".set pop\n"
1739                      : : : );
1740         use_mips32r2_instructions = !got_sigill;
1741     }
1742 #endif
1743
1744     sigaction(SIGILL, &sa_old, NULL);
1745 }
1746
1747 /* Generate global QEMU prologue and epilogue code */
1748 static void tcg_target_qemu_prologue(TCGContext *s)
1749 {
1750     int i, frame_size;
1751
1752     /* reserve some stack space, also for TCG temps. */
1753     frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1754                  + TCG_STATIC_CALL_ARGS_SIZE
1755                  + CPU_TEMP_BUF_NLONGS * sizeof(long);
1756     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1757                  ~(TCG_TARGET_STACK_ALIGN - 1);
1758     tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1759                   + TCG_STATIC_CALL_ARGS_SIZE,
1760                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1761
1762     /* TB prologue */
1763     tcg_out_addi(s, TCG_REG_SP, -frame_size);
1764     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1765         tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1766                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1767     }
1768
1769     /* Call generated code */
1770     tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1771     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1772     tb_ret_addr = s->code_ptr;
1773
1774     /* TB epilogue */
1775     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1776         tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1777                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1778     }
1779
1780     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1781     tcg_out_addi(s, TCG_REG_SP, frame_size);
1782 }
1783
1784 static void tcg_target_init(TCGContext *s)
1785 {
1786     tcg_target_detect_isa();
1787     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1788     tcg_regset_set(tcg_target_call_clobber_regs,
1789                    (1 << TCG_REG_V0) |
1790                    (1 << TCG_REG_V1) |
1791                    (1 << TCG_REG_A0) |
1792                    (1 << TCG_REG_A1) |
1793                    (1 << TCG_REG_A2) |
1794                    (1 << TCG_REG_A3) |
1795                    (1 << TCG_REG_T0) |
1796                    (1 << TCG_REG_T1) |
1797                    (1 << TCG_REG_T2) |
1798                    (1 << TCG_REG_T3) |
1799                    (1 << TCG_REG_T4) |
1800                    (1 << TCG_REG_T5) |
1801                    (1 << TCG_REG_T6) |
1802                    (1 << TCG_REG_T7) |
1803                    (1 << TCG_REG_T8) |
1804                    (1 << TCG_REG_T9));
1805
1806     tcg_regset_clear(s->reserved_regs);
1807     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1808     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1809     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1810     tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);     /* internal use */
1811     tcg_regset_set_reg(s->reserved_regs, TCG_TMP1);     /* internal use */
1812     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1813     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1814     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1815
1816     tcg_add_target_add_op_defs(mips_op_defs);
1817 }
1818
1819 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
1820 {
1821     uint32_t *ptr = (uint32_t *)jmp_addr;
1822     *ptr = deposit32(*ptr, 0, 26, addr >> 2);
1823     flush_icache_range(jmp_addr, jmp_addr + 4);
1824 }