Statistics
| Branch: | Revision:

root / tcg / i386 / tcg-target.c @ be5a4eb7

History | View | Annotate | Download (43.9 kB)

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

    
25
#ifndef NDEBUG
26
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
27
    "%eax",
28
    "%ecx",
29
    "%edx",
30
    "%ebx",
31
    "%esp",
32
    "%ebp",
33
    "%esi",
34
    "%edi",
35
};
36
#endif
37

    
38
static const int tcg_target_reg_alloc_order[] = {
39
    TCG_REG_EBX,
40
    TCG_REG_ESI,
41
    TCG_REG_EDI,
42
    TCG_REG_EBP,
43
    TCG_REG_ECX,
44
    TCG_REG_EDX,
45
    TCG_REG_EAX,
46
};
47

    
48
static const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX };
49
static const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
50

    
51
static uint8_t *tb_ret_addr;
52

    
53
static void patch_reloc(uint8_t *code_ptr, int type,
54
                        tcg_target_long value, tcg_target_long addend)
55
{
56
    value += addend;
57
    switch(type) {
58
    case R_386_32:
59
        *(uint32_t *)code_ptr = value;
60
        break;
61
    case R_386_PC32:
62
        *(uint32_t *)code_ptr = value - (long)code_ptr;
63
        break;
64
    case R_386_PC8:
65
        value -= (long)code_ptr;
66
        if (value != (int8_t)value) {
67
            tcg_abort();
68
        }
69
        *(uint8_t *)code_ptr = value;
70
        break;
71
    default:
72
        tcg_abort();
73
    }
74
}
75

    
76
/* maximum number of register used for input function arguments */
77
static inline int tcg_target_get_call_iarg_regs_count(int flags)
78
{
79
    flags &= TCG_CALL_TYPE_MASK;
80
    switch(flags) {
81
    case TCG_CALL_TYPE_STD:
82
        return 0;
83
    case TCG_CALL_TYPE_REGPARM_1:
84
    case TCG_CALL_TYPE_REGPARM_2:
85
    case TCG_CALL_TYPE_REGPARM:
86
        return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
87
    default:
88
        tcg_abort();
89
    }
90
}
91

    
92
/* parse target specific constraints */
93
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
94
{
95
    const char *ct_str;
96

    
97
    ct_str = *pct_str;
98
    switch(ct_str[0]) {
99
    case 'a':
100
        ct->ct |= TCG_CT_REG;
101
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
102
        break;
103
    case 'b':
104
        ct->ct |= TCG_CT_REG;
105
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
106
        break;
107
    case 'c':
108
        ct->ct |= TCG_CT_REG;
109
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
110
        break;
111
    case 'd':
112
        ct->ct |= TCG_CT_REG;
113
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
114
        break;
115
    case 'S':
116
        ct->ct |= TCG_CT_REG;
117
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
118
        break;
119
    case 'D':
120
        ct->ct |= TCG_CT_REG;
121
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
122
        break;
123
    case 'q':
124
        ct->ct |= TCG_CT_REG;
125
        tcg_regset_set32(ct->u.regs, 0, 0xf);
126
        break;
127
    case 'r':
128
        ct->ct |= TCG_CT_REG;
129
        tcg_regset_set32(ct->u.regs, 0, 0xff);
130
        break;
131

    
132
        /* qemu_ld/st address constraint */
133
    case 'L':
134
        ct->ct |= TCG_CT_REG;
135
        tcg_regset_set32(ct->u.regs, 0, 0xff);
136
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
137
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
138
        break;
139
    default:
140
        return -1;
141
    }
142
    ct_str++;
143
    *pct_str = ct_str;
144
    return 0;
145
}
146

    
147
/* test if a constant matches the constraint */
148
static inline int tcg_target_const_match(tcg_target_long val,
149
                                         const TCGArgConstraint *arg_ct)
150
{
151
    int ct;
152
    ct = arg_ct->ct;
153
    if (ct & TCG_CT_CONST)
154
        return 1;
155
    else
156
        return 0;
157
}
158

    
159
#define P_EXT                0x100                /* 0x0f opcode prefix */
160
#define P_DATA16        0x200                /* 0x66 opcode prefix */
161

    
162
#define OPC_ARITH_EvIz        (0x81)
163
#define OPC_ARITH_EvIb        (0x83)
164
#define OPC_ARITH_GvEv        (0x03)                /* ... plus (ARITH_FOO << 3) */
165
#define OPC_ADD_GvEv        (OPC_ARITH_GvEv | (ARITH_ADD << 3))
166
#define OPC_BSWAP        (0xc8 | P_EXT)
167
#define OPC_CALL_Jz        (0xe8)
168
#define OPC_CMP_GvEv        (OPC_ARITH_GvEv | (ARITH_CMP << 3))
169
#define OPC_DEC_r32        (0x48)
170
#define OPC_IMUL_GvEv        (0xaf | P_EXT)
171
#define OPC_IMUL_GvEvIb        (0x6b)
172
#define OPC_IMUL_GvEvIz        (0x69)
173
#define OPC_INC_r32        (0x40)
174
#define OPC_JCC_long        (0x80 | P_EXT)        /* ... plus condition code */
175
#define OPC_JCC_short        (0x70)                /* ... plus condition code */
176
#define OPC_JMP_long        (0xe9)
177
#define OPC_JMP_short        (0xeb)
178
#define OPC_LEA         (0x8d)
179
#define OPC_MOVB_EvGv        (0x88)                /* stores, more or less */
180
#define OPC_MOVL_EvGv        (0x89)                /* stores, more or less */
181
#define OPC_MOVL_GvEv        (0x8b)                /* loads, more or less */
182
#define OPC_MOVL_Iv     (0xb8)
183
#define OPC_MOVSBL        (0xbe | P_EXT)
184
#define OPC_MOVSWL        (0xbf | P_EXT)
185
#define OPC_MOVZBL        (0xb6 | P_EXT)
186
#define OPC_MOVZWL        (0xb7 | P_EXT)
187
#define OPC_POP_r32        (0x58)
188
#define OPC_PUSH_r32        (0x50)
189
#define OPC_PUSH_Iv        (0x68)
190
#define OPC_PUSH_Ib        (0x6a)
191
#define OPC_RET                (0xc3)
192
#define OPC_SETCC        (0x90 | P_EXT)        /* ... plus condition code */
193
#define OPC_SHIFT_1        (0xd1)
194
#define OPC_SHIFT_Ib        (0xc1)
195
#define OPC_SHIFT_cl        (0xd3)
196
#define OPC_TESTL        (0x85)
197
#define OPC_XCHG_ax_r32        (0x90)
198

    
199
#define OPC_GRP3_Ev        (0xf7)
200
#define OPC_GRP5        (0xff)
201

    
202
/* Group 1 opcode extensions for 0x80-0x83.
203
   These are also used as modifiers for OPC_ARITH.  */
