Exemplo n.º 1
0
        public int        ElementCount => elementSize == size ? 1 : size / elementSize; // ElementSize can be 0 so we don't divide by it if es == s

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="memorySize">Memory size value</param>
        /// <param name="size">Size of location</param>
        /// <param name="elementSize">Size of the packed element, or <paramref name="size"/> if it's not packed data</param>
        /// <param name="elementType">Element type if it's packed data or <paramref name="memorySize"/> if it's not packed data</param>
        /// <param name="isSigned"><see langword="true"/> if signed data</param>
        /// <param name="isBroadcast"><see langword="true"/> if broadcast</param>
        public MemorySizeInfo(MemorySize memorySize, int size, int elementSize, MemorySize elementType, bool isSigned, bool isBroadcast)
        {
            if (size < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException_size();
            }
            if (elementSize < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException_elementSize();
            }
            if (elementSize > size)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException_elementSize();
            }
            Static.Assert(IcedConstants.NumberOfMemorySizes <= byte.MaxValue + 1 ? 0 : -1);
            this.memorySize = (byte)memorySize;
            Debug.Assert(size <= ushort.MaxValue);
            this.size = (ushort)size;
            Debug.Assert(elementSize <= ushort.MaxValue);
            this.elementSize = (ushort)elementSize;
            Static.Assert(IcedConstants.NumberOfMemorySizes <= byte.MaxValue + 1 ? 0 : -1);
            this.elementType = (byte)elementType;
            this.isSigned    = isSigned;
            this.isBroadcast = isBroadcast;
        }
Exemplo n.º 2
0
 internal InstructionInfo(bool dummy)
 {
     usedRegisters       = new SimpleList <UsedRegister>(new UsedRegister[InstrInfoConstants.DefaultUsedRegisterCollCapacity]);
     usedMemoryLocations = new SimpleList <UsedMemory>(new UsedMemory[InstrInfoConstants.DefaultUsedMemoryCollCapacity]);
     unsafe {
         opAccesses[0] = 0;
         opAccesses[1] = 0;
         opAccesses[2] = 0;
         opAccesses[3] = 0;
         opAccesses[4] = 0;
         Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1);
     }
 }
Exemplo n.º 3
0
 internal InstructionInfo(bool dummy)
 {
     usedRegisters       = new SimpleList <UsedRegister>(new UsedRegister[InstrInfoConstants.DefaultUsedRegisterCollCapacity]);
     usedMemoryLocations = new SimpleList <UsedMemory>(new UsedMemory[InstrInfoConstants.DefaultUsedMemoryCollCapacity]);
     unsafe {
         opAccesses[0] = 0;
         opAccesses[1] = 0;
         opAccesses[2] = 0;
         opAccesses[3] = 0;
         opAccesses[4] = 0;
         Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1);
     }
     cpuidFeatureInternal = 0;
     flowControl          = 0;
     encoding             = 0;
     rflagsInfo           = 0;
     flags = 0;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the virtual address of a memory operand
        /// </summary>
        /// <param name="operand">Operand number, must be a memory operand</param>
        /// <param name="elementIndex">Only used if it's a vsib memory operand. This is the element index of the vector index register.</param>
        /// <param name="registerValueProvider">Returns values of registers and segment base addresses</param>
        /// <param name="result">Result if this method returns <see langword="true"/></param>
        /// <returns></returns>
        public readonly bool TryGetVirtualAddress(int operand, int elementIndex, IVATryGetRegisterValueProvider registerValueProvider, out ulong result)
        {
            if (registerValueProvider is null)
            {
                throw new ArgumentNullException(nameof(registerValueProvider));
            }
            ulong seg, @base;

            switch (GetOpKind(operand))
            {
            case OpKind.Register:
            case OpKind.NearBranch16:
            case OpKind.NearBranch32:
            case OpKind.NearBranch64:
            case OpKind.FarBranch16:
            case OpKind.FarBranch32:
            case OpKind.Immediate8:
            case OpKind.Immediate8_2nd:
            case OpKind.Immediate16:
            case OpKind.Immediate32:
            case OpKind.Immediate64:
            case OpKind.Immediate8to16:
            case OpKind.Immediate8to32:
            case OpKind.Immediate8to64:
            case OpKind.Immediate32to64:
                result = 0;
                return(true);

            case OpKind.MemorySegSI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.SI, 0, 0, out @base))
                {
                    result = seg + (ushort)@base;
                    return(true);
                }
                break;

            case OpKind.MemorySegESI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.ESI, 0, 0, out @base))
                {
                    result = seg + (uint)@base;
                    return(true);
                }
                break;

            case OpKind.MemorySegRSI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.RSI, 0, 0, out @base))
                {
                    result = seg + @base;
                    return(true);
                }
                break;

            case OpKind.MemorySegDI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.DI, 0, 0, out @base))
                {
                    result = seg + (ushort)@base;
                    return(true);
                }
                break;

            case OpKind.MemorySegEDI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.EDI, 0, 0, out @base))
                {
                    result = seg + (uint)@base;
                    return(true);
                }
                break;

            case OpKind.MemorySegRDI:
                if (registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.RDI, 0, 0, out @base))
                {
                    result = seg + @base;
                    return(true);
                }
                break;

            case OpKind.MemoryESDI:
                if (registerValueProvider.TryGetRegisterValue(Register.ES, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.DI, 0, 0, out @base))
                {
                    result = seg + (ushort)@base;
                    return(true);
                }
                break;

            case OpKind.MemoryESEDI:
                if (registerValueProvider.TryGetRegisterValue(Register.ES, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.EDI, 0, 0, out @base))
                {
                    result = seg + (uint)@base;
                    return(true);
                }
                break;

            case OpKind.MemoryESRDI:
                if (registerValueProvider.TryGetRegisterValue(Register.ES, 0, 0, out seg) &&
                    registerValueProvider.TryGetRegisterValue(Register.RDI, 0, 0, out @base))
                {
                    result = seg + @base;
                    return(true);
                }
                break;

            case OpKind.Memory:
                var   baseReg  = MemoryBase;
                var   indexReg = MemoryIndex;
                int   addrSize = InstructionUtils.GetAddressSizeInBytes(baseReg, indexReg, MemoryDisplSize, CodeSize);
                ulong offset   = MemoryDisplacement64;
                ulong offsetMask;
                if (addrSize == 8)
                {
                    offsetMask = ulong.MaxValue;
                }
                else if (addrSize == 4)
                {
                    offsetMask = uint.MaxValue;
                }
                else
                {
                    Debug.Assert(addrSize == 2);
                    offsetMask = ushort.MaxValue;
                }
                if (baseReg != Register.None && baseReg != Register.RIP && baseReg != Register.EIP)
                {
                    if (!registerValueProvider.TryGetRegisterValue(baseReg, 0, 0, out @base))
                    {
                        break;
                    }
                    offset += @base;
                }
                var code = Code;
                if (indexReg != Register.None && !code.IgnoresIndex() && !code.IsTileStrideIndex())
                {
                    if (TryGetVsib64(out bool vsib64))
                    {
                        bool b;
                        if (vsib64)
                        {
                            b = registerValueProvider.TryGetRegisterValue(indexReg, elementIndex, 8, out @base);
                        }
                        else
                        {
                            b     = registerValueProvider.TryGetRegisterValue(indexReg, elementIndex, 4, out @base);
                            @base = (ulong)(int)@base;
                        }
                        if (!b)
                        {
                            break;
                        }
                        offset += @base << InternalMemoryIndexScale;
                    }
                    else
                    {
                        if (!registerValueProvider.TryGetRegisterValue(indexReg, 0, 0, out @base))
                        {
                            break;
                        }
                        offset += @base << InternalMemoryIndexScale;
                    }
                }
#if MVEX
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 1 == Code.MVEX_Vloadunpackhq_zmm_k1_mt ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 2 == Code.MVEX_Vpackstorehd_mt_k1_zmm ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 3 == Code.MVEX_Vpackstorehq_mt_k1_zmm ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 4 == Code.MVEX_Vloadunpackhps_zmm_k1_mt ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 5 == Code.MVEX_Vloadunpackhpd_zmm_k1_mt ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 6 == Code.MVEX_Vpackstorehps_mt_k1_zmm ? 0 : -1);
                Static.Assert(Code.MVEX_Vloadunpackhd_zmm_k1_mt + 7 == Code.MVEX_Vpackstorehpd_mt_k1_zmm ? 0 : -1);
                if (code >= Code.MVEX_Vloadunpackhd_zmm_k1_mt && code <= Code.MVEX_Vpackstorehpd_mt_k1_zmm)
                {
                    offset -= 0x40;
                }
#endif
                offset &= offsetMask;
                if (!code.IgnoresSegment())
                {
                    if (!registerValueProvider.TryGetRegisterValue(MemorySegment, 0, 0, out seg))
                    {
                        break;
                    }
                    offset += seg;
                }
                result = offset;
                return(true);

            default:
                throw new InvalidOperationException();
            }

            result = 0;
            return(false);
        }