]> Git Repo - qemu.git/blame - tcg/i386/tcg-target.c
pixman: fix warning
[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,
f54b3f92 115 tcg_target_long value, tcg_target_long 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;
b18212c6 193#if TCG_TARGET_REG_BITS == 64
5d8a4f8f 194 tcg_regset_set32(ct->u.regs, 0, 0xffff);
b18212c6 195#else
5d8a4f8f 196 tcg_regset_set32(ct->u.regs, 0, 0xff);
b18212c6 197#endif
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
FB
543{
544 if (arg == 0) {
81570a70 545 tgen_arithr(s, ARITH_XOR, ret, ret);
5d8a4f8f
RH
546 return;
547 } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
548 tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
549 tcg_out32(s, arg);
550 } else if (arg == (int32_t)arg) {
551 tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
552 tcg_out32(s, arg);
c896fe29 553 } else {
5d8a4f8f 554 tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
c896fe29 555 tcg_out32(s, arg);
5d8a4f8f 556 tcg_out32(s, arg >> 31 >> 1);
c896fe29
FB
557 }
558}
559
6858614e
RH
560static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
561{
562 if (val == (int8_t)val) {
5d8a4f8f 563 tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
6858614e 564 tcg_out8(s, val);
5d8a4f8f
RH
565 } else if (val == (int32_t)val) {
566 tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
6858614e 567 tcg_out32(s, val);
5d8a4f8f
RH
568 } else {
569 tcg_abort();
6858614e
RH
570 }
571}
572
573static inline void tcg_out_push(TCGContext *s, int reg)
574{
5d8a4f8f 575 tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
6858614e
RH
576}
577
578static inline void tcg_out_pop(TCGContext *s, int reg)
579{
5d8a4f8f 580 tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
6858614e
RH
581}
582
2a534aff
RH
583static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
584 TCGReg arg1, tcg_target_long arg2)
c896fe29 585{
5d8a4f8f
RH
586 int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
587 tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
c896fe29
FB
588}
589
2a534aff
RH
590static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
591 TCGReg arg1, tcg_target_long arg2)
c896fe29 592{
5d8a4f8f
RH
593 int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
594 tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
c896fe29
FB
595}
596
f53dba01
RH
597static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
598{
96b4cf38
RH
599 /* Propagate an opcode prefix, such as P_DATA16. */
600 int ext = subopc & ~0x7;
601 subopc &= 0x7;
602
f53dba01 603 if (count == 1) {
5d8a4f8f 604 tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
f53dba01 605 } else {
5d8a4f8f 606 tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
f53dba01
RH
607 tcg_out8(s, count);
608 }
609}
610
fcb5dac1
RH
611static inline void tcg_out_bswap32(TCGContext *s, int reg)
612{
5d8a4f8f 613 tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
fcb5dac1
RH
614}
615
616static inline void tcg_out_rolw_8(TCGContext *s, int reg)
617{
5d8a4f8f 618 tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
fcb5dac1
RH
619}
620
55e082a7
RH
621static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
622{
623 /* movzbl */
5d8a4f8f
RH
624 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
625 tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
55e082a7
RH
626}
627
5d8a4f8f 628static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
6817c355
RH
629{
630 /* movsbl */
5d8a4f8f
RH
631 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
632 tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
6817c355
RH
633}
634
55e082a7
RH
635static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
636{
637 /* movzwl */
638 tcg_out_modrm(s, OPC_MOVZWL, dest, src);
639}
640
5d8a4f8f 641static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
6817c355 642{
5d8a4f8f
RH
643 /* movsw[lq] */
644 tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
6817c355
RH
645}
646
5d8a4f8f 647static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
c896fe29 648{
5d8a4f8f
RH
649 /* 32-bit mov zero extends. */
650 tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
651}
652
653static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
654{
655 tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
656}
657
658static inline void tcg_out_bswap64(TCGContext *s, int reg)
659{
660 tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
661}
662
663static void tgen_arithi(TCGContext *s, int c, int r0,
664 tcg_target_long val, int cf)
665{
666 int rexw = 0;
667
668 if (TCG_TARGET_REG_BITS == 64) {
669 rexw = c & -8;
670 c &= 7;
671 }
672
81570a70
RH
673 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
674 partial flags update stalls on Pentium4 and are not recommended
675 by current Intel optimization manuals. */
676 if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
447d681e 677 int is_inc = (c == ARITH_ADD) ^ (val < 0);
5d8a4f8f
RH
678 if (TCG_TARGET_REG_BITS == 64) {
679 /* The single-byte increment encodings are re-tasked as the
680 REX prefixes. Use the MODRM encoding. */
681 tcg_out_modrm(s, OPC_GRP5 + rexw,
682 (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
683 } else {
684 tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
685 }
686 return;
687 }
688
689 if (c == ARITH_AND) {
690 if (TCG_TARGET_REG_BITS == 64) {
691 if (val == 0xffffffffu) {
692 tcg_out_ext32u(s, r0, r0);
693 return;
694 }
695 if (val == (uint32_t)val) {
696 /* AND with no high bits set can use a 32-bit operation. */
697 rexw = 0;
698 }
699 }
dc397ca3 700 if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
5d8a4f8f
RH
701 tcg_out_ext8u(s, r0, r0);
702 return;
703 }
704 if (val == 0xffffu) {
705 tcg_out_ext16u(s, r0, r0);
706 return;
707 }
708 }
709
710 if (val == (int8_t)val) {
711 tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
c896fe29 712 tcg_out8(s, val);
5d8a4f8f
RH
713 return;
714 }
715 if (rexw == 0 || val == (int32_t)val) {
716 tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
c896fe29 717 tcg_out32(s, val);
5d8a4f8f 718 return;
c896fe29 719 }
5d8a4f8f
RH
720
721 tcg_abort();
c896fe29
FB
722}
723
3e9a474e 724static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
c896fe29 725{
5d8a4f8f
RH
726 if (val != 0) {
727 tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
728 }
c896fe29
FB
729}
730
f75b56c1
RH
731/* Use SMALL != 0 to force a short forward branch. */
732static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
c896fe29
FB
733{
734 int32_t val, val1;
735 TCGLabel *l = &s->labels[label_index];
78686523 736
c896fe29
FB
737 if (l->has_value) {
738 val = l->u.value - (tcg_target_long)s->code_ptr;
739 val1 = val - 2;
740 if ((int8_t)val1 == val1) {
f75b56c1 741 if (opc == -1) {
da441cff 742 tcg_out8(s, OPC_JMP_short);
f75b56c1 743 } else {
da441cff 744 tcg_out8(s, OPC_JCC_short + opc);
f75b56c1 745 }
c896fe29
FB
746 tcg_out8(s, val1);
747 } else {
f75b56c1
RH
748 if (small) {
749 tcg_abort();
750 }
c896fe29 751 if (opc == -1) {
da441cff 752 tcg_out8(s, OPC_JMP_long);
c896fe29
FB
753 tcg_out32(s, val - 5);
754 } else {
5d8a4f8f 755 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
c896fe29
FB
756 tcg_out32(s, val - 6);
757 }
758 }
f75b56c1
RH
759 } else if (small) {
760 if (opc == -1) {
da441cff 761 tcg_out8(s, OPC_JMP_short);
f75b56c1 762 } else {
da441cff 763 tcg_out8(s, OPC_JCC_short + opc);
f75b56c1
RH
764 }
765 tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
766 s->code_ptr += 1;
c896fe29
FB
767 } else {
768 if (opc == -1) {
da441cff 769 tcg_out8(s, OPC_JMP_long);
c896fe29 770 } else {
5d8a4f8f 771 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
c896fe29
FB
772 }
773 tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
623e265c 774 s->code_ptr += 4;
c896fe29
FB
775 }
776}
777
1d2699ae 778static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
5d8a4f8f 779 int const_arg2, int rexw)
c896fe29 780{
c896fe29
FB
781 if (const_arg2) {
782 if (arg2 == 0) {
c896fe29 783 /* test r, r */
5d8a4f8f 784 tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
c896fe29 785 } else {
5d8a4f8f 786 tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
c896fe29
FB
787 }
788 } else {
5d8a4f8f 789 tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
c896fe29 790 }
1d2699ae
RH
791}
792
5d8a4f8f
RH
793static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
794 TCGArg arg1, TCGArg arg2, int const_arg2,
795 int label_index, int small)
1d2699ae 796{
5d8a4f8f 797 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
f75b56c1 798 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
c896fe29
FB
799}
800
5d8a4f8f
RH
801#if TCG_TARGET_REG_BITS == 64
802static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
803 TCGArg arg1, TCGArg arg2, int const_arg2,
804 int label_index, int small)
805{
806 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
807 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
808}
809#else
c896fe29
FB
810/* XXX: we implement it at the target level to avoid having to
811 handle cross basic blocks temporaries */
f75b56c1
RH
812static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
813 const int *const_args, int small)
c896fe29
FB
814{
815 int label_next;
816 label_next = gen_new_label();
817 switch(args[4]) {
818 case TCG_COND_EQ:
5d8a4f8f
RH
819 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
820 label_next, 1);
821 tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
822 args[5], small);
c896fe29
FB
823 break;
824 case TCG_COND_NE:
5d8a4f8f
RH
825 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
826 args[5], small);
827 tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
828 args[5], small);
c896fe29
FB
829 break;
830 case TCG_COND_LT:
5d8a4f8f
RH
831 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
832 args[5], small);
f75b56c1 833 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
834 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
835 args[5], small);
c896fe29
FB
836 break;
837 case TCG_COND_LE:
5d8a4f8f
RH
838 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
839 args[5], small);
f75b56c1 840 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
841 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
842 args[5], small);
c896fe29
FB
843 break;
844 case TCG_COND_GT:
5d8a4f8f
RH
845 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
846 args[5], small);
f75b56c1 847 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
848 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
849 args[5], small);
c896fe29
FB
850 break;
851 case TCG_COND_GE:
5d8a4f8f
RH
852 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
853 args[5], small);
f75b56c1 854 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
855 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
856 args[5], small);
c896fe29
FB
857 break;
858 case TCG_COND_LTU:
5d8a4f8f
RH
859 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
860 args[5], small);
f75b56c1 861 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
862 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
863 args[5], small);
c896fe29
FB
864 break;
865 case TCG_COND_LEU:
5d8a4f8f
RH
866 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
867 args[5], small);
f75b56c1 868 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
869 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
870 args[5], small);
c896fe29
FB
871 break;
872 case TCG_COND_GTU:
5d8a4f8f
RH
873 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
874 args[5], small);
f75b56c1 875 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
876 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
877 args[5], small);
c896fe29
FB
878 break;
879 case TCG_COND_GEU:
5d8a4f8f
RH
880 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
881 args[5], small);
f75b56c1 882 tcg_out_jxx(s, JCC_JNE, label_next, 1);
5d8a4f8f
RH
883 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
884 args[5], small);
c896fe29
FB
885 break;
886 default:
887 tcg_abort();
888 }
9d6fca70 889 tcg_out_label(s, label_next, s->code_ptr);
c896fe29 890}
5d8a4f8f 891#endif
c896fe29 892
5d8a4f8f
RH
893static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
894 TCGArg arg1, TCGArg arg2, int const_arg2)
1d2699ae 895{
5d8a4f8f 896 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
32a8ffb9 897 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
a369a702 898 tcg_out_ext8u(s, dest, dest);
1d2699ae
RH
899}
900
5d8a4f8f
RH
901#if TCG_TARGET_REG_BITS == 64
902static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
903 TCGArg arg1, TCGArg arg2, int const_arg2)
904{
905 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
906 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
907 tcg_out_ext8u(s, dest, dest);
908}
909#else
1d2699ae
RH
910static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
911 const int *const_args)
912{
913 TCGArg new_args[6];
914 int label_true, label_over;
915
916 memcpy(new_args, args+1, 5*sizeof(TCGArg));
917
918 if (args[0] == args[1] || args[0] == args[2]
919 || (!const_args[3] && args[0] == args[3])
920 || (!const_args[4] && args[0] == args[4])) {
921 /* When the destination overlaps with one of the argument
922 registers, don't do anything tricky. */
923 label_true = gen_new_label();
924 label_over = gen_new_label();
925
926 new_args[5] = label_true;
927 tcg_out_brcond2(s, new_args, const_args+1, 1);
928
929 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
930 tcg_out_jxx(s, JCC_JMP, label_over, 1);
9d6fca70 931 tcg_out_label(s, label_true, s->code_ptr);
1d2699ae
RH
932
933 tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
9d6fca70 934 tcg_out_label(s, label_over, s->code_ptr);
1d2699ae
RH
935 } else {
936 /* When the destination does not overlap one of the arguments,
937 clear the destination first, jump if cond false, and emit an
938 increment in the true case. This results in smaller code. */
939
940 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
941
942 label_over = gen_new_label();
943 new_args[4] = tcg_invert_cond(new_args[4]);
944 new_args[5] = label_over;
945 tcg_out_brcond2(s, new_args, const_args+1, 1);
946
947 tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
9d6fca70 948 tcg_out_label(s, label_over, s->code_ptr);
1d2699ae
RH
949 }
950}
5d8a4f8f
RH
951#endif
952
d0a16297
RH
953static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
954 TCGArg c1, TCGArg c2, int const_c2,
955 TCGArg v1)
956{
957 tcg_out_cmp(s, c1, c2, const_c2, 0);
76a347e1
RH
958 if (have_cmov) {
959 tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
960 } else {
961 int over = gen_new_label();
962 tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
963 tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
964 tcg_out_label(s, over, s->code_ptr);
965 }
d0a16297
RH
966}
967
968#if TCG_TARGET_REG_BITS == 64
969static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
970 TCGArg c1, TCGArg c2, int const_c2,
971 TCGArg v1)
972{
973 tcg_out_cmp(s, c1, c2, const_c2, P_REXW);
974 tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | P_REXW, dest, v1);
975}
976#endif
977
5d8a4f8f
RH
978static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
979{
980 tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
981
982 if (disp == (int32_t)disp) {
983 tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
984 tcg_out32(s, disp);
985 } else {
986 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
987 tcg_out_modrm(s, OPC_GRP5,
988 call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
989 }
990}
991
992static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
993{
994 tcg_out_branch(s, 1, dest);
995}
1d2699ae 996
5d8a4f8f 997static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
aadb21a4 998{
5d8a4f8f 999 tcg_out_branch(s, 0, dest);
aadb21a4
RH
1000}
1001
c896fe29 1002#if defined(CONFIG_SOFTMMU)
79383c9c 1003
022c62cb 1004#include "exec/softmmu_defs.h"
c896fe29 1005
e141ab52
BS
1006/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1007 int mmu_idx) */
1008static const void *qemu_ld_helpers[4] = {
1009 helper_ldb_mmu,
1010 helper_ldw_mmu,
1011 helper_ldl_mmu,
1012 helper_ldq_mmu,
1013};
1014
1015/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1016 uintxx_t val, int mmu_idx) */
1017static const void *qemu_st_helpers[4] = {
1018 helper_stb_mmu,
1019 helper_stw_mmu,
1020 helper_stl_mmu,
1021 helper_stq_mmu,
1022};
8516a044 1023
b76f0d8c
YL
1024static void add_qemu_ldst_label(TCGContext *s,
1025 int is_ld,
1026 int opc,
1027 int data_reg,
1028 int data_reg2,
1029 int addrlo_reg,
1030 int addrhi_reg,
1031 int mem_index,
1032 uint8_t *raddr,
1033 uint8_t **label_ptr);
1034
8516a044
RH
1035/* Perform the TLB load and compare.
1036
1037 Inputs:
1038 ADDRLO_IDX contains the index into ARGS of the low part of the
1039 address; the high part of the address is at ADDR_LOW_IDX+1.
1040
1041 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1042
1043 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1044 This should be offsetof addr_read or addr_write.
1045
1046 Outputs:
1047 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
1048 positions of the displacements of forward jumps to the TLB miss case.
1049
166792f7 1050 Second argument register is loaded with the low part of the address.
5d8a4f8f
RH
1051 In the TLB hit case, it has been adjusted as indicated by the TLB
1052 and so is a host address. In the TLB miss case, it continues to
1053 hold a guest address.
8516a044 1054
166792f7 1055 First argument register is clobbered. */
8516a044 1056
c28b14c6
AJ
1057static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
1058 int mem_index, int s_bits,
4309a79b 1059 const TCGArg *args,
c28b14c6 1060 uint8_t **label_ptr, int which)
8516a044
RH
1061{
1062 const int addrlo = args[addrlo_idx];
b18212c6
SW
1063 const int r0 = TCG_REG_L0;
1064 const int r1 = TCG_REG_L1;
5d8a4f8f
RH
1065 TCGType type = TCG_TYPE_I32;
1066 int rexw = 0;
1067
1068 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
1069 type = TCG_TYPE_I64;
1070 rexw = P_REXW;
1071 }
8516a044 1072
5d8a4f8f 1073 tcg_out_mov(s, type, r0, addrlo);
166792f7 1074 tcg_out_mov(s, type, r1, addrlo);
8516a044 1075
166792f7 1076 tcg_out_shifti(s, SHIFT_SHR + rexw, r0,
5d8a4f8f 1077 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
8516a044 1078
5d8a4f8f 1079 tgen_arithi(s, ARITH_AND + rexw, r1,
166792f7
AJ
1080 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
1081 tgen_arithi(s, ARITH_AND + rexw, r0,
5d8a4f8f 1082 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
8516a044 1083
166792f7 1084 tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r0, TCG_AREG0, r0, 0,
9349b4f9 1085 offsetof(CPUArchState, tlb_table[mem_index][0])
8516a044
RH
1086 + which);
1087
166792f7
AJ
1088 /* cmp 0(r0), r1 */
1089 tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r1, r0, 0);
8516a044 1090
166792f7 1091 tcg_out_mov(s, type, r1, addrlo);
8516a044 1092
b76f0d8c
YL
1093 /* jne slow_path */
1094 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
8516a044 1095 label_ptr[0] = s->code_ptr;
b76f0d8c 1096 s->code_ptr += 4;
8516a044 1097
5d8a4f8f 1098 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
166792f7
AJ
1099 /* cmp 4(r0), addrhi */
1100 tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r0, 4);
8516a044 1101
b76f0d8c
YL
1102 /* jne slow_path */
1103 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
8516a044 1104 label_ptr[1] = s->code_ptr;
b76f0d8c 1105 s->code_ptr += 4;
8516a044
RH
1106 }
1107
1108 /* TLB Hit. */
1109
166792f7
AJ
1110 /* add addend(r0), r1 */
1111 tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r1, r0,
8516a044
RH
1112 offsetof(CPUTLBEntry, addend) - which);
1113}
44b37ace
RH
1114#elif defined(__x86_64__) && defined(__linux__)
1115# include <asm/prctl.h>
1116# include <sys/prctl.h>
1117
1118int arch_prctl(int code, unsigned long addr);
1119
1120static int guest_base_flags;
1121static inline void setup_guest_base_seg(void)
1122{
1123 if (arch_prctl(ARCH_SET_GS, GUEST_BASE) == 0) {
1124 guest_base_flags = P_GS;
1125 }
1126}
1127#else
1128# define guest_base_flags 0
1129static inline void setup_guest_base_seg(void) { }
1130#endif /* SOFTMMU */
c896fe29 1131
be5a4eb7 1132static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
44b37ace
RH
1133 int base, tcg_target_long ofs, int seg,
1134 int sizeop)
be5a4eb7
RH
1135{
1136#ifdef TARGET_WORDS_BIGENDIAN
1137 const int bswap = 1;
1138#else
1139 const int bswap = 0;
379f6698 1140#endif
be5a4eb7
RH
1141 switch (sizeop) {
1142 case 0:
44b37ace 1143 tcg_out_modrm_offset(s, OPC_MOVZBL + seg, datalo, base, ofs);
be5a4eb7
RH
1144 break;
1145 case 0 | 4:
44b37ace 1146 tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW + seg, datalo, base, ofs);
be5a4eb7
RH
1147 break;
1148 case 1:
44b37ace 1149 tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
be5a4eb7
RH
1150 if (bswap) {
1151 tcg_out_rolw_8(s, datalo);
1152 }
1153 break;
1154 case 1 | 4:
be5a4eb7 1155 if (bswap) {
44b37ace 1156 tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
be5a4eb7 1157 tcg_out_rolw_8(s, datalo);
5d8a4f8f
RH
1158 tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
1159 } else {
44b37ace
RH
1160 tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW + seg,
1161 datalo, base, ofs);
be5a4eb7
RH
1162 }
1163 break;
1164 case 2:
44b37ace 1165 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg, datalo, base, ofs);
be5a4eb7
RH
1166 if (bswap) {
1167 tcg_out_bswap32(s, datalo);
1168 }
1169 break;
5d8a4f8f
RH
1170#if TCG_TARGET_REG_BITS == 64
1171 case 2 | 4:
be5a4eb7 1172 if (bswap) {
44b37ace 1173 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg, datalo, base, ofs);
5d8a4f8f
RH
1174 tcg_out_bswap32(s, datalo);
1175 tcg_out_ext32s(s, datalo, datalo);
be5a4eb7 1176 } else {
44b37ace 1177 tcg_out_modrm_offset(s, OPC_MOVSLQ + seg, datalo, base, ofs);
be5a4eb7 1178 }
5d8a4f8f
RH
1179 break;
1180#endif
1181 case 3:
1182 if (TCG_TARGET_REG_BITS == 64) {
44b37ace
RH
1183 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + P_REXW + seg,
1184 datalo, base, ofs);
5d8a4f8f
RH
1185 if (bswap) {
1186 tcg_out_bswap64(s, datalo);
1187 }
1188 } else {
1189 if (bswap) {
1190 int t = datalo;
1191 datalo = datahi;
1192 datahi = t;
1193 }
1194 if (base != datalo) {
44b37ace
RH
1195 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg,
1196 datalo, base, ofs);
1197 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg,
1198 datahi, base, ofs + 4);
5d8a4f8f 1199 } else {
44b37ace
RH
1200 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg,
1201 datahi, base, ofs + 4);
1202 tcg_out_modrm_offset(s, OPC_MOVL_GvEv + seg,
1203 datalo, base, ofs);
5d8a4f8f
RH
1204 }
1205 if (bswap) {
1206 tcg_out_bswap32(s, datalo);
1207 tcg_out_bswap32(s, datahi);
1208 }
be5a4eb7
RH
1209 }
1210 break;
1211 default:
1212 tcg_abort();
1213 }
1214}
379f6698 1215
c896fe29
FB
1216/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1217 EAX. It will be useful once fixed registers globals are less
1218 common. */
1219static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1220 int opc)
1221{
1a6dc1e4 1222 int data_reg, data_reg2 = 0;
8516a044 1223 int addrlo_idx;
c896fe29 1224#if defined(CONFIG_SOFTMMU)
6a18ae2d 1225 int mem_index, s_bits;
b76f0d8c 1226 uint8_t *label_ptr[2];
c896fe29
FB
1227#endif
1228
8516a044
RH
1229 data_reg = args[0];
1230 addrlo_idx = 1;
5d8a4f8f 1231 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
8516a044
RH
1232 data_reg2 = args[1];
1233 addrlo_idx = 2;
1a6dc1e4 1234 }
c896fe29
FB
1235
1236#if defined(CONFIG_SOFTMMU)
5d8a4f8f 1237 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
8516a044 1238 s_bits = opc & 3;
1a6dc1e4 1239
8516a044
RH
1240 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1241 label_ptr, offsetof(CPUTLBEntry, addr_read));
1a6dc1e4
RH
1242
1243 /* TLB Hit. */
44b37ace 1244 tcg_out_qemu_ld_direct(s, data_reg, data_reg2, TCG_REG_L1, 0, 0, opc);
c896fe29 1245
b76f0d8c
YL
1246 /* Record the current context of a load into ldst label */
1247 add_qemu_ldst_label(s,
1248 1,
1249 opc,
1250 data_reg,
1251 data_reg2,
1252 args[addrlo_idx],
1253 args[addrlo_idx + 1],
1254 mem_index,
1255 s->code_ptr,
1256 label_ptr);
c896fe29 1257#else
5d8a4f8f
RH
1258 {
1259 int32_t offset = GUEST_BASE;
1260 int base = args[addrlo_idx];
44b37ace
RH
1261 int seg = 0;
1262
1263 /* ??? We assume all operations have left us with register contents
1264 that are zero extended. So far this appears to be true. If we
1265 want to enforce this, we can either do an explicit zero-extension
1266 here, or (if GUEST_BASE == 0, or a segment register is in use)
1267 use the ADDR32 prefix. For now, do nothing. */
1268 if (GUEST_BASE && guest_base_flags) {
1269 seg = guest_base_flags;
1270 offset = 0;
1271 } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
1272 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
1273 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
1274 base = TCG_REG_L1;
1275 offset = 0;
5d8a4f8f
RH
1276 }
1277
44b37ace 1278 tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, seg, opc);
5d8a4f8f 1279 }
c896fe29 1280#endif
be5a4eb7 1281}
c896fe29 1282
be5a4eb7 1283static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
44b37ace
RH
1284 int base, tcg_target_long ofs, int seg,
1285 int sizeop)
be5a4eb7 1286{
c896fe29 1287#ifdef TARGET_WORDS_BIGENDIAN
be5a4eb7 1288 const int bswap = 1;
c896fe29 1289#else
be5a4eb7 1290 const int bswap = 0;
c896fe29 1291#endif
be5a4eb7
RH
1292 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1293 we could perform the bswap twice to restore the original value
1294 instead of moving to the scratch. But as it is, the L constraint
166792f7
AJ
1295 means that TCG_REG_L0 is definitely free here. */
1296 const int scratch = TCG_REG_L0;
be5a4eb7
RH
1297
1298 switch (sizeop) {
c896fe29 1299 case 0:
44b37ace
RH
1300 tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg,
1301 datalo, base, ofs);
c896fe29
FB
1302 break;
1303 case 1:
c896fe29 1304 if (bswap) {
3b6dac34 1305 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1306 tcg_out_rolw_8(s, scratch);
1307 datalo = scratch;
c896fe29 1308 }
44b37ace
RH
1309 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16 + seg,
1310 datalo, base, ofs);
c896fe29
FB
1311 break;
1312 case 2:
c896fe29 1313 if (bswap) {
3b6dac34 1314 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1315 tcg_out_bswap32(s, scratch);
1316 datalo = scratch;
c896fe29 1317 }
44b37ace 1318 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, datalo, base, ofs);
c896fe29
FB
1319 break;
1320 case 3:
5d8a4f8f
RH
1321 if (TCG_TARGET_REG_BITS == 64) {
1322 if (bswap) {
1323 tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
1324 tcg_out_bswap64(s, scratch);
1325 datalo = scratch;
1326 }
44b37ace
RH
1327 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_REXW + seg,
1328 datalo, base, ofs);
5d8a4f8f 1329 } else if (bswap) {
3b6dac34 1330 tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
be5a4eb7 1331 tcg_out_bswap32(s, scratch);
44b37ace 1332 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs);
3b6dac34 1333 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7 1334 tcg_out_bswap32(s, scratch);
44b37ace 1335 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs+4);
c896fe29 1336 } else {
44b37ace
RH
1337 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, datalo, base, ofs);
1338 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, datahi, base, ofs+4);
c896fe29
FB
1339 }
1340 break;
1341 default:
1342 tcg_abort();
1343 }
c896fe29
FB
1344}
1345
c896fe29
FB
1346static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1347 int opc)
1348{
1a6dc1e4 1349 int data_reg, data_reg2 = 0;
8516a044 1350 int addrlo_idx;
c896fe29 1351#if defined(CONFIG_SOFTMMU)
8516a044 1352 int mem_index, s_bits;
b76f0d8c 1353 uint8_t *label_ptr[2];
c896fe29
FB
1354#endif
1355
8516a044
RH
1356 data_reg = args[0];
1357 addrlo_idx = 1;
5d8a4f8f 1358 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
8516a044
RH
1359 data_reg2 = args[1];
1360 addrlo_idx = 2;
1a6dc1e4 1361 }
c896fe29
FB
1362
1363#if defined(CONFIG_SOFTMMU)
5d8a4f8f 1364 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
8516a044 1365 s_bits = opc;
1a6dc1e4 1366
8516a044
RH
1367 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1368 label_ptr, offsetof(CPUTLBEntry, addr_write));
1a6dc1e4
RH
1369
1370 /* TLB Hit. */
44b37ace 1371 tcg_out_qemu_st_direct(s, data_reg, data_reg2, TCG_REG_L1, 0, 0, opc);
c896fe29 1372
b76f0d8c
YL
1373 /* Record the current context of a store into ldst label */
1374 add_qemu_ldst_label(s,
1375 0,
1376 opc,
1377 data_reg,
1378 data_reg2,
1379 args[addrlo_idx],
1380 args[addrlo_idx + 1],
1381 mem_index,
1382 s->code_ptr,
1383 label_ptr);
1384#else
1385 {
1386 int32_t offset = GUEST_BASE;
1387 int base = args[addrlo_idx];
1388 int seg = 0;
1389
1390 /* ??? We assume all operations have left us with register contents
1391 that are zero extended. So far this appears to be true. If we
1392 want to enforce this, we can either do an explicit zero-extension
1393 here, or (if GUEST_BASE == 0, or a segment register is in use)
1394 use the ADDR32 prefix. For now, do nothing. */
1395 if (GUEST_BASE && guest_base_flags) {
1396 seg = guest_base_flags;
1397 offset = 0;
1398 } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
1399 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
1400 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
1401 base = TCG_REG_L1;
1402 offset = 0;
1403 }
1404
1405 tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, seg, opc);
1406 }
1407#endif
1408}
1409
1410#if defined(CONFIG_SOFTMMU)
1411/*
1412 * Record the context of a call to the out of line helper code for the slow path
1413 * for a load or store, so that we can later generate the correct helper code
1414 */
1415static void add_qemu_ldst_label(TCGContext *s,
1416 int is_ld,
1417 int opc,
1418 int data_reg,
1419 int data_reg2,
1420 int addrlo_reg,
1421 int addrhi_reg,
1422 int mem_index,
1423 uint8_t *raddr,
1424 uint8_t **label_ptr)
1425{
1426 int idx;
1427 TCGLabelQemuLdst *label;
1428
1429 if (s->nb_qemu_ldst_labels >= TCG_MAX_QEMU_LDST) {
1430 tcg_abort();
1431 }
1432
1433 idx = s->nb_qemu_ldst_labels++;
1434 label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[idx];
1435 label->is_ld = is_ld;
1436 label->opc = opc;
1437 label->datalo_reg = data_reg;
1438 label->datahi_reg = data_reg2;
1439 label->addrlo_reg = addrlo_reg;
1440 label->addrhi_reg = addrhi_reg;
1441 label->mem_index = mem_index;
1442 label->raddr = raddr;
1443 label->label_ptr[0] = label_ptr[0];
1444 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1445 label->label_ptr[1] = label_ptr[1];
1446 }
1447}
1448
1449/*
1450 * Generate code for the slow path for a load at the end of block
1451 */
1452static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
1453{
1454 int s_bits;
1455 int opc = label->opc;
1456 int mem_index = label->mem_index;
1457#if TCG_TARGET_REG_BITS == 32
1458 int stack_adjust;
1459 int addrlo_reg = label->addrlo_reg;
1460 int addrhi_reg = label->addrhi_reg;
1461#endif
1462 int data_reg = label->datalo_reg;
1463 int data_reg2 = label->datahi_reg;
1464 uint8_t *raddr = label->raddr;
1465 uint8_t **label_ptr = &label->label_ptr[0];
1466
1467 s_bits = opc & 3;
1468
1469 /* resolve label address */
1470 *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
1471 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1472 *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
1473 }
1474
1475#if TCG_TARGET_REG_BITS == 32
1476 tcg_out_pushi(s, mem_index);
1477 stack_adjust = 4;
1478 if (TARGET_LONG_BITS == 64) {
1479 tcg_out_push(s, addrhi_reg);
1480 stack_adjust += 4;
1481 }
1482 tcg_out_push(s, addrlo_reg);
1483 stack_adjust += 4;
1484 tcg_out_push(s, TCG_AREG0);
1485 stack_adjust += 4;
1486#else
1487 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
1488 /* The second argument is already loaded with addrlo. */
1489 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
1490#endif
1491
1492 /* Code generation of qemu_ld/st's slow path calling MMU helper
1493
1494 PRE_PROC ...
1495 call MMU helper
1496 jmp POST_PROC (2b) : short forward jump <- GETRA()
1497 jmp next_code (5b) : dummy long backward jump which is never executed
1498 POST_PROC ... : do post-processing <- GETRA() + 7
1499 jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
1500 */
1501
1502 tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
1503
1504 /* Jump to post-processing code */
1a6dc1e4 1505 tcg_out8(s, OPC_JMP_short);
b76f0d8c
YL
1506 tcg_out8(s, 5);
1507 /* Dummy backward jump having information of fast path'pc for MMU helpers */
1508 tcg_out8(s, OPC_JMP_long);
1509 *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
1510 s->code_ptr += 4;
78686523 1511
b76f0d8c
YL
1512#if TCG_TARGET_REG_BITS == 32
1513 if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
1514 /* Pop and discard. This is 2 bytes smaller than the add. */
1515 tcg_out_pop(s, TCG_REG_ECX);
1516 } else if (stack_adjust != 0) {
1517 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
1518 }
1519#endif
1a6dc1e4 1520
b76f0d8c
YL
1521 switch(opc) {
1522 case 0 | 4:
1523 tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
1524 break;
1525 case 1 | 4:
1526 tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
1527 break;
1528 case 0:
1529 tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
1530 break;
1531 case 1:
1532 tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
1533 break;
1534 case 2:
1535 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1536 break;
1537#if TCG_TARGET_REG_BITS == 64
1538 case 2 | 4:
1539 tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1540 break;
1541#endif
1542 case 3:
1543 if (TCG_TARGET_REG_BITS == 64) {
1544 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
1545 } else if (data_reg == TCG_REG_EDX) {
1546 /* xchg %edx, %eax */
1547 tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
1548 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
1549 } else {
1550 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1551 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
1552 }
1553 break;
1554 default:
1555 tcg_abort();
1556 }
1557
1558 /* Jump to the code corresponding to next IR of qemu_st */
1559 tcg_out_jmp(s, (tcg_target_long)raddr);
1560}
1561
1562/*
1563 * Generate code for the slow path for a store at the end of block
1564 */
1565static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
1566{
1567 int s_bits;
1568 int stack_adjust;
1569 int opc = label->opc;
1570 int mem_index = label->mem_index;
1571 int data_reg = label->datalo_reg;
1572#if TCG_TARGET_REG_BITS == 32
1573 int data_reg2 = label->datahi_reg;
1574 int addrlo_reg = label->addrlo_reg;
1575 int addrhi_reg = label->addrhi_reg;
1576#endif
1577 uint8_t *raddr = label->raddr;
1578 uint8_t **label_ptr = &label->label_ptr[0];
1579
1580 s_bits = opc & 3;
1581
1582 /* resolve label address */
1583 *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
5d8a4f8f 1584 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
b76f0d8c 1585 *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
1a6dc1e4 1586 }
c896fe29 1587
6a18ae2d
BS
1588#if TCG_TARGET_REG_BITS == 32
1589 tcg_out_pushi(s, mem_index);
1590 stack_adjust = 4;
1591 if (opc == 3) {
1592 tcg_out_push(s, data_reg2);
1593 stack_adjust += 4;
1594 }
1595 tcg_out_push(s, data_reg);
1596 stack_adjust += 4;
1597 if (TARGET_LONG_BITS == 64) {
b76f0d8c 1598 tcg_out_push(s, addrhi_reg);
6a18ae2d 1599 stack_adjust += 4;
c896fe29 1600 }
b76f0d8c 1601 tcg_out_push(s, addrlo_reg);
6a18ae2d 1602 stack_adjust += 4;
e141ab52
BS
1603 tcg_out_push(s, TCG_AREG0);
1604 stack_adjust += 4;
6a18ae2d 1605#else
166792f7
AJ
1606 tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
1607 /* The second argument is already loaded with addrlo. */
6a18ae2d 1608 tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
166792f7
AJ
1609 tcg_target_call_iarg_regs[2], data_reg);
1610 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], mem_index);
6a18ae2d
BS
1611 stack_adjust = 0;
1612#endif
aadb21a4 1613
b76f0d8c
YL
1614 /* Code generation of qemu_ld/st's slow path calling MMU helper
1615
1616 PRE_PROC ...
1617 call MMU helper
1618 jmp POST_PROC (2b) : short forward jump <- GETRA()
1619 jmp next_code (5b) : dummy long backward jump which is never executed
1620 POST_PROC ... : do post-processing <- GETRA() + 7
1621 jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
1622 */
1623
aadb21a4
RH
1624 tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1625
b76f0d8c
YL
1626 /* Jump to post-processing code */
1627 tcg_out8(s, OPC_JMP_short);
1628 tcg_out8(s, 5);
1629 /* Dummy backward jump having information of fast path'pc for MMU helpers */
1630 tcg_out8(s, OPC_JMP_long);
1631 *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
1632 s->code_ptr += 4;
1633
5d8a4f8f 1634 if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
aadb21a4
RH
1635 /* Pop and discard. This is 2 bytes smaller than the add. */
1636 tcg_out_pop(s, TCG_REG_ECX);
1637 } else if (stack_adjust != 0) {
e83c80f7 1638 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
aadb21a4
RH
1639 }
1640
b76f0d8c
YL
1641 /* Jump to the code corresponding to next IR of qemu_st */
1642 tcg_out_jmp(s, (tcg_target_long)raddr);
1643}
44b37ace 1644
b76f0d8c
YL
1645/*
1646 * Generate TB finalization at the end of block
1647 */
1648void tcg_out_tb_finalize(TCGContext *s)
1649{
1650 int i;
1651 TCGLabelQemuLdst *label;
1652
1653 /* qemu_ld/st slow paths */
1654 for (i = 0; i < s->nb_qemu_ldst_labels; i++) {
1655 label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[i];
1656 if (label->is_ld) {
1657 tcg_out_qemu_ld_slow_path(s, label);
1658 } else {
1659 tcg_out_qemu_st_slow_path(s, label);
5d8a4f8f 1660 }
5d8a4f8f 1661 }
c896fe29 1662}
b76f0d8c 1663#endif /* CONFIG_SOFTMMU */
c896fe29 1664
a9751609 1665static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
c896fe29
FB
1666 const TCGArg *args, const int *const_args)
1667{
5d8a4f8f
RH
1668 int c, rexw = 0;
1669
1670#if TCG_TARGET_REG_BITS == 64
1671# define OP_32_64(x) \
1672 case glue(glue(INDEX_op_, x), _i64): \
1673 rexw = P_REXW; /* FALLTHRU */ \
1674 case glue(glue(INDEX_op_, x), _i32)
1675#else
1676# define OP_32_64(x) \
1677 case glue(glue(INDEX_op_, x), _i32)
1678#endif
78686523 1679
c896fe29
FB
1680 switch(opc) {
1681 case INDEX_op_exit_tb:
5d8a4f8f
RH
1682 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
1683 tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
c896fe29
FB
1684 break;
1685 case INDEX_op_goto_tb:
1686 if (s->tb_jmp_offset) {
1687 /* direct jump method */
da441cff 1688 tcg_out8(s, OPC_JMP_long); /* jmp im */
c896fe29
FB
1689 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1690 tcg_out32(s, 0);
1691 } else {
1692 /* indirect jump method */
9363dedb 1693 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
c896fe29
FB
1694 (tcg_target_long)(s->tb_next + args[0]));
1695 }
1696 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1697 break;
1698 case INDEX_op_call:
1699 if (const_args[0]) {
aadb21a4 1700 tcg_out_calli(s, args[0]);
c896fe29 1701 } else {
aadb21a4 1702 /* call *reg */
9363dedb 1703 tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
c896fe29
FB
1704 }
1705 break;
c896fe29 1706 case INDEX_op_br:
f75b56c1 1707 tcg_out_jxx(s, JCC_JMP, args[0], 0);
c896fe29
FB
1708 break;
1709 case INDEX_op_movi_i32:
1710 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1711 break;
5d8a4f8f
RH
1712 OP_32_64(ld8u):
1713 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1714 tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
c896fe29 1715 break;
5d8a4f8f
RH
1716 OP_32_64(ld8s):
1717 tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
c896fe29 1718 break;
5d8a4f8f
RH
1719 OP_32_64(ld16u):
1720 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1721 tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
c896fe29 1722 break;
5d8a4f8f
RH
1723 OP_32_64(ld16s):
1724 tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
c896fe29 1725 break;
5d8a4f8f
RH
1726#if TCG_TARGET_REG_BITS == 64
1727 case INDEX_op_ld32u_i64:
1728#endif
c896fe29 1729 case INDEX_op_ld_i32:
af266089 1730 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
c896fe29 1731 break;
5d8a4f8f
RH
1732
1733 OP_32_64(st8):
5c2d2a9e
AJ
1734 if (const_args[0]) {
1735 tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
1736 0, args[1], args[2]);
1737 tcg_out8(s, args[0]);
1738 } else {
1739 tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
1740 args[0], args[1], args[2]);
1741 }
c896fe29 1742 break;
5d8a4f8f 1743 OP_32_64(st16):
5c2d2a9e
AJ
1744 if (const_args[0]) {
1745 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
1746 0, args[1], args[2]);
1747 tcg_out16(s, args[0]);
1748 } else {
1749 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1750 args[0], args[1], args[2]);
1751 }
c896fe29 1752 break;
5d8a4f8f
RH
1753#if TCG_TARGET_REG_BITS == 64
1754 case INDEX_op_st32_i64:
1755#endif
c896fe29 1756 case INDEX_op_st_i32:
5c2d2a9e
AJ
1757 if (const_args[0]) {
1758 tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
1759 tcg_out32(s, args[0]);
1760 } else {
1761 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1762 }
c896fe29 1763 break;
5d8a4f8f
RH
1764
1765 OP_32_64(add):
5d1e4e85
RH
1766 /* For 3-operand addition, use LEA. */
1767 if (args[0] != args[1]) {
1768 TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1769
1770 if (const_args[2]) {
1771 c3 = a2, a2 = -1;
1772 } else if (a0 == a2) {
1773 /* Watch out for dest = src + dest, since we've removed
1774 the matching constraint on the add. */
5d8a4f8f 1775 tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
5d1e4e85
RH
1776 break;
1777 }
1778
5d8a4f8f 1779 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
5d1e4e85
RH
1780 break;
1781 }
1782 c = ARITH_ADD;
1783 goto gen_arith;
5d8a4f8f 1784 OP_32_64(sub):
c896fe29
FB
1785 c = ARITH_SUB;
1786 goto gen_arith;
5d8a4f8f 1787 OP_32_64(and):
c896fe29
FB
1788 c = ARITH_AND;
1789 goto gen_arith;
5d8a4f8f 1790 OP_32_64(or):
c896fe29
FB
1791 c = ARITH_OR;
1792 goto gen_arith;
5d8a4f8f 1793 OP_32_64(xor):
c896fe29
FB
1794 c = ARITH_XOR;
1795 goto gen_arith;
c896fe29
FB
1796 gen_arith:
1797 if (const_args[2]) {
5d8a4f8f 1798 tgen_arithi(s, c + rexw, args[0], args[2], 0);
c896fe29 1799 } else {
5d8a4f8f 1800 tgen_arithr(s, c + rexw, args[0], args[2]);
c896fe29
FB
1801 }
1802 break;
5d8a4f8f
RH
1803
1804 OP_32_64(mul):
c896fe29
FB
1805 if (const_args[2]) {
1806 int32_t val;
1807 val = args[2];
1808 if (val == (int8_t)val) {
5d8a4f8f 1809 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
c896fe29
FB
1810 tcg_out8(s, val);
1811 } else {
5d8a4f8f 1812 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
c896fe29
FB
1813 tcg_out32(s, val);
1814 }
1815 } else {
5d8a4f8f 1816 tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
c896fe29
FB
1817 }
1818 break;
5d8a4f8f
RH
1819
1820 OP_32_64(div2):
1821 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
c896fe29 1822 break;
5d8a4f8f
RH
1823 OP_32_64(divu2):
1824 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
c896fe29 1825 break;
5d8a4f8f
RH
1826
1827 OP_32_64(shl):
c896fe29 1828 c = SHIFT_SHL;
5d8a4f8f
RH
1829 goto gen_shift;
1830 OP_32_64(shr):
c896fe29 1831 c = SHIFT_SHR;
5d8a4f8f
RH
1832 goto gen_shift;
1833 OP_32_64(sar):
c896fe29 1834 c = SHIFT_SAR;
5d8a4f8f
RH
1835 goto gen_shift;
1836 OP_32_64(rotl):
9619376c 1837 c = SHIFT_ROL;
5d8a4f8f
RH
1838 goto gen_shift;
1839 OP_32_64(rotr):
9619376c 1840 c = SHIFT_ROR;
5d8a4f8f
RH
1841 goto gen_shift;
1842 gen_shift:
1843 if (const_args[2]) {
1844 tcg_out_shifti(s, c + rexw, args[0], args[2]);
81570a70 1845 } else {
5d8a4f8f 1846 tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
81570a70 1847 }
c896fe29 1848 break;
5d8a4f8f 1849
c896fe29 1850 case INDEX_op_brcond_i32:
5d8a4f8f
RH
1851 tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
1852 args[3], 0);
c896fe29 1853 break;
5d8a4f8f
RH
1854 case INDEX_op_setcond_i32:
1855 tcg_out_setcond32(s, args[3], args[0], args[1],
1856 args[2], const_args[2]);
c896fe29 1857 break;
d0a16297
RH
1858 case INDEX_op_movcond_i32:
1859 tcg_out_movcond32(s, args[5], args[0], args[1],
1860 args[2], const_args[2], args[3]);
1861 break;
c896fe29 1862
5d8a4f8f 1863 OP_32_64(bswap16):
fcb5dac1 1864 tcg_out_rolw_8(s, args[0]);
5d40cd63 1865 break;
5d8a4f8f 1866 OP_32_64(bswap32):
fcb5dac1 1867 tcg_out_bswap32(s, args[0]);
9619376c
AJ
1868 break;
1869
5d8a4f8f
RH
1870 OP_32_64(neg):
1871 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
9619376c 1872 break;
5d8a4f8f
RH
1873 OP_32_64(not):
1874 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
9619376c
AJ
1875 break;
1876
5d8a4f8f
RH
1877 OP_32_64(ext8s):
1878 tcg_out_ext8s(s, args[0], args[1], rexw);
9619376c 1879 break;
5d8a4f8f
RH
1880 OP_32_64(ext16s):
1881 tcg_out_ext16s(s, args[0], args[1], rexw);
9619376c 1882 break;
5d8a4f8f 1883 OP_32_64(ext8u):
55e082a7 1884 tcg_out_ext8u(s, args[0], args[1]);
5f0ce17f 1885 break;
5d8a4f8f 1886 OP_32_64(ext16u):
55e082a7 1887 tcg_out_ext16u(s, args[0], args[1]);
5f0ce17f 1888 break;
9619376c 1889
c896fe29
FB
1890 case INDEX_op_qemu_ld8u:
1891 tcg_out_qemu_ld(s, args, 0);
1892 break;
1893 case INDEX_op_qemu_ld8s:
1894 tcg_out_qemu_ld(s, args, 0 | 4);
1895 break;
1896 case INDEX_op_qemu_ld16u:
1897 tcg_out_qemu_ld(s, args, 1);
1898 break;
1899 case INDEX_op_qemu_ld16s:
1900 tcg_out_qemu_ld(s, args, 1 | 4);
1901 break;
5d8a4f8f
RH
1902#if TCG_TARGET_REG_BITS == 64
1903 case INDEX_op_qemu_ld32u:
1904#endif
86feb1c8 1905 case INDEX_op_qemu_ld32:
c896fe29
FB
1906 tcg_out_qemu_ld(s, args, 2);
1907 break;
1908 case INDEX_op_qemu_ld64:
1909 tcg_out_qemu_ld(s, args, 3);
1910 break;
78686523 1911
c896fe29
FB
1912 case INDEX_op_qemu_st8:
1913 tcg_out_qemu_st(s, args, 0);
1914 break;
1915 case INDEX_op_qemu_st16:
1916 tcg_out_qemu_st(s, args, 1);
1917 break;
1918 case INDEX_op_qemu_st32:
1919 tcg_out_qemu_st(s, args, 2);
1920 break;
1921 case INDEX_op_qemu_st64:
1922 tcg_out_qemu_st(s, args, 3);
1923 break;
1924
5d8a4f8f
RH
1925#if TCG_TARGET_REG_BITS == 32
1926 case INDEX_op_brcond2_i32:
1927 tcg_out_brcond2(s, args, const_args, 0);
1928 break;
1929 case INDEX_op_setcond2_i32:
1930 tcg_out_setcond2(s, args, const_args);
1931 break;
1932 case INDEX_op_mulu2_i32:
1933 tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1934 break;
1935 case INDEX_op_add2_i32:
1936 if (const_args[4]) {
1937 tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1938 } else {
1939 tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1940 }
1941 if (const_args[5]) {
1942 tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1943 } else {
1944 tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1945 }
1946 break;
1947 case INDEX_op_sub2_i32:
1948 if (const_args[4]) {
1949 tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1950 } else {
1951 tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1952 }
1953 if (const_args[5]) {
1954 tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1955 } else {
1956 tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1957 }
1958 break;
1959#else /* TCG_TARGET_REG_BITS == 64 */
1960 case INDEX_op_movi_i64:
1961 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1962 break;
1963 case INDEX_op_ld32s_i64:
1964 tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
1965 break;
1966 case INDEX_op_ld_i64:
1967 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1968 break;
1969 case INDEX_op_st_i64:
5c2d2a9e
AJ
1970 if (const_args[0]) {
1971 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
1972 0, args[1], args[2]);
1973 tcg_out32(s, args[0]);
1974 } else {
1975 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1976 }
5d8a4f8f
RH
1977 break;
1978 case INDEX_op_qemu_ld32s:
1979 tcg_out_qemu_ld(s, args, 2 | 4);
1980 break;
1981
1982 case INDEX_op_brcond_i64:
1983 tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
1984 args[3], 0);
1985 break;
1986 case INDEX_op_setcond_i64:
1987 tcg_out_setcond64(s, args[3], args[0], args[1],
1988 args[2], const_args[2]);
1989 break;
d0a16297
RH
1990 case INDEX_op_movcond_i64:
1991 tcg_out_movcond64(s, args[5], args[0], args[1],
1992 args[2], const_args[2], args[3]);
1993 break;
5d8a4f8f
RH
1994
1995 case INDEX_op_bswap64_i64:
1996 tcg_out_bswap64(s, args[0]);
1997 break;
1998 case INDEX_op_ext32u_i64:
1999 tcg_out_ext32u(s, args[0], args[1]);
2000 break;
2001 case INDEX_op_ext32s_i64:
2002 tcg_out_ext32s(s, args[0], args[1]);
2003 break;
2004#endif
2005
a4773324
JK
2006 OP_32_64(deposit):
2007 if (args[3] == 0 && args[4] == 8) {
2008 /* load bits 0..7 */
2009 tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
2010 args[2], args[0]);
2011 } else if (args[3] == 8 && args[4] == 8) {
2012 /* load bits 8..15 */
2013 tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
2014 } else if (args[3] == 0 && args[4] == 16) {
2015 /* load bits 0..15 */
2016 tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
2017 } else {
2018 tcg_abort();
2019 }
2020 break;
2021
c896fe29
FB
2022 default:
2023 tcg_abort();
2024 }
5d8a4f8f
RH
2025
2026#undef OP_32_64
c896fe29
FB
2027}
2028
2029static const TCGTargetOpDef x86_op_defs[] = {
2030 { INDEX_op_exit_tb, { } },
2031 { INDEX_op_goto_tb, { } },
2032 { INDEX_op_call, { "ri" } },
c896fe29
FB
2033 { INDEX_op_br, { } },
2034 { INDEX_op_mov_i32, { "r", "r" } },
2035 { INDEX_op_movi_i32, { "r" } },
2036 { INDEX_op_ld8u_i32, { "r", "r" } },
2037 { INDEX_op_ld8s_i32, { "r", "r" } },
2038 { INDEX_op_ld16u_i32, { "r", "r" } },
2039 { INDEX_op_ld16s_i32, { "r", "r" } },
2040 { INDEX_op_ld_i32, { "r", "r" } },
5c2d2a9e
AJ
2041 { INDEX_op_st8_i32, { "qi", "r" } },
2042 { INDEX_op_st16_i32, { "ri", "r" } },
2043 { INDEX_op_st_i32, { "ri", "r" } },
c896fe29 2044
5d1e4e85 2045 { INDEX_op_add_i32, { "r", "r", "ri" } },
c896fe29
FB
2046 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2047 { INDEX_op_mul_i32, { "r", "0", "ri" } },
c896fe29
FB
2048 { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
2049 { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
2050 { INDEX_op_and_i32, { "r", "0", "ri" } },
2051 { INDEX_op_or_i32, { "r", "0", "ri" } },
2052 { INDEX_op_xor_i32, { "r", "0", "ri" } },
2053
2054 { INDEX_op_shl_i32, { "r", "0", "ci" } },
2055 { INDEX_op_shr_i32, { "r", "0", "ci" } },
2056 { INDEX_op_sar_i32, { "r", "0", "ci" } },
9619376c
AJ
2057 { INDEX_op_rotl_i32, { "r", "0", "ci" } },
2058 { INDEX_op_rotr_i32, { "r", "0", "ci" } },
c896fe29
FB
2059
2060 { INDEX_op_brcond_i32, { "r", "ri" } },
2061
5d40cd63 2062 { INDEX_op_bswap16_i32, { "r", "0" } },
66896cb8 2063 { INDEX_op_bswap32_i32, { "r", "0" } },
9619376c
AJ
2064
2065 { INDEX_op_neg_i32, { "r", "0" } },
2066
2067 { INDEX_op_not_i32, { "r", "0" } },
2068
2069 { INDEX_op_ext8s_i32, { "r", "q" } },
2070 { INDEX_op_ext16s_i32, { "r", "r" } },
55e082a7
RH
2071 { INDEX_op_ext8u_i32, { "r", "q" } },
2072 { INDEX_op_ext16u_i32, { "r", "r" } },
9619376c 2073
1d2699ae 2074 { INDEX_op_setcond_i32, { "q", "r", "ri" } },
5d8a4f8f 2075
a4773324 2076 { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
f813cb83 2077#if TCG_TARGET_HAS_movcond_i32
d0a16297 2078 { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
f813cb83 2079#endif
a4773324 2080
5d8a4f8f
RH
2081#if TCG_TARGET_REG_BITS == 32
2082 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
2083 { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
2084 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
2085 { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1d2699ae 2086 { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
5d8a4f8f
RH
2087#else
2088 { INDEX_op_mov_i64, { "r", "r" } },
2089 { INDEX_op_movi_i64, { "r" } },
2090 { INDEX_op_ld8u_i64, { "r", "r" } },
2091 { INDEX_op_ld8s_i64, { "r", "r" } },
2092 { INDEX_op_ld16u_i64, { "r", "r" } },
2093 { INDEX_op_ld16s_i64, { "r", "r" } },
2094 { INDEX_op_ld32u_i64, { "r", "r" } },
2095 { INDEX_op_ld32s_i64, { "r", "r" } },
2096 { INDEX_op_ld_i64, { "r", "r" } },
5c2d2a9e
AJ
2097 { INDEX_op_st8_i64, { "ri", "r" } },
2098 { INDEX_op_st16_i64, { "ri", "r" } },
2099 { INDEX_op_st32_i64, { "ri", "r" } },
2100 { INDEX_op_st_i64, { "re", "r" } },
5d8a4f8f
RH
2101
2102 { INDEX_op_add_i64, { "r", "0", "re" } },
2103 { INDEX_op_mul_i64, { "r", "0", "re" } },
2104 { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
2105 { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
2106 { INDEX_op_sub_i64, { "r", "0", "re" } },
2107 { INDEX_op_and_i64, { "r", "0", "reZ" } },
2108 { INDEX_op_or_i64, { "r", "0", "re" } },
2109 { INDEX_op_xor_i64, { "r", "0", "re" } },
2110
2111 { INDEX_op_shl_i64, { "r", "0", "ci" } },
2112 { INDEX_op_shr_i64, { "r", "0", "ci" } },
2113 { INDEX_op_sar_i64, { "r", "0", "ci" } },
2114 { INDEX_op_rotl_i64, { "r", "0", "ci" } },
2115 { INDEX_op_rotr_i64, { "r", "0", "ci" } },
2116
2117 { INDEX_op_brcond_i64, { "r", "re" } },
2118 { INDEX_op_setcond_i64, { "r", "r", "re" } },
2119
2120 { INDEX_op_bswap16_i64, { "r", "0" } },
2121 { INDEX_op_bswap32_i64, { "r", "0" } },
2122 { INDEX_op_bswap64_i64, { "r", "0" } },
2123 { INDEX_op_neg_i64, { "r", "0" } },
2124 { INDEX_op_not_i64, { "r", "0" } },
2125
2126 { INDEX_op_ext8s_i64, { "r", "r" } },
2127 { INDEX_op_ext16s_i64, { "r", "r" } },
2128 { INDEX_op_ext32s_i64, { "r", "r" } },
2129 { INDEX_op_ext8u_i64, { "r", "r" } },
2130 { INDEX_op_ext16u_i64, { "r", "r" } },
2131 { INDEX_op_ext32u_i64, { "r", "r" } },
a4773324
JK
2132
2133 { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
d0a16297 2134 { INDEX_op_movcond_i64, { "r", "r", "re", "r", "0" } },
5d8a4f8f 2135#endif
1d2699ae 2136
5d8a4f8f
RH
2137#if TCG_TARGET_REG_BITS == 64
2138 { INDEX_op_qemu_ld8u, { "r", "L" } },
2139 { INDEX_op_qemu_ld8s, { "r", "L" } },
2140 { INDEX_op_qemu_ld16u, { "r", "L" } },
2141 { INDEX_op_qemu_ld16s, { "r", "L" } },
2142 { INDEX_op_qemu_ld32, { "r", "L" } },
2143 { INDEX_op_qemu_ld32u, { "r", "L" } },
2144 { INDEX_op_qemu_ld32s, { "r", "L" } },
2145 { INDEX_op_qemu_ld64, { "r", "L" } },
2146
2147 { INDEX_op_qemu_st8, { "L", "L" } },
2148 { INDEX_op_qemu_st16, { "L", "L" } },
2149 { INDEX_op_qemu_st32, { "L", "L" } },
2150 { INDEX_op_qemu_st64, { "L", "L" } },
2151#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
c896fe29
FB
2152 { INDEX_op_qemu_ld8u, { "r", "L" } },
2153 { INDEX_op_qemu_ld8s, { "r", "L" } },
2154 { INDEX_op_qemu_ld16u, { "r", "L" } },
2155 { INDEX_op_qemu_ld16s, { "r", "L" } },
86feb1c8 2156 { INDEX_op_qemu_ld32, { "r", "L" } },
c896fe29
FB
2157 { INDEX_op_qemu_ld64, { "r", "r", "L" } },
2158
2159 { INDEX_op_qemu_st8, { "cb", "L" } },
2160 { INDEX_op_qemu_st16, { "L", "L" } },
2161 { INDEX_op_qemu_st32, { "L", "L" } },
2162 { INDEX_op_qemu_st64, { "L", "L", "L" } },
2163#else
2164 { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
2165 { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
2166 { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
2167 { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
86feb1c8 2168 { INDEX_op_qemu_ld32, { "r", "L", "L" } },
c896fe29
FB
2169 { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
2170
2171 { INDEX_op_qemu_st8, { "cb", "L", "L" } },
2172 { INDEX_op_qemu_st16, { "L", "L", "L" } },
2173 { INDEX_op_qemu_st32, { "L", "L", "L" } },
2174 { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
2175#endif
2176 { -1 },
2177};
2178
b03cce8e 2179static int tcg_target_callee_save_regs[] = {
5d8a4f8f
RH
2180#if TCG_TARGET_REG_BITS == 64
2181 TCG_REG_RBP,
2182 TCG_REG_RBX,
8d918718
SW
2183#if defined(_WIN64)
2184 TCG_REG_RDI,
2185 TCG_REG_RSI,
2186#endif
5d8a4f8f
RH
2187 TCG_REG_R12,
2188 TCG_REG_R13,
cea5f9a2 2189 TCG_REG_R14, /* Currently used for the global env. */
5d8a4f8f
RH
2190 TCG_REG_R15,
2191#else
cea5f9a2 2192 TCG_REG_EBP, /* Currently used for the global env. */
b03cce8e
FB
2193 TCG_REG_EBX,
2194 TCG_REG_ESI,
2195 TCG_REG_EDI,
5d8a4f8f 2196#endif
b03cce8e
FB
2197};
2198
813da627
RH
2199/* Compute frame size via macros, to share between tcg_target_qemu_prologue
2200 and tcg_register_jit. */
2201
2202#define PUSH_SIZE \
2203 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
2204 * (TCG_TARGET_REG_BITS / 8))
2205
2206#define FRAME_SIZE \
2207 ((PUSH_SIZE \
2208 + TCG_STATIC_CALL_ARGS_SIZE \
2209 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2210 + TCG_TARGET_STACK_ALIGN - 1) \
2211 & ~(TCG_TARGET_STACK_ALIGN - 1))
2212
b03cce8e 2213/* Generate global QEMU prologue and epilogue code */
e4d58b41 2214static void tcg_target_qemu_prologue(TCGContext *s)
b03cce8e 2215{
813da627 2216 int i, stack_addend;
78686523 2217
b03cce8e 2218 /* TB prologue */
5d8a4f8f 2219
ac0275dc 2220 /* Reserve some stack space, also for TCG temps. */
813da627 2221 stack_addend = FRAME_SIZE - PUSH_SIZE;
ac0275dc
BS
2222 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2223 CPU_TEMP_BUF_NLONGS * sizeof(long));
2224
2225 /* Save all callee saved registers. */
2226 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2227 tcg_out_push(s, tcg_target_callee_save_regs[i]);
2228 }
2229
6a18ae2d
BS
2230#if TCG_TARGET_REG_BITS == 32
2231 tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
2232 (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
b18212c6
SW
2233 tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
2234 /* jmp *tb. */
2235 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_ESP,
2236 (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4
2237 + stack_addend);
6a18ae2d 2238#else
cea5f9a2 2239 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
6a18ae2d 2240 tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
5d8a4f8f 2241 /* jmp *tb. */
cea5f9a2 2242 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
b18212c6 2243#endif
78686523 2244
b03cce8e
FB
2245 /* TB epilogue */
2246 tb_ret_addr = s->code_ptr;
5d8a4f8f 2247
e83c80f7 2248 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
5d8a4f8f
RH
2249
2250 for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
b03cce8e
FB
2251 tcg_out_pop(s, tcg_target_callee_save_regs[i]);
2252 }
5d8a4f8f 2253 tcg_out_opc(s, OPC_RET, 0, 0, 0);
44b37ace
RH
2254
2255#if !defined(CONFIG_SOFTMMU)
2256 /* Try to set up a segment register to point to GUEST_BASE. */
2257 if (GUEST_BASE) {
2258 setup_guest_base_seg();
2259 }
2260#endif
b03cce8e
FB
2261}
2262
e4d58b41 2263static void tcg_target_init(TCGContext *s)
c896fe29 2264{
76a347e1
RH
2265 /* For 32-bit, 99% certainty that we're running on hardware that supports
2266 cmov, but we still need to check. In case cmov is not available, we'll
2267 use a small forward branch. */
2268#ifndef have_cmov
2269 {
2270 unsigned a, b, c, d;
2271 have_cmov = (__get_cpuid(1, &a, &b, &c, &d) && (d & bit_CMOV));
2272 }
2273#endif
2274
20cb400d 2275#if !defined(CONFIG_USER_ONLY)
c896fe29
FB
2276 /* fail safe */
2277 if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
2278 tcg_abort();
20cb400d 2279#endif
c896fe29 2280
5d8a4f8f
RH
2281 if (TCG_TARGET_REG_BITS == 64) {
2282 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2283 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2284 } else {
2285 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
2286 }
4ab50ccf
RH
2287
2288 tcg_regset_clear(tcg_target_call_clobber_regs);
2289 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
2290 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
2291 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
5d8a4f8f 2292 if (TCG_TARGET_REG_BITS == 64) {
8d918718 2293#if !defined(_WIN64)
5d8a4f8f
RH
2294 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
2295 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
8d918718 2296#endif
5d8a4f8f
RH
2297 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2298 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2299 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2300 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2301 }
4ab50ccf 2302
c896fe29 2303 tcg_regset_clear(s->reserved_regs);
e83c80f7 2304 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
c896fe29
FB
2305
2306 tcg_add_target_add_op_defs(x86_op_defs);
2307}
813da627
RH
2308
2309typedef struct {
2310 uint32_t len __attribute__((aligned((sizeof(void *)))));
2311 uint32_t id;
2312 uint8_t version;
2313 char augmentation[1];
2314 uint8_t code_align;
2315 uint8_t data_align;
2316 uint8_t return_column;
2317} DebugFrameCIE;
2318
2319typedef struct {
2320 uint32_t len __attribute__((aligned((sizeof(void *)))));
2321 uint32_t cie_offset;
2322 tcg_target_long func_start __attribute__((packed));
2323 tcg_target_long func_len __attribute__((packed));
2324 uint8_t def_cfa[4];
2325 uint8_t reg_ofs[14];
2326} DebugFrameFDE;
2327
2328typedef struct {
2329 DebugFrameCIE cie;
2330 DebugFrameFDE fde;
2331} DebugFrame;
2332
c170cb66
SW
2333#if !defined(__ELF__)
2334 /* Host machine without ELF. */
2335#elif TCG_TARGET_REG_BITS == 64
813da627
RH
2336#define ELF_HOST_MACHINE EM_X86_64
2337static DebugFrame debug_frame = {
2338 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2339 .cie.id = -1,
2340 .cie.version = 1,
2341 .cie.code_align = 1,
2342 .cie.data_align = 0x78, /* sleb128 -8 */
2343 .cie.return_column = 16,
2344
2345 .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
2346 .fde.def_cfa = {
2347 12, 7, /* DW_CFA_def_cfa %rsp, ... */
2348 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2349 (FRAME_SIZE >> 7)
2350 },
2351 .fde.reg_ofs = {
2352 0x90, 1, /* DW_CFA_offset, %rip, -8 */
2353 /* The following ordering must match tcg_target_callee_save_regs. */
2354 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
2355 0x83, 3, /* DW_CFA_offset, %rbx, -24 */
2356 0x8c, 4, /* DW_CFA_offset, %r12, -32 */
2357 0x8d, 5, /* DW_CFA_offset, %r13, -40 */
2358 0x8e, 6, /* DW_CFA_offset, %r14, -48 */
2359 0x8f, 7, /* DW_CFA_offset, %r15, -56 */
2360 }
2361};
2362#else
2363#define ELF_HOST_MACHINE EM_386
2364static DebugFrame debug_frame = {
2365 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2366 .cie.id = -1,
2367 .cie.version = 1,
2368 .cie.code_align = 1,
2369 .cie.data_align = 0x7c, /* sleb128 -4 */
2370 .cie.return_column = 8,
2371
2372 .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
2373 .fde.def_cfa = {
2374 12, 4, /* DW_CFA_def_cfa %esp, ... */
2375 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2376 (FRAME_SIZE >> 7)
2377 },
2378 .fde.reg_ofs = {
2379 0x88, 1, /* DW_CFA_offset, %eip, -4 */
2380 /* The following ordering must match tcg_target_callee_save_regs. */
2381 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
2382 0x83, 3, /* DW_CFA_offset, %ebx, -12 */
2383 0x86, 4, /* DW_CFA_offset, %esi, -16 */
2384 0x87, 5, /* DW_CFA_offset, %edi, -20 */
2385 }
2386};
2387#endif
2388
c170cb66 2389#if defined(ELF_HOST_MACHINE)
813da627
RH
2390void tcg_register_jit(void *buf, size_t buf_size)
2391{
2392 /* We're expecting a 2 byte uleb128 encoded value. */
2393 assert(FRAME_SIZE >> 14 == 0);
2394
2395 debug_frame.fde.func_start = (tcg_target_long) buf;
2396 debug_frame.fde.func_len = buf_size;
2397
2398 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2399}
c170cb66 2400#endif
This page took 0.961132 seconds and 4 git commands to generate.