Getting ppc tests building again (big surprise: they are failing).

This commit is contained in:
Ben Vanik
2014-09-09 20:25:38 -07:00
parent 437ec45d66
commit a337ce33ed
63 changed files with 471 additions and 453 deletions

View File

@@ -1,132 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/alloy.h>
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h>
#include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_frontend.h>
#include <alloy/runtime/raw_module.h>
#include <poly/main.h>
#include <poly/poly.h>
#include <gflags/gflags.h>
namespace alloy {
namespace sandbox {
using alloy::frontend::ppc::PPCContext;
using alloy::runtime::Runtime;
class ThreadState : public alloy::runtime::ThreadState {
public:
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
size_t stack_size, uint64_t thread_state_address)
: alloy::runtime::ThreadState(runtime, thread_id),
stack_address_(stack_address),
stack_size_(stack_size),
thread_state_address_(thread_state_address) {
memset(memory_->Translate(stack_address_), 0, stack_size_);
// Allocate with 64b alignment.
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
assert_true((reinterpret_cast<uint64_t>(context_) & 0xF) == 0);
// Stash pointers to common structures that callbacks may need.
context_->reserve_address = memory_->reserve_address();
context_->membase = memory_->membase();
context_->runtime = runtime;
context_->thread_state = this;
// Set initial registers.
context_->r[1] = stack_address_ + stack_size;
context_->r[13] = thread_state_address_;
// Pad out stack a bit, as some games seem to overwrite the caller by about
// 16 to 32b.
context_->r[1] -= 64;
raw_context_ = context_;
runtime_->debugger()->OnThreadCreated(this);
}
~ThreadState() override {
runtime_->debugger()->OnThreadDestroyed(this);
free(context_);
}
PPCContext* context() const { return context_; }
private:
uint64_t stack_address_;
size_t stack_size_;
uint64_t thread_state_address_;
// NOTE: must be 64b aligned for SSE ops.
PPCContext* context_;
};
// TODO(benvanik): simple memory? move more into core?
int main(std::vector<std::wstring>& args) {
#if XE_OPTION_PROFILING
xe::Profiler::Initialize();
xe::Profiler::ThreadEnter("main");
#endif // XE_OPTION_PROFILING
size_t memory_size = 16 * 1024 * 1024;
auto memory = std::make_unique<SimpleMemory>(memory_size);
auto runtime = std::make_unique<Runtime>(memory.get());
auto frontend =
std::make_unique<alloy::frontend::ppc::PPCFrontend>(runtime.get());
std::unique_ptr<alloy::backend::Backend> backend;
// backend =
// std::make_unique<alloy::backend::ivm::IVMBackend>(runtime.get());
// backend =
// std::make_unique<alloy::backend::x64::X64Backend>(runtime.get());
runtime->Initialize(std::move(frontend), std::move(backend));
auto module = std::make_unique<alloy::runtime::RawModule>(runtime.get());
module->LoadFile(0x00001000, L"test\\codegen\\instr_add.bin");
runtime->AddModule(std::move(module));
{
uint64_t stack_size = 64 * 1024;
uint64_t stack_address = memory_size - stack_size;
uint64_t thread_state_address = stack_address - 0x1000;
auto thread_state = std::make_unique<ThreadState>(
runtime.get(), 100, stack_address, stack_size, thread_state_address);
alloy::runtime::Function* fn;
runtime->ResolveFunction(0x1000, &fn);
auto ctx = thread_state->context();
ctx->lr = 0xBEBEBEBE;
ctx->r[5] = 10;
ctx->r[25] = 25;
fn->Call(thread_state.get(), ctx->lr);
auto result = ctx->r[11];
printf("%llu", result);
}
runtime.reset();
memory.reset();
#if XE_OPTION_PROFILING
xe::Profiler::Dump();
xe::Profiler::ThreadExit();
#endif // XE_OPTION_PROFILING
return 0;
}
} // namespace sandbox
} // namespace alloy
DEFINE_ENTRY_POINT(L"alloy-sandbox", L"?", alloy::sandbox::main);

View File

@@ -1,28 +0,0 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'targets': [
{
'target_name': 'alloy-sandbox',
'type': 'executable',
'msvs_settings': {
'VCLinkerTool': {
'SubSystem': '1'
},
},
'dependencies': [
'alloy',
'xenia',
],
'include_dirs': [
'.',
],
'sources': [
'alloy-sandbox.cc',
],
},
],
}

View File

@@ -1,44 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#define CATCH_CONFIG_RUNNER
#include <third_party/catch/single_include/catch.hpp>
#include <tools/alloy-test/util.h>
namespace alloy {
namespace test {
using alloy::frontend::ppc::PPCContext;
using alloy::runtime::Runtime;
int main(std::vector<std::wstring>& args) {
std::vector<std::string> narrow_args;
auto narrow_argv = new char* [args.size()];
for (size_t i = 0; i < args.size(); ++i) {
auto narrow_arg = poly::to_string(args[i]);
narrow_argv[i] = const_cast<char*>(narrow_arg.data());
narrow_args.push_back(std::move(narrow_arg));
}
int ret = Catch::Session().run(int(args.size()), narrow_argv);
if (ret) {
#if XE_LIKE_WIN32
// Visual Studio kills the console on shutdown, so prevent that.
if (poly::debugging::IsDebuggerAttached()) {
poly::debugging::Break();
}
#endif // XE_LIKE_WIN32
}
return ret;
}
} // namespace test
} // namespace alloy
DEFINE_ENTRY_POINT(L"alloy-test", L"?", alloy::test::main);

View File

@@ -1,92 +0,0 @@
# Copyright 2014 Ben Vanik. All Rights Reserved.
{
'targets': [
{
'target_name': 'alloy-test',
'type': 'executable',
'msvs_settings': {
'VCLinkerTool': {
'SubSystem': '1'
},
},
'dependencies': [
'alloy',
'xenia',
],
'include_dirs': [
'.',
],
'sources': [
'alloy-test.cc',
#'test_abs.cc',
'test_add.cc',
#'test_add_carry.cc',
#'test_and.cc',
#'test_assign.cc',
#'test_atomic_add.cc',
#'test_atomic_exchange.cc',
#'test_atomic_sub.cc',
#'test_branch.cc',
#'test_byte_swap.cc',
#'test_cast.cc',
#'test_cntlz.cc',
#'test_compare.cc',
#'test_compare_exchange.cc',
#'test_convert.cc',
#'test_did_carry.cc',
#'test_div.cc',
#'test_dot_product_3.cc',
#'test_dot_product_4.cc',
'test_extract.cc',
'test_insert.cc',
#'test_is_true_false.cc',
#'test_load_clock.cc',
'test_load_vector_shl_shr.cc',
#'test_log2.cc',
#'test_max.cc',
#'test_min.cc',
#'test_mul.cc',
#'test_mul_add.cc',
#'test_mul_hi.cc',
#'test_mul_sub.cc',
#'test_neg.cc',
#'test_not.cc',
#'test_or.cc',
'test_pack.cc',
'test_permute.cc',
#'test_pow2.cc',
#'test_rotate_left.cc',
#'test_round.cc',
#'test_rsqrt.cc',
#'test_select.cc',
'test_sha.cc',
'test_shl.cc',
'test_shr.cc',
#'test_sign_extend.cc',
#'test_splat.cc',
#'test_sqrt.cc',
#'test_sub.cc',
'test_swizzle.cc',
#'test_truncate.cc',
'test_unpack.cc',
'test_vector_add.cc',
#'test_vector_compare.cc',
#'test_vector_convert.cc',
'test_vector_max.cc',
'test_vector_min.cc',
'test_vector_rotate_left.cc',
'test_vector_sha.cc',
'test_vector_shl.cc',
'test_vector_shr.cc',
#'test_vector_sub.cc',
#'test_xor.cc',
#'test_zero_extend.cc',
'util.h',
],
},
],
}

View File

@@ -1,552 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("ADD_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 10;
ctx->r[5] = 25;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == 0x23);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = -10;
ctx->r[5] = -5;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == -15);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT8_MIN;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == INT8_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT8_MAX;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == UINT8_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT8_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == INT8_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT8_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<int8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("ADD_I8_CARRY", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE), ARITHMETIC_SET_CARRY);
StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT8_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT8_MAX;
ctx->r[5] = UINT8_MAX;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT8_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
}
TEST_CASE("ADD_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT16_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 10;
ctx->r[5] = 25;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == 0x23);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = -10;
ctx->r[5] = -5;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == -15);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT16_MIN;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == INT16_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT16_MAX;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == UINT16_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT16_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == INT16_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT16_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<int16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("ADD_I16_CARRY", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT16_TYPE), ARITHMETIC_SET_CARRY);
StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT16_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT16_MAX;
ctx->r[5] = UINT16_MAX;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT16_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
}
TEST_CASE("ADD_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT32_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 10;
ctx->r[5] = 25;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == 0x23);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = -10;
ctx->r[5] = -5;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == -15);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT32_MIN;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == INT32_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT32_MAX;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == UINT32_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT32_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == INT32_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT32_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<int32_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("ADD_I32_CARRY", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT32_TYPE), ARITHMETIC_SET_CARRY);
StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT32_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT32_MAX;
ctx->r[5] = UINT32_MAX;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT32_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
}
TEST_CASE("ADD_I64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.Add(LoadGPR(b, 4), LoadGPR(b, 5)));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 10;
ctx->r[5] = 25;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0x23);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = -10;
ctx->r[5] = -5;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == -15);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT64_MIN;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == INT64_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT64_MAX;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == UINT64_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT64_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == INT64_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT64_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
}
TEST_CASE("ADD_I64_CARRY", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT64_TYPE),
b.Truncate(LoadGPR(b, 5), INT64_TYPE), ARITHMETIC_SET_CARRY);
StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT64_MAX;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = UINT64_MAX;
ctx->r[5] = UINT64_MAX;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = INT64_MIN;
ctx->r[5] = -1;
},
[](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == 1);
});
}
TEST_CASE("ADD_F32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreFPR(b, 3, b.Convert(b.Add(b.Convert(LoadFPR(b, 4), FLOAT32_TYPE),
b.Convert(LoadFPR(b, 5), FLOAT32_TYPE)),
FLOAT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = 0.0;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == 0.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = 5.0;
ctx->f[5] = 7.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == 12.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = FLT_MAX / 2.0;
ctx->f[5] = FLT_MAX / 2.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == FLT_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = -100.0;
ctx->f[5] = -150.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == -250.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = FLT_MIN;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == FLT_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = FLT_MAX;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == FLT_MAX);
});
}
TEST_CASE("ADD_F64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreFPR(b, 3, b.Add(LoadFPR(b, 4), LoadFPR(b, 5)));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = 0.0;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == 0.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = 5.0;
ctx->f[5] = 7.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == 12.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = DBL_MAX / 2.0;
ctx->f[5] = DBL_MAX / 2.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == DBL_MAX);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = -100.0;
ctx->f[5] = -150.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == -250.0);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = DBL_MIN;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == DBL_MIN);
});
test.Run([](PPCContext* ctx) {
ctx->f[4] = DBL_MAX;
ctx->f[5] = 0.0;
},
[](PPCContext* ctx) {
auto result = ctx->f[3];
REQUIRE(result == DBL_MAX);
});
}

View File

