Statistics
| Branch: | Revision:

root / tcg / i386 / tcg-target.c @ 0954d0d9

History | View | Annotate | Download (33.1 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
const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
25
    "%eax",
26
    "%ecx",
27
    "%edx",
28
    "%ebx",
29
    "%esp",
30
    "%ebp",
31
    "%esi",
32
    "%edi",
33
};
34

    
35
int tcg_target_reg_alloc_order[] = {
36
    TCG_REG_EAX,
37
    TCG_REG_EDX,
38
    TCG_REG_ECX,
39
    TCG_REG_EBX,
40
    TCG_REG_ESI,
41
    TCG_REG_EDI,
42
    TCG_REG_EBP,
43
    TCG_REG_ESP,
44
};
45

    
46
const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX };
47
const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
48

    
49
static void patch_reloc(uint8_t *code_ptr, int type, 
50
                        tcg_target_long value)
51
{
52
    switch(type) {
53
    case R_386_32:
54
        *(uint32_t *)code_ptr = value;
55
        break;
56
    case R_386_PC32:
57
        *(uint32_t *)code_ptr = value - (long)code_ptr;
58
        break;
59
    default:
60
        tcg_abort();
61
    }
62
}
63

    
64
/* maximum number of register used for input function arguments */
65
static inline int tcg_target_get_call_iarg_regs_count(int flags)
66
{
67
    flags &= TCG_CALL_TYPE_MASK;
68
    switch(flags) {
69
    case TCG_CALL_TYPE_STD:
70
        return 0;
71
    case TCG_CALL_TYPE_REGPARM_1:
72
    case TCG_CALL_TYPE_REGPARM_2:
73
    case TCG_CALL_TYPE_REGPARM:
74
        return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
75
    default:
76
        tcg_abort();
77
    }
78
}
79

    
80
/* parse target specific constraints */
81
int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
82
{
83
    const char *ct_str;
84

    
85
    ct_str = *pct_str;
86
    switch(ct_str[0]) {
87
    case 'a':
88
        ct->ct |= TCG_CT_REG;
89
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
90
        break;
91
    case 'b':
92
        ct->ct |= TCG_CT_REG;
93
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
94
        break;
95
    case 'c':
96
        ct->ct |= TCG_CT_REG;
97
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
98
        break;
99
    case 'd':
100
        ct->ct |= TCG_CT_REG;
101
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
102
        break;
103
    case 'S':
104
        ct->ct |= TCG_CT_REG;
105
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
106
        break;
107
    case 'D':
108
        ct->ct |= TCG_CT_REG;
109
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
110
        break;
111
    case 'q':
112
        ct->ct |= TCG_CT_REG;
113
        tcg_regset_set32(ct->u.regs, 0, 0xf);
114
        break;
115
    case 'r':
116
        ct->ct |= TCG_CT_REG;
117
        tcg_regset_set32(ct->u.regs, 0, 0xff);
118
        break;
119

    
120
        /* qemu_ld/st address constraint */
121
    case 'L':
122
        ct->ct |= TCG_CT_REG;
123
        tcg_regset_set32(ct->u.regs, 0, 0xff);
124
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
125
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
126
        break;
127
    default:
128
        return -1;
129
    }
130
    ct_str++;
131
    *pct_str = ct_str;
132
    return 0;
133
}
134

    
135
/* test if a constant matches the constraint */
136
static inline int tcg_target_const_match(tcg_target_long val,
137
                                         const TCGArgConstraint *arg_ct)
138
{
139
    int ct;
140
    ct = arg_ct->ct;
141
    if (ct & TCG_CT_CONST)
142
        return 1;
143
    else
144
        return 0;
145
}
146

    
147
#define ARITH_ADD 0
148
#define ARITH_OR  1
149
#define ARITH_ADC 2
150
#define ARITH_SBB 3
151
#define ARITH_AND 4
152
#define ARITH_SUB 5
153
#define ARITH_XOR 6
154
#define ARITH_CMP 7
155

    
156
#define SHIFT_SHL 4
157
#define SHIFT_SHR 5
158
#define SHIFT_SAR 7
159

    
160
#define JCC_JMP (-1)
161
#define JCC_JO  0x0
162
#define JCC_JNO 0x1
163
#define JCC_JB  0x2
164
#define JCC_JAE 0x3
165
#define JCC_JE  0x4
166
#define JCC_JNE 0x5
167
#define JCC_JBE 0x6
168
#define JCC_JA  0x7
169
#define JCC_JS  0x8
170
#define JCC_JNS 0x9
171
#define JCC_JP  0xa
172
#define JCC_JNP 0xb
173
#define JCC_JL  0xc
174
#define JCC_JGE 0xd
175
#define JCC_JLE 0xe
176
#define JCC_JG  0xf
177

    
178
#define P_EXT   0x100 /* 0x0f opcode prefix */
179

    
180
static const uint8_t tcg_cond_to_jcc[10] = {
181
    [TCG_COND_EQ] = JCC_JE,
182
    [TCG_COND_NE] = JCC_JNE,
183
    [TCG_COND_LT] = JCC_JL,
184
    [TCG_COND_GE] = JCC_JGE,
185
    [TCG_COND_LE] = JCC_JLE,
186
    [TCG_COND_GT] = JCC_JG,
187
    [TCG_COND_LTU] = JCC_JB,
188
    [TCG_COND_GEU] = JCC_JAE,
189
    [TCG_COND_LEU] = JCC_JBE,
190
    [TCG_COND_GTU] = JCC_JA,
191
};
192

    
193
static inline void tcg_out_opc(TCGContext *s, int opc)
194
{
195
    if (opc & P_EXT)
196
        tcg_out8(s, 0x0f);
197
    tcg_out8(s, opc);
198
}
199

    
200
static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
201
{
202
    tcg_out_opc(s, opc);
203
    tcg_out8(s, 0xc0 | (r << 3) | rm);
204
}
205

    
206
/* rm == -1 means no register index */
207
static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm, 
208
                                        int32_t offset)
209
{
210
    tcg_out_opc(s, opc);
211
    if (rm == -1) {
212
        tcg_out8(s, 0x05 | (r << 3));
213
        tcg_out32(s, offset);
214
    } else if (offset == 0 && rm != TCG_REG_EBP) {
215
        if (rm == TCG_REG_ESP) {
216
            tcg_out8(s, 0x04 | (r << 3));
217
            tcg_out8(s, 0x24);
218
        } else {
219
            tcg_out8(s, 0x00 | (r << 3) | rm);
220
        }
221
    } else if ((int8_t)offset == offset) {
222
        if (rm == TCG_REG_ESP) {
223
            tcg_out8(s, 0x44 | (r << 3));
224
            tcg_out8(s, 0x24);
225
        } else {
226
            tcg_out8(s, 0x40 | (r << 3) | rm);
227
        }
228
        tcg_out8(s, offset);
229
    } else {
230
        if (rm == TCG_REG_ESP) {
231
            tcg_out8(s, 0x84 | (r << 3));
232
            tcg_out8(s, 0x24);
233
        } else {
234
            tcg_out8(s, 0x80 | (r << 3) | rm);
235
        }
236
        tcg_out32(s, offset);
237
    }
238
}
239

    
240
static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
241
{
242
    if (arg != ret)
243
        tcg_out_modrm(s, 0x8b, ret, arg);
244
}
245

    
246
static inline void tcg_out_movi(TCGContext *s, TCGType type,
247
                                int ret, int32_t arg)
248
{
249
    if (arg == 0) {
250
        /* xor r0,r0 */
251
        tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret);
252
    } else {
253
        tcg_out8(s, 0xb8 + ret);
254
        tcg_out32(s, arg);
255
    }
256
}
257

    
258
static inline void tcg_out_ld(TCGContext *s, int ret, 
259
                              int arg1, int32_t arg2)
260
{
261
    /* movl */
262
    tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2);
263
}
264

    
265
static inline void tcg_out_st(TCGContext *s, int arg, 
266
                              int arg1, int32_t arg2)
267
{
268
    /* movl */
269
    tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2);
270
}
271

    
272
static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val)
273
{
274
    if (val == (int8_t)val) {
275
        tcg_out_modrm(s, 0x83, c, r0);
276
        tcg_out8(s, val);
277
    } else {
278
        tcg_out_modrm(s, 0x81, c, r0);
279
        tcg_out32(s, val);
280
    }
281
}
282

    
283
void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
284
{
285
    if (val != 0)
286
        tgen_arithi(s, ARITH_ADD, reg, val);
287
}
288

    
289
static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
290
{
291
    int32_t val, val1;
292
    TCGLabel *l = &s->labels[label_index];
293
    
294
    if (l->has_value) {
295
        val = l->u.value - (tcg_target_long)s->code_ptr;
296
        val1 = val - 2;
297
        if ((int8_t)val1 == val1) {
298
            if (opc == -1)
299
                tcg_out8(s, 0xeb);
300
            else
301
                tcg_out8(s, 0x70 + opc);
302
            tcg_out8(s, val1);
303
        } else {
304
            if (opc == -1) {
305
                tcg_out8(s, 0xe9);
306
                tcg_out32(s, val - 5);
307
            } else {
308
                tcg_out8(s, 0x0f);
309
                tcg_out8(s, 0x80 + opc);
310
                tcg_out32(s, val - 6);
311
            }
312
        }
313
    } else {
314
        if (opc == -1) {
315
            tcg_out8(s, 0xe9);
316
        } else {
317
            tcg_out8(s, 0x0f);
318
            tcg_out8(s, 0x80 + opc);
319
        }
320
        tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
321
        s->code_ptr += 4;
322
    }
323
}
324

    
325
static void tcg_out_brcond(TCGContext *s, int cond, 
326
                           TCGArg arg1, TCGArg arg2, int const_arg2,
327
                           int label_index)
