Statistics
| Branch: | Revision:

root / tcg / i386 / tcg-target.c @ 96b4cf38

History | View | Annotate | Download (43.3 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
#ifndef CONFIG_USER_ONLY
708
#define GUEST_BASE 0
709
#endif
710

    
711
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
712
   EAX. It will be useful once fixed registers globals are less
713
   common. */
714
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
715
                            int opc)
716
{
717
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
718
#if defined(CONFIG_SOFTMMU)
719
    uint8_t *label1_ptr, *label2_ptr;
720
#endif
721
#if TARGET_LONG_BITS == 64
722
#if defined(CONFIG_SOFTMMU)
723
    uint8_t *label3_ptr;
724
#endif
725
    int addr_reg2;
726
#endif
727

    
728
    data_reg = *args++;
729
    if (opc == 3)
730
        data_reg2 = *args++;
731
    else
732
        data_reg2 = 0;
733
    addr_reg = *args++;
734
#if TARGET_LONG_BITS == 64
735
    addr_reg2 = *args++;
736
#endif
737
    mem_index = *args;
738
    s_bits = opc & 3;
739

    
740
    r0 = TCG_REG_EAX;
741
    r1 = TCG_REG_EDX;
742

    
743
#if defined(CONFIG_SOFTMMU)
744
    tcg_out_mov(s, r1, addr_reg);
745
    tcg_out_mov(s, r0, addr_reg);
746

    
747
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
748

    
749
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
750
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
751

    
752
    tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
753
                             offsetof(CPUState,
754
                                      tlb_table[mem_index][0].addr_read));
755

    
756
    /* cmp 0(r1), r0 */
757
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
758

    
759
    tcg_out_mov(s, r0, addr_reg);
760

    
761
#if TARGET_LONG_BITS == 32
762
    /* je label1 */
763
    tcg_out8(s, OPC_JCC_short + JCC_JE);
764
    label1_ptr = s->code_ptr;
765
    s->code_ptr++;
766
#else
767
    /* jne label3 */
768
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
769
    label3_ptr = s->code_ptr;
770
    s->code_ptr++;
771

    
772
    /* cmp 4(r1), addr_reg2 */
773
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
774

    
775
    /* je label1 */
776
    tcg_out8(s, OPC_JCC_short + JCC_JE);
777
    label1_ptr = s->code_ptr;
778
    s->code_ptr++;
779

    
780
    /* label3: */
781
    *label3_ptr = s->code_ptr - label3_ptr - 1;
782
#endif
783

    
784
    /* XXX: move that code at the end of the TB */
785
#if TARGET_LONG_BITS == 32
786
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
787
#else
788
    tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
789
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
790
#endif
791
    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
792

    
793
    switch(opc) {
794
    case 0 | 4:
795
        tcg_out_ext8s(s, data_reg, TCG_REG_EAX);
796
        break;
797
    case 1 | 4:
798
        tcg_out_ext16s(s, data_reg, TCG_REG_EAX);
799
        break;
800
    case 0:
801
        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
802
        break;
803
    case 1:
804
        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
805
        break;
806
    case 2:
807
    default:
808
        tcg_out_mov(s, data_reg, TCG_REG_EAX);
809
        break;
810
    case 3:
811
        if (data_reg == TCG_REG_EDX) {
812
            /* xchg %edx, %eax */
813
            tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX);
814
            tcg_out_mov(s, data_reg2, TCG_REG_EAX);
815
        } else {
816
            tcg_out_mov(s, data_reg, TCG_REG_EAX);
817
            tcg_out_mov(s, data_reg2, TCG_REG_EDX);
818
        }
819
        break;
820
    }
821

    
822
    /* jmp label2 */
823
    tcg_out8(s, OPC_JMP_short);
824
    label2_ptr = s->code_ptr;
825
    s->code_ptr++;
826

    
827
    /* label1: */
828
    *label1_ptr = s->code_ptr - label1_ptr - 1;
829

    
830
    /* add x(r1), r0 */
831
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
832
                         offsetof(CPUTLBEntry, addend) -
