~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to tcg/mips/tcg-target.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#endif
 
221
        break;
 
222
    case 'S': /* qemu_st constraint */
 
223
        ct->ct |= TCG_CT_REG;
 
224
        tcg_regset_set(ct->u.regs, 0xffffffff);
 
225
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
 
226
#if defined(CONFIG_SOFTMMU)
 
227
# if TARGET_LONG_BITS == 64
 
228
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
 
229
# endif
 
230
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
 
231
#endif
 
232
        break;
 
233
    case 'I':
 
234
        ct->ct |= TCG_CT_CONST_U16;
 
235
        break;
 
236
    case 'J':
 
237
        ct->ct |= TCG_CT_CONST_S16;
 
238
        break;
 
239
    case 'Z':
 
240
        /* We are cheating a bit here, using the fact that the register
 
241
           ZERO is also the register number 0. Hence there is no need
 
242
           to check for const_args in each instruction. */
 
243
        ct->ct |= TCG_CT_CONST_ZERO;
 
244
        break;
 
245
    default:
 
246
        return -1;
 
247
    }
 
248
    ct_str++;
 
249
    *pct_str = ct_str;
 
250
    return 0;
 
251
}
 
252
 
 
253
/* test if a constant matches the constraint */
 
254
static inline int tcg_target_const_match(tcg_target_long val,
 
255
                                         const TCGArgConstraint *arg_ct)
 
256
{
 
257
    int ct;
 
258
    ct = arg_ct->ct;
 
259
    if (ct & TCG_CT_CONST)
 
260
        return 1;
 
261
    else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
 
262
        return 1;
 
263
    else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
 
264
        return 1;
 
265
    else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
 
266
        return 1;
 
267
    else
 
268
        return 0;
 
269
}
 
270
 
 
271
/* instruction opcodes */
 
272
enum {
 
273
    OPC_BEQ      = 0x04 << 26,
 
274
    OPC_BNE      = 0x05 << 26,
 
275
    OPC_ADDIU    = 0x09 << 26,
 
276
    OPC_SLTI     = 0x0A << 26,
 
277
    OPC_SLTIU    = 0x0B << 26,
 
278
    OPC_ANDI     = 0x0C << 26,
 
279
    OPC_ORI      = 0x0D << 26,
 
280
    OPC_XORI     = 0x0E << 26,
 
281
    OPC_LUI      = 0x0F << 26,
 
282
    OPC_LB       = 0x20 << 26,
 
283
    OPC_LH       = 0x21 << 26,
 
284
    OPC_LW       = 0x23 << 26,
 
285
    OPC_LBU      = 0x24 << 26,
 
286
    OPC_LHU      = 0x25 << 26,
 
287
    OPC_LWU      = 0x27 << 26,
 
288
    OPC_SB       = 0x28 << 26,
 
289
    OPC_SH       = 0x29 << 26,
 
290
    OPC_SW       = 0x2B << 26,
 
291
 
 
292
    OPC_SPECIAL  = 0x00 << 26,
 
293
    OPC_SLL      = OPC_SPECIAL | 0x00,
 
294
    OPC_SRL      = OPC_SPECIAL | 0x02,
 
295
    OPC_SRA      = OPC_SPECIAL | 0x03,
 
296
    OPC_SLLV     = OPC_SPECIAL | 0x04,
 
297
    OPC_SRLV     = OPC_SPECIAL | 0x06,
 
298
    OPC_SRAV     = OPC_SPECIAL | 0x07,
 
299
    OPC_JR       = OPC_SPECIAL | 0x08,
 
300
    OPC_JALR     = OPC_SPECIAL | 0x09,
 
301
    OPC_MFHI     = OPC_SPECIAL | 0x10,
 
302
    OPC_MFLO     = OPC_SPECIAL | 0x12,
 
303
    OPC_MULT     = OPC_SPECIAL | 0x18,
 
304
    OPC_MULTU    = OPC_SPECIAL | 0x19,
 
305
    OPC_DIV      = OPC_SPECIAL | 0x1A,
 
306
    OPC_DIVU     = OPC_SPECIAL | 0x1B,
 
307
    OPC_ADDU     = OPC_SPECIAL | 0x21,
 
308
    OPC_SUBU     = OPC_SPECIAL | 0x23,
 
309
    OPC_AND      = OPC_SPECIAL | 0x24,
 
310
    OPC_OR       = OPC_SPECIAL | 0x25,
 
311
    OPC_XOR      = OPC_SPECIAL | 0x26,
 
312
    OPC_NOR      = OPC_SPECIAL | 0x27,
 
313
    OPC_SLT      = OPC_SPECIAL | 0x2A,
 
314
    OPC_SLTU     = OPC_SPECIAL | 0x2B,
 
315
 
 
316
    OPC_SPECIAL3 = 0x1f << 26,
 
317
    OPC_SEB      = OPC_SPECIAL3 | 0x420,
 
318
    OPC_SEH      = OPC_SPECIAL3 | 0x620,
 
319
};
 
320
 
 
321
/*
 
322
 * Type reg
 
323
 */
 
