public RiscVRewriter(RiscVArchitecture arch, Decoder[] decoders, EndianImageReader rdr, ProcessorState state, IStorageBinder binder, IRewriterHost host) { this.arch = arch; this.dasm = new RiscVDisassembler(arch, decoders, rdr).GetEnumerator(); this.state = state; this.binder = binder; this.host = host; this.rdr = rdr; this.rtlInstructions = new List <RtlInstruction>(); this.m = new RtlEmitter(rtlInstructions); this.instr = default !;
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var addr = dasm.Current.Address; var len = dasm.Current.Length; this.rtlInstructions = new List <RtlInstruction>(); this.rtlc = RtlClass.Linear; this.m = new RtlEmitter(rtlInstructions); switch (instr.opcode) { default: host.Warn( instr.Address, "Risc-V instruction '{0}' not supported yet.", instr.opcode); rtlc = RtlClass.Invalid; m.Invalid(); break; case Opcode.invalid: rtlc = RtlClass.Invalid; m.Invalid(); break; case Opcode.add: RewriteAdd(); break; case Opcode.addi: RewriteAdd(); break; case Opcode.addiw: RewriteAddw(); break; case Opcode.addw: RewriteAddw(); break; case Opcode.and: RewriteAnd(); break; case Opcode.andi: RewriteAnd(); break; case Opcode.auipc: RewriteAuipc(); break; case Opcode.beq: RewriteBranch(m.Eq); break; case Opcode.bge: RewriteBranch(m.Ge); break; case Opcode.bgeu: RewriteBranch(m.Uge); break; case Opcode.blt: RewriteBranch(m.Lt); break; case Opcode.bltu: RewriteBranch(m.Ult); break; case Opcode.bne: RewriteBranch(m.Ne); break; case Opcode.fcvt_d_s: RewriteFcvt(PrimitiveType.Real64); break; case Opcode.feq_s: RewriteFcmp(PrimitiveType.Real32, m.FEq); break; case Opcode.fmadd_s: RewriteFmadd(PrimitiveType.Real32, m.FAdd); break; case Opcode.fmv_d_x: RewriteFcvt(PrimitiveType.Real64); break; case Opcode.fmv_s_x: RewriteFcvt(PrimitiveType.Real32); break; case Opcode.flw: RewriteFload(PrimitiveType.Real32); break; case Opcode.jal: RewriteJal(); break; case Opcode.jalr: RewriteJalr(); break; case Opcode.lb: RewriteLoad(PrimitiveType.SByte); break; case Opcode.lbu: RewriteLoad(PrimitiveType.Byte); break; case Opcode.ld: RewriteLoad(PrimitiveType.Word64); break; case Opcode.lh: RewriteLoad(PrimitiveType.Int16); break; case Opcode.lhu: RewriteLoad(PrimitiveType.UInt16); break; case Opcode.lui: RewriteLui(); break; case Opcode.lw: RewriteLoad(PrimitiveType.Int32); break; case Opcode.lwu: RewriteLoad(PrimitiveType.UInt32); break; case Opcode.or: RewriteOr(); break; case Opcode.ori: RewriteOr(); break; case Opcode.sb: RewriteStore(PrimitiveType.Byte); break; case Opcode.sd: RewriteStore(PrimitiveType.Word64); break; case Opcode.sh: RewriteStore(PrimitiveType.Word16); break; case Opcode.sw: RewriteStore(PrimitiveType.Word32); break; case Opcode.slli: RewriteShift(m.Shl); break; case Opcode.slliw: RewriteShiftw(m.Shl); break; case Opcode.sllw: RewriteShiftw(m.Shl); break; case Opcode.slt: RewriteSlt(false); break; case Opcode.sltu: RewriteSlt(true); break; case Opcode.srai: RewriteShift(m.Sar); break; case Opcode.sraiw: RewriteShiftw(m.Sar); break; case Opcode.srli: RewriteShift(m.Shr); break; case Opcode.srliw: RewriteShiftw(m.Shr); break; case Opcode.sub: RewriteSub(); break; case Opcode.subw: RewriteSubw(); break; case Opcode.xor: RewriteXor(); break; case Opcode.xori: RewriteXor(); break; } yield return(new RtlInstructionCluster( addr, len, rtlInstructions.ToArray()) { Class = rtlc, }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var addr = dasm.Current.Address; var len = dasm.Current.Length; var rtlInstructions = new List <RtlInstruction>(); this.iclass = this.instr.InstructionClass; this.m = new RtlEmitter(rtlInstructions); switch (instr.Mnemonic) { default: host.Warn( instr.Address, "Risc-V instruction '{0}' not supported yet.", instr.Mnemonic); EmitUnitTest(); iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.invalid: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.addi: RewriteAdd(); break; case Mnemonic.addiw: RewriteAddw(); break; case Mnemonic.addw: RewriteAddw(); break; case Mnemonic.and: RewriteBinOp(m.And); break; case Mnemonic.andi: RewriteBinOp(m.And); break; case Mnemonic.auipc: RewriteAuipc(); break; case Mnemonic.beq: RewriteBranch(m.Eq); break; case Mnemonic.bge: RewriteBranch(m.Ge); break; case Mnemonic.bgeu: RewriteBranch(m.Uge); break; case Mnemonic.blt: RewriteBranch(m.Lt); break; case Mnemonic.bltu: RewriteBranch(m.Ult); break; case Mnemonic.bne: RewriteBranch(m.Ne); break; case Mnemonic.c_add: RewriteCompressedBinOp(m.IAdd); break; case Mnemonic.c_addi: RewriteCompressedBinOp(m.IAdd); break; case Mnemonic.c_addi16sp: RewriteAddi16sp(); break; case Mnemonic.c_addi4spn: RewriteAddi4spn(); break; case Mnemonic.c_addiw: RewriteCompressedAdd(PrimitiveType.Word32); break; case Mnemonic.c_addw: RewriteCompressedAdd(PrimitiveType.Word32); break; case Mnemonic.c_and: RewriteCompressedBinOp(m.And); break; case Mnemonic.c_andi: RewriteCompressedBinOp(m.And); break; case Mnemonic.c_beqz: RewriteCompressedBranch(m.Eq); break; case Mnemonic.c_bnez: RewriteCompressedBranch(m.Ne); break; case Mnemonic.c_fld: RewriteFload(PrimitiveType.Real64); break; case Mnemonic.c_fldsp: RewriteLxsp(PrimitiveType.Real64); break; case Mnemonic.c_fsd: RewriteStore(PrimitiveType.Real64); break; case Mnemonic.c_fsdsp: RewriteSxsp(PrimitiveType.Real64); break; case Mnemonic.c_j: RewriteCompressedJ(); break; case Mnemonic.c_jalr: RewriteCompressedJalr(); break; case Mnemonic.c_jr: RewriteCompressedJr(); break; case Mnemonic.c_ld: RewriteLoad(PrimitiveType.Word64); break; case Mnemonic.c_li: RewriteLi(); break; case Mnemonic.c_ldsp: RewriteLxsp(PrimitiveType.Word64); break; case Mnemonic.c_lui: RewriteLui(); break; case Mnemonic.c_lw: RewriteLoad(PrimitiveType.Word32); break; case Mnemonic.c_lwsp: RewriteLxsp(PrimitiveType.Word32); break; case Mnemonic.c_mv: RewriteCompressedMv(); break; case Mnemonic.c_or: RewriteCompressedBinOp(m.Or); break; case Mnemonic.c_slli: RewriteCompressedBinOp(SllI); break; case Mnemonic.c_srai: RewriteCompressedBinOp(SraI); break; case Mnemonic.c_srli: RewriteCompressedBinOp(SrlI); break; case Mnemonic.c_sub: RewriteCompressedBinOp(m.ISub); break; case Mnemonic.c_sd: RewriteStore(PrimitiveType.Word64); break; case Mnemonic.c_sdsp: RewriteSxsp(PrimitiveType.Word64); break; case Mnemonic.c_subw: RewriteCompressedBinOp(m.ISub, PrimitiveType.Word32); break; case Mnemonic.c_sw: RewriteStore(PrimitiveType.Word32); break; case Mnemonic.c_swsp: RewriteSxsp(PrimitiveType.Word32); break; case Mnemonic.c_xor: RewriteCompressedBinOp(m.Xor); break; case Mnemonic.divuw: RewriteBinOp(m.UDiv, PrimitiveType.Word32); break; case Mnemonic.divw: RewriteBinOp(m.SDiv, PrimitiveType.Word32); break; case Mnemonic.fcvt_d_s: RewriteFcvt(PrimitiveType.Real64); break; case Mnemonic.feq_s: RewriteFcmp(PrimitiveType.Real32, m.FEq); break; case Mnemonic.fmadd_s: RewriteFmadd(PrimitiveType.Real32, m.FAdd); break; case Mnemonic.fmv_d_x: RewriteFcvt(PrimitiveType.Real64); break; case Mnemonic.fmv_w_x: RewriteFcvt(PrimitiveType.Real32); break; case Mnemonic.fld: RewriteFload(PrimitiveType.Real64); break; case Mnemonic.flw: RewriteFload(PrimitiveType.Real32); break; case Mnemonic.fsd: RewriteStore(PrimitiveType.Real64); break; case Mnemonic.fsw: RewriteStore(PrimitiveType.Real32); break; case Mnemonic.jal: RewriteJal(); break; case Mnemonic.jalr: RewriteJalr(); break; case Mnemonic.lb: RewriteLoad(PrimitiveType.SByte); break; case Mnemonic.lbu: RewriteLoad(PrimitiveType.Byte); break; case Mnemonic.ld: RewriteLoad(PrimitiveType.Word64); break; case Mnemonic.lh: RewriteLoad(PrimitiveType.Int16); break; case Mnemonic.lhu: RewriteLoad(PrimitiveType.UInt16); break; case Mnemonic.lui: RewriteLui(); break; case Mnemonic.lw: RewriteLoad(PrimitiveType.Int32); break; case Mnemonic.lwu: RewriteLoad(PrimitiveType.UInt32); break; case Mnemonic.mulw: RewriteBinOp(m.IMul, PrimitiveType.Word32); break; case Mnemonic.or: RewriteOr(); break; case Mnemonic.ori: RewriteOr(); break; //$TODO: Reko has no unsigned modulus operator case Mnemonic.remuw: RewriteBinOp(m.Mod, PrimitiveType.Word32); break; case Mnemonic.remw: RewriteBinOp(m.Mod, PrimitiveType.Word32); break; case Mnemonic.sb: RewriteStore(PrimitiveType.Byte); break; case Mnemonic.sd: RewriteStore(PrimitiveType.Word64); break; case Mnemonic.sh: RewriteStore(PrimitiveType.Word16); break; case Mnemonic.sw: RewriteStore(PrimitiveType.Word32); break; case Mnemonic.sll: RewriteBinOp(m.Shl); break; case Mnemonic.slli: RewriteShift(m.Shl); break; case Mnemonic.slliw: RewriteShiftw(m.Shl); break; case Mnemonic.sllw: RewriteShiftw(m.Shl); break; case Mnemonic.slt: RewriteSlt(false); break; case Mnemonic.sltiu: RewriteSlti(true); break; case Mnemonic.sltu: RewriteSlt(true); break; case Mnemonic.srai: RewriteShift(m.Sar); break; case Mnemonic.sraiw: RewriteShiftw(m.Sar); break; case Mnemonic.srl: RewriteBinOp(m.Shr); break; case Mnemonic.srli: RewriteShift(m.Shr); break; case Mnemonic.srliw: RewriteShiftw(SrlI); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.subw: RewriteSubw(); break; case Mnemonic.xor: RewriteXor(); break; case Mnemonic.xori: RewriteXor(); break; } yield return(m.MakeCluster(addr, len, iclass)); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.rtlc = new RtlInstructionCluster(dasm.Current.Address, dasm.Current.Length); this.rtlc.Class = RtlClass.Linear; this.m = new RtlEmitter(rtlc.Instructions); switch (instr.opcode) { default: throw new AddressCorrelatedException( instr.Address, "Rewriting of Risc-V instruction '{0}' not implemented yet.", instr.opcode); case Opcode.add: RewriteAdd(); break; case Opcode.addi: RewriteAdd(); break; case Opcode.addiw: RewriteAddw(); break; case Opcode.addw: RewriteAddw(); break; case Opcode.and: RewriteAnd(); break; case Opcode.andi: RewriteAnd(); break; case Opcode.auipc: RewriteAuipc(); break; case Opcode.beq: RewriteBranch(m.Eq); break; case Opcode.bge: RewriteBranch(m.Ge); break; case Opcode.bgeu: RewriteBranch(m.Uge); break; case Opcode.blt: RewriteBranch(m.Lt); break; case Opcode.bltu: RewriteBranch(m.Ult); break; case Opcode.bne: RewriteBranch(m.Ne); break; case Opcode.fcvt_d_s: RewriteFcvt(PrimitiveType.Real64); break; case Opcode.feq_s: RewriteFcmp(PrimitiveType.Real32, m.FEq); break; case Opcode.fmv_d_x: RewriteFcvt(PrimitiveType.Real64); break; case Opcode.fmv_s_x: RewriteFcvt(PrimitiveType.Real32); break; case Opcode.flw: RewriteFload(PrimitiveType.Real32); break; case Opcode.jal: RewriteJal(); break; case Opcode.jalr: RewriteJalr(); break; case Opcode.lb: RewriteLoad(PrimitiveType.SByte); break; case Opcode.lbu: RewriteLoad(PrimitiveType.Byte); break; case Opcode.ld: RewriteLoad(PrimitiveType.Word64); break; case Opcode.lui: RewriteLui(); break; case Opcode.lw: RewriteLoad(PrimitiveType.Int32); break; case Opcode.lwu: RewriteLoad(PrimitiveType.UInt32); break; case Opcode.or: RewriteOr(); break; case Opcode.ori: RewriteOr(); break; case Opcode.sb: RewriteStore(PrimitiveType.Byte); break; case Opcode.sd: RewriteStore(PrimitiveType.Word64); break; case Opcode.sh: RewriteStore(PrimitiveType.Word16); break; case Opcode.sw: RewriteStore(PrimitiveType.Word32); break; case Opcode.slli: RewriteShift(m.Shl); break; case Opcode.slliw: RewriteShiftw(m.Shl); break; case Opcode.sllw: RewriteShiftw(m.Shl); break; case Opcode.slt: RewriteSlt(false); break; case Opcode.sltu: RewriteSlt(true); break; case Opcode.srai: RewriteShift(m.Sar); break; case Opcode.sraiw: RewriteShiftw(m.Sar); break; case Opcode.srli: RewriteShift(m.Shr); break; case Opcode.srliw: RewriteShiftw(m.Shr); break; case Opcode.sub: RewriteSub(); break; case Opcode.subw: RewriteSubw(); break; case Opcode.xor: RewriteXor(); break; case Opcode.xori: RewriteXor(); break; } yield return(rtlc); } }