Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ 7d7c4930

History | View | Annotate | Download (53.7 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 TCGReg tcg_target_reg_alloc_order[] = {
72
    TCG_REG_S0,
73
    TCG_REG_S1,
74
    TCG_REG_S2,
75
    TCG_REG_S3,
76
    TCG_REG_S4,
77
    TCG_REG_S5,
78
    TCG_REG_S6,
79
    TCG_REG_S7,
80
    TCG_REG_T1,
81
    TCG_REG_T2,
82
    TCG_REG_T3,
83
    TCG_REG_T4,
84
    TCG_REG_T5,
85
    TCG_REG_T6,
86
    TCG_REG_T7,
87
    TCG_REG_T8,
88
    TCG_REG_T9,
89
    TCG_REG_A0,
90
    TCG_REG_A1,
91
    TCG_REG_A2,
92
    TCG_REG_A3,
93
    TCG_REG_V0,
94
    TCG_REG_V1
95
};
96

    
97
static const TCGReg tcg_target_call_iarg_regs[4] = {
98
    TCG_REG_A0,
99
    TCG_REG_A1,
100
    TCG_REG_A2,
101
    TCG_REG_A3
102
};
103

    
104
static const TCGReg tcg_target_call_oarg_regs[2] = {
105
    TCG_REG_V0,
106
    TCG_REG_V1
107
};
108

    
109
static uint8_t *tb_ret_addr;
110

    
111
static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
112
{
113
    return target & 0xffff;
114
}
115

    
116
static inline void reloc_lo16 (void *pc, tcg_target_long target)
117
{
118
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
119
                       | reloc_lo16_val(pc, target);
120
}
121

    
122
static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
123
{
124
    return (target >> 16) & 0xffff;
125
}
126

    
127
static inline void reloc_hi16 (void *pc, tcg_target_long target)
128
{
129
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
130
                       | reloc_hi16_val(pc, target);
131
}
132

    
133
static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
134
{
135
    int32_t disp;
136

    
137
    disp = target - (tcg_target_long) pc - 4;
138
    if (disp != (disp << 14) >> 14) {
139
        tcg_abort ();
140
    }
141

    
142
    return (disp >> 2) & 0xffff;
143
}
144

    
145
static inline void reloc_pc16 (void *pc, tcg_target_long target)
146
{
147
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
148
                       | reloc_pc16_val(pc, target);
149
}
150

    
151
static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
152
{
153
    if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
154
        tcg_abort ();
155
    }
156

    
157
    return (target >> 2) & 0x3ffffff;
158
}
159

    
160
static inline void reloc_pc26 (void *pc, tcg_target_long target)
161
{
162
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
163
                       | reloc_26_val(pc, target);
164
}
165

    
166
static void patch_reloc(uint8_t *code_ptr, int type,
167
                        tcg_target_long value, tcg_target_long addend)
168
{
169
    value += addend;
170
    switch(type) {
171
    case R_MIPS_LO16:
172
        reloc_lo16(code_ptr, value);
173
        break;
174
    case R_MIPS_HI16:
175
        reloc_hi16(code_ptr, value);
176
        break;
177
    case R_MIPS_PC16:
178
        reloc_pc16(code_ptr, value);
179
        break;
180
    case R_MIPS_26:
181
        reloc_pc26(code_ptr, value);
182
        break;
183
    default:
184
        tcg_abort();
185
    }
186
}
187

    
188
/* maximum number of register used for input function arguments */
189
static inline int tcg_target_get_call_iarg_regs_count(int flags)
190
{
191
    return 4;
192
}
193

    
194
/* parse target specific constraints */
195
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
196
{
197
    const char *ct_str;
198

    
199
    ct_str = *pct_str;
200
    switch(ct_str[0]) {
201
    case 'r':
202
        ct->ct |= TCG_CT_REG;
203
        tcg_regset_set(ct->u.regs, 0xffffffff);
204
        break;
205
    case 'C':
206
        ct->ct |= TCG_CT_REG;
207
        tcg_regset_clear(ct->u.regs);
208
        tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
209
        break;
210
    case 'L': /* qemu_ld output arg constraint */
211
        ct->ct |= TCG_CT_REG;
212
        tcg_regset_set(ct->u.regs, 0xffffffff);
213
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
214
        break;
215
    case 'l': /* qemu_ld input arg constraint */
216
        ct->ct |= TCG_CT_REG;
217
        tcg_regset_set(ct->u.regs, 0xffffffff);
218
#if defined(CONFIG_SOFTMMU)
219
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
220
# if (TARGET_LONG_BITS == 64)
221
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
222
# endif
223
#endif
224
        break;
225
    case 'S': /* qemu_st constraint */
226
        ct->ct |= TCG_CT_REG;
227
        tcg_regset_set(ct->u.regs, 0xffffffff);
228
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
229
#if defined(CONFIG_SOFTMMU)
230
# if (TARGET_LONG_BITS == 32)
231
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
232
# endif
233
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
234
# if TARGET_LONG_BITS == 64
235
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
236
# endif
237
#endif
238
        break;
239
    case 'I':
240
        ct->ct |= TCG_CT_CONST_U16;
241
        break;
242
    case 'J':
243
        ct->ct |= TCG_CT_CONST_S16;
244
        break;
245
    case 'Z':
246
        /* We are cheating a bit here, using the fact that the register
247
           ZERO is also the register number 0. Hence there is no need
248
           to check for const_args in each instruction. */
249
        ct->ct |= TCG_CT_CONST_ZERO;
250
        break;
251
    default:
252
        return -1;
253
    }
254
    ct_str++;
255
    *pct_str = ct_str;
256
    return 0;
257
}
258

    
259
/* test if a constant matches the constraint */
260
static inline int tcg_target_const_match(tcg_target_long val,
261
                                         const TCGArgConstraint *arg_ct)
