tcg-target.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,300 行 · 第 1/3 页
C
1,300 行
} } } else { if (opc == -1) { tcg_out8(s, 0xe9); } else { tcg_out8(s, 0x0f); tcg_out8(s, 0x80 + opc); } tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4); s->code_ptr += 4; }}static void tcg_out_brcond(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, int const_arg2, int label_index, int rexw){ int c; if (const_arg2) { if (arg2 == 0) { /* use test */ switch(cond) { case TCG_COND_EQ: c = JCC_JE; break; case TCG_COND_NE: c = JCC_JNE; break; case TCG_COND_LT: c = JCC_JS; break; case TCG_COND_GE: c = JCC_JNS; break; default: goto do_cmpi; } /* test r, r */ tcg_out_modrm(s, 0x85 | rexw, arg1, arg1); tcg_out_jxx(s, c, label_index); } else { do_cmpi: if (rexw) tgen_arithi64(s, ARITH_CMP, arg1, arg2); else tgen_arithi32(s, ARITH_CMP, arg1, arg2); tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index); } } else { tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3) | rexw, arg2, arg1); tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index); }}#if defined(CONFIG_SOFTMMU)extern void __ldb_mmu(void);extern void __ldw_mmu(void);extern void __ldl_mmu(void);extern void __ldq_mmu(void);extern void __stb_mmu(void);extern void __stw_mmu(void);extern void __stl_mmu(void);extern void __stq_mmu(void);static void *qemu_ld_helpers[4] = { __ldb_mmu, __ldw_mmu, __ldl_mmu, __ldq_mmu,};static void *qemu_st_helpers[4] = { __stb_mmu, __stw_mmu, __stl_mmu, __stq_mmu,};#endifstatic void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc){ int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;#if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr;#endif data_reg = *args++; addr_reg = *args++; mem_index = *args; s_bits = opc & 3; r0 = TCG_REG_RDI; r1 = TCG_REG_RSI;#if TARGET_LONG_BITS == 32 rexw = 0;#else rexw = P_REXW;#endif#if defined(CONFIG_SOFTMMU) /* mov */ tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg); /* mov */ tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */ tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */ tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1)); tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */ tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS); /* lea offset(r1, env), r1 */ tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0, offsetof(CPUState, tlb_table[mem_index][0].addr_read)); /* cmp 0(r1), r0 */ tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0); /* mov */ tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++; /* XXX: move that code at the end of the TB */ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RSI, mem_index); tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); switch(opc) { case 0 | 4: /* movsbq */ tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, data_reg, TCG_REG_RAX); break; case 1 | 4: /* movswq */ tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, data_reg, TCG_REG_RAX); break; case 2 | 4: /* movslq */ tcg_out_modrm(s, 0x63 | P_REXW, data_reg, TCG_REG_RAX); break; case 0: case 1: case 2: default: /* movl */ tcg_out_modrm(s, 0x8b, data_reg, TCG_REG_RAX); break; case 3: tcg_out_mov(s, data_reg, TCG_REG_RAX); break; } /* jmp label2 */ tcg_out8(s, 0xeb); label2_ptr = s->code_ptr; s->code_ptr++; /* label1: */ *label1_ptr = s->code_ptr - label1_ptr - 1; /* add x(r1), r0 */ tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read));#else r0 = addr_reg;#endif #ifdef TARGET_WORDS_BIGENDIAN bswap = 1;#else bswap = 0;#endif switch(opc) { case 0: /* movzbl */ tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0); break; case 0 | 4: /* movsbX */ tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0); break; case 1: /* movzwl */ tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0); if (bswap) { /* rolw $8, data_reg */ tcg_out8(s, 0x66); tcg_out_modrm(s, 0xc1, 0, data_reg); tcg_out8(s, 8); } break; case 1 | 4: if (bswap) { /* movzwl */ tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0); /* rolw $8, data_reg */ tcg_out8(s, 0x66); tcg_out_modrm(s, 0xc1, 0, data_reg); tcg_out8(s, 8); /* movswX data_reg, data_reg */ tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg); } else { /* movswX */ tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0); } break; case 2: /* movl (r0), data_reg */ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0); if (bswap) { /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); } break; case 2 | 4: if (bswap) { /* movl (r0), data_reg */ tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0); /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0); /* movslq */ tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg); } else { /* movslq */ tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0); } break; case 3: /* movq (r0), data_reg */ tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0); if (bswap) { /* bswap */ tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0); } break; default: tcg_abort(); }#if defined(CONFIG_SOFTMMU) /* label2: */ *label2_ptr = s->code_ptr - label2_ptr - 1;#endif}static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc){ int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;#if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr;#endif data_reg = *args++; addr_reg = *args++; mem_index = *args; s_bits = opc; r0 = TCG_REG_RDI; r1 = TCG_REG_RSI;#if TARGET_LONG_BITS == 32 rexw = 0;#else rexw = P_REXW;#endif#if defined(CONFIG_SOFTMMU) /* mov */ tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg); /* mov */ tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */ tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */ tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1)); tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */ tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS); /* lea offset(r1, env), r1 */ tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0, offsetof(CPUState, tlb_table[mem_index][0].addr_write)); /* cmp 0(r1), r0 */ tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0); /* mov */ tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++; /* XXX: move that code at the end of the TB */ switch(opc) { case 0: /* movzbl */ tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg); break; case 1: /* movzwl */ tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_RSI, data_reg); break; case 2: /* movl */ tcg_out_modrm(s, 0x8b, TCG_REG_RSI, data_reg); break; default: case 3: tcg_out_mov(s, TCG_REG_RSI, data_reg); break; } tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index); tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); /* jmp label2 */ tcg_out8(s, 0xeb); label2_ptr = s->code_ptr; s->code_ptr++; /* label1: */ *label1_ptr = s->code_ptr - label1_ptr - 1; /* add x(r1), r0 */ tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write));#else r0 = addr_reg;#endif#ifdef TARGET_WORDS_BIGENDIAN bswap = 1;#else bswap = 0;#endif switch(opc) { case 0: /* movb */ tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0); break; case 1: if (bswap) { tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */ tcg_out8(s, 0x66); /* rolw $8, %ecx */ tcg_out_modrm(s, 0xc1, 0, r1); tcg_out8(s, 8); data_reg = r1; } /* movw */ tcg_out8(s, 0x66); tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0); break; case 2: if (bswap) { tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */ /* bswap data_reg */ tcg_out_opc(s, (0xc8 + r1) | P_EXT, 0, r1, 0); data_reg = r1; } /* movl */ tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0); break; case 3: if (bswap) { tcg_out_mov(s, r1, data_reg); /* bswap data_reg */ tcg_out_opc(s, (0xc8 + r1) | P_EXT | P_REXW, 0, r1, 0); data_reg = r1; } /* movq */ tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0); break; default: tcg_abort(); }#if defined(CONFIG_SOFTMMU) /* label2: */ *label2_ptr = s->code_ptr - label2_ptr - 1;#endif}static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, const int *const_args){ int c; switch(opc) { case INDEX_op_exit_tb: tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, args[0]); tcg_out8(s, 0xe9); /* jmp tb_ret_addr */ tcg_out32(s, tb_ret_addr - s->code_ptr - 4); break; case INDEX_op_goto_tb: if (s->tb_jmp_offset) { /* direct jump method */ tcg_out8(s, 0xe9); /* jmp im */ s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; tcg_out32(s, 0); } else { /* indirect jump method */ /* jmp Ev */ tcg_out_modrm_offset(s, 0xff, 4, -1, (tcg_target_long)(s->tb_next + args[0])); } s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; break; case INDEX_op_call: if (const_args[0]) { tcg_out8(s, 0xe8); tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4); } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?