#include "libnux/vx/globaladdress.h" #include "libnux/vx/unittest.h" using namespace libnux::vx; auto to_hexstring(uint32_t const value) { // creates 0x....'.... std::array<char, 12> ret; char constexpr hex_index[] = "0123456789abcdef"; ret[ 0] = '0'; ret[ 1] = 'x'; ret[ 2] = hex_index[(*((uint8_t*)(&value) + 0) >> 4) & 0xf]; ret[ 3] = hex_index[(*((uint8_t*)(&value) + 0) ) & 0xf]; ret[ 4] = hex_index[(*((uint8_t*)(&value) + 1) >> 4) & 0xf]; ret[ 5] = hex_index[(*((uint8_t*)(&value) + 1) ) & 0xf]; ret[ 6] = '\''; ret[ 7] = hex_index[(*((uint8_t*)(&value) + 2) >> 4) & 0xf]; ret[ 8] = hex_index[(*((uint8_t*)(&value) + 2) ) & 0xf]; ret[ 9] = hex_index[(*((uint8_t*)(&value) + 3) >> 4) & 0xf]; ret[10] = hex_index[(*((uint8_t*)(&value) + 3) ) & 0xf]; ret[11] = 0; return ret; } void start() { test_init(); uint32_t next_offset = 0x100; { testcase_begin("Vector (generated) write to extmem (vector address via vector type), scalar read (generated) of one element"); auto const ga = GlobalAddress::from_global(AddressSpace::extmem.to_global_omnibus() + next_offset); next_offset += 0x100; *ga.to_extmem().to_scalar<__vector uint16_t>() = vec_splat_u16(0x1); auto val = *ga.to_extmem().to_scalar<uint16_t>(); test_equal(val, 0x1); testcase_end(); test_write_string("at address: "); test_write_string(to_hexstring(ga.to_global_omnibus()).data()); test_write_string("\n"); } { testcase_begin("Vector (fxvstax) write to extmem (scalar address), scalar read (generated) of one element"); auto const ga = GlobalAddress::from_global(AddressSpace::extmem.to_global_omnibus() + next_offset); next_offset += 0x100; __vector uint8_t data = vec_splat_u8(0x2); // clang-format off asm volatile( "fxvstax %[data], %[base], %[index]\n" "sync\n" :: [data] "qv" (data), [base] "b" (ga.to_extmem().to_scalar_addr()), [index] "r" (0) : "memory" ); // clang-format on auto const val = *ga.to_extmem().to_scalar<uint8_t>(); test_equal(val, 0x2); testcase_end(); test_write_string("at address: "); test_write_string(to_hexstring(ga.to_global_omnibus()).data()); test_write_string("\n"); } { testcase_begin("Vector (fxvoutx) write to extmem (hioff(scalar) >> 4 | 1<<31), scalar read (generated) of one element"); auto const ga = GlobalAddress::from_global(AddressSpace::extmem.to_global_omnibus() + next_offset); next_offset += 0x100; __vector uint8_t data = vec_splat_u8(0x9); uint32_t const address = ((ga.to_extmem().to_scalar_addr() & 0x3fff'ffff) >> 4) | (1ull<<31); // clang-format off asm volatile( "fxvoutx %[data], %[base], %[index]\n" "sync\n" :: [data] "qv" (data), [base] "b" (address), [index] "r" (0) : "memory" ); // clang-format on auto const val = *ga.to_extmem().to_scalar<uint8_t>(); test_equal(val, 0x9); testcase_end(); test_write_string("at address: "); test_write_string(to_hexstring(ga.to_global_omnibus()).data()); test_write_string("\n"); } { testcase_begin("Vector (fxvoutx) write to extmem (fxviox address), scalar read (generated) of one element"); auto const ga = GlobalAddress::from_global(AddressSpace::extmem.to_global_omnibus() + next_offset); next_offset += 0x100; __vector uint8_t data = vec_splat_u8(0xb); // clang-format off asm volatile( "fxvoutx %[data], %[base], %[index]\n" "sync\n" :: [data] "qv" (data), [base] "b" (ga.to_extmem().to_fxviox_addr()), [index] "r" (0) : "memory" ); // clang-format on auto const val = *ga.to_extmem().to_scalar<uint8_t>(); test_equal(val, 0xb); testcase_end(); test_write_string("at address: "); test_write_string(to_hexstring(ga.to_global_omnibus()).data()); test_write_string("\n"); } test_summary(); test_shutdown(); }