translate.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,182 行 · 第 1/5 页
C
2,182 行
break; case OPC_VR54XX_MACCU: gen_op_maccu(); opn = "maccu"; break; case OPC_VR54XX_MSAC: gen_op_msac(); opn = "msac"; break; case OPC_VR54XX_MSACU: gen_op_msacu(); opn = "msacu"; break; case OPC_VR54XX_MULHI: gen_op_mulhi(); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: gen_op_mulhiu(); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: gen_op_mulshi(); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: gen_op_mulshiu(); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: gen_op_macchi(); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: gen_op_macchiu(); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: gen_op_msachi(); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: gen_op_msachiu(); opn = "msachiu"; break; default: MIPS_INVAL("mul vr54xx"); generate_exception(ctx, EXCP_RI); return; } GEN_STORE_T0_REG(rd); MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);}static void gen_cl (DisasContext *ctx, uint32_t opc, int rd, int rs){ const char *opn = "CLx"; if (rd == 0) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); return; } GEN_LOAD_REG_T0(rs); switch (opc) { case OPC_CLO: gen_op_clo(); opn = "clo"; break; case OPC_CLZ: gen_op_clz(); opn = "clz"; break;#if defined(TARGET_MIPS64) case OPC_DCLO: gen_op_dclo(); opn = "dclo"; break; case OPC_DCLZ: gen_op_dclz(); opn = "dclz"; break;#endif default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } gen_op_store_gpr_T0(rd); MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);}/* Traps */static void gen_trap (DisasContext *ctx, uint32_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_T0(rs); GEN_LOAD_REG_T1(rt); cond = 1; } break; 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_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"); generate_exception(ctx, EXCP_RI); return; } } else { switch (opc) { case OPC_TEQ: case OPC_TEQI: gen_op_eq(); break; case OPC_TGE: case OPC_TGEI: gen_op_ge(); break; case OPC_TGEU: case OPC_TGEIU: gen_op_geu(); break; case OPC_TLT: case OPC_TLTI: gen_op_lt(); break; case OPC_TLTU: case OPC_TLTIU: gen_op_ltu(); break; case OPC_TNE: case OPC_TNEI: gen_op_ne(); break; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); return; } } save_cpu_state(ctx, 1); gen_op_trap(); ctx->bstate = BS_STOP;}static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest){ TranslationBlock *tb; tb = ctx->tb; if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); gen_save_pc(dest); tcg_gen_exit_tb((long)tb + n); } else { gen_save_pc(dest); tcg_gen_exit_tb(0); }}static inline void tcg_gen_set_bcond(void){ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));}static inline void tcg_gen_jnz_bcond(int label){ int r_tmp = tcg_temp_new(TCG_TYPE_TL); tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond)); tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_tl(0), label);}/* Branches (before delay slot) */static void gen_compute_branch (DisasContext *ctx, uint32_t opc, int rs, int rt, int32_t offset){ target_ulong btarget = -1; int blink = 0; int bcond = 0; if (ctx->hflags & MIPS_HFLAG_BMASK) {#ifdef MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc); }#endif generate_exception(ctx, EXCP_RI); return; } /* Load needed operands */ switch (opc) { case OPC_BEQ: case OPC_BEQL: case OPC_BNE: case OPC_BNEL: /* Compare two registers */ if (rs != rt) { GEN_LOAD_REG_T0(rs); GEN_LOAD_REG_T1(rt); bcond = 1; } btarget = ctx->pc + 4 + offset; break; case OPC_BGEZ: case OPC_BGEZAL: case OPC_BGEZALL: case OPC_BGEZL: case OPC_BGTZ: case OPC_BGTZL: case OPC_BLEZ: case OPC_BLEZL: case OPC_BLTZ: case OPC_BLTZAL: case OPC_BLTZALL: case OPC_BLTZL: /* Compare to zero */ if (rs != 0) { gen_op_load_gpr_T0(rs); bcond = 1; } btarget = ctx->pc + 4 + offset; break; case OPC_J: case OPC_JAL: /* Jump to immediate */ btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset; break; case OPC_JR: case OPC_JALR: /* Jump to register */ if (offset != 0 && offset != 16) { /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the others are reserved. */ MIPS_INVAL("jump hint"); generate_exception(ctx, EXCP_RI); return; } GEN_LOAD_REG_T1(rs); gen_op_save_breg_target(); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); return; } if (bcond == 0) { /* No condition to be computed */ switch (opc) { case OPC_BEQ: /* rx == rx */ case OPC_BEQL: /* rx == rx likely */ case OPC_BGEZ: /* 0 >= 0 */ case OPC_BGEZL: /* 0 >= 0 likely */ case OPC_BLEZ: /* 0 <= 0 */ case OPC_BLEZL: /* 0 <= 0 likely */ /* Always take */ ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways"); break; case OPC_BGEZAL: /* 0 >= 0 */ case OPC_BGEZALL: /* 0 >= 0 likely */ /* Always take and link */ blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways and link"); break; case OPC_BNE: /* rx != rx */ case OPC_BGTZ: /* 0 > 0 */ case OPC_BLTZ: /* 0 < 0 */ /* Treat as NOP. */ MIPS_DEBUG("bnever (NOP)"); return; case OPC_BLTZAL: /* 0 < 0 */ GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_gpr_T0(31); MIPS_DEBUG("bnever and link"); return; case OPC_BLTZALL: /* 0 < 0 likely */ GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_gpr_T0(31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); ctx->pc += 4; return; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ case OPC_BLTZL: /* 0 < 0 likely */ /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); ctx->pc += 4; return; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j " TARGET_FMT_lx, btarget); break; case OPC_JAL: blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("jal " TARGET_FMT_lx, btarget); break; case OPC_JR: ctx->hflags |= MIPS_HFLAG_BR; MIPS_DEBUG("jr %s", regnames[rs]); break; case OPC_JALR: blink = rt; ctx->hflags |= MIPS_HFLAG_BR; MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); return; } } else { switch (opc) { case OPC_BEQ: gen_op_eq(); MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: gen_op_eq(); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: gen_op_ne(); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: gen_op_ne(); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: gen_op_gez(); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGEZL: gen_op_gez(); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGEZAL: gen_op_gez(); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: gen_op_gez(); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGTZ: gen_op_gtz(); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGTZL: gen_op_gtz(); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLEZ: gen_op_lez(); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLEZL: gen_op_lez(); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZ: gen_op_ltz(); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLTZL: gen_op_ltz(); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZAL: gen_op_ltz(); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget); not_likely: ctx->hflags |= MIPS_HFLAG_BC; tcg_gen_set_bcond(); break; case OPC_BLTZALL: gen_op
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?