?? translate.c
字號:
MIPS_DEBUG("NOP"); return; } GEN_LOAD_REG_T0(rs); /* Specialcase the conventional move operation. */ if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU || opc == OPC_SUBU || opc == OPC_DSUBU)) { GEN_STORE_T0_REG(rd); return; } GEN_LOAD_REG_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;#if defined(TARGET_MIPS64) case OPC_DADD: save_cpu_state(ctx, 1); gen_op_daddo(); opn = "dadd"; break; case OPC_DADDU: gen_op_dadd(); opn = "daddu"; break; case OPC_DSUB: save_cpu_state(ctx, 1); gen_op_dsubo(); opn = "dsub"; break; case OPC_DSUBU: gen_op_dsub(); opn = "dsubu"; break;#endif 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: switch ((ctx->opcode >> 6) & 0x1f) { case 0: gen_op_srlv(); opn = "srlv"; break; case 1: /* rotrv is decoded as srlv on non-R2 CPUs */ if (env->insn_flags & ISA_MIPS32R2) { gen_op_rotrv(); opn = "rotrv"; } else { gen_op_srlv(); opn = "srlv"; } break; default: MIPS_INVAL("invalid srlv flag"); generate_exception(ctx, EXCP_RI); break; } break;#if defined(TARGET_MIPS64) case OPC_DSLLV: gen_op_dsllv(); opn = "dsllv"; break; case OPC_DSRAV: gen_op_dsrav(); opn = "dsrav"; break; case OPC_DSRLV: switch ((ctx->opcode >> 6) & 0x1f) { case 0: gen_op_dsrlv(); opn = "dsrlv"; break; case 1: /* drotrv is decoded as dsrlv on non-R2 CPUs */ if (env->insn_flags & ISA_MIPS32R2) { gen_op_drotrv(); opn = "drotrv"; } else { gen_op_dsrlv(); opn = "dsrlv"; } break; default: MIPS_INVAL("invalid dsrlv flag"); generate_exception(ctx, EXCP_RI); break; } break;#endif default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } GEN_STORE_T0_REG(rd); 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, uint32_t opc, int reg){ const char *opn = "hilo"; if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); return; } switch (opc) { case OPC_MFHI: gen_op_load_HI(0); GEN_STORE_T0_REG(reg); opn = "mfhi"; break; case OPC_MFLO: gen_op_load_LO(0); GEN_STORE_T0_REG(reg); opn = "mflo"; break; case OPC_MTHI: GEN_LOAD_REG_T0(reg); gen_op_store_HI(0); opn = "mthi"; break; case OPC_MTLO: GEN_LOAD_REG_T0(reg); gen_op_store_LO(0); opn = "mtlo"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s", opn, regnames[reg]);}static void gen_muldiv (DisasContext *ctx, uint32_t opc, int rs, int rt){ const char *opn = "mul/div"; GEN_LOAD_REG_T0(rs); GEN_LOAD_REG_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;#if defined(TARGET_MIPS64) case OPC_DDIV: gen_op_ddiv(); opn = "ddiv"; break; case OPC_DDIVU: gen_op_ddivu(); opn = "ddivu"; break; case OPC_DMULT: gen_op_dmult(); opn = "dmult"; break; case OPC_DMULTU: gen_op_dmultu(); opn = "dmultu"; break;#endif 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(opn); generate_exception(ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);}static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt){ const char *opn = "mul vr54xx"; GEN_LOAD_REG_T0(rs); GEN_LOAD_REG_T1(rt); switch (opc) { case OPC_VR54XX_MULS: gen_op_muls(); opn = "muls"; break; case OPC_VR54XX_MULSU: gen_op_mulsu(); opn = "mulsu"; break; case OPC_VR54XX_MACC: gen_op_macc(); opn = "macc"; 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_T0_gpr(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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -