Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 /// <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;
 }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
 /// <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))));
        }
Beispiel #9
0
 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);
        }
Beispiel #12
0
        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!");
        }
Beispiel #13
0
 public override string ToValueString() => $"{Pointer} as {Type.ToTypeString()}";
Beispiel #14
0
        private Register AllocateRegister(Type type)
        {
            var ctx = GetCurrentProcContext();

            return(new Register(type, ctx.RegisterCount++));
        }
Beispiel #15
0
 /// <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;
 }
Beispiel #16
0
 /// <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;
 }
Beispiel #17
0
 public override string ToString() => $"{Type.ToTypeString()} {ToValueString()}";
Beispiel #18
0
 /// <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);
 }
Beispiel #19
0
 public override string ToValueString() => $"{Type.ToTypeString()} " +
 $"[{string.Join(", ", Values.Select(v => v.ToValueString()))}]";
Beispiel #20
0
 /// <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;
 }
Beispiel #21
0
 public override PtrValue OffsetBy(int amount, Type newType) =>
 new NativePtrValue(new IntPtr(Pointer.ToInt64() + amount), newType);
Beispiel #22
0
 public NativePtrValue(IntPtr pointer, Type baseType)
     : base(baseType)
 {
     Pointer = pointer;
 }
Beispiel #23
0
 public abstract PtrValue OffsetBy(int amount, Type newBaseType);
Beispiel #24
0
 public PtrValue(Type baseType)
 {
     BaseType = baseType;
 }