@@ -1,141 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("EXTRACT_INT8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4),
b.Truncate(LoadGPR(b, 4), INT8_TYPE),
INT8_TYPE),
INT64_TYPE));
b.Return();
});
for (int i = 0; i < 16; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == i);
});
}
}
TEST_CASE("EXTRACT_INT8_CONSTANT", "[instr]") {
for (int i = 0; i < 16; ++i) {
TestFunction([i](hir::HIRBuilder& b) {
StoreGPR(b, 3,
b.ZeroExtend(
b.Extract(LoadVR(b, 4),
b.LoadConstant(int8_t(i)), INT8_TYPE),
INT64_TYPE));
b.Return();
}).Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == i);
});
}
}
TEST_CASE("EXTRACT_INT16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4),
b.Truncate(LoadGPR(b, 4), INT8_TYPE),
INT16_TYPE),
INT64_TYPE));
b.Return();
});
for (int i = 0; i < 8; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128s(0x0000, 0x1001, 0x2002, 0x3003, 0x4004,
0x5005, 0x6006, 0x7007);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == (i | (i << 12)));
});
}
}
TEST_CASE("EXTRACT_INT16_CONSTANT", "[instr]") {
for (int i = 0; i < 8; ++i) {
TestFunction([i](hir::HIRBuilder& b) {
StoreGPR(b, 3,
b.ZeroExtend(b.Extract(LoadVR(b, 4),
b.LoadConstant(int8_t(i)),
INT16_TYPE),
INT64_TYPE));
b.Return();
}).Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == i);
});
}
}
TEST_CASE("EXTRACT_INT32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4),
b.Truncate(LoadGPR(b, 4), INT8_TYPE),
INT32_TYPE),
INT64_TYPE));
b.Return();
});
for (int i = 0; i < 4; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128i(0, 1, 2, 3);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == i);
});
}
}
TEST_CASE("EXTRACT_INT32_CONSTANT", "[instr]") {
for (int i = 0; i < 4; ++i) {
TestFunction([i](hir::HIRBuilder& b) {
StoreGPR(b, 3,
b.ZeroExtend(b.Extract(LoadVR(b, 4),
b.LoadConstant(int8_t(i)),
INT32_TYPE),
INT64_TYPE));
b.Return();
}).Run([i](PPCContext* ctx) {
ctx->r[4] = i;
ctx->v[4] = vec128i(0, 1, 2, 3);
},
[i](PPCContext* ctx) {
auto result = ctx->r[3];
REQUIRE(result == i);
});
}
}

View File

@@ -1,83 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("INSERT_INT8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
for (int i = 0; i < 16; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15);
expected.i8[i ^ 0x3] = 100 + i;
REQUIRE(result == expected);
});
}
}
TEST_CASE("INSERT_INT16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4),
b.Truncate(LoadGPR(b, 5), INT16_TYPE)));
b.Return();
});
for (int i = 0; i < 8; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
expected.i16[i ^ 0x1] = 100 + i;
REQUIRE(result == expected);
});
}
}
TEST_CASE("INSERT_INT32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4),
b.Truncate(LoadGPR(b, 5), INT32_TYPE)));
b.Return();
});
for (int i = 0; i < 4; ++i) {
test.Run([i](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected = vec128i(0, 1, 2, 3);
expected.i32[i] = 100 + i;
REQUIRE(result == expected);
});
}
}

View File

@@ -1,78 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("LOAD_VECTOR_SHL", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.LoadVectorShl(b.Truncate(LoadGPR(b, 4), INT8_TYPE)));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 0; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 7; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 15; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 16; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15));
});
}
TEST_CASE("LOAD_VECTOR_SHR", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.LoadVectorShr(b.Truncate(LoadGPR(b, 4), INT8_TYPE)));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 0; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 7; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 15; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16));
});
test.Run([](PPCContext* ctx) { ctx->r[4] = 16; },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31));
});
}

View File

@@ -1,111 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("PACK_D3DCOLOR", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_D3DCOLOR));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128f(1.0f); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x3F800050, 0x3F800060, 0x3F800070, 0x3F800080);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x80506070));
});
}
TEST_CASE("PACK_FLOAT16_2", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_FLOAT16_2));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x3F800000); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x47FFE000, 0xC7FFE000, 0x00000000, 0x3F800000);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x7FFFFFFF));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x42AAA000, 0x44CCC000, 0x00000000, 0x3F800000);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x55556666));
});
}
TEST_CASE("PACK_FLOAT16_4", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_FLOAT16_4));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x449A4000, 0x45B17000, 0x41103261, 0x40922B6B);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x00000000, 0x00000000, 0x64D26D8C, 0x48824491));
});
}
TEST_CASE("PACK_SHORT_2", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_SHORT_2));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0x43817E00, 0xC37CFC00, 0, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x7FFF8001));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0xC0D47D97, 0xC2256E9D, 0, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x80018001));
});
}

View File

@@ -1,139 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("PERMUTE_V128_BY_INT32_CONSTANT", "[instr]") {
{
uint32_t mask = PERMUTE_MASK(0, 0, 0, 1, 0, 2, 0, 3);
TestFunction([mask](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4),
LoadVR(b, 5), INT32_TYPE));
b.Return();
}).Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->v[5] = vec128i(4, 5, 6, 7);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 1, 2, 3));
});
}
{
uint32_t mask = PERMUTE_MASK(1, 0, 1, 1, 1, 2, 1, 3);
TestFunction([mask](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4),
LoadVR(b, 5), INT32_TYPE));
b.Return();
}).Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->v[5] = vec128i(4, 5, 6, 7);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(4, 5, 6, 7));
});
}
{
uint32_t mask = PERMUTE_MASK(0, 3, 0, 2, 0, 1, 0, 0);
TestFunction([mask](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4),
LoadVR(b, 5), INT32_TYPE));
b.Return();
}).Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->v[5] = vec128i(4, 5, 6, 7);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(3, 2, 1, 0));
});
}
{
uint32_t mask = PERMUTE_MASK(1, 3, 1, 2, 1, 1, 1, 0);
TestFunction([mask](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4),
LoadVR(b, 5), INT32_TYPE));
b.Return();
}).Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->v[5] = vec128i(4, 5, 6, 7);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(7, 6, 5, 4));
});
}
}
TEST_CASE("PERMUTE_V128_BY_V128", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3,
b.Permute(LoadVR(b, 3), LoadVR(b, 4), LoadVR(b, 5), VEC128_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[3] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[4] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15);
ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15));
});
test.Run([](PPCContext* ctx) {
ctx->v[3] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31);
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(116, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(116, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31));
});
test.Run([](PPCContext* ctx) {
ctx->v[3] =
vec128b(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
ctx->v[4] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15);
ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
3, 2, 1, 100));
});
test.Run([](PPCContext* ctx) {
ctx->v[3] = vec128b(31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20,
19, 18, 17, 16);
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 131);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(131, 30, 29, 28, 27, 26, 25, 24, 23, 22,
21, 20, 19, 18, 17, 16));
});
}

View File

@@ -1,211 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("SHA_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xF0;
ctx->r[5] = 4;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7F;
ctx->r[5] = 7;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHA_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF00;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFF;
ctx->r[5] = 15;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHA_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFF0000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80000000;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x80000000);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFF;
ctx->r[5] = 31;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHA_I64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.Sha(b.Truncate(LoadGPR(b, 4), INT64_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF00000000ull;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFFull;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFEull;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000000000000000ull;
ctx->r[5] = 64;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x8000000000000000ull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFFFFFFFFFFull;
ctx->r[5] = 63;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}

View File

@@ -1,211 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("SHL_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x0F;
ctx->r[5] = 4;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xF0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFE);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7F;
ctx->r[5] = 7;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0x80);
});
}
TEST_CASE("SHL_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x00FF;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFF00);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFE);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFF;
ctx->r[5] = 15;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0x8000);
});
}
TEST_CASE("SHL_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x0000FFFF;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF0000);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFE);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80000000;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x80000000);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFF;
ctx->r[5] = 31;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x80000000);
});
}
TEST_CASE("SHL_I64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.Shl(b.Truncate(LoadGPR(b, 4), INT64_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x00000000FFFFFFFFull;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF00000000ull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFFull;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFFFFFFFFFFull;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFEull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000000000000000ull;
ctx->r[5] = 64;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x8000000000000000ull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFFFFFFFFFFull;
ctx->r[5] = 63;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x8000000000000000ull);
});
}

View File

@@ -1,211 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("SHR_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xF0;
ctx->r[5] = 4;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0x0F);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0x7F);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7F;
ctx->r[5] = 7;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFF00;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0x00FF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0x7FFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFF;
ctx->r[5] = 15;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFF0000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x0000FFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x7FFFFFFF);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x80000000;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x80000000);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFF;
ctx->r[5] = 31;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.Shr(b.Truncate(LoadGPR(b, 4), INT64_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF00000000ull;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x00000000FFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFFull;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFEull;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x7FFFFFFFFFFFFFFFull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x8000000000000000ull;
ctx->r[5] = 64;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x8000000000000000ull);
});
test.Run([](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFFFFFFFFFFull;
ctx->r[5] = 63;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}

View File

@@ -1,46 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("SWIZZLE_V128", "[instr]") {
TestFunction([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE,
SWIZZLE_MASK(0, 1, 2, 3)));
b.Return();
}).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 1, 2, 3));
});
TestFunction([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE,
SWIZZLE_MASK(3, 2, 1, 0)));
b.Return();
}).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(3, 2, 1, 0));
});
TestFunction([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE,
SWIZZLE_MASK(1, 1, 2, 2)));
b.Return();
}).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(1, 1, 2, 2));
});
}

View File

@@ -1,162 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("UNPACK_D3DCOLOR", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_D3DCOLOR));
b.Return();
});
test.Run([](PPCContext* ctx) {
uint32_t value = 0;
ctx->v[4] = vec128i(0, 0, 0, value);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128f(1.0f, 1.0f, 1.0f, 1.0f));
});
test.Run([](PPCContext* ctx) {
uint32_t value = 0x80506070;
ctx->v[4] = vec128i(0, 0, 0, value);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x3F800050, 0x3F800060, 0x3F800070, 0x3F800080));
});
}
TEST_CASE("UNPACK_FLOAT16_2", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_FLOAT16_2));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 0, 0x3F800000));
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x7FFFFFFF); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x47FFE000, 0xC7FFE000, 0x00000000, 0x3F800000));
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x55556666); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x42AAA000, 0x44CCC000, 0x00000000, 0x3F800000));
});
}
TEST_CASE("UNPACK_FLOAT16_4", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_FLOAT16_4));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 0, 0, 0, 0x64D2, 0x6D8B, 0x4881, 0x4491);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x449A4000, 0x45B16000, 0x41102000, 0x40922000));
});
}
TEST_CASE("UNPACK_SHORT_2", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_SHORT_2));
b.Return();
});
test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); },
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x40400000, 0x40400000, 0x00000000, 0x3F800000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7004FD60, 0x8201C990, 0x00000000, 0x7FFF8001);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x40407FFF, 0x403F8001, 0x00000000, 0x3F800000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 0, 0, (0x1234u << 16) | 0x5678u);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x40401234, 0x40405678, 0x00000000, 0x3F800000));
});
}
// TEST_CASE("UNPACK_S8_IN_16_LO", "[instr]") {
// TestFunction test([](hir::HIRBuilder& b) {
// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S8_IN_16_LO));
// b.Return();
// });
// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); },
// [](PPCContext* ctx) {
// auto result = ctx->v[3];
// REQUIRE(result == vec128b(0));
// });
//}
//
// TEST_CASE("UNPACK_S8_IN_16_HI", "[instr]") {
// TestFunction test([](hir::HIRBuilder& b) {
// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S8_IN_16_HI));
// b.Return();
// });
// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); },
// [](PPCContext* ctx) {
// auto result = ctx->v[3];
// REQUIRE(result == vec128b(0));
// });
//}
//
// TEST_CASE("UNPACK_S16_IN_32_LO", "[instr]") {
// TestFunction test([](hir::HIRBuilder& b) {
// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S16_IN_32_LO));
// b.Return();
// });
// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); },
// [](PPCContext* ctx) {
// auto result = ctx->v[3];
// REQUIRE(result == vec128b(0));
// });
//}
//
// TEST_CASE("UNPACK_S16_IN_32_HI", "[instr]") {
// TestFunction test([](hir::HIRBuilder& b) {
// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S16_IN_32_HI));
// b.Return();
// });
// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); },
// [](PPCContext* ctx) {
// auto result = ctx->v[3];
// REQUIRE(result == vec128b(0));
// });
//}

View File

