mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-12 00:58:39 +00:00
Revert example
This commit is contained in:
@@ -1,364 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
unsafe class LdindTest
|
namespace HelloWorldApp
|
||||||
|
{
|
||||||
|
class Program
|
||||||
{
|
{
|
||||||
static int Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
var failures = 0;
|
Console.WriteLine("Hello");
|
||||||
// Test Ldind.i1 (signed byte)
|
|
||||||
failures += TestLdindI1();
|
|
||||||
|
|
||||||
// Test Ldind.u1 (unsigned byte)
|
|
||||||
failures += TestLdindU1();
|
|
||||||
|
|
||||||
// Test Ldind.i2 (signed short)
|
|
||||||
failures += TestLdindI2();
|
|
||||||
|
|
||||||
// Test Ldind.u2 (unsigned short)
|
|
||||||
failures += TestLdindU2();
|
|
||||||
|
|
||||||
// Test Ldind.i4 (signed int)
|
|
||||||
failures += TestLdindI4();
|
|
||||||
|
|
||||||
// Test Ldind.u4 (unsigned int)
|
|
||||||
failures += TestLdindU4();
|
|
||||||
|
|
||||||
// Test Ldind.i8 (signed long)
|
|
||||||
failures += TestLdindI8();
|
|
||||||
|
|
||||||
// Test Ldind.i8 via u8 (there's no Ldind.u8)
|
|
||||||
failures += TestLdindI8ViaU8();
|
|
||||||
|
|
||||||
// Test Ldind.r4 (float)
|
|
||||||
failures += TestLdindR4();
|
|
||||||
|
|
||||||
// Test Ldind.r8 (double)
|
|
||||||
failures += TestLdindR8();
|
|
||||||
|
|
||||||
// Test truncation behavior
|
|
||||||
failures += TestTruncation();
|
|
||||||
|
|
||||||
// Test with managed pointers (ref)
|
|
||||||
failures += TestManagedPointers();
|
|
||||||
|
|
||||||
// Test Ldind.i (native int)
|
|
||||||
failures += TestLdindI();
|
|
||||||
|
|
||||||
return failures;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI1()
|
|
||||||
{
|
|
||||||
sbyte value = -128;
|
|
||||||
sbyte* ptr = &value;
|
|
||||||
sbyte loaded = *ptr; // This generates ldind.i1
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 127;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int TestLdindU1()
|
|
||||||
{
|
|
||||||
byte value = 255;
|
|
||||||
byte* ptr = &value;
|
|
||||||
byte loaded = *ptr; // This generates ldind.u1
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI2()
|
|
||||||
{
|
|
||||||
short value = -32768;
|
|
||||||
short* ptr = &value;
|
|
||||||
short loaded = *ptr; // This generates ldind.i2
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 32767;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindU2()
|
|
||||||
{
|
|
||||||
ushort value = 65535;
|
|
||||||
ushort* ptr = &value;
|
|
||||||
ushort loaded = *ptr; // This generates ldind.u2
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI4()
|
|
||||||
{
|
|
||||||
int value = int.MinValue;
|
|
||||||
int* ptr = &value;
|
|
||||||
int loaded = *ptr; // This generates ldind.i4
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = int.MaxValue;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindU4()
|
|
||||||
{
|
|
||||||
uint value = uint.MaxValue;
|
|
||||||
uint* ptr = &value;
|
|
||||||
uint loaded = *ptr; // This generates ldind.u4
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI8()
|
|
||||||
{
|
|
||||||
long value = long.MinValue;
|
|
||||||
long* ptr = &value;
|
|
||||||
long loaded = *ptr; // This generates ldind.i8
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = long.MaxValue;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI8ViaU8()
|
|
||||||
{
|
|
||||||
ulong value = ulong.MaxValue;
|
|
||||||
ulong* ptr = &value;
|
|
||||||
ulong loaded = *ptr; // This generates ldind.i8 again, because there's no ldind.u8
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = 0;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindR4()
|
|
||||||
{
|
|
||||||
float value = float.MinValue;
|
|
||||||
float* ptr = &value;
|
|
||||||
float loaded = *ptr; // This generates ldind.r4
|
|
||||||
if (BitConverter.SingleToInt32Bits(value) != BitConverter.SingleToInt32Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = float.MaxValue;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (BitConverter.SingleToInt32Bits(value) != BitConverter.SingleToInt32Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = float.NaN;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (BitConverter.SingleToInt32Bits(value) != BitConverter.SingleToInt32Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindR8()
|
|
||||||
{
|
|
||||||
double value = double.MinValue;
|
|
||||||
double* ptr = &value;
|
|
||||||
double loaded = *ptr; // This generates ldind.r8
|
|
||||||
if (BitConverter.DoubleToInt64Bits(value) != BitConverter.DoubleToInt64Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = double.MaxValue;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (BitConverter.DoubleToInt64Bits(value) != BitConverter.DoubleToInt64Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = double.NaN;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (BitConverter.DoubleToInt64Bits(value) != BitConverter.DoubleToInt64Bits(loaded))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestLdindI()
|
|
||||||
{
|
|
||||||
IntPtr value = new IntPtr(42);
|
|
||||||
IntPtr* ptr = &value;
|
|
||||||
IntPtr loaded = *ptr; // This generates ldind.i
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = IntPtr.Zero;
|
|
||||||
loaded = *ptr;
|
|
||||||
if (value != loaded)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestTruncation()
|
|
||||||
{
|
|
||||||
// Store a larger value and load as smaller type
|
|
||||||
int largeValue = 0x1234ABCD;
|
|
||||||
void* ptr = &largeValue;
|
|
||||||
|
|
||||||
byte byteValue = *(byte*)ptr; // Should truncate to 0xCD
|
|
||||||
if (byteValue != 0xCD)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
short shortValue = *(short*)ptr; // Should truncate to 0xABCD
|
|
||||||
if (shortValue != -21555)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test sign extension
|
|
||||||
sbyte signedByte = *(sbyte*)ptr; // 0xCD as signed byte is -51
|
|
||||||
if (signedByte != -51)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestManagedPointers()
|
|
||||||
{
|
|
||||||
int value = 42;
|
|
||||||
ref int refValue = ref value;
|
|
||||||
var expected42 = TestRefParameter(ref refValue);
|
|
||||||
if (expected42 != 42)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refValue != 84)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with array element
|
|
||||||
int[] array = new int[3];
|
|
||||||
array[0] = 10;
|
|
||||||
array[1] = 20;
|
|
||||||
array[2] = 30;
|
|
||||||
ref int element = ref array[1];
|
|
||||||
if (element != 20)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test with local variable
|
|
||||||
int local = 100;
|
|
||||||
var expected100 = TestRefLocal(ref local);
|
|
||||||
if (expected100 != 100)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestRefParameter(ref int param)
|
|
||||||
{
|
|
||||||
var result = 0;
|
|
||||||
// This will use ldind instructions when accessing param
|
|
||||||
result += param;
|
|
||||||
param = 84;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TestRefLocal(ref int local)
|
|
||||||
{
|
|
||||||
// Create a ref local
|
|
||||||
ref int refLocal = ref local;
|
|
||||||
return refLocal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user