]> Git Repo - qemu.git/blame - tcg/i386/tcg-target.c
tcg: Push merged memop+mmu_idx parameter to softmmu routines
[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,
37c5d0d5 1175 int mem_index, TCGMemOp s_bits,
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;
5d8a4f8f 1183
d5dad3be
RH
1184 if (TCG_TARGET_REG_BITS == 64) {
1185 if (TARGET_LONG_BITS == 64) {
1186 ttype = TCG_TYPE_I64;
1187 trexw = P_REXW;
1188 }
1189 if (TCG_TYPE_PTR == TCG_TYPE_I64) {
1190 htype = TCG_TYPE_I64;
1191 hrexw = P_REXW;
1192 }
5d8a4f8f 1193 }
8516a044 1194
d5dad3be
RH
1195 tcg_out_mov(s, htype, r0, addrlo);
1196 tcg_out_mov(s, ttype, r1, addrlo);
8516a044 1197
d5dad3be 1198 tcg_out_shifti(s, SHIFT_SHR + hrexw, r0,
5d8a4f8f 1199 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
8516a044 1200
d5dad3be 1201 tgen_arithi(s, ARITH_AND + trexw, r1,
166792f7 1202 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
d5dad3be 1203 tgen_arithi(s, ARITH_AND + hrexw, r0,
5d8a4f8f 1204 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
8516a044 1205
d5dad3be 1206 tcg_out_modrm_sib_offset(s, OPC_LEA + hrexw, r0, TCG_AREG0, r0, 0,
9349b4f9 1207 offsetof(CPUArchState, tlb_table[mem_index][0])
8516a044
RH
1208 + which);
1209
166792f7 1210 /* cmp 0(r0), r1 */
d5dad3be 1211 tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, 0);
8516a044 1212
d5dad3be
RH
1213 /* Prepare for both the fast path add of the tlb addend, and the slow
1214 path function argument setup. There are two cases worth note:
1215 For 32-bit guest and x86_64 host, MOVL zero-extends the guest address
1216 before the fastpath ADDQ below. For 64-bit guest and x32 host, MOVQ
1217 copies the entire guest address for the slow path, while truncation
1218 for the 32-bit host happens with the fastpath ADDL below. */
1219 tcg_out_mov(s, ttype, r1, addrlo);
8516a044 1220
b76f0d8c
YL
1221 /* jne slow_path */
1222 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
8516a044 1223 label_ptr[0] = s->code_ptr;
b76f0d8c 1224 s->code_ptr += 4;
8516a044 1225
5d8a4f8f 1226 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
166792f7 1227 /* cmp 4(r0), addrhi */
7352ee54 1228 tcg_out_modrm_offset(s, OPC_CMP_GvEv, addrhi, r0, 4);
8516a044 1229
b76f0d8c
YL
1230 /* jne slow_path */
1231 tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
8516a044 1232 label_ptr[1] = s->code_ptr;
b76f0d8c 1233 s->code_ptr += 4;
8516a044
RH
1234 }
1235
1236 /* TLB Hit. */
1237
166792f7 1238 /* add addend(r0), r1 */
d5dad3be 1239 tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0,
8516a044
RH
1240 offsetof(CPUTLBEntry, addend) - which);
1241}
7352ee54
RH
1242
1243/*
1244 * Record the context of a call to the out of line helper code for the slow path
1245 * for a load or store, so that we can later generate the correct helper code
1246 */
3972ef6f 1247static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
7352ee54
RH
1248 TCGReg datalo, TCGReg datahi,
1249 TCGReg addrlo, TCGReg addrhi,
3972ef6f 1250 tcg_insn_unit *raddr,
f6bff89d 1251 tcg_insn_unit **label_ptr)
7352ee54
RH
1252{
1253 TCGLabelQemuLdst *label = new_ldst_label(s);
1254
1255 label->is_ld = is_ld;
3972ef6f 1256 label->oi = oi;
7352ee54
RH
1257 label->datalo_reg = datalo;
1258 label->datahi_reg = datahi;
1259 label->addrlo_reg = addrlo;
1260 label->addrhi_reg = addrhi;
7352ee54
RH
1261 label->raddr = raddr;
1262 label->label_ptr[0] = label_ptr[0];
1263 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1264 label->label_ptr[1] = label_ptr[1];
1265 }
1266}
1267
1268/*
1269 * Generate code for the slow path for a load at the end of block
1270 */
1271static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1272{
3972ef6f
RH
1273 TCGMemOpIdx oi = l->oi;
1274 TCGMemOp opc = get_memop(oi);
7352ee54 1275 TCGReg data_reg;
f6bff89d 1276 tcg_insn_unit **label_ptr = &l->label_ptr[0];
7352ee54
RH
1277
1278 /* resolve label address */
5c53bb81 1279 tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
7352ee54 1280 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
5c53bb81 1281 tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
7352ee54
RH
1282 }
1283
1284 if (TCG_TARGET_REG_BITS == 32) {
1285 int ofs = 0;
1286
1287 tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
1288 ofs += 4;
1289
1290 tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
1291 ofs += 4;
1292
1293 if (TARGET_LONG_BITS == 64) {
1294 tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
1295 ofs += 4;
1296 }
1297
3972ef6f 1298 tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
7352ee54
RH
1299 ofs += 4;
1300
3972ef6f 1301 tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, ofs, (uintptr_t)l->raddr);
7352ee54
RH
1302 } else {
1303 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1304 /* The second argument is already loaded with addrlo. */
3972ef6f 1305 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], oi);
7352ee54
RH
1306 tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3],
1307 (uintptr_t)l->raddr);
1308 }
1309
6bf3e997 1310 tcg_out_call(s, qemu_ld_helpers[opc & ~MO_SIGN]);
7352ee54
RH
1311
1312 data_reg = l->datalo_reg;
1313 switch (opc & MO_SSIZE) {
1314 case MO_SB:
1315 tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
1316 break;
1317 case MO_SW:
1318 tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
1319 break;
1320#if TCG_TARGET_REG_BITS == 64
1321 case MO_SL:
1322 tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1323 break;
1324#endif
1325 case MO_UB:
1326 case MO_UW:
1327 /* Note that the helpers have zero-extended to tcg_target_long. */
1328 case MO_UL:
1329 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1330 break;
1331 case MO_Q:
1332 if (TCG_TARGET_REG_BITS == 64) {
1333 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
1334 } else if (data_reg == TCG_REG_EDX) {
1335 /* xchg %edx, %eax */
1336 tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
1337 tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX);
1338 } else {
1339 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1340 tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX);
1341 }
1342 break;
1343 default:
1344 tcg_abort();
1345 }
1346
1347 /* Jump to the code corresponding to next IR of qemu_st */
f6bff89d 1348 tcg_out_jmp(s, l->raddr);
7352ee54
RH
1349}
1350
1351/*
1352 * Generate code for the slow path for a store at the end of block
1353 */
1354static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
1355{
3972ef6f
RH
1356 TCGMemOpIdx oi = l->oi;
1357 TCGMemOp opc = get_memop(oi);
7352ee54 1358 TCGMemOp s_bits = opc & MO_SIZE;
f6bff89d 1359 tcg_insn_unit **label_ptr = &l->label_ptr[0];
7352ee54
RH
1360 TCGReg retaddr;
1361
1362 /* resolve label address */
5c53bb81 1363 tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
7352ee54 1364 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
5c53bb81 1365 tcg_patch32(label_ptr[1], s->code_ptr - label_ptr[1] - 4);
7352ee54
RH
1366 }
1367
1368 if (TCG_TARGET_REG_BITS == 32) {
1369 int ofs = 0;
1370
1371 tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
1372 ofs += 4;
1373
1374 tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
1375 ofs += 4;
1376
1377 if (TARGET_LONG_BITS == 64) {
1378 tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
1379 ofs += 4;
1380 }
1381
1382 tcg_out_st(s, TCG_TYPE_I32, l->datalo_reg, TCG_REG_ESP, ofs);
1383 ofs += 4;
1384
1385 if (s_bits == MO_64) {
1386 tcg_out_st(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_ESP, ofs);
1387 ofs += 4;
1388 }
1389
3972ef6f 1390 tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
7352ee54
RH
1391 ofs += 4;
1392
1393 retaddr = TCG_REG_EAX;
3972ef6f
RH
1394 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr);
1395 tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, ofs);
7352ee54
RH
1396 } else {
1397 tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
1398 /* The second argument is already loaded with addrlo. */
1399 tcg_out_mov(s, (s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1400 tcg_target_call_iarg_regs[2], l->datalo_reg);
3972ef6f 1401 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], oi);
7352ee54
RH
1402
1403 if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) {
1404 retaddr = tcg_target_call_iarg_regs[4];
1405 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr);
1406 } else {
1407 retaddr = TCG_REG_RAX;
1408 tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr);
0b919667
RH
1409 tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP,
1410 TCG_TARGET_CALL_STACK_OFFSET);
7352ee54
RH
1411 }
1412 }
1413
1414 /* "Tail call" to the helper, with the return address back inline. */
1415 tcg_out_push(s, retaddr);
f6bff89d 1416 tcg_out_jmp(s, qemu_st_helpers[opc]);
7352ee54 1417}
44b37ace
RH
1418#elif defined(__x86_64__) && defined(__linux__)
1419# include <asm/prctl.h>
1420# include <sys/prctl.h>
1421
1422int arch_prctl(int code, unsigned long addr);
1423
1424static int guest_base_flags;
1425static inline void setup_guest_base_seg(void)
1426{
1427 if (arch_prctl(ARCH_SET_GS, GUEST_BASE) == 0) {
1428 guest_base_flags = P_GS;
1429 }
1430}
1431#else
1432# define guest_base_flags 0
1433static inline void setup_guest_base_seg(void) { }
1434#endif /* SOFTMMU */
c896fe29 1435
37c5d0d5
RH
1436static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1437 TCGReg base, intptr_t ofs, int seg,
1438 TCGMemOp memop)
be5a4eb7 1439{
085bb5bb
AJ
1440 const TCGMemOp real_bswap = memop & MO_BSWAP;
1441 TCGMemOp bswap = real_bswap;
1442 int movop = OPC_MOVL_GvEv;
1443
1444 if (have_movbe && real_bswap) {
1445 bswap = 0;
1446 movop = OPC_MOVBE_GyMy;
1447 }
37c5d0d5
RH
1448
1449 switch (memop & MO_SSIZE) {
1450 case MO_UB:
44b37ace 1451 tcg_out_modrm_offset(s, OPC_MOVZBL + seg, datalo, base, ofs);
be5a4eb7 1452 break;
37c5d0d5 1453 case MO_SB:
44b37ace 1454 tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW + seg, datalo, base, ofs);
be5a4eb7 1455 break;
37c5d0d5 1456 case MO_UW:
44b37ace 1457 tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
085bb5bb 1458 if (real_bswap) {
be5a4eb7
RH
1459 tcg_out_rolw_8(s, datalo);
1460 }
1461 break;
37c5d0d5 1462 case MO_SW:
085bb5bb
AJ
1463 if (real_bswap) {
1464 if (have_movbe) {
1465 tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
1466 datalo, base, ofs);
1467 } else {
1468 tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
1469 tcg_out_rolw_8(s, datalo);
1470 }
5d8a4f8f
RH
1471 tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
1472 } else {
44b37ace
RH
1473 tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW + seg,
1474 datalo, base, ofs);
be5a4eb7
RH
1475 }
1476 break;
37c5d0d5 1477 case MO_UL:
085bb5bb 1478 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
be5a4eb7
RH
1479 if (bswap) {
1480 tcg_out_bswap32(s, datalo);
1481 }
1482 break;
5d8a4f8f 1483#if TCG_TARGET_REG_BITS == 64
37c5d0d5 1484 case MO_SL:
085bb5bb
AJ
1485 if (real_bswap) {
1486 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
1487 if (bswap) {
1488 tcg_out_bswap32(s, datalo);
1489 }
5d8a4f8f 1490 tcg_out_ext32s(s, datalo, datalo);
be5a4eb7 1491 } else {
44b37ace 1492 tcg_out_modrm_offset(s, OPC_MOVSLQ + seg, datalo, base, ofs);
be5a4eb7 1493 }
5d8a4f8f
RH
1494 break;
1495#endif
37c5d0d5 1496 case MO_Q:
5d8a4f8f 1497 if (TCG_TARGET_REG_BITS == 64) {
085bb5bb 1498 tcg_out_modrm_offset(s, movop + P_REXW + seg, datalo, base, ofs);
5d8a4f8f
RH
1499 if (bswap) {
1500 tcg_out_bswap64(s, datalo);
1501 }
1502 } else {
085bb5bb 1503 if (real_bswap) {
5d8a4f8f
RH
1504 int t = datalo;
1505 datalo = datahi;
1506 datahi = t;
1507 }
1508 if (base != datalo) {
085bb5bb
AJ
1509 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
1510 tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs + 4);
5d8a4f8f 1511 } else {
085bb5bb
AJ
1512 tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs + 4);
1513 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
5d8a4f8f
RH
1514 }
1515 if (bswap) {
1516 tcg_out_bswap32(s, datalo);
1517 tcg_out_bswap32(s, datahi);
1518 }
be5a4eb7
RH
1519 }
1520 break;
1521 default:
1522 tcg_abort();
1523 }
1524}
379f6698 1525
c896fe29
FB
1526/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1527 EAX. It will be useful once fixed registers globals are less
1528 common. */
8221a267 1529static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
c896fe29 1530{
7352ee54 1531 TCGReg datalo, datahi, addrlo;
8221a267 1532 TCGReg addrhi __attribute__((unused));
59227d5d 1533 TCGMemOpIdx oi;
8221a267 1534 TCGMemOp opc;
c896fe29 1535#if defined(CONFIG_SOFTMMU)
37c5d0d5
RH
1536 int mem_index;
1537 TCGMemOp s_bits;
f6bff89d 1538 tcg_insn_unit *label_ptr[2];
c896fe29
FB
1539#endif
1540
7352ee54 1541 datalo = *args++;
8221a267 1542 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
7352ee54 1543 addrlo = *args++;
8221a267 1544 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
59227d5d
RH
1545 oi = *args++;
1546 opc = get_memop(oi);
c896fe29
FB
1547
1548#if defined(CONFIG_SOFTMMU)
59227d5d 1549 mem_index = get_mmuidx(oi);
37c5d0d5 1550 s_bits = opc & MO_SIZE;
1a6dc1e4 1551
7352ee54 1552 tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits,
8516a044 1553 label_ptr, offsetof(CPUTLBEntry, addr_read));
1a6dc1e4
RH
1554
1555 /* TLB Hit. */
7352ee54 1556 tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc);
c896fe29 1557
b76f0d8c 1558 /* Record the current context of a load into ldst label */
3972ef6f
RH
1559 add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
1560 s->code_ptr, label_ptr);
c896fe29 1561#else
5d8a4f8f
RH
1562 {
1563 int32_t offset = GUEST_BASE;
7352ee54 1564 TCGReg base = addrlo;
44b37ace
RH
1565 int seg = 0;
1566
1567 /* ??? We assume all operations have left us with register contents
1568 that are zero extended. So far this appears to be true. If we
1569 want to enforce this, we can either do an explicit zero-extension
1570 here, or (if GUEST_BASE == 0, or a segment register is in use)
1571 use the ADDR32 prefix. For now, do nothing. */
1572 if (GUEST_BASE && guest_base_flags) {
1573 seg = guest_base_flags;
1574 offset = 0;
1575 } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
1576 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
1577 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
1578 base = TCG_REG_L1;
1579 offset = 0;
5d8a4f8f
RH
1580 }
1581
7352ee54 1582 tcg_out_qemu_ld_direct(s, datalo, datahi, base, offset, seg, opc);
5d8a4f8f 1583 }
c896fe29 1584#endif
be5a4eb7 1585}
c896fe29 1586
37c5d0d5
RH
1587static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
1588 TCGReg base, intptr_t ofs, int seg,
1589 TCGMemOp memop)
be5a4eb7 1590{
be5a4eb7
RH
1591 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1592 we could perform the bswap twice to restore the original value
1593 instead of moving to the scratch. But as it is, the L constraint
166792f7 1594 means that TCG_REG_L0 is definitely free here. */
37c5d0d5 1595 const TCGReg scratch = TCG_REG_L0;
085bb5bb
AJ
1596 const TCGMemOp real_bswap = memop & MO_BSWAP;
1597 TCGMemOp bswap = real_bswap;
1598 int movop = OPC_MOVL_EvGv;
1599
1600 if (have_movbe && real_bswap) {
1601 bswap = 0;
1602 movop = OPC_MOVBE_MyGy;
1603 }
be5a4eb7 1604
37c5d0d5
RH
1605 switch (memop & MO_SIZE) {
1606 case MO_8:
8589467f 1607 /* In 32-bit mode, 8-bit stores can only happen from [abcd]x.
b3e2bc50
RH
1608 Use the scratch register if necessary. */
1609 if (TCG_TARGET_REG_BITS == 32 && datalo >= 4) {
1610 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1611 datalo = scratch;
1612 }
44b37ace
RH
1613 tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg,
1614 datalo, base, ofs);
c896fe29 1615 break;
37c5d0d5 1616 case MO_16:
c896fe29 1617 if (bswap) {
3b6dac34 1618 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1619 tcg_out_rolw_8(s, scratch);
1620 datalo = scratch;
c896fe29 1621 }
085bb5bb 1622 tcg_out_modrm_offset(s, movop + P_DATA16 + seg, datalo, base, ofs);
c896fe29 1623 break;
37c5d0d5 1624 case MO_32:
c896fe29 1625 if (bswap) {
3b6dac34 1626 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7
RH
1627 tcg_out_bswap32(s, scratch);
1628 datalo = scratch;
c896fe29 1629 }
085bb5bb 1630 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
c896fe29 1631 break;
37c5d0d5 1632 case MO_64:
5d8a4f8f
RH
1633 if (TCG_TARGET_REG_BITS == 64) {
1634 if (bswap) {
1635 tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
1636 tcg_out_bswap64(s, scratch);
1637 datalo = scratch;
1638 }
085bb5bb 1639 tcg_out_modrm_offset(s, movop + P_REXW + seg, datalo, base, ofs);
5d8a4f8f 1640 } else if (bswap) {
3b6dac34 1641 tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
be5a4eb7 1642 tcg_out_bswap32(s, scratch);
44b37ace 1643 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs);
3b6dac34 1644 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
be5a4eb7 1645 tcg_out_bswap32(s, scratch);
44b37ace 1646 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs+4);
c896fe29 1647 } else {
085bb5bb
AJ
1648 if (real_bswap) {
1649 int t = datalo;
1650 datalo = datahi;
1651 datahi = t;
1652 }
1653 tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
1654 tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs+4);
c896fe29
FB
1655 }
1656 break;
1657 default:
1658 tcg_abort();
1659 }
c896fe29
FB
1660}
1661
8221a267 1662static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
c896fe29 1663{
7352ee54 1664 TCGReg datalo, datahi, addrlo;
8221a267 1665 TCGReg addrhi __attribute__((unused));
59227d5d 1666 TCGMemOpIdx oi;
8221a267 1667 TCGMemOp opc;
c896fe29 1668#if defined(CONFIG_SOFTMMU)
37c5d0d5
RH
1669 int mem_index;
1670 TCGMemOp s_bits;
f6bff89d 1671 tcg_insn_unit *label_ptr[2];
c896fe29
FB
1672#endif
1673
7352ee54 1674 datalo = *args++;
8221a267 1675 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
7352ee54 1676 addrlo = *args++;
8221a267 1677 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
59227d5d
RH
1678 oi = *args++;
1679 opc = get_memop(oi);
c896fe29
FB
1680
1681#if defined(CONFIG_SOFTMMU)
59227d5d 1682 mem_index = get_mmuidx(oi);
37c5d0d5 1683 s_bits = opc & MO_SIZE;
1a6dc1e4 1684
7352ee54 1685 tcg_out_tlb_load(s, addrlo, addrhi, mem_index, s_bits,
8516a044 1686 label_ptr, offsetof(CPUTLBEntry, addr_write));
1a6dc1e4
RH
1687
1688 /* TLB Hit. */
7352ee54 1689 tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc);
c896fe29 1690
b76f0d8c 1691 /* Record the current context of a store into ldst label */
3972ef6f
RH
1692 add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
1693 s->code_ptr, label_ptr);
b76f0d8c
YL
1694#else
1695 {
1696 int32_t offset = GUEST_BASE;
7352ee54 1697 TCGReg base = addrlo;
b76f0d8c
YL
1698 int seg = 0;
1699
1700 /* ??? We assume all operations have left us with register contents
1701 that are zero extended. So far this appears to be true. If we
1702 want to enforce this, we can either do an explicit zero-extension
1703 here, or (if GUEST_BASE == 0, or a segment register is in use)
1704 use the ADDR32 prefix. For now, do nothing. */
1705 if (GUEST_BASE && guest_base_flags) {
1706 seg = guest_base_flags;
1707 offset = 0;
1708 } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
1709 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
1710 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
1711 base = TCG_REG_L1;
1712 offset = 0;
1713 }
1714
7352ee54 1715 tcg_out_qemu_st_direct(s, datalo, datahi, base, offset, seg, opc);
b76f0d8c 1716 }
b76f0d8c 1717#endif
b76f0d8c 1718}
c896fe29 1719
a9751609 1720static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
c896fe29
FB
1721 const TCGArg *args, const int *const_args)
1722{
6399ab33 1723 int c, vexop, rexw = 0;
5d8a4f8f
RH
1724
1725#if TCG_TARGET_REG_BITS == 64
1726# define OP_32_64(x) \
1727 case glue(glue(INDEX_op_, x), _i64): \
1728 rexw = P_REXW; /* FALLTHRU */ \
1729 case glue(glue(INDEX_op_, x), _i32)
1730#else
1731# define OP_32_64(x) \
1732 case glue(glue(INDEX_op_, x), _i32)
1733#endif
78686523 1734
c896fe29
FB
1735 switch(opc) {
1736 case INDEX_op_exit_tb:
5d8a4f8f 1737 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
f6bff89d 1738 tcg_out_jmp(s, tb_ret_addr);
c896fe29
FB
1739 break;
1740 case INDEX_op_goto_tb:
1741 if (s->tb_jmp_offset) {
1742 /* direct jump method */
da441cff 1743 tcg_out8(s, OPC_JMP_long); /* jmp im */
f6bff89d 1744 s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
c896fe29
FB
1745 tcg_out32(s, 0);
1746 } else {
1747 /* indirect jump method */
9363dedb 1748 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
357e3d8a 1749 (intptr_t)(s->tb_next + args[0]));
c896fe29 1750 }
f6bff89d 1751 s->tb_next_offset[args[0]] = tcg_current_code_size(s);
c896fe29 1752 break;
c896fe29 1753 case INDEX_op_br:
bec16311 1754 tcg_out_jxx(s, JCC_JMP, arg_label(args[0]), 0);
c896fe29 1755 break;
5d8a4f8f
RH
1756 OP_32_64(ld8u):
1757 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1758 tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
c896fe29 1759 break;
5d8a4f8f
RH
1760 OP_32_64(ld8s):
1761 tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
c896fe29 1762 break;
5d8a4f8f
RH
1763 OP_32_64(ld16u):
1764 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
55e082a7 1765 tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
c896fe29 1766 break;
5d8a4f8f
RH
1767 OP_32_64(ld16s):
1768 tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
c896fe29 1769 break;
5d8a4f8f
RH
1770#if TCG_TARGET_REG_BITS == 64
1771 case INDEX_op_ld32u_i64:
1772#endif
c896fe29 1773 case INDEX_op_ld_i32:
af266089 1774 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
c896fe29 1775 break;
5d8a4f8f
RH
1776
1777 OP_32_64(st8):
5c2d2a9e
AJ
1778 if (const_args[0]) {
1779 tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
1780 0, args[1], args[2]);
1781 tcg_out8(s, args[0]);
1782 } else {
1783 tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
1784 args[0], args[1], args[2]);
1785 }
c896fe29 1786 break;
5d8a4f8f 1787 OP_32_64(st16):
5c2d2a9e
AJ
1788 if (const_args[0]) {
1789 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
1790 0, args[1], args[2]);
1791 tcg_out16(s, args[0]);
1792 } else {
1793 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1794 args[0], args[1], args[2]);
1795 }
c896fe29 1796 break;
5d8a4f8f
RH
1797#if TCG_TARGET_REG_BITS == 64
1798 case INDEX_op_st32_i64:
1799#endif
c896fe29 1800 case INDEX_op_st_i32:
5c2d2a9e
AJ
1801 if (const_args[0]) {
1802 tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
1803 tcg_out32(s, args[0]);
1804 } else {
1805 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1806 }
c896fe29 1807 break;
5d8a4f8f
RH
1808
1809 OP_32_64(add):
5d1e4e85
RH
1810 /* For 3-operand addition, use LEA. */
1811 if (args[0] != args[1]) {
1812 TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1813
1814 if (const_args[2]) {
1815 c3 = a2, a2 = -1;
1816 } else if (a0 == a2) {
1817 /* Watch out for dest = src + dest, since we've removed
1818 the matching constraint on the add. */
5d8a4f8f 1819 tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
5d1e4e85
RH
1820 break;
1821 }
1822
5d8a4f8f 1823 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
5d1e4e85
RH
1824 break;
1825 }
1826 c = ARITH_ADD;
1827 goto gen_arith;
5d8a4f8f 1828 OP_32_64(sub):
c896fe29
FB
1829 c = ARITH_SUB;
1830 goto gen_arith;
5d8a4f8f 1831 OP_32_64(and):
c896fe29
FB
1832 c = ARITH_AND;
1833 goto gen_arith;
5d8a4f8f 1834 OP_32_64(or):
c896fe29
FB
1835 c = ARITH_OR;
1836 goto gen_arith;
5d8a4f8f 1837 OP_32_64(xor):
c896fe29
FB
1838 c = ARITH_XOR;
1839 goto gen_arith;
c896fe29
FB
1840 gen_arith:
1841 if (const_args[2]) {
5d8a4f8f 1842 tgen_arithi(s, c + rexw, args[0], args[2], 0);
c896fe29 1843 } else {
5d8a4f8f 1844 tgen_arithr(s, c + rexw, args[0], args[2]);
c896fe29
FB
1845 }
1846 break;
5d8a4f8f 1847
9d2eec20
RH
1848 OP_32_64(andc):
1849 if (const_args[2]) {
1850 tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32,
1851 args[0], args[1]);
1852 tgen_arithi(s, ARITH_AND + rexw, args[0], ~args[2], 0);
1853 } else {
1854 tcg_out_vex_modrm(s, OPC_ANDN + rexw, args[0], args[2], args[1]);
1855 }
1856 break;
1857
5d8a4f8f 1858 OP_32_64(mul):
c896fe29
FB
1859 if (const_args[2]) {
1860 int32_t val;
1861 val = args[2];
1862 if (val == (int8_t)val) {
5d8a4f8f 1863 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
c896fe29
FB
1864 tcg_out8(s, val);
1865 } else {
5d8a4f8f 1866 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
c896fe29
FB
1867 tcg_out32(s, val);
1868 }
1869 } else {
5d8a4f8f 1870 tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
c896fe29
FB
1871 }
1872 break;
5d8a4f8f
RH
1873
1874 OP_32_64(div2):
1875 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
c896fe29 1876 break;
5d8a4f8f
RH
1877 OP_32_64(divu2):
1878 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
c896fe29 1879 break;
5d8a4f8f
RH
1880
1881 OP_32_64(shl):
c896fe29 1882 c = SHIFT_SHL;
6399ab33
RH
1883 vexop = OPC_SHLX;
1884 goto gen_shift_maybe_vex;
5d8a4f8f 1885 OP_32_64(shr):
c896fe29 1886 c = SHIFT_SHR;
6399ab33
RH
1887 vexop = OPC_SHRX;
1888 goto gen_shift_maybe_vex;
5d8a4f8f 1889 OP_32_64(sar):
c896fe29 1890 c = SHIFT_SAR;
6399ab33
RH
1891 vexop = OPC_SARX;
1892 goto gen_shift_maybe_vex;
5d8a4f8f 1893 OP_32_64(rotl):
9619376c 1894 c = SHIFT_ROL;
5d8a4f8f
RH
1895 goto gen_shift;
1896 OP_32_64(rotr):
9619376c 1897 c = SHIFT_ROR;
5d8a4f8f 1898 goto gen_shift;
6399ab33
RH
1899 gen_shift_maybe_vex:
1900 if (have_bmi2 && !const_args[2]) {
1901 tcg_out_vex_modrm(s, vexop + rexw, args[0], args[2], args[1]);
1902 break;
1903 }
1904 /* FALLTHRU */
5d8a4f8f
RH
1905 gen_shift:
1906 if (const_args[2]) {
1907 tcg_out_shifti(s, c + rexw, args[0], args[2]);
81570a70 1908 } else {
5d8a4f8f 1909 tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
81570a70 1910 }
c896fe29 1911 break;
5d8a4f8f 1912
c896fe29 1913 case INDEX_op_brcond_i32:
5d8a4f8f 1914 tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
bec16311 1915 arg_label(args[3]), 0);
c896fe29 1916 break;
5d8a4f8f
RH
1917 case INDEX_op_setcond_i32:
1918 tcg_out_setcond32(s, args[3], args[0], args[1],
1919 args[2], const_args[2]);
c896fe29 1920 break;
d0a16297
RH
1921 case INDEX_op_movcond_i32:
1922 tcg_out_movcond32(s, args[5], args[0], args[1],
1923 args[2], const_args[2], args[3]);
1924 break;
c896fe29 1925
5d8a4f8f 1926 OP_32_64(bswap16):
fcb5dac1 1927 tcg_out_rolw_8(s, args[0]);
5d40cd63 1928 break;
5d8a4f8f 1929 OP_32_64(bswap32):
fcb5dac1 1930 tcg_out_bswap32(s, args[0]);
9619376c
AJ
1931 break;
1932
5d8a4f8f
RH
1933 OP_32_64(neg):
1934 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
9619376c 1935 break;
5d8a4f8f
RH
1936 OP_32_64(not):
1937 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
9619376c
AJ
1938 break;
1939
5d8a4f8f
RH
1940 OP_32_64(ext8s):
1941 tcg_out_ext8s(s, args[0], args[1], rexw);
9619376c 1942 break;
5d8a4f8f
RH
1943 OP_32_64(ext16s):
1944 tcg_out_ext16s(s, args[0], args[1], rexw);
9619376c 1945 break;
5d8a4f8f 1946 OP_32_64(ext8u):
55e082a7 1947 tcg_out_ext8u(s, args[0], args[1]);
5f0ce17f 1948 break;
5d8a4f8f 1949 OP_32_64(ext16u):
55e082a7 1950 tcg_out_ext16u(s, args[0], args[1]);
5f0ce17f 1951 break;
9619376c 1952
8221a267
RH
1953 case INDEX_op_qemu_ld_i32:
1954 tcg_out_qemu_ld(s, args, 0);
c896fe29 1955 break;
8221a267
RH
1956 case INDEX_op_qemu_ld_i64:
1957 tcg_out_qemu_ld(s, args, 1);
c896fe29 1958 break;
8221a267
RH
1959 case INDEX_op_qemu_st_i32:
1960 tcg_out_qemu_st(s, args, 0);
c896fe29 1961 break;
8221a267
RH
1962 case INDEX_op_qemu_st_i64:
1963 tcg_out_qemu_st(s, args, 1);
c896fe29
FB
1964 break;
1965
624988a5
RH
1966 OP_32_64(mulu2):
1967 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_MUL, args[3]);
5d8a4f8f 1968 break;
624988a5
RH
1969 OP_32_64(muls2):
1970 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IMUL, args[3]);
1971 break;
1972 OP_32_64(add2):
5d8a4f8f 1973 if (const_args[4]) {
624988a5 1974 tgen_arithi(s, ARITH_ADD + rexw, args[0], args[4], 1);
5d8a4f8f 1975 } else {
624988a5 1976 tgen_arithr(s, ARITH_ADD + rexw, args[0], args[4]);
5d8a4f8f
RH
1977 }
1978 if (const_args[5]) {
624988a5 1979 tgen_arithi(s, ARITH_ADC + rexw, args[1], args[5], 1);
5d8a4f8f 1980 } else {
624988a5 1981 tgen_arithr(s, ARITH_ADC + rexw, args[1], args[5]);
5d8a4f8f
RH
1982 }
1983 break;
624988a5 1984 OP_32_64(sub2):
5d8a4f8f 1985 if (const_args[4]) {
624988a5 1986 tgen_arithi(s, ARITH_SUB + rexw, args[0], args[4], 1);
5d8a4f8f 1987 } else {
624988a5 1988 tgen_arithr(s, ARITH_SUB + rexw, args[0], args[4]);
5d8a4f8f
RH
1989 }
1990 if (const_args[5]) {
624988a5 1991 tgen_arithi(s, ARITH_SBB + rexw, args[1], args[5], 1);
5d8a4f8f 1992 } else {
624988a5 1993 tgen_arithr(s, ARITH_SBB + rexw, args[1], args[5]);
5d8a4f8f
RH
1994 }
1995 break;
bbc863bf
RH
1996
1997#if TCG_TARGET_REG_BITS == 32
1998 case INDEX_op_brcond2_i32:
1999 tcg_out_brcond2(s, args, const_args, 0);
2000 break;
2001 case INDEX_op_setcond2_i32:
2002 tcg_out_setcond2(s, args, const_args);
2003 break;
5d8a4f8f 2004#else /* TCG_TARGET_REG_BITS == 64 */
5d8a4f8f
RH
2005 case INDEX_op_ld32s_i64:
2006 tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
2007 break;
2008 case INDEX_op_ld_i64:
2009 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2010 break;
2011 case INDEX_op_st_i64:
5c2d2a9e
AJ
2012 if (const_args[0]) {
2013 tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
2014 0, args[1], args[2]);
2015 tcg_out32(s, args[0]);
2016 } else {
2017 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
2018 }
5d8a4f8f 2019 break;
5d8a4f8f
RH
2020
2021 case INDEX_op_brcond_i64:
2022 tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
bec16311 2023 arg_label(args[3]), 0);
5d8a4f8f
RH
2024 break;
2025 case INDEX_op_setcond_i64:
2026 tcg_out_setcond64(s, args[3], args[0], args[1],
2027 args[2], const_args[2]);
2028 break;
d0a16297
RH
2029 case INDEX_op_movcond_i64:
2030 tcg_out_movcond64(s, args[5], args[0], args[1],
2031 args[2], const_args[2], args[3]);
2032 break;
5d8a4f8f
RH
2033
2034 case INDEX_op_bswap64_i64:
2035 tcg_out_bswap64(s, args[0]);
2036 break;
2037 case INDEX_op_ext32u_i64:
2038 tcg_out_ext32u(s, args[0], args[1]);
2039 break;
2040 case INDEX_op_ext32s_i64:
2041 tcg_out_ext32s(s, args[0], args[1]);
2042 break;
2043#endif
2044
a4773324
JK
2045 OP_32_64(deposit):
2046 if (args[3] == 0 && args[4] == 8) {
2047 /* load bits 0..7 */
2048 tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
2049 args[2], args[0]);
2050 } else if (args[3] == 8 && args[4] == 8) {
2051 /* load bits 8..15 */
2052 tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
2053 } else if (args[3] == 0 && args[4] == 16) {
2054 /* load bits 0..15 */
2055 tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
2056 } else {
2057 tcg_abort();
2058 }
2059 break;
2060
96d0ee7f
RH
2061 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2062 case INDEX_op_mov_i64:
2063 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2064 case INDEX_op_movi_i64:
2065 case INDEX_op_call: /* Always emitted via tcg_out_call. */
c896fe29
FB
2066 default:
2067 tcg_abort();
2068 }
5d8a4f8f
RH
2069
2070#undef OP_32_64
c896fe29
FB
2071}
2072
2073static const TCGTargetOpDef x86_op_defs[] = {
2074 { INDEX_op_exit_tb, { } },
2075 { INDEX_op_goto_tb, { } },
c896fe29 2076 { INDEX_op_br, { } },
c896fe29
FB
2077 { INDEX_op_ld8u_i32, { "r", "r" } },
2078 { INDEX_op_ld8s_i32, { "r", "r" } },
2079 { INDEX_op_ld16u_i32, { "r", "r" } },
2080 { INDEX_op_ld16s_i32, { "r", "r" } },
2081 { INDEX_op_ld_i32, { "r", "r" } },
5c2d2a9e
AJ
2082 { INDEX_op_st8_i32, { "qi", "r" } },
2083 { INDEX_op_st16_i32, { "ri", "r" } },
2084 { INDEX_op_st_i32, { "ri", "r" } },
c896fe29 2085
5d1e4e85 2086 { INDEX_op_add_i32, { "r", "r", "ri" } },
c896fe29
FB
2087 { INDEX_op_sub_i32, { "r", "0", "ri" } },
2088 { INDEX_op_mul_i32, { "r", "0", "ri" } },
c896fe29
FB
2089 { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
2090 { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
2091 { INDEX_op_and_i32, { "r", "0", "ri" } },
2092 { INDEX_op_or_i32, { "r", "0", "ri" } },
2093 { INDEX_op_xor_i32, { "r", "0", "ri" } },
9d2eec20 2094 { INDEX_op_andc_i32, { "r", "r", "ri" } },
c896fe29 2095
6399ab33
RH
2096 { INDEX_op_shl_i32, { "r", "0", "Ci" } },
2097 { INDEX_op_shr_i32, { "r", "0", "Ci" } },
2098 { INDEX_op_sar_i32, { "r", "0", "Ci" } },
9619376c
AJ
2099 { INDEX_op_rotl_i32, { "r", "0", "ci" } },
2100 { INDEX_op_rotr_i32, { "r", "0", "ci" } },
c896fe29
FB
2101
2102 { INDEX_op_brcond_i32, { "r", "ri" } },
2103
5d40cd63 2104 { INDEX_op_bswap16_i32, { "r", "0" } },
66896cb8 2105 { INDEX_op_bswap32_i32, { "r", "0" } },
9619376c
AJ
2106
2107 { INDEX_op_neg_i32, { "r", "0" } },
2108
2109 { INDEX_op_not_i32, { "r", "0" } },
2110
2111 { INDEX_op_ext8s_i32, { "r", "q" } },
2112 { INDEX_op_ext16s_i32, { "r", "r" } },
55e082a7
RH
2113 { INDEX_op_ext8u_i32, { "r", "q" } },
2114 { INDEX_op_ext16u_i32, { "r", "r" } },
9619376c 2115
1d2699ae 2116 { INDEX_op_setcond_i32, { "q", "r", "ri" } },
5d8a4f8f 2117
a4773324 2118 { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
d0a16297 2119 { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
a4773324 2120
5d8a4f8f 2121 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
624988a5 2122 { INDEX_op_muls2_i32, { "a", "d", "a", "r" } },
5d8a4f8f
RH
2123 { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
2124 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
bbc863bf
RH
2125
2126#if TCG_TARGET_REG_BITS == 32
5d8a4f8f 2127 { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1d2699ae 2128 { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
5d8a4f8f 2129#else
5d8a4f8f
RH
2130 { INDEX_op_ld8u_i64, { "r", "r" } },
2131 { INDEX_op_ld8s_i64, { "r", "r" } },
2132 { INDEX_op_ld16u_i64, { "r", "r" } },
2133 { INDEX_op_ld16s_i64, { "r", "r" } },
2134 { INDEX_op_ld32u_i64, { "r", "r" } },
2135 { INDEX_op_ld32s_i64, { "r", "r" } },
2136 { INDEX_op_ld_i64, { "r", "r" } },
5c2d2a9e
AJ
2137 { INDEX_op_st8_i64, { "ri", "r" } },
2138 { INDEX_op_st16_i64, { "ri", "r" } },
2139 { INDEX_op_st32_i64, { "ri", "r" } },
2140 { INDEX_op_st_i64, { "re", "r" } },
5d8a4f8f 2141
163fa4b0 2142 { INDEX_op_add_i64, { "r", "r", "re" } },
5d8a4f8f
RH
2143 { INDEX_op_mul_i64, { "r", "0", "re" } },
2144 { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
2145 { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
2146 { INDEX_op_sub_i64, { "r", "0", "re" } },
2147 { INDEX_op_and_i64, { "r", "0", "reZ" } },
2148 { INDEX_op_or_i64, { "r", "0", "re" } },
2149 { INDEX_op_xor_i64, { "r", "0", "re" } },
9d2eec20 2150 { INDEX_op_andc_i64, { "r", "r", "rI" } },
5d8a4f8f 2151
6399ab33
RH
2152 { INDEX_op_shl_i64, { "r", "0", "Ci" } },
2153 { INDEX_op_shr_i64, { "r", "0", "Ci" } },
2154 { INDEX_op_sar_i64, { "r", "0", "Ci" } },
5d8a4f8f
RH
2155 { INDEX_op_rotl_i64, { "r", "0", "ci" } },
2156 { INDEX_op_rotr_i64, { "r", "0", "ci" } },
2157
2158 { INDEX_op_brcond_i64, { "r", "re" } },
2159 { INDEX_op_setcond_i64, { "r", "r", "re" } },
2160
2161 { INDEX_op_bswap16_i64, { "r", "0" } },
2162 { INDEX_op_bswap32_i64, { "r", "0" } },
2163 { INDEX_op_bswap64_i64, { "r", "0" } },
2164 { INDEX_op_neg_i64, { "r", "0" } },
2165 { INDEX_op_not_i64, { "r", "0" } },
2166
2167 { INDEX_op_ext8s_i64, { "r", "r" } },
2168 { INDEX_op_ext16s_i64, { "r", "r" } },
2169 { INDEX_op_ext32s_i64, { "r", "r" } },
2170 { INDEX_op_ext8u_i64, { "r", "r" } },
2171 { INDEX_op_ext16u_i64, { "r", "r" } },
2172 { INDEX_op_ext32u_i64, { "r", "r" } },
a4773324
JK
2173
2174 { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
d0a16297 2175 { INDEX_op_movcond_i64, { "r", "r", "re", "r", "0" } },
624988a5
RH
2176
2177 { INDEX_op_mulu2_i64, { "a", "d", "a", "r" } },
2178 { INDEX_op_muls2_i64, { "a", "d", "a", "r" } },
2179 { INDEX_op_add2_i64, { "r", "r", "0", "1", "re", "re" } },
2180 { INDEX_op_sub2_i64, { "r", "r", "0", "1", "re", "re" } },
5d8a4f8f 2181#endif
1d2699ae 2182
5d8a4f8f 2183#if TCG_TARGET_REG_BITS == 64
8221a267
RH
2184 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2185 { INDEX_op_qemu_st_i32, { "L", "L" } },
2186 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2187 { INDEX_op_qemu_st_i64, { "L", "L" } },
5d8a4f8f 2188#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
8221a267
RH
2189 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2190 { INDEX_op_qemu_st_i32, { "L", "L" } },
2191 { INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
2192 { INDEX_op_qemu_st_i64, { "L", "L", "L" } },
c896fe29 2193#else
8221a267
RH
2194 { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
2195 { INDEX_op_qemu_st_i32, { "L", "L", "L" } },
2196 { INDEX_op_qemu_ld_i64, { "r", "r", "L", "L" } },
2197 { INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
c896fe29
FB
2198#endif
2199 { -1 },
2200};
2201
b03cce8e 2202static int tcg_target_callee_save_regs[] = {
5d8a4f8f
RH
2203#if TCG_TARGET_REG_BITS == 64
2204 TCG_REG_RBP,
2205 TCG_REG_RBX,
8d918718
SW
2206#if defined(_WIN64)
2207 TCG_REG_RDI,
2208 TCG_REG_RSI,
2209#endif
5d8a4f8f
RH
2210 TCG_REG_R12,
2211 TCG_REG_R13,
cea5f9a2 2212 TCG_REG_R14, /* Currently used for the global env. */
5d8a4f8f
RH
2213 TCG_REG_R15,
2214#else
cea5f9a2 2215 TCG_REG_EBP, /* Currently used for the global env. */
b03cce8e
FB
2216 TCG_REG_EBX,
2217 TCG_REG_ESI,
2218 TCG_REG_EDI,
5d8a4f8f 2219#endif
b03cce8e
FB
2220};
2221
813da627
RH
2222/* Compute frame size via macros, to share between tcg_target_qemu_prologue
2223 and tcg_register_jit. */
2224
2225#define PUSH_SIZE \
2226 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
2227 * (TCG_TARGET_REG_BITS / 8))
2228
2229#define FRAME_SIZE \
2230 ((PUSH_SIZE \
2231 + TCG_STATIC_CALL_ARGS_SIZE \
2232 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2233 + TCG_TARGET_STACK_ALIGN - 1) \
2234 & ~(TCG_TARGET_STACK_ALIGN - 1))
2235
b03cce8e 2236/* Generate global QEMU prologue and epilogue code */
e4d58b41 2237static void tcg_target_qemu_prologue(TCGContext *s)
b03cce8e 2238{
813da627 2239 int i, stack_addend;
78686523 2240
b03cce8e 2241 /* TB prologue */
5d8a4f8f 2242
ac0275dc 2243 /* Reserve some stack space, also for TCG temps. */
813da627 2244 stack_addend = FRAME_SIZE - PUSH_SIZE;
ac0275dc
BS
2245 tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2246 CPU_TEMP_BUF_NLONGS * sizeof(long));
2247
2248 /* Save all callee saved registers. */
2249 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
2250 tcg_out_push(s, tcg_target_callee_save_regs[i]);
2251 }
2252
6a18ae2d
BS
2253#if TCG_TARGET_REG_BITS == 32
2254 tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
2255 (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
b18212c6
SW
2256 tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
2257 /* jmp *tb. */
2258 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, TCG_REG_ESP,
2259 (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4
2260 + stack_addend);
6a18ae2d 2261#else
cea5f9a2 2262 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
6a18ae2d 2263 tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
5d8a4f8f 2264 /* jmp *tb. */
cea5f9a2 2265 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
b18212c6 2266#endif
78686523 2267
b03cce8e
FB
2268 /* TB epilogue */
2269 tb_ret_addr = s->code_ptr;
5d8a4f8f 2270
e83c80f7 2271 tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
5d8a4f8f
RH
2272
2273 for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
b03cce8e
FB
2274 tcg_out_pop(s, tcg_target_callee_save_regs[i]);
2275 }
5d8a4f8f 2276 tcg_out_opc(s, OPC_RET, 0, 0, 0);
44b37ace
RH
2277
2278#if !defined(CONFIG_SOFTMMU)
2279 /* Try to set up a segment register to point to GUEST_BASE. */
2280 if (GUEST_BASE) {
2281 setup_guest_base_seg();
2282 }
2283#endif
b03cce8e
FB
2284}
2285
e4d58b41 2286static void tcg_target_init(TCGContext *s)
c896fe29 2287{
774d566c 2288#ifdef CONFIG_CPUID_H
9d2eec20
RH
2289 unsigned a, b, c, d;
2290 int max = __get_cpuid_max(0, 0);
085bb5bb 2291
9d2eec20
RH
2292 if (max >= 1) {
2293 __cpuid(1, a, b, c, d);
2294#ifndef have_cmov
085bb5bb
AJ
2295 /* For 32-bit, 99% certainty that we're running on hardware that
2296 supports cmov, but we still need to check. In case cmov is not
2297 available, we'll use a small forward branch. */
9d2eec20
RH
2298 have_cmov = (d & bit_CMOV) != 0;
2299#endif
2300#ifndef have_movbe
085bb5bb
AJ
2301 /* MOVBE is only available on Intel Atom and Haswell CPUs, so we
2302 need to probe for it. */
9d2eec20
RH
2303 have_movbe = (c & bit_MOVBE) != 0;
2304#endif
76a347e1 2305 }
9d2eec20
RH
2306
2307 if (max >= 7) {
2308 /* BMI1 is available on AMD Piledriver and Intel Haswell CPUs. */
2309 __cpuid_count(7, 0, a, b, c, d);
2310#ifdef bit_BMI
2311 have_bmi1 = (b & bit_BMI) != 0;
6399ab33
RH
2312#endif
2313#ifndef have_bmi2
2314 have_bmi2 = (b & bit_BMI2) != 0;
76a347e1 2315#endif
9d2eec20 2316 }
774d566c 2317#endif
76a347e1 2318
5d8a4f8f
RH
2319 if (TCG_TARGET_REG_BITS == 64) {
2320 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2321 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
2322 } else {
2323 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
2324 }
4ab50ccf
RH
2325
2326 tcg_regset_clear(tcg_target_call_clobber_regs);
2327 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
2328 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
2329 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
5d8a4f8f 2330 if (TCG_TARGET_REG_BITS == 64) {
8d918718 2331#if !defined(_WIN64)
5d8a4f8f
RH
2332 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
2333 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
8d918718 2334#endif
5d8a4f8f
RH
2335 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2336 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2337 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2338 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2339 }
4ab50ccf 2340
c896fe29 2341 tcg_regset_clear(s->reserved_regs);
e83c80f7 2342 tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
c896fe29
FB
2343
2344 tcg_add_target_add_op_defs(x86_op_defs);
2345}
813da627 2346
813da627 2347typedef struct {
e9a9a5b6 2348 DebugFrameHeader h;
497a22eb
RH
2349 uint8_t fde_def_cfa[4];
2350 uint8_t fde_reg_ofs[14];
813da627
RH
2351} DebugFrame;
2352
b5cc476d
RH
2353/* We're expecting a 2 byte uleb128 encoded value. */
2354QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2355
c170cb66
SW
2356#if !defined(__ELF__)
2357 /* Host machine without ELF. */
2358#elif TCG_TARGET_REG_BITS == 64
813da627 2359#define ELF_HOST_MACHINE EM_X86_64
e9a9a5b6
RH
2360static const DebugFrame debug_frame = {
2361 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2362 .h.cie.id = -1,
2363 .h.cie.version = 1,
2364 .h.cie.code_align = 1,
2365 .h.cie.data_align = 0x78, /* sleb128 -8 */
2366 .h.cie.return_column = 16,
813da627 2367
497a22eb 2368 /* Total FDE size does not include the "len" member. */
e9a9a5b6 2369 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
497a22eb
RH
2370
2371 .fde_def_cfa = {
813da627
RH
2372 12, 7, /* DW_CFA_def_cfa %rsp, ... */
2373 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2374 (FRAME_SIZE >> 7)
2375 },
497a22eb 2376 .fde_reg_ofs = {
813da627
RH
2377 0x90, 1, /* DW_CFA_offset, %rip, -8 */
2378 /* The following ordering must match tcg_target_callee_save_regs. */
2379 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
2380 0x83, 3, /* DW_CFA_offset, %rbx, -24 */
2381 0x8c, 4, /* DW_CFA_offset, %r12, -32 */
2382 0x8d, 5, /* DW_CFA_offset, %r13, -40 */
2383 0x8e, 6, /* DW_CFA_offset, %r14, -48 */
2384 0x8f, 7, /* DW_CFA_offset, %r15, -56 */
2385 }
2386};
2387#else
2388#define ELF_HOST_MACHINE EM_386
e9a9a5b6
RH
2389static const DebugFrame debug_frame = {
2390 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2391 .h.cie.id = -1,
2392 .h.cie.version = 1,
2393 .h.cie.code_align = 1,
2394 .h.cie.data_align = 0x7c, /* sleb128 -4 */
2395 .h.cie.return_column = 8,
813da627 2396
497a22eb 2397 /* Total FDE size does not include the "len" member. */
e9a9a5b6 2398 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
497a22eb
RH
2399
2400 .fde_def_cfa = {
813da627
RH
2401 12, 4, /* DW_CFA_def_cfa %esp, ... */
2402 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2403 (FRAME_SIZE >> 7)
2404 },
497a22eb 2405 .fde_reg_ofs = {
813da627
RH
2406 0x88, 1, /* DW_CFA_offset, %eip, -4 */
2407 /* The following ordering must match tcg_target_callee_save_regs. */
2408 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
2409 0x83, 3, /* DW_CFA_offset, %ebx, -12 */
2410 0x86, 4, /* DW_CFA_offset, %esi, -16 */
2411 0x87, 5, /* DW_CFA_offset, %edi, -20 */
2412 }
2413};
2414#endif
2415
c170cb66 2416#if defined(ELF_HOST_MACHINE)
813da627
RH
2417void tcg_register_jit(void *buf, size_t buf_size)
2418{
813da627
RH
2419 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2420}
c170cb66 2421#endif
This page took 1.095181 seconds and 4 git commands to generate.