324
static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
 
325
{
 
326
    int32_t inst;
 
327
 
 
328
    inst = opc;
 
329
    inst |= (rs & 0x1F) << 21;
 
330
    inst |= (rt & 0x1F) << 16;
 
331
    inst |= (rd & 0x1F) << 11;
 
332
    tcg_out32(s, inst);
 
333
}
 
334
 
 
335
/*
 
336
 * Type immediate
 
337
 */
 
338
static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
 
339
{
 
340
    int32_t inst;
 
341
 
 
342
    inst = opc;
 
343
    inst |= (rs & 0x1F) << 21;
 
344
    inst |= (rt & 0x1F) << 16;
 
345
    inst |= (imm & 0xffff);
 
346
    tcg_out32(s, inst);
 
347
}
 
348
 
 
349
/*
 
350
 * Type branch
 
351
 */
 
352
static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
 
353
{
 
354
    /* We pay attention here to not modify the branch target by reading
 
355
       the existing value and using it again. This ensure that caches and
 
356
       memory are kept coherent during retranslation. */
 
357
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
 
358
 
 
359
    tcg_out_opc_imm(s, opc, rt, rs, offset);
 
360
}
 
361
 
 
362
/*
 
363
 * Type sa
 
364
 */
 
365
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
 
366
{
 
367
    int32_t inst;
 
368
 
 
369
    inst = opc;
 
370
    inst |= (rt & 0x1F) << 16;
 
371
    inst |= (rd & 0x1F) << 11;
 
372
    inst |= (sa & 0x1F) <<  6;
 
373
    tcg_out32(s, inst);
 
374
 
 
375
}
 
376
 
 
377
static inline void tcg_out_nop(TCGContext *s)
 
378
{
 
379
    tcg_out32(s, 0);
 
380
}
 
381
 
 
382
static inline void tcg_out_mov(TCGContext *s, TCGType type,
 
383
                               TCGReg ret, TCGReg arg)
 
384
{
 
385
    tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
 
386
}
 
387
 
 
388
static inline void tcg_out_movi(TCGContext *s, TCGType type,
 
389
                                TCGReg reg, tcg_target_long arg)
 
390
{
 
391
    if (arg == (int16_t)arg) {
 
392
        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
 
393
    } else if (arg == (uint16_t)arg) {
 
394
        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
 
395
    } else {
 
396
        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
 
397
        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
 
398
    }
 
399
}
 
400
 
 
401
static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
 
402
{
 
403
    /* ret and arg can't be register at */
 
404
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 
405
        tcg_abort();
 
406
    }
 
407
 
 
408
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 
409
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
 
410
 
 
411
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
 
412
    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
 
413
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
414
}
 
415
 
 
416
static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
 
417
{
 
418
    /* ret and arg can't be register at */
 
419
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
 
420
        tcg_abort();
 
421
    }
 
422
 
 
423
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 
424
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
 
425
 
 
426
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 
427
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 
428
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
429
}
 
430
 
 
431
static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
 
432
{
 
433
    /* ret and arg must be different and can't be register at */
 
434
    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
 
435
        tcg_abort();
 
436
    }
 
437
 
 
438
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 
439
 
 
440
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
 
441
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
442
 
 
443
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
 
444
    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
 
445
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
446
 
 
447
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
 
448
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
 
449
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
450
}
 
451
 
 
452
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
 
453
{
 
454
#ifdef _MIPS_ARCH_MIPS32R2
 
455
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 
456
#else
 
457
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 
458
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
 
459
#endif
 
460
}
 
461
 
 
462
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
 
463
{
 
464
#ifdef _MIPS_ARCH_MIPS32R2
 
465
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 
466
#else
 
467
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
 
468
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
 
469
#endif
 
470
}
 
471
 
 
472
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
 
473
                              int arg1, tcg_target_long arg2)
 
474
{
 
475
    if (arg2 == (int16_t) arg2) {
 
476
        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
 
477
    } else {
 
478
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
 
479
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
 
480
        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
 
481
    }
 
482
}
 
483
 
 
484
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 
485
                              TCGReg arg1, tcg_target_long arg2)
 
486
{
 
487
    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
 
488
}
 
489
 
 
490
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 
491
                              TCGReg arg1, tcg_target_long arg2)
 
492
{
 
493
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 
494
}
 
495
 
 
496
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
 
497
{
 
498
    if (val == (int16_t)val) {
 
499
        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
 
500
    } else {
 
501
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
 
502
        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
 
503
    }
 
504
}
 
505
 
 
506
static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
 
507
                           int arg2, int label_index)
 
