private static TypeDescriptor MakeUFixSFix(TypeDescriptor t) { var fmt = UFix.GetFormat(t); var smp = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth); return(TypeDescriptor.GetTypeOf(smp)); }
public static string Convert_SLV_UFix(string value, TypeDescriptor ttype) { FixFormat fmt = UFix.GetFormat(ttype); return("lv_to_ufixed(" + value + ", sc_fixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (0))"); //return "sc_ufixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (sc_bigint<" + fmt.TotalWidth + ">(" + value + "))"; }
/// <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 ConvertUnsigned(Unsigned src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(Unsigned))) { return(src.Resize(UFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(UFix))) { return(UFix.FromUnsigned(src.Resize(UFix.GetFormat(dstType).TotalWidth), UFix.GetFormat(dstType).FracWidth)); } else { return(ConvertUnsigned(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 ConvertDouble(double src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(SFix))) { var fmt = SFix.GetFormat(dstType); return(SFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth)); } else if (dstType.CILType.Equals(typeof(UFix))) { var fmt = UFix.GetFormat(dstType); return(UFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth)); } else { throw new NotImplementedException(); } }
/// <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)); } }
/// <summary> /// Returns a sequence of adminissible result types, given instruction operand types. /// </summary> /// <param name="instr">XIL instruction</param> /// <param name="operandTypes">operand types</param> /// <returns>admissible result types</returns> public static IEnumerable <TypeDescriptor> GetDefaultResultTypes(this XILInstr instr, TypeDescriptor[] operandTypes) { switch (instr.Name) { case InstructionCodes.Abs: if (operandTypes[0].CILType.Equals(typeof(float)) || operandTypes[0].CILType.Equals(typeof(double)) || operandTypes[0].CILType.Equals(typeof(int)) || operandTypes[0].CILType.Equals(typeof(long)) || operandTypes[0].CILType.Equals(typeof(sbyte)) || operandTypes[0].CILType.Equals(typeof(short))) { yield return(operandTypes[0]); } else if (operandTypes[0].CILType.Equals(typeof(double))) { yield return(typeof(double)); } else if (operandTypes[0].CILType.Equals(typeof(SFix))) { var fmt = SFix.GetFormat(operandTypes[0]); var ssample = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth); yield return(TypeDescriptor.GetTypeOf(ssample)); var usample = UFix.FromDouble(0.0, fmt.IntWidth, fmt.FracWidth); yield return(TypeDescriptor.GetTypeOf(usample)); } else if (operandTypes[0].CILType.Equals(typeof(UFix))) { yield return(operandTypes[0]); } else { throw new NotSupportedException("Operand type not supported"); } break; case InstructionCodes.Add: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 + o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.And: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 & o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Barrier: case InstructionCodes.BranchIfFalse: case InstructionCodes.BranchIfTrue: yield break; case InstructionCodes.Ceil: case InstructionCodes.Floor: case InstructionCodes.SinCos: if (operandTypes[0].CILType.Equals(typeof(float)) || operandTypes[0].CILType.Equals(typeof(double))) { yield return(operandTypes[0]); } else { throw new NotSupportedException(); } break; case InstructionCodes.Cos: case InstructionCodes.Sin: if (operandTypes[0].CILType.Equals(typeof(float)) || operandTypes[0].CILType.Equals(typeof(double))) { yield return(operandTypes[0]); } else if (operandTypes[0].CILType.Equals(typeof(UFix)) || operandTypes[0].CILType.Equals(typeof(SFix))) { var fmt = operandTypes[0].GetFixFormat(); // computation works for at most 26 fractional bits double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth)); double yinc = 1.0 - Math.Cos(xinc); int fw = -MathExt.FloorLog2(yinc); // Xilinx Cordic doesn't like more than 48 result bits if (fw > 48) { fw = 48; } while (fw >= 0) { yield return(SFix.MakeType(2, fw)); --fw; } } else { throw new NotSupportedException(); } break; case InstructionCodes.ScSin: case InstructionCodes.ScCos: case InstructionCodes.ScSinCos: if (operandTypes[0].CILType.Equals(typeof(float)) || operandTypes[0].CILType.Equals(typeof(double))) { yield return(operandTypes[0]); } else if (operandTypes[0].CILType.Equals(typeof(UFix)) || operandTypes[0].CILType.Equals(typeof(SFix))) { var fmt = operandTypes[0].GetFixFormat(); // computation works for at most 26 fractional bits double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth)); double yinc = 1.0 - Math.Cos(xinc); int fw = -MathExt.FloorLog2(yinc); // Xilinx Cordic doesn't like more than 48 result bits if (fw > 48) { fw = 48; } while (fw >= 0) { yield return(SFix.MakeType(2, fw)); --fw; } } else { throw new NotSupportedException(); } break; case InstructionCodes.Sqrt: if (operandTypes[0].CILType.Equals(typeof(float)) || operandTypes[0].CILType.Equals(typeof(double))) { yield return(operandTypes[0]); } else if (operandTypes[0].CILType.Equals(typeof(UFix))) { var fmt = UFix.GetFormat(operandTypes[0]); int iw = (fmt.IntWidth + 1) / 2; yield return(UFix.MakeType(iw, fmt.TotalWidth - iw)); } else if (operandTypes[0].CILType.Equals(typeof(SFix))) { var fmt = SFix.GetFormat(operandTypes[0]); int iw = fmt.IntWidth / 2; yield return(UFix.MakeType(iw, fmt.TotalWidth - iw - 1)); } else if (operandTypes[0].CILType.Equals(typeof(Unsigned))) { var fmt = UFix.GetFormat(operandTypes[0]); int iw = (fmt.IntWidth + 1) / 2; yield return(Unsigned.MakeType(iw)); } else if (operandTypes[0].CILType.Equals(typeof(Signed))) { var fmt = SFix.GetFormat(operandTypes[0]); int iw = fmt.IntWidth / 2; yield return(Unsigned.MakeType(iw)); } else { throw new NotImplementedException(); } break; case InstructionCodes.Cmp: throw new NotImplementedException(); case InstructionCodes.Concat: { var v1 = (StdLogicVector)operandTypes[0].GetSampleInstance(); var v2 = (StdLogicVector)operandTypes[1].GetSampleInstance(); var c = v1.Concat(v2); yield return(TypeDescriptor.GetTypeOf(c)); } break; case InstructionCodes.Convert: throw new NotImplementedException(); case InstructionCodes.Dig: case InstructionCodes.Dup: case InstructionCodes.Swap: throw new NotSupportedException(); case InstructionCodes.Div: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero); object r = o1 / o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.ExitMarshal: case InstructionCodes.Goto: case InstructionCodes.Nop: case InstructionCodes.Pop: case InstructionCodes.Return: case InstructionCodes.StelemFixA: case InstructionCodes.StelemFixAFixI: case InstructionCodes.StoreVar: case InstructionCodes.WrMem: case InstructionCodes.WrMemFix: case InstructionCodes.WrPort: yield break; case InstructionCodes.Mod2: { var fmt = operandTypes[0].GetFixFormat(); if (fmt == null) { throw new NotSupportedException("mod2 is only supported for fixed-point types"); } for (int iw = 2; iw <= fmt.IntWidth; iw++) { yield return(new FixFormat(fmt.IsSigned, iw, fmt.FracWidth).ToType()); } } break; case InstructionCodes.DivQF: case InstructionCodes.ExtendSign: case InstructionCodes.Ld0: case InstructionCodes.LdelemFixA: case InstructionCodes.LdelemFixAFixI: case InstructionCodes.LdMemBase: case InstructionCodes.LShift: case InstructionCodes.RdMem: case InstructionCodes.RdMemFix: case InstructionCodes.RShift: case InstructionCodes.Sign: case InstructionCodes.SliceFixI: throw new NotImplementedException(); case InstructionCodes.IsEq: case InstructionCodes.IsGt: case InstructionCodes.IsGte: case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsNEq: yield return(typeof(bool)); break; case InstructionCodes.LdConst: yield return(TypeDescriptor.GetTypeOf(instr.Operand)); break; case InstructionCodes.LoadVar: { var lit = (IStorableLiteral)instr.Operand; yield return(lit.Type); } break; case InstructionCodes.Max: case InstructionCodes.Min: yield return(operandTypes[0]); break; case InstructionCodes.Mul: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 * o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Neg: { dynamic o1 = operandTypes[0].GetSampleInstance(); object r = -o1; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Not: { dynamic o1 = operandTypes[0].GetSampleInstance(); object r = !o1; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Or: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 | o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.RdPort: { var port = (ISignalOrPortDescriptor)instr.Operand; yield return(port.ElementType); } break; case InstructionCodes.Rem: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero); object r = o1 % o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Rempow2: { dynamic o1 = operandTypes[0].GetSampleInstance(); int n = (int)instr.Operand; object r = MathExt.Rempow2((dynamic)o1, n); yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Select: yield return(operandTypes[1]); break; case InstructionCodes.Slice: yield return(typeof(StdLogicVector)); break; case InstructionCodes.Sub: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 - o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; case InstructionCodes.Xor: { dynamic o1 = operandTypes[0].GetSampleInstance(); dynamic o2 = operandTypes[1].GetSampleInstance(); object r = o1 ^ o2; yield return(TypeDescriptor.GetTypeOf(r)); } break; default: throw new NotImplementedException(); } }
/// <summary> /// Returns a type which is able to represent either of two given types without loss of precision /// </summary> /// <param name="td1">first given type</param> /// <param name="td2">second given type</param> /// <returns></returns> private static TypeDescriptor GetCommonType(TypeDescriptor td1, TypeDescriptor td2) { if (td1.Equals(td2)) { return(td1); } if (IsSFix(td1) && IsUFix(td2)) { var fmt1 = SFix.GetFormat(td1); var fmt2 = UFix.GetFormat(td2); return(SFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth + 1), Math.Max(fmt1.FracWidth, fmt2.FracWidth))); } else if (IsUFix(td1) && IsSFix(td2)) { return(GetCommonType(td2, td1)); } else if (IsSFix(td1) && IsSFix(td2)) { var fmt1 = SFix.GetFormat(td1); var fmt2 = SFix.GetFormat(td2); return(SFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth), Math.Max(fmt1.FracWidth, fmt2.FracWidth))); } else if (IsUFix(td1) && IsUFix(td2)) { var fmt1 = UFix.GetFormat(td1); var fmt2 = UFix.GetFormat(td2); return(UFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth), Math.Max(fmt1.FracWidth, fmt2.FracWidth))); } else if (IsSigned(td1)) { var fmt = SFix.GetFormat(td1); var td1x = SFix.MakeType(fmt.IntWidth, fmt.FracWidth); return(GetCommonType(td1x, td2)); } else if (IsSigned(td2)) { return(GetCommonType(td2, td1)); } else if (IsUnsigned(td1)) { var fmt = UFix.GetFormat(td1); var td1x = UFix.MakeType(fmt.IntWidth, fmt.FracWidth); return(GetCommonType(td1x, td2)); } else if (IsUnsigned(td2)) { return(GetCommonType(td2, td1)); } else { throw new NotSupportedException( "Cannot determine common type between " + td1.ToString() + " and " + td2.ToString()); } }
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])); } }
private InstructionDependency[] Convert(InstructionDependency[] preds, TypeDescriptor from, TypeDescriptor to) { if (from.Equals(to)) { // nothing to do return(preds); } else if (IsSFix(from) && IsUFix(to)) { var fromFmt = SFix.GetFormat(from); var toFmt = UFix.GetFormat(to); int interIW = toFmt.IntWidth + 1; int interFW = toFmt.FracWidth; if (interIW != fromFmt.IntWidth || interFW != fromFmt.FracWidth) { var interType = SFix.MakeType(interIW, interFW); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to)); } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } return(new InstructionDependency[0]); } else if (IsUFix(from) && IsSFix(to)) { var fromFmt = UFix.GetFormat(from); var toFmt = SFix.GetFormat(to); int interIW = toFmt.IntWidth - 1; int interFW = toFmt.FracWidth; if (interIW != fromFmt.IntWidth || interFW != fromFmt.FracWidth) { var interType = UFix.MakeType(interIW, interFW); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to)); } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } return(new InstructionDependency[0]); } else if (IsSLV(from)) { int wfrom = TypeLowering.Instance.GetWireWidth(from); int wto = TypeLowering.Instance.GetWireWidth(to); if (wfrom == wto) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } else { var interType = StdLogicVector.MakeType(wto); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Convert(interType, to); } return(new InstructionDependency[0]); } else if (IsSLV(to)) { int wfrom = TypeLowering.Instance.GetWireWidth(from); int wto = TypeLowering.Instance.GetWireWidth(to); if (wfrom == wto) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } else { var interType = StdLogicVector.MakeType(wfrom); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Convert(interType, to); } return(new InstructionDependency[0]); } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); return(new InstructionDependency[0]); } }