Beispiel #1
0
        public Mem(GPReg @base, IntPtr displacement, int size = 0)
            : base(size: size)
        {
            if (@base == null)
                throw new ArgumentNullException("base");
            Contract.EndContractBlock();

            _type = MemoryType.Native;
            _segmentPrefix = SegmentPrefix.None;

            _sizePrefix = @base.Size != IntPtr.Size;

            _base = @base.RegisterIndex;
            _index = RegIndex.Invalid;
            _scalingFactor = ScalingFactor.Times1;

            _target = IntPtr.Zero;
            _displacement = displacement;
        }
Beispiel #2
0
        private static Mem MemPtrBuild(Label label, GPReg index, ScalingFactor scalingFactor, int displacement, Size size)
        {
            Contract.Requires(label != null);
            Contract.Requires(index != null);
            Contract.Requires(scalingFactor >= ScalingFactor.Times1 && scalingFactor <= ScalingFactor.Times8);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return new Mem(label, index, scalingFactor, (IntPtr)displacement, (int)size);
        }
Beispiel #3
0
        private static Mem MemPtrAbs(IntPtr target, GPReg index, ScalingFactor scalingFactor, int displacement, SegmentPrefix segmentPrefix, Size size)
        {
            Contract.Requires(index != null);
            Contract.Requires(scalingFactor >= ScalingFactor.Times1 && scalingFactor <= ScalingFactor.Times8);

            return new Mem(target, index, scalingFactor, (IntPtr)displacement, segmentPrefix, (int)size);
        }
Beispiel #4
0
        public static Mem xmmword_ptr(GPReg @base, GPReg index, ScalingFactor scalingFactor, int displacement = 0)
        {
            Contract.Requires(@base != null);
            Contract.Requires(index != null);
            Contract.Requires(scalingFactor >= ScalingFactor.Times1 && scalingFactor <= ScalingFactor.Times8);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return MemPtrBuild(@base, index, scalingFactor, displacement, NAsmJit.Size.DQWORD);
        }
Beispiel #5
0
        public static Mem xmmword_ptr(GPReg @base, int displacement = 0)
        {
            Contract.Requires(@base != null);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return MemPtrBuild(@base, displacement, NAsmJit.Size.DQWORD);
        }
Beispiel #6
0
        public static Mem word_ptr(IntPtr target, GPReg index, ScalingFactor scalingFactor, int displacement = 0, SegmentPrefix segmentPrefix = SegmentPrefix.None)
        {
            Contract.Requires(index != null);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return MemPtrAbs(target, index, scalingFactor, displacement, segmentPrefix, NAsmJit.Size.WORD);
        }
Beispiel #7
0
        public static Mem sysint_ptr(GPReg @base, int displacement = 0)
        {
            Contract.Requires(@base != null);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return MemPtrBuild(@base, displacement, (NAsmJit.Size)IntPtr.Size);
        }
Beispiel #8
0
        public Mem(Label label, GPReg index, ScalingFactor scalingFactor, IntPtr displacement, int size = 0)
            : this(label, displacement, size)
        {
            if (index == null)
                throw new ArgumentNullException("index");
            if (scalingFactor < ScalingFactor.Times1 || scalingFactor > ScalingFactor.Times8)
                throw new ArgumentOutOfRangeException("scalingFactor");
            Contract.EndContractBlock();

            _index = index.RegisterIndex;
            _scalingFactor = scalingFactor;
        }
Beispiel #9
0
        public static Mem ptr(GPReg @base, int displacement = 0)
        {
            Contract.Requires(@base != null);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return MemPtrBuild(@base, displacement, 0);
        }
Beispiel #10
0
        public Mem(GPReg @base, GPReg index, ScalingFactor scalingFactor, IntPtr displacement, int size = 0)
            : base(size: size)
        {
            if (@base == null)
                throw new ArgumentNullException("base");
            if (index == null)
                throw new ArgumentNullException("index");
            if (scalingFactor < ScalingFactor.Times1 || scalingFactor > ScalingFactor.Times8)
                throw new ArgumentOutOfRangeException("scalingFactor");
            Contract.EndContractBlock();

            _type = MemoryType.Native;
            _segmentPrefix = SegmentPrefix.None;

            _sizePrefix = @base.Size != IntPtr.Size;

            _base = @base.RegisterIndex;
            _index = index.RegisterIndex;
            _scalingFactor = scalingFactor;

            _target = IntPtr.Zero;
            _displacement = displacement;
        }
Beispiel #11
0
        public Mem(IntPtr target, GPReg index, ScalingFactor scalingFactor, IntPtr displacement, SegmentPrefix segmentPrefix, int size = 0)
            : base(size: size)
        {
            if (index == null)
                throw new ArgumentNullException("index");
            if (scalingFactor < ScalingFactor.Times1 || scalingFactor > ScalingFactor.Times8)
                throw new ArgumentOutOfRangeException("scalingFactor");
            Contract.EndContractBlock();

            _type = MemoryType.Absolute;
            _segmentPrefix = segmentPrefix;

            _sizePrefix = index.Size != IntPtr.Size;

            _base = RegIndex.Invalid;
            _index = index.RegisterIndex;
            _scalingFactor = scalingFactor;

            _target = target;
            _displacement = displacement;
        }
Beispiel #12
0
        private static Mem MemPtrBuild(GPReg @base, int displacement, Size size)
        {
            Contract.Requires(@base != null);
            Contract.Ensures(Contract.Result<Mem>() != null);

            return new Mem(@base, (IntPtr)displacement, (int)size);
        }
Beispiel #13
0
        internal void DumpFunction(CompilerContext cc)
        {
            Logger logger = Compiler.Logger;
            if (logger == null)
                throw new InvalidOperationException("Cannot dump a function without a logger.");

            int i;
            StringBuilder buffer = new StringBuilder();

            // Log function prototype.
            {
                int argumentsCount = _functionPrototype.Arguments.Length;
                bool first = true;

                logger.LogString("; Function Prototype:" + Environment.NewLine);
                logger.LogString(";" + Environment.NewLine);

                for (i = 0; i < argumentsCount; i++)
                {
                    FunctionDeclaration.Argument a = _functionPrototype.Arguments[i];
                    CompilerVar vdata = _argumentVariables[i];

                    if (first)
                    {
                        logger.LogString("; IDX| Type     | Sz | Home           |" + Environment.NewLine);
                        logger.LogString("; ---+----------+----+----------------+" + Environment.NewLine);
                    }

                    buffer.Clear();

                    if (a._registerIndex != RegIndex.Invalid)
                    {
                        var regOp = new GPReg(Register.NativeRegisterType, a._registerIndex);
                        Assembler.DumpOperand(buffer, regOp, Register.NativeRegisterType);
                    }
                    else
                    {
                        Mem memOp = new Mem();
                        memOp.Base = RegIndex.Esp;
                        memOp.Displacement = (IntPtr)a._stackOffset;
                        Assembler.DumpOperand(buffer, memOp, Register.NativeRegisterType);
                    }

                    // original format string: "; %-3u| %-9s| %-3u| %-15s|\n"
                    logger.LogFormat("; {0,-3}| {1,-9}| {2,-3}| {3,-15}|" + Environment.NewLine,
                        // Argument index.
                        i,
                        // Argument type.
                        (int)vdata.Type < _variableTypeCount ? VariableInfo.GetVariableInfo(vdata.Type).Name : "invalid",
                        // Argument size.
                        vdata.Size,
                        // Argument memory home.
                        buffer
                        );

                    first = false;
                }
                logger.LogString(";" + Environment.NewLine);
            }

            // Log variables.
            {
                int variablesCount = Compiler.Variables.Count;
                bool first = true;

                logger.LogString("; Variables:" + Environment.NewLine);
                logger.LogString(";" + Environment.NewLine);

                for (i = 0; i < variablesCount; i++)
                {
                    CompilerVar vdata = Compiler.GetVarData(i);
                    Contract.Assert(vdata != null);

                    // If this variable is not related to this function then skip it.
                    if (vdata.Scope != this)
                        continue;

                    // Get some information about variable type.
                    VariableInfo vinfo = VariableInfo.GetVariableInfo(vdata.Type);

                    if (first)
                    {
                        logger.LogString("; ID | Type     | Sz | Home           | Register Access   | Memory Access     |" + Environment.NewLine);
                        logger.LogString("; ---+----------+----+----------------+-------------------+-------------------+" + Environment.NewLine);
                    }

                    buffer.Clear();
                    buffer.Append("[None]");

                    if (vdata.HomeMemoryData != null)
                    {
                        buffer.Clear();

                        Mem memOp = new Mem();
                        if (vdata.IsMemArgument)
                        {
                            FunctionDeclaration.Argument a = _functionPrototype.Arguments[i];

                            memOp.Base = cc.ArgumentsBaseReg;
                            memOp.Displacement += cc.ArgumentsBaseOffset;
                            memOp.Displacement += a._stackOffset;
                        }
                        else
                        {
                            VarMemBlock memBlock = vdata.HomeMemoryData;
                            memOp.Base = cc.VariablesBaseReg;
                            memOp.Displacement += cc.VariablesBaseOffset;
                            memOp.Displacement += memBlock.Offset;
                        }

                        Assembler.DumpOperand(buffer, memOp, Register.NativeRegisterType);
                    }

                    string registerAccess = string.Format("r={0}w={1}x={2}", vdata.RegisterReadCount, vdata.RegisterWriteCount, vdata.RegisterRWCount);
                    string memoryAccess = string.Format("r={0}w={1}x={2}", vdata.MemoryReadCount, vdata.MemoryWriteCount, vdata.MemoryRWCount);
                    logger.LogFormat("; {0,-3}| {1,-9}| {2,-3}| {3,-15}| {4,-18}| {5,-18}|" + Environment.NewLine,
                        // Variable id.
                        (uint)(i & Operand.OperandIdValueMask),
                        // Variable type.
                        (int)vdata.Type < _variableTypeCount ? vinfo.Name : "invalid",
                        // Variable size.
                        vdata.Size,
                        // Variable memory home.
                        buffer,
                        // Register access count.
                        registerAccess,
                        // Memory access count.
                        memoryAccess
                        );

                    first = false;
                }
                logger.LogString(";" + Environment.NewLine);
            }

            // Log modified registers.
            {
                buffer.Clear();

                int r;
                int modifiedRegisters = 0;

                for (r = 0; r < 3; r++)
                {
                    bool first = true;
                    RegisterMask regs;
                    RegType type;

                    switch (r)
                    {
                    case 0:
                        regs = cc.ModifiedGPRegisters;
                        type = Register.NativeRegisterType;
                        buffer.Append("; GP : ");
                        break;
                    case 1:
                        regs = cc.ModifiedMMRegisters;
                        type = RegType.MM;
                        buffer.Append("; MM : ");
                        break;
                    case 2:
                        regs = cc.ModifiedXMMRegisters;
                        type = RegType.XMM;
                        buffer.Append("; XMM: ");
                        break;
                    default:
                        Contract.Assert(false, "");
                        continue;
                    }

                    for (i = 0; i < RegNum.Base; i++)
                    {
                        if ((regs & RegisterMask.FromIndex((RegIndex)i)) != RegisterMask.Zero)
                        {
                            if (!first)
                            {
                                buffer.Append(',');
                                buffer.Append(' ');
                            }

                            DumpRegister(buffer, type, i);
                            first = false;
                            modifiedRegisters++;
                        }
                    }

                    buffer.AppendLine();
                }

                logger.LogFormat("; Modified registers ({0}):" + Environment.NewLine, modifiedRegisters);
                logger.LogString(buffer.ToString());
            }

            logger.LogString(Environment.NewLine);
        }
Beispiel #14
0
        public void TranslateOperands(Operand[] operands)
        {
            Contract.Requires(operands != null);

            int i;
            int count = operands.Length;

            // Translate variables to registers.
            for (i = 0; i < count; i++)
            {
                Operand o = operands[i];

                if (o.IsVar)
                {
                    CompilerVar vdata = _compiler.GetVarData(o.Id);
                    Contract.Assert(vdata != null);

                    operands[i] = new GPReg(((BaseVar)o).RegisterType, vdata.RegisterIndex);
                }
                else if (o.IsMem)
                {
                    Mem mem = (Mem)o;

                    if ((o.Id & Operand.OperandIdTypeMask) == Operand.OperandIdTypeVar)
                    {
                        // Memory access. We just increment here actual displacement.
                        CompilerVar vdata = _compiler.GetVarData(o.Id);
                        Contract.Assert(vdata != null);

                        mem.Displacement += vdata.IsMemArgument
                          ? _argumentsActualDisp
                          : _variablesActualDisp;
                        // NOTE: This is not enough, variable position will be patched later
                        // by CompilerContext::_patchMemoryOperands().
                    }
                    else if (((int)mem.Base & Operand.OperandIdTypeMask) == Operand.OperandIdTypeVar)
                    {
                        CompilerVar vdata = _compiler.GetVarData((int)mem.Base);
                        Contract.Assert(vdata != null);

                        mem.Base = vdata.RegisterIndex;
                    }

                    if (((int)mem.Index & Operand.OperandIdTypeMask) == Operand.OperandIdTypeVar)
                    {
                        CompilerVar vdata = _compiler.GetVarData((int)mem.Index);
                        Contract.Assert(vdata != null);

                        mem.Index = vdata.RegisterIndex;
                    }
                }
            }
        }