Ejemplo n.º 1
0
 public static void SetReturnAddressForStackFrame(uint stackframe, uint value)
 {
     Intrinsic.Store32(stackframe, NativeIntSize, value);
 }
Ejemplo n.º 2
0
            public override string ToString()
            {
                string text;

                switch (op)
                {
                case Op.AssignA:
                    text = string.Format("{0} := {1}", lhs, rhsA);
                    break;

                case Op.AssignImplicit:
                    text = string.Format("_ := {0}", rhsA);
                    break;

                case Op.APlusB:
                    text = string.Format("{0} := {1} + {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AMinusB:
                    text = string.Format("{0} := {1} - {2}", lhs, rhsA, rhsB);
                    break;

                case Op.ATimesB:
                    text = string.Format("{0} := {1} * {2}", lhs, rhsA, rhsB);
                    break;

                case Op.ADividedByB:
                    text = string.Format("{0} := {1} / {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AModB:
                    text = string.Format("{0} := {1} % {2}", lhs, rhsA, rhsB);
                    break;

                case Op.APowB:
                    text = string.Format("{0} := {1} ^ {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AEqualB:
                    text = string.Format("{0} := {1} == {2}", lhs, rhsA, rhsB);
                    break;

                case Op.ANotEqualB:
                    text = string.Format("{0} := {1} != {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AGreaterThanB:
                    text = string.Format("{0} := {1} > {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AGreatOrEqualB:
                    text = string.Format("{0} := {1} >= {2}", lhs, rhsA, rhsB);
                    break;

                case Op.ALessThanB:
                    text = string.Format("{0} := {1} < {2}", lhs, rhsA, rhsB);
                    break;

                case Op.ALessOrEqualB:
                    text = string.Format("{0} := {1} <= {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AAndB:
                    text = string.Format("{0} := {1} and {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AOrB:
                    text = string.Format("{0} := {1} or {2}", lhs, rhsA, rhsB);
                    break;

                case Op.AisaB:
                    text = string.Format("{0} := {1} isa {2}", lhs, rhsA, rhsB);
                    break;

                case Op.CopyA:
                    text = string.Format("{0} := copy of {1}", lhs, rhsA);
                    break;

                case Op.NotA:
                    text = string.Format("{0} := not {1}", lhs, rhsA);
                    break;

                case Op.GotoA:
                    text = string.Format("goto {0}", rhsA);
                    break;

                case Op.GotoAifB:
                    text = string.Format("goto {0} if {1}", rhsA, rhsB);
                    break;

                case Op.GotoAifTrulyB:
                    text = string.Format("goto {0} if truly {1}", rhsA, rhsB);
                    break;

                case Op.GotoAifNotB:
                    text = string.Format("goto {0} if not {1}", rhsA, rhsB);
                    break;

                case Op.PushParam:
                    text = string.Format("push param {0}", rhsA);
                    break;

                case Op.CallFunctionA:
                    text = string.Format("{0} := call {1} with {2} args", lhs, rhsA, rhsB);
                    break;

                case Op.CallIntrinsicA:
                    text = string.Format("intrinsic {0}", Intrinsic.GetByID(rhsA.IntValue()));
                    break;

                case Op.ReturnA:
                    text = string.Format("{0} := {1}; return", lhs, rhsA);
                    break;

                case Op.ElemBofA:
                    text = string.Format("{0} = {1}[{2}]", lhs, rhsA, rhsB);
                    break;

                case Op.ElemBofIterA:
                    text = string.Format("{0} = {1} iter {2}", lhs, rhsA, rhsB);
                    break;

                case Op.LengthOfA:
                    text = string.Format("{0} = len({1})", lhs, rhsA);
                    break;

                default:
                    throw new RuntimeException("unknown opcode: " + op);
                }
//				if (comment != null) text = text + "\t// " + comment;
                return(text);
            }
Ejemplo n.º 3
0
 public static IntrinsicInfo GetInfo(Intrinsic intrin)
 {
     return(_intrinTable[(int)intrin]);
 }
Ejemplo n.º 4
0
        public static void EmitVectorByScalarOpF32(ArmEmitterContext context, Intrinsic inst32, Intrinsic inst64)
        {
            OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp;

            Intrinsic inst = (op.Size & 1) != 0 ? inst64 : inst32;

            EmitVectorByScalarOpSimd32(context, (n, m) => context.AddIntrinsic(inst, n, m));
        }
Ejemplo n.º 5
0
 public static ValNumber IntrinsicByName(string name)
 {
     return(new ValNumber(Intrinsic.GetByName(name).id));
 }
Ejemplo n.º 6
0
 public TypeDefinition GetTypeDefinition(uint slot)
 {
     return(new TypeDefinition(Intrinsic.LoadPointer(Ptr, (IntPtr.Size * 4) + (IntPtr.Size * (int)slot))));
 }
Ejemplo n.º 7
0
        public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst32, Intrinsic inst64)
        {
            OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;

            Intrinsic inst = (op.Size & 1) != 0 ? inst64 : inst32;

            EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m));
        }
Ejemplo n.º 8
0
 internal static IntPtr GetFunctionPointerForDelegateInternal(Delegate d)
 {
     return(Intrinsic.GetObjectAddress(d).LoadPointer(0).ToIntPtr());
 }
Ejemplo n.º 9
0
 public ProtectedRegionDefinition GetProtectedRegionDefinition(uint slot)
 {
     return(new ProtectedRegionDefinition(Intrinsic.LoadPointer(Ptr, IntPtr.Size + (IntPtr.Size * (int)slot))));
 }
Ejemplo n.º 10
0
        private static void EmitVectorTranspose(ArmEmitterContext context, int part)
        {
            OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;

            if (Optimizations.UseSsse3)
            {
                Operand mask = null;

                if (op.Size < 3)
                {
                    long maskE0 = _masksE0_TrnUzpXtn[op.Size];
                    long maskE1 = _masksE1_TrnUzp   [op.Size];

                    mask = X86GetScalar(context, maskE0);

                    mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
                }

                Operand n = GetVec(op.Rn);

                if (op.Size < 3)
                {
                    n = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
                }

                Operand m = GetVec(op.Rm);

                if (op.Size < 3)
                {
                    m = context.AddIntrinsic(Intrinsic.X86Pshufb, m, mask);
                }

                Intrinsic punpckInst = part == 0
                    ? X86PunpcklInstruction[op.Size]
                    : X86PunpckhInstruction[op.Size];

                Operand res = context.AddIntrinsic(punpckInst, n, m);

                if (op.RegisterSize == RegisterSize.Simd64)
                {
                    res = context.VectorZeroUpper64(res);
                }

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                Operand res = context.VectorZero();

                int pairs = op.GetPairsCount() >> op.Size;

                for (int index = 0; index < pairs; index++)
                {
                    int pairIndex = index << 1;

                    Operand ne = EmitVectorExtractZx(context, op.Rn, pairIndex + part, op.Size);
                    Operand me = EmitVectorExtractZx(context, op.Rm, pairIndex + part, op.Size);

                    res = EmitVectorInsert(context, res, ne, pairIndex, op.Size);
                    res = EmitVectorInsert(context, res, me, pairIndex + 1, op.Size);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }
Ejemplo n.º 11
0
        /// <inheritdoc />
        public override object Run(Closure closure)
        {
            var operand = closure.Unbox <object>(this.operandNode.Run(closure));

            if (operand == null && (this.targetType.CanBeNull || this.isTargetTypeNullable))
            {
                return(null);
            }

            var operandType = closure.GetType(operand);
            var convertType = this.convertExpression.NodeType;

            if (convertType != ExpressionType.Convert)
            {
                convertType = ExpressionType.ConvertChecked;
            }

            // un-box
            if ((this.sourceType == typeof(object) || this.sourceType == typeof(ValueType) || this.sourceType.IsInterface) && this.targetType.IsValueType)
            {
                // null un-box
                if (operand == null)
                {
                    throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand));
                }
                // type check for un-box
                if (operandType == this.targetType)
                {
                    return(operand);
                }
                throw new InvalidCastException();
            }
            // box
            else if (this.sourceType.IsValueType && (this.targetType == typeof(object) || this.targetType == typeof(ValueType) || this.targetType.IsInterface))
            {
                // type check for box
                return(this.targetType.IsAssignableFrom(operandType) ? operand : null);
            }
            // to enum
            else if (this.targetType.IsEnum && (this.sourceType == typeof(byte) ||
                                                this.sourceType == typeof(sbyte) ||
                                                this.sourceType == typeof(short) ||
                                                this.sourceType == typeof(ushort) ||
                                                this.sourceType == typeof(int) ||
                                                this.sourceType == typeof(uint) ||
                                                this.sourceType == typeof(long) ||
                                                this.sourceType == typeof(ulong)))
            {
                if (operand == null)
                {
                    throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand));
                }

                operand = Intrinsic.InvokeConversion(closure, operand, Enum.GetUnderlyingType(this.targetType), this.convertExpression.NodeType, null);
                return(Enum.ToObject(this.targetType, closure.Unbox <object>(operand)));
            }
            // from enum
            else if (this.sourceType.IsEnum && (this.targetType == typeof(byte) ||
                                                this.targetType == typeof(sbyte) ||
                                                this.targetType == typeof(short) ||
                                                this.targetType == typeof(ushort) ||
                                                this.targetType == typeof(int) ||
                                                this.targetType == typeof(uint) ||
                                                this.targetType == typeof(long) ||
                                                this.targetType == typeof(ulong)))
            {
                if (operand == null)
                {
                    throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand));
                }

                operand = Convert.ChangeType(closure.Unbox <object>(operand), Enum.GetUnderlyingType(this.sourceType));
                operand = Intrinsic.InvokeConversion(closure, operand, this.targetType, this.convertExpression.NodeType, null);
                return(operand);
            }
            // from nullable
            if (this.targetType.IsValueType && this.isSourceTypeNullable)
            {
                if (operand == null)
                {
                    throw new NullReferenceException(string.Format(Properties.Resources.EXCEPTION_EXECUTION_EXPRESSIONGIVESNULLRESULT, this.convertExpression.Operand));
                }

                operand = Intrinsic.InvokeConversion(closure, operand, this.targetType, this.convertExpression.NodeType, null);
            }
            else if (this.targetType.IsAssignableFrom(operandType))
            {
                return(operand);
            }

            return(Intrinsic.InvokeConversion(closure, operand, this.targetType, convertType, this.operation));
        }
