?? translate.c
字號:
#if defined(TARGET_MIPS64)OP_LD_TABLE(d);OP_LD_TABLE(dl);OP_LD_TABLE(dr);OP_ST_TABLE(d);OP_ST_TABLE(dl);OP_ST_TABLE(dr);OP_LD_TABLE(ld);OP_ST_TABLE(cd);OP_LD_TABLE(wu);#endifOP_LD_TABLE(w);OP_LD_TABLE(wl);OP_LD_TABLE(wr);OP_ST_TABLE(w);OP_ST_TABLE(wl);OP_ST_TABLE(wr);OP_LD_TABLE(h);OP_LD_TABLE(hu);OP_ST_TABLE(h);OP_LD_TABLE(b);OP_LD_TABLE(bu);OP_ST_TABLE(b);OP_LD_TABLE(l);OP_ST_TABLE(c);OP_LD_TABLE(wc1);OP_ST_TABLE(wc1);OP_LD_TABLE(dc1);OP_ST_TABLE(dc1);OP_LD_TABLE(uxc1);OP_ST_TABLE(uxc1);/* Load and store */static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, int base, int16_t offset){ const char *opn = "ldst"; if (base == 0) { GEN_LOAD_IMM_TN(T0, offset); } else if (offset == 0) { gen_op_load_gpr_T0(base); } else { gen_op_load_gpr_T0(base); gen_op_set_T1(offset); gen_op_addr_add(); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) {#if defined(TARGET_MIPS64) case OPC_LWU: op_ldst(lwu); GEN_STORE_T0_REG(rt); opn = "lwu"; break; case OPC_LD: op_ldst(ld); GEN_STORE_T0_REG(rt); opn = "ld"; break; case OPC_LLD: op_ldst(lld); GEN_STORE_T0_REG(rt); opn = "lld"; break; case OPC_SD: GEN_LOAD_REG_T1(rt); op_ldst(sd); opn = "sd"; break; case OPC_SCD: save_cpu_state(ctx, 1); GEN_LOAD_REG_T1(rt); op_ldst(scd); GEN_STORE_T0_REG(rt); opn = "scd"; break; case OPC_LDL: GEN_LOAD_REG_T1(rt); op_ldst(ldl); GEN_STORE_T1_REG(rt); opn = "ldl"; break; case OPC_SDL: GEN_LOAD_REG_T1(rt); op_ldst(sdl); opn = "sdl"; break; case OPC_LDR: GEN_LOAD_REG_T1(rt); op_ldst(ldr); GEN_STORE_T1_REG(rt); opn = "ldr"; break; case OPC_SDR: GEN_LOAD_REG_T1(rt); op_ldst(sdr); opn = "sdr"; break;#endif case OPC_LW: op_ldst(lw); GEN_STORE_T0_REG(rt); opn = "lw"; break; case OPC_SW: GEN_LOAD_REG_T1(rt); op_ldst(sw); opn = "sw"; break; case OPC_LH: op_ldst(lh); GEN_STORE_T0_REG(rt); opn = "lh"; break; case OPC_SH: GEN_LOAD_REG_T1(rt); op_ldst(sh); opn = "sh"; break; case OPC_LHU: op_ldst(lhu); GEN_STORE_T0_REG(rt); opn = "lhu"; break; case OPC_LB: op_ldst(lb); GEN_STORE_T0_REG(rt); opn = "lb"; break; case OPC_SB: GEN_LOAD_REG_T1(rt); op_ldst(sb); opn = "sb"; break; case OPC_LBU: op_ldst(lbu); GEN_STORE_T0_REG(rt); opn = "lbu"; break; case OPC_LWL: GEN_LOAD_REG_T1(rt); op_ldst(lwl); GEN_STORE_T1_REG(rt); opn = "lwl"; break; case OPC_SWL: GEN_LOAD_REG_T1(rt); op_ldst(swl); opn = "swr"; break; case OPC_LWR: GEN_LOAD_REG_T1(rt); op_ldst(lwr); GEN_STORE_T1_REG(rt); opn = "lwr"; break; case OPC_SWR: GEN_LOAD_REG_T1(rt); op_ldst(swr); opn = "swr"; break; case OPC_LL: op_ldst(ll); GEN_STORE_T0_REG(rt); opn = "ll"; break; case OPC_SC: save_cpu_state(ctx, 1); GEN_LOAD_REG_T1(rt); op_ldst(sc); GEN_STORE_T0_REG(rt); opn = "sc"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);}/* Load and store */static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, int base, int16_t offset){ const char *opn = "flt_ldst"; if (base == 0) { GEN_LOAD_IMM_TN(T0, offset); } else if (offset == 0) { gen_op_load_gpr_T0(base); } else { gen_op_load_gpr_T0(base); gen_op_set_T1(offset); gen_op_addr_add(); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { case OPC_LWC1: op_ldst(lwc1); GEN_STORE_FTN_FREG(ft, WT0); opn = "lwc1"; break; case OPC_SWC1: GEN_LOAD_FREG_FTN(WT0, ft); op_ldst(swc1); opn = "swc1"; break; case OPC_LDC1: op_ldst(ldc1); GEN_STORE_FTN_FREG(ft, DT0); opn = "ldc1"; break; case OPC_SDC1: GEN_LOAD_FREG_FTN(DT0, ft); op_ldst(sdc1); opn = "sdc1"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);}/* Arithmetic with immediate operand */static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rs, int16_t imm){ target_ulong uimm; const char *opn = "imm arith"; if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { /* If no destination, treat it as a NOP. For addi, we must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); return; } uimm = (uint16_t)imm; switch (opc) { case OPC_ADDI: case OPC_ADDIU:#if defined(TARGET_MIPS64) case OPC_DADDI: case OPC_DADDIU:#endif case OPC_SLTI: case OPC_SLTIU: uimm = (target_long)imm; /* Sign extend to 32/64 bits */ /* Fall through. */ case OPC_ANDI: case OPC_ORI: case OPC_XORI: GEN_LOAD_REG_T0(rs); GEN_LOAD_IMM_TN(T1, uimm); break; case OPC_LUI: GEN_LOAD_IMM_TN(T0, imm << 16); break; case OPC_SLL: case OPC_SRA: case OPC_SRL:#if defined(TARGET_MIPS64) case OPC_DSLL: case OPC_DSRA: case OPC_DSRL: case OPC_DSLL32: case OPC_DSRA32: case OPC_DSRL32:#endif uimm &= 0x1f; GEN_LOAD_REG_T0(rs); GEN_LOAD_IMM_TN(T1, uimm); break; } switch (opc) { 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. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -