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
84 static const int tcg_target_call_oarg_regs
[] = {
86 #if TCG_TARGET_REG_BITS == 32
91 static uint8_t *tb_ret_addr
;
93 static void patch_reloc(uint8_t *code_ptr
, int type
,
94 tcg_target_long value
, tcg_target_long addend
)
99 value
-= (uintptr_t)code_ptr
;
100 if (value
!= (int32_t)value
) {
103 *(uint32_t *)code_ptr
= value
;
106 value
-= (uintptr_t)code_ptr
;
107 if (value
!= (int8_t)value
) {
110 *(uint8_t *)code_ptr
= value
;
117 /* maximum number of register used for input function arguments */
118 static inline int tcg_target_get_call_iarg_regs_count(int flags
)
120 if (TCG_TARGET_REG_BITS
== 64) {
127 /* parse target specific constraints */
128 static int target_parse_constraint(TCGArgConstraint
*ct
, const char **pct_str
)
135 ct
->ct
|= TCG_CT_REG
;
136 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EAX
);
139 ct
->ct
|= TCG_CT_REG
;
140 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EBX
);
143 ct
->ct
|= TCG_CT_REG
;
144 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ECX
);
147 ct
->ct
|= TCG_CT_REG
;
148 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDX
);
151 ct
->ct
|= TCG_CT_REG
;
152 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_ESI
);
155 ct
->ct
|= TCG_CT_REG
;
156 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_EDI
);
159 ct
->ct
|= TCG_CT_REG
;
160 if (TCG_TARGET_REG_BITS
== 64) {
161 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
163 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
167 ct
->ct
|= TCG_CT_REG
;
168 tcg_regset_set32(ct
->u
.regs
, 0, 0xf);
171 ct
->ct
|= TCG_CT_REG
;
172 if (TCG_TARGET_REG_BITS
== 64) {
173 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
175 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
179 /* qemu_ld/st address constraint */
181 ct
->ct
|= TCG_CT_REG
;
182 if (TCG_TARGET_REG_BITS
== 64) {
183 tcg_regset_set32(ct
->u
.regs
, 0, 0xffff);
184 tcg_regset_reset_reg(ct
->u
.regs
, tcg_target_call_iarg_regs
[0]);
185 tcg_regset_reset_reg(ct
->u
.regs
, tcg_target_call_iarg_regs
[1]);
186 #ifdef CONFIG_TCG_PASS_AREG0
187 tcg_regset_reset_reg(ct
->u
.regs
, tcg_target_call_iarg_regs
[2]);
190 tcg_regset_set32(ct
->u
.regs
, 0, 0xff);
191 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EAX
);
192 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_EDX
);
197 ct
->ct
|= TCG_CT_CONST_S32
;
200 ct
->ct
|= TCG_CT_CONST_U32
;
211 /* test if a constant matches the constraint */
212 static inline int tcg_target_const_match(tcg_target_long val
,
213 const TCGArgConstraint
*arg_ct
)
216 if (ct
& TCG_CT_CONST
) {
219 if ((ct
& TCG_CT_CONST_S32
) && val
== (int32_t)val
) {
222 if ((ct
& TCG_CT_CONST_U32
) && val
== (uint32_t)val
) {
228 #if TCG_TARGET_REG_BITS == 64
229 # define LOWREGMASK(x) ((x) & 7)
231 # define LOWREGMASK(x) (x)
234 #define P_EXT 0x100 /* 0x0f opcode prefix */
235 #define P_DATA16 0x200 /* 0x66 opcode prefix */
236 #if TCG_TARGET_REG_BITS == 64
237 # define P_ADDR32 0x400 /* 0x67 opcode prefix */
238 # define P_REXW 0x800 /* Set REX.W = 1 */
239 # define P_REXB_R 0x1000 /* REG field as byte register */
240 # define P_REXB_RM 0x2000 /* R/M field as byte register */
248 #define OPC_ARITH_EvIz (0x81)
249 #define OPC_ARITH_EvIb (0x83)
250 #define OPC_ARITH_GvEv (0x03) /* ... plus (ARITH_FOO << 3) */
251 #define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
252 #define OPC_BSWAP (0xc8 | P_EXT)
253 #define OPC_CALL_Jz (0xe8)
254 #define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
255 #define OPC_DEC_r32 (0x48)
256 #define OPC_IMUL_GvEv (0xaf | P_EXT)
257 #define OPC_IMUL_GvEvIb (0x6b)
258 #define OPC_IMUL_GvEvIz (0x69)
259 #define OPC_INC_r32 (0x40)
260 #define OPC_JCC_long (0x80 | P_EXT) /* ... plus condition code */
261 #define OPC_JCC_short (0x70) /* ... plus condition code */
262 #define OPC_JMP_long (0xe9)
263 #define OPC_JMP_short (0xeb)
264 #define OPC_LEA (0x8d)
265 #define OPC_MOVB_EvGv (0x88) /* stores, more or less */
266 #define OPC_MOVL_EvGv (0x89) /* stores, more or less */
267 #define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
268 #define OPC_MOVL_EvIz (0xc7)
269 #define OPC_MOVL_Iv (0xb8)
270 #define OPC_MOVSBL (0xbe | P_EXT)
271 #define OPC_MOVSWL (0xbf | P_EXT)
272 #define OPC_MOVSLQ (0x63 | P_REXW)
273 #define OPC_MOVZBL (0xb6 | P_EXT)
274 #define OPC_MOVZWL (0xb7 | P_EXT)
275 #define OPC_POP_r32 (0x58)
276 #define OPC_PUSH_r32 (0x50)
277 #define OPC_PUSH_Iv (0x68)
278 #define OPC_PUSH_Ib (0x6a)
279 #define OPC_RET (0xc3)
280 #define OPC_SETCC (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
281 #define OPC_SHIFT_1 (0xd1)
282 #define OPC_SHIFT_Ib (0xc1)
283 #define OPC_SHIFT_cl (0xd3)
284 #define OPC_TESTL (0x85)
285 #define OPC_XCHG_ax_r32 (0x90)
287 #define OPC_GRP3_Ev (0xf7)
288 #define OPC_GRP5 (0xff)
290 /* Group 1 opcode extensions for 0x80-0x83.
291 These are also used as modifiers for OPC_ARITH. */
301 /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3. */
308 /* Group 3 opcode extensions for 0xf6, 0xf7. To be used with OPC_GRP3. */
316 /* Group 5 opcode extensions for 0xff. To be used with OPC_GRP5. */
317 #define EXT5_INC_Ev 0
318 #define EXT5_DEC_Ev 1
319 #define EXT5_CALLN_Ev 2
320 #define EXT5_JMPN_Ev 4
322 /* Condition codes to be added to OPC_JCC_{long,short}. */
341 static const uint8_t tcg_cond_to_jcc
[10] = {
342 [TCG_COND_EQ
] = JCC_JE
,
343 [TCG_COND_NE
] = JCC_JNE
,
344 [TCG_COND_LT
] = JCC_JL
,
345 [TCG_COND_GE
] = JCC_JGE
,
346 [TCG_COND_LE
] = JCC_JLE
,
347 [TCG_COND_GT
] = JCC_JG
,
348 [TCG_COND_LTU
] = JCC_JB
,
349 [TCG_COND_GEU
] = JCC_JAE
,
350 [TCG_COND_LEU
] = JCC_JBE
,
351 [TCG_COND_GTU
] = JCC_JA
,
354 #if TCG_TARGET_REG_BITS == 64
355 static void tcg_out_opc(TCGContext
*s
, int opc
, int r
, int rm
, int x
)
359 if (opc
& P_DATA16
) {
360 /* We should never be asking for both 16 and 64-bit operation. */
361 assert((opc
& P_REXW
) == 0);
364 if (opc
& P_ADDR32
) {
369 rex
|= (opc
& P_REXW
) >> 8; /* REX.W */
370 rex
|= (r
& 8) >> 1; /* REX.R */
371 rex
|= (x
& 8) >> 2; /* REX.X */
372 rex
|= (rm
& 8) >> 3; /* REX.B */
374 /* P_REXB_{R,RM} indicates that the given register is the low byte.
375 For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
376 as otherwise the encoding indicates %[abcd]h. Note that the values
377 that are ORed in merely indicate that the REX byte must be present;
378 those bits get discarded in output. */
379 rex
|= opc
& (r
>= 4 ? P_REXB_R
: 0);
380 rex
|= opc
& (rm
>= 4 ? P_REXB_RM
: 0);
383 tcg_out8(s
, (uint8_t)(rex
| 0x40));
392 static void tcg_out_opc(TCGContext
*s
, int opc
)
394 if (opc
& P_DATA16
) {
402 /* Discard the register arguments to tcg_out_opc early, so as not to penalize
403 the 32-bit compilation paths. This method works with all versions of gcc,
404 whereas relying on optimization may not be able to exclude them. */
405 #define tcg_out_opc(s, opc, r, rm, x) (tcg_out_opc)(s, opc)
408 static void tcg_out_modrm(TCGContext
*s
, int opc
, int r
, int rm
)
410 tcg_out_opc(s
, opc
, r
, rm
, 0);
411 tcg_out8(s
, 0xc0 | (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
414 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
415 We handle either RM and INDEX missing with a negative value. In 64-bit
416 mode for absolute addresses, ~RM is the size of the immediate operand
417 that will follow the instruction. */
419 static void tcg_out_modrm_sib_offset(TCGContext
*s
, int opc
, int r
, int rm
,
420 int index
, int shift
,
421 tcg_target_long offset
)
425 if (index
< 0 && rm
< 0) {
426 if (TCG_TARGET_REG_BITS
== 64) {
427 /* Try for a rip-relative addressing mode. This has replaced
428 the 32-bit-mode absolute addressing encoding. */
429 tcg_target_long pc
= (tcg_target_long
)s
->code_ptr
+ 5 + ~rm
;
430 tcg_target_long disp
= offset
- pc
;
431 if (disp
== (int32_t)disp
) {
432 tcg_out_opc(s
, opc
, r
, 0, 0);
433 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 5);
438 /* Try for an absolute address encoding. This requires the
439 use of the MODRM+SIB encoding and is therefore larger than
440 rip-relative addressing. */
441 if (offset
== (int32_t)offset
) {
442 tcg_out_opc(s
, opc
, r
, 0, 0);
443 tcg_out8(s
, (LOWREGMASK(r
) << 3) | 4);
444 tcg_out8(s
, (4 << 3) | 5);
445 tcg_out32(s
, offset
);
449 /* ??? The memory isn't directly addressable. */
452 /* Absolute address. */
453 tcg_out_opc(s
, opc
, r
, 0, 0);
454 tcg_out8(s
, (r
<< 3) | 5);
455 tcg_out32(s
, offset
);
460 /* Find the length of the immediate addend. Note that the encoding
461 that would be used for (%ebp) indicates absolute addressing. */
463 mod
= 0, len
= 4, rm
= 5;
464 } else if (offset
== 0 && LOWREGMASK(rm
) != TCG_REG_EBP
) {
466 } else if (offset
== (int8_t)offset
) {
472 /* Use a single byte MODRM format if possible. Note that the encoding
473 that would be used for %esp is the escape to the two byte form. */
474 if (index
< 0 && LOWREGMASK(rm
) != TCG_REG_ESP
) {
475 /* Single byte MODRM format. */
476 tcg_out_opc(s
, opc
, r
, rm
, 0);
477 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | LOWREGMASK(rm
));
479 /* Two byte MODRM+SIB format. */
481 /* Note that the encoding that would place %esp into the index
482 field indicates no index register. In 64-bit mode, the REX.X
483 bit counts, so %r12 can be used as the index. */
487 assert(index
!= TCG_REG_ESP
);
490 tcg_out_opc(s
, opc
, r
, rm
, index
);
491 tcg_out8(s
, mod
| (LOWREGMASK(r
) << 3) | 4);
492 tcg_out8(s
, (shift
<< 6) | (LOWREGMASK(index
) << 3) | LOWREGMASK(rm
));
497 } else if (len
== 4) {
498 tcg_out32(s
, offset
);
502 /* A simplification of the above with no index or shift. */
503 static inline void tcg_out_modrm_offset(TCGContext
*s
, int opc
, int r
,
504 int rm
, tcg_target_long offset
)
506 tcg_out_modrm_sib_offset(s
, opc
, r
, rm
, -1, 0, offset
);
509 /* Generate dest op= src. Uses the same ARITH_* codes as tgen_arithi. */
510 static inline void tgen_arithr(TCGContext
*s
, int subop
, int dest
, int src
)
512 /* Propagate an opcode prefix, such as P_REXW. */
513 int ext
= subop
& ~0x7;
516 tcg_out_modrm(s
, OPC_ARITH_GvEv
+ (subop
<< 3) + ext
, dest
, src
);
519 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
520 TCGReg ret
, TCGReg arg
)
523 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
524 tcg_out_modrm(s
, opc
, ret
, arg
);
528 static void tcg_out_movi(TCGContext
*s
, TCGType type
,
529 TCGReg ret
, tcg_target_long arg
)
532 tgen_arithr(s
, ARITH_XOR
, ret
, ret
);
534 } else if (arg
== (uint32_t)arg
|| type
== TCG_TYPE_I32
) {
535 tcg_out_opc(s
, OPC_MOVL_Iv
+ LOWREGMASK(ret
), 0, ret
, 0);
537 } else if (arg
== (int32_t)arg
) {
538 tcg_out_modrm(s
, OPC_MOVL_EvIz
+ P_REXW
, 0, ret
);
541 tcg_out_opc(s
, OPC_MOVL_Iv
+ P_REXW
+ LOWREGMASK(ret
), 0, ret
, 0);
543 tcg_out32(s
, arg
>> 31 >> 1);
547 static inline void tcg_out_pushi(TCGContext
*s
, tcg_target_long val
)
549 if (val
== (int8_t)val
) {
550 tcg_out_opc(s
, OPC_PUSH_Ib
, 0, 0, 0);
552 } else if (val
== (int32_t)val
) {
553 tcg_out_opc(s
, OPC_PUSH_Iv
, 0, 0, 0);
560 static inline void tcg_out_push(TCGContext
*s
, int reg
)
562 tcg_out_opc(s
, OPC_PUSH_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
565 static inline void tcg_out_pop(TCGContext
*s
, int reg
)
567 tcg_out_opc(s
, OPC_POP_r32
+ LOWREGMASK(reg
), 0, reg
, 0);
570 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg ret
,
571 TCGReg arg1
, tcg_target_long arg2
)
573 int opc
= OPC_MOVL_GvEv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
574 tcg_out_modrm_offset(s
, opc
, ret
, arg1
, arg2
);
577 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
578 TCGReg arg1
, tcg_target_long arg2
)
580 int opc
= OPC_MOVL_EvGv
+ (type
== TCG_TYPE_I64
? P_REXW
: 0);
581 tcg_out_modrm_offset(s
, opc
, arg
, arg1
, arg2
);
584 static void tcg_out_shifti(TCGContext
*s
, int subopc
, int reg
, int count
)
586 /* Propagate an opcode prefix, such as P_DATA16. */
587 int ext
= subopc
& ~0x7;
591 tcg_out_modrm(s
, OPC_SHIFT_1
+ ext
, subopc
, reg
);
593 tcg_out_modrm(s
, OPC_SHIFT_Ib
+ ext
, subopc
, reg
);
598 static inline void tcg_out_bswap32(TCGContext
*s
, int reg
)
600 tcg_out_opc(s
, OPC_BSWAP
+ LOWREGMASK(reg
), 0, reg
, 0);
603 static inline void tcg_out_rolw_8(TCGContext
*s
, int reg
)
605 tcg_out_shifti(s
, SHIFT_ROL
+ P_DATA16
, reg
, 8);
608 static inline void tcg_out_ext8u(TCGContext
*s
, int dest
, int src
)
611 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
612 tcg_out_modrm(s
, OPC_MOVZBL
+ P_REXB_RM
, dest
, src
);
615 static void tcg_out_ext8s(TCGContext
*s
, int dest
, int src
, int rexw
)
618 assert(src
< 4 || TCG_TARGET_REG_BITS
== 64);
619 tcg_out_modrm(s
, OPC_MOVSBL
+ P_REXB_RM
+ rexw
, dest
, src
);
622 static inline void tcg_out_ext16u(TCGContext
*s
, int dest
, int src
)
625 tcg_out_modrm(s
, OPC_MOVZWL
, dest
, src
);
628 static inline void tcg_out_ext16s(TCGContext
*s
, int dest
, int src
, int rexw
)
631 tcg_out_modrm(s
, OPC_MOVSWL
+ rexw
, dest
, src
);
634 static inline void tcg_out_ext32u(TCGContext
*s
, int dest
, int src
)
636 /* 32-bit mov zero extends. */
637 tcg_out_modrm(s
, OPC_MOVL_GvEv
, dest
, src
);
640 static inline void tcg_out_ext32s(TCGContext
*s
, int dest
, int src
)
642 tcg_out_modrm(s
, OPC_MOVSLQ
, dest
, src
);
645 static inline void tcg_out_bswap64(TCGContext
*s
, int reg
)
647 tcg_out_opc(s
, OPC_BSWAP
+ P_REXW
+ LOWREGMASK(reg
), 0, reg
, 0);
650 static void tgen_arithi(TCGContext
*s
, int c
, int r0
,
651 tcg_target_long val
, int cf
)
655 if (TCG_TARGET_REG_BITS
== 64) {
660 /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
661 partial flags update stalls on Pentium4 and are not recommended
662 by current Intel optimization manuals. */
663 if (!cf
&& (c
== ARITH_ADD
|| c
== ARITH_SUB
) && (val
== 1 || val
== -1)) {
664 int is_inc
= (c
== ARITH_ADD
) ^ (val
< 0);
665 if (TCG_TARGET_REG_BITS
== 64) {
666 /* The single-byte increment encodings are re-tasked as the
667 REX prefixes. Use the MODRM encoding. */
668 tcg_out_modrm(s
, OPC_GRP5
+ rexw
,
669 (is_inc
? EXT5_INC_Ev
: EXT5_DEC_Ev
), r0
);
671 tcg_out8(s
, (is_inc
? OPC_INC_r32
: OPC_DEC_r32
) + r0
);
676 if (c
== ARITH_AND
) {
677 if (TCG_TARGET_REG_BITS
== 64) {
678 if (val
== 0xffffffffu
) {
679 tcg_out_ext32u(s
, r0
, r0
);
682 if (val
== (uint32_t)val
) {
683 /* AND with no high bits set can use a 32-bit operation. */
687 if (val
== 0xffu
&& (r0
< 4 || TCG_TARGET_REG_BITS
== 64)) {
688 tcg_out_ext8u(s
, r0
, r0
);
691 if (val
== 0xffffu
) {
692 tcg_out_ext16u(s
, r0
, r0
);
697 if (val
== (int8_t)val
) {
698 tcg_out_modrm(s
, OPC_ARITH_EvIb
+ rexw
, c
, r0
);
702 if (rexw
== 0 || val
== (int32_t)val
) {
703 tcg_out_modrm(s
, OPC_ARITH_EvIz
+ rexw
, c
, r0
);
711 static void tcg_out_addi(TCGContext
*s
, int reg
, tcg_target_long val
)
714 tgen_arithi(s
, ARITH_ADD
+ P_REXW
, reg
, val
, 0);
718 /* Use SMALL != 0 to force a short forward branch. */
719 static void tcg_out_jxx(TCGContext
*s
, int opc
, int label_index
, int small
)
722 TCGLabel
*l
= &s
->labels
[label_index
];
725 val
= l
->u
.value
- (tcg_target_long
)s
->code_ptr
;
727 if ((int8_t)val1
== val1
) {
729 tcg_out8(s
, OPC_JMP_short
);
731 tcg_out8(s
, OPC_JCC_short
+ opc
);
739 tcg_out8(s
, OPC_JMP_long
);
740 tcg_out32(s
, val
- 5);
742 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
743 tcg_out32(s
, val
- 6);
748 tcg_out8(s
, OPC_JMP_short
);
750 tcg_out8(s
, OPC_JCC_short
+ opc
);
752 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC8
, label_index
, -1);
756 tcg_out8(s
, OPC_JMP_long
);
758 tcg_out_opc(s
, OPC_JCC_long
+ opc
, 0, 0, 0);
760 tcg_out_reloc(s
, s
->code_ptr
, R_386_PC32
, label_index
, -4);
765 static void tcg_out_cmp(TCGContext
*s
, TCGArg arg1
, TCGArg arg2
,
766 int const_arg2
, int rexw
)
771 tcg_out_modrm(s
, OPC_TESTL
+ rexw
, arg1
, arg1
);
773 tgen_arithi(s
, ARITH_CMP
+ rexw
, arg1
, arg2
, 0);
776 tgen_arithr(s
, ARITH_CMP
+ rexw
, arg1
, arg2
);
780 static void tcg_out_brcond32(TCGContext
*s
, TCGCond cond
,
781 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
782 int label_index
, int small
)
784 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
785 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
788 #if TCG_TARGET_REG_BITS == 64
789 static void tcg_out_brcond64(TCGContext
*s
, TCGCond cond
,
790 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
791 int label_index
, int small
)
793 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
794 tcg_out_jxx(s
, tcg_cond_to_jcc
[cond
], label_index
, small
);
797 /* XXX: we implement it at the target level to avoid having to
798 handle cross basic blocks temporaries */
799 static void tcg_out_brcond2(TCGContext
*s
, const TCGArg
*args
,
800 const int *const_args
, int small
)
803 label_next
= gen_new_label();
806 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
808 tcg_out_brcond32(s
, TCG_COND_EQ
, args
[1], args
[3], const_args
[3],
812 tcg_out_brcond32(s
, TCG_COND_NE
, args
[0], args
[2], const_args
[2],
814 tcg_out_brcond32(s
, TCG_COND_NE
, args
[1], args
[3], const_args
[3],
818 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
820 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
821 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
825 tcg_out_brcond32(s
, TCG_COND_LT
, args
[1], args
[3], const_args
[3],
827 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
828 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
832 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
834 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
835 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
839 tcg_out_brcond32(s
, TCG_COND_GT
, args
[1], args
[3], const_args
[3],
841 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
842 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
846 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
848 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
849 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[0], args
[2], const_args
[2],
853 tcg_out_brcond32(s
, TCG_COND_LTU
, args
[1], args
[3], const_args
[3],
855 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
856 tcg_out_brcond32(s
, TCG_COND_LEU
, args
[0], args
[2], const_args
[2],
860 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
862 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
863 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[0], args
[2], const_args
[2],
867 tcg_out_brcond32(s
, TCG_COND_GTU
, args
[1], args
[3], const_args
[3],
869 tcg_out_jxx(s
, JCC_JNE
, label_next
, 1);
870 tcg_out_brcond32(s
, TCG_COND_GEU
, args
[0], args
[2], const_args
[2],
876 tcg_out_label(s
, label_next
, s
->code_ptr
);
880 static void tcg_out_setcond32(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
881 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
883 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, 0);
884 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
885 tcg_out_ext8u(s
, dest
, dest
);
888 #if TCG_TARGET_REG_BITS == 64
889 static void tcg_out_setcond64(TCGContext
*s
, TCGCond cond
, TCGArg dest
,
890 TCGArg arg1
, TCGArg arg2
, int const_arg2
)
892 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
, P_REXW
);
893 tcg_out_modrm(s
, OPC_SETCC
| tcg_cond_to_jcc
[cond
], 0, dest
);
894 tcg_out_ext8u(s
, dest
, dest
);
897 static void tcg_out_setcond2(TCGContext
*s
, const TCGArg
*args
,
898 const int *const_args
)
901 int label_true
, label_over
;
903 memcpy(new_args
, args
+1, 5*sizeof(TCGArg
));
905 if (args
[0] == args
[1] || args
[0] == args
[2]
906 || (!const_args
[3] && args
[0] == args
[3])
907 || (!const_args
[4] && args
[0] == args
[4])) {
908 /* When the destination overlaps with one of the argument
909 registers, don't do anything tricky. */
910 label_true
= gen_new_label();
911 label_over
= gen_new_label();
913 new_args
[5] = label_true
;
914 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
916 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
917 tcg_out_jxx(s
, JCC_JMP
, label_over
, 1);
918 tcg_out_label(s
, label_true
, s
->code_ptr
);
920 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 1);
921 tcg_out_label(s
, label_over
, s
->code_ptr
);
923 /* When the destination does not overlap one of the arguments,
924 clear the destination first, jump if cond false, and emit an
925 increment in the true case. This results in smaller code. */
927 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], 0);
929 label_over
= gen_new_label();
930 new_args
[4] = tcg_invert_cond(new_args
[4]);
931 new_args
[5] = label_over
;
932 tcg_out_brcond2(s
, new_args
, const_args
+1, 1);
934 tgen_arithi(s
, ARITH_ADD
, args
[0], 1, 0);
935 tcg_out_label(s
, label_over
, s
->code_ptr
);
940 static void tcg_out_branch(TCGContext
*s
, int call
, tcg_target_long dest
)
942 tcg_target_long disp
= dest
- (tcg_target_long
)s
->code_ptr
- 5;
944 if (disp
== (int32_t)disp
) {
945 tcg_out_opc(s
, call
? OPC_CALL_Jz
: OPC_JMP_long
, 0, 0, 0);
948 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_R10
, dest
);
949 tcg_out_modrm(s
, OPC_GRP5
,
950 call
? EXT5_CALLN_Ev
: EXT5_JMPN_Ev
, TCG_REG_R10
);
954 static inline void tcg_out_calli(TCGContext
*s
, tcg_target_long dest
)
956 tcg_out_branch(s
, 1, dest
);
959 static void tcg_out_jmp(TCGContext
*s
, tcg_target_long dest
)
961 tcg_out_branch(s
, 0, dest
);
964 #if defined(CONFIG_SOFTMMU)
966 #include "../../softmmu_defs.h"
968 #ifdef CONFIG_TCG_PASS_AREG0
969 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
971 static const void *qemu_ld_helpers
[4] = {
978 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
979 uintxx_t val, int mmu_idx) */
980 static const void *qemu_st_helpers
[4] = {
987 /* legacy helper signature: __ld_mmu(target_ulong addr, int
989 static void *qemu_ld_helpers
[4] = {
996 /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
998 static void *qemu_st_helpers
[4] = {
1006 /* Perform the TLB load and compare.
1009 ADDRLO_IDX contains the index into ARGS of the low part of the
1010 address; the high part of the address is at ADDR_LOW_IDX+1.
1012 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1014 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1015 This should be offsetof addr_read or addr_write.
1018 LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
1019 positions of the displacements of forward jumps to the TLB miss case.
1021 First argument register is loaded with the low part of the address.
1022 In the TLB hit case, it has been adjusted as indicated by the TLB
1023 and so is a host address. In the TLB miss case, it continues to
1024 hold a guest address.
1026 Second argument register is clobbered. */
1028 static inline void tcg_out_tlb_load(TCGContext
*s
, int addrlo_idx
,
1029 int mem_index
, int s_bits
,
1031 uint8_t **label_ptr
, int which
)
1033 const int addrlo
= args
[addrlo_idx
];
1034 const int r0
= tcg_target_call_iarg_regs
[0];
1035 const int r1
= tcg_target_call_iarg_regs
[1];
1036 TCGType type
= TCG_TYPE_I32
;
1039 if (TCG_TARGET_REG_BITS
== 64 && TARGET_LONG_BITS
== 64) {
1040 type
= TCG_TYPE_I64
;
1044 tcg_out_mov(s
, type
, r1
, addrlo
);
1045 tcg_out_mov(s
, type
, r0
, addrlo
);
1047 tcg_out_shifti(s
, SHIFT_SHR
+ rexw
, r1
,
1048 TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1050 tgen_arithi(s
, ARITH_AND
+ rexw
, r0
,
1051 TARGET_PAGE_MASK
| ((1 << s_bits
) - 1), 0);
1052 tgen_arithi(s
, ARITH_AND
+ rexw
, r1
,
1053 (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
, 0);
1055 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ P_REXW
, r1
, TCG_AREG0
, r1
, 0,
1056 offsetof(CPUArchState
, tlb_table
[mem_index
][0])
1060 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
+ rexw
, r0
, r1
, 0);
1062 tcg_out_mov(s
, type
, r0
, addrlo
);
1065 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1066 label_ptr
[0] = s
->code_ptr
;
1069 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1070 /* cmp 4(r1), addrhi */
1071 tcg_out_modrm_offset(s
, OPC_CMP_GvEv
, args
[addrlo_idx
+1], r1
, 4);
1074 tcg_out8(s
, OPC_JCC_short
+ JCC_JNE
);
1075 label_ptr
[1] = s
->code_ptr
;
1081 /* add addend(r1), r0 */
1082 tcg_out_modrm_offset(s
, OPC_ADD_GvEv
+ P_REXW
, r0
, r1
,
1083 offsetof(CPUTLBEntry
, addend
) - which
);
1087 static void tcg_out_qemu_ld_direct(TCGContext
*s
, int datalo
, int datahi
,
1088 int base
, tcg_target_long ofs
, int sizeop
)
1090 #ifdef TARGET_WORDS_BIGENDIAN
1091 const int bswap
= 1;
1093 const int bswap
= 0;
1097 tcg_out_modrm_offset(s
, OPC_MOVZBL
, datalo
, base
, ofs
);
1100 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ P_REXW
, datalo
, base
, ofs
);
1103 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1105 tcg_out_rolw_8(s
, datalo
);
1110 tcg_out_modrm_offset(s
, OPC_MOVZWL
, datalo
, base
, ofs
);
1111 tcg_out_rolw_8(s
, datalo
);
1112 tcg_out_modrm(s
, OPC_MOVSWL
+ P_REXW
, datalo
, datalo
);
1114 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ P_REXW
, datalo
, base
, ofs
);
1118 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1120 tcg_out_bswap32(s
, datalo
);
1123 #if TCG_TARGET_REG_BITS == 64
1126 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1127 tcg_out_bswap32(s
, datalo
);
1128 tcg_out_ext32s(s
, datalo
, datalo
);
1130 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, datalo
, base
, ofs
);
1135 if (TCG_TARGET_REG_BITS
== 64) {
1136 tcg_out_ld(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1138 tcg_out_bswap64(s
, datalo
);
1146 if (base
!= datalo
) {
1147 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1148 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1150 tcg_out_ld(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1151 tcg_out_ld(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1154 tcg_out_bswap32(s
, datalo
);
1155 tcg_out_bswap32(s
, datahi
);
1164 /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
1165 EAX. It will be useful once fixed registers globals are less
1167 static void tcg_out_qemu_ld(TCGContext
*s
, const TCGArg
*args
,
1170 int data_reg
, data_reg2
= 0;
1172 #if defined(CONFIG_SOFTMMU)
1173 int mem_index
, s_bits
;
1174 #if TCG_TARGET_REG_BITS == 64
1179 uint8_t *label_ptr
[3];
1184 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1185 data_reg2
= args
[1];
1189 #if defined(CONFIG_SOFTMMU)
1190 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1193 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1194 label_ptr
, offsetof(CPUTLBEntry
, addr_read
));
1197 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
,
1198 tcg_target_call_iarg_regs
[0], 0, opc
);
1201 tcg_out8(s
, OPC_JMP_short
);
1202 label_ptr
[2] = s
->code_ptr
;
1208 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1209 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1210 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1213 /* XXX: move that code at the end of the TB */
1214 #if TCG_TARGET_REG_BITS == 32
1215 tcg_out_pushi(s
, mem_index
);
1217 if (TARGET_LONG_BITS
== 64) {
1218 tcg_out_push(s
, args
[addrlo_idx
+ 1]);
1221 tcg_out_push(s
, args
[addrlo_idx
]);
1223 #ifdef CONFIG_TCG_PASS_AREG0
1224 tcg_out_push(s
, TCG_AREG0
);
1228 /* The first argument is already loaded with addrlo. */
1230 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[arg_idx
],
1232 #ifdef CONFIG_TCG_PASS_AREG0
1233 /* XXX/FIXME: suboptimal */
1234 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[3],
1235 tcg_target_call_iarg_regs
[2]);
1236 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[2],
1237 tcg_target_call_iarg_regs
[1]);
1238 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[1],
1239 tcg_target_call_iarg_regs
[0]);
1240 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0],
1245 tcg_out_calli(s
, (tcg_target_long
)qemu_ld_helpers
[s_bits
]);
1247 #if TCG_TARGET_REG_BITS == 32
1248 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1249 /* Pop and discard. This is 2 bytes smaller than the add. */
1250 tcg_out_pop(s
, TCG_REG_ECX
);
1251 } else if (stack_adjust
!= 0) {
1252 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1258 tcg_out_ext8s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1261 tcg_out_ext16s(s
, data_reg
, TCG_REG_EAX
, P_REXW
);
1264 tcg_out_ext8u(s
, data_reg
, TCG_REG_EAX
);
1267 tcg_out_ext16u(s
, data_reg
, TCG_REG_EAX
);
1270 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1272 #if TCG_TARGET_REG_BITS == 64
1274 tcg_out_ext32s(s
, data_reg
, TCG_REG_EAX
);
1278 if (TCG_TARGET_REG_BITS
== 64) {
1279 tcg_out_mov(s
, TCG_TYPE_I64
, data_reg
, TCG_REG_RAX
);
1280 } else if (data_reg
== TCG_REG_EDX
) {
1281 /* xchg %edx, %eax */
1282 tcg_out_opc(s
, OPC_XCHG_ax_r32
+ TCG_REG_EDX
, 0, 0, 0);
1283 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EAX
);
1285 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg
, TCG_REG_EAX
);
1286 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_EDX
);
1294 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1297 int32_t offset
= GUEST_BASE
;
1298 int base
= args
[addrlo_idx
];
1300 if (TCG_TARGET_REG_BITS
== 64) {
1301 /* ??? We assume all operations have left us with register
1302 contents that are zero extended. So far this appears to
1303 be true. If we want to enforce this, we can either do
1304 an explicit zero-extension here, or (if GUEST_BASE == 0)
1305 use the ADDR32 prefix. For now, do nothing. */
1307 if (offset
!= GUEST_BASE
) {
1308 tcg_out_movi(s
, TCG_TYPE_I64
,
1309 tcg_target_call_iarg_regs
[0], GUEST_BASE
);
1310 tgen_arithr(s
, ARITH_ADD
+ P_REXW
,
1311 tcg_target_call_iarg_regs
[0], base
);
1312 base
= tcg_target_call_iarg_regs
[0];
1317 tcg_out_qemu_ld_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1322 static void tcg_out_qemu_st_direct(TCGContext
*s
, int datalo
, int datahi
,
1323 int base
, tcg_target_long ofs
, int sizeop
)
1325 #ifdef TARGET_WORDS_BIGENDIAN
1326 const int bswap
= 1;
1328 const int bswap
= 0;
1330 /* ??? Ideally we wouldn't need a scratch register. For user-only,
1331 we could perform the bswap twice to restore the original value
1332 instead of moving to the scratch. But as it is, the L constraint
1333 means that the second argument reg is definitely free here. */
1334 int scratch
= tcg_target_call_iarg_regs
[1];
1338 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
+ P_REXB_R
, datalo
, base
, ofs
);
1342 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1343 tcg_out_rolw_8(s
, scratch
);
1346 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
+ P_DATA16
, datalo
, base
, ofs
);
1350 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1351 tcg_out_bswap32(s
, scratch
);
1354 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1357 if (TCG_TARGET_REG_BITS
== 64) {
1359 tcg_out_mov(s
, TCG_TYPE_I64
, scratch
, datalo
);
1360 tcg_out_bswap64(s
, scratch
);
1363 tcg_out_st(s
, TCG_TYPE_I64
, datalo
, base
, ofs
);
1365 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datahi
);
1366 tcg_out_bswap32(s
, scratch
);
1367 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
);
1368 tcg_out_mov(s
, TCG_TYPE_I32
, scratch
, datalo
);
1369 tcg_out_bswap32(s
, scratch
);
1370 tcg_out_st(s
, TCG_TYPE_I32
, scratch
, base
, ofs
+ 4);
1372 tcg_out_st(s
, TCG_TYPE_I32
, datalo
, base
, ofs
);
1373 tcg_out_st(s
, TCG_TYPE_I32
, datahi
, base
, ofs
+ 4);
1381 static void tcg_out_qemu_st(TCGContext
*s
, const TCGArg
*args
,
1384 int data_reg
, data_reg2
= 0;
1386 #if defined(CONFIG_SOFTMMU)
1387 int mem_index
, s_bits
;
1389 uint8_t *label_ptr
[3];
1394 if (TCG_TARGET_REG_BITS
== 32 && opc
== 3) {
1395 data_reg2
= args
[1];
1399 #if defined(CONFIG_SOFTMMU)
1400 mem_index
= args
[addrlo_idx
+ 1 + (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
)];
1403 tcg_out_tlb_load(s
, addrlo_idx
, mem_index
, s_bits
, args
,
1404 label_ptr
, offsetof(CPUTLBEntry
, addr_write
));
1407 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
,
1408 tcg_target_call_iarg_regs
[0], 0, opc
);
1411 tcg_out8(s
, OPC_JMP_short
);
1412 label_ptr
[2] = s
->code_ptr
;
1418 *label_ptr
[0] = s
->code_ptr
- label_ptr
[0] - 1;
1419 if (TARGET_LONG_BITS
> TCG_TARGET_REG_BITS
) {
1420 *label_ptr
[1] = s
->code_ptr
- label_ptr
[1] - 1;
1423 /* XXX: move that code at the end of the TB */
1424 #if TCG_TARGET_REG_BITS == 32
1425 tcg_out_pushi(s
, mem_index
);
1428 tcg_out_push(s
, data_reg2
);
1431 tcg_out_push(s
, data_reg
);
1433 if (TARGET_LONG_BITS
== 64) {
1434 tcg_out_push(s
, args
[addrlo_idx
+ 1]);
1437 tcg_out_push(s
, args
[addrlo_idx
]);
1439 #ifdef CONFIG_TCG_PASS_AREG0
1440 tcg_out_push(s
, TCG_AREG0
);
1444 tcg_out_mov(s
, (opc
== 3 ? TCG_TYPE_I64
: TCG_TYPE_I32
),
1445 tcg_target_call_iarg_regs
[1], data_reg
);
1446 tcg_out_movi(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[2], mem_index
);
1448 #ifdef CONFIG_TCG_PASS_AREG0
1449 /* XXX/FIXME: suboptimal */
1450 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[3],
1451 tcg_target_call_iarg_regs
[2]);
1452 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[2],
1453 tcg_target_call_iarg_regs
[1]);
1454 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[1],
1455 tcg_target_call_iarg_regs
[0]);
1456 tcg_out_mov(s
, TCG_TYPE_I64
, tcg_target_call_iarg_regs
[0],
1461 tcg_out_calli(s
, (tcg_target_long
)qemu_st_helpers
[s_bits
]);
1463 if (stack_adjust
== (TCG_TARGET_REG_BITS
/ 8)) {
1464 /* Pop and discard. This is 2 bytes smaller than the add. */
1465 tcg_out_pop(s
, TCG_REG_ECX
);
1466 } else if (stack_adjust
!= 0) {
1467 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_adjust
);
1471 *label_ptr
[2] = s
->code_ptr
- label_ptr
[2] - 1;
1474 int32_t offset
= GUEST_BASE
;
1475 int base
= args
[addrlo_idx
];
1477 if (TCG_TARGET_REG_BITS
== 64) {
1478 /* ??? We assume all operations have left us with register
1479 contents that are zero extended. So far this appears to
1480 be true. If we want to enforce this, we can either do
1481 an explicit zero-extension here, or (if GUEST_BASE == 0)
1482 use the ADDR32 prefix. For now, do nothing. */
1484 if (offset
!= GUEST_BASE
) {
1485 tcg_out_movi(s
, TCG_TYPE_I64
,
1486 tcg_target_call_iarg_regs
[0], GUEST_BASE
);
1487 tgen_arithr(s
, ARITH_ADD
+ P_REXW
,
1488 tcg_target_call_iarg_regs
[0], base
);
1489 base
= tcg_target_call_iarg_regs
[0];
1494 tcg_out_qemu_st_direct(s
, data_reg
, data_reg2
, base
, offset
, opc
);
1499 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1500 const TCGArg
*args
, const int *const_args
)
1504 #if TCG_TARGET_REG_BITS == 64
1505 # define OP_32_64(x) \
1506 case glue(glue(INDEX_op_, x), _i64): \
1507 rexw = P_REXW; /* FALLTHRU */ \
1508 case glue(glue(INDEX_op_, x), _i32)
1510 # define OP_32_64(x) \
1511 case glue(glue(INDEX_op_, x), _i32)
1515 case INDEX_op_exit_tb
:
1516 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_EAX
, args
[0]);
1517 tcg_out_jmp(s
, (tcg_target_long
) tb_ret_addr
);
1519 case INDEX_op_goto_tb
:
1520 if (s
->tb_jmp_offset
) {
1521 /* direct jump method */
1522 tcg_out8(s
, OPC_JMP_long
); /* jmp im */
1523 s
->tb_jmp_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1526 /* indirect jump method */
1527 tcg_out_modrm_offset(s
, OPC_GRP5
, EXT5_JMPN_Ev
, -1,
1528 (tcg_target_long
)(s
->tb_next
+ args
[0]));
1530 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1533 if (const_args
[0]) {
1534 tcg_out_calli(s
, args
[0]);
1537 tcg_out_modrm(s
, OPC_GRP5
, EXT5_CALLN_Ev
, args
[0]);
1541 if (const_args
[0]) {
1542 tcg_out_jmp(s
, args
[0]);
1545 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, args
[0]);
1549 tcg_out_jxx(s
, JCC_JMP
, args
[0], 0);
1551 case INDEX_op_movi_i32
:
1552 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1555 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1556 tcg_out_modrm_offset(s
, OPC_MOVZBL
, args
[0], args
[1], args
[2]);
1559 tcg_out_modrm_offset(s
, OPC_MOVSBL
+ rexw
, args
[0], args
[1], args
[2]);
1562 /* Note that we can ignore REXW for the zero-extend to 64-bit. */
1563 tcg_out_modrm_offset(s
, OPC_MOVZWL
, args
[0], args
[1], args
[2]);
1566 tcg_out_modrm_offset(s
, OPC_MOVSWL
+ rexw
, args
[0], args
[1], args
[2]);
1568 #if TCG_TARGET_REG_BITS == 64
1569 case INDEX_op_ld32u_i64
:
1571 case INDEX_op_ld_i32
:
1572 tcg_out_ld(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1576 tcg_out_modrm_offset(s
, OPC_MOVB_EvGv
| P_REXB_R
,
1577 args
[0], args
[1], args
[2]);
1580 tcg_out_modrm_offset(s
, OPC_MOVL_EvGv
| P_DATA16
,
1581 args
[0], args
[1], args
[2]);
1583 #if TCG_TARGET_REG_BITS == 64
1584 case INDEX_op_st32_i64
:
1586 case INDEX_op_st_i32
:
1587 tcg_out_st(s
, TCG_TYPE_I32
, args
[0], args
[1], args
[2]);
1591 /* For 3-operand addition, use LEA. */
1592 if (args
[0] != args
[1]) {
1593 TCGArg a0
= args
[0], a1
= args
[1], a2
= args
[2], c3
= 0;
1595 if (const_args
[2]) {
1597 } else if (a0
== a2
) {
1598 /* Watch out for dest = src + dest, since we've removed
1599 the matching constraint on the add. */
1600 tgen_arithr(s
, ARITH_ADD
+ rexw
, a0
, a1
);
1604 tcg_out_modrm_sib_offset(s
, OPC_LEA
+ rexw
, a0
, a1
, a2
, 0, c3
);
1622 if (const_args
[2]) {
1623 tgen_arithi(s
, c
+ rexw
, args
[0], args
[2], 0);
1625 tgen_arithr(s
, c
+ rexw
, args
[0], args
[2]);
1630 if (const_args
[2]) {
1633 if (val
== (int8_t)val
) {
1634 tcg_out_modrm(s
, OPC_IMUL_GvEvIb
+ rexw
, args
[0], args
[0]);
1637 tcg_out_modrm(s
, OPC_IMUL_GvEvIz
+ rexw
, args
[0], args
[0]);
1641 tcg_out_modrm(s
, OPC_IMUL_GvEv
+ rexw
, args
[0], args
[2]);
1646 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_IDIV
, args
[4]);
1649 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_DIV
, args
[4]);
1668 if (const_args
[2]) {
1669 tcg_out_shifti(s
, c
+ rexw
, args
[0], args
[2]);
1671 tcg_out_modrm(s
, OPC_SHIFT_cl
+ rexw
, c
, args
[0]);
1675 case INDEX_op_brcond_i32
:
1676 tcg_out_brcond32(s
, args
[2], args
[0], args
[1], const_args
[1],
1679 case INDEX_op_setcond_i32
:
1680 tcg_out_setcond32(s
, args
[3], args
[0], args
[1],
1681 args
[2], const_args
[2]);
1685 tcg_out_rolw_8(s
, args
[0]);
1688 tcg_out_bswap32(s
, args
[0]);
1692 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NEG
, args
[0]);
1695 tcg_out_modrm(s
, OPC_GRP3_Ev
+ rexw
, EXT3_NOT
, args
[0]);
1699 tcg_out_ext8s(s
, args
[0], args
[1], rexw
);
1702 tcg_out_ext16s(s
, args
[0], args
[1], rexw
);
1705 tcg_out_ext8u(s
, args
[0], args
[1]);
1708 tcg_out_ext16u(s
, args
[0], args
[1]);
1711 case INDEX_op_qemu_ld8u
:
1712 tcg_out_qemu_ld(s
, args
, 0);
1714 case INDEX_op_qemu_ld8s
:
1715 tcg_out_qemu_ld(s
, args
, 0 | 4);
1717 case INDEX_op_qemu_ld16u
:
1718 tcg_out_qemu_ld(s
, args
, 1);
1720 case INDEX_op_qemu_ld16s
:
1721 tcg_out_qemu_ld(s
, args
, 1 | 4);
1723 #if TCG_TARGET_REG_BITS == 64
1724 case INDEX_op_qemu_ld32u
:
1726 case INDEX_op_qemu_ld32
:
1727 tcg_out_qemu_ld(s
, args
, 2);
1729 case INDEX_op_qemu_ld64
:
1730 tcg_out_qemu_ld(s
, args
, 3);
1733 case INDEX_op_qemu_st8
:
1734 tcg_out_qemu_st(s
, args
, 0);
1736 case INDEX_op_qemu_st16
:
1737 tcg_out_qemu_st(s
, args
, 1);
1739 case INDEX_op_qemu_st32
:
1740 tcg_out_qemu_st(s
, args
, 2);
1742 case INDEX_op_qemu_st64
:
1743 tcg_out_qemu_st(s
, args
, 3);
1746 #if TCG_TARGET_REG_BITS == 32
1747 case INDEX_op_brcond2_i32
:
1748 tcg_out_brcond2(s
, args
, const_args
, 0);
1750 case INDEX_op_setcond2_i32
:
1751 tcg_out_setcond2(s
, args
, const_args
);
1753 case INDEX_op_mulu2_i32
:
1754 tcg_out_modrm(s
, OPC_GRP3_Ev
, EXT3_MUL
, args
[3]);
1756 case INDEX_op_add2_i32
:
1757 if (const_args
[4]) {
1758 tgen_arithi(s
, ARITH_ADD
, args
[0], args
[4], 1);
1760 tgen_arithr(s
, ARITH_ADD
, args
[0], args
[4]);
1762 if (const_args
[5]) {
1763 tgen_arithi(s
, ARITH_ADC
, args
[1], args
[5], 1);
1765 tgen_arithr(s
, ARITH_ADC
, args
[1], args
[5]);
1768 case INDEX_op_sub2_i32
:
1769 if (const_args
[4]) {
1770 tgen_arithi(s
, ARITH_SUB
, args
[0], args
[4], 1);
1772 tgen_arithr(s
, ARITH_SUB
, args
[0], args
[4]);
1774 if (const_args
[5]) {
1775 tgen_arithi(s
, ARITH_SBB
, args
[1], args
[5], 1);
1777 tgen_arithr(s
, ARITH_SBB
, args
[1], args
[5]);
1780 #else /* TCG_TARGET_REG_BITS == 64 */
1781 case INDEX_op_movi_i64
:
1782 tcg_out_movi(s
, TCG_TYPE_I64
, args
[0], args
[1]);
1784 case INDEX_op_ld32s_i64
:
1785 tcg_out_modrm_offset(s
, OPC_MOVSLQ
, args
[0], args
[1], args
[2]);
1787 case INDEX_op_ld_i64
:
1788 tcg_out_ld(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1790 case INDEX_op_st_i64
:
1791 tcg_out_st(s
, TCG_TYPE_I64
, args
[0], args
[1], args
[2]);
1793 case INDEX_op_qemu_ld32s
:
1794 tcg_out_qemu_ld(s
, args
, 2 | 4);
1797 case INDEX_op_brcond_i64
:
1798 tcg_out_brcond64(s
, args
[2], args
[0], args
[1], const_args
[1],
1801 case INDEX_op_setcond_i64
:
1802 tcg_out_setcond64(s
, args
[3], args
[0], args
[1],
1803 args
[2], const_args
[2]);
1806 case INDEX_op_bswap64_i64
:
1807 tcg_out_bswap64(s
, args
[0]);
1809 case INDEX_op_ext32u_i64
:
1810 tcg_out_ext32u(s
, args
[0], args
[1]);
1812 case INDEX_op_ext32s_i64
:
1813 tcg_out_ext32s(s
, args
[0], args
[1]);
1818 if (args
[3] == 0 && args
[4] == 8) {
1819 /* load bits 0..7 */
1820 tcg_out_modrm(s
, OPC_MOVB_EvGv
| P_REXB_R
| P_REXB_RM
,
1822 } else if (args
[3] == 8 && args
[4] == 8) {
1823 /* load bits 8..15 */
1824 tcg_out_modrm(s
, OPC_MOVB_EvGv
, args
[2], args
[0] + 4);
1825 } else if (args
[3] == 0 && args
[4] == 16) {
1826 /* load bits 0..15 */
1827 tcg_out_modrm(s
, OPC_MOVL_EvGv
| P_DATA16
, args
[2], args
[0]);
1840 static const TCGTargetOpDef x86_op_defs
[] = {
1841 { INDEX_op_exit_tb
, { } },
1842 { INDEX_op_goto_tb
, { } },
1843 { INDEX_op_call
, { "ri" } },
1844 { INDEX_op_jmp
, { "ri" } },
1845 { INDEX_op_br
, { } },
1846 { INDEX_op_mov_i32
, { "r", "r" } },
1847 { INDEX_op_movi_i32
, { "r" } },
1848 { INDEX_op_ld8u_i32
, { "r", "r" } },
1849 { INDEX_op_ld8s_i32
, { "r", "r" } },
1850 { INDEX_op_ld16u_i32
, { "r", "r" } },
1851 { INDEX_op_ld16s_i32
, { "r", "r" } },
1852 { INDEX_op_ld_i32
, { "r", "r" } },
1853 { INDEX_op_st8_i32
, { "q", "r" } },
1854 { INDEX_op_st16_i32
, { "r", "r" } },
1855 { INDEX_op_st_i32
, { "r", "r" } },
1857 { INDEX_op_add_i32
, { "r", "r", "ri" } },
1858 { INDEX_op_sub_i32
, { "r", "0", "ri" } },
1859 { INDEX_op_mul_i32
, { "r", "0", "ri" } },
1860 { INDEX_op_div2_i32
, { "a", "d", "0", "1", "r" } },
1861 { INDEX_op_divu2_i32
, { "a", "d", "0", "1", "r" } },
1862 { INDEX_op_and_i32
, { "r", "0", "ri" } },
1863 { INDEX_op_or_i32
, { "r", "0", "ri" } },
1864 { INDEX_op_xor_i32
, { "r", "0", "ri" } },
1866 { INDEX_op_shl_i32
, { "r", "0", "ci" } },
1867 { INDEX_op_shr_i32
, { "r", "0", "ci" } },
1868 { INDEX_op_sar_i32
, { "r", "0", "ci" } },
1869 { INDEX_op_rotl_i32
, { "r", "0", "ci" } },
1870 { INDEX_op_rotr_i32
, { "r", "0", "ci" } },
1872 { INDEX_op_brcond_i32
, { "r", "ri" } },
1874 { INDEX_op_bswap16_i32
, { "r", "0" } },
1875 { INDEX_op_bswap32_i32
, { "r", "0" } },
1877 { INDEX_op_neg_i32
, { "r", "0" } },
1879 { INDEX_op_not_i32
, { "r", "0" } },
1881 { INDEX_op_ext8s_i32
, { "r", "q" } },
1882 { INDEX_op_ext16s_i32
, { "r", "r" } },
1883 { INDEX_op_ext8u_i32
, { "r", "q" } },
1884 { INDEX_op_ext16u_i32
, { "r", "r" } },
1886 { INDEX_op_setcond_i32
, { "q", "r", "ri" } },
1888 { INDEX_op_deposit_i32
, { "Q", "0", "Q" } },
1890 #if TCG_TARGET_REG_BITS == 32
1891 { INDEX_op_mulu2_i32
, { "a", "d", "a", "r" } },
1892 { INDEX_op_add2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1893 { INDEX_op_sub2_i32
, { "r", "r", "0", "1", "ri", "ri" } },
1894 { INDEX_op_brcond2_i32
, { "r", "r", "ri", "ri" } },
1895 { INDEX_op_setcond2_i32
, { "r", "r", "r", "ri", "ri" } },
1897 { INDEX_op_mov_i64
, { "r", "r" } },
1898 { INDEX_op_movi_i64
, { "r" } },
1899 { INDEX_op_ld8u_i64
, { "r", "r" } },
1900 { INDEX_op_ld8s_i64
, { "r", "r" } },
1901 { INDEX_op_ld16u_i64
, { "r", "r" } },
1902 { INDEX_op_ld16s_i64
, { "r", "r" } },
1903 { INDEX_op_ld32u_i64
, { "r", "r" } },
1904 { INDEX_op_ld32s_i64
, { "r", "r" } },
1905 { INDEX_op_ld_i64
, { "r", "r" } },
1906 { INDEX_op_st8_i64
, { "r", "r" } },
1907 { INDEX_op_st16_i64
, { "r", "r" } },
1908 { INDEX_op_st32_i64
, { "r", "r" } },
1909 { INDEX_op_st_i64
, { "r", "r" } },
1911 { INDEX_op_add_i64
, { "r", "0", "re" } },
1912 { INDEX_op_mul_i64
, { "r", "0", "re" } },
1913 { INDEX_op_div2_i64
, { "a", "d", "0", "1", "r" } },
1914 { INDEX_op_divu2_i64
, { "a", "d", "0", "1", "r" } },
1915 { INDEX_op_sub_i64
, { "r", "0", "re" } },
1916 { INDEX_op_and_i64
, { "r", "0", "reZ" } },
1917 { INDEX_op_or_i64
, { "r", "0", "re" } },
1918 { INDEX_op_xor_i64
, { "r", "0", "re" } },
1920 { INDEX_op_shl_i64
, { "r", "0", "ci" } },
1921 { INDEX_op_shr_i64
, { "r", "0", "ci" } },
1922 { INDEX_op_sar_i64
, { "r", "0", "ci" } },
1923 { INDEX_op_rotl_i64
, { "r", "0", "ci" } },
1924 { INDEX_op_rotr_i64
, { "r", "0", "ci" } },
1926 { INDEX_op_brcond_i64
, { "r", "re" } },
1927 { INDEX_op_setcond_i64
, { "r", "r", "re" } },
1929 { INDEX_op_bswap16_i64
, { "r", "0" } },
1930 { INDEX_op_bswap32_i64
, { "r", "0" } },
1931 { INDEX_op_bswap64_i64
, { "r", "0" } },
1932 { INDEX_op_neg_i64
, { "r", "0" } },
1933 { INDEX_op_not_i64
, { "r", "0" } },
1935 { INDEX_op_ext8s_i64
, { "r", "r" } },
1936 { INDEX_op_ext16s_i64
, { "r", "r" } },
1937 { INDEX_op_ext32s_i64
, { "r", "r" } },
1938 { INDEX_op_ext8u_i64
, { "r", "r" } },
1939 { INDEX_op_ext16u_i64
, { "r", "r" } },
1940 { INDEX_op_ext32u_i64
, { "r", "r" } },
1942 { INDEX_op_deposit_i64
, { "Q", "0", "Q" } },
1945 #if TCG_TARGET_REG_BITS == 64
1946 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1947 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1948 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1949 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1950 { INDEX_op_qemu_ld32
, { "r", "L" } },
1951 { INDEX_op_qemu_ld32u
, { "r", "L" } },
1952 { INDEX_op_qemu_ld32s
, { "r", "L" } },
1953 { INDEX_op_qemu_ld64
, { "r", "L" } },
1955 { INDEX_op_qemu_st8
, { "L", "L" } },
1956 { INDEX_op_qemu_st16
, { "L", "L" } },
1957 { INDEX_op_qemu_st32
, { "L", "L" } },
1958 { INDEX_op_qemu_st64
, { "L", "L" } },
1959 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1960 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1961 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1962 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1963 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1964 { INDEX_op_qemu_ld32
, { "r", "L" } },
1965 { INDEX_op_qemu_ld64
, { "r", "r", "L" } },
1967 { INDEX_op_qemu_st8
, { "cb", "L" } },
1968 { INDEX_op_qemu_st16
, { "L", "L" } },
1969 { INDEX_op_qemu_st32
, { "L", "L" } },
1970 { INDEX_op_qemu_st64
, { "L", "L", "L" } },
1972 { INDEX_op_qemu_ld8u
, { "r", "L", "L" } },
1973 { INDEX_op_qemu_ld8s
, { "r", "L", "L" } },
1974 { INDEX_op_qemu_ld16u
, { "r", "L", "L" } },
1975 { INDEX_op_qemu_ld16s
, { "r", "L", "L" } },
1976 { INDEX_op_qemu_ld32
, { "r", "L", "L" } },
1977 { INDEX_op_qemu_ld64
, { "r", "r", "L", "L" } },
1979 { INDEX_op_qemu_st8
, { "cb", "L", "L" } },
1980 { INDEX_op_qemu_st16
, { "L", "L", "L" } },
1981 { INDEX_op_qemu_st32
, { "L", "L", "L" } },
1982 { INDEX_op_qemu_st64
, { "L", "L", "L", "L" } },
1987 static int tcg_target_callee_save_regs
[] = {
1988 #if TCG_TARGET_REG_BITS == 64
1997 TCG_REG_R14
, /* Currently used for the global env. */
2000 TCG_REG_EBP
, /* Currently used for the global env. */
2007 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
2008 and tcg_register_jit. */
2011 ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
2012 * (TCG_TARGET_REG_BITS / 8))
2014 #define FRAME_SIZE \
2016 + TCG_STATIC_CALL_ARGS_SIZE \
2017 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2018 + TCG_TARGET_STACK_ALIGN - 1) \
2019 & ~(TCG_TARGET_STACK_ALIGN - 1))
2021 /* Generate global QEMU prologue and epilogue code */
2022 static void tcg_target_qemu_prologue(TCGContext
*s
)
2024 int i
, stack_addend
;
2028 /* Reserve some stack space, also for TCG temps. */
2029 stack_addend
= FRAME_SIZE
- PUSH_SIZE
;
2030 tcg_set_frame(s
, TCG_REG_CALL_STACK
, TCG_STATIC_CALL_ARGS_SIZE
,
2031 CPU_TEMP_BUF_NLONGS
* sizeof(long));
2033 /* Save all callee saved registers. */
2034 for (i
= 0; i
< ARRAY_SIZE(tcg_target_callee_save_regs
); i
++) {
2035 tcg_out_push(s
, tcg_target_callee_save_regs
[i
]);
2038 #if TCG_TARGET_REG_BITS == 32
2039 tcg_out_ld(s
, TCG_TYPE_PTR
, TCG_AREG0
, TCG_REG_ESP
,
2040 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 1) * 4);
2041 tcg_out_ld(s
, TCG_TYPE_PTR
, tcg_target_call_iarg_regs
[1], TCG_REG_ESP
,
2042 (ARRAY_SIZE(tcg_target_callee_save_regs
) + 2) * 4);
2044 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
2046 tcg_out_addi(s
, TCG_REG_ESP
, -stack_addend
);
2049 tcg_out_modrm(s
, OPC_GRP5
, EXT5_JMPN_Ev
, tcg_target_call_iarg_regs
[1]);
2052 tb_ret_addr
= s
->code_ptr
;
2054 tcg_out_addi(s
, TCG_REG_CALL_STACK
, stack_addend
);
2056 for (i
= ARRAY_SIZE(tcg_target_callee_save_regs
) - 1; i
>= 0; i
--) {
2057 tcg_out_pop(s
, tcg_target_callee_save_regs
[i
]);
2059 tcg_out_opc(s
, OPC_RET
, 0, 0, 0);
2062 static void tcg_target_init(TCGContext
*s
)
2064 #if !defined(CONFIG_USER_ONLY)
2066 if ((1 << CPU_TLB_ENTRY_BITS
) != sizeof(CPUTLBEntry
))
2070 if (TCG_TARGET_REG_BITS
== 64) {
2071 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffff);
2072 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffff);
2074 tcg_regset_set32(tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xff);
2077 tcg_regset_clear(tcg_target_call_clobber_regs
);
2078 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EAX
);
2079 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_EDX
);
2080 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_ECX
);
2081 if (TCG_TARGET_REG_BITS
== 64) {
2082 #if !defined(_WIN64)
2083 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RDI
);
2084 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_RSI
);
2086 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R8
);
2087 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R9
);
2088 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R10
);
2089 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_R11
);
2092 tcg_regset_clear(s
->reserved_regs
);
2093 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_CALL_STACK
);
2095 tcg_add_target_add_op_defs(x86_op_defs
);
2099 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2102 char augmentation
[1];
2105 uint8_t return_column
;
2109 uint32_t len
__attribute__((aligned((sizeof(void *)))));
2110 uint32_t cie_offset
;
2111 tcg_target_long func_start
__attribute__((packed
));
2112 tcg_target_long func_len
__attribute__((packed
));
2114 uint8_t reg_ofs
[14];
2122 #if !defined(__ELF__)
2123 /* Host machine without ELF. */
2124 #elif TCG_TARGET_REG_BITS == 64
2125 #define ELF_HOST_MACHINE EM_X86_64
2126 static DebugFrame debug_frame
= {
2127 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2130 .cie
.code_align
= 1,
2131 .cie
.data_align
= 0x78, /* sleb128 -8 */
2132 .cie
.return_column
= 16,
2134 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2136 12, 7, /* DW_CFA_def_cfa %rsp, ... */
2137 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2141 0x90, 1, /* DW_CFA_offset, %rip, -8 */
2142 /* The following ordering must match tcg_target_callee_save_regs. */
2143 0x86, 2, /* DW_CFA_offset, %rbp, -16 */
2144 0x83, 3, /* DW_CFA_offset, %rbx, -24 */
2145 0x8c, 4, /* DW_CFA_offset, %r12, -32 */
2146 0x8d, 5, /* DW_CFA_offset, %r13, -40 */
2147 0x8e, 6, /* DW_CFA_offset, %r14, -48 */
2148 0x8f, 7, /* DW_CFA_offset, %r15, -56 */
2152 #define ELF_HOST_MACHINE EM_386
2153 static DebugFrame debug_frame
= {
2154 .cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
2157 .cie
.code_align
= 1,
2158 .cie
.data_align
= 0x7c, /* sleb128 -4 */
2159 .cie
.return_column
= 8,
2161 .fde
.len
= sizeof(DebugFrameFDE
)-4, /* length after .len member */
2163 12, 4, /* DW_CFA_def_cfa %esp, ... */
2164 (FRAME_SIZE
& 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2168 0x88, 1, /* DW_CFA_offset, %eip, -4 */
2169 /* The following ordering must match tcg_target_callee_save_regs. */
2170 0x85, 2, /* DW_CFA_offset, %ebp, -8 */
2171 0x83, 3, /* DW_CFA_offset, %ebx, -12 */
2172 0x86, 4, /* DW_CFA_offset, %esi, -16 */
2173 0x87, 5, /* DW_CFA_offset, %edi, -20 */
2178 #if defined(ELF_HOST_MACHINE)
2179 void tcg_register_jit(void *buf
, size_t buf_size
)
2181 /* We're expecting a 2 byte uleb128 encoded value. */
2182 assert(FRAME_SIZE
>> 14 == 0);
2184 debug_frame
.fde
.func_start
= (tcg_target_long
) buf
;
2185 debug_frame
.fde
.func_len
= buf_size
;
2187 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));