Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (67.9 kB)

1 c896fe29 bellard
/*
2 c896fe29 bellard
 * Tiny Code Generator for QEMU
3 c896fe29 bellard
 *
4 c896fe29 bellard
 * Copyright (c) 2008 Fabrice Bellard
5 c896fe29 bellard
 *
6 c896fe29 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 c896fe29 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 c896fe29 bellard
 * in the Software without restriction, including without limitation the rights
9 c896fe29 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 c896fe29 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 c896fe29 bellard
 * furnished to do so, subject to the following conditions:
12 c896fe29 bellard
 *
13 c896fe29 bellard
 * The above copyright notice and this permission notice shall be included in
14 c896fe29 bellard
 * all copies or substantial portions of the Software.
15 c896fe29 bellard
 *
16 c896fe29 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 c896fe29 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 c896fe29 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 c896fe29 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 c896fe29 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 c896fe29 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 c896fe29 bellard
 * THE SOFTWARE.
23 c896fe29 bellard
 */
24 d4a9eb1f blueswir1
25 d4a9eb1f blueswir1
#ifndef NDEBUG
26 d4a9eb1f blueswir1
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
27 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
28 5d8a4f8f Richard Henderson
    "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
29 5d8a4f8f Richard Henderson
    "%r8",  "%r9",  "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
30 5d8a4f8f Richard Henderson
#else
31 5d8a4f8f Richard Henderson
    "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
32 5d8a4f8f Richard Henderson
#endif
33 c896fe29 bellard
};
34 d4a9eb1f blueswir1
#endif
35 c896fe29 bellard
36 d4a9eb1f blueswir1
static const int tcg_target_reg_alloc_order[] = {
37 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
38 5d8a4f8f Richard Henderson
    TCG_REG_RBP,
39 5d8a4f8f Richard Henderson
    TCG_REG_RBX,
40 5d8a4f8f Richard Henderson
    TCG_REG_R12,
41 5d8a4f8f Richard Henderson
    TCG_REG_R13,
42 5d8a4f8f Richard Henderson
    TCG_REG_R14,
43 5d8a4f8f Richard Henderson
    TCG_REG_R15,
44 5d8a4f8f Richard Henderson
    TCG_REG_R10,
45 5d8a4f8f Richard Henderson
    TCG_REG_R11,
46 5d8a4f8f Richard Henderson
    TCG_REG_R9,
47 5d8a4f8f Richard Henderson
    TCG_REG_R8,
48 5d8a4f8f Richard Henderson
    TCG_REG_RCX,
49 5d8a4f8f Richard Henderson
    TCG_REG_RDX,
50 5d8a4f8f Richard Henderson
    TCG_REG_RSI,
51 5d8a4f8f Richard Henderson
    TCG_REG_RDI,
52 5d8a4f8f Richard Henderson
    TCG_REG_RAX,
53 5d8a4f8f Richard Henderson
#else
54 c896fe29 bellard
    TCG_REG_EBX,
55 c896fe29 bellard
    TCG_REG_ESI,
56 c896fe29 bellard
    TCG_REG_EDI,
57 c896fe29 bellard
    TCG_REG_EBP,
58 6648e296 Richard Henderson
    TCG_REG_ECX,
59 6648e296 Richard Henderson
    TCG_REG_EDX,
60 6648e296 Richard Henderson
    TCG_REG_EAX,
61 5d8a4f8f Richard Henderson
#endif
62 c896fe29 bellard
};
63 c896fe29 bellard
64 5d8a4f8f Richard Henderson
static const int tcg_target_call_iarg_regs[] = {
65 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
66 8d918718 Stefan Weil
#if defined(_WIN64)
67 8d918718 Stefan Weil
    TCG_REG_RCX,
68 8d918718 Stefan Weil
    TCG_REG_RDX,
69 8d918718 Stefan Weil
#else
70 5d8a4f8f Richard Henderson
    TCG_REG_RDI,
71 5d8a4f8f Richard Henderson
    TCG_REG_RSI,
72 5d8a4f8f Richard Henderson
    TCG_REG_RDX,
73 5d8a4f8f Richard Henderson
    TCG_REG_RCX,
74 8d918718 Stefan Weil
#endif
75 5d8a4f8f Richard Henderson
    TCG_REG_R8,
76 5d8a4f8f Richard Henderson
    TCG_REG_R9,
77 5d8a4f8f Richard Henderson
#else
78 d73685e3 Stefan Weil
    /* 32 bit mode uses stack based calling convention (GCC default). */
79 5d8a4f8f Richard Henderson
#endif
80 5d8a4f8f Richard Henderson
};
81 5d8a4f8f Richard Henderson
82 68af23af Stefan Weil
static const int tcg_target_call_oarg_regs[] = {
83 5d8a4f8f Richard Henderson
    TCG_REG_EAX,
84 68af23af Stefan Weil
#if TCG_TARGET_REG_BITS == 32
85 5d8a4f8f Richard Henderson
    TCG_REG_EDX
86 68af23af Stefan Weil
#endif
87 5d8a4f8f Richard Henderson
};
88 c896fe29 bellard
89 b18212c6 Stefan Weil
/* Registers used with L constraint, which are the first argument 
90 b18212c6 Stefan Weil
   registers on x86_64, and two random call clobbered registers on
91 b18212c6 Stefan Weil
   i386. */
92 b18212c6 Stefan Weil
#if TCG_TARGET_REG_BITS == 64
93 b18212c6 Stefan Weil
# define TCG_REG_L0 tcg_target_call_iarg_regs[0]
94 b18212c6 Stefan Weil
# define TCG_REG_L1 tcg_target_call_iarg_regs[1]
95 b18212c6 Stefan Weil
# define TCG_REG_L2 tcg_target_call_iarg_regs[2]
96 b18212c6 Stefan Weil
#else
97 b18212c6 Stefan Weil
# define TCG_REG_L0 TCG_REG_EAX
98 b18212c6 Stefan Weil
# define TCG_REG_L1 TCG_REG_EDX
99 b18212c6 Stefan Weil
#endif
100 b18212c6 Stefan Weil
101 b03cce8e bellard
static uint8_t *tb_ret_addr;
102 b03cce8e bellard
103 78686523 Richard Henderson
static void patch_reloc(uint8_t *code_ptr, int type,
104 f54b3f92 aurel32
                        tcg_target_long value, tcg_target_long addend)
105 c896fe29 bellard
{
106 f54b3f92 aurel32
    value += addend;
107 c896fe29 bellard
    switch(type) {
108 c896fe29 bellard
    case R_386_PC32:
109 5d8a4f8f Richard Henderson
        value -= (uintptr_t)code_ptr;
110 5d8a4f8f Richard Henderson
        if (value != (int32_t)value) {
111 5d8a4f8f Richard Henderson
            tcg_abort();
112 5d8a4f8f Richard Henderson
        }
113 5d8a4f8f Richard Henderson
        *(uint32_t *)code_ptr = value;
114 c896fe29 bellard
        break;
115 f75b56c1 Richard Henderson
    case R_386_PC8:
116 5d8a4f8f Richard Henderson
        value -= (uintptr_t)code_ptr;
117 f75b56c1 Richard Henderson
        if (value != (int8_t)value) {
118 f75b56c1 Richard Henderson
            tcg_abort();
119 f75b56c1 Richard Henderson
        }
120 f75b56c1 Richard Henderson
        *(uint8_t *)code_ptr = value;
121 f75b56c1 Richard Henderson
        break;
122 c896fe29 bellard
    default:
123 c896fe29 bellard
        tcg_abort();
124 c896fe29 bellard
    }
125 c896fe29 bellard
}
126 c896fe29 bellard
127 c896fe29 bellard
/* maximum number of register used for input function arguments */
128 c896fe29 bellard
static inline int tcg_target_get_call_iarg_regs_count(int flags)
129 c896fe29 bellard
{
130 d73685e3 Stefan Weil
    return ARRAY_SIZE(tcg_target_call_iarg_regs);
131 c896fe29 bellard
}
132 c896fe29 bellard
133 c896fe29 bellard
/* parse target specific constraints */
134 d4a9eb1f blueswir1
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
135 c896fe29 bellard
{
136 c896fe29 bellard
    const char *ct_str;
137 c896fe29 bellard
138 c896fe29 bellard
    ct_str = *pct_str;
139 c896fe29 bellard
    switch(ct_str[0]) {
140 c896fe29 bellard
    case 'a':
141 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
142 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
143 c896fe29 bellard
        break;
144 c896fe29 bellard
    case 'b':
145 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
146 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
147 c896fe29 bellard
        break;
148 c896fe29 bellard
    case 'c':
149 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
150 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
151 c896fe29 bellard
        break;
152 c896fe29 bellard
    case 'd':
153 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
154 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
155 c896fe29 bellard
        break;
156 c896fe29 bellard
    case 'S':
157 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
158 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
159 c896fe29 bellard
        break;
160 c896fe29 bellard
    case 'D':
161 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
162 c896fe29 bellard
        tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
163 c896fe29 bellard
        break;
164 c896fe29 bellard
    case 'q':
165 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
166 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
167 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xffff);
168 5d8a4f8f Richard Henderson
        } else {
169 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xf);
170 5d8a4f8f Richard Henderson
        }
171 c896fe29 bellard
        break;
172 a4773324 Jan Kiszka
    case 'Q':
173 a4773324 Jan Kiszka
        ct->ct |= TCG_CT_REG;
174 a4773324 Jan Kiszka
        tcg_regset_set32(ct->u.regs, 0, 0xf);
175 a4773324 Jan Kiszka
        break;
176 c896fe29 bellard
    case 'r':
177 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
178 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
179 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xffff);
180 5d8a4f8f Richard Henderson
        } else {
181 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xff);
182 5d8a4f8f Richard Henderson
        }
183 c896fe29 bellard
        break;
184 c896fe29 bellard
185 c896fe29 bellard
        /* qemu_ld/st address constraint */
186 c896fe29 bellard
    case 'L':
187 c896fe29 bellard
        ct->ct |= TCG_CT_REG;
188 b18212c6 Stefan Weil
#if TCG_TARGET_REG_BITS == 64
189 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xffff);
190 b18212c6 Stefan Weil
            tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
191 b18212c6 Stefan Weil
            tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
192 b18212c6 Stefan Weil
            tcg_regset_reset_reg(ct->u.regs, TCG_REG_L2);
193 b18212c6 Stefan Weil
#else
194 5d8a4f8f Richard Henderson
            tcg_regset_set32(ct->u.regs, 0, 0xff);
195 b18212c6 Stefan Weil
            tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
196 b18212c6 Stefan Weil
            tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
197 b18212c6 Stefan Weil
#endif
198 5d8a4f8f Richard Henderson
        break;
199 5d8a4f8f Richard Henderson
200 5d8a4f8f Richard Henderson
    case 'e':
201 5d8a4f8f Richard Henderson
        ct->ct |= TCG_CT_CONST_S32;
202 5d8a4f8f Richard Henderson
        break;
203 5d8a4f8f Richard Henderson
    case 'Z':
204 5d8a4f8f Richard Henderson
        ct->ct |= TCG_CT_CONST_U32;
205 c896fe29 bellard
        break;
206 5d8a4f8f Richard Henderson
207 c896fe29 bellard
    default:
208 c896fe29 bellard
        return -1;
209 c896fe29 bellard
    }
210 c896fe29 bellard
    ct_str++;
211 c896fe29 bellard
    *pct_str = ct_str;
212 c896fe29 bellard
    return 0;
213 c896fe29 bellard
}
214 c896fe29 bellard
215 c896fe29 bellard
/* test if a constant matches the constraint */
216 c896fe29 bellard
static inline int tcg_target_const_match(tcg_target_long val,
217 c896fe29 bellard
                                         const TCGArgConstraint *arg_ct)
218 c896fe29 bellard
{
219 5d8a4f8f Richard Henderson
    int ct = arg_ct->ct;
220 5d8a4f8f Richard Henderson
    if (ct & TCG_CT_CONST) {
221 c896fe29 bellard
        return 1;
222 5d8a4f8f Richard Henderson
    }
223 5d8a4f8f Richard Henderson
    if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
224 5d8a4f8f Richard Henderson
        return 1;
225 5d8a4f8f Richard Henderson
    }
226 5d8a4f8f Richard Henderson
    if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
227 5d8a4f8f Richard Henderson
        return 1;
228 5d8a4f8f Richard Henderson
    }
229 5d8a4f8f Richard Henderson
    return 0;
230 c896fe29 bellard
}
231 c896fe29 bellard
232 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
233 5d8a4f8f Richard Henderson
# define LOWREGMASK(x)        ((x) & 7)
234 5d8a4f8f Richard Henderson
#else
235 5d8a4f8f Richard Henderson
# define LOWREGMASK(x)        (x)
236 5d8a4f8f Richard Henderson
#endif
237 5d8a4f8f Richard Henderson
238 96b4cf38 Richard Henderson
#define P_EXT                0x100                /* 0x0f opcode prefix */
239 96b4cf38 Richard Henderson
#define P_DATA16        0x200                /* 0x66 opcode prefix */
240 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
241 5d8a4f8f Richard Henderson
# define P_ADDR32        0x400                /* 0x67 opcode prefix */
242 5d8a4f8f Richard Henderson
# define P_REXW                0x800                /* Set REX.W = 1 */
243 5d8a4f8f Richard Henderson
# define P_REXB_R        0x1000                /* REG field as byte register */
244 5d8a4f8f Richard Henderson
# define P_REXB_RM        0x2000                /* R/M field as byte register */
245 5d8a4f8f Richard Henderson
#else
246 5d8a4f8f Richard Henderson
# define P_ADDR32        0
247 5d8a4f8f Richard Henderson
# define P_REXW                0
248 5d8a4f8f Richard Henderson
# define P_REXB_R        0
249 5d8a4f8f Richard Henderson
# define P_REXB_RM        0
250 5d8a4f8f Richard Henderson
#endif
251 fcb5dac1 Richard Henderson
252 a369a702 Richard Henderson
#define OPC_ARITH_EvIz        (0x81)
253 a369a702 Richard Henderson
#define OPC_ARITH_EvIb        (0x83)
254 81570a70 Richard Henderson
#define OPC_ARITH_GvEv        (0x03)                /* ... plus (ARITH_FOO << 3) */
255 81570a70 Richard Henderson
#define OPC_ADD_GvEv        (OPC_ARITH_GvEv | (ARITH_ADD << 3))
256 fcb5dac1 Richard Henderson
#define OPC_BSWAP        (0xc8 | P_EXT)
257 aadb21a4 Richard Henderson
#define OPC_CALL_Jz        (0xe8)
258 d0a16297 Richard Henderson
#define OPC_CMOVCC      (0x40 | P_EXT)  /* ... plus condition code */
259 81570a70 Richard Henderson
#define OPC_CMP_GvEv        (OPC_ARITH_GvEv | (ARITH_CMP << 3))
260 81570a70 Richard Henderson
#define OPC_DEC_r32        (0x48)
261 0566d387 Richard Henderson
#define OPC_IMUL_GvEv        (0xaf | P_EXT)
262 0566d387 Richard Henderson
#define OPC_IMUL_GvEvIb        (0x6b)
263 0566d387 Richard Henderson
#define OPC_IMUL_GvEvIz        (0x69)
264 81570a70 Richard Henderson
#define OPC_INC_r32        (0x40)
265 da441cff Richard Henderson
#define OPC_JCC_long        (0x80 | P_EXT)        /* ... plus condition code */
266 da441cff Richard Henderson
#define OPC_JCC_short        (0x70)                /* ... plus condition code */
267 da441cff Richard Henderson
#define OPC_JMP_long        (0xe9)
268 da441cff Richard Henderson
#define OPC_JMP_short        (0xeb)
269 34a6d0b7 Richard Henderson
#define OPC_LEA         (0x8d)
270 af266089 Richard Henderson
#define OPC_MOVB_EvGv        (0x88)                /* stores, more or less */
271 af266089 Richard Henderson
#define OPC_MOVL_EvGv        (0x89)                /* stores, more or less */
272 af266089 Richard Henderson
#define OPC_MOVL_GvEv        (0x8b)                /* loads, more or less */
273 5c2d2a9e Aurelien Jarno
#define OPC_MOVB_EvIz   (0xc6)
274 5d8a4f8f Richard Henderson
#define OPC_MOVL_EvIz        (0xc7)
275 ef10b106 Richard Henderson
#define OPC_MOVL_Iv     (0xb8)
276 6817c355 Richard Henderson
#define OPC_MOVSBL        (0xbe | P_EXT)
277 6817c355 Richard Henderson
#define OPC_MOVSWL        (0xbf | P_EXT)
278 5d8a4f8f Richard Henderson
#define OPC_MOVSLQ        (0x63 | P_REXW)
279 55e082a7 Richard Henderson
#define OPC_MOVZBL        (0xb6 | P_EXT)
280 55e082a7 Richard Henderson
#define OPC_MOVZWL        (0xb7 | P_EXT)
281 6858614e Richard Henderson
#define OPC_POP_r32        (0x58)
282 6858614e Richard Henderson
#define OPC_PUSH_r32        (0x50)
283 6858614e Richard Henderson
#define OPC_PUSH_Iv        (0x68)
284 6858614e Richard Henderson
#define OPC_PUSH_Ib        (0x6a)
285 3c3accc6 Richard Henderson
#define OPC_RET                (0xc3)
286 5d8a4f8f Richard Henderson
#define OPC_SETCC        (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
287 f53dba01 Richard Henderson
#define OPC_SHIFT_1        (0xd1)
288 f53dba01 Richard Henderson
#define OPC_SHIFT_Ib        (0xc1)
289 f53dba01 Richard Henderson
#define OPC_SHIFT_cl        (0xd3)
290 81570a70 Richard Henderson
#define OPC_TESTL        (0x85)
291 b3e66df7 Richard Henderson
#define OPC_XCHG_ax_r32        (0x90)
292 fcb5dac1 Richard Henderson
293 9363dedb Richard Henderson
#define OPC_GRP3_Ev        (0xf7)
294 9363dedb Richard Henderson
#define OPC_GRP5        (0xff)
295 9363dedb Richard Henderson
296 9363dedb Richard Henderson
/* Group 1 opcode extensions for 0x80-0x83.
297 9363dedb Richard Henderson
   These are also used as modifiers for OPC_ARITH.  */