204
#define ARITH_ADD 0
205
#define ARITH_OR  1
206
#define ARITH_ADC 2
207
#define ARITH_SBB 3
208
#define ARITH_AND 4
209
#define ARITH_SUB 5
210
#define ARITH_XOR 6
211
#define ARITH_CMP 7
212

    
213
/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3.  */
214
#define SHIFT_ROL 0
215
#define SHIFT_ROR 1
216
#define SHIFT_SHL 4
217
#define SHIFT_SHR 5
218
#define SHIFT_SAR 7
219

    
220
/* Group 3 opcode extensions for 0xf6, 0xf7.  To be used with OPC_GRP3.  */
221
#define EXT3_NOT   2
222
#define EXT3_NEG   3
223
#define EXT3_MUL   4
224
#define EXT3_IMUL  5
225
#define EXT3_DIV   6
226
#define EXT3_IDIV  7
227

    
228
/* Group 5 opcode extensions for 0xff.  To be used with OPC_GRP5.  */
229
#define EXT5_CALLN_Ev        2
230
#define EXT5_JMPN_Ev        4
231

    
232
/* Condition codes to be added to OPC_JCC_{long,short}.  */
233
#define JCC_JMP (-1)
234
#define JCC_JO  0x0
235
#define JCC_JNO 0x1
236
#define JCC_JB  0x2
237
#define JCC_JAE 0x3
238
#define JCC_JE  0x4
239
#define JCC_JNE 0x5
240
#define JCC_JBE 0x6
241
#define JCC_JA  0x7
242
#define JCC_JS  0x8
243
#define JCC_JNS 0x9
244
#define JCC_JP  0xa
245
#define JCC_JNP 0xb
246
#define JCC_JL  0xc
247
#define JCC_JGE 0xd
248
#define JCC_JLE 0xe
249
#define JCC_JG  0xf
250

    
251
static const uint8_t tcg_cond_to_jcc[10] = {
252
    [TCG_COND_EQ] = JCC_JE,
253
    [TCG_COND_NE] = JCC_JNE,
254
    [TCG_COND_LT] = JCC_JL,
255
    [TCG_COND_GE] = JCC_JGE,
256
    [TCG_COND_LE] = JCC_JLE,
257
    [TCG_COND_GT] = JCC_JG,
258
    [TCG_COND_LTU] = JCC_JB,
259
    [TCG_COND_GEU] = JCC_JAE,
260
    [TCG_COND_LEU] = JCC_JBE,
261
    [TCG_COND_GTU] = JCC_JA,
262
};
263

    
264
static inline void tcg_out_opc(TCGContext *s, int opc)
265
{
266
    if (opc & P_DATA16) {
267
        tcg_out8(s, 0x66);
268
    }
269
    if (opc & P_EXT) {
270
        tcg_out8(s, 0x0f);
271
    }
272
    tcg_out8(s, opc);
273
}
274

    
275
static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
276
{
277
    tcg_out_opc(s, opc);
278
    tcg_out8(s, 0xc0 | (r << 3) | rm);
279
}
280

    
281
/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
282
   We handle either RM and INDEX missing with a -1 value.  */
283

    
284
static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
285
                                     int index, int shift, int32_t offset)
286
{
287
    int mod, len;
288

    
289
    if (index == -1 && rm == -1) {
290
        /* Absolute address.  */
291
        tcg_out_opc(s, opc);
292
        tcg_out8(s, (r << 3) | 5);
293
        tcg_out32(s, offset);
294
        return;
295
    }
296

    
297
    tcg_out_opc(s, opc);
298

    
299
    /* Find the length of the immediate addend.  Note that the encoding
300
       that would be used for (%ebp) indicates absolute addressing.  */
301
    if (rm == -1) {
302
        mod = 0, len = 4, rm = 5;
303
    } else if (offset == 0 && rm != TCG_REG_EBP) {
304
        mod = 0, len = 0;
305
    } else if (offset == (int8_t)offset) {
306
        mod = 0x40, len = 1;
307
    } else {
308
        mod = 0x80, len = 4;
309
    }
310

    
311
    /* Use a single byte MODRM format if possible.  Note that the encoding
312
       that would be used for %esp is the escape to the two byte form.  */
313
    if (index == -1 && rm != TCG_REG_ESP) {
314
        /* Single byte MODRM format.  */
315
        tcg_out8(s, mod | (r << 3) | rm);
316
    } else {
317
        /* Two byte MODRM+SIB format.  */
318

    
319
        /* Note that the encoding that would place %esp into the index
320
           field indicates no index register.  */
321
        if (index == -1) {
322
            index = 4;
323
        } else {
324
            assert(index != TCG_REG_ESP);
325
        }
326

    
327
        tcg_out8(s, mod | (r << 3) | 4);
328
        tcg_out8(s, (shift << 6) | (index << 3) | rm);
329
    }
330

    
331
    if (len == 1) {
332
        tcg_out8(s, offset);
333
    } else if (len == 4) {
334
        tcg_out32(s, offset);
335
    }
336
}
337

    
338
/* rm == -1 means no register index */
339
static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
340
                                        int32_t offset)
341
{
342
    tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
343
}
344

    
345
/* Generate dest op= src.  Uses the same ARITH_* codes as tgen_arithi.  */
346
static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
347
{
348
    tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3), dest, src);