328
{
329
    int c;
330
    if (const_arg2) {
331
        if (arg2 == 0) {
332
            /* use test */
333
            switch(cond) {
334
            case TCG_COND_EQ:
335
                c = JCC_JE;
336
                break;
337
            case TCG_COND_NE:
338
                c = JCC_JNE;
339
                break;
340
            case TCG_COND_LT:
341
                c = JCC_JS;
342
                break;
343
            case TCG_COND_GE:
344
                c = JCC_JNS;
345
                break;
346
            default:
347
                goto do_cmpi;
348
            }
349
            /* test r, r */
350
            tcg_out_modrm(s, 0x85, arg1, arg1);
351
            tcg_out_jxx(s, c, label_index);
352
        } else {
353
        do_cmpi:
354
            tgen_arithi(s, ARITH_CMP, arg1, arg2);
355
            tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
356
        }
357
    } else {
358
        tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1);
359
        tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
360
    }
361
}
362

    
363
/* XXX: we implement it at the target level to avoid having to
364
   handle cross basic blocks temporaries */
365
static void tcg_out_brcond2(TCGContext *s,
366
                            const TCGArg *args, const int *const_args)
367
{
368
    int label_next;
369
    label_next = gen_new_label();
370
    switch(args[4]) {
371
    case TCG_COND_EQ:
372
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next);
373
        tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]);
374
        break;
375
    case TCG_COND_NE:
376
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]);
377
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]);
378
        break;
379
    case TCG_COND_LT:
380
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
381
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
382
        tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], args[5]);
383
        break;
384
    case TCG_COND_LE:
385
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
386
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
387
        tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], args[5]);
388
        break;
389
    case TCG_COND_GT:
390
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
391
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
392
        tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], args[5]);
393
        break;
394
    case TCG_COND_GE:
395
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
396
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
397
        tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], args[5]);
398
        break;
399
    case TCG_COND_LTU:
400
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
401
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
402
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
403
        break;
404
    case TCG_COND_LEU:
405
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
406
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
407
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
408
        break;
409
    case TCG_COND_GTU:
410
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
411
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
412
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
413
        break;
414
    case TCG_COND_GEU:
415
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
416
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
417
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
418
        break;
419
    default:
420
        tcg_abort();
421
    }
422
    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
423
}
424

    
425
#if defined(CONFIG_SOFTMMU)
426
extern void __ldb_mmu(void);
427
extern void __ldw_mmu(void);
428
extern void __ldl_mmu(void);
429
extern void __ldq_mmu(void);
430

    
431
extern void __stb_mmu(void);
432
extern void __stw_mmu(void);
433
extern void __stl_mmu(void);
434
extern void __stq_mmu(void);
435

    
436
static void *qemu_ld_helpers[4] = {
437
    __ldb_mmu,
438
    __ldw_mmu,
439
    __ldl_mmu,
440
    __ldq_mmu,
441
};
442

    
443
static void *qemu_st_helpers[4] = {
444
    __stb_mmu,
445
    __stw_mmu,
446
    __stl_mmu,
447
    __stq_mmu,
448
};
449
#endif
450

    
451
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
452
   EAX. It will be useful once fixed registers globals are less
453
   common. */
454
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
455
                            int opc)
