public M6812Rewriter(M6812Architecture arch, EndianImageReader rdr, M6812State state, IStorageBinder binder, IRewriterHost host) { this.arch = arch; this.rdr = rdr; this.state = state; this.binder = binder; this.host = host; this.dasm = new M6812Disassembler(arch, rdr).GetEnumerator(); this.instr = null !; this.m = null !; }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var rtlInstrs = new List <RtlInstruction>(); this.m = new RtlEmitter(rtlInstrs); this.rtlc = instr.InstructionClass; switch (instr.Opcode) { case Opcode.mov: case Opcode.rev: case Opcode.revw: case Opcode.tbl: host.Warn( instr.Address, "M6812 instruction '{0}' is not supported yet.", instr.Opcode); goto case Opcode.invalid; case Opcode.invalid: this.rtlc = InstrClass.Invalid; m.Invalid(); break; case Opcode.aba: RewriteAba(); break; case Opcode.adca: RewriteAdcSbc(Registers.a, m.IAdd); break; case Opcode.adcb: RewriteAdcSbc(Registers.b, m.IAdd); break; case Opcode.adda: RewriteArithmetic(Registers.a, m.IAdd); break; case Opcode.addb: RewriteArithmetic(Registers.b, m.IAdd); break; case Opcode.addd: RewriteArithmetic(Registers.d, m.IAdd); break; case Opcode.anda: RewriteLogical(Registers.a, m.And); break; case Opcode.andb: RewriteLogical(Registers.b, m.And); break; case Opcode.andcc: RewriteAndcc(); break; case Opcode.asr: RewriteShiftMem(m.Sar); break; case Opcode.asra: RewriteArithmetic(Registers.a, m.Sar); break; case Opcode.asrb: RewriteArithmetic(Registers.b, m.Sar); break; case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Opcode.bclr: RewriteBclr(); break; case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Opcode.bvc: RewriteBcc(ConditionCode.NO, FlagM.VF); break; case Opcode.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break; case Opcode.bgnd: RewriteBgnd(); break; case Opcode.bita: RewriteBit(Registers.a); break; case Opcode.bitb: RewriteBit(Registers.b); break; case Opcode.bra: RewriteBra(); break; case Opcode.brclr: RewriteBrclr(); break; case Opcode.brn: m.Nop(); break; case Opcode.brset: RewriteBrset(); break; case Opcode.bset: RewriteBset(); break; case Opcode.bsr: RewriteBsr(); break; case Opcode.call: RewriteCall(); break; case Opcode.cba: RewriteCba(); break; case Opcode.clr: RewriteClr(); break; case Opcode.clra: RewriteClr(Registers.a); break; case Opcode.clrb: RewriteClr(Registers.b); break; case Opcode.cmpa: RewriteCmp(Registers.a); break; case Opcode.cmpb: RewriteCmp(Registers.b); break; case Opcode.com: RewriteCom(); break; case Opcode.coma: RewriteCom(Registers.a); break; case Opcode.comb: RewriteCom(Registers.b); break; case Opcode.cpd: RewriteCmp(Registers.d); break; case Opcode.cps: RewriteCmp(Registers.sp); break; case Opcode.cpx: RewriteCmp(Registers.x); break; case Opcode.cpy: RewriteCmp(Registers.y); break; case Opcode.daa: RewriteDaa(); break; case Opcode.dbeq: RewriteDb(m.Eq0); break; case Opcode.dbne: RewriteDb(m.Ne0); break; case Opcode.dec: RewriteIncDec(m.ISub); break; case Opcode.deca: RewriteIncDec(Registers.a, m.ISub); break; case Opcode.decb: RewriteIncDec(Registers.b, m.ISub); break; case Opcode.dex: RewriteIncDecXY(Registers.x, m.ISub); break; case Opcode.dey: RewriteIncDecXY(Registers.y, m.ISub); break; case Opcode.ediv: RewriteEdiv(m.UDiv, m.Remainder); break; case Opcode.edivs: RewriteEdiv(m.SDiv, m.Remainder); break; case Opcode.emacs: RewriteEmacs(); break; case Opcode.emaxd: RewriteEmaxmind("__umax"); break; case Opcode.emaxm: RewriteEmaxminm("__umax"); break; case Opcode.emind: RewriteEmaxmind("__umin"); break; case Opcode.eminm: RewriteEmaxminm("__umin"); break; case Opcode.emul: RewriteEmul(m.UMul); break; case Opcode.emuls: RewriteEmul(m.SMul); break; case Opcode.eora: RewriteLogical(Registers.a, m.Xor); break; case Opcode.eorb: RewriteLogical(Registers.b, m.Xor); break; case Opcode.etbl: RewriteEtbl(); break; case Opcode.fdiv: RewriteFdiv(); break; case Opcode.ibeq: RewriteIb(m.Eq0); break; case Opcode.ibne: RewriteIb(m.Ne0); break; case Opcode.idiv: RewriteIdiv(m.UDiv); break; case Opcode.idivs: RewriteIdiv(m.SDiv); break; case Opcode.inc: RewriteIncDec(m.IAdd); break; case Opcode.inca: RewriteIncDec(Registers.a, m.IAdd); break; case Opcode.incb: RewriteIncDec(Registers.b, m.IAdd); break; case Opcode.inx: RewriteIncDecXY(Registers.x, m.IAdd); break; case Opcode.iny: RewriteIncDecXY(Registers.y, m.IAdd); break; case Opcode.jmp: RewriteJmp(); break; case Opcode.jsr: RewriteJsr(); break; case Opcode.lbcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Opcode.lbcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Opcode.lbeq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.lbge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.lbgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.lbhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.lble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.lblt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.lbls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.lbmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Opcode.lbne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.lbpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Opcode.lbra: RewriteBra(); break; case Opcode.lbrn: m.Nop(); break; case Opcode.lbvc: RewriteBcc(ConditionCode.NO, FlagM.VF); break; case Opcode.lbvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break; case Opcode.ldaa: RewriteLd(Registers.a); break; case Opcode.ldab: RewriteLd(Registers.b); break; case Opcode.ldd: RewriteLd(Registers.d); break; case Opcode.lds: RewriteLd(Registers.sp); break; case Opcode.ldx: RewriteLd(Registers.x); break; case Opcode.ldy: RewriteLd(Registers.y); break; case Opcode.leas: RewriteLea(Registers.sp); break; case Opcode.leax: RewriteLea(Registers.x); break; case Opcode.leay: RewriteLea(Registers.y); break; case Opcode.lsl: RewriteShiftMem(m.Shl); break; case Opcode.lsla: RewriteArithmetic(Registers.a, m.Shl); break; case Opcode.lslb: RewriteArithmetic(Registers.b, m.Shl); break; case Opcode.lsld: RewriteArithmetic(Registers.d, m.Shl); break; case Opcode.lsr: RewriteShiftMem(m.Shr); break; case Opcode.lsra: RewriteArithmetic(Registers.a, m.Shr); break; case Opcode.lsrb: RewriteArithmetic(Registers.b, m.Shr); break; case Opcode.lsrd: RewriteArithmetic(Registers.d, m.Shr); break; case Opcode.maxa: RewriteMaxmina("__umax_b"); break; case Opcode.maxm: RewriteMaxminm("__umax_b"); break; case Opcode.mem: RewriteMem(); break; case Opcode.mina: RewriteMaxmina("__umin_b"); break; case Opcode.minm: RewriteMaxminm("__umin_b"); break; case Opcode.mul: RewriteMul(); break; case Opcode.neg: RewriteNeg(); break; case Opcode.nega: RewriteNeg(Registers.a); break; case Opcode.negb: RewriteNeg(Registers.b); break; case Opcode.nop: m.Nop(); break; case Opcode.oraa: RewriteLogical(Registers.a, m.Or); break; case Opcode.orab: RewriteLogical(Registers.b, m.Or); break; case Opcode.orcc: RewriteOrcc(); break; case Opcode.psha: RewritePsh(Registers.a); break; case Opcode.pshb: RewritePsh(Registers.b); break; case Opcode.pshc: RewritePsh(Registers.ccr); break; case Opcode.pshd: RewritePsh(Registers.d); break; case Opcode.pshx: RewritePsh(Registers.x); break; case Opcode.pshy: RewritePsh(Registers.y); break; case Opcode.pula: RewritePul(Registers.a); break; case Opcode.pulb: RewritePul(Registers.b); break; case Opcode.pulc: RewritePul(Registers.ccr); break; case Opcode.puld: RewritePul(Registers.d); break; case Opcode.pulx: RewritePul(Registers.x); break; case Opcode.puly: RewritePul(Registers.y); break; case Opcode.rol: RewriteShiftMem(Rol); break; case Opcode.rola: RewriteArithmetic(Registers.a, Rol); break; case Opcode.rolb: RewriteArithmetic(Registers.b, Rol); break; case Opcode.ror: RewriteShiftMem(Ror); break; case Opcode.rora: RewriteArithmetic(Registers.a, Ror); break; case Opcode.rorb: RewriteArithmetic(Registers.a, Ror); break; case Opcode.rtc: RewriteRtc(); break; case Opcode.rti: RewriteRti(); break; case Opcode.rts: RewriteRts(); break; case Opcode.sba: RewriteSba(); break; case Opcode.sbca: RewriteAdcSbc(Registers.a, m.ISub); break; case Opcode.sbcb: RewriteAdcSbc(Registers.b, m.ISub); break; case Opcode.sex: RewriteSex(); break; case Opcode.staa: RewriteSt(Registers.a); break; case Opcode.stab: RewriteSt(Registers.b); break; case Opcode.std: RewriteSt(Registers.d); break; case Opcode.stop: RewriteStop(); break; case Opcode.sts: RewriteSt(Registers.sp); break; case Opcode.stx: RewriteSt(Registers.x); break; case Opcode.sty: RewriteSt(Registers.y); break; case Opcode.suba: RewriteSub(Registers.a); break; case Opcode.subb: RewriteSub(Registers.b); break; case Opcode.subd: RewriteSub(Registers.d); break; case Opcode.swi: RewriteSwi(); break; case Opcode.tab: RewriteTab(); break; case Opcode.tba: RewriteTba(); break; case Opcode.tbeq: RewriteTb(m.Eq0); break; case Opcode.tbne: RewriteTb(m.Ne0); break; case Opcode.tfr: RewriteTfr(); break; case Opcode.trap: RewriteTrap(); break; case Opcode.tst: RewriteTst(); break; case Opcode.tsta: RewriteTst(Registers.a); break; case Opcode.tstb: RewriteTst(Registers.b); break; case Opcode.wai: RewriteWai(); break; case Opcode.wav: RewriteWav(); break; } yield return(new RtlInstructionCluster( instr.Address, instr.Length, rtlInstrs.ToArray()) { Class = rtlc }); } }