configure: avoid basename usage message
[qemu/ar7.git] / tcg / i386 / tcg-target.c
blobbb19a950bf50b1516ac32975eeb0acd86f600b86
1 /*
2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 #ifndef NDEBUG
26 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
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
34 #endif
36 static const int tcg_target_reg_alloc_order[] = {
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
54 TCG_REG_EBX,
55 TCG_REG_ESI,
56 TCG_REG_EDI,
57 TCG_REG_EBP,
58 TCG_REG_ECX,
59 TCG_REG_EDX,
60 TCG_REG_EAX,
61 #endif
64 static const int tcg_target_call_iarg_regs[] = {
65 #if TCG_TARGET_REG_BITS == 64
66 TCG_REG_RDI,
67 TCG_REG_RSI,
68 TCG_REG_RDX,
69 TCG_REG_RCX,
70 TCG_REG_R8,
71 TCG_REG_R9,
72 #else
73 TCG_REG_EAX,
74 TCG_REG_EDX,
75 TCG_REG_ECX
76 #endif
79 static const int tcg_target_call_oarg_regs[2] = {
80 TCG_REG_EAX,
81 TCG_REG_EDX
84 static uint8_t *tb_ret_addr;
86 static void patch_reloc(uint8_t *code_ptr, int type,
87 tcg_target_long value, tcg_target_long addend)
89 value += addend;
90 switch(type) {
91 case R_386_PC32:
92 value -= (uintptr_t)code_ptr;
93 if (value != (int32_t)value) {
94 tcg_abort();
96 *(uint32_t *)code_ptr = value;
97 break;
98 case R_386_PC8:
99 value -= (uintptr_t)code_ptr;
100 if (value != (int8_t)value) {
101 tcg_abort();
103 *(uint8_t *)code_ptr = value;
104 break;
105 default:
106 tcg_abort();
110 /* maximum number of register used for input function arguments */
111 static inline int tcg_target_get_call_iarg_regs_count(int flags)
113 if (TCG_TARGET_REG_BITS == 64) {
114 return 6;
117 flags &= TCG_CALL_TYPE_MASK;
118 switch(flags) {
119 case TCG_CALL_TYPE_STD:
120 return 0;
121 case TCG_CALL_TYPE_REGPARM_1:
122 case TCG_CALL_TYPE_REGPARM_2:
123 case TCG_CALL_TYPE_REGPARM:
124 return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
125 default:
126 tcg_abort();
130 /* parse target specific constraints */
131 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
133 const char *ct_str;
135 ct_str = *pct_str;
136 switch(ct_str[0]) {
137 case 'a':
138 ct->ct |= TCG_CT_REG;
139 tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
140 break;
141 case 'b':
142 ct->ct |= TCG_CT_REG;
143 tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
144 break;
145 case 'c':
146 ct->ct |= TCG_CT_REG;
147 tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
148 break;
149 case 'd':
150 ct->ct |= TCG_CT_REG;
151 tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
152 break;
153 case 'S':
154 ct->ct |= TCG_CT_REG;
155 tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
156 break;
157 case 'D':
158 ct->ct |= TCG_CT_REG;
159 tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
160 break;
161 case 'q':
162 ct->ct |= TCG_CT_REG;
163 if (TCG_TARGET_REG_BITS == 64) {
164 tcg_regset_set32(ct->u.regs, 0, 0xffff);
165 } else {
166 tcg_regset_set32(ct->u.regs, 0, 0xf);
168 break;
169 case 'r':
170 ct->ct |= TCG_CT_REG;
171 if (TCG_TARGET_REG_BITS == 64) {
172 tcg_regset_set32(ct->u.regs, 0, 0xffff);
173 } else {
174 tcg_regset_set32(ct->u.regs, 0, 0xff);
176 break;
178 /* qemu_ld/st address constraint */
179 case 'L':
180 ct->ct |= TCG_CT_REG;
181 if (TCG_TARGET_REG_BITS == 64) {
182 tcg_regset_set32(ct->u.regs, 0, 0xffff);
183 tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
184 tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
185 } else {
186 tcg_regset_set32(ct->u.regs, 0, 0xff);
187 tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
188 tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
190 break;
192 case 'e':
193 ct->ct |= TCG_CT_CONST_S32;
194 break;
195 case 'Z':
196 ct->ct |= TCG_CT_CONST_U32;
197 break;
199 default:
200 return -1;
202 ct_str++;
203 *pct_str = ct_str;
204 return 0;
207 /* test if a constant matches the constraint */
208 static inline int tcg_target_const_match(tcg_target_long val,
209 const TCGArgConstraint *arg_ct)
211 int ct = arg_ct->ct;
212 if (ct & TCG_CT_CONST) {
213 return 1;
215 if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
216 return 1;
218 if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
219 return 1;
221 return 0;
224 #if TCG_TARGET_REG_BITS == 64
225 # define LOWREGMASK(x) ((x) & 7)
226 #else
227 # define LOWREGMASK(x) (x)
228 #endif
230 #define P_EXT 0x100 /* 0x0f opcode prefix */
231 #define P_DATA16 0x200 /* 0x66 opcode prefix */
232 #if TCG_TARGET_REG_BITS == 64
233 # define P_ADDR32 0x400 /* 0x67 opcode prefix */
234 # define P_REXW 0x800 /* Set REX.W = 1 */
235 # define P_REXB_R 0x1000 /* REG field as byte register */
236 # define P_REXB_RM 0x2000 /* R/M field as byte register */
237 #else
238 # define P_ADDR32 0
239 # define P_REXW 0
240 # define P_REXB_R 0
241 # define P_REXB_RM 0
242 #endif
244 #define OPC_ARITH_EvIz (0x81)
245 #define OPC_ARITH_EvIb (0x83)
246 #define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
247 #define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
248 #define OPC_BSWAP (0xc8 | P_EXT)
249 #define OPC_CALL_Jz (0xe8)
250 #define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
251 #define OPC_DEC_r32 (0x48)
252 #define OPC_IMUL_GvEv (0xaf | P_EXT)
253 #define OPC_IMUL_GvEvIb (0x6b)
254 #define OPC_IMUL_GvEvIz (0x69)
255 #define OPC_INC_r32 (0x40)
256 #define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
257 #define OPC_JCC_short (0x70) /* ... plus condition code */
258 #define OPC_JMP_long (0xe9)
259 #define OPC_JMP_short (0xeb)
260 #define OPC_LEA (0x8d)
261 #define OPC_MOVB_EvGv (0x88) /* stores, more or less */
262 #define OPC_MOVL_EvGv (0x89) /* stores, more or less */
263 #define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
264 #define OPC_MOVL_EvIz (0xc7)
265 #define OPC_MOVL_Iv (0xb8)
266 #define OPC_MOVSBL (0xbe | P_EXT)
267 #define OPC_MOVSWL (0xbf | P_EXT)
268 #define OPC_MOVSLQ (0x63 | P_REXW)
269 #define OPC_MOVZBL (0xb6 | P_EXT)
270 #define OPC_MOVZWL (0xb7 | P_EXT)
271 #define OPC_POP_r32 (0x58)
272 #define OPC_PUSH_r32 (0x50)
273 #define OPC_PUSH_Iv (0x68)
274 #define OPC_PUSH_Ib (0x6a)
275 #define OPC_RET (0xc3)
276 #define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
277 #define OPC_SHIFT_1 (0xd1)
278 #define OPC_SHIFT_Ib (0xc1)
279 #define OPC_SHIFT_cl (0xd3)
280 #define OPC_TESTL (0x85)
281 #define OPC_XCHG_ax_r32 (0x90)
283 #define OPC_GRP3_Ev (0xf7)
284 #define OPC_GRP5 (0xff)
286 /* Group 1 opcode extensions for 0x80-0x83.
287 These are also used as modifiers for OPC_ARITH. */
288 #define ARITH_ADD 0
289 #define ARITH_OR 1
290 #define ARITH_ADC 2
291 #define ARITH_SBB 3
292 #define ARITH_AND 4
293 #define ARITH_SUB 5
294 #define ARITH_XOR 6
295 #define ARITH_CMP 7
297 /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
298 #define SHIFT_ROL 0
299 #define SHIFT_ROR 1
300 #define SHIFT_SHL 4
301 #define SHIFT_SHR 5
302 #define SHIFT_SAR 7
304 /* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
305 #define EXT3_NOT 2
306 #define EXT3_NEG 3
307 #define EXT3_MUL 4
308 #define EXT3_IMUL 5
309 #define EXT3_DIV 6
310 #define EXT3_IDIV 7
312 /* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
313 #define EXT5_INC_Ev 0
314 #define EXT5_DEC_Ev 1
315 #define EXT5_CALLN_Ev 2
316 #define EXT5_JMPN_Ev 4
318 /* Condition codes to be added to OPC_JCC_{long,short}. */
319 #define JCC_JMP (-1)
320 #define JCC_JO 0x0
321 #define JCC_JNO 0x1
322 #define JCC_JB 0x2
323 #define JCC_JAE 0x3
324 #define JCC_JE 0x4
325 #define JCC_JNE 0x5
326 #define JCC_JBE 0x6
327 #define JCC_JA 0x7
328 #define JCC_JS 0x8
329 #define JCC_JNS 0x9
330 #define JCC_JP 0xa
331 #define JCC_JNP 0xb
332 #define JCC_JL 0xc
333 #define JCC_JGE 0xd
334 #define JCC_JLE 0xe
335 #define JCC_JG 0xf
337 static const uint8_t tcg_cond_to_jcc[10] = {
338 [TCG_COND_EQ] = JCC_JE,
339 [TCG_COND_NE] = JCC_JNE,
340 [TCG_COND_LT] = JCC_JL,
341 [TCG_COND_GE] = JCC_JGE,
342 [TCG_COND_LE] = JCC_JLE,
343 [TCG_COND_GT] = JCC_JG,
344 [TCG_COND_LTU] = JCC_JB,
345 [TCG_COND_GEU] = JCC_JAE,
346 [TCG_COND_LEU] = JCC_JBE,
347 [TCG_COND_GTU] = JCC_JA,
350 #if TCG_TARGET_REG_BITS == 64
351 static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
353 int rex;
355 if (opc & P_DATA16) {
356 /* We should never be asking for both 16 and 64-bit operation. */
357 assert((opc & P_REXW) == 0);
358 tcg_out8(s, 0x66);
360 if (opc & P_ADDR32) {
361 tcg_out8(s, 0x67);
364 rex = 0;
365 rex |= (opc & P_REXW) >> 8; /* REX.W */
366 rex |= (r & 8) >> 1; /* REX.R */
367 rex |= (x & 8) >> 2; /* REX.X */
368 rex |= (rm & 8) >> 3; /* REX.B */
370 /* P_REXB_{R,RM} indicates that the given register is the low byte.
371 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
372 as otherwise the encoding indicates %[abcd]h. Note that the values
373 that are ORed in merely indicate that the REX byte must be present;
374 those bits get discarded in output. */
375 rex |= opc & (r >= 4 ? P_REXB_R : 0);
376 rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
378 if (rex) {
379 tcg_out8(s, (uint8_t)(rex | 0x40));
382 if (opc & P_EXT) {
383 tcg_out8(s, 0x0f);
385 tcg_out8(s, opc);
387 #else
388 static void tcg_out_opc(TCGContext *s, int opc)
390 if (opc & P_DATA16) {
391 tcg_out8(s, 0x66);
393 if (opc & P_EXT) {
394 tcg_out8(s, 0x0f);
396 tcg_out8(s, opc);
398 /* Discard the register arguments to tcg_out_opc early, so as not to penalize
399 the 32-bit compilation paths. This method works with all versions of gcc,
400 whereas relying on optimization may not be able to exclude them. */
401 #define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
402 #endif
404 static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
406 tcg_out_opc(s, opc, r, rm, 0);
407 tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
410 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
411 We handle either RM and INDEX missing with a negative value. In 64-bit
412 mode for absolute addresses, ~RM is the size of the immediate operand
413 that will follow the instruction. */
415 static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
416 int index, int shift,
417 tcg_target_long offset)
419 int mod, len;
421 if (index < 0 && rm < 0) {
422 if (TCG_TARGET_REG_BITS == 64) {
423 /* Try for a rip-relative addressing mode. This has replaced
424 the 32-bit-mode absolute addressing encoding. */
425 tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
426 tcg_target_long disp = offset - pc;
427 if (disp == (int32_t)disp) {
428 tcg_out_opc(s, opc, r, 0, 0);
429 tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
430 tcg_out32(s, disp);
431 return;
434 /* Try for an absolute address encoding. This requires the
435 use of the MODRM+SIB encoding and is therefore larger than
436 rip-relative addressing. */
437 if (offset == (int32_t)offset) {
438 tcg_out_opc(s, opc, r, 0, 0);
439 tcg_out8(s, (LOWREGMASK(r) << 3) | 4);
440 tcg_out8(s, (4 << 3) | 5);
441 tcg_out32(s, offset);
442 return;
445 /* ??? The memory isn't directly addressable. */
446 tcg_abort();
447 } else {
448 /* Absolute address. */
449 tcg_out_opc(s, opc, r, 0, 0);
450 tcg_out8(s, (r << 3) | 5);
451 tcg_out32(s, offset);
452 return;
456 /* Find the length of the immediate addend. Note that the encoding
457 that would be used for (%ebp) indicates absolute addressing. */
458 if (rm < 0) {
459 mod = 0, len = 4, rm = 5;
460 } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) {
461 mod = 0, len = 0;
462 } else if (offset == (int8_t)offset) {
463 mod = 0x40, len = 1;
464 } else {
465 mod = 0x80, len = 4;
468 /* Use a single byte MODRM format if possible. Note that the encoding
469 that would be used for %esp is the escape to the two byte form. */
470 if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) {
471 /* Single byte MODRM format. */
472 tcg_out_opc(s, opc, r, rm, 0);
473 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
474 } else {
475 /* Two byte MODRM+SIB format. */
477 /* Note that the encoding that would place %esp into the index
478 field indicates no index register. In 64-bit mode, the REX.X
479 bit counts, so %r12 can be used as the index. */
480 if (index < 0) {
481 index = 4;
482 } else {
483 assert(index != TCG_REG_ESP);
486 tcg_out_opc(s, opc, r, rm, index);
487 tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4);
488 tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm));
491 if (len == 1) {
492 tcg_out8(s, offset);
493 } else if (len == 4) {
494 tcg_out32(s, offset);
498 /* A simplification of the above with no index or shift. */
499 static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
500 int rm, tcg_target_long offset)
502 tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
505 /* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
506 static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
508 /* Propagate an opcode prefix, such as P_REXW. */
509 int ext = subop & ~0x7;
510 subop &= 0x7;
512 tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
515 static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg)
517 if (arg != ret) {
518 int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
519 tcg_out_modrm(s, opc, ret, arg);
523 static void tcg_out_movi(TCGContext *s, TCGType type,
524 int ret, tcg_target_long arg)
526 if (arg == 0) {
527 tgen_arithr(s, ARITH_XOR, ret, ret);
528 return;
529 } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
530 tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
531 tcg_out32(s, arg);
532 } else if (arg == (int32_t)arg) {
533 tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
534 tcg_out32(s, arg);
535 } else {
536 tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
537 tcg_out32(s, arg);
538 tcg_out32(s, arg >> 31 >> 1);
542 static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
544 if (val == (int8_t)val) {
545 tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
546 tcg_out8(s, val);
547 } else if (val == (int32_t)val) {
548 tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
549 tcg_out32(s, val);
550 } else {
551 tcg_abort();
555 static inline void tcg_out_push(TCGContext *s, int reg)
557 tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
560 static inline void tcg_out_pop(TCGContext *s, int reg)
562 tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
565 static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
566 int arg1, tcg_target_long arg2)
568 int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
569 tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
572 static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
573 int arg1, tcg_target_long arg2)
575 int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
576 tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
579 static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
581 /* Propagate an opcode prefix, such as P_DATA16. */
582 int ext = subopc & ~0x7;
583 subopc &= 0x7;
585 if (count == 1) {
586 tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
587 } else {
588 tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
589 tcg_out8(s, count);
593 static inline void tcg_out_bswap32(TCGContext *s, int reg)
595 tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
598 static inline void tcg_out_rolw_8(TCGContext *s, int reg)
600 tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
603 static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
605 /* movzbl */
606 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
607 tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
610 static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
612 /* movsbl */
613 assert(src < 4 || TCG_TARGET_REG_BITS == 64);
614 tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
617 static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
619 /* movzwl */
620 tcg_out_modrm(s, OPC_MOVZWL, dest, src);
623 static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
625 /* movsw[lq] */
626 tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
629 static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
631 /* 32-bit mov zero extends. */
632 tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
635 static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
637 tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
640 static inline void tcg_out_bswap64(TCGContext *s, int reg)
642 tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
645 static void tgen_arithi(TCGContext *s, int c, int r0,
646 tcg_target_long val, int cf)
648 int rexw = 0;
650 if (TCG_TARGET_REG_BITS == 64) {
651 rexw = c & -8;
652 c &= 7;
655 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
656 partial flags update stalls on Pentium4 and are not recommended
657 by current Intel optimization manuals. */
658 if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
659 int is_inc = (c == ARITH_ADD) ^ (val < 0);
660 if (TCG_TARGET_REG_BITS == 64) {
661 /* The single-byte increment encodings are re-tasked as the
662 REX prefixes. Use the MODRM encoding. */
663 tcg_out_modrm(s, OPC_GRP5 + rexw,
664 (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
665 } else {
666 tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
668 return;
671 if (c == ARITH_AND) {
672 if (TCG_TARGET_REG_BITS == 64) {
673 if (val == 0xffffffffu) {
674 tcg_out_ext32u(s, r0, r0);
675 return;
677 if (val == (uint32_t)val) {
678 /* AND with no high bits set can use a 32-bit operation. */
679 rexw = 0;
682 if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
683 tcg_out_ext8u(s, r0, r0);
684 return;
686 if (val == 0xffffu) {
687 tcg_out_ext16u(s, r0, r0);
688 return;
692 if (val == (int8_t)val) {
693 tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
694 tcg_out8(s, val);
695 return;
697 if (rexw == 0 || val == (int32_t)val) {
698 tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
699 tcg_out32(s, val);
700 return;
703 tcg_abort();
706 static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
708 if (val != 0) {
709 tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
713 /* Use SMALL != 0 to force a short forward branch. */
714 static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
716 int32_t val, val1;
717 TCGLabel *l = &s->labels[label_index];
719 if (l->has_value) {
720 val = l->u.value - (tcg_target_long)s->code_ptr;
721 val1 = val - 2;
722 if ((int8_t)val1 == val1) {
723 if (opc == -1) {
724 tcg_out8(s, OPC_JMP_short);
725 } else {
726 tcg_out8(s, OPC_JCC_short + opc);
728 tcg_out8(s, val1);
729 } else {
730 if (small) {
731 tcg_abort();
733 if (opc == -1) {
734 tcg_out8(s, OPC_JMP_long);
735 tcg_out32(s, val - 5);
736 } else {
737 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
738 tcg_out32(s, val - 6);
741 } else if (small) {
742 if (opc == -1) {
743 tcg_out8(s, OPC_JMP_short);
744 } else {
745 tcg_out8(s, OPC_JCC_short + opc);
747 tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
748 s->code_ptr += 1;
749 } else {
750 if (opc == -1) {
751 tcg_out8(s, OPC_JMP_long);
752 } else {
753 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
755 tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
756 s->code_ptr += 4;
760 static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
761 int const_arg2, int rexw)
763 if (const_arg2) {
764 if (arg2 == 0) {
765 /* test r, r */
766 tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
767 } else {
768 tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
770 } else {
771 tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
775 static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
776 TCGArg arg1, TCGArg arg2, int const_arg2,
777 int label_index, int small)
779 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
780 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
783 #if TCG_TARGET_REG_BITS == 64
784 static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
785 TCGArg arg1, TCGArg arg2, int const_arg2,
786 int label_index, int small)
788 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
789 tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
791 #else
792 /* XXX: we implement it at the target level to avoid having to
793 handle cross basic blocks temporaries */
794 static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
795 const int *const_args, int small)
797 int label_next;
798 label_next = gen_new_label();
799 switch(args[4]) {
800 case TCG_COND_EQ:
801 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
802 label_next, 1);
803 tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
804 args[5], small);
805 break;
806 case TCG_COND_NE:
807 tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
808 args[5], small);
809 tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
810 args[5], small);
811 break;
812 case TCG_COND_LT:
813 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
814 args[5], small);
815 tcg_out_jxx(s, JCC_JNE, label_next, 1);
816 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
817 args[5], small);
818 break;
819 case TCG_COND_LE:
820 tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
821 args[5], small);
822 tcg_out_jxx(s, JCC_JNE, label_next, 1);
823 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
824 args[5], small);
825 break;
826 case TCG_COND_GT:
827 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
828 args[5], small);
829 tcg_out_jxx(s, JCC_JNE, label_next, 1);
830 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
831 args[5], small);
832 break;
833 case TCG_COND_GE:
834 tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
835 args[5], small);
836 tcg_out_jxx(s, JCC_JNE, label_next, 1);
837 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
838 args[5], small);
839 break;
840 case TCG_COND_LTU:
841 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
842 args[5], small);
843 tcg_out_jxx(s, JCC_JNE, label_next, 1);
844 tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
845 args[5], small);
846 break;
847 case TCG_COND_LEU:
848 tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
849 args[5], small);
850 tcg_out_jxx(s, JCC_JNE, label_next, 1);
851 tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
852 args[5], small);
853 break;
854 case TCG_COND_GTU:
855 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
856 args[5], small);
857 tcg_out_jxx(s, JCC_JNE, label_next, 1);
858 tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
859 args[5], small);
860 break;
861 case TCG_COND_GEU:
862 tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
863 args[5], small);
864 tcg_out_jxx(s, JCC_JNE, label_next, 1);
865 tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
866 args[5], small);
867 break;
868 default:
869 tcg_abort();
871 tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
873 #endif
875 static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
876 TCGArg arg1, TCGArg arg2, int const_arg2)
878 tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
879 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
880 tcg_out_ext8u(s, dest, dest);
883 #if TCG_TARGET_REG_BITS == 64
884 static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
885 TCGArg arg1, TCGArg arg2, int const_arg2)
887 tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
888 tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
889 tcg_out_ext8u(s, dest, dest);
891 #else
892 static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
893 const int *const_args)
895 TCGArg new_args[6];
896 int label_true, label_over;
898 memcpy(new_args, args+1, 5*sizeof(TCGArg));
900 if (args[0] == args[1] || args[0] == args[2]
901 || (!const_args[3] && args[0] == args[3])
902 || (!const_args[4] && args[0] == args[4])) {
903 /* When the destination overlaps with one of the argument
904 registers, don't do anything tricky. */
905 label_true = gen_new_label();
906 label_over = gen_new_label();
908 new_args[5] = label_true;
909 tcg_out_brcond2(s, new_args, const_args+1, 1);
911 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
912 tcg_out_jxx(s, JCC_JMP, label_over, 1);
913 tcg_out_label(s, label_true, (tcg_target_long)s->code_ptr);
915 tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
916 tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
917 } else {
918 /* When the destination does not overlap one of the arguments,
919 clear the destination first, jump if cond false, and emit an
920 increment in the true case. This results in smaller code. */
922 tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
924 label_over = gen_new_label();
925 new_args[4] = tcg_invert_cond(new_args[4]);
926 new_args[5] = label_over;
927 tcg_out_brcond2(s, new_args, const_args+1, 1);
929 tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
930 tcg_out_label(s, label_over, (tcg_target_long)s->code_ptr);
933 #endif
935 static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
937 tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
939 if (disp == (int32_t)disp) {
940 tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
941 tcg_out32(s, disp);
942 } else {
943 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
944 tcg_out_modrm(s, OPC_GRP5,
945 call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
949 static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
951 tcg_out_branch(s, 1, dest);
954 static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
956 tcg_out_branch(s, 0, dest);
959 #if defined(CONFIG_SOFTMMU)
961 #include "../../softmmu_defs.h"
963 static void *qemu_ld_helpers[4] = {
964 __ldb_mmu,
965 __ldw_mmu,
966 __ldl_mmu,
967 __ldq_mmu,
970 static void *qemu_st_helpers[4] = {
971 __stb_mmu,
972 __stw_mmu,
973 __stl_mmu,
974 __stq_mmu,
977 /* Perform the TLB load and compare.
979 Inputs:
980 ADDRLO_IDX contains the index into ARGS of the low part of the
981 address; the high part of the address is at ADDR_LOW_IDX+1.
983 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
985 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
986 This should be offsetof addr_read or addr_write.
988 Outputs:
989 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
990 positions of the displacements of forward jumps to the TLB miss case.
992 First argument register is loaded with the low part of the address.
993 In the TLB hit case, it has been adjusted as indicated by the TLB
994 and so is a host address. In the TLB miss case, it continues to
995 hold a guest address.
997 Second argument register is clobbered. */
999 static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
1000 int mem_index, int s_bits,
1001 const TCGArg *args,
1002 uint8_t **label_ptr, int which)
1004 const int addrlo = args[addrlo_idx];
1005 const int r0 = tcg_target_call_iarg_regs[0];
1006 const int r1 = tcg_target_call_iarg_regs[1];
1007 TCGType type = TCG_TYPE_I32;
1008 int rexw = 0;
1010 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
1011 type = TCG_TYPE_I64;
1012 rexw = P_REXW;
1015 tcg_out_mov(s, type, r1, addrlo);
1016 tcg_out_mov(s, type, r0, addrlo);
1018 tcg_out_shifti(s, SHIFT_SHR + rexw, r1,
1019 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1021 tgen_arithi(s, ARITH_AND + rexw, r0,
1022 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
1023 tgen_arithi(s, ARITH_AND + rexw, r1,
1024 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
1026 tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
1027 offsetof(CPUState, tlb_table[mem_index][0])
1028 + which);
1030 /* cmp 0(r1), r0 */
1031 tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r0, r1, 0);
1033 tcg_out_mov(s, type, r0, addrlo);
1035 /* jne label1 */
1036 tcg_out8(s, OPC_JCC_short + JCC_JNE);
1037 label_ptr[0] = s->code_ptr;
1038 s->code_ptr++;
1040 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1041 /* cmp 4(r1), addrhi */
1042 tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
1044 /* jne label1 */
1045 tcg_out8(s, OPC_JCC_short + JCC_JNE);
1046 label_ptr[1] = s->code_ptr;
1047 s->code_ptr++;
1050 /* TLB Hit. */
1052 /* add addend(r1), r0 */
1053 tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r0, r1,
1054 offsetof(CPUTLBEntry, addend) - which);
1056 #endif
1058 static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
1059 int base, tcg_target_long ofs, int sizeop)
1061 #ifdef TARGET_WORDS_BIGENDIAN
1062 const int bswap = 1;
1063 #else
1064 const int bswap = 0;
1065 #endif
1066 switch (sizeop) {
1067 case 0:
1068 tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
1069 break;
1070 case 0 | 4:
1071 tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW, datalo, base, ofs);
1072 break;
1073 case 1:
1074 tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
1075 if (bswap) {
1076 tcg_out_rolw_8(s, datalo);
1078 break;
1079 case 1 | 4:
1080 if (bswap) {
1081 tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
1082 tcg_out_rolw_8(s, datalo);
1083 tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
1084 } else {
1085 tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW, datalo, base, ofs);
1087 break;
1088 case 2:
1089 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1090 if (bswap) {
1091 tcg_out_bswap32(s, datalo);
1093 break;
1094 #if TCG_TARGET_REG_BITS == 64
1095 case 2 | 4:
1096 if (bswap) {
1097 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1098 tcg_out_bswap32(s, datalo);
1099 tcg_out_ext32s(s, datalo, datalo);
1100 } else {
1101 tcg_out_modrm_offset(s, OPC_MOVSLQ, datalo, base, ofs);
1103 break;
1104 #endif
1105 case 3:
1106 if (TCG_TARGET_REG_BITS == 64) {
1107 tcg_out_ld(s, TCG_TYPE_I64, datalo, base, ofs);
1108 if (bswap) {
1109 tcg_out_bswap64(s, datalo);
1111 } else {
1112 if (bswap) {
1113 int t = datalo;
1114 datalo = datahi;
1115 datahi = t;
1117 if (base != datalo) {
1118 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1119 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1120 } else {
1121 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1122 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
1124 if (bswap) {
1125 tcg_out_bswap32(s, datalo);
1126 tcg_out_bswap32(s, datahi);
1129 break;
1130 default:
1131 tcg_abort();
1135 /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1136 EAX. It will be useful once fixed registers globals are less
1137 common. */
1138 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
1139 int opc)
1141 int data_reg, data_reg2 = 0;
1142 int addrlo_idx;
1143 #if defined(CONFIG_SOFTMMU)
1144 int mem_index, s_bits, arg_idx;
1145 uint8_t *label_ptr[3];
1146 #endif
1148 data_reg = args[0];
1149 addrlo_idx = 1;
1150 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
1151 data_reg2 = args[1];
1152 addrlo_idx = 2;
1155 #if defined(CONFIG_SOFTMMU)
1156 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
1157 s_bits = opc & 3;
1159 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1160 label_ptr, offsetof(CPUTLBEntry, addr_read));
1162 /* TLB Hit. */
1163 tcg_out_qemu_ld_direct(s, data_reg, data_reg2,
1164 tcg_target_call_iarg_regs[0], 0, opc);
1166 /* jmp label2 */
1167 tcg_out8(s, OPC_JMP_short);
1168 label_ptr[2] = s->code_ptr;
1169 s->code_ptr++;
1171 /* TLB Miss. */
1173 /* label1: */
1174 *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
1175 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1176 *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1179 /* XXX: move that code at the end of the TB */
1180 /* The first argument is already loaded with addrlo. */
1181 arg_idx = 1;
1182 if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
1183 tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++],
1184 args[addrlo_idx + 1]);
1186 tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
1187 mem_index);
1188 tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
1190 switch(opc) {
1191 case 0 | 4:
1192 tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
1193 break;
1194 case 1 | 4:
1195 tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
1196 break;
1197 case 0:
1198 tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
1199 break;
1200 case 1:
1201 tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
1202 break;
1203 case 2:
1204 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1205 break;
1206 #if TCG_TARGET_REG_BITS == 64
1207 case 2 | 4:
1208 tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1209 break;
1210 #endif
1211 case 3:
1212 if (TCG_TARGET_REG_BITS == 64) {
1213 tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
1214 } else if (data_reg == TCG_REG_EDX) {
1215 /* xchg %edx, %eax */
1216 tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
1217 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
1218 } else {
1219 tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
1220 tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
1222 break;
1223 default:
1224 tcg_abort();
1227 /* label2: */
1228 *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1229 #else
1231 int32_t offset = GUEST_BASE;
1232 int base = args[addrlo_idx];
1234 if (TCG_TARGET_REG_BITS == 64) {
1235 /* ??? We assume all operations have left us with register
1236 contents that are zero extended. So far this appears to
1237 be true. If we want to enforce this, we can either do
1238 an explicit zero-extension here, or (if GUEST_BASE == 0)
1239 use the ADDR32 prefix. For now, do nothing. */
1241 if (offset != GUEST_BASE) {
1242 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
1243 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
1244 base = TCG_REG_RDI, offset = 0;
1248 tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, opc);
1250 #endif
1253 static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
1254 int base, tcg_target_long ofs, int sizeop)
1256 #ifdef TARGET_WORDS_BIGENDIAN
1257 const int bswap = 1;
1258 #else
1259 const int bswap = 0;
1260 #endif
1261 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1262 we could perform the bswap twice to restore the original value
1263 instead of moving to the scratch. But as it is, the L constraint
1264 means that the second argument reg is definitely free here. */
1265 int scratch = tcg_target_call_iarg_regs[1];
1267 switch (sizeop) {
1268 case 0:
1269 tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
1270 break;
1271 case 1:
1272 if (bswap) {
1273 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1274 tcg_out_rolw_8(s, scratch);
1275 datalo = scratch;
1277 tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16, datalo, base, ofs);
1278 break;
1279 case 2:
1280 if (bswap) {
1281 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1282 tcg_out_bswap32(s, scratch);
1283 datalo = scratch;
1285 tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1286 break;
1287 case 3:
1288 if (TCG_TARGET_REG_BITS == 64) {
1289 if (bswap) {
1290 tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
1291 tcg_out_bswap64(s, scratch);
1292 datalo = scratch;
1294 tcg_out_st(s, TCG_TYPE_I64, datalo, base, ofs);
1295 } else if (bswap) {
1296 tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
1297 tcg_out_bswap32(s, scratch);
1298 tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
1299 tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
1300 tcg_out_bswap32(s, scratch);
1301 tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
1302 } else {
1303 tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1304 tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1306 break;
1307 default:
1308 tcg_abort();
1312 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1313 int opc)
1315 int data_reg, data_reg2 = 0;
1316 int addrlo_idx;
1317 #if defined(CONFIG_SOFTMMU)
1318 int mem_index, s_bits;
1319 int stack_adjust;
1320 uint8_t *label_ptr[3];
1321 #endif
1323 data_reg = args[0];
1324 addrlo_idx = 1;
1325 if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
1326 data_reg2 = args[1];
1327 addrlo_idx = 2;
1330 #if defined(CONFIG_SOFTMMU)
1331 mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
1332 s_bits = opc;
1334 tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
1335 label_ptr, offsetof(CPUTLBEntry, addr_write));
1337 /* TLB Hit. */
1338 tcg_out_qemu_st_direct(s, data_reg, data_reg2,
1339 tcg_target_call_iarg_regs[0], 0, opc);
1341 /* jmp label2 */
1342 tcg_out8(s, OPC_JMP_short);
1343 label_ptr[2] = s->code_ptr;
1344 s->code_ptr++;
1346 /* TLB Miss. */
1348 /* label1: */
1349 *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
1350 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1351 *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
1354 /* XXX: move that code at the end of the TB */
1355 if (TCG_TARGET_REG_BITS == 64) {
1356 tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
1357 TCG_REG_RSI, data_reg);
1358 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
1359 stack_adjust = 0;
1360 } else if (TARGET_LONG_BITS == 32) {
1361 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg);
1362 if (opc == 3) {
1363 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg2);
1364 tcg_out_pushi(s, mem_index);
1365 stack_adjust = 4;
1366 } else {
1367 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
1368 stack_adjust = 0;
1370 } else {
1371 if (opc == 3) {
1372 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
1373 tcg_out_pushi(s, mem_index);
1374 tcg_out_push(s, data_reg2);
1375 tcg_out_push(s, data_reg);
1376 stack_adjust = 12;
1377 } else {
1378 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
1379 switch(opc) {
1380 case 0:
1381 tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
1382 break;
1383 case 1:
1384 tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
1385 break;
1386 case 2:
1387 tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg);
1388 break;
1390 tcg_out_pushi(s, mem_index);
1391 stack_adjust = 4;
1395 tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1397 if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
1398 /* Pop and discard. This is 2 bytes smaller than the add. */
1399 tcg_out_pop(s, TCG_REG_ECX);
1400 } else if (stack_adjust != 0) {
1401 tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
1404 /* label2: */
1405 *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1406 #else
1408 int32_t offset = GUEST_BASE;
1409 int base = args[addrlo_idx];
1411 if (TCG_TARGET_REG_BITS == 64) {
1412 /* ??? We assume all operations have left us with register
1413 contents that are zero extended. So far this appears to
1414 be true. If we want to enforce this, we can either do
1415 an explicit zero-extension here, or (if GUEST_BASE == 0)
1416 use the ADDR32 prefix. For now, do nothing. */
1418 if (offset != GUEST_BASE) {
1419 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
1420 tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
1421 base = TCG_REG_RDI, offset = 0;
1425 tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, opc);
1427 #endif
1430 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1431 const TCGArg *args, const int *const_args)
1433 int c, rexw = 0;
1435 #if TCG_TARGET_REG_BITS == 64
1436 # define OP_32_64(x) \
1437 case glue(glue(INDEX_op_, x), _i64): \
1438 rexw = P_REXW; /* FALLTHRU */ \
1439 case glue(glue(INDEX_op_, x), _i32)
1440 #else
1441 # define OP_32_64(x) \
1442 case glue(glue(INDEX_op_, x), _i32)
1443 #endif
1445 switch(opc) {
1446 case INDEX_op_exit_tb:
1447 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
1448 tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
1449 break;
1450 case INDEX_op_goto_tb:
1451 if (s->tb_jmp_offset) {
1452 /* direct jump method */
1453 tcg_out8(s, OPC_JMP_long); /* jmp im */
1454 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1455 tcg_out32(s, 0);
1456 } else {
1457 /* indirect jump method */
1458 tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1459 (tcg_target_long)(s->tb_next + args[0]));
1461 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1462 break;
1463 case INDEX_op_call:
1464 if (const_args[0]) {
1465 tcg_out_calli(s, args[0]);
1466 } else {
1467 /* call *reg */
1468 tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1470 break;
1471 case INDEX_op_jmp:
1472 if (const_args[0]) {
1473 tcg_out_jmp(s, args[0]);
1474 } else {
1475 /* jmp *reg */
1476 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1478 break;
1479 case INDEX_op_br:
1480 tcg_out_jxx(s, JCC_JMP, args[0], 0);
1481 break;
1482 case INDEX_op_movi_i32:
1483 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1484 break;
1485 OP_32_64(ld8u):
1486 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1487 tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
1488 break;
1489 OP_32_64(ld8s):
1490 tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
1491 break;
1492 OP_32_64(ld16u):
1493 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1494 tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1495 break;
1496 OP_32_64(ld16s):
1497 tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
1498 break;
1499 #if TCG_TARGET_REG_BITS == 64
1500 case INDEX_op_ld32u_i64:
1501 #endif
1502 case INDEX_op_ld_i32:
1503 tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1504 break;
1506 OP_32_64(st8):
1507 tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
1508 args[0], args[1], args[2]);
1509 break;
1510 OP_32_64(st16):
1511 tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1512 args[0], args[1], args[2]);
1513 break;
1514 #if TCG_TARGET_REG_BITS == 64
1515 case INDEX_op_st32_i64:
1516 #endif
1517 case INDEX_op_st_i32:
1518 tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1519 break;
1521 OP_32_64(add):
1522 /* For 3-operand addition, use LEA. */
1523 if (args[0] != args[1]) {
1524 TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
1526 if (const_args[2]) {
1527 c3 = a2, a2 = -1;
1528 } else if (a0 == a2) {
1529 /* Watch out for dest = src + dest, since we've removed
1530 the matching constraint on the add. */
1531 tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
1532 break;
1535 tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
1536 break;
1538 c = ARITH_ADD;
1539 goto gen_arith;
1540 OP_32_64(sub):
1541 c = ARITH_SUB;
1542 goto gen_arith;
1543 OP_32_64(and):
1544 c = ARITH_AND;
1545 goto gen_arith;
1546 OP_32_64(or):
1547 c = ARITH_OR;
1548 goto gen_arith;
1549 OP_32_64(xor):
1550 c = ARITH_XOR;
1551 goto gen_arith;
1552 gen_arith:
1553 if (const_args[2]) {
1554 tgen_arithi(s, c + rexw, args[0], args[2], 0);
1555 } else {
1556 tgen_arithr(s, c + rexw, args[0], args[2]);
1558 break;
1560 OP_32_64(mul):
1561 if (const_args[2]) {
1562 int32_t val;
1563 val = args[2];
1564 if (val == (int8_t)val) {
1565 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
1566 tcg_out8(s, val);
1567 } else {
1568 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
1569 tcg_out32(s, val);
1571 } else {
1572 tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
1574 break;
1576 OP_32_64(div2):
1577 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
1578 break;
1579 OP_32_64(divu2):
1580 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
1581 break;
1583 OP_32_64(shl):
1584 c = SHIFT_SHL;
1585 goto gen_shift;
1586 OP_32_64(shr):
1587 c = SHIFT_SHR;
1588 goto gen_shift;
1589 OP_32_64(sar):
1590 c = SHIFT_SAR;
1591 goto gen_shift;
1592 OP_32_64(rotl):
1593 c = SHIFT_ROL;
1594 goto gen_shift;
1595 OP_32_64(rotr):
1596 c = SHIFT_ROR;
1597 goto gen_shift;
1598 gen_shift:
1599 if (const_args[2]) {
1600 tcg_out_shifti(s, c + rexw, args[0], args[2]);
1601 } else {
1602 tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
1604 break;
1606 case INDEX_op_brcond_i32:
1607 tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
1608 args[3], 0);
1609 break;
1610 case INDEX_op_setcond_i32:
1611 tcg_out_setcond32(s, args[3], args[0], args[1],
1612 args[2], const_args[2]);
1613 break;
1615 OP_32_64(bswap16):
1616 tcg_out_rolw_8(s, args[0]);
1617 break;
1618 OP_32_64(bswap32):
1619 tcg_out_bswap32(s, args[0]);
1620 break;
1622 OP_32_64(neg):
1623 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
1624 break;
1625 OP_32_64(not):
1626 tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
1627 break;
1629 OP_32_64(ext8s):
1630 tcg_out_ext8s(s, args[0], args[1], rexw);
1631 break;
1632 OP_32_64(ext16s):
1633 tcg_out_ext16s(s, args[0], args[1], rexw);
1634 break;
1635 OP_32_64(ext8u):
1636 tcg_out_ext8u(s, args[0], args[1]);
1637 break;
1638 OP_32_64(ext16u):
1639 tcg_out_ext16u(s, args[0], args[1]);
1640 break;
1642 case INDEX_op_qemu_ld8u:
1643 tcg_out_qemu_ld(s, args, 0);
1644 break;
1645 case INDEX_op_qemu_ld8s:
1646 tcg_out_qemu_ld(s, args, 0 | 4);
1647 break;
1648 case INDEX_op_qemu_ld16u:
1649 tcg_out_qemu_ld(s, args, 1);
1650 break;
1651 case INDEX_op_qemu_ld16s:
1652 tcg_out_qemu_ld(s, args, 1 | 4);
1653 break;
1654 #if TCG_TARGET_REG_BITS == 64
1655 case INDEX_op_qemu_ld32u:
1656 #endif
1657 case INDEX_op_qemu_ld32:
1658 tcg_out_qemu_ld(s, args, 2);
1659 break;
1660 case INDEX_op_qemu_ld64:
1661 tcg_out_qemu_ld(s, args, 3);
1662 break;
1664 case INDEX_op_qemu_st8:
1665 tcg_out_qemu_st(s, args, 0);
1666 break;
1667 case INDEX_op_qemu_st16:
1668 tcg_out_qemu_st(s, args, 1);
1669 break;
1670 case INDEX_op_qemu_st32:
1671 tcg_out_qemu_st(s, args, 2);
1672 break;
1673 case INDEX_op_qemu_st64:
1674 tcg_out_qemu_st(s, args, 3);
1675 break;
1677 #if TCG_TARGET_REG_BITS == 32
1678 case INDEX_op_brcond2_i32:
1679 tcg_out_brcond2(s, args, const_args, 0);
1680 break;
1681 case INDEX_op_setcond2_i32:
1682 tcg_out_setcond2(s, args, const_args);
1683 break;
1684 case INDEX_op_mulu2_i32:
1685 tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
1686 break;
1687 case INDEX_op_add2_i32:
1688 if (const_args[4]) {
1689 tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
1690 } else {
1691 tgen_arithr(s, ARITH_ADD, args[0], args[4]);
1693 if (const_args[5]) {
1694 tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
1695 } else {
1696 tgen_arithr(s, ARITH_ADC, args[1], args[5]);
1698 break;
1699 case INDEX_op_sub2_i32:
1700 if (const_args[4]) {
1701 tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
1702 } else {
1703 tgen_arithr(s, ARITH_SUB, args[0], args[4]);
1705 if (const_args[5]) {
1706 tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
1707 } else {
1708 tgen_arithr(s, ARITH_SBB, args[1], args[5]);
1710 break;
1711 #else /* TCG_TARGET_REG_BITS == 64 */
1712 case INDEX_op_movi_i64:
1713 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1714 break;
1715 case INDEX_op_ld32s_i64:
1716 tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
1717 break;
1718 case INDEX_op_ld_i64:
1719 tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1720 break;
1721 case INDEX_op_st_i64:
1722 tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
1723 break;
1724 case INDEX_op_qemu_ld32s:
1725 tcg_out_qemu_ld(s, args, 2 | 4);
1726 break;
1728 case INDEX_op_brcond_i64:
1729 tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
1730 args[3], 0);
1731 break;
1732 case INDEX_op_setcond_i64:
1733 tcg_out_setcond64(s, args[3], args[0], args[1],
1734 args[2], const_args[2]);
1735 break;
1737 case INDEX_op_bswap64_i64:
1738 tcg_out_bswap64(s, args[0]);
1739 break;
1740 case INDEX_op_ext32u_i64:
1741 tcg_out_ext32u(s, args[0], args[1]);
1742 break;
1743 case INDEX_op_ext32s_i64:
1744 tcg_out_ext32s(s, args[0], args[1]);
1745 break;
1746 #endif
1748 default:
1749 tcg_abort();
1752 #undef OP_32_64
1755 static const TCGTargetOpDef x86_op_defs[] = {
1756 { INDEX_op_exit_tb, { } },
1757 { INDEX_op_goto_tb, { } },
1758 { INDEX_op_call, { "ri" } },
1759 { INDEX_op_jmp, { "ri" } },
1760 { INDEX_op_br, { } },
1761 { INDEX_op_mov_i32, { "r", "r" } },
1762 { INDEX_op_movi_i32, { "r" } },
1763 { INDEX_op_ld8u_i32, { "r", "r" } },
1764 { INDEX_op_ld8s_i32, { "r", "r" } },
1765 { INDEX_op_ld16u_i32, { "r", "r" } },
1766 { INDEX_op_ld16s_i32, { "r", "r" } },
1767 { INDEX_op_ld_i32, { "r", "r" } },
1768 { INDEX_op_st8_i32, { "q", "r" } },
1769 { INDEX_op_st16_i32, { "r", "r" } },
1770 { INDEX_op_st_i32, { "r", "r" } },
1772 { INDEX_op_add_i32, { "r", "r", "ri" } },
1773 { INDEX_op_sub_i32, { "r", "0", "ri" } },
1774 { INDEX_op_mul_i32, { "r", "0", "ri" } },
1775 { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1776 { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1777 { INDEX_op_and_i32, { "r", "0", "ri" } },
1778 { INDEX_op_or_i32, { "r", "0", "ri" } },
1779 { INDEX_op_xor_i32, { "r", "0", "ri" } },
1781 { INDEX_op_shl_i32, { "r", "0", "ci" } },
1782 { INDEX_op_shr_i32, { "r", "0", "ci" } },
1783 { INDEX_op_sar_i32, { "r", "0", "ci" } },
1784 { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1785 { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1787 { INDEX_op_brcond_i32, { "r", "ri" } },
1789 { INDEX_op_bswap16_i32, { "r", "0" } },
1790 { INDEX_op_bswap32_i32, { "r", "0" } },
1792 { INDEX_op_neg_i32, { "r", "0" } },
1794 { INDEX_op_not_i32, { "r", "0" } },
1796 { INDEX_op_ext8s_i32, { "r", "q" } },
1797 { INDEX_op_ext16s_i32, { "r", "r" } },
1798 { INDEX_op_ext8u_i32, { "r", "q" } },
1799 { INDEX_op_ext16u_i32, { "r", "r" } },
1801 { INDEX_op_setcond_i32, { "q", "r", "ri" } },
1803 #if TCG_TARGET_REG_BITS == 32
1804 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
1805 { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1806 { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
1807 { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
1808 { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1809 #else
1810 { INDEX_op_mov_i64, { "r", "r" } },
1811 { INDEX_op_movi_i64, { "r" } },
1812 { INDEX_op_ld8u_i64, { "r", "r" } },
1813 { INDEX_op_ld8s_i64, { "r", "r" } },
1814 { INDEX_op_ld16u_i64, { "r", "r" } },
1815 { INDEX_op_ld16s_i64, { "r", "r" } },
1816 { INDEX_op_ld32u_i64, { "r", "r" } },
1817 { INDEX_op_ld32s_i64, { "r", "r" } },
1818 { INDEX_op_ld_i64, { "r", "r" } },
1819 { INDEX_op_st8_i64, { "r", "r" } },
1820 { INDEX_op_st16_i64, { "r", "r" } },
1821 { INDEX_op_st32_i64, { "r", "r" } },
1822 { INDEX_op_st_i64, { "r", "r" } },
1824 { INDEX_op_add_i64, { "r", "0", "re" } },
1825 { INDEX_op_mul_i64, { "r", "0", "re" } },
1826 { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
1827 { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
1828 { INDEX_op_sub_i64, { "r", "0", "re" } },
1829 { INDEX_op_and_i64, { "r", "0", "reZ" } },
1830 { INDEX_op_or_i64, { "r", "0", "re" } },
1831 { INDEX_op_xor_i64, { "r", "0", "re" } },
1833 { INDEX_op_shl_i64, { "r", "0", "ci" } },
1834 { INDEX_op_shr_i64, { "r", "0", "ci" } },
1835 { INDEX_op_sar_i64, { "r", "0", "ci" } },
1836 { INDEX_op_rotl_i64, { "r", "0", "ci" } },
1837 { INDEX_op_rotr_i64, { "r", "0", "ci" } },
1839 { INDEX_op_brcond_i64, { "r", "re" } },
1840 { INDEX_op_setcond_i64, { "r", "r", "re" } },
1842 { INDEX_op_bswap16_i64, { "r", "0" } },
1843 { INDEX_op_bswap32_i64, { "r", "0" } },
1844 { INDEX_op_bswap64_i64, { "r", "0" } },
1845 { INDEX_op_neg_i64, { "r", "0" } },
1846 { INDEX_op_not_i64, { "r", "0" } },
1848 { INDEX_op_ext8s_i64, { "r", "r" } },
1849 { INDEX_op_ext16s_i64, { "r", "r" } },
1850 { INDEX_op_ext32s_i64, { "r", "r" } },
1851 { INDEX_op_ext8u_i64, { "r", "r" } },
1852 { INDEX_op_ext16u_i64, { "r", "r" } },
1853 { INDEX_op_ext32u_i64, { "r", "r" } },
1854 #endif
1856 #if TCG_TARGET_REG_BITS == 64
1857 { INDEX_op_qemu_ld8u, { "r", "L" } },
1858 { INDEX_op_qemu_ld8s, { "r", "L" } },
1859 { INDEX_op_qemu_ld16u, { "r", "L" } },
1860 { INDEX_op_qemu_ld16s, { "r", "L" } },
1861 { INDEX_op_qemu_ld32, { "r", "L" } },
1862 { INDEX_op_qemu_ld32u, { "r", "L" } },
1863 { INDEX_op_qemu_ld32s, { "r", "L" } },
1864 { INDEX_op_qemu_ld64, { "r", "L" } },
1866 { INDEX_op_qemu_st8, { "L", "L" } },
1867 { INDEX_op_qemu_st16, { "L", "L" } },
1868 { INDEX_op_qemu_st32, { "L", "L" } },
1869 { INDEX_op_qemu_st64, { "L", "L" } },
1870 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1871 { INDEX_op_qemu_ld8u, { "r", "L" } },
1872 { INDEX_op_qemu_ld8s, { "r", "L" } },
1873 { INDEX_op_qemu_ld16u, { "r", "L" } },
1874 { INDEX_op_qemu_ld16s, { "r", "L" } },
1875 { INDEX_op_qemu_ld32, { "r", "L" } },
1876 { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1878 { INDEX_op_qemu_st8, { "cb", "L" } },
1879 { INDEX_op_qemu_st16, { "L", "L" } },
1880 { INDEX_op_qemu_st32, { "L", "L" } },
1881 { INDEX_op_qemu_st64, { "L", "L", "L" } },
1882 #else
1883 { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
1884 { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
1885 { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
1886 { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1887 { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1888 { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
1890 { INDEX_op_qemu_st8, { "cb", "L", "L" } },
1891 { INDEX_op_qemu_st16, { "L", "L", "L" } },
1892 { INDEX_op_qemu_st32, { "L", "L", "L" } },
1893 { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
1894 #endif
1895 { -1 },
1898 static int tcg_target_callee_save_regs[] = {
1899 #if TCG_TARGET_REG_BITS == 64
1900 TCG_REG_RBP,
1901 TCG_REG_RBX,
1902 TCG_REG_R12,
1903 TCG_REG_R13,
1904 /* TCG_REG_R14, */ /* Currently used for the global env. */
1905 TCG_REG_R15,
1906 #else
1907 /* TCG_REG_EBP, */ /* Currently used for the global env. */
1908 TCG_REG_EBX,
1909 TCG_REG_ESI,
1910 TCG_REG_EDI,
1911 #endif
1914 /* Generate global QEMU prologue and epilogue code */
1915 static void tcg_target_qemu_prologue(TCGContext *s)
1917 int i, frame_size, push_size, stack_addend;
1919 /* TB prologue */
1921 /* Save all callee saved registers. */
1922 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1923 tcg_out_push(s, tcg_target_callee_save_regs[i]);
1926 /* Reserve some stack space. */
1927 push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
1928 push_size *= TCG_TARGET_REG_BITS / 8;
1930 frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1931 frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1932 ~(TCG_TARGET_STACK_ALIGN - 1);
1933 stack_addend = frame_size - push_size;
1934 tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1936 /* jmp *tb. */
1937 tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]);
1939 /* TB epilogue */
1940 tb_ret_addr = s->code_ptr;
1942 tcg_out_addi(s, TCG_REG_ESP, stack_addend);
1944 for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1945 tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1947 tcg_out_opc(s, OPC_RET, 0, 0, 0);
1950 static void tcg_target_init(TCGContext *s)
1952 #if !defined(CONFIG_USER_ONLY)
1953 /* fail safe */
1954 if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1955 tcg_abort();
1956 #endif
1958 if (TCG_TARGET_REG_BITS == 64) {
1959 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
1960 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
1961 } else {
1962 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
1965 tcg_regset_clear(tcg_target_call_clobber_regs);
1966 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
1967 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
1968 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
1969 if (TCG_TARGET_REG_BITS == 64) {
1970 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
1971 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
1972 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
1973 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
1974 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
1975 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
1978 tcg_regset_clear(s->reserved_regs);
1979 tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
1981 tcg_add_target_add_op_defs(x86_op_defs);