Skip to content

Commit ecd8499

Browse files
committed
BitOperations are now used for native performance of certain WASM instructions when the target framework supports it.
1 parent 2b69476 commit ecd8499

11 files changed

+135
-12
lines changed

WebAssembly/Instructions/Int32CountLeadingZeroes.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int32CountLeadingZeroes()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo leadingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.LeadingZeroCount), new[] { typeof(uint) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be Int32.
2634
context.ValidateStack(OpCode.Int32CountLeadingZeroes, WebAssemblyValueType.Int32);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, leadingZeroCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountLeadingZeroes, (helper, c) =>
2940
{
3041
var result = context.CheckedExportsBuilder.DefineMethod(
@@ -80,6 +91,7 @@ internal sealed override void Compile(CompilationContext context)
8091

8192
return result;
8293
}
83-
]);
94+
]);
95+
#endif
8496
}
8597
}

WebAssembly/Instructions/Int32CountOneBits.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int32CountOneBits()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo popCount = typeof(BitOperations).GetMethod(nameof(BitOperations.PopCount), new[] { typeof(uint) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be Int32.
2634
context.ValidateStack(OpCode.Int32CountOneBits, WebAssemblyValueType.Int32);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, popCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountOneBits, CreateHelper]);
2940
}
3041

@@ -71,7 +82,7 @@ internal static MethodBuilder CreateHelper(HelperMethod helper, CompilationConte
7182
il.Emit(OpCodes.Ldc_I4_S, 24);
7283
il.Emit(OpCodes.Shr_Un);
7384
il.Emit(OpCodes.Ret);
74-
7585
return result;
86+
#endif
7687
}
7788
}

WebAssembly/Instructions/Int32CountTrailingZeroes.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int32CountTrailingZeroes()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo trailingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.TrailingZeroCount), new[] { typeof(uint) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be this.
2634
context.ValidateStack(OpCode.Int32CountTrailingZeroes, WebAssemblyValueType.Int32);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, trailingZeroCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountTrailingZeroes, (helper, c) =>
2940
{
3041
var result = context.CheckedExportsBuilder.DefineMethod(
@@ -49,5 +60,6 @@ internal sealed override void Compile(CompilationContext context)
4960
return result;
5061
}
5162
]);
63+
#endif
5264
}
5365
}

WebAssembly/Instructions/Int32RotateLeft.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,13 +24,20 @@ public Int32RotateLeft()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo rotateLeft = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateLeft), new[] { typeof(uint), typeof(int) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
var stack = context.Stack;
2634

2735
context.PopStackNoReturn(OpCode.Int32RotateLeft, WebAssemblyValueType.Int32, WebAssemblyValueType.Int32);
2836
stack.Push(WebAssemblyValueType.Int32);
2937

38+
#if NETCOREAPP3_0_OR_GREATER
39+
context.Emit(OpCodes.Call, rotateLeft);
40+
#else
3041
context.Emit(OpCodes.Call, context[HelperMethod.Int32RotateLeft, (helper, c) =>
3142
{
3243
var builder = c.CheckedExportsBuilder.DefineMethod(
@@ -60,5 +71,6 @@ internal sealed override void Compile(CompilationContext context)
6071
return builder;
6172
}
6273
]);
74+
#endif
6375
}
6476
}

WebAssembly/Instructions/Int32RotateRight.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,13 +24,20 @@ public Int32RotateRight()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo rotateRight = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateRight), new[] { typeof(uint), typeof(int) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
var stack = context.Stack;
2634

2735
context.PopStackNoReturn(OpCode.Int32RotateRight, WebAssemblyValueType.Int32, WebAssemblyValueType.Int32);
2836
stack.Push(WebAssemblyValueType.Int32);
2937

38+
#if NETCOREAPP3_0_OR_GREATER
39+
context.Emit(OpCodes.Call, rotateRight);
40+
#else
3041
context.Emit(OpCodes.Call, context[HelperMethod.Int32RotateRight, (helper, c) =>
3142
{
3243
var builder = c.CheckedExportsBuilder.DefineMethod(
@@ -60,5 +71,6 @@ internal sealed override void Compile(CompilationContext context)
6071
return builder;
6172
}
6273
]);
74+
#endif
6375
}
6476
}

