]> git.proxmox.com Git - qemu.git/blame - tcg/i386/tcg-target.c
TCG/x86: use TCG_REG_CALL_STACK instead of TCG_REG_ESP
[qemu.git] / tcg / i386 / tcg-target.c
CommitLineData
c896fe29
FB
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
d4a9eb1f
BS
24
25#ifndef NDEBUG
26static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
5d8a4f8f
RH
27#if TCG_TARGET_REG_BITS == 64
28 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
29 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
30#else
31 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
32#endif
c896fe29 33};
d4a9eb1f 34#endif
c896fe29 35
d4a9eb1f 36static const int tcg_target_reg_alloc_order[] = {
5d8a4f8f
RH
37#if TCG_TARGET_REG_BITS == 64
38 TCG_REG_RBP,
39 TCG_REG_RBX,
40 TCG_REG_R12,
41 TCG_REG_R13,
42 TCG_REG_R14,
43 TCG_REG_R15,
44 TCG_REG_R10,
45 TCG_REG_R11,
46 TCG_REG_R9,
47 TCG_REG_R8,
48 TCG_REG_RCX,
49 TCG_REG_RDX,
50 TCG_REG_RSI,
51 TCG_REG_RDI,
52 TCG_REG_RAX,
53#else
c896fe29
FB
54 TCG_REG_EBX,
55 TCG_REG_ESI,
56 TCG_REG_EDI,
57 TCG_REG_EBP,
6648e296
RH
58 TCG_REG_ECX,
59 TCG_REG_EDX,
60 TCG_REG_EAX,
5d8a4f8f 61#endif
c896fe29
FB
62};
63
5d8a4f8f
RH
64static const int tcg_target_call_iarg_regs[] = {
65#if TCG_TARGET_REG_BITS == 64
66 TCG_REG_RDI,
67 TCG_REG_RSI,
68 TCG_REG_RDX,
69 TCG_REG_RCX,
70 TCG_REG_R8,
71 TCG_REG_R9,
72#else
73 TCG_REG_EAX,
74 TCG_REG_EDX,
75 TCG_REG_ECX
76#endif
77};
78
79static const int tcg_target_call_oarg_regs[2] = {
80 TCG_REG_EAX,
81 TCG_REG_EDX
82};
c896fe29 83
b03cce8e
FB
84static uint8_t *tb_ret_addr;
85
78686523 86static void patch_reloc(uint8_t *code_ptr, int type,
f54b3f92 87 tcg_target_long value, tcg_target_long addend)
c896fe29 88{
f54b3f92 89 value += addend;
c896fe29 90 switch(type) {
c896fe29 91 case R_386_PC32:
5d8a4f8f
RH
92 value -= (uintptr_t)code_ptr;
93 if (value != (int32_t)value) {
94 tcg_abort();
95 }
96 *(uint32_t *)code_ptr = value;
c896fe29 97 break;
f75b56c1 98 case R_386_PC8:
5d8a4f8f 99 value -= (uintptr_t)code_ptr;
f75b56c1
RH
100 if (value != (int8_t)value) {
101 tcg_abort();
102 }
103 *(uint8_t *)code_ptr = value;
104 break;
c896fe29
FB
105 default:
106 tcg_abort();
107 }
108}
109
110/* maximum number of register used for input function arguments */
111static inline int tcg_target_get_call_iarg_regs_count(int flags)
112{
5d8a4f8f
RH
113 if (TCG_TARGET_REG_BITS == 64) {
114 return 6;
115 }
116
c896fe29
FB
117 flags &= TCG_CALL_TYPE_MASK;
118 switch(flags) {
119 case TCG_CALL_TYPE_STD:
120 return 0;
121 case TCG_CALL_TYPE_REGPARM_1:
122 case TCG_CALL_TYPE_REGPARM_2:
123 case TCG_CALL_TYPE_REGPARM:
124 return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
125 default:
126 tcg_abort();
127 }
128}
129
130/* parse target specific constraints */
d4a9eb1f 131static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
c896fe29
FB
132{
133 const char *ct_str;
134
135 ct_str = *pct_str;
136 switch(ct_str[0]) {
137 case 'a':
138 ct->ct |= TCG_CT_REG;
139 tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
140 break;
141 case 'b':
142 ct->ct |= TCG_CT_REG;
143 tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
144 break;
145 case 'c':
146 ct->ct |= TCG_CT_REG;
147 tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
148 break;
149 case 'd':
150 ct->ct |= TCG_CT_REG;
151 tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
152 break;
153 case 'S':
154 ct->ct |= TCG_CT_REG;
155 tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
156 break;
157 case 'D':
158 ct->ct |= TCG_CT_REG;
159 tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
160 break;
161 case 'q':
162 ct->ct |= TCG_CT_REG;
5d8a4f8f
RH
163 if (TCG_TARGET_REG_BITS == 64) {
164 tcg_regset_set32(ct->u.regs, 0, 0xffff);
165 } else {
166 tcg_regset_set32(ct->u.regs, 0, 0xf);
167 }
c896fe29
FB
168 break;
169 case 'r':
170 ct->ct |= TCG_CT_REG;
5d8a4f8f
RH
171 if (TCG_TARGET_REG_BITS == 64) {
172 tcg_regset_set32(ct->u.regs, 0, 0xffff);
173 } else {
174 tcg_regset_set32(ct->u.regs, 0, 0xff);
175 }
c896fe29
FB
176 break;
177
178 /* qemu_ld/st address constraint */
179 case 'L':
180 ct->ct |= TCG_CT_REG;
5d8a4f8f
RH
181 if (TCG_TARGET_REG_BITS == 64) {
182 tcg_regset_set32(ct->u.regs, 0, 0xffff);
183 tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
184 tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
185 } else {
186 tcg_regset_set32(ct->u.regs, 0, 0xff);
187 tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
188 tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
189 }
190 break;
191
192 case 'e':
193 ct->ct |= TCG_CT_CONST_S32;
194 break;
195 case 'Z':
196 ct->ct |= TCG_CT_CONST_U32;
c896fe29 197 break;
5d8a4f8f 198
c896fe29
FB
199 default:
200 return -1;
201 }
202 ct_str++;
203 *pct_str = ct_str;
204 return 0;
205}
206
207/* test if a constant matches the constraint */
208static inline int tcg_target_const_match(tcg_target_long val,
209 const TCGArgConstraint *arg_ct)
210{
5d8a4f8f
RH
211 int ct = arg_ct->ct;
212 if (ct & TCG_CT_CONST) {
c896fe29 213 return 1;
5d8a4f8f
RH
214 }
215 if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
216 return 1;
217 }
218 if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
219 return 1;
220 }
221 return 0;
c896fe29
FB
222}
223
5d8a4f8f
RH
224#if TCG_TARGET_REG_BITS == 64
225# define LOWREGMASK(x) ((x) & 7)
226#else
227# define LOWREGMASK(x) (x)
228#endif
229
96b4cf38
RH
230#define P_EXT 0x100 /* 0x0f opcode prefix */
231#define P_DATA16 0x200 /* 0x66 opcode prefix */
5d8a4f8f
RH
232#if TCG_TARGET_REG_BITS == 64
233# define P_ADDR32 0x400 /* 0x67 opcode prefix */
234# define P_REXW 0x800 /* Set REX.W = 1 */
235# define P_REXB_R 0x1000 /* REG field as byte register */
236# define P_REXB_RM 0x2000 /* R/M field as byte register */
237#else
238# define P_ADDR32 0
239# define P_REXW 0
240# define P_REXB_R 0
241# define P_REXB_RM 0
242#endif
fcb5dac1 243
a369a702
RH
244#define OPC_ARITH_EvIz (0x81)
245#define OPC_ARITH_EvIb (0x83)
81570a70
RH
246#define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
247#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
fcb5dac1 248#define OPC_BSWAP (0xc8 | P_EXT)
aadb21a4 249#define OPC_CALL_Jz (0xe8)
81570a70
RH
250#define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
251#define OPC_DEC_r32 (0x48)
0566d387
RH
252#define OPC_IMUL_GvEv (0xaf | P_EXT)
253#define OPC_IMUL_GvEvIb (0x6b)
254#define OPC_IMUL_GvEvIz (0x69)
81570a70 255#define OPC_INC_r32 (0x40)
da441cff
RH
256#define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
257#define OPC_JCC_short (0x70) /* ... plus condition code */
258#define OPC_JMP_long (0xe9)
259#define OPC_JMP_short (0xeb)
34a6d0b7 260#define OPC_LEA (0x8d)
af266089
RH
261#define OPC_MOVB_EvGv (0x88) /* stores, more or less */
262#define OPC_MOVL_EvGv (0x89) /* stores, more or less */
263#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
5d8a4f8f 264#define OPC_MOVL_EvIz (0xc7)
ef10b106 265#define OPC_MOVL_Iv (0xb8)
6817c355
RH
266#define OPC_MOVSBL (0xbe | P_EXT)
267#define OPC_MOVSWL (0xbf | P_EXT)
5d8a4f8f 268#define OPC_MOVSLQ (0x63 | P_REXW)
55e082a7
RH
269#define OPC_MOVZBL (0xb6 | P_EXT)
270#define OPC_MOVZWL (0xb7 | P_EXT)
6858614e
RH
271#define OPC_POP_r32 (0x58)
272#define OPC_PUSH_r32 (0x50)
273#define OPC_PUSH_Iv (0x68)
274#define OPC_PUSH_Ib (0x6a)
3c3accc6 275#define OPC_RET (0xc3)
5d8a4f8f 276#define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
f53dba01
RH
277#define OPC_SHIFT_1 (0xd1)
278#define OPC_SHIFT_Ib (0xc1)
279#define OPC_SHIFT_cl (0xd3)
81570a70 280#define OPC_TESTL (0x85)
b3e66df7 281#define OPC_XCHG_ax_r32 (0x90)
fcb5dac1 282
9363dedb
RH
283#define OPC_GRP3_Ev (0xf7)
284#define OPC_GRP5 (0xff)
285
286/* Group 1 opcode extensions for 0x80-0x83.
287 These are also used as modifiers for OPC_ARITH. */
c896fe29
FB
288#define ARITH_ADD 0
289#define ARITH_OR 1
290#define ARITH_ADC 2
291#define ARITH_SBB 3
292#define ARITH_AND 4
293#define ARITH_SUB 5
294#define ARITH_XOR 6
295#define ARITH_CMP 7
296
da441cff 297/* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
9619376c
AJ
298#define SHIFT_ROL 0
299#define SHIFT_ROR 1
c896fe29
FB
300#define SHIFT_SHL 4
301#define SHIFT_SHR 5
302#define SHIFT_SAR 7
303
9363dedb
RH
304/* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
305#define EXT3_NOT 2
306#define EXT3_NEG 3
307#define EXT3_MUL 4
308#define EXT3_IMUL 5
309#define EXT3_DIV 6
310#define EXT3_IDIV 7
311
312/* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
5d8a4f8f
RH
313#define EXT5_INC_Ev 0
314#define EXT5_DEC_Ev 1
9363dedb
RH
315#define EXT5_CALLN_Ev 2
316#define EXT5_JMPN_Ev 4
da441cff
RH
317
318/* Condition codes to be added to OPC_JCC_{long,short}. */
c896fe29
FB
319#define JCC_JMP (-1)
320#define JCC_JO 0x0
321#define JCC_JNO 0x1
322#define JCC_JB 0x2
323#define JCC_JAE 0x3
324#define JCC_JE 0x4
325#define JCC_JNE 0x5
326#define JCC_JBE 0x6
327#define JCC_JA 0x7
328#define JCC_JS 0x8
329#define JCC_JNS 0x9
330#define JCC_JP 0xa
331#define JCC_JNP 0xb
332#define JCC_JL 0xc
333#define JCC_JGE 0xd
334#define JCC_JLE 0xe
335#define JCC_JG 0xf
336
c896fe29
FB
337static const uint8_t tcg_cond_to_jcc[10] = {
338 [TCG_COND_EQ] = JCC_JE,
339 [TCG_COND_NE] = JCC_JNE,
340 [TCG_COND_LT] = JCC_JL,
341 [TCG_COND_GE] = JCC_JGE,
342 [TCG_COND_LE] = JCC_JLE,
343 [TCG_COND_GT] = JCC_JG,
344 [TCG_COND_LTU] = JCC_JB,
345 [TCG_COND_GEU] = JCC_JAE,
346 [TCG_COND_LEU] = JCC_JBE,
347 [TCG_COND_GTU] = JCC_JA,
348};
349
5d8a4f8f
RH
350#if TCG_TARGET_REG_BITS == 64
351static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
352{
353 int rex;
354
355 if (opc & P_DATA16) {
356 /* We should never be asking for both 16 and 64-bit operation. */
357 assert((opc & P_REXW) == 0);
358 tcg_out8(s, 0x66);
359 }
360 if (opc & P_ADDR32) {
361 tcg_out8(s, 0x67);
362 }
363
364 rex = 0;
365 rex |= (opc & P_REXW) >> 8; /* REX.W */
366 rex |= (r & 8) >> 1; /* REX.R */
367 rex |= (x & 8) >> 2; /* REX.X */
368 rex |= (rm & 8) >> 3; /* REX.B */
369
370 /* P_REXB_{R,RM} indicates that the given register is the low byte.
371 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
372 as otherwise the encoding indicates %[abcd]h. Note that the values
373 that are ORed in merely indicate that the REX byte must be present;
374 those bits get discarded in output. */
375 rex |= opc & (r >= 4 ? P_REXB_R : 0);
376 rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
377
378 if (rex) {
379 tcg_out8(s, (uint8_t)(rex | 0x40));
380 }
381
382 if (opc & P_EXT) {
383 tcg_out8(s, 0x0f);
384 }
385 tcg_out8(s, opc);
386}
387#else
388static void tcg_out_opc(TCGContext *s, int opc)
c896fe29 389{
96b4cf38
RH
390 if (opc & P_DATA16) {
391 tcg_out8(s, 0x66);
392 }
393 if (opc & P_EXT) {
c896fe29 394 tcg_out8(s, 0x0f);
96b4cf38 395 }
c896fe29
FB
396 tcg_out8(s, opc);
397}
5d8a4f8f
RH
398/* Discard the register arguments to tcg_out_opc early, so as not to penalize
399 the 32-bit compilation paths. This method works with all versions of gcc,
400 whereas relying on optimization may not be able to exclude them. */
401#define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
402#endif
c896fe29 403
5d8a4f8f 404static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
c896fe29 405{
5d8a4f8f
RH
406 tcg_out_opc(s, opc, r, rm, 0);
407 tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
c896fe29
FB
408}
409
34a6d0b7 410/* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
5d8a4f8f
RH
411 We handle either RM and INDEX missing with a negative value. In 64-bit
412 mode for absolute addresses, ~RM is the size of the immediate operand
413 that will follow the instruction. */
34a6d0b7
RH
414
415static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
5d8a4f8f
RH
416 int index, int shift,
417 tcg_target_long offset)
c896fe29 418{
34a6d0b7
RH
419 int mod, len;
420
5d8a4f8f
RH
421 if (index < 0 && rm < 0) {
422 if (TCG_TARGET_REG_BITS == 64) {
423 /* Try for a rip-relative addressing mode. This has replaced
424 the 32-bit-mode absolute addressing encoding. */
425 tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
426 tcg_target_long disp = offset - pc;
427 if (disp == (int32_t)disp) {
428 tcg_out_opc(s, opc, r, 0, 0);
429 tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
430 tcg_out32(s, disp);
431 return;
432 }
34a6d0b7 433
5d8a4f8f
RH
434 /* Try for an absolute address encoding. This requires the
435 use of the MODRM+SIB encoding and is therefore larger than
436 rip-relative addressing. */
437 if (offset == (int32_t)offset) {
438 tcg_out_opc(s, opc, r, 0, 0);
439 tcg_out8(s, (LOWREGMASK(r) << 3) | 4);
440 tcg_out8(s, (4 << 3) | 5);
441 tcg_out32(s, offset);
442 return;
443 }
444
445 /* ??? The memory isn't directly addressable. */
446 tcg_abort();
447 } else {
448 /* Absolute address. */
449 tcg_out_opc(s, opc, r, 0, 0);
450 tcg_out8(s, (r << 3) | 5);
451 tcg_out32(s, offset);
452 return;
453 }
454 }
34a6d0b7
RH
455
456 /* Find the length of the immediate addend. Note that the encoding
457 that would be used for (%ebp) indicates absolute addressing. */
5d8a4f8f 458 if (rm < 0) {
34a6d0b7 459 mod = 0, len = 4, rm = 5;
5d8a4f8f 460 } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) {
34a6d0b7
RH
461 mod = 0, len = 0;
462 } else if (offset == (int8_t)offset) {
463 mod = 0x40, len = 1;
c896fe29 464 } else {
34a6d0b7
RH
465 mod = 0x80, len = 4;
466 }
467
468 /* Use a single byte MODRM format if possible. Note that the encoding
469 that would be used for %esp is the escape to the two byte form. */
5d8a4f8f 470 if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) {
34a6d0b7 471 /* Single byte MODRM format. */
5d8a4f8f
RH
472 tcg_out_opc(s, opc, r, rm, 0);
473 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
34a6d0b7
RH
474 } else {
475 /* Two byte MODRM+SIB format. */
476
477 /* Note that the encoding that would place %esp into the index
5d8a4f8f
RH
478 field indicates no index register. In 64-bit mode, the REX.X
479 bit counts, so %r12 can be used as the index. */
480 if (index < 0) {
34a6d0b7 481 index = 4;
c896fe29 482 } else {
34a6d0b7 483 assert(index != TCG_REG_ESP);
c896fe29 484 }
34a6d0b7 485
5d8a4f8f
RH
486 tcg_out_opc(s, opc, r, rm, index);
487 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4);
488 tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm));
34a6d0b7
RH
489 }
490
491 if (len == 1) {
492 tcg_out8(s, offset);
493 } else if (len == 4) {
c896fe29
FB
494 tcg_out32(s, offset);
495 }
496}
497
5d8a4f8f
RH
498/* A simplification of the above with no index or shift. */
499static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
500 int rm, tcg_target_long offset)
34a6d0b7
RH
501{
502 tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
503}
504
81570a70
RH
505/* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
506static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
507{
5d8a4f8f
RH
508 /* Propagate an opcode prefix, such as P_REXW. */
509 int ext = subop & ~0x7;
510 subop &= 0x7;
511
512 tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
81570a70
RH
513}
514
3b6dac34 515static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
c896fe29 516{
af266089 517 if (arg != ret) {
5d8a4f8f
RH
518 int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
519 tcg_out_modrm(s, opc, ret, arg);
af266089 520 }
c896fe29
FB
521}
522
5d8a4f8f
RH
523static void tcg_out_movi(TCGContext *s, TCGType type,
524 int ret, tcg_target_long arg)
c896fe29
FB
525{
526 if (arg == 0) {
81570a70 527 tgen_arithr(s, ARITH_XOR, ret, ret);
5d8a4f8f
RH
528 return;
529 } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
530 tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
531 tcg_out32(s, arg);
532 } else if (arg == (int32_t)arg) {
533 tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
534 tcg_out32(s, arg);
c896fe29 535 } else {
5d8a4f8f 536 tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
c896fe29 537 tcg_out32(s, arg);
5d8a4f8f 538 tcg_out32(s, arg >> 31 >> 1);
c896fe29
FB
539 }
540}
541
6858614e
RH
542static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
543{
544 if (val == (int8_t)val) {
5d8a4f8f 545 tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
6858614e 546 tcg_out8(s, val);
5d8a4f8f
RH
547 } else if (val == (int32_t)val) {
548 tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
6858614e 549 tcg_out32(s, val);
5d8a4f8f
RH
550 } else {
551 tcg_abort();
6858614e
RH
552 }
553}
554
555static inline void tcg_out_push(TCGContext *s, int reg)
556{
5d8a4f8f 557 tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
6858614e
RH
558}
559
560static inline void tcg_out_pop(TCGContext *s, int reg)
561{
5d8a4f8f 562 tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
6858614e
RH
563}
564
e4d5434c
BS
565static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
566 int arg1, tcg_target_long arg2)
c896fe29 567{
5d8a4f8f
RH
568 int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
569 tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
c896fe29
FB
570}
571
e4d5434c
BS
572static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
573 int arg1, tcg_target_long arg2)
c896fe29 574{
5d8a4f8f
RH
575 int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
576 tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
c896fe29
FB
577}
578
f53dba01
RH
579static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
580{
96b4cf38
RH
581 /* Propagate an opcode prefix, such as P_DATA16. */
582 int ext = subopc & ~0x7;
583 subopc &= 0x7;
584
f53dba01 585 if (count == 1) {
5d8a4f8f 586 tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
f53dba01 587 } else {
5d8a4f8f 588 tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
f53dba01
RH
589 tcg_out8(s, count);
590 }
591}
592
fcb5dac1
RH
593static inline void tcg_out_bswap32(TCGContext *s, int reg)
594{
5d8a4f8f 595 tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
fcb5dac1
RH
596}
597
598static inline void tcg_out_rolw_8(TCGContext *s, int reg)
599{
5d8a4f8f 600 tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
fcb5dac1
RH
601}
602
55e082a7
RH
603static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
604{
605 /* movzbl */
5d8a4f8f
RH
606 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
607 tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
55e082a7
RH
608}
609
5d8a4f8f 610static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
6817c355
RH
611{
612 /* movsbl */
5d8a4f8f
RH
613 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
614 tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
6817c355
RH
615}
616
55e082a7
RH
617static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
618{
619 /* movzwl */
620 tcg_out_modrm(s, OPC_MOVZWL, dest, src);
621}
622
5d8a4f8f 623static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
6817c355 624{
5d8a4f8f
RH
625 /* movsw[lq] */
626 tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
6817c355
RH
627}
628
5d8a4f8f 629static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
c896fe29 630{
5d8a4f8f
RH
631 /* 32-bit mov zero extends. */
632 tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
633}
634
635static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
636{
637 tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
638}
639
640static inline void tcg_out_bswap64(TCGContext *s, int reg)
641{
642 tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
643}
644
645static void tgen_arithi(TCGContext *s, int c, int r0,
646 tcg_target_long val, int cf)
647{
648 int rexw = 0;
649
650 if (TCG_TARGET_REG_BITS == 64) {
651 rexw = c & -8;
652 c &= 7;
653 }
654
81570a70
RH
655 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
656 partial flags update stalls on Pentium4 and are not recommended
657 by current Intel optimization manuals. */
658 if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
447d681e 659 int is_inc = (c == ARITH_ADD) ^ (val < 0);
5d8a4f8f
RH
660 if (TCG_TARGET_REG_BITS == 64) {
661 /* The single-byte increment encodings are re-tasked as the
662 REX prefixes. Use the MODRM encoding. */
663 tcg_out_modrm(s, OPC_GRP5 + rexw,
664 (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
665 } else {
666 tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
667 }
668 return;
669 }
670
671 if (c == ARITH_AND) {
672 if (TCG_TARGET_REG_BITS == 64) {
673 if (val == 0xffffffffu) {
674 tcg_out_ext32u(s, r0, r0);
675 return;
676 }
677 if (val == (uint32_t)val) {
678 /* AND with no high bits set can use a 32-bit operation. */
679 rexw = 0;
680 }
681 }
dc397ca3 682 if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
5d8a4f8f
RH
683 tcg_out_ext8u(s, r0, r0);
684 return;
685 }
686 if (val == 0xffffu) {
687 tcg_out_ext16u(s, r0, r0);
688 return;
689 }
690 }
691
692 if (val == (int8_t)val) {
693 tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
c896fe29 694 tcg_out8(s, val);
5d8a4f8f
RH
695 return;
696 }
697 if (rexw == 0 || val == (int32_t)val) {
698 tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
c896fe29 699 tcg_out32(s, val);
5d8a4f8f 700 return;
c896fe29 701 }
5d8a4f8f
RH
702
703 tcg_abort();
c896fe29
FB
704}
705
3e9a474e 706static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
c896fe29 707{
5d8a4f8f
RH
708 if (val != 0) {
709 tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
710 }
c896fe29
FB
711}
712
f75b56c1
RH
713/* Use SMALL != 0 to force a short forward branch. */
714static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
c896fe29
FB
715{
716 int32_t val, val1;
717 TCGLabel *l = &s->labels[label_index];
78686523 718
c896fe29
FB
719 if (l->has_value) {
720 val = l->u.value - (tcg_target_long)s->code_ptr;
721 val1 = val - 2;
722 if ((int8_t)val1 == val1) {
f75b56c1 723 if (opc == -1) {
da441cff 724 tcg_out8(s, OPC_JMP_short);
f75b56c1 725 } else {
da441cff 726 tcg_out8(s, OPC_JCC_short + opc);
f75b56c1 727 }
c896fe29
FB
728 tcg_out8(s, val1);
729 } else {
f75b56c1
RH
730 if (small) {
731 tcg_abort();
732 }
c896fe29 733 if (opc == -1) {
da441cff 734 tcg_out8(s, OPC_JMP_long);
c896fe29
FB
735 tcg_out32(s, val - 5);
736 } else {
5d8a4f8f 737 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
c896fe29
FB
738 tcg_out32(s, val - 6);
739 }
740 }
f75b56c1
RH
741 } else if (small) {
742 if (opc == -1) {
da441cff 743 tcg_out8(s, OPC_JMP_short);
f75b56c1 744 } else {
da441cff 745 tcg_out8(s, OPC_JCC_short + opc);
f75b56c1
RH
746 }
747 tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
748 s->code_ptr += 1;
c896fe29
FB
749 } else {
750 if (opc == -1) {
da441cff 751 tcg_out8(s, OPC_JMP_long);
c896fe29 752 } else {
5d8a4f8f 753 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
c896fe29
FB
754 }
755 tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
623e265c 756 s->code_ptr += 4;
c896fe29
FB
757 }
758}
759
1d2699ae 760static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
5d8a4f8f 761 int const_arg2, int rexw)
c896fe29 762{
c896fe29
FB
763 if (const_arg2) {
764 if (arg2 == 0) {
c896fe29 765 /* test r, r */
5d8a4f8f 766 tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
c896fe29 767 } else {
5d8a4f8f 768 tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
c896fe29
FB
769 }
770 } else {
5d8a4f8f 771 tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
c896fe29 772 }
1d2699ae
RH
773}
774
5d8a4f8f
RH
775static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
776 TCGArg arg1, TCGArg arg2, int const_arg2,
777 int label_index, int small)
1d2699ae 778{
5d8a4f8f 779 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
f75b56c1 780 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
c896fe29
FB
781}
782
5d8a4f8f
RH
783#if TCG_TARGET_REG_BITS == 64
784static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
785 TCGArg arg1, TCGArg arg2, int const_arg2,
786 int label_index, int small)
787{
788 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
789 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
790}
791#else
c896fe29
FB
792/* XXX: we implement it at the target level to avoid having to
793 handle cross basic blocks temporaries */
f75b56c1
RH
794static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
795 const int *const_args, int small)
c896fe29
FB
796{
797 int label_next;
798 label_next = gen_new_label();
799 switch(args[4]) {
800 case TCG_COND_EQ:
5d8a4f8f
RH
801 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
802 label_next, 1);
803 tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
804 args[5], small);
c896fe29
FB
805 break;
806 case TCG_COND_NE:
5d8a4f8f
RH
807 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
808 args[5], small);
809 tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
810 args[5], small);
c896fe29
FB
811 break;
812 case TCG_COND_LT:
5d8a4f8f
RH
813 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
814 args[5], small);
f75b56c1 815 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
816 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
817 args[5], small);
c896fe29
FB
818 break;
819 case TCG_COND_LE:
5d8a4f8f
RH
820 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
821 args[5], small);
f75b56c1 822 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
823 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
824 args[5], small);
c896fe29
FB
825 break;
826 case TCG_COND_GT:
5d8a4f8f
RH
827 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
828 args[5], small);
f75b56c1 829 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
830 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
831 args[5], small);
c896fe29
FB
832 break;
833 case TCG_COND_GE:
5d8a4f8f
RH
834 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
835 args[5], small);
f75b56c1 836 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
837 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
838 args[5], small);
c896fe29
FB
839 break;
840 case TCG_COND_LTU:
5d8a4f8f
RH
841 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
842 args[5], small);
f75b56c1 843 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
844 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
845 args[5], small);
c896fe29
FB
846 break;
847 case TCG_COND_LEU:
5d8a4f8f
RH
848 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
849 args[5], small);
f75b56c1 850 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
851 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
852 args[5], small);
c896fe29
FB
853 break;
854 case TCG_COND_GTU:
5d8a4f8f
RH
855 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
856 args[5], small);
f75b56c1 857 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
858 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
859 args[5], small);
c896fe29
FB
860 break;
861 case TCG_COND_GEU:
5d8a4f8f
RH
862 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
863 args[5], small);
f75b56c1 864 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
865 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
866 args[5], small);
c896fe29
FB
867 break;
868 default:
869 tcg_abort();
870 }
871 tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
872}
5d8a4f8f 873#endif
c896fe29 874
5d8a4f8f
RH
875static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
876 TCGArg arg1, TCGArg arg2, int const_arg2)
1d2699ae 877{
5d8a4f8f 878 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
32a8ffb9 879 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
a369a702 880 tcg_out_ext8u(s, dest, dest);
1d2699ae
RH
881}
882
5d8a4f8f
RH
883#if TCG_TARGET_REG_BITS == 64
884static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
885 TCGArg arg1, TCGArg arg2, int const_arg2)
886{
887 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
888 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
889 tcg_out_ext8u(s, dest, dest);
890}
891#else
1d2699ae
RH
892static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
893 const int *const_args)
894{
895 TCGArg new_args[6];
896 int label_true, label_over;
897
898 memcpy(new_args, args+1, 5*sizeof(TCGArg));
899
900 if (args[0] == args[1] || args[0] == args[2]
901 || (!const_args[3] && args[0] == args[3])
902 || (!const_args[4] && args[0] == args[4])) {
903 /* When the destination overlaps with one of the argument
904 registers, don't do anything tricky. */
905 label_true = gen_new_label();
906 label_over = gen_new_label();
907
908 new_args[5] = label_true;
909 tcg_out_brcond2(s, new_args, const_args+1, 1);
910
911 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
912 tcg_out_jxx(s, JCC_JMP, label_over, 1);
913 tcg_out_label(s, label_true, (tcg_target_long)s->code_ptr);
914
915 tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
916 tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
917 } else {
918 /* When the destination does not overlap one of the arguments,
919 clear the destination first, jump if cond false, and emit an
920 increment in the true case. This results in smaller code. */
921
922 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
923
924 label_over = gen_new_label();
925 new_args[4] = tcg_invert_cond(new_args[4]);
926 new_args[5] = label_over;
927 tcg_out_brcond2(s, new_args, const_args+1, 1);
928
929 tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
930 tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
931 }
932}
5d8a4f8f
RH
933#endif
934
935static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
936{
937 tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
938
939 if (disp == (int32_t)disp) {
940 tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
941 tcg_out32(s, disp);
942 } else {
943 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
944 tcg_out_modrm(s, OPC_GRP5,
945 call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
946 }
947}
948
949static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
950{
951 tcg_out_branch(s, 1, dest);
952}
1d2699ae 953
5d8a4f8f 954static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
aadb21a4 955{
5d8a4f8f 956 tcg_out_branch(s, 0, dest);
aadb21a4
RH
957}
958
c896fe29 959#if defined(CONFIG_SOFTMMU)
79383c9c
BS
960
961#include "../../softmmu_defs.h"
c896fe29
FB
962
963static void *qemu_ld_helpers[4] = {
964 __ldb_mmu,
965 __ldw_mmu,
966 __ldl_mmu,
967 __ldq_mmu,
968};
969
970static void *qemu_st_helpers[4] = {
971 __stb_mmu,
972 __stw_mmu,
973 __stl_mmu,
974 __stq_mmu,
975};
8516a044
RH
976
977/* Perform the TLB load and compare.
978
979 Inputs:
980 ADDRLO_IDX contains the index into ARGS of the low part of the
981 address; the high part of the address is at ADDR_LOW_IDX+1.
982
983 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
984
985 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
986 This should be offsetof addr_read or addr_write.
987
988 Outputs:
989 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
990 positions of the displacements of forward jumps to the TLB miss case.
991
5d8a4f8f
RH
992 First argument register is loaded with the low part of the address.
993 In the TLB hit case, it has been adjusted as indicated by the TLB
994 and so is a host address. In the TLB miss case, it continues to
995 hold a guest address.
8516a044 996
5d8a4f8f 997 Second argument register is clobbered. */
8516a044 998
c28b14c6
AJ
999static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
1000 int mem_index, int s_bits,
4309a79b 1001 const TCGArg *args,
c28b14c6 1002 uint8_t **label_ptr, int which)
8516a044
RH
1003{
1004 const int addrlo = args[addrlo_idx];
5d8a4f8f
RH
1005 const int r0 = tcg_target_call_iarg_regs[0];
1006 const int r1 = tcg_target_call_iarg_regs[1];
1007 TCGType type = TCG_TYPE_I32;
1008 int rexw = 0;
1009
1010 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
1011 type = TCG_TYPE_I64;
1012 rexw = P_REXW;
1013 }
8516a044 1014
5d8a4f8f
RH
1015 tcg_out_mov(s, type, r1, addrlo);
1016 tcg_out_mov(s, type, r0, addrlo);
8516a044 1017
5d8a4f8f
RH
1018 tcg_out_shifti(s, SHIFT_SHR + rexw, r1,
1019 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
8516a044 1020
5d8a4f8f
RH
1021 tgen_arithi(s, ARITH_AND + rexw, r0,
1022 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
1023 tgen_arithi(s, ARITH_AND + rexw, r1,
1024 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
8516a044 1025
5d8a4f8f 1026 tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
8516a044
RH
1027 offsetof(CPUState, tlb_table[mem_index][0])
1028 + which);
1029
1030 /* cmp 0(r1), r0 */
5d8a4f8f 1031 tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r0, r1, 0);
8516a044 1032
5d8a4f8f 1033 tcg_out_mov(s, type, r0, addrlo);
8516a044
RH
1034
1035 /* jne label1 */
1036 tcg_out8(s, OPC_JCC_short + JCC_JNE);
1037 label_ptr[0] = s->code_ptr;
1038 s->code_ptr++;
1039
5d8a4f8f 1040 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
8516a044
RH
1041 /* cmp 4(r1), addrhi */
1042 tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
1043
1044 /* jne label1 */
1045 tcg_out8(s, OPC_JCC_short + JCC_JNE);
1046 label_ptr[1] = s->code_ptr;
1047 s->code_ptr++;
1048 }
1049
1050 /* TLB Hit. */
1051
1052 /* add addend(r1), r0 */
5d8a4f8f 1053 tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r0, r1,
8516a044
RH
1054 offsetof(CPUTLBEntry, addend) - which);
1055}
c896fe29
FB
1056#endif
1057
be5a4eb7
RH
1058static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
1059 int base, tcg_target_long ofs, int sizeop)
1060{
1061#ifdef TARGET_WORDS_BIGENDIAN
1062 const int bswap = 1;
1063#else
1064 const int bswap = 0;
379f6698 1065#endif
be5a4eb7
RH
1066 switch (sizeop) {
1067 case 0:
be5a4eb7
RH
1068 tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
1069 break;
1070 case 0 | 4:
5d8a4f8f 1071 tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW, datalo, base, ofs);
be5a4eb7
RH
1072 break;
1073 case 1:
be5a4eb7
RH
1074 tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
1075 if (bswap) {
1076 tcg_out_rolw_8(s, datalo);
1077 }
1078 break;
1079 case 1 | 4:
be5a4eb7 1080 if (bswap) {
5d8a4f8f 1081 tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
be5a4eb7 1082 tcg_out_rolw_8(s, datalo);
5d8a4f8f
RH
1083 tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
1084 } else {
1085 tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW, datalo, base, ofs);
be5a4eb7
RH
1086 }
1087 break;
1088 case 2:
1089 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1090 if (bswap) {
1091 tcg_out_bswap32(s, datalo);
1092 }
1093 break;
5d8a4f8f
RH
1094#if TCG_TARGET_REG_BITS == 64
1095 case 2 | 4:
be5a4eb7 1096 if (bswap) {
be5a4eb7 1097 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
5d8a4f8f
RH
1098 tcg_out_bswap32(s, datalo);
1099 tcg_out_ext32s(s, datalo, datalo);
be5a4eb7 1100 } else {
5d8a4f8f 1101 tcg_out_modrm_offset(s, OPC_MOVSLQ, datalo, base, ofs);
be5a4eb7 1102 }
5d8a4f8f
RH
1103 break;
1104#endif
1105 case 3:
1106 if (TCG_TARGET_REG_BITS == 64) {
1107 tcg_out_ld(s, TCG_TYPE_I64, datalo, base, ofs);
1108 if (bswap) {
1109 tcg_out_bswap64(s, datalo);
1110 }
1111 } else {
1112 if (bswap) {
1113 int t = datalo;
1114 datalo = datahi;
1115 datahi = t;
1116 }
1117 if (base != datalo) {
1118 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1119 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1120 } else {
1121 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1122 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1123 }
1124 if (bswap) {
1125 tcg_out_bswap32(s, datalo);
1126 tcg_out_bswap32(s, datahi);
1127 }
be5a4eb7
RH
1128 }
1129 break;
1130 default:
1131 tcg_abort();
1132 }
1133}
379f6698 1134
c896fe29
FB
1135/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1136 EAX. It will be useful once fixed registers globals are less
1137 common. */
1138static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1139 int opc)
1140{
1a6dc1e4 1141 int data_reg, data_reg2 = 0;
8516a044 1142 int addrlo_idx;
c896fe29 1143#if defined(CONFIG_SOFTMMU)
82bb07db 1144 int mem_index, s_bits, arg_idx;
1a6dc1e4 1145 uint8_t *label_ptr[3];
c896fe29
FB
1146#endif
1147
8516a044
RH
1148 data_reg = args[0];
1149 addrlo_idx = 1;
5d8a4f8f 1150 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
8516a044
RH
1151 data_reg2 = args[1];
1152 addrlo_idx = 2;
1a6dc1e4 1153 }
c896fe29
FB
1154
1155#if defined(CONFIG_SOFTMMU)
5d8a4f8f 1156 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
8516a044 1157 s_bits = opc & 3;
1a6dc1e4 1158
8516a044
RH
1159 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1160 label_ptr, offsetof(CPUTLBEntry, addr_read));
1a6dc1e4
RH
1161
1162 /* TLB Hit. */
5d8a4f8f
RH
1163 tcg_out_qemu_ld_direct(s, data_reg, data_reg2,
1164 tcg_target_call_iarg_regs[0], 0, opc);
c896fe29 1165
1a6dc1e4
RH
1166 /* jmp label2 */
1167 tcg_out8(s, OPC_JMP_short);
1168 label_ptr[2] = s->code_ptr;
c896fe29 1169 s->code_ptr++;
78686523 1170
1a6dc1e4
RH
1171 /* TLB Miss. */
1172
1173 /* label1: */
1174 *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
5d8a4f8f 1175 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1a6dc1e4
RH
1176 *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1177 }
c896fe29
FB
1178
1179 /* XXX: move that code at the end of the TB */
5d8a4f8f 1180 /* The first argument is already loaded with addrlo. */
82bb07db 1181 arg_idx = 1;
5d8a4f8f 1182 if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
3b6dac34 1183 tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++],
82bb07db
RH
1184 args[addrlo_idx + 1]);
1185 }
1186 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
1187 mem_index);
aadb21a4 1188 tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
c896fe29
FB
1189
1190 switch(opc) {
1191 case 0 | 4:
5d8a4f8f 1192 tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
c896fe29
FB
1193 break;
1194 case 1 | 4:
5d8a4f8f 1195 tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
c896fe29
FB
1196 break;
1197 case 0:
55e082a7 1198 tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
9db3ba4d 1199 break;
c896fe29 1200 case 1:
55e082a7 1201 tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
9db3ba4d 1202 break;
c896fe29 1203 case 2:
3b6dac34 1204 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
c896fe29 1205 break;
5d8a4f8f
RH
1206#if TCG_TARGET_REG_BITS == 64
1207 case 2 | 4:
1208 tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1209 break;
1210#endif
c896fe29 1211 case 3:
5d8a4f8f
RH
1212 if (TCG_TARGET_REG_BITS == 64) {
1213 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
1214 } else if (data_reg == TCG_REG_EDX) {
b3e66df7 1215 /* xchg %edx, %eax */
5d8a4f8f 1216 tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
3b6dac34 1217 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
c896fe29 1218 } else {
3b6dac34
RH
1219 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1220 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
c896fe29
FB
1221 }
1222 break;
5d8a4f8f
RH
1223 default:
1224 tcg_abort();
c896fe29
FB
1225 }
1226
be5a4eb7 1227 /* label2: */
1a6dc1e4 1228 *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
c896fe29 1229#else
5d8a4f8f
RH
1230 {
1231 int32_t offset = GUEST_BASE;
1232 int base = args[addrlo_idx];
1233
1234 if (TCG_TARGET_REG_BITS == 64) {
1235 /* ??? We assume all operations have left us with register
1236 contents that are zero extended. So far this appears to
1237 be true. If we want to enforce this, we can either do
1238 an explicit zero-extension here, or (if GUEST_BASE == 0)
1239 use the ADDR32 prefix. For now, do nothing. */
1240
1241 if (offset != GUEST_BASE) {
1242 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
1243 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
1244 base = TCG_REG_RDI, offset = 0;
1245 }
1246 }
1247
1248 tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, opc);
1249 }
c896fe29 1250#endif
be5a4eb7 1251}
c896fe29 1252
be5a4eb7
RH
1253static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
1254 int base, tcg_target_long ofs, int sizeop)
1255{
c896fe29 1256#ifdef TARGET_WORDS_BIGENDIAN
be5a4eb7 1257 const int bswap = 1;
c896fe29 1258#else
be5a4eb7 1259 const int bswap = 0;
c896fe29 1260#endif
be5a4eb7
RH
1261 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1262 we could perform the bswap twice to restore the original value
1263 instead of moving to the scratch. But as it is, the L constraint
5d8a4f8f
RH
1264 means that the second argument reg is definitely free here. */
1265 int scratch = tcg_target_call_iarg_regs[1];
be5a4eb7
RH
1266
1267 switch (sizeop) {
c896fe29 1268 case 0:
5d8a4f8f 1269 tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
c896fe29
FB
1270 break;
1271 case 1:
c896fe29 1272 if (bswap) {
3b6dac34 1273 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1274 tcg_out_rolw_8(s, scratch);
1275 datalo = scratch;
c896fe29 1276 }
5d8a4f8f 1277 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16, datalo, base, ofs);
c896fe29
FB
1278 break;
1279 case 2:
c896fe29 1280 if (bswap) {
3b6dac34 1281 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1282 tcg_out_bswap32(s, scratch);
1283 datalo = scratch;
c896fe29 1284 }
be5a4eb7 1285 tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
c896fe29
FB
1286 break;
1287 case 3:
5d8a4f8f
RH
1288 if (TCG_TARGET_REG_BITS == 64) {
1289 if (bswap) {
1290 tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
1291 tcg_out_bswap64(s, scratch);
1292 datalo = scratch;
1293 }
1294 tcg_out_st(s, TCG_TYPE_I64, datalo, base, ofs);
1295 } else if (bswap) {
3b6dac34 1296 tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
be5a4eb7
RH
1297 tcg_out_bswap32(s, scratch);
1298 tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
3b6dac34 1299 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1300 tcg_out_bswap32(s, scratch);
1301 tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
c896fe29 1302 } else {
be5a4eb7
RH
1303 tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1304 tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
c896fe29
FB
1305 }
1306 break;
1307 default:
1308 tcg_abort();
1309 }
c896fe29
FB
1310}
1311
c896fe29
FB
1312static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1313 int opc)
1314{
1a6dc1e4 1315 int data_reg, data_reg2 = 0;
8516a044 1316 int addrlo_idx;
c896fe29 1317#if defined(CONFIG_SOFTMMU)
8516a044 1318 int mem_index, s_bits;
aadb21a4 1319 int stack_adjust;
1a6dc1e4 1320 uint8_t *label_ptr[3];
c896fe29
FB
1321#endif
1322
8516a044
RH
1323 data_reg = args[0];
1324 addrlo_idx = 1;
5d8a4f8f 1325 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
8516a044
RH
1326 data_reg2 = args[1];
1327 addrlo_idx = 2;
1a6dc1e4 1328 }
c896fe29
FB
1329
1330#if defined(CONFIG_SOFTMMU)
5d8a4f8f 1331 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
8516a044 1332 s_bits = opc;
1a6dc1e4 1333
8516a044
RH
1334 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1335 label_ptr, offsetof(CPUTLBEntry, addr_write));
1a6dc1e4
RH
1336
1337 /* TLB Hit. */
5d8a4f8f
RH
1338 tcg_out_qemu_st_direct(s, data_reg, data_reg2,
1339 tcg_target_call_iarg_regs[0], 0, opc);
c896fe29 1340
1a6dc1e4
RH
1341 /* jmp label2 */
1342 tcg_out8(s, OPC_JMP_short);
1343 label_ptr[2] = s->code_ptr;
c896fe29 1344 s->code_ptr++;
78686523 1345
1a6dc1e4
RH
1346 /* TLB Miss. */
1347
1348 /* label1: */
1349 *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
5d8a4f8f 1350 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1a6dc1e4
RH
1351 *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1352 }
c896fe29
FB
1353
1354 /* XXX: move that code at the end of the TB */
5d8a4f8f
RH
1355 if (TCG_TARGET_REG_BITS == 64) {
1356 tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1357 TCG_REG_RSI, data_reg);
1358 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
1359 stack_adjust = 0;
1360 } else if (TARGET_LONG_BITS == 32) {
3b6dac34 1361 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg);
82bb07db 1362 if (opc == 3) {
3b6dac34 1363 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg2);
82bb07db
RH
1364 tcg_out_pushi(s, mem_index);
1365 stack_adjust = 4;
1366 } else {
1367 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
1368 stack_adjust = 0;
c896fe29 1369 }
c896fe29 1370 } else {
82bb07db 1371 if (opc == 3) {
3b6dac34 1372 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
82bb07db
RH
1373 tcg_out_pushi(s, mem_index);
1374 tcg_out_push(s, data_reg2);
1375 tcg_out_push(s, data_reg);
1376 stack_adjust = 12;
1377 } else {
3b6dac34 1378 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
82bb07db
RH
1379 switch(opc) {
1380 case 0:
1381 tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
1382 break;
1383 case 1:
1384 tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
1385 break;
1386 case 2:
3b6dac34 1387 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg);
82bb07db
RH
1388 break;
1389 }
1390 tcg_out_pushi(s, mem_index);
1391 stack_adjust = 4;
c896fe29 1392 }
c896fe29 1393 }
aadb21a4
RH
1394
1395 tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1396
5d8a4f8f 1397 if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
aadb21a4
RH
1398 /* Pop and discard. This is 2 bytes smaller than the add. */
1399 tcg_out_pop(s, TCG_REG_ECX);
1400 } else if (stack_adjust != 0) {
e83c80f7 1401 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
aadb21a4
RH
1402 }
1403
c896fe29 1404 /* label2: */
1a6dc1e4 1405 *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
be5a4eb7 1406#else
5d8a4f8f
RH
1407 {
1408 int32_t offset = GUEST_BASE;
1409 int base = args[addrlo_idx];
1410
1411 if (TCG_TARGET_REG_BITS == 64) {
1412 /* ??? We assume all operations have left us with register
1413 contents that are zero extended. So far this appears to
1414 be true. If we want to enforce this, we can either do
1415 an explicit zero-extension here, or (if GUEST_BASE == 0)
1416 use the ADDR32 prefix. For now, do nothing. */
1417
1418 if (offset != GUEST_BASE) {
1419 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
1420 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
1421 base = TCG_REG_RDI, offset = 0;
1422 }
1423 }
1424
1425 tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, opc);
1426 }
c896fe29
FB
1427#endif
1428}
1429
a9751609 1430static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
c896fe29
FB
1431 const TCGArg *args, const int *const_args)
1432{
5d8a4f8f
RH
1433 int c, rexw = 0;
1434
1435#if TCG_TARGET_REG_BITS == 64
1436# define OP_32_64(x) \
1437 case glue(glue(INDEX_op_, x), _i64): \
1438 rexw = P_REXW; /* FALLTHRU */ \
1439 case glue(glue(INDEX_op_, x), _i32)
1440#else
1441# define OP_32_64(x) \
1442 case glue(glue(INDEX_op_, x), _i32)
1443#endif
78686523 1444
c896fe29
FB
1445 switch(opc) {
1446 case INDEX_op_exit_tb:
5d8a4f8f
RH
1447 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
1448 tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
c896fe29
FB
1449 break;
1450 case INDEX_op_goto_tb:
1451 if (s->tb_jmp_offset) {
1452 /* direct jump method */
da441cff 1453 tcg_out8(s, OPC_JMP_long); /* jmp im */
c896fe29
FB
1454 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1455 tcg_out32(s, 0);
1456 } else {
1457 /* indirect jump method */
9363dedb 1458 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
c896fe29
FB
1459 (tcg_target_long)(s->tb_next + args[0]));
1460 }
1461 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1462 break;
1463 case INDEX_op_call:
1464 if (const_args[0]) {
aadb21a4 1465 tcg_out_calli(s, args[0]);
c896fe29 1466 } else {
aadb21a4 1467 /* call *reg */
9363dedb 1468 tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
c896fe29
FB
1469 }
1470 break;
1471 case INDEX_op_jmp:
1472 if (const_args[0]) {
5d8a4f8f 1473 tcg_out_jmp(s, args[0]);
c896fe29 1474 } else {
da441cff 1475 /* jmp *reg */
9363dedb 1476 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
c896fe29
FB
1477 }
1478 break;
1479 case INDEX_op_br:
f75b56c1 1480 tcg_out_jxx(s, JCC_JMP, args[0], 0);
c896fe29
FB
1481 break;
1482 case INDEX_op_movi_i32:
1483 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1484 break;
5d8a4f8f
RH
1485 OP_32_64(ld8u):
1486 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1487 tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
c896fe29 1488 break;
5d8a4f8f
RH
1489 OP_32_64(ld8s):
1490 tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
c896fe29 1491 break;
5d8a4f8f
RH
1492 OP_32_64(ld16u):
1493 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1494 tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
c896fe29 1495 break;
5d8a4f8f
RH
1496 OP_32_64(ld16s):
1497 tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
c896fe29 1498 break;
5d8a4f8f
RH
1499#if TCG_TARGET_REG_BITS == 64
1500 case INDEX_op_ld32u_i64:
1501#endif
c896fe29 1502 case INDEX_op_ld_i32:
af266089 1503 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
c896fe29 1504 break;
5d8a4f8f
RH
1505
1506 OP_32_64(st8):
1507 tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
1508 args[0], args[1], args[2]);
c896fe29 1509 break;
5d8a4f8f 1510 OP_32_64(st16):
96b4cf38
RH
1511 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1512 args[0], args[1], args[2]);
c896fe29 1513 break;
5d8a4f8f
RH
1514#if TCG_TARGET_REG_BITS == 64
1515 case INDEX_op_st32_i64:
1516#endif
c896fe29 1517 case INDEX_op_st_i32:
af266089 1518 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
c896fe29 1519 break;
5d8a4f8f
RH
1520
1521 OP_32_64(add):
5d1e4e85
RH
1522 /* For 3-operand addition, use LEA. */
1523 if (args[0] != args[1]) {
1524 TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1525
1526 if (const_args[2]) {
1527 c3 = a2, a2 = -1;
1528 } else if (a0 == a2) {
1529 /* Watch out for dest = src + dest, since we've removed
1530 the matching constraint on the add. */
5d8a4f8f 1531 tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
5d1e4e85
RH
1532 break;
1533 }
1534
5d8a4f8f 1535 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
5d1e4e85
RH
1536 break;
1537 }
1538 c = ARITH_ADD;
1539 goto gen_arith;
5d8a4f8f 1540 OP_32_64(sub):
c896fe29
FB
1541 c = ARITH_SUB;
1542 goto gen_arith;
5d8a4f8f 1543 OP_32_64(and):
c896fe29
FB
1544 c = ARITH_AND;
1545 goto gen_arith;
5d8a4f8f 1546 OP_32_64(or):
c896fe29
FB
1547 c = ARITH_OR;
1548 goto gen_arith;
5d8a4f8f 1549 OP_32_64(xor):
c896fe29
FB
1550 c = ARITH_XOR;
1551 goto gen_arith;
c896fe29
FB
1552 gen_arith:
1553 if (const_args[2]) {
5d8a4f8f 1554 tgen_arithi(s, c + rexw, args[0], args[2], 0);
c896fe29 1555 } else {
5d8a4f8f 1556 tgen_arithr(s, c + rexw, args[0], args[2]);
c896fe29
FB
1557 }
1558 break;
5d8a4f8f
RH
1559
1560 OP_32_64(mul):
c896fe29
FB
1561 if (const_args[2]) {
1562 int32_t val;
1563 val = args[2];
1564 if (val == (int8_t)val) {
5d8a4f8f 1565 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
c896fe29
FB
1566 tcg_out8(s, val);
1567 } else {
5d8a4f8f 1568 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
c896fe29
FB
1569 tcg_out32(s, val);
1570 }
1571 } else {
5d8a4f8f 1572 tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
c896fe29
FB
1573 }
1574 break;
5d8a4f8f
RH
1575
1576 OP_32_64(div2):
1577 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
c896fe29 1578 break;
5d8a4f8f
RH
1579 OP_32_64(divu2):
1580 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
c896fe29 1581 break;
5d8a4f8f
RH
1582
1583 OP_32_64(shl):
c896fe29 1584 c = SHIFT_SHL;
5d8a4f8f
RH
1585 goto gen_shift;
1586 OP_32_64(shr):
c896fe29 1587 c = SHIFT_SHR;
5d8a4f8f
RH
1588 goto gen_shift;
1589 OP_32_64(sar):
c896fe29 1590 c = SHIFT_SAR;
5d8a4f8f
RH
1591 goto gen_shift;
1592 OP_32_64(rotl):
9619376c 1593 c = SHIFT_ROL;
5d8a4f8f
RH
1594 goto gen_shift;
1595 OP_32_64(rotr):
9619376c 1596 c = SHIFT_ROR;
5d8a4f8f
RH
1597 goto gen_shift;
1598 gen_shift:
1599 if (const_args[2]) {
1600 tcg_out_shifti(s, c + rexw, args[0], args[2]);
81570a70 1601 } else {
5d8a4f8f 1602 tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
81570a70 1603 }
c896fe29 1604 break;
5d8a4f8f 1605
c896fe29 1606 case INDEX_op_brcond_i32:
5d8a4f8f
RH
1607 tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
1608 args[3], 0);
c896fe29 1609 break;
5d8a4f8f
RH
1610 case INDEX_op_setcond_i32:
1611 tcg_out_setcond32(s, args[3], args[0], args[1],
1612 args[2], const_args[2]);
c896fe29
FB
1613 break;
1614
5d8a4f8f 1615 OP_32_64(bswap16):
fcb5dac1 1616 tcg_out_rolw_8(s, args[0]);
5d40cd63 1617 break;
5d8a4f8f 1618 OP_32_64(bswap32):
fcb5dac1 1619 tcg_out_bswap32(s, args[0]);
9619376c
AJ
1620 break;
1621
5d8a4f8f
RH
1622 OP_32_64(neg):
1623 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
9619376c 1624 break;
5d8a4f8f
RH
1625 OP_32_64(not):
1626 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
9619376c
AJ
1627 break;
1628
5d8a4f8f
RH
1629 OP_32_64(ext8s):
1630 tcg_out_ext8s(s, args[0], args[1], rexw);
9619376c 1631 break;
5d8a4f8f
RH
1632 OP_32_64(ext16s):
1633 tcg_out_ext16s(s, args[0], args[1], rexw);
9619376c 1634 break;
5d8a4f8f 1635 OP_32_64(ext8u):
55e082a7 1636 tcg_out_ext8u(s, args[0], args[1]);
5f0ce17f 1637 break;
5d8a4f8f 1638 OP_32_64(ext16u):
55e082a7 1639 tcg_out_ext16u(s, args[0], args[1]);
5f0ce17f 1640 break;
9619376c 1641
c896fe29
FB
1642 case INDEX_op_qemu_ld8u:
1643 tcg_out_qemu_ld(s, args, 0);
1644 break;
1645 case INDEX_op_qemu_ld8s:
1646 tcg_out_qemu_ld(s, args, 0 | 4);
1647 break;
1648 case INDEX_op_qemu_ld16u:
1649 tcg_out_qemu_ld(s, args, 1);
1650 break;
1651 case INDEX_op_qemu_ld16s:
1652 tcg_out_qemu_ld(s, args, 1 | 4);
1653 break;
5d8a4f8f
RH
1654#if TCG_TARGET_REG_BITS == 64
1655 case INDEX_op_qemu_ld32u:
1656#endif
86feb1c8 1657 case INDEX_op_qemu_ld32:
c896fe29
FB
1658 tcg_out_qemu_ld(s, args, 2);
1659 break;
1660 case INDEX_op_qemu_ld64:
1661 tcg_out_qemu_ld(s, args, 3);
1662 break;
78686523 1663
c896fe29
FB
1664 case INDEX_op_qemu_st8:
1665 tcg_out_qemu_st(s, args, 0);
1666 break;
1667 case INDEX_op_qemu_st16:
1668 tcg_out_qemu_st(s, args, 1);
1669 break;
1670 case INDEX_op_qemu_st32:
1671 tcg_out_qemu_st(s, args, 2);
1672 break;
1673 case INDEX_op_qemu_st64:
1674 tcg_out_qemu_st(s, args, 3);
1675 break;
1676
5d8a4f8f
RH
1677#if TCG_TARGET_REG_BITS == 32
1678 case INDEX_op_brcond2_i32:
1679 tcg_out_brcond2(s, args, const_args, 0);
1680 break;
1681 case INDEX_op_setcond2_i32:
1682 tcg_out_setcond2(s, args, const_args);
1683 break;
1684 case INDEX_op_mulu2_i32:
1685 tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1686 break;
1687 case INDEX_op_add2_i32:
1688 if (const_args[4]) {
1689 tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1690 } else {
1691 tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1692 }
1693 if (const_args[5]) {
1694 tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1695 } else {
1696 tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1697 }
1698 break;
1699 case INDEX_op_sub2_i32:
1700 if (const_args[4]) {
1701 tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1702 } else {
1703 tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1704 }
1705 if (const_args[5]) {
1706 tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1707 } else {
1708 tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1709 }
1710 break;
1711#else /* TCG_TARGET_REG_BITS == 64 */
1712 case INDEX_op_movi_i64:
1713 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1714 break;
1715 case INDEX_op_ld32s_i64:
1716 tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
1717 break;
1718 case INDEX_op_ld_i64:
1719 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1720 break;
1721 case INDEX_op_st_i64:
1722 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1723 break;
1724 case INDEX_op_qemu_ld32s:
1725 tcg_out_qemu_ld(s, args, 2 | 4);
1726 break;
1727
1728 case INDEX_op_brcond_i64:
1729 tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
1730 args[3], 0);
1731 break;
1732 case INDEX_op_setcond_i64:
1733 tcg_out_setcond64(s, args[3], args[0], args[1],
1734 args[2], const_args[2]);
1735 break;
1736
1737 case INDEX_op_bswap64_i64:
1738 tcg_out_bswap64(s, args[0]);
1739 break;
1740 case INDEX_op_ext32u_i64:
1741 tcg_out_ext32u(s, args[0], args[1]);
1742 break;
1743 case INDEX_op_ext32s_i64:
1744 tcg_out_ext32s(s, args[0], args[1]);
1745 break;
1746#endif
1747
c896fe29
FB
1748 default:
1749 tcg_abort();
1750 }
5d8a4f8f
RH
1751
1752#undef OP_32_64
c896fe29
FB
1753}
1754
1755static const TCGTargetOpDef x86_op_defs[] = {
1756 { INDEX_op_exit_tb, { } },
1757 { INDEX_op_goto_tb, { } },
1758 { INDEX_op_call, { "ri" } },
1759 { INDEX_op_jmp, { "ri" } },
1760 { INDEX_op_br, { } },
1761 { INDEX_op_mov_i32, { "r", "r" } },
1762 { INDEX_op_movi_i32, { "r" } },
1763 { INDEX_op_ld8u_i32, { "r", "r" } },
1764 { INDEX_op_ld8s_i32, { "r", "r" } },
1765 { INDEX_op_ld16u_i32, { "r", "r" } },
1766 { INDEX_op_ld16s_i32, { "r", "r" } },
1767 { INDEX_op_ld_i32, { "r", "r" } },
1768 { INDEX_op_st8_i32, { "q", "r" } },
1769 { INDEX_op_st16_i32, { "r", "r" } },
1770 { INDEX_op_st_i32, { "r", "r" } },
1771
5d1e4e85 1772 { INDEX_op_add_i32, { "r", "r", "ri" } },
c896fe29
FB
1773 { INDEX_op_sub_i32, { "r", "0", "ri" } },
1774 { INDEX_op_mul_i32, { "r", "0", "ri" } },
c896fe29
FB
1775 { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1776 { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1777 { INDEX_op_and_i32, { "r", "0", "ri" } },
1778 { INDEX_op_or_i32, { "r", "0", "ri" } },
1779 { INDEX_op_xor_i32, { "r", "0", "ri" } },
1780
1781 { INDEX_op_shl_i32, { "r", "0", "ci" } },
1782 { INDEX_op_shr_i32, { "r", "0", "ci" } },
1783 { INDEX_op_sar_i32, { "r", "0", "ci" } },
9619376c
AJ
1784 { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1785 { INDEX_op_rotr_i32, { "r", "0", "ci" } },
c896fe29
FB
1786
1787 { INDEX_op_brcond_i32, { "r", "ri" } },
1788
5d40cd63 1789 { INDEX_op_bswap16_i32, { "r", "0" } },
66896cb8 1790 { INDEX_op_bswap32_i32, { "r", "0" } },
9619376c
AJ
1791
1792 { INDEX_op_neg_i32, { "r", "0" } },
1793
1794 { INDEX_op_not_i32, { "r", "0" } },
1795
1796 { INDEX_op_ext8s_i32, { "r", "q" } },
1797 { INDEX_op_ext16s_i32, { "r", "r" } },
55e082a7
RH
1798 { INDEX_op_ext8u_i32, { "r", "q" } },
1799 { INDEX_op_ext16u_i32, { "r", "r" } },
9619376c 1800
1d2699ae 1801 { INDEX_op_setcond_i32, { "q", "r", "ri" } },
5d8a4f8f
RH
1802
1803#if TCG_TARGET_REG_BITS == 32
1804 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1805 { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1806 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1807 { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1d2699ae 1808 { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
5d8a4f8f
RH
1809#else
1810 { INDEX_op_mov_i64, { "r", "r" } },
1811 { INDEX_op_movi_i64, { "r" } },
1812 { INDEX_op_ld8u_i64, { "r", "r" } },
1813 { INDEX_op_ld8s_i64, { "r", "r" } },
1814 { INDEX_op_ld16u_i64, { "r", "r" } },
1815 { INDEX_op_ld16s_i64, { "r", "r" } },
1816 { INDEX_op_ld32u_i64, { "r", "r" } },
1817 { INDEX_op_ld32s_i64, { "r", "r" } },
1818 { INDEX_op_ld_i64, { "r", "r" } },
1819 { INDEX_op_st8_i64, { "r", "r" } },
1820 { INDEX_op_st16_i64, { "r", "r" } },
1821 { INDEX_op_st32_i64, { "r", "r" } },
1822 { INDEX_op_st_i64, { "r", "r" } },
1823
1824 { INDEX_op_add_i64, { "r", "0", "re" } },
1825 { INDEX_op_mul_i64, { "r", "0", "re" } },
1826 { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
1827 { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
1828 { INDEX_op_sub_i64, { "r", "0", "re" } },
1829 { INDEX_op_and_i64, { "r", "0", "reZ" } },
1830 { INDEX_op_or_i64, { "r", "0", "re" } },
1831 { INDEX_op_xor_i64, { "r", "0", "re" } },
1832
1833 { INDEX_op_shl_i64, { "r", "0", "ci" } },
1834 { INDEX_op_shr_i64, { "r", "0", "ci" } },
1835 { INDEX_op_sar_i64, { "r", "0", "ci" } },
1836 { INDEX_op_rotl_i64, { "r", "0", "ci" } },
1837 { INDEX_op_rotr_i64, { "r", "0", "ci" } },
1838
1839 { INDEX_op_brcond_i64, { "r", "re" } },
1840 { INDEX_op_setcond_i64, { "r", "r", "re" } },
1841
1842 { INDEX_op_bswap16_i64, { "r", "0" } },
1843 { INDEX_op_bswap32_i64, { "r", "0" } },
1844 { INDEX_op_bswap64_i64, { "r", "0" } },
1845 { INDEX_op_neg_i64, { "r", "0" } },
1846 { INDEX_op_not_i64, { "r", "0" } },
1847
1848 { INDEX_op_ext8s_i64, { "r", "r" } },
1849 { INDEX_op_ext16s_i64, { "r", "r" } },
1850 { INDEX_op_ext32s_i64, { "r", "r" } },
1851 { INDEX_op_ext8u_i64, { "r", "r" } },
1852 { INDEX_op_ext16u_i64, { "r", "r" } },
1853 { INDEX_op_ext32u_i64, { "r", "r" } },
1854#endif
1d2699ae 1855
5d8a4f8f
RH
1856#if TCG_TARGET_REG_BITS == 64
1857 { INDEX_op_qemu_ld8u, { "r", "L" } },
1858 { INDEX_op_qemu_ld8s, { "r", "L" } },
1859 { INDEX_op_qemu_ld16u, { "r", "L" } },
1860 { INDEX_op_qemu_ld16s, { "r", "L" } },
1861 { INDEX_op_qemu_ld32, { "r", "L" } },
1862 { INDEX_op_qemu_ld32u, { "r", "L" } },
1863 { INDEX_op_qemu_ld32s, { "r", "L" } },
1864 { INDEX_op_qemu_ld64, { "r", "L" } },
1865
1866 { INDEX_op_qemu_st8, { "L", "L" } },
1867 { INDEX_op_qemu_st16, { "L", "L" } },
1868 { INDEX_op_qemu_st32, { "L", "L" } },
1869 { INDEX_op_qemu_st64, { "L", "L" } },
1870#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
c896fe29
FB
1871 { INDEX_op_qemu_ld8u, { "r", "L" } },
1872 { INDEX_op_qemu_ld8s, { "r", "L" } },
1873 { INDEX_op_qemu_ld16u, { "r", "L" } },
1874 { INDEX_op_qemu_ld16s, { "r", "L" } },
86feb1c8 1875 { INDEX_op_qemu_ld32, { "r", "L" } },
c896fe29
FB
1876 { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1877
1878 { INDEX_op_qemu_st8, { "cb", "L" } },
1879 { INDEX_op_qemu_st16, { "L", "L" } },
1880 { INDEX_op_qemu_st32, { "L", "L" } },
1881 { INDEX_op_qemu_st64, { "L", "L", "L" } },
1882#else
1883 { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1884 { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1885 { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1886 { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
86feb1c8 1887 { INDEX_op_qemu_ld32, { "r", "L", "L" } },
c896fe29
FB
1888 { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1889
1890 { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1891 { INDEX_op_qemu_st16, { "L", "L", "L" } },
1892 { INDEX_op_qemu_st32, { "L", "L", "L" } },
1893 { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1894#endif
1895 { -1 },
1896};
1897
b03cce8e 1898static int tcg_target_callee_save_regs[] = {
5d8a4f8f
RH
1899#if TCG_TARGET_REG_BITS == 64
1900 TCG_REG_RBP,
1901 TCG_REG_RBX,
1902 TCG_REG_R12,
1903 TCG_REG_R13,
cea5f9a2 1904 TCG_REG_R14, /* Currently used for the global env. */
5d8a4f8f
RH
1905 TCG_REG_R15,
1906#else
cea5f9a2 1907 TCG_REG_EBP, /* Currently used for the global env. */
b03cce8e
FB
1908 TCG_REG_EBX,
1909 TCG_REG_ESI,
1910 TCG_REG_EDI,
5d8a4f8f 1911#endif
b03cce8e
FB
1912};
1913
b03cce8e 1914/* Generate global QEMU prologue and epilogue code */
e4d58b41 1915static void tcg_target_qemu_prologue(TCGContext *s)
b03cce8e
FB
1916{
1917 int i, frame_size, push_size, stack_addend;
78686523 1918
b03cce8e 1919 /* TB prologue */
5d8a4f8f
RH
1920
1921 /* Save all callee saved registers. */
1922 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
b03cce8e
FB
1923 tcg_out_push(s, tcg_target_callee_save_regs[i]);
1924 }
5d8a4f8f
RH
1925
1926 /* Reserve some stack space. */
1927 push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
1928 push_size *= TCG_TARGET_REG_BITS / 8;
1929
b03cce8e 1930 frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
78686523 1931 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
b03cce8e
FB
1932 ~(TCG_TARGET_STACK_ALIGN - 1);
1933 stack_addend = frame_size - push_size;
e83c80f7 1934 tcg_out_addi(s, TCG_REG_CALL_STACK, -stack_addend);
b03cce8e 1935
cea5f9a2
BS
1936 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1937
5d8a4f8f 1938 /* jmp *tb. */
cea5f9a2 1939 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
78686523 1940
b03cce8e
FB
1941 /* TB epilogue */
1942 tb_ret_addr = s->code_ptr;
5d8a4f8f 1943
e83c80f7 1944 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
5d8a4f8f
RH
1945
1946 for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
b03cce8e
FB
1947 tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1948 }
5d8a4f8f 1949 tcg_out_opc(s, OPC_RET, 0, 0, 0);
b03cce8e
FB
1950}
1951
e4d58b41 1952static void tcg_target_init(TCGContext *s)
c896fe29 1953{
20cb400d 1954#if !defined(CONFIG_USER_ONLY)
c896fe29
FB
1955 /* fail safe */
1956 if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1957 tcg_abort();
20cb400d 1958#endif
c896fe29 1959
5d8a4f8f
RH
1960 if (TCG_TARGET_REG_BITS == 64) {
1961 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
1962 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
1963 } else {
1964 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1965 }
4ab50ccf
RH
1966
1967 tcg_regset_clear(tcg_target_call_clobber_regs);
1968 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1969 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1970 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
5d8a4f8f
RH
1971 if (TCG_TARGET_REG_BITS == 64) {
1972 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
1973 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
1974 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
1975 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
1976 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
1977 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
1978 }
4ab50ccf 1979
c896fe29 1980 tcg_regset_clear(s->reserved_regs);
e83c80f7 1981 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
c896fe29
FB
1982
1983 tcg_add_target_add_op_defs(x86_op_defs);
614f104d
BS
1984 tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
1985 CPU_TEMP_BUF_NLONGS * sizeof(long));
c896fe29 1986}