349
}
350

    
351
static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
352
{
353
    if (arg != ret) {
354
        tcg_out_modrm(s, OPC_MOVL_GvEv, ret, arg);
355
    }
356
}
357

    
358
static inline void tcg_out_movi(TCGContext *s, TCGType type,
359
                                int ret, int32_t arg)
360
{
361
    if (arg == 0) {
362
        tgen_arithr(s, ARITH_XOR, ret, ret);
363
    } else {
364
        tcg_out8(s, OPC_MOVL_Iv + ret);
365
        tcg_out32(s, arg);
366
    }
367
}
368

    
369
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
370
{
371
    if (val == (int8_t)val) {
372
        tcg_out_opc(s, OPC_PUSH_Ib);
373
        tcg_out8(s, val);
374
    } else {
375
        tcg_out_opc(s, OPC_PUSH_Iv);
376
        tcg_out32(s, val);
377
    }
378
}
379

    
380
static inline void tcg_out_push(TCGContext *s, int reg)
381
{
382
    tcg_out_opc(s, OPC_PUSH_r32 + reg);
383
}
384

    
385
static inline void tcg_out_pop(TCGContext *s, int reg)
386
{
387
    tcg_out_opc(s, OPC_POP_r32 + reg);
388
}
389

    
390
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
391
                              int arg1, tcg_target_long arg2)
392
{
393
    tcg_out_modrm_offset(s, OPC_MOVL_GvEv, ret, arg1, arg2);
394
}
395

    
396
static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
397
                              int arg1, tcg_target_long arg2)
398
{
399
    tcg_out_modrm_offset(s, OPC_MOVL_EvGv, arg, arg1, arg2);
400
}
401

    
402
static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
403
{
404
    /* Propagate an opcode prefix, such as P_DATA16.  */
405
    int ext = subopc & ~0x7;
406
    subopc &= 0x7;
407

    
408
    if (count == 1) {
409
        tcg_out_modrm(s, OPC_SHIFT_1 | ext, subopc, reg);
410
    } else {
411
        tcg_out_modrm(s, OPC_SHIFT_Ib | ext, subopc, reg);
412
        tcg_out8(s, count);
413
    }
414
}
415

    
416
static inline void tcg_out_bswap32(TCGContext *s, int reg)
417
{
418
    tcg_out_opc(s, OPC_BSWAP + reg);
419
}
420

    
421
static inline void tcg_out_rolw_8(TCGContext *s, int reg)
422
{
423
    tcg_out_shifti(s, SHIFT_ROL | P_DATA16, reg, 8);
424
}
425

    
426
static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
427
{
428
    /* movzbl */
429
    assert(src < 4);
430
    tcg_out_modrm(s, OPC_MOVZBL, dest, src);
431
}
432

    
433
static void tcg_out_ext8s(TCGContext *s, int dest, int src)
434
{
435
    /* movsbl */
436
    assert(src < 4);
437
    tcg_out_modrm(s, OPC_MOVSBL, dest, src);
438
}
439

    
440
static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
441
{
442
    /* movzwl */
443
    tcg_out_modrm(s, OPC_MOVZWL, dest, src);
444
}
445

    
446
static inline void tcg_out_ext16s(TCGContext *s, int dest, int src)
447
{
448
    /* movswl */
449
    tcg_out_modrm(s, OPC_MOVSWL, dest, src);
450
}
451

    
452
static inline void tgen_arithi(TCGContext *s, int c, int r0,
453
                               int32_t val, int cf)
454
{
455
    /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
456
       partial flags update stalls on Pentium4 and are not recommended
457
       by current Intel optimization manuals.  */
458
    if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
459
        int opc = ((c == ARITH_ADD) ^ (val < 0) ? OPC_INC_r32 : OPC_DEC_r32);
460
        tcg_out_opc(s, opc + r0);
461
    } else if (val == (int8_t)val) {
462
        tcg_out_modrm(s, OPC_ARITH_EvIb, c, r0);
463
        tcg_out8(s, val);
464
    } else if (c == ARITH_AND && val == 0xffu && r0 < 4) {
465
        tcg_out_ext8u(s, r0, r0);
466
    } else if (c == ARITH_AND && val == 0xffffu) {
467
        tcg_out_ext16u(s, r0, r0);
468
    } else {
469
        tcg_out_modrm(s, OPC_ARITH_EvIz, c, r0);
470
        tcg_out32(s, val);
471
    }
472
}
473

    
474
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
475
{
476
    if (val != 0)
477
        tgen_arithi(s, ARITH_ADD, reg, val, 0);
478
}
479

    
480
/* Use SMALL != 0 to force a short forward branch.  */
481
static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
482
{
483
    int32_t val, val1;
484
    TCGLabel *l = &s->labels[label_index];
485

    
486
    if (l->has_value) {
487
        val = l->u.value - (tcg_target_long)s->code_ptr;
488
        val1 = val - 2;
489
        if ((int8_t)val1 == val1) {
490
            if (opc == -1) {
491
                tcg_out8(s, OPC_JMP_short);
492
            } else {
493
                tcg_out8(s, OPC_JCC_short + opc);
494
            }
495
            tcg_out8(s, val1);
496
        } else {
497
            if (small) {
498
                tcg_abort();
499
            }
500
            if (opc == -1) {
501
                tcg_out8(s, OPC_JMP_long);
502
                tcg_out32(s, val - 5);
503
            } else {
504
                tcg_out_opc(s, OPC_JCC_long + opc);
505
                tcg_out32(s, val - 6);
506
            }
507
        }
508
    } else if (small) {
509
        if (opc == -1) {
510
            tcg_out8(s, OPC_JMP_short);
511
        } else {
512
            tcg_out8(s, OPC_JCC_short + opc);
513
        }
514
        tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
515
        s->code_ptr += 1;
516
    } else {
517
        if (opc == -1) {
518
            tcg_out8(s, OPC_JMP_long);
519
        } else {
520
            tcg_out_opc(s, OPC_JCC_long + opc);
521
        }
522
        tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
523
        s->code_ptr += 4;
524
    }
525
}
526

    
527
static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
528
                        int const_arg2)
