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