Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ 0834c9ea

History | View | Annotate | Download (48.5 kB)

1
/*
2
 * Tiny Code Generator for QEMU
3
 *
4
 * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5
 * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6
 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26

    
27
#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 int 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 int 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 int 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_ADDIU    = 0x09 << 26,
282
    OPC_SLTI     = 0x0A << 26,
283
    OPC_SLTIU    = 0x0B << 26,
284
    OPC_ANDI     = 0x0C << 26,
285
    OPC_ORI      = 0x0D << 26,
286
    OPC_XORI     = 0x0E << 26,
287
    OPC_LUI      = 0x0F << 26,
288
    OPC_LB       = 0x20 << 26,
289
    OPC_LH       = 0x21 << 26,
290
    OPC_LW       = 0x23 << 26,
291
    OPC_LBU      = 0x24 << 26,
292
    OPC_LHU      = 0x25 << 26,
293
    OPC_LWU      = 0x27 << 26,
294
    OPC_SB       = 0x28 << 26,
295
    OPC_SH       = 0x29 << 26,
296
    OPC_SW       = 0x2B << 26,
297

    
298
    OPC_SPECIAL  = 0x00 << 26,
299
    OPC_SLL      = OPC_SPECIAL | 0x00,
300
    OPC_SRL      = OPC_SPECIAL | 0x02,
301
    OPC_SRA      = OPC_SPECIAL | 0x03,
302
    OPC_SLLV     = OPC_SPECIAL | 0x04,
303
    OPC_SRLV     = OPC_SPECIAL | 0x06,
304
    OPC_SRAV     = OPC_SPECIAL | 0x07,
305
    OPC_JR       = OPC_SPECIAL | 0x08,
306
    OPC_JALR     = OPC_SPECIAL | 0x09,
307
    OPC_MFHI     = OPC_SPECIAL | 0x10,
308
    OPC_MFLO     = OPC_SPECIAL | 0x12,
309
    OPC_MULT     = OPC_SPECIAL | 0x18,
310
    OPC_MULTU    = OPC_SPECIAL | 0x19,
311
    OPC_DIV      = OPC_SPECIAL | 0x1A,
312
    OPC_DIVU     = OPC_SPECIAL | 0x1B,
313
    OPC_ADDU     = OPC_SPECIAL | 0x21,
314
    OPC_SUBU     = OPC_SPECIAL | 0x23,
315
    OPC_AND      = OPC_SPECIAL | 0x24,
316
    OPC_OR       = OPC_SPECIAL | 0x25,
317
    OPC_XOR      = OPC_SPECIAL | 0x26,
318
    OPC_NOR      = OPC_SPECIAL | 0x27,
319
    OPC_SLT      = OPC_SPECIAL | 0x2A,
320
    OPC_SLTU     = OPC_SPECIAL | 0x2B,
321

    
322
    OPC_SPECIAL3 = 0x1f << 26,
323
    OPC_SEB      = OPC_SPECIAL3 | 0x420,
324
    OPC_SEH      = OPC_SPECIAL3 | 0x620,
325
};
326

    
327
/*
328
 * Type reg
329
 */
330
static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
331
{
332
    int32_t inst;
333

    
334
    inst = opc;
335
    inst |= (rs & 0x1F) << 21;
336
    inst |= (rt & 0x1F) << 16;
337
    inst |= (rd & 0x1F) << 11;
338
    tcg_out32(s, inst);
339
}
340

    
341
/*
342
 * Type immediate
343
 */
344
static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
345
{
346
    int32_t inst;
347

    
348
    inst = opc;
349
    inst |= (rs & 0x1F) << 21;
350
    inst |= (rt & 0x1F) << 16;
351
    inst |= (imm & 0xffff);
352
    tcg_out32(s, inst);
353
}
354

    
355
/*
356
 * Type branch
357
 */
358
static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
359
{
360
    /* We pay attention here to not modify the branch target by reading
361
       the existing value and using it again. This ensure that caches and
362
       memory are kept coherent during retranslation. */
363
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
364

    
365
    tcg_out_opc_imm(s, opc, rt, rs, offset);
366
}
367

    
368
/*
369
 * Type sa
370
 */
