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

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            break;        case 0x18 ... 0x1B: /* MULT / DIV */            gen_muldiv(ctx, op1 | EXT_SPECIAL, rs, rt);            break;        case 0x08 ... 0x09: /* Jumps */            gen_compute_branch(ctx, op1 | EXT_SPECIAL, rs, rd, sa);            return;        case 0x30 ... 0x34: /* Traps */        case 0x36:            gen_trap(ctx, op1 | EXT_SPECIAL, rs, rt, -1);            break;        case 0x10:          /* Move from HI/LO */        case 0x12:            gen_HILO(ctx, op1 | EXT_SPECIAL, rd);            break;        case 0x11:        case 0x13:          /* Move to HI/LO */            gen_HILO(ctx, op1 | EXT_SPECIAL, rs);            break;        case 0x0C:          /* SYSCALL */            generate_exception(ctx, EXCP_SYSCALL);            break;        case 0x0D:          /* BREAK */            generate_exception(ctx, EXCP_BREAK);            break;        case 0x0F:          /* SYNC */            /* Treat as a noop */            break;        case 0x05:          /* Pmon entry point */            gen_op_pmon((ctx->opcode >> 6) & 0x1F);            break;        case 0x01:          /* MOVCI */#if defined (MIPS_HAS_MOVCI)            /* XXX */#else            /* Not implemented */            generate_exception_err (ctx, EXCP_CpU, 1);#endif            break;#if defined (TARGET_MIPS64)        case 0x14: /* MIPS64 specific opcodes */        case 0x16:        case 0x17:        case 0x1C ... 0x1F:        case 0x2C ... 0x2F:        case 0x37:        case 0x39 ... 0x3B:        case 0x3E ... 0x3F:#endif        default:            /* Invalid */            MIPS_INVAL("special");            generate_exception(ctx, EXCP_RI);            break;        }        break;    case 0x1C:          /* Special2 opcode */        op1 = ctx->opcode & 0x3F;        switch (op1) {#if defined (MIPS_USES_R4K_EXT)        /* Those instructions are not part of MIPS32 core */        case 0x00 ... 0x01: /* Multiply and add/sub */        case 0x04 ... 0x05:            gen_muldiv(ctx, op1 | EXT_SPECIAL2, rs, rt);            break;        case 0x02:          /* MUL */            gen_arith(ctx, op1 | EXT_SPECIAL2, rd, rs, rt);            break;        case 0x20 ... 0x21: /* CLO / CLZ */            gen_cl(ctx, op1 | EXT_SPECIAL2, rd, rs);            break;#endif        case 0x3F:          /* SDBBP */            /* XXX: not clear which exception should be raised             *      when in debug mode...             */            if (!(ctx->hflags & MIPS_HFLAG_DM)) {                generate_exception(ctx, EXCP_DBp);            } else {                generate_exception(ctx, EXCP_DBp);            }            /* Treat as a noop */            break;        default:            /* Invalid */            MIPS_INVAL("special2");            generate_exception(ctx, EXCP_RI);            break;        }        break;    case 0x01:          /* B REGIMM opcode */        op1 = ((ctx->opcode >> 16) & 0x1F);        switch (op1) {        case 0x00 ... 0x03: /* REGIMM branches */        case 0x10 ... 0x13:            gen_compute_branch(ctx, op1 | EXT_REGIMM, rs, -1, imm << 2);            return;        case 0x08 ... 0x0C: /* Traps */        case 0x0E:            gen_trap(ctx, op1 | EXT_REGIMM, rs, -1, imm);            break;        default:            /* Invalid */            MIPS_INVAL("REGIMM");            generate_exception(ctx, EXCP_RI);            break;        }        break;    case 0x10:          /* CP0 opcode */        op1 = ((ctx->opcode >> 21) & 0x1F);        switch (op1) {        case 0x00:        case 0x04:            gen_cp0(ctx, op1 | EXT_CP0, rt, rd);            break;        default:            gen_cp0(ctx, (ctx->opcode & 0x3F) | EXT_CP0, rt, rd);            break;        }        break;    case 0x08 ... 0x0F: /* Arithmetic with immediate opcode */        gen_arith_imm(ctx, op, rt, rs, imm);        break;    case 0x02 ... 0x03: /* Jump */        offset = (int32_t)(ctx->opcode & 0x03FFFFFF) << 2;        gen_compute_branch(ctx, op, rs, rt, offset);        return;    case 0x04 ... 0x07: /* Branch */    case 0x14 ... 0x17:        gen_compute_branch(ctx, op, rs, rt, imm << 2);        return;    case 0x20 ... 0x26: /* Load and stores */    case 0x28 ... 0x2E:    case 0x30:    case 0x38:        gen_ldst(ctx, op, rt, rs, imm);        break;    case 0x2F:          /* Cache operation */        /* Treat as a noop */        break;    case 0x33:          /* Prefetch */        /* Treat as a noop */        break;    case 0x3F: /* HACK */        break;    /* Floating point.  */    case 0x31: /* LWC1 */    case 0x35: /* LDC1 */    case 0x39: /* SWC1 */    case 0x3D: /* SDC1 */    case 0x11:          /* CP1 opcode */#if defined(MIPS_USES_FPU)        /* XXX: not correct */#else        generate_exception_err(ctx, EXCP_CpU, 1);#endif        break;    /* COP2.  */    case 0x32: /* LWC2 */    case 0x36: /* LDC2 */    case 0x3A: /* SWC2 */    case 0x3E: /* SDC2 */    case 0x12:          /* CP2 opcode */        /* Not implemented */        generate_exception_err(ctx, EXCP_CpU, 2);        break;    case 0x13:          /* CP3 opcode */        /* Not implemented */        generate_exception_err(ctx, EXCP_CpU, 3);        break;#if defined (TARGET_MIPS64)    case 0x18 ... 0x1B:    case 0x27:    case 0x34:    case 0x37:        /* MIPS64 opcodes */#endif#if defined (MIPS_HAS_JALX)    case 0x1D:        /* JALX: not implemented */#endif    case 0x1E:        /* ASE specific */    default:            /* Invalid */        MIPS_INVAL("");        generate_exception(ctx, EXCP_RI);        break;    }    if (ctx->hflags & MIPS_HFLAG_BMASK) {        int hflags = ctx->hflags;        /* Branches completion */        ctx->hflags &= ~MIPS_HFLAG_BMASK;        ctx->bstate = BS_BRANCH;        save_cpu_state(ctx, 0);        switch (hflags & MIPS_HFLAG_BMASK) {        case MIPS_HFLAG_B:            /* unconditional branch */            MIPS_DEBUG("unconditional branch");            gen_goto_tb(ctx, 0, ctx->btarget);            break;        case MIPS_HFLAG_BL:            /* blikely taken case */            MIPS_DEBUG("blikely branch taken");            gen_goto_tb(ctx, 0, ctx->btarget);            break;        case MIPS_HFLAG_BC:            /* Conditional branch */            MIPS_DEBUG("conditional branch");            {              int l1;              l1 = gen_new_label();              gen_op_jnz_T2(l1);              gen_goto_tb(ctx, 1, ctx->pc + 4);              gen_set_label(l1);              gen_goto_tb(ctx, 0, ctx->btarget);            }            break;        case MIPS_HFLAG_BR:            /* unconditional branch to register */            MIPS_DEBUG("branch to register");            gen_op_breg();            break;        default:            MIPS_DEBUG("unknown branch");            break;        }    }}int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,                                    int search_pc){    DisasContext ctx, *ctxp = &ctx;    target_ulong pc_start;    uint16_t *gen_opc_end;    int j, lj = -1;    if (search_pc && loglevel)	fprintf (logfile, "search pc %d\n", search_pc);    pc_start = tb->pc;    gen_opc_ptr = gen_opc_buf;    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;    gen_opparam_ptr = gen_opparam_buf;    nb_gen_labels = 0;    ctx.pc = pc_start;    ctx.saved_pc = -1;    ctx.tb = tb;    ctx.bstate = BS_NONE;    /* Restore delay slot state from the tb context.  */    ctx.hflags = tb->flags;    ctx.saved_hflags = ctx.hflags;    if (ctx.hflags & MIPS_HFLAG_BR) {        gen_op_restore_breg_target();    } else if (ctx.hflags & MIPS_HFLAG_B) {        ctx.btarget = env->btarget;    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {        /* If we are in the delay slot of a conditional branch,         * restore the branch condition from env->bcond to T2         */        ctx.btarget = env->btarget;        gen_op_restore_bcond();    }#if defined(CONFIG_USER_ONLY)    ctx.mem_idx = 0;#else    ctx.mem_idx = (ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 0 : 1;#endif    ctx.CP0_Status = env->CP0_Status;#ifdef DEBUG_DISAS    if (loglevel & CPU_LOG_TB_CPU) {        fprintf(logfile, "------------------------------------------------\n");        /* FIXME: This may print out stale hflags from env... */        cpu_dump_state(env, logfile, fprintf, 0);    }#endif#if defined MIPS_DEBUG_DISAS    if (loglevel & CPU_LOG_TB_IN_ASM)        fprintf(logfile, "\ntb %p super %d cond %04x\n",                tb, ctx.mem_idx, ctx.hflags);#endif    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {        if (env->nb_breakpoints > 0) {            for(j = 0; j < env->nb_breakpoints; j++) {                if (env->breakpoints[j] == ctx.pc) {                    save_cpu_state(ctxp, 1);                    ctx.bstate = BS_BRANCH;                    gen_op_debug();                    goto done_generating;                }            }        }        if (search_pc) {            j = gen_opc_ptr - gen_opc_buf;            if (lj < j) {                lj++;                while (lj < j)                    gen_opc_instr_start[lj++] = 0;            }            gen_opc_pc[lj] = ctx.pc;            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;            gen_opc_instr_start[lj] = 1;        }        ctx.opcode = ldl_code(ctx.pc);        decode_opc(&ctx);        ctx.pc += 4;        if (env->singlestep_enabled)            break;        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)            break;#if defined (MIPS_SINGLE_STEP)        break;#endif    }    if (env->singlestep_enabled) {        save_cpu_state(ctxp, ctx.bstate == BS_NONE);        gen_op_debug();        goto done_generating;    }    else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {        save_cpu_state(ctxp, 0);        gen_goto_tb(&ctx, 0, ctx.pc);    }    gen_op_reset_T0();    /* Generate the return instruction */    gen_op_exit_tb();done_generating:    *gen_opc_ptr = INDEX_op_end;    if (search_pc) {        j = gen_opc_ptr - gen_opc_buf;        lj++;        while (lj <= j)            gen_opc_instr_start[lj++] = 0;        tb->size = 0;    } else {        tb->size = ctx.pc - pc_start;    }#ifdef DEBUG_DISAS#if defined MIPS_DEBUG_DISAS    if (loglevel & CPU_LOG_TB_IN_ASM)        fprintf(logfile, "\n");#endif    if (loglevel & CPU_LOG_TB_IN_ASM) {        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));	target_disas(logfile, pc_start, ctx.pc - pc_start, 0);        fprintf(logfile, "\n");    }    if (loglevel & CPU_LOG_TB_OP) {        fprintf(logfile, "OP:\n");        dump_ops(gen_opc_buf, gen_opparam_buf);        fprintf(logfile, "\n");    }    if (loglevel & CPU_LOG_TB_CPU) {        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);    }#endif        return 0;}int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb){    return gen_intermediate_code_internal(env, tb, 0);}int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb){    return gen_intermediate_code_internal(env, tb, 1);}void cpu_dump_state (CPUState *env, FILE *f,                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),                     int flags){    uint32_t c0_status;    int i;        cpu_fprintf(f, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);    for (i = 0; i < 32; i++) {        if ((i & 3) == 0)            cpu_fprintf(f, "GPR%02d:", i);        cpu_fprintf(f, " %s %08x", regnames[i], env->gpr[i]);        if ((i & 3) == 3)            cpu_fprintf(f, "\n");    }    c0_status = env->CP0_Status;    if (env->hflags & MIPS_HFLAG_UM)        c0_status |= (1 << CP0St_UM);    if (env->hflags & MIPS_HFLAG_ERL)        c0_status |= (1 << CP0St_ERL);    if (env->hflags & MIPS_HFLAG_EXL)        c0_status |= (1 << CP0St_EXL);    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x%08x\n",                c0_status, env->CP0_Cause, env->CP0_EPC);    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n",                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);}CPUMIPSState *cpu_mips_init (void){    CPUMIPSState *env;    env = qemu_mallocz(sizeof(CPUMIPSState));    if (!env)        return NULL;    cpu_exec_init(env);    tlb_flush(env, 1);    /* Minimal init */    env->PC = 0xBFC00000;#if defined (MIPS_USES_R4K_TLB)    env->CP0_random = MIPS_TLB_NB - 1;#endif    env->CP0_Wired = 0;    env->CP0_Config0 = MIPS_CONFIG0;#if defined (MIPS_CONFIG1)        env->CP0_Config1 = MIPS_CONFIG1;#endif#if defined (MIPS_CONFIG2)        env->CP0_Config2 = MIPS_CONFIG2;#endif#if defined (MIPS_CONFIG3)        env->CP0_Config3 = MIPS_CONFIG3;#endif    env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);    env->CP0_WatchLo = 0;    env->hflags = MIPS_HFLAG_ERL;    /* Count register increments in debug mode, EJTAG version 1 */    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);    env->CP0_PRid = MIPS_CPU;    env->exception_index = EXCP_NONE;#if defined(CONFIG_USER_ONLY)    env->hflags |= MIPS_HFLAG_UM;#endif    return env;}

⌨️ 快捷键说明

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