Statistics
| Branch: | Revision:

root / tcg / i386 / tcg-target.c @ 9363dedb

History | View | Annotate | Download (41.4 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

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

    
193
#define OPC_GRP3_Ev        (0xf7)
194
#define OPC_GRP5        (0xff)
195

    
196
/* Group 1 opcode extensions for 0x80-0x83.
197
   These are also used as modifiers for OPC_ARITH.  */
198
#define ARITH_ADD 0
199
#define ARITH_OR  1
200
#define ARITH_ADC 2
201
#define ARITH_SBB 3
202
#define ARITH_AND 4
203
#define ARITH_SUB 5
204
#define ARITH_XOR 6
205
#define ARITH_CMP 7
206

    
207
/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3.  */
208
#define SHIFT_ROL 0
209
#define SHIFT_ROR 1
210
#define SHIFT_SHL 4
211
#define SHIFT_SHR 5
212
#define SHIFT_SAR 7
213

    
214
/* Group 3 opcode extensions for 0xf6, 0xf7.  To be used with OPC_GRP3.  */
215
#define EXT3_NOT   2
216
#define EXT3_NEG   3
217
#define EXT3_MUL   4
218
#define EXT3_IMUL  5
219
#define EXT3_DIV   6
220
#define EXT3_IDIV  7
221

    
222
/* Group 5 opcode extensions for 0xff.  To be used with OPC_GRP5.  */
223
#define EXT5_CALLN_Ev        2
224
#define EXT5_JMPN_Ev        4
225

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

    
245
static const uint8_t tcg_cond_to_jcc[10] = {
246
    [TCG_COND_EQ] = JCC_JE,
247
    [TCG_COND_NE] = JCC_JNE,
248
    [TCG_COND_LT] = JCC_JL,
249
    [TCG_COND_GE] = JCC_JGE,
250
    [TCG_COND_LE] = JCC_JLE,
251
    [TCG_COND_GT] = JCC_JG,
252
    [TCG_COND_LTU] = JCC_JB,
253
    [TCG_COND_GEU] = JCC_JAE,
254
    [TCG_COND_LEU] = JCC_JBE,
255
    [TCG_COND_GTU] = JCC_JA,
256
};
257

    
258
static inline void tcg_out_opc(TCGContext *s, int opc)
259
{
260
    if (opc & P_EXT)
261
        tcg_out8(s, 0x0f);
262
    tcg_out8(s, opc);
263
}
264

    
265
static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
266
{
267
    tcg_out_opc(s, opc);
268
    tcg_out8(s, 0xc0 | (r << 3) | rm);
269
}
270

    
271
/* rm == -1 means no register index */
272
static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm, 
273
                                        int32_t offset)
274
{
275
    tcg_out_opc(s, opc);
276
    if (rm == -1) {
277
        tcg_out8(s, 0x05 | (r << 3));
278
        tcg_out32(s, offset);
279
    } else if (offset == 0 && rm != TCG_REG_EBP) {
280
        if (rm == TCG_REG_ESP) {
281
            tcg_out8(s, 0x04 | (r << 3));
282
            tcg_out8(s, 0x24);
283
        } else {
284
            tcg_out8(s, 0x00 | (r << 3) | rm);
285
        }
286
    } else if ((int8_t)offset == offset) {
287
        if (rm == TCG_REG_ESP) {
288
            tcg_out8(s, 0x44 | (r << 3));
289
            tcg_out8(s, 0x24);
290
        } else {
291
            tcg_out8(s, 0x40 | (r << 3) | rm);
292
        }
293
        tcg_out8(s, offset);
294
    } else {
295
        if (rm == TCG_REG_ESP) {
296
            tcg_out8(s, 0x84 | (r << 3));
297
            tcg_out8(s, 0x24);
298
        } else {
299
            tcg_out8(s, 0x80 | (r << 3) | rm);
300
        }
301
        tcg_out32(s, offset);
302
    }
303
}
304

    
305
/* Generate dest op= src.  Uses the same ARITH_* codes as tgen_arithi.  */
306
static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
307
{
308
    tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3), dest, src);
309
}
310

    
311
static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
312
{
313
    if (arg != ret) {
314
        tcg_out_modrm(s, OPC_MOVL_GvEv, ret, arg);
315
    }
316
}
317

    
318
static inline void tcg_out_movi(TCGContext *s, TCGType type,
319
                                int ret, int32_t arg)
320
{
321
    if (arg == 0) {
322
        tgen_arithr(s, ARITH_XOR, ret, ret);
323
    } else {
324
        tcg_out8(s, OPC_MOVL_Iv + ret);
325
        tcg_out32(s, arg);
326
    }
327
}
328

    
329
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
330
{
331
    if (val == (int8_t)val) {
332
        tcg_out_opc(s, OPC_PUSH_Ib);
333
        tcg_out8(s, val);
334
    } else {
335
        tcg_out_opc(s, OPC_PUSH_Iv);
336
        tcg_out32(s, val);
337
    }
338
}
339

    
340
static inline void tcg_out_push(TCGContext *s, int reg)
341
{
342
    tcg_out_opc(s, OPC_PUSH_r32 + reg);
343
}
344

    
345
static inline void tcg_out_pop(TCGContext *s, int reg)
346
{
347
    tcg_out_opc(s, OPC_POP_r32 + reg);
348
}
349

    
350
static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
351
                              int arg1, tcg_target_long arg2)
352
{
353
    tcg_out_modrm_offset(s, OPC_MOVL_GvEv, ret, arg1, arg2);
354
}
355

    
356
static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
357
                              int arg1, tcg_target_long arg2)
358
{
359
    tcg_out_modrm_offset(s, OPC_MOVL_EvGv, arg, arg1, arg2);
360
}
361

    
362
static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
363
{
364
    if (count == 1) {
365
        tcg_out_modrm(s, OPC_SHIFT_1, subopc, reg);
366
    } else {
367
        tcg_out_modrm(s, OPC_SHIFT_Ib, subopc, reg);
368
        tcg_out8(s, count);
369
    }
370
}
371

    
372
static inline void tcg_out_bswap32(TCGContext *s, int reg)
373
{
374
    tcg_out_opc(s, OPC_BSWAP + reg);
375
}
376

    
377
static inline void tcg_out_rolw_8(TCGContext *s, int reg)
378
{
379
    tcg_out8(s, 0x66);
380
    tcg_out_shifti(s, SHIFT_ROL, reg, 8);
381
}
382

    
383
static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
384
{
385
    /* movzbl */
386
    assert(src < 4);
387
    tcg_out_modrm(s, OPC_MOVZBL, dest, src);
388
}
389

    
390
static void tcg_out_ext8s(TCGContext *s, int dest, int src)
391
{
392
    /* movsbl */
393
    assert(src < 4);
394
    tcg_out_modrm(s, OPC_MOVSBL, dest, src);
395
}
396

    
397
static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
398
{
399
    /* movzwl */
400
    tcg_out_modrm(s, OPC_MOVZWL, dest, src);
401
}
402

    
403
static inline void tcg_out_ext16s(TCGContext *s, int dest, int src)
404
{
405
    /* movswl */
406
    tcg_out_modrm(s, OPC_MOVSWL, dest, src);
407
}
408

    
409
static inline void tgen_arithi(TCGContext *s, int c, int r0,
410
                               int32_t val, int cf)
411
{
412
    /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
413
       partial flags update stalls on Pentium4 and are not recommended
414
       by current Intel optimization manuals.  */
415
    if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
416
        int opc = ((c == ARITH_ADD) ^ (val < 0) ? OPC_INC_r32 : OPC_DEC_r32);
417
        tcg_out_opc(s, opc + r0);
418
    } else if (val == (int8_t)val) {
419
        tcg_out_modrm(s, OPC_ARITH_EvIb, c, r0);
420
        tcg_out8(s, val);
421
    } else if (c == ARITH_AND && val == 0xffu && r0 < 4) {
422
        tcg_out_ext8u(s, r0, r0);
423
    } else if (c == ARITH_AND && val == 0xffffu) {
424
        tcg_out_ext16u(s, r0, r0);
425
    } else {
426
        tcg_out_modrm(s, OPC_ARITH_EvIz, c, r0);
427
        tcg_out32(s, val);
428
    }
429
}
430

    
431
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
432
{
433
    if (val != 0)
434
        tgen_arithi(s, ARITH_ADD, reg, val, 0);
435
}
436

    
437
/* Use SMALL != 0 to force a short forward branch.  */
438
static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
439
{
440
    int32_t val, val1;
441
    TCGLabel *l = &s->labels[label_index];
442
    
443
    if (l->has_value) {
444
        val = l->u.value - (tcg_target_long)s->code_ptr;
445
        val1 = val - 2;
446
        if ((int8_t)val1 == val1) {
447
            if (opc == -1) {
448
                tcg_out8(s, OPC_JMP_short);
449
            } else {
450
                tcg_out8(s, OPC_JCC_short + opc);
451
            }
452
            tcg_out8(s, val1);
453
        } else {
454
            if (small) {
455
                tcg_abort();
456
            }
457
            if (opc == -1) {
458
                tcg_out8(s, OPC_JMP_long);
459
                tcg_out32(s, val - 5);
460
            } else {
461
                tcg_out_opc(s, OPC_JCC_long + opc);
462
                tcg_out32(s, val - 6);
463
            }
464
        }
465
    } else if (small) {
466
        if (opc == -1) {
467
            tcg_out8(s, OPC_JMP_short);
468
        } else {
469
            tcg_out8(s, OPC_JCC_short + opc);
470
        }
471
        tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
472
        s->code_ptr += 1;
473
    } else {
474
        if (opc == -1) {
475
            tcg_out8(s, OPC_JMP_long);
476
        } else {
477
            tcg_out_opc(s, OPC_JCC_long + opc);
478
        }
479
        tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
480
        s->code_ptr += 4;
481
    }
482
}
483

    
484
static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
485
                        int const_arg2)