508
{
 
509
    TCGLabel *l = &s->labels[label_index];
 
510
 
 
511
    switch (cond) {
 
512
    case TCG_COND_EQ:
 
513
        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
 
514
        break;
 
515
    case TCG_COND_NE:
 
516
        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
 
517
        break;
 
518
    case TCG_COND_LT:
 
519
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 
520
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 
521
        break;
 
522
    case TCG_COND_LTU:
 
523
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 
524
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 
525
        break;
 
526
    case TCG_COND_GE:
 
527
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
 
528
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 
529
        break;
 
530
    case TCG_COND_GEU:
 
531
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
 
532
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 
533
        break;
 
534
    case TCG_COND_LE:
 
535
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 
536
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 
537
        break;
 
538
    case TCG_COND_LEU:
 
539
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 
540
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
 
541
        break;
 
542
    case TCG_COND_GT:
 
543
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
 
544
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 
545
        break;
 
546
    case TCG_COND_GTU:
 
547
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
 
548
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
 
549
        break;
 
550
    default:
 
551
        tcg_abort();
 
552
        break;
 
553
    }
 
554
    if (l->has_value) {
 
555
        reloc_pc16(s->code_ptr - 4, l->u.value);
 
556
    } else {
 
557
        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
 
558
    }
 
559
    tcg_out_nop(s);
 
560
}
 
561
 
 
562
/* XXX: we implement it at the target level to avoid having to
 
563
   handle cross basic blocks temporaries */
 
564
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
 
565
                            int arg2, int arg3, int arg4, int label_index)
 
566
{
 
567
    void *label_ptr;
 
568
 
 
569
    switch(cond) {
 
570
    case TCG_COND_NE:
 
571
        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
 
572
        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
 
573
        return;
 
574
    case TCG_COND_EQ:
 
575
        break;
 
576
    case TCG_COND_LT:
 
577
    case TCG_COND_LE:
 
578
        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
 
579
        break;
 
580
    case TCG_COND_GT:
 
581
    case TCG_COND_GE:
 
582
        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
 
583
        break;
 
584
    case TCG_COND_LTU:
 
585
    case TCG_COND_LEU:
 
586
        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
 
587
        break;
 
588
    case TCG_COND_GTU:
 
589
    case TCG_COND_GEU:
 
590
        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
 
591
        break;
 
592
    default:
 
593
        tcg_abort();
 
594
    }
 
595
 
 
596
    label_ptr = s->code_ptr;
 
597
    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
 
598
    tcg_out_nop(s);
 
599
 
 
600
    switch(cond) {
 
601
    case TCG_COND_EQ:
 
602
        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
 
603
        break;
 
604
    case TCG_COND_LT:
 
605
    case TCG_COND_LTU:
 
606
        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
 
607
        break;
 
608
    case TCG_COND_LE:
 
609
    case TCG_COND_LEU:
 
610
        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
 
611
        break;
 
612
    case TCG_COND_GT:
 
613
    case TCG_COND_GTU:
 
614
        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
 
615
        break;
 
616
    case TCG_COND_GE:
 
617
    case TCG_COND_GEU:
 
618
        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
 
619
        break;
 
620
    default:
 
621
        tcg_abort();
 
622
    }
 
623
 
 
624
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
 
625
}
 
626
 
 
627
static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
 
628
                            int arg1, int arg2)
 
629
{
 
630
    switch (cond) {
 
631
    case TCG_COND_EQ:
 
632
        if (arg1 == 0) {
 
633
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
 
634
        } else if (arg2 == 0) {
 
635
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
 
636
        } else {
 
637
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 
638
            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
 
639
        }
 
640
        break;
 
641
    case TCG_COND_NE:
 
642
        if (arg1 == 0) {
 
643
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
 
644
        } else if (arg2 == 0) {
 
645
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
 
646
        } else {
 
647
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
 
648
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
 
649
        }
 
650
        break;
 
651
    case TCG_COND_LT:
 
652
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 
653
        break;
 
654
    case TCG_COND_LTU:
 
655
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 
656
        break;
 
657
    case TCG_COND_GE:
 
658
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
 
659
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 
660
        break;
 
661
    case TCG_COND_GEU:
 
662
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
 
663
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 
664
        break;
 
665
    case TCG_COND_LE:
 
666
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 
667
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 
668
        break;
 
669
    case TCG_COND_LEU:
 
670
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 
671
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
 
672
        break;
 
673
    case TCG_COND_GT:
 
674
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
 
675
        break;
 
676
    case TCG_COND_GTU:
 
677
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
 
678
        break;
 
679
    default:
 
680
        tcg_abort();
 
681
        break;
 
682
    }
 
683
}
 
684
 
 
685
/* XXX: we implement it at the target level to avoid having to
 
686
   handle cross basic blocks temporaries */
 
687
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
 
688
                             int arg1, int arg2, int arg3, int arg4)
 
689
{
 
690
    switch (cond) {
 
691
    case TCG_COND_EQ:
 
692
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
 
693
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
 
694
        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
 
695
        return;
 
696
    case TCG_COND_NE:
 
697
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
 
698
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
 
699
        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
 
700
        return;
 
701
    case TCG_COND_LT:
 
702
    case TCG_COND_LE:
 
703
        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
 
704
        break;
 
705
    case TCG_COND_GT:
 
706
    case TCG_COND_GE:
 
707
        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
 
708
        break;
 
709
    case TCG_COND_LTU:
 
710
    case TCG_COND_LEU:
 
711
        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
 
712
        break;
 
713
    case TCG_COND_GTU:
 
714
    case TCG_COND_GEU:
 
715
        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
 
716
        break;
 
717
    default:
 
718
        tcg_abort();
 
719
        break;
 
720
    }
 
721
 
 
722
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
 
723
 
 
724
    switch(cond) {
 
725
    case TCG_COND_LT:
 
726
    case TCG_COND_LTU:
 
727
        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
 
728
        break;
 
729
    case TCG_COND_LE:
 
730
    case TCG_COND_LEU:
 
731
        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
 
732
        break;
 
733
    case TCG_COND_GT:
 
734
    case TCG_COND_GTU:
 
735
        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
 
736
        break;
 
737
    case TCG_COND_GE:
 
738
    case TCG_COND_GEU:
 
739
        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
 
740
        break;
 
741
    default:
 
742
        tcg_abort();
 
743
    }
 
744
 
 
745
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
 
746
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
747
}
 
748
 
 
749
#if defined(CONFIG_SOFTMMU)
 
750
 
 
751
#include "../../softmmu_defs.h"
 
752
 
 
753
static void *qemu_ld_helpers[4] = {
 
754
    __ldb_mmu,
 
755
    __ldw_mmu,
 
756
    __ldl_mmu,
 
757
    __ldq_mmu,
 
758
};
 
759
 
 
760
static void *qemu_st_helpers[4] = {
 
761
    __stb_mmu,
 
762
    __stw_mmu,
 
763
    __stl_mmu,
 
764
    __stq_mmu,
 
765
};
 
766
#endif
 
767
 
 
768
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
 
769
                            int opc)
 
770
{
 
771
    int addr_regl, addr_reg1, addr_meml;
 
772
    int data_regl, data_regh, data_reg1, data_reg2;
 
773
    int mem_index, s_bits;
 
774
#if defined(CONFIG_SOFTMMU)
 
775
    void *label1_ptr, *label2_ptr;
 
776
    int sp_args;
 
777
#endif
 
778
#if TARGET_LONG_BITS == 64
 
779
# if defined(CONFIG_SOFTMMU)
 
780
    uint8_t *label3_ptr;
 
781
# endif
 
782
    int addr_regh, addr_reg2, addr_memh;
 
783
#endif
 
784
    data_regl = *args++;
 
785
    if (opc == 3)
 
786
        data_regh = *args++;
 
787
    else
 
788
        data_regh = 0;
 
789
    addr_regl = *args++;
 
790
#if TARGET_LONG_BITS == 64
 
791
    addr_regh = *args++;
 
792
#endif
 
793
    mem_index = *args;
 
794
    s_bits = opc & 3;
 
795
 
 
796
    if (opc == 3) {
 
797
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
 
798
        data_reg1 = data_regh;
 
799
        data_reg2 = data_regl;
 
800
#else
 
801
        data_reg1 = data_regl;
 
802
        data_reg2 = data_regh;
 
803
#endif
 
804
    } else {
 
805
        data_reg1 = data_regl;
 
806
        data_reg2 = 0;
 
807
    }
 
808
#if TARGET_LONG_BITS == 64
 
809
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
 
810
    addr_reg1 = addr_regh;
 
811
    addr_reg2 = addr_regl;
 
812
    addr_memh = 0;
 
813
    addr_meml = 4;
 
814
# else
 
815
    addr_reg1 = addr_regl;
 
816
    addr_reg2 = addr_regh;
 
817
    addr_memh = 4;
 
818
    addr_meml = 0;
 
819
# endif
 
820
#else
 
821
    addr_reg1 = addr_regl;
 
822
    addr_meml = 0;
 
823
#endif
 
824
 
 
825
#if defined(CONFIG_SOFTMMU)
 
826
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 
827
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
 
828
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
 
829
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 
830
                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);
 
831
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
 
832
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
 
833
 
 
834
# if TARGET_LONG_BITS == 64
 
835
    label3_ptr = s->code_ptr;
 
836
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
 
837
    tcg_out_nop(s);
 
838
 
 
839
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 
840
                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);
 
841
 
 
842
    label1_ptr = s->code_ptr;
 
843
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
 
844
    tcg_out_nop(s);
 
845
 
 
846
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
 
847
# else
 
848
    label1_ptr = s->code_ptr;
 
849
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
 
850
    tcg_out_nop(s);
 
851
# endif
 
852
 
 
853
    /* slow path */
 
854
    sp_args = TCG_REG_A0;
 
855
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
 
856
# if TARGET_LONG_BITS == 64
 
857
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
 
858
# endif
 
859
    tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
 
860
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
 
861
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
 
862
    tcg_out_nop(s);
 
863
 
 
864
    switch(opc) {
 
865
    case 0:
 
866
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
 
867
        break;
 
868
    case 0 | 4:
 
869
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
 
870
        break;
 
871
    case 1:
 
872
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
 
873
        break;
 
874
    case 1 | 4:
 
875
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
 
876
        break;
 
877
    case 2:
 
878
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
 
879
        break;
 
880
    case 3:
 
881
        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
 
882
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
 
883
        break;
 
884
    default:
 
885
        tcg_abort();
 
886
    }
 