262
{
263
    int ct;
264
    ct = arg_ct->ct;
265
    if (ct & TCG_CT_CONST)
266
        return 1;
267
    else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
268
        return 1;
269
    else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
270
        return 1;
271
    else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
272
        return 1;
273
    else
274
        return 0;
275
}
276

    
277
/* instruction opcodes */
278
enum {
279
    OPC_BEQ      = 0x04 << 26,
280
    OPC_BNE      = 0x05 << 26,
281
    OPC_BLEZ     = 0x06 << 26,
282
    OPC_BGTZ     = 0x07 << 26,
283
    OPC_ADDIU    = 0x09 << 26,
284
    OPC_SLTI     = 0x0A << 26,
285
    OPC_SLTIU    = 0x0B << 26,
286
    OPC_ANDI     = 0x0C << 26,
287
    OPC_ORI      = 0x0D << 26,
288
    OPC_XORI     = 0x0E << 26,
289
    OPC_LUI      = 0x0F << 26,
290
    OPC_LB       = 0x20 << 26,
291
    OPC_LH       = 0x21 << 26,
292
    OPC_LW       = 0x23 << 26,
293
    OPC_LBU      = 0x24 << 26,
294
    OPC_LHU      = 0x25 << 26,
295
    OPC_LWU      = 0x27 << 26,
296
    OPC_SB       = 0x28 << 26,
297
    OPC_SH       = 0x29 << 26,
298
    OPC_SW       = 0x2B << 26,
299

    
300
    OPC_SPECIAL  = 0x00 << 26,
301
    OPC_SLL      = OPC_SPECIAL | 0x00,
302
    OPC_SRL      = OPC_SPECIAL | 0x02,
303
    OPC_ROTR     = OPC_SPECIAL | (0x01 << 21) | 0x02,
304
    OPC_SRA      = OPC_SPECIAL | 0x03,
305
    OPC_SLLV     = OPC_SPECIAL | 0x04,
306
    OPC_SRLV     = OPC_SPECIAL | 0x06,
307
    OPC_ROTRV    = OPC_SPECIAL | (0x01 <<  6) | 0x06,
308
    OPC_SRAV     = OPC_SPECIAL | 0x07,
309
    OPC_JR       = OPC_SPECIAL | 0x08,
310
    OPC_JALR     = OPC_SPECIAL | 0x09,
311
    OPC_MOVZ     = OPC_SPECIAL | 0x0A,
312
    OPC_MOVN     = OPC_SPECIAL | 0x0B,
313
    OPC_MFHI     = OPC_SPECIAL | 0x10,
314
    OPC_MFLO     = OPC_SPECIAL | 0x12,
315
    OPC_MULT     = OPC_SPECIAL | 0x18,
316
    OPC_MULTU    = OPC_SPECIAL | 0x19,
317
    OPC_DIV      = OPC_SPECIAL | 0x1A,
318
    OPC_DIVU     = OPC_SPECIAL | 0x1B,
319
    OPC_ADDU     = OPC_SPECIAL | 0x21,
320
    OPC_SUBU     = OPC_SPECIAL | 0x23,
321
    OPC_AND      = OPC_SPECIAL | 0x24,
322
    OPC_OR       = OPC_SPECIAL | 0x25,
323
    OPC_XOR      = OPC_SPECIAL | 0x26,
324
    OPC_NOR      = OPC_SPECIAL | 0x27,
325
    OPC_SLT      = OPC_SPECIAL | 0x2A,
326
    OPC_SLTU     = OPC_SPECIAL | 0x2B,
327

    
328
    OPC_REGIMM   = 0x01 << 26,
329
    OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
330
    OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
331

    
332
    OPC_SPECIAL3 = 0x1f << 26,
333
    OPC_INS      = OPC_SPECIAL3 | 0x004,
334
    OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
335
    OPC_SEB      = OPC_SPECIAL3 | 0x420,
336
    OPC_SEH      = OPC_SPECIAL3 | 0x620,
337
};
338

    
339
/*
340
 * Type reg
341
 */
342
static inline void tcg_out_opc_reg(TCGContext *s, int opc,
343
                                   TCGReg rd, TCGReg rs, TCGReg rt)
