Beispiel #1
0
        private void RewriteMovx()
        {
            var src  = SrcOperand(1);
            var from = PrimitiveType.Create(Domain.SignedInt, src.DataType.BitSize);

            m.Assign(Reg(0), m.Convert(src, from, PrimitiveType.Int32));
        }
Beispiel #2
0
        private void RewriteLoad(PrimitiveType dtDst)
        {
            var        dst = Reg(instrCur.Operands[0]);
            Expression mem = Mem(instrCur.Operands[1]);

            if (mem.DataType.BitSize < dtDst.BitSize)
            {
                mem = m.Convert(mem, mem.DataType, dtDst);
            }
            m.Assign(dst, mem);
        }
Beispiel #3
0
        private void RewriteLoad(PrimitiveType dt)
        {
            var src = Rewrite(instr.Operands[1]);
            var dst = Rewrite(instr.Operands[0]);

            if (src.DataType.BitSize < dst.DataType.BitSize)
            {
                src = m.Convert(src, src.DataType, dt);
            }
            m.Assign(dst, src);
        }
Beispiel #4
0
        private void RewriteCast(PrimitiveType dtFrom, PrimitiveType dtTo)
        {
            var src = RewriteOp(0);

            if (src.DataType.BitSize > dtFrom.BitSize)
            {
                src = m.Slice(dtFrom, src, 0);
            }
            var dst = RewriteOpDst(0, m.Convert(src, dtFrom, dtTo));

            EmitCc(NZC, dst);
        }
 private void EmitLoad(Identifier dst, MemoryAccess src)
 {
     if (src.DataType.BitSize < dst.DataType.BitSize)
     {
         var tmp = binder.CreateTemporary(src.DataType);
         m.Assign(tmp, src);
         m.Assign(dst, m.Convert(tmp, tmp.DataType, dst.DataType));
     }
     else
     {
         m.Assign(dst, src);
     }
 }
Beispiel #6
0
 private MemoryAccess RewriteMemoryOperand(MemoryOperand memop)
 {
     if (memop.Base != null)
     {
         Expression baseReg;
         if (memop.Base == Registers.pc)
         {
             baseReg = instr.Address + instr.Length;
         }
         else
         {
             baseReg = binder.EnsureRegister(memop.Base);
         }
         Expression ea = baseReg;
         if (memop.Index != null)
         {
             Expression idx = binder.EnsureRegister(memop.Index);
             if (idx.DataType.BitSize < ea.DataType.BitSize)
             {
                 idx = m.Convert(idx, idx.DataType, PrimitiveType.UInt16);
             }
             ea = m.IAdd(baseReg, idx);
         }
         else if (memop.PreIncrement)
         {
             m.Assign(ea, m.IAddS(ea, memop.Offset.Value));
         }
         else if (memop.PostIncrement)
         {
             var tmp = binder.CreateTemporary(baseReg.DataType);
             m.Assign(tmp, ea);
             m.Assign(baseReg, m.IAddS(baseReg, memop.Offset.Value));
             ea = tmp;
         }
         else
         {
             ea = m.IAdd(baseReg, (ushort)memop.Offset.Value);
         }
         if (memop.Indirect)
         {
             ea = m.Mem(PrimitiveType.Ptr16, ea);
         }
         return(m.Mem(memop.Width, ea));
     }
     else
     {
         Debug.Assert(memop.Offset != null);
         return(m.Mem(memop.Width, Address.Ptr16((ushort)memop.Offset.Value)));
     }
 }
Beispiel #7
0
        private void RewriteMovz()
        {
            var src = Op(1);
            var dst = Op(0);

            m.Assign(dst, m.Convert(src, src.DataType, dst.DataType));
        }
Beispiel #8
0
        private void RewriteSxt(string flags)
        {
            var src = RewriteOp(instr.Operands[0]);
            var tmp = binder.CreateTemporary(PrimitiveType.Byte);

            m.Assign(tmp, m.Slice(PrimitiveType.Byte, src, 0));
            var dst = RewriteDst(instr.Operands[0], tmp, (a, b) => m.Convert(b, b.DataType, PrimitiveType.Int16));

            EmitCc(dst, flags);
        }
Beispiel #9
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand reg:
                return(binder.EnsureRegister(reg.Register));

            case AddressOperand addr:
                return(addr.Address);

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    ea = binder.EnsureRegister(mem.Base);
                    if (mem.Index != null)
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(
                            ea,
                            m.Convert(idx, idx.DataType, PrimitiveType.Int16));
                    }
                    else if (mem.Offset != null)
                    {
                        ea = m.IAdd(
                            ea,
                            m.Int16((sbyte)mem.Offset.ToByte()));
                    }
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(mem.Offset, false);
                }
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, ea));
                return(tmp);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Beispiel #10
0
        private void RewriteSxt()
        {
            var src = RewriteOp(instr.Operands[0]);
            var tmp = binder.CreateTemporary(PrimitiveType.Byte);

            m.Assign(tmp, m.Slice(PrimitiveType.Byte, src, 0));
            var dst = RewriteDst(instr.Operands[0], tmp, (a, b) => m.Convert(b, b.DataType, PrimitiveType.Int16));

            EmitCc(dst, Registers.NZC);
            Assign(Registers.V, Constant.False());
        }
Beispiel #11
0
        private void RewriteLoad(MipsInstruction instr, PrimitiveType dt)
        {
            var src = Rewrite(instr.Operands[1]);
            var dst = Rewrite(instr.Operands[0]);

            src.DataType = dt;
            if (dst.DataType.Size != src.DataType.Size)
            {
                // If the source is smaller than the destination register,
                // perform a sign/zero extension/conversion.
                src = m.Convert(src, src.DataType, arch.WordWidth);
            }
            m.Assign(dst, src);
        }
Beispiel #12
0
        private void RewriteExt(H8Instruction instr, Domain domain)
        {
            var dstRange = new BitRange(0, instr.Size !.BitSize);
            var srcRange = new BitRange(0, instr.Size !.BitSize / 2);
            var dt       = PrimitiveType.Create(domain, dstRange.Extent);
            var dst      = (Identifier)OpSrc(instr.Operands[0]);
            var src      = binder.EnsureRegister(arch.GetRegister(
                                                     dst.Storage.Domain,
                                                     srcRange) !);

            m.Assign(dst, m.Convert(src, src.DataType, dt));
            EmitCond(Z, dst);
            m.Assign(binder.EnsureFlagGroup(N), Constant.False());
            m.Assign(binder.EnsureFlagGroup(V), Constant.False());
        }
Beispiel #13
0
        private void RewriteAddw()
        {
            var src = RewriteSrc(instr.Operands[1]);
            Func <Expression, Expression, Expression> fn;

            if (src.DataType.Size < instr.Operands[0].Width.Size)
            {
                if (src is Constant c)
                {
                    fn = (a, b) => m.IAddS(a, c.ToInt32());
                }
                else
                {
                    fn = (a, b) => m.IAdd(a, m.Convert(b, b.DataType, PrimitiveType.UInt16));
                }
            }
            else
            {
                fn = m.IAdd;
            }
            var dst = RewriteDst(instr.Operands[0], src, fn);

            EmitCond(dst, CZ());
        }
Beispiel #14
0
 private void RewriteExt(PrimitiveType dtSrc, PrimitiveType dtDst)
 {
     var src = SrcOp(instr.Operands[0], null);
     var dst = DstOp(instr.Operands[1], src, (a, b) =>
     {
         if (b.DataType.BitSize > dtSrc.BitSize)
         {
             b = m.Slice(dtSrc, b, 0);
         }
         return(m.Convert(b, dtSrc, dtDst));
     });
 }
Beispiel #15
0
        private Expression Operand(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Address != null)
                {
                    if (mem.Register != null)
                    {
                        ea = m.IAdd(
                            mem.Address,
                            m.Convert(binder.EnsureRegister(mem.Register), mem.Register.DataType, PrimitiveType.UInt16));
                    }
                    else
                    {
                        ea = mem.Address;
                    }
                }
                else
                {
                    ea = RegisterPair(mem.Register !);
                }
                return(m.Mem(mem.Width, ea));

            case AddressOperand addr:
                return(addr.Address);

            default:
                throw new NotImplementedException(op.GetType().Name);
            }
        }
