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)); }
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)); }
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); }
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); }
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); }
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); }