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) {
122 /* parse target specific constraints */
123 static int target_parse_constraint(TCGArgConstraint
*ct
, const char **pct_str
)
130 ct
->ct
|= TCG_CT_REG
;
131 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EAX
);
134 ct
->ct
|= TCG_CT_REG
;
135 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EBX
);
138 ct
->ct
|= TCG_CT_REG
;
139 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ECX
);
142 ct
->ct
|= TCG_CT_REG
;
143 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDX
);
146 ct
->ct
|= TCG_CT_REG
;
147 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ESI
);
150 ct
->ct
|= TCG_CT_REG
;
151 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDI
);
154 ct
->ct
|= TCG_CT_REG
;
155 if (TCG_TARGET_REG_BITS
== 64) {
156 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
158 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
162 ct
->ct
|= TCG_CT_REG
;
163 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
166 ct
->ct
|= TCG_CT_REG
;
167 if (TCG_TARGET_REG_BITS
== 64) {
168 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
170 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
174 /* qemu_ld/st address constraint */
176 ct
->ct
|= TCG_CT_REG
;
177 if (TCG_TARGET_REG_BITS
== 64) {
178 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
179 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_RSI
);
180 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_RDI
);
181 #ifdef CONFIG_TCG_PASS_AREG0
182 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_RDX
);
185 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
186 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EAX
);
187 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EDX
);
192 ct
->ct
|= TCG_CT_CONST_S32
;
195 ct
->ct
|= TCG_CT_CONST_U32
;
206 /* test if a constant matches the constraint */
207 static inline int tcg_target_const_match(tcg_target_long val
,
208 const TCGArgConstraint
*arg_ct
)
211 if (ct
& TCG_CT_CONST
) {
214 if ((ct
& TCG_CT_CONST_S32
) && val
== (int32_t)val
) {
217 if ((ct
& TCG_CT_CONST_U32
) && val
== (uint32_t)val
) {
223 #if TCG_TARGET_REG_BITS == 64
224 # define LOWREGMASK(x) ((x) & 7)
226 # define LOWREGMASK(x) (x)
229 #define P_EXT 0x100 /* 0x0f opcode prefix */
230 #define P_DATA16 0x200 /* 0x66 opcode prefix */
231 #if TCG_TARGET_REG_BITS == 64
232 # define P_ADDR32 0x400 /* 0x67 opcode prefix */
233 # define P_REXW 0x800 /* Set REX.W = 1 */
234 # define P_REXB_R 0x1000 /* REG field as byte register */
235 # define P_REXB_RM 0x2000 /* R/M field as byte register */
243 #define OPC_ARITH_EvIz (0x81)
244 #define OPC_ARITH_EvIb (0x83)
245 #define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
246 #define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
247 #define OPC_BSWAP (0xc8 | P_EXT)
248 #define OPC_CALL_Jz (0xe8)
249 #define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
250 #define OPC_DEC_r32 (0x48)
251 #define OPC_IMUL_GvEv (0xaf | P_EXT)
252 #define OPC_IMUL_GvEvIb (0x6b)
253 #define OPC_IMUL_GvEvIz (0x69)
254 #define OPC_INC_r32 (0x40)
255 #define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
256 #define OPC_JCC_short (0x70) /* ... plus condition code */
257 #define OPC_JMP_long (0xe9)
258 #define OPC_JMP_short (0xeb)
259 #define OPC_LEA (0x8d)
260 #define OPC_MOVB_EvGv (0x88) /* stores, more or less */
261 #define OPC_MOVL_EvGv (0x89) /* stores, more or less */
262 #define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
263 #define OPC_MOVL_EvIz (0xc7)
264 #define OPC_MOVL_Iv (0xb8)
265 #define OPC_MOVSBL (0xbe | P_EXT)
266 #define OPC_MOVSWL (0xbf | P_EXT)
267 #define OPC_MOVSLQ (0x63 | P_REXW)
268 #define OPC_MOVZBL (0xb6 | P_EXT)
269 #define OPC_MOVZWL (0xb7 | P_EXT)
270 #define OPC_POP_r32 (0x58)
271 #define OPC_PUSH_r32 (0x50)
272 #define OPC_PUSH_Iv (0x68)
273 #define OPC_PUSH_Ib (0x6a)
274 #define OPC_RET (0xc3)
275 #define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
276 #define OPC_SHIFT_1 (0xd1)
277 #define OPC_SHIFT_Ib (0xc1)
278 #define OPC_SHIFT_cl (0xd3)
279 #define OPC_TESTL (0x85)
280 #define OPC_XCHG_ax_r32 (0x90)
282 #define OPC_GRP3_Ev (0xf7)
283 #define OPC_GRP5 (0xff)
285 /* Group 1 opcode extensions for 0x80-0x83.
286 These are also used as modifiers for OPC_ARITH. */
296 /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
303 /* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
311 /* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
312 #define EXT5_INC_Ev 0
313 #define EXT5_DEC_Ev 1
314 #define EXT5_CALLN_Ev 2
315 #define EXT5_JMPN_Ev 4
317 /* Condition codes to be added to OPC_JCC_{long,short}. */
336 static const uint8_t tcg_cond_to_jcc
[10] = {
337 [TCG_COND_EQ
] = JCC_JE
,
338 [TCG_COND_NE
] = JCC_JNE
,
339 [TCG_COND_LT
] = JCC_JL
,
340 [TCG_COND_GE
] = JCC_JGE
,
341 [TCG_COND_LE
] = JCC_JLE
,
342 [TCG_COND_GT
] = JCC_JG
,
343 [TCG_COND_LTU
] = JCC_JB
,
344 [TCG_COND_GEU
] = JCC_JAE
,
345 [TCG_COND_LEU
] = JCC_JBE
,
346 [TCG_COND_GTU
] = JCC_JA
,
349 #if TCG_TARGET_REG_BITS == 64
350 static void tcg_out_opc(TCGContext
*s
, int opc
, int r
, int rm
, int x
)
354 if (opc
& P_DATA16
) {
355 /* We should never be asking for both 16 and 64-bit operation. */
356 assert((opc
& P_REXW
) == 0);
359 if (opc
& P_ADDR32
) {
364 rex
|= (opc
& P_REXW
) >> 8; /* REX.W */
365 rex
|= (r
& 8) >> 1; /* REX.R */
366 rex
|= (x
& 8) >> 2; /* REX.X */
367 rex
|= (rm
& 8) >> 3; /* REX.B */
369 /* P_REXB_{R,RM} indicates that the given register is the low byte.
370 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
371 as otherwise the encoding indicates %[abcd]h. Note that the values
372 that are ORed in merely indicate that the REX byte must be present;
373 those bits get discarded in output. */
374 rex
|= opc
& (r
>= 4 ? P_REXB_R
: 0);
375 rex
|= opc
& (rm
>= 4 ? P_REXB_RM
: 0);
378 tcg_out8(s
, (uint8_t)(rex
| 0x40));
387 static void tcg_out_opc(TCGContext
*s
, int opc
)
389 if (opc
& P_DATA16
) {
397 /* Discard the register arguments to tcg_out_opc early, so as not to penalize
398 the 32-bit compilation paths. This method works with all versions of gcc,
399 whereas relying on optimization may not be able to exclude them. */
400 #define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
403 static void tcg_out_modrm(TCGContext
*s
, int opc
, int r
, int rm
)
405 tcg_out_opc(s
, opc
, r
, rm
, 0);
406 tcg_out8(s
, 0xc0 | (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
409 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
410 We handle either RM and INDEX missing with a negative value. In 64-bit
411 mode for absolute addresses, ~RM is the size of the immediate operand
412 that will follow the instruction. */
414 static void tcg_out_modrm_sib_offset(TCGContext
*s
, int opc
, int r
, int rm
,
415 int index
, int shift
,
416 tcg_target_long offset
)
420 if (index
< 0 && rm
< 0) {
421 if (TCG_TARGET_REG_BITS
== 64) {
422 /* Try for a rip-relative addressing mode. This has replaced
423 the 32-bit-mode absolute addressing encoding. */
424 tcg_target_long pc
= (tcg_target_long
)s
->code_ptr
+ 5 + ~rm
;
425 tcg_target_long disp
= offset
- pc
;
426 if (disp
== (int32_t)disp
) {
427 tcg_out_opc(s
, opc
, r
, 0, 0);
428 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 5);
433 /* Try for an absolute address encoding. This requires the
434 use of the MODRM+SIB encoding and is therefore larger than
435 rip-relative addressing. */
436 if (offset
== (int32_t)offset
) {
437 tcg_out_opc(s
, opc
, r
, 0, 0);
438 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 4);
439 tcg_out8(s
, (4 << 3) | 5);
440 tcg_out32(s
, offset
);
444 /* ??? The memory isn't directly addressable. */
447 /* Absolute address. */
448 tcg_out_opc(s
, opc
, r
, 0, 0);
449 tcg_out8(s
, (r
<< 3) | 5);
450 tcg_out32(s
, offset
);
455 /* Find the length of the immediate addend. Note that the encoding
456 that would be used for (%ebp) indicates absolute addressing. */
458 mod
= 0, len
= 4, rm
= 5;
459 } else if (offset
== 0 && LOWREGMASK(rm
) != TCG_REG_EBP
) {
461 } else if (offset
== (int8_t)offset
) {
467 /* Use a single byte MODRM format if possible. Note that the encoding
468 that would be used for %esp is the escape to the two byte form. */
469 if (index
< 0 && LOWREGMASK(rm
) != TCG_REG_ESP
) {
470 /* Single byte MODRM format. */
471 tcg_out_opc(s
, opc
, r
, rm
, 0);
472 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
474 /* Two byte MODRM+SIB format. */
476 /* Note that the encoding that would place %esp into the index
477 field indicates no index register. In 64-bit mode, the REX.X
478 bit counts, so %r12 can be used as the index. */
482 assert(index
!= TCG_REG_ESP
);
485 tcg_out_opc(s
, opc
, r
, rm
, index
);
486 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | 4);
487 tcg_out8(s
, (shift
<< 6) | (LOWREGMASK(index
) << 3) | LOWREGMASK(rm
));
492 } else if (len
== 4) {
493 tcg_out32(s
, offset
);
497 /* A simplification of the above with no index or shift. */
498 static inline void tcg_out_modrm_offset(TCGContext
*s
, int opc
, int r
,
499 int rm
, tcg_target_long offset
)
501 tcg_out_modrm_sib_offset(s
, opc
, r
, rm
, -1, 0, offset
);
504 /* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
505 static inline void tgen_arithr(TCGContext
*s
, int subop
, int dest
, int src
)
507 /* Propagate an opcode prefix, such as P_REXW. */
508 int ext
= subop
& ~0x7;
511 tcg_out_modrm(s
, OPC_ARITH_GvEv
+ (subop
<< 3) + ext
, dest
, src
);
514 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
515 TCGReg ret
, TCGReg arg
)
518 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
519 tcg_out_modrm(s
, opc
, ret
, arg
);
523 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
524 TCGReg ret
, tcg_target_long arg
)
527 tgen_arithr(s
, ARITH_XOR
, ret
, ret
);
529 } else if (arg
== (uint32_t)arg
|| type
== TCG_TYPE_I32
) {
530 tcg_out_opc(s
, OPC_MOVL_Iv
+ LOWREGMASK(ret
), 0, ret
, 0);
532 } else if (arg
== (int32_t)arg
) {
533 tcg_out_modrm(s
, OPC_MOVL_EvIz
+ P_REXW
, 0, ret
);
536 tcg_out_opc(s
, OPC_MOVL_Iv
+ P_REXW
+ LOWREGMASK(ret
), 0, ret
, 0);
538 tcg_out32(s
, arg
>> 31 >> 1);
542 static inline void tcg_out_pushi(TCGContext
*s
, tcg_target_long val
)
544 if (val
== (int8_t)val
) {
545 tcg_out_opc(s
, OPC_PUSH_Ib
, 0, 0, 0);
547 } else if (val
== (int32_t)val
) {
548 tcg_out_opc(s
, OPC_PUSH_Iv
, 0, 0, 0);
555 static inline void tcg_out_push(TCGContext
*s
, int reg
)
557 tcg_out_opc(s
, OPC_PUSH_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
560 static inline void tcg_out_pop(TCGContext
*s
, int reg
)
562 tcg_out_opc(s
, OPC_POP_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
565 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg ret
,
566 TCGReg arg1
, tcg_target_long arg2
)
568 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
569 tcg_out_modrm_offset(s
, opc
, ret
, arg1
, arg2
);
572 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
573 TCGReg arg1
, tcg_target_long arg2
)
575 int opc
= OPC_MOVL_EvGv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
576 tcg_out_modrm_offset(s
, opc
, arg
, arg1
, arg2
);
579 static void tcg_out_shifti(TCGContext
*s
, int subopc
, int reg
, int count
)
581 /* Propagate an opcode prefix, such as P_DATA16. */
582 int ext
= subopc
& ~0x7;
586 tcg_out_modrm(s
, OPC_SHIFT_1
+ ext
, subopc
, reg
);
588 tcg_out_modrm(s
, OPC_SHIFT_Ib
+ ext
, subopc
, reg
);
593 static inline void tcg_out_bswap32(TCGContext
*s
, int reg
)
595 tcg_out_opc(s
, OPC_BSWAP
+ LOWREGMASK(reg
), 0, reg
, 0);
598 static inline void tcg_out_rolw_8(TCGContext
*s
, int reg
)
600 tcg_out_shifti(s
, SHIFT_ROL
+ P_DATA16
, reg
, 8);
603 static inline void tcg_out_ext8u(TCGContext
*s
, int dest
, int src
)
606 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
607 tcg_out_modrm(s
, OPC_MOVZBL
+ P_REXB_RM
, dest
, src
);
610 static void tcg_out_ext8s(TCGContext
*s
, int dest
, int src
, int rexw
)
613 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
614 tcg_out_modrm(s
, OPC_MOVSBL
+ P_REXB_RM
+ rexw
, dest
, src
);
617 static inline void tcg_out_ext16u(TCGContext
*s
, int dest
, int src
)
620 tcg_out_modrm(s
, OPC_MOVZWL
, dest
, src
);
623 static inline void tcg_out_ext16s(TCGContext
*s
, int dest
, int src
, int rexw
)
626 tcg_out_modrm(s
, OPC_MOVSWL
+ rexw
, dest
, src
);
629 static inline void tcg_out_ext32u(TCGContext
*s
, int dest
, int src
)
631 /* 32-bit mov zero extends. */
632 tcg_out_modrm(s
, OPC_MOVL_GvEv
, dest
, src
);
635 static inline void tcg_out_ext32s(TCGContext
*s
, int dest
, int src
)
637 tcg_out_modrm(s
, OPC_MOVSLQ
, dest
, src
);
640 static inline void tcg_out_bswap64(TCGContext
*s
, int reg
)
642 tcg_out_opc(s
, OPC_BSWAP
+ P_REXW
+ LOWREGMASK(reg
), 0, reg
, 0);
645 static void tgen_arithi(TCGContext
*s
, int c
, int r0
,
646 tcg_target_long val
, int cf
)
650 if (TCG_TARGET_REG_BITS
== 64) {
655 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
656 partial flags update stalls on Pentium4 and are not recommended
657 by current Intel optimization manuals. */
658 if (!cf
&& (c
== ARITH_ADD
|| c
== ARITH_SUB
) && (val
== 1 || val
== -1)) {
659 int is_inc
= (c
== ARITH_ADD
) ^ (val
< 0);
660 if (TCG_TARGET_REG_BITS
== 64) {
661 /* The single-byte increment encodings are re-tasked as the
662 REX prefixes. Use the MODRM encoding. */
663 tcg_out_modrm(s
, OPC_GRP5
+ rexw
,
664 (is_inc
? EXT5_INC_Ev
: EXT5_DEC_Ev
), r0
);
666 tcg_out8(s
, (is_inc
? OPC_INC_r32
: OPC_DEC_r32
) + r0
);
671 if (c
== ARITH_AND
) {
672 if (TCG_TARGET_REG_BITS
== 64) {
673 if (val
== 0xffffffffu
) {
674 tcg_out_ext32u(s
, r0
, r0
);
677 if (val
== (uint32_t)val
) {
678 /* AND with no high bits set can use a 32-bit operation. */
682 if (val
== 0xffu
&& (r0
< 4 || TCG_TARGET_REG_BITS
== 64)) {
683 tcg_out_ext8u(s
, r0
, r0
);
686 if (val
== 0xffffu
) {
687 tcg_out_ext16u(s
, r0
, r0
);
692 if (val
== (int8_t)val
) {
693 tcg_out_modrm(s
, OPC_ARITH_EvIb
+ rexw
, c
, r0
);
697 if (rexw
== 0 || val
== (int32_t)val
) {
698 tcg_out_modrm(s
, OPC_ARITH_EvIz
+ rexw
, c
, r0
);
706 static void tcg_out_addi(TCGContext
*s
, int reg
, tcg_target_long val
)
709 tgen_arithi(s
, ARITH_ADD
+ P_REXW
, reg
, val
, 0);
713 /* Use SMALL != 0 to force a short forward branch. */
714 static void tcg_out_jxx(TCGContext
*s
, int opc
, int label_index
, int small
)
717 TCGLabel
*l
= &s
->labels
[label_index
];
720 val
= l
->u
.value
- (tcg_target_long
)s
->code_ptr
;
722 if ((int8_t)val1
== val1
) {
724 tcg_out8(s
, OPC_JMP_short
);
726 tcg_out8(s
, OPC_JCC_short
+ opc
);
734 tcg_out8(s
, OPC_JMP_long
);
735 tcg_out32(s
, val
- 5);
737 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
738 tcg_out32(s
, val
- 6);
743 tcg_out8(s
, OPC_JMP_short
);
745 tcg_out8(s
, OPC_JCC_short
+ opc
);
747 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC8
, label_index
, -1);
751 tcg_out8(s
, OPC_JMP_long
);
753 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
755 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC32
, label_index
, -4);
760 static void tcg_out_cmp(TCGContext
*s
, TCGArg arg1
, TCGArg arg2
,
761 int const_arg2
, int rexw
)
766 tcg_out_modrm(s
, OPC_TESTL
+ rexw
, arg1
, arg1
);
768 tgen_arithi(s
, ARITH_CMP
+ rexw
, arg1
, arg2
, 0);
771 tgen_arithr(s
, ARITH_CMP
+ rexw
, arg1
, arg2
);
775 static void tcg_out_brcond32(TCGContext
*s
, TCGCond cond
,
776 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
777 int label_index
, int small
)
779 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
780 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
783 #if TCG_TARGET_REG_BITS == 64
784 static void tcg_out_brcond64(TCGContext
*s
, TCGCond cond
,
785 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
786 int label_index
, int small
)
788 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
789 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
792 /* XXX: we implement it at the target level to avoid having to
793 handle cross basic blocks temporaries */
794 static void tcg_out_brcond2(TCGContext
*s
, const TCGArg
*args
,
795 const int *const_args
, int small
)
798 label_next
= gen_new_label();
801 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
803 tcg_out_brcond32(s
, TCG_COND_EQ
, args
[1], args
[3], const_args
[3],
807 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
809 tcg_out_brcond32(s
, TCG_COND_NE
, args
[1], args
[3], const_args
[3],
813 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
815 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
816 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
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_LEU
, args
[0], args
[2], const_args
[2],
827 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
829 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
830 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
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_GEU
, args
[0], args
[2], const_args
[2],
841 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
843 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
844 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
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_LEU
, args
[0], args
[2], const_args
[2],
855 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
857 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
858 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
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_GEU
, args
[0], args
[2], const_args
[2],
871 tcg_out_label(s
, label_next
, s
->code_ptr
);
875 static void tcg_out_setcond32(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
876 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
878 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
879 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
880 tcg_out_ext8u(s
, dest
, dest
);
883 #if TCG_TARGET_REG_BITS == 64
884 static void tcg_out_setcond64(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
885 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
887 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
888 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
889 tcg_out_ext8u(s
, dest
, dest
);
892 static void tcg_out_setcond2(TCGContext
*s
, const TCGArg
*args
,
893 const int *const_args
)
896 int label_true
, label_over
;
898 memcpy(new_args
, args
+1, 5*sizeof(TCGArg
));
900 if (args
[0] == args
[1] || args
[0] == args
[2]
901 || (!const_args
[3] && args
[0] == args
[3])
902 || (!const_args
[4] && args
[0] == args
[4])) {
903 /* When the destination overlaps with one of the argument
904 registers, don't do anything tricky. */
905 label_true
= gen_new_label();
906 label_over
= gen_new_label();
908 new_args
[5] = label_true
;
909 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
911 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
912 tcg_out_jxx(s
, JCC_JMP
, label_over
, 1);
913 tcg_out_label(s
, label_true
, s
->code_ptr
);
915 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 1);
916 tcg_out_label(s
, label_over
, s
->code_ptr
);
918 /* When the destination does not overlap one of the arguments,
919 clear the destination first, jump if cond false, and emit an
920 increment in the true case. This results in smaller code. */
922 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
924 label_over
= gen_new_label();
925 new_args
[4] = tcg_invert_cond(new_args
[4]);
926 new_args
[5] = label_over
;
927 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
929 tgen_arithi(s
, ARITH_ADD
, args
[0], 1, 0);
930 tcg_out_label(s
, label_over
, s
->code_ptr
);
935 static void tcg_out_branch(TCGContext
*s
, int call
, tcg_target_long dest
)
937 tcg_target_long disp
= dest
- (tcg_target_long
)s
->code_ptr
- 5;
939 if (disp
== (int32_t)disp
) {
940 tcg_out_opc(s
, call
? OPC_CALL_Jz
: OPC_JMP_long
, 0, 0, 0);
943 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R10
, dest
);
944 tcg_out_modrm(s
, OPC_GRP5
,
945 call
? EXT5_CALLN_Ev
: EXT5_JMPN_Ev
, TCG_REG_R10
);
949 static inline void tcg_out_calli(TCGContext
*s
, tcg_target_long dest
)
951 tcg_out_branch(s
, 1, dest
);
954 static void tcg_out_jmp(TCGContext
*s
, tcg_target_long dest
)
956 tcg_out_branch(s
, 0, dest
);
959 #if defined(CONFIG_SOFTMMU)
961 #include "../../softmmu_defs.h"
963 #ifdef CONFIG_TCG_PASS_AREG0
964 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
966 static const void *qemu_ld_helpers
[4] = {
973 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
974 uintxx_t val, int mmu_idx) */
975 static const void *qemu_st_helpers
[4] = {
982 /* legacy helper signature: __ld_mmu(target_ulong addr, int
984 static void *qemu_ld_helpers
[4] = {
991 /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
993 static void *qemu_st_helpers
[4] = {
1001 /* Perform the TLB load and compare.
1004 ADDRLO_IDX contains the index into ARGS of the low part of the
1005 address; the high part of the address is at ADDR_LOW_IDX+1.
1007 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1009 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1010 This should be offsetof addr_read or addr_write.
1013 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
1014 positions of the displacements of forward jumps to the TLB miss case.
1016 First argument register is loaded with the low part of the address.
1017 In the TLB hit case, it has been adjusted as indicated by the TLB
1018 and so is a host address. In the TLB miss case, it continues to
1019 hold a guest address.
1021 Second argument register is clobbered. */
1023 static inline void tcg_out_tlb_load(TCGContext
*s
, int addrlo_idx
,
1024 int mem_index
, int s_bits
,
1026 uint8_t **label_ptr
, int which
)
1028 const int addrlo
= args
[addrlo_idx
];
1029 const int r0
= tcg_target_call_iarg_regs
[0];
1030 const int r1
= tcg_target_call_iarg_regs
[1];
1031 TCGType type
= TCG_TYPE_I32
;
1034 if (TCG_TARGET_REG_BITS
== 64 && TARGET_LONG_BITS
== 64) {
1035 type
= TCG_TYPE_I64
;
1039 tcg_out_mov(s
, type
, r1
, addrlo
);
1040 tcg_out_mov(s
, type
, r0
, addrlo
);
1042 tcg_out_shifti(s
, SHIFT_SHR
+ rexw
, r1
,
1043 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1045 tgen_arithi(s
, ARITH_AND
+ rexw
, r0
,
1046 TARGET_PAGE_MASK
| ((1 << s_bits
) - 1), 0);
1047 tgen_arithi(s
, ARITH_AND
+ rexw
, r1
,
1048 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
, 0);
1050 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ P_REXW
, r1
, TCG_AREG0
, r1
, 0,
1051 offsetof(CPUArchState
, tlb_table
[mem_index
][0])
1055 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
+ rexw
, r0
, r1
, 0);
1057 tcg_out_mov(s
, type
, r0
, addrlo
);
1060 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1061 label_ptr
[0] = s
->code_ptr
;
1064 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1065 /* cmp 4(r1), addrhi */
1066 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
, args
[addrlo_idx
+1], r1
, 4);
1069 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1070 label_ptr
[1] = s
->code_ptr
;
1076 /* add addend(r1), r0 */
1077 tcg_out_modrm_offset(s
, OPC_ADD_GvEv
+ P_REXW
, r0
, r1
,
1078 offsetof(CPUTLBEntry
, addend
) - which
);
1082 static void tcg_out_qemu_ld_direct(TCGContext
*s
, int datalo
, int datahi
,
1083 int base
, tcg_target_long ofs
, int sizeop
)
1085 #ifdef TARGET_WORDS_BIGENDIAN
1086 const int bswap
= 1;
1088 const int bswap
= 0;
1092 tcg_out_modrm_offset(s
, OPC_MOVZBL
, datalo
, base
, ofs
);
1095 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ P_REXW
, datalo
, base
, ofs
);
1098 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1100 tcg_out_rolw_8(s
, datalo
);
1105 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1106 tcg_out_rolw_8(s
, datalo
);
1107 tcg_out_modrm(s
, OPC_MOVSWL
+ P_REXW
, datalo
, datalo
);
1109 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ P_REXW
, datalo
, base
, ofs
);
1113 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1115 tcg_out_bswap32(s
, datalo
);
1118 #if TCG_TARGET_REG_BITS == 64
1121 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1122 tcg_out_bswap32(s
, datalo
);
1123 tcg_out_ext32s(s
, datalo
, datalo
);
1125 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, datalo
, base
, ofs
);
1130 if (TCG_TARGET_REG_BITS
== 64) {
1131 tcg_out_ld(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1133 tcg_out_bswap64(s
, datalo
);
1141 if (base
!= datalo
) {
1142 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1143 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1145 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1146 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1149 tcg_out_bswap32(s
, datalo
);
1150 tcg_out_bswap32(s
, datahi
);
1159 /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1160 EAX. It will be useful once fixed registers globals are less
1162 static void tcg_out_qemu_ld(TCGContext
*s
, const TCGArg
*args
,
1165 int data_reg
, data_reg2
= 0;
1167 #if defined(CONFIG_SOFTMMU)
1168 int mem_index
, s_bits
;
1169 #if TCG_TARGET_REG_BITS == 64
1174 uint8_t *label_ptr
[3];
1179 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1180 data_reg2
= args
[1];
1184 #if defined(CONFIG_SOFTMMU)
1185 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1188 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1189 label_ptr
, offsetof(CPUTLBEntry
, addr_read
));
1192 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
,
1193 tcg_target_call_iarg_regs
[0], 0, opc
);
1196 tcg_out8(s
, OPC_JMP_short
);
1197 label_ptr
[2] = s
->code_ptr
;
1203 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1204 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1205 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1208 /* XXX: move that code at the end of the TB */
1209 #if TCG_TARGET_REG_BITS == 32
1210 tcg_out_pushi(s
, mem_index
);
1212 if (TARGET_LONG_BITS
== 64) {
1213 tcg_out_push(s
, args
[addrlo_idx
+ 1]);
1216 tcg_out_push(s
, args
[addrlo_idx
]);
1218 #ifdef CONFIG_TCG_PASS_AREG0
1219 tcg_out_push(s
, TCG_AREG0
);
1223 /* The first argument is already loaded with addrlo. */
1225 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[arg_idx
],
1227 #ifdef CONFIG_TCG_PASS_AREG0
1228 /* XXX/FIXME: suboptimal */
1229 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[3],
1230 tcg_target_call_iarg_regs
[2]);
1231 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[2],
1232 tcg_target_call_iarg_regs
[1]);
1233 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[1],
1234 tcg_target_call_iarg_regs
[0]);
1235 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0],
1240 tcg_out_calli(s
, (tcg_target_long
)qemu_ld_helpers
[s_bits
]);
1242 #if TCG_TARGET_REG_BITS == 32
1243 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1244 /* Pop and discard. This is 2 bytes smaller than the add. */
1245 tcg_out_pop(s
, TCG_REG_ECX
);
1246 } else if (stack_adjust
!= 0) {
1247 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1253 tcg_out_ext8s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1256 tcg_out_ext16s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1259 tcg_out_ext8u(s
, data_reg
, TCG_REG_EAX
);
1262 tcg_out_ext16u(s
, data_reg
, TCG_REG_EAX
);
1265 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1267 #if TCG_TARGET_REG_BITS == 64
1269 tcg_out_ext32s(s
, data_reg
, TCG_REG_EAX
);
1273 if (TCG_TARGET_REG_BITS
== 64) {
1274 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_RAX
);
1275 } else if (data_reg
== TCG_REG_EDX
) {
1276 /* xchg %edx, %eax */
1277 tcg_out_opc(s
, OPC_XCHG_ax_r32
+ TCG_REG_EDX
, 0, 0, 0);
1278 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EAX
);
1280 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1281 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EDX
);
1289 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1292 int32_t offset
= GUEST_BASE
;
1293 int base
= args
[addrlo_idx
];
1295 if (TCG_TARGET_REG_BITS
== 64) {
1296 /* ??? We assume all operations have left us with register
1297 contents that are zero extended. So far this appears to
1298 be true. If we want to enforce this, we can either do
1299 an explicit zero-extension here, or (if GUEST_BASE == 0)
1300 use the ADDR32 prefix. For now, do nothing. */
1302 if (offset
!= GUEST_BASE
) {
1303 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_RDI
, GUEST_BASE
);
1304 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_RDI
, base
);
1305 base
= TCG_REG_RDI
, offset
= 0;
1309 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1314 static void tcg_out_qemu_st_direct(TCGContext
*s
, int datalo
, int datahi
,
1315 int base
, tcg_target_long ofs
, int sizeop
)
1317 #ifdef TARGET_WORDS_BIGENDIAN
1318 const int bswap
= 1;
1320 const int bswap
= 0;
1322 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1323 we could perform the bswap twice to restore the original value
1324 instead of moving to the scratch. But as it is, the L constraint
1325 means that the second argument reg is definitely free here. */
1326 int scratch
= tcg_target_call_iarg_regs
[1];
1330 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
+ P_REXB_R
, datalo
, base
, ofs
);
1334 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1335 tcg_out_rolw_8(s
, scratch
);
1338 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ P_DATA16
, datalo
, base
, ofs
);
1342 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1343 tcg_out_bswap32(s
, scratch
);
1346 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1349 if (TCG_TARGET_REG_BITS
== 64) {
1351 tcg_out_mov(s
, TCG_TYPE_I64
, scratch
, datalo
);
1352 tcg_out_bswap64(s
, scratch
);
1355 tcg_out_st(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1357 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datahi
);
1358 tcg_out_bswap32(s
, scratch
);
1359 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
);
1360 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1361 tcg_out_bswap32(s
, scratch
);
1362 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
+ 4);
1364 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1365 tcg_out_st(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1373 static void tcg_out_qemu_st(TCGContext
*s
, const TCGArg
*args
,
1376 int data_reg
, data_reg2
= 0;
1378 #if defined(CONFIG_SOFTMMU)
1379 int mem_index
, s_bits
;
1381 uint8_t *label_ptr
[3];
1386 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1387 data_reg2
= args
[1];
1391 #if defined(CONFIG_SOFTMMU)
1392 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1395 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1396 label_ptr
, offsetof(CPUTLBEntry
, addr_write
));
1399 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
,
1400 tcg_target_call_iarg_regs
[0], 0, opc
);
1403 tcg_out8(s
, OPC_JMP_short
);
1404 label_ptr
[2] = s
->code_ptr
;
1410 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1411 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1412 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1415 /* XXX: move that code at the end of the TB */
1416 #if TCG_TARGET_REG_BITS == 32
1417 tcg_out_pushi(s
, mem_index
);
1420 tcg_out_push(s
, data_reg2
);
1423 tcg_out_push(s
, data_reg
);
1425 if (TARGET_LONG_BITS
== 64) {
1426 tcg_out_push(s
, args
[addrlo_idx
+ 1]);
1429 tcg_out_push(s
, args
[addrlo_idx
]);
1431 #ifdef CONFIG_TCG_PASS_AREG0
1432 tcg_out_push(s
, TCG_AREG0
);
1436 tcg_out_mov(s
, (opc
== 3 ? TCG_TYPE_I64
: TCG_TYPE_I32
),
1437 TCG_REG_RSI
, data_reg
);
1438 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_RDX
, mem_index
);
1440 #ifdef CONFIG_TCG_PASS_AREG0
1441 /* XXX/FIXME: suboptimal */
1442 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[3],
1443 tcg_target_call_iarg_regs
[2]);
1444 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[2],
1445 tcg_target_call_iarg_regs
[1]);
1446 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[1],
1447 tcg_target_call_iarg_regs
[0]);
1448 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0],
1453 tcg_out_calli(s
, (tcg_target_long
)qemu_st_helpers
[s_bits
]);
1455 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1456 /* Pop and discard. This is 2 bytes smaller than the add. */
1457 tcg_out_pop(s
, TCG_REG_ECX
);
1458 } else if (stack_adjust
!= 0) {
1459 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1463 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1466 int32_t offset
= GUEST_BASE
;
1467 int base
= args
[addrlo_idx
];
1469 if (TCG_TARGET_REG_BITS
== 64) {
1470 /* ??? We assume all operations have left us with register
1471 contents that are zero extended. So far this appears to
1472 be true. If we want to enforce this, we can either do
1473 an explicit zero-extension here, or (if GUEST_BASE == 0)
1474 use the ADDR32 prefix. For now, do nothing. */
1476 if (offset
!= GUEST_BASE
) {
1477 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_RDI
, GUEST_BASE
);
1478 tgen_arithr(s
, ARITH_ADD
+ P_REXW
, TCG_REG_RDI
, base
);
1479 base
= TCG_REG_RDI
, offset
= 0;
1483 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1488 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1489 const TCGArg
*args
, const int *const_args
)
1493 #if TCG_TARGET_REG_BITS == 64
1494 # define OP_32_64(x) \
1495 case glue(glue(INDEX_op_, x), _i64): \
1496 rexw = P_REXW; /* FALLTHRU */ \
1497 case glue(glue(INDEX_op_, x), _i32)
1499 # define OP_32_64(x) \
1500 case glue(glue(INDEX_op_, x), _i32)
1504 case INDEX_op_exit_tb
:
1505 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_EAX
, args
[0]);
1506 tcg_out_jmp(s
, (tcg_target_long
) tb_ret_addr
);
1508 case INDEX_op_goto_tb
:
1509 if (s
->tb_jmp_offset
) {
1510 /* direct jump method */
1511 tcg_out8(s
, OPC_JMP_long
); /* jmp im */
1512 s
->tb_jmp_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1515 /* indirect jump method */
1516 tcg_out_modrm_offset(s
, OPC_GRP5
, EXT5_JMPN_Ev
, -1,
1517 (tcg_target_long
)(s
->tb_next
+ args
[0]));
1519 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1522 if (const_args
[0]) {
1523 tcg_out_calli(s
, args
[0]);
1526 tcg_out_modrm(s
, OPC_GRP5
, EXT5_CALLN_Ev
, args
[0]);
1530 if (const_args
[0]) {
1531 tcg_out_jmp(s
, args
[0]);
1534 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, args
[0]);
1538 tcg_out_jxx(s
, JCC_JMP
, args
[0], 0);
1540 case INDEX_op_movi_i32
:
1541 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1544 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1545 tcg_out_modrm_offset(s
, OPC_MOVZBL
, args
[0], args
[1], args
[2]);
1548 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ rexw
, args
[0], args
[1], args
[2]);
1551 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1552 tcg_out_modrm_offset(s
, OPC_MOVZWL
, args
[0], args
[1], args
[2]);
1555 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ rexw
, args
[0], args
[1], args
[2]);
1557 #if TCG_TARGET_REG_BITS == 64
1558 case INDEX_op_ld32u_i64
:
1560 case INDEX_op_ld_i32
:
1561 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1565 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
| P_REXB_R
,
1566 args
[0], args
[1], args
[2]);
1569 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
| P_DATA16
,
1570 args
[0], args
[1], args
[2]);
1572 #if TCG_TARGET_REG_BITS == 64
1573 case INDEX_op_st32_i64
:
1575 case INDEX_op_st_i32
:
1576 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1580 /* For 3-operand addition, use LEA. */
1581 if (args
[0] != args
[1]) {
1582 TCGArg a0
= args
[0], a1
= args
[1], a2
= args
[2], c3
= 0;
1584 if (const_args
[2]) {
1586 } else if (a0
== a2
) {
1587 /* Watch out for dest = src + dest, since we've removed
1588 the matching constraint on the add. */
1589 tgen_arithr(s
, ARITH_ADD
+ rexw
, a0
, a1
);
1593 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ rexw
, a0
, a1
, a2
, 0, c3
);
1611 if (const_args
[2]) {
1612 tgen_arithi(s
, c
+ rexw
, args
[0], args
[2], 0);
1614 tgen_arithr(s
, c
+ rexw
, args
[0], args
[2]);
1619 if (const_args
[2]) {
1622 if (val
== (int8_t)val
) {
1623 tcg_out_modrm(s
, OPC_IMUL_GvEvIb
+ rexw
, args
[0], args
[0]);
1626 tcg_out_modrm(s
, OPC_IMUL_GvEvIz
+ rexw
, args
[0], args
[0]);
1630 tcg_out_modrm(s
, OPC_IMUL_GvEv
+ rexw
, args
[0], args
[2]);
1635 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_IDIV
, args
[4]);
1638 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_DIV
, args
[4]);
1657 if (const_args
[2]) {
1658 tcg_out_shifti(s
, c
+ rexw
, args
[0], args
[2]);
1660 tcg_out_modrm(s
, OPC_SHIFT_cl
+ rexw
, c
, args
[0]);
1664 case INDEX_op_brcond_i32
:
1665 tcg_out_brcond32(s
, args
[2], args
[0], args
[1], const_args
[1],
1668 case INDEX_op_setcond_i32
:
1669 tcg_out_setcond32(s
, args
[3], args
[0], args
[1],
1670 args
[2], const_args
[2]);
1674 tcg_out_rolw_8(s
, args
[0]);
1677 tcg_out_bswap32(s
, args
[0]);
1681 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NEG
, args
[0]);
1684 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NOT
, args
[0]);
1688 tcg_out_ext8s(s
, args
[0], args
[1], rexw
);
1691 tcg_out_ext16s(s
, args
[0], args
[1], rexw
);
1694 tcg_out_ext8u(s
, args
[0], args
[1]);
1697 tcg_out_ext16u(s
, args
[0], args
[1]);
1700 case INDEX_op_qemu_ld8u
:
1701 tcg_out_qemu_ld(s
, args
, 0);
1703 case INDEX_op_qemu_ld8s
:
1704 tcg_out_qemu_ld(s
, args
, 0 | 4);
1706 case INDEX_op_qemu_ld16u
:
1707 tcg_out_qemu_ld(s
, args
, 1);
1709 case INDEX_op_qemu_ld16s
:
1710 tcg_out_qemu_ld(s
, args
, 1 | 4);
1712 #if TCG_TARGET_REG_BITS == 64
1713 case INDEX_op_qemu_ld32u
:
1715 case INDEX_op_qemu_ld32
:
1716 tcg_out_qemu_ld(s
, args
, 2);
1718 case INDEX_op_qemu_ld64
:
1719 tcg_out_qemu_ld(s
, args
, 3);
1722 case INDEX_op_qemu_st8
:
1723 tcg_out_qemu_st(s
, args
, 0);
1725 case INDEX_op_qemu_st16
:
1726 tcg_out_qemu_st(s
, args
, 1);
1728 case INDEX_op_qemu_st32
:
1729 tcg_out_qemu_st(s
, args
, 2);
1731 case INDEX_op_qemu_st64
:
1732 tcg_out_qemu_st(s
, args
, 3);
1735 #if TCG_TARGET_REG_BITS == 32
1736 case INDEX_op_brcond2_i32
:
1737 tcg_out_brcond2(s
, args
, const_args
, 0);
1739 case INDEX_op_setcond2_i32
:
1740 tcg_out_setcond2(s
, args
, const_args
);
1742 case INDEX_op_mulu2_i32
:
1743 tcg_out_modrm(s
, OPC_GRP3_Ev
, EXT3_MUL
, args
[3]);
1745 case INDEX_op_add2_i32
:
1746 if (const_args
[4]) {
1747 tgen_arithi(s
, ARITH_ADD
, args
[0], args
[4], 1);
1749 tgen_arithr(s
, ARITH_ADD
, args
[0], args
[4]);
1751 if (const_args
[5]) {
1752 tgen_arithi(s
, ARITH_ADC
, args
[1], args
[5], 1);
1754 tgen_arithr(s
, ARITH_ADC
, args
[1], args
[5]);
1757 case INDEX_op_sub2_i32
:
1758 if (const_args
[4]) {
1759 tgen_arithi(s
, ARITH_SUB
, args
[0], args
[4], 1);
1761 tgen_arithr(s
, ARITH_SUB
, args
[0], args
[4]);
1763 if (const_args
[5]) {
1764 tgen_arithi(s
, ARITH_SBB
, args
[1], args
[5], 1);
1766 tgen_arithr(s
, ARITH_SBB
, args
[1], args
[5]);
1769 #else /* TCG_TARGET_REG_BITS == 64 */
1770 case INDEX_op_movi_i64
:
1771 tcg_out_movi(s
, TCG_TYPE_I64
, args
[0], args
[1]);
1773 case INDEX_op_ld32s_i64
:
1774 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, args
[0], args
[1], args
[2]);
1776 case INDEX_op_ld_i64
:
1777 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1779 case INDEX_op_st_i64
:
1780 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1782 case INDEX_op_qemu_ld32s
:
1783 tcg_out_qemu_ld(s
, args
, 2 | 4);
1786 case INDEX_op_brcond_i64
:
1787 tcg_out_brcond64(s
, args
[2], args
[0], args
[1], const_args
[1],
1790 case INDEX_op_setcond_i64
:
1791 tcg_out_setcond64(s
, args
[3], args
[0], args
[1],
1792 args
[2], const_args
[2]);
1795 case INDEX_op_bswap64_i64
:
1796 tcg_out_bswap64(s
, args
[0]);
1798 case INDEX_op_ext32u_i64
:
1799 tcg_out_ext32u(s
, args
[0], args
[1]);
1801 case INDEX_op_ext32s_i64
:
1802 tcg_out_ext32s(s
, args
[0], args
[1]);
1807 if (args
[3] == 0 && args
[4] == 8) {
1808 /* load bits 0..7 */
1809 tcg_out_modrm(s
, OPC_MOVB_EvGv
| P_REXB_R
| P_REXB_RM
,
1811 } else if (args
[3] == 8 && args
[4] == 8) {
1812 /* load bits 8..15 */
1813 tcg_out_modrm(s
, OPC_MOVB_EvGv
, args
[2], args
[0] + 4);
1814 } else if (args
[3] == 0 && args
[4] == 16) {
1815 /* load bits 0..15 */
1816 tcg_out_modrm(s
, OPC_MOVL_EvGv
| P_DATA16
, args
[2], args
[0]);
1829 static const TCGTargetOpDef x86_op_defs
[] = {
1830 { INDEX_op_exit_tb
, { } },
1831 { INDEX_op_goto_tb
, { } },
1832 { INDEX_op_call
, { "ri" } },
1833 { INDEX_op_jmp
, { "ri" } },
1834 { INDEX_op_br
, { } },
1835 { INDEX_op_mov_i32
, { "r", "r" } },
1836 { INDEX_op_movi_i32
, { "r" } },
1837 { INDEX_op_ld8u_i32
, { "r", "r" } },
1838 { INDEX_op_ld8s_i32
, { "r", "r" } },
1839 { INDEX_op_ld16u_i32
, { "r", "r" } },
1840 { INDEX_op_ld16s_i32
, { "r", "r" } },
1841 { INDEX_op_ld_i32
, { "r", "r" } },
1842 { INDEX_op_st8_i32
, { "q", "r" } },
1843 { INDEX_op_st16_i32
, { "r", "r" } },
1844 { INDEX_op_st_i32
, { "r", "r" } },
1846 { INDEX_op_add_i32
, { "r", "r", "ri" } },
1847 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
1848 { INDEX_op_mul_i32
, { "r", "0", "ri" } },
1849 { INDEX_op_div2_i32
, { "a", "d", "0", "1", "r" } },
1850 { INDEX_op_divu2_i32
, { "a", "d", "0", "1", "r" } },
1851 { INDEX_op_and_i32
, { "r", "0", "ri" } },
1852 { INDEX_op_or_i32
, { "r", "0", "ri" } },
1853 { INDEX_op_xor_i32
, { "r", "0", "ri" } },
1855 { INDEX_op_shl_i32
, { "r", "0", "ci" } },
1856 { INDEX_op_shr_i32
, { "r", "0", "ci" } },
1857 { INDEX_op_sar_i32
, { "r", "0", "ci" } },
1858 { INDEX_op_rotl_i32
, { "r", "0", "ci" } },
1859 { INDEX_op_rotr_i32
, { "r", "0", "ci" } },
1861 { INDEX_op_brcond_i32
, { "r", "ri" } },
1863 { INDEX_op_bswap16_i32
, { "r", "0" } },
1864 { INDEX_op_bswap32_i32
, { "r", "0" } },
1866 { INDEX_op_neg_i32
, { "r", "0" } },
1868 { INDEX_op_not_i32
, { "r", "0" } },
1870 { INDEX_op_ext8s_i32
, { "r", "q" } },
1871 { INDEX_op_ext16s_i32
, { "r", "r" } },
1872 { INDEX_op_ext8u_i32
, { "r", "q" } },
1873 { INDEX_op_ext16u_i32
, { "r", "r" } },
1875 { INDEX_op_setcond_i32
, { "q", "r", "ri" } },
1877 { INDEX_op_deposit_i32
, { "Q", "0", "Q" } },
1879 #if TCG_TARGET_REG_BITS == 32
1880 { INDEX_op_mulu2_i32
, { "a", "d", "a", "r" } },
1881 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1882 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1883 { INDEX_op_brcond2_i32
, { "r", "r", "ri", "ri" } },
1884 { INDEX_op_setcond2_i32
, { "r", "r", "r", "ri", "ri" } },
1886 { INDEX_op_mov_i64
, { "r", "r" } },
1887 { INDEX_op_movi_i64
, { "r" } },
1888 { INDEX_op_ld8u_i64
, { "r", "r" } },
1889 { INDEX_op_ld8s_i64
, { "r", "r" } },
1890 { INDEX_op_ld16u_i64
, { "r", "r" } },
1891 { INDEX_op_ld16s_i64
, { "r", "r" } },
1892 { INDEX_op_ld32u_i64
, { "r", "r" } },
1893 { INDEX_op_ld32s_i64
, { "r", "r" } },
1894 { INDEX_op_ld_i64
, { "r", "r" } },
1895 { INDEX_op_st8_i64
, { "r", "r" } },
1896 { INDEX_op_st16_i64
, { "r", "r" } },
1897 { INDEX_op_st32_i64
, { "r", "r" } },
1898 { INDEX_op_st_i64
, { "r", "r" } },
1900 { INDEX_op_add_i64
, { "r", "0", "re" } },
1901 { INDEX_op_mul_i64
, { "r", "0", "re" } },
1902 { INDEX_op_div2_i64
, { "a", "d", "0", "1", "r" } },
1903 { INDEX_op_divu2_i64
, { "a", "d", "0", "1", "r" } },
1904 { INDEX_op_sub_i64
, { "r", "0", "re" } },
1905 { INDEX_op_and_i64
, { "r", "0", "reZ" } },
1906 { INDEX_op_or_i64
, { "r", "0", "re" } },
1907 { INDEX_op_xor_i64
, { "r", "0", "re" } },
1909 { INDEX_op_shl_i64
, { "r", "0", "ci" } },
1910 { INDEX_op_shr_i64
, { "r", "0", "ci" } },
1911 { INDEX_op_sar_i64
, { "r", "0", "ci" } },
1912 { INDEX_op_rotl_i64
, { "r", "0", "ci" } },
1913 { INDEX_op_rotr_i64
, { "r", "0", "ci" } },
1915 { INDEX_op_brcond_i64
, { "r", "re" } },
1916 { INDEX_op_setcond_i64
, { "r", "r", "re" } },
1918 { INDEX_op_bswap16_i64
, { "r", "0" } },
1919 { INDEX_op_bswap32_i64
, { "r", "0" } },
1920 { INDEX_op_bswap64_i64
, { "r", "0" } },
1921 { INDEX_op_neg_i64
, { "r", "0" } },
1922 { INDEX_op_not_i64
, { "r", "0" } },
1924 { INDEX_op_ext8s_i64
, { "r", "r" } },
1925 { INDEX_op_ext16s_i64
, { "r", "r" } },
1926 { INDEX_op_ext32s_i64
, { "r", "r" } },
1927 { INDEX_op_ext8u_i64
, { "r", "r" } },
1928 { INDEX_op_ext16u_i64
, { "r", "r" } },
1929 { INDEX_op_ext32u_i64
, { "r", "r" } },
1931 { INDEX_op_deposit_i64
, { "Q", "0", "Q" } },
1934 #if TCG_TARGET_REG_BITS == 64
1935 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1936 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1937 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1938 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1939 { INDEX_op_qemu_ld32
, { "r", "L" } },
1940 { INDEX_op_qemu_ld32u
, { "r", "L" } },
1941 { INDEX_op_qemu_ld32s
, { "r", "L" } },
1942 { INDEX_op_qemu_ld64
, { "r", "L" } },
1944 { INDEX_op_qemu_st8
, { "L", "L" } },
1945 { INDEX_op_qemu_st16
, { "L", "L" } },
1946 { INDEX_op_qemu_st32
, { "L", "L" } },
1947 { INDEX_op_qemu_st64
, { "L", "L" } },
1948 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1949 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1950 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1951 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1952 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1953 { INDEX_op_qemu_ld32
, { "r", "L" } },
1954 { INDEX_op_qemu_ld64
, { "r", "r", "L" } },
1956 { INDEX_op_qemu_st8
, { "cb", "L" } },
1957 { INDEX_op_qemu_st16
, { "L", "L" } },
1958 { INDEX_op_qemu_st32
, { "L", "L" } },
1959 { INDEX_op_qemu_st64
, { "L", "L", "L" } },
1961 { INDEX_op_qemu_ld8u
, { "r", "L", "L" } },
1962 { INDEX_op_qemu_ld8s
, { "r", "L", "L" } },
1963 { INDEX_op_qemu_ld16u
, { "r", "L", "L" } },
1964 { INDEX_op_qemu_ld16s
, { "r", "L", "L" } },
1965 { INDEX_op_qemu_ld32
, { "r", "L", "L" } },
1966 { INDEX_op_qemu_ld64
, { "r", "r", "L", "L" } },
1968 { INDEX_op_qemu_st8
, { "cb", "L", "L" } },
1969 { INDEX_op_qemu_st16
, { "L", "L", "L" } },
1970 { INDEX_op_qemu_st32
, { "L", "L", "L" } },
1971 { INDEX_op_qemu_st64
, { "L", "L", "L", "L" } },
1976 static int tcg_target_callee_save_regs
[] = {
1977 #if TCG_TARGET_REG_BITS == 64
1982 TCG_REG_R14
, /* Currently used for the global env. */
1985 TCG_REG_EBP
, /* Currently used for the global env. */
1992 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
1993 and tcg_register_jit. */
1996 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
1997 * (TCG_TARGET_REG_BITS / 8))
1999 #define FRAME_SIZE \
2001 + TCG_STATIC_CALL_ARGS_SIZE \
2002 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2003 + TCG_TARGET_STACK_ALIGN - 1) \
2004 & ~(TCG_TARGET_STACK_ALIGN - 1))
2006 /* Generate global QEMU prologue and epilogue code */
2007 static void tcg_target_qemu_prologue(TCGContext
*s
)
2009 int i
, stack_addend
;
2013 /* Reserve some stack space, also for TCG temps. */
2014 stack_addend
= FRAME_SIZE
- PUSH_SIZE
;
2015 tcg_set_frame(s
, TCG_REG_CALL_STACK
, TCG_STATIC_CALL_ARGS_SIZE
,
2016 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2018 /* Save all callee saved registers. */
2019 for (i
= 0; i
< ARRAY_SIZE(tcg_target_callee_save_regs
); i
++) {
2020 tcg_out_push(s
, tcg_target_callee_save_regs
[i
]);
2023 #if TCG_TARGET_REG_BITS == 32
2024 tcg_out_ld(s
, TCG_TYPE_PTR
, TCG_AREG0
, TCG_REG_ESP
,
2025 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 1) * 4);
2026 tcg_out_ld(s
, TCG_TYPE_PTR
, tcg_target_call_iarg_regs
[1], TCG_REG_ESP
,
2027 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 2) * 4);
2029 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2031 tcg_out_addi(s
, TCG_REG_ESP
, -stack_addend
);
2034 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, tcg_target_call_iarg_regs
[1]);
2037 tb_ret_addr
= s
->code_ptr
;
2039 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_addend
);
2041 for (i
= ARRAY_SIZE(tcg_target_callee_save_regs
) - 1; i
>= 0; i
--) {
2042 tcg_out_pop(s
, tcg_target_callee_save_regs
[i
]);
2044 tcg_out_opc(s
, OPC_RET
, 0, 0, 0);
2047 static void tcg_target_init(TCGContext
*s
)
2049 #if !defined(CONFIG_USER_ONLY)
2051 if ((1 << CPU_TLB_ENTRY_BITS
) != sizeof(CPUTLBEntry
))
2055 if (TCG_TARGET_REG_BITS
== 64) {
2056 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2057 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2059 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xff);
2062 tcg_regset_clear(tcg_target_call_clobber_regs
);
2063 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EAX
);
2064 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EDX
);
2065 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_ECX
);
2066 if (TCG_TARGET_REG_BITS
== 64) {
2067 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RDI
);
2068 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RSI
);
2069 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R8
);
2070 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R9
);
2071 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R10
);
2072 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R11
);
2075 tcg_regset_clear(s
->reserved_regs
);
2076 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2078 tcg_add_target_add_op_defs(x86_op_defs
);
2082 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2085 char augmentation
[1];
2088 uint8_t return_column
;
2092 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2093 uint32_t cie_offset
;
2094 tcg_target_long func_start
__attribute__((packed
));
2095 tcg_target_long func_len
__attribute__((packed
));
2097 uint8_t reg_ofs
[14];
2105 #if !defined(__ELF__)
2106 /* Host machine without ELF. */
2107 #elif TCG_TARGET_REG_BITS == 64
2108 #define ELF_HOST_MACHINE EM_X86_64
2109 static DebugFrame debug_frame
= {
2110 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2113 .cie
.code_align
= 1,
2114 .cie
.data_align
= 0x78, /* sleb128 -8 */
2115 .cie
.return_column
= 16,
2117 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2119 12, 7, /* DW_CFA_def_cfa %rsp, ... */
2120 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2124 0x90, 1, /* DW_CFA_offset, %rip, -8 */
2125 /* The following ordering must match tcg_target_callee_save_regs. */
2126 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
2127 0x83, 3, /* DW_CFA_offset, %rbx, -24 */
2128 0x8c, 4, /* DW_CFA_offset, %r12, -32 */
2129 0x8d, 5, /* DW_CFA_offset, %r13, -40 */
2130 0x8e, 6, /* DW_CFA_offset, %r14, -48 */
2131 0x8f, 7, /* DW_CFA_offset, %r15, -56 */
2135 #define ELF_HOST_MACHINE EM_386
2136 static DebugFrame debug_frame
= {
2137 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2140 .cie
.code_align
= 1,
2141 .cie
.data_align
= 0x7c, /* sleb128 -4 */
2142 .cie
.return_column
= 8,
2144 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2146 12, 4, /* DW_CFA_def_cfa %esp, ... */
2147 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2151 0x88, 1, /* DW_CFA_offset, %eip, -4 */
2152 /* The following ordering must match tcg_target_callee_save_regs. */
2153 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
2154 0x83, 3, /* DW_CFA_offset, %ebx, -12 */
2155 0x86, 4, /* DW_CFA_offset, %esi, -16 */
2156 0x87, 5, /* DW_CFA_offset, %edi, -20 */
2161 #if defined(ELF_HOST_MACHINE)
2162 void tcg_register_jit(void *buf
, size_t buf_size
)
2164 /* We're expecting a 2 byte uleb128 encoded value. */
2165 assert(FRAME_SIZE
>> 14 == 0);
2167 debug_frame
.fde
.func_start
= (tcg_target_long
) buf
;
2168 debug_frame
.fde
.func_len
= buf_size
;
2170 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));