94 lines
3.3 KiB
Text
94 lines
3.3 KiB
Text
// Generated by rexglue recompile-tests
|
|
// DO NOT EDIT - this file is auto-generated
|
|
|
|
#include <catch2/catch_test_macros.hpp>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
#include "ppc_config.h"
|
|
#include <rex/ppc.h>
|
|
#include <rex/system/xmemory.h>
|
|
#include "ppc_test_decls.h"
|
|
|
|
// Global memory instance - same class used by real runtime
|
|
static rex::memory::Memory& get_memory() {
|
|
static rex::memory::Memory memory;
|
|
static bool initialized = false;
|
|
if (!initialized) {
|
|
if (!memory.Initialize()) {
|
|
throw std::runtime_error("Failed to initialize memory");
|
|
}
|
|
// Allocate test memory region starting after null guard page (0x10000)
|
|
auto* heap = memory.LookupHeap(0x10000);
|
|
if (heap) {
|
|
// Allocate from end of guard page (0x10000) up to cover test addresses
|
|
heap->AllocFixed(0x10000, 0x10000000, 0x1000,
|
|
rex::memory::kMemoryAllocationReserve | rex::memory::kMemoryAllocationCommit,
|
|
rex::memory::kMemoryProtectRead | rex::memory::kMemoryProtectWrite);
|
|
}
|
|
initialized = true;
|
|
}
|
|
return memory;
|
|
}
|
|
|
|
## for test in tests
|
|
TEST_CASE("{{ test.name }}", "[ppc][{{ test.category }}][{{ test.stem }}]") {
|
|
auto& mem = get_memory();
|
|
uint8_t* memory = mem.virtual_membase();
|
|
PPCContext ctx{};
|
|
ctx.fpscr.loadFromHost();
|
|
|
|
## for reg in test.inputs.registers
|
|
## if reg.type == "cr"
|
|
ctx.cr0.set_raw(({{ reg.value }} >> 28) & 0xF);
|
|
ctx.cr1.set_raw(({{ reg.value }} >> 24) & 0xF);
|
|
ctx.cr2.set_raw(({{ reg.value }} >> 20) & 0xF);
|
|
ctx.cr3.set_raw(({{ reg.value }} >> 16) & 0xF);
|
|
ctx.cr4.set_raw(({{ reg.value }} >> 12) & 0xF);
|
|
ctx.cr5.set_raw(({{ reg.value }} >> 8) & 0xF);
|
|
ctx.cr6.set_raw(({{ reg.value }} >> 4) & 0xF);
|
|
ctx.cr7.set_raw({{ reg.value }} & 0xF);
|
|
## else if reg.type == "vector"
|
|
ctx.{{ reg.reg }}.u32[3] = 0x{{ reg.values.0 }};
|
|
ctx.{{ reg.reg }}.u32[2] = 0x{{ reg.values.1 }};
|
|
ctx.{{ reg.reg }}.u32[1] = 0x{{ reg.values.2 }};
|
|
ctx.{{ reg.reg }}.u32[0] = 0x{{ reg.values.3 }};
|
|
## else if reg.type == "float"
|
|
ctx.{{ reg.reg }}.f64 = {{ reg.value }};
|
|
## else
|
|
ctx.{{ reg.reg }}.u64 = {{ reg.value }};
|
|
## endif
|
|
## endfor
|
|
## for mem_in in test.inputs.memory
|
|
## for entry in mem_in.bytes
|
|
memory[0x{{ mem_in.address }} + 0x{{ entry.offset }}] = 0x{{ entry.value }};
|
|
## endfor
|
|
## endfor
|
|
|
|
{{ test.symbol }}(ctx, memory);
|
|
|
|
## for reg in test.outputs.registers
|
|
## if reg.type == "cr"
|
|
{
|
|
uint32_t cr_actual = (ctx.cr0.raw() << 28) | (ctx.cr1.raw() << 24) | (ctx.cr2.raw() << 20) | (ctx.cr3.raw() << 16) | (ctx.cr4.raw() << 12) | (ctx.cr5.raw() << 8) | (ctx.cr6.raw() << 4) | ctx.cr7.raw();
|
|
REQUIRE(cr_actual == {{ reg.value }});
|
|
}
|
|
## else if reg.type == "vector"
|
|
REQUIRE(ctx.{{ reg.reg }}.u32[3] == 0x{{ reg.values.0 }});
|
|
REQUIRE(ctx.{{ reg.reg }}.u32[2] == 0x{{ reg.values.1 }});
|
|
REQUIRE(ctx.{{ reg.reg }}.u32[1] == 0x{{ reg.values.2 }});
|
|
REQUIRE(ctx.{{ reg.reg }}.u32[0] == 0x{{ reg.values.3 }});
|
|
## else if reg.type == "float"
|
|
REQUIRE(ctx.{{ reg.reg }}.f64 == {{ reg.value }});
|
|
## else
|
|
REQUIRE(ctx.{{ reg.reg }}.u64 == {{ reg.value }});
|
|
## endif
|
|
## endfor
|
|
## for mem_out in test.outputs.memory
|
|
## for entry in mem_out.bytes
|
|
REQUIRE(memory[0x{{ mem_out.address }} + 0x{{ entry.offset }}] == 0x{{ entry.value }});
|
|
## endfor
|
|
## endfor
|
|
}
|
|
|
|
## endfor
|