Statistics
| Branch: | Revision:

root / tcg / i386 / tcg-target.c @ 3b6dac34

History | View | Annotate | Download (44 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, TCGType type, 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

    
706
/* Perform the TLB load and compare.
707

708
   Inputs:
709
   ADDRLO_IDX contains the index into ARGS of the low part of the
710
   address; the high part of the address is at ADDR_LOW_IDX+1.
711

712
   MEM_INDEX and S_BITS are the memory context and log2 size of the load.
713

714
   WHICH is the offset into the CPUTLBEntry structure of the slot to read.
715
   This should be offsetof addr_read or addr_write.
716

717
   Outputs:
718
   LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
719
   positions of the displacements of forward jumps to the TLB miss case.
720

721
   EAX is loaded with the low part of the address.  In the TLB hit case,
722
   it has been adjusted as indicated by the TLB and so is a host address.
723
   In the TLB miss case, it continues to hold a guest address.
724

725
   EDX is clobbered.  */
726

    
727
static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
728
                                    int mem_index, int s_bits,
729
                                    const TCGArg *args,
730
                                    uint8_t **label_ptr, int which)
731
{
732
    const int addrlo = args[addrlo_idx];
733
    const int r0 = TCG_REG_EAX;
734
    const int r1 = TCG_REG_EDX;
735

    
736
    tcg_out_mov(s, TCG_TYPE_I32, r1, addrlo);
737
    tcg_out_mov(s, TCG_TYPE_I32, r0, addrlo);
738

    
739
    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
740

    
741
    tgen_arithi(s, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
742
    tgen_arithi(s, ARITH_AND, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
743

    
744
    tcg_out_modrm_sib_offset(s, OPC_LEA, r1, TCG_AREG0, r1, 0,
745
                             offsetof(CPUState, tlb_table[mem_index][0])
746
                             + which);
747

    
748
    /* cmp 0(r1), r0 */
749
    tcg_out_modrm_offset(s, OPC_CMP_GvEv, r0, r1, 0);
750

    
751
    tcg_out_mov(s, TCG_TYPE_I32, r0, addrlo);
752

    
753
    /* jne label1 */
754
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
755
    label_ptr[0] = s->code_ptr;
756
    s->code_ptr++;
757

    
758
    if (TARGET_LONG_BITS == 64) {
759
        /* cmp 4(r1), addrhi */
760
        tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
761

    
762
        /* jne label1 */
763
        tcg_out8(s, OPC_JCC_short + JCC_JNE);
764
        label_ptr[1] = s->code_ptr;
765
        s->code_ptr++;
766
    }
767

    
768
    /* TLB Hit.  */
769

    
770
    /* add addend(r1), r0 */
771
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
772
                         offsetof(CPUTLBEntry, addend) - which);
773
}
774
#endif
775

    
776
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
777
                                   int base, tcg_target_long ofs, int sizeop)
778
{
779
#ifdef TARGET_WORDS_BIGENDIAN
780
    const int bswap = 1;
781
#else
782
    const int bswap = 0;
783
#endif
784
    switch (sizeop) {
785
    case 0:
786
        /* movzbl */
787
        tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
788
        break;
789
    case 0 | 4:
790
        /* movsbl */
791
        tcg_out_modrm_offset(s, OPC_MOVSBL, datalo, base, ofs);
792
        break;
793
    case 1:
794
        /* movzwl */
795
        tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
796
        if (bswap) {
797
            tcg_out_rolw_8(s, datalo);
798
        }
799
        break;
800
    case 1 | 4:
801
        /* movswl */
802
        tcg_out_modrm_offset(s, OPC_MOVSWL, datalo, base, ofs);
803
        if (bswap) {
804
            tcg_out_rolw_8(s, datalo);
805
            tcg_out_modrm(s, OPC_MOVSWL, datalo, datalo);
806
        }
807
        break;
808
    case 2:
809
        tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
810
        if (bswap) {
811
            tcg_out_bswap32(s, datalo);
812
        }
813
        break;
814
    case 3:
815
        if (bswap) {
816
            int t = datalo;
817
            datalo = datahi;
818
            datahi = t;
819
        }
820
        if (base != datalo) {
821
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
822
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
823
        } else {
824
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
825
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
826
        }
827
        if (bswap) {
828
            tcg_out_bswap32(s, datalo);
829
            tcg_out_bswap32(s, datahi);
830
        }
831
        break;
832
    default:
833
        tcg_abort();
834
    }
835
}
836

    
837
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
838
   EAX. It will be useful once fixed registers globals are less