371
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
372
{
373
    int32_t inst;
374

    
375
    inst = opc;
376
    inst |= (rt & 0x1F) << 16;
377
    inst |= (rd & 0x1F) << 11;
378
    inst |= (sa & 0x1F) <<  6;
379
    tcg_out32(s, inst);
380

    
381
}
382

    
383
static inline void tcg_out_nop(TCGContext *s)
384
{
385
    tcg_out32(s, 0);
386
}
387

    
388
static inline void tcg_out_mov(TCGContext *s, TCGType type,
389
                               TCGReg ret, TCGReg arg)
390
{
391
    /* Simple reg-reg move, optimising out the 'do nothing' case */
392
    if (ret != arg) {
393
        tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
394
    }
395
}
396

    
397
static inline void tcg_out_movi(TCGContext *s, TCGType type,
398
                                TCGReg reg, tcg_target_long arg)
399
{
400
    if (arg == (int16_t)arg) {
401
        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
402
    } else if (arg == (uint16_t)arg) {
403
        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
404
    } else {
405
        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
406
        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
407
    }
408
}
409

    
410
static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
411
{
412
    /* ret and arg can't be register at */
413
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
414
        tcg_abort();
415
    }
416

    
417
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
418
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
419

    
420
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
421
    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
422
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
423
}
424

    
425
static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
426
{
427
    /* ret and arg can't be register at */
428
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
429
        tcg_abort();
430
    }
431

    
432
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
433
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
434

    
435
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
436
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
437
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
438
}
439

    
440
static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
441
{
442
    /* ret and arg must be different and can't be register at */
443
    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
444
        tcg_abort();
445
    }
446

    
447
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
448

    
449
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
450
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
451

    
452
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
453
    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
454
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
455

    
456
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
457
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
458
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
459
}
460

    
461
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
462
{
463
#ifdef _MIPS_ARCH_MIPS32R2
464
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
465
#else
466
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
467
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
468
#endif
469
}
470

    
471
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
472
{
473
#ifdef _MIPS_ARCH_MIPS32R2
474
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
475
#else
476
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
477
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
478
#endif
479
}
480

    
481
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
482
                              int arg1, tcg_target_long arg2)
483
{
484
    if (arg2 == (int16_t) arg2) {
485
        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
486
    } else {
487
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
488
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
489
        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
490
    }
491
}
492

    
493
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
494
                              TCGReg arg1, tcg_target_long arg2)
495
{
496
    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
497
}
498

    
499
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
500
                              TCGReg arg1, tcg_target_long arg2)
501
{
502
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
503
}
504

    
505
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
506
{
507
    if (val == (int16_t)val) {
508
        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
509
    } else {
510
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
511
        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
512
    }
513
}
514

    
515
/* Helper routines for marshalling helper function arguments into
516
 * the correct registers and stack.
517
 * arg_num is where we want to put this argument, and is updated to be ready
518
 * for the next call. arg is the argument itself. Note that arg_num 0..3 is
519
 * real registers, 4+ on stack.
520
 *
521
 * We provide routines for arguments which are: immediate, 32 bit
522
 * value in register, 16 and 8 bit values in register (which must be zero
523
 * extended before use) and 64 bit value in a lo:hi register pair.
524
 */
525
#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM)                               \
526
    static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM)             \
527
    {                                                                          \
528
    if (*arg_num < 4) {                                                        \
529
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
530
    } else {                                                                   \
531
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT);                          \
532
        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num));   \
533
    }                                                                          \
534
    (*arg_num)++;                                                              \
535
}
536
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
537
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
538
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
539
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
540
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
541
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
542
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
543
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
544
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
545
    tcg_out_movi(s, TCG_TYPE_I32, A, arg);
546
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg)
547
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
548

    
549
/* We don't use the macro for this one to avoid an unnecessary reg-reg
550
   move when storing to the stack. */
551
static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
552
                                           TCGReg arg)
553
{
554
    if (*arg_num < 4) {
555
        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
556
    } else {
557
        tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
558
    }
559
    (*arg_num)++;
560
}
561

    
562
static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
563
                                           TCGReg arg_low, TCGReg arg_high)
