Ejemplo n.º 1
0
        private Expression Mem(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                var baseReg = binder.EnsureRegister(mem.Base);
                ea = baseReg;
                if (mem.Predecrement)
                {
                    m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size));
                }
                if (mem.Offset != 0)
                {
                    ea = m.IAdd(ea, mem.Offset);
                }
                if (mem.Postincrement)
                {
                    m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size));
                }
            }
            else
            {
                ea = Address.Ptr16((ushort)mem.Offset);
            }
            return(m.Mem(mem.Width, ea));
        }
Ejemplo n.º 2
0
        private void RewriteMem(int iOp, Expression src, Action <Expression, Expression> write, Expression seg)
        {
            var        op      = instr.operands[iOp];
            var        mop     = (MemoryOperand)op;
            var        baseReg = binder.EnsureRegister(mop.Base);
            Expression ea      = baseReg;

            if (mop.PreDecrement)
            {
                m.Assign(baseReg, m.ISubS(baseReg, 1));
            }
            else if (mop.Displacement != 0)
            {
                ea = m.IAddS(ea, mop.Displacement);
            }
            Expression val;

            if (seg != null)
            {
                val = m.SegMem(mop.Width, seg, ea);
            }
            else
            {
                val = m.Mem(mop.Width, ea);
            }
            write(val, src);
            if (mop.PostIncrement)
            {
                m.Assign(baseReg, m.IAddS(baseReg, 1));
            }
        }
Ejemplo n.º 3
0
        private Expression SrcOp(MachineOperand op, Func <int, int>?immediateFn = null)
        {
            switch (op)
            {
            case RegisterOperand regOp:
                var id = binder.EnsureRegister(regOp.Register);
                return(id);

            case ImmediateOperand immOp:
                return(Constant.Word32(immediateFn !(immOp.Value.ToInt32())));

            case AddressOperand addrOp:
                return(addrOp.Address);

            case MemoryOperand mem:
                Identifier reg;
                switch (mem.mode)
                {
                default:
                    throw new NotImplementedException(mem.mode.ToString());

                case AddressingMode.Indirect:
                    return(m.Mem(mem.Width, binder.EnsureRegister(mem.reg)));

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.ISubS(reg, mem.Width.Size));
                    return(m.Mem(mem.Width, reg));

                case AddressingMode.IndirectPostIncr:
                    var t = binder.CreateTemporary(mem.Width);
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(t, m.Mem(mem.Width, reg));
                    m.Assign(reg, m.IAddS(reg, t.DataType.Size));
                    return(t);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    return(m.Mem(
                               mem.Width,
                               m.IAddS(reg, mem.disp)));

                case AddressingMode.IndexedIndirect:
                    return(m.Mem(mem.Width, m.IAdd(
                                     binder.EnsureRegister(Registers.r0),
                                     binder.EnsureRegister(mem.reg))));

                case AddressingMode.PcRelativeDisplacement:
                    var addr = instr.Address.ToUInt32();
                    if (mem.Width.Size == 4)
                    {
                        addr &= ~3u;
                    }
                    addr += (uint)(mem.disp + 4);
                    return(m.Mem(mem.Width, Address.Ptr32(addr)));
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Ejemplo n.º 4
0
        private void RewriteAllocFrame(MachineOperand opImm)
        {
            var ea = binder.CreateTemporary(PrimitiveType.Ptr32);

            m.Assign(ea, m.ISubS(binder.EnsureRegister(Registers.sp), 8));
            m.Assign(m.Mem32(ea), binder.EnsureRegister(Registers.fp));
            m.Assign(m.Mem32(m.IAddS(ea, 4)), binder.EnsureRegister(Registers.lr));
            m.Assign(binder.EnsureRegister(Registers.fp), ea);
            m.Assign(binder.EnsureRegister(Registers.sp), m.ISubS(ea, ((ImmediateOperand)opImm).Value.ToInt32()));
        }
Ejemplo n.º 5
0
        private void Pull(RegisterStorage reg)
        {
            var id = binder.EnsureRegister(reg);
            var s  = binder.EnsureRegister(arch.StackRegister);
            var c  = FlagGroupStorage(FlagM.NF | FlagM.ZF);

            m.Assign(id, m.Mem8(s));
            m.Assign(s, m.IAddS(s, 1));
            m.Assign(c, m.Cond(id));
        }
Ejemplo n.º 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.Cast(PrimitiveType.UInt16, idx);
             }
             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)));
     }
 }
