?? translate.c
字號:
OPC_NMSUB_S = 0x38 | OPC_CP3, OPC_NMSUB_D = 0x39 | OPC_CP3, OPC_NMSUB_PS= 0x3E | OPC_CP3,};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", };/* Warning: no function for r0 register (hard wired to zero) */#define GEN32(func, NAME) \static GenOpFunc *NAME ## _table [32] = { \NULL, 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](); \}/* General purpose registers moves */GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);/* Moves to/from shadow registers */GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);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_REG_T2(Rn) \do { \ if (Rn == 0) { \ gen_op_reset_T2(); \ } else { \ gen_op_load_gpr_T2(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)#if defined(TARGET_MIPS64)#define GEN_LOAD_IMM_TN(Tn, Imm) \do { \ if (Imm == 0) { \ glue(gen_op_reset_, Tn)(); \ } else if ((int32_t)Imm == Imm) { \ glue(gen_op_set_, Tn)(Imm); \ } else { \ glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm); \ } \} while (0)#else#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)#endif#define GEN_STORE_T0_REG(Rn) \do { \ if (Rn != 0) { \ glue(gen_op_store_T0,_gpr)(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) \ glue(gen_op_store_T1,_gpr)(Rn); \} while (0)#define GEN_STORE_TN_SRSREG(Rn, Tn) \do { \ if (Rn != 0) { \ glue(glue(gen_op_store_, Tn),_srsgpr)(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: gen_op_save_breg_target(); break; case MIPS_HFLAG_BC: gen_op_save_bcond(); /* fall through */ case MIPS_HFLAG_BL: /* bcond was already saved by the BL insn */ /* fall through */ 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: gen_op_restore_breg_target(); break; case MIPS_HFLAG_B: ctx->btarget = env->btarget; break; case MIPS_HFLAG_BC: case MIPS_HFLAG_BL: ctx->btarget = env->btarget; gen_op_restore_bcond(); break; }}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))) generate_exception_err(ctx, EXCP_CpU, 1);}static always_inline void check_cp1_enabled(DisasContext *ctx){ if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) generate_exception_err(ctx, EXCP_CpU, 1);}/* Verify that the processor is running with COP1X instructions enabled. This is associated with the nabla symbol in the MIPS32 and MIPS64 opcode tables. */static always_inline void check_cop1x(DisasContext *ctx){ if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) generate_exception(ctx, EXCP_RI);}/* Verify that the processor is running with 64-bit floating-point operations enabled. */static always_inline void check_cp1_64bitmode(DisasContext *ctx){ if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) generate_exception(ctx, EXCP_RI);}/* * Verify if floating point register is valid; an operation is not defined * if bit 0 of any register specification is set and the FR bit in the * Status register equals zero, since the register numbers specify an * even-odd pair of adjacent coprocessor general registers. When the FR bit * in the Status register equals one, both even and odd register numbers * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. * * Multiple 64 bit wide registers can be checked by calling * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); */void check_cp1_registers(DisasContext *ctx, int regs){ if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) generate_exception(ctx, EXCP_RI);}/* This code generates a "reserved instruction" exception if the CPU does not support the instruction set corresponding to flags. */static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags){ if (unlikely(!(env->insn_flags & flags))) generate_exception(ctx, EXCP_RI);}/* This code generates a "reserved instruction" exception if 64-bit instructions are not enabled. */static always_inline void check_mips_64(DisasContext *ctx){ if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) generate_exception(ctx, EXCP_RI);}#if defined(CONFIG_USER_ONLY)#define op_ldst(name) gen_op_##name##_raw()#define OP_LD_TABLE(width)#define OP_ST_TABLE(width)#else#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()#define OP_LD_TABLE(width) \static GenOpFunc *gen_op_l##width[] = { \ &gen_op_l##width##_kernel, \ &gen_op_l##width##_super, \ &gen_op_l##width##_user, \}#define OP_ST_TABLE(width) \static GenOpFunc *gen_op_s##width[] = { \ &gen_op_s##width##_kernel, \ &gen_op_s##width##_super, \ &gen_op_s##width##_user, \}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -