Ejemplo n.º 1
0
        private Expression Rol(Expression a, Expression b)
        {
            var C         = binder.EnsureFlagGroup(Registers.C);
            var intrinsic = m.Fn(CommonOps.RolC, a, b, C);

            return(intrinsic);
        }
Ejemplo n.º 2
0
 public Identifier FlagGroup(FlagM flags)
 {
     return(frame.EnsureFlagGroup(Registers.eflags, (uint)flags, arch.GrfToString((uint)flags), PrimitiveType.Byte));
 }
Ejemplo n.º 3
0
 private void RewriteAddcSubc(Func <Expression, Expression, Expression> fn)
 {
     var t   = binder.EnsureFlagGroup(Registers.T);
     var src = SrcOp(instr.Operands[0], null);
     var dst = DstOp(instr.Operands[1], src, (a, b) =>
                     fn(fn(a, b), t));
 }
Ejemplo n.º 4
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;
        }
Ejemplo n.º 5
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                var instr = dasm.Current;
                this.iclass = instr.InstructionClass;
                switch (instr.Mnemonic)
                {
                default:
                    EmitUnitTest(instr);
                    goto case Mnemonic.Invalid;

                case Mnemonic.Invalid:
                    m.Invalid();
                    iclass = InstrClass.Invalid;
                    break;

                case Mnemonic.add: RewriteAdd(instr); break;

                case Mnemonic.adds: RewriteAdds(instr); break;

                case Mnemonic.addx: RewriteAddxSubx(instr, m.IAdd); break;

                case Mnemonic.and: RewriteLogical(instr, m.And); break;

                case Mnemonic.bld: RewriteBtst(instr, C); break;

                case Mnemonic.bset: RewriteBset(instr, Constant.True()); break;

                case Mnemonic.bst: RewriteBset(instr, binder.EnsureFlagGroup(C)); break;

                case Mnemonic.btst: RewriteBtst(instr, Z); break;

                case Mnemonic.bra: RewriteBranch(instr); break;

                case Mnemonic.brn: RewriteNop(); break;

                case Mnemonic.bhi: RewriteBranch(instr, ConditionCode.UGT, ZC); break;

                case Mnemonic.bls: RewriteBranch(instr, ConditionCode.ULE, ZC); break;

                case Mnemonic.bcc: RewriteBranch(instr, ConditionCode.UGE, C); break;

                case Mnemonic.bcs: RewriteBranch(instr, ConditionCode.ULT, C); break;

                case Mnemonic.bne: RewriteBranch(instr, ConditionCode.NE, Z); break;

                case Mnemonic.beq: RewriteBranch(instr, ConditionCode.EQ, Z); break;

                case Mnemonic.bvc: RewriteBranch(instr, ConditionCode.NO, V); break;

                case Mnemonic.bvs: RewriteBranch(instr, ConditionCode.OV, V); break;

                case Mnemonic.bpl: RewriteBranch(instr, ConditionCode.GE, N); break;

                case Mnemonic.bmi: RewriteBranch(instr, ConditionCode.LT, N); break;

                case Mnemonic.bge: RewriteBranch(instr, ConditionCode.GE, NV); break;

                case Mnemonic.blt: RewriteBranch(instr, ConditionCode.LT, NV); break;

                case Mnemonic.bgt: RewriteBranch(instr, ConditionCode.GT, NZV); break;

                case Mnemonic.ble: RewriteBranch(instr, ConditionCode.LE, NZV); break;

                case Mnemonic.cmp: RewriteCmp(instr); break;

                case Mnemonic.extu: RewriteExt(instr, Domain.UnsignedInt); break;

                case Mnemonic.jmp: RewriteJmp(instr); break;

                case Mnemonic.jsr: RewriteJsr(instr); break;

                case Mnemonic.ldc: RewriteLdc(instr); break;

                case Mnemonic.mov: RewriteMov(instr); break;

                case Mnemonic.mulxu: RewriteMulxu(instr); break;

                case Mnemonic.nop: RewriteNop(); break;

                case Mnemonic.not: RewriteUnaryLogical(instr, m.Comp); break;

                case Mnemonic.or: RewriteLogical(instr, m.Or); break;

                case Mnemonic.rotxl: RewriteRotationX(instr, PseudoProcedure.RolC); break;

                case Mnemonic.rotxr: RewriteRotationX(instr, PseudoProcedure.RorC); break;

                case Mnemonic.rts: RewriteRts(); break;

                case Mnemonic.shal: RewriteShift(instr, m.Shl); break;

                case Mnemonic.shar: RewriteShift(instr, m.Sar); break;

                case Mnemonic.shll: RewriteShift(instr, m.Shl); break;

                case Mnemonic.shlr: RewriteShift(instr, m.Shr); break;

                case Mnemonic.sub: RewriteSub(instr); break;

                case Mnemonic.subs: RewriteSubs(instr); break;

                case Mnemonic.subx: RewriteAddxSubx(instr, m.ISub); break;

                case Mnemonic.xor: RewriteLogical(instr, m.Xor); break;
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, iclass));

                this.m = new RtlEmitter(new List <RtlInstruction>());
            }
        }
