Inheritance: Reko.Core.Machine.MachineInstruction
Example #1
0
 public Rewriter(M68kArchitecture m68kArchitecture, EndianImageReader rdr, M68kState m68kState, IStorageBinder binder, IRewriterHost host)
 {
     this.arch            = m68kArchitecture;
     this.state           = m68kState;
     this.binder          = binder;
     this.host            = host;
     this.rdr             = rdr;
     this.dasm            = arch.CreateDisassemblerImpl(rdr).GetEnumerator();
     this.instr           = default !;
Example #2
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                instr = dasm.Current;
                var addr = instr.Address;
                var len  = instr.Length;
                rtlInstructions = new List <RtlInstruction>();
                rtlc            = instr.InstructionClass;
                m   = new RtlEmitter(rtlInstructions);
                orw = new OperandRewriter(arch, this.m, this.binder, instr.dataWidth);
                switch (instr.Mnemonic)
                {
                default:
                    host.Warn(
                        instr.Address,
                        "M68k instruction '{0}' is not supported yet.",
                        instr.Mnemonic);
                    m.Invalid();
                    break;

                case Mnemonic.illegal: RewriteIllegal(); break;

                case Mnemonic.abcd: RewriteAbcd(); break;

                case Mnemonic.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break;

                case Mnemonic.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break;

                case Mnemonic.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break;

                case Mnemonic.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break;

                case Mnemonic.addx: RewriteAddSubx(m.IAdd); break;

                case Mnemonic.and: RewriteLogical((s, d) => m.And(d, s)); break;

                case Mnemonic.andi: RewriteLogical((s, d) => m.And(d, s)); break;

                case Mnemonic.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break;

                case Mnemonic.asr: RewriteShift((s, d) => m.Sar(d, s)); break;

/*
 *
 * Mnemonic Condition Encoding Test
 * T* True 0000 1
 * F* False 0001 0
 * HI High 0010 C L Z
 * LS Low or Same 0011 C V Z
 * VC Overflow Clear 1000 V
 * VS Overflow Set 1001 V
 */
                case Mnemonic.bclr: RewriteBclrBset("__bclr"); break;

                case Mnemonic.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break;

                case Mnemonic.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break;

                case Mnemonic.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break;

                case Mnemonic.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Mnemonic.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.bls: RewriteBcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.blt: RewriteBcc(ConditionCode.LT, FlagM.NF | FlagM.VF); break;

                case Mnemonic.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break;

                case Mnemonic.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break;

                case Mnemonic.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break;

                case Mnemonic.bvc: RewriteBcc(ConditionCode.NO, FlagM.VF); break;

                case Mnemonic.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break;

                case Mnemonic.bchg: RewriteBchg(); break;

                case Mnemonic.bkpt: RewriteBkpt(); break;

                case Mnemonic.bra: RewriteBra(); break;

                case Mnemonic.bset: RewriteBclrBset("__bset"); break;

                case Mnemonic.bsr: RewriteBsr(); break;

                case Mnemonic.btst: RewriteBtst(); break;

                case Mnemonic.callm: RewriteCallm(); break;

                case Mnemonic.cas: RewriteCas(); break;

                case Mnemonic.clr: RewriteClr(); break;

                case Mnemonic.chk: RewriteChk(); break;

                case Mnemonic.chk2: RewriteChk2(); break;

                case Mnemonic.cmp: RewriteCmp(); break;

                case Mnemonic.cmp2: RewriteCmp2(); break;

                case Mnemonic.cmpa: RewriteCmp(); break;

                case Mnemonic.cmpi: RewriteCmp(); break;

                case Mnemonic.cmpm: RewriteCmp(); break;

                case Mnemonic.dbcc: RewriteDbcc(ConditionCode.UGE, FlagM.CF); break;

                case Mnemonic.dbcs: RewriteDbcc(ConditionCode.ULT, FlagM.CF); break;

                case Mnemonic.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break;

                case Mnemonic.dbge: RewriteDbcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Mnemonic.dbgt: RewriteDbcc(ConditionCode.GE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.dbhi: RewriteDbcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.dbls: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.dblt: RewriteDbcc(ConditionCode.LT, FlagM.NF | FlagM.VF); break;

                case Mnemonic.dbmi: RewriteDbcc(ConditionCode.LT, FlagM.NF); break;

                case Mnemonic.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break;

                case Mnemonic.dbpl: RewriteDbcc(ConditionCode.GT, FlagM.NF); break;

                case Mnemonic.dbt: RewriteDbcc(ConditionCode.ALWAYS, 0); break;

                case Mnemonic.dbra: RewriteDbcc(ConditionCode.None, 0); break;

                case Mnemonic.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break;

                case Mnemonic.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break;

                case Mnemonic.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break;

                case Mnemonic.divul: RewriteDiv(m.UDiv, PrimitiveType.UInt32); break;

                case Mnemonic.eor: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Mnemonic.eori: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Mnemonic.exg: RewriteExg(); break;

                case Mnemonic.ext: RewriteExt(); break;

                case Mnemonic.extb: RewriteExtb(); break;

                case Mnemonic.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break;

                //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs.
                case Mnemonic.fbf: m.Nop(); break;

                case Mnemonic.fblt: RewriteFbcc(ConditionCode.LT); break;

                case Mnemonic.fbgl: RewriteFbcc(ConditionCode.NE); break;

                case Mnemonic.fbgt: RewriteFbcc(ConditionCode.GT); break;

                case Mnemonic.fbgle: RewriteFbcc(ConditionCode.NE); break;    //$BUG: should be !is_nan

                case Mnemonic.fbne: RewriteFbcc(ConditionCode.NE); break;

                case Mnemonic.fbnge: RewriteFbcc(ConditionCode.LT); break;

                case Mnemonic.fbngl: RewriteFbcc(ConditionCode.EQ); break;

                case Mnemonic.fbngle: RewriteFbcc(ConditionCode.EQ); break;   //$BUG: should be is_nan

                case Mnemonic.fbnlt: RewriteFbcc(ConditionCode.GE); break;

                case Mnemonic.fbnle: RewriteFbcc(ConditionCode.GT); break;

                case Mnemonic.fbogl: RewriteFbcc(ConditionCode.NE); break;

                case Mnemonic.fbole: RewriteFbcc(ConditionCode.LE); break;

                case Mnemonic.fbolt: RewriteFbcc(ConditionCode.LT); break;

                case Mnemonic.fbogt: RewriteFbcc(ConditionCode.GT); break;

                case Mnemonic.fbor: RewriteFbcc(ConditionCode.EQ); break;     //$REVIEW: is this correct?

                case Mnemonic.fbseq: RewriteFbcc(ConditionCode.EQ); break;

                case Mnemonic.fbsf: RewriteFbcc(ConditionCode.NEVER); break;

                case Mnemonic.fbsne: RewriteFbcc(ConditionCode.NE); break;

                case Mnemonic.fbst: RewriteFbcc(ConditionCode.ALWAYS); break;

                case Mnemonic.fbuge: RewriteFbcc(ConditionCode.GE); break;

                case Mnemonic.fbugt: RewriteFbcc(ConditionCode.GT); break;

                case Mnemonic.fbult: RewriteFbcc(ConditionCode.LT); break;

                case Mnemonic.fbun: RewriteFbcc(ConditionCode.IS_NAN); break;

                case Mnemonic.fasin: RewriteFasin(); break;

                case Mnemonic.fintrz: RewriteFintrz(); break;

                case Mnemonic.fcmp: RewriteFcmp(); break;

                case Mnemonic.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break;

                case Mnemonic.fmove: RewriteFmove(); break;

                case Mnemonic.fmovecr: RewriteFmovecr(); break;

                case Mnemonic.fmovem: RewriteMovem(i => Registers.GetRegister(i + Registers.fp0.Number)); break;

                case Mnemonic.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break;

                case Mnemonic.fneg: RewriteFUnaryOp(m.Neg); break;

                case Mnemonic.fsqrt: RewriteFsqrt(); break;

                case Mnemonic.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break;

                case Mnemonic.ftan: RewriteFtan(); break;

                case Mnemonic.jmp: RewriteJmp(); break;

                case Mnemonic.jsr: RewriteJsr(); break;

                case Mnemonic.lea: RewriteLea(); break;

                case Mnemonic.link: RewriteLink(); break;

                case Mnemonic.lsl: RewriteShift((s, d) => m.Shl(d, s)); break;

                case Mnemonic.lsr: RewriteShift((s, d) => m.Shr(d, s)); break;

                case Mnemonic.move: RewriteMove(true); break;

                case Mnemonic.move16: RewriteMove16(); break;

                case Mnemonic.movea: RewriteMove(false); break;

                case Mnemonic.movep: RewriteMovep(); break;

                case Mnemonic.moveq: RewriteMoveq(); break;

                case Mnemonic.moves: RewriteMoves(); break;

                case Mnemonic.movem: RewriteMovem(Registers.GetRegister); break;

                case Mnemonic.muls: RewriteMul((s, d) => m.SMul(d, s)); break;

                case Mnemonic.mulu: RewriteMul((s, d) => m.UMul(d, s)); break;

                case Mnemonic.nbcd: RewriteNbcd(); break;

                case Mnemonic.neg: RewriteUnary(s => m.Neg(s), AllConditions); break;

                case Mnemonic.negx: RewriteUnary(RewriteNegx, AllConditions); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break;

                case Mnemonic.or: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Mnemonic.ori: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Mnemonic.pack: RewritePack(); break;

                case Mnemonic.pea: RewritePea(); break;

                case Mnemonic.pflushr: RewritePflushr(); break;

                case Mnemonic.ptest: RewritePtest(); break;

                case Mnemonic.rol: RewriteRotation(PseudoProcedure.Rol); break;

                case Mnemonic.ror: RewriteRotation(PseudoProcedure.Ror);  break;

                case Mnemonic.roxl: RewriteRotationX(PseudoProcedure.RolC);  break;

                case Mnemonic.roxr: RewriteRotationX(PseudoProcedure.RorC);  break;

                case Mnemonic.rtd: RewriteRtd(); break;

                case Mnemonic.rte: RewriteRte(); break;

                case Mnemonic.rtm: RewriteRtm(); break;

                case Mnemonic.rts: RewriteRts(); break;

                case Mnemonic.sbcd: RewriteSbcd(); break;

                case Mnemonic.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break;

                case Mnemonic.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break;

                case Mnemonic.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break;

                case Mnemonic.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Mnemonic.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.sls: RewriteScc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.slt: RewriteScc(ConditionCode.LT, FlagM.NF | FlagM.ZF); break;

                case Mnemonic.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break;

                case Mnemonic.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break;

                case Mnemonic.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break;

                case Mnemonic.svc: RewriteScc(ConditionCode.NO, FlagM.VF); break;

                case Mnemonic.svs: RewriteScc(ConditionCode.OV, FlagM.VF); break;

                case Mnemonic.st: orw.RewriteMoveDst(instr.Operands[0], instr.Address, PrimitiveType.Bool, Constant.True()); break;

                case Mnemonic.sf: orw.RewriteMoveDst(instr.Operands[0], instr.Address, PrimitiveType.Bool, Constant.False()); break;

                case Mnemonic.stop: RewriteStop(); break;

                case Mnemonic.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Mnemonic.suba: RewriteBinOp((s, d) => m.ISub(d, s)); break;

                case Mnemonic.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Mnemonic.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break;

                case Mnemonic.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break;

                case Mnemonic.swap: RewriteSwap(); break;

                case Mnemonic.trap: RewriteTrap(); break;

                case Mnemonic.trapcc: RewriteTrapCc(ConditionCode.UGE, FlagM.CF); break;

                case Mnemonic.trapcs: RewriteTrapCc(ConditionCode.ULT, FlagM.CF); break;

                case Mnemonic.trapeq: RewriteTrapCc(ConditionCode.EQ, FlagM.ZF); break;

                case Mnemonic.trapf: RewriteTrapCc(ConditionCode.NEVER, 0); break;

                case Mnemonic.trapge: RewriteTrapCc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Mnemonic.trapgt: RewriteTrapCc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.traphi: RewriteTrapCc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Mnemonic.traple: RewriteTrapCc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Mnemonic.traplt: RewriteTrapCc(ConditionCode.LT, FlagM.CF | FlagM.VF); break;

                case Mnemonic.trapls: RewriteTrapCc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Mnemonic.trapmi: RewriteTrapCc(ConditionCode.LT, FlagM.NF); break;

                case Mnemonic.trapne: RewriteTrapCc(ConditionCode.NE, FlagM.ZF); break;

                case Mnemonic.trappl: RewriteTrapCc(ConditionCode.GT, FlagM.NF); break;

                case Mnemonic.trapvc: RewriteTrapCc(ConditionCode.NO, FlagM.VF); break;

                case Mnemonic.trapvs: RewriteTrapCc(ConditionCode.OV, FlagM.VF); break;

                case Mnemonic.tas: RewriteTas(); break;

                case Mnemonic.tst: RewriteTst(); break;

                case Mnemonic.unlk: RewriteUnlk(); break;

                case Mnemonic.unpk: RewriteUnpk(); break;
                }
                yield return(new RtlInstructionCluster(
                                 addr,
                                 len,
                                 rtlInstructions.ToArray())
                {
                    Class = rtlc
                });
            }
            yield break;
        }
