Rewrites M68k operands into sequences of RTL expressions and possibly instructions.
Some of the operands, like (A6)+ and -(A5), have side effects that need to be expressed as separate instructions. We must therefore insert RTL instructions into the stream as these operands are rewritten. Because of these side effects, it is critical that we don't call Rewrite twice on the same operand, as this will cause two side effect instructions to be generated.
Beispiel #1
0
        public void M68korw_MemOp()
        {
            var orw = new OperandRewriter(
                arch,
                new RtlEmitter(new List<RtlInstruction>()),
                new Frame(arch.FramePointerType),
                PrimitiveType.Byte);
            var exp = orw.RewriteSrc(new MemoryOperand(PrimitiveType.Byte, Registers.a1, Constant.Int16(4)), addrInstr);

            var ea = (BinaryExpression) ((MemoryAccess) exp).EffectiveAddress;
            Assert.AreEqual(ea.Left.DataType.Size, ea.Right.DataType.Size);
        }
Beispiel #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;
        }
Beispiel #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;
        }
Beispiel #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;
        }