486
{
487
    if (const_arg2) {
488
        if (arg2 == 0) {
489
            /* test r, r */
490
            tcg_out_modrm(s, OPC_TESTL, arg1, arg1);
491
        } else {
492
            tgen_arithi(s, ARITH_CMP, arg1, arg2, 0);
493
        }
494
    } else {
495
        tgen_arithr(s, ARITH_CMP, arg1, arg2);
496
    }
497
}
498

    
499
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
500
                           TCGArg arg1, TCGArg arg2, int const_arg2,
501
                           int label_index, int small)
502
{
503
    tcg_out_cmp(s, arg1, arg2, const_arg2);
504
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
505
}
506

    
507
/* XXX: we implement it at the target level to avoid having to
508
   handle cross basic blocks temporaries */
509
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
510
                            const int *const_args, int small)
511
{
512
    int label_next;
513
    label_next = gen_new_label();
514
    switch(args[4]) {
515
    case TCG_COND_EQ:
516
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
517
                       label_next, 1);
518
        tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3],
519
                       args[5], small);
520
        break;
521
    case TCG_COND_NE:
522
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2],
523
                       args[5], small);
524
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3],
525
                       args[5], small);
526
        break;
527
    case TCG_COND_LT:
528
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
529
                       args[5], small);
530
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
531
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
532
                       args[5], small);
533
        break;
534
    case TCG_COND_LE:
535
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
536
                       args[5], small);
537
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
538
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
539
                       args[5], small);
540
        break;
541
    case TCG_COND_GT:
542
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
543
                       args[5], small);
544
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
545
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
546
                       args[5], small);
547
        break;
548
    case TCG_COND_GE:
549
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
550
                       args[5], small);
551
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
552
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
553
                       args[5], small);
554
        break;
555
    case TCG_COND_LTU:
556
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
557
                       args[5], small);
558
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
559
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
560
                       args[5], small);
561
        break;
562
    case TCG_COND_LEU:
563
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
564
                       args[5], small);
565
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
566
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
567
                       args[5], small);
568
        break;
569
    case TCG_COND_GTU:
570
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
571
                       args[5], small);
572
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
573
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
574
                       args[5], small);
575
        break;
576
    case TCG_COND_GEU:
577
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
578
                       args[5], small);
579
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
580
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
581
                       args[5], small);
582
        break;
583
    default:
584
        tcg_abort();
585
    }
586
    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
587
}
588

    
589
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGArg dest,
590
                            TCGArg arg1, TCGArg arg2, int const_arg2)
591
{
592
    tcg_out_cmp(s, arg1, arg2, const_arg2);
593
    tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
594
    tcg_out_ext8u(s, dest, dest);
595
}
596

    
597
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
598
                             const int *const_args)
599
{
600
    TCGArg new_args[6];
601
    int label_true, label_over;
602

    
603
    memcpy(new_args, args+1, 5*sizeof(TCGArg));
604

    
605
    if (args[0] == args[1] || args[0] == args[2]
606
        || (!const_args[3] && args[0] == args[3])
607
        || (!const_args[4] && args[0] == args[4])) {
608
        /* When the destination overlaps with one of the argument
609
           registers, don't do anything tricky.  */
610
        label_true = gen_new_label();
611
        label_over = gen_new_label();
612

    
613
        new_args[5] = label_true;
614
        tcg_out_brcond2(s, new_args, const_args+1, 1);
615

    
616
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
617
        tcg_out_jxx(s, JCC_JMP, label_over, 1);
618
        tcg_out_label(s, label_true, (tcg_target_long)s->code_ptr);
619

    
620
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
621
        tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
622
    } else {
623
        /* When the destination does not overlap one of the arguments,
624
           clear the destination first, jump if cond false, and emit an
625
           increment in the true case.  This results in smaller code.  */
626

    
627
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
628

    
629
        label_over = gen_new_label();
630
        new_args[4] = tcg_invert_cond(new_args[4]);
631
        new_args[5] = label_over;
632
        tcg_out_brcond2(s, new_args, const_args+1, 1);
633

    
634
        tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
635
        tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
636
    }
637
}
638

    
639
static void tcg_out_calli(TCGContext *s, tcg_target_long dest)
640
{
641
    tcg_out_opc(s, OPC_CALL_Jz);
642
    tcg_out32(s, dest - (tcg_target_long)s->code_ptr - 4);
643
}
644

    
645
#if defined(CONFIG_SOFTMMU)
646

    
647
#include "../../softmmu_defs.h"
648

    
649
static void *qemu_ld_helpers[4] = {
650
    __ldb_mmu,
651
    __ldw_mmu,
652
    __ldl_mmu,
653
    __ldq_mmu,
654
};
655

    
656
static void *qemu_st_helpers[4] = {
657
    __stb_mmu,
658
    __stw_mmu,
659
    __stl_mmu,
660
    __stq_mmu,
661
};
662
#endif
663

    
664
#ifndef CONFIG_USER_ONLY
665
#define GUEST_BASE 0
666
#endif
667

    
668
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
669
   EAX. It will be useful once fixed registers globals are less