WebAssembly/Instructions/Int64CountLeadingZeroes.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int64CountLeadingZeroes()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo leadingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.LeadingZeroCount), new[] { typeof(ulong) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be Int64.
2634
context.ValidateStack(OpCode.Int64CountLeadingZeroes, WebAssemblyValueType.Int64);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, leadingZeroCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountLeadingZeroes, (helper, c) =>
2940
{
3041
var result = context.CheckedExportsBuilder.DefineMethod(
@@ -89,5 +100,6 @@ internal sealed override void Compile(CompilationContext context)
89100
return result;
90101
}
91102
]);
103+
#endif
92104
}
93105
}

WebAssembly/Instructions/Int64CountOneBits.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int64CountOneBits()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo popCount = typeof(BitOperations).GetMethod(nameof(BitOperations.PopCount), new[] { typeof(ulong) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be Int64.
2634
context.ValidateStack(OpCode.Int64CountOneBits, WebAssemblyValueType.Int64);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, popCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountOneBits, CreateHelper]);
2940
}
3041

@@ -73,5 +84,6 @@ internal static MethodBuilder CreateHelper(HelperMethod helper, CompilationConte
7384
il.Emit(OpCodes.Ret);
7485

7586
return result;
87+
#endif
7688
}
7789
}

WebAssembly/Instructions/Int64CountTrailingZeroes.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,11 +24,18 @@ public Int64CountTrailingZeroes()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo trailingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.TrailingZeroCount), new[] { typeof(ulong) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
//Assuming validation passes, the remaining type will be Int64.
2634
context.ValidateStack(OpCode.Int64CountTrailingZeroes, WebAssemblyValueType.Int64);
2735

36+
#if NETCOREAPP3_0_OR_GREATER
37+
context.Emit(OpCodes.Call, trailingZeroCount);
38+
#else
2839
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountTrailingZeroes, (helper, c) =>
2940
{
3041
var result = context.CheckedExportsBuilder.DefineMethod(
@@ -50,5 +61,6 @@ internal sealed override void Compile(CompilationContext context)
5061
return result;
5162
}
5263
]);
64+
#endif
5365
}
5466
}

WebAssembly/Instructions/Int64RotateLeft.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,13 +24,21 @@ public Int64RotateLeft()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo rotateLeft = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateLeft), new[] { typeof(ulong), typeof(int) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
var stack = context.Stack;
2634

2735
context.PopStackNoReturn(OpCode.Int64RotateLeft, WebAssemblyValueType.Int64, WebAssemblyValueType.Int64);
2836
stack.Push(WebAssemblyValueType.Int64);
2937

38+
#if NETCOREAPP3_0_OR_GREATER
39+
context.Emit(OpCodes.Conv_I4);
40+
context.Emit(OpCodes.Call, rotateLeft);
41+
#else
3042
context.Emit(OpCodes.Call, context[HelperMethod.Int64RotateLeft, (helper, c) =>
3143
{
3244
var builder = c.CheckedExportsBuilder.DefineMethod(
@@ -62,5 +74,6 @@ internal sealed override void Compile(CompilationContext context)
6274
return builder;
6375
}
6476
]);
77+
#endif
6578
}
6679
}

WebAssembly/Instructions/Int64RotateRight.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
using System.Reflection.Emit;
1+
#if NETCOREAPP3_0_OR_GREATER
2+
using System.Numerics;
3+
using System.Reflection;
4+
#endif
5+
using System.Reflection.Emit;
26
using WebAssembly.Runtime.Compilation;
37

48
namespace WebAssembly.Instructions;
@@ -20,13 +24,21 @@ public Int64RotateRight()
2024
{
2125
}
2226

27+
#if NETCOREAPP3_0_OR_GREATER
28+
private static readonly MethodInfo rotateRight = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateRight), new[] { typeof(ulong), typeof(int) })!;
29+
#endif
30+
2331
internal sealed override void Compile(CompilationContext context)
2432
{
2533
var stack = context.Stack;
2634

2735
context.PopStackNoReturn(OpCode.Int64RotateRight, WebAssemblyValueType.Int64, WebAssemblyValueType.Int64);
2836
stack.Push(WebAssemblyValueType.Int64);
2937

38+
#if NETCOREAPP3_0_OR_GREATER
39+
context.Emit(OpCodes.Conv_I4);
40+
context.Emit(OpCodes.Call, rotateRight);
41+
#else
3042
context.Emit(OpCodes.Call, context[HelperMethod.Int64RotateRight, (helper, c) =>
3143
{
3244
var builder = c.CheckedExportsBuilder.DefineMethod(
@@ -62,5 +74,6 @@ internal sealed override void Compile(CompilationContext context)
6274
return builder;
6375
}
6476
]);
77+
#endif
6578
}
6679
}

0 commit comments

Comments
 (0)