Ejemplo n.º 12
0
        private Page *AllocateInternal(uint pages, AllocatePageOptions options = default)
        {
            if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages)
            {
                KernelMessage.Path(DebugName, "Requesting Pages: {1}. Available: {2} DebugName={0}", options.DebugName, pages, _FreePages);
            }

            if (pages == 256)
            {
                Debug.Nop();
            }

            UninterruptibleMonitor.Enter(this);
            try
            {
                SelfCheck("SC1");
                if (pages > 1 && (AddressSpaceKind == AddressSpaceKind.Virtual || options.Continuous))
                {
                    if (!MoveToFreeContinuous(pages))
                    {
                        // Compact
                        //KernelMessage.Path(DebugName, "Compacting Linked List");
                        //this.DumpPages();
                        BuildLinkedLists();
                        if (!MoveToFreeContinuous(pages))
                        {
                            this.DumpPages();
                            KernelMessage.WriteLine("Requesting {0} pages failed", pages);
                            Panic.Error("Requesting pages failed: out of memory");
                        }
                    }
                }

                // ---
                var head     = FreeList;
                var headPage = (Page *)head;
                FreeList = head->next;
                list_head.list_del_init(head);
                headPage->Status = PageStatus.Used;
                if (KConfig.Log.PageAllocation)
                {
                    if (options.DebugName != null)
                    {
                        headPage->DebugTag = (uint)Intrinsic.GetObjectAddress(options.DebugName);
                    }
                    else
                    {
                        headPage->DebugTag = null;
                    }
                }
                _FreePages--;
                // ---

                for (var i = 1; i < pages; i++)
                {
                    var tmpNextFree = FreeList->next;
                    list_head.list_move_tail(FreeList, head);
                    var p = (Page *)FreeList;
                    if (p->Status == PageStatus.Used)
                    {
                        this.DumpPages();
                        this.DumpPage(p);
                        KernelMessage.Path(DebugName, "Double Alloc pages={0} allocs={1} free={2} ptr={3:X8}", pages, (uint)_Requests, _FreePages, (uint)p);
                        Panic.Error("Double Alloc");
                    }
                    p->Status = PageStatus.Used;
                    FreeList  = tmpNextFree;
                    _FreePages--;
                }

                if (KConfig.Log.PageAllocation && TraceOptions.Enabled && pages >= TraceOptions.MinPages)
                {
                    KernelMessage.Path(DebugName, "Allocation done. Addr: {0:X8} Available: {1}", GetAddress(headPage), _FreePages);
                }

                _Requests++;

                CheckAllocation(headPage, pages);
                SelfCheck("SC2");

                return(headPage);
            }
            finally
            {
                UninterruptibleMonitor.Exit(this);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Decompresses the data using LibLZF algorithm
        /// </summary>
        /// <param name="input">Reference to the data to decompress</param>
        /// <param name="inputLength">Length of the data to decompress</param>
        /// <param name="output">Reference to a buffer which will contain the decompressed data</param>
        /// <param name="outputLength">The size of the decompressed archive in the output buffer</param>
        /// <returns></returns>
        public static bool Decompress(IntPtr input, uint inputLength, IntPtr output, uint outputLength)
        {
            uint iidx = 0;
            uint oidx = 0;

            do
            {
                //uint ctrl = input[iidx++];
                uint ctrl = Intrinsic.Load8(input, iidx);
                iidx++;

                if (ctrl < (1 << 5))                 /* literal run */
                {
                    ctrl++;

                    if (oidx + ctrl > outputLength)
                    {
                        //SET_ERRNO (E2BIG);
                        return(false);
                    }

                    do
                    {
                        //output[oidx++] = input[iidx++];
                        Intrinsic.Store8(output, oidx, Intrinsic.Load8(input, iidx));
                        oidx++;
                        iidx++;
                    }while ((--ctrl) != 0);
                }
                else                 /* back reference */
                {
                    uint len = ctrl >> 5;

                    uint reference = (uint)(oidx - ((ctrl & 0x1f) << 8) - 1);

                    if (len == 7)
                    {
                        //len += input[iidx++];
                        len += Intrinsic.Load8(input, iidx);
                        iidx++;
                    }

                    //reference -= input[iidx++];
                    reference -= Intrinsic.Load8(input, iidx);
                    iidx++;

                    if (oidx + len + 2 > outputLength)
                    {
                        //SET_ERRNO (E2BIG);
                        return(false);
                    }

                    //if (reference < 0)
                    //{
                    //	//SET_ERRNO (EINVAL);
                    //	return false;
                    //}

                    //output[oidx++] = output[reference++];
                    Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference));
                    oidx++;
                    reference++;

                    //output[oidx++] = output[reference++];
                    Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference));
                    oidx++;
                    reference++;

                    do
                    {
                        //output[oidx++] = output[reference++];
                        Intrinsic.Store8(output, oidx, Intrinsic.Load8(output, reference));
                        oidx++;
                        reference++;
                    }while ((--len) != 0);
                }
            }while (iidx < inputLength);

            return(true);
        }
