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 + -
显示快捷键?