@@ -1,282 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_ADD_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(100, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
22, 24, 26, 28, 30));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128b(UINT8_MAX);
ctx->v[5] = vec128b(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0));
});
}
TEST_CASE("VECTOR_ADD_I8_SAT_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE,
ARITHMETIC_SATURATE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128b(INT8_MAX);
ctx->v[5] = vec128b(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(INT8_MAX));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128b(INT8_MIN);
ctx->v[5] = vec128b(-1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(INT8_MIN));
});
}
TEST_CASE("VECTOR_ADD_I8_SAT_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE,
ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128b(UINT8_MAX);
ctx->v[5] = vec128b(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(UINT8_MAX));
});
}
TEST_CASE("VECTOR_ADD_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
ctx->v[5] = vec128s(100, 1, 2, 3, 4, 5, 6, 7);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(100, 2, 4, 6, 8, 10, 12, 14));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(UINT16_MAX);
ctx->v[5] = vec128s(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0);
ctx->v[5] = vec128s(-1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(UINT16_MAX));
});
}
TEST_CASE("VECTOR_ADD_I16_SAT_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE,
ARITHMETIC_SATURATE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(INT16_MAX);
ctx->v[5] = vec128s(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(INT16_MAX));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(INT16_MIN);
ctx->v[5] = vec128s(-1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(INT16_MIN));
});
}
TEST_CASE("VECTOR_ADD_I16_SAT_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE,
ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(UINT16_MAX);
ctx->v[5] = vec128s(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(UINT16_MAX));
});
}
TEST_CASE("VECTOR_ADD_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->v[5] = vec128i(100, 1, 2, 3);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(100, 2, 4, 6));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(UINT32_MAX);
ctx->v[5] = vec128i(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0);
ctx->v[5] = vec128i(-1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(UINT32_MAX));
});
}
TEST_CASE("VECTOR_ADD_I32_SAT_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE,
ARITHMETIC_SATURATE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(5);
ctx->v[5] = vec128i(5);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(10));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(INT32_MAX);
ctx->v[5] = vec128i(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(INT32_MAX));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(INT32_MIN);
ctx->v[5] = vec128i(-1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(INT32_MIN));
});
}
TEST_CASE("VECTOR_ADD_I32_SAT_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE,
ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(5);
ctx->v[5] = vec128i(5);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(10));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(UINT32_MAX);
ctx->v[5] = vec128i(1);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(UINT32_MAX));
});
}
TEST_CASE("VECTOR_ADD_F32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), FLOAT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128f(0.12f, 0.34f, 0.56f, 0.78f);
ctx->v[5] = vec128f(0.12f, 0.34f, 0.56f, 0.78f);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x3E75C28F, 0x3F2E147B, 0x3F8F5C29, 0x3FC7AE14));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128f(FLT_MAX);
ctx->v[5] = vec128f(FLT_MAX);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0x7F800000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128f(-FLT_MIN);
ctx->v[5] = vec128f(-1.0f);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0xBF800000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128f(FLT_MAX);
ctx->v[5] = vec128f(1.0f);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0x7F7FFFFF));
});
}

View File

@@ -1,118 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_MAX_I8_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10,
INT8_MIN, INT8_MAX, 13, 2, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0, 1, 100, 3, 4, 5, 60, 7, 8, 9, 10, 11,
INT8_MAX, 13, 14, 15));
});
}
TEST_CASE("VECTOR_MAX_I8_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10,
INT8_MIN, INT8_MAX, 13, 2, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9,
10, INT8_MIN, INT8_MAX, 13, 14, 15));
});
}
TEST_CASE("VECTOR_MAX_I16_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7);
ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, SHRT_MAX, 6, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0, 1, 2, 3, 4, SHRT_MAX, 6, 7));
});
}
TEST_CASE("VECTOR_MAX_I16_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7);
ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, 6, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, -6000, 7));
});
}
TEST_CASE("VECTOR_MAX_I32_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 123, 3);
ctx->v[5] = vec128i(-1000000, 0, INT_MAX, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 1, INT_MAX, 3));
});
}
TEST_CASE("VECTOR_MAX_I32_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 123, 3);
ctx->v[5] = vec128i(-1000000, 0, UINT_MAX, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(-1000000, 1, UINT_MAX, 3));
});
}

View File

@@ -1,117 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_MIN_I8_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10,
INT8_MIN, INT8_MAX, 13, 2, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(-100, 1, 2, -3, 4, -5, 6, 7, -80, 9, 10,
INT8_MIN, 12, 13, 2, 0));
});
}
TEST_CASE("VECTOR_MIN_I8_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->v[5] = vec128b(255, 1, 200, -3, 4, -5, 60, 7, -80, 9, 10, 11,
12, 13, 2, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 2, 0));
});
}
TEST_CASE("VECTOR_MIN_I16_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7);
ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, SHRT_MAX, 6, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(-1000, 1, -2000, 3, 4, 5, -6000, 0));
});
}
TEST_CASE("VECTOR_MIN_I16_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7);
ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, 6, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0, 1, 2, 3, 4, 5, 6, 0));
});
}
TEST_CASE("VECTOR_MIN_I32_SIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 123, 3);
ctx->v[5] = vec128i(-1000000, 0, INT_MAX, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(-1000000, 0, 123, 0));
});
}
TEST_CASE("VECTOR_MIN_I32_UNSIGNED", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE,
ARITHMETIC_UNSIGNED));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 123, 3);
ctx->v[5] = vec128i(-1000000, 0, UINT_MAX, 0);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128i(0, 0, 123, 0));
});
}

View File

@@ -1,71 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <third_party/xbyak/xbyak/xbyak_bin2hex.h>
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_ROTATE_LEFT_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128b(B00000001);
ctx->v[5] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128b(B00000001, B00000010, B00000100, B00001000,
B00010000, B00100000, B01000000, B10000000,
B00000001, B00000010, B00000100, B00001000,
B00010000, B00100000, B01000000, B10000000));
});
}
TEST_CASE("VECTOR_ROTATE_LEFT_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x0001, 0x0001, 0x0001, 0x0001, 0x1000, 0x1000,
0x1000, 0x1000);
ctx->v[5] = vec128s(0, 1, 2, 3, 14, 15, 16, 17);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x0001, 0x0002, 0x0004, 0x0008, 0x0400,
0x0800, 0x1000, 0x2000));
});
}
TEST_CASE("VECTOR_ROTATE_LEFT_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x00000001, 0x00000001, 0x80000000, 0x80000000);
ctx->v[5] = vec128i(0, 1, 1, 2);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x00000001, 0x00000002, 0x00000001, 0x00000002));
});
}