298 c896fe29 bellard
#define ARITH_ADD 0
299 c896fe29 bellard
#define ARITH_OR  1
300 c896fe29 bellard
#define ARITH_ADC 2
301 c896fe29 bellard
#define ARITH_SBB 3
302 c896fe29 bellard
#define ARITH_AND 4
303 c896fe29 bellard
#define ARITH_SUB 5
304 c896fe29 bellard
#define ARITH_XOR 6
305 c896fe29 bellard
#define ARITH_CMP 7
306 c896fe29 bellard
307 da441cff Richard Henderson
/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3.  */
308 9619376c aurel32
#define SHIFT_ROL 0
309 9619376c aurel32
#define SHIFT_ROR 1
310 c896fe29 bellard
#define SHIFT_SHL 4
311 c896fe29 bellard
#define SHIFT_SHR 5
312 c896fe29 bellard
#define SHIFT_SAR 7
313 c896fe29 bellard
314 9363dedb Richard Henderson
/* Group 3 opcode extensions for 0xf6, 0xf7.  To be used with OPC_GRP3.  */
315 9363dedb Richard Henderson
#define EXT3_NOT   2
316 9363dedb Richard Henderson
#define EXT3_NEG   3
317 9363dedb Richard Henderson
#define EXT3_MUL   4
318 9363dedb Richard Henderson
#define EXT3_IMUL  5
319 9363dedb Richard Henderson
#define EXT3_DIV   6
320 9363dedb Richard Henderson
#define EXT3_IDIV  7
321 9363dedb Richard Henderson
322 9363dedb Richard Henderson
/* Group 5 opcode extensions for 0xff.  To be used with OPC_GRP5.  */
323 5d8a4f8f Richard Henderson
#define EXT5_INC_Ev        0
324 5d8a4f8f Richard Henderson
#define EXT5_DEC_Ev        1
325 9363dedb Richard Henderson
#define EXT5_CALLN_Ev        2
326 9363dedb Richard Henderson
#define EXT5_JMPN_Ev        4
327 da441cff Richard Henderson
328 da441cff Richard Henderson
/* Condition codes to be added to OPC_JCC_{long,short}.  */
329 c896fe29 bellard
#define JCC_JMP (-1)
330 c896fe29 bellard
#define JCC_JO  0x0
331 c896fe29 bellard
#define JCC_JNO 0x1
332 c896fe29 bellard
#define JCC_JB  0x2
333 c896fe29 bellard
#define JCC_JAE 0x3
334 c896fe29 bellard
#define JCC_JE  0x4
335 c896fe29 bellard
#define JCC_JNE 0x5
336 c896fe29 bellard
#define JCC_JBE 0x6
337 c896fe29 bellard
#define JCC_JA  0x7
338 c896fe29 bellard
#define JCC_JS  0x8
339 c896fe29 bellard
#define JCC_JNS 0x9
340 c896fe29 bellard
#define JCC_JP  0xa
341 c896fe29 bellard
#define JCC_JNP 0xb
342 c896fe29 bellard
#define JCC_JL  0xc
343 c896fe29 bellard
#define JCC_JGE 0xd
344 c896fe29 bellard
#define JCC_JLE 0xe
345 c896fe29 bellard
#define JCC_JG  0xf
346 c896fe29 bellard
347 c896fe29 bellard
static const uint8_t tcg_cond_to_jcc[10] = {
348 c896fe29 bellard
    [TCG_COND_EQ] = JCC_JE,
349 c896fe29 bellard
    [TCG_COND_NE] = JCC_JNE,
350 c896fe29 bellard
    [TCG_COND_LT] = JCC_JL,
351 c896fe29 bellard
    [TCG_COND_GE] = JCC_JGE,
352 c896fe29 bellard
    [TCG_COND_LE] = JCC_JLE,
353 c896fe29 bellard
    [TCG_COND_GT] = JCC_JG,
354 c896fe29 bellard
    [TCG_COND_LTU] = JCC_JB,
355 c896fe29 bellard
    [TCG_COND_GEU] = JCC_JAE,
356 c896fe29 bellard
    [TCG_COND_LEU] = JCC_JBE,
357 c896fe29 bellard
    [TCG_COND_GTU] = JCC_JA,
358 c896fe29 bellard
};
359 c896fe29 bellard
360 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
361 5d8a4f8f Richard Henderson
static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
362 5d8a4f8f Richard Henderson
{
363 5d8a4f8f Richard Henderson
    int rex;
364 5d8a4f8f Richard Henderson
365 5d8a4f8f Richard Henderson
    if (opc & P_DATA16) {
366 5d8a4f8f Richard Henderson
        /* We should never be asking for both 16 and 64-bit operation.  */
367 5d8a4f8f Richard Henderson
        assert((opc & P_REXW) == 0);
368 5d8a4f8f Richard Henderson
        tcg_out8(s, 0x66);
369 5d8a4f8f Richard Henderson
    }
370 5d8a4f8f Richard Henderson
    if (opc & P_ADDR32) {
371 5d8a4f8f Richard Henderson
        tcg_out8(s, 0x67);
372 5d8a4f8f Richard Henderson
    }
373 5d8a4f8f Richard Henderson
374 5d8a4f8f Richard Henderson
    rex = 0;
375 5d8a4f8f Richard Henderson
    rex |= (opc & P_REXW) >> 8;                /* REX.W */
376 5d8a4f8f Richard Henderson
    rex |= (r & 8) >> 1;                /* REX.R */
377 5d8a4f8f Richard Henderson
    rex |= (x & 8) >> 2;                /* REX.X */
378 5d8a4f8f Richard Henderson
    rex |= (rm & 8) >> 3;                /* REX.B */
379 5d8a4f8f Richard Henderson
380 5d8a4f8f Richard Henderson
    /* P_REXB_{R,RM} indicates that the given register is the low byte.
381 5d8a4f8f Richard Henderson
       For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
382 5d8a4f8f Richard Henderson
       as otherwise the encoding indicates %[abcd]h.  Note that the values
383 5d8a4f8f Richard Henderson
       that are ORed in merely indicate that the REX byte must be present;
384 5d8a4f8f Richard Henderson
       those bits get discarded in output.  */
385 5d8a4f8f Richard Henderson
    rex |= opc & (r >= 4 ? P_REXB_R : 0);
386 5d8a4f8f Richard Henderson
    rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
387 5d8a4f8f Richard Henderson
388 5d8a4f8f Richard Henderson
    if (rex) {
389 5d8a4f8f Richard Henderson
        tcg_out8(s, (uint8_t)(rex | 0x40));
390 5d8a4f8f Richard Henderson
    }
391 5d8a4f8f Richard Henderson
392 5d8a4f8f Richard Henderson
    if (opc & P_EXT) {
393 5d8a4f8f Richard Henderson
        tcg_out8(s, 0x0f);
394 5d8a4f8f Richard Henderson
    }
395 5d8a4f8f Richard Henderson
    tcg_out8(s, opc);
396 5d8a4f8f Richard Henderson
}
397 5d8a4f8f Richard Henderson
#else
398 5d8a4f8f Richard Henderson
static void tcg_out_opc(TCGContext *s, int opc)
399 c896fe29 bellard
{
400 96b4cf38 Richard Henderson
    if (opc & P_DATA16) {
401 96b4cf38 Richard Henderson
        tcg_out8(s, 0x66);
402 96b4cf38 Richard Henderson
    }
403 96b4cf38 Richard Henderson
    if (opc & P_EXT) {
404 c896fe29 bellard
        tcg_out8(s, 0x0f);
405 96b4cf38 Richard Henderson
    }
406 c896fe29 bellard
    tcg_out8(s, opc);
407 c896fe29 bellard
}
408 5d8a4f8f Richard Henderson
/* Discard the register arguments to tcg_out_opc early, so as not to penalize
409 5d8a4f8f Richard Henderson
   the 32-bit compilation paths.  This method works with all versions of gcc,
410 5d8a4f8f Richard Henderson
   whereas relying on optimization may not be able to exclude them.  */
411 5d8a4f8f Richard Henderson
#define tcg_out_opc(s, opc, r, rm, x)  (tcg_out_opc)(s, opc)
412 5d8a4f8f Richard Henderson
#endif
413 c896fe29 bellard
414 5d8a4f8f Richard Henderson
static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
415 c896fe29 bellard
{
416 5d8a4f8f Richard Henderson
    tcg_out_opc(s, opc, r, rm, 0);
417 5d8a4f8f Richard Henderson
    tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
418 c896fe29 bellard
}
419 c896fe29 bellard
420 34a6d0b7 Richard Henderson
/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
421 5d8a4f8f Richard Henderson
   We handle either RM and INDEX missing with a negative value.  In 64-bit
422 5d8a4f8f Richard Henderson
   mode for absolute addresses, ~RM is the size of the immediate operand
423 5d8a4f8f Richard Henderson
   that will follow the instruction.  */
424 34a6d0b7 Richard Henderson
425 34a6d0b7 Richard Henderson
static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
426 5d8a4f8f Richard Henderson
                                     int index, int shift,
427 5d8a4f8f Richard Henderson
                                     tcg_target_long offset)
428 c896fe29 bellard
{
429 34a6d0b7 Richard Henderson
    int mod, len;
430 34a6d0b7 Richard Henderson
431 5d8a4f8f Richard Henderson
    if (index < 0 && rm < 0) {
432 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
433 5d8a4f8f Richard Henderson
            /* Try for a rip-relative addressing mode.  This has replaced
434 5d8a4f8f Richard Henderson
               the 32-bit-mode absolute addressing encoding.  */
435 5d8a4f8f Richard Henderson
            tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
436 5d8a4f8f Richard Henderson
            tcg_target_long disp = offset - pc;
437 5d8a4f8f Richard Henderson
            if (disp == (int32_t)disp) {
438 5d8a4f8f Richard Henderson
                tcg_out_opc(s, opc, r, 0, 0);
439 5d8a4f8f Richard Henderson
                tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
440 5d8a4f8f Richard Henderson
                tcg_out32(s, disp);
441 5d8a4f8f Richard Henderson
                return;
442 5d8a4f8f Richard Henderson
            }
443 34a6d0b7 Richard Henderson
444 5d8a4f8f Richard Henderson
            /* Try for an absolute address encoding.  This requires the
445 5d8a4f8f Richard Henderson
               use of the MODRM+SIB encoding and is therefore larger than
446 5d8a4f8f Richard Henderson
               rip-relative addressing.  */
447 5d8a4f8f Richard Henderson
            if (offset == (int32_t)offset) {
448 5d8a4f8f Richard Henderson
                tcg_out_opc(s, opc, r, 0, 0);
449 5d8a4f8f Richard Henderson
                tcg_out8(s, (LOWREGMASK(r) << 3) | 4);
450 5d8a4f8f Richard Henderson
                tcg_out8(s, (4 << 3) | 5);
451 5d8a4f8f Richard Henderson
                tcg_out32(s, offset);
452 5d8a4f8f Richard Henderson
                return;
453 5d8a4f8f Richard Henderson
            }
454 5d8a4f8f Richard Henderson
455 5d8a4f8f Richard Henderson
            /* ??? The memory isn't directly addressable.  */
456 5d8a4f8f Richard Henderson
            tcg_abort();
457 5d8a4f8f Richard Henderson
        } else {
458 5d8a4f8f Richard Henderson
            /* Absolute address.  */
459 5d8a4f8f Richard Henderson
            tcg_out_opc(s, opc, r, 0, 0);
460 5d8a4f8f Richard Henderson
            tcg_out8(s, (r << 3) | 5);
461 5d8a4f8f Richard Henderson
            tcg_out32(s, offset);
462 5d8a4f8f Richard Henderson
            return;
463 5d8a4f8f Richard Henderson
        }
464 5d8a4f8f Richard Henderson
    }
465 34a6d0b7 Richard Henderson
466 34a6d0b7 Richard Henderson
    /* Find the length of the immediate addend.  Note that the encoding
467 34a6d0b7 Richard Henderson
       that would be used for (%ebp) indicates absolute addressing.  */
468 5d8a4f8f Richard Henderson
    if (rm < 0) {
469 34a6d0b7 Richard Henderson
        mod = 0, len = 4, rm = 5;
470 5d8a4f8f Richard Henderson
    } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) {
471 34a6d0b7 Richard Henderson
        mod = 0, len = 0;
472 34a6d0b7 Richard Henderson
    } else if (offset == (int8_t)offset) {
473 34a6d0b7 Richard Henderson
        mod = 0x40, len = 1;
474 c896fe29 bellard
    } else {
475 34a6d0b7 Richard Henderson
        mod = 0x80, len = 4;
476 34a6d0b7 Richard Henderson
    }
477 34a6d0b7 Richard Henderson
478 34a6d0b7 Richard Henderson
    /* Use a single byte MODRM format if possible.  Note that the encoding
479 34a6d0b7 Richard Henderson
       that would be used for %esp is the escape to the two byte form.  */
480 5d8a4f8f Richard Henderson
    if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) {
481 34a6d0b7 Richard Henderson
        /* Single byte MODRM format.  */
482 5d8a4f8f Richard Henderson
        tcg_out_opc(s, opc, r, rm, 0);
483 5d8a4f8f Richard Henderson
        tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
484 34a6d0b7 Richard Henderson
    } else {
485 34a6d0b7 Richard Henderson
        /* Two byte MODRM+SIB format.  */
486 34a6d0b7 Richard Henderson
487 34a6d0b7 Richard Henderson
        /* Note that the encoding that would place %esp into the index
488 5d8a4f8f Richard Henderson
           field indicates no index register.  In 64-bit mode, the REX.X
489 5d8a4f8f Richard Henderson
           bit counts, so %r12 can be used as the index.  */
490 5d8a4f8f Richard Henderson
        if (index < 0) {
491 34a6d0b7 Richard Henderson
            index = 4;
492 c896fe29 bellard
        } else {
493 34a6d0b7 Richard Henderson
            assert(index != TCG_REG_ESP);
494 c896fe29 bellard
        }
495 34a6d0b7 Richard Henderson
496 5d8a4f8f Richard Henderson
        tcg_out_opc(s, opc, r, rm, index);
497 5d8a4f8f Richard Henderson
        tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4);
498 5d8a4f8f Richard Henderson
        tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm));
499 34a6d0b7 Richard Henderson
    }
500 34a6d0b7 Richard Henderson
501 34a6d0b7 Richard Henderson
    if (len == 1) {
502 34a6d0b7 Richard Henderson
        tcg_out8(s, offset);
503 34a6d0b7 Richard Henderson
    } else if (len == 4) {
504 c896fe29 bellard
        tcg_out32(s, offset);
505 c896fe29 bellard
    }
506 c896fe29 bellard
}
507 c896fe29 bellard
508 5d8a4f8f Richard Henderson
/* A simplification of the above with no index or shift.  */
509 5d8a4f8f Richard Henderson
static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
510 5d8a4f8f Richard Henderson
                                        int rm, tcg_target_long offset)
511 34a6d0b7 Richard Henderson
{
512 34a6d0b7 Richard Henderson
    tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
513 34a6d0b7 Richard Henderson
}
514 34a6d0b7 Richard Henderson
515 81570a70 Richard Henderson
/* Generate dest op= src.  Uses the same ARITH_* codes as tgen_arithi.  */
516 81570a70 Richard Henderson
static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
517 81570a70 Richard Henderson
{
518 5d8a4f8f Richard Henderson
    /* Propagate an opcode prefix, such as P_REXW.  */
519 5d8a4f8f Richard Henderson
    int ext = subop & ~0x7;
520 5d8a4f8f Richard Henderson
    subop &= 0x7;
521 5d8a4f8f Richard Henderson
522 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
523 81570a70 Richard Henderson
}
524 81570a70 Richard Henderson
525 2a534aff Richard Henderson
static inline void tcg_out_mov(TCGContext *s, TCGType type,
526 2a534aff Richard Henderson
                               TCGReg ret, TCGReg arg)
527 c896fe29 bellard
{
528 af266089 Richard Henderson
    if (arg != ret) {
529 5d8a4f8f Richard Henderson
        int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
530 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, opc, ret, arg);
531 af266089 Richard Henderson
    }
