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
78 /* 32 bit mode uses stack based calling convention (GCC default). */
82 static const int tcg_target_call_oarg_regs
[] = {
84 #if TCG_TARGET_REG_BITS == 32
89 /* Registers used with L constraint, which are the first argument
90 registers on x86_64, and two random call clobbered registers on
92 #if TCG_TARGET_REG_BITS == 64
93 # define TCG_REG_L0 tcg_target_call_iarg_regs[0]
94 # define TCG_REG_L1 tcg_target_call_iarg_regs[1]
96 # define TCG_REG_L0 TCG_REG_EAX
97 # define TCG_REG_L1 TCG_REG_EDX
100 /* For 32-bit, we are going to attempt to determine at runtime whether cmov
101 is available. However, the host compiler must supply <cpuid.h>, as we're
102 not going to go so far as our own inline assembly. */
103 #if TCG_TARGET_REG_BITS == 64
105 #elif defined(CONFIG_CPUID_H)
107 static bool have_cmov
;
112 static uint8_t *tb_ret_addr
;
114 static void patch_reloc(uint8_t *code_ptr
, int type
,
115 tcg_target_long value
, tcg_target_long addend
)
120 value
-= (uintptr_t)code_ptr
;
121 if (value
!= (int32_t)value
) {
124 *(uint32_t *)code_ptr
= value
;
127 value
-= (uintptr_t)code_ptr
;
128 if (value
!= (int8_t)value
) {
131 *(uint8_t *)code_ptr
= value
;
138 /* parse target specific constraints */
139 static int target_parse_constraint(TCGArgConstraint
*ct
, const char **pct_str
)
146 ct
->ct
|= TCG_CT_REG
;
147 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EAX
);
150 ct
->ct
|= TCG_CT_REG
;
151 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EBX
);
154 ct
->ct
|= TCG_CT_REG
;
155 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ECX
);
158 ct
->ct
|= TCG_CT_REG
;
159 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDX
);
162 ct
->ct
|= TCG_CT_REG
;
163 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ESI
);
166 ct
->ct
|= TCG_CT_REG
;
167 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDI
);
170 ct
->ct
|= TCG_CT_REG
;
171 if (TCG_TARGET_REG_BITS
== 64) {
172 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
174 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
178 ct
->ct
|= TCG_CT_REG
;
179 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
182 ct
->ct
|= TCG_CT_REG
;
183 if (TCG_TARGET_REG_BITS
== 64) {
184 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
186 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
190 /* qemu_ld/st address constraint */
192 ct
->ct
|= TCG_CT_REG
;
193 #if TCG_TARGET_REG_BITS == 64
194 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
196 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
198 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_L0
);
199 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_L1
);
203 ct
->ct
|= TCG_CT_CONST_S32
;
206 ct
->ct
|= TCG_CT_CONST_U32
;
217 /* test if a constant matches the constraint */
218 static inline int tcg_target_const_match(tcg_target_long val
,
219 const TCGArgConstraint
*arg_ct
)
222 if (ct
& TCG_CT_CONST
) {
225 if ((ct
& TCG_CT_CONST_S32
) && val
== (int32_t)val
) {
228 if ((ct
& TCG_CT_CONST_U32
) && val
== (uint32_t)val
) {
234 #if TCG_TARGET_REG_BITS == 64
235 # define LOWREGMASK(x) ((x) & 7)
237 # define LOWREGMASK(x) (x)
240 #define P_EXT 0x100 /* 0x0f opcode prefix */
241 #define P_DATA16 0x200 /* 0x66 opcode prefix */
242 #if TCG_TARGET_REG_BITS == 64
243 # define P_ADDR32 0x400 /* 0x67 opcode prefix */
244 # define P_REXW 0x800 /* Set REX.W = 1 */
245 # define P_REXB_R 0x1000 /* REG field as byte register */
246 # define P_REXB_RM 0x2000 /* R/M field as byte register */
247 # define P_GS 0x4000 /* gs segment override */
256 #define OPC_ARITH_EvIz (0x81)
257 #define OPC_ARITH_EvIb (0x83)
258 #define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
259 #define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
260 #define OPC_BSWAP (0xc8 | P_EXT)
261 #define OPC_CALL_Jz (0xe8)
262 #define OPC_CMOVCC (0x40 | P_EXT) /* ... plus condition code */
263 #define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
264 #define OPC_DEC_r32 (0x48)
265 #define OPC_IMUL_GvEv (0xaf | P_EXT)
266 #define OPC_IMUL_GvEvIb (0x6b)
267 #define OPC_IMUL_GvEvIz (0x69)
268 #define OPC_INC_r32 (0x40)
269 #define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
270 #define OPC_JCC_short (0x70) /* ... plus condition code */
271 #define OPC_JMP_long (0xe9)
272 #define OPC_JMP_short (0xeb)
273 #define OPC_LEA (0x8d)
274 #define OPC_MOVB_EvGv (0x88) /* stores, more or less */
275 #define OPC_MOVL_EvGv (0x89) /* stores, more or less */
276 #define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
277 #define OPC_MOVB_EvIz (0xc6)
278 #define OPC_MOVL_EvIz (0xc7)
279 #define OPC_MOVL_Iv (0xb8)
280 #define OPC_MOVSBL (0xbe | P_EXT)
281 #define OPC_MOVSWL (0xbf | P_EXT)
282 #define OPC_MOVSLQ (0x63 | P_REXW)
283 #define OPC_MOVZBL (0xb6 | P_EXT)
284 #define OPC_MOVZWL (0xb7 | P_EXT)
285 #define OPC_POP_r32 (0x58)
286 #define OPC_PUSH_r32 (0x50)
287 #define OPC_PUSH_Iv (0x68)
288 #define OPC_PUSH_Ib (0x6a)
289 #define OPC_RET (0xc3)
290 #define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
291 #define OPC_SHIFT_1 (0xd1)
292 #define OPC_SHIFT_Ib (0xc1)
293 #define OPC_SHIFT_cl (0xd3)
294 #define OPC_TESTL (0x85)
295 #define OPC_XCHG_ax_r32 (0x90)
297 #define OPC_GRP3_Ev (0xf7)
298 #define OPC_GRP5 (0xff)
300 /* Group 1 opcode extensions for 0x80-0x83.
301 These are also used as modifiers for OPC_ARITH. */
311 /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
318 /* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
326 /* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
327 #define EXT5_INC_Ev 0
328 #define EXT5_DEC_Ev 1
329 #define EXT5_CALLN_Ev 2
330 #define EXT5_JMPN_Ev 4
332 /* Condition codes to be added to OPC_JCC_{long,short}. */
351 static const uint8_t tcg_cond_to_jcc
[] = {
352 [TCG_COND_EQ
] = JCC_JE
,
353 [TCG_COND_NE
] = JCC_JNE
,
354 [TCG_COND_LT
] = JCC_JL
,
355 [TCG_COND_GE
] = JCC_JGE
,
356 [TCG_COND_LE
] = JCC_JLE
,
357 [TCG_COND_GT
] = JCC_JG
,
358 [TCG_COND_LTU
] = JCC_JB
,
359 [TCG_COND_GEU
] = JCC_JAE
,
360 [TCG_COND_LEU
] = JCC_JBE
,
361 [TCG_COND_GTU
] = JCC_JA
,
364 #if TCG_TARGET_REG_BITS == 64
365 static void tcg_out_opc(TCGContext
*s
, int opc
, int r
, int rm
, int x
)
372 if (opc
& P_DATA16
) {
373 /* We should never be asking for both 16 and 64-bit operation. */
374 assert((opc
& P_REXW
) == 0);
377 if (opc
& P_ADDR32
) {
382 rex
|= (opc
& P_REXW
) >> 8; /* REX.W */
383 rex
|= (r
& 8) >> 1; /* REX.R */
384 rex
|= (x
& 8) >> 2; /* REX.X */
385 rex
|= (rm
& 8) >> 3; /* REX.B */
387 /* P_REXB_{R,RM} indicates that the given register is the low byte.
388 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
389 as otherwise the encoding indicates %[abcd]h. Note that the values
390 that are ORed in merely indicate that the REX byte must be present;
391 those bits get discarded in output. */
392 rex
|= opc
& (r
>= 4 ? P_REXB_R
: 0);
393 rex
|= opc
& (rm
>= 4 ? P_REXB_RM
: 0);
396 tcg_out8(s
, (uint8_t)(rex
| 0x40));
405 static void tcg_out_opc(TCGContext
*s
, int opc
)
407 if (opc
& P_DATA16
) {
415 /* Discard the register arguments to tcg_out_opc early, so as not to penalize
416 the 32-bit compilation paths. This method works with all versions of gcc,
417 whereas relying on optimization may not be able to exclude them. */
418 #define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
421 static void tcg_out_modrm(TCGContext
*s
, int opc
, int r
, int rm
)
423 tcg_out_opc(s
, opc
, r
, rm
, 0);
424 tcg_out8(s
, 0xc0 | (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
427 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
428 We handle either RM and INDEX missing with a negative value. In 64-bit
429 mode for absolute addresses, ~RM is the size of the immediate operand
430 that will follow the instruction. */
432 static void tcg_out_modrm_sib_offset(TCGContext
*s
, int opc
, int r
, int rm
,
433 int index
, int shift
,
434 tcg_target_long offset
)
438 if (index
< 0 && rm
< 0) {
439 if (TCG_TARGET_REG_BITS
== 64) {
440 /* Try for a rip-relative addressing mode. This has replaced
441 the 32-bit-mode absolute addressing encoding. */
442 tcg_target_long pc
= (tcg_target_long
)s
->code_ptr
+ 5 + ~rm
;
443 tcg_target_long disp
= offset
- pc
;
444 if (disp
== (int32_t)disp
) {
445 tcg_out_opc(s
, opc
, r
, 0, 0);
446 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 5);
451 /* Try for an absolute address encoding. This requires the
452 use of the MODRM+SIB encoding and is therefore larger than
453 rip-relative addressing. */
454 if (offset
== (int32_t)offset
) {
455 tcg_out_opc(s
, opc
, r
, 0, 0);
456 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 4);
457 tcg_out8(s
, (4 << 3) | 5);
458 tcg_out32(s
, offset
);
462 /* ??? The memory isn't directly addressable. */
465 /* Absolute address. */
466 tcg_out_opc(s
, opc
, r
, 0, 0);
467 tcg_out8(s
, (r
<< 3) | 5);
468 tcg_out32(s
, offset
);
473 /* Find the length of the immediate addend. Note that the encoding
474 that would be used for (%ebp) indicates absolute addressing. */
476 mod
= 0, len
= 4, rm
= 5;
477 } else if (offset
== 0 && LOWREGMASK(rm
) != TCG_REG_EBP
) {
479 } else if (offset
== (int8_t)offset
) {
485 /* Use a single byte MODRM format if possible. Note that the encoding
486 that would be used for %esp is the escape to the two byte form. */
487 if (index
< 0 && LOWREGMASK(rm
) != TCG_REG_ESP
) {
488 /* Single byte MODRM format. */
489 tcg_out_opc(s
, opc
, r
, rm
, 0);
490 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
492 /* Two byte MODRM+SIB format. */
494 /* Note that the encoding that would place %esp into the index
495 field indicates no index register. In 64-bit mode, the REX.X
496 bit counts, so %r12 can be used as the index. */
500 assert(index
!= TCG_REG_ESP
);
503 tcg_out_opc(s
, opc
, r
, rm
, index
);
504 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | 4);
505 tcg_out8(s
, (shift
<< 6) | (LOWREGMASK(index
) << 3) | LOWREGMASK(rm
));
510 } else if (len
== 4) {
511 tcg_out32(s
, offset
);
515 /* A simplification of the above with no index or shift. */
516 static inline void tcg_out_modrm_offset(TCGContext
*s
, int opc
, int r
,
517 int rm
, tcg_target_long offset
)
519 tcg_out_modrm_sib_offset(s
, opc
, r
, rm
, -1, 0, offset
);
522 /* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
523 static inline void tgen_arithr(TCGContext
*s
, int subop
, int dest
, int src
)
525 /* Propagate an opcode prefix, such as P_REXW. */
526 int ext
= subop
& ~0x7;
529 tcg_out_modrm(s
, OPC_ARITH_GvEv
+ (subop
<< 3) + ext
, dest
, src
);
532 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
533 TCGReg ret
, TCGReg arg
)
536 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
537 tcg_out_modrm(s
, opc
, ret
, arg
);
541 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
542 TCGReg ret
, tcg_target_long arg
)
545 tgen_arithr(s
, ARITH_XOR
, ret
, ret
);
547 } else if (arg
== (uint32_t)arg
|| type
== TCG_TYPE_I32
) {
548 tcg_out_opc(s
, OPC_MOVL_Iv
+ LOWREGMASK(ret
), 0, ret
, 0);
550 } else if (arg
== (int32_t)arg
) {
551 tcg_out_modrm(s
, OPC_MOVL_EvIz
+ P_REXW
, 0, ret
);
554 tcg_out_opc(s
, OPC_MOVL_Iv
+ P_REXW
+ LOWREGMASK(ret
), 0, ret
, 0);
556 tcg_out32(s
, arg
>> 31 >> 1);
560 static inline void tcg_out_pushi(TCGContext
*s
, tcg_target_long val
)
562 if (val
== (int8_t)val
) {
563 tcg_out_opc(s
, OPC_PUSH_Ib
, 0, 0, 0);
565 } else if (val
== (int32_t)val
) {
566 tcg_out_opc(s
, OPC_PUSH_Iv
, 0, 0, 0);
573 static inline void tcg_out_push(TCGContext
*s
, int reg
)
575 tcg_out_opc(s
, OPC_PUSH_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
578 static inline void tcg_out_pop(TCGContext
*s
, int reg
)
580 tcg_out_opc(s
, OPC_POP_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
583 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg ret
,
584 TCGReg arg1
, tcg_target_long arg2
)
586 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
587 tcg_out_modrm_offset(s
, opc
, ret
, arg1
, arg2
);
590 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
591 TCGReg arg1
, tcg_target_long arg2
)
593 int opc
= OPC_MOVL_EvGv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
594 tcg_out_modrm_offset(s
, opc
, arg
, arg1
, arg2
);
597 static void tcg_out_shifti(TCGContext
*s
, int subopc
, int reg
, int count
)
599 /* Propagate an opcode prefix, such as P_DATA16. */
600 int ext
= subopc
& ~0x7;
604 tcg_out_modrm(s
, OPC_SHIFT_1
+ ext
, subopc
, reg
);
606 tcg_out_modrm(s
, OPC_SHIFT_Ib
+ ext
, subopc
, reg
);
611 static inline void tcg_out_bswap32(TCGContext
*s
, int reg
)
613 tcg_out_opc(s
, OPC_BSWAP
+ LOWREGMASK(reg
), 0, reg
, 0);
616 static inline void tcg_out_rolw_8(TCGContext
*s
, int reg
)
618 tcg_out_shifti(s
, SHIFT_ROL
+ P_DATA16
, reg
, 8);
621 static inline void tcg_out_ext8u(TCGContext
*s
, int dest
, int src
)
624 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
625 tcg_out_modrm(s
, OPC_MOVZBL
+ P_REXB_RM
, dest
, src
);
628 static void tcg_out_ext8s(TCGContext
*s
, int dest
, int src
, int rexw
)
631 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
632 tcg_out_modrm(s
, OPC_MOVSBL
+ P_REXB_RM
+ rexw
, dest
, src
);
635 static inline void tcg_out_ext16u(TCGContext
*s
, int dest
, int src
)
638 tcg_out_modrm(s
, OPC_MOVZWL
, dest
, src
);
641 static inline void tcg_out_ext16s(TCGContext
*s
, int dest
, int src
, int rexw
)
644 tcg_out_modrm(s
, OPC_MOVSWL
+ rexw
, dest
, src
);
647 static inline void tcg_out_ext32u(TCGContext
*s
, int dest
, int src
)
649 /* 32-bit mov zero extends. */
650 tcg_out_modrm(s
, OPC_MOVL_GvEv
, dest
, src
);
653 static inline void tcg_out_ext32s(TCGContext
*s
, int dest
, int src
)
655 tcg_out_modrm(s
, OPC_MOVSLQ
, dest
, src
);
658 static inline void tcg_out_bswap64(TCGContext
*s
, int reg
)
660 tcg_out_opc(s
, OPC_BSWAP
+ P_REXW
+ LOWREGMASK(reg
), 0, reg
, 0);
663 static void tgen_arithi(TCGContext
*s
, int c
, int r0
,
664 tcg_target_long val
, int cf
)
668 if (TCG_TARGET_REG_BITS
== 64) {
673 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
674 partial flags update stalls on Pentium4 and are not recommended
675 by current Intel optimization manuals. */
676 if (!cf
&& (c
== ARITH_ADD
|| c
== ARITH_SUB
) && (val
== 1 || val
== -1)) {
677 int is_inc
= (c
== ARITH_ADD
) ^ (val
< 0);
678 if (TCG_TARGET_REG_BITS
== 64) {
679 /* The single-byte increment encodings are re-tasked as the
680 REX prefixes. Use the MODRM encoding. */
681 tcg_out_modrm(s
, OPC_GRP5
+ rexw
,
682 (is_inc
? EXT5_INC_Ev
: EXT5_DEC_Ev
), r0
);
684 tcg_out8(s
, (is_inc
? OPC_INC_r32
: OPC_DEC_r32
) + r0
);
689 if (c
== ARITH_AND
) {
690 if (TCG_TARGET_REG_BITS
== 64) {
691 if (val
== 0xffffffffu
) {
692 tcg_out_ext32u(s
, r0
, r0
);
695 if (val
== (uint32_t)val
) {
696 /* AND with no high bits set can use a 32-bit operation. */
700 if (val
== 0xffu
&& (r0
< 4 || TCG_TARGET_REG_BITS
== 64)) {
701 tcg_out_ext8u(s
, r0
, r0
);
704 if (val
== 0xffffu
) {
705 tcg_out_ext16u(s
, r0
, r0
);
710 if (val
== (int8_t)val
) {
711 tcg_out_modrm(s
, OPC_ARITH_EvIb
+ rexw
, c
, r0
);
715 if (rexw
== 0 || val
== (int32_t)val
) {
716 tcg_out_modrm(s
, OPC_ARITH_EvIz
+ rexw
, c
, r0
);
724 static void tcg_out_addi(TCGContext
*s
, int reg
, tcg_target_long val
)
727 tgen_arithi(s
, ARITH_ADD
+ P_REXW
, reg
, val
, 0);
731 /* Use SMALL != 0 to force a short forward branch. */
732 static void tcg_out_jxx(TCGContext
*s
, int opc
, int label_index
, int small
)
735 TCGLabel
*l
= &s
->labels
[label_index
];
738 val
= l
->u
.value
- (tcg_target_long
)s
->code_ptr
;
740 if ((int8_t)val1
== val1
) {
742 tcg_out8(s
, OPC_JMP_short
);
744 tcg_out8(s
, OPC_JCC_short
+ opc
);
752 tcg_out8(s
, OPC_JMP_long
);
753 tcg_out32(s
, val
- 5);
755 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
756 tcg_out32(s
, val
- 6);
761 tcg_out8(s
, OPC_JMP_short
);
763 tcg_out8(s
, OPC_JCC_short
+ opc
);
765 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC8
, label_index
, -1);
769 tcg_out8(s
, OPC_JMP_long
);
771 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
773 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC32
, label_index
, -4);
778 static void tcg_out_cmp(TCGContext
*s
, TCGArg arg1
, TCGArg arg2
,
779 int const_arg2
, int rexw
)
784 tcg_out_modrm(s
, OPC_TESTL
+ rexw
, arg1
, arg1
);
786 tgen_arithi(s
, ARITH_CMP
+ rexw
, arg1
, arg2
, 0);
789 tgen_arithr(s
, ARITH_CMP
+ rexw
, arg1
, arg2
);
793 static void tcg_out_brcond32(TCGContext
*s
, TCGCond cond
,
794 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
795 int label_index
, int small
)
797 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
798 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
801 #if TCG_TARGET_REG_BITS == 64
802 static void tcg_out_brcond64(TCGContext
*s
, TCGCond cond
,
803 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
804 int label_index
, int small
)
806 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
807 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
810 /* XXX: we implement it at the target level to avoid having to
811 handle cross basic blocks temporaries */
812 static void tcg_out_brcond2(TCGContext
*s
, const TCGArg
*args
,
813 const int *const_args
, int small
)
816 label_next
= gen_new_label();
819 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
821 tcg_out_brcond32(s
, TCG_COND_EQ
, args
[1], args
[3], const_args
[3],
825 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
827 tcg_out_brcond32(s
, TCG_COND_NE
, args
[1], args
[3], const_args
[3],
831 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
833 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
834 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
838 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
840 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
841 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
845 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
847 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
848 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
852 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
854 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
855 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
859 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
861 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
862 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
866 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
868 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
869 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
873 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
875 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
876 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
880 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
882 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
883 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
889 tcg_out_label(s
, label_next
, s
->code_ptr
);
893 static void tcg_out_setcond32(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
894 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
896 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
897 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
898 tcg_out_ext8u(s
, dest
, dest
);
901 #if TCG_TARGET_REG_BITS == 64
902 static void tcg_out_setcond64(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
903 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
905 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
906 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
907 tcg_out_ext8u(s
, dest
, dest
);
910 static void tcg_out_setcond2(TCGContext
*s
, const TCGArg
*args
,
911 const int *const_args
)
914 int label_true
, label_over
;
916 memcpy(new_args
, args
+1, 5*sizeof(TCGArg
));
918 if (args
[0] == args
[1] || args
[0] == args
[2]
919 || (!const_args
[3] && args
[0] == args
[3])
920 || (!const_args
[4] && args
[0] == args
[4])) {
921 /* When the destination overlaps with one of the argument
922 registers, don't do anything tricky. */
923 label_true
= gen_new_label();
924 label_over
= gen_new_label();
926 new_args
[5] = label_true
;
927 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
929 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
930 tcg_out_jxx(s
, JCC_JMP
, label_over
, 1);
931 tcg_out_label(s
, label_true
, s
->code_ptr
);
933 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 1);
934 tcg_out_label(s
, label_over
, s
->code_ptr
);
936 /* When the destination does not overlap one of the arguments,
937 clear the destination first, jump if cond false, and emit an
938 increment in the true case. This results in smaller code. */
940 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
942 label_over
= gen_new_label();
943 new_args
[4] = tcg_invert_cond(new_args
[4]);
944 new_args
[5] = label_over
;
945 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
947 tgen_arithi(s
, ARITH_ADD
, args
[0], 1, 0);
948 tcg_out_label(s
, label_over
, s
->code_ptr
);
953 static void tcg_out_movcond32(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
954 TCGArg c1
, TCGArg c2
, int const_c2
,
957 tcg_out_cmp(s
, c1
, c2
, const_c2
, 0);
959 tcg_out_modrm(s
, OPC_CMOVCC
| tcg_cond_to_jcc
[cond
], dest
, v1
);
961 int over
= gen_new_label();
962 tcg_out_jxx(s
, tcg_cond_to_jcc
[tcg_invert_cond(cond
)], over
, 1);
963 tcg_out_mov(s
, TCG_TYPE_I32
, dest
, v1
);
964 tcg_out_label(s
, over
, s
->code_ptr
);
968 #if TCG_TARGET_REG_BITS == 64
969 static void tcg_out_movcond64(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
970 TCGArg c1
, TCGArg c2
, int const_c2
,
973 tcg_out_cmp(s
, c1
, c2
, const_c2
, P_REXW
);
974 tcg_out_modrm(s
, OPC_CMOVCC
| tcg_cond_to_jcc
[cond
] | P_REXW
, dest
, v1
);
978 static void tcg_out_branch(TCGContext
*s
, int call
, tcg_target_long dest
)
980 tcg_target_long disp
= dest
- (tcg_target_long
)s
->code_ptr
- 5;
982 if (disp
== (int32_t)disp
) {
983 tcg_out_opc(s
, call
? OPC_CALL_Jz
: OPC_JMP_long
, 0, 0, 0);
986 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R10
, dest
);
987 tcg_out_modrm(s
, OPC_GRP5
,
988 call
? EXT5_CALLN_Ev
: EXT5_JMPN_Ev
, TCG_REG_R10
);
992 static inline void tcg_out_calli(TCGContext
*s
, tcg_target_long dest
)
994 tcg_out_branch(s
, 1, dest
);
997 static void tcg_out_jmp(TCGContext
*s
, tcg_target_long dest
)
999 tcg_out_branch(s
, 0, dest
);
1002 #if defined(CONFIG_SOFTMMU)
1004 #include "exec/softmmu_defs.h"
1006 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1008 static const void *qemu_ld_helpers
[4] = {
1015 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1016 uintxx_t val, int mmu_idx) */
1017 static const void *qemu_st_helpers
[4] = {
1024 static void add_qemu_ldst_label(TCGContext
*s
,
1033 uint8_t **label_ptr
);
1035 /* Perform the TLB load and compare.
1038 ADDRLO_IDX contains the index into ARGS of the low part of the
1039 address; the high part of the address is at ADDR_LOW_IDX+1.
1041 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1043 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1044 This should be offsetof addr_read or addr_write.
1047 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
1048 positions of the displacements of forward jumps to the TLB miss case.
1050 Second argument register is loaded with the low part of the address.
1051 In the TLB hit case, it has been adjusted as indicated by the TLB
1052 and so is a host address. In the TLB miss case, it continues to
1053 hold a guest address.
1055 First argument register is clobbered. */
1057 static inline void tcg_out_tlb_load(TCGContext
*s
, int addrlo_idx
,
1058 int mem_index
, int s_bits
,
1060 uint8_t **label_ptr
, int which
)
1062 const int addrlo
= args
[addrlo_idx
];
1063 const int r0
= TCG_REG_L0
;
1064 const int r1
= TCG_REG_L1
;
1065 TCGType type
= TCG_TYPE_I32
;
1068 if (TCG_TARGET_REG_BITS
== 64 && TARGET_LONG_BITS
== 64) {
1069 type
= TCG_TYPE_I64
;
1073 tcg_out_mov(s
, type
, r0
, addrlo
);
1074 tcg_out_mov(s
, type
, r1
, addrlo
);
1076 tcg_out_shifti(s
, SHIFT_SHR
+ rexw
, r0
,
1077 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1079 tgen_arithi(s
, ARITH_AND
+ rexw
, r1
,
1080 TARGET_PAGE_MASK
| ((1 << s_bits
) - 1), 0);
1081 tgen_arithi(s
, ARITH_AND
+ rexw
, r0
,
1082 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
, 0);
1084 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ P_REXW
, r0
, TCG_AREG0
, r0
, 0,
1085 offsetof(CPUArchState
, tlb_table
[mem_index
][0])
1089 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
+ rexw
, r1
, r0
, 0);
1091 tcg_out_mov(s
, type
, r1
, addrlo
);
1094 tcg_out_opc(s
, OPC_JCC_long
+ JCC_JNE
, 0, 0, 0);
1095 label_ptr
[0] = s
->code_ptr
;
1098 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1099 /* cmp 4(r0), addrhi */
1100 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
, args
[addrlo_idx
+1], r0
, 4);
1103 tcg_out_opc(s
, OPC_JCC_long
+ JCC_JNE
, 0, 0, 0);
1104 label_ptr
[1] = s
->code_ptr
;
1110 /* add addend(r0), r1 */
1111 tcg_out_modrm_offset(s
, OPC_ADD_GvEv
+ P_REXW
, r1
, r0
,
1112 offsetof(CPUTLBEntry
, addend
) - which
);
1114 #elif defined(__x86_64__) && defined(__linux__)
1115 # include <asm/prctl.h>
1116 # include <sys/prctl.h>
1118 int arch_prctl(int code
, unsigned long addr
);
1120 static int guest_base_flags
;
1121 static inline void setup_guest_base_seg(void)
1123 if (arch_prctl(ARCH_SET_GS
, GUEST_BASE
) == 0) {
1124 guest_base_flags
= P_GS
;
1128 # define guest_base_flags 0
1129 static inline void setup_guest_base_seg(void) { }
1130 #endif /* SOFTMMU */
1132 static void tcg_out_qemu_ld_direct(TCGContext
*s
, int datalo
, int datahi
,
1133 int base
, tcg_target_long ofs
, int seg
,
1136 #ifdef TARGET_WORDS_BIGENDIAN
1137 const int bswap
= 1;
1139 const int bswap
= 0;
1143 tcg_out_modrm_offset(s
, OPC_MOVZBL
+ seg
, datalo
, base
, ofs
);
1146 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ P_REXW
+ seg
, datalo
, base
, ofs
);
1149 tcg_out_modrm_offset(s
, OPC_MOVZWL
+ seg
, datalo
, base
, ofs
);
1151 tcg_out_rolw_8(s
, datalo
);
1156 tcg_out_modrm_offset(s
, OPC_MOVZWL
+ seg
, datalo
, base
, ofs
);
1157 tcg_out_rolw_8(s
, datalo
);
1158 tcg_out_modrm(s
, OPC_MOVSWL
+ P_REXW
, datalo
, datalo
);
1160 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ P_REXW
+ seg
,
1165 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
, datalo
, base
, ofs
);
1167 tcg_out_bswap32(s
, datalo
);
1170 #if TCG_TARGET_REG_BITS == 64
1173 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
, datalo
, base
, ofs
);
1174 tcg_out_bswap32(s
, datalo
);
1175 tcg_out_ext32s(s
, datalo
, datalo
);
1177 tcg_out_modrm_offset(s
, OPC_MOVSLQ
+ seg
, datalo
, base
, ofs
);
1182 if (TCG_TARGET_REG_BITS
== 64) {
1183 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ P_REXW
+ seg
,
1186 tcg_out_bswap64(s
, datalo
);
1194 if (base
!= datalo
) {
1195 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
,
1197 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
,
1198 datahi
, base
, ofs
+ 4);
1200 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
,
1201 datahi
, base
, ofs
+ 4);
1202 tcg_out_modrm_offset(s
, OPC_MOVL_GvEv
+ seg
,
1206 tcg_out_bswap32(s
, datalo
);
1207 tcg_out_bswap32(s
, datahi
);
1216 /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1217 EAX. It will be useful once fixed registers globals are less
1219 static void tcg_out_qemu_ld(TCGContext
*s
, const TCGArg
*args
,
1222 int data_reg
, data_reg2
= 0;
1224 #if defined(CONFIG_SOFTMMU)
1225 int mem_index
, s_bits
;
1226 uint8_t *label_ptr
[2];
1231 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1232 data_reg2
= args
[1];
1236 #if defined(CONFIG_SOFTMMU)
1237 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1240 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1241 label_ptr
, offsetof(CPUTLBEntry
, addr_read
));
1244 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
, TCG_REG_L1
, 0, 0, opc
);
1246 /* Record the current context of a load into ldst label */
1247 add_qemu_ldst_label(s
,
1253 args
[addrlo_idx
+ 1],
1259 int32_t offset
= GUEST_BASE
;
1260 int base
= args
[addrlo_idx
];
1263 /* ??? We assume all operations have left us with register contents
1264 that are zero extended. So far this appears to be true. If we
1265 want to enforce this, we can either do an explicit zero-extension
1266 here, or (if GUEST_BASE == 0, or a segment register is in use)
1267 use the ADDR32 prefix. For now, do nothing. */
1268 if (GUEST_BASE
&& guest_base_flags
) {
1269 seg
= guest_base_flags
;
1271 } else if (TCG_TARGET_REG_BITS
== 64 && offset
!= GUEST_BASE
) {
1272 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_L1
, GUEST_BASE
);
1273 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_L1
, base
);
1278 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
, base
, offset
, seg
, opc
);
1283 static void tcg_out_qemu_st_direct(TCGContext
*s
, int datalo
, int datahi
,
1284 int base
, tcg_target_long ofs
, int seg
,
1287 #ifdef TARGET_WORDS_BIGENDIAN
1288 const int bswap
= 1;
1290 const int bswap
= 0;
1292 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1293 we could perform the bswap twice to restore the original value
1294 instead of moving to the scratch. But as it is, the L constraint
1295 means that TCG_REG_L0 is definitely free here. */
1296 const int scratch
= TCG_REG_L0
;
1300 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
+ P_REXB_R
+ seg
,
1305 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1306 tcg_out_rolw_8(s
, scratch
);
1309 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ P_DATA16
+ seg
,
1314 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1315 tcg_out_bswap32(s
, scratch
);
1318 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ seg
, datalo
, base
, ofs
);
1321 if (TCG_TARGET_REG_BITS
== 64) {
1323 tcg_out_mov(s
, TCG_TYPE_I64
, scratch
, datalo
);
1324 tcg_out_bswap64(s
, scratch
);
1327 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ P_REXW
+ seg
,
1330 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datahi
);
1331 tcg_out_bswap32(s
, scratch
);
1332 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ seg
, scratch
, base
, ofs
);
1333 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1334 tcg_out_bswap32(s
, scratch
);
1335 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ seg
, scratch
, base
, ofs
+4);
1337 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ seg
, datalo
, base
, ofs
);
1338 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ seg
, datahi
, base
, ofs
+4);
1346 static void tcg_out_qemu_st(TCGContext
*s
, const TCGArg
*args
,
1349 int data_reg
, data_reg2
= 0;
1351 #if defined(CONFIG_SOFTMMU)
1352 int mem_index
, s_bits
;
1353 uint8_t *label_ptr
[2];
1358 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1359 data_reg2
= args
[1];
1363 #if defined(CONFIG_SOFTMMU)
1364 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1367 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1368 label_ptr
, offsetof(CPUTLBEntry
, addr_write
));
1371 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
, TCG_REG_L1
, 0, 0, opc
);
1373 /* Record the current context of a store into ldst label */
1374 add_qemu_ldst_label(s
,
1380 args
[addrlo_idx
+ 1],
1386 int32_t offset
= GUEST_BASE
;
1387 int base
= args
[addrlo_idx
];
1390 /* ??? We assume all operations have left us with register contents
1391 that are zero extended. So far this appears to be true. If we
1392 want to enforce this, we can either do an explicit zero-extension
1393 here, or (if GUEST_BASE == 0, or a segment register is in use)
1394 use the ADDR32 prefix. For now, do nothing. */
1395 if (GUEST_BASE
&& guest_base_flags
) {
1396 seg
= guest_base_flags
;
1398 } else if (TCG_TARGET_REG_BITS
== 64 && offset
!= GUEST_BASE
) {
1399 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_L1
, GUEST_BASE
);
1400 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_L1
, base
);
1405 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
, base
, offset
, seg
, opc
);
1410 #if defined(CONFIG_SOFTMMU)
1412 * Record the context of a call to the out of line helper code for the slow path
1413 * for a load or store, so that we can later generate the correct helper code
1415 static void add_qemu_ldst_label(TCGContext
*s
,
1424 uint8_t **label_ptr
)
1427 TCGLabelQemuLdst
*label
;
1429 if (s
->nb_qemu_ldst_labels
>= TCG_MAX_QEMU_LDST
) {
1433 idx
= s
->nb_qemu_ldst_labels
++;
1434 label
= (TCGLabelQemuLdst
*)&s
->qemu_ldst_labels
[idx
];
1435 label
->is_ld
= is_ld
;
1437 label
->datalo_reg
= data_reg
;
1438 label
->datahi_reg
= data_reg2
;
1439 label
->addrlo_reg
= addrlo_reg
;
1440 label
->addrhi_reg
= addrhi_reg
;
1441 label
->mem_index
= mem_index
;
1442 label
->raddr
= raddr
;
1443 label
->label_ptr
[0] = label_ptr
[0];
1444 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1445 label
->label_ptr
[1] = label_ptr
[1];
1450 * Generate code for the slow path for a load at the end of block
1452 static void tcg_out_qemu_ld_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*label
)
1455 int opc
= label
->opc
;
1456 int mem_index
= label
->mem_index
;
1457 #if TCG_TARGET_REG_BITS == 32
1459 int addrlo_reg
= label
->addrlo_reg
;
1460 int addrhi_reg
= label
->addrhi_reg
;
1462 int data_reg
= label
->datalo_reg
;
1463 int data_reg2
= label
->datahi_reg
;
1464 uint8_t *raddr
= label
->raddr
;
1465 uint8_t **label_ptr
= &label
->label_ptr
[0];
1469 /* resolve label address */
1470 *(uint32_t *)label_ptr
[0] = (uint32_t)(s
->code_ptr
- label_ptr
[0] - 4);
1471 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1472 *(uint32_t *)label_ptr
[1] = (uint32_t)(s
->code_ptr
- label_ptr
[1] - 4);
1475 #if TCG_TARGET_REG_BITS == 32
1476 tcg_out_pushi(s
, mem_index
);
1478 if (TARGET_LONG_BITS
== 64) {
1479 tcg_out_push(s
, addrhi_reg
);
1482 tcg_out_push(s
, addrlo_reg
);
1484 tcg_out_push(s
, TCG_AREG0
);
1487 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0], TCG_AREG0
);
1488 /* The second argument is already loaded with addrlo. */
1489 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[2], mem_index
);
1492 /* Code generation of qemu_ld/st's slow path calling MMU helper
1496 jmp POST_PROC (2b) : short forward jump <- GETRA()
1497 jmp next_code (5b) : dummy long backward jump which is never executed
1498 POST_PROC ... : do post-processing <- GETRA() + 7
1499 jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
1502 tcg_out_calli(s
, (tcg_target_long
)qemu_ld_helpers
[s_bits
]);
1504 /* Jump to post-processing code */
1505 tcg_out8(s
, OPC_JMP_short
);
1507 /* Dummy backward jump having information of fast path'pc for MMU helpers */
1508 tcg_out8(s
, OPC_JMP_long
);
1509 *(int32_t *)s
->code_ptr
= (int32_t)(raddr
- s
->code_ptr
- 4);
1512 #if TCG_TARGET_REG_BITS == 32
1513 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1514 /* Pop and discard. This is 2 bytes smaller than the add. */
1515 tcg_out_pop(s
, TCG_REG_ECX
);
1516 } else if (stack_adjust
!= 0) {
1517 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1523 tcg_out_ext8s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1526 tcg_out_ext16s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1529 tcg_out_ext8u(s
, data_reg
, TCG_REG_EAX
);
1532 tcg_out_ext16u(s
, data_reg
, TCG_REG_EAX
);
1535 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1537 #if TCG_TARGET_REG_BITS == 64
1539 tcg_out_ext32s(s
, data_reg
, TCG_REG_EAX
);
1543 if (TCG_TARGET_REG_BITS
== 64) {
1544 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_RAX
);
1545 } else if (data_reg
== TCG_REG_EDX
) {
1546 /* xchg %edx, %eax */
1547 tcg_out_opc(s
, OPC_XCHG_ax_r32
+ TCG_REG_EDX
, 0, 0, 0);
1548 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EAX
);
1550 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1551 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EDX
);
1558 /* Jump to the code corresponding to next IR of qemu_st */
1559 tcg_out_jmp(s
, (tcg_target_long
)raddr
);
1563 * Generate code for the slow path for a store at the end of block
1565 static void tcg_out_qemu_st_slow_path(TCGContext
*s
, TCGLabelQemuLdst
*label
)
1569 int opc
= label
->opc
;
1570 int mem_index
= label
->mem_index
;
1571 int data_reg
= label
->datalo_reg
;
1572 #if TCG_TARGET_REG_BITS == 32
1573 int data_reg2
= label
->datahi_reg
;
1574 int addrlo_reg
= label
->addrlo_reg
;
1575 int addrhi_reg
= label
->addrhi_reg
;
1577 uint8_t *raddr
= label
->raddr
;
1578 uint8_t **label_ptr
= &label
->label_ptr
[0];
1582 /* resolve label address */
1583 *(uint32_t *)label_ptr
[0] = (uint32_t)(s
->code_ptr
- label_ptr
[0] - 4);
1584 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1585 *(uint32_t *)label_ptr
[1] = (uint32_t)(s
->code_ptr
- label_ptr
[1] - 4);
1588 #if TCG_TARGET_REG_BITS == 32
1589 tcg_out_pushi(s
, mem_index
);
1592 tcg_out_push(s
, data_reg2
);
1595 tcg_out_push(s
, data_reg
);
1597 if (TARGET_LONG_BITS
== 64) {
1598 tcg_out_push(s
, addrhi_reg
);
1601 tcg_out_push(s
, addrlo_reg
);
1603 tcg_out_push(s
, TCG_AREG0
);
1606 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0], TCG_AREG0
);
1607 /* The second argument is already loaded with addrlo. */
1608 tcg_out_mov(s
, (opc
== 3 ? TCG_TYPE_I64
: TCG_TYPE_I32
),
1609 tcg_target_call_iarg_regs
[2], data_reg
);
1610 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[3], mem_index
);
1614 /* Code generation of qemu_ld/st's slow path calling MMU helper
1618 jmp POST_PROC (2b) : short forward jump <- GETRA()
1619 jmp next_code (5b) : dummy long backward jump which is never executed
1620 POST_PROC ... : do post-processing <- GETRA() + 7
1621 jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
1624 tcg_out_calli(s
, (tcg_target_long
)qemu_st_helpers
[s_bits
]);
1626 /* Jump to post-processing code */
1627 tcg_out8(s
, OPC_JMP_short
);
1629 /* Dummy backward jump having information of fast path'pc for MMU helpers */
1630 tcg_out8(s
, OPC_JMP_long
);
1631 *(int32_t *)s
->code_ptr
= (int32_t)(raddr
- s
->code_ptr
- 4);
1634 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1635 /* Pop and discard. This is 2 bytes smaller than the add. */
1636 tcg_out_pop(s
, TCG_REG_ECX
);
1637 } else if (stack_adjust
!= 0) {
1638 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1641 /* Jump to the code corresponding to next IR of qemu_st */
1642 tcg_out_jmp(s
, (tcg_target_long
)raddr
);
1646 * Generate TB finalization at the end of block
1648 void tcg_out_tb_finalize(TCGContext
*s
)
1651 TCGLabelQemuLdst
*label
;
1653 /* qemu_ld/st slow paths */
1654 for (i
= 0; i
< s
->nb_qemu_ldst_labels
; i
++) {
1655 label
= (TCGLabelQemuLdst
*)&s
->qemu_ldst_labels
[i
];
1657 tcg_out_qemu_ld_slow_path(s
, label
);
1659 tcg_out_qemu_st_slow_path(s
, label
);
1663 #endif /* CONFIG_SOFTMMU */
1665 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1666 const TCGArg
*args
, const int *const_args
)
1670 #if TCG_TARGET_REG_BITS == 64
1671 # define OP_32_64(x) \
1672 case glue(glue(INDEX_op_, x), _i64): \
1673 rexw = P_REXW; /* FALLTHRU */ \
1674 case glue(glue(INDEX_op_, x), _i32)
1676 # define OP_32_64(x) \
1677 case glue(glue(INDEX_op_, x), _i32)
1681 case INDEX_op_exit_tb
:
1682 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_EAX
, args
[0]);
1683 tcg_out_jmp(s
, (tcg_target_long
) tb_ret_addr
);
1685 case INDEX_op_goto_tb
:
1686 if (s
->tb_jmp_offset
) {
1687 /* direct jump method */
1688 tcg_out8(s
, OPC_JMP_long
); /* jmp im */
1689 s
->tb_jmp_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1692 /* indirect jump method */
1693 tcg_out_modrm_offset(s
, OPC_GRP5
, EXT5_JMPN_Ev
, -1,
1694 (tcg_target_long
)(s
->tb_next
+ args
[0]));
1696 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1699 if (const_args
[0]) {
1700 tcg_out_calli(s
, args
[0]);
1703 tcg_out_modrm(s
, OPC_GRP5
, EXT5_CALLN_Ev
, args
[0]);
1707 tcg_out_jxx(s
, JCC_JMP
, args
[0], 0);
1709 case INDEX_op_movi_i32
:
1710 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1713 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1714 tcg_out_modrm_offset(s
, OPC_MOVZBL
, args
[0], args
[1], args
[2]);
1717 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ rexw
, args
[0], args
[1], args
[2]);
1720 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1721 tcg_out_modrm_offset(s
, OPC_MOVZWL
, args
[0], args
[1], args
[2]);
1724 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ rexw
, args
[0], args
[1], args
[2]);
1726 #if TCG_TARGET_REG_BITS == 64
1727 case INDEX_op_ld32u_i64
:
1729 case INDEX_op_ld_i32
:
1730 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1734 if (const_args
[0]) {
1735 tcg_out_modrm_offset(s
, OPC_MOVB_EvIz
,
1736 0, args
[1], args
[2]);
1737 tcg_out8(s
, args
[0]);
1739 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
| P_REXB_R
,
1740 args
[0], args
[1], args
[2]);
1744 if (const_args
[0]) {
1745 tcg_out_modrm_offset(s
, OPC_MOVL_EvIz
| P_DATA16
,
1746 0, args
[1], args
[2]);
1747 tcg_out16(s
, args
[0]);
1749 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
| P_DATA16
,
1750 args
[0], args
[1], args
[2]);
1753 #if TCG_TARGET_REG_BITS == 64
1754 case INDEX_op_st32_i64
:
1756 case INDEX_op_st_i32
:
1757 if (const_args
[0]) {
1758 tcg_out_modrm_offset(s
, OPC_MOVL_EvIz
, 0, args
[1], args
[2]);
1759 tcg_out32(s
, args
[0]);
1761 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1766 /* For 3-operand addition, use LEA. */
1767 if (args
[0] != args
[1]) {
1768 TCGArg a0
= args
[0], a1
= args
[1], a2
= args
[2], c3
= 0;
1770 if (const_args
[2]) {
1772 } else if (a0
== a2
) {
1773 /* Watch out for dest = src + dest, since we've removed
1774 the matching constraint on the add. */
1775 tgen_arithr(s
, ARITH_ADD
+ rexw
, a0
, a1
);
1779 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ rexw
, a0
, a1
, a2
, 0, c3
);
1797 if (const_args
[2]) {
1798 tgen_arithi(s
, c
+ rexw
, args
[0], args
[2], 0);
1800 tgen_arithr(s
, c
+ rexw
, args
[0], args
[2]);
1805 if (const_args
[2]) {
1808 if (val
== (int8_t)val
) {
1809 tcg_out_modrm(s
, OPC_IMUL_GvEvIb
+ rexw
, args
[0], args
[0]);
1812 tcg_out_modrm(s
, OPC_IMUL_GvEvIz
+ rexw
, args
[0], args
[0]);
1816 tcg_out_modrm(s
, OPC_IMUL_GvEv
+ rexw
, args
[0], args
[2]);
1821 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_IDIV
, args
[4]);
1824 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_DIV
, args
[4]);
1843 if (const_args
[2]) {
1844 tcg_out_shifti(s
, c
+ rexw
, args
[0], args
[2]);
1846 tcg_out_modrm(s
, OPC_SHIFT_cl
+ rexw
, c
, args
[0]);
1850 case INDEX_op_brcond_i32
:
1851 tcg_out_brcond32(s
, args
[2], args
[0], args
[1], const_args
[1],
1854 case INDEX_op_setcond_i32
:
1855 tcg_out_setcond32(s
, args
[3], args
[0], args
[1],
1856 args
[2], const_args
[2]);
1858 case INDEX_op_movcond_i32
:
1859 tcg_out_movcond32(s
, args
[5], args
[0], args
[1],
1860 args
[2], const_args
[2], args
[3]);
1864 tcg_out_rolw_8(s
, args
[0]);
1867 tcg_out_bswap32(s
, args
[0]);
1871 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NEG
, args
[0]);
1874 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NOT
, args
[0]);
1878 tcg_out_ext8s(s
, args
[0], args
[1], rexw
);
1881 tcg_out_ext16s(s
, args
[0], args
[1], rexw
);
1884 tcg_out_ext8u(s
, args
[0], args
[1]);
1887 tcg_out_ext16u(s
, args
[0], args
[1]);
1890 case INDEX_op_qemu_ld8u
:
1891 tcg_out_qemu_ld(s
, args
, 0);
1893 case INDEX_op_qemu_ld8s
:
1894 tcg_out_qemu_ld(s
, args
, 0 | 4);
1896 case INDEX_op_qemu_ld16u
:
1897 tcg_out_qemu_ld(s
, args
, 1);
1899 case INDEX_op_qemu_ld16s
:
1900 tcg_out_qemu_ld(s
, args
, 1 | 4);
1902 #if TCG_TARGET_REG_BITS == 64
1903 case INDEX_op_qemu_ld32u
:
1905 case INDEX_op_qemu_ld32
:
1906 tcg_out_qemu_ld(s
, args
, 2);
1908 case INDEX_op_qemu_ld64
:
1909 tcg_out_qemu_ld(s
, args
, 3);
1912 case INDEX_op_qemu_st8
:
1913 tcg_out_qemu_st(s
, args
, 0);
1915 case INDEX_op_qemu_st16
:
1916 tcg_out_qemu_st(s
, args
, 1);
1918 case INDEX_op_qemu_st32
:
1919 tcg_out_qemu_st(s
, args
, 2);
1921 case INDEX_op_qemu_st64
:
1922 tcg_out_qemu_st(s
, args
, 3);
1926 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_MUL
, args
[3]);
1929 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_IMUL
, args
[3]);
1932 if (const_args
[4]) {
1933 tgen_arithi(s
, ARITH_ADD
+ rexw
, args
[0], args
[4], 1);
1935 tgen_arithr(s
, ARITH_ADD
+ rexw
, args
[0], args
[4]);
1937 if (const_args
[5]) {
1938 tgen_arithi(s
, ARITH_ADC
+ rexw
, args
[1], args
[5], 1);
1940 tgen_arithr(s
, ARITH_ADC
+ rexw
, args
[1], args
[5]);
1944 if (const_args
[4]) {
1945 tgen_arithi(s
, ARITH_SUB
+ rexw
, args
[0], args
[4], 1);
1947 tgen_arithr(s
, ARITH_SUB
+ rexw
, args
[0], args
[4]);
1949 if (const_args
[5]) {
1950 tgen_arithi(s
, ARITH_SBB
+ rexw
, args
[1], args
[5], 1);
1952 tgen_arithr(s
, ARITH_SBB
+ rexw
, args
[1], args
[5]);
1956 #if TCG_TARGET_REG_BITS == 32
1957 case INDEX_op_brcond2_i32
:
1958 tcg_out_brcond2(s
, args
, const_args
, 0);
1960 case INDEX_op_setcond2_i32
:
1961 tcg_out_setcond2(s
, args
, const_args
);
1963 #else /* TCG_TARGET_REG_BITS == 64 */
1964 case INDEX_op_movi_i64
:
1965 tcg_out_movi(s
, TCG_TYPE_I64
, args
[0], args
[1]);
1967 case INDEX_op_ld32s_i64
:
1968 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, args
[0], args
[1], args
[2]);
1970 case INDEX_op_ld_i64
:
1971 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1973 case INDEX_op_st_i64
:
1974 if (const_args
[0]) {
1975 tcg_out_modrm_offset(s
, OPC_MOVL_EvIz
| P_REXW
,
1976 0, args
[1], args
[2]);
1977 tcg_out32(s
, args
[0]);
1979 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1982 case INDEX_op_qemu_ld32s
:
1983 tcg_out_qemu_ld(s
, args
, 2 | 4);
1986 case INDEX_op_brcond_i64
:
1987 tcg_out_brcond64(s
, args
[2], args
[0], args
[1], const_args
[1],
1990 case INDEX_op_setcond_i64
:
1991 tcg_out_setcond64(s
, args
[3], args
[0], args
[1],
1992 args
[2], const_args
[2]);
1994 case INDEX_op_movcond_i64
:
1995 tcg_out_movcond64(s
, args
[5], args
[0], args
[1],
1996 args
[2], const_args
[2], args
[3]);
1999 case INDEX_op_bswap64_i64
:
2000 tcg_out_bswap64(s
, args
[0]);
2002 case INDEX_op_ext32u_i64
:
2003 tcg_out_ext32u(s
, args
[0], args
[1]);
2005 case INDEX_op_ext32s_i64
:
2006 tcg_out_ext32s(s
, args
[0], args
[1]);
2011 if (args
[3] == 0 && args
[4] == 8) {
2012 /* load bits 0..7 */
2013 tcg_out_modrm(s
, OPC_MOVB_EvGv
| P_REXB_R
| P_REXB_RM
,
2015 } else if (args
[3] == 8 && args
[4] == 8) {
2016 /* load bits 8..15 */
2017 tcg_out_modrm(s
, OPC_MOVB_EvGv
, args
[2], args
[0] + 4);
2018 } else if (args
[3] == 0 && args
[4] == 16) {
2019 /* load bits 0..15 */
2020 tcg_out_modrm(s
, OPC_MOVL_EvGv
| P_DATA16
, args
[2], args
[0]);
2033 static const TCGTargetOpDef x86_op_defs
[] = {
2034 { INDEX_op_exit_tb
, { } },
2035 { INDEX_op_goto_tb
, { } },
2036 { INDEX_op_call
, { "ri" } },
2037 { INDEX_op_br
, { } },
2038 { INDEX_op_mov_i32
, { "r", "r" } },
2039 { INDEX_op_movi_i32
, { "r" } },
2040 { INDEX_op_ld8u_i32
, { "r", "r" } },
2041 { INDEX_op_ld8s_i32
, { "r", "r" } },
2042 { INDEX_op_ld16u_i32
, { "r", "r" } },
2043 { INDEX_op_ld16s_i32
, { "r", "r" } },
2044 { INDEX_op_ld_i32
, { "r", "r" } },
2045 { INDEX_op_st8_i32
, { "qi", "r" } },
2046 { INDEX_op_st16_i32
, { "ri", "r" } },
2047 { INDEX_op_st_i32
, { "ri", "r" } },
2049 { INDEX_op_add_i32
, { "r", "r", "ri" } },
2050 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
2051 { INDEX_op_mul_i32
, { "r", "0", "ri" } },
2052 { INDEX_op_div2_i32
, { "a", "d", "0", "1", "r" } },
2053 { INDEX_op_divu2_i32
, { "a", "d", "0", "1", "r" } },
2054 { INDEX_op_and_i32
, { "r", "0", "ri" } },
2055 { INDEX_op_or_i32
, { "r", "0", "ri" } },
2056 { INDEX_op_xor_i32
, { "r", "0", "ri" } },
2058 { INDEX_op_shl_i32
, { "r", "0", "ci" } },
2059 { INDEX_op_shr_i32
, { "r", "0", "ci" } },
2060 { INDEX_op_sar_i32
, { "r", "0", "ci" } },
2061 { INDEX_op_rotl_i32
, { "r", "0", "ci" } },
2062 { INDEX_op_rotr_i32
, { "r", "0", "ci" } },
2064 { INDEX_op_brcond_i32
, { "r", "ri" } },
2066 { INDEX_op_bswap16_i32
, { "r", "0" } },
2067 { INDEX_op_bswap32_i32
, { "r", "0" } },
2069 { INDEX_op_neg_i32
, { "r", "0" } },
2071 { INDEX_op_not_i32
, { "r", "0" } },
2073 { INDEX_op_ext8s_i32
, { "r", "q" } },
2074 { INDEX_op_ext16s_i32
, { "r", "r" } },
2075 { INDEX_op_ext8u_i32
, { "r", "q" } },
2076 { INDEX_op_ext16u_i32
, { "r", "r" } },
2078 { INDEX_op_setcond_i32
, { "q", "r", "ri" } },
2080 { INDEX_op_deposit_i32
, { "Q", "0", "Q" } },
2081 #if TCG_TARGET_HAS_movcond_i32
2082 { INDEX_op_movcond_i32
, { "r", "r", "ri", "r", "0" } },
2085 { INDEX_op_mulu2_i32
, { "a", "d", "a", "r" } },
2086 { INDEX_op_muls2_i32
, { "a", "d", "a", "r" } },
2087 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
2088 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
2090 #if TCG_TARGET_REG_BITS == 32
2091 { INDEX_op_brcond2_i32
, { "r", "r", "ri", "ri" } },
2092 { INDEX_op_setcond2_i32
, { "r", "r", "r", "ri", "ri" } },
2094 { INDEX_op_mov_i64
, { "r", "r" } },
2095 { INDEX_op_movi_i64
, { "r" } },
2096 { INDEX_op_ld8u_i64
, { "r", "r" } },
2097 { INDEX_op_ld8s_i64
, { "r", "r" } },
2098 { INDEX_op_ld16u_i64
, { "r", "r" } },
2099 { INDEX_op_ld16s_i64
, { "r", "r" } },
2100 { INDEX_op_ld32u_i64
, { "r", "r" } },
2101 { INDEX_op_ld32s_i64
, { "r", "r" } },
2102 { INDEX_op_ld_i64
, { "r", "r" } },
2103 { INDEX_op_st8_i64
, { "ri", "r" } },
2104 { INDEX_op_st16_i64
, { "ri", "r" } },
2105 { INDEX_op_st32_i64
, { "ri", "r" } },
2106 { INDEX_op_st_i64
, { "re", "r" } },
2108 { INDEX_op_add_i64
, { "r", "r", "re" } },
2109 { INDEX_op_mul_i64
, { "r", "0", "re" } },
2110 { INDEX_op_div2_i64
, { "a", "d", "0", "1", "r" } },
2111 { INDEX_op_divu2_i64
, { "a", "d", "0", "1", "r" } },
2112 { INDEX_op_sub_i64
, { "r", "0", "re" } },
2113 { INDEX_op_and_i64
, { "r", "0", "reZ" } },
2114 { INDEX_op_or_i64
, { "r", "0", "re" } },
2115 { INDEX_op_xor_i64
, { "r", "0", "re" } },
2117 { INDEX_op_shl_i64
, { "r", "0", "ci" } },
2118 { INDEX_op_shr_i64
, { "r", "0", "ci" } },
2119 { INDEX_op_sar_i64
, { "r", "0", "ci" } },
2120 { INDEX_op_rotl_i64
, { "r", "0", "ci" } },
2121 { INDEX_op_rotr_i64
, { "r", "0", "ci" } },
2123 { INDEX_op_brcond_i64
, { "r", "re" } },
2124 { INDEX_op_setcond_i64
, { "r", "r", "re" } },
2126 { INDEX_op_bswap16_i64
, { "r", "0" } },
2127 { INDEX_op_bswap32_i64
, { "r", "0" } },
2128 { INDEX_op_bswap64_i64
, { "r", "0" } },
2129 { INDEX_op_neg_i64
, { "r", "0" } },
2130 { INDEX_op_not_i64
, { "r", "0" } },
2132 { INDEX_op_ext8s_i64
, { "r", "r" } },
2133 { INDEX_op_ext16s_i64
, { "r", "r" } },
2134 { INDEX_op_ext32s_i64
, { "r", "r" } },
2135 { INDEX_op_ext8u_i64
, { "r", "r" } },
2136 { INDEX_op_ext16u_i64
, { "r", "r" } },
2137 { INDEX_op_ext32u_i64
, { "r", "r" } },
2139 { INDEX_op_deposit_i64
, { "Q", "0", "Q" } },
2140 { INDEX_op_movcond_i64
, { "r", "r", "re", "r", "0" } },
2142 { INDEX_op_mulu2_i64
, { "a", "d", "a", "r" } },
2143 { INDEX_op_muls2_i64
, { "a", "d", "a", "r" } },
2144 { INDEX_op_add2_i64
, { "r", "r", "0", "1", "re", "re" } },
2145 { INDEX_op_sub2_i64
, { "r", "r", "0", "1", "re", "re" } },
2148 #if TCG_TARGET_REG_BITS == 64
2149 { INDEX_op_qemu_ld8u
, { "r", "L" } },
2150 { INDEX_op_qemu_ld8s
, { "r", "L" } },
2151 { INDEX_op_qemu_ld16u
, { "r", "L" } },
2152 { INDEX_op_qemu_ld16s
, { "r", "L" } },
2153 { INDEX_op_qemu_ld32
, { "r", "L" } },
2154 { INDEX_op_qemu_ld32u
, { "r", "L" } },
2155 { INDEX_op_qemu_ld32s
, { "r", "L" } },
2156 { INDEX_op_qemu_ld64
, { "r", "L" } },
2158 { INDEX_op_qemu_st8
, { "L", "L" } },
2159 { INDEX_op_qemu_st16
, { "L", "L" } },
2160 { INDEX_op_qemu_st32
, { "L", "L" } },
2161 { INDEX_op_qemu_st64
, { "L", "L" } },
2162 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
2163 { INDEX_op_qemu_ld8u
, { "r", "L" } },
2164 { INDEX_op_qemu_ld8s
, { "r", "L" } },
2165 { INDEX_op_qemu_ld16u
, { "r", "L" } },
2166 { INDEX_op_qemu_ld16s
, { "r", "L" } },
2167 { INDEX_op_qemu_ld32
, { "r", "L" } },
2168 { INDEX_op_qemu_ld64
, { "r", "r", "L" } },
2170 { INDEX_op_qemu_st8
, { "cb", "L" } },
2171 { INDEX_op_qemu_st16
, { "L", "L" } },
2172 { INDEX_op_qemu_st32
, { "L", "L" } },
2173 { INDEX_op_qemu_st64
, { "L", "L", "L" } },
2175 { INDEX_op_qemu_ld8u
, { "r", "L", "L" } },
2176 { INDEX_op_qemu_ld8s
, { "r", "L", "L" } },
2177 { INDEX_op_qemu_ld16u
, { "r", "L", "L" } },
2178 { INDEX_op_qemu_ld16s
, { "r", "L", "L" } },
2179 { INDEX_op_qemu_ld32
, { "r", "L", "L" } },
2180 { INDEX_op_qemu_ld64
, { "r", "r", "L", "L" } },
2182 { INDEX_op_qemu_st8
, { "cb", "L", "L" } },
2183 { INDEX_op_qemu_st16
, { "L", "L", "L" } },
2184 { INDEX_op_qemu_st32
, { "L", "L", "L" } },
2185 { INDEX_op_qemu_st64
, { "L", "L", "L", "L" } },
2190 static int tcg_target_callee_save_regs
[] = {
2191 #if TCG_TARGET_REG_BITS == 64
2200 TCG_REG_R14
, /* Currently used for the global env. */
2203 TCG_REG_EBP
, /* Currently used for the global env. */
2210 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
2211 and tcg_register_jit. */
2214 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
2215 * (TCG_TARGET_REG_BITS / 8))
2217 #define FRAME_SIZE \
2219 + TCG_STATIC_CALL_ARGS_SIZE \
2220 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2221 + TCG_TARGET_STACK_ALIGN - 1) \
2222 & ~(TCG_TARGET_STACK_ALIGN - 1))
2224 /* Generate global QEMU prologue and epilogue code */
2225 static void tcg_target_qemu_prologue(TCGContext
*s
)
2227 int i
, stack_addend
;
2231 /* Reserve some stack space, also for TCG temps. */
2232 stack_addend
= FRAME_SIZE
- PUSH_SIZE
;
2233 tcg_set_frame(s
, TCG_REG_CALL_STACK
, TCG_STATIC_CALL_ARGS_SIZE
,
2234 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2236 /* Save all callee saved registers. */
2237 for (i
= 0; i
< ARRAY_SIZE(tcg_target_callee_save_regs
); i
++) {
2238 tcg_out_push(s
, tcg_target_callee_save_regs
[i
]);
2241 #if TCG_TARGET_REG_BITS == 32
2242 tcg_out_ld(s
, TCG_TYPE_PTR
, TCG_AREG0
, TCG_REG_ESP
,
2243 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 1) * 4);
2244 tcg_out_addi(s
, TCG_REG_ESP
, -stack_addend
);
2246 tcg_out_modrm_offset(s
, OPC_GRP5
, EXT5_JMPN_Ev
, TCG_REG_ESP
,
2247 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 2) * 4
2250 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2251 tcg_out_addi(s
, TCG_REG_ESP
, -stack_addend
);
2253 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, tcg_target_call_iarg_regs
[1]);
2257 tb_ret_addr
= s
->code_ptr
;
2259 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_addend
);
2261 for (i
= ARRAY_SIZE(tcg_target_callee_save_regs
) - 1; i
>= 0; i
--) {
2262 tcg_out_pop(s
, tcg_target_callee_save_regs
[i
]);
2264 tcg_out_opc(s
, OPC_RET
, 0, 0, 0);
2266 #if !defined(CONFIG_SOFTMMU)
2267 /* Try to set up a segment register to point to GUEST_BASE. */
2269 setup_guest_base_seg();
2274 static void tcg_target_init(TCGContext
*s
)
2276 /* For 32-bit, 99% certainty that we're running on hardware that supports
2277 cmov, but we still need to check. In case cmov is not available, we'll
2278 use a small forward branch. */
2281 unsigned a
, b
, c
, d
;
2282 have_cmov
= (__get_cpuid(1, &a
, &b
, &c
, &d
) && (d
& bit_CMOV
));
2286 #if !defined(CONFIG_USER_ONLY)
2288 if ((1 << CPU_TLB_ENTRY_BITS
) != sizeof(CPUTLBEntry
))
2292 if (TCG_TARGET_REG_BITS
== 64) {
2293 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2294 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2296 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xff);
2299 tcg_regset_clear(tcg_target_call_clobber_regs
);
2300 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EAX
);
2301 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EDX
);
2302 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_ECX
);
2303 if (TCG_TARGET_REG_BITS
== 64) {
2304 #if !defined(_WIN64)
2305 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RDI
);
2306 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RSI
);
2308 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R8
);
2309 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R9
);
2310 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R10
);
2311 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R11
);
2314 tcg_regset_clear(s
->reserved_regs
);
2315 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2317 tcg_add_target_add_op_defs(x86_op_defs
);
2321 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2324 char augmentation
[1];
2327 uint8_t return_column
;
2331 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2332 uint32_t cie_offset
;
2333 tcg_target_long func_start
__attribute__((packed
));
2334 tcg_target_long func_len
__attribute__((packed
));
2336 uint8_t reg_ofs
[14];
2344 #if !defined(__ELF__)
2345 /* Host machine without ELF. */
2346 #elif TCG_TARGET_REG_BITS == 64
2347 #define ELF_HOST_MACHINE EM_X86_64
2348 static DebugFrame debug_frame
= {
2349 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2352 .cie
.code_align
= 1,
2353 .cie
.data_align
= 0x78, /* sleb128 -8 */
2354 .cie
.return_column
= 16,
2356 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2358 12, 7, /* DW_CFA_def_cfa %rsp, ... */
2359 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2363 0x90, 1, /* DW_CFA_offset, %rip, -8 */
2364 /* The following ordering must match tcg_target_callee_save_regs. */
2365 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
2366 0x83, 3, /* DW_CFA_offset, %rbx, -24 */
2367 0x8c, 4, /* DW_CFA_offset, %r12, -32 */
2368 0x8d, 5, /* DW_CFA_offset, %r13, -40 */
2369 0x8e, 6, /* DW_CFA_offset, %r14, -48 */
2370 0x8f, 7, /* DW_CFA_offset, %r15, -56 */
2374 #define ELF_HOST_MACHINE EM_386
2375 static DebugFrame debug_frame
= {
2376 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2379 .cie
.code_align
= 1,
2380 .cie
.data_align
= 0x7c, /* sleb128 -4 */
2381 .cie
.return_column
= 8,
2383 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2385 12, 4, /* DW_CFA_def_cfa %esp, ... */
2386 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2390 0x88, 1, /* DW_CFA_offset, %eip, -4 */
2391 /* The following ordering must match tcg_target_callee_save_regs. */
2392 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
2393 0x83, 3, /* DW_CFA_offset, %ebx, -12 */
2394 0x86, 4, /* DW_CFA_offset, %esi, -16 */
2395 0x87, 5, /* DW_CFA_offset, %edi, -20 */
2400 #if defined(ELF_HOST_MACHINE)
2401 void tcg_register_jit(void *buf
, size_t buf_size
)
2403 /* We're expecting a 2 byte uleb128 encoded value. */
2404 assert(FRAME_SIZE
>> 14 == 0);
2406 debug_frame
.fde
.func_start
= (tcg_target_long
) buf
;
2407 debug_frame
.fde
.func_len
= buf_size
;
2409 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));