translate.c

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

C
2,182
字号
    case OPC_ADDI:        save_cpu_state(ctx, 1);        gen_op_addo();        opn = "addi";        break;    case OPC_ADDIU:        gen_op_add();        opn = "addiu";        break;#if defined(TARGET_MIPS64)    case OPC_DADDI:        save_cpu_state(ctx, 1);        gen_op_daddo();        opn = "daddi";        break;    case OPC_DADDIU:        gen_op_dadd();        opn = "daddiu";        break;#endif    case OPC_SLTI:        gen_op_lt();        opn = "slti";        break;    case OPC_SLTIU:        gen_op_ltu();        opn = "sltiu";        break;    case OPC_ANDI:        gen_op_and();        opn = "andi";        break;    case OPC_ORI:        gen_op_or();        opn = "ori";        break;    case OPC_XORI:        gen_op_xor();        opn = "xori";        break;    case OPC_LUI:        opn = "lui";        break;    case OPC_SLL:        gen_op_sll();        opn = "sll";        break;    case OPC_SRA:        gen_op_sra();        opn = "sra";        break;    case OPC_SRL:        switch ((ctx->opcode >> 21) & 0x1f) {        case 0:            gen_op_srl();            opn = "srl";            break;        case 1:            /* rotr is decoded as srl on non-R2 CPUs */            if (env->insn_flags & ISA_MIPS32R2) {                gen_op_rotr();                opn = "rotr";            } else {                gen_op_srl();                opn = "srl";            }            break;        default:            MIPS_INVAL("invalid srl flag");            generate_exception(ctx, EXCP_RI);            break;        }        break;#if defined(TARGET_MIPS64)    case OPC_DSLL:        gen_op_dsll();        opn = "dsll";        break;    case OPC_DSRA:        gen_op_dsra();        opn = "dsra";        break;    case OPC_DSRL:        switch ((ctx->opcode >> 21) & 0x1f) {        case 0:            gen_op_dsrl();            opn = "dsrl";            break;        case 1:            /* drotr is decoded as dsrl on non-R2 CPUs */            if (env->insn_flags & ISA_MIPS32R2) {                gen_op_drotr();                opn = "drotr";            } else {                gen_op_dsrl();                opn = "dsrl";            }            break;        default:            MIPS_INVAL("invalid dsrl flag");            generate_exception(ctx, EXCP_RI);            break;        }        break;    case OPC_DSLL32:        gen_op_dsll32();        opn = "dsll32";        break;    case OPC_DSRA32:        gen_op_dsra32();        opn = "dsra32";        break;    case OPC_DSRL32:        switch ((ctx->opcode >> 21) & 0x1f) {        case 0:            gen_op_dsrl32();            opn = "dsrl32";            break;        case 1:            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */            if (env->insn_flags & ISA_MIPS32R2) {                gen_op_drotr32();                opn = "drotr32";            } else {                gen_op_dsrl32();                opn = "dsrl32";            }            break;        default:            MIPS_INVAL("invalid dsrl32 flag");            generate_exception(ctx, EXCP_RI);            break;        }        break;#endif    default:        MIPS_INVAL(opn);        generate_exception(ctx, EXCP_RI);        return;    }    GEN_STORE_T0_REG(rt);    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);}/* Arithmetic */static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,                       int rd, int rs, int rt){    const char *opn = "arith";    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB       && opc != OPC_DADD && opc != OPC_DSUB) {        /* If no destination, treat it as a NOP.           For add & sub, we must generate the overflow exception when needed. */        MIPS_DEBUG("NOP");        return;    }    GEN_LOAD_REG_T0(rs);    /* Specialcase the conventional move operation. */    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {        GEN_STORE_T0_REG(rd);        return;    }    GEN_LOAD_REG_T1(rt);    switch (opc) {    case OPC_ADD:        save_cpu_state(ctx, 1);        gen_op_addo();        opn = "add";        break;    case OPC_ADDU:        gen_op_add();        opn = "addu";        break;    case OPC_SUB:        save_cpu_state(ctx, 1);        gen_op_subo();        opn = "sub";        break;    case OPC_SUBU:        gen_op_sub();        opn = "subu";        break;#if defined(TARGET_MIPS64)    case OPC_DADD:        save_cpu_state(ctx, 1);        gen_op_daddo();        opn = "dadd";        break;    case OPC_DADDU:        gen_op_dadd();        opn = "daddu";        break;    case OPC_DSUB:        save_cpu_state(ctx, 1);        gen_op_dsubo();        opn = "dsub";        break;    case OPC_DSUBU:        gen_op_dsub();        opn = "dsubu";        break;#endif    case OPC_SLT:        gen_op_lt();        opn = "slt";        break;    case OPC_SLTU:        gen_op_ltu();        opn = "sltu";        break;    case OPC_AND:        gen_op_and();        opn = "and";        break;    case OPC_NOR:        gen_op_nor();        opn = "nor";        break;    case OPC_OR:        gen_op_or();        opn = "or";        break;    case OPC_XOR:        gen_op_xor();        opn = "xor";        break;    case OPC_MUL:        gen_op_mul();        opn = "mul";        break;    case OPC_MOVN:        gen_op_movn(rd);        opn = "movn";        goto print;    case OPC_MOVZ:        gen_op_movz(rd);        opn = "movz";        goto print;    case OPC_SLLV:        gen_op_sllv();        opn = "sllv";        break;    case OPC_SRAV:        gen_op_srav();        opn = "srav";        break;    case OPC_SRLV:        switch ((ctx->opcode >> 6) & 0x1f) {        case 0:            gen_op_srlv();            opn = "srlv";            break;        case 1:            /* rotrv is decoded as srlv on non-R2 CPUs */            if (env->insn_flags & ISA_MIPS32R2) {                gen_op_rotrv();                opn = "rotrv";            } else {                gen_op_srlv();                opn = "srlv";            }            break;        default:            MIPS_INVAL("invalid srlv flag");            generate_exception(ctx, EXCP_RI);            break;        }        break;#if defined(TARGET_MIPS64)    case OPC_DSLLV:        gen_op_dsllv();        opn = "dsllv";        break;    case OPC_DSRAV:        gen_op_dsrav();        opn = "dsrav";        break;    case OPC_DSRLV:        switch ((ctx->opcode >> 6) & 0x1f) {        case 0:            gen_op_dsrlv();            opn = "dsrlv";            break;        case 1:            /* drotrv is decoded as dsrlv on non-R2 CPUs */            if (env->insn_flags & ISA_MIPS32R2) {                gen_op_drotrv();                opn = "drotrv";            } else {                gen_op_dsrlv();                opn = "dsrlv";            }            break;        default:            MIPS_INVAL("invalid dsrlv flag");            generate_exception(ctx, EXCP_RI);            break;        }        break;#endif    default:        MIPS_INVAL(opn);        generate_exception(ctx, EXCP_RI);        return;    }    GEN_STORE_T0_REG(rd); print:    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);}/* Arithmetic on HI/LO registers */static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg){    const char *opn = "hilo";    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {        /* Treat as NOP. */        MIPS_DEBUG("NOP");        return;    }    switch (opc) {    case OPC_MFHI:        gen_op_load_HI(0);        GEN_STORE_T0_REG(reg);        opn = "mfhi";        break;    case OPC_MFLO:        gen_op_load_LO(0);        GEN_STORE_T0_REG(reg);        opn = "mflo";        break;    case OPC_MTHI:        GEN_LOAD_REG_T0(reg);        gen_op_store_HI(0);        opn = "mthi";        break;    case OPC_MTLO:        GEN_LOAD_REG_T0(reg);        gen_op_store_LO(0);        opn = "mtlo";        break;    default:        MIPS_INVAL(opn);        generate_exception(ctx, EXCP_RI);        return;    }    MIPS_DEBUG("%s %s", opn, regnames[reg]);}static void gen_muldiv (DisasContext *ctx, uint32_t opc,                        int rs, int rt){    const char *opn = "mul/div";    GEN_LOAD_REG_T0(rs);    GEN_LOAD_REG_T1(rt);    switch (opc) {    case OPC_DIV:        gen_op_div();        opn = "div";        break;    case OPC_DIVU:        gen_op_divu();        opn = "divu";        break;    case OPC_MULT:        gen_op_mult();        opn = "mult";        break;    case OPC_MULTU:        gen_op_multu();        opn = "multu";        break;#if defined(TARGET_MIPS64)    case OPC_DDIV:        gen_op_ddiv();        opn = "ddiv";        break;    case OPC_DDIVU:        gen_op_ddivu();        opn = "ddivu";        break;    case OPC_DMULT:        gen_op_dmult();        opn = "dmult";        break;    case OPC_DMULTU:        gen_op_dmultu();        opn = "dmultu";        break;#endif    case OPC_MADD:        gen_op_madd();        opn = "madd";        break;    case OPC_MADDU:        gen_op_maddu();        opn = "maddu";        break;    case OPC_MSUB:        gen_op_msub();        opn = "msub";        break;    case OPC_MSUBU:        gen_op_msubu();        opn = "msubu";        break;    default:        MIPS_INVAL(opn);        generate_exception(ctx, EXCP_RI);        return;    }    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);}static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,                            int rd, int rs, int rt){    const char *opn = "mul vr54xx";    GEN_LOAD_REG_T0(rs);    GEN_LOAD_REG_T1(rt);    switch (opc) {    case OPC_VR54XX_MULS:        gen_op_muls();        opn = "muls";	break;    case OPC_VR54XX_MULSU:        gen_op_mulsu();        opn = "mulsu";	break;    case OPC_VR54XX_MACC:        gen_op_macc();        opn = "macc";

⌨️ 快捷键说明

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