Ejemplo n.º 7
0
        private Expression RewriteMemoryOperand(MemoryOperand mem)
        {
            var baseReg = binder.EnsureRegister(mem.Base);

            if (mem.PostIncrement)
            {
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, baseReg));
                m.Assign(baseReg, m.IAddS(baseReg, mem.Width.Size));
                return(tmp);
            }
            if (mem.PreDecrement)
            {
                m.Assign(baseReg, m.ISubS(baseReg, mem.Width.Size));
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, baseReg));
                return(tmp);
            }
            Expression ea = baseReg;

            if (mem.Index != null)
            {
                Expression idx = binder.EnsureRegister(mem.Index);
                if (mem.Shift > 0)
                {
                    idx = m.IMul(idx, m.Word32(1 << mem.Shift));
                }
                ea = m.IAdd(ea, idx);
            }
            if (mem.Offset != 0)
            {
                ea = m.IAddS(ea, mem.Offset);
            }
            return(m.Mem(mem.Width, ea));
        }
Ejemplo n.º 8
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand iop:
                return(iop.Value);

            case AddressOperand aop:
                return(aop.Address);

            case MemoryOperand mop:
                Expression ea;
                if (mop.Base != null)
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (mop.Offset != 0)
                    {
                        ea = m.IAddS(ea, mop.Offset);
                    }
                }
                else
                {
                    ea = m.Ptr32((uint)mop.Offset);
                }
                if (mop.Index != null)
                {
                    var idx = binder.EnsureRegister(mop.Index);
                    ea = m.IAdd(ea, idx);
                }
                return(m.Mem(op.Width, ea));

            case BitOperand bit:
                var bitSrc = RewriteSrc(bit.Operand);
                return(host.Intrinsic(
                           "__bit",
                           false,
                           PrimitiveType.Bool,
                           bitSrc,
                           Constant.Byte((byte)bit.BitPosition)));

            case FlagGroupOperand fop:
                return(binder.EnsureFlagGroup(fop.FlagGroup));

            default:
                throw new NotImplementedException($"Rl87Rewriter: operand type {op.GetType().Name} not implemented yet.");
            }
        }
Ejemplo n.º 9
0
        private void Pull(RegisterStorage stackptr, RegisterStorage reg)
        {
            var sp = binder.EnsureRegister(stackptr);
            var r  = binder.EnsureRegister(reg);

            if (reg == Registers.PCR)
            {
                m.Return(2, 0);
            }
            else
            {
                m.Assign(r, m.Mem(r.DataType, sp));
                m.Assign(sp, m.IAddS(sp, r.DataType.Size));
            }
        }
Ejemplo n.º 10
0
        private Expression EffectiveAddress(MachineOperand operand, RtlEmitter emitter)
        {
            var mop    = (MemoryOperand)operand;
            var reg    = binder.EnsureRegister(mop.BaseRegister);
            var offset = mop.Offset;

            return(emitter.IAddS(reg, offset));
        }
Ejemplo n.º 11
0
        private Expression RewriteOp(int iOp)
        {
            switch (instr.Operands[iOp])
            {
            case RegisterOperand r:
                if (r.Register == arch.Registers.GpRegs[0])
                {
                    return(Constant.Zero(r.Register.DataType));
                }
                else
                {
                    return(binder.EnsureRegister(r.Register));
                }

            case ImmediateOperand i:
                return(i.Value);

            case LeftImmediateOperand l:
                return(l.Value);

            case AddressOperand a:
                return(a.Address);

            case MemoryOperand mem:
                Identifier rb = binder.EnsureRegister(mem.Base);
                Expression ea = rb;
                if (mem.Index != null)
                {
                    if (mem.Index != arch.Registers.GpRegs[0])
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(ea, idx);
                    }
                }
                else if (mem.Offset != 0)
                {
                    ea = m.IAddS(ea, mem.Offset);
                }
                if (instr.BaseReg == AddrRegMod.mb)
                {
                    m.Assign(rb, ea);
                    ea = rb;
                }
                else if (instr.BaseReg == AddrRegMod.ma)
                {
                    var tmp = binder.CreateTemporary(rb.DataType);
                    m.Assign(tmp, ea);
                    m.Assign(rb, tmp);
                    ea = tmp;
                }
                return(m.Mem(mem.Width, ea));
            }
            throw new NotImplementedException($"Unimplemented PA-RISC operand type {instr.Operands[iOp].GetType()}.");
        }
Ejemplo n.º 12
0
        private Expression OpDst(MachineOperand op, Expression src, Func <Expression, Expression, Expression> fn)
        {
            Expression dst;

            switch (op)
            {
            case RegisterOperand reg:
                dst = binder.EnsureRegister(reg.Register);
                m.Assign(dst, fn(dst, src));
                return(dst);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    var regBase = binder.EnsureRegister(mem.Base);
                    if (mem.PreDecrement)
                    {
                        ea = binder.EnsureRegister(mem.Base !);
                        m.Assign(ea, m.ISubS(ea, mem.Width.Size));
                    }
                    else if (mem.PostIncrement)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        ea = m.AddSubSignedInt(regBase, mem.Offset);
                    }
                }
                else
                {
                    ea = Address.Ptr16((ushort)mem.Offset);
                }
                dst = fn(m.Mem(mem.Width, ea), src);
                if (dst is Identifier || dst is Constant)
                {
                    m.Assign(m.Mem(mem.Width, ea), dst);
                }
                else
                {
                    var tmp = binder.CreateTemporary(mem.Width);
                    m.Assign(tmp, dst);
                    dst = tmp;
                }
                if (mem.PostIncrement)
                {
                    m.Assign(ea, m.IAddS(ea, mem.Width.Size));
                }
                return(dst);
            }
            throw new NotImplementedException();
        }
Ejemplo n.º 13
0
        private Expression EffectiveAddress_r0(MachineOperand operand, RtlEmitter emitter)
        {
            var mop = (MemoryOperand)operand;

            if (mop.BaseRegister.Number == 0)
            {
                return(Constant.Word32(mop.Offset));
            }
            else
            {
                var reg    = binder.EnsureRegister(mop.BaseRegister);
                var offset = mop.Offset;
                if (offset != 0)
                {
                    return(emitter.IAddS(reg, offset));
                }
                else
                {
                    return(reg);
                }
            }
        }
Ejemplo n.º 14
0
 private Expression Inc(Expression e)
 {
     return(m.IAddS(e, 1));
 }