Ejemplo n.º 6
0
        private void SetCc(Expression e)
        {
            var cc = binder.EnsureFlagGroup(Registers.CC);

            m.Assign(cc, e);
        }
Ejemplo n.º 7
0
 private Identifier FlagGroup(FlagM flags)
 {
     return(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.psw, (uint)flags)));
 }
Ejemplo n.º 8
0
        public void EmitCc(Expression exp, string szhvnc)
        {
            // SZIH XVNC
            var  mask = 1u << 7;
            uint grf  = 0;

            foreach (var c in szhvnc)
            {
                switch (c)
                {
                case '*':
                case 'S':
                case 'Z':
                case 'I':
                case 'H':
                case 'X':
                case 'V':
                case 'N':
                case 'C':
                    grf |= mask;
                    break;

                case '0':
                    m.Assign(
                        binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)),
                        Constant.False());
                    break;

                case '1':
                    m.Assign(
                        binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, mask)),
                        Constant.True());
                    break;
                }
                mask >>= 1;
            }
            if (grf != 0)
            {
                m.Assign(
                    binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, grf)),
                    m.Cond(exp));
            }
        }
Ejemplo n.º 9
0
 private void EmitFlags(Expression e, FlagM mod = 0, FlagM clr = 0, FlagM set = 0)
 {
     if (mod != 0)
     {
         var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, (uint)mod));
         m.Assign(grf, m.Cond(e));
     }
     if (clr != 0)
     {
         uint grfMask = 1;
         while (grfMask <= (uint)clr)
         {
             if ((grfMask & (uint)clr) != 0)
             {
                 var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, grfMask));
                 m.Assign(grf, 0);
             }
             grfMask <<= 1;
         }
     }
     if (set != 0)
     {
         uint grfMask = 1;
         while (grfMask <= (uint)set)
         {
             if ((grfMask & (uint)set) != 0)
             {
                 var grf = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.sreg, grfMask));
                 m.Assign(grf, 1);
             }
             grfMask <<= 1;
         }
     }
 }
Ejemplo n.º 10
0
        private void CV(Identifier dst)
        {
            var cv = binder.EnsureFlagGroup(arch.GetFlagGroup((uint)(FlagM.CY | FlagM.OV)));

            m.Assign(cv, m.Cond(dst));
        }
Ejemplo n.º 11
0
        private void NZV_(Expression e)
        {
            var grf = arch.GetFlagGroup(Registers.ccr, (uint)(FlagM.NF | FlagM.ZF | FlagM.VF));

            m.Assign(binder.EnsureFlagGroup(grf), m.Cond(e));
        }
Ejemplo n.º 12
0
        private void RewriteBinop(Func <Expression, Expression, BinaryExpression> fn, FlagGroupStorage grf = null)
        {
            var dst = OpSrc(instr.Operands[0], arch.DataMemory);
            var src = OpSrc(instr.Operands[1], arch.DataMemory);

            m.Assign(dst, fn(dst, src));
            if (grf != null)
            {
                m.Assign(binder.EnsureFlagGroup(grf), m.Cond(dst));
            }
        }
Ejemplo n.º 13
0
 public Expression VisitFlagGroupStorage(FlagGroupStorage grf)
 {
     return(binder.EnsureFlagGroup(grf.FlagRegister, grf.FlagGroupBits, grf.Name, grf.DataType));
 }
