/// <summary> /// Adds a new <see cref="Instr.Cast"/>. /// </summary> /// <param name="target">The target <see cref="Type"/> to cast the <see cref="Value"/> to.</param> /// <param name="value">The <see cref="Value"/> to cast.</param> /// <returns>The casted <see cref="Value"/>.</returns> public Value Cast(Type target, Value value) { var resultReg = AllocateRegister(target); AddInstr(new Instr.Cast(resultReg, target, value)); return(resultReg); }
/// <summary> /// Defines a new parameter in the current procedure. /// </summary> /// <param name="type">The <see cref="Type"/> of the parameter.</param> /// <returns>The read-only <see cref="Value"/> of the new parameter.</returns> public Value DefineParameter(Type type) { var reg = AllocateRegister(type); CurrentProc.Parameters.Add(reg); return(reg); }
/// <summary> /// Adds a new <see cref="Extern"/> symbol definition to the <see cref="Assembly"/>. /// </summary> /// <param name="name">The name of the external symbol.</param> /// <param name="type">The <see cref="Type"/> of the external symbol.</param> /// <param name="linkName">The actual linked symbol name that the linker will search for.</param> /// <param name="path">The path to the binary containing the external symbol.</param> /// <returns>The <see cref="Value"/> referring to the external symbol.</returns> public Value DefineExtern(string name, Type type, string linkName, string path) { var external = new Extern(name, type, linkName, path); Assembly.Externals.Add(external); return(external); }
/// <summary> /// Initializes a new <see cref="Extern"/>. /// </summary> /// <param name="name">The name of the external symbol.</param> /// <param name="type">The <see cref="Type"/> of the external symbol.</param> /// <param name="linkName">The actual linked symbol name that the linker will search for.</param> /// <param name="path">The path of the binary the symbol originates from.</param> public Extern(string name, Type type, string linkName, string?path) { Name = name; Type = type; LinkName = linkName; Path = path; }
/// <summary> /// Adds a new <see cref="Global"/> symbol definition to the <see cref="Assembly"/>. /// </summary> /// <param name="name">The name of the global symbol.</param> /// <param name="type">The <see cref="Type"/> of the global symbol.</param> /// <returns>The <see cref="Value"/> referring to the global symbol.</returns> public Value DefineGlobal(string name, Type type) { var global = new Global(name, type); Assembly.Globals.Add(global); return(global); }
/// <summary> /// Adds a new <see cref="Instr.Alloc"/>. /// </summary> /// <param name="type">The <see cref="Type"/> to allocate space for.</param> /// <returns>The pointer to the allocated space.</returns> public Value Alloc(Type type) { var ptrType = new Type.Ptr(type); var resultReg = AllocateRegister(ptrType); AddInstr(new Instr.Alloc(resultReg)); return(resultReg); }
/// <summary> /// Initializes a new <see cref="Int"/>. /// </summary> /// <param name="type">The exact integer <see cref="Type"/>.</param> /// <param name="value">The integer value.</param> public Int(Type.Int type, BigInt value) { if (value < type.MinValue || value > type.MaxValue) { throw new ArgumentOutOfRangeException(nameof(type), "The integer type is too small to store the given value!"); } Type = type; Value = value; }
/// <summary> /// Writes out an array initialization. /// </summary> /// <param name="builder">The <see cref="Builder"/> to build the initialization in.</param> /// <param name="elementType">The element <see cref="Type"/> in the array.</param> /// <param name="values">The <see cref="Value"/>s to initialize array elements to.</param> /// <returns>The pointer <see cref="Value"/> to the allocated and initialized array.</returns> public static Value InitArray(this Builder builder, Type elementType, params Value[] values) { var arrayLen = values.Length; var arrayType = new Type.Array(elementType, arrayLen); int index = 0; return(InitArray( builder, arrayType, values.Select(v => new KeyValuePair <int, Value>(index++, v)))); }
public static Type AccessedSubtype(Type type, int index) { if (!(type is Type.Ptr ptrTy && ptrTy.Subtype is Struct structTy)) { throw new ArgumentException("The accessed type must be a pointer to a struct type!", nameof(type)); } if (structTy.Fields.Count <= index) { throw new ArgumentOutOfRangeException(nameof(index)); } return(new Type.Ptr(structTy.Fields[index])); }
/// <summary> /// Writes out a struct initialization. /// </summary> /// <param name="builder">The <see cref="Builder"/> to build the initialization in.</param> /// <param name="structType">The struct <see cref="Type"/> to initialize.</param> /// <param name="fieldValues">The pairs of field index and field <see cref="Value"/> to initialize to.</param> /// <returns>The pointer <see cref="Value"/> to the allocated and initialized struct.</returns> public static Value InitStruct(this Builder builder, Type structType, IEnumerable <KeyValuePair <int, Value> > fieldValues) { if (!(structType is Struct)) { throw new ArgumentException("The type of a struct initialization must be a struct type!", nameof(structType)); } var structPtr = builder.Alloc(structType); foreach (var(idx, value) in fieldValues) { var fieldPtr = builder.ElementPtr(structPtr, idx); builder.Store(fieldPtr, value); } return(structPtr); }
/// <summary> /// Writes out an array initialization. /// </summary> /// <param name="builder">The <see cref="Builder"/> to build the initialization in.</param> /// <param name="arrayType">The array <see cref="Type"/> to initialize.</param> /// <param name="arrayValues">The pairs of field index and field <see cref="Value"/> to initialize to.</param> /// <returns>The pointer <see cref="Value"/> to the allocated and initialized array.</returns> public static Value InitArray(this Builder builder, Type arrayType, IEnumerable <KeyValuePair <int, Value> > arrayValues) { if (!(arrayType is Type.Array at)) { throw new ArgumentException("The type of a array initialization must be an array type!", nameof(arrayType)); } var arrayValuePtr = builder.Alloc(arrayType); var arrayPtr = builder.Cast(new Type.Ptr(at.Subtype), arrayValuePtr); foreach (var(idx, value) in arrayValues) { var fieldPtr = builder.Add(arrayPtr, Type.I32.NewValue(idx)); builder.Store(fieldPtr, value); } return(arrayValuePtr); }
public static Type CommonArithmeticType(Type left, Type right) { if (left is Type.Int) { if (!left.Equals(right)) { throw new ArgumentException("Operand type mismatch!"); } return(left); } // NOTE: We expect pointer to be on the left if (left is Type.Ptr p && right is Type.Int) { return(p); } throw new ArgumentException("No common arithmetic type for types!"); }
public override string ToValueString() => $"{Pointer} as {Type.ToTypeString()}";
private Register AllocateRegister(Type type) { var ctx = GetCurrentProcContext(); return(new Register(type, ctx.RegisterCount++)); }
/// <summary> /// Initializes a new <see cref="Register"/>. /// </summary> /// <param name="type">The <see cref="Type"/> this register stores.</param> /// <param name="index">The index of the <see cref="Register"/>.</param> public Register(Type type, int index) { Type = type; Index = index; }
/// <summary> /// Initializes a new <see cref="Array"/>. /// </summary> /// <param name="type">The array <see cref="Type"/>.</param> /// <param name="values">The <see cref="Value"/>s of the array.</param> public Array(Type type, IValueList <Value> values) { Type = type; Values = values; }
public override string ToString() => $"{Type.ToTypeString()} {ToValueString()}";
/// <summary> /// Initializes a new <see cref="Global"/>. /// </summary> /// <param name="name">The name of the global symbol.</param> /// <param name="type">The <see cref="Type"/> of the global symbol.</param> public Global(string name, Type type) { Name = name; Type = new Type.Ptr(type); }
public override string ToValueString() => $"{Type.ToTypeString()} " + $"[{string.Join(", ", Values.Select(v => v.ToValueString()))}]";
/// <summary> /// Initializes a new <see cref="Struct"/>. /// </summary> /// <param name="type">The <see cref="Type"/> os the struct.</param> /// <param name="values">The list of <see cref="Value"/>s.</param> public Struct(Type type, IValueList <Value> values) { Type = type; Values = values; }
public override PtrValue OffsetBy(int amount, Type newType) => new NativePtrValue(new IntPtr(Pointer.ToInt64() + amount), newType);
public NativePtrValue(IntPtr pointer, Type baseType) : base(baseType) { Pointer = pointer; }
public abstract PtrValue OffsetBy(int amount, Type newBaseType);
public PtrValue(Type baseType) { BaseType = baseType; }