aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMerry <[email protected]>2024-01-28 17:02:37 +0000
committerMerry <[email protected]>2024-01-28 17:02:37 +0000
commita37f3673f8ca59a0c7046616247db1c6bc00e131 (patch)
treea3d77250e141722a96f32724d5cafb3d77c2e4ea
parent99c0a73f91e7a5e66db686f29e158e99193a043d (diff)
downloaddynarmic-a37f3673f8ca59a0c7046616247db1c6bc00e131.tar.gz
dynarmic-a37f3673f8ca59a0c7046616247db1c6bc00e131.zip
Squashed 'externals/oaknut/' changes from d0488d932..9d091109d
9d091109d oaknut: 2.0.1 7f3e9f600 oaknut: Support single argument constructor for CodeGenerator again git-subtree-dir: externals/oaknut git-subtree-split: 9d091109deb445bc6e9289c6195a282b7c993d49
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md4
-rw-r--r--include/oaknut/oaknut.hpp17
-rw-r--r--tests/basic.cpp20
-rw-r--r--tests/fpsimd.cpp24
-rw-r--r--tests/general.cpp24
-rw-r--r--tests/vector_code_gen.cpp10
7 files changed, 58 insertions, 43 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a0278d64..1ad90ba5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.8)
-project(oaknut LANGUAGES CXX VERSION 2.0.0)
+project(oaknut LANGUAGES CXX VERSION 2.0.1)
# Determine if we're built as a subproject (using add_subdirectory)
# or if this is the master project.
diff --git a/README.md b/README.md
index 8e32760b..a0e08450 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ EmittedFunction EmitExample(oaknut::CodeGenerator& code, int value)
int main()
{
oaknut::CodeBlock mem{4096};
- oaknut::CodeGenerator code{mem.ptr(), mem.ptr()};
+ oaknut::CodeGenerator code{mem.ptr()};
mem.unprotect();
@@ -47,7 +47,7 @@ int main()
}
```
-CodeGenerator takes two pointers. The first pointer is the memory address to write to, and the second pointer is the memory address that the code will be executing from. This allows you to write to a buffer before copying to the final destination for execution, or to have to use dual-mapped memory blocks to avoid memory protection overhead.
+CodeGenerator also has a constructor taking two pointers. The first pointer is the memory address to write to, and the second pointer is the memory address that the code will be executing from. This allows you to write to a buffer before copying to the final destination for execution, or to have to use dual-mapped memory blocks to avoid memory protection overhead.
Below is an example of using the oaknut-provided utility header for dual-mapped memory blocks:
diff --git a/include/oaknut/oaknut.hpp b/include/oaknut/oaknut.hpp
index aa80f81b..265a06a3 100644
--- a/include/oaknut/oaknut.hpp
+++ b/include/oaknut/oaknut.hpp
@@ -300,8 +300,21 @@ private:
std::uint32_t* const m_xmem;
};
-using CodeGenerator = BasicCodeGenerator<PointerCodeGeneratorPolicy>;
-using VectorCodeGenerator = BasicCodeGenerator<VectorCodeGeneratorPolicy>;
+struct CodeGenerator : BasicCodeGenerator<PointerCodeGeneratorPolicy> {
+public:
+ CodeGenerator(std::uint32_t* mem)
+ : BasicCodeGenerator<PointerCodeGeneratorPolicy>(mem, mem) {}
+ CodeGenerator(std::uint32_t* wmem, std::uint32_t* xmem)
+ : BasicCodeGenerator<PointerCodeGeneratorPolicy>(wmem, xmem) {}
+};
+
+struct VectorCodeGenerator : BasicCodeGenerator<VectorCodeGeneratorPolicy> {
+public:
+ VectorCodeGenerator(std::vector<std::uint32_t>& mem)
+ : BasicCodeGenerator<VectorCodeGeneratorPolicy>(mem, nullptr) {}
+ VectorCodeGenerator(std::vector<std::uint32_t>& wmem, std::uint32_t* xmem)
+ : BasicCodeGenerator<VectorCodeGeneratorPolicy>(wmem, xmem) {}
+};
namespace util {
diff --git a/tests/basic.cpp b/tests/basic.cpp
index 38342ca4..e621faec 100644
--- a/tests/basic.cpp
+++ b/tests/basic.cpp
@@ -18,7 +18,7 @@ using namespace oaknut::util;
TEST_CASE("Basic Test")
{
CodeBlock mem{4096};
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
mem.unprotect();
@@ -49,7 +49,7 @@ TEST_CASE("Basic Test (Dual)")
TEST_CASE("Fibonacci")
{
CodeBlock mem{4096};
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
mem.unprotect();
@@ -142,7 +142,7 @@ TEST_CASE("Immediate generation (32-bit)", "[slow]")
for (int i = 0; i < 0x100000; i++) {
const std::uint32_t value = RandInt<std::uint32_t>(0, 0xffffffff);
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -162,7 +162,7 @@ TEST_CASE("Immediate generation (64-bit)", "[slow]")
for (int i = 0; i < 0x100000; i++) {
const std::uint64_t value = RandInt<std::uint64_t>(0, 0xffffffff'ffffffff);
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -182,7 +182,7 @@ TEST_CASE("ADR", "[slow]")
for (std::int64_t i = -1048576; i < 1048576; i++) {
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem.ptr()) + i;
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
auto f = code.xptr<std::intptr_t (*)()>();
mem.unprotect();
@@ -218,7 +218,7 @@ TEST_CASE("ADRP", "[slow]")
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem.ptr()) + diff;
const std::uint64_t expect = static_cast<std::uint64_t>(value) & ~static_cast<std::uint64_t>(0xfff);
- CodeGenerator code{mem.ptr(), mem.ptr()};
+ CodeGenerator code{mem.ptr()};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -241,7 +241,7 @@ TEST_CASE("ADRL (near)")
const std::int64_t diff = i;
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem_ptr) + diff;
- CodeGenerator code{mem_ptr, mem_ptr};
+ CodeGenerator code{mem_ptr};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -264,7 +264,7 @@ TEST_CASE("ADRL (far)", "[slow]")
const std::int64_t diff = RandInt<std::int64_t>(-4294967296 + 100, 4294967295 - 100);
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem_ptr) + diff;
- CodeGenerator code{mem_ptr, mem_ptr};
+ CodeGenerator code{mem_ptr};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -288,7 +288,7 @@ TEST_CASE("MOVP2R (far)", "[slow]")
std::numeric_limits<std::int64_t>::max());
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem_ptr) + diff;
- CodeGenerator code{mem_ptr, mem_ptr};
+ CodeGenerator code{mem_ptr};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
@@ -310,7 +310,7 @@ TEST_CASE("MOVP2R (4GiB boundary)")
const auto test = [&](std::int64_t diff) {
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem_ptr) + diff;
- CodeGenerator code{mem_ptr, mem_ptr};
+ CodeGenerator code{mem_ptr};
auto f = code.xptr<std::uint64_t (*)()>();
mem.unprotect();
diff --git a/tests/fpsimd.cpp b/tests/fpsimd.cpp
index d164f8e6..e0cb0e26 100644
--- a/tests/fpsimd.cpp
+++ b/tests/fpsimd.cpp
@@ -8,18 +8,18 @@
#include "oaknut/oaknut.hpp"
-#define T(HEX, CMD) \
- TEST_CASE(#CMD) \
- { \
- using namespace oaknut; \
- using namespace oaknut::util; \
- \
- std::uint32_t result; \
- CodeGenerator code{&result, &result}; \
- \
- code.CMD; \
- \
- REQUIRE(result == HEX); \
+#define T(HEX, CMD) \
+ TEST_CASE(#CMD) \
+ { \
+ using namespace oaknut; \
+ using namespace oaknut::util; \
+ \
+ std::uint32_t result; \
+ CodeGenerator code{&result}; \
+ \
+ code.CMD; \
+ \
+ REQUIRE(result == HEX); \
}
T(0x5ee0bb61, ABS(D1, D27))
diff --git a/tests/general.cpp b/tests/general.cpp
index 0acb35f3..2caf4652 100644
--- a/tests/general.cpp
+++ b/tests/general.cpp
@@ -8,18 +8,18 @@
#include "oaknut/oaknut.hpp"
-#define T(HEX, CMD) \
- TEST_CASE(#CMD) \
- { \
- using namespace oaknut; \
- using namespace oaknut::util; \
- \
- std::uint32_t result; \
- CodeGenerator code{&result, &result}; \
- \
- code.CMD; \
- \
- REQUIRE(result == HEX); \
+#define T(HEX, CMD) \
+ TEST_CASE(#CMD) \
+ { \
+ using namespace oaknut; \
+ using namespace oaknut::util; \
+ \
+ std::uint32_t result; \
+ CodeGenerator code{&result}; \
+ \
+ code.CMD; \
+ \
+ REQUIRE(result == HEX); \
}
T(0x1a0f01c3, ADC(W3, W14, W15))
diff --git a/tests/vector_code_gen.cpp b/tests/vector_code_gen.cpp
index e06b135c..baceeeff 100644
--- a/tests/vector_code_gen.cpp
+++ b/tests/vector_code_gen.cpp
@@ -18,13 +18,14 @@ using namespace oaknut::util;
TEST_CASE("Basic Test (VectorCodeGenerator)")
{
- CodeBlock mem{4096};
std::vector<std::uint32_t> vec;
- VectorCodeGenerator code{vec, mem.ptr()};
+ VectorCodeGenerator code{vec};
code.MOV(W0, 42);
code.RET();
+ CodeBlock mem{4096};
+
mem.unprotect();
std::memcpy(mem.ptr(), vec.data(), vec.size() * sizeof(std::uint32_t));
mem.protect();
@@ -36,9 +37,8 @@ TEST_CASE("Basic Test (VectorCodeGenerator)")
TEST_CASE("Fibonacci (VectorCodeGenerator)")
{
- CodeBlock mem{4096};
std::vector<std::uint32_t> vec;
- VectorCodeGenerator code{vec, mem.ptr()};
+ VectorCodeGenerator code{vec};
Label start, end, zero, recurse;
@@ -69,6 +69,8 @@ TEST_CASE("Fibonacci (VectorCodeGenerator)")
code.LDP(X29, X30, SP, POST_INDEXED, 32);
code.RET();
+ CodeBlock mem{4096};
+
mem.unprotect();
std::memcpy(mem.ptr(), vec.data(), vec.size() * sizeof(std::uint32_t));
mem.protect();