344
{
345
    int32_t inst;
346

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

    
354
/*
355
 * Type immediate
356
 */
357
static inline void tcg_out_opc_imm(TCGContext *s, int opc,
358
                                   TCGReg rt, TCGReg rs, TCGArg imm)
359
{
360
    int32_t inst;
361

    
362
    inst = opc;
363
    inst |= (rs & 0x1F) << 21;
364
    inst |= (rt & 0x1F) << 16;
365
    inst |= (imm & 0xffff);
366
    tcg_out32(s, inst);
367
}
368

    
369
/*
370
 * Type branch
371
 */
372
static inline void tcg_out_opc_br(TCGContext *s, int opc,
373
                                  TCGReg rt, TCGReg rs)
374
{
375
    /* We pay attention here to not modify the branch target by reading
376
       the existing value and using it again. This ensure that caches and
377
       memory are kept coherent during retranslation. */
378
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
379

    
380
    tcg_out_opc_imm(s, opc, rt, rs, offset);
381
}
382

    
383
/*
384
 * Type sa
385
 */
386
static inline void tcg_out_opc_sa(TCGContext *s, int opc,
387
                                  TCGReg rd, TCGReg rt, TCGArg sa)
388
{
389
    int32_t inst;
390

    
391
    inst = opc;
392
    inst |= (rt & 0x1F) << 16;
393
    inst |= (rd & 0x1F) << 11;
394
    inst |= (sa & 0x1F) <<  6;
395
    tcg_out32(s, inst);
396

    
397
}
398

    
399
static inline void tcg_out_nop(TCGContext *s)
400
{
401
    tcg_out32(s, 0);
402
}
403

    
404
static inline void tcg_out_mov(TCGContext *s, TCGType type,
405
                               TCGReg ret, TCGReg arg)
406
{
407
    /* Simple reg-reg move, optimising out the 'do nothing' case */
408
    if (ret != arg) {
409
        tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
410
    }
411
}
412

    
413
static inline void tcg_out_movi(TCGContext *s, TCGType type,
414
                                TCGReg reg, tcg_target_long arg)
415
{
416
    if (arg == (int16_t)arg) {
417
        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
418
    } else if (arg == (uint16_t)arg) {
419
        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
420
    } else {
421
        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
422
        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
423
    }
424
}
425

    
426
static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
427
{
428
#ifdef _MIPS_ARCH_MIPS32R2
429
    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
430
#else
431
    /* ret and arg can't be register at */
432
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
433
        tcg_abort();
434
    }
435

    
436
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
437
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
438
    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
439
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
440
#endif
441
}
442

    
443
static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
444
{
445
#ifdef _MIPS_ARCH_MIPS32R2
446
    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
447
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
448
#else
449
    /* ret and arg can't be register at */
450
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
451
        tcg_abort();
452
    }
453

    
454
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
455
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
456
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
457
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
458
#endif
459
}
460

    
461
static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
462
{
463
#ifdef _MIPS_ARCH_MIPS32R2
464
    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
465
    tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
466
#else
467
    /* ret and arg must be different and can't be register at */
468
    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
469
        tcg_abort();
470
    }
471

    
472
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
473

    
474
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
475
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
476

    
477
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
478
    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
479
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
480

    
481
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
482
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
483
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
484
#endif
485
}
486

    
487
static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
488
{
489
#ifdef _MIPS_ARCH_MIPS32R2
490
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
491
#else
492
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
493
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
494
#endif
495
}
496

    
497
static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
498
{
499
#ifdef _MIPS_ARCH_MIPS32R2
500
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
501
#else
502
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
503
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
504
#endif
505
}
506

    
507
static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
508
                                TCGReg arg1, TCGArg arg2)
509
{
510
    if (arg2 == (int16_t) arg2) {
511
        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
512
    } else {
513
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
514
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
515
        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
516
    }
517
}
518

    
519
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
520
                              TCGReg arg1, tcg_target_long arg2)
521
{
522
    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
523
}
524

    
525
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
526
                              TCGReg arg1, tcg_target_long arg2)
527
{
528
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
529
}
530

    
531
static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
532
{
533
    if (val == (int16_t)val) {
534
        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
535
    } else {
536
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
537
        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
538
    }
539
}
540

    
541
/* Helper routines for marshalling helper function arguments into
542
 * the correct registers and stack.
543
 * arg_num is where we want to put this argument, and is updated to be ready
544
 * for the next call. arg is the argument itself. Note that arg_num 0..3 is
545
 * real registers, 4+ on stack.
546
 *
547
 * We provide routines for arguments which are: immediate, 32 bit
548
 * value in register, 16 and 8 bit values in register (which must be zero
549
 * extended before use) and 64 bit value in a lo:hi register pair.
550
 */
551
#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM)                               \
552
    static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM)             \
553
    {                                                                          \
554
    if (*arg_num < 4) {                                                        \
555
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
556
    } else {                                                                   \
557
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT);                          \
558
        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num));   \
559
    }                                                                          \
560
    (*arg_num)++;                                                              \
561
}
562
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
563
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
564
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
565
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
566
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
567
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
568
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
569
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
570
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
571
    tcg_out_movi(s, TCG_TYPE_I32, A, arg);
572
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
573
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
574

    
575
/* We don't use the macro for this one to avoid an unnecessary reg-reg
576
   move when storing to the stack. */
577
static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
578
                                           TCGReg arg)
579
{
580
    if (*arg_num < 4) {
581
        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
582
    } else {
583
        tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
584
    }
585
    (*arg_num)++;
586
}
587

    
588
static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
589
                                           TCGReg arg_low, TCGReg arg_high)
590
{
591
    (*arg_num) = (*arg_num + 1) & ~1;
592

    
593
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
594
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
595
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
596
#else
597
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
598
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
599
#endif
600
}
601

    
602
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
603
                           TCGArg arg2, int label_index)
