Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ d43ffce1

History | View | Annotate | Download (45.3 kB)

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

    
27
#if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28
# define TCG_NEED_BSWAP 0
29
#else
30
# define TCG_NEED_BSWAP 1
31
#endif
32

    
33
#ifndef NDEBUG
34
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
35
    "zero",
36
    "at",
37
    "v0",
38
    "v1",
39
    "a0",
40
    "a1",
41
    "a2",
42
    "a3",
43
    "t0",
44
    "t1",
45
    "t2",
46
    "t3",
47
    "t4",
48
    "t5",
49
    "t6",
50
    "t7",
51
    "s0",
52
    "s1",
53
    "s2",
54
    "s3",
55
    "s4",
56
    "s5",
57
    "s6",
58
    "s7",
59
    "t8",
60
    "t9",
61
    "k0",
62
    "k1",
63
    "gp",
64
    "sp",
65
    "fp",
66
    "ra",
67
};
68
#endif
69

    
70
/* check if we really need so many registers :P */
71
static const int tcg_target_reg_alloc_order[] = {
72
    TCG_REG_S0,
73
    TCG_REG_S1,
74
    TCG_REG_S2,
75
    TCG_REG_S3,
76
    TCG_REG_S4,
77
    TCG_REG_S5,
78
    TCG_REG_S6,
79
    TCG_REG_S7,
80
    TCG_REG_T1,
81
    TCG_REG_T2,
82
    TCG_REG_T3,
83
    TCG_REG_T4,
84
    TCG_REG_T5,
85
    TCG_REG_T6,
86
    TCG_REG_T7,
87
    TCG_REG_T8,
88
    TCG_REG_T9,
89
    TCG_REG_A0,
90
    TCG_REG_A1,
91
    TCG_REG_A2,
92
    TCG_REG_A3,
93
    TCG_REG_V0,
94
    TCG_REG_V1
95
};
96

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

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

    
109
static uint8_t *tb_ret_addr;
110

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
199
    ct_str = *pct_str;
200
    switch(ct_str[0]) {
201
    case 'r':
202
        ct->ct |= TCG_CT_REG;
203
        tcg_regset_set(ct->u.regs, 0xffffffff);
204
        break;
205
    case 'C':
206
        ct->ct |= TCG_CT_REG;
207
        tcg_regset_clear(ct->u.regs);
208
        tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
209
        break;
210
    case 'L': /* qemu_ld output arg constraint */
211
        ct->ct |= TCG_CT_REG;
212
        tcg_regset_set(ct->u.regs, 0xffffffff);
213
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
214
        break;
215
    case 'l': /* qemu_ld input arg constraint */
216
        ct->ct |= TCG_CT_REG;
217
        tcg_regset_set(ct->u.regs, 0xffffffff);
218
#if defined(CONFIG_SOFTMMU)
219
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
220
#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 need to keep the offset unchanged for retranslation */
355
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
356

    
357
    tcg_out_opc_imm(s, opc, rt, rs, offset);
358
}
359

    
360
/*
361
 * Type sa
362
 */
363
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
364
{
365
    int32_t inst;
366

    
367
    inst = opc;
368
    inst |= (rt & 0x1F) << 16;
369
    inst |= (rd & 0x1F) << 11;
370
    inst |= (sa & 0x1F) <<  6;
371
    tcg_out32(s, inst);
372

    
373
}
374

    
375
static inline void tcg_out_nop(TCGContext *s)
376
{
377
    tcg_out32(s, 0);
378
}
379

    
380
static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
381
{
382
    tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
383
}
384

    
385
static inline void tcg_out_movi(TCGContext *s, TCGType type,
386
                                int reg, int32_t arg)
387
{
388
    if (arg == (int16_t)arg) {
389
        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
390
    } else if (arg == (uint16_t)arg) {
391
        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
392
    } else {
393
        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
394
        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
395
    }
396
}
397

    
398
static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
399
{
400
    /* ret and arg can't be register at */
401
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
402
        tcg_abort();
403
    }
404

    
405
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
406
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
407

    
408
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
409
    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
410
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
411
}
412

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

    
420
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
421
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
422

    
423
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
424
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
425
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
426
}
427

    
428
static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
429
{
430
    /* ret and arg must be different and can't be register at */
431
    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
432
        tcg_abort();
433
    }
434

    
435
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
436

    
437
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
438
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
439

    
440
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
441
    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
442
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
443

    
444
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
445
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
446
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
447
}
448

    
449
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
450
{
451
#ifdef _MIPS_ARCH_MIPS32R2
452
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
453
#else
454
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
455
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
456
#endif
457
}
458

    
459
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
460
{
461
#ifdef _MIPS_ARCH_MIPS32R2
462
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
463
#else
464
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
465
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
466
#endif
467
}
468

    
469
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
470
                              int arg1, tcg_target_long arg2)
471
{
472
    if (arg2 == (int16_t) arg2) {
473
        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
474
    } else {
475
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
476
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
477
        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
478
    }
479
}
480

    
481
static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
482
                              int arg1, tcg_target_long arg2)
483
{
484
    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
485
}
486

    
487
static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
488
                              int arg1, tcg_target_long arg2)
489
{
490
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
491
}
492

    
493
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
494
{
495
    if (val == (int16_t)val) {
496
        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
497
    } else {
498
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
499
        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
500
    }
501
}
502

    
503
static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
504
                           int arg2, int label_index)
505
{
506
    TCGLabel *l = &s->labels[label_index];
507

    
508
    switch (cond) {
509
    case TCG_COND_EQ:
510
        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
511
        break;
512
    case TCG_COND_NE:
513
        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
514
        break;
515
    case TCG_COND_LT:
516
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
517
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
518
        break;
519
    case TCG_COND_LTU:
520
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
521
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
522
        break;
523
    case TCG_COND_GE:
524
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
525
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
526
        break;
527
    case TCG_COND_GEU:
528
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
529
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
530
        break;
531
    case TCG_COND_LE:
532
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
533
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
534
        break;
535
    case TCG_COND_LEU:
536
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
537
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
538
        break;
539
    case TCG_COND_GT:
540
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
541
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
542
        break;
543
    case TCG_COND_GTU:
544
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
545
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
546
        break;
547
    default:
548
        tcg_abort();
549
        break;
550
    }
551
    if (l->has_value) {
552
        reloc_pc16(s->code_ptr - 4, l->u.value);
553
    } else {
554
        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
555
    }
556
    tcg_out_nop(s);
557
}
558

    
559
/* XXX: we implement it at the target level to avoid having to
560
   handle cross basic blocks temporaries */
561
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
562
                            int arg2, int arg3, int arg4, int label_index)
563
{
564
    void *label_ptr;
565

    
566
    switch(cond) {
567
    case TCG_COND_NE:
568
        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
569
        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
570
        return;
571
    case TCG_COND_EQ:
572
        break;
573
    case TCG_COND_LT:
574
    case TCG_COND_LE:
575
        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
576
        break;
577
    case TCG_COND_GT:
578
    case TCG_COND_GE:
579
        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
580
        break;
581
    case TCG_COND_LTU:
582
    case TCG_COND_LEU:
583
        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
584
        break;
585
    case TCG_COND_GTU:
586
    case TCG_COND_GEU:
587
        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
588
        break;
589
    default:
590
        tcg_abort();
591
    }
592

    
593
    label_ptr = s->code_ptr;
594
    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
595
    tcg_out_nop(s);
596

    
597
    switch(cond) {
598
    case TCG_COND_EQ:
599
        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
600
        break;
601
    case TCG_COND_LT:
602
    case TCG_COND_LTU:
603
        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
604
        break;
605
    case TCG_COND_LE:
606
    case TCG_COND_LEU:
607
        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
608
        break;
609
    case TCG_COND_GT:
610
    case TCG_COND_GTU:
611
        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
612
        break;
613
    case TCG_COND_GE:
614
    case TCG_COND_GEU:
615
        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
616
        break;
617
    default:
618
        tcg_abort();
619
    }
620

    
621
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
622
}
623

    
624
static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
625
                            int arg1, int arg2)