564
{
565
    (*arg_num) = (*arg_num + 1) & ~1;
566

    
567
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
568
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
569
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
570
#else
571
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
572
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
573
#endif
574
}
575

    
576
static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
577
                           int arg2, int label_index)
578
{
579
    TCGLabel *l = &s->labels[label_index];
580

    
581
    switch (cond) {
582
    case TCG_COND_EQ:
583
        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
584
        break;
585
    case TCG_COND_NE:
586
        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
587
        break;
588
    case TCG_COND_LT:
589
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
590
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
591
        break;
592
    case TCG_COND_LTU:
593
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
594
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
595
        break;
596
    case TCG_COND_GE:
597
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
598
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
599
        break;
600
    case TCG_COND_GEU:
601
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
602
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
603
        break;
604
    case TCG_COND_LE:
605
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
606
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
607
        break;
608
    case TCG_COND_LEU:
609
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
610
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
611
        break;
612
    case TCG_COND_GT:
613
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
614
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
615
        break;
616
    case TCG_COND_GTU:
617
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
618
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
619
        break;
620
    default:
621
        tcg_abort();
622
        break;
623
    }
624
    if (l->has_value) {
625
        reloc_pc16(s->code_ptr - 4, l->u.value);
626
    } else {
627
        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
628
    }
629
    tcg_out_nop(s);
630
}
631

    
632
/* XXX: we implement it at the target level to avoid having to
633
   handle cross basic blocks temporaries */
634
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
635
                            int arg2, int arg3, int arg4, int label_index)
636
{
637
    void *label_ptr;
638

    
639
    switch(cond) {
640
    case TCG_COND_NE:
641
        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
642
        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
643
        return;
644
    case TCG_COND_EQ:
645
        break;
646
    case TCG_COND_LT:
647
    case TCG_COND_LE:
648
        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
649
        break;
650
    case TCG_COND_GT:
651
    case TCG_COND_GE:
652
        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
653
        break;
654
    case TCG_COND_LTU:
655
    case TCG_COND_LEU:
656
        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
657
        break;
658
    case TCG_COND_GTU:
659
    case TCG_COND_GEU:
660
        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
661
        break;
662
    default:
663
        tcg_abort();
664
    }
665

    
666
    label_ptr = s->code_ptr;
667
    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
668
    tcg_out_nop(s);
669

    
670
    switch(cond) {
671
    case TCG_COND_EQ:
672
        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
673
        break;
674
    case TCG_COND_LT:
675
    case TCG_COND_LTU:
676
        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
677
        break;
678
    case TCG_COND_LE:
679
    case TCG_COND_LEU:
680
        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
681
        break;
682
    case TCG_COND_GT:
683
    case TCG_COND_GTU:
684
        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
685
        break;
686
    case TCG_COND_GE:
687
    case TCG_COND_GEU:
688
        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
689
        break;
690
    default:
691
        tcg_abort();
692
    }
693

    
694
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
695
}
696

    
697
static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
698
                            int arg1, int arg2)
699
{
700
    switch (cond) {
701
    case TCG_COND_EQ:
702
        if (arg1 == 0) {
703
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
704
        } else if (arg2 == 0) {
705
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
706
        } else {
707
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
708
            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
709
        }
710
        break;
711
    case TCG_COND_NE:
712
        if (arg1 == 0) {
713
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
714
        } else if (arg2 == 0) {
715
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
716
        } else {
717
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
718
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
719
        }
720
        break;
721
    case TCG_COND_LT:
722
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
723
        break;
724
    case TCG_COND_LTU:
725
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
726
        break;
727
    case TCG_COND_GE:
728
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
729
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
730
        break;
731
    case TCG_COND_GEU:
732
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
733
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
734
        break;
735
    case TCG_COND_LE:
736
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
737
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
738
        break;
739
    case TCG_COND_LEU:
740
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
741
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
742
        break;
743
    case TCG_COND_GT:
744
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
745
        break;
746
    case TCG_COND_GTU:
747
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
748
        break;
749
    default:
750
        tcg_abort();
751
        break;
752
    }
753
}
754

    
755
/* XXX: we implement it at the target level to avoid having to
756
   handle cross basic blocks temporaries */