Ejemplo n.º 14
0
 protected SmbiosStructure(IntPtr address)
 {
     this.address = address;
     length       = Intrinsic.Load8(address, 0x01u);
     handle       = Intrinsic.Load16(address, 0x02u);
 }
Ejemplo n.º 15
0
 public Operand AddIntrinsic(Intrinsic intrin, params Operand[] args)
 {
     return(Add(intrin, Local(OperandType.V128), args));
 }
Ejemplo n.º 16
0
 // TODO: Doc
 public void DefineBuiltin(string name, Intrinsic intr) =>
 GlobalScope.Define(new Symbol.Const(name, intr.Type, new Value.User(intr)));
Ejemplo n.º 17
0
 public Operand AddIntrinsicLong(Intrinsic intrin, params Operand[] args)
 {
     return(Add(intrin, Local(OperandType.I64), args));
 }
Ejemplo n.º 18
0
 public static ValNumber IntrinsicByName(string name)
 {
     return(ValNumber.Create(Intrinsic.GetByName(name).id));
 }
Ejemplo n.º 19
0
        private object ResolveArgumentValue(CustomAttributeArgument argument, Type type)
        {
            var typeCode = argument.ArgumentType.TypeCode;
            var valuePtr = argument.GetArgumentValue();

            // If its an enum type
            if (argument.ArgumentType.ParentType.Handle == EnumTypePtr.Handle)
            {
                typeCode = argument.ArgumentType.ElementType.TypeCode;
            }

            switch (typeCode)
            {
            // 1 byte
            case TypeCode.Boolean:
                return((bool)(Intrinsic.Load8(valuePtr) != 0));

            case TypeCode.U1:
                return((byte)Intrinsic.Load8(valuePtr));

            case TypeCode.I1:
                return((sbyte)Intrinsic.Load8(valuePtr));

            // 2 bytes
            case TypeCode.Char:
                return((char)Intrinsic.Load16(valuePtr));

            case TypeCode.U2:
                return((ushort)Intrinsic.Load16(valuePtr));

            case TypeCode.I2:
                return((short)Intrinsic.Load16(valuePtr));

            // 4 bytes
            case TypeCode.U4:
                return((uint)Intrinsic.Load32(valuePtr));

            case TypeCode.I4:
                return((int)Intrinsic.Load32(valuePtr));

            case TypeCode.R4:
                return(Intrinsic.LoadR4(valuePtr));

            // 8 bytes
            case TypeCode.U8:
                return((ulong)Intrinsic.Load64(valuePtr));

            case TypeCode.I8:
                return((long)Intrinsic.Load64(valuePtr));

            case TypeCode.R8:
                return(Intrinsic.LoadR8(valuePtr));

            // SZArray
            case TypeCode.SZArray:
                return(ResolveArrayValue(argument, type));

            // String
            case TypeCode.String:
                return((string)Intrinsic.GetObjectFromAddress(valuePtr));

            default:
                if (type.FullName == "System.Type")
                {
                    // Get the argument type
                    var argTypeHandle = new RuntimeTypeHandle(argument.ArgumentType.Ptr);

                    return(Type.GetTypeFromHandle(argTypeHandle));
                }
                throw new ArgumentException();
            }
        }