Beispiel #16
0
        private Expression?RewriteApplication(ApplicationOperand app)
        {
            var ops = app.Operands.Select(o => OperandSrc(o) !).ToArray();
            var dt  = app.Width;

            switch (app.Mnemonic)
            {
            case Mnemonic.add: return(m.IAdd(ops[0], ops[1]));

            case Mnemonic.addasl: return(RewriteAddAsl(ops[0], ops[1], ops[2]));

            case Mnemonic.allocframe: RewriteAllocFrame(app.Operands[0]); return(null);

            case Mnemonic.and: return(m.And(ops[0], ops[1]));

            case Mnemonic.asl: return(m.Shl(ops[0], ops[1]));

            case Mnemonic.aslh: return(m.Shl(ops[0], 16));

            case Mnemonic.asr: return(m.Sar(ops[0], ops[1]));

            case Mnemonic.asrh: return(m.Sar(ops[0], 16));

            case Mnemonic.cmp__eq: return(m.Eq(ops[0], ops[1]));

            case Mnemonic.cmp__gt: return(m.Gt(ops[0], ops[1]));

            case Mnemonic.cmp__gtu: return(m.Ugt(ops[0], ops[1]));

            case Mnemonic.cmpb__eq: return(RewriteCmp(PrimitiveType.Byte, m.Eq, ops[0], ops[1]));

            case Mnemonic.cmpb__gt: return(RewriteCmp(PrimitiveType.Byte, m.Gt, ops[0], ops[1]));

            case Mnemonic.cmpb__gtu: return(RewriteCmp(PrimitiveType.Byte, m.Ugt, ops[0], ops[1]));

            case Mnemonic.cmph__eq: return(RewriteCmp(PrimitiveType.Word16, m.Eq, ops[0], ops[1]));

            case Mnemonic.cmph__gt: return(RewriteCmp(PrimitiveType.Word16, m.Gt, ops[0], ops[1]));

            case Mnemonic.cmph__gtu: return(RewriteCmp(PrimitiveType.Word16, m.Ugt, ops[0], ops[1]));

            case Mnemonic.dfcmp__eq: return(m.FEq(ops[0], ops[1]));

            case Mnemonic.dfcmp__ge: return(m.FGe(ops[0], ops[1]));

            case Mnemonic.dfcmp__uo: return(host.Intrinsic("isunordered", false, PrimitiveType.Bool, ops[0], ops[1]));

            case Mnemonic.combine: return(RewriteCombine(ops[0], ops[1]));

            case Mnemonic.convert_d2df: return(m.Convert(ops[0], PrimitiveType.Int64, PrimitiveType.Real64));

            case Mnemonic.convert_df2sf: return(m.Convert(ops[0], PrimitiveType.Real64, PrimitiveType.Real32));

            case Mnemonic.convert_sf2df: return(m.Convert(ops[0], PrimitiveType.Real32, PrimitiveType.Real64));

            case Mnemonic.EQ: return(m.Eq(ops[0], ops[1]));

            case Mnemonic.extract: return(RewriteExtract(Domain.SignedInt, ops[0], app.Operands));

            case Mnemonic.extractu: return(RewriteExtract(Domain.UnsignedInt, ops[0], app.Operands));

            case Mnemonic.loop0: RewriteLoop(0, ops); return(null);

            case Mnemonic.loop1: RewriteLoop(1, ops); return(null);

            case Mnemonic.lsl: return(m.Shl(ops[0], ops[1]));

            case Mnemonic.lsr: return(m.Shr(ops[0], ops[1]));

            case Mnemonic.mpy: return(RewriteMpy(ops[0], ops[1]));

            case Mnemonic.mpyi: return(RewriteMpyi(ops[0], ops[1]));

            case Mnemonic.mpyu: return(RewriteMpyu(app.Width, ops[0], ops[1]));

            case Mnemonic.mux: return(m.Conditional(ops[1].DataType, ops[0], ops[1], ops[2]));

            case Mnemonic.NE: return(m.Ne(ops[0], ops[1]));

            case Mnemonic.neg: return(m.Neg(ops[0]));

            case Mnemonic.not: return(m.Not(ops[0]));

            case Mnemonic.or: return(m.Or(ops[0], ops[1]));

            case Mnemonic.sub: return(m.ISub(ops[0], ops[1]));

            case Mnemonic.sxtb: return(RewriteExt(ops[0], PrimitiveType.SByte, PrimitiveType.Int32));

            case Mnemonic.sxth: return(RewriteExt(ops[0], PrimitiveType.Int16, PrimitiveType.Int32));

            case Mnemonic.xor: return(m.Xor(ops[0], ops[1]));

            case Mnemonic.zxtb: return(RewriteExt(ops[0], PrimitiveType.Byte, PrimitiveType.UInt32));

            case Mnemonic.zxth: return(RewriteExt(ops[0], PrimitiveType.UInt16, PrimitiveType.UInt32));

            case Mnemonic.abs: dt = PrimitiveType.Int32; goto intrinsicFunc;

            case Mnemonic.max: dt = PrimitiveType.Int32; goto intrinsicFunc;

            case Mnemonic.maxu: dt = PrimitiveType.UInt32; goto intrinsicFunc;

            case Mnemonic.min: dt = PrimitiveType.Int32; goto intrinsicFunc;

            case Mnemonic.minu: dt = PrimitiveType.UInt32; goto intrinsicFunc;

            case Mnemonic.all8:
            case Mnemonic.any8:
            case Mnemonic.bitsclr:
            case Mnemonic.bitsplit:
            case Mnemonic.bitsset:
            case Mnemonic.ciad:
            case Mnemonic.cl0:
            case Mnemonic.cl1:
            case Mnemonic.clb:
            case Mnemonic.clrbit:
            case Mnemonic.crswap:
            case Mnemonic.cswi:
            case Mnemonic.ct0:
            case Mnemonic.dfclass:
            case Mnemonic.fastcorner9:
            case Mnemonic.insert:   //$BUG: like DPB?
            case Mnemonic.memw_locked:
            case Mnemonic.setbit:
            case Mnemonic.start:
            case Mnemonic.stop:
            case Mnemonic.tlbw:
            case Mnemonic.tlbp:
            case Mnemonic.trap0:
            case Mnemonic.trap1:
            case Mnemonic.togglebit:
            case Mnemonic.tstbit:
intrinsicFunc:
                return(RewriteIntrinsic(app.Mnemonic.ToString(), true, dt, ops));

            case Mnemonic.dccleana:
            case Mnemonic.dccleaninva:
            case Mnemonic.dcfetch:
            case Mnemonic.dcinva:
            case Mnemonic.dczeroa:
                return(RewriteIntrinsic(app.Mnemonic.ToString(), true, VoidType.Instance, ops));

            case Mnemonic.vavgh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Word16, ops));

            case Mnemonic.vcmpb__eq: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops));

            case Mnemonic.vmux: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops));

            case Mnemonic.vsplatb: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops));

            case Mnemonic.vsubh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Int16, ops));
            }
            throw new ArgumentException($"Hexagon rewriter for {app.Mnemonic} not implemented yet.", app.Mnemonic.ToString());
        }