604
{
605
    TCGLabel *l = &s->labels[label_index];
606

    
607
    switch (cond) {
608
    case TCG_COND_EQ:
609
        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
610
        break;
611
    case TCG_COND_NE:
612
        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
613
        break;
614
    case TCG_COND_LT:
615
        if (arg2 == 0) {
616
            tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
617
        } else {
618
            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
619
            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
620
        }
621
        break;
622
    case TCG_COND_LTU:
623
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
624
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
625
        break;
626
    case TCG_COND_GE:
627
        if (arg2 == 0) {
628
            tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
629
        } else {
630
            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
631
            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
632
        }
633
        break;
634
    case TCG_COND_GEU:
635
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
636
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
637
        break;
638
    case TCG_COND_LE:
639
        if (arg2 == 0) {
640
            tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
641
        } else {
642
            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
643
            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
644
        }
645
        break;
646
    case TCG_COND_LEU:
647
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
648
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
649
        break;
650
    case TCG_COND_GT:
651
        if (arg2 == 0) {
652
            tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
653
        } else {
654
            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
655
            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
656
        }
657
        break;
658
    case TCG_COND_GTU:
659
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
660
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
661
        break;
662
    default:
663
        tcg_abort();
664
        break;
665
    }
666
    if (l->has_value) {
667
        reloc_pc16(s->code_ptr - 4, l->u.value);
668
    } else {
669
        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
670
    }
671
    tcg_out_nop(s);
672
}
673

    
674
/* XXX: we implement it at the target level to avoid having to
675
   handle cross basic blocks temporaries */
676
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
677
                            TCGArg arg2, TCGArg arg3, TCGArg arg4,
678
                            int label_index)
679
{
680
    void *label_ptr;
681

    
682
    switch(cond) {
683
    case TCG_COND_NE:
684
        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
685
        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
686
        return;
687
    case TCG_COND_EQ:
688
        break;
689
    case TCG_COND_LT:
690
    case TCG_COND_LE:
691
        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
692
        break;
693
    case TCG_COND_GT:
694
    case TCG_COND_GE:
695
        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
696
        break;
697
    case TCG_COND_LTU:
698
    case TCG_COND_LEU:
699
        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
700
        break;
701
    case TCG_COND_GTU:
702
    case TCG_COND_GEU:
703
        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
704
        break;
705
    default:
706
        tcg_abort();
707
    }
708

    
709
    label_ptr = s->code_ptr;
710
    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
711
    tcg_out_nop(s);
712

    
713
    switch(cond) {
714
    case TCG_COND_EQ:
715
        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
716
        break;
717
    case TCG_COND_LT:
718
    case TCG_COND_LTU:
719
        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
720
        break;
721
    case TCG_COND_LE:
722
    case TCG_COND_LEU:
723
        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
724
        break;
725
    case TCG_COND_GT:
726
    case TCG_COND_GTU:
727
        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
728
        break;
729
    case TCG_COND_GE:
730
    case TCG_COND_GEU:
731
        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
732
        break;
733
    default:
734
        tcg_abort();
735
    }
736

    
737
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
738
}
739

    
740
static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
741
                            TCGArg c1, TCGArg c2, TCGArg v)
742
{
743
    switch (cond) {
744
    case TCG_COND_EQ:
745
        if (c1 == 0) {
746
            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
747
        } else if (c2 == 0) {
748
            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
749
        } else {
750
            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
751
            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
752
        }
753
        break;
754
    case TCG_COND_NE:
755
        if (c1 == 0) {
756
            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
757
        } else if (c2 == 0) {
758
            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
759
        } else {
760
            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
761
            tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
762
        }
763
        break;
764
    case TCG_COND_LT:
765
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
766
        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
767
        break;
768
    case TCG_COND_LTU:
769
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
770
        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
771
        break;
772
    case TCG_COND_GE:
773
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
774
        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
775
        break;
776
    case TCG_COND_GEU:
777
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
778
        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
779
        break;
780
    case TCG_COND_LE:
781
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
782
        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
783
        break;
784
    case TCG_COND_LEU:
785
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
786
        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
787
        break;
788
    case TCG_COND_GT:
789
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
790
        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
791
        break;
792
    case TCG_COND_GTU:
793
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
794
        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
795
        break;
796
    default:
797
        tcg_abort();
798
        break;
799
    }
800
}
801

    
802
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
803
                            TCGArg arg1, TCGArg arg2)
804
{
805
    switch (cond) {
806
    case TCG_COND_EQ:
807
        if (arg1 == 0) {
808
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
809
        } else if (arg2 == 0) {
810
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
811
        } else {
812
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
813
            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
814
        }
815
        break;
816
    case TCG_COND_NE:
817
        if (arg1 == 0) {
818
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
819
        } else if (arg2 == 0) {
820
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
821
        } else {
822
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
823
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
824
        }
825
        break;
826
    case TCG_COND_LT:
827
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
828
        break;
829
    case TCG_COND_LTU:
830
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
831
        break;
832
    case TCG_COND_GE:
833
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
834
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
835
        break;
836
    case TCG_COND_GEU:
837
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
838
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
839
        break;
840
    case TCG_COND_LE:
841
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
842
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
843
        break;
844
    case TCG_COND_LEU:
845
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
846
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
847
        break;
848
    case TCG_COND_GT:
849
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
850
        break;
851
    case TCG_COND_GTU:
852
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
853
        break;
854
    default:
855
        tcg_abort();
856
        break;
857
    }
858
}
859

    
860
/* XXX: we implement it at the target level to avoid having to
861
   handle cross basic blocks temporaries */
862
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
863
                             TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
