Example #1
0
        private Expression RewriteMemoryOperand(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Index != null)
                {
                    Expression index = binder.EnsureRegister(mem.Index);
                    if (mem.Shift > 0)
                    {
                        index = m.IMul(index, 1 << mem.Shift);
                    }
                    ea = m.IAdd(ea, index);
                }
                if (mem.Offset != 0)
                {
                    ea = m.AddSubSignedInt(ea, mem.Offset);
                }
            }
            else
            {
                ea = Address.Ptr32((uint)mem.Offset);
                if (mem.Index != null)
                {
                    var idx = binder.EnsureRegister(mem.Index);
                    ea = m.IAdd(ea, idx);
                }
            }
            return(m.Mem(mem.Width, ea));
        }
Example #2
0
        /// <summary>
        /// Rewrites the effective address of a memory load.
        /// </summary>
        /// <param name="mem"></param>
        /// <returns></returns>
        private Expression RewriteSrcEa(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Increment < 0)
                {
                    m.Assign(ea, m.AddSubSignedInt(ea, mem.Increment));
                }
                if (mem.Offset != null)
                {
                    ea = m.IAdd(ea, mem.Offset);
                }
                if (mem.Increment > 0)
                {
                    var tmp = binder.CreateTemporary(ea.DataType);
                    m.Assign(tmp, ea);
                    m.Assign(ea, m.AddSubSignedInt(ea, mem.Increment));
                    ea = tmp;
                }
            }
            else
            {
                ea = arch.MakeAddressFromConstant(mem.Offset !, false);
            }
            return(ea);
        }
Example #3
0
        private Expression Rewrite(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case AddressOperand addr:
                return(addr.Address);

            case IndirectOperand mem:
                Expression ea;
                if (mem.Base == arch.pc)
                {
                    ea = dasm.Current.Address + mem.Offset;
                }
                else
                {
                    ea = binder.EnsureRegister(mem.Base);
                    ea = m.AddSubSignedInt(ea, mem.Offset);
                }
                return(m.Mem(op.Width, ea));
            }
            throw new NotImplementedException($"Mips16e operand {op.GetType()} not implemented yet.");
        }
Example #4
0
        private Expression EffectiveAddress(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Index != null)
                {
                    throw new NotImplementedException();
                }
                if (mem.Offset != 0)
                {
                    ea = m.AddSubSignedInt(ea, mem.Offset);
                }
                if (mem.PostDecrement || mem.PostIncrement)
                {
                    var tmp = binder.CreateTemporary(ea.DataType);
                    m.Assign(tmp, ea);
                    var size = mem.Width.Size;
                    m.Assign(ea, m.AddSubSignedInt(ea, mem.PostIncrement
                        ? size
                        : -size));
                    ea = tmp;
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return(ea);
        }
Example #5
0
        private void RewriteLoadOffset(PrimitiveType dt)
        {
            var dst     = Reg(0);
            var baseReg = Reg0(1);
            var offset  = Imm(2);

            if (baseReg.IsZero)
            {
                EmitLoad(dst, m.Mem(dt, Address.Ptr32(offset.ToUInt32())));
            }
            else
            {
                EmitLoad(dst, m.Mem(dt, m.AddSubSignedInt(baseReg, offset.ToInt32())));
            }
        }
Example #6
0
        private void RewriteStm()
        {
            var regs = instr.Operands
                       .Skip(1)
                       .Cast <RegisterRange>()
                       .SelectMany(rr => rr.Enumerate());
            Identifier sp;
            bool       preDec = false;

            if (instr.Operands[0] is MemoryOperand pre)
            {
                Debug.Assert(pre.PreDecrement);
                sp     = binder.EnsureRegister(pre.Base);
                preDec = true;
            }
            else
            {
                sp = binder.EnsureRegister(((RegisterOperand)instr.Operands[0]).Register);
            }
            int offset = 0;

            foreach (var reg in regs)
            {
                offset -= reg.DataType.Size;
                m.Assign(m.Mem(reg.DataType, m.IAddS(sp, offset)), binder.EnsureRegister(reg));
            }
            if (preDec)
            {
                m.Assign(sp, m.AddSubSignedInt(sp, offset));
            }
        }
Example #7
0
        private Expression Rewrite(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                if (rop.Register.Number == 0)
                {
                    return(Constant.Create(rop.Register.DataType, 0));
                }
                else
                {
                    return(binder.EnsureRegister(rop.Register));
                }

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base.Number == 0)
                {
                    ea = Address.Ptr32((uint)mem.Offset);
                }
                else
                {
                    ea = binder.EnsureRegister(mem.Base);
                    ea = m.AddSubSignedInt(ea, mem.Offset);
                }
                return(m.Mem(mem.Width, ea));

            case AddressOperand aop:
                return(aop.Address);
            }
            throw new NotImplementedException($"{op.GetType().Name} not implemented.");
        }
Example #8
0
        private MemoryAccess Mem(MachineOperand op)
        {
            var        mop = (MemoryOperand)op;
            Expression ea  = binder.EnsureRegister(mop.Base);

            ea = m.AddSubSignedInt(ea, mop.Offset);
            return(m.Mem(op.Width, ea));
        }
Example #9
0
        private void RewriteCmpIncDec(int increment)
        {
            var left  = Src(0);
            var right = Src(1);

            EmitCond(EZVCN, m.ISub(left, right));
            m.Assign(left, m.AddSubSignedInt(left, increment));
        }
Example #10
0
        private Expression OpSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand reg:
                return(binder.EnsureRegister(reg.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    var regBase = binder.EnsureRegister(mem.Base);
                    if (mem.PostIncrement)
                    {
                        ea = binder.CreateTemporary(regBase.DataType);
                        m.Assign(ea, regBase);
                    }
                    else if (mem.PreDecrement)
                    {
                        m.Assign(regBase, m.ISubS(regBase, mem.Width.Size));
                        ea = regBase;
                    }
                    else
                    {
                        ea = m.AddSubSignedInt(regBase, mem.Offset);
                    }
                }
                else
                {
                    ea = Address.Ptr16((ushort)mem.Offset);
                }
                return(m.Mem(mem.Width ?? (DataType)VoidType.Instance, ea));
            }
            throw new NotImplementedException();
        }
Example #11
0
        private Expression EffectiveAddress(MemoryOperand mem)
        {
            Expression ea;

            if (mem.Base != null)
            {
                ea = binder.EnsureRegister(mem.Base);
                if (mem.Offset != 0)
                {
                    ea = m.AddSubSignedInt(ea, mem.Offset);
                }
            }
            else
            {
                ea = Address.Ptr32((uint)mem.Offset);
            }
            return(ea);
        }
Example #12
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);
        }
Example #13
0
        private void PreDec(int iOp)
        {
            var reg = RewriteOp(instr.Operands[iOp]);

            m.Assign(reg, m.AddSubSignedInt(reg, -4));
        }