Ejemplo n.º 15
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>
        /// <returns></returns>
        public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false)
        {
            var reg = operand as RegisterOperand;

            if (reg != null)
            {
                Expression r = binder.EnsureRegister(reg.Register);
                if (DataWidth != null && DataWidth.Size != reg.Width.Size)
                {
                    r = m.Cast(DataWidth, r);
                }
                return(r);
            }
            var imm = operand as M68kImmediateOperand;

            if (imm != null)
            {
                if (imm.Width.Domain == Domain.Real)
                {
                    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()));
                }
            }
            var mem = operand as MemoryOperand;

            if (mem != null)
            {
                return(RewriteMemoryAccess(mem, DataWidth, addrInstr));
            }
            var addr = operand as M68kAddressOperand;

            if (addr != null)
            {
                if (addressAsAddress)
                {
                    return(addr.Address);
                }
                else
                {
                    return(m.Mem(DataWidth, addr.Address));
                }
            }
            var pre = operand as PredecrementMemoryOperand;

            if (pre != null)
            {
                var ea = binder.EnsureRegister(pre.Register);
                m.Assign(ea, m.ISubS(ea, DataWidth.Size));
                return(m.Mem(DataWidth, ea));
            }
            var post = operand as PostIncrementMemoryOperand;

            if (post != null)
            {
                var 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);
            }
            var indidx = operand as IndirectIndexedOperand;

            if (indidx != null)
            {
                Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr);
                Expression ix = binder.EnsureRegister(indidx.XRegister);
                if (indidx.XWidth.Size != 4)
                {
                    ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix));
                }
                if (indidx.Scale > 1)
                {
                    ix = m.IMul(ix, Constant.Int32(indidx.Scale));
                }
                return(m.Mem(DataWidth, m.IAdd(ea, ix)));
            }
            var indop = operand as IndexedOperand;

            if (indop != null)
            {
                Expression ea = Combine(indop.Base, indop.base_reg);
                if (indop.postindex)
                {
                    ea = m.Mem32(ea);
                }
                if (indop.index_reg != null)
                {
                    var idx = Combine(null, indop.index_reg);
                    if (indop.index_reg_width.BitSize != 32)
                    {
                        idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx));
                    }
                    if (indop.index_scale > 1)
                    {
                        idx = m.IMul(idx, indop.index_scale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.Mem32(ea);
                }
                ea = Combine(ea, indop.outer);
                return(m.Mem(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr = dasm.Current;
                var instrs = new List <RtlInstruction>();
                this.m      = new RtlEmitter(instrs);
                this.iclass = dasm.Current.InstructionClass;
                switch (instr.Mnemonic)
                {
                case Mnemonic.invalid:
                    m.Invalid(); break;

                case Mnemonic.brk:
                case Mnemonic.cmps:
                case Mnemonic.movs:
                case Mnemonic.retb:
                case Mnemonic.stop:
                default:
                    EmitUnitTest();
                    this.iclass = InstrClass.Invalid;
                    m.Invalid();
                    break;

                case Mnemonic.add: RewriteAdd(); break;

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

                case Mnemonic.addw: RewriteAddw(); break;

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

                case Mnemonic.and1: RewriteLogical1(m.And); break;

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

                case Mnemonic.bf: RewriteBf(); break;

                case Mnemonic.bh: RewriteBranch(ConditionCode.UGT, CZ()); break;

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

                case Mnemonic.bnh: RewriteBranch(ConditionCode.ULE, CZ()); break;

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

                case Mnemonic.br: RewriteBr(); break;

                case Mnemonic.bt: RewriteBt(); break;

                case Mnemonic.btclr: RewriteBtclr(); break;

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

                case Mnemonic.call: RewriteCall(); break;

                case Mnemonic.callt: RewriteCall(); break;

                case Mnemonic.clr1: RewriteClr1(); break;

                case Mnemonic.clrb: RewriteClr(PrimitiveType.Byte); break;

                case Mnemonic.clrw: RewriteClr(PrimitiveType.Word16); break;

                case Mnemonic.cmp: RewriteCmp(); break;

                case Mnemonic.cmp0: RewriteCmp0(); break;

                case Mnemonic.cmpw: RewriteCmp(); break;

                case Mnemonic.dec: RewriteIncDec((a, b) => m.ISubS(a, 1)); break;

                case Mnemonic.decw: RewriteIncwDecw((a, b) => m.ISubS(a, 1)); break;

                case Mnemonic.halt: RewriteHalt(); break;

                case Mnemonic.inc: RewriteIncDec((a, b) => m.IAddS(a, 1)); break;

                case Mnemonic.incw: RewriteIncwDecw((a, b) => m.IAddS(a, 1)); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.mov1: RewriteMov1(); break;

                case Mnemonic.movw: RewriteMov(); break;

                case Mnemonic.mulu: RewriteMulu(); break;

                case Mnemonic.oneb: RewriteOne(PrimitiveType.Byte); break;

                case Mnemonic.onew: RewriteOne(PrimitiveType.Word16); break;

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

                case Mnemonic.or1: RewriteLogical1(m.Or); break;

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

                case Mnemonic.not1: RewriteNot1(); break;

                case Mnemonic.pop: RewritePop(); break;

                case Mnemonic.push: RewritePush(); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.reti: RewriteRet(); break;

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

                case Mnemonic.rolc: RewriteRotateC(PseudoProcedure.RolC); break;

                case Mnemonic.rolwc: RewriteRotateC(PseudoProcedure.RolC); break;

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

                case Mnemonic.rorc: RewriteRotate(PseudoProcedure.RorC); break;

                case Mnemonic.sar: RewriteShift(m.Sar); break;

                case Mnemonic.sarw: RewriteShiftw(m.Sar); break;

                case Mnemonic.sel: RewriteSel(); break;

                case Mnemonic.set1: RewriteSet1(); break;

                case Mnemonic.shl: RewriteShift(m.Shl); break;

                case Mnemonic.shlw: RewriteShiftw(m.Shl); break;

                case Mnemonic.shr: RewriteShift(m.Shr); break;

                case Mnemonic.shrw: RewriteShiftw(m.Shr); break;

                case Mnemonic.skc: RewriteSkip(ConditionCode.ULT, C()); break;

                case Mnemonic.skh: RewriteSkip(ConditionCode.UGT, CZ()); break;

                case Mnemonic.sknc: RewriteSkip(ConditionCode.UGE, C()); break;

                case Mnemonic.sknh: RewriteSkip(ConditionCode.ULE, CZ()); break;

                case Mnemonic.sknz: RewriteSkip(ConditionCode.NE, Z()); break;

                case Mnemonic.skz: RewriteSkip(ConditionCode.EQ, Z()); break;

                case Mnemonic.sub: RewriteSub(); break;

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

                case Mnemonic.subw: RewriteSubw(); break;

                case Mnemonic.xch: RewriteXch(); break;

                case Mnemonic.xchw: RewriteXch(); break;

                case Mnemonic.xor: RewriteLogical(m.Xor); break;

                case Mnemonic.xor1: RewriteLogical1(m.Xor); break;
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, iclass));
            }
        }
