Exemplo n.º 1
0
        private void EmitIndexComputation(Array array)
        {
            MemoryMappedStorage mms    = GetDataLayout(array);
            ArrayMemoryLayout   layout = mms.Layout as ArrayMemoryLayout;

            if (layout.ElementsPerWord > 1)
            {
                throw new NotImplementedException("Multiple elements per word not yet implemented");
            }
            MemoryRegion region = mms.Region;
            IMarshalInfo minfo  = region.MarshalInfo;

            int            shiftWidth = MathExt.CeilLog2(mms.Region.AddressWidth);
            TypeDescriptor indexType  = TypeDescriptor.GetTypeOf(mms.BaseAddress);

            for (int i = 0; i < layout.Strides.Length; i++)
            {
                TypeDescriptor orgIndexType;
                if (i > 0)
                {
                    orgIndexType = TypeStack.Skip(1).First();
                    Emit(_iset.Swap().CreateStk(2, orgIndexType, indexType, indexType, orgIndexType));
                }
                else
                {
                    orgIndexType = TypeStack.Peek();
                }

                ulong stride = layout.Strides[layout.Strides.Length - i - 1];

                if (MathExt.IsPow2(stride))
                {
                    Emit(_iset.Convert().CreateStk(1, orgIndexType, indexType));
                    int ishift = MathExt.CeilLog2(stride);
                    if (ishift > 0)
                    {
                        Unsigned       shift     = Unsigned.FromULong((ulong)ishift, shiftWidth);
                        TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift);
                        Emit(_iset.LdConst(shift).CreateStk(0, shiftType));
                        Emit(_iset.LShift().CreateStk(2, indexType, shiftType, indexType));
                    }
                }
                else
                {
                    throw new NotImplementedException("Stride ain't a power of 2");
                }

                if (i > 0)
                {
                    Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType));
                }
            }

            if (mms.BaseAddress.ULongValue != 0)
            {
                Emit(_iset.LdConst(mms.BaseAddress).CreateStk(0, indexType));
                if (minfo.UseStrongPow2Alignment)
                {
                    Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType));
                }
                else
                {
                    Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType));
                }
            }
        }