Skip to content

Commit b9bc70c

Browse files
Scalar bitwise implementation (#667)
* Scalar bitwise things * A few tests * Double to be reinterpreted as ulong
1 parent 09c33b7 commit b9bc70c

File tree

9 files changed

+1229
-0
lines changed

9 files changed

+1229
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Globalization;
6+
using System.Runtime.InteropServices;
7+
using Xunit;
8+
9+
namespace Silk.NET.Maths.Tests
10+
{
11+
public class ScalarBitwiseTest
12+
{
13+
[Fact]
14+
public void RotateLeft1()
15+
{
16+
Assert.Equal((byte)0b1110_0001, Scalar.RotateLeft((byte)0b1111_0000, 1));
17+
}
18+
19+
[Fact]
20+
public void RotateLeft2()
21+
{
22+
Assert.Equal((ushort)0b1100_1000_0000_0011, Scalar.RotateLeft((ushort)0b1111_0010_0000_0000, 2));
23+
}
24+
25+
[Fact]
26+
public void RotateRight1()
27+
{
28+
Assert.Equal((byte)0b1111_0000, Scalar.RotateRight((byte)0b1110_0001, 1));
29+
}
30+
31+
[Fact]
32+
public void RotateRight2()
33+
{
34+
Assert.Equal((ushort)0b1111_0010_0000_0000, Scalar.RotateRight((ushort)0b1100_1000_0000_0011, 2));
35+
}
36+
37+
[Fact]
38+
public void And1()
39+
{
40+
Assert.Equal(0b1010, Scalar.And(0b1110, 0b1011));
41+
}
42+
43+
[Fact]
44+
public void And2()
45+
{
46+
Assert.Equal((byte)0b1010, Scalar.And((byte)0b1110, (byte)0b1011));
47+
}
48+
49+
[Fact]
50+
public void And3()
51+
{
52+
Assert.Equal((long)0b1010, Scalar.And((long)0b1110, (long)0b1011));
53+
}
54+
55+
[Fact]
56+
public void Or1()
57+
{
58+
Assert.Equal(0b1111, Scalar.Or(0b1110, 0b1011));
59+
}
60+
61+
[Fact]
62+
public void Or2()
63+
{
64+
Assert.Equal((byte)0b1111, Scalar.Or((byte)0b1110, (byte)0b1011));
65+
}
66+
67+
[Fact]
68+
public void Or3()
69+
{
70+
Assert.Equal((long)0b1111, Scalar.Or((long)0b1110, (long)0b1011));
71+
}
72+
73+
[Fact]
74+
public void Xor1()
75+
{
76+
Assert.Equal(0b0101, Scalar.Xor(0b1110, 0b1011));
77+
}
78+
79+
[Fact]
80+
public void Xor2()
81+
{
82+
Assert.Equal((byte)0b0101, Scalar.Xor((byte)0b1110, (byte)0b1011));
83+
}
84+
85+
[Fact]
86+
public void Xor3()
87+
{
88+
Assert.Equal((long)0b0101, Scalar.Xor((long)0b1110, (long)0b1011));
89+
}
90+
91+
[Fact]
92+
public void Not1()
93+
{
94+
Assert.Equal(~0b1110, Scalar.Not(0b1110));
95+
}
96+
97+
[Fact]
98+
public void Not2()
99+
{
100+
var b = ~(byte)0b1110;
101+
// ReSharper disable once IntVariableOverflowInUncheckedContext
102+
Assert.Equal((byte)b, Scalar.Not((byte)0b1110));
103+
}
104+
105+
[Fact]
106+
public void Not3()
107+
{
108+
Assert.Equal(~(ulong)0b1110, Scalar.Not((ulong)0b1110));
109+
}
110+
}
111+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.CompilerServices;
5+
6+
namespace Silk.NET.Maths
7+
{
8+
static partial class Scalar
9+
{
10+
/// <summary>
11+
/// Performs And on supported types
12+
/// </summary>
13+
public static T And<T>(T left, T right) where T : unmanaged
14+
{
15+
return Byte(left, right);
16+
17+
[MethodImpl(MaxOpt)]
18+
static T Byte(T left, T right)
19+
{
20+
if (typeof(T) == typeof(byte))
21+
{
22+
return (T) (object) (byte) ((byte) (object) left & (byte) (object) right);
23+
}
24+
25+
return SByte(left, right);
26+
}
27+
28+
[MethodImpl(MaxOpt)]
29+
static T SByte(T left, T right)
30+
{
31+
if (typeof(T) == typeof(sbyte))
32+
{
33+
return (T) (object) (sbyte) ((sbyte) (object) left & (sbyte) (object) right);
34+
}
35+
36+
return UInt16(left, right);
37+
}
38+
39+
[MethodImpl(MaxOpt)]
40+
static T UInt16(T left, T right)
41+
{
42+
if (typeof(T) == typeof(ushort))
43+
{
44+
return (T) (object) (ushort) ((ushort) (object) left & (ushort) (object) right);
45+
}
46+
47+
return Int16(left, right);
48+
}
49+
50+
[MethodImpl(MaxOpt)]
51+
static T Int16(T left, T right)
52+
{
53+
if (typeof(T) == typeof(short))
54+
{
55+
return (T) (object) (short) ((short) (object) left & (short) (object) right);
56+
}
57+
58+
return UInt32(left, right);
59+
}
60+
61+
[MethodImpl(MaxOpt)]
62+
static T UInt32(T left, T right)
63+
{
64+
if (typeof(T) == typeof(uint))
65+
{
66+
return (T) (object) (uint) ((uint) (object) left & (uint) (object) right);
67+
}
68+
69+
return Int32(left, right);
70+
}
71+
72+
[MethodImpl(MaxOpt)]
73+
static T Int32(T left, T right)
74+
{
75+
if (typeof(T) == typeof(int))
76+
{
77+
return (T) (object) (int) ((int) (object) left & (int) (object) right);
78+
}
79+
80+
return UInt64(left, right);
81+
}
82+
83+
[MethodImpl(MaxOpt)]
84+
static T UInt64(T left, T right)
85+
{
86+
if (typeof(T) == typeof(ulong))
87+
{
88+
return (T) (object) (ulong) ((ulong) (object) left & (ulong) (object) right);
89+
}
90+
91+
return Int64(left, right);
92+
}
93+
94+
[MethodImpl(MaxOpt)]
95+
static T Int64(T left, T right)
96+
{
97+
if (typeof(T) == typeof(long))
98+
{
99+
return (T) (object) (long) ((long) (object) left & (long) (object) right);
100+
}
101+
102+
return Single(left, right);
103+
}
104+
105+
[MethodImpl(MaxOpt)]
106+
static T Single(T left, T right)
107+
{
108+
if (typeof(T) == typeof(float))
109+
{
110+
var res = Unsafe.As<T, uint>(ref left) & Unsafe.As<T, uint>(ref right);
111+
return Unsafe.As<uint, T>(ref res);
112+
}
113+
114+
return Double(left, right);
115+
}
116+
117+
[MethodImpl(MaxOpt)]
118+
static T Double(T left, T right)
119+
{
120+
if (typeof(T) == typeof(double))
121+
{
122+
var res = Unsafe.As<T, ulong>(ref left) & Unsafe.As<T, ulong>(ref right);
123+
return Unsafe.As<ulong, T>(ref res);
124+
}
125+
126+
return Other(left, right);
127+
}
128+
129+
[MethodImpl(MaxOpt)]
130+
static T Other(T left, T right)
131+
{
132+
ThrowUnsupportedType();
133+
return default;
134+
}
135+
}
136+
}
137+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.CompilerServices;
5+
6+
namespace Silk.NET.Maths
7+
{
8+
static partial class Scalar
9+
{
10+
/// <summary>
11+
/// Performs Not on supported types
12+
/// </summary>
13+
public static T Not<T>(T value) where T : unmanaged
14+
{
15+
return Byte(value);
16+
17+
[MethodImpl(MaxOpt)]
18+
static T Byte(T value)
19+
{
20+
if (typeof(T) == typeof(byte))
21+
{
22+
return (T) (object) (byte) (~ (byte) (object) value);
23+
}
24+
25+
return SByte(value);
26+
}
27+
28+
[MethodImpl(MaxOpt)]
29+
static T SByte(T value)
30+
{
31+
if (typeof(T) == typeof(sbyte))
32+
{
33+
return (T) (object) (sbyte) (~ (sbyte) (object) value);
34+
}
35+
36+
return UInt16(value);
37+
}
38+
39+
[MethodImpl(MaxOpt)]
40+
static T UInt16(T value)
41+
{
42+
if (typeof(T) == typeof(ushort))
43+
{
44+
return (T) (object) (ushort) (~ (ushort) (object) value);
45+
}
46+
47+
return Int16(value);
48+
}
49+
50+
[MethodImpl(MaxOpt)]
51+
static T Int16(T value)
52+
{
53+
if (typeof(T) == typeof(short))
54+
{
55+
return (T) (object) (short) (~ (short) (object) value);
56+
}
57+
58+
return UInt32(value);
59+
}
60+
61+
[MethodImpl(MaxOpt)]
62+
static T UInt32(T value)
63+
{
64+
if (typeof(T) == typeof(uint))
65+
{
66+
return (T) (object) (uint) (~ (uint) (object) value);
67+
}
68+
69+
return Int32(value);
70+
}
71+
72+
[MethodImpl(MaxOpt)]
73+
static T Int32(T value)
74+
{
75+
if (typeof(T) == typeof(int))
76+
{
77+
return (T) (object) (int) (~ (int) (object) value);
78+
}
79+
80+
return UInt64(value);
81+
}
82+
83+
[MethodImpl(MaxOpt)]
84+
static T UInt64(T value)
85+
{
86+
if (typeof(T) == typeof(ulong))
87+
{
88+
return (T) (object) (ulong) (~ (ulong) (object) value);
89+
}
90+
91+
return Int64(value);
92+
}
93+
94+
[MethodImpl(MaxOpt)]
95+
static T Int64(T value)
96+
{
97+
if (typeof(T) == typeof(long))
98+
{
99+
return (T) (object) (long) (~ (long) (object) value);
100+
}
101+
102+
return Single(value);
103+
}
104+
105+
[MethodImpl(MaxOpt)]
106+
static T Single(T value)
107+
{
108+
if (typeof(T) == typeof(float))
109+
{
110+
var res = ~ Unsafe.As<T, uint>(ref value);
111+
return Unsafe.As<uint, T>(ref res);
112+
}
113+
114+
return Double(value);
115+
}
116+
117+
[MethodImpl(MaxOpt)]
118+
static T Double(T value)
119+
{
120+
if (typeof(T) == typeof(double))
121+
{
122+
var res = ~ Unsafe.As<T, ulong>(ref value);
123+
return Unsafe.As<ulong, T>(ref res);
124+
}
125+
126+
return Other(value);
127+
}
128+
129+
[MethodImpl(MaxOpt)]
130+
static T Other(T value)
131+
{
132+
ThrowUnsupportedType();
133+
return default;
134+
}
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)