View File

@@ -1,145 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_SHA_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
ctx->v[5] =
vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0xF8, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHA_I8_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128b(
0, 1, 2, 8, 4, 4, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15)),
INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0xF8, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHA_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0xFFFF,
0xFFFF, 0x0000, 0x1234));
});
}
TEST_CASE("VECTOR_SHA_I16_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128s(
0, 1, 8, 15, 15, 8, 1, 16)),
INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0xFFFF,
0xFFFF, 0x0000, 0x1234));
});
}
TEST_CASE("VECTOR_SHA_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] = vec128i(0, 1, 16, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
ctx->v[5] = vec128i(31, 16, 1, 32);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x12345678));
});
}
TEST_CASE("VECTOR_SHA_I32_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3,
b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)),
INT32_TYPE));
StoreVR(b, 4,
b.VectorSha(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)),
INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000));
auto result2 = ctx->v[4];
REQUIRE(result2 ==
vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x12345678));
});
}

View File

@@ -1,145 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_SHL_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
ctx->v[5] =
vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0xFC, 0xF8, 0x7F, 0x00, 0xF0, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHL_I8_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128b(
0, 1, 2, 8, 4, 4, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15)),
INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0xFC, 0xF8, 0x7F, 0x00, 0xF0, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHL_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0xFFFC, 0xFE00, 0x8000, 0x0000,
0xFF00, 0x0002, 0x1234));
});
}
TEST_CASE("VECTOR_SHL_I16_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128s(
0, 1, 8, 15, 15, 8, 1, 16)),
INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0xFFFC, 0xFE00, 0x8000, 0x0000,
0xFF00, 0x0002, 0x1234));
});
}
TEST_CASE("VECTOR_SHL_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] = vec128i(0, 1, 16, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x7FFFFFFE, 0xFFFFFFFC, 0xFFFE0000, 0x80000000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
ctx->v[5] = vec128i(31, 16, 1, 32);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x00000000, 0xFFFF0000, 0x00000002, 0x12345678));
});
}
TEST_CASE("VECTOR_SHL_I32_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3,
b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)),
INT32_TYPE));
StoreVR(b, 4,
b.VectorShl(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)),
INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0x7FFFFFFE, 0xFFFFFFFC, 0xFFFE0000, 0x80000000));
auto result2 = ctx->v[4];
REQUIRE(result2 ==
vec128i(0x00000000, 0xFFFF0000, 0x00000002, 0x12345678));
});
}

View File

@@ -1,145 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <tools/alloy-test/util.h>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
TEST_CASE("VECTOR_SHR_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
ctx->v[5] =
vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0x08, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHR_I8_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128b(
0, 1, 2, 8, 4, 4, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15)),
INT8_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0x08, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00));
});
}
TEST_CASE("VECTOR_SHR_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0x0001,
0x00FF, 0x0000, 0x1234));
});
}
TEST_CASE("VECTOR_SHR_I16_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128s(
0, 1, 8, 15, 15, 8, 1, 16)),
INT16_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF,
0x0001, 0x1234);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0x0001,
0x00FF, 0x0000, 0x1234));
});
}
TEST_CASE("VECTOR_SHR_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] = vec128i(0, 1, 16, 31);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000));
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
ctx->v[5] = vec128i(31, 16, 1, 32);
},
[](PPCContext* ctx) {
auto result = ctx->v[3];
REQUIRE(result ==
vec128i(0x00000001, 0x0000FFFF, 0x00000000, 0x12345678));
});
}
TEST_CASE("VECTOR_SHR_I32_CONSTANT", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3,
b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)),
INT32_TYPE));
StoreVR(b, 4,
b.VectorShr(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)),
INT32_TYPE));
b.Return();
});
test.Run([](PPCContext* ctx) {
ctx->v[4] =
vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF);
ctx->v[5] =
vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000));
auto result2 = ctx->v[4];
REQUIRE(result2 ==
vec128i(0x00000001, 0x0000FFFF, 0x00000000, 0x12345678));
});
}

View File

@@ -1,181 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_TEST_UTIL_H_
#define ALLOY_TEST_UTIL_H_
#include <alloy/alloy.h>
#include <alloy/backend/ivm/ivm_backend.h>
#include <alloy/backend/x64/x64_backend.h>
#include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_frontend.h>
#include <alloy/hir/hir_builder.h>
#include <alloy/runtime/test_module.h>
#include <poly/main.h>
#include <poly/poly.h>
#include <third_party/catch/single_include/catch.hpp>
#define ALLOY_TEST_IVM 1
#define ALLOY_TEST_X64 1
namespace alloy {
namespace test {
using alloy::frontend::ppc::PPCContext;
using alloy::runtime::Runtime;
class ThreadState : public alloy::runtime::ThreadState {
public:
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
size_t stack_size, uint64_t thread_state_address)
: alloy::runtime::ThreadState(runtime, thread_id),
stack_address_(stack_address),
stack_size_(stack_size),
thread_state_address_(thread_state_address) {
memset(memory_->Translate(stack_address_), 0, stack_size_);
// Allocate with 64b alignment.
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
assert_true((reinterpret_cast<uint64_t>(context_) & 0xF) == 0);
// Stash pointers to common structures that callbacks may need.
context_->reserve_address = memory_->reserve_address();
context_->membase = memory_->membase();
context_->runtime = runtime;
context_->thread_state = this;
// Set initial registers.
context_->r[1] = stack_address_ + stack_size;
context_->r[13] = thread_state_address_;
// Pad out stack a bit, as some games seem to overwrite the caller by about
// 16 to 32b.
context_->r[1] -= 64;
raw_context_ = context_;
runtime_->debugger()->OnThreadCreated(this);
}
~ThreadState() override {
runtime_->debugger()->OnThreadDestroyed(this);
free(context_);
}
PPCContext* context() const { return context_; }
private:
uint64_t stack_address_;
size_t stack_size_;
uint64_t thread_state_address_;
// NOTE: must be 64b aligned for SSE ops.
PPCContext* context_;
};
class TestFunction {
public:
TestFunction(std::function<void(hir::HIRBuilder& b)> generator) {
memory_size = 16 * 1024 * 1024;
memory.reset(new SimpleMemory(memory_size));
#if ALLOY_TEST_IVM
{
auto runtime = std::make_unique<Runtime>(memory.get());
auto frontend =
std::make_unique<alloy::frontend::ppc::PPCFrontend>(runtime.get());
auto backend =
std::make_unique<alloy::backend::ivm::IVMBackend>(runtime.get());
runtime->Initialize(std::move(frontend), std::move(backend));
runtimes.emplace_back(std::move(runtime));
}
#endif // ALLOY_TEST_IVM
#ifdef ALLOY_TEST_X64
{
auto runtime = std::make_unique<Runtime>(memory.get());
auto frontend =
std::make_unique<alloy::frontend::ppc::PPCFrontend>(runtime.get());
auto backend =
std::make_unique<alloy::backend::x64::X64Backend>(runtime.get());
runtime->Initialize(std::move(frontend), std::move(backend));
runtimes.emplace_back(std::move(runtime));
}
#endif // ALLOY_TEST_X64
for (auto& runtime : runtimes) {
auto module = std::make_unique<alloy::runtime::TestModule>(
runtime.get(), "Test",
[](uint64_t address) { return address == 0x1000; },
[generator](hir::HIRBuilder& b) {
generator(b);
return true;
});
runtime->AddModule(std::move(module));
}
}
~TestFunction() {
runtimes.clear();
memory.reset();
}
void Run(std::function<void(PPCContext*)> pre_call,
std::function<void(PPCContext*)> post_call) {
for (auto& runtime : runtimes) {
memory->Zero(0, memory_size);
alloy::runtime::Function* fn;
runtime->ResolveFunction(0x1000, &fn);
uint64_t stack_size = 64 * 1024;
uint64_t stack_address = memory_size - stack_size;
uint64_t thread_state_address = stack_address - 0x1000;
auto thread_state = std::make_unique<ThreadState>(
runtime.get(), 100, stack_address, stack_size, thread_state_address);
auto ctx = thread_state->context();
ctx->lr = 0xBEBEBEBE;
pre_call(ctx);
fn->Call(thread_state.get(), ctx->lr);
post_call(ctx);
}
}
size_t memory_size;
std::unique_ptr<Memory> memory;
std::vector<std::unique_ptr<Runtime>> runtimes;
};
inline hir::Value* LoadGPR(hir::HIRBuilder& b, int reg) {
return b.LoadContext(offsetof(PPCContext, r) + reg * 8, hir::INT64_TYPE);
}
inline void StoreGPR(hir::HIRBuilder& b, int reg, hir::Value* value) {
b.StoreContext(offsetof(PPCContext, r) + reg * 8, value);
}
inline hir::Value* LoadFPR(hir::HIRBuilder& b, int reg) {
return b.LoadContext(offsetof(PPCContext, f) + reg * 8, hir::FLOAT64_TYPE);
}
inline void StoreFPR(hir::HIRBuilder& b, int reg, hir::Value* value) {
b.StoreContext(offsetof(PPCContext, f) + reg * 8, value);
}
inline hir::Value* LoadVR(hir::HIRBuilder& b, int reg) {
return b.LoadContext(offsetof(PPCContext, v) + reg * 16, hir::VEC128_TYPE);
}
inline void StoreVR(hir::HIRBuilder& b, int reg, hir::Value* value) {
b.StoreContext(offsetof(PPCContext, v) + reg * 16, value);
}
} // namespace test
} // namespace alloy
#endif // ALLOY_TEST_UTIL_H_

View File

@@ -1,11 +1,8 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'includes': [
'alloy-sandbox/alloy-sandbox.gypi',
'alloy-test/alloy-test.gypi',
'xenia-compare/xenia-compare.gypi',
'xenia-debug/xenia-debug.gypi',
'xenia-run/xenia-run.gypi',
#'xenia-test/xenia-test.gypi',
],
}

View File

