diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 10466de77af15..9d3d95c4e2631 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -108,12 +108,11 @@
+
+
-
-
-
-
-
+
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/ReaderBigEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs
similarity index 100%
rename from src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/ReaderBigEndian.cs
rename to src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/ReaderLittleEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs
similarity index 100%
rename from src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/ReaderLittleEndian.cs
rename to src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReverseEndianness.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReverseEndianness.cs
index 6f355d2089f83..c229efb2f3d38 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReverseEndianness.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReverseEndianness.cs
@@ -2,14 +2,172 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
+#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
+
+#if TARGET_64BIT
+using nint_t = System.Int64;
+using nuint_t = System.UInt64;
+#else
+using nint_t = System.Int32;
+using nuint_t = System.UInt32;
+#endif
+
namespace System.Buffers.Binary
{
public static partial class BinaryPrimitives
{
+ ///
+ /// This is a no-op and added only for consistency.
+ /// This allows the caller to read a struct of numeric primitives and reverse each field
+ /// rather than having to skip sbyte fields.
+ ///
+ [CLSCompliant(false)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static sbyte ReverseEndianness(sbyte value) => value;
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static short ReverseEndianness(short value) => (short)ReverseEndianness((ushort)value);
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int ReverseEndianness(int value) => (int)ReverseEndianness((uint)value);
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long ReverseEndianness(long value) => (long)ReverseEndianness((ulong)value);
+
+ /// Reverses a primitive value by performing an endianness swap of the specified value.
+ /// The value to reverse.
+ /// The reversed value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static nint ReverseEndianness(nint value) => (nint)ReverseEndianness((nint_t)value);
+
+ /// Reverses a primitive value by performing an endianness swap of the specified value.
+ /// The value to reverse.
+ /// The reversed value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Int128 ReverseEndianness(Int128 value)
+ {
+ return new Int128(
+ ReverseEndianness(value.Lower),
+ ReverseEndianness(value.Upper)
+ );
+ }
+
+ ///
+ /// This is a no-op and added only for consistency.
+ /// This allows the caller to read a struct of numeric primitives and reverse each field
+ /// rather than having to skip byte fields.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte ReverseEndianness(byte value) => value;
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ushort ReverseEndianness(ushort value)
+ {
+ // Don't need to AND with 0xFF00 or 0x00FF since the final
+ // cast back to ushort will clear out all bits above [ 15 .. 00 ].
+ // This is normally implemented via "movzx eax, ax" on the return.
+ // Alternatively, the compiler could elide the movzx instruction
+ // entirely if it knows the caller is only going to access "ax"
+ // instead of "eax" / "rax" when the function returns.
+
+ return (ushort)((value >> 8) + (value << 8));
+ }
+
+ ///
+ /// Reverses a 16-bit character value - performs an endianness swap
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static char ReverseEndianness(char value) => (char)ReverseEndianness((ushort)value);
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint ReverseEndianness(uint value)
+ {
+ // This takes advantage of the fact that the JIT can detect
+ // ROL32 / ROR32 patterns and output the correct intrinsic.
+ //
+ // Input: value = [ ww xx yy zz ]
+ //
+ // First line generates : [ ww xx yy zz ]
+ // & [ 00 FF 00 FF ]
+ // = [ 00 xx 00 zz ]
+ // ROR32(8) = [ zz 00 xx 00 ]
+ //
+ // Second line generates: [ ww xx yy zz ]
+ // & [ FF 00 FF 00 ]
+ // = [ ww 00 yy 00 ]
+ // ROL32(8) = [ 00 yy 00 ww ]
+ //
+ // (sum) = [ zz yy xx ww ]
+ //
+ // Testing shows that throughput increases if the AND
+ // is performed before the ROL / ROR.
+
+ return BitOperations.RotateRight(value & 0x00FF00FFu, 8) // xx zz
+ + BitOperations.RotateLeft(value & 0xFF00FF00u, 8); // ww yy
+ }
+
+ ///
+ /// Reverses a primitive value - performs an endianness swap
+ ///
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong ReverseEndianness(ulong value)
+ {
+ // Operations on 32-bit values have higher throughput than
+ // operations on 64-bit values, so decompose.
+
+ return ((ulong)ReverseEndianness((uint)value) << 32)
+ + ReverseEndianness((uint)(value >> 32));
+ }
+
+ /// Reverses a primitive value by performing an endianness swap of the specified value.
+ /// The value to reverse.
+ /// The reversed value.
+ [CLSCompliant(false)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static nuint ReverseEndianness(nuint value) => (nuint)ReverseEndianness((nuint_t)value);
+
+ /// Reverses a primitive value by performing an endianness swap of the specified value.
+ /// The value to reverse.
+ /// The reversed value.
+ [CLSCompliant(false)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static UInt128 ReverseEndianness(UInt128 value)
+ {
+ return new UInt128(
+ ReverseEndianness(value.Lower),
+ ReverseEndianness(value.Upper)
+ );
+ }
+
/// Copies every primitive value from to , reversing each primitive by performing an endianness swap as part of writing each.
/// The source span to copy.
/// The destination to which the source elements should be copied.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/WriterBigEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs
similarity index 100%
rename from src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/WriterBigEndian.cs
rename to src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/WriterLittleEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs
similarity index 100%
rename from src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/WriterLittleEndian.cs
rename to src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/Reader.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/Reader.cs
deleted file mode 100644
index 540f8732b6859..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/Reader.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using System.Runtime.Intrinsics;
-
-#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
-
-#if TARGET_64BIT
-using nint_t = System.Int64;
-using nuint_t = System.UInt64;
-#else
-using nint_t = System.Int32;
-using nuint_t = System.UInt32;
-#endif
-
-namespace System.Buffers.Binary
-{
- ///
- /// Reads bytes as primitives with specific endianness
- ///
- ///
- /// Use these helpers when you need to read specific endianness.
- ///
- public static partial class BinaryPrimitives
- {
- ///
- /// This is a no-op and added only for consistency.
- /// This allows the caller to read a struct of numeric primitives and reverse each field
- /// rather than having to skip sbyte fields.
- ///
- [CLSCompliant(false)]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static sbyte ReverseEndianness(sbyte value) => value;
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static short ReverseEndianness(short value) => (short)ReverseEndianness((ushort)value);
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int ReverseEndianness(int value) => (int)ReverseEndianness((uint)value);
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static long ReverseEndianness(long value) => (long)ReverseEndianness((ulong)value);
-
- /// Reverses a primitive value by performing an endianness swap of the specified value.
- /// The value to reverse.
- /// The reversed value.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static nint ReverseEndianness(nint value) => (nint)ReverseEndianness((nint_t)value);
-
- /// Reverses a primitive value by performing an endianness swap of the specified value.
- /// The value to reverse.
- /// The reversed value.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Int128 ReverseEndianness(Int128 value)
- {
- return new Int128(
- ReverseEndianness(value.Lower),
- ReverseEndianness(value.Upper)
- );
- }
-
- ///
- /// This is a no-op and added only for consistency.
- /// This allows the caller to read a struct of numeric primitives and reverse each field
- /// rather than having to skip byte fields.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static byte ReverseEndianness(byte value) => value;
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [CLSCompliant(false)]
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ushort ReverseEndianness(ushort value)
- {
- // Don't need to AND with 0xFF00 or 0x00FF since the final
- // cast back to ushort will clear out all bits above [ 15 .. 00 ].
- // This is normally implemented via "movzx eax, ax" on the return.
- // Alternatively, the compiler could elide the movzx instruction
- // entirely if it knows the caller is only going to access "ax"
- // instead of "eax" / "rax" when the function returns.
-
- return (ushort)((value >> 8) + (value << 8));
- }
-
- ///
- /// Reverses a 16-bit character value - performs an endianness swap
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static char ReverseEndianness(char value) => (char)ReverseEndianness((ushort)value);
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [CLSCompliant(false)]
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static uint ReverseEndianness(uint value)
- {
- // This takes advantage of the fact that the JIT can detect
- // ROL32 / ROR32 patterns and output the correct intrinsic.
- //
- // Input: value = [ ww xx yy zz ]
- //
- // First line generates : [ ww xx yy zz ]
- // & [ 00 FF 00 FF ]
- // = [ 00 xx 00 zz ]
- // ROR32(8) = [ zz 00 xx 00 ]
- //
- // Second line generates: [ ww xx yy zz ]
- // & [ FF 00 FF 00 ]
- // = [ ww 00 yy 00 ]
- // ROL32(8) = [ 00 yy 00 ww ]
- //
- // (sum) = [ zz yy xx ww ]
- //
- // Testing shows that throughput increases if the AND
- // is performed before the ROL / ROR.
-
- return BitOperations.RotateRight(value & 0x00FF00FFu, 8) // xx zz
- + BitOperations.RotateLeft(value & 0xFF00FF00u, 8); // ww yy
- }
-
- ///
- /// Reverses a primitive value - performs an endianness swap
- ///
- [CLSCompliant(false)]
- [Intrinsic]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ulong ReverseEndianness(ulong value)
- {
- // Operations on 32-bit values have higher throughput than
- // operations on 64-bit values, so decompose.
-
- return ((ulong)ReverseEndianness((uint)value) << 32)
- + ReverseEndianness((uint)(value >> 32));
- }
-
- /// Reverses a primitive value by performing an endianness swap of the specified value.
- /// The value to reverse.
- /// The reversed value.
- [CLSCompliant(false)]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static nuint ReverseEndianness(nuint value) => (nuint)ReverseEndianness((nuint_t)value);
-
- /// Reverses a primitive value by performing an endianness swap of the specified value.
- /// The value to reverse.
- /// The reversed value.
- [CLSCompliant(false)]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static UInt128 ReverseEndianness(UInt128 value)
- {
- return new UInt128(
- ReverseEndianness(value.Lower),
- ReverseEndianness(value.Upper)
- );
- }
- }
-}