864
{
865
    switch (cond) {
866
    case TCG_COND_EQ:
867
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
868
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
869
        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
870
        return;
871
    case TCG_COND_NE:
872
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
873
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
874
        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
875
        return;
876
    case TCG_COND_LT:
877
    case TCG_COND_LE:
878
        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
879
        break;
880
    case TCG_COND_GT:
881
    case TCG_COND_GE:
882
        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
883
        break;
884
    case TCG_COND_LTU:
885
    case TCG_COND_LEU:
886
        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
887
        break;
888
    case TCG_COND_GTU:
889
    case TCG_COND_GEU:
890
        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
891
        break;
892
    default:
893
        tcg_abort();
894
        break;
895
    }
896

    
897
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
898

    
899
    switch(cond) {
900
    case TCG_COND_LT:
901
    case TCG_COND_LTU:
902
        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
903
        break;
904
    case TCG_COND_LE:
905
    case TCG_COND_LEU:
906
        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
907
        break;
908
    case TCG_COND_GT:
909
    case TCG_COND_GTU:
910
        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
911
        break;
912
    case TCG_COND_GE:
913
    case TCG_COND_GEU:
914
        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
915
        break;
916
    default:
917
        tcg_abort();
918
    }
919

    
920
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
921
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
922
}
923

    
924
#if defined(CONFIG_SOFTMMU)
925

    
926
#include "../../softmmu_defs.h"
927

    
928
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
929
   int mmu_idx) */
930
static const void * const qemu_ld_helpers[4] = {
931
    helper_ldb_mmu,
932
    helper_ldw_mmu,
933
    helper_ldl_mmu,
934
    helper_ldq_mmu,
935
};
936

    
937
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
938
   uintxx_t val, int mmu_idx) */
939
static const void * const qemu_st_helpers[4] = {
940
    helper_stb_mmu,
941
    helper_stw_mmu,
942
    helper_stl_mmu,
943
    helper_stq_mmu,
944
};
945
#endif
946

    
947
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
948
                            int opc)
949
{
950
    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
951
#if defined(CONFIG_SOFTMMU)
952
    void *label1_ptr, *label2_ptr;
953
    int arg_num;
954
    int mem_index, s_bits;
955
    int addr_meml;
956
# if TARGET_LONG_BITS == 64
957
    uint8_t *label3_ptr;
958
    TCGReg addr_regh;
959
    int addr_memh;
960
# endif
961
#endif
962
    data_regl = *args++;
963
    if (opc == 3)
964
        data_regh = *args++;
965
    else
966
        data_regh = 0;
967
    addr_regl = *args++;
968
#if defined(CONFIG_SOFTMMU)
969
# if TARGET_LONG_BITS == 64
970
    addr_regh = *args++;
971
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
972
    addr_memh = 0;
973
    addr_meml = 4;
974
#  else
975
    addr_memh = 4;
976
    addr_meml = 0;
977
#  endif
978
# else
979
    addr_meml = 0;
980
# endif
981
    mem_index = *args;
982
    s_bits = opc & 3;
983
#endif
984

    
985
    if (opc == 3) {
986
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
987
        data_reg1 = data_regh;
988
        data_reg2 = data_regl;
989
#else
990
        data_reg1 = data_regl;
991
        data_reg2 = data_regh;
992
#endif
993
    } else {
994
        data_reg1 = data_regl;
995
        data_reg2 = 0;
996
    }
997
#if defined(CONFIG_SOFTMMU)
998
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
999
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1000
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1001
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1002
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
1003
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1004
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1005

    
1006
# if TARGET_LONG_BITS == 64
1007
    label3_ptr = s->code_ptr;
1008
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1009
    tcg_out_nop(s);
1010

    
1011
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1012
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
1013

    
1014
    label1_ptr = s->code_ptr;
1015
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1016
    tcg_out_nop(s);
1017

    
1018
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1019
# else
1020
    label1_ptr = s->code_ptr;
1021
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1022
    tcg_out_nop(s);
1023
# endif
1024

    
1025
    /* slow path */
1026
    arg_num = 0;
1027
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1028
# if TARGET_LONG_BITS == 64
1029
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1030
# else
1031
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1032
# endif
1033
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1034
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
1035
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1036
    tcg_out_nop(s);
1037

    
1038
    switch(opc) {
1039
    case 0:
1040
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
1041
        break;
1042
    case 0 | 4:
1043
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
1044
        break;
1045
    case 1:
1046
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
1047
        break;
1048
    case 1 | 4:
1049
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
1050
        break;
1051
    case 2:
1052
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1053
        break;
1054
    case 3:
1055
        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
1056
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
1057
        break;
1058
    default:
1059
        tcg_abort();
1060
    }
1061

    
1062
    label2_ptr = s->code_ptr;
1063
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1064
    tcg_out_nop(s);
1065

    
1066
    /* label1: fast path */
1067
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1068

    
1069
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1070
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1071
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
1072
#else
1073
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1074
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
1075
    } else {
1076
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
1077
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
1078
    }
1079
#endif
1080

    
1081
    switch(opc) {
1082
    case 0:
1083
        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
1084
        break;
1085
    case 0 | 4:
1086
        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
1087
        break;
1088
    case 1:
1089
        if (TCG_NEED_BSWAP) {
1090
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1091
            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
1092
        } else {
1093
            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
1094
        }
1095
        break;
1096
    case 1 | 4:
1097
        if (TCG_NEED_BSWAP) {
1098
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
1099
            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
1100
        } else {
1101
            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
1102
        }
1103
        break;
1104
    case 2:
1105
        if (TCG_NEED_BSWAP) {
1106
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1107
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1108
        } else {
1109
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1110
        }
1111
        break;
1112
    case 3:
1113
        if (TCG_NEED_BSWAP) {
1114
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1115
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1116
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1117
            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1118
        } else {
1119
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1120
            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1121
        }
1122
        break;
1123
    default:
1124
        tcg_abort();
1125
    }