@@ -1,292 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/xenia.h>
#if !XE_LIKE(WIN32)
#include <dirent.h>
#endif // !WIN32
#include <gflags/gflags.h>
#include <poly/main.h>
using namespace std;
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
#if XE_LIKE(WIN32)
DEFINE_string(test_path, "test\\codegen\\",
"Directory scanned for test files.");
#else
DEFINE_string(test_path, "test/codegen/",
"Directory scanned for test files.");
#endif // WIN32
typedef vector<pair<string, string> > annotations_list_t;
int read_annotations(string& src_file_path, annotations_list_t& annotations) {
// TODO(benvanik): use PAL instead of this
FILE* f = fopen(src_file_path.c_str(), "r");
char line_buffer[BUFSIZ];
while (fgets(line_buffer, sizeof(line_buffer), f)) {
if (strlen(line_buffer) > 3 &&
line_buffer[0] == '#' &&
line_buffer[1] == ' ') {
// Comment - check if formed like an annotation.
// We don't actually verify anything here.
char* next_space = strchr(line_buffer + 3, ' ');
if (next_space) {
// Looks legit.
string key = string(line_buffer + 2, next_space);
string value = string(next_space + 1);
while (value.find_last_of(" \t\n") == value.size() - 1) {
value.erase(value.end() - 1);
}
annotations.push_back(pair<string, string>(key, value));
}
}
}
fclose(f);
return 0;
}
int setup_test_state(xe_memory_ref memory, Processor* processor,
ThreadState* thread_state,
annotations_list_t& annotations) {
xe_ppc_state_t* ppc_state = thread_state->ppc_state();
for (annotations_list_t::iterator it = annotations.begin();
it != annotations.end(); ++it) {
if (it->first == "REGISTER_IN") {
size_t space_pos = it->second.find(" ");
string reg_name = it->second.substr(0, space_pos);
string reg_value = it->second.substr(space_pos + 1);
ppc_state->SetRegFromString(reg_name.c_str(), reg_value.c_str());
}
}
return 0;
}
int check_test_results(xe_memory_ref memory, Processor* processor,
ThreadState* thread_state,
annotations_list_t& annotations) {
xe_ppc_state_t* ppc_state = thread_state->ppc_state();
char actual_value[2048];
bool any_failed = false;
for (annotations_list_t::iterator it = annotations.begin();
it != annotations.end(); ++it) {
if (it->first == "REGISTER_OUT") {
size_t space_pos = it->second.find(" ");
string reg_name = it->second.substr(0, space_pos);
string reg_value = it->second.substr(space_pos + 1);
if (!ppc_state->CompareRegWithString(
reg_name.c_str(), reg_value.c_str(),
actual_value, XECOUNT(actual_value))) {
any_failed = true;
printf("Register %s assert failed:\n", reg_name.c_str());
printf(" Expected: %s == %s\n", reg_name.c_str(), reg_value.c_str());
printf(" Actual: %s == %s\n", reg_name.c_str(), actual_value);
}
}
}
return any_failed;
}
int run_test(string& src_file_path) {
int result_code = 1;
// test.s -> test.bin
string bin_file_path;
size_t dot = src_file_path.find_last_of(".s");
bin_file_path = src_file_path;
bin_file_path.replace(dot - 1, 2, ".bin");
xe_memory_ref memory = NULL;
shared_ptr<Backend> backend;
shared_ptr<Processor> processor;
shared_ptr<Runtime> runtime;
annotations_list_t annotations;
ThreadState* thread_state = NULL;
XEEXPECTZERO(read_annotations(src_file_path, annotations));
while (!memory) {
xe_memory_options_t memory_options;
xe_zero_struct(&memory_options, sizeof(memory_options));
memory = xe_memory_create(memory_options);
}
backend = shared_ptr<Backend>(new xe::cpu::x64::X64Backend());
processor = shared_ptr<Processor>(new Processor(memory, backend));
XEEXPECTZERO(processor->Setup());
runtime = shared_ptr<Runtime>(new Runtime(processor, XT("")));
// Load the binary module.
#if XE_WCHAR
xechar_t bin_file_path_str[XE_MAX_PATH];
XEEXPECTTRUE(xestrwiden(bin_file_path_str, XECOUNT(bin_file_path_str),
bin_file_path.c_str()));
#else
const xechar_t* bin_file_path_str = bin_file_path.c_str();
#endif // XE_CHAR
XEEXPECTZERO(processor->LoadRawBinary(bin_file_path_str, 0x82010000));
// Simulate a thread.
thread_state = processor->AllocThread(256 * 1024, 0, 100);
// Setup test state from annotations.
XEEXPECTZERO(setup_test_state(memory, processor.get(), thread_state,
annotations));
// Execute test.
XEEXPECTZERO(processor->Execute(thread_state, 0x82010000));
// Assert test state expectations.
XEEXPECTZERO(check_test_results(memory, processor.get(), thread_state,
annotations));
result_code = 0;
XECLEANUP:
if (processor && thread_state) {
processor->DeallocThread(thread_state);
}
runtime.reset();
processor.reset();
xe_memory_release(memory);
return result_code;
}
int discover_tests(string& test_path,
vector<string>& test_files) {
// TODO(benvanik): use PAL instead of this.
#if XE_LIKE(WIN32)
string search_path = test_path;
search_path.append("\\*.s");
WIN32_FIND_DATAA ffd;
HANDLE hFind = FindFirstFileA(search_path.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE) {
XELOGE("Unable to find test path %s", test_path.c_str());
return 1;
}
do {
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
string file_name = string(ffd.cFileName);
string file_path = test_path;
if (*(test_path.end() - 1) != '\\') {
file_path += "\\";
}
file_path += file_name;
test_files.push_back(file_path);
}
} while (FindNextFileA(hFind, &ffd));
FindClose(hFind);
#else
DIR* d = opendir(test_path.c_str());
if (!d) {
XELOGE("Unable to find test path %s", test_path.c_str());
return 1;
}
struct dirent* dir;
while ((dir = readdir(d))) {
if (dir->d_type == DT_REG) {
// Only return .s files.
string file_name = string(dir->d_name);
if (file_name.rfind(".s") != string::npos) {
string file_path = test_path;
if (*(test_path.end() - 1) != '/') {
file_path += "/";
}
file_path += file_name;
test_files.push_back(file_path);
}
}
}
closedir(d);
#endif // WIN32
return 0;
}
int run_tests(std::string& test_name) {
int result_code = 1;
int failed_count = 0;
int passed_count = 0;
vector<string> test_files;
XEEXPECTZERO(discover_tests(FLAGS_test_path, test_files));
if (!test_files.size()) {
printf("No tests discovered - invalid path?\n");
XEFAIL();
}
printf("%d tests discovered.\n", (int)test_files.size());
printf("\n");
for (vector<string>::iterator it = test_files.begin();
it != test_files.end(); ++it) {
if (test_name.length() && *it != test_name) {
continue;
}
printf("Running %s...\n", (*it).c_str());
if (run_test(*it)) {
printf("TEST FAILED\n");
failed_count++;
} else {
printf("Passed\n");
passed_count++;
}
}
printf("\n");
printf("Total tests: %d\n", failed_count + passed_count);
printf("Passed: %d\n", passed_count);
printf("Failed: %d\n", failed_count);
result_code = failed_count ? 1 : 0;
XECLEANUP:
return result_code;
}
int xenia_test(int argc, xechar_t **argv) {
int result_code = 1;
// Grab test name, if present.
const xechar_t* test_name = NULL;
if (argc >= 2) {
test_name = argv[1];
}
string test_name_str;
if (test_name) {
#if XE_WCHAR
char test_name_buffer[XE_MAX_PATH];
XEIGNORE(xestrnarrow(test_name_buffer, XECOUNT(test_name_buffer),
test_name));
test_name_str = test_name_buffer;
#else
test_name_str = test_name;
#endif // XE_WCHAR
}
result_code = run_tests(test_name_str);
return result_code;
}
DEFINE_ENTRY_POINT(L"xenia-test", L"xenia-test some.xex", xenia_test);

View File

@@ -1,27 +0,0 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'targets': [
{
'target_name': 'xenia-test',
'type': 'executable',
'msvs_settings': {
'VCLinkerTool': {
'SubSystem': '1',
},
},
'dependencies': [
'xenia',
],
'include_dirs': [
'.',
],
'sources': [
'xenia-test.cc',
],
},
],
}