Example #3
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                di = dasm.Current;
                var addr = di.Address;
                var len  = di.Length;
                rtlInstructions = new List <RtlInstruction>();
                rtlc            = RtlClass.Linear;
                m   = new RtlEmitter(rtlInstructions);
                orw = new OperandRewriter(arch, this.m, this.binder, di.dataWidth);
                switch (di.code)
                {
                default:
                    host.Warn(
                        di.Address,
                        "Rewriting M68k opcode '{0}' is not supported yet.",
                        di.code);
                    m.Invalid();
                    break;

                case Opcode.illegal: RewriteIllegal(); break;

                case Opcode.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break;

                case Opcode.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break;

                case Opcode.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break;

                case Opcode.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break;

                case Opcode.addx: RewriteAddSubx(m.IAdd); break;

                case Opcode.and: RewriteLogical((s, d) => m.And(d, s)); break;

                case Opcode.andi: RewriteLogical((s, d) => m.And(d, s)); break;

                case Opcode.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break;

                case Opcode.asr: RewriteShift((s, d) => m.Sar(d, s)); break;

/*
 *
 * Mnemonic Condition Encoding Test
 * T* True 0000 1
 * F* False 0001 0
 * HI High 0010 C L Z
 * LS Low or Same 0011 C V Z
 * VC Overflow Clear 1000 V
 * VS Overflow Set 1001 V
 */
                case Opcode.bclr: RewriteBclrBset("__bclr"); break;

                case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); 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.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break;

                case Opcode.bchg: RewriteBchg(); break;

                case Opcode.bra: RewriteBra(); break;

                case Opcode.bset: RewriteBclrBset("__bset"); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.btst: RewriteBtst(); break;

                case Opcode.cas: RewriteCas(); break;

                case Opcode.clr: RewriteClr(); break;

                case Opcode.chk: RewriteChk(); break;

                case Opcode.chk2: RewriteChk2(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmp2: RewriteCmp2(); break;

                case Opcode.cmpa: RewriteCmp(); break;

                case Opcode.cmpi: RewriteCmp(); break;

                case Opcode.cmpm: RewriteCmp(); break;

                case Opcode.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Opcode.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break;

                case Opcode.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break;

                case Opcode.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break;

                case Opcode.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break;

                case Opcode.eor: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Opcode.eori: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Opcode.exg: RewriteExg(); break;

                case Opcode.ext: RewriteExt(); break;

                case Opcode.extb: RewriteExtb(); break;

                case Opcode.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break;

                //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs.
                case Opcode.fbf: m.Nop(); break;

                case Opcode.fbnge: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbnlt: RewriteFbcc(ConditionCode.GE); break;

                case Opcode.fbnle: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fbogl: RewriteFbcc(ConditionCode.NE); break;

                case Opcode.fbult: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbun: RewriteFbcc(ConditionCode.IS_NAN); break;

                case Opcode.fcmp: RewriteFcmp(); break;

                case Opcode.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break;

                case Opcode.fmove: RewriteFmove(); break;

                case Opcode.fmovecr: RewriteFmovecr(); break;

                case Opcode.fmovem: RewriteMovem(i => arch.GetRegister(i + Registers.fp0.Number)); break;

                case Opcode.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break;

                case Opcode.fneg: RewriteFUnaryOp(m.Neg); break;

                case Opcode.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.jsr: RewriteJsr(); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.link: RewriteLink(); break;

                case Opcode.lsl: RewriteShift((s, d) => m.Shl(d, s)); break;

                case Opcode.lsr: RewriteShift((s, d) => m.Shr(d, s)); break;

                case Opcode.move: RewriteMove(true); break;

                case Opcode.movea: RewriteMove(false); break;

                case Opcode.movep: RewriteMovep(); break;

                case Opcode.moveq: RewriteMoveq(); break;

                case Opcode.movem: RewriteMovem(arch.GetRegister); break;

                case Opcode.muls: RewriteMul((s, d) => m.SMul(d, s)); break;

                case Opcode.mulu: RewriteMul((s, d) => m.UMul(d, s)); break;

                case Opcode.neg: RewriteUnary(s => m.Neg(s), AllConditions); break;

                case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break;

                case Opcode.nop: m.Nop(); break;

                case Opcode.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break;

                case Opcode.or: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Opcode.ori: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Opcode.pea: RewritePea(); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror);  break;

                case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC);  break;

                case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC);  break;

                case Opcode.rts: RewriteRts(); break;

                case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break;

                case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break;

                case Opcode.stop: RewriteStop(); break;

                case Opcode.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.suba: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break;

                case Opcode.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break;

                case Opcode.swap: RewriteSwap(); break;

                case Opcode.trap: RewriteTrap(); break;

                case Opcode.tst: RewriteTst(); break;

                case Opcode.unlk: RewriteUnlk(); break;
                }
                yield return(new RtlInstructionCluster(
                                 addr,
                                 len,
                                 rtlInstructions.ToArray())
                {
                    Class = rtlc
                });
            }
            yield break;
        }
Example #4
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                di      = dasm.Current;
                ric     = new RtlInstructionCluster(di.Address, di.Length);
                emitter = new RtlEmitter(ric.Instructions);
                orw     = new OperandRewriter(arch, this.emitter, this.frame, di.dataWidth);
                switch (di.code)
                {
                case Opcode.add: RewriteBinOp((s, d) => emitter.IAdd(d, s), FlagM.CVZNX); break;

                case Opcode.adda: RewriteBinOp((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addi: RewriteArithmetic((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addq: RewriteAddSubq((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addx: RewriteAddSubx(Operator.IAdd); break;

                case Opcode.and: RewriteLogical((s, d) => emitter.And(d, s)); break;

                case Opcode.andi: RewriteLogical((s, d) => emitter.And(d, s)); break;

                case Opcode.asl: RewriteArithmetic((s, d) => emitter.Shl(d, s)); break;

                case Opcode.asr: RewriteShift((s, d) => emitter.Sar(d, s)); break;

/*
 *
 * Mnemonic Condition Encoding Test
 * T* True 0000 1
 * F* False 0001 0
 * HI High 0010 C L Z
 * LS Low or Same 0011 C V Z
 * VC Overflow Clear 1000 V
 * VS Overflow Set 1001 V
 */
                case Opcode.bclr: RewriteBclrBset("__bclr"); break;

                case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); 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.bchg: RewriteBchg(); break;

                case Opcode.bra: RewriteBra(); break;

                case Opcode.bset: RewriteBclrBset("__bset"); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.btst: RewriteBtst(); break;

                case Opcode.clr: RewriteClr(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmpa: RewriteCmp(); break;

                case Opcode.cmpi: RewriteCmp(); break;

                case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break;

                case Opcode.divu: RewriteDiv(Operator.UDiv); break;

                case Opcode.eor: RewriteLogical((s, d) => emitter.Xor(d, s)); break;

                case Opcode.eori: RewriteLogical((s, d) => emitter.Xor(d, s)); break;

                case Opcode.exg: RewriteExg(); break;

                case Opcode.ext: RewriteExt(); break;

                case Opcode.extb: RewriteExtb(); break;

                case Opcode.illegal: if (!RewriteIllegal())
                    {
                        goto default;
                    }
                    break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.jsr: RewriteJsr(); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.link: RewriteLink(); break;

                case Opcode.lsl: RewriteShift((s, d) => emitter.Shl(d, s)); break;

                case Opcode.lsr: RewriteShift((s, d) => emitter.Shr(d, s)); break;

                case Opcode.move: RewriteMove(true); break;

                case Opcode.movea: RewriteMove(false); break;

                case Opcode.moveq: RewriteMoveq(); break;

                case Opcode.movem: RewriteMovem(); break;

                case Opcode.muls: RewriteMul((s, d) => emitter.SMul(d, s)); break;

                case Opcode.mulu: RewriteMul((s, d) => emitter.UMul(d, s)); break;

                case Opcode.neg: RewriteUnary(s => emitter.Neg(s), AllConditions); break;

                case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break;

                case Opcode.nop: continue;

                case Opcode.not: RewriteUnary(s => emitter.Comp(s), LogicalConditions); break;

                case Opcode.or: RewriteLogical((s, d) => emitter.Or(d, s)); break;

                case Opcode.ori: RewriteLogical((s, d) => emitter.Or(d, s)); break;

                case Opcode.pea: RewritePea(); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror);  break;

                case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC);  break;

                case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC);  break;

                case Opcode.rts: emitter.Return(4, 0); break;

                case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break;

                case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break;

                case Opcode.sub: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.suba: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subi: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subq: RewriteAddSubq((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subx: RewriteArithmetic((s, d) => emitter.ISub(emitter.ISub(d, s), frame.EnsureFlagGroup((uint)FlagM.XF, "X", PrimitiveType.Bool))); break;

                case Opcode.swap: RewriteSwap(); break;

                case Opcode.tst: RewriteTst(); break;

                case Opcode.unlk: RewriteUnlk(); break;

                default:
                    throw new AddressCorrelatedException(
                              di.Address,
                              "Rewriting M68k opcode '{0}' is not supported yet.",
                              di.code);
                }
                yield return(ric);
            }
            yield break;
        }