Beispiel #17
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr  = dasm.Current;
                this.iclass = this.instr.InstructionClass;
                var instrs = new List <RtlInstruction>();
                this.m = new RtlEmitter(instrs);
                switch (instr.Mnemonic)
                {
                default:
                    host.Error(
                        dasm.Current.Address,
                        string.Format(
                            "SuperH instruction {0} not supported yet.",
                            dasm.Current.Mnemonic));
                    EmitUnitTest();
                    goto case Mnemonic.invalid;

                case Mnemonic.invalid:
                    Invalid();
                    break;

                case Mnemonic.add: RewriteBinOp(m.IAdd, n => (sbyte)n); break;

                case Mnemonic.addc: RewriteAddcSubc(m.IAdd); break;

                case Mnemonic.addv: RewriteAddv(m.IAdd); break;

                case Mnemonic.and: RewriteBinOp(m.And, n => (byte)n); break;

                case Mnemonic.and_b: RewriteBinOp(m.And, n => (byte)n); break;

                case Mnemonic.bf: RewriteBranch(false, false); break;

                case Mnemonic.bf_s: RewriteBranch(false, true); break;

                case Mnemonic.bra: RewriteGoto(); break;

                case Mnemonic.braf: RewriteBraf(); break;

                case Mnemonic.brk: RewriteBrk(); break;

                case Mnemonic.bsr: RewriteBsr(); break;

                case Mnemonic.bsrf: RewriteBsrf(); break;

                case Mnemonic.bt: RewriteBranch(true, false); break;

                case Mnemonic.bt_s: RewriteBranch(true, true); break;

                case Mnemonic.clrmac: RewriteClr(Registers.mac); break;

                case Mnemonic.clrs: RewriteClrtSet(Registers.S, Constant.False()); break;

                case Mnemonic.clrt: RewriteClrtSet(Registers.T, Constant.False()); break;

                case Mnemonic.cmp_eq: RewriteCmp(m.Eq); break;

                case Mnemonic.cmp_ge: RewriteCmp(m.Ge); break;

                case Mnemonic.cmp_gt: RewriteCmp(m.Gt); break;

                case Mnemonic.cmp_hs: RewriteCmp(m.Uge); break;

                case Mnemonic.cmp_hi: RewriteCmp(m.Ugt); break;

                case Mnemonic.cmp_pl: RewriteCmp0(m.Gt0); break;

                case Mnemonic.cmp_pz: RewriteCmp0(m.Ge0); break;

                case Mnemonic.cmp_str: RewriteCmpStr(); break;

                case Mnemonic.div0s: RewriteDiv0s(); break;

                case Mnemonic.div0u: RewriteDiv0u(); break;

                case Mnemonic.div1: RewriteDiv1(); break;

                case Mnemonic.dmuls_l: RewriteDmul(m.SMul); break;

                case Mnemonic.dmulu_l: RewriteDmul(m.UMul); break;

                case Mnemonic.dt: RewriteDt(); break;

                case Mnemonic.exts_b: RewriteExt(PrimitiveType.SByte, PrimitiveType.Int32); break;

                case Mnemonic.exts_w: RewriteExt(PrimitiveType.Int16, PrimitiveType.Int32); break;

                case Mnemonic.extu_b: RewriteExt(PrimitiveType.Byte, PrimitiveType.UInt32); break;

                case Mnemonic.extu_w: RewriteExt(PrimitiveType.UInt16, PrimitiveType.UInt32); break;

                case Mnemonic.fabs: RewriteFabs(); break;

                case Mnemonic.fadd: RewriteBinOp(m.FAdd, null); break;

                case Mnemonic.fcmp_eq: RewriteCmp(m.FEq); break;

                case Mnemonic.fcmp_gt: RewriteCmp(m.FGt); break;

                case Mnemonic.fcnvds: RewriteUnary(d => m.Convert(d, PrimitiveType.Real64, PrimitiveType.Real32)); break;

                case Mnemonic.fcnvsd: RewriteUnary(d => m.Convert(d, PrimitiveType.Real32, PrimitiveType.Real64)); break;

                case Mnemonic.fdiv: RewriteBinOp(m.FDiv, null); break;

                case Mnemonic.fldi0: RewriteFldi(0.0F); break;

                case Mnemonic.fldi1: RewriteFldi(1.0F); break;

                case Mnemonic.flds: RewriteMov(); break;

                case Mnemonic.@float: RewriteFloat(); break;

                case Mnemonic.fmac: RewriteFmac(); break;

                case Mnemonic.fmov: RewriteMov(); break;

                case Mnemonic.fmov_d: RewriteMov(); break;

                case Mnemonic.fmov_s: RewriteMov(); break;

                case Mnemonic.fmul: RewriteBinOp(m.FMul, n => n); break;

                case Mnemonic.fsts: RewriteMov(); break;

                case Mnemonic.ftrc: RewriteFtrc(); break;

                case Mnemonic.jmp: RewriteJmp(); break;

                case Mnemonic.jsr: RewriteJsr(); break;

                case Mnemonic.lds: RewriteMov(); break;

                case Mnemonic.lds_l: RewriteMov(); break;

                case Mnemonic.mac_l: RewriteMac(PrimitiveType.Int64); break;

                case Mnemonic.mac_w: RewriteMac(PrimitiveType.Int32); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.mova: RewriteMova(); break;

                case Mnemonic.mov_b: RewriteMov(); break;

                case Mnemonic.mov_w: RewriteMov(); break;

                case Mnemonic.mov_l: RewriteMov(); break;

                case Mnemonic.movt: RewriteMovt(); break;

                case Mnemonic.mul_l: RewriteMul_l(); break;

                case Mnemonic.muls_w: RewriteMul_w(PrimitiveType.Int16, m.SMul); break;

                case Mnemonic.mulu_w: RewriteMul_w(PrimitiveType.UInt16, m.UMul); break;

                case Mnemonic.neg: RewriteUnary(m.Neg); break;

                case Mnemonic.negc: RewriteNegc(); break;

                case Mnemonic.not: RewriteUnary(m.Comp); break;

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

                case Mnemonic.ocbi: RewriteOcbi(); break;

                case Mnemonic.or: RewriteBinOp(m.Or, u => (byte)u); break;

                case Mnemonic.rotcl: RewriteRotc(IntrinsicProcedure.RolC); break;

                case Mnemonic.rotcr: RewriteRotc(IntrinsicProcedure.RorC); break;

                case Mnemonic.rotl: RewriteRot(IntrinsicProcedure.Rol); break;

                case Mnemonic.rotr: RewriteRot(IntrinsicProcedure.Ror); break;

                case Mnemonic.rts: RewriteRts(); break;

                case Mnemonic.sett: RewriteClrtSet(Registers.T, Constant.True()); break;

                case Mnemonic.shad: RewriteShd(m.Shl, m.Sar); break;

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

                case Mnemonic.shld: RewriteShd(m.Shl, m.Shr); break;

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

                case Mnemonic.shll2: RewriteShift(m.Shl, 2); break;

                case Mnemonic.shll8: RewriteShift(m.Shl, 8); break;

                case Mnemonic.shll16: RewriteShift(m.Shl, 16); break;

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

                case Mnemonic.shlr2: RewriteShift(m.Shr, 2); break;

                case Mnemonic.shlr8: RewriteShift(m.Shr, 8); break;

                case Mnemonic.shlr16: RewriteShift(m.Shr, 16); break;

                case Mnemonic.stc: RewriteMov(); break;

                case Mnemonic.sts: RewriteMov(); break;

                case Mnemonic.sts_l: RewriteMov(); break;

                case Mnemonic.sub: RewriteBinOp(m.ISub, null); break;

                case Mnemonic.subc: RewriteAddcSubc(m.ISub); break;

                case Mnemonic.swap_w: RewriteSwapW(); break;

                case Mnemonic.tst: RewriteTst(); break;

                case Mnemonic.xor: RewriteBinOp(m.Xor, n => (byte)n); break;

                case Mnemonic.xtrct: RewriteXtrct(); break;
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, this.iclass));
            }
        }
Beispiel #18
0
        public HExpr Cast(BaseType type, HExpr a)
        {
            var src = GetExpression(a);

            return(MapToHandle(m.Convert(src, src.DataType, Interop.DataTypes[type])));
        }
Beispiel #19
0
        private void RewriteOp(
            Storage rDst,
            Func <Func <Expression, Expression, Expression>, Expression, Expression, MemoryOperand, Expression> memFn,
            Func <Expression, Expression, Expression> bin,
            Action <Expression> genFlags)
        {
            Expression dst = rDst != null?binder.EnsureIdentifier(rDst) : null;

            Expression tmp;

            switch (instr.Operands[0])
            {
            case RegisterOperand reg:
                tmp = binder.EnsureRegister(reg.Register);
                m.Assign(tmp, bin(dst, tmp));
                break;

            case ImmediateOperand imm:
                m.Assign(dst, bin(dst, imm.Value));
                tmp = dst;
                break;

            case MemoryOperand mem:
                Expression ea;
                Expression idx;
                switch (mem.AccessMode)
                {
                case MemoryOperand.Mode.AccumulatorOffset:
                    ea  = binder.EnsureRegister(mem.Base);
                    idx = binder.EnsureRegister(mem.Index);
                    if (idx.DataType.BitSize < ea.DataType.BitSize)
                    {
                        idx = m.Convert(idx, idx.DataType, PrimitiveType.Int16);
                    }
                    ea  = m.IAdd(ea, idx);
                    tmp = memFn(bin, dst, ea, mem);
                    break;

                case MemoryOperand.Mode.ConstantOffset:
                    if (mem.Base == null)
                    {
                        ea = Address.Ptr16((ushort)mem.Offset);
                    }
                    else if (mem.Base == Registers.PCR)
                    {
                        ea = instr.Address + (instr.Length + mem.Offset);
                    }
                    else
                    {
                        ea = binder.EnsureRegister(mem.Base);
                        ea = m.AddSubSignedInt(ea, mem.Offset);
                    }
                    tmp = memFn(bin, dst, ea, mem);
                    break;

                case MemoryOperand.Mode.Direct:
                    ea  = m.IAdd(binder.EnsureRegister(Registers.DP), Constant.Word16((byte)mem.Offset));
                    tmp = memFn(bin, dst, ea, mem);
                    break;

                case MemoryOperand.Mode.PostInc1:
                    ea  = binder.EnsureRegister(mem.Base);
                    tmp = memFn(bin, dst, ea, mem);
                    m.Assign(ea, m.IAddS(ea, 1));
                    break;

                case MemoryOperand.Mode.PostInc2:
                    ea  = binder.EnsureRegister(mem.Base);
                    tmp = memFn(bin, dst, ea, mem);
                    m.Assign(ea, m.IAddS(ea, 2));
                    break;

                case MemoryOperand.Mode.PreDec1:
                    ea = binder.EnsureRegister(mem.Base);
                    m.Assign(ea, m.ISubS(ea, 1));
                    tmp = memFn(bin, dst, ea, mem);
                    break;

                case MemoryOperand.Mode.PreDec2:
                    ea = binder.EnsureRegister(mem.Base);
                    m.Assign(ea, m.ISubS(ea, 2));
                    tmp = memFn(bin, dst, ea, mem);
                    break;

                default:
                    throw new NotImplementedException($"Unimplemented access mode {mem.AccessMode.ToString()}");
                }
                break;

            default:
                throw new NotImplementedException($"Unimplemented operand type {instr.Operands[0].GetType().Name}");
            }
            genFlags(tmp);
        }
