[a64] Optimize OPCODE_MEMSET with zva
* Add unit tests * Use `dc zva` to zero out entire cache-lines worth of data, when possible * Special instruction that zaps an entire cache-line into being zero-values, typically 64-bytes at a time * Statically read and initialize the `DCZID_EL0` register value since reading registers with `mrs` can be kinda slow and isn't worth doing redundantly at JIT-time when it never changes. * Update store-instructions to use inline post-increments to avoid an additional `add` instruction and keep encoded instruction immediates small Pretty much every arm processor has a cache line size of 64 bytes, so a typical `dcbz128` to clear 128-bytes of data now results in: ``` dc zva, x0 add x0, x0, 64 dc zva, x0 ``` rather than a sequence of 8 `stp xzr, xzr, ...` instructions
This commit is contained in:
@@ -241,6 +241,49 @@ TEST_CASE("STORE_F64_CONSTANT_BYTE_SWAP", "[instr]") {
|
||||
});
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// MEMSET — constant size
|
||||
// =============================================================================
|
||||
TEST_CASE("MEMSET_32_ZERO", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
auto addr = LoadGPR(b, 4);
|
||||
b.Memset(addr, b.LoadZeroInt8(), b.LoadConstantInt64(32));
|
||||
b.Return();
|
||||
});
|
||||
test.Run(
|
||||
[&test](PPCContext* ctx) {
|
||||
uint32_t addr = test.memory->SystemHeapAlloc(32, 32);
|
||||
ctx->r[4] = addr;
|
||||
},
|
||||
[&test](PPCContext* ctx) {
|
||||
auto* host =
|
||||
test.memory->TranslateVirtual(static_cast<uint32_t>(ctx->r[4]));
|
||||
const uint8_t result[32] = {};
|
||||
REQUIRE(std::memcmp(result, host, 32) == 0);
|
||||
test.memory->SystemHeapFree(static_cast<uint32_t>(ctx->r[4]));
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE("MEMSET_128_ZERO", "[instr]") {
|
||||
TestFunction test([](HIRBuilder& b) {
|
||||
auto addr = LoadGPR(b, 4);
|
||||
b.Memset(addr, b.LoadZeroInt8(), b.LoadConstantInt64(128));
|
||||
b.Return();
|
||||
});
|
||||
test.Run(
|
||||
[&test](PPCContext* ctx) {
|
||||
uint32_t addr = test.memory->SystemHeapAlloc(128, 128);
|
||||
ctx->r[4] = addr;
|
||||
},
|
||||
[&test](PPCContext* ctx) {
|
||||
auto* host =
|
||||
test.memory->TranslateVirtual(static_cast<uint32_t>(ctx->r[4]));
|
||||
const uint8_t result[128] = {};
|
||||
REQUIRE(std::memcmp(result, host, 128) == 0);
|
||||
test.memory->SystemHeapFree(static_cast<uint32_t>(ctx->r[4]));
|
||||
});
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// LOAD_F32 / LOAD_F64 byte-swap (entirely unimplemented on x64)
|
||||
// =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user