Ejemplo n.º 1
0
        public void GenerateAssign(Register source, CodeGen codeGen, ILinkingInfo fixer)
        {
            switch (Kind)
            {
            case ResultKind.Value:
                GenerateAssignValue(source, codeGen);
                return;

            case ResultKind.Pointer:
                GenerateAssignPointer(source, codeGen);
                return;

            case ResultKind.Pointer2:
                GenerateAssignPointer2(source, codeGen);
                return;

            case ResultKind.Pointer3:
                GenerateAssignPointer3(source, codeGen);
                return;

            case ResultKind.Offset:
                GenerateAssignOffset(source, codeGen, fixer);
                return;

            default:
                throw new NotImplementedException($"{nameof(ExpressionResult)}: {nameof(GenerateAssign)} has not implemented kind: {Kind}");
            }
        }
        public void GenerateMoveTo(Register target, CodeGen codeGen, ILinkingInfo fixer)
        {
            switch (Kind)
            {
            case ResultKind.Value:
                GenerateMoveToValue(target, codeGen);
                return;

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

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

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

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

            default:
                throw new NotImplementedException($"{nameof(ExpressionResult)}: {nameof(GenerateMoveTo)} has not implemented kind: {Kind}");
            }
        }
Ejemplo n.º 3
0
        public void Store(ExpressionResult expressionResult, CodeGen codeGen, ILinkingInfo linkingInfo)
        {
            if (!IsRegister)
            {
                var tempRegister = IsIntegerType ? (Register)TempIntRegister : TempFloatRegister;
                expressionResult.GenerateMoveTo(tempRegister, expressionResult.ValueType, codeGen, linkingInfo);

                if (IsIntegerType)
                {
                    codeGen.MovToDereferenced(Register64.RSP, tempRegister, StackOffset, Segment.SS);
                }
                else
                {
                    codeGen.MovqToDereferenced(Register64.RSP, tempRegister, StackOffset, Segment.SS);
                }
            }
            else
            {
                expressionResult.GenerateMoveTo(
                    expressionResult.ValueType.MakeRegisterWithCorrectSize(Register),
                    expressionResult.ValueType,
                    codeGen,
                    linkingInfo
                    );
            }
        }
Ejemplo n.º 4
0
        public static void InsertCode(this CodeGen codeGen, ILinkingInfo myFixer, long position, Action <CodeGen> insertAction)
        {
            var insertCode = new CodeGen();

            insertAction(insertCode);
            myFixer.Insert(position, insertCode.GetBufferSpan().Length);
            codeGen.Insert(insertCode.GetBufferSpan(), position);
        }
Ejemplo n.º 5
0
        public Compiler(ICompilerStore nodeCompilers, IFactory <ILinkingInfo> linkingInfoFactory, IEnumerable <FunctionImport> imports, IEnumerable <FunctionDeclaration> declarations)
        {
            _nodeCompilers      = nodeCompilers ?? throw new ArgumentNullException(nameof(nodeCompilers));
            _linkingInfoFactory = linkingInfoFactory ?? throw new ArgumentNullException(nameof(linkingInfoFactory));
            _imports            = imports ?? throw new ArgumentNullException(nameof(imports));
            _declarations       = declarations ?? throw new ArgumentNullException(nameof(declarations));

            LinkingInfo = _linkingInfoFactory.Create();
        }
Ejemplo n.º 6
0
        private static ExpressionResult CastIntToFloat(
            Type sourceType,
            Type targetType,
            Register targetRegister,
            ExpressionResult source,
            CodeGen codeGen,
            ILinkingInfo linkingInfo
            )
        {
            var sourceTypeSize = sourceType.SizeOf();
            var tempSource     = Register.IntRegisterFromSize(sourceTypeSize, 0);

            source.GenerateMoveTo(tempSource, Constants.LongType, codeGen, linkingInfo);

            if (targetType == Constants.FloatType)
            {
                switch (sourceTypeSize)
                {
                case 8:
                    codeGen.CvtSi2Ss(targetRegister.AsFloat(), tempSource.AsR64());
                    break;

                case 4:
                    codeGen.CvtSi2Ss(targetRegister.AsFloat(), tempSource.AsR32());
                    break;

                default:
                    ThrowBadCast(sourceType, targetType);
                    break;
                }
            }

            if (targetType == Constants.DoubleType)
            {
                switch (sourceTypeSize)
                {
                case 8:
                    codeGen.CvtSi2Sd(targetRegister.AsFloat(), tempSource.AsR64());
                    break;

                case 4:
                    codeGen.CvtSi2Sd(targetRegister.AsFloat(), tempSource.AsR32());
                    break;

                default:
                    ThrowBadCast(sourceType, targetType);
                    break;
                }
            }
            else
            {
                ThrowBadCast(sourceType, targetType);
            }

            return(new ExpressionResult(targetType, targetRegister));
        }