529
{
530
    if (const_arg2) {
531
        if (arg2 == 0) {
532
            /* test r, r */
533
            tcg_out_modrm(s, OPC_TESTL, arg1, arg1);
534
        } else {
535
            tgen_arithi(s, ARITH_CMP, arg1, arg2, 0);
536
        }
537
    } else {
538
        tgen_arithr(s, ARITH_CMP, arg1, arg2);
539
    }
540
}
541

    
542
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
543
                           TCGArg arg1, TCGArg arg2, int const_arg2,
544
                           int label_index, int small)
545
{
546
    tcg_out_cmp(s, arg1, arg2, const_arg2);
547
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
548
}
549

    
550
/* XXX: we implement it at the target level to avoid having to
551
   handle cross basic blocks temporaries */
552
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
553
                            const int *const_args, int small)
554
{
555
    int label_next;
556
    label_next = gen_new_label();
557
    switch(args[4]) {
558
    case TCG_COND_EQ:
559
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
560
                       label_next, 1);
561
        tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3],
562
                       args[5], small);
563
        break;
564
    case TCG_COND_NE:
565
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
566
                       args[5], small);
567
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3],
568
                       args[5], small);
569
        break;
570
    case TCG_COND_LT:
571
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
572
                       args[5], small);
573
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
574
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
575
                       args[5], small);
576
        break;
577
    case TCG_COND_LE:
578
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
579
                       args[5], small);
580
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
581
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
582
                       args[5], small);
583
        break;
584
    case TCG_COND_GT:
585
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
586
                       args[5], small);
587
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
588
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
589
                       args[5], small);
590
        break;
591
    case TCG_COND_GE:
592
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
593
                       args[5], small);
594
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
595
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
596
                       args[5], small);
597
        break;
598
    case TCG_COND_LTU:
599
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
600
                       args[5], small);
601
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
602
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
603
                       args[5], small);
604
        break;
605
    case TCG_COND_LEU:
606
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
607
                       args[5], small);
608
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
609
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
610
                       args[5], small);
611
        break;
612
    case TCG_COND_GTU:
613
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
614
                       args[5], small);
615
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
616
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
617
                       args[5], small);
618
        break;
619
    case TCG_COND_GEU:
620
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
621
                       args[5], small);
622
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
623
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
624
                       args[5], small);
625
        break;
626
    default:
627
        tcg_abort();
628
    }
629
    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
630
}
631

    
632
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGArg dest,
633
                            TCGArg arg1, TCGArg arg2, int const_arg2)
634
{
635
    tcg_out_cmp(s, arg1, arg2, const_arg2);
636
    tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
637
    tcg_out_ext8u(s, dest, dest);
638
}
639

    
640
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
641
                             const int *const_args)
642
{
643
    TCGArg new_args[6];
644
    int label_true, label_over;
645

    
646
    memcpy(new_args, args+1, 5*sizeof(TCGArg));
647

    
648
    if (args[0] == args[1] || args[0] == args[2]
649
        || (!const_args[3] && args[0] == args[3])
650
        || (!const_args[4] && args[0] == args[4])) {
651
        /* When the destination overlaps with one of the argument
652
           registers, don't do anything tricky.  */
653
        label_true = gen_new_label();
654
        label_over = gen_new_label();
655

    
656
        new_args[5] = label_true;
657
        tcg_out_brcond2(s, new_args, const_args+1, 1);
658

    
659
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
660
        tcg_out_jxx(s, JCC_JMP, label_over, 1);
661
        tcg_out_label(s, label_true, (tcg_target_long)s->code_ptr);
662

    
663
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
664
        tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
665
    } else {
666
        /* When the destination does not overlap one of the arguments,
667
           clear the destination first, jump if cond false, and emit an
668
           increment in the true case.  This results in smaller code.  */
669

    
670
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
671

    
672
        label_over = gen_new_label();
673
        new_args[4] = tcg_invert_cond(new_args[4]);
674
        new_args[5] = label_over;
675
        tcg_out_brcond2(s, new_args, const_args+1, 1);
676

    
677
        tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
678
        tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
679
    }
680
}
681

    
682
static void tcg_out_calli(TCGContext *s, tcg_target_long dest)
683
{
684
    tcg_out_opc(s, OPC_CALL_Jz);
685
    tcg_out32(s, dest - (tcg_target_long)s->code_ptr - 4);
686
}
687

    
688
#if defined(CONFIG_SOFTMMU)
689

    
690
#include "../../softmmu_defs.h"
691

    
692
static void *qemu_ld_helpers[4] = {
693
    __ldb_mmu,
694
    __ldw_mmu,
695
    __ldl_mmu,
696
    __ldq_mmu,
697
};
698

    
699
static void *qemu_st_helpers[4] = {
700
    __stb_mmu,
701
    __stw_mmu,
702
    __stl_mmu,
703
    __stq_mmu,
704
};
705
#endif
706

    
707
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
708
                                   int base, tcg_target_long ofs, int sizeop)
709
{
710
#ifdef TARGET_WORDS_BIGENDIAN
711
    const int bswap = 1;
712
#else
713
    const int bswap = 0;
714
#endif
715
    switch (sizeop) {
716
    case 0:
717
        /* movzbl */
718
        tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
719
        break;
720
    case 0 | 4:
721
        /* movsbl */
722
        tcg_out_modrm_offset(s, OPC_MOVSBL, datalo, base, ofs);
723
        break;
724
    case 1:
725
        /* movzwl */
726
        tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
727
        if (bswap) {
728
            tcg_out_rolw_8(s, datalo);
729
        }
730
        break;
731
    case 1 | 4:
732
        /* movswl */
733
        tcg_out_modrm_offset(s, OPC_MOVSWL, datalo, base, ofs);
734
        if (bswap) {
735
            tcg_out_rolw_8(s, datalo);
736
            tcg_out_modrm(s, OPC_MOVSWL, datalo, datalo);
737
        }
738
        break;
739
    case 2:
740
        tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
741
        if (bswap) {
742
            tcg_out_bswap32(s, datalo);
743
        }
744
        break;
745
    case 3:
746
        if (bswap) {
747
            int t = datalo;
748
            datalo = datahi;
749
            datahi = t;
750
        }
751
        if (base != datalo) {
752
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
753
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
754
        } else {
755
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
756
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
757
        }
758
        if (bswap) {
759
            tcg_out_bswap32(s, datalo);
760
            tcg_out_bswap32(s, datahi);
761
        }
762
        break;
763
    default:
764
        tcg_abort();
765
    }
766
}
767

    
768
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
769
   EAX. It will be useful once fixed registers globals are less
