translate.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,182 行 · 第 1/5 页
C
2,182 行
case OPC_ADDI: save_cpu_state(ctx, 1); gen_op_addo(); opn = "addi"; break; case OPC_ADDIU: gen_op_add(); opn = "addiu"; break;#if defined(TARGET_MIPS64) case OPC_DADDI: save_cpu_state(ctx, 1); gen_op_daddo(); opn = "daddi"; break; case OPC_DADDIU: gen_op_dadd(); opn = "daddiu"; break;#endif case OPC_SLTI: gen_op_lt(); opn = "slti"; break; case OPC_SLTIU: gen_op_ltu(); opn = "sltiu"; break; case OPC_ANDI: gen_op_and(); opn = "andi"; break; case OPC_ORI: gen_op_or(); opn = "ori"; break; case OPC_XORI: gen_op_xor(); opn = "xori"; break; case OPC_LUI: opn = "lui"; break; case OPC_SLL: gen_op_sll(); opn = "sll"; break; case OPC_SRA: gen_op_sra(); opn = "sra"; break; case OPC_SRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: gen_op_srl(); opn = "srl"; break; case 1: /* rotr is decoded as srl on non-R2 CPUs */ if (env->insn_flags & ISA_MIPS32R2) { gen_op_rotr(); opn = "rotr"; } else { gen_op_srl(); opn = "srl"; } break; default: MIPS_INVAL("invalid srl flag"); generate_exception(ctx, EXCP_RI); break; } break;#if defined(TARGET_MIPS64) case OPC_DSLL: gen_op_dsll(); opn = "dsll"; break; case OPC_DSRA: gen_op_dsra(); opn = "dsra"; break; case OPC_DSRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: gen_op_dsrl(); opn = "dsrl"; break; case 1: /* drotr is decoded as dsrl on non-R2 CPUs */ if (env->insn_flags & ISA_MIPS32R2) { gen_op_drotr(); opn = "drotr"; } else { gen_op_dsrl(); opn = "dsrl"; } break; default: MIPS_INVAL("invalid dsrl flag"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_DSLL32: gen_op_dsll32(); opn = "dsll32"; break; case OPC_DSRA32: gen_op_dsra32(); opn = "dsra32"; break; case OPC_DSRL32: switch ((ctx->opcode >> 21) & 0x1f) { case 0: gen_op_dsrl32(); opn = "dsrl32"; break; case 1: /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ if (env->insn_flags & ISA_MIPS32R2) { gen_op_drotr32(); opn = "drotr32"; } else { gen_op_dsrl32(); opn = "dsrl32"; } break; default: MIPS_INVAL("invalid dsrl32 flag"); generate_exception(ctx, EXCP_RI); break; } break;#endif default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } GEN_STORE_T0_REG(rt); MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);}/* Arithmetic */static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int rd, int rs, int rt){ const char *opn = "arith"; if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB && opc != OPC_DADD && opc != OPC_DSUB) { /* If no destination, treat it as a NOP. For add & sub, we must generate the overflow exception when needed. */ 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";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?