887
 
 
888
    label2_ptr = s->code_ptr;
 
889
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
 
890
    tcg_out_nop(s);
 
891
 
 
892
    /* label1: fast path */
 
893
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
 
894
 
 
895
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
 
896
                    offsetof(CPUState, tlb_table[mem_index][0].addend));
 
897
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
 
898
#else
 
899
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
 
900
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
 
901
    } else {
 
902
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
 
903
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
 
904
    }
 
905
#endif
 
906
 
 
907
    switch(opc) {
 
908
    case 0:
 
909
        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
 
910
        break;
 
911
    case 0 | 4:
 
912
        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
 
913
        break;
 
914
    case 1:
 
915
        if (TCG_NEED_BSWAP) {
 
916
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
 
917
            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
 
918
        } else {
 
919
            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
 
920
        }
 
921
        break;
 
922
    case 1 | 4:
 
923
        if (TCG_NEED_BSWAP) {
 
924
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
 
925
            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
 
926
        } else {
 
927
            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
 
928
        }
 
929
        break;
 
930
    case 2:
 
931
        if (TCG_NEED_BSWAP) {
 
932
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
 
933
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
 
934
        } else {
 
935
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
 
936
        }
 
937
        break;
 
938
    case 3:
 
939
        if (TCG_NEED_BSWAP) {
 
940
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
 
941
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
 
942
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
 
943
            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
 
944
        } else {
 
945
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
 
946
            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
 
947
        }
 
948
        break;
 
949
    default:
 
950
        tcg_abort();
 
951
    }
 
952
 
 
953
#if defined(CONFIG_SOFTMMU)
 
954
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
 
955
#endif
 
956
}
 
957
 
 
958
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
 
959
                            int opc)
 
960
{
 
961
    int addr_regl, addr_reg1, addr_meml;
 
962
    int data_regl, data_regh, data_reg1, data_reg2;
 
963
    int mem_index, s_bits;
 
964
#if defined(CONFIG_SOFTMMU)
 
965
    uint8_t *label1_ptr, *label2_ptr;
 
966
    int sp_args;
 
967
#endif
 
968
#if TARGET_LONG_BITS == 64
 
969
# if defined(CONFIG_SOFTMMU)
 
970
    uint8_t *label3_ptr;
 
971
# endif
 
972
    int addr_regh, addr_reg2, addr_memh;
 
973
#endif
 
974
 
 
975
    data_regl = *args++;
 
976
    if (opc == 3) {
 
977
        data_regh = *args++;
 
978
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
 
979
        data_reg1 = data_regh;
 
980
        data_reg2 = data_regl;
 
981
#else
 
982
        data_reg1 = data_regl;
 
983
        data_reg2 = data_regh;
 
984
#endif
 
985
    } else {
 
986
        data_reg1 = data_regl;
 
987
        data_reg2 = 0;
 
988
        data_regh = 0;
 
989
    }
 
990
    addr_regl = *args++;
 
991
#if TARGET_LONG_BITS == 64
 
992
    addr_regh = *args++;
 
993
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
 
994
    addr_reg1 = addr_regh;
 
995
    addr_reg2 = addr_regl;
 
996
    addr_memh = 0;
 
997
    addr_meml = 4;
 
998
# else
 
999
    addr_reg1 = addr_regl;
 
1000
    addr_reg2 = addr_regh;
 
1001
    addr_memh = 4;
 
1002
    addr_meml = 0;
 
1003
# endif
 
1004
#else
 
1005
    addr_reg1 = addr_regl;
 
1006
    addr_meml = 0;
 
1007
#endif
 
1008
    mem_index = *args;
 
1009
    s_bits = opc;
 
1010
 
 
1011
#if defined(CONFIG_SOFTMMU)
 
1012
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 
1013
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
 
1014
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
 
1015
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 
1016
                    offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_meml);
 
1017
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
 
1018
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
 
1019
 
 
1020
# if TARGET_LONG_BITS == 64
 
1021
    label3_ptr = s->code_ptr;
 
1022
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
 
1023
    tcg_out_nop(s);
 
1024
 
 
1025
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
 
1026
                    offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_memh);
 
1027
 
 
1028
    label1_ptr = s->code_ptr;
 
1029
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
 
1030
    tcg_out_nop(s);
 
1031
 
 
1032
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
 
1033
# else
 
1034
    label1_ptr = s->code_ptr;
 
1035
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
 
1036
    tcg_out_nop(s);
 
1037
# endif
 
1038
 
 
1039
    /* slow path */
 
1040
    sp_args = TCG_REG_A0;
 
1041
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
 
1042
# if TARGET_LONG_BITS == 64
 
1043
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
 
1044
# endif
 
