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