⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        opn = "ldr";        break;    case OPC_SDR:        GEN_LOAD_REG_TN(T1, rt);        op_ldst(sdr);        opn = "sdr";        break;#endif    case OPC_LW:#if defined (MIPS_HAS_UNALIGNED_LS)    case OPC_ULW:#endif        op_ldst(lw);        GEN_STORE_TN_REG(rt, T0);        opn = "lw";        break;    case OPC_SW:#if defined (MIPS_HAS_UNALIGNED_LS)    case OPC_USW:#endif        GEN_LOAD_REG_TN(T1, rt);        op_ldst(sw);        opn = "sw";        break;    case OPC_LH:#if defined (MIPS_HAS_UNALIGNED_LS)    case OPC_ULH:#endif        op_ldst(lh);        GEN_STORE_TN_REG(rt, T0);        opn = "lh";        break;    case OPC_SH:#if defined (MIPS_HAS_UNALIGNED_LS)    case OPC_USH:#endif        GEN_LOAD_REG_TN(T1, rt);        op_ldst(sh);        opn = "sh";        break;    case OPC_LHU:#if defined (MIPS_HAS_UNALIGNED_LS)    case OPC_ULHU:#endif        op_ldst(lhu);        GEN_STORE_TN_REG(rt, T0);        opn = "lhu";        break;    case OPC_LB:        op_ldst(lb);        GEN_STORE_TN_REG(rt, T0);        opn = "lb";        break;    case OPC_SB:        GEN_LOAD_REG_TN(T1, rt);        op_ldst(sb);        opn = "sb";        break;    case OPC_LBU:        op_ldst(lbu);        GEN_STORE_TN_REG(rt, T0);        opn = "lbu";        break;    case OPC_LWL:	GEN_LOAD_REG_TN(T1, rt);        op_ldst(lwl);        GEN_STORE_TN_REG(rt, T0);        opn = "lwl";        break;    case OPC_SWL:        GEN_LOAD_REG_TN(T1, rt);        op_ldst(swl);        opn = "swr";        break;    case OPC_LWR:	GEN_LOAD_REG_TN(T1, rt);        op_ldst(lwr);        GEN_STORE_TN_REG(rt, T0);        opn = "lwr";        break;    case OPC_SWR:        GEN_LOAD_REG_TN(T1, rt);        op_ldst(swr);        opn = "swr";        break;    case OPC_LL:        op_ldst(ll);        GEN_STORE_TN_REG(rt, T0);        opn = "ll";        break;    case OPC_SC:        GEN_LOAD_REG_TN(T1, rt);        op_ldst(sc);        GEN_STORE_TN_REG(rt, T0);        opn = "sc";        break;    default:        MIPS_INVAL("load/store");        generate_exception(ctx, EXCP_RI);        return;    }    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);}/* Arithmetic with immediate operand */static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,                           int rs, int16_t imm){    uint32_t uimm;    const unsigned char *opn = "unk";    if (rt == 0 && opc != OPC_ADDI) {        /* if no destination, treat it as a NOP          * For addi, we must generate the overflow exception when needed.         */        MIPS_DEBUG("NOP");        return;    }    if (opc == OPC_ADDI || opc == OPC_ADDIU ||        opc == OPC_SLTI || opc == OPC_SLTIU)        uimm = (int32_t)imm; /* Sign extent to 32 bits */    else        uimm = (uint16_t)imm;    if (opc != OPC_LUI) {        GEN_LOAD_REG_TN(T0, rs);        GEN_LOAD_IMM_TN(T1, uimm);    } else {        uimm = uimm << 16;        GEN_LOAD_IMM_TN(T0, uimm);    }    switch (opc) {    case OPC_ADDI:        save_cpu_state(ctx, 1);        gen_op_addo();        opn = "addi";        break;    case OPC_ADDIU:        gen_op_add();        opn = "addiu";        break;    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:        gen_op_srl();        opn = "srl";        break;    default:        MIPS_INVAL("imm arith");        generate_exception(ctx, EXCP_RI);        return;    }    GEN_STORE_TN_REG(rt, T0);    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);}/* Arithmetic */static void gen_arith (DisasContext *ctx, uint16_t opc,                       int rd, int rs, int rt){    const unsigned char *opn = "unk";    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB) {        /* 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_TN(T0, rs);    GEN_LOAD_REG_TN(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;    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:        gen_op_srlv();        opn = "srlv";        break;    default:        MIPS_INVAL("arith");        generate_exception(ctx, EXCP_RI);        return;    }    GEN_STORE_TN_REG(rd, T0); 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, uint16_t opc, int reg){    const unsigned char *opn = "unk";    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {        /* Treat as a NOP */        MIPS_DEBUG("NOP");        return;    }    switch (opc) {    case OPC_MFHI:        gen_op_load_HI();        GEN_STORE_TN_REG(reg, T0);        opn = "mfhi";        break;    case OPC_MFLO:        gen_op_load_LO();        GEN_STORE_TN_REG(reg, T0);        opn = "mflo";        break;    case OPC_MTHI:        GEN_LOAD_REG_TN(T0, reg);        gen_op_store_HI();        opn = "mthi";        break;    case OPC_MTLO:        GEN_LOAD_REG_TN(T0, reg);        gen_op_store_LO();        opn = "mtlo";        break;    default:        MIPS_INVAL("HILO");        generate_exception(ctx, EXCP_RI);        return;    }    MIPS_DEBUG("%s %s", opn, regnames[reg]);}static void gen_muldiv (DisasContext *ctx, uint16_t opc,                        int rs, int rt){    const unsigned char *opn = "unk";    GEN_LOAD_REG_TN(T0, rs);    GEN_LOAD_REG_TN(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;    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("mul/div");        generate_exception(ctx, EXCP_RI);        return;    }    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);}static void gen_cl (DisasContext *ctx, uint16_t opc,                    int rd, int rs){    const unsigned char *opn = "unk";    if (rd == 0) {        /* Treat as a NOP */        MIPS_DEBUG("NOP");        return;    }    GEN_LOAD_REG_TN(T0, rs);    switch (opc) {    case OPC_CLO:        /* CLO */        gen_op_clo();        opn = "clo";        break;    case OPC_CLZ:        /* CLZ */        gen_op_clz();        opn = "clz";        break;    default:        MIPS_INVAL("CLx");        generate_exception(ctx, EXCP_RI);        return;    }    gen_op_store_T0_gpr(rd);    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);}/* Traps */static void gen_trap (DisasContext *ctx, uint16_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_TN(T0, rs);            GEN_LOAD_REG_TN(T1, rt);            cond = 1;        }    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_TN(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");

⌨️ 快捷键说明

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