Ejemplo n.º 14
0
        public void AddFlagGroupReturnValue(KeyValuePair <RegisterStorage, uint> bits, IStorageBinder binder)
        {
            var grf = arch.GetFlagGroup(bits.Key, bits.Value) !;

            ret = binder.EnsureFlagGroup(grf);
        }
Ejemplo n.º 15
0
 private void Assign(FlagGroupStorage grf, Expression e)
 {
     m.Assign(binder.EnsureFlagGroup(grf), e);
 }
Ejemplo n.º 16
0
 private Identifier NZCV()
 {
     return(binder.EnsureFlagGroup(Registers.NZCV));
 }
Ejemplo n.º 17
0
        private void C(Expression e)
        {
            var carry = binder.EnsureFlagGroup(Registers.C);

            m.Assign(carry, m.Cond(e));
        }
Ejemplo n.º 18
0
 private void EmitCc(FlagGroupStorage grf, Expression exp)
 {
     m.Assign(binder.EnsureFlagGroup(grf), m.Cond(exp));
 }
Ejemplo n.º 19
0
 private Identifier FlagGroup(FlagGroupStorage flags)
 {
     return(binder.EnsureFlagGroup(flags));
 }
Ejemplo n.º 20
0
 public Identifier FlagGroup(FlagGroupStorage flags) => binder.EnsureFlagGroup(flags);
Ejemplo n.º 21
0
 private void ClrCc(Expression e)
 {
     m.Assign(binder.EnsureFlagGroup(Registers.N), Constant.False());
     m.Assign(binder.EnsureFlagGroup(Registers.Z), Constant.True());
     m.Assign(binder.EnsureFlagGroup(Registers.V), Constant.False());
     m.Assign(binder.EnsureFlagGroup(Registers.C), Constant.False());
 }
Ejemplo n.º 22
0
 protected Identifier FlagGroup(FlagM flags)
 => binder.EnsureFlagGroup(PICRegisters.STATUS, (uint)flags, arch.GrfToString((uint)flags), PrimitiveType.Byte);
Ejemplo n.º 23
0
        private void CNZ(Expression e)
        {
            var cnz = binder.EnsureFlagGroup(arch.GetFlagGroup(arch.st, (uint)FlagM.CNZ));

            m.Assign(cnz, m.Cond(e));
        }
Ejemplo n.º 24
0
        private void RewriteBinop(Func <Expression, Expression, BinaryExpression> fn, FlagM grf)
        {
            var dst = OpSrc(instr.Operands[0]);
            var src = OpSrc(instr.Operands[1]);

            m.Assign(dst, fn(dst, src));
            if (grf != 0)
            {
                var flg = arch.GetFlagGroup(Registers.PSW, (uint)grf);
                m.Assign(binder.EnsureFlagGroup(flg), m.Cond(dst));
            }
        }
Ejemplo n.º 25
0
 private Identifier C()
 {
     return(binder.EnsureFlagGroup(Registers.C));
 }
Ejemplo n.º 26
0
        private Identifier NZCV()
        {
            var nzcv = arch.GetFlagGroup((uint)(FlagM.NF | FlagM.ZF | FlagM.CF | FlagM.VF));

            return(binder.EnsureFlagGroup(nzcv));
        }
Ejemplo n.º 27
0
        private Expression Rol(Expression a, Expression b)
        {
            var C         = binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.ccr, (uint)FlagM.CF));
            var intrinsic = host.Intrinsic(IntrinsicProcedure.RolC, true, a.DataType, a, b, C);

            return(intrinsic);
        }
Ejemplo n.º 28
0
 public Identifier FlagGroup(FlagM flags)
 {
     return(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.f, (uint)flags)));
 }
Ejemplo n.º 29
0
 public Identifier FlagGroup(FlagM flags)
 {
     return(binder.EnsureFlagGroup(arch.GetFlagGroup((uint)flags)));;
 }
Ejemplo n.º 30
0
 private void ClrCc(Expression e)
 {
     m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.N)), Constant.False());
     m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.Z)), Constant.True());
     m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.V)), Constant.False());
     m.Assign(binder.EnsureFlagGroup(arch.GetFlagGroup(Registers.CC, (uint)FlagM.C)), Constant.False());
 }