626
{
627
    switch (cond) {
628
    case TCG_COND_EQ:
629
        if (arg1 == 0) {
630
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
631
        } else if (arg2 == 0) {
632
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
633
        } else {
634
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
635
            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
636
        }
637
        break;
638
    case TCG_COND_NE:
639
        if (arg1 == 0) {
640
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
641
        } else if (arg2 == 0) {
642
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
643
        } else {
644
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
645
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
646
        }
647
        break;
648
    case TCG_COND_LT:
649
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
650
        break;
651
    case TCG_COND_LTU:
652
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
653
        break;
654
    case TCG_COND_GE:
655
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
656
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
657
        break;
658
    case TCG_COND_GEU:
659
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
660
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
661
        break;
662
    case TCG_COND_LE:
663
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
664
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
665
        break;
666
    case TCG_COND_LEU:
667
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
668
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
669
        break;
670
    case TCG_COND_GT:
671
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
672
        break;
673
    case TCG_COND_GTU:
674
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
675
        break;
676
    default:
677
        tcg_abort();
678
        break;
679
    }
680
}
681

    
682
/* XXX: we implement it at the target level to avoid having to
683
   handle cross basic blocks temporaries */
684
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
685
                             int arg1, int arg2, int arg3, int arg4)
686
{
687
    switch (cond) {
688
    case TCG_COND_EQ:
689
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
690
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
691
        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
692
        return;
693
    case TCG_COND_NE:
694
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
695
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
696
        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
697
        return;
698
    case TCG_COND_LT:
699
    case TCG_COND_LE:
700
        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
701
        break;
702
    case TCG_COND_GT:
703
    case TCG_COND_GE:
704
        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
705
        break;
706
    case TCG_COND_LTU:
707
    case TCG_COND_LEU:
708
        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
709
        break;
710
    case TCG_COND_GTU:
711
    case TCG_COND_GEU:
712
        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
713
        break;
714
    default:
715
        tcg_abort();
716
        break;
717
    }
718

    
719
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
720

    
721
    switch(cond) {
722
    case TCG_COND_LT:
723
    case TCG_COND_LTU:
724
        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
725
        break;
726
    case TCG_COND_LE:
727
    case TCG_COND_LEU:
728
        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
729
        break;
730
    case TCG_COND_GT:
731
    case TCG_COND_GTU:
732
        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
733
        break;
734
    case TCG_COND_GE:
735
    case TCG_COND_GEU:
736
        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
737
        break;
738
    default:
739
        tcg_abort();
740
    }
741

    
742
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
743
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
744
}
745

    
746
#if defined(CONFIG_SOFTMMU)
747

    
748
#include "../../softmmu_defs.h"
749

    
750
static void *qemu_ld_helpers[4] = {
751
    __ldb_mmu,
752
    __ldw_mmu,
753
    __ldl_mmu,
754
    __ldq_mmu,
755
};
756

    
757
static void *qemu_st_helpers[4] = {
758
    __stb_mmu,
759
    __stw_mmu,
760
    __stl_mmu,
761
    __stq_mmu,
762
};
763
#endif
764

    
765
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
766
                            int opc)
767
{
768
    int addr_regl, addr_reg1, addr_meml;
769
    int data_regl, data_regh, data_reg1, data_reg2;
770
    int mem_index, s_bits;
771
#if defined(CONFIG_SOFTMMU)
772
    void *label1_ptr, *label2_ptr;
773
    int sp_args;
774
#endif
775
#if TARGET_LONG_BITS == 64
776
# if defined(CONFIG_SOFTMMU)
777
    uint8_t *label3_ptr;
778
# endif
779
    int addr_regh, addr_reg2, addr_memh;
780
#endif
781
    data_regl = *args++;
782
    if (opc == 3)
783
        data_regh = *args++;
784
    else
785
        data_regh = 0;
786
    addr_regl = *args++;
787
#if TARGET_LONG_BITS == 64
788
    addr_regh = *args++;
789
#endif
790
    mem_index = *args;
791
    s_bits = opc & 3;
792

    
793
    if (opc == 3) {
794
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
795
        data_reg1 = data_regh;
796
        data_reg2 = data_regl;
797
#else
798
        data_reg1 = data_regl;
799
        data_reg2 = data_regh;
800
#endif
801
    } else {
802
        data_reg1 = data_regl;
803
        data_reg2 = 0;
804
    }
805
#if TARGET_LONG_BITS == 64
806
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
807
    addr_reg1 = addr_regh;
808
    addr_reg2 = addr_regl;
809
    addr_memh = 0;
810
    addr_meml = 4;
811
# else
812
    addr_reg1 = addr_regl;
813
    addr_reg2 = addr_regh;
814
    addr_memh = 4;
815
    addr_meml = 0;
816
# endif
817
#else
818
    addr_reg1 = addr_regl;
819
    addr_meml = 0;
820
#endif
821

    
822
#if defined(CONFIG_SOFTMMU)
823
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
824
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
825
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
826
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
827
                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);
