[A64] Inline all vector C helpers using NEON/GPR and add some tests
This commit is contained in:
@@ -115,3 +115,70 @@ TEST_CASE("PACK_SHORT_2", "[instr]") {
|
||||
REQUIRE(result == vec128i(0, 0, 0, 0x80018001));
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE("PACK_UINT_2101010", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_UINT_2101010));
|
||||
b.Return();
|
||||
});
|
||||
// All magic-zero: XYZ and W all at base → packed=0
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x40400000, 0x40400000, 0x40400000, 0x40400000);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result == vec128i(0, 0, 0, 0));
|
||||
});
|
||||
// x=100, y=200, z=3, w=2 → packed=0x80332064
|
||||
// The packed result is defined in u32[3]; other lanes are don't-care
|
||||
// (vpkd3d128 permutes the packed value into the correct position).
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x40400064, 0x404000C8, 0x40400003, 0x40400002);
|
||||
},
|
||||
[](PPCContext* ctx) { REQUIRE(ctx->v[3].u32[3] == 0x80332064); });
|
||||
// x=-100 (0x39C), y=50, z=-1 (0x3FF), w=3 → packed=0xFFF0CB9C
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x403FFF9C, 0x40400032, 0x403FFFFF, 0x40400003);
|
||||
},
|
||||
[](PPCContext* ctx) { REQUIRE(ctx->v[3].u32[3] == 0xFFF0CB9C); });
|
||||
}
|
||||
|
||||
TEST_CASE("PACK_ULONG_4202020", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_ULONG_4202020));
|
||||
b.Return();
|
||||
});
|
||||
// All magic-zero: → packed=0
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x40400000, 0x40400000, 0x40400000, 0x40400000);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result == vec128i(0, 0, 0, 0));
|
||||
});
|
||||
// x=1000, y=2000, z=100, w=5
|
||||
// packed=0x500064007D0003E8, u32[2]=high, u32[3]=low
|
||||
// Only u32[2]:u32[3] are defined (64-bit packed result).
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x404003E8, 0x404007D0, 0x40400064, 0x40400005);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
REQUIRE(ctx->v[3].u32[2] == 0x50006400);
|
||||
REQUIRE(ctx->v[3].u32[3] == 0x7D0003E8);
|
||||
});
|
||||
// Negative x=-100, y=50, z=-1, w=10
|
||||
// packed64=0xAFFFFF00032FFF9C, u32[2]=0xAFFFFF00, u32[3]=0x032FFF9C
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0x403FFF9C, 0x40400032, 0x403FFFFF, 0x4040000A);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
REQUIRE(ctx->v[3].u32[2] == 0xAFFFFF00);
|
||||
REQUIRE(ctx->v[3].u32[3] == 0x032FFF9C);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -117,6 +117,98 @@ TEST_CASE("UNPACK_SHORT_2", "[instr]") {
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE("UNPACK_UINT_2101010", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_UINT_2101010));
|
||||
b.Return();
|
||||
});
|
||||
// All-zero: XYZ=0 → magic 3.0, W=0 → 1.0
|
||||
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x40400000, 0x40400000, 0x40400000, 0x3F800000));
|
||||
});
|
||||
// Positive values: x=100, y=200, z=3, w=2
|
||||
// packed = 100 | (200<<10) | (3<<20) | (2<<30) = 0x80332064
|
||||
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x80332064); },
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x40400064, 0x404000C8, 0x40400003, 0x3F800002));
|
||||
});
|
||||
// Negative x=-100 (10-bit: 0x39C), y=50, z=-1 (10-bit: 0x3FF), w=3
|
||||
// packed = 0x39C | (50<<10) | (0x3FF<<20) | (3<<30) = 0xFFF0CB9C
|
||||
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0xFFF0CB9C); },
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
// x=-100: 0x40400000+0xFFFFFF9C = 0x403FFF9C
|
||||
// y=50: 0x40400000+50 = 0x40400032
|
||||
// z=-1: 0x40400000+0xFFFFFFFF = 0x403FFFFF
|
||||
// w=3: 0x3F800000+3 = 0x3F800003
|
||||
REQUIRE(result ==
|
||||
vec128i(0x403FFF9C, 0x40400032, 0x403FFFFF, 0x3F800003));
|
||||
});
|
||||
// Overflow: x=-512 (10-bit: 0x200) → 0x403FFE00 → QNaN
|
||||
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x00000200); },
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x7FC00000, 0x40400000, 0x40400000, 0x3F800000));
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE("UNPACK_ULONG_4202020", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_ULONG_4202020));
|
||||
b.Return();
|
||||
});
|
||||
// All-zero: XYZ=0 → magic 3.0, W=0 → 1.0
|
||||
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x40400000, 0x40400000, 0x40400000, 0x3F800000));
|
||||
});
|
||||
// x=1000, y=2000, z=100, w=5
|
||||
// packed64 = 1000|(2000<<20)|(100<<40)|(5<<60) = 0x500064007D0003E8
|
||||
// u32[2]=0x50006400 (high), u32[3]=0x7D0003E8 (low)
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0, 0, 0x50006400, 0x7D0003E8);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
// x=1000: 0x40400000+1000 = 0x404003E8
|
||||
// y=2000: 0x40400000+2000 = 0x404007D0
|
||||
// z=100: 0x40400000+100 = 0x40400064
|
||||
// w=5: 0x3F800000+5 = 0x3F800005
|
||||
REQUIRE(result ==
|
||||
vec128i(0x404003E8, 0x404007D0, 0x40400064, 0x3F800005));
|
||||
});
|
||||
// Negative x=-100, y=50, z=-1, w=10
|
||||
// packed64=0xAFFFFF00032FFF9C, u32[2]=0xAFFFFF00, u32[3]=0x032FFF9C
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0, 0, 0xAFFFFF00, 0x032FFF9C);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x403FFF9C, 0x40400032, 0x403FFFFF, 0x3F80000A));
|
||||
});
|
||||
// Overflow: x=-524288 (20-bit: 0x80000) → 0x40380000 → QNaN
|
||||
test.Run(
|
||||
[](PPCContext* ctx) {
|
||||
ctx->v[4] = vec128i(0, 0, 0x00000000, 0x00080000);
|
||||
},
|
||||
[](PPCContext* ctx) {
|
||||
auto result = ctx->v[3];
|
||||
REQUIRE(result ==
|
||||
vec128i(0x7FC00000, 0x40400000, 0x40400000, 0x3F800000));
|
||||
});
|
||||
}
|
||||
|
||||
// TEST_CASE("UNPACK_S8_IN_16_LO", "[instr]") {
|
||||
// TestFunction test([](HIRBuilder& b) {
|
||||
// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S8_IN_16_LO));
|
||||
|
||||
Reference in New Issue
Block a user