Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ 2ceb3a9e

History | View | Annotate | Download (48.4 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, addr_meml;
846
    int data_regl, data_regh, data_reg1, data_reg2;
847
    int mem_index, s_bits;
848
#if defined(CONFIG_SOFTMMU)
849
    void *label1_ptr, *label2_ptr;
850
    int arg_num;
851
#endif
852
#if TARGET_LONG_BITS == 64
853
# if defined(CONFIG_SOFTMMU)
854
    uint8_t *label3_ptr;
855
# endif
856
    int addr_regh, addr_memh;
857
#endif
858
    data_regl = *args++;
859
    if (opc == 3)
860
        data_regh = *args++;
861
    else
862
        data_regh = 0;
863
    addr_regl = *args++;
864
#if TARGET_LONG_BITS == 64
865
    addr_regh = *args++;
866
#endif
867
    mem_index = *args;
868
    s_bits = opc & 3;
869

    
870
    if (opc == 3) {
871
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
872
        data_reg1 = data_regh;
873
        data_reg2 = data_regl;
874
#else
875
        data_reg1 = data_regl;
876
        data_reg2 = data_regh;
877
#endif
878
    } else {
879
        data_reg1 = data_regl;
880
        data_reg2 = 0;
881
    }
882
#if TARGET_LONG_BITS == 64
883
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
884
    addr_memh = 0;
885
    addr_meml = 4;
886
# else
887
    addr_memh = 4;
888
    addr_meml = 0;
889
# endif
890
#else
891
    addr_meml = 0;
892
#endif
893

    
894
#if defined(CONFIG_SOFTMMU)
895
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
896
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
897
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
898
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
899
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
900
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
901
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
902

    
903
# if TARGET_LONG_BITS == 64
904
    label3_ptr = s->code_ptr;
905
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
906
    tcg_out_nop(s);
907

    
908
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
909
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
910

    
911
    label1_ptr = s->code_ptr;
912
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
913
    tcg_out_nop(s);
914

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

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

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

    
959
    label2_ptr = s->code_ptr;
960
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
961
    tcg_out_nop(s);
962

    
963
    /* label1: fast path */
964
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
965

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

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

    
1024
#if defined(CONFIG_SOFTMMU)
1025
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1026
#endif
1027
}
1028

    
1029
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1030
                            int opc)
1031
{
1032
    int addr_regl, addr_meml;
1033
    int data_regl, data_regh, data_reg1, data_reg2;
1034
    int mem_index, s_bits;
1035
#if defined(CONFIG_SOFTMMU)
1036
    uint8_t *label1_ptr, *label2_ptr;
1037
    int arg_num;
1038
#endif
1039
#if TARGET_LONG_BITS == 64
1040
# if defined(CONFIG_SOFTMMU)
1041
    uint8_t *label3_ptr;
1042
# endif
1043
    int addr_regh, addr_memh;
1044
#endif
1045

    
1046
    data_regl = *args++;
1047
    if (opc == 3) {
1048
        data_regh = *args++;
1049
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1050
        data_reg1 = data_regh;
1051
        data_reg2 = data_regl;
1052
#else
1053
        data_reg1 = data_regl;
1054
        data_reg2 = data_regh;
1055
#endif
1056
    } else {
1057
        data_reg1 = data_regl;
1058
        data_reg2 = 0;
1059
        data_regh = 0;
1060
    }
1061
    addr_regl = *args++;
1062
#if TARGET_LONG_BITS == 64
1063
    addr_regh = *args++;
1064
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
1065
    addr_memh = 0;
1066
    addr_meml = 4;
1067
# else
1068
    addr_memh = 4;
1069
    addr_meml = 0;
1070
# endif
1071
#else
1072
    addr_meml = 0;
1073
#endif
1074
    mem_index = *args;
1075
    s_bits = opc;
1076

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

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

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

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

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

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

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

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

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

    
1152
#endif
1153

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

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

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

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

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

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

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

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

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

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

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

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

    
1433
    default:
1434
        tcg_abort();
1435
    }
1436
}
1437

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

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

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

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

    
1471
    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1472
    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1473
    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1474

    
1475
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1476
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1477

    
1478
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1479
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1480
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1481

    
1482
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1483
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1484
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1485

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

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

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

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

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

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

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

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

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

    
1557
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1558
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1559
}
1560

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

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

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