828
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
829
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
830

    
831
# if TARGET_LONG_BITS == 64
832
    label3_ptr = s->code_ptr;
833
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
834
    tcg_out_nop(s);
835

    
836
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
837
                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);
838

    
839
    label1_ptr = s->code_ptr;
840
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
841
    tcg_out_nop(s);
842

    
843
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
844
# else
845
    label1_ptr = s->code_ptr;
846
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
847
    tcg_out_nop(s);
848
# endif
849

    
850
    /* slow path */
851
    sp_args = TCG_REG_A0;
852
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
853
# if TARGET_LONG_BITS == 64
854
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
855
# endif
856
    tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
857
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
858
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
859
    tcg_out_nop(s);
860

    
861
    switch(opc) {
862
    case 0:
863
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
864
        break;
865
    case 0 | 4:
866
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
867
        break;
868
    case 1:
869
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
870
        break;
871
    case 1 | 4:
872
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
873
        break;
874
    case 2:
875
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
876
        break;
877
    case 3:
878
        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
879
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
880
        break;
881
    default:
882
        tcg_abort();
883
    }
884

    
885
    label2_ptr = s->code_ptr;
886
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
887
    tcg_out_nop(s);
888

    
889
    /* label1: fast path */
890
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
891

    
892
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
893
                    offsetof(CPUState, tlb_table[mem_index][0].addend));
894
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
895
#else
896
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
897
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
898
    } else {
899
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
900
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
901
    }
902
#endif
903

    
904
    switch(opc) {
905
    case 0:
906
        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
907
        break;
908
    case 0 | 4:
909
        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
910
        break;
911
    case 1:
912
        if (TCG_NEED_BSWAP) {
913
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
914
            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
915
        } else {
916
            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
917
        }
918
        break;
919
    case 1 | 4:
920
        if (TCG_NEED_BSWAP) {
921
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
922
            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
923
        } else {
924
            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
925
        }
926
        break;
927
    case 2:
928
        if (TCG_NEED_BSWAP) {
929
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
930
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
931
        } else {
932
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
933
        }
934
        break;
935
    case 3:
936
        if (TCG_NEED_BSWAP) {
937
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
938
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
939
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
940
            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
941
        } else {
942
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
943
            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
944
        }
945
        break;
946
    default:
947
        tcg_abort();
948
    }
949

    
950
#if defined(CONFIG_SOFTMMU)
951
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
952
#endif
953
}
954

    
955
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
956
                            int opc)
957
{
958
    int addr_regl, addr_reg1, addr_meml;
959
    int data_regl, data_regh, data_reg1, data_reg2;
960
    int mem_index, s_bits;
961
#if defined(CONFIG_SOFTMMU)
962
    uint8_t *label1_ptr, *label2_ptr;
963
    int sp_args;
964
#endif
965
#if TARGET_LONG_BITS == 64
966
# if defined(CONFIG_SOFTMMU)
967
    uint8_t *label3_ptr;
968
# endif
969
    int addr_regh, addr_reg2, addr_memh;
970
#endif
971

    
972
    data_regl = *args++;
973
    if (opc == 3) {
974
        data_regh = *args++;
975
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
976
        data_reg1 = data_regh;
977
        data_reg2 = data_regl;
978
#else
979
        data_reg1 = data_regl;
980
        data_reg2 = data_regh;
981
#endif
982
    } else {
983
        data_reg1 = data_regl;
984
        data_reg2 = 0;
985
        data_regh = 0;
986
    }
987
    addr_regl = *args++;
988
#if TARGET_LONG_BITS == 64
989
    addr_regh = *args++;
990
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
991
    addr_reg1 = addr_regh;
992
    addr_reg2 = addr_regl;
993
    addr_memh = 0;
994
    addr_meml = 4;
995
# else
996
    addr_reg1 = addr_regl;
997
    addr_reg2 = addr_regh;
998
    addr_memh = 4;
999
    addr_meml = 0;
1000
# endif
1001
#else
1002
    addr_reg1 = addr_regl;
1003
    addr_meml = 0;
1004
#endif
1005
    mem_index = *args;
1006
    s_bits = opc;
1007

    
1008
#if defined(CONFIG_SOFTMMU)
1009
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1010
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1011
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1012
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1013
                    offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_meml);