770
   common. */
771
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
772
                            int opc)
773
{
774
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
775
#if defined(CONFIG_SOFTMMU)
776
    uint8_t *label1_ptr, *label2_ptr;
777
#endif
778
#if TARGET_LONG_BITS == 64
779
#if defined(CONFIG_SOFTMMU)
780
    uint8_t *label3_ptr;
781
#endif
782
    int addr_reg2;
783
#endif
784

    
785
    data_reg = *args++;
786
    if (opc == 3)
787
        data_reg2 = *args++;
788
    else
789
        data_reg2 = 0;
790
    addr_reg = *args++;
791
#if TARGET_LONG_BITS == 64
792
    addr_reg2 = *args++;
793
#endif
794
    mem_index = *args;
795
    s_bits = opc & 3;
796

    
797
    r0 = TCG_REG_EAX;
798
    r1 = TCG_REG_EDX;
799

    
800
#if defined(CONFIG_SOFTMMU)
801
    tcg_out_mov(s, r1, addr_reg);
802
    tcg_out_mov(s, r0, addr_reg);
803

    
804
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
805

    
806
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
807
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
808

    
809
    tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
810
                             offsetof(CPUState,
811
                                      tlb_table[mem_index][0].addr_read));
812

    
813
    /* cmp 0(r1), r0 */
814
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
815

    
816
    tcg_out_mov(s, r0, addr_reg);
817

    
818
#if TARGET_LONG_BITS == 32
819
    /* je label1 */
820
    tcg_out8(s, OPC_JCC_short + JCC_JE);
821
    label1_ptr = s->code_ptr;
822
    s->code_ptr++;
823
#else
824
    /* jne label3 */
825
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
826
    label3_ptr = s->code_ptr;
827
    s->code_ptr++;
828

    
829
    /* cmp 4(r1), addr_reg2 */
830
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
831

    
832
    /* je label1 */
833
    tcg_out8(s, OPC_JCC_short + JCC_JE);
834
    label1_ptr = s->code_ptr;
835
    s->code_ptr++;
836

    
837
    /* label3: */
838
    *label3_ptr = s->code_ptr - label3_ptr - 1;
839
#endif
840

    
841
    /* XXX: move that code at the end of the TB */
842
#if TARGET_LONG_BITS == 32
843
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
844
#else
845
    tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
846
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
847
#endif
848
    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
849

    
850
    switch(opc) {
851
    case 0 | 4:
852
        tcg_out_ext8s(s, data_reg, TCG_REG_EAX);
853
        break;
854
    case 1 | 4:
855
        tcg_out_ext16s(s, data_reg, TCG_REG_EAX);
856
        break;
857
    case 0:
858
        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
859
        break;
860
    case 1:
861
        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
862
        break;
863
    case 2:
864
    default:
865
        tcg_out_mov(s, data_reg, TCG_REG_EAX);
866
        break;
867
    case 3:
868
        if (data_reg == TCG_REG_EDX) {
869
            /* xchg %edx, %eax */
870
            tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX);
871
            tcg_out_mov(s, data_reg2, TCG_REG_EAX);
872
        } else {
873
            tcg_out_mov(s, data_reg, TCG_REG_EAX);
874
            tcg_out_mov(s, data_reg2, TCG_REG_EDX);
875
        }
876
        break;
877
    }
878

    
879
    /* jmp label2 */
880
    tcg_out8(s, OPC_JMP_short);
881
    label2_ptr = s->code_ptr;
882
    s->code_ptr++;
883

    
884
    /* label1: */
885
    *label1_ptr = s->code_ptr - label1_ptr - 1;
886

    
887
    /* add x(r1), r0 */
888
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
889
                         offsetof(CPUTLBEntry, addend) -
890
                         offsetof(CPUTLBEntry, addr_read));
891

    
892
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, r0, 0, opc);
893

    
894
    /* label2: */
895
    *label2_ptr = s->code_ptr - label2_ptr - 1;
896
#else
897
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
898
#endif
899
}
900

    
901
static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
902
                                   int base, tcg_target_long ofs, int sizeop)
903
{
904
#ifdef TARGET_WORDS_BIGENDIAN
905
    const int bswap = 1;
906
#else
907
    const int bswap = 0;
908
#endif
909
    /* ??? Ideally we wouldn't need a scratch register.  For user-only,
910
       we could perform the bswap twice to restore the original value
911
       instead of moving to the scratch.  But as it is, the L constraint
912
       means that EDX is definitely free here.  */
913
    int scratch = TCG_REG_EDX;
914

    
915
    switch (sizeop) {
916
    case 0:
917
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, datalo, base, ofs);
918
        break;
919
    case 1:
920
        if (bswap) {
921
            tcg_out_mov(s, scratch, datalo);
922
            tcg_out_rolw_8(s, scratch);
923
            datalo = scratch;
924
        }
925
        /* movw */
926
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
927
                             datalo, base, ofs);
928
        break;
929
    case 2:
930
        if (bswap) {
931
            tcg_out_mov(s, scratch, datalo);
932
            tcg_out_bswap32(s, scratch);
933
            datalo = scratch;
934
        }
935
        tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
936
        break;
937
    case 3:
