]> Git Repo - qemu.git/blob - tcg/mips/tcg-target.c
tcg/mips: optimize brcond arg, 0
[qemu.git] / tcg / mips / tcg-target.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 #if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28 # define TCG_NEED_BSWAP 0
29 #else
30 # define TCG_NEED_BSWAP 1
31 #endif
32
33 #ifndef NDEBUG
34 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
35     "zero",
36     "at",
37     "v0",
38     "v1",
39     "a0",
40     "a1",
41     "a2",
42     "a3",
43     "t0",
44     "t1",
45     "t2",
46     "t3",
47     "t4",
48     "t5",
49     "t6",
50     "t7",
51     "s0",
52     "s1",
53     "s2",
54     "s3",
55     "s4",
56     "s5",
57     "s6",
58     "s7",
59     "t8",
60     "t9",
61     "k0",
62     "k1",
63     "gp",
64     "sp",
65     "fp",
66     "ra",
67 };
68 #endif
69
70 /* check if we really need so many registers :P */
71 static const TCGReg tcg_target_reg_alloc_order[] = {
72     TCG_REG_S0,
73     TCG_REG_S1,
74     TCG_REG_S2,
75     TCG_REG_S3,
76     TCG_REG_S4,
77     TCG_REG_S5,
78     TCG_REG_S6,
79     TCG_REG_S7,
80     TCG_REG_T1,
81     TCG_REG_T2,
82     TCG_REG_T3,
83     TCG_REG_T4,
84     TCG_REG_T5,
85     TCG_REG_T6,
86     TCG_REG_T7,
87     TCG_REG_T8,
88     TCG_REG_T9,
89     TCG_REG_A0,
90     TCG_REG_A1,
91     TCG_REG_A2,
92     TCG_REG_A3,
93     TCG_REG_V0,
94     TCG_REG_V1
95 };
96
97 static const TCGReg tcg_target_call_iarg_regs[4] = {
98     TCG_REG_A0,
99     TCG_REG_A1,
100     TCG_REG_A2,
101     TCG_REG_A3
102 };
103
104 static const TCGReg tcg_target_call_oarg_regs[2] = {
105     TCG_REG_V0,
106     TCG_REG_V1
107 };
108
109 static uint8_t *tb_ret_addr;
110
111 static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
112 {
113     return target & 0xffff;
114 }
115
116 static inline void reloc_lo16 (void *pc, tcg_target_long target)
117 {
118     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
119                        | reloc_lo16_val(pc, target);
120 }
121
122 static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
123 {
124     return (target >> 16) & 0xffff;
125 }
126
127 static inline void reloc_hi16 (void *pc, tcg_target_long target)
128 {
129     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
130                        | reloc_hi16_val(pc, target);
131 }
132
133 static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
134 {
135     int32_t disp;
136
137     disp = target - (tcg_target_long) pc - 4;
138     if (disp != (disp << 14) >> 14) {
139         tcg_abort ();
140     }
141
142     return (disp >> 2) & 0xffff;
143 }
144
145 static inline void reloc_pc16 (void *pc, tcg_target_long target)
146 {
147     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
148                        | reloc_pc16_val(pc, target);
149 }
150
151 static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
152 {
153     if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
154         tcg_abort ();
155     }
156
157     return (target >> 2) & 0x3ffffff;
158 }
159
160 static inline void reloc_pc26 (void *pc, tcg_target_long target)
161 {
162     *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
163                        | reloc_26_val(pc, target);
164 }
165
166 static void patch_reloc(uint8_t *code_ptr, int type,
167                         tcg_target_long value, tcg_target_long addend)
168 {
169     value += addend;
170     switch(type) {
171     case R_MIPS_LO16:
172         reloc_lo16(code_ptr, value);
173         break;
174     case R_MIPS_HI16:
175         reloc_hi16(code_ptr, value);
176         break;
177     case R_MIPS_PC16:
178         reloc_pc16(code_ptr, value);
179         break;
180     case R_MIPS_26:
181         reloc_pc26(code_ptr, value);
182         break;
183     default:
184         tcg_abort();
185     }
186 }
187
188 /* maximum number of register used for input function arguments */
189 static inline int tcg_target_get_call_iarg_regs_count(int flags)
190 {
191     return 4;
192 }
193
194 /* parse target specific constraints */
195 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
196 {
197     const char *ct_str;
198
199     ct_str = *pct_str;
200     switch(ct_str[0]) {
201     case 'r':
202         ct->ct |= TCG_CT_REG;
203         tcg_regset_set(ct->u.regs, 0xffffffff);
204         break;
205     case 'C':
206         ct->ct |= TCG_CT_REG;
207         tcg_regset_clear(ct->u.regs);
208         tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
209         break;
210     case 'L': /* qemu_ld output arg constraint */
211         ct->ct |= TCG_CT_REG;
212         tcg_regset_set(ct->u.regs, 0xffffffff);
213         tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
214         break;
215     case 'l': /* qemu_ld input arg constraint */
216         ct->ct |= TCG_CT_REG;
217         tcg_regset_set(ct->u.regs, 0xffffffff);
218 #if defined(CONFIG_SOFTMMU)
219         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
220 # if (TARGET_LONG_BITS == 64)
221         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
222 # endif
223 #endif
224         break;
225     case 'S': /* qemu_st constraint */
226         ct->ct |= TCG_CT_REG;
227         tcg_regset_set(ct->u.regs, 0xffffffff);
228         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
229 #if defined(CONFIG_SOFTMMU)
230 # if (TARGET_LONG_BITS == 32)
231         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
232 # endif
233         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
234 # if TARGET_LONG_BITS == 64
235         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
236 # endif
237 #endif
238         break;
239     case 'I':
240         ct->ct |= TCG_CT_CONST_U16;
241         break;
242     case 'J':
243         ct->ct |= TCG_CT_CONST_S16;
244         break;
245     case 'Z':
246         /* We are cheating a bit here, using the fact that the register
247            ZERO is also the register number 0. Hence there is no need
248            to check for const_args in each instruction. */
249         ct->ct |= TCG_CT_CONST_ZERO;
250         break;
251     default:
252         return -1;
253     }
254     ct_str++;
255     *pct_str = ct_str;
256     return 0;
257 }
258
259 /* test if a constant matches the constraint */
260 static inline int tcg_target_const_match(tcg_target_long val,
261                                          const TCGArgConstraint *arg_ct)
262 {
263     int ct;
264     ct = arg_ct->ct;
265     if (ct & TCG_CT_CONST)
266         return 1;
267     else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
268         return 1;
269     else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
270         return 1;
271     else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
272         return 1;
273     else
274         return 0;
275 }
276
277 /* instruction opcodes */
278 enum {
279     OPC_BEQ      = 0x04 << 26,
280     OPC_BNE      = 0x05 << 26,
281     OPC_BLEZ     = 0x06 << 26,
282     OPC_BGTZ     = 0x07 << 26,
283     OPC_ADDIU    = 0x09 << 26,
284     OPC_SLTI     = 0x0A << 26,
285     OPC_SLTIU    = 0x0B << 26,
286     OPC_ANDI     = 0x0C << 26,
287     OPC_ORI      = 0x0D << 26,
288     OPC_XORI     = 0x0E << 26,
289     OPC_LUI      = 0x0F << 26,
290     OPC_LB       = 0x20 << 26,
291     OPC_LH       = 0x21 << 26,
292     OPC_LW       = 0x23 << 26,
293     OPC_LBU      = 0x24 << 26,
294     OPC_LHU      = 0x25 << 26,
295     OPC_LWU      = 0x27 << 26,
296     OPC_SB       = 0x28 << 26,
297     OPC_SH       = 0x29 << 26,
298     OPC_SW       = 0x2B << 26,
299
300     OPC_SPECIAL  = 0x00 << 26,
301     OPC_SLL      = OPC_SPECIAL | 0x00,
302     OPC_SRL      = OPC_SPECIAL | 0x02,
303     OPC_SRA      = OPC_SPECIAL | 0x03,
304     OPC_SLLV     = OPC_SPECIAL | 0x04,
305     OPC_SRLV     = OPC_SPECIAL | 0x06,
306     OPC_SRAV     = OPC_SPECIAL | 0x07,
307     OPC_JR       = OPC_SPECIAL | 0x08,
308     OPC_JALR     = OPC_SPECIAL | 0x09,
309     OPC_MFHI     = OPC_SPECIAL | 0x10,
310     OPC_MFLO     = OPC_SPECIAL | 0x12,
311     OPC_MULT     = OPC_SPECIAL | 0x18,
312     OPC_MULTU    = OPC_SPECIAL | 0x19,
313     OPC_DIV      = OPC_SPECIAL | 0x1A,
314     OPC_DIVU     = OPC_SPECIAL | 0x1B,
315     OPC_ADDU     = OPC_SPECIAL | 0x21,
316     OPC_SUBU     = OPC_SPECIAL | 0x23,
317     OPC_AND      = OPC_SPECIAL | 0x24,
318     OPC_OR       = OPC_SPECIAL | 0x25,
319     OPC_XOR      = OPC_SPECIAL | 0x26,
320     OPC_NOR      = OPC_SPECIAL | 0x27,
321     OPC_SLT      = OPC_SPECIAL | 0x2A,
322     OPC_SLTU     = OPC_SPECIAL | 0x2B,
323
324     OPC_REGIMM   = 0x01 << 26,
325     OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
326     OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
327
328     OPC_SPECIAL3 = 0x1f << 26,
329     OPC_SEB      = OPC_SPECIAL3 | 0x420,
330     OPC_SEH      = OPC_SPECIAL3 | 0x620,
331 };
332
333 /*
334  * Type reg
335  */
336 static inline void tcg_out_opc_reg(TCGContext *s, int opc,
337                                    TCGReg rd, TCGReg rs, TCGReg rt)
338 {
339     int32_t inst;
340
341     inst = opc;
342     inst |= (rs & 0x1F) << 21;
343     inst |= (rt & 0x1F) << 16;
344     inst |= (rd & 0x1F) << 11;
345     tcg_out32(s, inst);
346 }
347
348 /*
349  * Type immediate
350  */
351 static inline void tcg_out_opc_imm(TCGContext *s, int opc,
352                                    TCGReg rt, TCGReg rs, TCGArg imm)
353 {
354     int32_t inst;
355
356     inst = opc;
357     inst |= (rs & 0x1F) << 21;
358     inst |= (rt & 0x1F) << 16;
359     inst |= (imm & 0xffff);
360     tcg_out32(s, inst);
361 }
362
363 /*
364  * Type branch
365  */
366 static inline void tcg_out_opc_br(TCGContext *s, int opc,
367                                   TCGReg rt, TCGReg rs)
368 {
369     /* We pay attention here to not modify the branch target by reading
370        the existing value and using it again. This ensure that caches and
371        memory are kept coherent during retranslation. */
372     uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
373
374     tcg_out_opc_imm(s, opc, rt, rs, offset);
375 }
376
377 /*
378  * Type sa
379  */
380 static inline void tcg_out_opc_sa(TCGContext *s, int opc,
381                                   TCGReg rd, TCGReg rt, TCGArg sa)
382 {
383     int32_t inst;
384
385     inst = opc;
386     inst |= (rt & 0x1F) << 16;
387     inst |= (rd & 0x1F) << 11;
388     inst |= (sa & 0x1F) <<  6;
389     tcg_out32(s, inst);
390
391 }
392
393 static inline void tcg_out_nop(TCGContext *s)
394 {
395     tcg_out32(s, 0);
396 }
397
398 static inline void tcg_out_mov(TCGContext *s, TCGType type,
399                                TCGReg ret, TCGReg arg)
400 {
401     /* Simple reg-reg move, optimising out the 'do nothing' case */
402     if (ret != arg) {
403         tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
404     }
405 }
406
407 static inline void tcg_out_movi(TCGContext *s, TCGType type,
408                                 TCGReg reg, tcg_target_long arg)
409 {
410     if (arg == (int16_t)arg) {
411         tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
412     } else if (arg == (uint16_t)arg) {
413         tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
414     } else {
415         tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
416         tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
417     }
418 }
419
420 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
421 {
422     /* ret and arg can't be register at */
423     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
424         tcg_abort();
425     }
426
427     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
428     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
429
430     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
431     tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
432     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
433 }
434
435 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
436 {
437     /* ret and arg can't be register at */
438     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
439         tcg_abort();
440     }
441
442     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
443     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
444
445     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
446     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
447     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
448 }
449
450 static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
451 {
452     /* ret and arg must be different and can't be register at */
453     if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
454         tcg_abort();
455     }
456
457     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
458
459     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
460     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
461
462     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
463     tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
464     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
465
466     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
467     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
468     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
469 }
470
471 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
472 {
473 #ifdef _MIPS_ARCH_MIPS32R2
474     tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
475 #else
476     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
477     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
478 #endif
479 }
480
481 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
482 {
483 #ifdef _MIPS_ARCH_MIPS32R2
484     tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
485 #else
486     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
487     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
488 #endif
489 }
490
491 static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
492                                 TCGReg arg1, TCGArg arg2)
493 {
494     if (arg2 == (int16_t) arg2) {
495         tcg_out_opc_imm(s, opc, arg, arg1, arg2);
496     } else {
497         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
498         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
499         tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
500     }
501 }
502
503 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
504                               TCGReg arg1, tcg_target_long arg2)
505 {
506     tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
507 }
508
509 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
510                               TCGReg arg1, tcg_target_long arg2)
511 {
512     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
513 }
514
515 static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
516 {
517     if (val == (int16_t)val) {
518         tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
519     } else {
520         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
521         tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
522     }
523 }
524
525 /* Helper routines for marshalling helper function arguments into
526  * the correct registers and stack.
527  * arg_num is where we want to put this argument, and is updated to be ready
528  * for the next call. arg is the argument itself. Note that arg_num 0..3 is
529  * real registers, 4+ on stack.
530  *
531  * We provide routines for arguments which are: immediate, 32 bit
532  * value in register, 16 and 8 bit values in register (which must be zero
533  * extended before use) and 64 bit value in a lo:hi register pair.
534  */
535 #define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM)                               \
536     static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM)             \
537     {                                                                          \
538     if (*arg_num < 4) {                                                        \
539         DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
540     } else {                                                                   \
541         DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT);                          \
542         tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num));   \
543     }                                                                          \
544     (*arg_num)++;                                                              \
545 }
546 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
547     tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
548 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
549 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
550 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
551     tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
552 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
553 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
554 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
555     tcg_out_movi(s, TCG_TYPE_I32, A, arg);
556 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
557 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
558
559 /* We don't use the macro for this one to avoid an unnecessary reg-reg
560    move when storing to the stack. */
561 static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
562                                            TCGReg arg)
563 {
564     if (*arg_num < 4) {
565         tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
566     } else {
567         tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
568     }
569     (*arg_num)++;
570 }
571
572 static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
573                                            TCGReg arg_low, TCGReg arg_high)
574 {
575     (*arg_num) = (*arg_num + 1) & ~1;
576
577 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
578     tcg_out_call_iarg_reg32(s, arg_num, arg_high);
579     tcg_out_call_iarg_reg32(s, arg_num, arg_low);
580 #else
581     tcg_out_call_iarg_reg32(s, arg_num, arg_low);
582     tcg_out_call_iarg_reg32(s, arg_num, arg_high);
583 #endif
584 }
585
586 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
587                            TCGArg arg2, int label_index)
588 {
589     TCGLabel *l = &s->labels[label_index];
590
591     switch (cond) {
592     case TCG_COND_EQ:
593         tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
594         break;
595     case TCG_COND_NE:
596         tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
597         break;
598     case TCG_COND_LT:
599         if (arg2 == 0) {
600             tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
601         } else {
602             tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
603             tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
604         }
605         break;
606     case TCG_COND_LTU:
607         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
608         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
609         break;
610     case TCG_COND_GE:
611         if (arg2 == 0) {
612             tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
613         } else {
614             tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
615             tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
616         }
617         break;
618     case TCG_COND_GEU:
619         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
620         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
621         break;
622     case TCG_COND_LE:
623         if (arg2 == 0) {
624             tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
625         } else {
626             tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
627             tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
628         }
629         break;
630     case TCG_COND_LEU:
631         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
632         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
633         break;
634     case TCG_COND_GT:
635         if (arg2 == 0) {
636             tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
637         } else {
638             tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
639             tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
640         }
641         break;
642     case TCG_COND_GTU:
643         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
644         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
645         break;
646     default:
647         tcg_abort();
648         break;
649     }
650     if (l->has_value) {
651         reloc_pc16(s->code_ptr - 4, l->u.value);
652     } else {
653         tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
654     }
655     tcg_out_nop(s);
656 }
657
658 /* XXX: we implement it at the target level to avoid having to
659    handle cross basic blocks temporaries */
660 static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
661                             TCGArg arg2, TCGArg arg3, TCGArg arg4,
662                             int label_index)
663 {
664     void *label_ptr;
665
666     switch(cond) {
667     case TCG_COND_NE:
668         tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
669         tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
670         return;
671     case TCG_COND_EQ:
672         break;
673     case TCG_COND_LT:
674     case TCG_COND_LE:
675         tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
676         break;
677     case TCG_COND_GT:
678     case TCG_COND_GE:
679         tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
680         break;
681     case TCG_COND_LTU:
682     case TCG_COND_LEU:
683         tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
684         break;
685     case TCG_COND_GTU:
686     case TCG_COND_GEU:
687         tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
688         break;
689     default:
690         tcg_abort();
691     }
692
693     label_ptr = s->code_ptr;
694     tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
695     tcg_out_nop(s);
696
697     switch(cond) {
698     case TCG_COND_EQ:
699         tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
700         break;
701     case TCG_COND_LT:
702     case TCG_COND_LTU:
703         tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
704         break;
705     case TCG_COND_LE:
706     case TCG_COND_LEU:
707         tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
708         break;
709     case TCG_COND_GT:
710     case TCG_COND_GTU:
711         tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
712         break;
713     case TCG_COND_GE:
714     case TCG_COND_GEU:
715         tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
716         break;
717     default:
718         tcg_abort();
719     }
720
721     reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
722 }
723
724 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
725                             TCGArg arg1, TCGArg arg2)
726 {
727     switch (cond) {
728     case TCG_COND_EQ:
729         if (arg1 == 0) {
730             tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
731         } else if (arg2 == 0) {
732             tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
733         } else {
734             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
735             tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
736         }
737         break;
738     case TCG_COND_NE:
739         if (arg1 == 0) {
740             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
741         } else if (arg2 == 0) {
742             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
743         } else {
744             tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
745             tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
746         }
747         break;
748     case TCG_COND_LT:
749         tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
750         break;
751     case TCG_COND_LTU:
752         tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
753         break;
754     case TCG_COND_GE:
755         tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
756         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
757         break;
758     case TCG_COND_GEU:
759         tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
760         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
761         break;
762     case TCG_COND_LE:
763         tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
764         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
765         break;
766     case TCG_COND_LEU:
767         tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
768         tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
769         break;
770     case TCG_COND_GT:
771         tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
772         break;
773     case TCG_COND_GTU:
774         tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
775         break;
776     default:
777         tcg_abort();
778         break;
779     }
780 }
781
782 /* XXX: we implement it at the target level to avoid having to
783    handle cross basic blocks temporaries */
784 static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
785                              TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
786 {
787     switch (cond) {
788     case TCG_COND_EQ:
789         tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
790         tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
791         tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
792         return;
793     case TCG_COND_NE:
794         tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
795         tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
796         tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
797         return;
798     case TCG_COND_LT:
799     case TCG_COND_LE:
800         tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
801         break;
802     case TCG_COND_GT:
803     case TCG_COND_GE:
804         tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
805         break;
806     case TCG_COND_LTU:
807     case TCG_COND_LEU:
808         tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
809         break;
810     case TCG_COND_GTU:
811     case TCG_COND_GEU:
812         tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
813         break;
814     default:
815         tcg_abort();
816         break;
817     }
818
819     tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
820
821     switch(cond) {
822     case TCG_COND_LT:
823     case TCG_COND_LTU:
824         tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
825         break;
826     case TCG_COND_LE:
827     case TCG_COND_LEU:
828         tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
829         break;
830     case TCG_COND_GT:
831     case TCG_COND_GTU:
832         tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
833         break;
834     case TCG_COND_GE:
835     case TCG_COND_GEU:
836         tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
837         break;
838     default:
839         tcg_abort();
840     }
841
842     tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
843     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
844 }
845
846 #if defined(CONFIG_SOFTMMU)
847
848 #include "../../softmmu_defs.h"
849
850 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
851    int mmu_idx) */
852 static const void * const qemu_ld_helpers[4] = {
853     helper_ldb_mmu,
854     helper_ldw_mmu,
855     helper_ldl_mmu,
856     helper_ldq_mmu,
857 };
858
859 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
860    uintxx_t val, int mmu_idx) */
861 static const void * const qemu_st_helpers[4] = {
862     helper_stb_mmu,
863     helper_stw_mmu,
864     helper_stl_mmu,
865     helper_stq_mmu,
866 };
867 #endif
868
869 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
870                             int opc)
871 {
872     TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
873 #if defined(CONFIG_SOFTMMU)
874     void *label1_ptr, *label2_ptr;
875     int arg_num;
876     int mem_index, s_bits;
877     int addr_meml;
878 # if TARGET_LONG_BITS == 64
879     uint8_t *label3_ptr;
880     TCGReg addr_regh;
881     int addr_memh;
882 # endif
883 #endif
884     data_regl = *args++;
885     if (opc == 3)
886         data_regh = *args++;
887     else
888         data_regh = 0;
889     addr_regl = *args++;
890 #if defined(CONFIG_SOFTMMU)
891 # if TARGET_LONG_BITS == 64
892     addr_regh = *args++;
893 #  if defined(TCG_TARGET_WORDS_BIGENDIAN)
894     addr_memh = 0;
895     addr_meml = 4;
896 #  else
897     addr_memh = 4;
898     addr_meml = 0;
899 #  endif
900 # else
901     addr_meml = 0;
902 # endif
903     mem_index = *args;
904     s_bits = opc & 3;
905 #endif
906
907     if (opc == 3) {
908 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
909         data_reg1 = data_regh;
910         data_reg2 = data_regl;
911 #else
912         data_reg1 = data_regl;
913         data_reg2 = data_regh;
914 #endif
915     } else {
916         data_reg1 = data_regl;
917         data_reg2 = 0;
918     }
919 #if defined(CONFIG_SOFTMMU)
920     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
921     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
922     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
923     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
924                     offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
925     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
926     tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
927
928 # if TARGET_LONG_BITS == 64
929     label3_ptr = s->code_ptr;
930     tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
931     tcg_out_nop(s);
932
933     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
934                     offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
935
936     label1_ptr = s->code_ptr;
937     tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
938     tcg_out_nop(s);
939
940     reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
941 # else
942     label1_ptr = s->code_ptr;
943     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
944     tcg_out_nop(s);
945 # endif
946
947     /* slow path */
948     arg_num = 0;
949     tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
950 # if TARGET_LONG_BITS == 64
951     tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
952 # else
953     tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
954 # endif
955     tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
956     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
957     tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
958     tcg_out_nop(s);
959
960     switch(opc) {
961     case 0:
962         tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
963         break;
964     case 0 | 4:
965         tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
966         break;
967     case 1:
968         tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
969         break;
970     case 1 | 4:
971         tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
972         break;
973     case 2:
974         tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
975         break;
976     case 3:
977         tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
978         tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
979         break;
980     default:
981         tcg_abort();
982     }
983
984     label2_ptr = s->code_ptr;
985     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
986     tcg_out_nop(s);
987
988     /* label1: fast path */
989     reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
990
991     tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
992                     offsetof(CPUArchState, tlb_table[mem_index][0].addend));
993     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
994 #else
995     if (GUEST_BASE == (int16_t)GUEST_BASE) {
996         tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
997     } else {
998         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
999         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
1000     }
1001 #endif
1002
1003     switch(opc) {
1004     case 0:
1005         tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
1006         break;
1007     case 0 | 4:
1008         tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
1009         break;
1010     case 1:
1011         if (TCG_NEED_BSWAP) {
1012             tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1013             tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
1014         } else {
1015             tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
1016         }
1017         break;
1018     case 1 | 4:
1019         if (TCG_NEED_BSWAP) {
1020             tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1021             tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
1022         } else {
1023             tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
1024         }
1025         break;
1026     case 2:
1027         if (TCG_NEED_BSWAP) {
1028             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1029             tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1030         } else {
1031             tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1032         }
1033         break;
1034     case 3:
1035         if (TCG_NEED_BSWAP) {
1036             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1037             tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1038             tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1039             tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1040         } else {
1041             tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1042             tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1043         }
1044         break;
1045     default:
1046         tcg_abort();
1047     }
1048
1049 #if defined(CONFIG_SOFTMMU)
1050     reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1051 #endif
1052 }
1053
1054 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1055                             int opc)
1056 {
1057     TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1058 #if defined(CONFIG_SOFTMMU)
1059     uint8_t *label1_ptr, *label2_ptr;
1060     int arg_num;
1061     int mem_index, s_bits;
1062     int addr_meml;
1063 #endif
1064 #if TARGET_LONG_BITS == 64
1065 # if defined(CONFIG_SOFTMMU)
1066     uint8_t *label3_ptr;
1067     TCGReg addr_regh;
1068     int addr_memh;
1069 # endif
1070 #endif
1071     data_regl = *args++;
1072     if (opc == 3) {
1073         data_regh = *args++;
1074     } else {
1075         data_regh = 0;
1076     }
1077     addr_regl = *args++;
1078 #if defined(CONFIG_SOFTMMU)
1079 # if TARGET_LONG_BITS == 64
1080     addr_regh = *args++;
1081 #  if defined(TCG_TARGET_WORDS_BIGENDIAN)
1082     addr_memh = 0;
1083     addr_meml = 4;
1084 #  else
1085     addr_memh = 4;
1086     addr_meml = 0;
1087 #  endif
1088 # else
1089     addr_meml = 0;
1090 # endif
1091     mem_index = *args;
1092     s_bits = opc;
1093 #endif
1094
1095     if (opc == 3) {
1096 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
1097         data_reg1 = data_regh;
1098         data_reg2 = data_regl;
1099 #else
1100         data_reg1 = data_regl;
1101         data_reg2 = data_regh;
1102 #endif
1103     } else {
1104         data_reg1 = data_regl;
1105         data_reg2 = 0;
1106     }
1107
1108 #if defined(CONFIG_SOFTMMU)
1109     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1110     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1111     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1112     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1113                     offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1114     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1115     tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1116
1117 # if TARGET_LONG_BITS == 64
1118     label3_ptr = s->code_ptr;
1119     tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1120     tcg_out_nop(s);
1121
1122     tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1123                     offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1124
1125     label1_ptr = s->code_ptr;
1126     tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1127     tcg_out_nop(s);
1128
1129     reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1130 # else
1131     label1_ptr = s->code_ptr;
1132     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1133     tcg_out_nop(s);
1134 # endif
1135
1136     /* slow path */
1137     arg_num = 0;
1138     tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1139 # if TARGET_LONG_BITS == 64
1140     tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1141 # else
1142     tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1143 # endif
1144     switch(opc) {
1145     case 0:
1146         tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1147         break;
1148     case 1:
1149         tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1150         break;
1151     case 2:
1152         tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1153         break;
1154     case 3:
1155         tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1156         break;
1157     default:
1158         tcg_abort();
1159     }
1160     tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1161     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1162     tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1163     tcg_out_nop(s);
1164
1165     label2_ptr = s->code_ptr;
1166     tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1167     tcg_out_nop(s);
1168
1169     /* label1: fast path */
1170     reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1171
1172     tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1173                     offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1174     tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1175 #else
1176     if (GUEST_BASE == (int16_t)GUEST_BASE) {
1177         tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1178     } else {
1179         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1180         tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1181     }
1182
1183 #endif
1184
1185     switch(opc) {
1186     case 0:
1187         tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1188         break;
1189     case 1:
1190         if (TCG_NEED_BSWAP) {
1191             tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1192             tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1193         } else {
1194             tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1195         }
1196         break;
1197     case 2:
1198         if (TCG_NEED_BSWAP) {
1199             tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1200             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1201         } else {
1202             tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1203         }
1204         break;
1205     case 3:
1206         if (TCG_NEED_BSWAP) {
1207             tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1208             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1209             tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1210             tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1211         } else {
1212             tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1213             tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1214         }
1215         break;
1216     default:
1217         tcg_abort();
1218     }
1219
1220 #if defined(CONFIG_SOFTMMU)
1221     reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1222 #endif
1223 }
1224
1225 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1226                               const TCGArg *args, const int *const_args)
1227 {
1228     switch(opc) {
1229     case INDEX_op_exit_tb:
1230         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1231         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1232         tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1233         tcg_out_nop(s);
1234         break;
1235     case INDEX_op_goto_tb:
1236         if (s->tb_jmp_offset) {
1237             /* direct jump method */
1238             tcg_abort();
1239         } else {
1240             /* indirect jump method */
1241             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1242             tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1243             tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1244         }
1245         tcg_out_nop(s);
1246         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1247         break;
1248     case INDEX_op_call:
1249         tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1250         tcg_out_nop(s);
1251         break;
1252     case INDEX_op_jmp:
1253         tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1254         tcg_out_nop(s);
1255         break;
1256     case INDEX_op_br:
1257         tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1258         break;
1259
1260     case INDEX_op_mov_i32:
1261         tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1262         break;
1263     case INDEX_op_movi_i32:
1264         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1265         break;
1266
1267     case INDEX_op_ld8u_i32:
1268         tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1269         break;
1270     case INDEX_op_ld8s_i32:
1271         tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1272         break;
1273     case INDEX_op_ld16u_i32:
1274         tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1275         break;
1276     case INDEX_op_ld16s_i32:
1277         tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1278         break;
1279     case INDEX_op_ld_i32:
1280         tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1281         break;
1282     case INDEX_op_st8_i32:
1283         tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1284         break;
1285     case INDEX_op_st16_i32:
1286         tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1287         break;
1288     case INDEX_op_st_i32:
1289         tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1290         break;
1291
1292     case INDEX_op_add_i32:
1293         if (const_args[2]) {
1294             tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1295         } else {
1296             tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1297         }
1298         break;
1299     case INDEX_op_add2_i32:
1300         if (const_args[4]) {
1301             tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1302         } else {
1303             tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1304         }
1305         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1306         if (const_args[5]) {
1307             tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1308         } else {
1309              tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1310         }
1311         tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1312         tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1313         break;
1314     case INDEX_op_sub_i32:
1315         if (const_args[2]) {
1316             tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1317         } else {
1318             tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1319         }
1320         break;
1321     case INDEX_op_sub2_i32:
1322         if (const_args[4]) {
1323             tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1324         } else {
1325             tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1326         }
1327         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1328         if (const_args[5]) {
1329             tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1330         } else {
1331              tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1332         }
1333         tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1334         tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1335         break;
1336     case INDEX_op_mul_i32:
1337         tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1338         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1339         break;
1340     case INDEX_op_mulu2_i32:
1341         tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1342         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1343         tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1344         break;
1345     case INDEX_op_div_i32:
1346         tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1347         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1348         break;
1349     case INDEX_op_divu_i32:
1350         tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1351         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1352         break;
1353     case INDEX_op_rem_i32:
1354         tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1355         tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1356         break;
1357     case INDEX_op_remu_i32:
1358         tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1359         tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1360         break;
1361
1362     case INDEX_op_and_i32:
1363         if (const_args[2]) {
1364             tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1365         } else {
1366             tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1367         }
1368         break;
1369     case INDEX_op_or_i32:
1370         if (const_args[2]) {
1371             tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1372         } else {
1373             tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1374         }
1375         break;
1376     case INDEX_op_nor_i32:
1377         tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1378         break;
1379     case INDEX_op_not_i32:
1380         tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1381         break;
1382     case INDEX_op_xor_i32:
1383         if (const_args[2]) {
1384             tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1385         } else {
1386             tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1387         }
1388         break;
1389
1390     case INDEX_op_sar_i32:
1391         if (const_args[2]) {
1392             tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1393         } else {
1394             tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1395         }
1396         break;
1397     case INDEX_op_shl_i32:
1398         if (const_args[2]) {
1399             tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1400         } else {
1401             tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1402         }
1403         break;
1404     case INDEX_op_shr_i32:
1405         if (const_args[2]) {
1406             tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1407         } else {
1408             tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1409         }
1410         break;
1411
1412     case INDEX_op_ext8s_i32:
1413         tcg_out_ext8s(s, args[0], args[1]);
1414         break;
1415     case INDEX_op_ext16s_i32:
1416         tcg_out_ext16s(s, args[0], args[1]);
1417         break;
1418
1419     case INDEX_op_brcond_i32:
1420         tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1421         break;
1422     case INDEX_op_brcond2_i32:
1423         tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1424         break;
1425
1426     case INDEX_op_setcond_i32:
1427         tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1428         break;
1429     case INDEX_op_setcond2_i32:
1430         tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1431         break;
1432
1433     case INDEX_op_qemu_ld8u:
1434         tcg_out_qemu_ld(s, args, 0);
1435         break;
1436     case INDEX_op_qemu_ld8s:
1437         tcg_out_qemu_ld(s, args, 0 | 4);
1438         break;
1439     case INDEX_op_qemu_ld16u:
1440         tcg_out_qemu_ld(s, args, 1);
1441         break;
1442     case INDEX_op_qemu_ld16s:
1443         tcg_out_qemu_ld(s, args, 1 | 4);
1444         break;
1445     case INDEX_op_qemu_ld32:
1446         tcg_out_qemu_ld(s, args, 2);
1447         break;
1448     case INDEX_op_qemu_ld64:
1449         tcg_out_qemu_ld(s, args, 3);
1450         break;
1451     case INDEX_op_qemu_st8:
1452         tcg_out_qemu_st(s, args, 0);
1453         break;
1454     case INDEX_op_qemu_st16:
1455         tcg_out_qemu_st(s, args, 1);
1456         break;
1457     case INDEX_op_qemu_st32:
1458         tcg_out_qemu_st(s, args, 2);
1459         break;
1460     case INDEX_op_qemu_st64:
1461         tcg_out_qemu_st(s, args, 3);
1462         break;
1463
1464     default:
1465         tcg_abort();
1466     }
1467 }
1468
1469 static const TCGTargetOpDef mips_op_defs[] = {
1470     { INDEX_op_exit_tb, { } },
1471     { INDEX_op_goto_tb, { } },
1472     { INDEX_op_call, { "C" } },
1473     { INDEX_op_jmp, { "r" } },
1474     { INDEX_op_br, { } },
1475
1476     { INDEX_op_mov_i32, { "r", "r" } },
1477     { INDEX_op_movi_i32, { "r" } },
1478     { INDEX_op_ld8u_i32, { "r", "r" } },
1479     { INDEX_op_ld8s_i32, { "r", "r" } },
1480     { INDEX_op_ld16u_i32, { "r", "r" } },
1481     { INDEX_op_ld16s_i32, { "r", "r" } },
1482     { INDEX_op_ld_i32, { "r", "r" } },
1483     { INDEX_op_st8_i32, { "rZ", "r" } },
1484     { INDEX_op_st16_i32, { "rZ", "r" } },
1485     { INDEX_op_st_i32, { "rZ", "r" } },
1486
1487     { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1488     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1489     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1490     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1491     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1492     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1493     { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1494     { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1495
1496     { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1497     { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1498     { INDEX_op_not_i32, { "r", "rZ" } },
1499     { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1500     { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1501
1502     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1503     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1504     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1505
1506     { INDEX_op_ext8s_i32, { "r", "rZ" } },
1507     { INDEX_op_ext16s_i32, { "r", "rZ" } },
1508
1509     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1510     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1511     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1512
1513     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1514     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1515     { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1516
1517 #if TARGET_LONG_BITS == 32
1518     { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1519     { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1520     { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1521     { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1522     { INDEX_op_qemu_ld32, { "L", "lZ" } },
1523     { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1524
1525     { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1526     { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1527     { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1528     { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1529 #else
1530     { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1531     { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1532     { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1533     { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1534     { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1535     { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1536
1537     { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1538     { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1539     { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1540     { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1541 #endif
1542     { -1 },
1543 };
1544
1545 static int tcg_target_callee_save_regs[] = {
1546     TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1547     TCG_REG_S1,
1548     TCG_REG_S2,
1549     TCG_REG_S3,
1550     TCG_REG_S4,
1551     TCG_REG_S5,
1552     TCG_REG_S6,
1553     TCG_REG_S7,
1554     TCG_REG_FP,
1555     TCG_REG_RA,       /* should be last for ABI compliance */
1556 };
1557
1558 /* Generate global QEMU prologue and epilogue code */
1559 static void tcg_target_qemu_prologue(TCGContext *s)
1560 {
1561     int i, frame_size;
1562
1563     /* reserve some stack space, also for TCG temps. */
1564     frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1565                  + TCG_STATIC_CALL_ARGS_SIZE
1566                  + CPU_TEMP_BUF_NLONGS * sizeof(long);
1567     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1568                  ~(TCG_TARGET_STACK_ALIGN - 1);
1569     tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1570                   + TCG_STATIC_CALL_ARGS_SIZE,
1571                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1572
1573     /* TB prologue */
1574     tcg_out_addi(s, TCG_REG_SP, -frame_size);
1575     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1576         tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1577                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1578     }
1579
1580     /* Call generated code */
1581     tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1582     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1583     tb_ret_addr = s->code_ptr;
1584
1585     /* TB epilogue */
1586     for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1587         tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1588                    TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1589     }
1590
1591     tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1592     tcg_out_addi(s, TCG_REG_SP, frame_size);
1593 }
1594
1595 static void tcg_target_init(TCGContext *s)
1596 {
1597     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1598     tcg_regset_set(tcg_target_call_clobber_regs,
1599                    (1 << TCG_REG_V0) |
1600                    (1 << TCG_REG_V1) |
1601                    (1 << TCG_REG_A0) |
1602                    (1 << TCG_REG_A1) |
1603                    (1 << TCG_REG_A2) |
1604                    (1 << TCG_REG_A3) |
1605                    (1 << TCG_REG_T1) |
1606                    (1 << TCG_REG_T2) |
1607                    (1 << TCG_REG_T3) |
1608                    (1 << TCG_REG_T4) |
1609                    (1 << TCG_REG_T5) |
1610                    (1 << TCG_REG_T6) |
1611                    (1 << TCG_REG_T7) |
1612                    (1 << TCG_REG_T8) |
1613                    (1 << TCG_REG_T9));
1614
1615     tcg_regset_clear(s->reserved_regs);
1616     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1617     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1618     tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1619     tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1620     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1621     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1622     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1623     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1624
1625     tcg_add_target_add_op_defs(mips_op_defs);
1626 }
This page took 0.121913 seconds and 4 git commands to generate.