GetRegister() public method

public GetRegister ( int i ) : RegisterStorage
i int
return RegisterStorage
Beispiel #1
0
        private Expression RewriteSrcOp(int iOp, PrimitiveType width)
        {
            var op    = dasm.Current.Operands[iOp];
            var regOp = op as RegisterOperand;

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

                    var regLo = frame.EnsureSequence(regHi1.Storage, reg.Storage, PrimitiveType.Word64);
                    var regHi = frame.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64);
                    return(frame.EnsureSequence(regHi.Storage, regLo.Storage, width));
                }
                else
                {
                    return(emitter.Cast(width, reg));
                }
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(immOp.Value);
            }
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                Expression ea;
                if (memOp.Base != null)
                {
                    var reg = frame.EnsureRegister(memOp.Base);
                    if (memOp.AutoDecrement)
                    {
                        emitter.Assign(reg, emitter.ISub(reg, width.Size));
                    }
                    else if (memOp.AutoIncrement)
                    {
                        var tmp = frame.CreateTemporary(reg.DataType);
                        emitter.Assign(tmp, reg);
                        reg = tmp;
                    }
                    ea = reg;
                    if (memOp.Offset != null)
                    {
                        ea = emitter.IAdd(ea, memOp.Offset);
                    }
                    if (memOp.Index != null)
                    {
                        Expression idx = frame.EnsureRegister(memOp.Index);
                        if (width.Size != 1)
                        {
                            idx = emitter.IMul(idx, Constant.Int32(width.Size));
                        }
                        ea = emitter.IAdd(ea, idx);
                    }
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = emitter.Load(width, emitter.LoadDw(ea));
                    }
                    else
                    {
                        load = emitter.Load(width, ea);
                    }
                    if (memOp.AutoIncrement)
                    {
                        if (memOp.AutoIncrement)
                        {
                            reg = frame.EnsureRegister(memOp.Base);
                            int inc = (memOp.Deferred) ? 4 : width.Size;
                            emitter.Assign(reg, emitter.IAdd(reg, inc));
                        }
                    }
                    return(load);
                }
                else
                {
                }
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Beispiel #2
0
        private bool TryDecodeOperand(PrimitiveType width, int maxReg, out MachineOperand op)
        {
            op = null;
            if (!rdr.TryReadByte(out byte bSpecifier))
            {
                return(false);
            }
            var reg = arch.GetRegister(bSpecifier & 0xF);

            switch (bSpecifier >> 4)
            {
            case 0: // Literal mode
            case 1:
            case 2:
            case 3:
                op = LiteralOperand(width, bSpecifier);
                break;

            case 4: // Index mode
                op = IndexOperand(width, reg);
                if (op == null)
                {
                    return(false);
                }
                break;

            case 5: // Register mode
                if (reg.Number > maxReg)
                {
                    return(false);
                }
                op = new RegisterOperand(reg);
                break;

            case 6: // Register deferred
                op = new MemoryOperand(width)
                {
                    Base = reg
                };
                break;

            case 7: // Autodecrement mode
                op = new MemoryOperand(width)
                {
                    Base          = reg,
                    AutoDecrement = true,
                };
                break;

            case 8: // Autoincrement mode
                if (reg.Number == 0x0F)
                {
                    op = ImmediateOperand(width);
                }
                else
                {
                    op = new MemoryOperand(width)
                    {
                        Base          = reg,
                        AutoIncrement = true,
                    };
                }
                break;

            case 9: // Deferred Autoincrement mode
                op = new MemoryOperand(width)
                {
                    Base          = reg,
                    AutoIncrement = true,
                    Deferred      = true,
                };
                break;

            case 0xA: // Displacement mode
            case 0xB:
                if (!rdr.TryReadByte(out byte b))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.SByte((sbyte)b), bSpecifier);
                break;

            case 0xC:
            case 0xD:
                if (!rdr.TryReadUInt16(out ushort w))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.Int16((short)w), bSpecifier);
                break;

            case 0xE:
            case 0xF:
                if (!rdr.TryReadUInt32(out uint dw))
                {
                    return(false);
                }
                op = DisplacementOperand(width, reg, Constant.Word32(dw), bSpecifier);
                break;

            default:
                throw new InvalidCastException("Impossiburu!");
            }
            return(true);
        }
Beispiel #3
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);
        }
Beispiel #4
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(regHi.Storage, reg.Storage, width));
                }
                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(regHi1.Storage, reg.Storage, PrimitiveType.Word64);
                    var regHi = binder.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64);
                    return(binder.EnsureSequence(regHi.Storage, regLo.Storage, width));
                }
                else
                {
                    return(m.Cast(width, reg));
                }

            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)
                    {
                        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)
                    {
                        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
                {
                }
                break;

            case AddressOperand addrOp:
                return(addrOp.Address);
            }
            throw new NotImplementedException(op.GetType().Name);
        }