670
   common. */
671
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
672
                            int opc)
673
{
674
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
675
#if defined(CONFIG_SOFTMMU)
676
    uint8_t *label1_ptr, *label2_ptr;
677
#endif
678
#if TARGET_LONG_BITS == 64
679
#if defined(CONFIG_SOFTMMU)
680
    uint8_t *label3_ptr;
681
#endif
682
    int addr_reg2;
683
#endif
684

    
685
    data_reg = *args++;
686
    if (opc == 3)
687
        data_reg2 = *args++;
688
    else
689
        data_reg2 = 0;
690
    addr_reg = *args++;
691
#if TARGET_LONG_BITS == 64
692
    addr_reg2 = *args++;
693
#endif
694
    mem_index = *args;
695
    s_bits = opc & 3;
696

    
697
    r0 = TCG_REG_EAX;
698
    r1 = TCG_REG_EDX;
699

    
700
#if defined(CONFIG_SOFTMMU)
701
    tcg_out_mov(s, r1, addr_reg); 
702
    tcg_out_mov(s, r0, addr_reg); 
703

    
704
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
705

    
706
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
707
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
708

    
709
    tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
710
    tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
711
    tcg_out8(s, (5 << 3) | r1);
712
    tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
713

    
714
    /* cmp 0(r1), r0 */
715
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
716
    
717
    tcg_out_mov(s, r0, addr_reg);
718
    
719
#if TARGET_LONG_BITS == 32
720
    /* je label1 */
721
    tcg_out8(s, OPC_JCC_short + JCC_JE);
722
    label1_ptr = s->code_ptr;
723
    s->code_ptr++;
724
#else
725
    /* jne label3 */
726
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
727
    label3_ptr = s->code_ptr;
728
    s->code_ptr++;
729
    
730
    /* cmp 4(r1), addr_reg2 */
731
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
732

    
733
    /* je label1 */
734
    tcg_out8(s, OPC_JCC_short + JCC_JE);
735
    label1_ptr = s->code_ptr;
736
    s->code_ptr++;
737
    
738
    /* label3: */
739
    *label3_ptr = s->code_ptr - label3_ptr - 1;
740
#endif
741

    
742
    /* XXX: move that code at the end of the TB */
743
#if TARGET_LONG_BITS == 32
744
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
745
#else
746
    tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
747
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
748
#endif
749
    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
750

    
751
    switch(opc) {
752
    case 0 | 4:
753
        tcg_out_ext8s(s, data_reg, TCG_REG_EAX);
754
        break;
755
    case 1 | 4:
756
        tcg_out_ext16s(s, data_reg, TCG_REG_EAX);
757
        break;
758
    case 0:
759
        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
760
        break;
761
    case 1:
762
        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
763
        break;
764
    case 2:
765
    default:
766
        tcg_out_mov(s, data_reg, TCG_REG_EAX);
767
        break;
768
    case 3:
769
        if (data_reg == TCG_REG_EDX) {
770
            tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */
771
            tcg_out_mov(s, data_reg2, TCG_REG_EAX);
772
        } else {
773
            tcg_out_mov(s, data_reg, TCG_REG_EAX);
774
            tcg_out_mov(s, data_reg2, TCG_REG_EDX);
775
        }
776
        break;
777
    }
778

    
779
    /* jmp label2 */
780
    tcg_out8(s, OPC_JMP_short);
781
    label2_ptr = s->code_ptr;
782
    s->code_ptr++;
783
    
784
    /* label1: */
785
    *label1_ptr = s->code_ptr - label1_ptr - 1;
786

    
787
    /* add x(r1), r0 */
788
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
789
                         offsetof(CPUTLBEntry, addend) -
790
                         offsetof(CPUTLBEntry, addr_read));
791
#else
792
    r0 = addr_reg;
793
#endif
794

    
795
#ifdef TARGET_WORDS_BIGENDIAN
796
    bswap = 1;
797
#else
798
    bswap = 0;
799
#endif
800
    switch(opc) {
801
    case 0:
802
        /* movzbl */
803
        tcg_out_modrm_offset(s, OPC_MOVZBL, data_reg, r0, GUEST_BASE);
804
        break;
805
    case 0 | 4:
806
        /* movsbl */
807
        tcg_out_modrm_offset(s, OPC_MOVSBL, data_reg, r0, GUEST_BASE);
808
        break;
809
    case 1:
810
        /* movzwl */
811
        tcg_out_modrm_offset(s, OPC_MOVZWL, data_reg, r0, GUEST_BASE);
812
        if (bswap) {
813
            tcg_out_rolw_8(s, data_reg);
814
        }
815
        break;
816
    case 1 | 4:
817
        /* movswl */
818
        tcg_out_modrm_offset(s, OPC_MOVSWL, data_reg, r0, GUEST_BASE);
819
        if (bswap) {
820
            tcg_out_rolw_8(s, data_reg);
821

    
822
            /* movswl data_reg, data_reg */
823
            tcg_out_modrm(s, OPC_MOVSWL, data_reg, data_reg);
824
        }
825
        break;
826
    case 2:
827
        tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
828
        if (bswap) {
829
            tcg_out_bswap32(s, data_reg);
830
        }
831
        break;
832
    case 3:
833
        if (bswap) {
834
            int t = data_reg;
835
            data_reg = data_reg2;
836
            data_reg2 = t;
837
        }
838
        if (r0 != data_reg) {
839
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
840
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
841
        } else {
842
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
843
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
844
        }
845
        if (bswap) {
846
            tcg_out_bswap32(s, data_reg);
847
            tcg_out_bswap32(s, data_reg2);
848
        }
849
        break;
850
    default:
851
        tcg_abort();
852
    }
853

    
854
#if defined(CONFIG_SOFTMMU)
855
    /* label2: */
856
    *label2_ptr = s->code_ptr - label2_ptr - 1;
857
#endif
858
}
859

    
860

    
861
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
862
                            int opc)
863
{
864
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
865
#if defined(CONFIG_SOFTMMU)
866
    int stack_adjust;
867
    uint8_t *label1_ptr, *label2_ptr;
868
#endif
869
#if TARGET_LONG_BITS == 64
870
#if defined(CONFIG_SOFTMMU)
871
    uint8_t *label3_ptr;
872
#endif
873
    int addr_reg2;
874
#endif
875

    
876
    data_reg = *args++;
877
    if (opc == 3)
878
        data_reg2 = *args++;
879
    else
880
        data_reg2 = 0;
881
    addr_reg = *args++;
882
#if TARGET_LONG_BITS == 64
883
    addr_reg2 = *args++;
884
#endif
885
    mem_index = *args;
886

    
887
    s_bits = opc;
888

    
889
    r0 = TCG_REG_EAX;
890
    r1 = TCG_REG_EDX;
891

    
892
#if defined(CONFIG_SOFTMMU)
893
    tcg_out_mov(s, r1, addr_reg); 
894
    tcg_out_mov(s, r0, addr_reg); 
895
 
896
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
897

    
898
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
899
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
900

    
901
    tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
902
    tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
903
    tcg_out8(s, (5 << 3) | r1);
904
    tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
905

    
906
    /* cmp 0(r1), r0 */
907
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
908
    
909
    tcg_out_mov(s, r0, addr_reg);
910
    
911
#if TARGET_LONG_BITS == 32
912
    /* je label1 */
913
    tcg_out8(s, OPC_JCC_short + JCC_JE);
914
    label1_ptr = s->code_ptr;
915
    s->code_ptr++;
916
#else
917
    /* jne label3 */
918
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
919
    label3_ptr = s->code_ptr;
920
    s->code_ptr++;
921
    
922
    /* cmp 4(r1), addr_reg2 */
923
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
924

    
925
    /* je label1 */
926
    tcg_out8(s, OPC_JCC_short + JCC_JE);
927
    label1_ptr = s->code_ptr;
928
    s->code_ptr++;
929
    
930
    /* label3: */
931
    *label3_ptr = s->code_ptr - label3_ptr - 1;
932
#endif
933

    
934
    /* XXX: move that code at the end of the TB */
935
#if TARGET_LONG_BITS == 32
936
    if (opc == 3) {
937
        tcg_out_mov(s, TCG_REG_EDX, data_reg);
938
        tcg_out_mov(s, TCG_REG_ECX, data_reg2);
939
        tcg_out_pushi(s, mem_index);
940
        stack_adjust = 4;
941
    } else {
942
        switch(opc) {
943
        case 0:
944
            tcg_out_ext8u(s, TCG_REG_EDX, data_reg);
945
            break;
946
        case 1:
947
            tcg_out_ext16u(s, TCG_REG_EDX, data_reg);
948
            break;
949
        case 2:
950
            tcg_out_mov(s, TCG_REG_EDX, data_reg);
951
            break;
952
        }
953
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
954
        stack_adjust = 0;
955
    }
956
#else
957
    if (opc == 3) {
958
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
959
        tcg_out_pushi(s, mem_index);
960
        tcg_out_push(s, data_reg2);
961
        tcg_out_push(s, data_reg);
962
        stack_adjust = 12;
963
    } else {
964
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
965
        switch(opc) {
966
        case 0:
967
            tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
968
            break;
969
        case 1:
970
            tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
971
            break;
972
        case 2:
973
            tcg_out_mov(s, TCG_REG_ECX, data_reg);
974
            break;
975
        }
976
        tcg_out_pushi(s, mem_index);
977
        stack_adjust = 4;
978
    }
979
#endif
980

    
981
    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
982

    
983
    if (stack_adjust == 4) {
984
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
985
        tcg_out_pop(s, TCG_REG_ECX);
986
    } else if (stack_adjust != 0) {
987
        tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
988
    }
989

    
990
    /* jmp label2 */
991
    tcg_out8(s, OPC_JMP_short);
992
    label2_ptr = s->code_ptr;
993
    s->code_ptr++;
994
    
995
    /* label1: */
996
    *label1_ptr = s->code_ptr - label1_ptr - 1;
997

    
998
    /* add x(r1), r0 */
999
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
1000
                         offsetof(CPUTLBEntry, addend) -
1001
                         offsetof(CPUTLBEntry, addr_write));
