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