상속: Reko.Core.Machine.MachineInstruction
예제 #1
0
 public Avr8Rewriter(Avr8Architecture arch, EndianImageReader rdr, ProcessorState state, IStorageBinder binder, IRewriterHost host)
 {
     this.arch            = arch;
     this.rdr             = rdr;
     this.dasm            = new LookaheadEnumerator <AvrInstruction>(new Avr8Disassembler(arch, rdr).GetEnumerator());
     this.state           = state;
     this.binder          = binder;
     this.host            = host;
     this.instr           = null !;
     this.m               = null !;
     this.rtlInstructions = null !;
     this.clusters        = null !;
 }
예제 #2
0
        public void Rewrite(AvrInstruction instr)
        {
            this.instr           = instr;
            this.rtlInstructions = new List <RtlInstruction>();
            this.rtlc            = instr.InstructionClass;
            this.m = new RtlEmitter(rtlInstructions);
            switch (instr.opcode)
            {
            case Mnemonic.adc: RewriteAdcSbc(m.IAdd); break;

            case Mnemonic.add: RewriteBinOp(m.IAdd, CmpFlags); break;

            case Mnemonic.adiw: RewriteAddSubIW(m.IAdd); break;

            case Mnemonic.and: RewriteBinOp(m.And, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break;

            case Mnemonic.andi: RewriteBinOp(m.And, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break;

            case Mnemonic.asr: RewriteAsr(); break;

            case Mnemonic.brcc: RewriteBranch(ConditionCode.UGE, FlagM.CF); break;

            case Mnemonic.brcs: RewriteBranch(ConditionCode.ULT, FlagM.CF); break;

            case Mnemonic.breq: RewriteBranch(ConditionCode.EQ, FlagM.ZF); break;

            case Mnemonic.brge: RewriteBranch(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

            case Mnemonic.brid: RewriteBranch(FlagM.IF, false); break;

            case Mnemonic.brne: RewriteBranch(ConditionCode.NE, FlagM.ZF); break;

            case Mnemonic.brpl: RewriteBranch(ConditionCode.GE, FlagM.NF); break;

            case Mnemonic.call: RewriteCall(); break;

            case Mnemonic.cli: RewriteCli(); break;

            case Mnemonic.com: RewriteUnary(m.Comp, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF, FlagM.CF); break;

            case Mnemonic.cp: RewriteCp(); break;

            case Mnemonic.cpi: RewriteCp(); break;

            case Mnemonic.cpc: RewriteCpc(); break;

            case Mnemonic.cpse: SkipIf(m.Eq); break;

            case Mnemonic.dec: RewriteIncDec(m.ISub); break;

            case Mnemonic.des: RewriteDes(); break;

            case Mnemonic.eor: RewriteBinOp(m.Xor, LogicalFlags, FlagM.VF); break;

            case Mnemonic.icall: RewriteIcall(); break;

            case Mnemonic.@in: RewriteIn(); break;

            case Mnemonic.inc: RewriteIncDec(m.IAdd); break;

            case Mnemonic.ijmp: RewriteIjmp(); break;

            case Mnemonic.jmp: RewriteJmp(); break;

            case Mnemonic.ld: RewriteLd(); break;

            case Mnemonic.ldd: RewriteLd(); break;

            case Mnemonic.ldi: RewriteLdi(); break;

            case Mnemonic.lds: RewriteLds(); break;

            case Mnemonic.lpm: RewriteLpm(); break;

            case Mnemonic.lsr: RewriteLsr(); break;

            case Mnemonic.mov: RewriteMov(); break;

            case Mnemonic.movw: RewriteMovw(); break;

            case Mnemonic.muls: RewriteMuls(); break;

            case Mnemonic.neg: RewriteUnary(m.Neg, CmpFlags); break;

            case Mnemonic.@out: RewriteOut(); break;

            case Mnemonic.or: RewriteBinOp(m.Or, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break;

            case Mnemonic.ori: RewriteBinOp(m.Or, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break;

            case Mnemonic.pop: RewritePop(); break;

            case Mnemonic.push: RewritePush(); break;

            case Mnemonic.rcall: RewriteCall(); break;

            case Mnemonic.ror: RewriteRor(); break;

            case Mnemonic.ret: RewriteRet(); break;

            case Mnemonic.reti: RewriteRet(); break;  //$TODO: more to indicate interrupt return?

            case Mnemonic.rjmp: RewriteJmp(); break;

            case Mnemonic.sbc: RewriteAdcSbc(m.ISub); break;

            case Mnemonic.sbci: RewriteAdcSbc(m.ISub); break;

            case Mnemonic.sbis: RewriteSbis(); return; // We've already added ourself to clusters.

            case Mnemonic.sbiw: RewriteAddSubIW(m.ISub); break;

            case Mnemonic.sbrc: SkipIf(Sbrc); break;

            case Mnemonic.sbrs: SkipIf(Sbrs); break;

            case Mnemonic.sec: RewriteSetBit(FlagM.CF, true); break;

            case Mnemonic.sei: RewriteSei(); break;

            case Mnemonic.st: RewriteSt(); break;

            case Mnemonic.std: RewriteSt(); break;

            case Mnemonic.sts: RewriteSts(); break;

            case Mnemonic.sub: RewriteBinOp(m.ISub, CmpFlags); break;

            case Mnemonic.subi: RewriteBinOp(m.ISub, CmpFlags); break;

            case Mnemonic.swap: RewriteSwap(); break;

            default:
                host.Error(instr.Address, string.Format("AVR8 instruction '{0}' is not supported yet.", instr.opcode));
                EmitUnitTest();
                m.Invalid();
                break;
            }
            clusters.Add(new RtlInstructionCluster(
                             instr.Address,
                             instr.Length,
                             rtlInstructions.ToArray())
            {
                Class = rtlc
            });
        }