456
{
457
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
458
#if defined(CONFIG_SOFTMMU)
459
    uint8_t *label1_ptr, *label2_ptr;
460
#endif
461
#if TARGET_LONG_BITS == 64
462
#if defined(CONFIG_SOFTMMU)
463
    uint8_t *label3_ptr;
464
#endif
465
    int addr_reg2;
466
#endif
467

    
468
    data_reg = *args++;
469
    if (opc == 3)
470
        data_reg2 = *args++;
471
    else
472
        data_reg2 = 0;
473
    addr_reg = *args++;
474
#if TARGET_LONG_BITS == 64
475
    addr_reg2 = *args++;
476
#endif
477
    mem_index = *args;
478
    s_bits = opc & 3;
479

    
480
    r0 = TCG_REG_EAX;
481
    r1 = TCG_REG_EDX;
482

    
483
#if defined(CONFIG_SOFTMMU)
484
    tcg_out_mov(s, r1, addr_reg); 
485

    
486
    tcg_out_mov(s, r0, addr_reg); 
487
 
488
    tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
489
    tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
490
    
491
    tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
492
    tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
493
    
494
    tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
495
    tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
496

    
497
    tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
498
    tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
499
    tcg_out8(s, (5 << 3) | r1);
500
    tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
501

    
502
    /* cmp 0(r1), r0 */
503
    tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
504
    
505
    tcg_out_mov(s, r0, addr_reg);
506
    
507
#if TARGET_LONG_BITS == 32
508
    /* je label1 */
509
    tcg_out8(s, 0x70 + JCC_JE);
510
    label1_ptr = s->code_ptr;
511
    s->code_ptr++;
512
#else
513
    /* jne label3 */
514
    tcg_out8(s, 0x70 + JCC_JNE);
515
    label3_ptr = s->code_ptr;
516
    s->code_ptr++;
517
    
518
    /* cmp 4(r1), addr_reg2 */
519
    tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
520

    
521
    /* je label1 */
522
    tcg_out8(s, 0x70 + JCC_JE);
523
    label1_ptr = s->code_ptr;
524
    s->code_ptr++;
525
    
526
    /* label3: */
527
    *label3_ptr = s->code_ptr - label3_ptr - 1;
528
#endif
529

    
530
    /* XXX: move that code at the end of the TB */
531
#if TARGET_LONG_BITS == 32
532
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
533
#else
534
    tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
535
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
536
#endif
537
    tcg_out8(s, 0xe8);
538
    tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] - 
539
              (tcg_target_long)s->code_ptr - 4);
540

    
541
    switch(opc) {
542
    case 0 | 4:
543
        /* movsbl */
544
        tcg_out_modrm(s, 0xbe | P_EXT, data_reg, TCG_REG_EAX);
545
        break;
546
    case 1 | 4:
547
        /* movswl */
548
        tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX);
549
        break;
550
    case 0:
551
    case 1:
552
    case 2:
553
    default:
554
        tcg_out_mov(s, data_reg, TCG_REG_EAX);
555
        break;
556
    case 3:
557
        if (data_reg == TCG_REG_EDX) {
558
            tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */
559
            tcg_out_mov(s, data_reg2, TCG_REG_EAX);
560
        } else {
561
            tcg_out_mov(s, data_reg, TCG_REG_EAX);
562
            tcg_out_mov(s, data_reg2, TCG_REG_EDX);
563
        }
564
        break;
565
    }
566

    
567
    /* jmp label2 */
568
    tcg_out8(s, 0xeb);
569
    label2_ptr = s->code_ptr;
570
    s->code_ptr++;
571
    
572
    /* label1: */
573
    *label1_ptr = s->code_ptr - label1_ptr - 1;
574

    
575
    /* add x(r1), r0 */
576
    tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) - 
577
                         offsetof(CPUTLBEntry, addr_read));
578
#else
579
    r0 = addr_reg;
580
#endif
581

    
582
#ifdef TARGET_WORDS_BIGENDIAN
583
    bswap = 1;
584
#else
585
    bswap = 0;
586
#endif
587
    switch(opc) {
588
    case 0:
589
        /* movzbl */
590
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
591
        break;
592
    case 0 | 4:
593
        /* movsbl */
594
        tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, 0);
595
        break;
596
    case 1:
597
        /* movzwl */
598
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
599
        if (bswap) {
600
            /* rolw $8, data_reg */
601
            tcg_out8(s, 0x66); 
602
            tcg_out_modrm(s, 0xc1, 0, data_reg);
603
            tcg_out8(s, 8);
604
        }
605
        break;
606
    case 1 | 4:
607
        /* movswl */
608
        tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, 0);
609
        if (bswap) {
610
            /* rolw $8, data_reg */
611
            tcg_out8(s, 0x66); 
612
            tcg_out_modrm(s, 0xc1, 0, data_reg);
613
            tcg_out8(s, 8);
614

    
615
            /* movswl data_reg, data_reg */
616
            tcg_out_modrm(s, 0xbf | P_EXT, data_reg, data_reg);
617
        }
618
        break;
619
    case 2:
620
        /* movl (r0), data_reg */
621
        tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
622
        if (bswap) {
623
            /* bswap */
624
            tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
625
        }