833
                         offsetof(CPUTLBEntry, addr_read));
834
#else
835
    r0 = addr_reg;
836
#endif
837

    
838
#ifdef TARGET_WORDS_BIGENDIAN
839
    bswap = 1;
840
#else
841
    bswap = 0;
842
#endif
843
    switch(opc) {
844
    case 0:
845
        /* movzbl */
846
        tcg_out_modrm_offset(s, OPC_MOVZBL, data_reg, r0, GUEST_BASE);
847
        break;
848
    case 0 | 4:
849
        /* movsbl */
850
        tcg_out_modrm_offset(s, OPC_MOVSBL, data_reg, r0, GUEST_BASE);
851
        break;
852
    case 1:
853
        /* movzwl */
854
        tcg_out_modrm_offset(s, OPC_MOVZWL, data_reg, r0, GUEST_BASE);
855
        if (bswap) {
856
            tcg_out_rolw_8(s, data_reg);
857
        }
858
        break;
859
    case 1 | 4:
860
        /* movswl */
861
        tcg_out_modrm_offset(s, OPC_MOVSWL, data_reg, r0, GUEST_BASE);
862
        if (bswap) {
863
            tcg_out_rolw_8(s, data_reg);
864

    
865
            /* movswl data_reg, data_reg */
866
            tcg_out_modrm(s, OPC_MOVSWL, data_reg, data_reg);
867
        }
868
        break;
869
    case 2:
870
        tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
871
        if (bswap) {
872
            tcg_out_bswap32(s, data_reg);
873
        }
874
        break;
875
    case 3:
876
        if (bswap) {
877
            int t = data_reg;
878
            data_reg = data_reg2;
879
            data_reg2 = t;
880
        }
881
        if (r0 != data_reg) {
882
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
883
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
884
        } else {
885
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
886
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
887
        }
888
        if (bswap) {
889
            tcg_out_bswap32(s, data_reg);
890
            tcg_out_bswap32(s, data_reg2);
891
        }
892
        break;
893
    default:
894
        tcg_abort();
895
    }
896

    
897
#if defined(CONFIG_SOFTMMU)
898
    /* label2: */
899
    *label2_ptr = s->code_ptr - label2_ptr - 1;
900
#endif
901
}
902

    
903

    
904
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
905
                            int opc)
906
{
907
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
908
#if defined(CONFIG_SOFTMMU)
909
    int stack_adjust;
910
    uint8_t *label1_ptr, *label2_ptr;
911
#endif
912
#if TARGET_LONG_BITS == 64
913
#if defined(CONFIG_SOFTMMU)
914
    uint8_t *label3_ptr;
915
#endif
916
    int addr_reg2;
917
#endif
918

    
919
    data_reg = *args++;
920
    if (opc == 3)
921
        data_reg2 = *args++;
922
    else
923
        data_reg2 = 0;
924
    addr_reg = *args++;
925
#if TARGET_LONG_BITS == 64
926
    addr_reg2 = *args++;
927
#endif
928
    mem_index = *args;
929

    
930
    s_bits = opc;
931

    
932
    r0 = TCG_REG_EAX;
933
    r1 = TCG_REG_EDX;
934

    
935
#if defined(CONFIG_SOFTMMU)
936
    tcg_out_mov(s, r1, addr_reg);
937
    tcg_out_mov(s, r0, addr_reg);
938

    
939
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
940

    
941
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
942
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
943

    
944
    tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
945
                             offsetof(CPUState,
946
                                      tlb_table[mem_index][0].addr_write));
947

    
948
    /* cmp 0(r1), r0 */
949
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
950

    
951
    tcg_out_mov(s, r0, addr_reg);
952

    
953
#if TARGET_LONG_BITS == 32
954
    /* je label1 */
955
    tcg_out8(s, OPC_JCC_short + JCC_JE);
956
    label1_ptr = s->code_ptr;
957
    s->code_ptr++;
958
#else
959
    /* jne label3 */
960
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
961
    label3_ptr = s->code_ptr;
962
    s->code_ptr++;