938
        if (bswap) {
939
            tcg_out_mov(s, scratch, datahi);
940
            tcg_out_bswap32(s, scratch);
941
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
942
            tcg_out_mov(s, scratch, datalo);
943
            tcg_out_bswap32(s, scratch);
944
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
945
        } else {
946
            tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
947
            tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
948
        }
949
        break;
950
    default:
951
        tcg_abort();
952
    }
953
}
954

    
955
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
956
                            int opc)
957
{
958
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
959
#if defined(CONFIG_SOFTMMU)
960
    int stack_adjust;
961
    uint8_t *label1_ptr, *label2_ptr;
962
#endif
963
#if TARGET_LONG_BITS == 64
964
#if defined(CONFIG_SOFTMMU)
965
    uint8_t *label3_ptr;
966
#endif
967
    int addr_reg2;
968
#endif
969

    
970
    data_reg = *args++;
971
    if (opc == 3)
972
        data_reg2 = *args++;
973
    else
974
        data_reg2 = 0;
975
    addr_reg = *args++;
976
#if TARGET_LONG_BITS == 64
977
    addr_reg2 = *args++;
978
#endif
979
    mem_index = *args;
980

    
981
    s_bits = opc;
982

    
983
    r0 = TCG_REG_EAX;
984
    r1 = TCG_REG_EDX;
985

    
986
#if defined(CONFIG_SOFTMMU)
987
    tcg_out_mov(s, r1, addr_reg);
988
    tcg_out_mov(s, r0, addr_reg);
989

    
990
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
991

    
992
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
993
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
994

    
995
    tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
996
                             offsetof(CPUState,
997
                                      tlb_table[mem_index][0].addr_write));
998

    
999
    /* cmp 0(r1), r0 */
1000
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
1001

    
1002
    tcg_out_mov(s, r0, addr_reg);
1003

    
1004
#if TARGET_LONG_BITS == 32
1005
    /* je label1 */
1006
    tcg_out8(s, OPC_JCC_short + JCC_JE);
1007
    label1_ptr = s->code_ptr;
1008
    s->code_ptr++;
1009
#else
1010
    /* jne label3 */
1011
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
1012
    label3_ptr = s->code_ptr;
1013
    s->code_ptr++;
1014

    
1015
    /* cmp 4(r1), addr_reg2 */
1016
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
1017

    
1018
    /* je label1 */
1019
    tcg_out8(s, OPC_JCC_short + JCC_JE);
1020
    label1_ptr = s->code_ptr;
1021
    s->code_ptr++;
1022

    
1023
    /* label3: */
1024
    *label3_ptr = s->code_ptr - label3_ptr - 1;
1025
#endif
1026

    
1027
    /* XXX: move that code at the end of the TB */
1028
#if TARGET_LONG_BITS == 32
1029
    if (opc == 3) {
1030
        tcg_out_mov(s, TCG_REG_EDX, data_reg);
1031
        tcg_out_mov(s, TCG_REG_ECX, data_reg2);
1032
        tcg_out_pushi(s, mem_index);
1033
        stack_adjust = 4;
1034
    } else {
1035
        switch(opc) {
1036
        case 0:
1037
            tcg_out_ext8u(s, TCG_REG_EDX, data_reg);
1038
            break;
1039
        case 1:
1040
            tcg_out_ext16u(s, TCG_REG_EDX, data_reg);
1041
            break;
1042
        case 2:
1043
            tcg_out_mov(s, TCG_REG_EDX, data_reg);
1044
            break;
1045
        }
1046
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
1047
        stack_adjust = 0;
1048
    }
1049
#else
1050
    if (opc == 3) {
1051
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
1052
        tcg_out_pushi(s, mem_index);
1053
        tcg_out_push(s, data_reg2);
1054
        tcg_out_push(s, data_reg);
1055
        stack_adjust = 12;
1056
    } else {
1057
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
1058
        switch(opc) {
1059
        case 0:
1060
            tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
1061
            break;
1062
        case 1:
1063
            tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
1064
            break;
1065
        case 2:
1066
            tcg_out_mov(s, TCG_REG_ECX, data_reg);
1067
            break;
1068
        }
1069
        tcg_out_pushi(s, mem_index);
1070
        stack_adjust = 4;
1071
    }
1072
#endif
1073

    
1074
    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1075

    
1076
    if (stack_adjust == 4) {
1077
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
1078
        tcg_out_pop(s, TCG_REG_ECX);
1079
    } else if (stack_adjust != 0) {
1080
        tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
1081
    }
1082

    
1083
    /* jmp label2 */
1084
    tcg_out8(s, OPC_JMP_short);
1085
    label2_ptr = s->code_ptr;
1086
    s->code_ptr++;
1087

    
1088
    /* label1: */
1089
    *label1_ptr = s->code_ptr - label1_ptr - 1;
1090

    
1091
    /* add x(r1), r0 */
1092
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
1093
                         offsetof(CPUTLBEntry, addend) -
1094
                         offsetof(CPUTLBEntry, addr_write));
1095

    
1096
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, r0, 0, opc);
1097

    
1098
    /* label2: */
1099
    *label2_ptr = s->code_ptr - label2_ptr - 1;
1100
#else
1101
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
1102
#endif
1103
}
1104

    
1105
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1106
                              const TCGArg *args, const int *const_args)