1002
#else
1003
    r0 = addr_reg;
1004
#endif
1005

    
1006
#ifdef TARGET_WORDS_BIGENDIAN
1007
    bswap = 1;
1008
#else
1009
    bswap = 0;
1010
#endif
1011
    switch(opc) {
1012
    case 0:
1013
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, data_reg, r0, GUEST_BASE);
1014
        break;
1015
    case 1:
1016
        if (bswap) {
1017
            tcg_out_mov(s, r1, data_reg);
1018
            tcg_out_rolw_8(s, r1);
1019
            data_reg = r1;
1020
        }
1021
        /* movw */
1022
        tcg_out8(s, 0x66);
1023
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv, data_reg, r0, GUEST_BASE);
1024
        break;
1025
    case 2:
1026
        if (bswap) {
1027
            tcg_out_mov(s, r1, data_reg);
1028
            tcg_out_bswap32(s, r1);
1029
            data_reg = r1;
1030
        }
1031
        tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1032
        break;
1033
    case 3:
1034
        if (bswap) {
1035
            tcg_out_mov(s, r1, data_reg2);
1036
            tcg_out_bswap32(s, r1);
1037
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE);
1038
            tcg_out_mov(s, r1, data_reg);
1039
            tcg_out_bswap32(s, r1);
1040
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE + 4);
1041
        } else {
1042
            tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1043
            tcg_out_st(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
1044
        }
1045
        break;
1046
    default:
1047
        tcg_abort();
1048
    }
1049

    
1050
#if defined(CONFIG_SOFTMMU)
1051
    /* label2: */
1052
    *label2_ptr = s->code_ptr - label2_ptr - 1;
1053
#endif
1054
}
1055

    
1056
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1057
                              const TCGArg *args, const int *const_args)
1058
{
1059
    int c;
1060
    
1061
    switch(opc) {
1062
    case INDEX_op_exit_tb:
1063
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
1064
        tcg_out8(s, OPC_JMP_long); /* jmp tb_ret_addr */
1065
        tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
1066
        break;
1067
    case INDEX_op_goto_tb:
1068
        if (s->tb_jmp_offset) {
1069
            /* direct jump method */
1070
            tcg_out8(s, OPC_JMP_long); /* jmp im */
1071
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1072
            tcg_out32(s, 0);
1073
        } else {
1074
            /* indirect jump method */
1075
            tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1076
                                 (tcg_target_long)(s->tb_next + args[0]));
1077
        }
1078
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1079
        break;
1080
    case INDEX_op_call:
1081
        if (const_args[0]) {
1082
            tcg_out_calli(s, args[0]);
1083
        } else {
1084
            /* call *reg */
1085
            tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1086
        }
1087
        break;
1088
    case INDEX_op_jmp:
1089
        if (const_args[0]) {
1090
            tcg_out8(s, OPC_JMP_long);
1091
            tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
1092
        } else {
1093
            /* jmp *reg */
1094
            tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1095
        }
1096
        break;
1097
    case INDEX_op_br:
1098
        tcg_out_jxx(s, JCC_JMP, args[0], 0);
1099
        break;
1100
    case INDEX_op_movi_i32:
1101
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1102
        break;
1103
    case INDEX_op_ld8u_i32:
1104
        /* movzbl */
1105
        tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
1106
        break;
1107
    case INDEX_op_ld8s_i32:
1108
        /* movsbl */
1109
        tcg_out_modrm_offset(s, OPC_MOVSBL, args[0], args[1], args[2]);
1110
        break;
1111
    case INDEX_op_ld16u_i32:
1112
        /* movzwl */
1113
        tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1114
        break;
1115
    case INDEX_op_ld16s_i32:
1116
        /* movswl */
1117
        tcg_out_modrm_offset(s, OPC_MOVSWL, args[0], args[1], args[2]);
1118
        break;
1119
    case INDEX_op_ld_i32:
1120
        tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1121
        break;
1122
    case INDEX_op_st8_i32:
1123
        /* movb */
1124
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, args[0], args[1], args[2]);
1125
        break;
1126
    case INDEX_op_st16_i32:
1127
        /* movw */
1128
        tcg_out8(s, 0x66);
1129
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv, args[0], args[1], args[2]);
1130
        break;
1131
    case INDEX_op_st_i32:
1132
        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1133
        break;
1134
    case INDEX_op_sub_i32:
1135
        c = ARITH_SUB;
1136
        goto gen_arith;
1137
    case INDEX_op_and_i32:
1138
        c = ARITH_AND;
1139
        goto gen_arith;
1140
    case INDEX_op_or_i32:
1141
        c = ARITH_OR;
1142
        goto gen_arith;
1143
    case INDEX_op_xor_i32:
1144
        c = ARITH_XOR;
1145
        goto gen_arith;
1146
    case INDEX_op_add_i32:
1147
        c = ARITH_ADD;
