Beispiel #1
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));
        }
Beispiel #2
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 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);
        }