626
        break;
627
    case 3:
628
        /* XXX: could be nicer */
629
        if (r0 == data_reg) {
630
            r1 = TCG_REG_EDX;
631
            if (r1 == data_reg)
632
                r1 = TCG_REG_EAX;
633
            tcg_out_mov(s, r1, r0);
634
            r0 = r1;
635
        }
636
        if (!bswap) {
637
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
638
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4);
639
        } else {
640
            tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4);
641
            tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
642

    
643
            tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0);
644
            /* bswap */
645
            tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT);
646
        }
647
        break;
648
    default:
649
        tcg_abort();
650
    }
651

    
652
#if defined(CONFIG_SOFTMMU)
653
    /* label2: */
654
    *label2_ptr = s->code_ptr - label2_ptr - 1;
655
#endif
656
}
657

    
658

    
659
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
660
                            int opc)
661
{
662
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
663
#if defined(CONFIG_SOFTMMU)
664
    uint8_t *label1_ptr, *label2_ptr;
665
#endif
666
#if TARGET_LONG_BITS == 64
667
#if defined(CONFIG_SOFTMMU)
668
    uint8_t *label3_ptr;
669
#endif
670
    int addr_reg2;
671
#endif
672

    
673
    data_reg = *args++;
674
    if (opc == 3)
675
        data_reg2 = *args++;
676
    else
677
        data_reg2 = 0;
678
    addr_reg = *args++;
679
#if TARGET_LONG_BITS == 64
680
    addr_reg2 = *args++;
681
#endif
682
    mem_index = *args;
683

    
684
    s_bits = opc;
685

    
686
    r0 = TCG_REG_EAX;
687
    r1 = TCG_REG_EDX;
688

    
689
#if defined(CONFIG_SOFTMMU)
690
    tcg_out_mov(s, r1, addr_reg); 
691

    
692
    tcg_out_mov(s, r0, addr_reg); 
693
 
694
    tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
695
    tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
696
    
697
    tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
698
    tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
699
    
700
    tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
701
    tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
702

    
703
    tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
704
    tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
705
    tcg_out8(s, (5 << 3) | r1);
706
    tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
707

    
708
    /* cmp 0(r1), r0 */
709
    tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
710
    
711
    tcg_out_mov(s, r0, addr_reg);
712
    
713
#if TARGET_LONG_BITS == 32
714
    /* je label1 */
715
    tcg_out8(s, 0x70 + JCC_JE);
716
    label1_ptr = s->code_ptr;
717
    s->code_ptr++;
718
#else
719
    /* jne label3 */
720
    tcg_out8(s, 0x70 + JCC_JNE);
721
    label3_ptr = s->code_ptr;
722
    s->code_ptr++;
723
    
724
    /* cmp 4(r1), addr_reg2 */
725
    tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
726

    
727
    /* je label1 */
728
    tcg_out8(s, 0x70 + JCC_JE);
729
    label1_ptr = s->code_ptr;
730
    s->code_ptr++;
731
    
732
    /* label3: */
733
    *label3_ptr = s->code_ptr - label3_ptr - 1;
734
#endif
735

    
736
    /* XXX: move that code at the end of the TB */
737
#if TARGET_LONG_BITS == 32
738
    if (opc == 3) {
739
        tcg_out_mov(s, TCG_REG_EDX, data_reg);
740
        tcg_out_mov(s, TCG_REG_ECX, data_reg2);
741
        tcg_out8(s, 0x6a); /* push Ib */
742
        tcg_out8(s, mem_index);
743
        tcg_out8(s, 0xe8);
744
        tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - 
745
                  (tcg_target_long)s->code_ptr - 4);
746
        tcg_out_addi(s, TCG_REG_ESP, 4);
747
    } else {
748
        switch(opc) {
749
        case 0:
750
            /* movzbl */
751
            tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_EDX, data_reg);
752
            break;
753
        case 1:
754
            /* movzwl */
755
            tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_EDX, data_reg);
756
            break;
757
        case 2:
758
            tcg_out_mov(s, TCG_REG_EDX, data_reg);
759
            break;
760
        }
761
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
762
        tcg_out8(s, 0xe8);
763
        tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - 
764
                  (tcg_target_long)s->code_ptr - 4);
765
    }
766
#else
767
    if (opc == 3) {
768
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
769
        tcg_out8(s, 0x6a); /* push Ib */
770
        tcg_out8(s, mem_index);
771
        tcg_out_opc(s, 0x50 + data_reg2); /* push */
772
        tcg_out_opc(s, 0x50 + data_reg); /* push */
773
        tcg_out8(s, 0xe8);
774
        tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - 
775
                  (tcg_target_long)s->code_ptr - 4);