532 c896fe29 bellard
}
533 c896fe29 bellard
534 5d8a4f8f Richard Henderson
static void tcg_out_movi(TCGContext *s, TCGType type,
535 2a534aff Richard Henderson
                         TCGReg ret, tcg_target_long arg)
536 c896fe29 bellard
{
537 c896fe29 bellard
    if (arg == 0) {
538 81570a70 Richard Henderson
        tgen_arithr(s, ARITH_XOR, ret, ret);
539 5d8a4f8f Richard Henderson
        return;
540 5d8a4f8f Richard Henderson
    } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
541 5d8a4f8f Richard Henderson
        tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
542 5d8a4f8f Richard Henderson
        tcg_out32(s, arg);
543 5d8a4f8f Richard Henderson
    } else if (arg == (int32_t)arg) {
544 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
545 5d8a4f8f Richard Henderson
        tcg_out32(s, arg);
546 c896fe29 bellard
    } else {
547 5d8a4f8f Richard Henderson
        tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
548 c896fe29 bellard
        tcg_out32(s, arg);
549 5d8a4f8f Richard Henderson
        tcg_out32(s, arg >> 31 >> 1);
550 c896fe29 bellard
    }
551 c896fe29 bellard
}
552 c896fe29 bellard
553 6858614e Richard Henderson
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
554 6858614e Richard Henderson
{
555 6858614e Richard Henderson
    if (val == (int8_t)val) {
556 5d8a4f8f Richard Henderson
        tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
557 6858614e Richard Henderson
        tcg_out8(s, val);
558 5d8a4f8f Richard Henderson
    } else if (val == (int32_t)val) {
559 5d8a4f8f Richard Henderson
        tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
560 6858614e Richard Henderson
        tcg_out32(s, val);
561 5d8a4f8f Richard Henderson
    } else {
562 5d8a4f8f Richard Henderson
        tcg_abort();
563 6858614e Richard Henderson
    }
564 6858614e Richard Henderson
}
565 6858614e Richard Henderson
566 6858614e Richard Henderson
static inline void tcg_out_push(TCGContext *s, int reg)
567 6858614e Richard Henderson
{
568 5d8a4f8f Richard Henderson
    tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
569 6858614e Richard Henderson
}
570 6858614e Richard Henderson
571 6858614e Richard Henderson
static inline void tcg_out_pop(TCGContext *s, int reg)
572 6858614e Richard Henderson
{
573 5d8a4f8f Richard Henderson
    tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
574 6858614e Richard Henderson
}
575 6858614e Richard Henderson
576 2a534aff Richard Henderson
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
577 2a534aff Richard Henderson
                              TCGReg arg1, tcg_target_long arg2)
578 c896fe29 bellard
{
579 5d8a4f8f Richard Henderson
    int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
580 5d8a4f8f Richard Henderson
    tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
581 c896fe29 bellard
}
582 c896fe29 bellard
583 2a534aff Richard Henderson
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
584 2a534aff Richard Henderson
                              TCGReg arg1, tcg_target_long arg2)
585 c896fe29 bellard
{
586 5d8a4f8f Richard Henderson
    int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
587 5d8a4f8f Richard Henderson
    tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
588 c896fe29 bellard
}
589 c896fe29 bellard
590 f53dba01 Richard Henderson
static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
591 f53dba01 Richard Henderson
{
592 96b4cf38 Richard Henderson
    /* Propagate an opcode prefix, such as P_DATA16.  */
593 96b4cf38 Richard Henderson
    int ext = subopc & ~0x7;
594 96b4cf38 Richard Henderson
    subopc &= 0x7;
595 96b4cf38 Richard Henderson
596 f53dba01 Richard Henderson
    if (count == 1) {
597 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
598 f53dba01 Richard Henderson
    } else {
599 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
600 f53dba01 Richard Henderson
        tcg_out8(s, count);
601 f53dba01 Richard Henderson
    }
602 f53dba01 Richard Henderson
}
603 f53dba01 Richard Henderson
604 fcb5dac1 Richard Henderson
static inline void tcg_out_bswap32(TCGContext *s, int reg)
605 fcb5dac1 Richard Henderson
{
606 5d8a4f8f Richard Henderson
    tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
607 fcb5dac1 Richard Henderson
}
608 fcb5dac1 Richard Henderson
609 fcb5dac1 Richard Henderson
static inline void tcg_out_rolw_8(TCGContext *s, int reg)
610 fcb5dac1 Richard Henderson
{
611 5d8a4f8f Richard Henderson
    tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
612 fcb5dac1 Richard Henderson
}
613 fcb5dac1 Richard Henderson
614 55e082a7 Richard Henderson
static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
615 55e082a7 Richard Henderson
{
616 55e082a7 Richard Henderson
    /* movzbl */
617 5d8a4f8f Richard Henderson
    assert(src < 4 || TCG_TARGET_REG_BITS == 64);
618 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
619 55e082a7 Richard Henderson
}
620 55e082a7 Richard Henderson
621 5d8a4f8f Richard Henderson
static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
622 6817c355 Richard Henderson
{
623 6817c355 Richard Henderson
    /* movsbl */
624 5d8a4f8f Richard Henderson
    assert(src < 4 || TCG_TARGET_REG_BITS == 64);
625 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
626 6817c355 Richard Henderson
}
627 6817c355 Richard Henderson
628 55e082a7 Richard Henderson
static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
629 55e082a7 Richard Henderson
{
630 55e082a7 Richard Henderson
    /* movzwl */
631 55e082a7 Richard Henderson
    tcg_out_modrm(s, OPC_MOVZWL, dest, src);
632 55e082a7 Richard Henderson
}
633 55e082a7 Richard Henderson
634 5d8a4f8f Richard Henderson
static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
635 6817c355 Richard Henderson
{
636 5d8a4f8f Richard Henderson
    /* movsw[lq] */
637 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
638 6817c355 Richard Henderson
}
639 6817c355 Richard Henderson
640 5d8a4f8f Richard Henderson
static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
641 c896fe29 bellard
{
642 5d8a4f8f Richard Henderson
    /* 32-bit mov zero extends.  */
643 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
644 5d8a4f8f Richard Henderson
}
645 5d8a4f8f Richard Henderson
646 5d8a4f8f Richard Henderson
static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
647 5d8a4f8f Richard Henderson
{
648 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
649 5d8a4f8f Richard Henderson
}
650 5d8a4f8f Richard Henderson
651 5d8a4f8f Richard Henderson
static inline void tcg_out_bswap64(TCGContext *s, int reg)
652 5d8a4f8f Richard Henderson
{
653 5d8a4f8f Richard Henderson
    tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
654 5d8a4f8f Richard Henderson
}
655 5d8a4f8f Richard Henderson
656 5d8a4f8f Richard Henderson
static void tgen_arithi(TCGContext *s, int c, int r0,
657 5d8a4f8f Richard Henderson
                        tcg_target_long val, int cf)
658 5d8a4f8f Richard Henderson
{
659 5d8a4f8f Richard Henderson
    int rexw = 0;
660 5d8a4f8f Richard Henderson
661 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 64) {
662 5d8a4f8f Richard Henderson
        rexw = c & -8;
663 5d8a4f8f Richard Henderson
        c &= 7;
664 5d8a4f8f Richard Henderson
    }
665 5d8a4f8f Richard Henderson
666 81570a70 Richard Henderson
    /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
667 81570a70 Richard Henderson
       partial flags update stalls on Pentium4 and are not recommended
668 81570a70 Richard Henderson
       by current Intel optimization manuals.  */
669 81570a70 Richard Henderson
    if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
670 447d681e Aurelien Jarno
        int is_inc = (c == ARITH_ADD) ^ (val < 0);
671 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
672 5d8a4f8f Richard Henderson
            /* The single-byte increment encodings are re-tasked as the
673 5d8a4f8f Richard Henderson
               REX prefixes.  Use the MODRM encoding.  */
674 5d8a4f8f Richard Henderson
            tcg_out_modrm(s, OPC_GRP5 + rexw,
675 5d8a4f8f Richard Henderson
                          (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
676 5d8a4f8f Richard Henderson
        } else {
677 5d8a4f8f Richard Henderson
            tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
678 5d8a4f8f Richard Henderson
        }
679 5d8a4f8f Richard Henderson
        return;
680 5d8a4f8f Richard Henderson
    }
681 5d8a4f8f Richard Henderson
682 5d8a4f8f Richard Henderson
    if (c == ARITH_AND) {
683 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
684 5d8a4f8f Richard Henderson
            if (val == 0xffffffffu) {
685 5d8a4f8f Richard Henderson
                tcg_out_ext32u(s, r0, r0);
686 5d8a4f8f Richard Henderson
                return;
687 5d8a4f8f Richard Henderson
            }
688 5d8a4f8f Richard Henderson
            if (val == (uint32_t)val) {
689 5d8a4f8f Richard Henderson
                /* AND with no high bits set can use a 32-bit operation.  */
690 5d8a4f8f Richard Henderson
                rexw = 0;
691 5d8a4f8f Richard Henderson
            }
692 5d8a4f8f Richard Henderson
        }
693 dc397ca3 Aurelien Jarno
        if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
694 5d8a4f8f Richard Henderson
            tcg_out_ext8u(s, r0, r0);
695 5d8a4f8f Richard Henderson
            return;
696 5d8a4f8f Richard Henderson
        }
697 5d8a4f8f Richard Henderson
        if (val == 0xffffu) {
698 5d8a4f8f Richard Henderson
            tcg_out_ext16u(s, r0, r0);
699 5d8a4f8f Richard Henderson
            return;
700 5d8a4f8f Richard Henderson
        }
701 5d8a4f8f Richard Henderson
    }
702 5d8a4f8f Richard Henderson
703 5d8a4f8f Richard Henderson
    if (val == (int8_t)val) {
704 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
705 c896fe29 bellard
        tcg_out8(s, val);
706 5d8a4f8f Richard Henderson
        return;
707 5d8a4f8f Richard Henderson
    }
708 5d8a4f8f Richard Henderson
    if (rexw == 0 || val == (int32_t)val) {
709 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
710 c896fe29 bellard
        tcg_out32(s, val);
711 5d8a4f8f Richard Henderson
        return;
712 c896fe29 bellard
    }
713 5d8a4f8f Richard Henderson
714 5d8a4f8f Richard Henderson
    tcg_abort();
715 c896fe29 bellard
}
716 c896fe29 bellard
717 3e9a474e aurel32
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
718 c896fe29 bellard
{
719 5d8a4f8f Richard Henderson
    if (val != 0) {
720 5d8a4f8f Richard Henderson
        tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
721 5d8a4f8f Richard Henderson
    }
722 c896fe29 bellard
}
723 c896fe29 bellard
724 f75b56c1 Richard Henderson
/* Use SMALL != 0 to force a short forward branch.  */
725 f75b56c1 Richard Henderson
static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
726 c896fe29 bellard
{
727 c896fe29 bellard
    int32_t val, val1;
728 c896fe29 bellard
    TCGLabel *l = &s->labels[label_index];
729 78686523 Richard Henderson
730 c896fe29 bellard
    if (l->has_value) {
731 c896fe29 bellard
        val = l->u.value - (tcg_target_long)s->code_ptr;
732 c896fe29 bellard
        val1 = val - 2;
733 c896fe29 bellard
        if ((int8_t)val1 == val1) {
734 f75b56c1 Richard Henderson
            if (opc == -1) {
735 da441cff Richard Henderson
                tcg_out8(s, OPC_JMP_short);
736 f75b56c1 Richard Henderson
            } else {
737 da441cff Richard Henderson
                tcg_out8(s, OPC_JCC_short + opc);
738 f75b56c1 Richard Henderson
            }
739 c896fe29 bellard
            tcg_out8(s, val1);
740 c896fe29 bellard
        } else {
741 f75b56c1 Richard Henderson
            if (small) {
742 f75b56c1 Richard Henderson
                tcg_abort();
743 f75b56c1 Richard Henderson
            }
744 c896fe29 bellard
            if (opc == -1) {
745 da441cff Richard Henderson
                tcg_out8(s, OPC_JMP_long);
746 c896fe29 bellard
                tcg_out32(s, val - 5);
747 c896fe29 bellard
            } else {
748 5d8a4f8f Richard Henderson
                tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
749 c896fe29 bellard
                tcg_out32(s, val - 6);
750 c896fe29 bellard
            }
751 c896fe29 bellard
        }
752 f75b56c1 Richard Henderson
    } else if (small) {
753 f75b56c1 Richard Henderson
        if (opc == -1) {
754 da441cff Richard Henderson
            tcg_out8(s, OPC_JMP_short);
755 f75b56c1 Richard Henderson
        } else {
756 da441cff Richard Henderson
            tcg_out8(s, OPC_JCC_short + opc);
757 f75b56c1 Richard Henderson
        }
758 f75b56c1 Richard Henderson
        tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
759 f75b56c1 Richard Henderson
        s->code_ptr += 1;
760 c896fe29 bellard
    } else {
761 c896fe29 bellard
        if (opc == -1) {
762 da441cff Richard Henderson
            tcg_out8(s, OPC_JMP_long);
763 c896fe29 bellard
        } else {
764 5d8a4f8f Richard Henderson
            tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
765 c896fe29 bellard
        }
766 c896fe29 bellard
        tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
767 623e265c pbrook
        s->code_ptr += 4;
768 c896fe29 bellard
    }
769 c896fe29 bellard
}
770 c896fe29 bellard
771 1d2699ae Richard Henderson
static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
772 5d8a4f8f Richard Henderson
                        int const_arg2, int rexw)
773 c896fe29 bellard
{
774 c896fe29 bellard
    if (const_arg2) {
775 c896fe29 bellard
        if (arg2 == 0) {
776 c896fe29 bellard
            /* test r, r */
777 5d8a4f8f Richard Henderson
            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
778 c896fe29 bellard
        } else {
779 5d8a4f8f Richard Henderson
            tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
780 c896fe29 bellard
        }
781 c896fe29 bellard
    } else {
782 5d8a4f8f Richard Henderson
        tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
783 c896fe29 bellard
    }
784 1d2699ae Richard Henderson
}
785 1d2699ae Richard Henderson
786 5d8a4f8f Richard Henderson
static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
787 5d8a4f8f Richard Henderson
                             TCGArg arg1, TCGArg arg2, int const_arg2,
788 5d8a4f8f Richard Henderson
                             int label_index, int small)
789 1d2699ae Richard Henderson
{
790 5d8a4f8f Richard Henderson
    tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
791 f75b56c1 Richard Henderson
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
792 c896fe29 bellard
}
793 c896fe29 bellard
794 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
795 5d8a4f8f Richard Henderson
static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
796 5d8a4f8f Richard Henderson
                             TCGArg arg1, TCGArg arg2, int const_arg2,
797 5d8a4f8f Richard Henderson
                             int label_index, int small)
798 5d8a4f8f Richard Henderson
{
799 5d8a4f8f Richard Henderson
    tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
800 5d8a4f8f Richard Henderson
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
801 5d8a4f8f Richard Henderson
}
802 5d8a4f8f Richard Henderson
#else
803 c896fe29 bellard
/* XXX: we implement it at the target level to avoid having to
804 c896fe29 bellard
   handle cross basic blocks temporaries */
805 f75b56c1 Richard Henderson
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
806 f75b56c1 Richard Henderson
                            const int *const_args, int small)
807 c896fe29 bellard
{
808 c896fe29 bellard
    int label_next;
809 c896fe29 bellard
    label_next = gen_new_label();
810 c896fe29 bellard
    switch(args[4]) {
811 c896fe29 bellard
    case TCG_COND_EQ:
812 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
813 5d8a4f8f Richard Henderson
                         label_next, 1);
814 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
815 5d8a4f8f Richard Henderson
                         args[5], small);
816 c896fe29 bellard
        break;
817 c896fe29 bellard
    case TCG_COND_NE:
818 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
819 5d8a4f8f Richard Henderson
                         args[5], small);
820 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
821 5d8a4f8f Richard Henderson
                         args[5], small);
822 c896fe29 bellard
        break;
823 c896fe29 bellard
    case TCG_COND_LT:
824 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
825 5d8a4f8f Richard Henderson
                         args[5], small);
826 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
827 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
828 5d8a4f8f Richard Henderson
                         args[5], small);
829 c896fe29 bellard
        break;
830 c896fe29 bellard
    case TCG_COND_LE:
831 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
832 5d8a4f8f Richard Henderson
                         args[5], small);
833 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
834 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
835 5d8a4f8f Richard Henderson
                         args[5], small);
836 c896fe29 bellard
        break;
837 c896fe29 bellard
    case TCG_COND_GT:
838 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
839 5d8a4f8f Richard Henderson
                         args[5], small);
840 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
841 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
842 5d8a4f8f Richard Henderson
                         args[5], small);
843 c896fe29 bellard
        break;
844 c896fe29 bellard
    case TCG_COND_GE:
845 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
846 5d8a4f8f Richard Henderson
                         args[5], small);
847 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
848 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
849 5d8a4f8f Richard Henderson
                         args[5], small);
850 c896fe29 bellard
        break;
851 c896fe29 bellard
    case TCG_COND_LTU:
852 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
853 5d8a4f8f Richard Henderson
                         args[5], small);
