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