Ejemplo n.º 7
0
 public static void InsertCode(
     this CodeGen codeGen,
     ILinkingInfo myFixer,
     long position,
     ReadOnlySpan <byte> data,
     ILinkingInfo otherFixer = null
     )
 {
     myFixer.Insert(position, data.Length);
     otherFixer?.CopyTo(myFixer, position);
     codeGen.Insert(data, position);
 }
Ejemplo n.º 8
0
        private static ExpressionResult CastFloatToInt(
            Type sourceType,
            Type targetType,
            Register targetRegister,
            ExpressionResult source,
            CodeGen codeGen,
            ILinkingInfo linkingInfo
            )
        {
            source.GenerateMoveTo(XmmRegister.XMM0, sourceType, codeGen, linkingInfo);
            if (sourceType == Constants.FloatType)
            {
                switch (targetType.SizeOf())
                {
                case 8:
                    codeGen.CvtSs2Si(targetRegister.AsR64(), XmmRegister.XMM0);
                    break;

                case 4:
                    codeGen.CvtSs2Si(targetRegister.AsR32(), XmmRegister.XMM0);
                    break;

                default:
                    ThrowBadCast(sourceType, targetType);
                    break;
                }
            }

            if (sourceType == Constants.DoubleType)
            {
                switch (targetType.SizeOf())
                {
                case 8:
                    codeGen.CvtSd2Si(targetRegister.AsR64(), XmmRegister.XMM0);
                    break;

                case 4:
                    codeGen.CvtSd2Si(targetRegister.AsR32(), XmmRegister.XMM0);
                    break;

                default:
                    ThrowBadCast(sourceType, targetType);
                    break;
                }
            }
            else
            {
                ThrowBadCast(sourceType, targetType);
            }

            return(new ExpressionResult(targetType, targetRegister));
        }
        private void GenerateMoveToOffset(Register register, CodeGen codeGen, ILinkingInfo fixer)
        {
            if (!register.FloatingPoint)
            {
                // mov target, [12345678]
                codeGen.MovFromDereferenced4(register, Constants.DummyOffsetInt);
            }
            else
            {
                // movq target, [12345678]
                codeGen.MovqFromDereferenced4(register.AsFloat(), Constants.DummyOffsetInt);
            }

            OffsetFixup(fixer, codeGen);
        }
Ejemplo n.º 10
0
        private void GenerateAssignOffset(Register register, CodeGen codeGen, ILinkingInfo fixer)
        {
            if (!register.FloatingPoint)
            {
                // mov [12345678], register
                codeGen.MovToDereferenced4(Constants.DummyOffsetInt, register);
            }
            else
            {
                // movq [12345678], register
                codeGen.MovqToDereferenced4(Constants.DummyOffsetInt, register.AsFloat());
            }

            OffsetFixup(fixer, codeGen);
        }
Ejemplo n.º 11
0
        private static bool CompileIntegerDivision(CodeGen codeGen, ILinkingInfo linkingInfo, Type type, Register leftReg, ExpressionResult rightExpr)
        {
            var rightReg = type.OtherVolatileIntRegister(leftReg, Register64.RAX, Register64.RDX);

            rightExpr.GenerateMoveTo(rightReg, type, codeGen, linkingInfo);

            if (!leftReg.IsSameRegister(Register64.RAX))
            {
                codeGen.Mov(Register64.RAX, leftReg.AsR64());
            }

            var typeIsByte   = type.SizeOf() == 1;
            var typeIsSigned = type.IsSignedInteger();

            if (typeIsByte)
            {
                if (typeIsSigned)
                {
                    codeGen.Movsx(Register64.RAX, Register8.AL);
                }
                else
                {
                    codeGen.Movzx(Register64.RAX, Register8.AL);
                }
            }
            else
            {
                codeGen.Xor(Register64.RDX, Register64.RDX);
                if (typeIsSigned)
                {
                    codeGen.Test(Register64.RAX, Register64.RAX);
                    codeGen.Jns(CodeGenExtensions.InstructionLength(gen => gen.Not(Register64.RDX)));
                    codeGen.Not(Register64.RDX);
                }
            }

            if (type.IsSignedInteger())
            {
                codeGen.Idiv(rightReg);
            }
            else
            {
                codeGen.Div(rightReg);
            }
            return(typeIsByte);
        }
        //todo: bug: rework this redundant shit
        private void GenerateUpgradeToOffset(Register target, CodeGen codeGen, ILinkingInfo fixer, bool signed)
        {
            if (!target.FloatingPoint && ValueType.IsIntegerRegisterType())
            {
                var bitize = Math.Min(target.BitSize, ValueType.SizeOf() * 8);
                if (bitize == 32)
                {
                    if (signed)
                    {
                        codeGen.MovsxdFromDereferenced4(target.AsR64(), Offset, Segment);
                    }
                    else
                    {
                        codeGen.MovFromDereferenced4(target, Offset, Segment);
                    }
                }
                else
                {
                    if (signed)
                    {
                        codeGen.MovsxFromDereferenced4(target, ValueType.SizeOf() == 1, Offset);
                    }
                    else
                    {
                        codeGen.MovzxFromDereferenced4(target, ValueType.SizeOf() == 1, Offset);
                    }
                }
            }
            else if (target.FloatingPoint && Value.FloatingPoint)
            {
                codeGen.CvtSs2SdFromDereferenced4(target, Offset, Segment);
            }
            else
            {
                throw new NotImplementedException();
            }

            OffsetFixup(fixer, codeGen);
        }