854 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
855 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
856 5d8a4f8f Richard Henderson
                         args[5], small);
857 c896fe29 bellard
        break;
858 c896fe29 bellard
    case TCG_COND_LEU:
859 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
860 5d8a4f8f Richard Henderson
                         args[5], small);
861 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
862 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
863 5d8a4f8f Richard Henderson
                         args[5], small);
864 c896fe29 bellard
        break;
865 c896fe29 bellard
    case TCG_COND_GTU:
866 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
867 5d8a4f8f Richard Henderson
                         args[5], small);
868 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
869 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
870 5d8a4f8f Richard Henderson
                         args[5], small);
871 c896fe29 bellard
        break;
872 c896fe29 bellard
    case TCG_COND_GEU:
873 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
874 5d8a4f8f Richard Henderson
                         args[5], small);
875 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
876 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
877 5d8a4f8f Richard Henderson
                         args[5], small);
878 c896fe29 bellard
        break;
879 c896fe29 bellard
    default:
880 c896fe29 bellard
        tcg_abort();
881 c896fe29 bellard
    }
882 9d6fca70 Stefan Weil
    tcg_out_label(s, label_next, s->code_ptr);
883 c896fe29 bellard
}
884 5d8a4f8f Richard Henderson
#endif
885 c896fe29 bellard
886 5d8a4f8f Richard Henderson
static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
887 5d8a4f8f Richard Henderson
                              TCGArg arg1, TCGArg arg2, int const_arg2)
888 1d2699ae Richard Henderson
{
889 5d8a4f8f Richard Henderson
    tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
890 32a8ffb9 Richard Henderson
    tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
891 a369a702 Richard Henderson
    tcg_out_ext8u(s, dest, dest);
892 1d2699ae Richard Henderson
}
893 1d2699ae Richard Henderson
894 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
895 5d8a4f8f Richard Henderson
static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
896 5d8a4f8f Richard Henderson
                              TCGArg arg1, TCGArg arg2, int const_arg2)
897 5d8a4f8f Richard Henderson
{
898 5d8a4f8f Richard Henderson
    tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
899 5d8a4f8f Richard Henderson
    tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
900 5d8a4f8f Richard Henderson
    tcg_out_ext8u(s, dest, dest);
901 5d8a4f8f Richard Henderson
}
902 5d8a4f8f Richard Henderson
#else
903 1d2699ae Richard Henderson
static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
904 1d2699ae Richard Henderson
                             const int *const_args)
905 1d2699ae Richard Henderson
{
906 1d2699ae Richard Henderson
    TCGArg new_args[6];
907 1d2699ae Richard Henderson
    int label_true, label_over;
908 1d2699ae Richard Henderson
909 1d2699ae Richard Henderson
    memcpy(new_args, args+1, 5*sizeof(TCGArg));
910 1d2699ae Richard Henderson
911 1d2699ae Richard Henderson
    if (args[0] == args[1] || args[0] == args[2]
912 1d2699ae Richard Henderson
        || (!const_args[3] && args[0] == args[3])
913 1d2699ae Richard Henderson
        || (!const_args[4] && args[0] == args[4])) {
914 1d2699ae Richard Henderson
        /* When the destination overlaps with one of the argument
915 1d2699ae Richard Henderson
           registers, don't do anything tricky.  */
916 1d2699ae Richard Henderson
        label_true = gen_new_label();
917 1d2699ae Richard Henderson
        label_over = gen_new_label();
918 1d2699ae Richard Henderson
919 1d2699ae Richard Henderson
        new_args[5] = label_true;
920 1d2699ae Richard Henderson
        tcg_out_brcond2(s, new_args, const_args+1, 1);
921 1d2699ae Richard Henderson
922 1d2699ae Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
923 1d2699ae Richard Henderson
        tcg_out_jxx(s, JCC_JMP, label_over, 1);
924 9d6fca70 Stefan Weil
        tcg_out_label(s, label_true, s->code_ptr);
925 1d2699ae Richard Henderson
926 1d2699ae Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
927 9d6fca70 Stefan Weil
        tcg_out_label(s, label_over, s->code_ptr);
928 1d2699ae Richard Henderson
    } else {
929 1d2699ae Richard Henderson
        /* When the destination does not overlap one of the arguments,
930 1d2699ae Richard Henderson
           clear the destination first, jump if cond false, and emit an
931 1d2699ae Richard Henderson
           increment in the true case.  This results in smaller code.  */
932 1d2699ae Richard Henderson
933 1d2699ae Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
934 1d2699ae Richard Henderson
935 1d2699ae Richard Henderson
        label_over = gen_new_label();
936 1d2699ae Richard Henderson
        new_args[4] = tcg_invert_cond(new_args[4]);
937 1d2699ae Richard Henderson
        new_args[5] = label_over;
938 1d2699ae Richard Henderson
        tcg_out_brcond2(s, new_args, const_args+1, 1);
939 1d2699ae Richard Henderson
940 1d2699ae Richard Henderson
        tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
941 9d6fca70 Stefan Weil
        tcg_out_label(s, label_over, s->code_ptr);
942 1d2699ae Richard Henderson
    }
943 1d2699ae Richard Henderson
}
944 5d8a4f8f Richard Henderson
#endif
945 5d8a4f8f Richard Henderson
946 d0a16297 Richard Henderson
static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
947 d0a16297 Richard Henderson
                              TCGArg c1, TCGArg c2, int const_c2,
948 d0a16297 Richard Henderson
                              TCGArg v1)
949 d0a16297 Richard Henderson
{
950 d0a16297 Richard Henderson
    tcg_out_cmp(s, c1, c2, const_c2, 0);
951 d0a16297 Richard Henderson
    tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
952 d0a16297 Richard Henderson
}
953 d0a16297 Richard Henderson
954 d0a16297 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
955 d0a16297 Richard Henderson
static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
956 d0a16297 Richard Henderson
                              TCGArg c1, TCGArg c2, int const_c2,
957 d0a16297 Richard Henderson
                              TCGArg v1)
958 d0a16297 Richard Henderson
{
959 d0a16297 Richard Henderson
    tcg_out_cmp(s, c1, c2, const_c2, P_REXW);
960 d0a16297 Richard Henderson
    tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | P_REXW, dest, v1);
961 d0a16297 Richard Henderson
}
962 d0a16297 Richard Henderson
#endif
963 d0a16297 Richard Henderson
964 5d8a4f8f Richard Henderson
static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
965 5d8a4f8f Richard Henderson
{
966 5d8a4f8f Richard Henderson
    tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
967 5d8a4f8f Richard Henderson
968 5d8a4f8f Richard Henderson
    if (disp == (int32_t)disp) {
969 5d8a4f8f Richard Henderson
        tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
970 5d8a4f8f Richard Henderson
        tcg_out32(s, disp);
971 5d8a4f8f Richard Henderson
    } else {
972 5d8a4f8f Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
973 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP5,
974 5d8a4f8f Richard Henderson
                      call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
975 5d8a4f8f Richard Henderson
    }
976 5d8a4f8f Richard Henderson
}
977 5d8a4f8f Richard Henderson
978 5d8a4f8f Richard Henderson
static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
979 5d8a4f8f Richard Henderson
{
980 5d8a4f8f Richard Henderson
    tcg_out_branch(s, 1, dest);
981 5d8a4f8f Richard Henderson
}
982 1d2699ae Richard Henderson
983 5d8a4f8f Richard Henderson
static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
984 aadb21a4 Richard Henderson
{
985 5d8a4f8f Richard Henderson
    tcg_out_branch(s, 0, dest);
986 aadb21a4 Richard Henderson
}
987 aadb21a4 Richard Henderson
988 c896fe29 bellard
#if defined(CONFIG_SOFTMMU)
989 79383c9c blueswir1
990 79383c9c blueswir1
#include "../../softmmu_defs.h"
991 c896fe29 bellard
992 e141ab52 Blue Swirl
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
993 e141ab52 Blue Swirl
   int mmu_idx) */
994 e141ab52 Blue Swirl
static const void *qemu_ld_helpers[4] = {
995 e141ab52 Blue Swirl
    helper_ldb_mmu,
996 e141ab52 Blue Swirl
    helper_ldw_mmu,
997 e141ab52 Blue Swirl
    helper_ldl_mmu,
998 e141ab52 Blue Swirl
    helper_ldq_mmu,
999 e141ab52 Blue Swirl
};
1000 e141ab52 Blue Swirl
1001 e141ab52 Blue Swirl
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1002 e141ab52 Blue Swirl
   uintxx_t val, int mmu_idx) */
1003 e141ab52 Blue Swirl
static const void *qemu_st_helpers[4] = {
1004 e141ab52 Blue Swirl
    helper_stb_mmu,
1005 e141ab52 Blue Swirl
    helper_stw_mmu,
1006 e141ab52 Blue Swirl
    helper_stl_mmu,
1007 e141ab52 Blue Swirl
    helper_stq_mmu,
1008 e141ab52 Blue Swirl
};
1009 8516a044 Richard Henderson
1010 8516a044 Richard Henderson
/* Perform the TLB load and compare.
1011 8516a044 Richard Henderson

1012 8516a044 Richard Henderson
   Inputs:
1013 8516a044 Richard Henderson
   ADDRLO_IDX contains the index into ARGS of the low part of the
1014 8516a044 Richard Henderson
   address; the high part of the address is at ADDR_LOW_IDX+1.
1015 8516a044 Richard Henderson

1016 8516a044 Richard Henderson
   MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1017 8516a044 Richard Henderson

1018 8516a044 Richard Henderson
   WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1019 8516a044 Richard Henderson
   This should be offsetof addr_read or addr_write.
1020 8516a044 Richard Henderson

1021 8516a044 Richard Henderson
   Outputs:
1022 8516a044 Richard Henderson
   LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
1023 8516a044 Richard Henderson
   positions of the displacements of forward jumps to the TLB miss case.
1024 8516a044 Richard Henderson

1025 5d8a4f8f Richard Henderson
   First argument register is loaded with the low part of the address.
1026 5d8a4f8f Richard Henderson
   In the TLB hit case, it has been adjusted as indicated by the TLB
1027 5d8a4f8f Richard Henderson
   and so is a host address.  In the TLB miss case, it continues to
1028 5d8a4f8f Richard Henderson
   hold a guest address.
1029 8516a044 Richard Henderson

1030 5d8a4f8f Richard Henderson
   Second argument register is clobbered.  */
1031 8516a044 Richard Henderson
1032 c28b14c6 Aurelien Jarno
static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
1033 c28b14c6 Aurelien Jarno
                                    int mem_index, int s_bits,
1034 4309a79b Aurelien Jarno
                                    const TCGArg *args,
1035 c28b14c6 Aurelien Jarno
                                    uint8_t **label_ptr, int which)
1036 8516a044 Richard Henderson
{
1037 8516a044 Richard Henderson
    const int addrlo = args[addrlo_idx];
1038 b18212c6 Stefan Weil
    const int r0 = TCG_REG_L0;
1039 b18212c6 Stefan Weil
    const int r1 = TCG_REG_L1;
1040 5d8a4f8f Richard Henderson
    TCGType type = TCG_TYPE_I32;
1041 5d8a4f8f Richard Henderson
    int rexw = 0;
1042 5d8a4f8f Richard Henderson
1043 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
1044 5d8a4f8f Richard Henderson
        type = TCG_TYPE_I64;
1045 5d8a4f8f Richard Henderson
        rexw = P_REXW;
1046 5d8a4f8f Richard Henderson
    }
1047 8516a044 Richard Henderson
1048 5d8a4f8f Richard Henderson
    tcg_out_mov(s, type, r1, addrlo);
1049 5d8a4f8f Richard Henderson
    tcg_out_mov(s, type, r0, addrlo);
1050 8516a044 Richard Henderson
1051 5d8a4f8f Richard Henderson
    tcg_out_shifti(s, SHIFT_SHR + rexw, r1,
1052 5d8a4f8f Richard Henderson
                   TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1053 8516a044 Richard Henderson
1054 5d8a4f8f Richard Henderson
    tgen_arithi(s, ARITH_AND + rexw, r0,
1055 5d8a4f8f Richard Henderson
                TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
1056 5d8a4f8f Richard Henderson
    tgen_arithi(s, ARITH_AND + rexw, r1,
1057 5d8a4f8f Richard Henderson
                (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
1058 8516a044 Richard Henderson
1059 5d8a4f8f Richard Henderson
    tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
1060 9349b4f9 Andreas Fรคrber
                             offsetof(CPUArchState, tlb_table[mem_index][0])
1061 8516a044 Richard Henderson
                             + which);
1062 8516a044 Richard Henderson
1063 8516a044 Richard Henderson
    /* cmp 0(r1), r0 */
1064 5d8a4f8f Richard Henderson
    tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r0, r1, 0);
1065 8516a044 Richard Henderson
1066 5d8a4f8f Richard Henderson
    tcg_out_mov(s, type, r0, addrlo);
1067 8516a044 Richard Henderson
1068 8516a044 Richard Henderson
    /* jne label1 */
1069 8516a044 Richard Henderson
    tcg_out8(s, OPC_JCC_short + JCC_JNE);
1070 8516a044 Richard Henderson
    label_ptr[0] = s->code_ptr;
1071 8516a044 Richard Henderson
    s->code_ptr++;
1072 8516a044 Richard Henderson
1073 5d8a4f8f Richard Henderson
    if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1074 8516a044 Richard Henderson
        /* cmp 4(r1), addrhi */
1075 8516a044 Richard Henderson
        tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
1076 8516a044 Richard Henderson
1077 8516a044 Richard Henderson
        /* jne label1 */
1078 8516a044 Richard Henderson
        tcg_out8(s, OPC_JCC_short + JCC_JNE);
1079 8516a044 Richard Henderson
        label_ptr[1] = s->code_ptr;
1080 8516a044 Richard Henderson
        s->code_ptr++;
1081 8516a044 Richard Henderson
    }
1082 8516a044 Richard Henderson
1083 8516a044 Richard Henderson
    /* TLB Hit.  */
1084 8516a044 Richard Henderson
1085 8516a044 Richard Henderson
    /* add addend(r1), r0 */
1086 5d8a4f8f Richard Henderson
    tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r0, r1,
1087 8516a044 Richard Henderson
                         offsetof(CPUTLBEntry, addend) - which);
1088 8516a044 Richard Henderson
}
1089 c896fe29 bellard
#endif
1090 c896fe29 bellard
1091 be5a4eb7 Richard Henderson
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
1092 be5a4eb7 Richard Henderson
                                   int base, tcg_target_long ofs, int sizeop)
1093 be5a4eb7 Richard Henderson
{
1094 be5a4eb7 Richard Henderson
#ifdef TARGET_WORDS_BIGENDIAN
1095 be5a4eb7 Richard Henderson
    const int bswap = 1;
1096 be5a4eb7 Richard Henderson
#else
1097 be5a4eb7 Richard Henderson
    const int bswap = 0;
1098 379f6698 Paul Brook
#endif
1099 be5a4eb7 Richard Henderson
    switch (sizeop) {
1100 be5a4eb7 Richard Henderson
    case 0:
1101 be5a4eb7 Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
1102 be5a4eb7 Richard Henderson
        break;
1103 be5a4eb7 Richard Henderson
    case 0 | 4:
1104 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW, datalo, base, ofs);
1105 be5a4eb7 Richard Henderson
        break;
1106 be5a4eb7 Richard Henderson
    case 1:
1107 be5a4eb7 Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
1108 be5a4eb7 Richard Henderson
        if (bswap) {
1109 be5a4eb7 Richard Henderson
            tcg_out_rolw_8(s, datalo);
1110 be5a4eb7 Richard Henderson
        }
1111 be5a4eb7 Richard Henderson
        break;
1112 be5a4eb7 Richard Henderson
    case 1 | 4:
1113 be5a4eb7 Richard Henderson
        if (bswap) {
1114 5d8a4f8f Richard Henderson
            tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
1115 be5a4eb7 Richard Henderson
            tcg_out_rolw_8(s, datalo);
1116 5d8a4f8f Richard Henderson
            tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
1117 5d8a4f8f Richard Henderson
        } else {
1118 5d8a4f8f Richard Henderson
            tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW, datalo, base, ofs);
1119 be5a4eb7 Richard Henderson
        }
1120 be5a4eb7 Richard Henderson
        break;
1121 be5a4eb7 Richard Henderson
    case 2:
1122 be5a4eb7 Richard Henderson
        tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1123 be5a4eb7 Richard Henderson
        if (bswap) {
1124 be5a4eb7 Richard Henderson
            tcg_out_bswap32(s, datalo);
1125 be5a4eb7 Richard Henderson
        }
1126 be5a4eb7 Richard Henderson
        break;
1127 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1128 5d8a4f8f Richard Henderson
    case 2 | 4:
1129 be5a4eb7 Richard Henderson
        if (bswap) {
1130 be5a4eb7 Richard Henderson
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1131 5d8a4f8f Richard Henderson
            tcg_out_bswap32(s, datalo);
1132 5d8a4f8f Richard Henderson
            tcg_out_ext32s(s, datalo, datalo);
1133 be5a4eb7 Richard Henderson
        } else {
1134 5d8a4f8f Richard Henderson
            tcg_out_modrm_offset(s, OPC_MOVSLQ, datalo, base, ofs);
1135 be5a4eb7 Richard Henderson
        }
