Example #1
0
        private static void EmitCrc32Optimized64(ArmEmitterContext context, bool castagnoli)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            long mu         = castagnoli ? 0x0DEA713F1 : 0x1F7011641; // mu' = floor(x^64/P(x))'
            long polynomial = castagnoli ? 0x105EC76F0 : 0x1DB710641; // P'(x) << 1

            Operand crc  = GetIntOrZR(context, op.Rn);
            Operand data = GetIntOrZR(context, op.Rm);

            crc  = context.VectorInsert(context.VectorZero(), crc, 0);
            data = context.VectorInsert(context.VectorZero(), data, 0);

            Operand tmp = context.AddIntrinsic(Intrinsic.X86Pxor, crc, data);
            Operand res = context.AddIntrinsic(Intrinsic.X86Pslldq, tmp, Const(4));

            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, res, X86GetScalar(context, mu), Const(0));
            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, tmp, X86GetScalar(context, polynomial), Const(0));

            tmp = context.AddIntrinsic(Intrinsic.X86Pxor, tmp, res);
            tmp = context.AddIntrinsic(Intrinsic.X86Psllq, tmp, Const(32));

            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, tmp, X86GetScalar(context, mu), Const(1));
            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, tmp, X86GetScalar(context, polynomial), Const(0));

            SetIntOrZR(context, op.Rd, context.VectorExtract(OperandType.I32, tmp, 2));
        }
Example #2
0
        private static void EmitCrc32Optimized(ArmEmitterContext context, bool castagnoli, int bitsize)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            long mu         = castagnoli ? 0x0DEA713F1 : 0x1F7011641; // mu' = floor(x^64/P(x))'
            long polynomial = castagnoli ? 0x105EC76F0 : 0x1DB710641; // P'(x) << 1

            Operand crc  = GetIntOrZR(context, op.Rn);
            Operand data = GetIntOrZR(context, op.Rm);

            crc = context.VectorInsert(context.VectorZero(), crc, 0);

            switch (bitsize)
            {
            case 8: data = context.VectorInsert8(context.VectorZero(), data, 0); break;

            case 16: data = context.VectorInsert16(context.VectorZero(), data, 0); break;

            case 32: data = context.VectorInsert(context.VectorZero(), data, 0); break;
            }

            Operand tmp = context.AddIntrinsic(Intrinsic.X86Pxor, crc, data);

            tmp = context.AddIntrinsic(Intrinsic.X86Psllq, tmp, Const(64 - bitsize));
            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, tmp, X86GetScalar(context, mu), Const(0));
            tmp = context.AddIntrinsic(Intrinsic.X86Pclmulqdq, tmp, X86GetScalar(context, polynomial), Const(0));

            if (bitsize < 32)
            {
                crc = context.AddIntrinsic(Intrinsic.X86Pslldq, crc, Const((64 - bitsize) / 8));
                tmp = context.AddIntrinsic(Intrinsic.X86Pxor, tmp, crc);
            }

            SetIntOrZR(context, op.Rd, context.VectorExtract(OperandType.I32, tmp, 2));
        }
Example #3
0
        private static void EmitCrc32Call(ArmEmitterContext context, int size, bool c)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            Operand n = GetIntOrZR(context, op.Rn);
            Operand m = GetIntOrZR(context, op.Rm);

            Operand d = EmitCrc32(context, n, m, size, c);

            SetIntOrZR(context, op.Rd, d);
        }
Example #4
0
        private static void EmitCrc32Call(ArmEmitterContext context, string name)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            Operand n = GetIntOrZR(context, op.Rn);
            Operand m = GetIntOrZR(context, op.Rm);

            Operand d = context.Call(typeof(SoftFallback).GetMethod(name), n, m);

            SetIntOrZR(context, op.Rd, d);
        }
Example #5
0
        private static void EmitCrc32Call(ArmEmitterContext context, Delegate dlg)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            Operand n = GetIntOrZR(context, op.Rn);
            Operand m = GetIntOrZR(context, op.Rm);

            Operand d = context.Call(dlg, n, m);

            SetIntOrZR(context, op.Rd, d);
        }
Example #6
0
        private static void EmitDiv(ArmEmitterContext context, bool unsigned)
        {
            OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;

            // If Rm == 0, Rd = 0 (division by zero).
            Operand n = GetIntOrZR(context, op.Rn);
            Operand m = GetIntOrZR(context, op.Rm);

            Operand divisorIsZero = context.ICompareEqual(m, Const(m.Type, 0));

            Operand lblBadDiv = Label();
            Operand lblEnd    = Label();

            context.BranchIfTrue(lblBadDiv, divisorIsZero);

            if (!unsigned)
            {
                // If Rn == INT_MIN && Rm == -1, Rd = INT_MIN (overflow).
                bool is32Bits = op.RegisterSize == RegisterSize.Int32;

                Operand intMin = is32Bits ? Const(int.MinValue) : Const(long.MinValue);
                Operand minus1 = is32Bits ? Const(-1)           : Const(-1L);

                Operand nIsIntMin = context.ICompareEqual(n, intMin);
                Operand mIsMinus1 = context.ICompareEqual(m, minus1);

                Operand lblGoodDiv = Label();

                context.BranchIfFalse(lblGoodDiv, context.BitwiseAnd(nIsIntMin, mIsMinus1));

                SetAluDOrZR(context, intMin);

                context.Branch(lblEnd);

                context.MarkLabel(lblGoodDiv);
            }

            Operand d = unsigned
                ? context.DivideUI(n, m)
                : context.Divide(n, m);

            SetAluDOrZR(context, d);

            context.Branch(lblEnd);

            context.MarkLabel(lblBadDiv);

            SetAluDOrZR(context, Const(op.GetOperandType(), 0));

            context.MarkLabel(lblEnd);
        }