1045
    switch(opc) {
 
1046
    case 0:
 
1047
        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
 
1048
        break;
 
1049
    case 1:
 
1050
        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
 
1051
        break;
 
1052
    case 2:
 
1053
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
 
1054
        break;
 
1055
    case 3:
 
1056
        sp_args = (sp_args + 1) & ~1;
 
1057
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
 
1058
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
 
1059
        break;
 
1060
    default:
 
1061
        tcg_abort();
 
1062
    }
 
1063
    if (sp_args > TCG_REG_A3) {
 
1064
        /* Push mem_index on the stack */
 
1065
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
 
1066
        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
 
1067
    } else {
 
1068
        tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
 
1069
    }
 
1070
 
 
1071
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
 
1072
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
 
1073
    tcg_out_nop(s);
 
1074
 
 
1075
    label2_ptr = s->code_ptr;
 
1076
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
 
1077
    tcg_out_nop(s);
 
1078
 
 
1079
    /* label1: fast path */
 
1080
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
 
1081
 
 
1082
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
 
1083
                    offsetof(CPUState, tlb_table[mem_index][0].addend));
 
1084
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
 
1085
#else
 
1086
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
 
1087
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
 
1088
    } else {
 
1089
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
 
1090
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
 
1091
    }
 
1092
 
 
1093
#endif
 
1094
 
 
1095
    switch(opc) {
 
1096
    case 0:
 
1097
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
 
1098
        break;
 
1099
    case 1:
 
1100
        if (TCG_NEED_BSWAP) {
 
1101
            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
 
1102
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
 
1103
        } else {
 
1104
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
 
1105
        }
 
1106
        break;
 
1107
    case 2:
 
1108
        if (TCG_NEED_BSWAP) {
 
1109
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
 
1110
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
 
1111
        } else {
 
1112
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
 
1113
        }
 
1114
        break;
 
1115
    case 3:
 
1116
        if (TCG_NEED_BSWAP) {
 
1117
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
 
1118
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
 
1119
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
 
1120
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
 
1121
        } else {
 
1122
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
 
1123
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
 
1124
        }
 
1125
        break;
 
1126
    default:
 
1127
        tcg_abort();
 
1128
    }
 
1129
 
 
1130
#if defined(CONFIG_SOFTMMU)
 
1131
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
 
1132
#endif
 
1133
}
 
1134
 
 
1135
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
1136
                              const TCGArg *args, const int *const_args)
 
