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