/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertLong(long src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(Signed))) { return(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(Unsigned))) { return(Unsigned.FromBigInt(new System.Numerics.BigInteger(src), UFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(SFix))) { return(SFix.FromSigned(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth), SFix.GetFormat(dstType).FracWidth)); } else if (dstType.CILType.Equals(typeof(StdLogicVector))) { return(StdLogicVector.FromLong(src, StdLogicVector.GetLength(dstType))); } else { return(ConvertLong(src, dstType.CILType)); } }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertUFix(UFix src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(UFix))) { return(src.Resize(UFix.GetFormat(dstType).IntWidth, UFix.GetFormat(dstType).FracWidth)); } else if (dstType.CILType.Equals(typeof(Unsigned))) { return(src.UnsignedValue.Resize(UFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(StdLogicVector))) { return(src.SLVValue[StdLogicVector.GetLength(dstType) - 1, 0]); } else { return(ConvertUFix(src, dstType.CILType)); } }
private void ProcessAddSub(XILSInstr i) { var preds = RemapPreds(i.Preds); if (IsFixed(i.OperandTypes[0]) && IsFixed(i.OperandTypes[1])) { if (IsSFix(i.OperandTypes[0]) && IsUFix(i.OperandTypes[1])) { var sfixt = MakeUFixSFix(i.OperandTypes[1]); Convert(preds, i.OperandTypes[1], sfixt); var inew = i.Command.CreateStk(2, i.OperandTypes[0], sfixt, i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsUFix(i.OperandTypes[0]) && IsSFix(i.OperandTypes[1])) { var sfixt = MakeUFixSFix(i.OperandTypes[0]); Swap(preds); Convert(i.OperandTypes[0], sfixt); Swap(); var inew = i.Command.CreateStk(2, sfixt, i.OperandTypes[1], i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsSFix(i.OperandTypes[0]) && IsSFix(i.OperandTypes[1])) { var fmt0 = SFix.GetFormat(i.OperandTypes[0]); var fmt1 = SFix.GetFormat(i.OperandTypes[1]); int iw = Math.Max(fmt0.IntWidth, fmt1.IntWidth); int fw = Math.Max(fmt0.FracWidth, fmt1.FracWidth); var smp = SFix.FromDouble(0.0, iw, fw); var to = TypeDescriptor.GetTypeOf(smp); var fmte = SFix.GetFormat(to); if (!fmte.Equals(fmt1)) { Convert(preds, i.OperandTypes[1], to); var inew = i.Command.CreateStk(2, i.OperandTypes[0], to, i.ResultTypes[0]); ProcessAddSub(inew); } else if (!fmte.Equals(fmt0)) { Swap(preds); Convert(i.OperandTypes[0], to); Swap(); var inew = i.Command.CreateStk(2, to, i.OperandTypes[1], i.ResultTypes[0]); ProcessAddSub(inew); } else { dynamic s0 = i.OperandTypes[0].GetSampleInstance(); dynamic s1 = i.OperandTypes[1].GetSampleInstance(); object r = s0 + s1; var rtype = TypeDescriptor.GetTypeOf(r); Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype)); if (!rtype.Equals(i.ResultTypes[0])) { Convert(rtype, i.ResultTypes[0]); } } } else if (IsUFix(i.OperandTypes[0]) && IsUFix(i.OperandTypes[1]) && IsSFix(i.ResultTypes[0])) { var sfixt = MakeUFixSFix(i.OperandTypes[1]); Convert(preds, i.OperandTypes[1], sfixt); var inew = i.Command.CreateStk(2, i.OperandTypes[0], sfixt, i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsUFix(i.OperandTypes[0]) && IsUFix(i.OperandTypes[1])) { var fmt0 = UFix.GetFormat(i.OperandTypes[0]); var fmt1 = UFix.GetFormat(i.OperandTypes[1]); int iw = Math.Max(fmt0.IntWidth, fmt1.IntWidth); int fw = Math.Max(fmt0.FracWidth, fmt1.FracWidth); var smp = UFix.FromDouble(0.0, iw, fw); var to = TypeDescriptor.GetTypeOf(smp); var fmte = UFix.GetFormat(to); if (!fmte.Equals(fmt1)) { Convert(preds, i.OperandTypes[1], to); var inew = i.Command.CreateStk(2, i.OperandTypes[0], to, i.ResultTypes[0]); ProcessAddSub(inew); } else if (!fmte.Equals(fmt0)) { Swap(preds); Convert(preds, i.OperandTypes[0], to); Swap(); var inew = i.Command.CreateStk(2, to, i.OperandTypes[1], i.ResultTypes[0]); ProcessAddSub(inew); } else { dynamic s0 = i.OperandTypes[0].GetSampleInstance(); dynamic s1 = i.OperandTypes[1].GetSampleInstance(); object r = s0 + s1; var rtype = TypeDescriptor.GetTypeOf(r); Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype)); if (!rtype.Equals(i.ResultTypes[0])) { Convert(rtype, i.ResultTypes[0]); } } } else { Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], i.ResultTypes[0])); } } else if (IsFloat(i.OperandTypes[0]) && IsFloat(i.OperandTypes[1])) { dynamic s0 = i.OperandTypes[0].GetSampleInstance(); dynamic s1 = i.OperandTypes[1].GetSampleInstance(); object r = s0 + s1; var rtype = TypeDescriptor.GetTypeOf(r); Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], rtype)); if (!rtype.Equals(i.ResultTypes[0])) { Convert(rtype, i.ResultTypes[0]); } } else if (IsFixed(i.OperandTypes[0]) && IsFloat(i.OperandTypes[1]) && IsFixed(i.ResultTypes[0])) { Convert(preds, i.OperandTypes[1], i.OperandTypes[0]); var inew = i.Command.CreateStk(2, i.OperandTypes[0], i.OperandTypes[0], i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsFloat(i.OperandTypes[0]) && IsFixed(i.OperandTypes[1]) && IsFixed(i.ResultTypes[0])) { Swap(preds); Convert(i.OperandTypes[0], i.OperandTypes[1]); Swap(); var inew = i.Command.CreateStk(2, i.OperandTypes[1], i.OperandTypes[0], i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsFixed(i.OperandTypes[0]) && IsFloat(i.OperandTypes[1]) && IsFloat(i.ResultTypes[0])) { Swap(preds); Convert(i.OperandTypes[0], i.OperandTypes[1]); Swap(); var inew = i.Command.CreateStk(2, i.OperandTypes[1], i.OperandTypes[0], i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsFloat(i.OperandTypes[0]) && IsFixed(i.OperandTypes[1]) && IsFloat(i.ResultTypes[0])) { Convert(preds, i.OperandTypes[1], i.OperandTypes[0]); var inew = i.Command.CreateStk(2, i.OperandTypes[0], i.OperandTypes[0], i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsSLV(i.OperandTypes[1])) { var signedType = SFix.MakeType(StdLogicVector.GetLength(i.OperandTypes[1]), 0); Convert(preds, i.OperandTypes[1], signedType); var inew = i.Command.CreateStk(2, i.OperandTypes[0], signedType, i.ResultTypes[0]); ProcessAddSub(inew); } else if (IsSLV(i.OperandTypes[0])) { var signedType = SFix.MakeType(StdLogicVector.GetLength(i.OperandTypes[0]), 0); Swap(preds); Convert(i.OperandTypes[0], signedType); Swap(); var inew = i.Command.CreateStk(2, signedType, i.OperandTypes[1], i.ResultTypes[0]); ProcessAddSub(inew); } else { Emit(i.Command.CreateStk(preds, 2, i.OperandTypes[0], i.OperandTypes[1], i.ResultTypes[0])); } }