1136 5d8a4f8f Richard Henderson
        break;
1137 5d8a4f8f Richard Henderson
#endif
1138 5d8a4f8f Richard Henderson
    case 3:
1139 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
1140 5d8a4f8f Richard Henderson
            tcg_out_ld(s, TCG_TYPE_I64, datalo, base, ofs);
1141 5d8a4f8f Richard Henderson
            if (bswap) {
1142 5d8a4f8f Richard Henderson
                tcg_out_bswap64(s, datalo);
1143 5d8a4f8f Richard Henderson
            }
1144 5d8a4f8f Richard Henderson
        } else {
1145 5d8a4f8f Richard Henderson
            if (bswap) {
1146 5d8a4f8f Richard Henderson
                int t = datalo;
1147 5d8a4f8f Richard Henderson
                datalo = datahi;
1148 5d8a4f8f Richard Henderson
                datahi = t;
1149 5d8a4f8f Richard Henderson
            }
1150 5d8a4f8f Richard Henderson
            if (base != datalo) {
1151 5d8a4f8f Richard Henderson
                tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1152 5d8a4f8f Richard Henderson
                tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1153 5d8a4f8f Richard Henderson
            } else {
1154 5d8a4f8f Richard Henderson
                tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1155 5d8a4f8f Richard Henderson
                tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1156 5d8a4f8f Richard Henderson
            }
1157 5d8a4f8f Richard Henderson
            if (bswap) {
1158 5d8a4f8f Richard Henderson
                tcg_out_bswap32(s, datalo);
1159 5d8a4f8f Richard Henderson
                tcg_out_bswap32(s, datahi);
1160 5d8a4f8f Richard Henderson
            }
1161 be5a4eb7 Richard Henderson
        }
1162 be5a4eb7 Richard Henderson
        break;
1163 be5a4eb7 Richard Henderson
    default:
1164 be5a4eb7 Richard Henderson
        tcg_abort();
1165 be5a4eb7 Richard Henderson
    }
1166 be5a4eb7 Richard Henderson
}
1167 379f6698 Paul Brook
1168 c896fe29 bellard
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1169 c896fe29 bellard
   EAX. It will be useful once fixed registers globals are less
1170 c896fe29 bellard
   common. */
1171 c896fe29 bellard
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1172 c896fe29 bellard
                            int opc)
1173 c896fe29 bellard
{
1174 1a6dc1e4 Richard Henderson
    int data_reg, data_reg2 = 0;
1175 8516a044 Richard Henderson
    int addrlo_idx;
1176 c896fe29 bellard
#if defined(CONFIG_SOFTMMU)
1177 6a18ae2d Blue Swirl
    int mem_index, s_bits;
1178 6a18ae2d Blue Swirl
#if TCG_TARGET_REG_BITS == 64
1179 6a18ae2d Blue Swirl
    int arg_idx;
1180 6a18ae2d Blue Swirl
#else
1181 6a18ae2d Blue Swirl
    int stack_adjust;
1182 6a18ae2d Blue Swirl
#endif
1183 1a6dc1e4 Richard Henderson
    uint8_t *label_ptr[3];
1184 c896fe29 bellard
#endif
1185 c896fe29 bellard
1186 8516a044 Richard Henderson
    data_reg = args[0];
1187 8516a044 Richard Henderson
    addrlo_idx = 1;
1188 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
1189 8516a044 Richard Henderson
        data_reg2 = args[1];
1190 8516a044 Richard Henderson
        addrlo_idx = 2;
1191 1a6dc1e4 Richard Henderson
    }
1192 c896fe29 bellard
1193 c896fe29 bellard
#if defined(CONFIG_SOFTMMU)
1194 5d8a4f8f Richard Henderson
    mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
1195 8516a044 Richard Henderson
    s_bits = opc & 3;
1196 1a6dc1e4 Richard Henderson
1197 8516a044 Richard Henderson
    tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1198 8516a044 Richard Henderson
                     label_ptr, offsetof(CPUTLBEntry, addr_read));
1199 1a6dc1e4 Richard Henderson
1200 1a6dc1e4 Richard Henderson
    /* TLB Hit.  */
1201 b18212c6 Stefan Weil
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, TCG_REG_L0, 0, opc);
1202 c896fe29 bellard
1203 1a6dc1e4 Richard Henderson
    /* jmp label2 */
1204 1a6dc1e4 Richard Henderson
    tcg_out8(s, OPC_JMP_short);
1205 1a6dc1e4 Richard Henderson
    label_ptr[2] = s->code_ptr;
1206 c896fe29 bellard
    s->code_ptr++;
1207 78686523 Richard Henderson
1208 1a6dc1e4 Richard Henderson
    /* TLB Miss.  */
1209 1a6dc1e4 Richard Henderson
1210 1a6dc1e4 Richard Henderson
    /* label1: */
1211 1a6dc1e4 Richard Henderson
    *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
1212 5d8a4f8f Richard Henderson
    if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1213 1a6dc1e4 Richard Henderson
        *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1214 1a6dc1e4 Richard Henderson
    }
1215 c896fe29 bellard
1216 c896fe29 bellard
    /* XXX: move that code at the end of the TB */
1217 6a18ae2d Blue Swirl
#if TCG_TARGET_REG_BITS == 32
1218 6a18ae2d Blue Swirl
    tcg_out_pushi(s, mem_index);
1219 6a18ae2d Blue Swirl
    stack_adjust = 4;
1220 6a18ae2d Blue Swirl
    if (TARGET_LONG_BITS == 64) {
1221 6a18ae2d Blue Swirl
        tcg_out_push(s, args[addrlo_idx + 1]);
1222 6a18ae2d Blue Swirl
        stack_adjust += 4;
1223 6a18ae2d Blue Swirl
    }
1224 6a18ae2d Blue Swirl
    tcg_out_push(s, args[addrlo_idx]);
1225 6a18ae2d Blue Swirl
    stack_adjust += 4;
1226 e141ab52 Blue Swirl
    tcg_out_push(s, TCG_AREG0);
1227 e141ab52 Blue Swirl
    stack_adjust += 4;
1228 6a18ae2d Blue Swirl
#else
1229 5d8a4f8f Richard Henderson
    /* The first argument is already loaded with addrlo.  */
1230 82bb07db Richard Henderson
    arg_idx = 1;
1231 82bb07db Richard Henderson
    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
1232 82bb07db Richard Henderson
                 mem_index);
1233 e141ab52 Blue Swirl
    /* XXX/FIXME: suboptimal */
1234 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3], TCG_REG_L2);
1235 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2], TCG_REG_L1);
1236 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1], TCG_REG_L0);
1237 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
1238 e141ab52 Blue Swirl
#endif
1239 6a18ae2d Blue Swirl
1240 aadb21a4 Richard Henderson
    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
1241 c896fe29 bellard
1242 6a18ae2d Blue Swirl
#if TCG_TARGET_REG_BITS == 32
1243 6a18ae2d Blue Swirl
    if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
1244 6a18ae2d Blue Swirl
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
1245 6a18ae2d Blue Swirl
        tcg_out_pop(s, TCG_REG_ECX);
1246 6a18ae2d Blue Swirl
    } else if (stack_adjust != 0) {
1247 6a18ae2d Blue Swirl
        tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
1248 6a18ae2d Blue Swirl
    }
1249 6a18ae2d Blue Swirl
#endif
1250 6a18ae2d Blue Swirl
1251 c896fe29 bellard
    switch(opc) {
1252 c896fe29 bellard
    case 0 | 4:
1253 5d8a4f8f Richard Henderson
        tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
1254 c896fe29 bellard
        break;
1255 c896fe29 bellard
    case 1 | 4:
1256 5d8a4f8f Richard Henderson
        tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
1257 c896fe29 bellard
        break;
1258 c896fe29 bellard
    case 0:
1259 55e082a7 Richard Henderson
        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
1260 9db3ba4d aurel32
        break;
1261 c896fe29 bellard
    case 1:
1262 55e082a7 Richard Henderson
        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
1263 9db3ba4d aurel32
        break;
1264 c896fe29 bellard
    case 2:
1265 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1266 c896fe29 bellard
        break;
1267 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1268 5d8a4f8f Richard Henderson
    case 2 | 4:
1269 5d8a4f8f Richard Henderson
        tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1270 5d8a4f8f Richard Henderson
        break;
1271 5d8a4f8f Richard Henderson
#endif
1272 c896fe29 bellard
    case 3:
1273 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
1274 5d8a4f8f Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
1275 5d8a4f8f Richard Henderson
        } else if (data_reg == TCG_REG_EDX) {
1276 b3e66df7 Richard Henderson
            /* xchg %edx, %eax */
1277 5d8a4f8f Richard Henderson
            tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
1278 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
1279 c896fe29 bellard
        } else {
1280 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1281 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
1282 c896fe29 bellard
        }
1283 c896fe29 bellard
        break;
1284 5d8a4f8f Richard Henderson
    default:
1285 5d8a4f8f Richard Henderson
        tcg_abort();
1286 c896fe29 bellard
    }
1287 c896fe29 bellard
1288 be5a4eb7 Richard Henderson
    /* label2: */
1289 1a6dc1e4 Richard Henderson
    *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1290 c896fe29 bellard
#else
1291 5d8a4f8f Richard Henderson
    {
1292 5d8a4f8f Richard Henderson
        int32_t offset = GUEST_BASE;
1293 5d8a4f8f Richard Henderson
        int base = args[addrlo_idx];
1294 5d8a4f8f Richard Henderson
1295 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
1296 5d8a4f8f Richard Henderson
            /* ??? We assume all operations have left us with register
1297 5d8a4f8f Richard Henderson
               contents that are zero extended.  So far this appears to
1298 5d8a4f8f Richard Henderson
               be true.  If we want to enforce this, we can either do
1299 5d8a4f8f Richard Henderson
               an explicit zero-extension here, or (if GUEST_BASE == 0)
1300 5d8a4f8f Richard Henderson
               use the ADDR32 prefix.  For now, do nothing.  */
1301 5d8a4f8f Richard Henderson
1302 5d8a4f8f Richard Henderson
            if (offset != GUEST_BASE) {
1303 b18212c6 Stefan Weil
                tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L0, GUEST_BASE);
1304 b18212c6 Stefan Weil
                tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L0, base);
1305 b18212c6 Stefan Weil
                base = TCG_REG_L0;
1306 8d918718 Stefan Weil
                offset = 0;
1307 5d8a4f8f Richard Henderson
            }
1308 5d8a4f8f Richard Henderson
        }
1309 5d8a4f8f Richard Henderson
1310 5d8a4f8f Richard Henderson
        tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, opc);
1311 5d8a4f8f Richard Henderson
    }
1312 c896fe29 bellard
#endif
1313 be5a4eb7 Richard Henderson
}
1314 c896fe29 bellard
1315 be5a4eb7 Richard Henderson
static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
1316 be5a4eb7 Richard Henderson
                                   int base, tcg_target_long ofs, int sizeop)
1317 be5a4eb7 Richard Henderson
{
1318 c896fe29 bellard
#ifdef TARGET_WORDS_BIGENDIAN
1319 be5a4eb7 Richard Henderson
    const int bswap = 1;
1320 c896fe29 bellard
#else
1321 be5a4eb7 Richard Henderson
    const int bswap = 0;
1322 c896fe29 bellard
#endif
1323 be5a4eb7 Richard Henderson
    /* ??? Ideally we wouldn't need a scratch register.  For user-only,
1324 be5a4eb7 Richard Henderson
       we could perform the bswap twice to restore the original value
1325 be5a4eb7 Richard Henderson
       instead of moving to the scratch.  But as it is, the L constraint
1326 b18212c6 Stefan Weil
       means that TCG_REG_L1 is definitely free here.  */
1327 b18212c6 Stefan Weil
    const int scratch = TCG_REG_L1;
1328 be5a4eb7 Richard Henderson
1329 be5a4eb7 Richard Henderson
    switch (sizeop) {
1330 c896fe29 bellard
    case 0:
1331 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
1332 c896fe29 bellard
        break;
1333 c896fe29 bellard
    case 1:
1334 c896fe29 bellard
        if (bswap) {
1335 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1336 be5a4eb7 Richard Henderson
            tcg_out_rolw_8(s, scratch);
1337 be5a4eb7 Richard Henderson
            datalo = scratch;
1338 c896fe29 bellard
        }
1339 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16, datalo, base, ofs);
1340 c896fe29 bellard
        break;
1341 c896fe29 bellard
    case 2:
1342 c896fe29 bellard
        if (bswap) {
1343 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1344 be5a4eb7 Richard Henderson
            tcg_out_bswap32(s, scratch);
1345 be5a4eb7 Richard Henderson
            datalo = scratch;
1346 c896fe29 bellard
        }
1347 be5a4eb7 Richard Henderson
        tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1348 c896fe29 bellard
        break;
1349 c896fe29 bellard
    case 3:
1350 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
1351 5d8a4f8f Richard Henderson
            if (bswap) {
1352 5d8a4f8f Richard Henderson
                tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
1353 5d8a4f8f Richard Henderson
                tcg_out_bswap64(s, scratch);
1354 5d8a4f8f Richard Henderson
                datalo = scratch;
1355 5d8a4f8f Richard Henderson
            }
1356 5d8a4f8f Richard Henderson
            tcg_out_st(s, TCG_TYPE_I64, datalo, base, ofs);
1357 5d8a4f8f Richard Henderson
        } else if (bswap) {
1358 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
1359 be5a4eb7 Richard Henderson
            tcg_out_bswap32(s, scratch);
1360 be5a4eb7 Richard Henderson
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
1361 3b6dac34 Richard Henderson
            tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1362 be5a4eb7 Richard Henderson
            tcg_out_bswap32(s, scratch);
1363 be5a4eb7 Richard Henderson
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
1364 c896fe29 bellard
        } else {
1365 be5a4eb7 Richard Henderson
            tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1366 be5a4eb7 Richard Henderson
            tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1367 c896fe29 bellard
        }
1368 c896fe29 bellard
        break;
1369 c896fe29 bellard
    default:
1370 c896fe29 bellard
        tcg_abort();
1371 c896fe29 bellard
    }
1372 c896fe29 bellard
}
1373 c896fe29 bellard
1374 c896fe29 bellard
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1375 c896fe29 bellard
                            int opc)
1376 c896fe29 bellard
{
1377 1a6dc1e4 Richard Henderson
    int data_reg, data_reg2 = 0;
1378 8516a044 Richard Henderson
    int addrlo_idx;
1379 c896fe29 bellard
#if defined(CONFIG_SOFTMMU)
1380 8516a044 Richard Henderson
    int mem_index, s_bits;
1381 aadb21a4 Richard Henderson
    int stack_adjust;
1382 1a6dc1e4 Richard Henderson
    uint8_t *label_ptr[3];
1383 c896fe29 bellard
#endif
1384 c896fe29 bellard
1385 8516a044 Richard Henderson
    data_reg = args[0];
1386 8516a044 Richard Henderson
    addrlo_idx = 1;
1387 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
1388 8516a044 Richard Henderson
        data_reg2 = args[1];
1389 8516a044 Richard Henderson
        addrlo_idx = 2;
1390 1a6dc1e4 Richard Henderson
    }
1391 c896fe29 bellard
1392 c896fe29 bellard
#if defined(CONFIG_SOFTMMU)
1393 5d8a4f8f Richard Henderson
    mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
1394 8516a044 Richard Henderson
    s_bits = opc;
1395 1a6dc1e4 Richard Henderson
1396 8516a044 Richard Henderson
    tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1397 8516a044 Richard Henderson
                     label_ptr, offsetof(CPUTLBEntry, addr_write));
1398 1a6dc1e4 Richard Henderson
1399 1a6dc1e4 Richard Henderson
    /* TLB Hit.  */
1400 b18212c6 Stefan Weil
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, TCG_REG_L0, 0, opc);
1401 c896fe29 bellard
1402 1a6dc1e4 Richard Henderson
    /* jmp label2 */
1403 1a6dc1e4 Richard Henderson
    tcg_out8(s, OPC_JMP_short);
1404 1a6dc1e4 Richard Henderson
    label_ptr[2] = s->code_ptr;
1405 c896fe29 bellard
    s->code_ptr++;
1406 78686523 Richard Henderson
1407 1a6dc1e4 Richard Henderson
    /* TLB Miss.  */
1408 1a6dc1e4 Richard Henderson
1409 1a6dc1e4 Richard Henderson
    /* label1: */
1410 1a6dc1e4 Richard Henderson
    *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
1411 5d8a4f8f Richard Henderson
    if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1412 1a6dc1e4 Richard Henderson
        *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1413 1a6dc1e4 Richard Henderson
    }
1414 c896fe29 bellard
1415 c896fe29 bellard
    /* XXX: move that code at the end of the TB */
1416 6a18ae2d Blue Swirl
#if TCG_TARGET_REG_BITS == 32
1417 6a18ae2d Blue Swirl
    tcg_out_pushi(s, mem_index);
1418 6a18ae2d Blue Swirl
    stack_adjust = 4;
1419 6a18ae2d Blue Swirl
    if (opc == 3) {
1420 6a18ae2d Blue Swirl
        tcg_out_push(s, data_reg2);
1421 6a18ae2d Blue Swirl
        stack_adjust += 4;
1422 6a18ae2d Blue Swirl
    }
