Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (45.6 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 pay attention here to not modify the branch target by reading
355
       the existing value and using it again. This ensure that caches and
356
       memory are kept coherent during retranslation. */
357
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
358

    
359
    tcg_out_opc_imm(s, opc, rt, rs, offset);
360
}
361

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

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

    
375
}
376

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

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

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

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

    
407
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
408
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
409

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

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

    
422
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
423
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
424

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

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

    
437
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
438

    
439
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
440
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
441

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
623
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
624
}
625

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

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

    
721
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
722

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

    
744
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
745
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
746
}
747

    
748
#if defined(CONFIG_SOFTMMU)
749

    
750
#include "../../softmmu_defs.h"
751

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1092
#endif
1093

    
1094
    switch(opc) {
1095
    case 0:
1096
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1097
        break;
1098
    case 1:
1099
        if (TCG_NEED_BSWAP) {
1100
            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1101
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1102
        } else {
1103
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1104
        }
1105
        break;
1106
    case 2:
1107
        if (TCG_NEED_BSWAP) {
1108
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1109
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1110
        } else {
1111
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1112
        }
1113
        break;
1114
    case 3:
1115
        if (TCG_NEED_BSWAP) {
1116
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1117
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1118
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1119
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1120
        } else {
1121
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1122
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1123
        }
1124
        break;
1125
    default:
1126
        tcg_abort();
1127
    }
1128

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

    
1134
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1135
                              const TCGArg *args, const int *const_args)
1136
{
1137
    switch(opc) {
1138
    case INDEX_op_exit_tb:
1139
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1140
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1141
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1142
        tcg_out_nop(s);
1143
        break;
1144
    case INDEX_op_goto_tb:
1145
        if (s->tb_jmp_offset) {
1146
            /* direct jump method */
1147
            tcg_abort();
1148
        } else {
1149
            /* indirect jump method */
1150
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1151
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1152
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1153
        }
1154
        tcg_out_nop(s);
1155
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1156
        break;
1157
    case INDEX_op_call:
1158
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1159
        tcg_out_nop(s);
1160
        break;
1161
    case INDEX_op_jmp:
1162
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1163
        tcg_out_nop(s);
1164
        break;
1165
    case INDEX_op_br:
1166
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1167
        break;
1168

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

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

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

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

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

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

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

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

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

    
1373
    default:
1374
        tcg_abort();
1375
    }
1376
}
1377

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

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

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

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

    
1411
    { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1412
    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1413
    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1414

    
1415
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1416
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1417

    
1418
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1419
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1420
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1421

    
1422
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1423
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1424
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1425

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

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

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

    
1454
static int tcg_target_callee_save_regs[] = {
1455
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
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_target_call_iarg_regs[1], 0);
1488
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
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
    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
1532
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1533
}