963

    
964
    /* cmp 4(r1), addr_reg2 */
965
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
966

    
967
    /* je label1 */
968
    tcg_out8(s, OPC_JCC_short + JCC_JE);
969
    label1_ptr = s->code_ptr;
970
    s->code_ptr++;
971

    
972
    /* label3: */
973
    *label3_ptr = s->code_ptr - label3_ptr - 1;
974
#endif
975

    
976
    /* XXX: move that code at the end of the TB */
977
#if TARGET_LONG_BITS == 32
978
    if (opc == 3) {
979
        tcg_out_mov(s, TCG_REG_EDX, data_reg);
980
        tcg_out_mov(s, TCG_REG_ECX, data_reg2);
981
        tcg_out_pushi(s, mem_index);
982
        stack_adjust = 4;
983
    } else {
984
        switch(opc) {
985
        case 0:
986
            tcg_out_ext8u(s, TCG_REG_EDX, data_reg);
987
            break;
988
        case 1:
989
            tcg_out_ext16u(s, TCG_REG_EDX, data_reg);
990
            break;
991
        case 2:
992
            tcg_out_mov(s, TCG_REG_EDX, data_reg);
993
            break;
994
        }
995
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
996
        stack_adjust = 0;
997
    }
998
#else
999
    if (opc == 3) {
1000
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
1001
        tcg_out_pushi(s, mem_index);
1002
        tcg_out_push(s, data_reg2);
1003
        tcg_out_push(s, data_reg);
1004
        stack_adjust = 12;
1005
    } else {
1006
        tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
1007
        switch(opc) {
1008
        case 0:
1009
            tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
1010
            break;
1011
        case 1:
1012
            tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
1013
            break;
1014
        case 2:
1015
            tcg_out_mov(s, TCG_REG_ECX, data_reg);
1016
            break;
1017
        }
1018
        tcg_out_pushi(s, mem_index);
1019
        stack_adjust = 4;
1020
    }
1021
#endif
1022

    
1023
    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1024

    
1025
    if (stack_adjust == 4) {
1026
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
1027
        tcg_out_pop(s, TCG_REG_ECX);
1028
    } else if (stack_adjust != 0) {
1029
        tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
1030
    }
1031

    
1032
    /* jmp label2 */
1033
    tcg_out8(s, OPC_JMP_short);
1034
    label2_ptr = s->code_ptr;
1035
    s->code_ptr++;
1036

    
1037
    /* label1: */
1038
    *label1_ptr = s->code_ptr - label1_ptr - 1;
1039

    
1040
    /* add x(r1), r0 */
1041
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
1042
                         offsetof(CPUTLBEntry, addend) -
1043
                         offsetof(CPUTLBEntry, addr_write));
1044
#else
1045
    r0 = addr_reg;
1046
#endif
1047

    
1048
#ifdef TARGET_WORDS_BIGENDIAN
1049
    bswap = 1;
1050
#else
1051
    bswap = 0;
1052
#endif
1053
    switch(opc) {
1054
    case 0:
1055
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, data_reg, r0, GUEST_BASE);
1056
        break;
1057
    case 1:
1058
        if (bswap) {
1059
            tcg_out_mov(s, r1, data_reg);
1060
            tcg_out_rolw_8(s, r1);
1061
            data_reg = r1;
1062
        }
1063
        /* movw */
1064
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1065
                             data_reg, r0, GUEST_BASE);
1066
        break;
1067
    case 2:
1068
        if (bswap) {
1069
            tcg_out_mov(s, r1, data_reg);
1070
            tcg_out_bswap32(s, r1);
1071
            data_reg = r1;
1072
        }
1073
        tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1074
        break;
1075
    case 3:
1076
        if (bswap) {
1077
            tcg_out_mov(s, r1, data_reg2);
1078
            tcg_out_bswap32(s, r1);
1079
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE);
1080
            tcg_out_mov(s, r1, data_reg);
1081
            tcg_out_bswap32(s, r1);