1014
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1015
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1016

    
1017
# if TARGET_LONG_BITS == 64
1018
    label3_ptr = s->code_ptr;
1019
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1020
    tcg_out_nop(s);
1021

    
1022
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1023
                    offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_memh);
1024

    
1025
    label1_ptr = s->code_ptr;
1026
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1027
    tcg_out_nop(s);
1028

    
1029
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1030
# else
1031
    label1_ptr = s->code_ptr;
1032
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1033
    tcg_out_nop(s);
1034
# endif
1035

    
1036
    /* slow path */
1037
    sp_args = TCG_REG_A0;
1038
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1039
# if TARGET_LONG_BITS == 64
1040
    tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1041
# endif
1042
    switch(opc) {
1043
    case 0:
1044
        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
1045
        break;
1046
    case 1:
1047
        tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
1048
        break;
1049
    case 2:
1050
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1051
        break;
1052
    case 3:
1053
        sp_args = (sp_args + 1) & ~1;
1054
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1055
        tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1056
        break;
1057
    default:
1058
        tcg_abort();
1059
    }
1060
    if (sp_args > TCG_REG_A3) {
1061
        /* Push mem_index on the stack */
1062
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
1063
        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
1064
    } else {
1065
        tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
1066
    }
1067

    
1068
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1069
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1070
    tcg_out_nop(s);
1071

    
1072
    label2_ptr = s->code_ptr;
1073
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1074
    tcg_out_nop(s);
1075

    
1076
    /* label1: fast path */
1077
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1078

    
1079
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1080
                    offsetof(CPUState, tlb_table[mem_index][0].addend));
1081
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1082
#else
1083
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1084
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1085
    } else {
1086
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1087
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1088
    }
