Inheritance: Reko.Core.Machine.MachineInstruction
Beispiel #1
0
 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 !;
Beispiel #2
0
        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,
                });
            }
        }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
        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);
            }
        }