Ejemplo n.º 18
0
        private Expression RewriteSrcOp(int iOp, PrimitiveType width)
        {
            var op = this.instr.Operands[iOp];

            switch (op)
            {
            case RegisterOperand regOp:
                var reg = binder.EnsureRegister(regOp.Register);
                if (reg == null)
                {
                    return(null);
                }
                if (width.Size == 4)
                {
                    return(reg);
                }
                else if (width.Size == 8)
                {
                    var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain);
                    if (rHi == null)
                    {
                        return(null);
                    }
                    var regHi = binder.EnsureRegister(rHi);
                    return(binder.EnsureSequence(width, regHi.Storage, reg.Storage));
                }
                else if (width.Size == 16)
                {
                    var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain));
                    var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain));
                    var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain));

                    var regLo = binder.EnsureSequence(PrimitiveType.Word64, regHi1.Storage, reg.Storage);
                    var regHi = binder.EnsureSequence(PrimitiveType.Word64, regHi3.Storage, regHi2.Storage);
                    return(binder.EnsureSequence(width, regHi.Storage, regLo.Storage));
                }
                else
                {
                    return(m.Slice(width, reg, 0));
                }

            case ImmediateOperand immOp:
                return(immOp.Value);

            case MemoryOperand memOp:
                Expression ea;
                if (memOp.Base != null)
                {
                    reg = binder.EnsureRegister(memOp.Base);
                    if (memOp.AutoDecrement)
                    {
                        m.Assign(reg, m.ISub(reg, width.Size));
                    }
                    else if (memOp.AutoIncrement)
                    {
                        var tmp = binder.CreateTemporary(reg.DataType);
                        m.Assign(tmp, reg);
                        reg = tmp;
                    }
                    ea = reg;
                    if (memOp.Offset != null)
                    {
                        if (memOp.Offset.DataType.BitSize < ea.DataType.BitSize)
                        {
                            ea = m.IAddS(ea, memOp.Offset.ToInt32());
                        }
                        else
                        {
                            ea = m.IAdd(ea, memOp.Offset);
                        }
                    }
                    if (memOp.Index != null)
                    {
                        Expression idx = binder.EnsureRegister(memOp.Index);
                        if (width.Size != 1)
                        {
                            idx = m.IMul(idx, Constant.Int32(width.Size));
                        }
                        ea = m.IAdd(ea, idx);
                    }
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = m.Mem(width, m.Mem32(ea));
                    }
                    else
                    {
                        load = m.Mem(width, ea);
                    }
                    if (memOp.AutoIncrement)
                    {
                        reg = binder.EnsureRegister(memOp.Base);
                        int inc = (memOp.Deferred) ? 4 : width.Size;
                        m.Assign(reg, m.IAdd(reg, inc));
                    }
                    return(load);
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(memOp.Offset, false);
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = m.Mem(width, m.Mem32(ea));
                    }
                    else
                    {
                        load = m.Mem(width, ea);
                    }
                    return(load);
                }

            case AddressOperand addrOp:
                //$BUG: enabling the commented code causes huge regressions in the
                // unzip subject.

                /*if (addrOp.Width.BitSize > width.BitSize)
                 * {
                 *  var c = addrOp.Address.ToUInt32();
                 *  return Constant.Create(width, c);
                 * }
                 * else*/
            {
                return(addrOp.Address);
            }
            }
            throw new NotImplementedException(op.GetType().Name);
        }