1082
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE + 4);
1083
        } else {
1084
            tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1085
            tcg_out_st(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
1086
        }
1087
        break;
1088
    default:
1089
        tcg_abort();
1090
    }
1091

    
1092
#if defined(CONFIG_SOFTMMU)
1093
    /* label2: */
1094
    *label2_ptr = s->code_ptr - label2_ptr - 1;
1095
#endif
1096
}
1097

    
1098
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1099
                              const TCGArg *args, const int *const_args)
1100
{
1101
    int c;
1102

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

    
1181
            if (const_args[2]) {
1182
                c3 = a2, a2 = -1;
1183
            } else if (a0 == a2) {
1184
                /* Watch out for dest = src + dest, since we've removed
1185
                   the matching constraint on the add.  */
1186
                tgen_arithr(s, ARITH_ADD, a0, a1);
1187
                break;
1188
            }
1189

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

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

    
1292
    case INDEX_op_bswap16_i32:
1293
        tcg_out_rolw_8(s, args[0]);
1294
        break;
1295
    case INDEX_op_bswap32_i32:
1296
        tcg_out_bswap32(s, args[0]);
1297
        break;
1298

    
1299
    case INDEX_op_neg_i32:
1300
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, args[0]);
1301
        break;
1302

    
1303
    case INDEX_op_not_i32:
1304
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NOT, args[0]);
1305
        break;
1306

    
1307
    case INDEX_op_ext8s_i32:
1308
        tcg_out_ext8s(s, args[0], args[1]);
1309
        break;
1310
    case INDEX_op_ext16s_i32:
1311
        tcg_out_ext16s(s, args[0], args[1]);
1312
        break;
1313
    case INDEX_op_ext8u_i32:
1314
        tcg_out_ext8u(s, args[0], args[1]);
1315
        break;
1316
    case INDEX_op_ext16u_i32:
1317
        tcg_out_ext16u(s, args[0], args[1]);
1318
        break;
1319

    
1320
    case INDEX_op_setcond_i32:
1321
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
1322
        break;
1323
    case INDEX_op_setcond2_i32:
1324
        tcg_out_setcond2(s, args, const_args);
1325
        break;
1326

    
1327
    case INDEX_op_qemu_ld8u:
1328
        tcg_out_qemu_ld(s, args, 0);
1329
        break;
1330
    case INDEX_op_qemu_ld8s:
1331
        tcg_out_qemu_ld(s, args, 0 | 4);
1332
        break;
1333
    case INDEX_op_qemu_ld16u:
1334
        tcg_out_qemu_ld(s, args, 1);
1335
        break;
1336
    case INDEX_op_qemu_ld16s:
1337
        tcg_out_qemu_ld(s, args, 1 | 4);
1338
        break;
1339
    case INDEX_op_qemu_ld32:
1340
        tcg_out_qemu_ld(s, args, 2);
1341
        break;
1342
    case INDEX_op_qemu_ld64:
1343
        tcg_out_qemu_ld(s, args, 3);
1344
        break;
1345

    
1346
    case INDEX_op_qemu_st8:
1347
        tcg_out_qemu_st(s, args, 0);
1348
        break;
1349
    case INDEX_op_qemu_st16:
1350
        tcg_out_qemu_st(s, args, 1);
1351
        break;
1352
    case INDEX_op_qemu_st32:
1353
        tcg_out_qemu_st(s, args, 2);
1354
        break;
1355
    case INDEX_op_qemu_st64:
1356
        tcg_out_qemu_st(s, args, 3);
1357
        break;
1358

    
1359
    default:
1360
        tcg_abort();
1361
    }