839
   common. */
840
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
841
                            int opc)
842
{
843
    int data_reg, data_reg2 = 0;
844
    int addrlo_idx;
845
#if defined(CONFIG_SOFTMMU)
846
    int mem_index, s_bits, arg_idx;
847
    uint8_t *label_ptr[3];
848
#endif
849

    
850
    data_reg = args[0];
851
    addrlo_idx = 1;
852
    if (opc == 3) {
853
        data_reg2 = args[1];
854
        addrlo_idx = 2;
855
    }
856

    
857
#if defined(CONFIG_SOFTMMU)
858
    mem_index = args[addrlo_idx + (TARGET_LONG_BITS / 32)];
859
    s_bits = opc & 3;
860

    
861
    tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
862
                     label_ptr, offsetof(CPUTLBEntry, addr_read));
863

    
864
    /* TLB Hit.  */
865
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, TCG_REG_EAX, 0, opc);
866

    
867
    /* jmp label2 */
868
    tcg_out8(s, OPC_JMP_short);
869
    label_ptr[2] = s->code_ptr;
870
    s->code_ptr++;
871

    
872
    /* TLB Miss.  */
873

    
874
    /* label1: */
875
    *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
876
    if (TARGET_LONG_BITS == 64) {
877
        *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
878
    }
879

    
880
    /* XXX: move that code at the end of the TB */
881
    /* EAX is already loaded.  */
882
    arg_idx = 1;
883
    if (TARGET_LONG_BITS == 64) {
884
        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++],
885
                    args[addrlo_idx + 1]);
886
    }
887
    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
888
                 mem_index);
889
    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
890

    
891
    switch(opc) {
892
    case 0 | 4:
893
        tcg_out_ext8s(s, data_reg, TCG_REG_EAX);
894
        break;
895
    case 1 | 4:
896
        tcg_out_ext16s(s, data_reg, TCG_REG_EAX);
897
        break;
898
    case 0:
899
        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
900
        break;
901
    case 1:
902
        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
903
        break;
904
    case 2:
905
    default:
906
        tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
907
        break;
908
    case 3:
909
        if (data_reg == TCG_REG_EDX) {
910
            /* xchg %edx, %eax */
911
            tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX);
912
            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
913
        } else {
914
            tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
915
            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
916
        }
917
        break;
918
    }
919

    
920
    /* label2: */
921
    *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
922
#else
923
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2,
924
                           args[addrlo_idx], GUEST_BASE, opc);
925
#endif
926
}
927

    
928
static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
929
                                   int base, tcg_target_long ofs, int sizeop)
930
{
931
#ifdef TARGET_WORDS_BIGENDIAN
932
    const int bswap = 1;
933
#else
934
    const int bswap = 0;
935
#endif
936
    /* ??? Ideally we wouldn't need a scratch register.  For user-only,
937
       we could perform the bswap twice to restore the original value
938
       instead of moving to the scratch.  But as it is, the L constraint
939
       means that EDX is definitely free here.  */
940
    int scratch = TCG_REG_EDX;
941

    
942
    switch (sizeop) {
943
    case 0:
944
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, datalo, base, ofs);
945
        break;
946
    case 1:
947
        if (bswap) {
948
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
949
            tcg_out_rolw_8(s, scratch);
950
            datalo = scratch;
951
        }
952
        /* movw */
953
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
954
                             datalo, base, ofs);
955
        break;
956
    case 2:
957
        if (bswap) {
958
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
959
            tcg_out_bswap32(s, scratch);
960
            datalo = scratch;
961
        }
962
        tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
963
        break;
964
    case 3:
965
        if (bswap) {
966
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
967
            tcg_out_bswap32(s, scratch);
968
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
969
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
970
            tcg_out_bswap32(s, scratch);
971
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
972
        } else {
973
            tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
974
            tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
975
        }
976
        break;
977
    default:
978
        tcg_abort();
979
    }
