Files
ed b5b7b9ab4b Added new string template formatter
- Based on a template formatter I have in used/evolved in other projects.
- Will eventually replace the current token formatter used in untyped code.
- Has some x86 simd support.. (opt-in if avail).
2026-10-16 13:30:42 -04:00

91 lines
4.5 KiB
C

gen_internal void expect_simd_lanes()
{
#if defined(GEN_SYSTEM_WINDOWS) && (defined(_M_X64) || defined(__x86_64__))
gen_u8 storage[32];
gen_mem_set(storage, 0x11, 32);
gen_u8 pattern[16] = {
0x00, 0x80, 0xFF, 0x01,
0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C, 0x0D
};
gen_mem_copy(storage + 1, pattern, 16);
gen_u8x16 loaded = gen_u8x16_load(storage + 1);
gen_u8x16 again = gen_u8x16_load(storage + 1);
gen_u16 same = gen_u8x16_mask(gen_u8x16_equal(loaded, again));
gen_u16 zero_mask = gen_u8x16_mask(gen_u8x16_equal(loaded, gen_u8x16_splat(0x00)));
gen_u16 high_bit = gen_u8x16_mask(gen_u8x16_equal(loaded, gen_u8x16_splat(0x80)));
gen_u16 top = gen_u8x16_mask(gen_u8x16_equal(loaded, gen_u8x16_splat(0xFF)));
expect(same == 0xFFFF, gen_txt("simd u8 equal load"));
expect(zero_mask == 0x0001, gen_txt("simd byte 0"));
expect(high_bit == 0x0002, gen_txt("simd byte 0x80"));
expect(top == 0x0004, gen_txt("simd byte 0xFF"));
gen_u8 high_lane[16];
gen_mem_set(high_lane, 0x22, 16);
high_lane[15] = 0xFF;
gen_u8x16 high_loaded = gen_u8x16_load(high_lane);
gen_u16 lane15 = gen_u8x16_mask(gen_u8x16_equal(high_loaded, gen_u8x16_splat(0xFF)));
expect(lane15 == 0x8000, gen_txt("simd lane 15"));
expect(gen_u32_mask_first_set(lane15) == 15, gen_txt("simd first set lane 15"));
gen_u8 window[24];
gen_mem_set(window, 0xEE, 24);
window[1] = 0x00;
window[2] = 0x80;
window[3] = 0xFF;
window[4] = 0x11;
window[5] = 0x22;
window[6] = 0x33;
window[7] = 0x44;
window[8] = 0x55;
gen_u8x16 loaded8 = gen_u8x16_load8(window + 1);
gen_u16 upper = gen_u8x16_mask(gen_u8x16_equal(loaded8, gen_u8x16_splat(0x00)));
gen_u16 low_ff = gen_u8x16_mask(gen_u8x16_equal(loaded8, gen_u8x16_splat(0xFF)));
gen_u16 low_80 = gen_u8x16_mask(gen_u8x16_equal(loaded8, gen_u8x16_splat(0x80)));
gen_u16 byte7 = gen_u8x16_mask(gen_u8x16_equal(loaded8, gen_u8x16_splat(0x55)));
expect((upper & 0xFF00) == 0xFF00, gen_txt("simd load8 upper zero"));
expect((upper & 0x0001) == 0x0001, gen_txt("simd load8 low zero"));
expect(low_ff == 0x0004, gen_txt("simd load8 low 0xFF"));
expect(low_80 == 0x0002, gen_txt("simd load8 low 0x80"));
expect(byte7 == 0x0080, gen_txt("simd load8 byte 7"));
gen_u16 sentinel = gen_u8x16_mask(gen_u8x16_equal(loaded8, gen_u8x16_splat(0xEE)));
expect(sentinel == 0, gen_txt("simd load8 ignores tail"));
gen_u8x16 loaded16 = gen_u8x16_load(window + 1);
gen_u16 tail = gen_u8x16_mask(gen_u8x16_equal(loaded16, gen_u8x16_splat(0xEE)));
expect(tail == 0xFF00, gen_txt("simd load16 sees load8 tail"));
gen_u32 hashes[4] = { 0x00000000u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu };
gen_u32x4 hash_loaded = gen_u32x4_load(hashes);
gen_u8 lane0 = gen_u32x4_mask(gen_u32x4_equal(hash_loaded, gen_u32x4_splat(0x00000000u)));
gen_u8 lane1 = gen_u32x4_mask(gen_u32x4_equal(hash_loaded, gen_u32x4_splat(0x7FFFFFFFu)));
gen_u8 lane2 = gen_u32x4_mask(gen_u32x4_equal(hash_loaded, gen_u32x4_splat(0x80000000u)));
gen_u8 lane3 = gen_u32x4_mask(gen_u32x4_equal(hash_loaded, gen_u32x4_splat(0xFFFFFFFFu)));
expect(lane0 == 0x01, gen_txt("simd u32 lane 0"));
expect(lane1 == 0x02, gen_txt("simd u32 lane 1"));
expect(lane2 == 0x04, gen_txt("simd u32 bit31 lane"));
expect(lane3 == 0x08, gen_txt("simd u32 lane 3"));
expect((lane2 & 0xF0) == 0, gen_txt("simd u32 mask low bits"));
gen_u32 all_values[4] = { 0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u };
gen_u32x4 all_loaded = gen_u32x4_load(all_values);
gen_u8 all_mask = gen_u32x4_mask(gen_u32x4_equal(all_loaded, gen_u32x4_splat(0x80000000u)));
expect(all_mask == 0x0F, gen_txt("simd u32 all bit31"));
gen_u8 none_mask = gen_u32x4_mask(gen_u32x4_equal(all_loaded, gen_u32x4_splat(0x7FFFFFFFu)));
expect(none_mask == 0x00, gen_txt("simd u32 none"));
gen_u8 hash_storage[20];
gen_mem_set (hash_storage, 0xA5, 20);
gen_mem_copy(hash_storage + 1, hashes, 16);
gen_u32x4 unaligned = gen_u32x4_load(hash_storage + 1);
gen_u8 unaligned_mask = gen_u32x4_mask(gen_u32x4_equal(unaligned, gen_u32x4_splat(0x80000000u)));
expect(unaligned_mask == 0x04, gen_txt("simd u32 unaligned bit31"));
expect(gen_u32_mask_first_set(0x1u) == 0, gen_txt("simd first set bit 0"));
expect(gen_u32_mask_first_set(0x14u) == 2, gen_txt("simd first set lowest"));
expect(gen_u32_mask_first_set(0x8000u) == 15, gen_txt("simd first set bit 15"));
expect(gen_u32_mask_first_set(0x80000000u) == 31, gen_txt("simd first set bit 31"));
expect(gen_u32_mask_first_set(0xFFFFFFFFu) == 0, gen_txt("simd first set all bits"));
#endif
}