1107
{
1108
    int c;
1109

    
1110
    switch(opc) {
1111
    case INDEX_op_exit_tb:
1112
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
1113
        tcg_out8(s, OPC_JMP_long); /* jmp tb_ret_addr */
1114
        tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
1115
        break;
1116
    case INDEX_op_goto_tb:
1117
        if (s->tb_jmp_offset) {
1118
            /* direct jump method */
1119
            tcg_out8(s, OPC_JMP_long); /* jmp im */
1120
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1121
            tcg_out32(s, 0);
1122
        } else {
1123
            /* indirect jump method */
1124
            tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1125
                                 (tcg_target_long)(s->tb_next + args[0]));
1126
        }
1127
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1128
        break;
1129
    case INDEX_op_call:
1130
        if (const_args[0]) {
1131
            tcg_out_calli(s, args[0]);
1132
        } else {
1133
            /* call *reg */
1134
            tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1135
        }
1136
        break;
1137
    case INDEX_op_jmp:
1138
        if (const_args[0]) {
1139
            tcg_out8(s, OPC_JMP_long);
1140
            tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
1141
        } else {
1142
            /* jmp *reg */
1143
            tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1144
        }
1145
        break;
1146
    case INDEX_op_br:
1147
        tcg_out_jxx(s, JCC_JMP, args[0], 0);
1148
        break;
1149
    case INDEX_op_movi_i32:
1150
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1151
        break;
1152
    case INDEX_op_ld8u_i32:
1153
        /* movzbl */
1154
        tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
1155
        break;
1156
    case INDEX_op_ld8s_i32:
1157
        /* movsbl */
1158
        tcg_out_modrm_offset(s, OPC_MOVSBL, args[0], args[1], args[2]);
1159
        break;
1160
    case INDEX_op_ld16u_i32:
1161
        /* movzwl */
1162
        tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1163
        break;
1164
    case INDEX_op_ld16s_i32:
1165
        /* movswl */
1166
        tcg_out_modrm_offset(s, OPC_MOVSWL, args[0], args[1], args[2]);
1167
        break;
1168
    case INDEX_op_ld_i32:
1169
        tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1170
        break;
1171
    case INDEX_op_st8_i32:
1172
        /* movb */
1173
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, args[0], args[1], args[2]);
1174
        break;
1175
    case INDEX_op_st16_i32:
1176
        /* movw */
1177
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1178
                             args[0], args[1], args[2]);
1179
        break;
1180
    case INDEX_op_st_i32:
1181
        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1182
        break;
1183
    case INDEX_op_add_i32:
1184
        /* For 3-operand addition, use LEA.  */
1185
        if (args[0] != args[1]) {
1186
            TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1187

    
1188
            if (const_args[2]) {
1189
                c3 = a2, a2 = -1;
1190
            } else if (a0 == a2) {
1191
                /* Watch out for dest = src + dest, since we've removed
1192
                   the matching constraint on the add.  */
1193
                tgen_arithr(s, ARITH_ADD, a0, a1);
1194
                break;
1195
            }
1196

    
1197
            tcg_out_modrm_sib_offset(s, OPC_LEA, a0, a1, a2, 0, c3);
1198
            break;
1199
        }
1200
        c = ARITH_ADD;
1201
        goto gen_arith;
1202
    case INDEX_op_sub_i32:
1203
        c = ARITH_SUB;
1204
        goto gen_arith;
1205
    case INDEX_op_and_i32:
1206
        c = ARITH_AND;
1207
        goto gen_arith;
1208
    case INDEX_op_or_i32:
1209
        c = ARITH_OR;
1210
        goto gen_arith;
1211
    case INDEX_op_xor_i32:
1212
        c = ARITH_XOR;
1213
        goto gen_arith;
1214
    gen_arith:
1215
        if (const_args[2]) {
1216
            tgen_arithi(s, c, args[0], args[2], 0);
1217
        } else {
1218
            tgen_arithr(s, c, args[0], args[2]);
1219
        }
1220
        break;
1221
    case INDEX_op_mul_i32:
1222
        if (const_args[2]) {
1223
            int32_t val;
1224
            val = args[2];
1225
            if (val == (int8_t)val) {
1226
                tcg_out_modrm(s, OPC_IMUL_GvEvIb, args[0], args[0]);
1227
                tcg_out8(s, val);
1228
            } else {
1229
                tcg_out_modrm(s, OPC_IMUL_GvEvIz, args[0], args[0]);
1230
                tcg_out32(s, val);
1231
            }
1232
        } else {
1233
            tcg_out_modrm(s, OPC_IMUL_GvEv, args[0], args[2]);
1234
        }
1235
        break;
1236
    case INDEX_op_mulu2_i32:
1237
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1238
        break;
1239
    case INDEX_op_div2_i32:
1240
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_IDIV, args[4]);
1241
        break;
1242
    case INDEX_op_divu2_i32:
1243
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_DIV, args[4]);
1244
        break;
1245
    case INDEX_op_shl_i32:
1246
        c = SHIFT_SHL;
1247
    gen_shift32:
1248
        if (const_args[2]) {
1249
            tcg_out_shifti(s, c, args[0], args[2]);
1250
        } else {
1251
            tcg_out_modrm(s, OPC_SHIFT_cl, c, args[0]);
1252
        }
1253
        break;
1254
    case INDEX_op_shr_i32:
1255
        c = SHIFT_SHR;
1256
        goto gen_shift32;
1257
    case INDEX_op_sar_i32:
1258
        c = SHIFT_SAR;
1259
        goto gen_shift32;
1260
    case INDEX_op_rotl_i32:
1261
        c = SHIFT_ROL;
1262
        goto gen_shift32;
1263
    case INDEX_op_rotr_i32:
1264
        c = SHIFT_ROR;
1265
        goto gen_shift32;
1266

    
1267
    case INDEX_op_add2_i32:
1268
        if (const_args[4]) {
1269
            tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1270
        } else {
1271
            tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1272
        }
1273
        if (const_args[5]) {
1274
            tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1275
        } else {
1276
            tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1277
        }
1278
        break;
1279
    case INDEX_op_sub2_i32:
1280
        if (const_args[4]) {
1281
            tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1282
        } else {
1283
            tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1284
        }
1285
        if (const_args[5]) {
1286
            tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1287
        } else {
1288
            tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1289
        }
1290
        break;
1291
    case INDEX_op_brcond_i32:
1292
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1293
                       args[3], 0);
1294
        break;
1295
    case INDEX_op_brcond2_i32:
1296
        tcg_out_brcond2(s, args, const_args, 0);
1297
        break;
1298

    
1299
    case INDEX_op_bswap16_i32:
1300
        tcg_out_rolw_8(s, args[0]);
1301
        break;
1302
    case INDEX_op_bswap32_i32:
1303
        tcg_out_bswap32(s, args[0]);
1304
        break;
1305

    
1306
    case INDEX_op_neg_i32:
1307
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, args[0]);
1308
        break;
