translate.c

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

C
2,182
字号
	break;    case OPC_VR54XX_MACCU:        gen_op_maccu();        opn = "maccu";	break;    case OPC_VR54XX_MSAC:        gen_op_msac();        opn = "msac";	break;    case OPC_VR54XX_MSACU:        gen_op_msacu();        opn = "msacu";	break;    case OPC_VR54XX_MULHI:        gen_op_mulhi();        opn = "mulhi";	break;    case OPC_VR54XX_MULHIU:        gen_op_mulhiu();        opn = "mulhiu";	break;    case OPC_VR54XX_MULSHI:        gen_op_mulshi();        opn = "mulshi";	break;    case OPC_VR54XX_MULSHIU:        gen_op_mulshiu();        opn = "mulshiu";	break;    case OPC_VR54XX_MACCHI:        gen_op_macchi();        opn = "macchi";	break;    case OPC_VR54XX_MACCHIU:        gen_op_macchiu();        opn = "macchiu";	break;    case OPC_VR54XX_MSACHI:        gen_op_msachi();        opn = "msachi";	break;    case OPC_VR54XX_MSACHIU:        gen_op_msachiu();        opn = "msachiu";	break;    default:        MIPS_INVAL("mul vr54xx");        generate_exception(ctx, EXCP_RI);        return;    }    GEN_STORE_T0_REG(rd);    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);}static void gen_cl (DisasContext *ctx, uint32_t opc,                    int rd, int rs){    const char *opn = "CLx";    if (rd == 0) {        /* Treat as NOP. */        MIPS_DEBUG("NOP");        return;    }    GEN_LOAD_REG_T0(rs);    switch (opc) {    case OPC_CLO:        gen_op_clo();        opn = "clo";        break;    case OPC_CLZ:        gen_op_clz();        opn = "clz";        break;#if defined(TARGET_MIPS64)    case OPC_DCLO:        gen_op_dclo();        opn = "dclo";        break;    case OPC_DCLZ:        gen_op_dclz();        opn = "dclz";        break;#endif    default:        MIPS_INVAL(opn);        generate_exception(ctx, EXCP_RI);        return;    }    gen_op_store_gpr_T0(rd);    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);}/* Traps */static void gen_trap (DisasContext *ctx, uint32_t opc,                      int rs, int rt, int16_t imm){    int cond;    cond = 0;    /* Load needed operands */    switch (opc) {    case OPC_TEQ:    case OPC_TGE:    case OPC_TGEU:    case OPC_TLT:    case OPC_TLTU:    case OPC_TNE:        /* Compare two registers */        if (rs != rt) {            GEN_LOAD_REG_T0(rs);            GEN_LOAD_REG_T1(rt);            cond = 1;        }        break;    case OPC_TEQI:    case OPC_TGEI:    case OPC_TGEIU:    case OPC_TLTI:    case OPC_TLTIU:    case OPC_TNEI:        /* Compare register to immediate */        if (rs != 0 || imm != 0) {            GEN_LOAD_REG_T0(rs);            GEN_LOAD_IMM_TN(T1, (int32_t)imm);            cond = 1;        }        break;    }    if (cond == 0) {        switch (opc) {        case OPC_TEQ:   /* rs == rs */        case OPC_TEQI:  /* r0 == 0  */        case OPC_TGE:   /* rs >= rs */        case OPC_TGEI:  /* r0 >= 0  */        case OPC_TGEU:  /* rs >= rs unsigned */        case OPC_TGEIU: /* r0 >= 0  unsigned */            /* Always trap */            gen_op_set_T0(1);            break;        case OPC_TLT:   /* rs < rs           */        case OPC_TLTI:  /* r0 < 0            */        case OPC_TLTU:  /* rs < rs unsigned  */        case OPC_TLTIU: /* r0 < 0  unsigned  */        case OPC_TNE:   /* rs != rs          */        case OPC_TNEI:  /* r0 != 0           */            /* Never trap: treat as NOP. */            return;        default:            MIPS_INVAL("trap");            generate_exception(ctx, EXCP_RI);            return;        }    } else {        switch (opc) {        case OPC_TEQ:        case OPC_TEQI:            gen_op_eq();            break;        case OPC_TGE:        case OPC_TGEI:            gen_op_ge();            break;        case OPC_TGEU:        case OPC_TGEIU:            gen_op_geu();            break;        case OPC_TLT:        case OPC_TLTI:            gen_op_lt();            break;        case OPC_TLTU:        case OPC_TLTIU:            gen_op_ltu();            break;        case OPC_TNE:        case OPC_TNEI:            gen_op_ne();            break;        default:            MIPS_INVAL("trap");            generate_exception(ctx, EXCP_RI);            return;        }    }    save_cpu_state(ctx, 1);    gen_op_trap();    ctx->bstate = BS_STOP;}static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest){    TranslationBlock *tb;    tb = ctx->tb;    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {        tcg_gen_goto_tb(n);        gen_save_pc(dest);        tcg_gen_exit_tb((long)tb + n);    } else {        gen_save_pc(dest);        tcg_gen_exit_tb(0);    }}static inline void tcg_gen_set_bcond(void){    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));}static inline void tcg_gen_jnz_bcond(int label){    int r_tmp = tcg_temp_new(TCG_TYPE_TL);    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));    tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);}/* Branches (before delay slot) */static void gen_compute_branch (DisasContext *ctx, uint32_t opc,                                int rs, int rt, int32_t offset){    target_ulong btarget = -1;    int blink = 0;    int bcond = 0;    if (ctx->hflags & MIPS_HFLAG_BMASK) {#ifdef MIPS_DEBUG_DISAS        if (loglevel & CPU_LOG_TB_IN_ASM) {            fprintf(logfile,                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",                    ctx->pc);	}#endif        generate_exception(ctx, EXCP_RI);        return;    }    /* Load needed operands */    switch (opc) {    case OPC_BEQ:    case OPC_BEQL:    case OPC_BNE:    case OPC_BNEL:        /* Compare two registers */        if (rs != rt) {            GEN_LOAD_REG_T0(rs);            GEN_LOAD_REG_T1(rt);            bcond = 1;        }        btarget = ctx->pc + 4 + offset;        break;    case OPC_BGEZ:    case OPC_BGEZAL:    case OPC_BGEZALL:    case OPC_BGEZL:    case OPC_BGTZ:    case OPC_BGTZL:    case OPC_BLEZ:    case OPC_BLEZL:    case OPC_BLTZ:    case OPC_BLTZAL:    case OPC_BLTZALL:    case OPC_BLTZL:        /* Compare to zero */        if (rs != 0) {            gen_op_load_gpr_T0(rs);            bcond = 1;        }        btarget = ctx->pc + 4 + offset;        break;    case OPC_J:    case OPC_JAL:        /* Jump to immediate */        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;        break;    case OPC_JR:    case OPC_JALR:        /* Jump to register */        if (offset != 0 && offset != 16) {            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the               others are reserved. */            MIPS_INVAL("jump hint");            generate_exception(ctx, EXCP_RI);            return;        }        GEN_LOAD_REG_T1(rs);        gen_op_save_breg_target();        break;    default:        MIPS_INVAL("branch/jump");        generate_exception(ctx, EXCP_RI);        return;    }    if (bcond == 0) {        /* No condition to be computed */        switch (opc) {        case OPC_BEQ:     /* rx == rx        */        case OPC_BEQL:    /* rx == rx likely */        case OPC_BGEZ:    /* 0 >= 0          */        case OPC_BGEZL:   /* 0 >= 0 likely   */        case OPC_BLEZ:    /* 0 <= 0          */        case OPC_BLEZL:   /* 0 <= 0 likely   */            /* Always take */            ctx->hflags |= MIPS_HFLAG_B;            MIPS_DEBUG("balways");            break;        case OPC_BGEZAL:  /* 0 >= 0          */        case OPC_BGEZALL: /* 0 >= 0 likely   */            /* Always take and link */            blink = 31;            ctx->hflags |= MIPS_HFLAG_B;            MIPS_DEBUG("balways and link");            break;        case OPC_BNE:     /* rx != rx        */        case OPC_BGTZ:    /* 0 > 0           */        case OPC_BLTZ:    /* 0 < 0           */            /* Treat as NOP. */            MIPS_DEBUG("bnever (NOP)");            return;        case OPC_BLTZAL:  /* 0 < 0           */            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);            gen_op_store_gpr_T0(31);            MIPS_DEBUG("bnever and link");            return;        case OPC_BLTZALL: /* 0 < 0 likely */            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);            gen_op_store_gpr_T0(31);            /* Skip the instruction in the delay slot */            MIPS_DEBUG("bnever, link and skip");            ctx->pc += 4;            return;        case OPC_BNEL:    /* rx != rx likely */        case OPC_BGTZL:   /* 0 > 0 likely */        case OPC_BLTZL:   /* 0 < 0 likely */            /* Skip the instruction in the delay slot */            MIPS_DEBUG("bnever and skip");            ctx->pc += 4;            return;        case OPC_J:            ctx->hflags |= MIPS_HFLAG_B;            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);            break;        case OPC_JAL:            blink = 31;            ctx->hflags |= MIPS_HFLAG_B;            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);            break;        case OPC_JR:            ctx->hflags |= MIPS_HFLAG_BR;            MIPS_DEBUG("jr %s", regnames[rs]);            break;        case OPC_JALR:            blink = rt;            ctx->hflags |= MIPS_HFLAG_BR;            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);            break;        default:            MIPS_INVAL("branch/jump");            generate_exception(ctx, EXCP_RI);            return;        }    } else {        switch (opc) {        case OPC_BEQ:            gen_op_eq();            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,                       regnames[rs], regnames[rt], btarget);            goto not_likely;        case OPC_BEQL:            gen_op_eq();            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,                       regnames[rs], regnames[rt], btarget);            goto likely;        case OPC_BNE:            gen_op_ne();            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,                       regnames[rs], regnames[rt], btarget);            goto not_likely;        case OPC_BNEL:            gen_op_ne();            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,                       regnames[rs], regnames[rt], btarget);            goto likely;        case OPC_BGEZ:            gen_op_gez();            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto not_likely;        case OPC_BGEZL:            gen_op_gez();            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto likely;        case OPC_BGEZAL:            gen_op_gez();            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);            blink = 31;            goto not_likely;        case OPC_BGEZALL:            gen_op_gez();            blink = 31;            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto likely;        case OPC_BGTZ:            gen_op_gtz();            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto not_likely;        case OPC_BGTZL:            gen_op_gtz();            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto likely;        case OPC_BLEZ:            gen_op_lez();            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto not_likely;        case OPC_BLEZL:            gen_op_lez();            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto likely;        case OPC_BLTZ:            gen_op_ltz();            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto not_likely;        case OPC_BLTZL:            gen_op_ltz();            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);            goto likely;        case OPC_BLTZAL:            gen_op_ltz();            blink = 31;            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);        not_likely:            ctx->hflags |= MIPS_HFLAG_BC;            tcg_gen_set_bcond();            break;        case OPC_BLTZALL:            gen_op

⌨️ 快捷键说明

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