Beispiel #20
0
        }                                                // the data width of the current instruction being rewritten.

        /// <summary>
        /// Rewrite operands being used as sources.
        /// </summary>
        /// <param name="operand"></param>
        /// <param name="addrInstr">Address of the current instruction</param>
        public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false)
        {
            Expression ea;
            Expression r;

            switch (operand)
            {
            case RegisterOperand reg:
                r = binder.EnsureRegister(reg.Register);
                if (DataWidth != null && DataWidth.Size != reg.Width.Size)
                {
                    if (DataWidth.Domain == Domain.Real)
                    {
                        r = m.Convert(r, r.DataType, DataWidth);
                    }
                    else
                    {
                        r = m.Slice(DataWidth, r, 0);
                    }
                }
                return(r);

            case M68kImmediateOperand imm:
                if (imm.Width.IsReal)
                {
                    return(imm.Constant.CloneExpression());
                }
                if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize)
                {
                    return(Constant.Create(DataWidth, imm.Constant.ToInt64()));
                }
                else
                {
                    return(Constant.Create(imm.Width, imm.Constant.ToUInt32()));
                }

            case MemoryOperand mem:
                return(RewriteMemoryAccess(mem, DataWidth, addrInstr));

            case M68kAddressOperand addr:
                if (addressAsAddress)
                {
                    return(addr.Address);
                }
                else
                {
                    return(m.Mem(DataWidth, addr.Address));
                }

            case PredecrementMemoryOperand pre:
                ea = binder.EnsureRegister(pre.Register);
                m.Assign(ea, m.ISubS(ea, DataWidth.Size));
                return(m.Mem(DataWidth, ea));

            case PostIncrementMemoryOperand post:
                r = binder.EnsureRegister(post.Register);
                var tmp = binder.CreateTemporary(DataWidth);
                m.Assign(tmp, m.Mem(DataWidth, r));
                m.Assign(r, m.IAddS(r, DataWidth.Size));
                return(tmp);

            case IndirectIndexedOperand indidx:
                ea = RewriteIndirectBaseRegister(indidx, addrInstr);
                Expression ix = binder.EnsureRegister(indidx.XRegister);
                if (indidx.XWidth.Size != 4)
                {
                    ix = m.Slice(PrimitiveType.Int16, ix, 0);
                    ix = m.Convert(ix, PrimitiveType.Int16, PrimitiveType.Int32);
                }
                if (indidx.Scale > 1)
                {
                    ix = m.IMul(ix, Constant.Int32(indidx.Scale));
                }
                return(m.Mem(DataWidth, m.IAdd(ea, ix)));

            case IndexedOperand indop:
                ea = Combine(indop.BaseDisplacement, indop.Base, addrInstr);
                if (indop.postindex)
                {
                    ea = m.Mem32(ea);
                }
                if (indop.Index != null)
                {
                    var idx = Combine(null, indop.Index, addrInstr);
                    if (indop.index_reg_width !.BitSize != 32)
                    {
                        idx = m.Convert(m.Slice(PrimitiveType.Int16, idx, 0), PrimitiveType.Int16, PrimitiveType.Int32);
                    }
                    if (indop.IndexScale > 1)
                    {
                        idx = m.IMul(idx, indop.IndexScale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.Mem32(ea);
                }
                ea = Combine(ea, indop.OuterDisplacement);
                return(m.Mem(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
Beispiel #21
0
        private void RewriteMovx()
        {
            var src = Operand(1);

            m.Assign(Reg(0), m.Convert(src, src.DataType, PrimitiveType.Word32));
        }