1137
{
 
1138
    switch(opc) {
 
1139
    case INDEX_op_exit_tb:
 
1140
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
 
1141
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
 
1142
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
 
1143
        tcg_out_nop(s);
 
1144
        break;
 
1145
    case INDEX_op_goto_tb:
 
1146
        if (s->tb_jmp_offset) {
 
1147
            /* direct jump method */
 
1148
            tcg_abort();
 
1149
        } else {
 
1150
            /* indirect jump method */
 
1151
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
 
1152
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
 
1153
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
 
1154
        }
 
1155
        tcg_out_nop(s);
 
1156
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
 
1157
        break;
 
1158
    case INDEX_op_call:
 
1159
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
 
1160
        tcg_out_nop(s);
 
1161
        break;
 
1162
    case INDEX_op_jmp:
 
1163
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
 
1164
        tcg_out_nop(s);
 
1165
        break;
 
1166
    case INDEX_op_br:
 
1167
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
 
1168
        break;
 
1169
 
 
1170
    case INDEX_op_mov_i32:
 
1171
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
 
1172
        break;
 
1173
    case INDEX_op_movi_i32:
 
1174
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
 
1175
        break;
 
1176
 
 
1177
    case INDEX_op_ld8u_i32:
 
1178
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
 
1179
        break;
 
1180
    case INDEX_op_ld8s_i32:
 
1181
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
 
1182
        break;
 
1183
    case INDEX_op_ld16u_i32:
 
1184
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
 
1185
        break;
 
1186
    case INDEX_op_ld16s_i32:
 
1187
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
 
1188
        break;
 
1189
    case INDEX_op_ld_i32:
 
1190
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
 
1191
        break;
 
1192
    case INDEX_op_st8_i32:
 
1193
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
 
1194
        break;
 
1195
    case INDEX_op_st16_i32:
 
1196
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
 
1197
        break;
 
1198
    case INDEX_op_st_i32:
 
1199
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
 
1200
        break;
 
1201
 
 
1202
    case INDEX_op_add_i32:
 
1203
        if (const_args[2]) {
 
1204
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
 
1205
        } else {
 
1206
            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
 
1207
        }
 
1208
        break;
 
1209
    case INDEX_op_add2_i32:
 
1210
        if (const_args[4]) {
 
1211
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
 
1212
        } else {
 
1213
            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
 
1214
        }
 
1215
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
 
1216
        if (const_args[5]) {
 
1217
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
 
1218
        } else {
 
1219
             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
 
1220
        }
 
1221
        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
 
1222
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
 
1223
        break;
 
1224
    case INDEX_op_sub_i32:
 
1225
        if (const_args[2]) {
 
1226
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
 
1227
        } else {
 
1228
            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
 
1229
        }
 
1230
        break;
 
1231
    case INDEX_op_sub2_i32:
 
1232
        if (const_args[4]) {
 
1233
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
 
1234
        } else {
 
1235
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
 
1236
        }
 
1237
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
 
1238
        if (const_args[5]) {
 
1239
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
 
1240
        } else {
 
1241
             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
 
1242
        }
 
1243
        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
 
1244
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
 
1245
        break;
 
1246
    case INDEX_op_mul_i32:
 
1247
        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
 
1248
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
 
1249
        break;
 
1250
    case INDEX_op_mulu2_i32:
 
1251
        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
 
1252
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
 
1253
        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
 
1254
        break;
 
1255
    case INDEX_op_div_i32:
 
1256
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
 
1257
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
 
1258
        break;
 
1259
    case INDEX_op_divu_i32:
 
1260
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
 
1261
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
 
1262
        break;
 
1263
    case INDEX_op_rem_i32:
 
1264
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
 
1265
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
 
1266
        break;
 
1267
    case INDEX_op_remu_i32:
 
1268
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
 
1269
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
 
1270
        break;
 
1271
 
 
1272
    case INDEX_op_and_i32:
 
1273
        if (const_args[2]) {
 
1274
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
 
1275
        } else {
 
1276
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
 
1277
        }
 
1278
        break;
 
1279
    case INDEX_op_or_i32:
 
1280
        if (const_args[2]) {
 
1281
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
 
1282
        } else {
 
1283
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
 
1284
        }
 
1285
        break;
 
1286
    case INDEX_op_nor_i32:
 
1287
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
 
1288
        break;
 
1289
    case INDEX_op_not_i32:
 
1290
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
 
1291
        break;
 
1292
    case INDEX_op_xor_i32:
 
1293
        if (const_args[2]) {
 
1294
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
 
1295
        } else {
 
1296
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
 
1297
        }
 
1298
        break;
 
1299
 
 
1300
    case INDEX_op_sar_i32:
 
1301
        if (const_args[2]) {
 
1302
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
 
1303
        } else {
 
1304
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
 
1305
        }
 
1306
        break;
 
1307
    case INDEX_op_shl_i32:
 
1308
        if (const_args[2]) {
 
1309
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
 
1310
        } else {
 
1311
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
 
1312
        }
 
1313
        break;
 
1314
    case INDEX_op_shr_i32:
 
1315
        if (const_args[2]) {
 
1316
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
 
1317
        } else {
 
1318
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
 
1319
        }
 
1320
        break;
 
1321
 
 
1322
    case INDEX_op_ext8s_i32:
 
1323
        tcg_out_ext8s(s, args[0], args[1]);
 
1324
        break;
 
1325
    case INDEX_op_ext16s_i32:
 
1326
        tcg_out_ext16s(s, args[0], args[1]);
 
1327
        break;
 
1328
 
 
1329
    case INDEX_op_brcond_i32:
 
1330
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
 
1331
        break;
 
1332
    case INDEX_op_brcond2_i32:
 
1333
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
 
1334
        break;
 
1335
 
 
1336
    case INDEX_op_setcond_i32:
 
1337
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
 
1338
        break;
 
1339
    case INDEX_op_setcond2_i32:
 
1340
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
 
1341
        break;
 
1342
 
 
1343
    case INDEX_op_qemu_ld8u:
 
1344
        tcg_out_qemu_ld(s, args, 0);
 
1345
        break;
 
1346
    case INDEX_op_qemu_ld8s:
 
1347
        tcg_out_qemu_ld(s, args, 0 | 4);
 
1348
        break;
 
1349
    case INDEX_op_qemu_ld16u:
 
1350
        tcg_out_qemu_ld(s, args, 1);
 
1351
        break;
 
1352
    case INDEX_op_qemu_ld16s:
 
1353
        tcg_out_qemu_ld(s, args, 1 | 4);
 
1354
        break;
 
1355
    case INDEX_op_qemu_ld32:
 
1356
        tcg_out_qemu_ld(s, args, 2);
 
1357
        break;
 
1358
    case INDEX_op_qemu_ld64:
 
1359
        tcg_out_qemu_ld(s, args, 3);
 
1360
        break;
 
1361
    case INDEX_op_qemu_st8:
 
1362
        tcg_out_qemu_st(s, args, 0);
 
1363
        break;
 
1364
    case INDEX_op_qemu_st16:
 
1365
        tcg_out_qemu_st(s, args, 1);
 
1366
        break;
 
1367
    case INDEX_op_qemu_st32:
 
1368
        tcg_out_qemu_st(s, args, 2);
 
1369
        break;
 
1370
    case INDEX_op_qemu_st64:
 
1371
        tcg_out_qemu_st(s, args, 3);
 
1372
        break;
 
1373
 
 
1374
    default:
 
1375
        tcg_abort();
 
1376
    }
 
1377
}
 