757
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
758
                             int arg1, int arg2, int arg3, int arg4)
759
{
760
    switch (cond) {
761
    case TCG_COND_EQ:
762
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
763
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
764
        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
765
        return;
766
    case TCG_COND_NE:
767
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
768
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
769
        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
770
        return;
771
    case TCG_COND_LT:
772
    case TCG_COND_LE:
773
        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
774
        break;
775
    case TCG_COND_GT:
776
    case TCG_COND_GE:
777
        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
778
        break;
779
    case TCG_COND_LTU:
780
    case TCG_COND_LEU:
781
        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
782
        break;
783
    case TCG_COND_GTU:
784
    case TCG_COND_GEU:
785
        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
786
        break;
787
    default:
788
        tcg_abort();
789
        break;
790
    }
791

    
792
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
793

    
794
    switch(cond) {
795
    case TCG_COND_LT:
796
    case TCG_COND_LTU:
797
        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
798
        break;
799
    case TCG_COND_LE:
800
    case TCG_COND_LEU:
801
        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
802
        break;
803
    case TCG_COND_GT:
804
    case TCG_COND_GTU:
805
        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
806
        break;
807
    case TCG_COND_GE:
808
    case TCG_COND_GEU:
809
        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
810
        break;
811
    default:
812
        tcg_abort();
813
    }
814

    
815
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
816
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
817
}
818

    
819
#if defined(CONFIG_SOFTMMU)
820

    
821
#include "../../softmmu_defs.h"
822

    
823
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
824
   int mmu_idx) */
825
static const void * const qemu_ld_helpers[4] = {
826
    helper_ldb_mmu,
827
    helper_ldw_mmu,
828
    helper_ldl_mmu,
829
    helper_ldq_mmu,
830
};
831

    
832
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
833
   uintxx_t val, int mmu_idx) */
834
static const void * const qemu_st_helpers[4] = {
835
    helper_stb_mmu,
836
    helper_stw_mmu,
837
    helper_stl_mmu,
838
    helper_stq_mmu,
839
};
840
#endif
841

    
842
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
843
                            int opc)
844
{
845
    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
846
#if defined(CONFIG_SOFTMMU)
847
    void *label1_ptr, *label2_ptr;
848
    int arg_num;
849
    int mem_index, s_bits;
850
    int addr_meml;
851
# if TARGET_LONG_BITS == 64
852
    uint8_t *label3_ptr;
853
    int addr_regh, addr_memh;
854
# endif
855
#endif
856
    data_regl = *args++;
857
    if (opc == 3)
858
        data_regh = *args++;
859
    else
860
        data_regh = 0;
861
    addr_regl = *args++;
862
#if defined(CONFIG_SOFTMMU)
863
# if TARGET_LONG_BITS == 64
864
    addr_regh = *args++;
865
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
866
    addr_memh = 0;
867
    addr_meml = 4;
868
#  else
869
    addr_memh = 4;
870
    addr_meml = 0;
871
#  endif
872
# else
873
    addr_meml = 0;
874
# endif
875
    mem_index = *args;
876
    s_bits = opc & 3;
877
#endif
878

    
879
    if (opc == 3) {
880
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
881
        data_reg1 = data_regh;
882
        data_reg2 = data_regl;
883
#else
884
        data_reg1 = data_regl;
885
        data_reg2 = data_regh;
886
#endif
887
    } else {
888
        data_reg1 = data_regl;
889
        data_reg2 = 0;
890
    }
891
#if defined(CONFIG_SOFTMMU)
892
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
893
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
894
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
895
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
896
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
897
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
898
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
899

    
900
# if TARGET_LONG_BITS == 64
901
    label3_ptr = s->code_ptr;
902
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
903
    tcg_out_nop(s);
904

    
905
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
906
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
907

    
908
    label1_ptr = s->code_ptr;
909
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
910
    tcg_out_nop(s);
911

    
912
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
913
# else
914
    label1_ptr = s->code_ptr;
915
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
916
    tcg_out_nop(s);
917
# endif
918

    
919
    /* slow path */
920
    arg_num = 0;
921
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
922
# if TARGET_LONG_BITS == 64
923
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
924
# else
925
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
926
# endif
927
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
928
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
929
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
930
    tcg_out_nop(s);
931

    
932
    switch(opc) {
933
    case 0:
934
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
935
        break;
936
    case 0 | 4:
937
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
938
        break;
939
    case 1:
940
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
941
        break;
942
    case 1 | 4:
943
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
944
        break;
945
    case 2:
946
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
947
        break;
948
    case 3:
949
        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
950
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
951
        break;
952
    default:
953
        tcg_abort();
954
    }
955

    
956
    label2_ptr = s->code_ptr;
957
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
958
    tcg_out_nop(s);
959

    
960
    /* label1: fast path */
961
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
962

    
963
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
964
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
965
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
966
#else
967
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
968
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
969
    } else {
970
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
971
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
972
    }