1089

    
1090
#endif
1091

    
1092
    switch(opc) {
1093
    case 0:
1094
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1095
        break;
1096
    case 1:
1097
        if (TCG_NEED_BSWAP) {
1098
            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1099
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1100
        } else {
1101
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1102
        }
1103
        break;
1104
    case 2:
1105
        if (TCG_NEED_BSWAP) {
1106
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1107
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1108
        } else {
1109
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1110
        }
1111
        break;
1112
    case 3:
1113
        if (TCG_NEED_BSWAP) {
1114
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1115
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1116
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1117
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1118
        } else {
1119
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1120
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 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 inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1133
                              const TCGArg *args, const int *const_args)
1134
{
1135
    switch(opc) {
1136
    case INDEX_op_exit_tb:
1137
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1138
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1139
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1140
        tcg_out_nop(s);
1141
        break;
1142
    case INDEX_op_goto_tb:
1143
        if (s->tb_jmp_offset) {
1144
            /* direct jump method */
1145
            tcg_abort();
1146
        } else {
1147
            /* indirect jump method */
1148
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1149
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1150
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1151
        }
1152
        tcg_out_nop(s);
1153
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1154
        break;
1155
    case INDEX_op_call:
1156
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1157
        tcg_out_nop(s);
1158
        break;
1159
    case INDEX_op_jmp:
1160
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1161
        tcg_out_nop(s);
1162
        break;
1163
    case INDEX_op_br:
1164
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1165
        break;
1166

    
1167
    case INDEX_op_mov_i32:
1168
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1169
        break;
1170
    case INDEX_op_movi_i32:
1171
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1172
        break;
1173

    
1174
    case INDEX_op_ld8u_i32:
1175
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1176
        break;
1177
    case INDEX_op_ld8s_i32:
1178
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1179
        break;
1180
    case INDEX_op_ld16u_i32:
1181
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1182
        break;
1183
    case INDEX_op_ld16s_i32:
1184
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1185
        break;
1186
    case INDEX_op_ld_i32:
1187
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1188
        break;
1189
    case INDEX_op_st8_i32:
1190
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1191
        break;
1192
    case INDEX_op_st16_i32:
1193
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1194
        break;
1195
    case INDEX_op_st_i32:
1196
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1197
        break;
1198

    
1199
    case INDEX_op_add_i32:
1200
        if (const_args[2]) {
1201
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1202
        } else {
1203
            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1204
        }
1205
        break;
1206
    case INDEX_op_add2_i32:
1207
        if (const_args[4]) {
1208
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1209
        } else {
1210
            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1211
        }
1212
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1213
        if (const_args[5]) {
1214
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1215
        } else {
1216
             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1217
        }
1218
        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1219
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1220
        break;
1221
    case INDEX_op_sub_i32:
1222
        if (const_args[2]) {
1223
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1224
        } else {
1225
            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1226
        }
1227
        break;
1228
    case INDEX_op_sub2_i32:
1229
        if (const_args[4]) {
1230
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1231
        } else {
1232
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1233
        }
1234
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1235
        if (const_args[5]) {
1236
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1237
        } else {
1238
             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1239
        }
1240
        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1241
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1242
        break;
1243
    case INDEX_op_mul_i32:
1244
        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1245
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1246
        break;
1247
    case INDEX_op_mulu2_i32:
1248
        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1249
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1250
        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1251
        break;
1252
    case INDEX_op_div_i32:
1253
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1254
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1255
        break;
1256
    case INDEX_op_divu_i32:
1257
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1258
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1259
        break;
1260
    case INDEX_op_rem_i32:
1261
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1262
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1263
        break;
1264
    case INDEX_op_remu_i32:
1265
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1266
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1267
        break;
1268

    
1269
    case INDEX_op_and_i32:
1270
        if (const_args[2]) {
1271
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1272
        } else {
1273
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1274
        }
1275
        break;
1276
    case INDEX_op_or_i32:
1277
        if (const_args[2]) {
1278
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1279
        } else {
1280
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1281
        }
1282
        break;
1283
    case INDEX_op_nor_i32:
1284
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1285
        break;
1286
    case INDEX_op_not_i32:
1287
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1288
        break;
1289
    case INDEX_op_xor_i32:
1290
        if (const_args[2]) {
1291
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1292
        } else {
1293
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1294
        }
1295
        break;
1296

    
1297
    case INDEX_op_sar_i32:
1298
        if (const_args[2]) {
1299
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1300
        } else {
1301
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1302
        }
1303
        break;
1304
    case INDEX_op_shl_i32:
1305
        if (const_args[2]) {
1306
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1307
        } else {
1308
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1309
        }
1310
        break;
1311
    case INDEX_op_shr_i32:
1312
        if (const_args[2]) {
1313
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1314
        } else {
1315
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1316
        }
1317
        break;
1318

    
1319
    case INDEX_op_ext8s_i32:
1320
        tcg_out_ext8s(s, args[0], args[1]);
1321
        break;
1322
    case INDEX_op_ext16s_i32:
1323
        tcg_out_ext16s(s, args[0], args[1]);
1324
        break;
1325

    
1326
    case INDEX_op_brcond_i32:
1327
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1328
        break;
1329
    case INDEX_op_brcond2_i32:
1330
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1331
        break;
1332

    
1333
    case INDEX_op_setcond_i32:
1334
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1335
        break;
1336
    case INDEX_op_setcond2_i32:
1337
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1338
        break;
1339

    
1340
    case INDEX_op_qemu_ld8u:
1341
        tcg_out_qemu_ld(s, args, 0);
1342
        break;
1343
    case INDEX_op_qemu_ld8s:
1344
        tcg_out_qemu_ld(s, args, 0 | 4);
1345
        break;
1346
    case INDEX_op_qemu_ld16u:
1347
        tcg_out_qemu_ld(s, args, 1);
1348
        break;
1349
    case INDEX_op_qemu_ld16s:
1350
        tcg_out_qemu_ld(s, args, 1 | 4);
1351
        break;
1352
    case INDEX_op_qemu_ld32:
1353
        tcg_out_qemu_ld(s, args, 2);
1354
        break;
1355
    case INDEX_op_qemu_ld64:
1356
        tcg_out_qemu_ld(s, args, 3);
1357
        break;
1358
    case INDEX_op_qemu_st8:
1359
        tcg_out_qemu_st(s, args, 0);
1360
        break;
1361
    case INDEX_op_qemu_st16:
1362
        tcg_out_qemu_st(s, args, 1);
1363
        break;
1364
    case INDEX_op_qemu_st32:
1365
        tcg_out_qemu_st(s, args, 2);
1366
        break;
1367
    case INDEX_op_qemu_st64:
1368
        tcg_out_qemu_st(s, args, 3);
1369
        break;
1370

    
1371
    default:
1372
        tcg_abort();
1373
    }
1374
}
1375

    
1376
static const TCGTargetOpDef mips_op_defs[] = {
1377
    { INDEX_op_exit_tb, { } },
1378
    { INDEX_op_goto_tb, { } },
1379
    { INDEX_op_call, { "C" } },
1380
    { INDEX_op_jmp, { "r" } },
1381
    { INDEX_op_br, { } },
1382

    
1383
    { INDEX_op_mov_i32, { "r", "r" } },
1384
    { INDEX_op_movi_i32, { "r" } },
1385
    { INDEX_op_ld8u_i32, { "r", "r" } },
1386
    { INDEX_op_ld8s_i32, { "r", "r" } },
1387
    { INDEX_op_ld16u_i32, { "r", "r" } },
1388
    { INDEX_op_ld16s_i32, { "r", "r" } },
1389
    { INDEX_op_ld_i32, { "r", "r" } },
1390
    { INDEX_op_st8_i32, { "rZ", "r" } },
1391
    { INDEX_op_st16_i32, { "rZ", "r" } },
1392
    { INDEX_op_st_i32, { "rZ", "r" } },
1393

    
1394
    { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
1395
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1396
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1397
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1398
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1399
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1400
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1401
    { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
1402

    
1403
    { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1404
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1405
    { INDEX_op_not_i32, { "r", "rZ" } },
1406
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1407
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1408

    
1409
    { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1410
    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1411
    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1412

    
1413
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1414
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1415

    
1416
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1417
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1418
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1419

    
1420
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1421
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1422
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1423

    
1424
#if TARGET_LONG_BITS == 32
1425
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1426
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1427
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1428
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1429
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1430
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1431

    
1432
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1433
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1434
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1435
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1436
#else
1437
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1438
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1439
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1440
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1441
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1442
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1443

    
1444
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1445
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1446
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1447
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1448
#endif
1449
    { -1 },
1450
};
1451

    
1452
static int tcg_target_callee_save_regs[] = {
1453
#if 0 /* used for the global env (TCG_AREG0), so no need to save */
1454
    TCG_REG_S0,
1455
#endif
1456
    TCG_REG_S1,
1457
    TCG_REG_S2,
1458
    TCG_REG_S3,
1459
    TCG_REG_S4,
1460
    TCG_REG_S5,
1461
    TCG_REG_S6,
1462
    TCG_REG_S7,
1463
    TCG_REG_GP,
1464
    TCG_REG_FP,
1465
    TCG_REG_RA,       /* should be last for ABI compliance */
1466
};
1467

    
1468
/* Generate global QEMU prologue and epilogue code */
1469
static void tcg_target_qemu_prologue(TCGContext *s)
1470
{
1471
    int i, frame_size;
1472

    
1473
    /* reserve some stack space */
1474
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1475
                 + TCG_STATIC_CALL_ARGS_SIZE;
1476
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1477
                 ~(TCG_TARGET_STACK_ALIGN - 1);
1478

    
1479
    /* TB prologue */
1480
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1481
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1482
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1483
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1484
    }
1485

    
1486
    /* Call generated code */
1487
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0);
1488
    tcg_out_nop(s);
1489
    tb_ret_addr = s->code_ptr;
1490

    
1491
    /* TB epilogue */
1492
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1493
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1494
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1495
    }
1496

    
1497
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1498
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1499
}
1500

    
1501
static void tcg_target_init(TCGContext *s)
1502
{
1503
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1504
    tcg_regset_set(tcg_target_call_clobber_regs,
1505
                   (1 << TCG_REG_V0) |
1506
                   (1 << TCG_REG_V1) |
1507
                   (1 << TCG_REG_A0) |
1508
                   (1 << TCG_REG_A1) |
1509
                   (1 << TCG_REG_A2) |
1510
                   (1 << TCG_REG_A3) |
1511
                   (1 << TCG_REG_T1) |
1512
                   (1 << TCG_REG_T2) |
1513
                   (1 << TCG_REG_T3) |
1514
                   (1 << TCG_REG_T4) |
1515
                   (1 << TCG_REG_T5) |
1516
                   (1 << TCG_REG_T6) |
1517
                   (1 << TCG_REG_T7) |
1518
                   (1 << TCG_REG_T8) |
1519
                   (1 << TCG_REG_T9));
1520

    
1521
    tcg_regset_clear(s->reserved_regs);
1522
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1523
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1524
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1525
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1526
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1527
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1528
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1529

    
1530
    tcg_add_target_add_op_defs(mips_op_defs);
1531
}