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 !; }
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 }); }