973
#endif
974

    
975
    switch(opc) {
976
    case 0:
977
        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
978
        break;
979
    case 0 | 4:
980
        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
981
        break;
982
    case 1:
983
        if (TCG_NEED_BSWAP) {
984
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
985
            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
986
        } else {
987
            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
988
        }
989
        break;
990
    case 1 | 4:
991
        if (TCG_NEED_BSWAP) {
992
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
993
            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
994
        } else {
995
            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
996
        }
997
        break;
998
    case 2:
999
        if (TCG_NEED_BSWAP) {
1000
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1001
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1002
        } else {
1003
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1004
        }
1005
        break;
1006
    case 3:
1007
        if (TCG_NEED_BSWAP) {
1008
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1009
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1010
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1011
            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1012
        } else {
1013
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1014
            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1015
        }
1016
        break;
1017
    default:
1018
        tcg_abort();
1019
    }
1020

    
1021
#if defined(CONFIG_SOFTMMU)
1022
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1023
#endif
1024
}
1025

    
1026
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1027
                            int opc)
1028
{
1029
    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1030
#if defined(CONFIG_SOFTMMU)
1031
    uint8_t *label1_ptr, *label2_ptr;
1032
    int arg_num;
1033
    int mem_index, s_bits;
1034
    int addr_meml;
1035
#endif
1036
#if TARGET_LONG_BITS == 64
1037
# if defined(CONFIG_SOFTMMU)
1038
    uint8_t *label3_ptr;
1039
    int addr_regh, addr_memh;
1040
# endif
1041
#endif
1042
    data_regl = *args++;
1043
    if (opc == 3) {
1044
        data_regh = *args++;
1045
    } else {
1046
        data_regh = 0;
1047
    }
1048
    addr_regl = *args++;
1049
#if defined(CONFIG_SOFTMMU)
1050
# if TARGET_LONG_BITS == 64
1051
    addr_regh = *args++;
1052
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
1053
    addr_memh = 0;
1054
    addr_meml = 4;
1055
#  else
1056
    addr_memh = 4;
1057
    addr_meml = 0;
1058
#  endif
1059
# else
1060
    addr_meml = 0;
1061
# endif
1062
    mem_index = *args;
1063
    s_bits = opc;
1064
#endif
1065

    
1066
    if (opc == 3) {
1067
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1068
        data_reg1 = data_regh;
1069
        data_reg2 = data_regl;
1070
#else
1071
        data_reg1 = data_regl;
1072
        data_reg2 = data_regh;
1073
#endif
1074
    } else {
1075
        data_reg1 = data_regl;
1076
        data_reg2 = 0;
1077
    }
1078

    
1079
#if defined(CONFIG_SOFTMMU)
1080
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1081
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1082
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1083
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1084
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1085
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1086
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1087

    
1088
# if TARGET_LONG_BITS == 64
1089
    label3_ptr = s->code_ptr;
1090
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1091
    tcg_out_nop(s);
1092

    
1093
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1094
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1095

    
1096
    label1_ptr = s->code_ptr;
1097
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1098
    tcg_out_nop(s);
1099

    
1100
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1101
# else
1102
    label1_ptr = s->code_ptr;
1103
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1104
    tcg_out_nop(s);
1105
# endif
1106

    
1107
    /* slow path */
1108
    arg_num = 0;
1109
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1110
# if TARGET_LONG_BITS == 64
1111
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1112
# else
1113
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1114
# endif
1115
    switch(opc) {
1116
    case 0:
1117
        tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1118
        break;
1119
    case 1:
1120
        tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1121
        break;
1122
    case 2:
1123
        tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1124
        break;
1125
    case 3:
1126
        tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1127
        break;
1128
    default:
1129
        tcg_abort();
1130
    }
1131
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1132
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1133
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1134
    tcg_out_nop(s);
1135

    
1136
    label2_ptr = s->code_ptr;
1137
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1138
    tcg_out_nop(s);
1139

    
1140
    /* label1: fast path */
1141
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1142

    
1143
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1144
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1145
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1146
#else
1147
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1148
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1149
    } else {
1150
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1151
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1152
    }