1423 6a18ae2d Blue Swirl
    tcg_out_push(s, data_reg);
1424 6a18ae2d Blue Swirl
    stack_adjust += 4;
1425 6a18ae2d Blue Swirl
    if (TARGET_LONG_BITS == 64) {
1426 6a18ae2d Blue Swirl
        tcg_out_push(s, args[addrlo_idx + 1]);
1427 6a18ae2d Blue Swirl
        stack_adjust += 4;
1428 c896fe29 bellard
    }
1429 6a18ae2d Blue Swirl
    tcg_out_push(s, args[addrlo_idx]);
1430 6a18ae2d Blue Swirl
    stack_adjust += 4;
1431 e141ab52 Blue Swirl
    tcg_out_push(s, TCG_AREG0);
1432 e141ab52 Blue Swirl
    stack_adjust += 4;
1433 6a18ae2d Blue Swirl
#else
1434 6a18ae2d Blue Swirl
    tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1435 b18212c6 Stefan Weil
                TCG_REG_L1, data_reg);
1436 b18212c6 Stefan Weil
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_L2, mem_index);
1437 6a18ae2d Blue Swirl
    stack_adjust = 0;
1438 e141ab52 Blue Swirl
    /* XXX/FIXME: suboptimal */
1439 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3], TCG_REG_L2);
1440 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2], TCG_REG_L1);
1441 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1], TCG_REG_L0);
1442 b18212c6 Stefan Weil
    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
1443 e141ab52 Blue Swirl
#endif
1444 aadb21a4 Richard Henderson
1445 aadb21a4 Richard Henderson
    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1446 aadb21a4 Richard Henderson
1447 5d8a4f8f Richard Henderson
    if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
1448 aadb21a4 Richard Henderson
        /* Pop and discard.  This is 2 bytes smaller than the add.  */
1449 aadb21a4 Richard Henderson
        tcg_out_pop(s, TCG_REG_ECX);
1450 aadb21a4 Richard Henderson
    } else if (stack_adjust != 0) {
1451 e83c80f7 Blue Swirl
        tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
1452 aadb21a4 Richard Henderson
    }
1453 aadb21a4 Richard Henderson
1454 c896fe29 bellard
    /* label2: */
1455 1a6dc1e4 Richard Henderson
    *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1456 be5a4eb7 Richard Henderson
#else
1457 5d8a4f8f Richard Henderson
    {
1458 5d8a4f8f Richard Henderson
        int32_t offset = GUEST_BASE;
1459 5d8a4f8f Richard Henderson
        int base = args[addrlo_idx];
1460 5d8a4f8f Richard Henderson
1461 5d8a4f8f Richard Henderson
        if (TCG_TARGET_REG_BITS == 64) {
1462 5d8a4f8f Richard Henderson
            /* ??? We assume all operations have left us with register
1463 5d8a4f8f Richard Henderson
               contents that are zero extended.  So far this appears to
1464 5d8a4f8f Richard Henderson
               be true.  If we want to enforce this, we can either do
1465 5d8a4f8f Richard Henderson
               an explicit zero-extension here, or (if GUEST_BASE == 0)
1466 5d8a4f8f Richard Henderson
               use the ADDR32 prefix.  For now, do nothing.  */
1467 5d8a4f8f Richard Henderson
1468 5d8a4f8f Richard Henderson
            if (offset != GUEST_BASE) {
1469 b18212c6 Stefan Weil
                tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L0, GUEST_BASE);
1470 b18212c6 Stefan Weil
                tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L0, base);
1471 b18212c6 Stefan Weil
                base = TCG_REG_L0;
1472 8d918718 Stefan Weil
                offset = 0;
1473 5d8a4f8f Richard Henderson
            }
1474 5d8a4f8f Richard Henderson
        }
1475 5d8a4f8f Richard Henderson
1476 5d8a4f8f Richard Henderson
        tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, opc);
1477 5d8a4f8f Richard Henderson
    }
1478 c896fe29 bellard
#endif
1479 c896fe29 bellard
}
1480 c896fe29 bellard
1481 a9751609 Richard Henderson
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1482 c896fe29 bellard
                              const TCGArg *args, const int *const_args)
1483 c896fe29 bellard
{
1484 5d8a4f8f Richard Henderson
    int c, rexw = 0;
1485 5d8a4f8f Richard Henderson
1486 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1487 5d8a4f8f Richard Henderson
# define OP_32_64(x) \
1488 5d8a4f8f Richard Henderson
        case glue(glue(INDEX_op_, x), _i64): \
1489 5d8a4f8f Richard Henderson
            rexw = P_REXW; /* FALLTHRU */    \
1490 5d8a4f8f Richard Henderson
        case glue(glue(INDEX_op_, x), _i32)
1491 5d8a4f8f Richard Henderson
#else
1492 5d8a4f8f Richard Henderson
# define OP_32_64(x) \
1493 5d8a4f8f Richard Henderson
        case glue(glue(INDEX_op_, x), _i32)
1494 5d8a4f8f Richard Henderson
#endif
1495 78686523 Richard Henderson
1496 c896fe29 bellard
    switch(opc) {
1497 c896fe29 bellard
    case INDEX_op_exit_tb:
1498 5d8a4f8f Richard Henderson
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
1499 5d8a4f8f Richard Henderson
        tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
1500 c896fe29 bellard
        break;
1501 c896fe29 bellard
    case INDEX_op_goto_tb:
1502 c896fe29 bellard
        if (s->tb_jmp_offset) {
1503 c896fe29 bellard
            /* direct jump method */
1504 da441cff Richard Henderson
            tcg_out8(s, OPC_JMP_long); /* jmp im */
1505 c896fe29 bellard
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1506 c896fe29 bellard
            tcg_out32(s, 0);
1507 c896fe29 bellard
        } else {
1508 c896fe29 bellard
            /* indirect jump method */
1509 9363dedb Richard Henderson
            tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1510 c896fe29 bellard
                                 (tcg_target_long)(s->tb_next + args[0]));
1511 c896fe29 bellard
        }
1512 c896fe29 bellard
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1513 c896fe29 bellard
        break;
1514 c896fe29 bellard
    case INDEX_op_call:
1515 c896fe29 bellard
        if (const_args[0]) {
1516 aadb21a4 Richard Henderson
            tcg_out_calli(s, args[0]);
1517 c896fe29 bellard
        } else {
1518 aadb21a4 Richard Henderson
            /* call *reg */
1519 9363dedb Richard Henderson
            tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1520 c896fe29 bellard
        }
1521 c896fe29 bellard
        break;
1522 c896fe29 bellard
    case INDEX_op_jmp:
1523 c896fe29 bellard
        if (const_args[0]) {
1524 5d8a4f8f Richard Henderson
            tcg_out_jmp(s, args[0]);
1525 c896fe29 bellard
        } else {
1526 da441cff Richard Henderson
            /* jmp *reg */
1527 9363dedb Richard Henderson
            tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1528 c896fe29 bellard
        }
1529 c896fe29 bellard
        break;
1530 c896fe29 bellard
    case INDEX_op_br:
1531 f75b56c1 Richard Henderson
        tcg_out_jxx(s, JCC_JMP, args[0], 0);
1532 c896fe29 bellard
        break;
1533 c896fe29 bellard
    case INDEX_op_movi_i32:
1534 c896fe29 bellard
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1535 c896fe29 bellard
        break;
1536 5d8a4f8f Richard Henderson
    OP_32_64(ld8u):
1537 5d8a4f8f Richard Henderson
        /* Note that we can ignore REXW for the zero-extend to 64-bit.  */
1538 55e082a7 Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
1539 c896fe29 bellard
        break;
1540 5d8a4f8f Richard Henderson
    OP_32_64(ld8s):
1541 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
1542 c896fe29 bellard
        break;
1543 5d8a4f8f Richard Henderson
    OP_32_64(ld16u):
1544 5d8a4f8f Richard Henderson
        /* Note that we can ignore REXW for the zero-extend to 64-bit.  */
1545 55e082a7 Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1546 c896fe29 bellard
        break;
1547 5d8a4f8f Richard Henderson
    OP_32_64(ld16s):
1548 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
1549 c896fe29 bellard
        break;
1550 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1551 5d8a4f8f Richard Henderson
    case INDEX_op_ld32u_i64:
1552 5d8a4f8f Richard Henderson
#endif
1553 c896fe29 bellard
    case INDEX_op_ld_i32:
1554 af266089 Richard Henderson
        tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1555 c896fe29 bellard
        break;
1556 5d8a4f8f Richard Henderson
1557 5d8a4f8f Richard Henderson
    OP_32_64(st8):
1558 5c2d2a9e Aurelien Jarno
        if (const_args[0]) {
1559 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
1560 5c2d2a9e Aurelien Jarno
                                 0, args[1], args[2]);
1561 5c2d2a9e Aurelien Jarno
            tcg_out8(s, args[0]);
1562 5c2d2a9e Aurelien Jarno
        } else {
1563 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
1564 5c2d2a9e Aurelien Jarno
                                 args[0], args[1], args[2]);
1565 5c2d2a9e Aurelien Jarno
        }
1566 c896fe29 bellard
        break;
1567 5d8a4f8f Richard Henderson
    OP_32_64(st16):
1568 5c2d2a9e Aurelien Jarno
        if (const_args[0]) {
1569 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
1570 5c2d2a9e Aurelien Jarno
                                 0, args[1], args[2]);
1571 5c2d2a9e Aurelien Jarno
            tcg_out16(s, args[0]);
1572 5c2d2a9e Aurelien Jarno
        } else {
1573 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1574 5c2d2a9e Aurelien Jarno
                                 args[0], args[1], args[2]);
1575 5c2d2a9e Aurelien Jarno
        }
1576 c896fe29 bellard
        break;
1577 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1578 5d8a4f8f Richard Henderson
    case INDEX_op_st32_i64:
1579 5d8a4f8f Richard Henderson
#endif
1580 c896fe29 bellard
    case INDEX_op_st_i32:
1581 5c2d2a9e Aurelien Jarno
        if (const_args[0]) {
1582 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
1583 5c2d2a9e Aurelien Jarno
            tcg_out32(s, args[0]);
1584 5c2d2a9e Aurelien Jarno
        } else {
1585 5c2d2a9e Aurelien Jarno
            tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1586 5c2d2a9e Aurelien Jarno
        }
1587 c896fe29 bellard
        break;
1588 5d8a4f8f Richard Henderson
1589 5d8a4f8f Richard Henderson
    OP_32_64(add):
1590 5d1e4e85 Richard Henderson
        /* For 3-operand addition, use LEA.  */
1591 5d1e4e85 Richard Henderson
        if (args[0] != args[1]) {
1592 5d1e4e85 Richard Henderson
            TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1593 5d1e4e85 Richard Henderson
1594 5d1e4e85 Richard Henderson
            if (const_args[2]) {
1595 5d1e4e85 Richard Henderson
                c3 = a2, a2 = -1;
1596 5d1e4e85 Richard Henderson
            } else if (a0 == a2) {
1597 5d1e4e85 Richard Henderson
                /* Watch out for dest = src + dest, since we've removed
1598 5d1e4e85 Richard Henderson
                   the matching constraint on the add.  */
1599 5d8a4f8f Richard Henderson
                tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
1600 5d1e4e85 Richard Henderson
                break;
1601 5d1e4e85 Richard Henderson
            }
1602 5d1e4e85 Richard Henderson
1603 5d8a4f8f Richard Henderson
            tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
1604 5d1e4e85 Richard Henderson
            break;
1605 5d1e4e85 Richard Henderson
        }
1606 5d1e4e85 Richard Henderson
        c = ARITH_ADD;
1607 5d1e4e85 Richard Henderson
        goto gen_arith;
1608 5d8a4f8f Richard Henderson
    OP_32_64(sub):
1609 c896fe29 bellard
        c = ARITH_SUB;
1610 c896fe29 bellard
        goto gen_arith;
1611 5d8a4f8f Richard Henderson
    OP_32_64(and):
1612 c896fe29 bellard
        c = ARITH_AND;
1613 c896fe29 bellard
        goto gen_arith;
1614 5d8a4f8f Richard Henderson
    OP_32_64(or):
1615 c896fe29 bellard
        c = ARITH_OR;
1616 c896fe29 bellard
        goto gen_arith;
1617 5d8a4f8f Richard Henderson
    OP_32_64(xor):
1618 c896fe29 bellard
        c = ARITH_XOR;
1619 c896fe29 bellard
        goto gen_arith;
1620 c896fe29 bellard
    gen_arith:
1621 c896fe29 bellard
        if (const_args[2]) {
1622 5d8a4f8f Richard Henderson
            tgen_arithi(s, c + rexw, args[0], args[2], 0);
1623 c896fe29 bellard
        } else {
1624 5d8a4f8f Richard Henderson
            tgen_arithr(s, c + rexw, args[0], args[2]);
1625 c896fe29 bellard
        }
1626 c896fe29 bellard
        break;
1627 5d8a4f8f Richard Henderson
1628 5d8a4f8f Richard Henderson
    OP_32_64(mul):
1629 c896fe29 bellard
        if (const_args[2]) {
1630 c896fe29 bellard
            int32_t val;
1631 c896fe29 bellard
            val = args[2];
1632 c896fe29 bellard
            if (val == (int8_t)val) {
1633 5d8a4f8f Richard Henderson
                tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
1634 c896fe29 bellard
                tcg_out8(s, val);
1635 c896fe29 bellard
            } else {
1636 5d8a4f8f Richard Henderson
                tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
1637 c896fe29 bellard
                tcg_out32(s, val);
1638 c896fe29 bellard
            }
1639 c896fe29 bellard
        } else {
1640 5d8a4f8f Richard Henderson
            tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
1641 c896fe29 bellard
        }
1642 c896fe29 bellard
        break;
1643 5d8a4f8f Richard Henderson
1644 5d8a4f8f Richard Henderson
    OP_32_64(div2):
1645 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
1646 c896fe29 bellard
        break;
1647 5d8a4f8f Richard Henderson
    OP_32_64(divu2):
1648 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
1649 c896fe29 bellard
        break;
1650 5d8a4f8f Richard Henderson
1651 5d8a4f8f Richard Henderson
    OP_32_64(shl):
1652 c896fe29 bellard
        c = SHIFT_SHL;
1653 5d8a4f8f Richard Henderson
        goto gen_shift;
1654 5d8a4f8f Richard Henderson
    OP_32_64(shr):
1655 c896fe29 bellard
        c = SHIFT_SHR;
1656 5d8a4f8f Richard Henderson
        goto gen_shift;
1657 5d8a4f8f Richard Henderson
    OP_32_64(sar):
1658 c896fe29 bellard
        c = SHIFT_SAR;
1659 5d8a4f8f Richard Henderson
        goto gen_shift;
1660 5d8a4f8f Richard Henderson
    OP_32_64(rotl):
1661 9619376c aurel32
        c = SHIFT_ROL;
1662 5d8a4f8f Richard Henderson
        goto gen_shift;
1663 5d8a4f8f Richard Henderson
    OP_32_64(rotr):
1664 9619376c aurel32
        c = SHIFT_ROR;
1665 5d8a4f8f Richard Henderson
        goto gen_shift;
1666 5d8a4f8f Richard Henderson
    gen_shift:
1667 5d8a4f8f Richard Henderson
        if (const_args[2]) {
1668 5d8a4f8f Richard Henderson
            tcg_out_shifti(s, c + rexw, args[0], args[2]);
1669 81570a70 Richard Henderson
        } else {
1670 5d8a4f8f Richard Henderson
            tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
1671 81570a70 Richard Henderson
        }
1672 c896fe29 bellard
        break;
1673 5d8a4f8f Richard Henderson
1674 c896fe29 bellard
    case INDEX_op_brcond_i32:
1675 5d8a4f8f Richard Henderson
        tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
1676 5d8a4f8f Richard Henderson
                         args[3], 0);
1677 c896fe29 bellard
        break;
1678 5d8a4f8f Richard Henderson
    case INDEX_op_setcond_i32:
1679 5d8a4f8f Richard Henderson
        tcg_out_setcond32(s, args[3], args[0], args[1],
1680 5d8a4f8f Richard Henderson
                          args[2], const_args[2]);
1681 c896fe29 bellard
        break;
1682 d0a16297 Richard Henderson
    case INDEX_op_movcond_i32:
1683 d0a16297 Richard Henderson
        tcg_out_movcond32(s, args[5], args[0], args[1],
1684 d0a16297 Richard Henderson
                          args[2], const_args[2], args[3]);
1685 d0a16297 Richard Henderson
        break;
1686 c896fe29 bellard
1687 5d8a4f8f Richard Henderson
    OP_32_64(bswap16):
1688 fcb5dac1 Richard Henderson
        tcg_out_rolw_8(s, args[0]);
1689 5d40cd63 aurel32
        break;
1690 5d8a4f8f Richard Henderson
    OP_32_64(bswap32):
1691 fcb5dac1 Richard Henderson
        tcg_out_bswap32(s, args[0]);
1692 9619376c aurel32
        break;
1693 9619376c aurel32
1694 5d8a4f8f Richard Henderson
    OP_32_64(neg):