1309

    
1310
    case INDEX_op_not_i32:
1311
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NOT, args[0]);
1312
        break;
1313

    
1314
    case INDEX_op_ext8s_i32:
1315
        tcg_out_ext8s(s, args[0], args[1]);
1316
        break;
1317
    case INDEX_op_ext16s_i32:
1318
        tcg_out_ext16s(s, args[0], args[1]);
1319
        break;
1320
    case INDEX_op_ext8u_i32:
1321
        tcg_out_ext8u(s, args[0], args[1]);
1322
        break;
1323
    case INDEX_op_ext16u_i32:
1324
        tcg_out_ext16u(s, args[0], args[1]);
1325
        break;
1326

    
1327
    case INDEX_op_setcond_i32:
1328
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
1329
        break;
1330
    case INDEX_op_setcond2_i32:
1331
        tcg_out_setcond2(s, args, const_args);
1332
        break;
1333

    
1334
    case INDEX_op_qemu_ld8u:
1335
        tcg_out_qemu_ld(s, args, 0);
1336
        break;
1337
    case INDEX_op_qemu_ld8s:
1338
        tcg_out_qemu_ld(s, args, 0 | 4);
1339
        break;
1340
    case INDEX_op_qemu_ld16u:
1341
        tcg_out_qemu_ld(s, args, 1);
1342
        break;
1343
    case INDEX_op_qemu_ld16s:
1344
        tcg_out_qemu_ld(s, args, 1 | 4);
1345
        break;
1346
    case INDEX_op_qemu_ld32:
1347
        tcg_out_qemu_ld(s, args, 2);
1348
        break;
1349
    case INDEX_op_qemu_ld64:
1350
        tcg_out_qemu_ld(s, args, 3);
1351
        break;
1352

    
1353
    case INDEX_op_qemu_st8:
1354
        tcg_out_qemu_st(s, args, 0);
1355
        break;
1356
    case INDEX_op_qemu_st16:
1357
        tcg_out_qemu_st(s, args, 1);
1358
        break;
1359
    case INDEX_op_qemu_st32:
1360
        tcg_out_qemu_st(s, args, 2);
1361
        break;
1362
    case INDEX_op_qemu_st64:
1363
        tcg_out_qemu_st(s, args, 3);
1364
        break;
1365

    
1366
    default:
1367
        tcg_abort();
1368
    }
1369
}
1370

    
1371
static const TCGTargetOpDef x86_op_defs[] = {
1372
    { INDEX_op_exit_tb, { } },
1373
    { INDEX_op_goto_tb, { } },
1374
    { INDEX_op_call, { "ri" } },
1375
    { INDEX_op_jmp, { "ri" } },
1376
    { INDEX_op_br, { } },
1377
    { INDEX_op_mov_i32, { "r", "r" } },
1378
    { INDEX_op_movi_i32, { "r" } },
1379
    { INDEX_op_ld8u_i32, { "r", "r" } },
1380
    { INDEX_op_ld8s_i32, { "r", "r" } },
1381
    { INDEX_op_ld16u_i32, { "r", "r" } },
1382
    { INDEX_op_ld16s_i32, { "r", "r" } },
1383
    { INDEX_op_ld_i32, { "r", "r" } },
1384
    { INDEX_op_st8_i32, { "q", "r" } },
1385
    { INDEX_op_st16_i32, { "r", "r" } },
1386
    { INDEX_op_st_i32, { "r", "r" } },
1387

    
1388
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1389
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1390
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1391
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1392
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1393
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1394
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1395
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1396
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1397

    
1398
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1399
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1400
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1401
    { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1402
    { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1403

    
1404
    { INDEX_op_brcond_i32, { "r", "ri" } },
1405

    
1406
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1407
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1408
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1409

    
1410
    { INDEX_op_bswap16_i32, { "r", "0" } },
1411
    { INDEX_op_bswap32_i32, { "r", "0" } },
1412

    
1413
    { INDEX_op_neg_i32, { "r", "0" } },
1414

    
1415
    { INDEX_op_not_i32, { "r", "0" } },
1416

    
1417
    { INDEX_op_ext8s_i32, { "r", "q" } },
1418
    { INDEX_op_ext16s_i32, { "r", "r" } },
1419
    { INDEX_op_ext8u_i32, { "r", "q" } },
1420
    { INDEX_op_ext16u_i32, { "r", "r" } },
1421

    
1422
    { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1423
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1424

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

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

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

    
1453
static int tcg_target_callee_save_regs[] = {
1454
    /*    TCG_REG_EBP, */ /* currently used for the global env, so no
1455
                             need to save */
1456
    TCG_REG_EBX,
1457
    TCG_REG_ESI,
1458
    TCG_REG_EDI,
1459
};
1460

    
1461
/* Generate global QEMU prologue and epilogue code */
1462
void tcg_target_qemu_prologue(TCGContext *s)
1463
{
1464
    int i, frame_size, push_size, stack_addend;
1465

    
1466
    /* TB prologue */
1467
    /* save all callee saved registers */
1468
    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1469
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
1470
    }
1471
    /* reserve some stack space */
1472
    push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1473
    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1474
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1475
        ~(TCG_TARGET_STACK_ALIGN - 1);
1476
    stack_addend = frame_size - push_size;
1477
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1478

    
1479
    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
1480

    
1481
    /* TB epilogue */
1482
    tb_ret_addr = s->code_ptr;
1483
    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1484
    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1485
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1486
    }
1487
    tcg_out_opc(s, OPC_RET);
1488
}
1489

    
1490
void tcg_target_init(TCGContext *s)
1491
{
1492
#if !defined(CONFIG_USER_ONLY)
1493
    /* fail safe */
1494
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1495
        tcg_abort();
1496
#endif
1497

    
1498
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1499

    
1500
    tcg_regset_clear(tcg_target_call_clobber_regs);
1501
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1502
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1503
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
1504

    
1505
    tcg_regset_clear(s->reserved_regs);
1506
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1507

    
1508
    tcg_add_target_add_op_defs(x86_op_defs);
1509
}