1153

    
1154
#endif
1155

    
1156
    switch(opc) {
1157
    case 0:
1158
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1159
        break;
1160
    case 1:
1161
        if (TCG_NEED_BSWAP) {
1162
            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1163
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1164
        } else {
1165
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1166
        }
1167
        break;
1168
    case 2:
1169
        if (TCG_NEED_BSWAP) {
1170
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1171
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1172
        } else {
1173
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1174
        }
1175
        break;
1176
    case 3:
1177
        if (TCG_NEED_BSWAP) {
1178
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1179
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1180
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1181
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1182
        } else {
1183
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1184
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1185
        }
1186
        break;
1187
    default:
1188
        tcg_abort();
1189
    }
1190

    
1191
#if defined(CONFIG_SOFTMMU)
1192
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1193
#endif
1194
}
1195

    
1196
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1197
                              const TCGArg *args, const int *const_args)
1198
{
1199
    switch(opc) {
1200
    case INDEX_op_exit_tb:
1201
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1202
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1203
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1204
        tcg_out_nop(s);
1205
        break;
1206
    case INDEX_op_goto_tb:
1207
        if (s->tb_jmp_offset) {
1208
            /* direct jump method */
1209
            tcg_abort();
1210
        } else {
1211
            /* indirect jump method */
1212
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1213
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1214
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1215
        }
1216
        tcg_out_nop(s);
1217
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1218
        break;
1219
    case INDEX_op_call:
1220
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1221
        tcg_out_nop(s);
1222
        break;
1223
    case INDEX_op_jmp:
1224
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1225
        tcg_out_nop(s);
1226
        break;
1227
    case INDEX_op_br:
1228
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1229
        break;
1230

    
1231
    case INDEX_op_mov_i32:
1232
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1233
        break;
1234
    case INDEX_op_movi_i32:
1235
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1236
        break;
1237

    
1238
    case INDEX_op_ld8u_i32:
1239
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1240
        break;
1241
    case INDEX_op_ld8s_i32:
1242
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1243
        break;
1244
    case INDEX_op_ld16u_i32:
1245
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1246
        break;
1247
    case INDEX_op_ld16s_i32:
1248
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1249
        break;
1250
    case INDEX_op_ld_i32:
1251
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1252
        break;
1253
    case INDEX_op_st8_i32:
1254
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1255
        break;
1256
    case INDEX_op_st16_i32:
1257
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1258
        break;
1259
    case INDEX_op_st_i32:
1260
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1261
        break;
1262

    
1263
    case INDEX_op_add_i32:
1264
        if (const_args[2]) {
1265
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1266
        } else {
1267
            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1268
        }
1269
        break;
1270
    case INDEX_op_add2_i32:
1271
        if (const_args[4]) {
1272
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1273
        } else {
1274
            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1275
        }
1276
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1277
        if (const_args[5]) {
1278
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1279
        } else {
1280
             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1281
        }
1282
        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1283
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1284
        break;
1285
    case INDEX_op_sub_i32:
1286
        if (const_args[2]) {
1287
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1288
        } else {
1289
            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1290
        }
1291
        break;
1292
    case INDEX_op_sub2_i32:
1293
        if (const_args[4]) {
1294
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1295
        } else {
1296
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1297
        }
1298
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1299
        if (const_args[5]) {
1300
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1301
        } else {
1302
             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1303
        }
1304
        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1305
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1306
        break;
1307
    case INDEX_op_mul_i32:
1308
        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1309
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1310
        break;
1311
    case INDEX_op_mulu2_i32:
1312
        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1313
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1314
        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1315
        break;
1316
    case INDEX_op_div_i32:
1317
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1318
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1319
        break;
1320
    case INDEX_op_divu_i32:
1321
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1322
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1323
        break;
1324
    case INDEX_op_rem_i32:
1325
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1326
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1327
        break;
1328
    case INDEX_op_remu_i32:
1329
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1330
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1331
        break;
1332

    
1333
    case INDEX_op_and_i32:
1334
        if (const_args[2]) {
1335
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1336
        } else {
1337
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1338
        }
1339
        break;
1340
    case INDEX_op_or_i32:
1341
        if (const_args[2]) {
1342
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1343
        } else {
1344
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1345
        }
1346
        break;
1347
    case INDEX_op_nor_i32:
1348
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1349
        break;
1350
    case INDEX_op_not_i32:
1351
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1352
        break;
1353
    case INDEX_op_xor_i32:
1354
        if (const_args[2]) {
1355
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1356
        } else {
1357
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1358
        }
1359
        break;
1360

    
1361
    case INDEX_op_sar_i32:
1362
        if (const_args[2]) {
1363
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1364
        } else {
1365
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1366
        }
1367
        break;
1368
    case INDEX_op_shl_i32:
1369
        if (const_args[2]) {
1370
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1371
        } else {
1372
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1373
        }
1374
        break;
1375
    case INDEX_op_shr_i32:
1376
        if (const_args[2]) {
1377
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1378
        } else {
1379
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1380
        }
1381
        break;
1382

    
1383
    case INDEX_op_ext8s_i32:
1384
        tcg_out_ext8s(s, args[0], args[1]);
1385
        break;
1386
    case INDEX_op_ext16s_i32:
1387
        tcg_out_ext16s(s, args[0], args[1]);
1388
        break;
1389

    
1390
    case INDEX_op_brcond_i32:
1391
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1392
        break;
1393
    case INDEX_op_brcond2_i32:
1394
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1395
        break;
1396

    
1397
    case INDEX_op_setcond_i32:
1398
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1399
        break;
1400
    case INDEX_op_setcond2_i32:
1401
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1402
        break;
1403

    
1404
    case INDEX_op_qemu_ld8u:
1405
        tcg_out_qemu_ld(s, args, 0);
1406
        break;
1407
    case INDEX_op_qemu_ld8s:
1408
        tcg_out_qemu_ld(s, args, 0 | 4);
1409
        break;
1410
    case INDEX_op_qemu_ld16u:
1411
        tcg_out_qemu_ld(s, args, 1);
1412
        break;
1413
    case INDEX_op_qemu_ld16s:
1414
        tcg_out_qemu_ld(s, args, 1 | 4);
1415
        break;
1416
    case INDEX_op_qemu_ld32:
1417
        tcg_out_qemu_ld(s, args, 2);
1418
        break;
1419
    case INDEX_op_qemu_ld64:
1420
        tcg_out_qemu_ld(s, args, 3);
1421
        break;
1422
    case INDEX_op_qemu_st8:
1423
        tcg_out_qemu_st(s, args, 0);
1424
        break;
1425
    case INDEX_op_qemu_st16:
1426
        tcg_out_qemu_st(s, args, 1);
1427
        break;
1428
    case INDEX_op_qemu_st32:
1429
        tcg_out_qemu_st(s, args, 2);
1430
        break;
1431
    case INDEX_op_qemu_st64:
1432
        tcg_out_qemu_st(s, args, 3);
1433
        break;
1434

    
1435
    default:
1436
        tcg_abort();
1437
    }
1438
}
1439

    
1440
static const TCGTargetOpDef mips_op_defs[] = {
1441
    { INDEX_op_exit_tb, { } },
1442
    { INDEX_op_goto_tb, { } },
1443
    { INDEX_op_call, { "C" } },
1444
    { INDEX_op_jmp, { "r" } },
1445
    { INDEX_op_br, { } },
1446

    
1447
    { INDEX_op_mov_i32, { "r", "r" } },
1448
    { INDEX_op_movi_i32, { "r" } },
1449
    { INDEX_op_ld8u_i32, { "r", "r" } },
1450
    { INDEX_op_ld8s_i32, { "r", "r" } },
1451
    { INDEX_op_ld16u_i32, { "r", "r" } },
1452
    { INDEX_op_ld16s_i32, { "r", "r" } },
1453
    { INDEX_op_ld_i32, { "r", "r" } },
1454
    { INDEX_op_st8_i32, { "rZ", "r" } },
1455
    { INDEX_op_st16_i32, { "rZ", "r" } },
1456
    { INDEX_op_st_i32, { "rZ", "r" } },
1457

    
1458
    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1459
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1460
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1461
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1462
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1463
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1464
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1465
    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1466

    
1467
    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1468
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1469
    { INDEX_op_not_i32, { "r", "rZ" } },
1470
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1471
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1472

    
1473
    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1474
    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1475
    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1476

    
1477
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1478
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1479

    
1480
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1481
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1482
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1483

    
1484
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1485
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1486
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1487

    
1488
#if TARGET_LONG_BITS == 32
1489
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1490
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1491
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1492
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1493
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1494
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1495

    
1496
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1497
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1498
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1499
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1500
#else
1501
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1502
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1503
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1504
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1505
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1506
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1507

    
1508
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1509
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1510
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1511
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1512
#endif
1513
    { -1 },
1514
};
1515

    
1516
static int tcg_target_callee_save_regs[] = {
1517
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1518
    TCG_REG_S1,
1519
    TCG_REG_S2,
1520
    TCG_REG_S3,
1521
    TCG_REG_S4,
1522
    TCG_REG_S5,
1523
    TCG_REG_S6,
1524
    TCG_REG_S7,
1525
    TCG_REG_GP,
1526
    TCG_REG_FP,
1527
    TCG_REG_RA,       /* should be last for ABI compliance */
1528
};
1529

    
1530
/* Generate global QEMU prologue and epilogue code */
1531
static void tcg_target_qemu_prologue(TCGContext *s)
1532
{
1533
    int i, frame_size;
1534

    
1535
    /* reserve some stack space */
1536
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1537
                 + TCG_STATIC_CALL_ARGS_SIZE;
1538
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1539
                 ~(TCG_TARGET_STACK_ALIGN - 1);
1540

    
1541
    /* TB prologue */
1542
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1543
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1544
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1545
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1546
    }