Ejemplo n.º 13
0
        public void DereferenceFromRegister(
            CodeGen codeGen,
            Register source,
            ILinkingInfo fixer,
            GenericBrotherAction brotherAction,
            GenericToDrefAction drefAction,
            GenericToDref2Action dref2Action,
            GenericToDref3Action dref3Action,
            GenericToDref4Action dref4Action
            )
        {
            switch (Kind)
            {
            case ResultKind.Value:
                DereferenceFromRegister(brotherAction, source);
                return;

            case ResultKind.Pointer:
                DereferenceFromRegister(drefAction, source);
                return;

            case ResultKind.Pointer2:
                DereferenceFromRegister(dref2Action, source);
                return;

            case ResultKind.Pointer3:
                DereferenceFromRegister(dref3Action, source);
                return;

            case ResultKind.Offset:
                DereferenceFromRegister(codeGen, source, dref4Action, fixer);
                return;

            default:
                throw new NotImplementedException($"{nameof(ExpressionResult)}: {nameof(GenerateMoveTo)} has not implemented kind: {Kind}");
            }
        }
Ejemplo n.º 14
0
 public static void TestTo(this ExpressionResult source, Register other, CodeGen codeGen, ILinkingInfo fixer)
 {
     source.DereferenceFromRegister(
         codeGen,
         other,
         fixer,
         codeGen.Test,
         codeGen.TestToDereferenced,
         codeGen.TestToDereferenced2,
         codeGen.TestToDereferenced3,
         codeGen.TestToDereferenced4
         );
 }
Ejemplo n.º 15
0
        public static void ImulTo(this ExpressionResult source, Register target, CodeGen codeGen, ILinkingInfo fixer)
        {
            if (target.BitSize == 8)
            {
                throw new ArgumentException($"{nameof(ImulTo)} does not work with 8 bit types");
            }

            source.DereferenceToRegister(
                target,
                codeGen,
                fixer,
                codeGen.Imul,
                codeGen.ImulFromDereferenced,
                codeGen.ImulFromDereferenced2,
                codeGen.ImulFromDereferenced3,
                codeGen.ImulFromDereferenced4
                );
        }
Ejemplo n.º 16
0
 public static void AddTo(this ExpressionResult source, Register target, CodeGen codeGen, ILinkingInfo fixer)
 {
     source.DereferenceToRegister(
         target,
         codeGen,
         fixer,
         codeGen.Add,
         codeGen.AddFromDereferenced,
         codeGen.AddFromDereferenced2,
         codeGen.AddFromDereferenced3,
         codeGen.AddFromDereferenced4
         );
 }
Ejemplo n.º 17
0
 private void DereferenceFromRegister(CodeGen codeGen, Register source, GenericToDref4Action action, ILinkingInfo fixer)
 {
     action(Offset, source);
     OffsetFixup(fixer, codeGen);
 }
        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}");
            }
        }
 private void DereferenceToRegister(Register target, CodeGen codeGen, GenericFromDref4Action action, ILinkingInfo fixer)
 {
     action(target, Offset);
     OffsetFixup(fixer, codeGen);
 }
Ejemplo n.º 20
0
 public static void SubsdTo(this ExpressionResult source, Register target, CodeGen codeGen, ILinkingInfo fixer)
 {
     source.DereferenceToRegister(
         target,
         codeGen,
         fixer,
         (targetRegister, sourceRegister) => codeGen.Subsd(targetRegister.AsFloat(), sourceRegister.AsFloat()),
         codeGen.SubsdFromDereferenced,
         codeGen.SubsdFromDereferenced2,
         codeGen.SubsdFromDereferenced3,
         codeGen.SubsdFromDereferenced4
         );
 }