internal MemoryRegion(IMarshalInfo marshalInfo) { Items = new List<MemoryMappedStorage>(); MarshalInfo = marshalInfo; }
internal EnumMemoryLayout(TypeDescriptor layoutedType, IMarshalInfo minfo) : base(layoutedType) { Contract.Requires(layoutedType.CILType.IsEnum); SizeInBits = (ulong)NumBits; _wordSize = minfo.WordSize; Size = (SizeInBits + minfo.WordSize - 1) / minfo.WordSize; }
private void HandleLdelemFixAFixI(XILSInstr xilsi) { FixedArrayRef far = (FixedArrayRef)xilsi.StaticOperand; Array array = far.ArrayObj; long[] indices = far.Indices; var preds = RemapPreds(xilsi.Preds); 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; TypeDescriptor dwType = minfo.GetRawWordType(); for (uint i = 0; i < layout.WordsPerElement; i++) { Unsigned addr = ComputeConstAddress(array, indices, i); Emit(_iset.LdConst(addr) .CreateStk(0, TypeDescriptor.GetTypeOf(addr))); Emit(_iset.RdMem(region) .CreateStk(preds, 1, TypeDescriptor.GetTypeOf(addr), dwType)); } uint concatTypeSize = minfo.WordSize * layout.WordsPerElement; TypeDescriptor concatType = TypeDescriptor.GetTypeOf( StdLogicVector._0s(concatTypeSize)); if (layout.WordsPerElement > 1) { TypeDescriptor[] stackTypes = new TypeDescriptor[layout.WordsPerElement + 1]; for (uint i = 0; i < layout.WordsPerElement; i++) { stackTypes[i] = dwType; } stackTypes[layout.WordsPerElement] = concatType; Emit(_iset.Concat().CreateStk((int)layout.WordsPerElement, stackTypes)); } TypeDescriptor elemTypeRaw = TypeDescriptor.GetTypeOf( StdLogicVector._0s((int)layout.ElementLayout.SizeInBits)); if (concatTypeSize != layout.ElementLayout.SizeInBits) { Emit(_iset.Convert().CreateStk(1, concatType, elemTypeRaw)); } TypeDescriptor elemType = layout.ElementLayout.LayoutedType; Emit(_iset.Convert().CreateStk(1, elemTypeRaw, elemType)); }
private void UpdateBindingMarshaling(YamlFunctionBinding fb, IMarshalInfo mi) { YamlBindingTransform xform; switch (mi) { case ArrayMarshalInfo ami: xform = new YamlArrayMarshalInfo( ) { Name = ami.ParameterName, Semantics = ami.Semantics, SubType = ami.ElementMarshalType, SizeParam = ami.SizeParam, }; break; case PrimitiveTypeMarshalInfo ptmi: xform = new YamlPrimitiveMarshalInfo( ) { Name = ptmi.ParameterName, Kind = ptmi.PrimitiveType, Semantics = ptmi.Semantics, }; break; case StringMarshalInfo smi: xform = new YamlStringMarshalInfo( ) { Name = smi.ParameterName, Kind = smi.DisposalKind, Semantics = smi.Semantics, }; break; default: throw new ArgumentException("Unknown marshal info"); } if (mi.Semantics == ParamSemantics.Return) { fb.ReturnTransform = xform; } else { fb.ParamTransforms.Add(xform); } }
private Unsigned ComputeConstAddress(Array array, long[] indices, uint nword) { 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; Unsigned addr = mms.BaseAddress; for (int i = 0; i < indices.Length; i++) { Unsigned offs = Unsigned.FromULong((ulong)indices[i] * layout.Strides[i], mms.Region.AddressWidth); addr += offs; } addr += Unsigned.FromUInt(nword, mms.Region.AddressWidth); addr = addr.Resize(mms.Region.AddressWidth); return(addr); }
/// <summary> /// Converts from measure "bits" to "words", depending on the platform-specific word size. /// </summary> /// <param name="numBits">number of bits</param> /// <param name="info">marshalling information</param> /// <returns>number of words</returns> private static ulong BitsToWords(long numBits, IMarshalInfo info) { return (ulong)((numBits + info.WordSize - 1) / info.WordSize); }
private void HandleLdelemFixA(XILSInstr xilsi) { Array array = (Array)xilsi.StaticOperand; var preds = RemapPreds(xilsi.Preds); 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; EmitIndexComputation(array); TypeDescriptor indexType = TypeDescriptor.GetTypeOf(mms.BaseAddress); TypeDescriptor dwType = minfo.GetRawWordType(); if (layout.WordsPerElement > 1) { Emit(_iset.Dup().CreateStk(1, indexType, indexType, indexType)); } for (uint i = 0; i < layout.WordsPerElement; i++) { Emit(_iset.RdMem(region).CreateStk(preds, 1, indexType, dwType)); if (i < layout.WordsPerElement - 1) { Emit(_iset.Swap().CreateStk(2, indexType, dwType, dwType, indexType)); if (minfo.UseStrongPow2Alignment) { if (i + 1 < layout.WordsPerElement - 1) { Emit(_iset.Dup().CreateStk(1, indexType, indexType, indexType)); } Unsigned inc = Unsigned.FromULong(i + 1, region.AddressWidth); Emit(_iset.LdConst(inc).CreateStk(0, indexType)); Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); } else { Unsigned inc = Unsigned.FromULong(1, region.AddressWidth); Emit(_iset.LdConst(inc).CreateStk(0, indexType)); Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType)); if (i + 1 < layout.WordsPerElement - 1) { Emit(_iset.Dup().CreateStk(1, indexType, indexType, indexType)); } } } } uint concatTypeSize = minfo.WordSize * layout.WordsPerElement; TypeDescriptor concatType = TypeDescriptor.GetTypeOf( StdLogicVector._0s(concatTypeSize)); if (layout.WordsPerElement > 1) { TypeDescriptor[] stackTypes = new TypeDescriptor[layout.WordsPerElement + 1]; for (uint i = 0; i < layout.WordsPerElement; i++) { stackTypes[i] = dwType; } stackTypes[layout.WordsPerElement] = concatType; Emit(_iset.Concat().CreateStk((int)layout.WordsPerElement, stackTypes)); } TypeDescriptor elemTypeRaw = TypeDescriptor.GetTypeOf( StdLogicVector._0s((int)layout.ElementLayout.SizeInBits)); if (concatTypeSize != layout.ElementLayout.SizeInBits) { Emit(_iset.Convert().CreateStk(1, concatType, elemTypeRaw)); } TypeDescriptor elemType = layout.ElementLayout.LayoutedType; Emit(_iset.Convert().CreateStk(1, elemTypeRaw, elemType)); }
/// <summary> /// Converts from measure "bits" to "words", depending on the platform-specific word size. /// </summary> /// <param name="numBits">number of bits</param> /// <param name="info">marshalling information</param> /// <returns>number of words</returns> private static ulong BitsToWords(long numBits, IMarshalInfo info) { return((ulong)((numBits + info.WordSize - 1) / info.WordSize)); }
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)); } } }
/// <summary> /// Computes a memory layout for a given type descriptor. /// </summary> /// <param name="td">type descriptor to layout</param> /// <param name="info">marshalling information</param> /// <returns>memory layout</returns> public static MemoryLayout Layout(TypeDescriptor td, IMarshalInfo info) { Type type = td.CILType; ISerializer ser = SLVSerializable.TryGetSerializer(type); if (ser != null) { object sample = td.GetSampleInstance(); return CreatePrimLayout(ser.Serialize(sample).Size, td, info); } if (ser == null && td.HasIntrinsicTypeOverride) throw new InvalidOperationException("Type " + type.Name + " has intrinsic type override but no serializer"); if (type.IsEnum) { return new EnumMemoryLayout(td, info); } if (type.IsArray) { td.AssertStatic(); TypeDescriptor elemTd = td.Element0Type; MemoryLayout elemLayout = Layout(elemTd, info); ulong subStride = elemLayout.SizeInBits; if (subStride == 0) { return new EmptyMemoryLayout(td) { Size = 0, SizeInBits = 0 }; } ulong[] strides = new ulong[type.GetArrayRank()]; ulong elemsPerWord = (ulong)info.WordSize / elemLayout.SizeInBits; ulong wordsPerElem = elemLayout.Size; if (elemsPerWord > 1) { if (info.UseArraySubWordAlignment) { if (info.UseArrayDimPow2Alignment) { elemsPerWord = MathExt.FloorPow2(elemsPerWord); subStride = info.WordSize / elemsPerWord; } } else { elemsPerWord = 1; } } ulong dimSize = (ulong)(int)td.TypeParams.Last(); ulong dimWords; if (elemsPerWord <= 1) { subStride = 0; if (info.UseArrayDimPow2Alignment) wordsPerElem = MathExt.CeilPow2(wordsPerElem); dimWords = wordsPerElem * dimSize; } else { wordsPerElem = 0; dimWords = (dimSize + elemsPerWord - 1) / elemsPerWord; } strides[strides.Length-1] = wordsPerElem; for (int i = strides.Length-2; i >= 0; i--) { if (info.UseArrayDimPow2Alignment) dimWords = MathExt.CeilPow2(dimWords); strides[i] = dimWords; dimSize = (ulong)(int)td.TypeParams[i]; dimWords *= dimSize; } return new ArrayMemoryLayout(td, info.WordSize, strides, subStride, (uint)elemsPerWord, (uint)wordsPerElem, elemLayout) { Size = dimWords, SizeInBits = dimWords * info.WordSize }; } if (type.IsValueType && !type.IsPrimitive) { StructMemoryLayout ml = new StructMemoryLayout(td); FieldInfo[] fields = type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); ulong offset = 0; foreach (FieldInfo field in fields) { TypeDescriptor fieldTd = td.GetFieldType(field); MemoryLayout fieldLayout = Layout(fieldTd, info); FieldLocation fieldLoc = new FieldLocation(field, fieldLayout, offset); ml.AddLocation(fieldLoc); offset += fieldLayout.Size; } ml.Size = offset; ml.SizeInBits = offset * info.WordSize; return ml; } throw new InvalidOperationException("Unable to create data layout for type " + type.Name); }
/// <summary> /// Computes a serialization of a value with respect to a specific marshaling information. /// </summary> /// <param name="value">value to serialize</param> /// <param name="minfo">marshalling information</param> /// <returns></returns> public static StdLogicVector[] Serialize(object value, IMarshalInfo minfo) { var layout = Layout(TypeDescriptor.GetTypeOf(value), minfo); return layout.SerializeInstance(value); }
private void HandleStelemFixA(XILSInstr xilsi) { Array array = (Array)xilsi.StaticOperand; var preds = RemapPreds(xilsi.Preds); 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; EmitIndexComputation(array); TypeDescriptor indexType = TypeDescriptor.GetTypeOf(mms.BaseAddress); TypeDescriptor elemType = layout.ElementLayout.LayoutedType; Emit(_iset.Swap().CreateStk(2, elemType, indexType, indexType, elemType)); TypeDescriptor rawElemType = TypeDescriptor.GetTypeOf( StdLogicVector._0s((long)layout.ElementLayout.SizeInBits)); if (!elemType.Equals(rawElemType)) { Emit(_iset.Convert().CreateStk(1, elemType, rawElemType)); } uint concatSize = layout.WordsPerElement * minfo.WordSize; TypeDescriptor concatType = TypeDescriptor.GetTypeOf( StdLogicVector._0s(concatSize)); if (!concatType.Equals(rawElemType)) { Emit(_iset.Convert().CreateStk(1, rawElemType, concatType)); } TypeDescriptor rawWordType = minfo.GetRawWordType(); int shiftSize = MathExt.CeilLog2(concatSize); if (layout.WordsPerElement > 1) { Emit(_iset.Swap().CreateStk(2, indexType, rawElemType, rawElemType, indexType)); Emit(_iset.Dup().CreateStk(1, indexType, indexType, indexType)); Emit(_iset.Dig(2).CreateStk(3, concatType, indexType, indexType, indexType, indexType, concatType)); Emit(_iset.Dup().CreateStk(1, concatType, concatType, concatType)); } for (uint i = 0; i < layout.WordsPerElement; i++) { Emit(_iset.Convert().CreateStk(1, concatType, rawWordType)); if (i < layout.WordsPerElement - 1) { Emit(_iset.Dig(2).CreateStk(3, indexType, concatType, rawWordType, concatType, rawWordType, indexType)); } else { Emit(_iset.Swap().CreateStk(2, indexType, rawWordType, rawWordType, indexType)); } Emit(_iset.WrMem(region).CreateStk(preds, 2, rawWordType, indexType)); if (i < layout.WordsPerElement - 1) { Unsigned shift = Unsigned.FromULong(minfo.WordSize, shiftSize); TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift); Emit(_iset.LdConst(shift).CreateStk(0, shiftType)); Emit(_iset.RShift().CreateStk(2, concatType, shiftType, concatType)); Emit(_iset.Swap().CreateStk(2, indexType, concatType, concatType, indexType)); if (minfo.UseStrongPow2Alignment) { if (i + 1 < layout.WordsPerElement) { Emit(_iset.Dup().CreateStk(1, indexType, indexType, indexType)); } Unsigned inc = Unsigned.FromULong(i + 1, region.AddressWidth); Emit(_iset.Or().CreateStk(2, indexType, indexType, indexType)); if (i + 1 < layout.WordsPerElement) { Emit(_iset.Dig(2).CreateStk(1, concatType, indexType, indexType, indexType, indexType, concatType)); Emit(_iset.Swap().CreateStk(2, concatType, indexType, indexType, concatType)); } } else { Unsigned inc = Unsigned.FromULong(1, region.AddressWidth); Emit(_iset.LdConst(inc).CreateStk(0, indexType)); Emit(_iset.Add().CreateStk(2, indexType, indexType, indexType)); Emit(_iset.Swap().CreateStk(2, concatType, indexType, indexType, concatType)); } } } }
/// <summary> /// Returns a type descriptor for describing a single word for the marshalling information. /// </summary> /// <param name="mi">marshalling information</param> /// <returns>descriptor of a single word</returns> public static TypeDescriptor GetRawWordType(this IMarshalInfo mi) { return(TypeDescriptor.GetTypeOf( StdLogicVector._0s(mi.WordSize))); }
internal MemoryRegion(IMarshalInfo marshalInfo) { Items = new List <MemoryMappedStorage>(); MarshalInfo = marshalInfo; }
/// <summary> /// Computes a serialization of a value with respect to a specific marshaling information. /// </summary> /// <param name="value">value to serialize</param> /// <param name="minfo">marshalling information</param> /// <returns></returns> public static StdLogicVector[] Serialize(object value, IMarshalInfo minfo) { var layout = Layout(TypeDescriptor.GetTypeOf(value), minfo); return(layout.SerializeInstance(value)); }
/// <summary> /// Computes a memory layout for a given type descriptor. /// </summary> /// <param name="td">type descriptor to layout</param> /// <param name="info">marshalling information</param> /// <returns>memory layout</returns> public static MemoryLayout Layout(TypeDescriptor td, IMarshalInfo info) { Type type = td.CILType; ISerializer ser = SLVSerializable.TryGetSerializer(type); if (ser != null) { object sample = td.GetSampleInstance(); return(CreatePrimLayout(ser.Serialize(sample).Size, td, info)); } if (ser == null && td.HasIntrinsicTypeOverride) { throw new InvalidOperationException("Type " + type.Name + " has intrinsic type override but no serializer"); } if (type.IsEnum) { return(new EnumMemoryLayout(td, info)); } if (type.IsArray) { td.AssertStatic(); TypeDescriptor elemTd = td.Element0Type; MemoryLayout elemLayout = Layout(elemTd, info); ulong subStride = elemLayout.SizeInBits; if (subStride == 0) { return(new EmptyMemoryLayout(td) { Size = 0, SizeInBits = 0 }); } ulong[] strides = new ulong[type.GetArrayRank()]; ulong elemsPerWord = (ulong)info.WordSize / elemLayout.SizeInBits; ulong wordsPerElem = elemLayout.Size; if (elemsPerWord > 1) { if (info.UseArraySubWordAlignment) { if (info.UseArrayDimPow2Alignment) { elemsPerWord = MathExt.FloorPow2(elemsPerWord); subStride = info.WordSize / elemsPerWord; } } else { elemsPerWord = 1; } } ulong dimSize = (ulong)(int)td.TypeParams.Last(); ulong dimWords; if (elemsPerWord <= 1) { subStride = 0; if (info.UseArrayDimPow2Alignment) { wordsPerElem = MathExt.CeilPow2(wordsPerElem); } dimWords = wordsPerElem * dimSize; } else { wordsPerElem = 0; dimWords = (dimSize + elemsPerWord - 1) / elemsPerWord; } strides[strides.Length - 1] = wordsPerElem; for (int i = strides.Length - 2; i >= 0; i--) { if (info.UseArrayDimPow2Alignment) { dimWords = MathExt.CeilPow2(dimWords); } strides[i] = dimWords; dimSize = (ulong)(int)td.TypeParams[i]; dimWords *= dimSize; } return(new ArrayMemoryLayout(td, info.WordSize, strides, subStride, (uint)elemsPerWord, (uint)wordsPerElem, elemLayout) { Size = dimWords, SizeInBits = dimWords * info.WordSize }); } if (type.IsValueType && !type.IsPrimitive) { StructMemoryLayout ml = new StructMemoryLayout(td); FieldInfo[] fields = type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); ulong offset = 0; foreach (FieldInfo field in fields) { TypeDescriptor fieldTd = td.GetFieldType(field); MemoryLayout fieldLayout = Layout(fieldTd, info); FieldLocation fieldLoc = new FieldLocation(field, fieldLayout, offset); ml.AddLocation(fieldLoc); offset += fieldLayout.Size; } ml.Size = offset; ml.SizeInBits = offset * info.WordSize; return(ml); } throw new InvalidOperationException("Unable to create data layout for type " + type.Name); }
private static MemoryLayout CreatePrimLayout(long numBits, TypeDescriptor type, IMarshalInfo info) { ulong numWords = BitsToWords(numBits, info); return(new PrimMemoryLayout(type, (int)info.WordSize) { Size = numWords, SizeInBits = (ulong)numBits }); }
private void HandleStelemFixAFixI(XILSInstr xilsi) { FixedArrayRef far = (FixedArrayRef)xilsi.StaticOperand; Array array = far.ArrayObj; long[] indices = far.Indices; var preds = RemapPreds(xilsi.Preds); 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; TypeDescriptor elemType = layout.ElementLayout.LayoutedType; TypeDescriptor rawElemType = TypeDescriptor.GetTypeOf( StdLogicVector._0s((long)layout.ElementLayout.SizeInBits)); if (!elemType.Equals(rawElemType)) { Emit(_iset.Convert().CreateStk(1, elemType, rawElemType)); } uint concatSize = layout.WordsPerElement * minfo.WordSize; TypeDescriptor concatType = TypeDescriptor.GetTypeOf( StdLogicVector._0s(concatSize)); if (!concatType.Equals(rawElemType)) { Emit(_iset.Convert().CreateStk(1, rawElemType, concatType)); } TypeDescriptor rawWordType = minfo.GetRawWordType(); int shiftSize = MathExt.CeilLog2(concatSize); if (layout.WordsPerElement > 1) { Emit(_iset.Dup().CreateStk(1, concatType, concatType, concatType)); } Unsigned shift = Unsigned.FromULong(minfo.WordSize, shiftSize); TypeDescriptor shiftType = TypeDescriptor.GetTypeOf(shift); TypeDescriptor dwType = minfo.GetRawWordType(); for (uint i = 0; i < layout.WordsPerElement; i++) { Unsigned addr = ComputeConstAddress(array, indices, i); Emit(_iset.LdConst(addr) .CreateStk(0, TypeDescriptor.GetTypeOf(addr))); Emit(_iset.WrMem(region) .CreateStk(preds, 2, dwType, TypeDescriptor.GetTypeOf(addr))); if (i < layout.WordsPerElement - 1) { Emit(_iset.LdConst(shift).CreateStk(0, shiftType)); Emit(_iset.RShift().CreateStk(2, concatType, shiftType, concatType)); if (i + 1 < layout.WordsPerElement - 1) { Emit(_iset.Dup().CreateStk(1, concatType, concatType, concatType)); } } } }
private static MemoryLayout CreatePrimLayout(long numBits, TypeDescriptor type, IMarshalInfo info) { ulong numWords = BitsToWords(numBits, info); return new PrimMemoryLayout(type, (int)info.WordSize) { Size = numWords, SizeInBits = (ulong)numBits }; }