980
}
981

    
982
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
983
                            int opc)
984
{
985
    int data_reg, data_reg2 = 0;
986
    int addrlo_idx;
987
#if defined(CONFIG_SOFTMMU)
988
    int mem_index, s_bits;
989
    int stack_adjust;
990
    uint8_t *label_ptr[3];
991
#endif
992

    
993
    data_reg = args[0];
994
    addrlo_idx = 1;
995
    if (opc == 3) {
996
        data_reg2 = args[1];
997
        addrlo_idx = 2;
998
    }
999

    
1000
#if defined(CONFIG_SOFTMMU)
1001
    mem_index = args[addrlo_idx + (TARGET_LONG_BITS / 32)];
1002
    s_bits = opc;
1003

    
1004
    tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1005
                     label_ptr, offsetof(CPUTLBEntry, addr_write));
1006

    
1007
    /* TLB Hit.  */
1008
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, TCG_REG_EAX, 0, opc);
1009

    
1010
    /* jmp label2 */
1011
    tcg_out8(s, OPC_JMP_short);
1012
    label_ptr[2] = s->code_ptr;
1013
    s->code_ptr++;
1014

    
1015
    /* TLB Miss.  */
1016

    
1017
    /* label1: */
1018
    *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
1019
    if (TARGET_LONG_BITS == 64) {
1020
        *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1021
    }
1022

    
1023
    /* XXX: move that code at the end of the TB */
1024
    if (TARGET_LONG_BITS == 32) {
1025
        tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg);
1026
        if (opc == 3) {
1027
            tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg2);
1028
            tcg_out_pushi(s, mem_index);
1029
            stack_adjust = 4;
1030
        } else {
1031
            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
1032
            stack_adjust = 0;
1033
        }
1034
    } else {
1035
        if (opc == 3) {
1036
            tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
1037
            tcg_out_pushi(s, mem_index);
1038
            tcg_out_push(s, data_reg2);
1039
            tcg_out_push(s, data_reg);
1040
            stack_adjust = 12;
1041
        } else {
1042
            tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
1043
            switch(opc) {
1044
            case 0:
1045
                tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
1046
                break;
1047
            case 1:
1048
                tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
1049
                break;
1050
            case 2:
1051
                tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg);
1052
                break;
1053
            }
1054
            tcg_out_pushi(s, mem_index);
1055
            stack_adjust = 4;
1056
        }
1057
    }
1058

    
1059
    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1060

    
1061
    if (stack_adjust == 4) {
1062
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
1063
        tcg_out_pop(s, TCG_REG_ECX);
1064
    } else if (stack_adjust != 0) {
1065
        tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
1066
    }
1067

    
1068
    /* label2: */
1069
    *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1070
#else
1071
    tcg_out_qemu_st_direct(s, data_reg, data_reg2,
1072
                           args[addrlo_idx], GUEST_BASE, opc);
1073
#endif
1074
}
1075

    
1076
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1077
                              const TCGArg *args, const int *const_args)
1078
{
1079
    int c;
1080

    
1081
    switch(opc) {
1082
    case INDEX_op_exit_tb:
1083
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
1084
        tcg_out8(s, OPC_JMP_long); /* jmp tb_ret_addr */
1085
        tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
1086
        break;
1087
    case INDEX_op_goto_tb:
1088
        if (s->tb_jmp_offset) {
1089
            /* direct jump method */
1090
            tcg_out8(s, OPC_JMP_long); /* jmp im */
1091
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1092
            tcg_out32(s, 0);
1093
        } else {
1094
            /* indirect jump method */
1095
            tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1096
                                 (tcg_target_long)(s->tb_next + args[0]));
1097
        }
1098
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1099
        break;
1100
    case INDEX_op_call:
1101
        if (const_args[0]) {
1102
            tcg_out_calli(s, args[0]);
1103
        } else {
1104
            /* call *reg */
1105
            tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1106
        }
1107
        break;
1108
    case INDEX_op_jmp:
1109
        if (const_args[0]) {
1110
            tcg_out8(s, OPC_JMP_long);
1111
            tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
1112
        } else {
1113
            /* jmp *reg */
1114
            tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1115
        }
1116
        break;
1117
    case INDEX_op_br:
1118
        tcg_out_jxx(s, JCC_JMP, args[0], 0);
1119
        break;
1120
    case INDEX_op_movi_i32:
1121
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1122
        break;
1123
    case INDEX_op_ld8u_i32:
1124
        /* movzbl */
1125
        tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
1126
        break;
1127
    case INDEX_op_ld8s_i32:
1128
        /* movsbl */
1129
        tcg_out_modrm_offset(s, OPC_MOVSBL, args[0], args[1], args[2]);
1130
        break;
1131
    case INDEX_op_ld16u_i32:
1132
        /* movzwl */
1133
        tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1134
        break;
1135
    case INDEX_op_ld16s_i32:
1136
        /* movswl */
1137
        tcg_out_modrm_offset(s, OPC_MOVSWL, args[0], args[1], args[2]);
1138
        break;
1139
    case INDEX_op_ld_i32:
1140
        tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1141
        break;
1142
    case INDEX_op_st8_i32:
1143
        /* movb */
1144
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, args[0], args[1], args[2]);
1145
        break;
