tcg-target.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 981 行 · 第 1/2 页

C
981
字号
#endif#ifdef TARGET_WORDS_BIGENDIAN    bswap = 0;#else    bswap = 1;#endif    switch (opc) {        case 0:            tcg_out_ldst(s, data_reg, r0, 0, LDB);            break;        case 0 | 4:            tcg_out_ldst(s, data_reg, r0, 0, LDB);            tcg_out_ext8s(s, data_reg, data_reg);            break;        case 1:            tcg_out_ldst(s, data_reg, r0, 0, LDH);            if (bswap)                tcg_out_bswap16(s, data_reg, data_reg);            break;        case 1 | 4:            tcg_out_ldst(s, data_reg, r0, 0, LDH);            if (bswap)                tcg_out_bswap16(s, data_reg, data_reg);            tcg_out_ext16s(s, data_reg, data_reg);            break;        case 2:            tcg_out_ldst(s, data_reg, r0, 0, LDW);            if (bswap)                tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);            break;        case 3:            tcg_abort();            if (!bswap) {                tcg_out_ldst(s, data_reg, r0, 0, LDW);                tcg_out_ldst(s, data_reg2, r0, 4, LDW);            } else {                tcg_out_ldst(s, data_reg, r0, 4, LDW);                tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);                tcg_out_ldst(s, data_reg2, r0, 0, LDW);                tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);            }            break;        default:            tcg_abort();    }#if defined(CONFIG_SOFTMMU)    /* label2: */    *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);#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)    uint32_t *label1_ptr, *label2_ptr;#endif#if TARGET_LONG_BITS == 64#if defined(CONFIG_SOFTMMU)    uint32_t *label3_ptr;#endif    int addr_reg2;#endif    data_reg = *args++;    if (opc == 3)        data_reg2 = *args++;    else        data_reg2 = 0; /* surpress warning */    addr_reg = *args++;#if TARGET_LONG_BITS == 64    addr_reg2 = *args++;#endif    mem_index = *args;    s_bits = opc;    r0 = TCG_REG_R26;    r1 = TCG_REG_R25;#if defined(CONFIG_SOFTMMU)    tcg_out_mov(s, r1, addr_reg);    tcg_out_mov(s, r0, addr_reg);    tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |                 INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));    tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),                   ARITH_AND);    tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,                   ARITH_AND);    tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);    tcg_out_arithi(s, r1, r1,                   offsetof(CPUState, tlb_table[mem_index][0].addr_write),                   ARITH_ADD);    tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);#if TARGET_LONG_BITS == 32    /* if equal, jump to label1 */    label1_ptr = (uint32_t *)s->code_ptr;    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |                 INSN_COND(COND_EQUAL));    tcg_out_mov(s, r0, addr_reg); /* delay slot */#else    /* if not equal, jump to label3 */    label3_ptr = (uint32_t *)s->code_ptr;    tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |                 INSN_COND(COND_EQUAL));    tcg_out_mov(s, r0, addr_reg); /* delay slot */    tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);    /* if equal, jump to label1 */    label1_ptr = (uint32_t *)s->code_ptr;    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |                 INSN_COND(COND_EQUAL));    tcg_out_nop(s); /* delay slot */    /* label3: */    *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);#endif    tcg_out_mov(s, TCG_REG_R26, addr_reg);#if TARGET_LONG_BITS == 64    tcg_out_mov(s, TCG_REG_R25, addr_reg2);    if (opc == 3) {        tcg_abort();        tcg_out_mov(s, TCG_REG_R24, data_reg);        tcg_out_mov(s, TCG_REG_R23, data_reg2);        /* TODO: push mem_index */        tcg_abort();    } else {        switch(opc) {        case 0:            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |                         INSN_SHDEP_P(31) | INSN_DEP_LEN(8));            break;        case 1:            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |                         INSN_SHDEP_P(31) | INSN_DEP_LEN(16));            break;        case 2:            tcg_out_mov(s, TCG_REG_R24, data_reg);            break;        }        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);    }#else    if (opc == 3) {        tcg_abort();        tcg_out_mov(s, TCG_REG_R25, data_reg);        tcg_out_mov(s, TCG_REG_R24, data_reg2);        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);    } else {        switch(opc) {        case 0:            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |                         INSN_SHDEP_P(31) | INSN_DEP_LEN(8));            break;        case 1:            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |                         INSN_SHDEP_P(31) | INSN_DEP_LEN(16));            break;        case 2:            tcg_out_mov(s, TCG_REG_R25, data_reg);            break;        }        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);    }#endif    tcg_out_call(s, qemu_st_helpers[s_bits]);    /* jump to label2 */    label2_ptr = (uint32_t *)s->code_ptr;    tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);    /* label1: */    *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);    tcg_out_arithi(s, TCG_REG_R20, r1,                   offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write),                   ARITH_ADD);    tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);    tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);#else    r0 = addr_reg;#endif#ifdef TARGET_WORDS_BIGENDIAN    bswap = 0;#else    bswap = 1;#endif    switch (opc) {    case 0:        tcg_out_ldst(s, data_reg, r0, 0, STB);        break;    case 1:        if (bswap) {            tcg_out_bswap16(s, TCG_REG_R20, data_reg);            data_reg = TCG_REG_R20;        }        tcg_out_ldst(s, data_reg, r0, 0, STH);        break;    case 2:        if (bswap) {            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);            data_reg = TCG_REG_R20;        }        tcg_out_ldst(s, data_reg, r0, 0, STW);        break;    case 3:        tcg_abort();        if (!bswap) {            tcg_out_ldst(s, data_reg, r0, 0, STW);            tcg_out_ldst(s, data_reg2, r0, 4, STW);        } else {            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);            tcg_out_ldst(s, TCG_REG_R20, r0, 4, STW);            tcg_out_bswap32(s, TCG_REG_R20, data_reg2, TCG_REG_R20);            tcg_out_ldst(s, TCG_REG_R20, r0, 0, STW);        }        break;    default:        tcg_abort();    }#if defined(CONFIG_SOFTMMU)    /* label2: */    *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);#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_RET0, args[0]);        tcg_out32(s, BV_N | INSN_R2(TCG_REG_R18));        break;    case INDEX_op_goto_tb:        if (s->tb_jmp_offset) {            /* direct jump method */            fprintf(stderr, "goto_tb direct\n");            tcg_abort();            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, args[0]);            tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;        } else {            /* indirect jump method */            tcg_out_ld_ptr(s, TCG_REG_R20,                           (tcg_target_long)(s->tb_next + args[0]));            tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));        }        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;        break;    case INDEX_op_call:        tcg_out32(s, BLE_SR4 | INSN_R2(args[0]));        tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);        break;    case INDEX_op_jmp:        fprintf(stderr, "unimplemented jmp\n");        tcg_abort();        break;    case INDEX_op_br:        fprintf(stderr, "unimplemented br\n");        tcg_abort();        break;    case INDEX_op_movi_i32:        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);        break;    case INDEX_op_ld8u_i32:        tcg_out_ldst(s, args[0], args[1], args[2], LDB);        break;    case INDEX_op_ld8s_i32:        tcg_out_ldst(s, args[0], args[1], args[2], LDB);        tcg_out_ext8s(s, args[0], args[0]);        break;    case INDEX_op_ld16u_i32:        tcg_out_ldst(s, args[0], args[1], args[2], LDH);        break;    case INDEX_op_ld16s_i32:        tcg_out_ldst(s, args[0], args[1], args[2], LDH);        tcg_out_ext16s(s, args[0], args[0]);        break;    case INDEX_op_ld_i32:        tcg_out_ldst(s, args[0], args[1], args[2], LDW);        break;    case INDEX_op_st8_i32:        tcg_out_ldst(s, args[0], args[1], args[2], STB);        break;    case INDEX_op_st16_i32:        tcg_out_ldst(s, args[0], args[1], args[2], STH);        break;    case INDEX_op_st_i32:        tcg_out_ldst(s, args[0], args[1], args[2], STW);        break;    case INDEX_op_sub_i32:        c = ARITH_SUB;        goto gen_arith;    case INDEX_op_and_i32:        c = ARITH_AND;        goto gen_arith;    case INDEX_op_or_i32:        c = ARITH_OR;        goto gen_arith;    case INDEX_op_xor_i32:        c = ARITH_XOR;        goto gen_arith;    case INDEX_op_add_i32:        c = ARITH_ADD;        goto gen_arith;    case INDEX_op_shl_i32:        tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |                     lowsignext(0x1f, 0, 11));        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));        tcg_out32(s, ZVDEP | INSN_R2(args[0]) | INSN_R1(args[1]) |                     INSN_DEP_LEN(32));        break;    case INDEX_op_shr_i32:        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(args[2]));        tcg_out32(s, VSHD | INSN_T(args[0]) | INSN_R1(TCG_REG_R0) |                     INSN_R2(args[1]));        break;    case INDEX_op_sar_i32:        tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |                     lowsignext(0x1f, 0, 11));        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));        tcg_out32(s, VEXTRS | INSN_R1(args[0]) | INSN_R2(args[1]) |                     INSN_DEP_LEN(32));        break;    case INDEX_op_mul_i32:        fprintf(stderr, "unimplemented mul\n");        tcg_abort();        break;    case INDEX_op_mulu2_i32:        fprintf(stderr, "unimplemented mulu2\n");        tcg_abort();        break;    case INDEX_op_div2_i32:        fprintf(stderr, "unimplemented div2\n");        tcg_abort();        break;    case INDEX_op_divu2_i32:        fprintf(stderr, "unimplemented divu2\n");        tcg_abort();        break;    case INDEX_op_brcond_i32:        fprintf(stderr, "unimplemented brcond\n");        tcg_abort();        break;    case INDEX_op_qemu_ld8u:        tcg_out_qemu_ld(s, args, 0);        break;    case INDEX_op_qemu_ld8s:        tcg_out_qemu_ld(s, args, 0 | 4);        break;    case INDEX_op_qemu_ld16u:        tcg_out_qemu_ld(s, args, 1);        break;    case INDEX_op_qemu_ld16s:        tcg_out_qemu_ld(s, args, 1 | 4);        break;    case INDEX_op_qemu_ld32u:        tcg_out_qemu_ld(s, args, 2);        break;    case INDEX_op_qemu_st8:        tcg_out_qemu_st(s, args, 0);        break;    case INDEX_op_qemu_st16:        tcg_out_qemu_st(s, args, 1);        break;    case INDEX_op_qemu_st32:        tcg_out_qemu_st(s, args, 2);        break;    default:        fprintf(stderr, "unknown opcode 0x%x\n", opc);        tcg_abort();    }    return;gen_arith:    tcg_out_arith(s, args[0], args[1], args[2], c);}static const TCGTargetOpDef hppa_op_defs[] = {    { INDEX_op_exit_tb, { } },    { INDEX_op_goto_tb, { } },    { INDEX_op_call, { "r" } },    { INDEX_op_jmp, { "r" } },    { INDEX_op_br, { } },    { INDEX_op_mov_i32, { "r", "r" } },    { INDEX_op_movi_i32, { "r" } },    { INDEX_op_ld8u_i32, { "r", "r" } },    { INDEX_op_ld8s_i32, { "r", "r" } },    { INDEX_op_ld16u_i32, { "r", "r" } },    { INDEX_op_ld16s_i32, { "r", "r" } },    { INDEX_op_ld_i32, { "r", "r" } },    { INDEX_op_st8_i32, { "r", "r" } },    { INDEX_op_st16_i32, { "r", "r" } },    { INDEX_op_st_i32, { "r", "r" } },    { INDEX_op_add_i32, { "r", "r", "r" } },    { INDEX_op_sub_i32, { "r", "r", "r" } },    { INDEX_op_and_i32, { "r", "r", "r" } },    { INDEX_op_or_i32, { "r", "r", "r" } },    { INDEX_op_xor_i32, { "r", "r", "r" } },    { INDEX_op_shl_i32, { "r", "r", "r" } },    { INDEX_op_shr_i32, { "r", "r", "r" } },    { INDEX_op_sar_i32, { "r", "r", "r" } },    { INDEX_op_brcond_i32, { "r", "r" } },#if TARGET_LONG_BITS == 32    { INDEX_op_qemu_ld8u, { "r", "L" } },    { INDEX_op_qemu_ld8s, { "r", "L" } },    { INDEX_op_qemu_ld16u, { "r", "L" } },    { INDEX_op_qemu_ld16s, { "r", "L" } },    { INDEX_op_qemu_ld32u, { "r", "L" } },    { INDEX_op_qemu_ld64, { "r", "r", "L" } },    { INDEX_op_qemu_st8, { "L", "L" } },    { INDEX_op_qemu_st16, { "L", "L" } },    { INDEX_op_qemu_st32, { "L", "L" } },    { INDEX_op_qemu_st64, { "L", "L", "L" } },#else    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },    { INDEX_op_qemu_ld32u, { "r", "L", "L" } },    { INDEX_op_qemu_ld32s, { "r", "L", "L" } },    { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },    { INDEX_op_qemu_st8, { "L", "L", "L" } },    { INDEX_op_qemu_st16, { "L", "L", "L" } },    { INDEX_op_qemu_st32, { "L", "L", "L" } },    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },#endif    { -1 },};void tcg_target_init(TCGContext *s){    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);    tcg_regset_set32(tcg_target_call_clobber_regs, 0,                     (1 << TCG_REG_R20) |                     (1 << TCG_REG_R21) |                     (1 << TCG_REG_R22) |                     (1 << TCG_REG_R23) |                     (1 << TCG_REG_R24) |                     (1 << TCG_REG_R25) |                     (1 << TCG_REG_R26));    tcg_regset_clear(s->reserved_regs);    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);  /* hardwired to zero */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);  /* addil target */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RP);  /* link register */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3);  /* frame pointer */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R18); /* return pointer */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R19); /* clobbered w/o pic */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R20); /* reserved */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP);  /* data pointer */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);  /* stack pointer */    tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */    tcg_add_target_add_op_defs(hppa_op_defs);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?