Exemple #1
0
 public static void AssertCanAssignImplicitly(this Type type, Type other)
 {
     if (!type.CanAssignImplicitly(other))
     {
         throw new TypeMismatchException(type.ToString(), other.ToString());
     }
 }
Exemple #2
0
        public static Register MakeRegisterWithCorrectSize(this Type type, Register64 intRegister, XmmRegister floatRegister)
        {
            if (!type.IsIntegerRegisterType())
            {
                return(floatRegister);
            }

            switch (type.SizeOf())
            {
            case 8:
                return(intRegister);

            case 4:
                return((Register32)intRegister);

            case 2:
                return((Register16)intRegister);

            case 1:
                return((Register8)intRegister);

            default:
                throw new NotImplementedException($"Proper register for type {type} (size {type.SizeOf()}) has not been implemented yet");
            }
        }
Exemple #3
0
 public ExpressionResult(Type valueType, Register64 ptr, int offset, Segment segment = Segment.DS)
 {
     ValueType = valueType ?? throw new ArgumentNullException(nameof(valueType));
     Ptr       = ptr;
     Offset    = offset;
     Segment   = segment;
     Kind      = ResultKind.Pointer;
 }
Exemple #4
0
 public static Register MakeRegisterWithCorrectSize(this Type type, Register register)
 {
     if (register.FloatingPoint)
     {
         return(register);
     }
     return(MakeRegisterWithCorrectSize(type, register.AsR64(), default));
 }
Exemple #5
0
        public static Register OtherVolatileFloatRegister(this Type targetType, params Register[] occupiedRegisters)
        {
            if (targetType == null)
            {
                throw new ArgumentNullException(nameof(targetType));
            }
            if (occupiedRegisters.Length >= VolatileFloatRegisters.Length)
            {
                throw new ArgumentException("No registers left", nameof(occupiedRegisters));
            }

            return(VolatileFloatRegisters.First(vol => occupiedRegisters.All(occ => !occ.IsSameRegister(vol))));
        }
Exemple #6
0
        public ExpressionResult(Type valueType, Register64 ptr, byte ptrMul, int offsetFlat = 0, Segment segment = Segment.DS)
        {
            if (ptrMul != 1 && ptrMul != 2 && ptrMul != 4 && ptrMul != 8)
            {
                throw new ArgumentOutOfRangeException("The multiplicative offset may only be 1, 2, 4 or 8");
            }

            ValueType = valueType ?? throw new ArgumentNullException(nameof(valueType));
            Ptr       = ptr;
            OffsetMul = ptrMul;
            Offset    = offsetFlat;
            Segment   = segment;
            Kind      = ResultKind.Pointer3;
        }
Exemple #7
0
        public static bool CanAssignImplicitly(this Type type, Type source)
        {
            if (type.ChildRelation != source.ChildRelation) // cannot do weird stuff implicitly
            {
                return(false);
            }

            if (type.ChildRelation == Type.WrappingType.None) // if they are the same type, or can be promoted to the same type, we are good
            {
                return(type.PrimitiveType == source.PrimitiveType || CanPromote(type.PrimitiveType, source.PrimitiveType));
            }

            return(CanAssignImplicitly(type.Child, source.Child)); // unwrap pointer/array/... and check type underneath
        }
        public void GenerateMoveTo(Register target, Type targetType, CodeGen codeGen, ILinkingInfo fixer, bool isExplicitCast = false)
        {
            if (!isExplicitCast && !targetType.CanAssignImplicitly(ValueType))
            {
                throw new TypeMismatchException(targetType.ToString(), ValueType.ToString());
            }
            if (!target.FloatingPoint && target.BitSize / 8 != targetType.SizeOf())
            {
                throw new ArgumentException($"Value of type {targetType} can not be moved to register {target}");
            }

            if (targetType == ValueType)
            {
                GenerateMoveTo(target, codeGen, fixer);
                return;
            }

            if (targetType.SizeOf() < ValueType.SizeOf())
            {
                throw new ArgumentException($"Cannot narrow type from {ValueType} to {targetType} without a cast", nameof(targetType));
            }

            var signed = targetType.IsSignedInteger();

            switch (Kind)
            {
            case ResultKind.Value:
                GenerateUpgradeToValue(target, codeGen, signed);
                return;

            case ResultKind.Pointer:
                GenerateUpgradeToPointer(target, codeGen, signed);
                return;

            case ResultKind.Pointer2:
                GenerateUpgradeToPointer2(target, codeGen, signed);
                return;

            case ResultKind.Pointer3:
                GenerateUpgradeToPointer3(target, codeGen, signed);
                return;

            case ResultKind.Offset:
                GenerateUpgradeToOffset(target, codeGen, fixer, signed);
                return;

            default:
                throw new NotImplementedException($"{nameof(ExpressionResult)}: {nameof(GenerateMoveTo)} has not implemented kind: {Kind}");
            }
        }
Exemple #9
0
        /// <summary>
        ///     Returns if a value of this type should be stored in general purpose (int) registers, or SSE2 registers (e.g. float,
        ///     double)
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsIntegerRegisterType(this Type type)
        {
            if (type.ChildRelation != Type.WrappingType.None)
            {
                return(true);
            }

            switch (type.PrimitiveType)
            {
            case "float":
            case "double":
                return(false);
            }

            return(true);
        }
Exemple #10
0
        public static int SizeOf(this Type type)
        {
            switch (type.ChildRelation)
            {
            case Type.WrappingType.None:
                return(SizeOfPrimitiveType(type.PrimitiveType));

            case Type.WrappingType.PointerOf:
                return(8);

            case Type.WrappingType.ArrayOf:
                return(8);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #11
0
        public static bool IsSignedInteger(this Type type)
        {
            if (type.ChildRelation != Type.WrappingType.None)
            {
                return(false);
            }

            switch (type.PrimitiveType)
            {
            case "long":
            case "int":
            case "short":
            case "sbyte":
                return(true);
            }

            return(false);
        }
Exemple #12
0
        public ExpressionResult(Type valueType, Register valueRegister)
        {
            if (valueType == null)
            {
                throw new ArgumentNullException(nameof(valueType));
            }
            if (valueRegister == null)
            {
                throw new ArgumentNullException(nameof(valueRegister));
            }
            if (valueType.IsIntegerRegisterType() == valueRegister.FloatingPoint)
            {
                throw new ArgumentException("Type does not match register");
            }
            if (!valueRegister.FloatingPoint && valueType.SizeOf() != valueRegister.BitSize / 8)
            {
                throw new ArgumentException($"Bad register for type: {valueRegister} {valueType}");
            }

            ValueType = valueType;
            Value     = valueRegister;
            Kind      = ResultKind.Value;
        }
Exemple #13
0
 public ExpressionResult(Type valueType, Action <ILinkingInfo, CodeGen> offsetFixup)
 {
     ValueType   = valueType ?? throw new ArgumentNullException(nameof(valueType));
     OffsetFixup = offsetFixup ?? throw new ArgumentNullException(nameof(offsetFixup));
     Kind        = ResultKind.Offset;
 }
Exemple #14
0
 public Register GetOccupiedOrVolatile(Type type)
 {
Exemple #15
0
 public void ChangeTypeUnsafe(Type newTypeUnsafe) => ValueType = newTypeUnsafe;