translate.c

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

C
2,182
字号
        abort();    if (GET_TCGV(temps[num_temps]))      return temps[num_temps++];    tmp = tcg_temp_new(TCG_TYPE_I32);    temps[num_temps++] = tmp;    return tmp;}/* Release a temporary variable.  */static void dead_tmp(TCGv tmp){    int i;    num_temps--;    i = num_temps;    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))        return;    /* Shuffle this temp to the last slot.  */    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))        i--;    while (i < num_temps) {        temps[i] = temps[i + 1];        i++;    }    temps[i] = tmp;}/* General purpose registers moves */const unsigned char *regnames[] =    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };static inline void gen_op_load_gpr_TN(int t_index, int reg){    tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);}static inline void gen_op_load_gpr_T0(int reg){    gen_op_load_gpr_TN(0, reg);}static inline void gen_op_load_gpr_T1(int reg){    gen_op_load_gpr_TN(1, reg);}static inline void gen_op_store_gpr_TN(int t_index, int reg){    tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);}static inline void gen_op_store_gpr_T0(int reg){    gen_op_store_gpr_TN(0, reg);}static inline void gen_op_store_gpr_T1(int reg){    gen_op_store_gpr_TN(1, reg);}/* Moves to/from shadow registers */static inline void gen_op_load_srsgpr_T0(int reg){    int r_tmp = new_tmp();    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);    tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);    dead_tmp(r_tmp);}static inline void gen_op_store_srsgpr_T0(int reg){    int r_tmp = new_tmp();    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);    dead_tmp(r_tmp);}/* Load immediates, zero being a special case. */static inline void gen_op_set_T0(target_ulong arg){    tcg_gen_movi_tl(cpu_T[0], arg);}static inline void gen_op_set_T1(target_ulong arg){    tcg_gen_movi_tl(cpu_T[1], arg);}static inline void gen_op_reset_T0(void){    tcg_gen_movi_tl(cpu_T[0], 0);}static inline void gen_op_reset_T1(void){    tcg_gen_movi_tl(cpu_T[1], 0);}/* Moves to/from HI/LO registers. */static inline void gen_op_load_HI(int reg){    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));}static inline void gen_op_store_HI(int reg){    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));}static inline void gen_op_load_LO(int reg){    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));}static inline void gen_op_store_LO(int reg){    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));}/* Floating point register moves. */static const char *fregnames[] =    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };#define FGEN32(func, NAME)                       \static GenOpFunc *NAME ## _table [32] = {        \NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \};                                               \static always_inline void func(int n)            \{                                                \    NAME ## _table[n]();                         \}FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);#define FOP_CONDS(type, fmt)                                            \static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \    gen_op_cmp ## type ## _ ## fmt ## _f,                               \    gen_op_cmp ## type ## _ ## fmt ## _un,                              \    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \    gen_op_cmp ## type ## _ ## fmt ## _le,                              \    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \};                                                                      \static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \{                                                                       \    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \}FOP_CONDS(, d)FOP_CONDS(abs, d)FOP_CONDS(, s)FOP_CONDS(abs, s)FOP_CONDS(, ps)FOP_CONDS(abs, ps)typedef struct DisasContext {    struct TranslationBlock *tb;    target_ulong pc, saved_pc;    uint32_t opcode;    uint32_t fp_status;    /* Routine used to access memory */    int mem_idx;    uint32_t hflags, saved_hflags;    int bstate;    target_ulong btarget;    void *last_T0_store;    int last_T0_gpr;} DisasContext;enum {    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an                      * exception condition                      */    BS_STOP     = 1, /* We want to stop translation for any reason */    BS_BRANCH   = 2, /* We reached a branch condition     */    BS_EXCP     = 3, /* We reached an exception condition */};#ifdef MIPS_DEBUG_DISAS#define MIPS_DEBUG(fmt, args...)                                              \do {                                                                          \    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \                ctx->pc, ctx->opcode , ##args);                               \    }                                                                         \} while (0)#else#define MIPS_DEBUG(fmt, args...) do { } while(0)#endif#define MIPS_INVAL(op)                                                        \do {                                                                          \    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \} while (0)#define GEN_LOAD_REG_T0(Rn)                                                   \do {                                                                          \    if (Rn == 0) {                                                            \        gen_op_reset_T0();                                                    \    } else {                                                                  \        if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \            || ctx->glue(last_T0, _gpr) != Rn) {                              \                gen_op_load_gpr_T0(Rn);                                       \        }                                                                     \    }                                                                         \} while (0)#define GEN_LOAD_REG_T1(Rn)                                                   \do {                                                                          \    if (Rn == 0) {                                                            \        gen_op_reset_T1();                                                    \    } else {                                                                  \        gen_op_load_gpr_T1(Rn);                                               \    }                                                                         \} while (0)#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \do {                                                                          \    if (Rn == 0) {                                                            \        glue(gen_op_reset_, Tn)();                                            \    } else {                                                                  \        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \    }                                                                         \} while (0)#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \do {                                                                          \    if (Imm == 0) {                                                           \        glue(gen_op_reset_, Tn)();                                            \    } else {                                                                  \        glue(gen_op_set_, Tn)(Imm);                                           \    }                                                                         \} while (0)#define GEN_STORE_T0_REG(Rn)                                                  \do {                                                                          \    if (Rn != 0) {                                                            \        gen_op_store_gpr_T0(Rn);                                              \        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \        ctx->glue(last_T0,_gpr) = Rn;                                         \    }                                                                         \} while (0)#define GEN_STORE_T1_REG(Rn)                                                  \do {                                                                          \    if (Rn != 0)                                                              \        gen_op_store_gpr_T1(Rn);                                              \} while (0)#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \do {                                                                          \    if (Rn != 0)                                                              \        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \} while (0)#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \do {                                                                          \    glue(gen_op_load_fpr_, FTn)(Fn);                                          \} while (0)#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \do {                                                                          \    glue(gen_op_store_fpr_, FTn)(Fn);                                         \} while (0)static always_inline void gen_save_pc(target_ulong pc){#if defined(TARGET_MIPS64)    if (pc == (int32_t)pc) {        gen_op_save_pc(pc);    } else {        gen_op_save_pc64(pc >> 32, (uint32_t)pc);    }#else    gen_op_save_pc(pc);#endif}static always_inline void gen_save_btarget(target_ulong btarget){#if defined(TARGET_MIPS64)    if (btarget == (int32_t)btarget) {        gen_op_save_btarget(btarget);    } else {        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);    }#else    gen_op_save_btarget(btarget);#endif}static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc){#if defined MIPS_DEBUG_DISAS    if (loglevel & CPU_LOG_TB_IN_ASM) {            fprintf(logfile, "hflags %08x saved %08x\n",                    ctx->hflags, ctx->saved_hflags);    }#endif    if (do_save_pc && ctx->pc != ctx->saved_pc) {        gen_save_pc(ctx->pc);        ctx->saved_pc = ctx->pc;    }    if (ctx->hflags != ctx->saved_hflags) {        gen_op_save_state(ctx->hflags);        ctx->saved_hflags = ctx->hflags;        switch (ctx->hflags & MIPS_HFLAG_BMASK) {        case MIPS_HFLAG_BR:            break;        case MIPS_HFLAG_BC:        case MIPS_HFLAG_BL:        case MIPS_HFLAG_B:            gen_save_btarget(ctx->btarget);            break;        }    }}static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx){    ctx->saved_hflags = ctx->hflags;    switch (ctx->hflags & MIPS_HFLAG_BMASK) {    case MIPS_HFLAG_BR:        break;    case MIPS_HFLAG_BC:    case MIPS_HFLAG_BL:    case MIPS_HFLAG_B:        ctx->btarget = env->btarget;        break;    }}static always_inline voidgenerate_tcg_exception_err (DisasContext *ctx, int excp, int err){    save_cpu_state(ctx, 1);    if (err == 0)        gen_op_raise_exception(excp);    else        gen_op_raise_exception_err(excp, err);    gen_op_interrupt_restart();    tcg_gen_exit_tb(0);}static always_inline voidgenerate_tcg_exception (DisasContext *ctx, int excp){    generate_tcg_exception_err (ctx, excp, 0);}static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err){#if defined MIPS_DEBUG_DISAS    if (loglevel & CPU_LOG_TB_IN_ASM)            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);#endif    save_cpu_state(ctx, 1);    if (err == 0)        gen_op_raise_exception(excp);    else        gen_op_raise_exception_err(excp, err);    ctx->bstate = BS_EXCP;}static always_inline void generate_exception (DisasContext *ctx, int excp){    generate_exception_err (ctx, excp, 0);}static always_inline void check_cp0_enabled(DisasContext *ctx){    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))

⌨️ 快捷键说明

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