776
        tcg_out_addi(s, TCG_REG_ESP, 12);
777
    } else {
778
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
779
        switch(opc) {
780
        case 0:
781
            /* movzbl */
782
            tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_ECX, data_reg);
783
            break;
784
        case 1:
785
            /* movzwl */
786
            tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_ECX, data_reg);
787
            break;
788
        case 2:
789
            tcg_out_mov(s, TCG_REG_ECX, data_reg);
790
            break;
791
        }
792
        tcg_out8(s, 0x6a); /* push Ib */
793
        tcg_out8(s, mem_index);
794
        tcg_out8(s, 0xe8);
795
        tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - 
796
                  (tcg_target_long)s->code_ptr - 4);
797
        tcg_out_addi(s, TCG_REG_ESP, 4);
798
    }
799
#endif
800
    
801
    /* jmp label2 */
802
    tcg_out8(s, 0xeb);
803
    label2_ptr = s->code_ptr;
804
    s->code_ptr++;
805
    
806
    /* label1: */
807
    *label1_ptr = s->code_ptr - label1_ptr - 1;
808

    
809
    /* add x(r1), r0 */
810
    tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) - 
811
                         offsetof(CPUTLBEntry, addr_write));
812
#else
813
    r0 = addr_reg;
814
#endif
815

    
816
#ifdef TARGET_WORDS_BIGENDIAN
817
    bswap = 1;
818
#else
819
    bswap = 0;
820
#endif
821
    switch(opc) {
822
    case 0:
823
        /* movb */
824
        tcg_out_modrm_offset(s, 0x88, data_reg, r0, 0);
825
        break;
826
    case 1:
827
        if (bswap) {
828
            tcg_out_mov(s, r1, data_reg);
829
            tcg_out8(s, 0x66); /* rolw $8, %ecx */
830
            tcg_out_modrm(s, 0xc1, 0, r1);
831
            tcg_out8(s, 8);
832
            data_reg = r1;
833
        }
834
        /* movw */
835
        tcg_out8(s, 0x66);
836
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
837
        break;
838
    case 2:
839
        if (bswap) {
840
            tcg_out_mov(s, r1, data_reg);
841
            /* bswap data_reg */
842
            tcg_out_opc(s, (0xc8 + r1) | P_EXT);
843
            data_reg = r1;
844
        }
845
        /* movl */
846
        tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
847
        break;
848
    case 3:
849
        if (bswap) {
850
            tcg_out_mov(s, r1, data_reg2);
851
            /* bswap data_reg */
852
            tcg_out_opc(s, (0xc8 + r1) | P_EXT);
853
            tcg_out_modrm_offset(s, 0x89, r1, r0, 0);
854
            tcg_out_mov(s, r1, data_reg);
855
            /* bswap data_reg */
856
            tcg_out_opc(s, (0xc8 + r1) | P_EXT);
857
            tcg_out_modrm_offset(s, 0x89, r1, r0, 4);
858
        } else {
859
            tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
860
            tcg_out_modrm_offset(s, 0x89, data_reg2, r0, 4);
861
        }
862
        break;
863
    default:
864
        tcg_abort();
865
    }
866

    
867
#if defined(CONFIG_SOFTMMU)
868
    /* label2: */
869
    *label2_ptr = s->code_ptr - label2_ptr - 1;
870
#endif
871
}
872

    
873
static inline void tcg_out_op(TCGContext *s, int opc, 
874
                              const TCGArg *args, const int *const_args)