1695 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
1696 9619376c aurel32
        break;
1697 5d8a4f8f Richard Henderson
    OP_32_64(not):
1698 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
1699 9619376c aurel32
        break;
1700 9619376c aurel32
1701 5d8a4f8f Richard Henderson
    OP_32_64(ext8s):
1702 5d8a4f8f Richard Henderson
        tcg_out_ext8s(s, args[0], args[1], rexw);
1703 9619376c aurel32
        break;
1704 5d8a4f8f Richard Henderson
    OP_32_64(ext16s):
1705 5d8a4f8f Richard Henderson
        tcg_out_ext16s(s, args[0], args[1], rexw);
1706 9619376c aurel32
        break;
1707 5d8a4f8f Richard Henderson
    OP_32_64(ext8u):
1708 55e082a7 Richard Henderson
        tcg_out_ext8u(s, args[0], args[1]);
1709 5f0ce17f Aurelien Jarno
        break;
1710 5d8a4f8f Richard Henderson
    OP_32_64(ext16u):
1711 55e082a7 Richard Henderson
        tcg_out_ext16u(s, args[0], args[1]);
1712 5f0ce17f Aurelien Jarno
        break;
1713 9619376c aurel32
1714 c896fe29 bellard
    case INDEX_op_qemu_ld8u:
1715 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 0);
1716 c896fe29 bellard
        break;
1717 c896fe29 bellard
    case INDEX_op_qemu_ld8s:
1718 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 0 | 4);
1719 c896fe29 bellard
        break;
1720 c896fe29 bellard
    case INDEX_op_qemu_ld16u:
1721 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 1);
1722 c896fe29 bellard
        break;
1723 c896fe29 bellard
    case INDEX_op_qemu_ld16s:
1724 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 1 | 4);
1725 c896fe29 bellard
        break;
1726 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1727 5d8a4f8f Richard Henderson
    case INDEX_op_qemu_ld32u:
1728 5d8a4f8f Richard Henderson
#endif
1729 86feb1c8 Richard Henderson
    case INDEX_op_qemu_ld32:
1730 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 2);
1731 c896fe29 bellard
        break;
1732 c896fe29 bellard
    case INDEX_op_qemu_ld64:
1733 c896fe29 bellard
        tcg_out_qemu_ld(s, args, 3);
1734 c896fe29 bellard
        break;
1735 78686523 Richard Henderson
1736 c896fe29 bellard
    case INDEX_op_qemu_st8:
1737 c896fe29 bellard
        tcg_out_qemu_st(s, args, 0);
1738 c896fe29 bellard
        break;
1739 c896fe29 bellard
    case INDEX_op_qemu_st16:
1740 c896fe29 bellard
        tcg_out_qemu_st(s, args, 1);
1741 c896fe29 bellard
        break;
1742 c896fe29 bellard
    case INDEX_op_qemu_st32:
1743 c896fe29 bellard
        tcg_out_qemu_st(s, args, 2);
1744 c896fe29 bellard
        break;
1745 c896fe29 bellard
    case INDEX_op_qemu_st64:
1746 c896fe29 bellard
        tcg_out_qemu_st(s, args, 3);
1747 c896fe29 bellard
        break;
1748 c896fe29 bellard
1749 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 32
1750 5d8a4f8f Richard Henderson
    case INDEX_op_brcond2_i32:
1751 5d8a4f8f Richard Henderson
        tcg_out_brcond2(s, args, const_args, 0);
1752 5d8a4f8f Richard Henderson
        break;
1753 5d8a4f8f Richard Henderson
    case INDEX_op_setcond2_i32:
1754 5d8a4f8f Richard Henderson
        tcg_out_setcond2(s, args, const_args);
1755 5d8a4f8f Richard Henderson
        break;
1756 5d8a4f8f Richard Henderson
    case INDEX_op_mulu2_i32:
1757 5d8a4f8f Richard Henderson
        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1758 5d8a4f8f Richard Henderson
        break;
1759 5d8a4f8f Richard Henderson
    case INDEX_op_add2_i32:
1760 5d8a4f8f Richard Henderson
        if (const_args[4]) {
1761 5d8a4f8f Richard Henderson
            tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1762 5d8a4f8f Richard Henderson
        } else {
1763 5d8a4f8f Richard Henderson
            tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1764 5d8a4f8f Richard Henderson
        }
1765 5d8a4f8f Richard Henderson
        if (const_args[5]) {
1766 5d8a4f8f Richard Henderson
            tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1767 5d8a4f8f Richard Henderson
        } else {
1768 5d8a4f8f Richard Henderson
            tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1769 5d8a4f8f Richard Henderson
        }
1770 5d8a4f8f Richard Henderson
        break;
1771 5d8a4f8f Richard Henderson
    case INDEX_op_sub2_i32:
1772 5d8a4f8f Richard Henderson
        if (const_args[4]) {
1773 5d8a4f8f Richard Henderson
            tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1774 5d8a4f8f Richard Henderson
        } else {
1775 5d8a4f8f Richard Henderson
            tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1776 5d8a4f8f Richard Henderson
        }
1777 5d8a4f8f Richard Henderson
        if (const_args[5]) {
1778 5d8a4f8f Richard Henderson
            tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1779 5d8a4f8f Richard Henderson
        } else {
1780 5d8a4f8f Richard Henderson
            tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1781 5d8a4f8f Richard Henderson
        }
1782 5d8a4f8f Richard Henderson
        break;
1783 5d8a4f8f Richard Henderson
#else /* TCG_TARGET_REG_BITS == 64 */
1784 5d8a4f8f Richard Henderson
    case INDEX_op_movi_i64:
1785 5d8a4f8f Richard Henderson
        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1786 5d8a4f8f Richard Henderson
        break;
1787 5d8a4f8f Richard Henderson
    case INDEX_op_ld32s_i64:
1788 5d8a4f8f Richard Henderson
        tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
1789 5d8a4f8f Richard Henderson
        break;
1790 5d8a4f8f Richard Henderson
    case INDEX_op_ld_i64:
1791 5d8a4f8f Richard Henderson
        tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1792 5d8a4f8f Richard Henderson
        break;
1793 5d8a4f8f Richard Henderson
    case INDEX_op_st_i64:
1794 5c2d2a9e Aurelien Jarno
        if (const_args[0]) {
1795 5c2d2a9e Aurelien Jarno
            tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
1796 5c2d2a9e Aurelien Jarno
                                 0, args[1], args[2]);
1797 5c2d2a9e Aurelien Jarno
            tcg_out32(s, args[0]);
1798 5c2d2a9e Aurelien Jarno
        } else {
1799 5c2d2a9e Aurelien Jarno
            tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1800 5c2d2a9e Aurelien Jarno
        }
1801 5d8a4f8f Richard Henderson
        break;
1802 5d8a4f8f Richard Henderson
    case INDEX_op_qemu_ld32s:
1803 5d8a4f8f Richard Henderson
        tcg_out_qemu_ld(s, args, 2 | 4);
1804 5d8a4f8f Richard Henderson
        break;
1805 5d8a4f8f Richard Henderson
1806 5d8a4f8f Richard Henderson
    case INDEX_op_brcond_i64:
1807 5d8a4f8f Richard Henderson
        tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
1808 5d8a4f8f Richard Henderson
                         args[3], 0);
1809 5d8a4f8f Richard Henderson
        break;
1810 5d8a4f8f Richard Henderson
    case INDEX_op_setcond_i64:
1811 5d8a4f8f Richard Henderson
        tcg_out_setcond64(s, args[3], args[0], args[1],
1812 5d8a4f8f Richard Henderson
                          args[2], const_args[2]);
1813 5d8a4f8f Richard Henderson
        break;
1814 d0a16297 Richard Henderson
    case INDEX_op_movcond_i64:
1815 d0a16297 Richard Henderson
        tcg_out_movcond64(s, args[5], args[0], args[1],
1816 d0a16297 Richard Henderson
                          args[2], const_args[2], args[3]);
1817 d0a16297 Richard Henderson
        break;
1818 5d8a4f8f Richard Henderson
1819 5d8a4f8f Richard Henderson
    case INDEX_op_bswap64_i64:
1820 5d8a4f8f Richard Henderson
        tcg_out_bswap64(s, args[0]);
1821 5d8a4f8f Richard Henderson
        break;
1822 5d8a4f8f Richard Henderson
    case INDEX_op_ext32u_i64:
1823 5d8a4f8f Richard Henderson
        tcg_out_ext32u(s, args[0], args[1]);
1824 5d8a4f8f Richard Henderson
        break;
1825 5d8a4f8f Richard Henderson
    case INDEX_op_ext32s_i64:
1826 5d8a4f8f Richard Henderson
        tcg_out_ext32s(s, args[0], args[1]);
1827 5d8a4f8f Richard Henderson
        break;
1828 5d8a4f8f Richard Henderson
#endif
1829 5d8a4f8f Richard Henderson
1830 a4773324 Jan Kiszka
    OP_32_64(deposit):
1831 a4773324 Jan Kiszka
        if (args[3] == 0 && args[4] == 8) {
1832 a4773324 Jan Kiszka
            /* load bits 0..7 */
1833 a4773324 Jan Kiszka
            tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
1834 a4773324 Jan Kiszka
                          args[2], args[0]);
1835 a4773324 Jan Kiszka
        } else if (args[3] == 8 && args[4] == 8) {
1836 a4773324 Jan Kiszka
            /* load bits 8..15 */
1837 a4773324 Jan Kiszka
            tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
1838 a4773324 Jan Kiszka
        } else if (args[3] == 0 && args[4] == 16) {
1839 a4773324 Jan Kiszka
            /* load bits 0..15 */
1840 a4773324 Jan Kiszka
            tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
1841 a4773324 Jan Kiszka
        } else {
1842 a4773324 Jan Kiszka
            tcg_abort();
1843 a4773324 Jan Kiszka
        }
1844 a4773324 Jan Kiszka
        break;
1845 a4773324 Jan Kiszka
1846 c896fe29 bellard
    default:
1847 c896fe29 bellard
        tcg_abort();
1848 c896fe29 bellard
    }