1146
    case INDEX_op_st16_i32:
1147
        /* movw */
1148
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1149
                             args[0], args[1], args[2]);
1150
        break;
1151
    case INDEX_op_st_i32:
1152
        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1153
        break;
1154
    case INDEX_op_add_i32:
1155
        /* For 3-operand addition, use LEA.  */
1156
        if (args[0] != args[1]) {
1157
            TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1158

    
1159
            if (const_args[2]) {
1160
                c3 = a2, a2 = -1;
1161
            } else if (a0 == a2) {
1162
                /* Watch out for dest = src + dest, since we've removed
1163
                   the matching constraint on the add.  */
1164
                tgen_arithr(s, ARITH_ADD, a0, a1);
1165
                break;
1166
            }
1167

    
1168
            tcg_out_modrm_sib_offset(s, OPC_LEA, a0, a1, a2, 0, c3);
1169
            break;
1170
        }
1171
        c = ARITH_ADD;
1172
        goto gen_arith;
1173
    case INDEX_op_sub_i32:
1174
        c = ARITH_SUB;
1175
        goto gen_arith;
1176
    case INDEX_op_and_i32:
1177
        c = ARITH_AND;
1178
        goto gen_arith;
1179
    case INDEX_op_or_i32:
1180
        c = ARITH_OR;
1181
        goto gen_arith;
1182
    case INDEX_op_xor_i32:
1183
        c = ARITH_XOR;
1184
        goto gen_arith;
1185
    gen_arith:
1186
        if (const_args[2]) {
1187
            tgen_arithi(s, c, args[0], args[2], 0);
1188
        } else {
1189
            tgen_arithr(s, c, args[0], args[2]);
1190
        }
1191
        break;
1192
    case INDEX_op_mul_i32:
1193
        if (const_args[2]) {
1194
            int32_t val;
1195
            val = args[2];
1196
            if (val == (int8_t)val) {
1197
                tcg_out_modrm(s, OPC_IMUL_GvEvIb, args[0], args[0]);
1198
                tcg_out8(s, val);
1199
            } else {
1200
                tcg_out_modrm(s, OPC_IMUL_GvEvIz, args[0], args[0]);
1201
                tcg_out32(s, val);
1202
            }
1203
        } else {
1204
            tcg_out_modrm(s, OPC_IMUL_GvEv, args[0], args[2]);
1205
        }
1206
        break;
1207
    case INDEX_op_mulu2_i32:
1208
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1209
        break;
1210
    case INDEX_op_div2_i32:
1211
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_IDIV, args[4]);
1212
        break;
1213
    case INDEX_op_divu2_i32:
1214
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_DIV, args[4]);
1215
        break;
1216
    case INDEX_op_shl_i32:
1217
        c = SHIFT_SHL;
1218
    gen_shift32:
1219
        if (const_args[2]) {
1220
            tcg_out_shifti(s, c, args[0], args[2]);
1221
        } else {
1222
            tcg_out_modrm(s, OPC_SHIFT_cl, c, args[0]);
1223
        }
1224
        break;
1225
    case INDEX_op_shr_i32:
1226
        c = SHIFT_SHR;
1227
        goto gen_shift32;
1228
    case INDEX_op_sar_i32:
1229
        c = SHIFT_SAR;
1230
        goto gen_shift32;
1231
    case INDEX_op_rotl_i32:
1232
        c = SHIFT_ROL;
1233
        goto gen_shift32;
1234
    case INDEX_op_rotr_i32:
1235
        c = SHIFT_ROR;
1236
        goto gen_shift32;
1237

    
1238
    case INDEX_op_add2_i32:
1239
        if (const_args[4]) {
1240
            tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1241
        } else {
1242
            tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1243
        }
1244
        if (const_args[5]) {
1245
            tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1246
        } else {
1247
            tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1248
        }
1249
        break;
1250
    case INDEX_op_sub2_i32:
1251
        if (const_args[4]) {
1252
            tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1253
        } else {
1254
            tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1255
        }
1256
        if (const_args[5]) {
1257
            tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1258
        } else {
1259
            tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1260
        }
1261
        break;
1262
    case INDEX_op_brcond_i32:
1263
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1264
                       args[3], 0);
1265
        break;
1266
    case INDEX_op_brcond2_i32:
1267
        tcg_out_brcond2(s, args, const_args, 0);
1268
        break;
1269

    
1270
    case INDEX_op_bswap16_i32:
1271
        tcg_out_rolw_8(s, args[0]);
1272
        break;
1273
    case INDEX_op_bswap32_i32:
1274
        tcg_out_bswap32(s, args[0]);
1275
        break;
1276

    
1277
    case INDEX_op_neg_i32:
1278
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, args[0]);
1279
        break;
1280

    
1281
    case INDEX_op_not_i32:
1282
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NOT, args[0]);
1283
        break;
1284

    
1285
    case INDEX_op_ext8s_i32:
1286
        tcg_out_ext8s(s, args[0], args[1]);
1287
        break;
1288
    case INDEX_op_ext16s_i32:
1289
        tcg_out_ext16s(s, args[0], args[1]);
1290
        break;
1291
    case INDEX_op_ext8u_i32:
1292
        tcg_out_ext8u(s, args[0], args[1]);
1293
        break;
1294
    case INDEX_op_ext16u_i32:
1295
        tcg_out_ext16u(s, args[0], args[1]);
1296
        break;
1297

    
1298
    case INDEX_op_setcond_i32:
1299
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
1300
        break;
1301
    case INDEX_op_setcond2_i32:
1302
        tcg_out_setcond2(s, args, const_args);
1303
        break;
1304

    
1305
    case INDEX_op_qemu_ld8u:
1306
        tcg_out_qemu_ld(s, args, 0);
1307
        break;
1308
    case INDEX_op_qemu_ld8s:
1309
        tcg_out_qemu_ld(s, args, 0 | 4);
1310
        break;
1311
    case INDEX_op_qemu_ld16u:
1312
        tcg_out_qemu_ld(s, args, 1);
1313
        break;
1314
    case INDEX_op_qemu_ld16s:
1315
        tcg_out_qemu_ld(s, args, 1 | 4);
1316
        break;
1317
    case INDEX_op_qemu_ld32:
1318
        tcg_out_qemu_ld(s, args, 2);
1319
        break;
1320
    case INDEX_op_qemu_ld64:
1321
        tcg_out_qemu_ld(s, args, 3);
1322
        break;
1323

    
1324
    case INDEX_op_qemu_st8:
1325
        tcg_out_qemu_st(s, args, 0);
1326
        break;
1327
    case INDEX_op_qemu_st16:
1328
        tcg_out_qemu_st(s, args, 1);
1329
        break;
1330
    case INDEX_op_qemu_st32:
1331
        tcg_out_qemu_st(s, args, 2);
1332
        break;
1333
    case INDEX_op_qemu_st64:
1334
        tcg_out_qemu_st(s, args, 3);
1335
        break;
1336

    
1337
    default:
1338
        tcg_abort();
1339
    }
