tcg-target.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,215 行 · 第 1/3 页
C
1,215 行
break; case TCG_COND_LEU: tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]); break; case TCG_COND_GTU: tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]); break; case TCG_COND_GEU: tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]); break; default: tcg_abort(); } tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);}#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,};#endif/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and EAX. It will be useful once fixed registers globals are less common. */static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc){ int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;#if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr;#endif#if TARGET_LONG_BITS == 64#if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr;#endif int addr_reg2;#endif data_reg = *args++; if (opc == 3) data_reg2 = *args++; else data_reg2 = 0; addr_reg = *args++;#if TARGET_LONG_BITS == 64 addr_reg2 = *args++;#endif mem_index = *args; s_bits = opc & 3; r0 = TCG_REG_EAX; r1 = TCG_REG_EDX;#if defined(CONFIG_SOFTMMU) tcg_out_mov(s, r1, addr_reg); tcg_out_mov(s, r0, addr_reg); tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */ tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tcg_out_modrm(s, 0x81, 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); tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */ tcg_out8(s, 0x80 | (r1 << 3) | 0x04); tcg_out8(s, (5 << 3) | r1); tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read)); /* cmp 0(r1), r0 */ tcg_out_modrm_offset(s, 0x3b, r0, r1, 0); tcg_out_mov(s, r0, addr_reg); #if TARGET_LONG_BITS == 32 /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++;#else /* jne label3 */ tcg_out8(s, 0x70 + JCC_JNE); label3_ptr = s->code_ptr; s->code_ptr++; /* cmp 4(r1), addr_reg2 */ tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4); /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++; /* label3: */ *label3_ptr = s->code_ptr - label3_ptr - 1;#endif /* XXX: move that code at the end of the TB */#if TARGET_LONG_BITS == 32 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);#else tcg_out_mov(s, TCG_REG_EDX, addr_reg2); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);#endif 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: /* movsbl */ tcg_out_modrm(s, 0xbe | P_EXT, data_reg, TCG_REG_EAX); break; case 1 | 4: /* movswl */ tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX); break; case 0: case 1: case 2: default: tcg_out_mov(s, data_reg, TCG_REG_EAX); break; case 3: if (data_reg == TCG_REG_EDX) { tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */ tcg_out_mov(s, data_reg2, TCG_REG_EAX); } else { tcg_out_mov(s, data_reg, TCG_REG_EAX); tcg_out_mov(s, data_reg2, TCG_REG_EDX); } 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, 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: /* movsbl */ tcg_out_modrm_offset(s, 0xbe | P_EXT, 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: /* movswl */ tcg_out_modrm_offset(s, 0xbf | 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); /* movswl data_reg, data_reg */ tcg_out_modrm(s, 0xbf | P_EXT, data_reg, data_reg); } 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) | P_EXT); } break; case 3: /* XXX: could be nicer */ if (r0 == data_reg) { r1 = TCG_REG_EDX; if (r1 == data_reg) r1 = TCG_REG_EAX; tcg_out_mov(s, r1, r0); r0 = r1; } if (!bswap) { tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0); tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4); } else { tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4); tcg_out_opc(s, (0xc8 + data_reg) | P_EXT); tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0); /* bswap */ tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT); } 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, data_reg2, r0, r1, mem_index, s_bits, bswap;#if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr;#endif#if TARGET_LONG_BITS == 64#if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr;#endif int addr_reg2;#endif data_reg = *args++; if (opc == 3) data_reg2 = *args++; else data_reg2 = 0; addr_reg = *args++;#if TARGET_LONG_BITS == 64 addr_reg2 = *args++;#endif mem_index = *args; s_bits = opc; r0 = TCG_REG_EAX; r1 = TCG_REG_EDX;#if defined(CONFIG_SOFTMMU) tcg_out_mov(s, r1, addr_reg); tcg_out_mov(s, r0, addr_reg); tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */ tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tcg_out_modrm(s, 0x81, 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); tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */ tcg_out8(s, 0x80 | (r1 << 3) | 0x04); tcg_out8(s, (5 << 3) | r1); tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write)); /* cmp 0(r1), r0 */ tcg_out_modrm_offset(s, 0x3b, r0, r1, 0); tcg_out_mov(s, r0, addr_reg); #if TARGET_LONG_BITS == 32 /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++;#else /* jne label3 */ tcg_out8(s, 0x70 + JCC_JNE); label3_ptr = s->code_ptr; s->code_ptr++; /* cmp 4(r1), addr_reg2 */ tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4); /* je label1 */ tcg_out8(s, 0x70 + JCC_JE); label1_ptr = s->code_ptr; s->code_ptr++; /* label3: */ *label3_ptr = s->code_ptr - label3_ptr - 1;#endif /* XXX: move that code at the end of the TB */#if TARGET_LONG_BITS == 32 if (opc == 3) { tcg_out_mov(s, TCG_REG_EDX, data_reg); tcg_out_mov(s, TCG_REG_ECX, data_reg2); tcg_out8(s, 0x6a); /* push Ib */ tcg_out8(s, mem_index); tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); tcg_out_addi(s, TCG_REG_ESP, 4); } else { switch(opc) { case 0: /* movzbl */ tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_EDX, data_reg); break; case 1: /* movzwl */ tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_EDX, data_reg); break; case 2: tcg_out_mov(s, TCG_REG_EDX, data_reg); break; } tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index); tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); }#else if (opc == 3) { tcg_out_mov(s, TCG_REG_EDX, addr_reg2); tcg_out8(s, 0x6a); /* push Ib */ tcg_out8(s, mem_index); tcg_out_opc(s, 0x50 + data_reg2); /* push */ tcg_out_opc(s, 0x50 + data_reg); /* push */ tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); tcg_out_addi(s, TCG_REG_ESP, 12); } else { tcg_out_mov(s, TCG_REG_EDX, addr_reg2); switch(opc) { case 0: /* movzbl */ tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_ECX, data_reg); break; case 1: /* movzwl */ tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_ECX, data_reg); break; case 2: tcg_out_mov(s, TCG_REG_ECX, data_reg); break; } tcg_out8(s, 0x6a); /* push Ib */ tcg_out8(s, mem_index); tcg_out8(s, 0xe8); tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - (tcg_target_long)s->code_ptr - 4); tcg_out_addi(s, TCG_REG_ESP, 4); }#endif /* jmp label2 */ tcg_out8(s, 0xeb); label2_ptr = s->code_ptr; s->code_ptr++; /* label1: */ *label1_ptr = s->code_ptr - label1_ptr - 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?