Ejemplo n.º 20
0
 public static void SetUnitTestMethodParameter(uint index, uint value)
 {
     Intrinsic.Store32(new IntPtr(Address.UnitTestStack), index * 4, value);
 }
Ejemplo n.º 21
0
        public static void EmitScalarTernaryOpF32(ArmEmitterContext context, Intrinsic inst32pt1, Intrinsic inst64pt1, Intrinsic inst32pt2, Intrinsic inst64pt2)
        {
            OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp;

            bool      doubleSize = (op.Size & 1) != 0;
            int       shift      = doubleSize ? 1 : 2;
            Intrinsic inst1      = doubleSize ? inst64pt1 : inst32pt1;
            Intrinsic inst2      = doubleSize ? inst64pt2 : inst32pt2;

            EmitScalarTernaryOpSimd32(context, (d, n, m) =>
            {
                Operand res = context.AddIntrinsic(inst1, n, m);
                return(context.AddIntrinsic(inst2, d, res));
            });
        }
Ejemplo n.º 22
0
        public static void EnterTestReadyLoop()
        {
            uint testCount = 0;

            Debugger.Ready();

            Screen.Write("Waiting for unit tests...");
            Screen.NextLine();
            Screen.NextLine();

            // allocate space on stack for parameters
            uint esp = Native.AllocateStackSpace(MaxParameters * 4);

            Screen.Write("Stack @ ");
            Screen.Write((uint)esp, 16, 8);

            Screen.NextLine();
            Screen.NextLine();

            uint row = Screen.Row;

            while (true)
            {
                if (testReady == 1)
                {
                    Screen.Goto(row, 0);
                    Screen.ClearRow();

                    Screen.Write("Test #: ");
                    Screen.Write(++testCount, 10, 7);

                    testResult         = 0;
                    testResultReady    = 0;
                    testResultReported = 0;
                    testReady          = 0;

                    // copy parameters into stack
                    for (uint index = 0; index < testParameters; index++)
                    {
                        uint value = Intrinsic.Load32(new IntPtr(Address.UnitTestStack), (index * 4));

                        Intrinsic.Store32(new IntPtr(esp), index * 4, value);
                    }

                    switch (testResultType)
                    {
                    case 0: Native.FrameCall(testMethodAddress); break;

                    case 1: testResult = Native.FrameCallRetU4(testMethodAddress); break;

                    case 2: testResult = Native.FrameCallRetU8(testMethodAddress); break;

                    case 3: testResult = Native.FrameCallRetR8(testMethodAddress); break;

                    default: break;
                    }

                    testResultReady = 1;

                    Native.Int(255);
                }
            }
        }