875
{
876
    int c;
877
    
878
    switch(opc) {
879
    case INDEX_op_exit_tb:
880
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
881
        tcg_out8(s, 0xc3); /* ret */
882
        break;
883
    case INDEX_op_goto_tb:
884
        if (s->tb_jmp_offset) {
885
            /* direct jump method */
886
            tcg_out8(s, 0xe9); /* jmp im */
887
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
888
            tcg_out32(s, 0);
889
        } else {
890
            /* indirect jump method */
891
            /* jmp Ev */
892
            tcg_out_modrm_offset(s, 0xff, 4, -1, 
893
                                 (tcg_target_long)(s->tb_next + args[0]));
894
        }
895
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
896
        break;
897
    case INDEX_op_call:
898
        if (const_args[0]) {
899
            tcg_out8(s, 0xe8);
900
            tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
901
        } else {
902
            tcg_out_modrm(s, 0xff, 2, args[0]);
903
        }
904
        break;
905
    case INDEX_op_jmp:
906
        if (const_args[0]) {
907
            tcg_out8(s, 0xe9);
908
            tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
909
        } else {
910
            tcg_out_modrm(s, 0xff, 4, args[0]);
911
        }
912
        break;
913
    case INDEX_op_br:
914
        tcg_out_jxx(s, JCC_JMP, args[0]);
915
        break;
916
    case INDEX_op_movi_i32:
917
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
918
        break;
919
    case INDEX_op_ld8u_i32:
920
        /* movzbl */
921
        tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
922
        break;
923
    case INDEX_op_ld8s_i32:
924
        /* movsbl */
925
        tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
926
        break;
927
    case INDEX_op_ld16u_i32:
928
        /* movzwl */
929
        tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
930
        break;
931
    case INDEX_op_ld16s_i32:
932
        /* movswl */
933
        tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
934
        break;
935
    case INDEX_op_ld_i32:
936
        /* movl */
937
        tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
938
        break;
939
    case INDEX_op_st8_i32:
940
        /* movb */
941
        tcg_out_modrm_offset(s, 0x88, args[0], args[1], args[2]);
942
        break;
943
    case INDEX_op_st16_i32:
944
        /* movw */
945
        tcg_out8(s, 0x66);
946
        tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
947
        break;
948
    case INDEX_op_st_i32:
949
        /* movl */
950
        tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
951
        break;
952
    case INDEX_op_sub_i32:
953
        c = ARITH_SUB;
954
        goto gen_arith;
955
    case INDEX_op_and_i32:
956
        c = ARITH_AND;
957
        goto gen_arith;
958
    case INDEX_op_or_i32:
959
        c = ARITH_OR;
960
        goto gen_arith;
961
    case INDEX_op_xor_i32:
962
        c = ARITH_XOR;
963
        goto gen_arith;
964
    case INDEX_op_add_i32:
965
        c = ARITH_ADD;
966
    gen_arith:
967
        if (const_args[2]) {
968
            tgen_arithi(s, c, args[0], args[2]);
969
        } else {
970
            tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
971
        }
972
        break;
973
    case INDEX_op_mul_i32:
974
        if (const_args[2]) {
975
            int32_t val;
976
            val = args[2];
977
            if (val == (int8_t)val) {
978
                tcg_out_modrm(s, 0x6b, args[0], args[0]);
979
                tcg_out8(s, val);
980
            } else {
981
                tcg_out_modrm(s, 0x69, args[0], args[0]);
982
                tcg_out32(s, val);
983
            }
984
        } else {
985
            tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
986
        }
987
        break;
988
    case INDEX_op_mulu2_i32:
989
        tcg_out_modrm(s, 0xf7, 4, args[3]);
990
        break;
991
    case INDEX_op_div2_i32:
992
        tcg_out_modrm(s, 0xf7, 7, args[4]);
993
        break;
994
    case INDEX_op_divu2_i32:
995
        tcg_out_modrm(s, 0xf7, 6, args[4]);
996
        break;
997
    case INDEX_op_shl_i32:
998
        c = SHIFT_SHL;
999
    gen_shift32:
1000
        if (const_args[2]) {
1001
            if (args[2] == 1) {
1002
                tcg_out_modrm(s, 0xd1, c, args[0]);
1003
            } else {
1004
                tcg_out_modrm(s, 0xc1, c, args[0]);
1005
                tcg_out8(s, args[2]);
1006
            }
1007
        } else {
1008
            tcg_out_modrm(s, 0xd3, c, args[0]);
1009
        }
1010
        break;
1011
    case INDEX_op_shr_i32:
1012
        c = SHIFT_SHR;
1013
        goto gen_shift32;
1014
    case INDEX_op_sar_i32:
1015
        c = SHIFT_SAR;
1016
        goto gen_shift32;
1017
        
1018
    case INDEX_op_add2_i32:
1019
        if (const_args[4]) 
1020
            tgen_arithi(s, ARITH_ADD, args[0], args[4]);
1021
        else
1022
            tcg_out_modrm(s, 0x01 | (ARITH_ADD << 3), args[4], args[0]);
1023
        if (const_args[5]) 
1024
            tgen_arithi(s, ARITH_ADC, args[1], args[5]);
1025
        else
1026
            tcg_out_modrm(s, 0x01 | (ARITH_ADC << 3), args[5], args[1]);
1027
        break;
1028
    case INDEX_op_sub2_i32:
1029
        if (const_args[4]) 
1030
            tgen_arithi(s, ARITH_SUB, args[0], args[4]);
1031
        else
1032
            tcg_out_modrm(s, 0x01 | (ARITH_SUB << 3), args[4], args[0]);
1033
        if (const_args[5]) 
1034
            tgen_arithi(s, ARITH_SBB, args[1], args[5]);
1035
        else
1036
            tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]);