1547

    
1548
    /* Call generated code */
1549
    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1550
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1551
    tb_ret_addr = s->code_ptr;
1552

    
1553
    /* TB epilogue */
1554
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1555
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1556
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1557
    }
1558

    
1559
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1560
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1561
}
1562

    
1563
static void tcg_target_init(TCGContext *s)
1564
{
1565
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1566
    tcg_regset_set(tcg_target_call_clobber_regs,
1567
                   (1 << TCG_REG_V0) |
1568
                   (1 << TCG_REG_V1) |
1569
                   (1 << TCG_REG_A0) |
1570
                   (1 << TCG_REG_A1) |
1571
                   (1 << TCG_REG_A2) |
1572
                   (1 << TCG_REG_A3) |
1573
                   (1 << TCG_REG_T1) |
1574
                   (1 << TCG_REG_T2) |
1575
                   (1 << TCG_REG_T3) |
1576
                   (1 << TCG_REG_T4) |
1577
                   (1 << TCG_REG_T5) |
1578
                   (1 << TCG_REG_T6) |
1579
                   (1 << TCG_REG_T7) |
1580
                   (1 << TCG_REG_T8) |
1581
                   (1 << TCG_REG_T9));
1582

    
1583
    tcg_regset_clear(s->reserved_regs);
1584
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1585
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1586
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1587
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1588
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1589
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1590
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1591

    
1592
    tcg_add_target_add_op_defs(mips_op_defs);
1593
    tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1594
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1595
}