Ejemplo n.º 23
0
        public static void EmitVectorsByScalarOpF32(ArmEmitterContext context, Intrinsic inst32pt1, Intrinsic inst64pt1, Intrinsic inst32pt2, Intrinsic inst64pt2)
        {
            OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp;

            Intrinsic inst1 = (op.Size & 1) != 0 ? inst64pt1 : inst32pt1;
            Intrinsic inst2 = (op.Size & 1) != 0 ? inst64pt2 : inst32pt2;

            EmitVectorsByScalarOpSimd32(context, (d, n, m) =>
            {
                Operand res = context.AddIntrinsic(inst1, n, m);
                return(res = context.AddIntrinsic(inst2, d, res));
            });
        }
Ejemplo n.º 24
0
        private static void EmitVectorUnzip(ArmEmitterContext context, int part)
        {
            OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;

            if (Optimizations.UseSsse3)
            {
                if (op.RegisterSize == RegisterSize.Simd128)
                {
                    Operand mask = default;

                    if (op.Size < 3)
                    {
                        long maskE0 = EvenMasks[op.Size];
                        long maskE1 = OddMasks [op.Size];

                        mask = X86GetScalar(context, maskE0);

                        mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);
                    }

                    Operand n = GetVec(op.Rn);

                    if (op.Size < 3)
                    {
                        n = context.AddIntrinsic(Intrinsic.X86Pshufb, n, mask);
                    }

                    Operand m = GetVec(op.Rm);

                    if (op.Size < 3)
                    {
                        m = context.AddIntrinsic(Intrinsic.X86Pshufb, m, mask);
                    }

                    Intrinsic punpckInst = part == 0
                        ? Intrinsic.X86Punpcklqdq
                        : Intrinsic.X86Punpckhqdq;

                    Operand res = context.AddIntrinsic(punpckInst, n, m);

                    context.Copy(GetVec(op.Rd), res);
                }
                else
                {
                    Operand n = GetVec(op.Rn);
                    Operand m = GetVec(op.Rm);

                    Intrinsic punpcklInst = X86PunpcklInstruction[op.Size];

                    Operand res = context.AddIntrinsic(punpcklInst, n, m);

                    if (op.Size < 2)
                    {
                        long maskE0 = _masksE0_Uzp[op.Size];
                        long maskE1 = _masksE1_Uzp[op.Size];

                        Operand mask = X86GetScalar(context, maskE0);

                        mask = EmitVectorInsert(context, mask, Const(maskE1), 1, 3);

                        res = context.AddIntrinsic(Intrinsic.X86Pshufb, res, mask);
                    }

                    Intrinsic punpckInst = part == 0
                        ? Intrinsic.X86Punpcklqdq
                        : Intrinsic.X86Punpckhqdq;

                    res = context.AddIntrinsic(punpckInst, res, context.VectorZero());

                    context.Copy(GetVec(op.Rd), res);
                }
            }
            else
            {
                Operand res = context.VectorZero();

                int pairs = op.GetPairsCount() >> op.Size;

                for (int index = 0; index < pairs; index++)
                {
                    int idx = index << 1;

                    Operand ne = EmitVectorExtractZx(context, op.Rn, idx + part, op.Size);
                    Operand me = EmitVectorExtractZx(context, op.Rm, idx + part, op.Size);

                    res = EmitVectorInsert(context, res, ne, index, op.Size);
                    res = EmitVectorInsert(context, res, me, pairs + index, op.Size);
                }

                context.Copy(GetVec(op.Rd), res);
            }
        }
