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