1037
        break;
1038
    case INDEX_op_brcond_i32:
1039
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
1040
        break;
1041
    case INDEX_op_brcond2_i32:
1042
        tcg_out_brcond2(s, args, const_args);
1043
        break;
1044

    
1045
    case INDEX_op_qemu_ld8u:
1046
        tcg_out_qemu_ld(s, args, 0);
1047
        break;
1048
    case INDEX_op_qemu_ld8s:
1049
        tcg_out_qemu_ld(s, args, 0 | 4);
1050
        break;
1051
    case INDEX_op_qemu_ld16u:
1052
        tcg_out_qemu_ld(s, args, 1);
1053
        break;
1054
    case INDEX_op_qemu_ld16s:
1055
        tcg_out_qemu_ld(s, args, 1 | 4);
1056
        break;
1057
    case INDEX_op_qemu_ld32u:
1058
        tcg_out_qemu_ld(s, args, 2);
1059
        break;
1060
    case INDEX_op_qemu_ld64:
1061
        tcg_out_qemu_ld(s, args, 3);
1062
        break;
1063
        
1064
    case INDEX_op_qemu_st8:
1065
        tcg_out_qemu_st(s, args, 0);
1066
        break;
1067
    case INDEX_op_qemu_st16:
1068
        tcg_out_qemu_st(s, args, 1);
1069
        break;
1070
    case INDEX_op_qemu_st32:
1071
        tcg_out_qemu_st(s, args, 2);
1072
        break;
1073
    case INDEX_op_qemu_st64:
1074
        tcg_out_qemu_st(s, args, 3);
1075
        break;
1076

    
1077
    default:
1078
        tcg_abort();
1079
    }
1080
}
1081

    
1082
static const TCGTargetOpDef x86_op_defs[] = {
1083
    { INDEX_op_exit_tb, { } },
1084
    { INDEX_op_goto_tb, { } },
1085
    { INDEX_op_call, { "ri" } },
1086
    { INDEX_op_jmp, { "ri" } },
1087
    { INDEX_op_br, { } },
1088
    { INDEX_op_mov_i32, { "r", "r" } },
1089
    { INDEX_op_movi_i32, { "r" } },
1090
    { INDEX_op_ld8u_i32, { "r", "r" } },
1091
    { INDEX_op_ld8s_i32, { "r", "r" } },
1092
    { INDEX_op_ld16u_i32, { "r", "r" } },
1093
    { INDEX_op_ld16s_i32, { "r", "r" } },
1094
    { INDEX_op_ld_i32, { "r", "r" } },
1095
    { INDEX_op_st8_i32, { "q", "r" } },
1096
    { INDEX_op_st16_i32, { "r", "r" } },
1097
    { INDEX_op_st_i32, { "r", "r" } },
1098

    
1099
    { INDEX_op_add_i32, { "r", "0", "ri" } },
1100
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1101
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1102
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1103
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1104
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1105
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1106
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1107
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1108

    
1109
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1110
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1111
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1112

    
1113
    { INDEX_op_brcond_i32, { "r", "ri" } },
1114

    
1115
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1116
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1117
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1118

    
1119
#if TARGET_LONG_BITS == 32
1120
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1121
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1122
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1123
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1124
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1125
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1126

    
1127
    { INDEX_op_qemu_st8, { "cb", "L" } },
1128
    { INDEX_op_qemu_st16, { "L", "L" } },
1129
    { INDEX_op_qemu_st32, { "L", "L" } },
1130
    { INDEX_op_qemu_st64, { "L", "L", "L" } },
1131
#else
1132
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1133
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1134
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1135
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1136
    { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
1137
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1138

    
1139
    { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1140
    { INDEX_op_qemu_st16, { "L", "L", "L" } },
1141
    { INDEX_op_qemu_st32, { "L", "L", "L" } },
1142
    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1143
#endif
1144
    { -1 },
1145
};
1146

    
1147
void tcg_target_init(TCGContext *s)
1148
{
1149
    /* fail safe */
1150
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1151
        tcg_abort();
1152

    
1153
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1154
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1155
                     (1 << TCG_REG_EAX) | 
1156
                     (1 << TCG_REG_EDX) | 
1157
                     (1 << TCG_REG_ECX));
1158
    
1159
    tcg_regset_clear(s->reserved_regs);
1160
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1161

    
1162
    tcg_add_target_add_op_defs(x86_op_defs);
1163
}