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