1148
    gen_arith:
1149
        if (const_args[2]) {
1150
            tgen_arithi(s, c, args[0], args[2], 0);
1151
        } else {
1152
            tgen_arithr(s, c, args[0], args[2]);
1153
        }
1154
        break;
1155
    case INDEX_op_mul_i32:
1156
        if (const_args[2]) {
1157
            int32_t val;
1158
            val = args[2];
1159
            if (val == (int8_t)val) {
1160
                tcg_out_modrm(s, 0x6b, args[0], args[0]);
1161
                tcg_out8(s, val);
1162
            } else {
1163
                tcg_out_modrm(s, 0x69, args[0], args[0]);
1164
                tcg_out32(s, val);
1165
            }
1166
        } else {
1167
            tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
1168
        }
1169
        break;
1170
    case INDEX_op_mulu2_i32:
1171
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1172
        break;
1173
    case INDEX_op_div2_i32:
1174
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_IDIV, args[4]);
1175
        break;
1176
    case INDEX_op_divu2_i32:
1177
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_DIV, args[4]);
1178
        break;
1179
    case INDEX_op_shl_i32:
1180
        c = SHIFT_SHL;
1181
    gen_shift32:
1182
        if (const_args[2]) {
1183
            tcg_out_shifti(s, c, args[0], args[2]);
1184
        } else {
1185
            tcg_out_modrm(s, OPC_SHIFT_cl, c, args[0]);
1186
        }
1187
        break;
1188
    case INDEX_op_shr_i32:
1189
        c = SHIFT_SHR;
1190
        goto gen_shift32;
1191
    case INDEX_op_sar_i32:
1192
        c = SHIFT_SAR;
1193
        goto gen_shift32;
1194
    case INDEX_op_rotl_i32:
1195
        c = SHIFT_ROL;
1196
        goto gen_shift32;
1197
    case INDEX_op_rotr_i32:
1198
        c = SHIFT_ROR;
1199
        goto gen_shift32;
1200

    
1201
    case INDEX_op_add2_i32:
1202
        if (const_args[4]) {
1203
            tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1204
        } else {
1205
            tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1206
        }
1207
        if (const_args[5]) {
1208
            tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1209
        } else {
1210
            tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1211
        }
1212
        break;
1213
    case INDEX_op_sub2_i32:
1214
        if (const_args[4]) {
1215
            tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1216
        } else {
1217
            tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1218
        }
1219
        if (const_args[5]) {
1220
            tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1221
        } else {
1222
            tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1223
        }
1224
        break;
1225
    case INDEX_op_brcond_i32:
1226
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1227
                       args[3], 0);
1228
        break;
1229
    case INDEX_op_brcond2_i32:
1230
        tcg_out_brcond2(s, args, const_args, 0);
1231
        break;
1232

    
1233
    case INDEX_op_bswap16_i32:
1234
        tcg_out_rolw_8(s, args[0]);
1235
        break;
1236
    case INDEX_op_bswap32_i32:
1237
        tcg_out_bswap32(s, args[0]);
1238
        break;
1239

    
1240
    case INDEX_op_neg_i32:
1241
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, args[0]);
1242
        break;
1243

    
1244
    case INDEX_op_not_i32:
1245
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NOT, args[0]);
1246
        break;
1247

    
1248
    case INDEX_op_ext8s_i32:
1249
        tcg_out_ext8s(s, args[0], args[1]);
1250
        break;
1251
    case INDEX_op_ext16s_i32:
1252
        tcg_out_ext16s(s, args[0], args[1]);
1253
        break;
1254
    case INDEX_op_ext8u_i32:
1255
        tcg_out_ext8u(s, args[0], args[1]);
1256
        break;
1257
    case INDEX_op_ext16u_i32:
1258
        tcg_out_ext16u(s, args[0], args[1]);
1259
        break;
1260

    
1261
    case INDEX_op_setcond_i32:
1262
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
1263
        break;
1264
    case INDEX_op_setcond2_i32:
1265
        tcg_out_setcond2(s, args, const_args);
1266
        break;
1267

    
1268
    case INDEX_op_qemu_ld8u:
1269
        tcg_out_qemu_ld(s, args, 0);
1270
        break;
1271
    case INDEX_op_qemu_ld8s:
1272
        tcg_out_qemu_ld(s, args, 0 | 4);
1273
        break;
1274
    case INDEX_op_qemu_ld16u:
1275
        tcg_out_qemu_ld(s, args, 1);
1276
        break;
1277
    case INDEX_op_qemu_ld16s:
1278
        tcg_out_qemu_ld(s, args, 1 | 4);
1279
        break;
1280
    case INDEX_op_qemu_ld32:
1281
        tcg_out_qemu_ld(s, args, 2);
1282
        break;
1283
    case INDEX_op_qemu_ld64:
1284
        tcg_out_qemu_ld(s, args, 3);
1285
        break;
1286
        
1287
    case INDEX_op_qemu_st8:
1288
        tcg_out_qemu_st(s, args, 0);
1289
        break;
1290
    case INDEX_op_qemu_st16:
1291
        tcg_out_qemu_st(s, args, 1);
1292
        break;
1293
    case INDEX_op_qemu_st32:
1294
        tcg_out_qemu_st(s, args, 2);
1295
        break;
1296
    case INDEX_op_qemu_st64:
1297
        tcg_out_qemu_st(s, args, 3);
1298
        break;
1299

    
1300
    default:
1301
        tcg_abort();
1302
    }
1303
}
1304

    
1305
static const TCGTargetOpDef x86_op_defs[] = {
1306
    { INDEX_op_exit_tb, { } },
1307
    { INDEX_op_goto_tb, { } },
1308
    { INDEX_op_call, { "ri" } },
1309
    { INDEX_op_jmp, { "ri" } },
1310
    { INDEX_op_br, { } },
1311
    { INDEX_op_mov_i32, { "r", "r" } },
1312
    { INDEX_op_movi_i32, { "r" } },
1313
    { INDEX_op_ld8u_i32, { "r", "r" } },
1314
    { INDEX_op_ld8s_i32, { "r", "r" } },
1315
    { INDEX_op_ld16u_i32, { "r", "r" } },
1316
    { INDEX_op_ld16s_i32, { "r", "r" } },
1317
    { INDEX_op_ld_i32, { "r", "r" } },
1318
    { INDEX_op_st8_i32, { "q", "r" } },
1319
    { INDEX_op_st16_i32, { "r", "r" } },
1320
    { INDEX_op_st_i32, { "r", "r" } },
1321

    
1322
    { INDEX_op_add_i32, { "r", "0", "ri" } },
1323
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1324
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1325
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1326
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1327
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1328
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1329
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1330
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1331

    
1332
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1333
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1334
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1335
    { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1336
    { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1337

    
1338
    { INDEX_op_brcond_i32, { "r", "ri" } },
1339

    
1340
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1341
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1342
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1343

    
1344
    { INDEX_op_bswap16_i32, { "r", "0" } },
1345
    { INDEX_op_bswap32_i32, { "r", "0" } },
1346

    
1347
    { INDEX_op_neg_i32, { "r", "0" } },
1348

    
1349
    { INDEX_op_not_i32, { "r", "0" } },
1350

    
1351
    { INDEX_op_ext8s_i32, { "r", "q" } },
1352
    { INDEX_op_ext16s_i32, { "r", "r" } },
1353
    { INDEX_op_ext8u_i32, { "r", "q" } },
1354
    { INDEX_op_ext16u_i32, { "r", "r" } },
1355

    
1356
    { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1357
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1358

    
1359
#if TARGET_LONG_BITS == 32
1360
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1361
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1362
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1363
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1364
    { INDEX_op_qemu_ld32, { "r", "L" } },
1365
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1366

    
1367
    { INDEX_op_qemu_st8, { "cb", "L" } },
1368
    { INDEX_op_qemu_st16, { "L", "L" } },
1369
    { INDEX_op_qemu_st32, { "L", "L" } },
1370
    { INDEX_op_qemu_st64, { "L", "L", "L" } },
1371
#else
1372
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1373
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1374
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1375
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1376
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1377
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1378

    
1379
    { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1380
    { INDEX_op_qemu_st16, { "L", "L", "L" } },
1381
    { INDEX_op_qemu_st32, { "L", "L", "L" } },
1382
    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1383
#endif
1384
    { -1 },
1385
};
1386

    
1387
static int tcg_target_callee_save_regs[] = {
1388
    /*    TCG_REG_EBP, */ /* currently used for the global env, so no
1389
                             need to save */
1390
    TCG_REG_EBX,
1391
    TCG_REG_ESI,
1392
    TCG_REG_EDI,
1393
};
1394

    
1395
/* Generate global QEMU prologue and epilogue code */
1396
void tcg_target_qemu_prologue(TCGContext *s)
1397
{
1398
    int i, frame_size, push_size, stack_addend;
1399
    
1400
    /* TB prologue */
1401
    /* save all callee saved registers */
1402
    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1403
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
1404
    }
1405
    /* reserve some stack space */
1406
    push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1407
    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1408
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & 
1409
        ~(TCG_TARGET_STACK_ALIGN - 1);
1410
    stack_addend = frame_size - push_size;
1411
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1412

    
1413
    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
1414
    
1415
    /* TB epilogue */
1416
    tb_ret_addr = s->code_ptr;
1417
    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1418
    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1419
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1420
    }
1421
    tcg_out_opc(s, OPC_RET);
1422
}
1423

    
1424
void tcg_target_init(TCGContext *s)
1425
{
1426
#if !defined(CONFIG_USER_ONLY)
1427
    /* fail safe */
1428
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1429
        tcg_abort();
1430
#endif
1431

    
1432
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1433

    
1434
    tcg_regset_clear(tcg_target_call_clobber_regs);
1435
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1436
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1437
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
1438

    
1439
    tcg_regset_clear(s->reserved_regs);
1440
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1441

    
1442
    tcg_add_target_add_op_defs(x86_op_defs);
1443
}