1126

    
1127
#if defined(CONFIG_SOFTMMU)
1128
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1129
#endif
1130
}
1131

    
1132
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1133
                            int opc)
1134
{
1135
    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1136
#if defined(CONFIG_SOFTMMU)
1137
    uint8_t *label1_ptr, *label2_ptr;
1138
    int arg_num;
1139
    int mem_index, s_bits;
1140
    int addr_meml;
1141
#endif
1142
#if TARGET_LONG_BITS == 64
1143
# if defined(CONFIG_SOFTMMU)
1144
    uint8_t *label3_ptr;
1145
    TCGReg addr_regh;
1146
    int addr_memh;
1147
# endif
1148
#endif
1149
    data_regl = *args++;
1150
    if (opc == 3) {
1151
        data_regh = *args++;
1152
    } else {
1153
        data_regh = 0;
1154
    }
1155
    addr_regl = *args++;
1156
#if defined(CONFIG_SOFTMMU)
1157
# if TARGET_LONG_BITS == 64
1158
    addr_regh = *args++;
1159
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
1160
    addr_memh = 0;
1161
    addr_meml = 4;
1162
#  else
1163
    addr_memh = 4;
1164
    addr_meml = 0;
1165
#  endif
1166
# else
1167
    addr_meml = 0;
1168
# endif
1169
    mem_index = *args;
1170
    s_bits = opc;
1171
#endif
1172

    
1173
    if (opc == 3) {
1174
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1175
        data_reg1 = data_regh;
1176
        data_reg2 = data_regl;
1177
#else
1178
        data_reg1 = data_regl;
1179
        data_reg2 = data_regh;
1180
#endif
1181
    } else {
1182
        data_reg1 = data_regl;
1183
        data_reg2 = 0;
1184
    }
1185

    
1186
#if defined(CONFIG_SOFTMMU)
1187
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1188
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1189
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1190
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1191
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1192
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1193
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1194

    
1195
# if TARGET_LONG_BITS == 64
1196
    label3_ptr = s->code_ptr;
1197
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1198
    tcg_out_nop(s);
1199

    
1200
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1201
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1202

    
1203
    label1_ptr = s->code_ptr;
1204
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1205
    tcg_out_nop(s);
1206

    
1207
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1208
# else
1209
    label1_ptr = s->code_ptr;
1210
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1211
    tcg_out_nop(s);
1212
# endif
1213

    
1214
    /* slow path */
1215
    arg_num = 0;
1216
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1217
# if TARGET_LONG_BITS == 64
1218
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1219
# else
1220
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1221
# endif
1222
    switch(opc) {
1223
    case 0:
1224
        tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1225
        break;
1226
    case 1:
1227
        tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1228
        break;
1229
    case 2:
1230
        tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1231
        break;
1232
    case 3:
1233
        tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1234
        break;
1235
    default:
1236
        tcg_abort();
1237
    }
1238
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1239
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1240
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1241
    tcg_out_nop(s);
1242

    
1243
    label2_ptr = s->code_ptr;
1244
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1245
    tcg_out_nop(s);
1246

    
1247
    /* label1: fast path */
1248
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1249

    
1250
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1251
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1252
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1253
#else
1254
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1255
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1256
    } else {
1257
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1258
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1259
    }
1260

    
1261
#endif
1262

    
1263
    switch(opc) {
1264
    case 0:
1265
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1266
        break;
1267
    case 1:
1268
        if (TCG_NEED_BSWAP) {
1269
            tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
1270
            tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
1271
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1272
        } else {
1273
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1274
        }
1275
        break;
1276
    case 2:
1277
        if (TCG_NEED_BSWAP) {
1278
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1279
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1280
        } else {
1281
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1282
        }
1283
        break;
1284
    case 3:
1285
        if (TCG_NEED_BSWAP) {
1286
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1287
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1288
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1289
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1290
        } else {
1291
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1292
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1293
        }
1294
        break;
1295
    default:
1296
        tcg_abort();
1297
    }
1298

    
1299
#if defined(CONFIG_SOFTMMU)
1300
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1301
#endif
1302
}
1303

    
1304
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1305
                              const TCGArg *args, const int *const_args)
