Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ 3cf246f0

History | View | Annotate | Download (56.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
#include "tcg-be-null.h"
28

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

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

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

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

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

    
111
static uint8_t *tb_ret_addr;
112

    
113
static inline uint32_t reloc_lo16_val(void *pc, intptr_t target)
114
{
115
    return target & 0xffff;
116
}
117

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

    
124
static inline uint32_t reloc_hi16_val(void *pc, intptr_t target)
125
{
126
    return (target >> 16) & 0xffff;
127
}
128

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

    
135
static inline uint32_t reloc_pc16_val(void *pc, intptr_t target)
136
{
137
    int32_t disp;
138

    
139
    disp = target - (intptr_t)pc - 4;
140
    if (disp != (disp << 14) >> 14) {
141
        tcg_abort ();
142
    }
143

    
144
    return (disp >> 2) & 0xffff;
145
}
146

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

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

    
159
    return (target >> 2) & 0x3ffffff;
160
}
161

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

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

    
190
/* parse target specific constraints */
191
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
192
{
193
    const char *ct_str;
194

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

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

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

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

    
324
    OPC_REGIMM   = 0x01 << 26,
325
    OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
326
    OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
327

    
328
    OPC_SPECIAL2 = 0x1c << 26,
329
    OPC_MUL      = OPC_SPECIAL2 | 0x002,
330

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

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

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

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

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

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

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

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

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

    
396
}
397

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
923
#if defined(CONFIG_SOFTMMU)
924
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
925
   int mmu_idx) */
926
static const void * const qemu_ld_helpers[4] = {
927
    helper_ldb_mmu,
928
    helper_ldw_mmu,
929
    helper_ldl_mmu,
930
    helper_ldq_mmu,
931
};
932

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

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

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

    
1002
# if TARGET_LONG_BITS == 64
1003
    label3_ptr = s->code_ptr;
1004
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1005
    tcg_out_nop(s);
1006

    
1007
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1008
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
1009

    
1010
    label1_ptr = s->code_ptr;
1011
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1012
    tcg_out_nop(s);
1013

    
1014
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1015
# else
1016
    label1_ptr = s->code_ptr;
1017
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1018
    tcg_out_nop(s);
1019
# endif
1020

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

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

    
1058
    label2_ptr = s->code_ptr;
1059
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1060
    tcg_out_nop(s);
1061

    
1062
    /* label1: fast path */
1063
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1064

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

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

    
1123
#if defined(CONFIG_SOFTMMU)
1124
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1125
#endif
1126
}
1127

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

    
1169
    if (opc == 3) {
1170
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1171
        data_reg1 = data_regh;
1172
        data_reg2 = data_regl;
1173
#else
1174
        data_reg1 = data_regl;
1175
        data_reg2 = data_regh;
1176
#endif
1177
    } else {
1178
        data_reg1 = data_regl;
1179
        data_reg2 = 0;
1180
    }
1181

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

    
1191
# if TARGET_LONG_BITS == 64
1192
    label3_ptr = s->code_ptr;
1193
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1194
    tcg_out_nop(s);
1195

    
1196
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1197
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1198

    
1199
    label1_ptr = s->code_ptr;
1200
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1201
    tcg_out_nop(s);
1202

    
1203
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1204
# else
1205
    label1_ptr = s->code_ptr;
1206
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1207
    tcg_out_nop(s);
1208
# endif
1209

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

    
1239
    label2_ptr = s->code_ptr;
1240
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1241
    tcg_out_nop(s);
1242

    
1243
    /* label1: fast path */
1244
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1245

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

    
1257
#endif
1258

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

    
1295
#if defined(CONFIG_SOFTMMU)
1296
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1297
#endif
1298
}
1299

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

    
1331
    case INDEX_op_mov_i32:
1332
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1333
        break;
1334
    case INDEX_op_movi_i32:
1335
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1336
        break;
1337

    
1338
    case INDEX_op_ld8u_i32:
1339
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1340
        break;
1341
    case INDEX_op_ld8s_i32:
1342
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1343
        break;
1344
    case INDEX_op_ld16u_i32:
1345
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1346
        break;
1347
    case INDEX_op_ld16s_i32:
1348
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1349
        break;
1350
    case INDEX_op_ld_i32:
1351
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1352
        break;
1353
    case INDEX_op_st8_i32:
1354
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1355
        break;
1356
    case INDEX_op_st16_i32:
1357
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1358
        break;
1359
    case INDEX_op_st_i32:
1360
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1361
        break;
1362

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

    
1450
    case INDEX_op_and_i32:
1451
        if (const_args[2]) {
1452
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1453
        } else {
1454
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1455
        }
1456
        break;
1457
    case INDEX_op_or_i32:
1458
        if (const_args[2]) {
1459
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1460
        } else {
1461
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1462
        }
1463
        break;
1464
    case INDEX_op_nor_i32:
1465
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1466
        break;
1467
    case INDEX_op_not_i32:
1468
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1469
        break;
1470
    case INDEX_op_xor_i32:
1471
        if (const_args[2]) {
1472
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1473
        } else {
1474
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1475
        }
1476
        break;
1477

    
1478
    case INDEX_op_sar_i32:
1479
        if (const_args[2]) {
1480
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1481
        } else {
1482
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1483
        }
1484
        break;
1485
    case INDEX_op_shl_i32:
1486
        if (const_args[2]) {
1487
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1488
        } else {
1489
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1490
        }
1491
        break;
1492
    case INDEX_op_shr_i32:
1493
        if (const_args[2]) {
1494
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1495
        } else {
1496
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1497
        }
1498
        break;
1499
    case INDEX_op_rotl_i32:
1500
        if (const_args[2]) {
1501
            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
1502
        } else {
1503
            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
1504
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
1505
            tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
1506
        }
1507
        break;
1508
    case INDEX_op_rotr_i32:
1509
        if (const_args[2]) {
1510
            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
1511
        } else {
1512
            tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
1513
        }
1514
        break;
1515

    
1516
    case INDEX_op_bswap16_i32:
1517
        tcg_out_opc_reg(s, OPC_WSBH, args[0], 0, args[1]);
1518
        break;
1519
    case INDEX_op_bswap32_i32:
1520
        tcg_out_opc_reg(s, OPC_WSBH, args[0], 0, args[1]);
1521
        tcg_out_opc_sa(s, OPC_ROTR, args[0], args[0], 16);
1522
        break;
1523

    
1524
    case INDEX_op_ext8s_i32:
1525
        tcg_out_opc_reg(s, OPC_SEB, args[0], 0, args[1]);
1526
        break;
1527
    case INDEX_op_ext16s_i32:
1528
        tcg_out_opc_reg(s, OPC_SEH, args[0], 0, args[1]);
1529
        break;
1530

    
1531
    case INDEX_op_deposit_i32:
1532
        tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
1533
                        ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
1534
        break;
1535

    
1536
    case INDEX_op_brcond_i32:
1537
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1538
        break;
1539
    case INDEX_op_brcond2_i32:
1540
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1541
        break;
1542

    
1543
    case INDEX_op_movcond_i32:
1544
        tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
1545
        break;
1546

    
1547
    case INDEX_op_setcond_i32:
1548
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1549
        break;
1550
    case INDEX_op_setcond2_i32:
1551
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1552
        break;
1553

    
1554
    case INDEX_op_qemu_ld8u:
1555
        tcg_out_qemu_ld(s, args, 0);
1556
        break;
1557
    case INDEX_op_qemu_ld8s:
1558
        tcg_out_qemu_ld(s, args, 0 | 4);
1559
        break;
1560
    case INDEX_op_qemu_ld16u:
1561
        tcg_out_qemu_ld(s, args, 1);
1562
        break;
1563
    case INDEX_op_qemu_ld16s:
1564
        tcg_out_qemu_ld(s, args, 1 | 4);
1565
        break;
1566
    case INDEX_op_qemu_ld32:
1567
        tcg_out_qemu_ld(s, args, 2);
1568
        break;
1569
    case INDEX_op_qemu_ld64:
1570
        tcg_out_qemu_ld(s, args, 3);
1571
        break;
1572
    case INDEX_op_qemu_st8:
1573
        tcg_out_qemu_st(s, args, 0);
1574
        break;
1575
    case INDEX_op_qemu_st16:
1576
        tcg_out_qemu_st(s, args, 1);
1577
        break;
1578
    case INDEX_op_qemu_st32:
1579
        tcg_out_qemu_st(s, args, 2);
1580
        break;
1581
    case INDEX_op_qemu_st64:
1582
        tcg_out_qemu_st(s, args, 3);
1583
        break;
1584

    
1585
    default:
1586
        tcg_abort();
1587
    }
1588
}
1589

    
1590
static const TCGTargetOpDef mips_op_defs[] = {
1591
    { INDEX_op_exit_tb, { } },
1592
    { INDEX_op_goto_tb, { } },
1593
    { INDEX_op_call, { "C" } },
1594
    { INDEX_op_br, { } },
1595

    
1596
    { INDEX_op_mov_i32, { "r", "r" } },
1597
    { INDEX_op_movi_i32, { "r" } },
1598
    { INDEX_op_ld8u_i32, { "r", "r" } },
1599
    { INDEX_op_ld8s_i32, { "r", "r" } },
1600
    { INDEX_op_ld16u_i32, { "r", "r" } },
1601
    { INDEX_op_ld16s_i32, { "r", "r" } },
1602
    { INDEX_op_ld_i32, { "r", "r" } },
1603
    { INDEX_op_st8_i32, { "rZ", "r" } },
1604
    { INDEX_op_st16_i32, { "rZ", "r" } },
1605
    { INDEX_op_st_i32, { "rZ", "r" } },
1606

    
1607
    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1608
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1609
    { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
1610
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1611
    { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
1612
    { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
1613
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1614
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1615
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1616
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1617
    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1618

    
1619
    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1620
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1621
    { INDEX_op_not_i32, { "r", "rZ" } },
1622
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1623
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1624

    
1625
    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1626
    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1627
    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1628
    { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
1629
    { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
1630

    
1631
    { INDEX_op_bswap16_i32, { "r", "r" } },
1632
    { INDEX_op_bswap32_i32, { "r", "r" } },
1633

    
1634
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1635
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1636

    
1637
    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1638

    
1639
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1640
    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
1641
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1642
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1643

    
1644
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1645
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1646
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1647

    
1648
#if TARGET_LONG_BITS == 32
1649
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1650
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1651
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1652
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1653
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1654
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1655

    
1656
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1657
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1658
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1659
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1660
#else
1661
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1662
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1663
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1664
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1665
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1666
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1667

    
1668
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1669
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1670
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1671
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1672
#endif
1673
    { -1 },
1674
};
1675

    
1676
static int tcg_target_callee_save_regs[] = {
1677
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1678
    TCG_REG_S1,
1679
    TCG_REG_S2,
1680
    TCG_REG_S3,
1681
    TCG_REG_S4,
1682
    TCG_REG_S5,
1683
    TCG_REG_S6,
1684
    TCG_REG_S7,
1685
    TCG_REG_FP,
1686
    TCG_REG_RA,       /* should be last for ABI compliance */
1687
};
1688

    
1689
/* The Linux kernel doesn't provide any information about the available
1690
   instruction set. Probe it using a signal handler. */
1691

    
1692
#include <signal.h>
1693

    
1694
#ifndef use_movnz_instructions
1695
bool use_movnz_instructions = false;
1696
#endif
1697

    
1698
#ifndef use_mips32_instructions
1699
bool use_mips32_instructions = false;
1700
#endif
1701

    
1702
#ifndef use_mips32r2_instructions
1703
bool use_mips32r2_instructions = false;
1704
#endif
1705

    
1706
static volatile sig_atomic_t got_sigill;
1707

    
1708
static void sigill_handler(int signo, siginfo_t *si, void *data)
1709
{
1710
    /* Skip the faulty instruction */
1711
    ucontext_t *uc = (ucontext_t *)data;
1712
    uc->uc_mcontext.pc += 4;
1713

    
1714
    got_sigill = 1;
1715
}
1716

    
1717
static void tcg_target_detect_isa(void)
1718
{
1719
    struct sigaction sa_old, sa_new;
1720

    
1721
    memset(&sa_new, 0, sizeof(sa_new));
1722
    sa_new.sa_flags = SA_SIGINFO;
1723
    sa_new.sa_sigaction = sigill_handler;
1724
    sigaction(SIGILL, &sa_new, &sa_old);
1725

    
1726
    /* Probe for movn/movz, necessary to implement movcond. */
1727
#ifndef use_movnz_instructions
1728
    got_sigill = 0;
1729
    asm volatile(".set push\n"
1730
                 ".set mips32\n"
1731
                 "movn $zero, $zero, $zero\n"
1732
                 "movz $zero, $zero, $zero\n"
1733
                 ".set pop\n"
1734
                 : : : );
1735
    use_movnz_instructions = !got_sigill;
1736
#endif
1737

    
1738
    /* Probe for MIPS32 instructions. As no subsetting is allowed
1739
       by the specification, it is only necessary to probe for one
1740
       of the instructions. */
1741
#ifndef use_mips32_instructions
1742
    got_sigill = 0;
1743
    asm volatile(".set push\n"
1744
                 ".set mips32\n"
1745
                 "mul $zero, $zero\n"
1746
                 ".set pop\n"
1747
                 : : : );
1748
    use_mips32_instructions = !got_sigill;
1749
#endif
1750

    
1751
    /* Probe for MIPS32r2 instructions if MIPS32 instructions are
1752
       available. As no subsetting is allowed by the specification,
1753
       it is only necessary to probe for one of the instructions. */
1754
#ifndef use_mips32r2_instructions
1755
    if (use_mips32_instructions) {
1756
        got_sigill = 0;
1757
        asm volatile(".set push\n"
1758
                     ".set mips32r2\n"
1759
                     "seb $zero, $zero\n"
1760
                     ".set pop\n"
1761
                     : : : );
1762
        use_mips32r2_instructions = !got_sigill;
1763
    }
1764
#endif
1765

    
1766
    sigaction(SIGILL, &sa_old, NULL);
1767
}
1768

    
1769
/* Generate global QEMU prologue and epilogue code */
1770
static void tcg_target_qemu_prologue(TCGContext *s)
1771
{
1772
    int i, frame_size;
1773

    
1774
    /* reserve some stack space, also for TCG temps. */
1775
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1776
                 + TCG_STATIC_CALL_ARGS_SIZE
1777
                 + CPU_TEMP_BUF_NLONGS * sizeof(long);
1778
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1779
                 ~(TCG_TARGET_STACK_ALIGN - 1);
1780
    tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1781
                  + TCG_STATIC_CALL_ARGS_SIZE,
1782
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1783

    
1784
    /* TB prologue */
1785
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1786
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1787
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1788
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1789
    }
1790

    
1791
    /* Call generated code */
1792
    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1793
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1794
    tb_ret_addr = s->code_ptr;
1795

    
1796
    /* TB epilogue */
1797
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1798
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1799
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1800
    }
1801

    
1802
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1803
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1804
}
1805

    
1806
static void tcg_target_init(TCGContext *s)
1807
{
1808
    tcg_target_detect_isa();
1809
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1810
    tcg_regset_set(tcg_target_call_clobber_regs,
1811
                   (1 << TCG_REG_V0) |
1812
                   (1 << TCG_REG_V1) |
1813
                   (1 << TCG_REG_A0) |
1814
                   (1 << TCG_REG_A1) |
1815
                   (1 << TCG_REG_A2) |
1816
                   (1 << TCG_REG_A3) |
1817
                   (1 << TCG_REG_T1) |
1818
                   (1 << TCG_REG_T2) |
1819
                   (1 << TCG_REG_T3) |
1820
                   (1 << TCG_REG_T4) |
1821
                   (1 << TCG_REG_T5) |
1822
                   (1 << TCG_REG_T6) |
1823
                   (1 << TCG_REG_T7) |
1824
                   (1 << TCG_REG_T8) |
1825
                   (1 << TCG_REG_T9));
1826

    
1827
    tcg_regset_clear(s->reserved_regs);
1828
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1829
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1830
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1831
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1832
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1833
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1834
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1835
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
1836

    
1837
    tcg_add_target_add_op_defs(mips_op_defs);
1838
}