public MemoryMapperTransactionSite(InlineMemoryMapper mapper, Component host, FixedArrayRef array) : base(host) { _mapper = mapper; _array = array; // work-around, since concept is currently not working: It is not possible to decide "on-the-fly" whether // write access is required or not, since transaction site needs to be established immediately. IndicateWriteAccess(true); }
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)); }
/// <summary> /// Creates an instruction which stores an element to a fixed array at a fixed index /// </summary> /// <param name="far">array and index specification</param> public XILInstr StelemFixAFixI(FixedArrayRef far) { return(new XILInstr(InstructionCodes.StelemFixAFixI, far)); }
/// <summary> /// Creates an instruction which loads an element from a fixed array /// </summary> /// <param name="far">array specification</param> public XILInstr LdelemFixA(FixedArrayRef far) { return(new XILInstr(InstructionCodes.LdelemFixA, far)); }
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)); } } } }
public void VisitArrayRef(ArrayRef arrayRef) { LiteralReference lr = arrayRef.ArrayExpr as LiteralReference; object arrayObj; if (lr == null || !lr.ReferencedObject.IsConst(out arrayObj)) { throw new NotSupportedException("Array references must be fixed (referenced array must be known in advance)!"); } Array array = arrayObj as Array; if (array == null) { throw new InvalidOperationException("Not an array"); } ELiteralAcceptMode saveMode = _litMode; _litMode = ELiteralAcceptMode.Read; FixedArrayRef far = arrayRef.AsFixed(); if (!far.IndicesConst) { foreach (Expression index in arrayRef.Indices) { index.Accept(this); } } _litMode = saveMode; int[] preds; switch (_litMode) { case ELiteralAcceptMode.Read: if (far.IndicesConst) { ArrayMod amod1 = new ArrayMod(array, far.Indices); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod3 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_storesInCurBB.Get(amod3)) .Union(_readsInCurBB.Get(amod3)) .Distinct() .ToArray(); _readsInCurBB.Add(amod1, NextInstructionIndex); _readsInCurBB.Add(amod3, NextInstructionIndex); Emit(ISet.LdelemFixAFixI(far), preds, 0, arrayRef.Type); } else { ArrayMod amod1 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod2)) .Distinct() .ToArray(); _readsInCurBB.Add(amod1, NextInstructionIndex); Emit(ISet.LdelemFixA(far), preds, arrayRef.Indices.Length, arrayRef.Type); } break; case ELiteralAcceptMode.Write: if (far.IndicesConst) { ArrayMod amod1 = new ArrayMod(array, far.Indices); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod3 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod3)) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod1)) .Union(_readsInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod3)) .Distinct() .ToArray(); _storesInCurBB.Add(amod1, NextInstructionIndex); _storesInCurBB.Add(amod3, NextInstructionIndex); Emit(ISet.StelemFixAFixI(far), preds, 1); } else { ArrayMod amod1 = new ArrayMod(array, ArrayMod.EMode.UnknownIndex); ArrayMod amod2 = new ArrayMod(array, ArrayMod.EMode.AnyIndex); preds = _storesInCurBB.Get(amod1) .Union(_storesInCurBB.Get(amod2)) .Union(_readsInCurBB.Get(amod1)) .Union(_readsInCurBB.Get(amod2)) .Distinct() .ToArray(); _storesInCurBB.Add(amod1, NextInstructionIndex); Emit(ISet.StelemFixA(far), preds, 1 + arrayRef.Indices.Length); } break; } }
public int TransformFunction(FunctionCall expr) { FunctionSpec fspec = expr.Callee as FunctionSpec; if (fspec == null) { throw new NotSupportedException(); } IntrinsicFunction ifun = fspec.IntrinsicRep; if (ifun == null) { throw new NotSupportedException(); } switch (ifun.Action) { case IntrinsicFunction.EAction.Convert: { // only first child should be evaluated, following children are conversion arguments. // These will be implicitly defined by the result type of the instruction expr.Children[0].Accept(this); ExtractCILIndex(expr); var cparams = (CastParams)ifun.Parameter; Emit(ISet.Convert(cparams.Reinterpret), expr, 1, expr.ResultType); } return(0); case IntrinsicFunction.EAction.Sign: expr.Children[0].Accept(this); ExtractCILIndex(expr); Emit(ISet.Sign(), expr, 1, expr.ResultType); return(0); case IntrinsicFunction.EAction.Resize: expr.Children[0].Accept(this); Emit(ISet.Convert(), expr, 1, expr.ResultType); ExtractCILIndex(expr); return(0); case IntrinsicFunction.EAction.Slice: if (expr.Children.Length == 3) { expr.Children[0].Accept(this); expr.Children[1].Accept(this); expr.Children[2].Accept(this); Emit(ISet.Slice(), expr, 3, expr.ResultType); } else { expr.Children[0].Accept(this); var range = (Range)ifun.Parameter; Emit(ISet.SliceFixI(range), expr, 1, expr.ResultType); } return(0); case IntrinsicFunction.EAction.Abs: expr.Children[0].Accept(this); Emit(ISet.Abs(), expr, 1, expr.ResultType); return(0); case IntrinsicFunction.EAction.Sqrt: expr.Children[0].Accept(this); Emit(ISet.Sqrt(), expr, 1, expr.ResultType); return(0); case IntrinsicFunction.EAction.GetArrayElement: { var aex = expr.Children[0]; var alr = (LiteralReference)aex; var alit = alr.ReferencedObject; var arr = (Array)aex.ResultType.GetSampleInstance(); var far = new FixedArrayRef(alit, arr); expr.Children[1].Accept(this); Emit(ISet.LdelemFixA(far), expr, 1, expr.ResultType); } return(0); case IntrinsicFunction.EAction.XILOpCode: { foreach (var child in expr.Children) { child.Accept(this); } var opcode = (XILInstr)ifun.Parameter; Emit(opcode, expr, expr.Children.Length, expr.ResultType.Unpick()); } return(0); case IntrinsicFunction.EAction.TupleSelect: { int item = (int)ifun.Parameter; var lr = expr.Children[0] as LiteralReference; if (lr == null) { throw new NotSupportedException("TupleSelect must refer to a literal"); } var tuple = lr.ReferencedObject as Variable; if (tuple == null) { throw new NotSupportedException("TupleSelect must refer to a local variable"); } var itemVars = Unpick(tuple); var itemLr = new LiteralReference(itemVars[item]); TransformLiteralReference(itemLr); } return(0); default: throw new NotImplementedException(); } }