1362
}
1363

    
1364
static const TCGTargetOpDef x86_op_defs[] = {
1365
    { INDEX_op_exit_tb, { } },
1366
    { INDEX_op_goto_tb, { } },
1367
    { INDEX_op_call, { "ri" } },
1368
    { INDEX_op_jmp, { "ri" } },
1369
    { INDEX_op_br, { } },
1370
    { INDEX_op_mov_i32, { "r", "r" } },
1371
    { INDEX_op_movi_i32, { "r" } },
1372
    { INDEX_op_ld8u_i32, { "r", "r" } },
1373
    { INDEX_op_ld8s_i32, { "r", "r" } },
1374
    { INDEX_op_ld16u_i32, { "r", "r" } },
1375
    { INDEX_op_ld16s_i32, { "r", "r" } },
1376
    { INDEX_op_ld_i32, { "r", "r" } },
1377
    { INDEX_op_st8_i32, { "q", "r" } },
1378
    { INDEX_op_st16_i32, { "r", "r" } },
1379
    { INDEX_op_st_i32, { "r", "r" } },
1380

    
1381
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1382
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1383
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1384
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1385
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1386
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1387
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1388
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1389
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1390

    
1391
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1392
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1393
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1394
    { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1395
    { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1396

    
1397
    { INDEX_op_brcond_i32, { "r", "ri" } },
1398

    
1399
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1400
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1401
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1402

    
1403
    { INDEX_op_bswap16_i32, { "r", "0" } },
1404
    { INDEX_op_bswap32_i32, { "r", "0" } },
1405

    
1406
    { INDEX_op_neg_i32, { "r", "0" } },
1407

    
1408
    { INDEX_op_not_i32, { "r", "0" } },
1409

    
1410
    { INDEX_op_ext8s_i32, { "r", "q" } },
1411
    { INDEX_op_ext16s_i32, { "r", "r" } },
1412
    { INDEX_op_ext8u_i32, { "r", "q" } },
1413
    { INDEX_op_ext16u_i32, { "r", "r" } },
1414

    
1415
    { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1416
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1417

    
1418
#if TARGET_LONG_BITS == 32
1419
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1420
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1421
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1422
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1423
    { INDEX_op_qemu_ld32, { "r", "L" } },
1424
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1425

    
1426
    { INDEX_op_qemu_st8, { "cb", "L" } },
1427
    { INDEX_op_qemu_st16, { "L", "L" } },
1428
    { INDEX_op_qemu_st32, { "L", "L" } },
1429
    { INDEX_op_qemu_st64, { "L", "L", "L" } },
1430
#else
1431
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1432
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1433
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1434
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1435
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1436
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1437

    
1438
    { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1439
    { INDEX_op_qemu_st16, { "L", "L", "L" } },
1440
    { INDEX_op_qemu_st32, { "L", "L", "L" } },
1441
    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1442
#endif
1443
    { -1 },
1444
};
1445

    
1446
static int tcg_target_callee_save_regs[] = {
1447
    /*    TCG_REG_EBP, */ /* currently used for the global env, so no
1448
                             need to save */
1449
    TCG_REG_EBX,
1450
    TCG_REG_ESI,
1451
    TCG_REG_EDI,
1452
};
1453

    
1454
/* Generate global QEMU prologue and epilogue code */
1455
void tcg_target_qemu_prologue(TCGContext *s)
1456
{
1457
    int i, frame_size, push_size, stack_addend;
1458

    
1459
    /* TB prologue */
1460
    /* save all callee saved registers */
1461
    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1462
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
1463
    }
1464
    /* reserve some stack space */
1465
    push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1466
    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1467
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1468
        ~(TCG_TARGET_STACK_ALIGN - 1);
1469
    stack_addend = frame_size - push_size;
1470
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1471

    
1472
    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
1473

    
1474
    /* TB epilogue */
1475
    tb_ret_addr = s->code_ptr;
1476
    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1477
    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1478
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1479
    }
1480
    tcg_out_opc(s, OPC_RET);
1481
}
1482

    
1483
void tcg_target_init(TCGContext *s)
1484
{
1485
#if !defined(CONFIG_USER_ONLY)
1486
    /* fail safe */
1487
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1488
        tcg_abort();
1489
#endif
1490

    
1491
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1492

    
1493
    tcg_regset_clear(tcg_target_call_clobber_regs);
1494
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1495
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1496
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
1497

    
1498
    tcg_regset_clear(s->reserved_regs);
1499
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1500

    
1501
    tcg_add_target_add_op_defs(x86_op_defs);
1502
}