1378
 
 
1379
static const TCGTargetOpDef mips_op_defs[] = {
 
1380
    { INDEX_op_exit_tb, { } },
 
1381
    { INDEX_op_goto_tb, { } },
 
1382
    { INDEX_op_call, { "C" } },
 
1383
    { INDEX_op_jmp, { "r" } },
 
1384
    { INDEX_op_br, { } },
 
1385
 
 
1386
    { INDEX_op_mov_i32, { "r", "r" } },
 
1387
    { INDEX_op_movi_i32, { "r" } },
 
1388
    { INDEX_op_ld8u_i32, { "r", "r" } },
 
1389
    { INDEX_op_ld8s_i32, { "r", "r" } },
 
1390
    { INDEX_op_ld16u_i32, { "r", "r" } },
 
1391
    { INDEX_op_ld16s_i32, { "r", "r" } },
 
1392
    { INDEX_op_ld_i32, { "r", "r" } },
 
1393
    { INDEX_op_st8_i32, { "rZ", "r" } },
 
1394
    { INDEX_op_st16_i32, { "rZ", "r" } },
 
1395
    { INDEX_op_st_i32, { "rZ", "r" } },
 
1396
 
 
1397
    { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
 
1398
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
 
1399
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
 
1400
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
 
1401
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
 
1402
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
 
1403
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
 
1404
    { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
 
1405
 
 
1406
    { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
 
1407
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
 
1408
    { INDEX_op_not_i32, { "r", "rZ" } },
 
1409
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
 
1410
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
 
1411
 
 
1412
    { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
 
1413
    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
 
1414
    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
 
1415
 
 
1416
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
 
1417
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
 
1418
 
 
1419
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
 
1420
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
 
1421
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
 
1422
 
 
1423
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
 
1424
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
 
1425
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
 
1426
 
 
1427
#if TARGET_LONG_BITS == 32
 
1428
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
 
1429
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
 
1430
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
 
1431
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
 
1432
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
 
1433
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
 
1434
 
 
1435
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
 
1436
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
 
1437
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
 
1438
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
 
1439
#else
 
1440
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
 
1441
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
 
1442
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
 
1443
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
 
1444
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
 
1445
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
 
1446
 
 
1447
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
 
1448
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
 
1449
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
 
1450
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
 
1451
#endif
 
1452
    { -1 },
 
1453
};
 
1454
 
 
1455
static int tcg_target_callee_save_regs[] = {
 
1456
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
 
1457
    TCG_REG_S1,
 
1458
    TCG_REG_S2,
 
1459
    TCG_REG_S3,
 
1460
    TCG_REG_S4,
 
1461
    TCG_REG_S5,
 
1462
    TCG_REG_S6,
 
1463
    TCG_REG_S7,
 
1464
    TCG_REG_GP,
 
1465
    TCG_REG_FP,
 
1466
    TCG_REG_RA,       /* should be last for ABI compliance */
 
1467
};
 
1468
 
 
1469
/* Generate global QEMU prologue and epilogue code */
 
1470
static void tcg_target_qemu_prologue(TCGContext *s)
 
1471
{
 
1472
    int i, frame_size;
 
1473
 
 
1474
    /* reserve some stack space */
 
1475
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
 
1476
                 + TCG_STATIC_CALL_ARGS_SIZE;
 
1477
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
 
1478
                 ~(TCG_TARGET_STACK_ALIGN - 1);
 
1479
 
 
1480
    /* TB prologue */
 
1481
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
 
1482
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
 
1483
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
 
1484
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
 
1485
    }
 
1486
 
 
1487
    /* Call generated code */
 
1488
    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
 
1489
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
 
1490
    tb_ret_addr = s->code_ptr;
 
1491
 
 
1492
    /* TB epilogue */
 
1493
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
 
1494
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
 
1495
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
 
1496
    }
 
1497
 
 
1498
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
 
1499
    tcg_out_addi(s, TCG_REG_SP, frame_size);
 
1500
}
 
1501
 
 
1502
static void tcg_target_init(TCGContext *s)
 
1503
{
 
1504
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
 
1505
    tcg_regset_set(tcg_target_call_clobber_regs,
 
1506
                   (1 << TCG_REG_V0) |
 
1507
                   (1 << TCG_REG_V1) |
 
1508
                   (1 << TCG_REG_A0) |
 
1509
                   (1 << TCG_REG_A1) |
 
1510
                   (1 << TCG_REG_A2) |
 
1511
                   (1 << TCG_REG_A3) |
 
1512
                   (1 << TCG_REG_T1) |
 
1513
                   (1 << TCG_REG_T2) |
 
1514
                   (1 << TCG_REG_T3) |
 
1515
                   (1 << TCG_REG_T4) |
 
1516
                   (1 << TCG_REG_T5) |
 
1517
                   (1 << TCG_REG_T6) |
 
1518
                   (1 << TCG_REG_T7) |
 
1519
                   (1 << TCG_REG_T8) |
 
1520
                   (1 << TCG_REG_T9));
 
1521
 
 
1522
    tcg_regset_clear(s->reserved_regs);
 
1523
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
 
1524
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
 
1525
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
 
1526
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
 
1527
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
 
1528
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
 
1529
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
 
1530
 
 
1531
    tcg_add_target_add_op_defs(mips_op_defs);
 
1532
    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
 
1533
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 
1534
}