1306
{
1307
    switch(opc) {
1308
    case INDEX_op_exit_tb:
1309
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1310
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1311
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1312
        tcg_out_nop(s);
1313
        break;
1314
    case INDEX_op_goto_tb:
1315
        if (s->tb_jmp_offset) {
1316
            /* direct jump method */
1317
            tcg_abort();
1318
        } else {
1319
            /* indirect jump method */
1320
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1321
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1322
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1323
        }
1324
        tcg_out_nop(s);
1325
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1326
        break;
1327
    case INDEX_op_call:
1328
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1329
        tcg_out_nop(s);
1330
        break;
1331
    case INDEX_op_jmp:
1332
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1333
        tcg_out_nop(s);
1334
        break;
1335
    case INDEX_op_br:
1336
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1337
        break;
1338

    
1339
    case INDEX_op_mov_i32:
1340
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1341
        break;
1342
    case INDEX_op_movi_i32:
1343
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1344
        break;
1345

    
1346
    case INDEX_op_ld8u_i32:
1347
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1348
        break;
1349
    case INDEX_op_ld8s_i32:
1350
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1351
        break;
1352
    case INDEX_op_ld16u_i32:
1353
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1354
        break;
1355
    case INDEX_op_ld16s_i32:
1356
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1357
        break;
1358
    case INDEX_op_ld_i32:
1359
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1360
        break;
1361
    case INDEX_op_st8_i32:
1362
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1363
        break;
1364
    case INDEX_op_st16_i32:
1365
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1366
        break;
1367
    case INDEX_op_st_i32:
1368
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1369
        break;
1370

    
1371
    case INDEX_op_add_i32:
1372
        if (const_args[2]) {
1373
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1374
        } else {
1375
            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1376
        }
1377
        break;
1378
    case INDEX_op_add2_i32:
1379
        if (const_args[4]) {
1380
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1381
        } else {
1382
            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1383
        }
1384
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1385
        if (const_args[5]) {
1386
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1387
        } else {
1388
             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1389
        }
1390
        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1391
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1392
        break;
1393
    case INDEX_op_sub_i32:
1394
        if (const_args[2]) {
1395
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1396
        } else {
1397
            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1398
        }
1399
        break;
1400
    case INDEX_op_sub2_i32:
1401
        if (const_args[4]) {
1402
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1403
        } else {
1404
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1405
        }
1406
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1407
        if (const_args[5]) {
1408
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1409
        } else {
1410
             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1411
        }
1412
        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1413
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1414
        break;
1415
    case INDEX_op_mul_i32:
1416
        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1417
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1418
        break;
1419
    case INDEX_op_mulu2_i32:
1420
        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1421
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1422
        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1423
        break;
1424
    case INDEX_op_div_i32:
1425
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1426
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1427
        break;
1428
    case INDEX_op_divu_i32:
1429
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1430
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1431
        break;
1432
    case INDEX_op_rem_i32:
1433
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1434
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1435
        break;
1436
    case INDEX_op_remu_i32:
1437
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1438
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1439
        break;
1440

    
1441
    case INDEX_op_and_i32:
1442
        if (const_args[2]) {
1443
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1444
        } else {
1445
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1446
        }
1447
        break;
1448
    case INDEX_op_or_i32:
1449
        if (const_args[2]) {
1450
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1451
        } else {
1452
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1453
        }
1454
        break;
1455
    case INDEX_op_nor_i32:
1456
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1457
        break;
1458
    case INDEX_op_not_i32:
1459
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1460
        break;
1461
    case INDEX_op_xor_i32:
1462
        if (const_args[2]) {
1463
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1464
        } else {
1465
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1466
        }
1467
        break;
1468

    
1469
    case INDEX_op_sar_i32:
1470
        if (const_args[2]) {
1471
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1472
        } else {
1473
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1474
        }
1475
        break;
1476
    case INDEX_op_shl_i32:
1477
        if (const_args[2]) {
1478
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1479
        } else {
1480
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1481
        }
1482
        break;
1483
    case INDEX_op_shr_i32:
1484
        if (const_args[2]) {
1485
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1486
        } else {
1487
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1488
        }
1489
        break;
1490
    case INDEX_op_rotl_i32:
1491
        if (const_args[2]) {
1492
            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
1493
        } else {
1494
            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
1495
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
1496
            tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
1497
        }
1498
        break;
1499
    case INDEX_op_rotr_i32:
1500
        if (const_args[2]) {
1501
            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
1502
        } else {
1503
            tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
1504
        }
1505
        break;
1506

    
1507
    /* The bswap routines do not work on non-R2 CPU. In that case
1508
       we let TCG generating the corresponding code. */
1509
    case INDEX_op_bswap16_i32:
1510
        tcg_out_bswap16(s, args[0], args[1]);
1511
        break;
1512
    case INDEX_op_bswap32_i32:
1513
        tcg_out_bswap32(s, args[0], args[1]);
1514
        break;
1515

    
1516
    case INDEX_op_ext8s_i32:
1517
        tcg_out_ext8s(s, args[0], args[1]);
1518
        break;
1519
    case INDEX_op_ext16s_i32:
1520
        tcg_out_ext16s(s, args[0], args[1]);
1521
        break;
1522

    
1523
    case INDEX_op_deposit_i32:
1524
        tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
1525
                        ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
1526
        break;
1527

    
1528
    case INDEX_op_brcond_i32:
1529
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1530
        break;
1531
    case INDEX_op_brcond2_i32:
1532
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1533
        break;
1534

    
1535
    case INDEX_op_movcond_i32:
1536
        tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
1537
        break;
1538

    
1539
    case INDEX_op_setcond_i32:
1540
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1541
        break;
1542
    case INDEX_op_setcond2_i32:
1543
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1544
        break;
1545

    
1546
    case INDEX_op_qemu_ld8u:
1547
        tcg_out_qemu_ld(s, args, 0);
1548
        break;
1549
    case INDEX_op_qemu_ld8s:
1550
        tcg_out_qemu_ld(s, args, 0 | 4);
1551
        break;
1552
    case INDEX_op_qemu_ld16u:
1553
        tcg_out_qemu_ld(s, args, 1);
1554
        break;
1555
    case INDEX_op_qemu_ld16s:
1556
        tcg_out_qemu_ld(s, args, 1 | 4);
1557
        break;
1558
    case INDEX_op_qemu_ld32:
1559
        tcg_out_qemu_ld(s, args, 2);
1560
        break;
1561
    case INDEX_op_qemu_ld64:
1562
        tcg_out_qemu_ld(s, args, 3);
1563
        break;
1564
    case INDEX_op_qemu_st8:
1565
        tcg_out_qemu_st(s, args, 0);
1566
        break;
1567
    case INDEX_op_qemu_st16:
1568
        tcg_out_qemu_st(s, args, 1);
1569
        break;
1570
    case INDEX_op_qemu_st32:
1571
        tcg_out_qemu_st(s, args, 2);
1572
        break;
1573
    case INDEX_op_qemu_st64:
1574
        tcg_out_qemu_st(s, args, 3);
1575
        break;
1576

    
1577
    default:
1578
        tcg_abort();
1579
    }
1580
}
1581

    
1582
static const TCGTargetOpDef mips_op_defs[] = {
1583
    { INDEX_op_exit_tb, { } },
1584
    { INDEX_op_goto_tb, { } },
1585
    { INDEX_op_call, { "C" } },
1586
    { INDEX_op_jmp, { "r" } },
1587
    { INDEX_op_br, { } },
1588

    
1589
    { INDEX_op_mov_i32, { "r", "r" } },
1590
    { INDEX_op_movi_i32, { "r" } },
1591
    { INDEX_op_ld8u_i32, { "r", "r" } },
1592
    { INDEX_op_ld8s_i32, { "r", "r" } },
1593
    { INDEX_op_ld16u_i32, { "r", "r" } },
1594
    { INDEX_op_ld16s_i32, { "r", "r" } },
1595
    { INDEX_op_ld_i32, { "r", "r" } },
1596
    { INDEX_op_st8_i32, { "rZ", "r" } },
1597
    { INDEX_op_st16_i32, { "rZ", "r" } },
1598
    { INDEX_op_st_i32, { "rZ", "r" } },
1599

    
1600
    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1601
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1602
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1603
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1604
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1605
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1606
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1607
    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1608

    
1609
    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1610
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1611
    { INDEX_op_not_i32, { "r", "rZ" } },
1612
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1613
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1614

    
1615
    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1616
    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1617
    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1618
    { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1619
    { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1620

    
1621
    { INDEX_op_bswap16_i32, { "r", "r" } },
1622
    { INDEX_op_bswap32_i32, { "r", "r" } },
1623

    
1624
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1625
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1626

    
1627
    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1628

    
1629
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1630
    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1631
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1632
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1633

    
1634
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1635
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1636
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1637

    
1638
#if TARGET_LONG_BITS == 32
1639
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1640
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1641
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1642
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1643
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1644
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1645

    
1646
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1647
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1648
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1649
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1650
#else
1651
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1652
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1653
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1654
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1655
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1656
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1657

    
1658
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1659
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1660
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1661
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1662
#endif
1663
    { -1 },
1664
};
1665

    
1666
static int tcg_target_callee_save_regs[] = {
1667
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1668
    TCG_REG_S1,
1669
    TCG_REG_S2,
1670
    TCG_REG_S3,
1671
    TCG_REG_S4,
1672
    TCG_REG_S5,
1673
    TCG_REG_S6,
1674
    TCG_REG_S7,
1675
    TCG_REG_FP,
1676
    TCG_REG_RA,       /* should be last for ABI compliance */
1677
};
1678

    
1679
/* Generate global QEMU prologue and epilogue code */
1680
static void tcg_target_qemu_prologue(TCGContext *s)
1681
{
1682
    int i, frame_size;
1683

    
1684
    /* reserve some stack space, also for TCG temps. */
1685
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1686
                 + TCG_STATIC_CALL_ARGS_SIZE
1687
                 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1688
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1689
                 ~(TCG_TARGET_STACK_ALIGN - 1);
1690
    tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1691
                  + TCG_STATIC_CALL_ARGS_SIZE,
1692
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1693

    
1694
    /* TB prologue */
1695
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1696
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1697
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1698
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1699
    }
1700

    
1701
    /* Call generated code */
1702
    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1703
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1704
    tb_ret_addr = s->code_ptr;
1705

    
1706
    /* TB epilogue */
1707
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1708
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1709
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1710
    }
1711

    
1712
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1713
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1714
}
1715

    
1716
static void tcg_target_init(TCGContext *s)
1717
{
1718
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1719
    tcg_regset_set(tcg_target_call_clobber_regs,
1720
                   (1 << TCG_REG_V0) |
1721
                   (1 << TCG_REG_V1) |
1722
                   (1 << TCG_REG_A0) |
1723
                   (1 << TCG_REG_A1) |
1724
                   (1 << TCG_REG_A2) |
1725
                   (1 << TCG_REG_A3) |
1726
                   (1 << TCG_REG_T1) |
1727
                   (1 << TCG_REG_T2) |
1728
                   (1 << TCG_REG_T3) |
1729
                   (1 << TCG_REG_T4) |
1730
                   (1 << TCG_REG_T5) |
1731
                   (1 << TCG_REG_T6) |
1732
                   (1 << TCG_REG_T7) |
1733
                   (1 << TCG_REG_T8) |
1734
                   (1 << TCG_REG_T9));
1735

    
1736
    tcg_regset_clear(s->reserved_regs);
1737
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1738
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1739
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1740
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1741
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1742
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1743
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1744
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1745

    
1746
    tcg_add_target_add_op_defs(mips_op_defs);
1747
}