1849 5d8a4f8f Richard Henderson
1850 5d8a4f8f Richard Henderson
#undef OP_32_64
1851 c896fe29 bellard
}
1852 c896fe29 bellard
1853 c896fe29 bellard
static const TCGTargetOpDef x86_op_defs[] = {
1854 c896fe29 bellard
    { INDEX_op_exit_tb, { } },
1855 c896fe29 bellard
    { INDEX_op_goto_tb, { } },
1856 c896fe29 bellard
    { INDEX_op_call, { "ri" } },
1857 c896fe29 bellard
    { INDEX_op_jmp, { "ri" } },
1858 c896fe29 bellard
    { INDEX_op_br, { } },
1859 c896fe29 bellard
    { INDEX_op_mov_i32, { "r", "r" } },
1860 c896fe29 bellard
    { INDEX_op_movi_i32, { "r" } },
1861 c896fe29 bellard
    { INDEX_op_ld8u_i32, { "r", "r" } },
1862 c896fe29 bellard
    { INDEX_op_ld8s_i32, { "r", "r" } },
1863 c896fe29 bellard
    { INDEX_op_ld16u_i32, { "r", "r" } },
1864 c896fe29 bellard
    { INDEX_op_ld16s_i32, { "r", "r" } },
1865 c896fe29 bellard
    { INDEX_op_ld_i32, { "r", "r" } },
1866 5c2d2a9e Aurelien Jarno
    { INDEX_op_st8_i32, { "qi", "r" } },
1867 5c2d2a9e Aurelien Jarno
    { INDEX_op_st16_i32, { "ri", "r" } },
1868 5c2d2a9e Aurelien Jarno
    { INDEX_op_st_i32, { "ri", "r" } },
1869 c896fe29 bellard
1870 5d1e4e85 Richard Henderson
    { INDEX_op_add_i32, { "r", "r", "ri" } },
1871 c896fe29 bellard
    { INDEX_op_sub_i32, { "r", "0", "ri" } },
1872 c896fe29 bellard
    { INDEX_op_mul_i32, { "r", "0", "ri" } },
1873 c896fe29 bellard
    { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1874 c896fe29 bellard
    { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1875 c896fe29 bellard
    { INDEX_op_and_i32, { "r", "0", "ri" } },
1876 c896fe29 bellard
    { INDEX_op_or_i32, { "r", "0", "ri" } },
1877 c896fe29 bellard
    { INDEX_op_xor_i32, { "r", "0", "ri" } },
1878 c896fe29 bellard
1879 c896fe29 bellard
    { INDEX_op_shl_i32, { "r", "0", "ci" } },
1880 c896fe29 bellard
    { INDEX_op_shr_i32, { "r", "0", "ci" } },
1881 c896fe29 bellard
    { INDEX_op_sar_i32, { "r", "0", "ci" } },
1882 9619376c aurel32
    { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1883 9619376c aurel32
    { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1884 c896fe29 bellard
1885 c896fe29 bellard
    { INDEX_op_brcond_i32, { "r", "ri" } },
1886 c896fe29 bellard
1887 5d40cd63 aurel32
    { INDEX_op_bswap16_i32, { "r", "0" } },
1888 66896cb8 aurel32
    { INDEX_op_bswap32_i32, { "r", "0" } },
1889 9619376c aurel32
1890 9619376c aurel32
    { INDEX_op_neg_i32, { "r", "0" } },
1891 9619376c aurel32
1892 9619376c aurel32
    { INDEX_op_not_i32, { "r", "0" } },
1893 9619376c aurel32
1894 9619376c aurel32
    { INDEX_op_ext8s_i32, { "r", "q" } },
1895 9619376c aurel32
    { INDEX_op_ext16s_i32, { "r", "r" } },
1896 55e082a7 Richard Henderson
    { INDEX_op_ext8u_i32, { "r", "q" } },
1897 55e082a7 Richard Henderson
    { INDEX_op_ext16u_i32, { "r", "r" } },
1898 9619376c aurel32
1899 1d2699ae Richard Henderson
    { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1900 5d8a4f8f Richard Henderson
1901 a4773324 Jan Kiszka
    { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
1902 d0a16297 Richard Henderson
    { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
1903 a4773324 Jan Kiszka
1904 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 32
1905 5d8a4f8f Richard Henderson
    { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1906 5d8a4f8f Richard Henderson
    { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1907 5d8a4f8f Richard Henderson
    { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1908 5d8a4f8f Richard Henderson
    { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1909 1d2699ae Richard Henderson
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1910 5d8a4f8f Richard Henderson
#else
1911 5d8a4f8f Richard Henderson
    { INDEX_op_mov_i64, { "r", "r" } },
1912 5d8a4f8f Richard Henderson
    { INDEX_op_movi_i64, { "r" } },
1913 5d8a4f8f Richard Henderson
    { INDEX_op_ld8u_i64, { "r", "r" } },
1914 5d8a4f8f Richard Henderson
    { INDEX_op_ld8s_i64, { "r", "r" } },
1915 5d8a4f8f Richard Henderson
    { INDEX_op_ld16u_i64, { "r", "r" } },
1916 5d8a4f8f Richard Henderson
    { INDEX_op_ld16s_i64, { "r", "r" } },
1917 5d8a4f8f Richard Henderson
    { INDEX_op_ld32u_i64, { "r", "r" } },
1918 5d8a4f8f Richard Henderson
    { INDEX_op_ld32s_i64, { "r", "r" } },
1919 5d8a4f8f Richard Henderson
    { INDEX_op_ld_i64, { "r", "r" } },
1920 5c2d2a9e Aurelien Jarno
    { INDEX_op_st8_i64, { "ri", "r" } },
1921 5c2d2a9e Aurelien Jarno
    { INDEX_op_st16_i64, { "ri", "r" } },
1922 5c2d2a9e Aurelien Jarno
    { INDEX_op_st32_i64, { "ri", "r" } },
1923 5c2d2a9e Aurelien Jarno
    { INDEX_op_st_i64, { "re", "r" } },
1924 5d8a4f8f Richard Henderson
1925 5d8a4f8f Richard Henderson
    { INDEX_op_add_i64, { "r", "0", "re" } },
1926 5d8a4f8f Richard Henderson
    { INDEX_op_mul_i64, { "r", "0", "re" } },
1927 5d8a4f8f Richard Henderson
    { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
1928 5d8a4f8f Richard Henderson
    { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
1929 5d8a4f8f Richard Henderson
    { INDEX_op_sub_i64, { "r", "0", "re" } },
1930 5d8a4f8f Richard Henderson
    { INDEX_op_and_i64, { "r", "0", "reZ" } },
1931 5d8a4f8f Richard Henderson
    { INDEX_op_or_i64, { "r", "0", "re" } },
1932 5d8a4f8f Richard Henderson
    { INDEX_op_xor_i64, { "r", "0", "re" } },
1933 5d8a4f8f Richard Henderson
1934 5d8a4f8f Richard Henderson
    { INDEX_op_shl_i64, { "r", "0", "ci" } },
1935 5d8a4f8f Richard Henderson
    { INDEX_op_shr_i64, { "r", "0", "ci" } },
1936 5d8a4f8f Richard Henderson
    { INDEX_op_sar_i64, { "r", "0", "ci" } },
1937 5d8a4f8f Richard Henderson
    { INDEX_op_rotl_i64, { "r", "0", "ci" } },
1938 5d8a4f8f Richard Henderson
    { INDEX_op_rotr_i64, { "r", "0", "ci" } },
1939 5d8a4f8f Richard Henderson
1940 5d8a4f8f Richard Henderson
    { INDEX_op_brcond_i64, { "r", "re" } },
1941 5d8a4f8f Richard Henderson
    { INDEX_op_setcond_i64, { "r", "r", "re" } },
1942 5d8a4f8f Richard Henderson
1943 5d8a4f8f Richard Henderson
    { INDEX_op_bswap16_i64, { "r", "0" } },
1944 5d8a4f8f Richard Henderson
    { INDEX_op_bswap32_i64, { "r", "0" } },
1945 5d8a4f8f Richard Henderson
    { INDEX_op_bswap64_i64, { "r", "0" } },
1946 5d8a4f8f Richard Henderson
    { INDEX_op_neg_i64, { "r", "0" } },
1947 5d8a4f8f Richard Henderson
    { INDEX_op_not_i64, { "r", "0" } },
1948 5d8a4f8f Richard Henderson
1949 5d8a4f8f Richard Henderson
    { INDEX_op_ext8s_i64, { "r", "r" } },
1950 5d8a4f8f Richard Henderson
    { INDEX_op_ext16s_i64, { "r", "r" } },
1951 5d8a4f8f Richard Henderson
    { INDEX_op_ext32s_i64, { "r", "r" } },
1952 5d8a4f8f Richard Henderson
    { INDEX_op_ext8u_i64, { "r", "r" } },
1953 5d8a4f8f Richard Henderson
    { INDEX_op_ext16u_i64, { "r", "r" } },
1954 5d8a4f8f Richard Henderson
    { INDEX_op_ext32u_i64, { "r", "r" } },
1955 a4773324 Jan Kiszka
1956 a4773324 Jan Kiszka
    { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
1957 d0a16297 Richard Henderson
    { INDEX_op_movcond_i64, { "r", "r", "re", "r", "0" } },
1958 5d8a4f8f Richard Henderson
#endif
1959 1d2699ae Richard Henderson
1960 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1961 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1962 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1963 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1964 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1965 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L" } },
1966 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1967 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld32s, { "r", "L" } },
1968 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_ld64, { "r", "L" } },
1969 5d8a4f8f Richard Henderson
1970 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_st8, { "L", "L" } },
1971 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_st16, { "L", "L" } },
1972 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_st32, { "L", "L" } },
1973 5d8a4f8f Richard Henderson
    { INDEX_op_qemu_st64, { "L", "L" } },
1974 5d8a4f8f Richard Henderson
#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1975 c896fe29 bellard
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1976 c896fe29 bellard
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1977 c896fe29 bellard
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1978 c896fe29 bellard
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1979 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L" } },
1980 c896fe29 bellard
    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1981 c896fe29 bellard
1982 c896fe29 bellard
    { INDEX_op_qemu_st8, { "cb", "L" } },
1983 c896fe29 bellard
    { INDEX_op_qemu_st16, { "L", "L" } },
1984 c896fe29 bellard
    { INDEX_op_qemu_st32, { "L", "L" } },
1985 c896fe29 bellard
    { INDEX_op_qemu_st64, { "L", "L", "L" } },
1986 c896fe29 bellard
#else
1987 c896fe29 bellard
    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1988 c896fe29 bellard
    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1989 c896fe29 bellard
    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1990 c896fe29 bellard
    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1991 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1992 c896fe29 bellard
    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1993 c896fe29 bellard
1994 c896fe29 bellard
    { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1995 c896fe29 bellard
    { INDEX_op_qemu_st16, { "L", "L", "L" } },
1996 c896fe29 bellard
    { INDEX_op_qemu_st32, { "L", "L", "L" } },
1997 c896fe29 bellard
    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1998 c896fe29 bellard
#endif
1999 c896fe29 bellard
    { -1 },
2000 c896fe29 bellard
};
2001 c896fe29 bellard
2002 b03cce8e bellard
static int tcg_target_callee_save_regs[] = {
2003 5d8a4f8f Richard Henderson
#if TCG_TARGET_REG_BITS == 64
2004 5d8a4f8f Richard Henderson
    TCG_REG_RBP,
2005 5d8a4f8f Richard Henderson
    TCG_REG_RBX,
2006 8d918718 Stefan Weil
#if defined(_WIN64)
2007 8d918718 Stefan Weil
    TCG_REG_RDI,
2008 8d918718 Stefan Weil
    TCG_REG_RSI,
2009 8d918718 Stefan Weil
#endif
2010 5d8a4f8f Richard Henderson
    TCG_REG_R12,
2011 5d8a4f8f Richard Henderson
    TCG_REG_R13,
2012 cea5f9a2 Blue Swirl
    TCG_REG_R14, /* Currently used for the global env. */
2013 5d8a4f8f Richard Henderson
    TCG_REG_R15,
2014 5d8a4f8f Richard Henderson
#else
2015 cea5f9a2 Blue Swirl
    TCG_REG_EBP, /* Currently used for the global env. */
2016 b03cce8e bellard
    TCG_REG_EBX,
2017 b03cce8e bellard
    TCG_REG_ESI,
2018 b03cce8e bellard
    TCG_REG_EDI,
2019 5d8a4f8f Richard Henderson
#endif
2020 b03cce8e bellard
};
2021 b03cce8e bellard
2022 813da627 Richard Henderson
/* Compute frame size via macros, to share between tcg_target_qemu_prologue
2023 813da627 Richard Henderson
   and tcg_register_jit.  */
2024 813da627 Richard Henderson
2025 813da627 Richard Henderson
#define PUSH_SIZE \
2026 813da627 Richard Henderson
    ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
2027 813da627 Richard Henderson
     * (TCG_TARGET_REG_BITS / 8))
2028 813da627 Richard Henderson
2029 813da627 Richard Henderson
#define FRAME_SIZE \
2030 813da627 Richard Henderson
    ((PUSH_SIZE \
2031 813da627 Richard Henderson
      + TCG_STATIC_CALL_ARGS_SIZE \
2032 813da627 Richard Henderson
      + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2033 813da627 Richard Henderson
      + TCG_TARGET_STACK_ALIGN - 1) \
2034 813da627 Richard Henderson
     & ~(TCG_TARGET_STACK_ALIGN - 1))
2035 813da627 Richard Henderson
2036 b03cce8e bellard
/* Generate global QEMU prologue and epilogue code */
2037 e4d58b41 Richard Henderson
static void tcg_target_qemu_prologue(TCGContext *s)
2038 b03cce8e bellard
{
2039 813da627 Richard Henderson
    int i, stack_addend;
2040 78686523 Richard Henderson
2041 b03cce8e bellard
    /* TB prologue */
2042 5d8a4f8f Richard Henderson
2043 ac0275dc Blue Swirl
    /* Reserve some stack space, also for TCG temps.  */
2044 813da627 Richard Henderson
    stack_addend = FRAME_SIZE - PUSH_SIZE;
2045 ac0275dc Blue Swirl
    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2046 ac0275dc Blue Swirl
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
2047 ac0275dc Blue Swirl
2048 ac0275dc Blue Swirl
    /* Save all callee saved registers.  */
2049 ac0275dc Blue Swirl
    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2050 ac0275dc Blue Swirl
        tcg_out_push(s, tcg_target_callee_save_regs[i]);
2051 ac0275dc Blue Swirl
    }
2052 ac0275dc Blue Swirl
2053 6a18ae2d Blue Swirl
#if TCG_TARGET_REG_BITS == 32
2054 6a18ae2d Blue Swirl
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
2055 6a18ae2d Blue Swirl
               (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
2056 b18212c6 Stefan Weil
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
2057 b18212c6 Stefan Weil
    /* jmp *tb.  */
2058 b18212c6 Stefan Weil
    tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_ESP,
2059 b18212c6 Stefan Weil
                         (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4
2060 b18212c6 Stefan Weil
                         + stack_addend);
2061 6a18ae2d Blue Swirl
#else
2062 cea5f9a2 Blue Swirl
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2063 6a18ae2d Blue Swirl
    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
2064 5d8a4f8f Richard Henderson
    /* jmp *tb.  */
2065 cea5f9a2 Blue Swirl
    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
2066 b18212c6 Stefan Weil
#endif
2067 78686523 Richard Henderson
2068 b03cce8e bellard
    /* TB epilogue */
2069 b03cce8e bellard
    tb_ret_addr = s->code_ptr;
2070 5d8a4f8f Richard Henderson
2071 e83c80f7 Blue Swirl
    tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
2072 5d8a4f8f Richard Henderson
2073 5d8a4f8f Richard Henderson
    for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
2074 b03cce8e bellard
        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
2075 b03cce8e bellard
    }
2076 5d8a4f8f Richard Henderson
    tcg_out_opc(s, OPC_RET, 0, 0, 0);
2077 b03cce8e bellard
}
2078 b03cce8e bellard
2079 e4d58b41 Richard Henderson
static void tcg_target_init(TCGContext *s)
2080 c896fe29 bellard
{
2081 20cb400d Paul Brook
#if !defined(CONFIG_USER_ONLY)
2082 c896fe29 bellard
    /* fail safe */
2083 c896fe29 bellard
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
2084 c896fe29 bellard
        tcg_abort();
2085 20cb400d Paul Brook
#endif
2086 c896fe29 bellard
2087 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 64) {
2088 5d8a4f8f Richard Henderson
        tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2089 5d8a4f8f Richard Henderson
        tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2090 5d8a4f8f Richard Henderson
    } else {
2091 5d8a4f8f Richard Henderson
        tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
2092 5d8a4f8f Richard Henderson
    }
2093 4ab50ccf Richard Henderson
2094 4ab50ccf Richard Henderson
    tcg_regset_clear(tcg_target_call_clobber_regs);
2095 4ab50ccf Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
2096 4ab50ccf Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
2097 4ab50ccf Richard Henderson
    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
2098 5d8a4f8f Richard Henderson
    if (TCG_TARGET_REG_BITS == 64) {
2099 8d918718 Stefan Weil
#if !defined(_WIN64)
2100 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
2101 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
2102 8d918718 Stefan Weil
#endif
2103 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2104 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2105 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2106 5d8a4f8f Richard Henderson
        tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2107 5d8a4f8f Richard Henderson
    }
2108 4ab50ccf Richard Henderson
2109 c896fe29 bellard
    tcg_regset_clear(s->reserved_regs);
2110 e83c80f7 Blue Swirl
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2111 c896fe29 bellard
2112 c896fe29 bellard
    tcg_add_target_add_op_defs(x86_op_defs);
2113 c896fe29 bellard
}
2114 813da627 Richard Henderson
2115 813da627 Richard Henderson
typedef struct {
2116 813da627 Richard Henderson
    uint32_t len __attribute__((aligned((sizeof(void *)))));
2117 813da627 Richard Henderson
    uint32_t id;
2118 813da627 Richard Henderson
    uint8_t version;
2119 813da627 Richard Henderson
    char augmentation[1];
2120 813da627 Richard Henderson
    uint8_t code_align;
2121 813da627 Richard Henderson
    uint8_t data_align;
2122 813da627 Richard Henderson
    uint8_t return_column;
2123 813da627 Richard Henderson
} DebugFrameCIE;
2124 813da627 Richard Henderson
2125 813da627 Richard Henderson
typedef struct {
2126 813da627 Richard Henderson
    uint32_t len __attribute__((aligned((sizeof(void *)))));
2127 813da627 Richard Henderson
    uint32_t cie_offset;
2128 813da627 Richard Henderson
    tcg_target_long func_start __attribute__((packed));
2129 813da627 Richard Henderson
    tcg_target_long func_len __attribute__((packed));
2130 813da627 Richard Henderson
    uint8_t def_cfa[4];
2131 813da627 Richard Henderson
    uint8_t reg_ofs[14];
2132 813da627 Richard Henderson
} DebugFrameFDE;
2133 813da627 Richard Henderson
2134 813da627 Richard Henderson
typedef struct {
2135 813da627 Richard Henderson
    DebugFrameCIE cie;
2136 813da627 Richard Henderson
    DebugFrameFDE fde;
2137 813da627 Richard Henderson
} DebugFrame;
2138 813da627 Richard Henderson
2139 c170cb66 Stefan Weil
#if !defined(__ELF__)
2140 c170cb66 Stefan Weil
    /* Host machine without ELF. */
2141 c170cb66 Stefan Weil
#elif TCG_TARGET_REG_BITS == 64
2142 813da627 Richard Henderson
#define ELF_HOST_MACHINE EM_X86_64
2143 813da627 Richard Henderson
static DebugFrame debug_frame = {
2144 813da627 Richard Henderson
    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2145 813da627 Richard Henderson
    .cie.id = -1,
2146 813da627 Richard Henderson
    .cie.version = 1,
2147 813da627 Richard Henderson
    .cie.code_align = 1,
2148 813da627 Richard Henderson
    .cie.data_align = 0x78,             /* sleb128 -8 */
2149 813da627 Richard Henderson
    .cie.return_column = 16,
2150 813da627 Richard Henderson
2151 813da627 Richard Henderson
    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
2152 813da627 Richard Henderson
    .fde.def_cfa = {
2153 813da627 Richard Henderson
        12, 7,                          /* DW_CFA_def_cfa %rsp, ... */
2154 813da627 Richard Henderson
        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2155 813da627 Richard Henderson
        (FRAME_SIZE >> 7)
2156 813da627 Richard Henderson
    },
2157 813da627 Richard Henderson
    .fde.reg_ofs = {
2158 813da627 Richard Henderson
        0x90, 1,                        /* DW_CFA_offset, %rip, -8 */
2159 813da627 Richard Henderson
        /* The following ordering must match tcg_target_callee_save_regs.  */
2160 813da627 Richard Henderson
        0x86, 2,                        /* DW_CFA_offset, %rbp, -16 */
2161 813da627 Richard Henderson
        0x83, 3,                        /* DW_CFA_offset, %rbx, -24 */
2162 813da627 Richard Henderson
        0x8c, 4,                        /* DW_CFA_offset, %r12, -32 */
2163 813da627 Richard Henderson
        0x8d, 5,                        /* DW_CFA_offset, %r13, -40 */
2164 813da627 Richard Henderson
        0x8e, 6,                        /* DW_CFA_offset, %r14, -48 */
2165 813da627 Richard Henderson
        0x8f, 7,                        /* DW_CFA_offset, %r15, -56 */
2166 813da627 Richard Henderson
    }
2167 813da627 Richard Henderson
};
2168 813da627 Richard Henderson
#else
2169 813da627 Richard Henderson
#define ELF_HOST_MACHINE EM_386
2170 813da627 Richard Henderson
static DebugFrame debug_frame = {
2171 813da627 Richard Henderson
    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2172 813da627 Richard Henderson
    .cie.id = -1,
2173 813da627 Richard Henderson
    .cie.version = 1,
2174 813da627 Richard Henderson
    .cie.code_align = 1,
2175 813da627 Richard Henderson
    .cie.data_align = 0x7c,             /* sleb128 -4 */
2176 813da627 Richard Henderson
    .cie.return_column = 8,
2177 813da627 Richard Henderson
2178 813da627 Richard Henderson
    .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
2179 813da627 Richard Henderson
    .fde.def_cfa = {
2180 813da627 Richard Henderson
        12, 4,                          /* DW_CFA_def_cfa %esp, ... */
2181 813da627 Richard Henderson
        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2182 813da627 Richard Henderson
        (FRAME_SIZE >> 7)
2183 813da627 Richard Henderson
    },
2184 813da627 Richard Henderson
    .fde.reg_ofs = {
2185 813da627 Richard Henderson
        0x88, 1,                        /* DW_CFA_offset, %eip, -4 */
2186 813da627 Richard Henderson
        /* The following ordering must match tcg_target_callee_save_regs.  */
2187 813da627 Richard Henderson
        0x85, 2,                        /* DW_CFA_offset, %ebp, -8 */
2188 813da627 Richard Henderson
        0x83, 3,                        /* DW_CFA_offset, %ebx, -12 */
2189 813da627 Richard Henderson
        0x86, 4,                        /* DW_CFA_offset, %esi, -16 */
2190 813da627 Richard Henderson
        0x87, 5,                        /* DW_CFA_offset, %edi, -20 */
2191 813da627 Richard Henderson
    }
2192 813da627 Richard Henderson
};
2193 813da627 Richard Henderson
#endif
2194 813da627 Richard Henderson
2195 c170cb66 Stefan Weil
#if defined(ELF_HOST_MACHINE)
2196 813da627 Richard Henderson
void tcg_register_jit(void *buf, size_t buf_size)
2197 813da627 Richard Henderson
{
2198 813da627 Richard Henderson
    /* We're expecting a 2 byte uleb128 encoded value.  */
2199 813da627 Richard Henderson
    assert(FRAME_SIZE >> 14 == 0);
2200 813da627 Richard Henderson
2201 813da627 Richard Henderson
    debug_frame.fde.func_start = (tcg_target_long) buf;
2202 813da627 Richard Henderson
    debug_frame.fde.func_len = buf_size;
2203 813da627 Richard Henderson
2204 813da627 Richard Henderson
    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2205 813da627 Richard Henderson
}
2206 c170cb66 Stefan Weil
#endif