Example #1
0
        public static void F2I(EmitterContext context)
        {
            OpCodeFArith op = (OpCodeFArith)context.CurrOp;

            IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2);

            if (intType == IntegerType.U64)
            {
                context.Config.GpuAccessor.Log("Unimplemented 64-bits F2I.");

                return;
            }

            bool isSmallInt = intType <= IntegerType.U16;

            FPType floatType = (FPType)op.RawOpCode.Extract(10, 2);

            bool isSignedInt = op.RawOpCode.Extract(12);
            bool negateB     = op.RawOpCode.Extract(45);
            bool absoluteB   = op.RawOpCode.Extract(49);

            if (isSignedInt)
            {
                intType |= IntegerType.S8;
            }

            Operand srcB = context.FPAbsNeg(GetSrcB(context, floatType), absoluteB, negateB);

            switch (op.RoundingMode)
            {
            case RoundingMode.ToNearest:
                srcB = context.FPRound(srcB);
                break;

            case RoundingMode.TowardsNegativeInfinity:
                srcB = context.FPFloor(srcB);
                break;

            case RoundingMode.TowardsPositiveInfinity:
                srcB = context.FPCeiling(srcB);
                break;

            case RoundingMode.TowardsZero:
                srcB = context.FPTruncate(srcB);
                break;
            }

            if (!isSignedInt)
            {
                // Negative float to uint cast is undefined, so we clamp
                // the value before conversion.
                srcB = context.FPMaximum(srcB, ConstF(0));
            }

            srcB = isSignedInt
                ? context.FPConvertToS32(srcB)
                : context.FPConvertToU32(srcB);

            if (isSmallInt)
            {
                int min = (int)GetIntMin(intType);
                int max = (int)GetIntMax(intType);

                srcB = isSignedInt
                    ? context.IClampS32(srcB, Const(min), Const(max))
                    : context.IClampU32(srcB, Const(min), Const(max));
            }

            Operand dest = GetDest(context);

            context.Copy(dest, srcB);

            // TODO: CC.
        }