1340
}
1341

    
1342
static const TCGTargetOpDef x86_op_defs[] = {
1343
    { INDEX_op_exit_tb, { } },
1344
    { INDEX_op_goto_tb, { } },
1345
    { INDEX_op_call, { "ri" } },
1346
    { INDEX_op_jmp, { "ri" } },
1347
    { INDEX_op_br, { } },
1348
    { INDEX_op_mov_i32, { "r", "r" } },
1349
    { INDEX_op_movi_i32, { "r" } },
1350
    { INDEX_op_ld8u_i32, { "r", "r" } },
1351
    { INDEX_op_ld8s_i32, { "r", "r" } },
1352
    { INDEX_op_ld16u_i32, { "r", "r" } },
1353
    { INDEX_op_ld16s_i32, { "r", "r" } },
1354
    { INDEX_op_ld_i32, { "r", "r" } },
1355
    { INDEX_op_st8_i32, { "q", "r" } },
1356
    { INDEX_op_st16_i32, { "r", "r" } },
1357
    { INDEX_op_st_i32, { "r", "r" } },
1358

    
1359
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1360
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1361
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1362
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1363
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1364
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1365
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1366
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1367
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1368

    
1369
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1370
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1371
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1372
    { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1373
    { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1374

    
1375
    { INDEX_op_brcond_i32, { "r", "ri" } },
1376

    
1377
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1378
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1379
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1380

    
1381
    { INDEX_op_bswap16_i32, { "r", "0" } },
1382
    { INDEX_op_bswap32_i32, { "r", "0" } },
1383

    
1384
    { INDEX_op_neg_i32, { "r", "0" } },
1385

    
1386
    { INDEX_op_not_i32, { "r", "0" } },
1387

    
1388
    { INDEX_op_ext8s_i32, { "r", "q" } },
1389
    { INDEX_op_ext16s_i32, { "r", "r" } },
1390
    { INDEX_op_ext8u_i32, { "r", "q" } },
1391
    { INDEX_op_ext16u_i32, { "r", "r" } },
1392

    
1393
    { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1394
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1395

    
1396
#if TARGET_LONG_BITS == 32
1397
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1398
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1399
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1400
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1401
    { INDEX_op_qemu_ld32, { "r", "L" } },
1402
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1403

    
1404
    { INDEX_op_qemu_st8, { "cb", "L" } },
1405
    { INDEX_op_qemu_st16, { "L", "L" } },
1406
    { INDEX_op_qemu_st32, { "L", "L" } },
1407
    { INDEX_op_qemu_st64, { "L", "L", "L" } },
1408
#else
1409
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1410
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1411
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1412
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1413
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1414
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1415

    
1416
    { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1417
    { INDEX_op_qemu_st16, { "L", "L", "L" } },
1418
    { INDEX_op_qemu_st32, { "L", "L", "L" } },
1419
    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1420
#endif
1421
    { -1 },
1422
};
1423

    
1424
static int tcg_target_callee_save_regs[] = {
1425
    /*    TCG_REG_EBP, */ /* currently used for the global env, so no
1426
                             need to save */
1427
    TCG_REG_EBX,
1428
    TCG_REG_ESI,
1429
    TCG_REG_EDI,
1430
};
1431

    
1432
/* Generate global QEMU prologue and epilogue code */
1433
void tcg_target_qemu_prologue(TCGContext *s)
1434
{
1435
    int i, frame_size, push_size, stack_addend;
1436

    
1437
    /* TB prologue */
1438
    /* save all callee saved registers */
1439
    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1440
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
1441
    }
1442
    /* reserve some stack space */
1443
    push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
1444
    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1445
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1446
        ~(TCG_TARGET_STACK_ALIGN - 1);
1447
    stack_addend = frame_size - push_size;
1448
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1449

    
1450
    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_EAX); /* jmp *%eax */
1451

    
1452
    /* TB epilogue */
1453
    tb_ret_addr = s->code_ptr;
1454
    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1455
    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1456
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1457
    }
1458
    tcg_out_opc(s, OPC_RET);
1459
}
1460

    
1461
void tcg_target_init(TCGContext *s)
1462
{
1463
#if !defined(CONFIG_USER_ONLY)
1464
    /* fail safe */
1465
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1466
        tcg_abort();
1467
#endif
1468

    
1469
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1470

    
1471
    tcg_regset_clear(tcg_target_call_clobber_regs);
1472
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1473
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1474
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
1475

    
1476
    tcg_regset_clear(s->reserved_regs);
1477
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1478

    
1479
    tcg_add_target_add_op_defs(x86_op_defs);
1480
}