/// <summary> /// 引数で渡された32bit長の命令をデコードし、cpuで実行する /// </summary> /// <param name="instruction">32bit長の命令</param> /// <param name="cpu">命令を実行するRV32CPU</param> /// <returns>実行の成否</returns> internal protected override bool Exec(UInt32[] ins) { bool result = false; // 命令の0~1bit目が "11" でない場合は対象なし if ((ins[0] & 0b11U) != 0b11U) { return(result); } Register rd = (Register)ins[1], rs1 = (Register)ins[3], rs2 = (Register)ins[4]; Opcode opcode = (Opcode)ins[0]; Funct3 funct3 = (Funct3)ins[2]; Funct7 funct7 = (Funct7)(ins[5] + (ins[6] << 6)); RV32_Mac alu; if (opcode == Opcode.miscOp && funct7 == Funct7.mul_div) // Op系命令(算術論理演算) { alu = (RV32_Mac)Decoder.Alu(typeof(RV32_Mac)); switch (funct3) { case Funct3.mul: // mul命令 result = alu.Mul(rd, rs1, rs2); break; case Funct3.mulh: // mulh命令 result = alu.Mulh(rd, rs1, rs2); break; case Funct3.mulhsu: // mulhsu命令 result = alu.Mulhsu(rd, rs1, rs2); break; case Funct3.mulhu: // mulhu命令 result = alu.Mulhu(rd, rs1, rs2); break; case Funct3.div: // div命令 result = alu.Div(rd, rs1, rs2); break; case Funct3.divu: // divu命令 result = alu.Divu(rd, rs1, rs2); break; case Funct3.rem: // rem命令 result = alu.Rem(rd, rs1, rs2); break; case Funct3.remu: // remu命令 result = alu.Remu(rd, rs1, rs2); break; } } return(result); }
/// <summary> /// 引数で渡された32bit長の命令をデコードし、cpuで実行する /// </summary> /// <param name="instruction">32bit長の命令</param> /// <param name="cpu">命令を実行するRV32CPU</param> /// <returns>実行の成否</returns> internal protected override bool Exec(UInt32[] ins) { bool result = false; // 命令の0~1bit目が "11" でない場合は対象なし if ((ins[0] & 0b11U) != 0b11U) { return(result); } FPRegister rd = (FPRegister)ins[1], rs1 = (FPRegister)ins[3], rs2 = (FPRegister)ins[4], rs3 = (FPRegister)((ins[5] >> 2) | (ins[6] << 4)); Opcode opcode = (Opcode)ins[0]; Funct3 funct3 = (Funct3)ins[2]; Funct5 funct5 = (Funct5)(ins[5] >> 2 | (ins[6] << 4)); FloatRoundingMode frm = (FloatRoundingMode)ins[2]; Int32 immediate = 0; RV32_SingleFpu fpu; RV32_FloatPointLsu lsu; switch (opcode) { case Opcode.fl when funct3 == Funct3.flw_fsw: // flw命令 immediate = GetImmediate('I', ins); lsu = (RV32_FloatPointLsu)Decoder.Lsu(typeof(RV32_FloatPointLsu)); result = lsu.Flw(rd, (Register)rs1, immediate); break; case Opcode.fs when funct3 == Funct3.flw_fsw: // fsw命令 immediate = GetImmediate('S', ins); lsu = (RV32_FloatPointLsu)Decoder.Lsu(typeof(RV32_FloatPointLsu)); result = lsu.Fsw((Register)rs1, rs2, immediate); break; case Opcode.fmadd when(ins[5]& 0x3U) == 0x0U: // fmadds命令 fpu = (RV32_SingleFpu)Decoder.Alu(typeof(RV32_SingleFpu)); result = fpu.FmaddS(rd, rs1, rs2, rs3, frm); break; case Opcode.fmsub when(ins[5]& 0x3U) == 0x0U: // fmsubs命令 fpu = (RV32_SingleFpu)Decoder.Alu(typeof(RV32_SingleFpu)); result = fpu.FmsubS(rd, rs1, rs2, rs3, frm); break; case Opcode.fnmadd when(ins[5]& 0x3U) == 0x0U: // fnmadds命令 fpu = (RV32_SingleFpu)Decoder.Alu(typeof(RV32_SingleFpu)); result = fpu.FnmaddS(rd, rs1, rs2, rs3, frm); break; case Opcode.fnmsub when(ins[5]& 0x3U) == 0x0U: // fnmsubs命令 fpu = (RV32_SingleFpu)Decoder.Alu(typeof(RV32_SingleFpu)); result = fpu.FnmsubS(rd, rs1, rs2, rs3, frm); break; case Opcode.fmiscOp when(ins[5]& 0x3U) == 0x0U: // Single Float-Point Op系命令(算術論理演算) fpu = (RV32_SingleFpu)Decoder.Alu(typeof(RV32_SingleFpu)); switch (funct5) { case Funct5.fadd: // fadds命令 result = fpu.FaddS(rd, rs1, rs2, frm); break; case Funct5.fsub: // fsubs命令 result = fpu.FsubS(rd, rs1, rs2, frm); break; case Funct5.fmul: // fmuls命令 result = fpu.FmulS(rd, rs1, rs2, frm); break; case Funct5.fdiv: // fmuls命令 result = fpu.FdivS(rd, rs1, rs2, frm); break; case Funct5.fsqrt: // fsqrts命令 result = fpu.FsqrtS(rd, rs1, frm); break; case Funct5.fsgnj: switch (funct3) { case Funct3.fsgnj: // fsgnjs命令 result = fpu.FsgnjS(rd, rs1, rs2); break; case Funct3.fsgnjn: // fsgnjns命令 result = fpu.FsgnjnS(rd, rs1, rs2); break; case Funct3.fsgnjx: // fsgnjxs命令 result = fpu.FsgnjxS(rd, rs1, rs2); break; } break; case Funct5.fmin_fmax: switch (funct3) { case Funct3.fmin: // fmins命令 result = fpu.FminS(rd, rs1, rs2); break; case Funct3.fmax: // fmaxs命令 result = fpu.FmaxS(rd, rs1, rs2); break; } break; case Funct5.fcompare: switch (funct3) { case Funct3.fcompare_eq: // feqs命令 result = fpu.FeqS((Register)rd, rs1, rs2); break; case Funct3.fcompare_lt: // flts命令 result = fpu.FltS((Register)rd, rs1, rs2); break; case Funct3.fcompare_le: // fles命令 result = fpu.FleS((Register)rd, rs1, rs2); break; } break; case Funct5.fcvttoW: switch (ins[4]) { case 0x0: // fcnvws命令 result = fpu.FcvtWS((Register)rd, rs1, frm); break; case 0x1: // fcnvwus命令 result = fpu.FcvtWUS((Register)rd, rs1, frm); break; } break; case Funct5.fcvtfromW: switch (ins[4]) { case 0x0: // fcnvsw命令 result = fpu.FcvtSW(rd, (Register)rs1, frm); break; case 0x1: // fcnvswu命令 result = fpu.FcvtSWU(rd, (Register)rs1, frm); break; } break; case Funct5.fmvXW_fclass: if (funct3 == (Funct3)0b000u) // fmvxw命令 { result = fpu.FmvXW((Register)rd, rs1); } else if (funct3 == (Funct3)0b001u) // fclasss命令 { result = fpu.FclassS((Register)rd, rs1); } break; case Funct5.fmvWX: // fmvwx命令 result = fpu.FmvWX(rd, (Register)rs1); break; } break; } return(result); }
/// <summary> /// 引数で渡された32bit長の命令をデコードし、cpuで実行する /// </summary> /// <param name="instruction">32bit長の命令</param> /// <param name="cpu">命令を実行するRV32CPU</param> /// <returns>実行の成否</returns> internal protected override bool Exec(UInt32[] ins) { bool result = false; // 命令の0~1bit目が "11" でない場合は対象なし if ((ins[0] & 0b11U) != 0b11U) { return(result); } FPRegister rd = (FPRegister)ins[1], rs1 = (FPRegister)ins[3], rs2 = (FPRegister)ins[4], rs3 = (FPRegister)((ins[5] >> 2) | (ins[6] << 4)); Opcode opcode = (Opcode)ins[0]; Funct3 funct3 = (Funct3)ins[2]; Funct5 funct5 = (Funct5)(ins[5] >> 2 | (ins[6] << 4)); FloatRoundingMode frm = (FloatRoundingMode)ins[2]; Int32 immediate = 0; RV32_DoubleFpu fpu; RV32_FloatPointLsu lsu; switch (opcode) { case Opcode.fl when funct3 == Funct3.fld_fsd: // fld命令 immediate = GetImmediate('I', ins); lsu = (RV32_FloatPointLsu)Decoder.Lsu(typeof(RV32_FloatPointLsu)); result = lsu.Fld(rd, (Register)rs1, immediate); break; case Opcode.fs when funct3 == Funct3.fld_fsd: // fsd命令 immediate = GetImmediate('S', ins); lsu = (RV32_FloatPointLsu)Decoder.Lsu(typeof(RV32_FloatPointLsu)); result = lsu.Fsd((Register)rs1, rs2, immediate); break; case Opcode.fmadd when(ins[5]& 0x3U) == 0x1U: // fmaddd命令 fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); result = fpu.FmaddD(rd, rs1, rs2, rs3, frm); break; case Opcode.fmsub when(ins[5]& 0x3U) == 0x1U: // fmsubd命令 fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); result = fpu.FmsubD(rd, rs1, rs2, rs3, frm); break; case Opcode.fnmadd when(ins[5]& 0x3U) == 0x1U: // fnmaddd命令 fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); result = fpu.FnmaddD(rd, rs1, rs2, rs3, frm); break; case Opcode.fnmsub when(ins[5]& 0x3U) == 0x1U: // fnmsubd命令 fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); result = fpu.FnmsubD(rd, rs1, rs2, rs3, frm); break; case Opcode.fmiscOp when(ins[5]& 0x3U) == 0x1U: // Double Float-Point Op系命令(算術論理演算) fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); switch (funct5) { case Funct5.fadd: // faddd命令 result = fpu.FaddD(rd, rs1, rs2, frm); break; case Funct5.fsub: // fsubd命令 result = fpu.FsubD(rd, rs1, rs2, frm); break; case Funct5.fmul: // fmuld命令 result = fpu.FmulD(rd, rs1, rs2, frm); break; case Funct5.fdiv: // fdivd命令 result = fpu.FdivD(rd, rs1, rs2, frm); break; case Funct5.fsqrt: // fsqrtd命令 result = fpu.FsqrtD(rd, rs1, frm); break; case Funct5.fsgnj: switch (funct3) { case Funct3.fsgnj: // fsgnjd命令 result = fpu.FsgnjD(rd, rs1, rs2); break; case Funct3.fsgnjn: // fsgnjnd命令 result = fpu.FsgnjnD(rd, rs1, rs2); break; case Funct3.fsgnjx: // fsgnjxd命令 result = fpu.FsgnjxD(rd, rs1, rs2); break; } break; case Funct5.fmin_fmax: switch (funct3) { case Funct3.fmin: // fmind命令 result = fpu.FminD(rd, rs1, rs2); break; case Funct3.fmax: // fmaxd命令 result = fpu.FmaxD(rd, rs1, rs2); break; } break; case Funct5.fcompare: switch (funct3) { case Funct3.fcompare_eq: // feqd命令 result = fpu.FeqD((Register)rd, rs1, rs2); break; case Funct3.fcompare_lt: // fltd命令 result = fpu.FltD((Register)rd, rs1, rs2); break; case Funct3.fcompare_le: // fled命令 result = fpu.FleD((Register)rd, rs1, rs2); break; } break; case Funct5.fcvttoW: switch (ins[4]) { case 0x0: // fcvtwd命令 result = fpu.FcvtWD((Register)rd, rs1, frm); break; case 0x1: // fcvtwud命令 result = fpu.FcvtWUD((Register)rd, rs1, frm); break; } break; case Funct5.fcvtfromW: switch (ins[4]) { case 0x0: // fcvtdw命令 result = fpu.FcvtDW(rd, (Register)rs1, frm); break; case 0x1: // fcvtdwu命令 result = fpu.FcvtDWU(rd, (Register)rs1, frm); break; } break; case Funct5.fmvXW_fclass: // fclassd命令 result = fpu.FclassD((Register)rd, rs1); break; case Funct5.fcvtSD: // fcvtds命令 result = fpu.FcvtDS(rd, rs1, frm); break; } break; case Opcode.fmiscOp when(ins[5]& 0x3U) == 0x0U && funct5 == Funct5.fcvtSD: // fcvtsd命令 fpu = (RV32_DoubleFpu)Decoder.Alu(typeof(RV32_DoubleFpu)); result = fpu.FcvtSD(rd, rs1, frm); break; } return(result); }
/// <summary> /// 引数で渡された32bit長の命令をデコードし、cpuで実行する /// </summary> /// <param name="instruction">32bit長の命令</param> /// <param name="cpu">命令を実行するRV32CPU</param> /// <returns>実行の成否</returns> internal protected override bool Exec(UInt32[] ins) { bool result = false; // 命令の0~1bit目が "11" でない場合は対象なし if ((ins[0] & 0b11U) != 0b11U) { return(result); } Register rd = (Register)ins[1], rs1 = (Register)ins[3], rs2 = (Register)ins[4]; Opcode opcode = (Opcode)ins[0]; Funct3 funct3 = (Funct3)ins[2]; Funct7 funct7 = (Funct7)(ins[5] | (ins[6] << 6)); Int32 immediate = 0; RV32_IntegerAlu alu; RV32_IntegerLsu lsu; switch (opcode) { case Opcode.lui: // lui命令 immediate = GetImmediate('U', ins); alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); result = alu.Lui(rd, immediate); break; case Opcode.auipc: // auipc命令 immediate = GetImmediate('U', ins); alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); result = alu.Auipc(rd, immediate); break; case Opcode.jal: // jal命令 immediate = GetImmediate('J', ins); result = Decoder.Reg.Jal(rd, immediate); break; case Opcode.jalr: // jalr命令 if (funct3 == Funct3.jalr) { immediate = GetImmediate('I', ins); result = Decoder.Reg.Jalr(rd, rs1, immediate); } break; case Opcode.branch: // Branch系命令 immediate = GetImmediate('B', ins); switch (funct3) { case Funct3.beq: // beq命令 result = Decoder.Reg.Beq(rs1, rs2, immediate); break; case Funct3.bne: // bne命令 result = Decoder.Reg.Bne(rs1, rs2, immediate); break; case Funct3.blt: // blt命令 result = Decoder.Reg.Blt(rs1, rs2, immediate); break; case Funct3.bge: // bge命令 result = Decoder.Reg.Bge(rs1, rs2, immediate); break; case Funct3.bltu: // bltu命令 result = Decoder.Reg.Bltu(rs1, rs2, immediate); break; case Funct3.bgeu: // bgeu命令 result = Decoder.Reg.Bgeu(rs1, rs2, immediate); break; } break; case Opcode.load: // Load系命令 immediate = GetImmediate('I', ins); lsu = (RV32_IntegerLsu)Decoder.Lsu(typeof(RV32_IntegerLsu)); switch (funct3) { case Funct3.lb: // lb命令 result = lsu.Lb(rd, rs1, immediate); break; case Funct3.lh: // lh命令 result = lsu.Lh(rd, rs1, immediate); break; case Funct3.lw: //010 lw命令 result = lsu.Lw(rd, rs1, immediate); break; case Funct3.lbu: //001 lbu命令 result = lsu.Lbu(rd, rs1, immediate); break; case Funct3.lhu: //101 lhu命令 result = lsu.Lhu(rd, rs1, immediate); break; } break; case Opcode.store: // Store系命令 immediate = GetImmediate('S', ins); lsu = (RV32_IntegerLsu)Decoder.Lsu(typeof(RV32_IntegerLsu)); switch (funct3) { case Funct3.sb: // sb命令 result = lsu.Sb(rs1, rs2, immediate); break; case Funct3.sh: // sh命令 result = lsu.Sh(rs1, rs2, immediate); break; case Funct3.sw: // sw命令 result = lsu.Sw(rs1, rs2, immediate); break; } break; case Opcode.miscOpImm: // Op-imm系命令(即値算術論理演算) alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); switch (funct3) { case Funct3.addi: // addi命令 immediate = GetImmediate('I', ins); result = alu.Addi(rd, rs1, immediate); break; case Funct3.xori: // xori命令 immediate = GetImmediate('I', ins); result = alu.Xori(rd, rs1, immediate); break; case Funct3.ori: // ori命令 immediate = GetImmediate('I', ins); result = alu.Ori(rd, rs1, immediate); break; case Funct3.andi: // andi命令 immediate = GetImmediate('I', ins); result = alu.Andi(rd, rs1, immediate); break; case Funct3.slti: // slti命令 immediate = GetImmediate('I', ins); result = alu.Slti(rd, rs1, immediate); break; case Funct3.sltiu: //110 sltiu命令 immediate = GetImmediate('I', ins); result = alu.Sltiu(rd, rs1, immediate); break; case Funct3.slli when funct7 == Funct7.slli: // slli命令 result = alu.Slli(rd, rs1, (Int32)ins[4]); break; case Funct3.srli_srai when funct7 == Funct7.srli: // srli命令 result = alu.Srli(rd, rs1, (Int32)ins[4]); break; case Funct3.srli_srai when funct7 == Funct7.srai: // srai命令 result = alu.Srai(rd, rs1, (Int32)ins[4]); break; } break; case Opcode.miscOp: // Op系命令(算術論理演算) alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); switch (((UInt16)funct3 | ((UInt16)funct7 << 3))) { case (UInt16)Funct3.add_sub | ((UInt16)Funct7.add << 3): // add命令 result = alu.Add(rd, rs1, rs2); break; case (UInt16)Funct3.add_sub | ((UInt16)Funct7.sub << 3): // sub命令 result = alu.Sub(rd, rs1, rs2); break; case (UInt16)Funct3.xor | ((UInt16)Funct7.xor << 3): // xor命令 result = alu.Xor(rd, rs1, rs2); break; case (UInt16)Funct3.or | ((UInt16)Funct7.or << 3): // or命令 result = alu.Or(rd, rs1, rs2); break; case (UInt16)Funct3.and | ((UInt16)Funct7.and << 3): // and命令 result = alu.And(rd, rs1, rs2); break; case (UInt16)Funct3.slt | ((UInt16)Funct7.slt << 3): // slt命令 result = alu.Slt(rd, rs1, rs2); break; case (UInt16)Funct3.sltu | ((UInt16)Funct7.sltu << 3): // sltu命令 result = alu.Sltu(rd, rs1, rs2); break; case (UInt16)Funct3.sll | ((UInt16)Funct7.sll << 3): // sll命令 result = alu.Sll(rd, rs1, rs2); break; case (UInt16)Funct3.srl_sra | ((UInt16)Funct7.srl << 3): // srl命令 result = alu.Srl(rd, rs1, rs2); break; case (UInt16)Funct3.srl_sra | ((UInt16)Funct7.sra << 3): // sra命令 result = alu.Sra(rd, rs1, rs2); break; } break; case Opcode.miscMem: // 同期命令 switch (funct3) { case Funct3.fence: // fence命令 result = Decoder.Reg.Fence((byte)(((ins[5] & 0x7) << 5) | ins[4])); break; case Funct3.fenceI: // fence.i命令 result = Decoder.Reg.FenceI(); break; } break; case Opcode.system: // システム命令 switch (funct3) { case Funct3.privilege: // 特権命令 if (rd == 0 && funct7 == Funct7.sfenceVma) { result = Decoder.Reg.SfenceVma(rs1, rs2); } else if (rd == 0 && rs1 == 0) { Funct12 funct12 = (Funct12)(ins[4] | (ins[5] << 5) | (ins[6] << 11));; switch (funct12) { case Funct12.ecall: result = Decoder.Reg.Ecall(); break; case Funct12.ebreak: result = Decoder.Reg.Ebreak(); break; case Funct12.mret: result = Decoder.Reg.Mret(); break; case Funct12.sret: result = Decoder.Reg.Sret(); break; case Funct12.uret: result = Decoder.Reg.Uret(); break; case Funct12.wfi: result = Decoder.Reg.Wfi(); break; } } break; case Funct3.csrrw: // csrrw命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrw(rd, rs1, (CSR)immediate); break; case Funct3.csrrs: // csrrs命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrs(rd, rs1, (CSR)immediate); break; case Funct3.csrrc: // csrrc命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrc(rd, rs1, (CSR)immediate); break; case Funct3.csrrwi: // csrrwi命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrwi(rd, (byte)ins[3], (CSR)immediate); break; case Funct3.csrrsi: // csrrsi命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrsi(rd, (byte)ins[3], (CSR)immediate); break; case Funct3.csrrci: // csrrci命令 immediate = (GetImmediate('I', ins) & 0xfff); result = Decoder.Reg.Csrrci(rd, (byte)ins[3], (CSR)immediate); break; } break; } return(result); }
/// <summary> /// 引数で渡された32bit長のうち、前半の16bitを命令としてデコードし、cpuで実行する /// </summary> /// <param name="instruction">32bit長の命令</param> /// <param name="cpu">命令を実行するRV32CPU</param> /// <returns>実行の成否</returns> internal protected override bool Exec(UInt32[] ins) { bool result = false; // 命令の0~1bit目が "11" の場合は対象なし if ((ins[0] & 0b11U) == 0b11U) { return(result); } // 32bit長命令の前半から16bit長命令を取り出し UInt32[] cins = SplitCompressedInstruction(ins); Register rd_rs1 = (Register)(cins[2] & 0x1f), rs2 = (Register)cins[1], crd_rs1 = (Register)(0x8 | (cins[2] & 0x7)), crs2 = (Register)(0x8 | (cins[1] & 0x7)); CompressedOpcode opcode = (CompressedOpcode)cins[0]; Int32 immediate = 0; RV32_IntegerAlu alu; RV32_IntegerLsu lsu; RV32_FloatPointLsu fplsu; switch (opcode) { case CompressedOpcode.addi: // addi命令 alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); immediate = GetSignedImmediate("CI", cins); result = alu.Addi(rd_rs1, rd_rs1, immediate, InstructionLength); break; case CompressedOpcode.misc_alu: alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); switch (cins[2] & 0b111000) { case 0b000000: // srli命令 immediate = GetUnsignedImmediate("CI", cins); result = alu.Srli(crd_rs1, crd_rs1, immediate, InstructionLength); break; case 0b001000: // srai命令 immediate = GetUnsignedImmediate("CI", cins); result = alu.Srai(crd_rs1, crd_rs1, immediate, InstructionLength); break; case 0b010000: case 0b110000: // andi命令 immediate = GetSignedImmediate("CI", cins); result = alu.Andi(crd_rs1, crd_rs1, immediate, InstructionLength); break; case 0b011000: switch (cins[1] & 0b11000) { case 0b00000: // sub命令 result = alu.Sub(crd_rs1, crd_rs1, crs2, InstructionLength); break; case 0b01000: // xor命令 result = alu.Xor(crd_rs1, crd_rs1, crs2, InstructionLength); break; case 0b10000: // or命令 result = alu.Or(crd_rs1, crd_rs1, crs2, InstructionLength); break; case 0b11000: // and命令 result = alu.And(crd_rs1, crd_rs1, crs2, InstructionLength); break; } break; } break; case CompressedOpcode.slli: // slli命令 if ((cins[2] & 0b100000) == 0b000000) { immediate = GetUnsignedImmediate("CI", cins); alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); result = alu.Slli(crd_rs1, crd_rs1, immediate, InstructionLength); } break; case CompressedOpcode.jr_mv_add: if (cins[1] != 0 && (cins[2] & 0x1f) != 0) { alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu)); if ((cins[2] & 0b100000) == 0) // mv命令 { result = alu.Add(rd_rs1, Register.zero, rs2, InstructionLength); } else // add命令 { result = alu.Add(rd_rs1, rd_rs1, rs2, InstructionLength); } }