Ejemplo n.º 25
0
            /// <summary>
            /// Evaluate this line and return the value that would be stored
            /// into the lhs.
            /// </summary>
            public Value Evaluate(Context context)
            {
                if (op == Op.AssignA || op == Op.ReturnA || op == Op.AssignImplicit)
                {
                    // Assignment is a bit of a special case.  It's EXTREMELY common
                    // in TAC, so needs to be efficient, but we have to watch out for
                    // the case of a RHS that is a list or map.  This means it was a
                    // literal in the source, and may contain references that need to
                    // be evaluated now.
                    if (rhsA is ValList || rhsA is ValMap)
                    {
                        return(rhsA.FullEval(context));
                    }
                    else if (rhsA == null)
                    {
                        return(null);
                    }
                    else
                    {
                        return(rhsA.Val(context));
                    }
                }
                if (op == Op.CopyA)
                {
                    // This opcode is used for assigning a literal.  We actually have
                    // to copy the literal, in the case of a mutable object like a
                    // list or map, to ensure that if the same code executes again,
                    // we get a new, unique object.
                    if (rhsA is ValList)
                    {
                        return(((ValList)rhsA).EvalCopy(context));
                    }
                    else if (rhsA is ValMap)
                    {
                        return(((ValMap)rhsA).EvalCopy(context));
                    }
                    else if (rhsA == null)
                    {
                        return(null);
                    }
                    else
                    {
                        return(rhsA.Val(context));
                    }
                }

                Value opA = rhsA != null?rhsA.Val(context) : null;

                Value opB = rhsB != null?rhsB.Val(context) : null;

                if (op == Op.AisaB)
                {
                    return(ValNumber.Truth(opA.IsA(opB, context.vm)));
                }

                if (op == Op.ElemBofA && opB is ValString)
                {
                    // You can now look for a string in almost anything...
                    // and we have a convenient (and relatively fast) method for it:
                    ValMap ignored;
                    return(ValSeqElem.Resolve(opA, ((ValString)opB).value, context, out ignored));
                }

                if (op == Op.AEqualB && (opA == null || opB == null))
                {
                    return(ValNumber.Truth(opA == opB));
                }
                if (op == Op.ANotEqualB && (opA == null || opB == null))
                {
                    return(ValNumber.Truth(opA != opB));
                }

                if (opA is ValNumber)
                {
                    double fA = ((ValNumber)opA).value;
                    switch (op)
                    {
                    case Op.GotoA:
                        context.lineNum = (int)fA;
                        return(null);

                    case Op.GotoAifB:
                        if (opB != null && opB.BoolValue())
                        {
                            context.lineNum = (int)fA;
                        }
                        return(null);

                    case Op.GotoAifTrulyB:
                    {
                        // Unlike GotoAifB, which branches if B has any nonzero
                        // value (including 0.5 or 0.001), this branches only if
                        // B is TRULY true, i.e., its integer value is nonzero.
                        // (Used for short-circuit evaluation of "or".)
                        int i = 0;
                        if (opB != null)
                        {
                            i = opB.IntValue();
                        }
                        if (i != 0)
                        {
                            context.lineNum = (int)fA;
                        }
                        return(null);
                    }

                    case Op.GotoAifNotB:
                        if (opB == null || !opB.BoolValue())
                        {
                            context.lineNum = (int)fA;
                        }
                        return(null);

                    case Op.CallIntrinsicA:
                        // NOTE: intrinsics do not go through NextFunctionContext.  Instead
                        // they execute directly in the current context.  (But usually, the
                        // current context is a wrapper function that was invoked via
                        // Op.CallFunction, so it got a parameter context at that time.)
                        Intrinsic.Result result = Intrinsic.Execute((int)fA, context, context.partialResult);
                        if (result.done)
                        {
                            context.partialResult = null;
                            return(result.result);
                        }
                        // OK, this intrinsic function is not yet done with its work.
                        // We need to stay on this same line and call it again with
                        // the partial result, until it reports that its job is complete.
                        context.partialResult = result;
                        context.lineNum--;
                        return(null);

                    case Op.NotA:
                        return(new ValNumber(1.0 - AbsClamp01(fA)));
                    }
                    if (opB is ValNumber || opB == null)
                    {
                        double fB = opB != null ? ((ValNumber)opB).value : 0;
                        switch (op)
                        {
                        case Op.APlusB:
                            return(new ValNumber(fA + fB));

                        case Op.AMinusB:
                            return(new ValNumber(fA - fB));

                        case Op.ATimesB:
                            return(new ValNumber(fA * fB));

                        case Op.ADividedByB:
                            return(new ValNumber(fA / fB));

                        case Op.AModB:
                            return(new ValNumber(fA % fB));

                        case Op.APowB:
                            return(new ValNumber(Math.Pow(fA, fB)));

                        case Op.AEqualB:
                            return(ValNumber.Truth(fA == fB));

                        case Op.ANotEqualB:
                            return(ValNumber.Truth(fA != fB));

                        case Op.AGreaterThanB:
                            return(ValNumber.Truth(fA > fB));

                        case Op.AGreatOrEqualB:
                            return(ValNumber.Truth(fA >= fB));

                        case Op.ALessThanB:
                            return(ValNumber.Truth(fA < fB));

                        case Op.ALessOrEqualB:
                            return(ValNumber.Truth(fA <= fB));

                        case Op.AAndB:
                            if (!(opB is ValNumber))
                            {
                                fB = opB != null && opB.BoolValue() ? 1 : 0;
                            }
                            return(new ValNumber(Clamp01(fA * fB)));

                        case Op.AOrB:
                            if (!(opB is ValNumber))
                            {
                                fB = opB != null && opB.BoolValue() ? 1 : 0;
                            }
                            return(new ValNumber(Clamp01(fA + fB - fA * fB)));

                        default:
                            break;
                        }
                    }
                    else if (opB is ValString)
                    {
                        // number (op) string
                        string sA = opA.ToString();
                        string sB = opB.ToString();
                        switch (op)
                        {
                        case Op.APlusB:
                            return(new ValString(sA + sB));

                        default:
                            break;
                        }
                    }
                }
                else if (opA is ValString)
                {
                    string sA = ((ValString)opA).value;
                    switch (op)
                    {
                    case Op.APlusB:
                    {
                        if (opB == null)
                        {
                            return(opA);
                        }
                        String sB = opB.ToString(context.vm);
                        if (sA.Length + sB.Length > ValString.maxSize)
                        {
                            throw new LimitExceededException("string too large");
                        }
                        return(new ValString(sA + sB));
                    }

                    case Op.AMinusB:
                    {
                        if (opB == null)
                        {
                            return(opA);
                        }
                        string sB = opB.ToString(context.vm);
                        if (sA.EndsWith(sB))
                        {
                            sA = sA.Substring(0, sA.Length - sB.Length);
                        }
                        return(new ValString(sA));
                    }

                    case Op.ATimesB:
                    case Op.ADividedByB:
                    {
                        double factor = 0;
                        if (op == Op.ATimesB)
                        {
                            Check.Type(opB, typeof(ValNumber), "string replication");
                            factor = ((ValNumber)opB).value;
                        }
                        else
                        {
                            Check.Type(opB, typeof(ValNumber), "string division");
                            factor = 1.0 / ((ValNumber)opB).value;
                        }
                        int repeats = (int)factor;
                        if (repeats < 0)
                        {
                            return(ValString.empty);
                        }
                        if (repeats * sA.Length > ValString.maxSize)
                        {
                            throw new LimitExceededException("string too large");
                        }
                        var result = new System.Text.StringBuilder();
                        for (int i = 0; i < repeats; i++)
                        {
                            result.Append(sA);
                        }
                        int extraChars = (int)(sA.Length * (factor - repeats));
                        if (extraChars > 0)
                        {
                            result.Append(sA.Substring(0, extraChars));
                        }
                        return(new ValString(result.ToString()));
                    }

                    case Op.AEqualB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) == 0));

                    case Op.ANotEqualB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) != 0));

                    case Op.AGreaterThanB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) > 0));

                    case Op.AGreatOrEqualB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) >= 0));

                    case Op.ALessThanB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) < 0));

                    case Op.ALessOrEqualB:
                        return(ValNumber.Truth(string.Compare(sA, opB.ToString(context.vm)) <= 0));

                    case Op.ElemBofA:
                    case Op.ElemBofIterA:
                    {
                        int idx = opB.IntValue();
                        Check.Range(idx, -sA.Length, sA.Length - 1, "string index");
                        if (idx < 0)
                        {
                            idx += sA.Length;
                        }
                        return(new ValString(sA.Substring(idx, 1)));
                    }

                    case Op.LengthOfA:
                        return(new ValNumber(sA.Length));

                    default:
                        break;
                    }
                }
                else if (opA is ValList)
                {
                    List <Value> list = ((ValList)opA).values;
                    if (op == Op.ElemBofA || op == Op.ElemBofIterA)
                    {
                        // list indexing
                        int idx = opB.IntValue();
                        Check.Range(idx, -list.Count, list.Count - 1, "list index");
                        if (idx < 0)
                        {
                            idx += list.Count;
                        }
                        return(list[idx]);
                    }
                    else if (op == Op.LengthOfA)
                    {
                        return(new ValNumber(list.Count));
                    }
                    else if (op == Op.AEqualB)
                    {
                        return(ValNumber.Truth(((ValList)opA).Equality(opB)));
                    }
                    else if (op == Op.ANotEqualB)
                    {
                        return(ValNumber.Truth(1.0 - ((ValList)opA).Equality(opB)));
                    }
                    else if (op == Op.APlusB)
                    {
                        // list concatenation
                        Check.Type(opB, typeof(ValList), "list concatenation");
                        List <Value> list2 = ((ValList)opB).values;
                        if (list.Count + list2.Count > ValList.maxSize)
                        {
                            throw new LimitExceededException("list too large");
                        }
                        List <Value> result = new List <Value>(list.Count + list2.Count);
                        foreach (Value v in list)
                        {
                            result.Add(v == null ? null : v.Val(context));
                        }
                        foreach (Value v in list2)
                        {
                            result.Add(v == null ? null : v.Val(context));
                        }
                        return(new ValList(result));
                    }
                    else if (op == Op.ATimesB || op == Op.ADividedByB)
                    {
                        // list replication (or division)
                        double factor = 0;
                        if (op == Op.ATimesB)
                        {
                            Check.Type(opB, typeof(ValNumber), "list replication");
                            factor = ((ValNumber)opB).value;
                        }
                        else
                        {
                            Check.Type(opB, typeof(ValNumber), "list division");
                            factor = 1.0 / ((ValNumber)opB).value;
                        }
                        if (factor <= 0)
                        {
                            return(new ValList());
                        }
                        int finalCount = (int)(list.Count * factor);
                        if (finalCount > ValList.maxSize)
                        {
                            throw new LimitExceededException("list too large");
                        }
                        List <Value> result = new List <Value>(finalCount);
                        for (int i = 0; i < finalCount; i++)
                        {
                            result.Add(list[i % list.Count]);
                        }
                        return(new ValList(result));
                    }
                    else if (op == Op.NotA)
                    {
                        return(ValNumber.Truth(!opA.BoolValue()));
                    }
                }
                else if (opA is ValMap)
                {
                    if (op == Op.ElemBofA)
                    {
                        // map lookup
                        // (note, cases where opB is a string are handled above, along with
                        // all the other types; so we'll only get here for non-string cases)
                        ValSeqElem se = new ValSeqElem(opA, opB);
                        return(se.Val(context));
                        // (This ensures we walk the "__isa" chain in the standard way.)
                    }
                    else if (op == Op.ElemBofIterA)
                    {
                        // With a map, ElemBofIterA is different from ElemBofA.  This one
                        // returns a mini-map containing a key/value pair.
                        return(((ValMap)opA).GetKeyValuePair(opB.IntValue()));
                    }
                    else if (op == Op.LengthOfA)
                    {
                        return(new ValNumber(((ValMap)opA).Count));
                    }
                    else if (op == Op.AEqualB)
                    {
                        return(ValNumber.Truth(((ValMap)opA).Equality(opB)));
                    }
                    else if (op == Op.ANotEqualB)
                    {
                        return(ValNumber.Truth(1.0 - ((ValMap)opA).Equality(opB)));
                    }
                    else if (op == Op.APlusB)
                    {
                        // map combination
                        Dictionary <Value, Value> map = ((ValMap)opA).map;
                        Check.Type(opB, typeof(ValMap), "map combination");
                        Dictionary <Value, Value> map2 = ((ValMap)opB).map;
                        ValMap result = new ValMap();
                        foreach (KeyValuePair <Value, Value> kv in map)
                        {
                            result.map[kv.Key] = kv.Value.Val(context);
                        }
                        foreach (KeyValuePair <Value, Value> kv in map2)
                        {
                            result.map[kv.Key] = kv.Value.Val(context);
                        }
                        return(result);
                    }
                    else if (op == Op.NotA)
                    {
                        return(ValNumber.Truth(!opA.BoolValue()));
                    }
                }
                else if (opA is ValFunction && opB is ValFunction)
                {
                    Function fA = ((ValFunction)opA).function;
                    Function fB = ((ValFunction)opB).function;
                    switch (op)
                    {
                    case Op.AEqualB:
                        return(ValNumber.Truth(fA == fB));

                    case Op.ANotEqualB:
                        return(ValNumber.Truth(fA != fB));
                    }
                }
                else
                {
                    // opA is something else... perhaps null
                    switch (op)
                    {
                    case Op.NotA:
                        return(opA != null && opA.BoolValue() ? ValNumber.zero : ValNumber.one);
                    }
                }

                if (op == Op.AAndB || op == Op.AOrB)
                {
                    // We already handled the case where opA was a number above;
                    // this code handles the case where opA is something else.
                    double fA = opA != null && opA.BoolValue() ? 1 : 0;
                    double fB;
                    if (opB is ValNumber)
                    {
                        fB = ((ValNumber)opB).value;
                    }
                    else
                    {
                        fB = opB != null && opB.BoolValue() ? 1 : 0;
                    }
                    double result;
                    if (op == Op.AAndB)
                    {
                        result = fA * fB;
                    }
                    else
                    {
                        result = 1.0 - (1.0 - AbsClamp01(fA)) * (1.0 - AbsClamp01(fB));
                    }
                    return(new ValNumber(result));
                }
                return(null);
            }
Ejemplo n.º 26
0
 /// <summary>
 /// Releases a page to the free list
 /// </summary>
 /// <param name="address">The address.</param>
 public static void Free(IntPtr address)
 {
     totalUsedPages--;
     at += 4;
     Intrinsic.Store32(at, address.ToInt32());
 }
Ejemplo n.º 27
0
 private static void Add(Intrinsic intrin, IntrinsicInfo info)
 {
     _intrinTable[(int)intrin] = info;
 }
Ejemplo n.º 28
0
 internal static IntPtr GetFunctionPointerForDelegateInternal(Delegate d)
 {
     return(Intrinsic.LoadPointer(Intrinsic.GetObjectAddress(d), IntPtr.Size * 2));
 }
Ejemplo n.º 29
0
 private static void IRQ251()
 {
     Intrinsic.SuppressStackFrame();
     Native.IRQ251();
 }
Ejemplo n.º 30
0
 private static IntPtr GetPointer(uint offset)
 {
     return(Intrinsic.LoadPointer(VBEModeInfo, offset));
 }