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
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",
31 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
36 static const int tcg_target_reg_alloc_order
[] = {
37 #if TCG_TARGET_REG_BITS == 64
64 static const int tcg_target_call_iarg_regs
[] = {
65 #if TCG_TARGET_REG_BITS == 64
79 static const int tcg_target_call_oarg_regs
[] = {
81 #if TCG_TARGET_REG_BITS == 32
86 static uint8_t *tb_ret_addr
;
88 static void patch_reloc(uint8_t *code_ptr
, int type
,
89 tcg_target_long value
, tcg_target_long addend
)
94 value
-= (uintptr_t)code_ptr
;
95 if (value
!= (int32_t)value
) {
98 *(uint32_t *)code_ptr
= value
;
101 value
-= (uintptr_t)code_ptr
;
102 if (value
!= (int8_t)value
) {
105 *(uint8_t *)code_ptr
= value
;
112 /* maximum number of register used for input function arguments */
113 static inline int tcg_target_get_call_iarg_regs_count(int flags
)
115 if (TCG_TARGET_REG_BITS
== 64) {
119 flags
&= TCG_CALL_TYPE_MASK
;
121 case TCG_CALL_TYPE_STD
:
123 case TCG_CALL_TYPE_REGPARM_1
:
124 case TCG_CALL_TYPE_REGPARM_2
:
125 case TCG_CALL_TYPE_REGPARM
:
126 return flags
- TCG_CALL_TYPE_REGPARM_1
+ 1;
132 /* parse target specific constraints */
133 static int target_parse_constraint(TCGArgConstraint
*ct
, const char **pct_str
)
140 ct
->ct
|= TCG_CT_REG
;
141 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EAX
);
144 ct
->ct
|= TCG_CT_REG
;
145 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EBX
);
148 ct
->ct
|= TCG_CT_REG
;
149 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ECX
);
152 ct
->ct
|= TCG_CT_REG
;
153 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDX
);
156 ct
->ct
|= TCG_CT_REG
;
157 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ESI
);
160 ct
->ct
|= TCG_CT_REG
;
161 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDI
);
164 ct
->ct
|= TCG_CT_REG
;
165 if (TCG_TARGET_REG_BITS
== 64) {
166 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
168 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
172 ct
->ct
|= TCG_CT_REG
;
173 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
176 ct
->ct
|= TCG_CT_REG
;
177 if (TCG_TARGET_REG_BITS
== 64) {
178 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
180 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
184 /* qemu_ld/st address constraint */
186 ct
->ct
|= TCG_CT_REG
;
187 if (TCG_TARGET_REG_BITS
== 64) {
188 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
189 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_RSI
);
190 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_RDI
);
192 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
193 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EAX
);
194 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EDX
);
199 ct
->ct
|= TCG_CT_CONST_S32
;
202 ct
->ct
|= TCG_CT_CONST_U32
;
213 /* test if a constant matches the constraint */
214 static inline int tcg_target_const_match(tcg_target_long val
,
215 const TCGArgConstraint
*arg_ct
)
218 if (ct
& TCG_CT_CONST
) {
221 if ((ct
& TCG_CT_CONST_S32
) && val
== (int32_t)val
) {
224 if ((ct
& TCG_CT_CONST_U32
) && val
== (uint32_t)val
) {
230 #if TCG_TARGET_REG_BITS == 64
231 # define LOWREGMASK(x) ((x) & 7)
233 # define LOWREGMASK(x) (x)
236 #define P_EXT 0x100 /* 0x0f opcode prefix */
237 #define P_DATA16 0x200 /* 0x66 opcode prefix */
238 #if TCG_TARGET_REG_BITS == 64
239 # define P_ADDR32 0x400 /* 0x67 opcode prefix */
240 # define P_REXW 0x800 /* Set REX.W = 1 */
241 # define P_REXB_R 0x1000 /* REG field as byte register */
242 # define P_REXB_RM 0x2000 /* R/M field as byte register */
250 #define OPC_ARITH_EvIz (0x81)
251 #define OPC_ARITH_EvIb (0x83)
252 #define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
253 #define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
254 #define OPC_BSWAP (0xc8 | P_EXT)
255 #define OPC_CALL_Jz (0xe8)
256 #define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
257 #define OPC_DEC_r32 (0x48)
258 #define OPC_IMUL_GvEv (0xaf | P_EXT)
259 #define OPC_IMUL_GvEvIb (0x6b)
260 #define OPC_IMUL_GvEvIz (0x69)
261 #define OPC_INC_r32 (0x40)
262 #define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
263 #define OPC_JCC_short (0x70) /* ... plus condition code */
264 #define OPC_JMP_long (0xe9)
265 #define OPC_JMP_short (0xeb)
266 #define OPC_LEA (0x8d)
267 #define OPC_MOVB_EvGv (0x88) /* stores, more or less */
268 #define OPC_MOVL_EvGv (0x89) /* stores, more or less */
269 #define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
270 #define OPC_MOVL_EvIz (0xc7)
271 #define OPC_MOVL_Iv (0xb8)
272 #define OPC_MOVSBL (0xbe | P_EXT)
273 #define OPC_MOVSWL (0xbf | P_EXT)
274 #define OPC_MOVSLQ (0x63 | P_REXW)
275 #define OPC_MOVZBL (0xb6 | P_EXT)
276 #define OPC_MOVZWL (0xb7 | P_EXT)
277 #define OPC_POP_r32 (0x58)
278 #define OPC_PUSH_r32 (0x50)
279 #define OPC_PUSH_Iv (0x68)
280 #define OPC_PUSH_Ib (0x6a)
281 #define OPC_RET (0xc3)
282 #define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
283 #define OPC_SHIFT_1 (0xd1)
284 #define OPC_SHIFT_Ib (0xc1)
285 #define OPC_SHIFT_cl (0xd3)
286 #define OPC_TESTL (0x85)
287 #define OPC_XCHG_ax_r32 (0x90)
289 #define OPC_GRP3_Ev (0xf7)
290 #define OPC_GRP5 (0xff)
292 /* Group 1 opcode extensions for 0x80-0x83.
293 These are also used as modifiers for OPC_ARITH. */
303 /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
310 /* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
318 /* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
319 #define EXT5_INC_Ev 0
320 #define EXT5_DEC_Ev 1
321 #define EXT5_CALLN_Ev 2
322 #define EXT5_JMPN_Ev 4
324 /* Condition codes to be added to OPC_JCC_{long,short}. */
343 static const uint8_t tcg_cond_to_jcc
[10] = {
344 [TCG_COND_EQ
] = JCC_JE
,
345 [TCG_COND_NE
] = JCC_JNE
,
346 [TCG_COND_LT
] = JCC_JL
,
347 [TCG_COND_GE
] = JCC_JGE
,
348 [TCG_COND_LE
] = JCC_JLE
,
349 [TCG_COND_GT
] = JCC_JG
,
350 [TCG_COND_LTU
] = JCC_JB
,
351 [TCG_COND_GEU
] = JCC_JAE
,
352 [TCG_COND_LEU
] = JCC_JBE
,
353 [TCG_COND_GTU
] = JCC_JA
,
356 #if TCG_TARGET_REG_BITS == 64
357 static void tcg_out_opc(TCGContext
*s
, int opc
, int r
, int rm
, int x
)
361 if (opc
& P_DATA16
) {
362 /* We should never be asking for both 16 and 64-bit operation. */
363 assert((opc
& P_REXW
) == 0);
366 if (opc
& P_ADDR32
) {
371 rex
|= (opc
& P_REXW
) >> 8; /* REX.W */
372 rex
|= (r
& 8) >> 1; /* REX.R */
373 rex
|= (x
& 8) >> 2; /* REX.X */
374 rex
|= (rm
& 8) >> 3; /* REX.B */
376 /* P_REXB_{R,RM} indicates that the given register is the low byte.
377 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
378 as otherwise the encoding indicates %[abcd]h. Note that the values
379 that are ORed in merely indicate that the REX byte must be present;
380 those bits get discarded in output. */
381 rex
|= opc
& (r
>= 4 ? P_REXB_R
: 0);
382 rex
|= opc
& (rm
>= 4 ? P_REXB_RM
: 0);
385 tcg_out8(s
, (uint8_t)(rex
| 0x40));
394 static void tcg_out_opc(TCGContext
*s
, int opc
)
396 if (opc
& P_DATA16
) {
404 /* Discard the register arguments to tcg_out_opc early, so as not to penalize
405 the 32-bit compilation paths. This method works with all versions of gcc,
406 whereas relying on optimization may not be able to exclude them. */
407 #define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
410 static void tcg_out_modrm(TCGContext
*s
, int opc
, int r
, int rm
)
412 tcg_out_opc(s
, opc
, r
, rm
, 0);
413 tcg_out8(s
, 0xc0 | (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
416 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
417 We handle either RM and INDEX missing with a negative value. In 64-bit
418 mode for absolute addresses, ~RM is the size of the immediate operand
419 that will follow the instruction. */
421 static void tcg_out_modrm_sib_offset(TCGContext
*s
, int opc
, int r
, int rm
,
422 int index
, int shift
,
423 tcg_target_long offset
)
427 if (index
< 0 && rm
< 0) {
428 if (TCG_TARGET_REG_BITS
== 64) {
429 /* Try for a rip-relative addressing mode. This has replaced
430 the 32-bit-mode absolute addressing encoding. */
431 tcg_target_long pc
= (tcg_target_long
)s
->code_ptr
+ 5 + ~rm
;
432 tcg_target_long disp
= offset
- pc
;
433 if (disp
== (int32_t)disp
) {
434 tcg_out_opc(s
, opc
, r
, 0, 0);
435 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 5);
440 /* Try for an absolute address encoding. This requires the
441 use of the MODRM+SIB encoding and is therefore larger than
442 rip-relative addressing. */
443 if (offset
== (int32_t)offset
) {
444 tcg_out_opc(s
, opc
, r
, 0, 0);
445 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 4);
446 tcg_out8(s
, (4 << 3) | 5);
447 tcg_out32(s
, offset
);
451 /* ??? The memory isn't directly addressable. */
454 /* Absolute address. */
455 tcg_out_opc(s
, opc
, r
, 0, 0);
456 tcg_out8(s
, (r
<< 3) | 5);
457 tcg_out32(s
, offset
);
462 /* Find the length of the immediate addend. Note that the encoding
463 that would be used for (%ebp) indicates absolute addressing. */
465 mod
= 0, len
= 4, rm
= 5;
466 } else if (offset
== 0 && LOWREGMASK(rm
) != TCG_REG_EBP
) {
468 } else if (offset
== (int8_t)offset
) {
474 /* Use a single byte MODRM format if possible. Note that the encoding
475 that would be used for %esp is the escape to the two byte form. */
476 if (index
< 0 && LOWREGMASK(rm
) != TCG_REG_ESP
) {
477 /* Single byte MODRM format. */
478 tcg_out_opc(s
, opc
, r
, rm
, 0);
479 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
481 /* Two byte MODRM+SIB format. */
483 /* Note that the encoding that would place %esp into the index
484 field indicates no index register. In 64-bit mode, the REX.X
485 bit counts, so %r12 can be used as the index. */
489 assert(index
!= TCG_REG_ESP
);
492 tcg_out_opc(s
, opc
, r
, rm
, index
);
493 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | 4);
494 tcg_out8(s
, (shift
<< 6) | (LOWREGMASK(index
) << 3) | LOWREGMASK(rm
));
499 } else if (len
== 4) {
500 tcg_out32(s
, offset
);
504 /* A simplification of the above with no index or shift. */
505 static inline void tcg_out_modrm_offset(TCGContext
*s
, int opc
, int r
,
506 int rm
, tcg_target_long offset
)
508 tcg_out_modrm_sib_offset(s
, opc
, r
, rm
, -1, 0, offset
);
511 /* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
512 static inline void tgen_arithr(TCGContext
*s
, int subop
, int dest
, int src
)
514 /* Propagate an opcode prefix, such as P_REXW. */
515 int ext
= subop
& ~0x7;
518 tcg_out_modrm(s
, OPC_ARITH_GvEv
+ (subop
<< 3) + ext
, dest
, src
);
521 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
522 TCGReg ret
, TCGReg arg
)
525 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
526 tcg_out_modrm(s
, opc
, ret
, arg
);
530 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
531 TCGReg ret
, tcg_target_long arg
)
534 tgen_arithr(s
, ARITH_XOR
, ret
, ret
);
536 } else if (arg
== (uint32_t)arg
|| type
== TCG_TYPE_I32
) {
537 tcg_out_opc(s
, OPC_MOVL_Iv
+ LOWREGMASK(ret
), 0, ret
, 0);
539 } else if (arg
== (int32_t)arg
) {
540 tcg_out_modrm(s
, OPC_MOVL_EvIz
+ P_REXW
, 0, ret
);
543 tcg_out_opc(s
, OPC_MOVL_Iv
+ P_REXW
+ LOWREGMASK(ret
), 0, ret
, 0);
545 tcg_out32(s
, arg
>> 31 >> 1);
549 static inline void tcg_out_pushi(TCGContext
*s
, tcg_target_long val
)
551 if (val
== (int8_t)val
) {
552 tcg_out_opc(s
, OPC_PUSH_Ib
, 0, 0, 0);
554 } else if (val
== (int32_t)val
) {
555 tcg_out_opc(s
, OPC_PUSH_Iv
, 0, 0, 0);
562 static inline void tcg_out_push(TCGContext
*s
, int reg
)
564 tcg_out_opc(s
, OPC_PUSH_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
567 static inline void tcg_out_pop(TCGContext
*s
, int reg
)
569 tcg_out_opc(s
, OPC_POP_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
572 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg ret
,
573 TCGReg arg1
, tcg_target_long arg2
)
575 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
576 tcg_out_modrm_offset(s
, opc
, ret
, arg1
, arg2
);
579 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
580 TCGReg arg1
, tcg_target_long arg2
)
582 int opc
= OPC_MOVL_EvGv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
583 tcg_out_modrm_offset(s
, opc
, arg
, arg1
, arg2
);
586 static void tcg_out_shifti(TCGContext
*s
, int subopc
, int reg
, int count
)
588 /* Propagate an opcode prefix, such as P_DATA16. */
589 int ext
= subopc
& ~0x7;
593 tcg_out_modrm(s
, OPC_SHIFT_1
+ ext
, subopc
, reg
);
595 tcg_out_modrm(s
, OPC_SHIFT_Ib
+ ext
, subopc
, reg
);
600 static inline void tcg_out_bswap32(TCGContext
*s
, int reg
)
602 tcg_out_opc(s
, OPC_BSWAP
+ LOWREGMASK(reg
), 0, reg
, 0);
605 static inline void tcg_out_rolw_8(TCGContext
*s
, int reg
)
607 tcg_out_shifti(s
, SHIFT_ROL
+ P_DATA16
, reg
, 8);
610 static inline void tcg_out_ext8u(TCGContext
*s
, int dest
, int src
)
613 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
614 tcg_out_modrm(s
, OPC_MOVZBL
+ P_REXB_RM
, dest
, src
);
617 static void tcg_out_ext8s(TCGContext
*s
, int dest
, int src
, int rexw
)
620 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
621 tcg_out_modrm(s
, OPC_MOVSBL
+ P_REXB_RM
+ rexw
, dest
, src
);
624 static inline void tcg_out_ext16u(TCGContext
*s
, int dest
, int src
)
627 tcg_out_modrm(s
, OPC_MOVZWL
, dest
, src
);
630 static inline void tcg_out_ext16s(TCGContext
*s
, int dest
, int src
, int rexw
)
633 tcg_out_modrm(s
, OPC_MOVSWL
+ rexw
, dest
, src
);
636 static inline void tcg_out_ext32u(TCGContext
*s
, int dest
, int src
)
638 /* 32-bit mov zero extends. */
639 tcg_out_modrm(s
, OPC_MOVL_GvEv
, dest
, src
);
642 static inline void tcg_out_ext32s(TCGContext
*s
, int dest
, int src
)
644 tcg_out_modrm(s
, OPC_MOVSLQ
, dest
, src
);
647 static inline void tcg_out_bswap64(TCGContext
*s
, int reg
)
649 tcg_out_opc(s
, OPC_BSWAP
+ P_REXW
+ LOWREGMASK(reg
), 0, reg
, 0);
652 static void tgen_arithi(TCGContext
*s
, int c
, int r0
,
653 tcg_target_long val
, int cf
)
657 if (TCG_TARGET_REG_BITS
== 64) {
662 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
663 partial flags update stalls on Pentium4 and are not recommended
664 by current Intel optimization manuals. */
665 if (!cf
&& (c
== ARITH_ADD
|| c
== ARITH_SUB
) && (val
== 1 || val
== -1)) {
666 int is_inc
= (c
== ARITH_ADD
) ^ (val
< 0);
667 if (TCG_TARGET_REG_BITS
== 64) {
668 /* The single-byte increment encodings are re-tasked as the
669 REX prefixes. Use the MODRM encoding. */
670 tcg_out_modrm(s
, OPC_GRP5
+ rexw
,
671 (is_inc
? EXT5_INC_Ev
: EXT5_DEC_Ev
), r0
);
673 tcg_out8(s
, (is_inc
? OPC_INC_r32
: OPC_DEC_r32
) + r0
);
678 if (c
== ARITH_AND
) {
679 if (TCG_TARGET_REG_BITS
== 64) {
680 if (val
== 0xffffffffu
) {
681 tcg_out_ext32u(s
, r0
, r0
);
684 if (val
== (uint32_t)val
) {
685 /* AND with no high bits set can use a 32-bit operation. */
689 if (val
== 0xffu
&& (r0
< 4 || TCG_TARGET_REG_BITS
== 64)) {
690 tcg_out_ext8u(s
, r0
, r0
);
693 if (val
== 0xffffu
) {
694 tcg_out_ext16u(s
, r0
, r0
);
699 if (val
== (int8_t)val
) {
700 tcg_out_modrm(s
, OPC_ARITH_EvIb
+ rexw
, c
, r0
);
704 if (rexw
== 0 || val
== (int32_t)val
) {
705 tcg_out_modrm(s
, OPC_ARITH_EvIz
+ rexw
, c
, r0
);
713 static void tcg_out_addi(TCGContext
*s
, int reg
, tcg_target_long val
)
716 tgen_arithi(s
, ARITH_ADD
+ P_REXW
, reg
, val
, 0);
720 /* Use SMALL != 0 to force a short forward branch. */
721 static void tcg_out_jxx(TCGContext
*s
, int opc
, int label_index
, int small
)
724 TCGLabel
*l
= &s
->labels
[label_index
];
727 val
= l
->u
.value
- (tcg_target_long
)s
->code_ptr
;
729 if ((int8_t)val1
== val1
) {
731 tcg_out8(s
, OPC_JMP_short
);
733 tcg_out8(s
, OPC_JCC_short
+ opc
);
741 tcg_out8(s
, OPC_JMP_long
);
742 tcg_out32(s
, val
- 5);
744 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
745 tcg_out32(s
, val
- 6);
750 tcg_out8(s
, OPC_JMP_short
);
752 tcg_out8(s
, OPC_JCC_short
+ opc
);
754 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC8
, label_index
, -1);
758 tcg_out8(s
, OPC_JMP_long
);
760 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
762 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC32
, label_index
, -4);
767 static void tcg_out_cmp(TCGContext
*s
, TCGArg arg1
, TCGArg arg2
,
768 int const_arg2
, int rexw
)
773 tcg_out_modrm(s
, OPC_TESTL
+ rexw
, arg1
, arg1
);
775 tgen_arithi(s
, ARITH_CMP
+ rexw
, arg1
, arg2
, 0);
778 tgen_arithr(s
, ARITH_CMP
+ rexw
, arg1
, arg2
);
782 static void tcg_out_brcond32(TCGContext
*s
, TCGCond cond
,
783 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
784 int label_index
, int small
)
786 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
787 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
790 #if TCG_TARGET_REG_BITS == 64
791 static void tcg_out_brcond64(TCGContext
*s
, TCGCond cond
,
792 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
793 int label_index
, int small
)
795 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
796 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
799 /* XXX: we implement it at the target level to avoid having to
800 handle cross basic blocks temporaries */
801 static void tcg_out_brcond2(TCGContext
*s
, const TCGArg
*args
,
802 const int *const_args
, int small
)
805 label_next
= gen_new_label();
808 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
810 tcg_out_brcond32(s
, TCG_COND_EQ
, args
[1], args
[3], const_args
[3],
814 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
816 tcg_out_brcond32(s
, TCG_COND_NE
, args
[1], args
[3], const_args
[3],
820 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
822 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
823 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
827 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
829 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
830 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
834 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
836 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
837 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
841 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
843 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
844 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
848 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
850 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
851 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
855 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
857 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
858 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
862 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
864 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
865 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
869 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
871 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
872 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
878 tcg_out_label(s
, label_next
, (tcg_target_long
)s
->code_ptr
);
882 static void tcg_out_setcond32(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
883 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
885 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
886 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
887 tcg_out_ext8u(s
, dest
, dest
);
890 #if TCG_TARGET_REG_BITS == 64
891 static void tcg_out_setcond64(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
892 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
894 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
895 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
896 tcg_out_ext8u(s
, dest
, dest
);
899 static void tcg_out_setcond2(TCGContext
*s
, const TCGArg
*args
,
900 const int *const_args
)
903 int label_true
, label_over
;
905 memcpy(new_args
, args
+1, 5*sizeof(TCGArg
));
907 if (args
[0] == args
[1] || args
[0] == args
[2]
908 || (!const_args
[3] && args
[0] == args
[3])
909 || (!const_args
[4] && args
[0] == args
[4])) {
910 /* When the destination overlaps with one of the argument
911 registers, don't do anything tricky. */
912 label_true
= gen_new_label();
913 label_over
= gen_new_label();
915 new_args
[5] = label_true
;
916 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
918 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
919 tcg_out_jxx(s
, JCC_JMP
, label_over
, 1);
920 tcg_out_label(s
, label_true
, (tcg_target_long
)s
->code_ptr
);
922 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 1);
923 tcg_out_label(s
, label_over
, (tcg_target_long
)s
->code_ptr
);
925 /* When the destination does not overlap one of the arguments,
926 clear the destination first, jump if cond false, and emit an
927 increment in the true case. This results in smaller code. */
929 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
931 label_over
= gen_new_label();
932 new_args
[4] = tcg_invert_cond(new_args
[4]);
933 new_args
[5] = label_over
;
934 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
936 tgen_arithi(s
, ARITH_ADD
, args
[0], 1, 0);
937 tcg_out_label(s
, label_over
, (tcg_target_long
)s
->code_ptr
);
942 static void tcg_out_branch(TCGContext
*s
, int call
, tcg_target_long dest
)
944 tcg_target_long disp
= dest
- (tcg_target_long
)s
->code_ptr
- 5;
946 if (disp
== (int32_t)disp
) {
947 tcg_out_opc(s
, call
? OPC_CALL_Jz
: OPC_JMP_long
, 0, 0, 0);
950 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R10
, dest
);
951 tcg_out_modrm(s
, OPC_GRP5
,
952 call
? EXT5_CALLN_Ev
: EXT5_JMPN_Ev
, TCG_REG_R10
);
956 static inline void tcg_out_calli(TCGContext
*s
, tcg_target_long dest
)
958 tcg_out_branch(s
, 1, dest
);
961 static void tcg_out_jmp(TCGContext
*s
, tcg_target_long dest
)
963 tcg_out_branch(s
, 0, dest
);
966 #if defined(CONFIG_SOFTMMU)
968 #include "../../softmmu_defs.h"
970 static void *qemu_ld_helpers
[4] = {
977 static void *qemu_st_helpers
[4] = {
984 /* Perform the TLB load and compare.
987 ADDRLO_IDX contains the index into ARGS of the low part of the
988 address; the high part of the address is at ADDR_LOW_IDX+1.
990 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
992 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
993 This should be offsetof addr_read or addr_write.
996 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
997 positions of the displacements of forward jumps to the TLB miss case.
999 First argument register is loaded with the low part of the address.
1000 In the TLB hit case, it has been adjusted as indicated by the TLB
1001 and so is a host address. In the TLB miss case, it continues to
1002 hold a guest address.
1004 Second argument register is clobbered. */
1006 static inline void tcg_out_tlb_load(TCGContext
*s
, int addrlo_idx
,
1007 int mem_index
, int s_bits
,
1009 uint8_t **label_ptr
, int which
)
1011 const int addrlo
= args
[addrlo_idx
];
1012 const int r0
= tcg_target_call_iarg_regs
[0];
1013 const int r1
= tcg_target_call_iarg_regs
[1];
1014 TCGType type
= TCG_TYPE_I32
;
1017 if (TCG_TARGET_REG_BITS
== 64 && TARGET_LONG_BITS
== 64) {
1018 type
= TCG_TYPE_I64
;
1022 tcg_out_mov(s
, type
, r1
, addrlo
);
1023 tcg_out_mov(s
, type
, r0
, addrlo
);
1025 tcg_out_shifti(s
, SHIFT_SHR
+ rexw
, r1
,
1026 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1028 tgen_arithi(s
, ARITH_AND
+ rexw
, r0
,
1029 TARGET_PAGE_MASK
| ((1 << s_bits
) - 1), 0);
1030 tgen_arithi(s
, ARITH_AND
+ rexw
, r1
,
1031 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
, 0);
1033 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ P_REXW
, r1
, TCG_AREG0
, r1
, 0,
1034 offsetof(CPUState
, tlb_table
[mem_index
][0])
1038 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
+ rexw
, r0
, r1
, 0);
1040 tcg_out_mov(s
, type
, r0
, addrlo
);
1043 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1044 label_ptr
[0] = s
->code_ptr
;
1047 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1048 /* cmp 4(r1), addrhi */
1049 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
, args
[addrlo_idx
+1], r1
, 4);
1052 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1053 label_ptr
[1] = s
->code_ptr
;
1059 /* add addend(r1), r0 */
1060 tcg_out_modrm_offset(s
, OPC_ADD_GvEv
+ P_REXW
, r0
, r1
,
1061 offsetof(CPUTLBEntry
, addend
) - which
);
1065 static void tcg_out_qemu_ld_direct(TCGContext
*s
, int datalo
, int datahi
,
1066 int base
, tcg_target_long ofs
, int sizeop
)
1068 #ifdef TARGET_WORDS_BIGENDIAN
1069 const int bswap
= 1;
1071 const int bswap
= 0;
1075 tcg_out_modrm_offset(s
, OPC_MOVZBL
, datalo
, base
, ofs
);
1078 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ P_REXW
, datalo
, base
, ofs
);
1081 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1083 tcg_out_rolw_8(s
, datalo
);
1088 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1089 tcg_out_rolw_8(s
, datalo
);
1090 tcg_out_modrm(s
, OPC_MOVSWL
+ P_REXW
, datalo
, datalo
);
1092 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ P_REXW
, datalo
, base
, ofs
);
1096 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1098 tcg_out_bswap32(s
, datalo
);
1101 #if TCG_TARGET_REG_BITS == 64
1104 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1105 tcg_out_bswap32(s
, datalo
);
1106 tcg_out_ext32s(s
, datalo
, datalo
);
1108 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, datalo
, base
, ofs
);
1113 if (TCG_TARGET_REG_BITS
== 64) {
1114 tcg_out_ld(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1116 tcg_out_bswap64(s
, datalo
);
1124 if (base
!= datalo
) {
1125 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1126 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1128 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1129 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1132 tcg_out_bswap32(s
, datalo
);
1133 tcg_out_bswap32(s
, datahi
);
1142 /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1143 EAX. It will be useful once fixed registers globals are less
1145 static void tcg_out_qemu_ld(TCGContext
*s
, const TCGArg
*args
,
1148 int data_reg
, data_reg2
= 0;
1150 #if defined(CONFIG_SOFTMMU)
1151 int mem_index
, s_bits
, arg_idx
;
1152 uint8_t *label_ptr
[3];
1157 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1158 data_reg2
= args
[1];
1162 #if defined(CONFIG_SOFTMMU)
1163 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1166 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1167 label_ptr
, offsetof(CPUTLBEntry
, addr_read
));
1170 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
,
1171 tcg_target_call_iarg_regs
[0], 0, opc
);
1174 tcg_out8(s
, OPC_JMP_short
);
1175 label_ptr
[2] = s
->code_ptr
;
1181 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1182 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1183 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1186 /* XXX: move that code at the end of the TB */
1187 /* The first argument is already loaded with addrlo. */
1189 if (TCG_TARGET_REG_BITS
== 32 && TARGET_LONG_BITS
== 64) {
1190 tcg_out_mov(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[arg_idx
++],
1191 args
[addrlo_idx
+ 1]);
1193 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[arg_idx
],
1195 tcg_out_calli(s
, (tcg_target_long
)qemu_ld_helpers
[s_bits
]);
1199 tcg_out_ext8s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1202 tcg_out_ext16s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1205 tcg_out_ext8u(s
, data_reg
, TCG_REG_EAX
);
1208 tcg_out_ext16u(s
, data_reg
, TCG_REG_EAX
);
1211 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1213 #if TCG_TARGET_REG_BITS == 64
1215 tcg_out_ext32s(s
, data_reg
, TCG_REG_EAX
);
1219 if (TCG_TARGET_REG_BITS
== 64) {
1220 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_RAX
);
1221 } else if (data_reg
== TCG_REG_EDX
) {
1222 /* xchg %edx, %eax */
1223 tcg_out_opc(s
, OPC_XCHG_ax_r32
+ TCG_REG_EDX
, 0, 0, 0);
1224 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EAX
);
1226 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1227 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EDX
);
1235 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1238 int32_t offset
= GUEST_BASE
;
1239 int base
= args
[addrlo_idx
];
1241 if (TCG_TARGET_REG_BITS
== 64) {
1242 /* ??? We assume all operations have left us with register
1243 contents that are zero extended. So far this appears to
1244 be true. If we want to enforce this, we can either do
1245 an explicit zero-extension here, or (if GUEST_BASE == 0)
1246 use the ADDR32 prefix. For now, do nothing. */
1248 if (offset
!= GUEST_BASE
) {
1249 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_RDI
, GUEST_BASE
);
1250 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_RDI
, base
);
1251 base
= TCG_REG_RDI
, offset
= 0;
1255 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1260 static void tcg_out_qemu_st_direct(TCGContext
*s
, int datalo
, int datahi
,
1261 int base
, tcg_target_long ofs
, int sizeop
)
1263 #ifdef TARGET_WORDS_BIGENDIAN
1264 const int bswap
= 1;
1266 const int bswap
= 0;
1268 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1269 we could perform the bswap twice to restore the original value
1270 instead of moving to the scratch. But as it is, the L constraint
1271 means that the second argument reg is definitely free here. */
1272 int scratch
= tcg_target_call_iarg_regs
[1];
1276 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
+ P_REXB_R
, datalo
, base
, ofs
);
1280 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1281 tcg_out_rolw_8(s
, scratch
);
1284 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ P_DATA16
, datalo
, base
, ofs
);
1288 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1289 tcg_out_bswap32(s
, scratch
);
1292 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1295 if (TCG_TARGET_REG_BITS
== 64) {
1297 tcg_out_mov(s
, TCG_TYPE_I64
, scratch
, datalo
);
1298 tcg_out_bswap64(s
, scratch
);
1301 tcg_out_st(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1303 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datahi
);
1304 tcg_out_bswap32(s
, scratch
);
1305 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
);
1306 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1307 tcg_out_bswap32(s
, scratch
);
1308 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
+ 4);
1310 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1311 tcg_out_st(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1319 static void tcg_out_qemu_st(TCGContext
*s
, const TCGArg
*args
,
1322 int data_reg
, data_reg2
= 0;
1324 #if defined(CONFIG_SOFTMMU)
1325 int mem_index
, s_bits
;
1327 uint8_t *label_ptr
[3];
1332 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1333 data_reg2
= args
[1];
1337 #if defined(CONFIG_SOFTMMU)
1338 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1341 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1342 label_ptr
, offsetof(CPUTLBEntry
, addr_write
));
1345 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
,
1346 tcg_target_call_iarg_regs
[0], 0, opc
);
1349 tcg_out8(s
, OPC_JMP_short
);
1350 label_ptr
[2] = s
->code_ptr
;
1356 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1357 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1358 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1361 /* XXX: move that code at the end of the TB */
1362 if (TCG_TARGET_REG_BITS
== 64) {
1363 tcg_out_mov(s
, (opc
== 3 ? TCG_TYPE_I64
: TCG_TYPE_I32
),
1364 TCG_REG_RSI
, data_reg
);
1365 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_RDX
, mem_index
);
1367 } else if (TARGET_LONG_BITS
== 32) {
1368 tcg_out_mov(s
, TCG_TYPE_I32
, TCG_REG_EDX
, data_reg
);
1370 tcg_out_mov(s
, TCG_TYPE_I32
, TCG_REG_ECX
, data_reg2
);
1371 tcg_out_pushi(s
, mem_index
);
1374 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_ECX
, mem_index
);
1379 tcg_out_mov(s
, TCG_TYPE_I32
, TCG_REG_EDX
, args
[addrlo_idx
+ 1]);
1380 tcg_out_pushi(s
, mem_index
);
1381 tcg_out_push(s
, data_reg2
);
1382 tcg_out_push(s
, data_reg
);
1385 tcg_out_mov(s
, TCG_TYPE_I32
, TCG_REG_EDX
, args
[addrlo_idx
+ 1]);
1388 tcg_out_ext8u(s
, TCG_REG_ECX
, data_reg
);
1391 tcg_out_ext16u(s
, TCG_REG_ECX
, data_reg
);
1394 tcg_out_mov(s
, TCG_TYPE_I32
, TCG_REG_ECX
, data_reg
);
1397 tcg_out_pushi(s
, mem_index
);
1402 tcg_out_calli(s
, (tcg_target_long
)qemu_st_helpers
[s_bits
]);
1404 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1405 /* Pop and discard. This is 2 bytes smaller than the add. */
1406 tcg_out_pop(s
, TCG_REG_ECX
);
1407 } else if (stack_adjust
!= 0) {
1408 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1412 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1415 int32_t offset
= GUEST_BASE
;
1416 int base
= args
[addrlo_idx
];
1418 if (TCG_TARGET_REG_BITS
== 64) {
1419 /* ??? We assume all operations have left us with register
1420 contents that are zero extended. So far this appears to
1421 be true. If we want to enforce this, we can either do
1422 an explicit zero-extension here, or (if GUEST_BASE == 0)
1423 use the ADDR32 prefix. For now, do nothing. */
1425 if (offset
!= GUEST_BASE
) {
1426 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_RDI
, GUEST_BASE
);
1427 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_RDI
, base
);
1428 base
= TCG_REG_RDI
, offset
= 0;
1432 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1437 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1438 const TCGArg
*args
, const int *const_args
)
1442 #if TCG_TARGET_REG_BITS == 64
1443 # define OP_32_64(x) \
1444 case glue(glue(INDEX_op_, x), _i64): \
1445 rexw = P_REXW; /* FALLTHRU */ \
1446 case glue(glue(INDEX_op_, x), _i32)
1448 # define OP_32_64(x) \
1449 case glue(glue(INDEX_op_, x), _i32)
1453 case INDEX_op_exit_tb
:
1454 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_EAX
, args
[0]);
1455 tcg_out_jmp(s
, (tcg_target_long
) tb_ret_addr
);
1457 case INDEX_op_goto_tb
:
1458 if (s
->tb_jmp_offset
) {
1459 /* direct jump method */
1460 tcg_out8(s
, OPC_JMP_long
); /* jmp im */
1461 s
->tb_jmp_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1464 /* indirect jump method */
1465 tcg_out_modrm_offset(s
, OPC_GRP5
, EXT5_JMPN_Ev
, -1,
1466 (tcg_target_long
)(s
->tb_next
+ args
[0]));
1468 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1471 if (const_args
[0]) {
1472 tcg_out_calli(s
, args
[0]);
1475 tcg_out_modrm(s
, OPC_GRP5
, EXT5_CALLN_Ev
, args
[0]);
1479 if (const_args
[0]) {
1480 tcg_out_jmp(s
, args
[0]);
1483 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, args
[0]);
1487 tcg_out_jxx(s
, JCC_JMP
, args
[0], 0);
1489 case INDEX_op_movi_i32
:
1490 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1493 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1494 tcg_out_modrm_offset(s
, OPC_MOVZBL
, args
[0], args
[1], args
[2]);
1497 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ rexw
, args
[0], args
[1], args
[2]);
1500 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1501 tcg_out_modrm_offset(s
, OPC_MOVZWL
, args
[0], args
[1], args
[2]);
1504 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ rexw
, args
[0], args
[1], args
[2]);
1506 #if TCG_TARGET_REG_BITS == 64
1507 case INDEX_op_ld32u_i64
:
1509 case INDEX_op_ld_i32
:
1510 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1514 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
| P_REXB_R
,
1515 args
[0], args
[1], args
[2]);
1518 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
| P_DATA16
,
1519 args
[0], args
[1], args
[2]);
1521 #if TCG_TARGET_REG_BITS == 64
1522 case INDEX_op_st32_i64
:
1524 case INDEX_op_st_i32
:
1525 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1529 /* For 3-operand addition, use LEA. */
1530 if (args
[0] != args
[1]) {
1531 TCGArg a0
= args
[0], a1
= args
[1], a2
= args
[2], c3
= 0;
1533 if (const_args
[2]) {
1535 } else if (a0
== a2
) {
1536 /* Watch out for dest = src + dest, since we've removed
1537 the matching constraint on the add. */
1538 tgen_arithr(s
, ARITH_ADD
+ rexw
, a0
, a1
);
1542 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ rexw
, a0
, a1
, a2
, 0, c3
);
1560 if (const_args
[2]) {
1561 tgen_arithi(s
, c
+ rexw
, args
[0], args
[2], 0);
1563 tgen_arithr(s
, c
+ rexw
, args
[0], args
[2]);
1568 if (const_args
[2]) {
1571 if (val
== (int8_t)val
) {
1572 tcg_out_modrm(s
, OPC_IMUL_GvEvIb
+ rexw
, args
[0], args
[0]);
1575 tcg_out_modrm(s
, OPC_IMUL_GvEvIz
+ rexw
, args
[0], args
[0]);
1579 tcg_out_modrm(s
, OPC_IMUL_GvEv
+ rexw
, args
[0], args
[2]);
1584 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_IDIV
, args
[4]);
1587 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_DIV
, args
[4]);
1606 if (const_args
[2]) {
1607 tcg_out_shifti(s
, c
+ rexw
, args
[0], args
[2]);
1609 tcg_out_modrm(s
, OPC_SHIFT_cl
+ rexw
, c
, args
[0]);
1613 case INDEX_op_brcond_i32
:
1614 tcg_out_brcond32(s
, args
[2], args
[0], args
[1], const_args
[1],
1617 case INDEX_op_setcond_i32
:
1618 tcg_out_setcond32(s
, args
[3], args
[0], args
[1],
1619 args
[2], const_args
[2]);
1623 tcg_out_rolw_8(s
, args
[0]);
1626 tcg_out_bswap32(s
, args
[0]);
1630 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NEG
, args
[0]);
1633 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NOT
, args
[0]);
1637 tcg_out_ext8s(s
, args
[0], args
[1], rexw
);
1640 tcg_out_ext16s(s
, args
[0], args
[1], rexw
);
1643 tcg_out_ext8u(s
, args
[0], args
[1]);
1646 tcg_out_ext16u(s
, args
[0], args
[1]);
1649 case INDEX_op_qemu_ld8u
:
1650 tcg_out_qemu_ld(s
, args
, 0);
1652 case INDEX_op_qemu_ld8s
:
1653 tcg_out_qemu_ld(s
, args
, 0 | 4);
1655 case INDEX_op_qemu_ld16u
:
1656 tcg_out_qemu_ld(s
, args
, 1);
1658 case INDEX_op_qemu_ld16s
:
1659 tcg_out_qemu_ld(s
, args
, 1 | 4);
1661 #if TCG_TARGET_REG_BITS == 64
1662 case INDEX_op_qemu_ld32u
:
1664 case INDEX_op_qemu_ld32
:
1665 tcg_out_qemu_ld(s
, args
, 2);
1667 case INDEX_op_qemu_ld64
:
1668 tcg_out_qemu_ld(s
, args
, 3);
1671 case INDEX_op_qemu_st8
:
1672 tcg_out_qemu_st(s
, args
, 0);
1674 case INDEX_op_qemu_st16
:
1675 tcg_out_qemu_st(s
, args
, 1);
1677 case INDEX_op_qemu_st32
:
1678 tcg_out_qemu_st(s
, args
, 2);
1680 case INDEX_op_qemu_st64
:
1681 tcg_out_qemu_st(s
, args
, 3);
1684 #if TCG_TARGET_REG_BITS == 32
1685 case INDEX_op_brcond2_i32
:
1686 tcg_out_brcond2(s
, args
, const_args
, 0);
1688 case INDEX_op_setcond2_i32
:
1689 tcg_out_setcond2(s
, args
, const_args
);
1691 case INDEX_op_mulu2_i32
:
1692 tcg_out_modrm(s
, OPC_GRP3_Ev
, EXT3_MUL
, args
[3]);
1694 case INDEX_op_add2_i32
:
1695 if (const_args
[4]) {
1696 tgen_arithi(s
, ARITH_ADD
, args
[0], args
[4], 1);
1698 tgen_arithr(s
, ARITH_ADD
, args
[0], args
[4]);
1700 if (const_args
[5]) {
1701 tgen_arithi(s
, ARITH_ADC
, args
[1], args
[5], 1);
1703 tgen_arithr(s
, ARITH_ADC
, args
[1], args
[5]);
1706 case INDEX_op_sub2_i32
:
1707 if (const_args
[4]) {
1708 tgen_arithi(s
, ARITH_SUB
, args
[0], args
[4], 1);
1710 tgen_arithr(s
, ARITH_SUB
, args
[0], args
[4]);
1712 if (const_args
[5]) {
1713 tgen_arithi(s
, ARITH_SBB
, args
[1], args
[5], 1);
1715 tgen_arithr(s
, ARITH_SBB
, args
[1], args
[5]);
1718 #else /* TCG_TARGET_REG_BITS == 64 */
1719 case INDEX_op_movi_i64
:
1720 tcg_out_movi(s
, TCG_TYPE_I64
, args
[0], args
[1]);
1722 case INDEX_op_ld32s_i64
:
1723 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, args
[0], args
[1], args
[2]);
1725 case INDEX_op_ld_i64
:
1726 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1728 case INDEX_op_st_i64
:
1729 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1731 case INDEX_op_qemu_ld32s
:
1732 tcg_out_qemu_ld(s
, args
, 2 | 4);
1735 case INDEX_op_brcond_i64
:
1736 tcg_out_brcond64(s
, args
[2], args
[0], args
[1], const_args
[1],
1739 case INDEX_op_setcond_i64
:
1740 tcg_out_setcond64(s
, args
[3], args
[0], args
[1],
1741 args
[2], const_args
[2]);
1744 case INDEX_op_bswap64_i64
:
1745 tcg_out_bswap64(s
, args
[0]);
1747 case INDEX_op_ext32u_i64
:
1748 tcg_out_ext32u(s
, args
[0], args
[1]);
1750 case INDEX_op_ext32s_i64
:
1751 tcg_out_ext32s(s
, args
[0], args
[1]);
1756 if (args
[3] == 0 && args
[4] == 8) {
1757 /* load bits 0..7 */
1758 tcg_out_modrm(s
, OPC_MOVB_EvGv
| P_REXB_R
| P_REXB_RM
,
1760 } else if (args
[3] == 8 && args
[4] == 8) {
1761 /* load bits 8..15 */
1762 tcg_out_modrm(s
, OPC_MOVB_EvGv
, args
[2], args
[0] + 4);
1763 } else if (args
[3] == 0 && args
[4] == 16) {
1764 /* load bits 0..15 */
1765 tcg_out_modrm(s
, OPC_MOVL_EvGv
| P_DATA16
, args
[2], args
[0]);
1778 static const TCGTargetOpDef x86_op_defs
[] = {
1779 { INDEX_op_exit_tb
, { } },
1780 { INDEX_op_goto_tb
, { } },
1781 { INDEX_op_call
, { "ri" } },
1782 { INDEX_op_jmp
, { "ri" } },
1783 { INDEX_op_br
, { } },
1784 { INDEX_op_mov_i32
, { "r", "r" } },
1785 { INDEX_op_movi_i32
, { "r" } },
1786 { INDEX_op_ld8u_i32
, { "r", "r" } },
1787 { INDEX_op_ld8s_i32
, { "r", "r" } },
1788 { INDEX_op_ld16u_i32
, { "r", "r" } },
1789 { INDEX_op_ld16s_i32
, { "r", "r" } },
1790 { INDEX_op_ld_i32
, { "r", "r" } },
1791 { INDEX_op_st8_i32
, { "q", "r" } },
1792 { INDEX_op_st16_i32
, { "r", "r" } },
1793 { INDEX_op_st_i32
, { "r", "r" } },
1795 { INDEX_op_add_i32
, { "r", "r", "ri" } },
1796 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
1797 { INDEX_op_mul_i32
, { "r", "0", "ri" } },
1798 { INDEX_op_div2_i32
, { "a", "d", "0", "1", "r" } },
1799 { INDEX_op_divu2_i32
, { "a", "d", "0", "1", "r" } },
1800 { INDEX_op_and_i32
, { "r", "0", "ri" } },
1801 { INDEX_op_or_i32
, { "r", "0", "ri" } },
1802 { INDEX_op_xor_i32
, { "r", "0", "ri" } },
1804 { INDEX_op_shl_i32
, { "r", "0", "ci" } },
1805 { INDEX_op_shr_i32
, { "r", "0", "ci" } },
1806 { INDEX_op_sar_i32
, { "r", "0", "ci" } },
1807 { INDEX_op_rotl_i32
, { "r", "0", "ci" } },
1808 { INDEX_op_rotr_i32
, { "r", "0", "ci" } },
1810 { INDEX_op_brcond_i32
, { "r", "ri" } },
1812 { INDEX_op_bswap16_i32
, { "r", "0" } },
1813 { INDEX_op_bswap32_i32
, { "r", "0" } },
1815 { INDEX_op_neg_i32
, { "r", "0" } },
1817 { INDEX_op_not_i32
, { "r", "0" } },
1819 { INDEX_op_ext8s_i32
, { "r", "q" } },
1820 { INDEX_op_ext16s_i32
, { "r", "r" } },
1821 { INDEX_op_ext8u_i32
, { "r", "q" } },
1822 { INDEX_op_ext16u_i32
, { "r", "r" } },
1824 { INDEX_op_setcond_i32
, { "q", "r", "ri" } },
1826 { INDEX_op_deposit_i32
, { "Q", "0", "Q" } },
1828 #if TCG_TARGET_REG_BITS == 32
1829 { INDEX_op_mulu2_i32
, { "a", "d", "a", "r" } },
1830 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1831 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1832 { INDEX_op_brcond2_i32
, { "r", "r", "ri", "ri" } },
1833 { INDEX_op_setcond2_i32
, { "r", "r", "r", "ri", "ri" } },
1835 { INDEX_op_mov_i64
, { "r", "r" } },
1836 { INDEX_op_movi_i64
, { "r" } },
1837 { INDEX_op_ld8u_i64
, { "r", "r" } },
1838 { INDEX_op_ld8s_i64
, { "r", "r" } },
1839 { INDEX_op_ld16u_i64
, { "r", "r" } },
1840 { INDEX_op_ld16s_i64
, { "r", "r" } },
1841 { INDEX_op_ld32u_i64
, { "r", "r" } },
1842 { INDEX_op_ld32s_i64
, { "r", "r" } },
1843 { INDEX_op_ld_i64
, { "r", "r" } },
1844 { INDEX_op_st8_i64
, { "r", "r" } },
1845 { INDEX_op_st16_i64
, { "r", "r" } },
1846 { INDEX_op_st32_i64
, { "r", "r" } },
1847 { INDEX_op_st_i64
, { "r", "r" } },
1849 { INDEX_op_add_i64
, { "r", "0", "re" } },
1850 { INDEX_op_mul_i64
, { "r", "0", "re" } },
1851 { INDEX_op_div2_i64
, { "a", "d", "0", "1", "r" } },
1852 { INDEX_op_divu2_i64
, { "a", "d", "0", "1", "r" } },
1853 { INDEX_op_sub_i64
, { "r", "0", "re" } },
1854 { INDEX_op_and_i64
, { "r", "0", "reZ" } },
1855 { INDEX_op_or_i64
, { "r", "0", "re" } },
1856 { INDEX_op_xor_i64
, { "r", "0", "re" } },
1858 { INDEX_op_shl_i64
, { "r", "0", "ci" } },
1859 { INDEX_op_shr_i64
, { "r", "0", "ci" } },
1860 { INDEX_op_sar_i64
, { "r", "0", "ci" } },
1861 { INDEX_op_rotl_i64
, { "r", "0", "ci" } },
1862 { INDEX_op_rotr_i64
, { "r", "0", "ci" } },
1864 { INDEX_op_brcond_i64
, { "r", "re" } },
1865 { INDEX_op_setcond_i64
, { "r", "r", "re" } },
1867 { INDEX_op_bswap16_i64
, { "r", "0" } },
1868 { INDEX_op_bswap32_i64
, { "r", "0" } },
1869 { INDEX_op_bswap64_i64
, { "r", "0" } },
1870 { INDEX_op_neg_i64
, { "r", "0" } },
1871 { INDEX_op_not_i64
, { "r", "0" } },
1873 { INDEX_op_ext8s_i64
, { "r", "r" } },
1874 { INDEX_op_ext16s_i64
, { "r", "r" } },
1875 { INDEX_op_ext32s_i64
, { "r", "r" } },
1876 { INDEX_op_ext8u_i64
, { "r", "r" } },
1877 { INDEX_op_ext16u_i64
, { "r", "r" } },
1878 { INDEX_op_ext32u_i64
, { "r", "r" } },
1880 { INDEX_op_deposit_i64
, { "Q", "0", "Q" } },
1883 #if TCG_TARGET_REG_BITS == 64
1884 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1885 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1886 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1887 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1888 { INDEX_op_qemu_ld32
, { "r", "L" } },
1889 { INDEX_op_qemu_ld32u
, { "r", "L" } },
1890 { INDEX_op_qemu_ld32s
, { "r", "L" } },
1891 { INDEX_op_qemu_ld64
, { "r", "L" } },
1893 { INDEX_op_qemu_st8
, { "L", "L" } },
1894 { INDEX_op_qemu_st16
, { "L", "L" } },
1895 { INDEX_op_qemu_st32
, { "L", "L" } },
1896 { INDEX_op_qemu_st64
, { "L", "L" } },
1897 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1898 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1899 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1900 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1901 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1902 { INDEX_op_qemu_ld32
, { "r", "L" } },
1903 { INDEX_op_qemu_ld64
, { "r", "r", "L" } },
1905 { INDEX_op_qemu_st8
, { "cb", "L" } },
1906 { INDEX_op_qemu_st16
, { "L", "L" } },
1907 { INDEX_op_qemu_st32
, { "L", "L" } },
1908 { INDEX_op_qemu_st64
, { "L", "L", "L" } },
1910 { INDEX_op_qemu_ld8u
, { "r", "L", "L" } },
1911 { INDEX_op_qemu_ld8s
, { "r", "L", "L" } },
1912 { INDEX_op_qemu_ld16u
, { "r", "L", "L" } },
1913 { INDEX_op_qemu_ld16s
, { "r", "L", "L" } },
1914 { INDEX_op_qemu_ld32
, { "r", "L", "L" } },
1915 { INDEX_op_qemu_ld64
, { "r", "r", "L", "L" } },
1917 { INDEX_op_qemu_st8
, { "cb", "L", "L" } },
1918 { INDEX_op_qemu_st16
, { "L", "L", "L" } },
1919 { INDEX_op_qemu_st32
, { "L", "L", "L" } },
1920 { INDEX_op_qemu_st64
, { "L", "L", "L", "L" } },
1925 static int tcg_target_callee_save_regs
[] = {
1926 #if TCG_TARGET_REG_BITS == 64
1931 TCG_REG_R14
, /* Currently used for the global env. */
1934 TCG_REG_EBP
, /* Currently used for the global env. */
1941 /* Generate global QEMU prologue and epilogue code */
1942 static void tcg_target_qemu_prologue(TCGContext
*s
)
1944 int i
, frame_size
, push_size
, stack_addend
;
1948 /* Reserve some stack space, also for TCG temps. */
1949 push_size
= 1 + ARRAY_SIZE(tcg_target_callee_save_regs
);
1950 push_size
*= TCG_TARGET_REG_BITS
/ 8;
1952 frame_size
= push_size
+ TCG_STATIC_CALL_ARGS_SIZE
+
1953 CPU_TEMP_BUF_NLONGS
* sizeof(long);
1954 frame_size
= (frame_size
+ TCG_TARGET_STACK_ALIGN
- 1) &
1955 ~(TCG_TARGET_STACK_ALIGN
- 1);
1956 stack_addend
= frame_size
- push_size
;
1957 tcg_set_frame(s
, TCG_REG_CALL_STACK
, TCG_STATIC_CALL_ARGS_SIZE
,
1958 CPU_TEMP_BUF_NLONGS
* sizeof(long));
1960 /* Save all callee saved registers. */
1961 for (i
= 0; i
< ARRAY_SIZE(tcg_target_callee_save_regs
); i
++) {
1962 tcg_out_push(s
, tcg_target_callee_save_regs
[i
]);
1965 tcg_out_addi(s
, TCG_REG_ESP
, -stack_addend
);
1967 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
1970 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, tcg_target_call_iarg_regs
[1]);
1973 tb_ret_addr
= s
->code_ptr
;
1975 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_addend
);
1977 for (i
= ARRAY_SIZE(tcg_target_callee_save_regs
) - 1; i
>= 0; i
--) {
1978 tcg_out_pop(s
, tcg_target_callee_save_regs
[i
]);
1980 tcg_out_opc(s
, OPC_RET
, 0, 0, 0);
1983 static void tcg_target_init(TCGContext
*s
)
1985 #if !defined(CONFIG_USER_ONLY)
1987 if ((1 << CPU_TLB_ENTRY_BITS
) != sizeof(CPUTLBEntry
))
1991 if (TCG_TARGET_REG_BITS
== 64) {
1992 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
1993 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
1995 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xff);
1998 tcg_regset_clear(tcg_target_call_clobber_regs
);
1999 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EAX
);
2000 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EDX
);
2001 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_ECX
);
2002 if (TCG_TARGET_REG_BITS
== 64) {
2003 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RDI
);
2004 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RSI
);
2005 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R8
);
2006 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R9
);
2007 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R10
);
2008 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R11
);
2011 tcg_regset_clear(s
->reserved_regs
);
2012 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2014 tcg_add_target_add_op_defs(x86_op_defs
);