Squashed 'externals/oaknut/' changes from 816481f10..c24f918e5
c24f918e5 oaknut: 1.1.6 3a70cd40a oaknut: Run clang-format dc54784b8 oaknut: Add support for iOS memory protection. 14207278a oaknut: 1.1.5 841f9b693 oaknut: throw OaknutException instead of plain C string git-subtree-dir: externals/oaknut git-subtree-split: c24f918e52e629fc315c6e4bca4ea62def8b55e8
This commit is contained in:
parent
b65b07d566
commit
720d6bbcd8
18 changed files with 436 additions and 328 deletions
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
project(oaknut LANGUAGES CXX VERSION 1.1.4)
|
||||
project(oaknut LANGUAGES CXX VERSION 1.1.6)
|
||||
|
||||
# Determine if we're built as a subproject (using add_subdirectory)
|
||||
# or if this is the master project.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# define NOMINMAX
|
||||
# include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include <TargetConditionals.h>
|
||||
# include <libkern/OSCacheControl.h>
|
||||
# include <pthread.h>
|
||||
# include <sys/mman.h>
|
||||
|
@ -30,7 +31,11 @@ public:
|
|||
#if defined(_WIN32)
|
||||
m_memory = (std::uint32_t*)VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
#elif defined(__APPLE__)
|
||||
# if TARGET_OS_IPHONE
|
||||
m_memory = (std::uint32_t*)mmap(nullptr, size, PROT_READ | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
# else
|
||||
m_memory = (std::uint32_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0);
|
||||
# endif
|
||||
#else
|
||||
m_memory = (std::uint32_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
@ -64,14 +69,22 @@ public:
|
|||
void protect()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
# if TARGET_OS_IPHONE
|
||||
mprotect(m_memory, m_size, PROT_READ | PROT_EXEC);
|
||||
# else
|
||||
pthread_jit_write_protect_np(1);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void unprotect()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
# if TARGET_OS_IPHONE
|
||||
mprotect(m_memory, m_size, PROT_READ | PROT_WRITE);
|
||||
# else
|
||||
pthread_jit_write_protect_np(0);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ std::uint32_t encode(MovImm16 v)
|
|||
if constexpr (std::popcount(splat) == 17) {
|
||||
constexpr std::uint32_t mask = (1 << std::popcount(splat)) - 1;
|
||||
if ((v.m_encoded & mask) != v.m_encoded)
|
||||
throw "invalid MovImm16";
|
||||
throw OaknutException{ExceptionType::InvalidMovImm16};
|
||||
}
|
||||
return pdep<splat>(v.m_encoded);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ void addsubext_verify_reg_size(AddSubExt ext, RReg rm)
|
|||
return;
|
||||
if (rm.bitsize() == 64 && (static_cast<int>(ext) & 0b011) == 0b011)
|
||||
return;
|
||||
throw "invalid AddSubExt choice for rm size";
|
||||
throw OaknutException{ExceptionType::InvalidAddSubExt};
|
||||
}
|
||||
|
||||
void indexext_verify_reg_size(IndexExt ext, RReg rm)
|
||||
|
@ -145,11 +145,11 @@ void indexext_verify_reg_size(IndexExt ext, RReg rm)
|
|||
return;
|
||||
if (rm.bitsize() == 64 && (static_cast<int>(ext) & 1) == 1)
|
||||
return;
|
||||
throw "invalid IndexExt choice for rm size";
|
||||
throw OaknutException{ExceptionType::InvalidIndexExt};
|
||||
}
|
||||
|
||||
void tbz_verify_reg_size(RReg rt, Imm<6> imm)
|
||||
{
|
||||
if (rt.bitsize() == 32 && imm.value() >= 32)
|
||||
throw "invalid imm choice for rt size";
|
||||
throw OaknutException{ExceptionType::BitPositionOutOfRange};
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ enum class TlbiOp {
|
|||
VALE1 = 0b000'0111'101,
|
||||
VAALE1 = 0b000'0111'111,
|
||||
IPAS2E1IS = 0b100'0000'001,
|
||||
RIPAS2E1IS = 0b100'0000'010, // ARMv8.4-TLBI
|
||||
RIPAS2E1IS = 0b100'0000'010, // ARMv8.4-TLBI
|
||||
IPAS2LE1IS = 0b100'0000'101,
|
||||
RIPAS2LE1IS = 0b100'0000'110, // ARMv8.4-TLBI
|
||||
ALLE2OS = 0b100'0001'000, // ARMv8.4-TLBI
|
||||
|
@ -214,11 +214,11 @@ enum class TlbiOp {
|
|||
ALLE1IS = 0b100'0011'100,
|
||||
VALE2IS = 0b100'0011'101,
|
||||
VMALLS12E1IS = 0b100'0011'110,
|
||||
IPAS2E1OS = 0b100'0100'000, // ARMv8.4-TLBI
|
||||
IPAS2E1OS = 0b100'0100'000, // ARMv8.4-TLBI
|
||||
IPAS2E1 = 0b100'0100'001,
|
||||
RIPAS2E1 = 0b100'0100'010, // ARMv8.4-TLBI
|
||||
RIPAS2E1OS = 0b100'0100'011, // ARMv8.4-TLBI
|
||||
IPAS2LE1OS = 0b100'0100'100, // ARMv8.4-TLBI
|
||||
RIPAS2E1 = 0b100'0100'010, // ARMv8.4-TLBI
|
||||
RIPAS2E1OS = 0b100'0100'011, // ARMv8.4-TLBI
|
||||
IPAS2LE1OS = 0b100'0100'100, // ARMv8.4-TLBI
|
||||
IPAS2LE1 = 0b100'0100'101,
|
||||
RIPAS2LE1 = 0b100'0100'110, // ARMv8.4-TLBI
|
||||
RIPAS2LE1OS = 0b100'0100'111, // ARMv8.4-TLBI
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include "oaknut/oaknut_exception.hpp"
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
template<std::size_t bit_size_>
|
||||
|
@ -22,7 +24,7 @@ public:
|
|||
: m_value(value_)
|
||||
{
|
||||
if (!is_valid(value_))
|
||||
throw "outsized Imm value";
|
||||
throw OaknutException{ExceptionType::ImmOutOfRange};
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const Imm& other) const { return m_value <=> other.m_value; }
|
||||
|
@ -52,7 +54,7 @@ public:
|
|||
: m_encoded(value_ | ((shift_ == AddSubImmShift::SHL_12) ? 1 << 12 : 0))
|
||||
{
|
||||
if ((value_ & 0xFFF) != value_)
|
||||
throw "invalid AddSubImm";
|
||||
throw OaknutException{ExceptionType::InvalidAddSubImm};
|
||||
}
|
||||
|
||||
constexpr /* implicit */ AddSubImm(std::uint64_t value_)
|
||||
|
@ -62,7 +64,7 @@ public:
|
|||
} else if ((value_ & 0xFFF000) == value_) {
|
||||
m_encoded = (value_ >> 12) | (1 << 12);
|
||||
} else {
|
||||
throw "invalid AddSubImm";
|
||||
throw OaknutException{ExceptionType::InvalidAddSubImm};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ public:
|
|||
m_encoded = lsw | (shift << 16);
|
||||
return;
|
||||
} else if (lsw != 0) {
|
||||
throw "invalid MovImm16";
|
||||
throw OaknutException{ExceptionType::InvalidMovImm16};
|
||||
}
|
||||
value_ >>= 16;
|
||||
shift++;
|
||||
|
@ -161,7 +163,7 @@ public:
|
|||
{
|
||||
const auto encoded = detail::encode_bit_imm(value);
|
||||
if (!encoded || (*encoded & 0x1000) != 0)
|
||||
throw "invalid BitImm32";
|
||||
throw OaknutException{ExceptionType::InvalidBitImm32};
|
||||
m_encoded = *encoded;
|
||||
}
|
||||
|
||||
|
@ -181,7 +183,7 @@ public:
|
|||
{
|
||||
const auto encoded = detail::encode_bit_imm(value);
|
||||
if (!encoded)
|
||||
throw "invalid BitImm64";
|
||||
throw OaknutException{ExceptionType::InvalidBitImm64};
|
||||
m_encoded = *encoded;
|
||||
}
|
||||
|
||||
|
@ -224,7 +226,7 @@ struct ImmConst {
|
|||
constexpr /* implicit */ ImmConst(int value)
|
||||
{
|
||||
if (value != A) {
|
||||
throw "invalid ImmConst";
|
||||
throw OaknutException{ExceptionType::InvalidImmConst};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -233,7 +235,7 @@ struct ImmConstFZero {
|
|||
constexpr /* implicit */ ImmConstFZero(double value)
|
||||
{
|
||||
if (value != 0) {
|
||||
throw "invalid ImmConstFZero";
|
||||
throw OaknutException{ExceptionType::InvalidImmConstFZero};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -250,7 +252,7 @@ struct ImmChoice<A, B> {
|
|||
} else if (value == B) {
|
||||
m_encoded = 1;
|
||||
} else {
|
||||
throw "invalid ImmChoice";
|
||||
throw OaknutException{ExceptionType::InvalidImmChoice};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,7 +275,7 @@ struct ImmChoice<A, B, C, D> {
|
|||
} else if (value == D) {
|
||||
m_encoded = 3;
|
||||
} else {
|
||||
throw "invalid ImmChoice";
|
||||
throw OaknutException{ExceptionType::InvalidImmChoice};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +291,7 @@ struct ImmRange {
|
|||
: m_value(value_)
|
||||
{
|
||||
if (value_ < Start || value_ > End) {
|
||||
throw "invalid ImmRange";
|
||||
throw OaknutException{ExceptionType::InvalidImmRange};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +307,7 @@ struct LslShift {
|
|||
: m_encoded((((-amount) & (max_value - 1)) << 6) | (max_value - amount - 1))
|
||||
{
|
||||
if (amount >= max_value)
|
||||
throw "LslShift out of range";
|
||||
throw OaknutException{ExceptionType::LslShiftOutOfRange};
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include "oaknut/oaknut_exception.hpp"
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
struct Elem;
|
||||
|
@ -40,7 +42,7 @@ struct List {
|
|||
static_assert(std::is_base_of_v<VRegArranged, T> || std::is_base_of_v<Elem, T> || detail::is_instance_of_ElemSelector_v<T>);
|
||||
|
||||
if (!verify(std::index_sequence_for<U...>{}, args...))
|
||||
throw "invalid List";
|
||||
throw OaknutException{ExceptionType::InvalidList};
|
||||
}
|
||||
|
||||
constexpr auto operator[](unsigned elem_index) const
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@
|
|||
void SQRDMLAH(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0111111101LMmmmm1101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLAH(SReg rd, SReg rn, SElem em)
|
||||
|
@ -14,13 +14,13 @@ void SQRDMLAH(SReg rd, SReg rn, SElem em)
|
|||
void SQRDMLAH(VReg_4H rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0010111101LMmmmm1101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLAH(VReg_8H rd, VReg_8H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0110111101LMmmmm1101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLAH(VReg_2S rd, VReg_2S rn, SElem em)
|
||||
|
@ -58,7 +58,7 @@ void SQRDMLAH(VReg_4S rd, VReg_4S rn, VReg_4S rm)
|
|||
void SQRDMLSH(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0111111101LMmmmm1111H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLSH(SReg rd, SReg rn, SElem em)
|
||||
|
@ -68,13 +68,13 @@ void SQRDMLSH(SReg rd, SReg rn, SElem em)
|
|||
void SQRDMLSH(VReg_4H rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0010111101LMmmmm1111H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLSH(VReg_8H rd, VReg_8H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0110111101LMmmmm1111H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void SQRDMLSH(VReg_2S rd, VReg_2S rn, SElem em)
|
||||
|
|
|
@ -412,19 +412,19 @@ void FMINV(HReg rd, VReg_8H rn)
|
|||
void FMLA(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0101111100LMmmmm0001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLA(VReg_8B rd, VReg_8B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0000111100LMmmmm0001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLA(VReg_16B rd, VReg_16B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0100111100LMmmmm0001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLA(VReg_4H rd, VReg_4H rn, VReg_4H rm)
|
||||
|
@ -438,25 +438,25 @@ void FMLA(VReg_8H rd, VReg_8H rn, VReg_8H rm)
|
|||
void FMLAL(VReg_2S rd, VReg_2H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0000111110LMmmmm0000H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLAL(VReg_4S rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0100111110LMmmmm0000H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLAL2(VReg_2S rd, VReg_2H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0010111110LMmmmm1000H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLAL2(VReg_4S rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0110111110LMmmmm1000H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLAL(VReg_2S rd, VReg_2H rn, VReg_2H rm)
|
||||
|
@ -478,19 +478,19 @@ void FMLAL2(VReg_4S rd, VReg_4H rn, VReg_4H rm)
|
|||
void FMLS(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0101111100LMmmmm0101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLS(VReg_8B rd, VReg_8B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0000111100LMmmmm0101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLS(VReg_16B rd, VReg_16B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0100111100LMmmmm0101H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLS(VReg_4H rd, VReg_4H rn, VReg_4H rm)
|
||||
|
@ -504,25 +504,25 @@ void FMLS(VReg_8H rd, VReg_8H rn, VReg_8H rm)
|
|||
void FMLSL(VReg_2S rd, VReg_2H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0000111110LMmmmm0100H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLSL(VReg_4S rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0100111110LMmmmm0100H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLSL2(VReg_2S rd, VReg_2H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0010111110LMmmmm1100H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLSL2(VReg_4S rd, VReg_4H rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0110111110LMmmmm1100H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMLSL(VReg_2S rd, VReg_2H rn, VReg_2H rm)
|
||||
|
@ -552,19 +552,19 @@ void FMOV(VReg_8H rd, FImm8 imm)
|
|||
void FMUL(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0101111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMUL(VReg_8B rd, VReg_8B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0000111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMUL(VReg_16B rd, VReg_16B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0100111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMUL(VReg_4H rd, VReg_4H rn, VReg_4H rm)
|
||||
|
@ -590,19 +590,19 @@ void FMULX(VReg_8H rd, VReg_8H rn, VReg_8H rm)
|
|||
void FMULX(HReg rd, HReg rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0111111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMULX(VReg_8B rd, VReg_8B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0010111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FMULX(VReg_16B rd, VReg_16B rn, HElem em)
|
||||
{
|
||||
if (em.reg_index() >= 16)
|
||||
throw "InvalidCombination";
|
||||
throw OaknutException{ExceptionType::InvalidCombination};
|
||||
emit<"0110111100LMmmmm1001H0nnnnnddddd", "d", "n", "m", "H", "L", "M">(rd, rn, em.reg_index(), em.elem_index() >> 2, (em.elem_index() >> 1) & 1, em.elem_index() & 1);
|
||||
}
|
||||
void FNEG(VReg_4H rd, VReg_4H rn)
|
||||
|
|
|
@ -166,13 +166,13 @@ void B(Cond cond, AddrOffset<21, 2> label)
|
|||
void BFI(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0011001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1);
|
||||
}
|
||||
void BFI(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1011001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1);
|
||||
}
|
||||
void BFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms)
|
||||
|
@ -186,13 +186,13 @@ void BFM(XReg xd, XReg xn, Imm<6> immr, Imm<6> imms)
|
|||
void BFXIL(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0011001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void BFXIL(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1011001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void BIC(WReg wd, WReg wn, WReg wm, LogShift shift = LogShift::LSL, Imm<5> shift_amount = 0)
|
||||
|
@ -278,25 +278,25 @@ void CCMP(XReg xn, XReg xm, Imm<4> nzcv, Cond cond)
|
|||
void CINC(WReg wd, WReg wn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"00011010100mmmmmcccc01nnnnnddddd", "d", "n", "m", "c">(wd, wn, wn, invert(cond));
|
||||
}
|
||||
void CINC(XReg xd, XReg xn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"10011010100mmmmmcccc01nnnnnddddd", "d", "n", "m", "c">(xd, xn, xn, invert(cond));
|
||||
}
|
||||
void CINV(WReg wd, WReg wn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"01011010100mmmmmcccc00nnnnnddddd", "d", "n", "m", "c">(wd, wn, wn, invert(cond));
|
||||
}
|
||||
void CINV(XReg xd, XReg xn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"11011010100mmmmmcccc00nnnnnddddd", "d", "n", "m", "c">(xd, xn, xn, invert(cond));
|
||||
}
|
||||
void CLREX(Imm<4> imm = 15)
|
||||
|
@ -392,13 +392,13 @@ void CMP(XReg xn, XReg xm, AddSubShift shift = AddSubShift::LSL, Imm<6> shift_am
|
|||
void CNEG(WReg wd, WReg wn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"01011010100mmmmmcccc01nnnnnddddd", "d", "n", "m", "c">(wd, wn, wn, invert(cond));
|
||||
}
|
||||
void CNEG(XReg xd, XReg xn, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"11011010100mmmmmcccc01nnnnnddddd", "d", "n", "m", "c">(xd, xn, xn, invert(cond));
|
||||
}
|
||||
void CRC32B(WReg wd, WReg wn, WReg wm)
|
||||
|
@ -448,25 +448,25 @@ void CSEL(XReg xd, XReg xn, XReg xm, Cond cond)
|
|||
void CSET(WReg wd, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"0001101010011111cccc0111111ddddd", "d", "c">(wd, invert(cond));
|
||||
}
|
||||
void CSET(XReg xd, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"1001101010011111cccc0111111ddddd", "d", "c">(xd, invert(cond));
|
||||
}
|
||||
void CSETM(WReg wd, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"0101101010011111cccc0011111ddddd", "d", "c">(wd, invert(cond));
|
||||
}
|
||||
void CSETM(XReg xd, Cond cond)
|
||||
{
|
||||
if (cond == Cond::AL || cond == Cond::NV)
|
||||
throw "invalid Cond";
|
||||
throw OaknutException{ExceptionType::InvalidCond};
|
||||
emit<"1101101010011111cccc0011111ddddd", "d", "c">(xd, invert(cond));
|
||||
}
|
||||
void CSINC(WReg wd, WReg wn, WReg wm, Cond cond)
|
||||
|
@ -1230,13 +1230,13 @@ void SBCS(XReg xd, XReg xn, XReg xm)
|
|||
void SBFIZ(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0001001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1);
|
||||
}
|
||||
void SBFIZ(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1001001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1);
|
||||
}
|
||||
void SBFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms)
|
||||
|
@ -1250,13 +1250,13 @@ void SBFM(XReg xd, XReg xn, Imm<6> immr, Imm<6> imms)
|
|||
void SBFX(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0001001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void SBFX(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1001001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void SDIV(WReg wd, WReg wn, WReg wm)
|
||||
|
@ -1626,13 +1626,13 @@ void TST(XReg xn, XReg xm, LogShift shift = LogShift::LSL, Imm<6> shift_amount =
|
|||
void UBFIZ(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0101001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, (-lsb.value()) & 31, width.value() - 1);
|
||||
}
|
||||
void UBFIZ(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1101001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, (-lsb.value()) & 63, width.value() - 1);
|
||||
}
|
||||
void UBFM(WReg wd, WReg wn, Imm<5> immr, Imm<5> imms)
|
||||
|
@ -1646,13 +1646,13 @@ void UBFM(XReg xd, XReg xn, Imm<6> immr, Imm<6> imms)
|
|||
void UBFX(WReg wd, WReg wn, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0101001100rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(wd, wn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void UBFX(XReg xd, XReg xn, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1101001101rrrrrrssssssnnnnnddddd", "d", "n", "r", "s">(xd, xn, lsb.value(), lsb.value() + width.value() - 1);
|
||||
}
|
||||
void UDF(Imm<16> imm)
|
||||
|
|
|
@ -68,97 +68,97 @@ void CASLH(WReg ws, WReg wt, XRegSp xn)
|
|||
void CASP(WReg ws, WReg ws2, WReg wt, WReg wt2, XRegSp xn)
|
||||
{
|
||||
if (wt.index() + 1 != wt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (wt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (ws.index() + 1 != ws2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (ws.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"00001000001sssss011111nnnnnttttt", "s", "t", "n">(ws, wt, xn);
|
||||
}
|
||||
void CASPA(WReg ws, WReg ws2, WReg wt, WReg wt2, XRegSp xn)
|
||||
{
|
||||
if (wt.index() + 1 != wt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (wt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (ws.index() + 1 != ws2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (ws.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"00001000011sssss011111nnnnnttttt", "s", "t", "n">(ws, wt, xn);
|
||||
}
|
||||
void CASPAL(WReg ws, WReg ws2, WReg wt, WReg wt2, XRegSp xn)
|
||||
{
|
||||
if (wt.index() + 1 != wt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (wt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (ws.index() + 1 != ws2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (ws.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"00001000011sssss111111nnnnnttttt", "s", "t", "n">(ws, wt, xn);
|
||||
}
|
||||
void CASPL(WReg ws, WReg ws2, WReg wt, WReg wt2, XRegSp xn)
|
||||
{
|
||||
if (wt.index() + 1 != wt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (wt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (ws.index() + 1 != ws2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (ws.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"00001000001sssss111111nnnnnttttt", "s", "t", "n">(ws, wt, xn);
|
||||
}
|
||||
void CASP(XReg xs, XReg xs2, XReg xt, XReg xt2, XRegSp xn)
|
||||
{
|
||||
if (xt.index() + 1 != xt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (xs.index() + 1 != xs2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xs.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"01001000001sssss011111nnnnnttttt", "s", "t", "n">(xs, xt, xn);
|
||||
}
|
||||
void CASPA(XReg xs, XReg xs2, XReg xt, XReg xt2, XRegSp xn)
|
||||
{
|
||||
if (xt.index() + 1 != xt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (xs.index() + 1 != xs2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xs.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"01001000011sssss011111nnnnnttttt", "s", "t", "n">(xs, xt, xn);
|
||||
}
|
||||
void CASPAL(XReg xs, XReg xs2, XReg xt, XReg xt2, XRegSp xn)
|
||||
{
|
||||
if (xt.index() + 1 != xt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (xs.index() + 1 != xs2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xs.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"01001000011sssss111111nnnnnttttt", "s", "t", "n">(xs, xt, xn);
|
||||
}
|
||||
void CASPL(XReg xs, XReg xs2, XReg xt, XReg xt2, XRegSp xn)
|
||||
{
|
||||
if (xt.index() + 1 != xt2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xt.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
if (xs.index() + 1 != xs2.index())
|
||||
throw "Invalid second register in pair";
|
||||
throw OaknutException{ExceptionType::InvalidPairSecond};
|
||||
if (xs.index() & 1)
|
||||
throw "Requires even register";
|
||||
throw OaknutException{ExceptionType::InvalidPairFirst};
|
||||
emit<"01001000001sssss111111nnnnnttttt", "s", "t", "n">(xs, xt, xn);
|
||||
}
|
||||
void LDADD(WReg ws, WReg wt, XRegSp xn)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
void BFC(WReg wd, Imm<5> lsb, Imm<5> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (32 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"0011001100rrrrrrssssss11111ddddd", "d", "r", "s">(wd, (-lsb.value()) & 31, width.value() - 1);
|
||||
}
|
||||
void BFC(XReg xd, Imm<6> lsb, Imm<6> width)
|
||||
{
|
||||
if (width.value() == 0 || width.value() > (64 - lsb.value()))
|
||||
throw "invalid width";
|
||||
throw OaknutException{ExceptionType::InvalidBitWidth};
|
||||
emit<"1011001101rrrrrrssssss11111ddddd", "d", "r", "s">(xd, (-lsb.value()) & 63, width.value() - 1);
|
||||
}
|
||||
void ESB()
|
||||
|
|
42
include/oaknut/impl/oaknut_exception.inc.hpp
Normal file
42
include/oaknut/impl/oaknut_exception.inc.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
// SPDX-FileCopyrightText: Copyright (c) 2023 merryhime <https://mary.rs>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// reg.hpp
|
||||
OAKNUT_EXCEPTION(InvalidWSPConversion, "toW: cannot convert WSP to WReg")
|
||||
OAKNUT_EXCEPTION(InvalidXSPConversion, "toX: cannot convert XSP to XReg")
|
||||
OAKNUT_EXCEPTION(InvalidWZRConversion, "unexpected WZR passed into an WRegWsp")
|
||||
OAKNUT_EXCEPTION(InvalidXZRConversion, "unexpected XZR passed into an XRegSp")
|
||||
OAKNUT_EXCEPTION(InvalidDElem_1, "invalid DElem_1")
|
||||
OAKNUT_EXCEPTION(InvalidElementIndex, "elem_index is out of range")
|
||||
|
||||
// imm.hpp / offset.hpp / list.hpp
|
||||
OAKNUT_EXCEPTION(InvalidAddSubImm, "invalid AddSubImm")
|
||||
OAKNUT_EXCEPTION(InvalidBitImm32, "invalid BitImm32")
|
||||
OAKNUT_EXCEPTION(InvalidBitImm64, "invalid BitImm64")
|
||||
OAKNUT_EXCEPTION(InvalidImmChoice, "invalid ImmChoice")
|
||||
OAKNUT_EXCEPTION(InvalidImmConst, "invalid ImmConst")
|
||||
OAKNUT_EXCEPTION(InvalidImmConstFZero, "invalid ImmConstFZero")
|
||||
OAKNUT_EXCEPTION(InvalidImmRange, "invalid ImmRange")
|
||||
OAKNUT_EXCEPTION(InvalidList, "invalid List")
|
||||
OAKNUT_EXCEPTION(InvalidMovImm16, "invalid MovImm16")
|
||||
OAKNUT_EXCEPTION(InvalidBitWidth, "invalid width")
|
||||
OAKNUT_EXCEPTION(LslShiftOutOfRange, "LslShift out of range")
|
||||
OAKNUT_EXCEPTION(OffsetMisaligned, "misalignment")
|
||||
OAKNUT_EXCEPTION(OffsetOutOfRange, "out of range")
|
||||
OAKNUT_EXCEPTION(ImmOutOfRange, "outsized Imm value")
|
||||
|
||||
// arm64_encode_helpers.inc.hpp
|
||||
OAKNUT_EXCEPTION(InvalidAddSubExt, "invalid AddSubExt choice for rm size")
|
||||
OAKNUT_EXCEPTION(InvalidIndexExt, "invalid IndexExt choice for rm size")
|
||||
OAKNUT_EXCEPTION(BitPositionOutOfRange, "bit position exceeds size of rt")
|
||||
|
||||
// mnemonics_*.inc.hpp
|
||||
OAKNUT_EXCEPTION(InvalidCombination, "InvalidCombination")
|
||||
OAKNUT_EXCEPTION(InvalidCond, "Cond cannot be AL or NV here")
|
||||
OAKNUT_EXCEPTION(InvalidPairFirst, "Requires even register")
|
||||
OAKNUT_EXCEPTION(InvalidPairSecond, "Invalid second register in pair")
|
||||
OAKNUT_EXCEPTION(InvalidOperandXZR, "xzr invalid here")
|
||||
|
||||
// oaknut.hpp
|
||||
OAKNUT_EXCEPTION(InvalidAlignment, "invalid alignment")
|
||||
OAKNUT_EXCEPTION(LabelRedefinition, "label already resolved")
|
|
@ -7,6 +7,8 @@
|
|||
#include <cstdint>
|
||||
#include <variant>
|
||||
|
||||
#include "oaknut/oaknut_exception.hpp"
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
struct Label;
|
||||
|
@ -51,9 +53,9 @@ struct AddrOffset {
|
|||
{
|
||||
const std::uint64_t diff_u64 = static_cast<std::uint64_t>(diff);
|
||||
if (detail::sign_extend<bitsize>(diff_u64) != diff_u64)
|
||||
throw "out of range";
|
||||
throw OaknutException{ExceptionType::OffsetOutOfRange};
|
||||
if (diff_u64 != (diff_u64 & detail::inverse_mask_from_size(alignment)))
|
||||
throw "misalignment";
|
||||
throw OaknutException{ExceptionType::OffsetMisaligned};
|
||||
|
||||
return static_cast<std::uint32_t>((diff_u64 & detail::mask_from_size(bitsize)) >> alignment);
|
||||
}
|
||||
|
@ -78,7 +80,7 @@ struct PageOffset {
|
|||
{
|
||||
std::uint64_t diff = (static_cast<std::uint64_t>(target) >> shift_amount) - (static_cast<std::uint64_t>(current_addr) >> shift_amount);
|
||||
if (detail::sign_extend<bitsize>(diff) != diff)
|
||||
throw "out of range";
|
||||
throw OaknutException{ExceptionType::OffsetOutOfRange};
|
||||
diff &= detail::mask_from_size(bitsize);
|
||||
return static_cast<std::uint32_t>(((diff & 3) << (bitsize - 2)) | (diff >> 2));
|
||||
}
|
||||
|
@ -95,9 +97,9 @@ struct SOffset {
|
|||
{
|
||||
const std::uint64_t diff_u64 = static_cast<std::uint64_t>(offset);
|
||||
if (detail::sign_extend<bitsize>(diff_u64) != diff_u64)
|
||||
throw "out of range";
|
||||
throw OaknutException{ExceptionType::OffsetOutOfRange};
|
||||
if (diff_u64 != (diff_u64 & detail::inverse_mask_from_size(alignment)))
|
||||
throw "misalignment";
|
||||
throw OaknutException{ExceptionType::OffsetMisaligned};
|
||||
|
||||
m_encoded = static_cast<std::uint32_t>((diff_u64 & detail::mask_from_size(bitsize)) >> alignment);
|
||||
}
|
||||
|
@ -114,9 +116,9 @@ struct POffset {
|
|||
{
|
||||
const std::uint64_t diff_u64 = static_cast<std::uint64_t>(offset);
|
||||
if (diff_u64 > detail::mask_from_size(bitsize))
|
||||
throw "out of range";
|
||||
throw OaknutException{ExceptionType::OffsetOutOfRange};
|
||||
if (diff_u64 != (diff_u64 & detail::inverse_mask_from_size(alignment)))
|
||||
throw "misalignment";
|
||||
throw OaknutException{ExceptionType::OffsetMisaligned};
|
||||
|
||||
m_encoded = static_cast<std::uint32_t>((diff_u64 & detail::mask_from_size(bitsize)) >> alignment);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "oaknut/oaknut_exception.hpp"
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
struct Reg;
|
||||
|
@ -117,14 +119,14 @@ struct WReg : public RReg {
|
|||
inline XReg RReg::toX() const
|
||||
{
|
||||
if (index() == -1)
|
||||
throw "cannot convert SP/WSP to XReg";
|
||||
throw OaknutException{ExceptionType::InvalidXSPConversion};
|
||||
return XReg{index()};
|
||||
}
|
||||
|
||||
inline WReg RReg::toW() const
|
||||
{
|
||||
if (index() == -1)
|
||||
throw "cannot convert SP/WSP to WReg";
|
||||
throw OaknutException{ExceptionType::InvalidWSPConversion};
|
||||
return WReg{index()};
|
||||
}
|
||||
|
||||
|
@ -146,7 +148,7 @@ struct XRegSp : public RReg {
|
|||
: RReg(64, xr.index())
|
||||
{
|
||||
if (xr.index() == 31)
|
||||
throw "unexpected ZR passed into an XRegSp";
|
||||
throw OaknutException{ExceptionType::InvalidXZRConversion};
|
||||
}
|
||||
|
||||
template<typename Policy>
|
||||
|
@ -161,7 +163,7 @@ struct WRegWsp : public RReg {
|
|||
: RReg(32, wr.index())
|
||||
{
|
||||
if (wr.index() == 31)
|
||||
throw "unexpected WZR passed into an WRegWsp";
|
||||
throw OaknutException{ExceptionType::InvalidWZRConversion};
|
||||
}
|
||||
|
||||
template<typename Policy>
|
||||
|
@ -296,7 +298,7 @@ struct Elem {
|
|||
: m_esize(esize_), m_reg(reg_), m_elem_index(elem_index_)
|
||||
{
|
||||
if (elem_index_ >= 128 / esize_)
|
||||
throw "invalid elem_index";
|
||||
throw OaknutException{ExceptionType::InvalidElementIndex};
|
||||
}
|
||||
|
||||
constexpr unsigned esize() const { return m_esize; }
|
||||
|
@ -338,7 +340,7 @@ struct DElem_1 : public DElem {
|
|||
: DElem(inner)
|
||||
{
|
||||
if (inner.elem_index() != 1)
|
||||
throw "invalid DElem_1";
|
||||
throw OaknutException{ExceptionType::InvalidDElem_1};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "oaknut/impl/offset.hpp"
|
||||
#include "oaknut/impl/reg.hpp"
|
||||
#include "oaknut/impl/string_literal.hpp"
|
||||
#include "oaknut/oaknut_exception.hpp"
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
|
@ -87,7 +88,7 @@ public:
|
|||
void l(Label& label)
|
||||
{
|
||||
if (label.m_addr)
|
||||
throw "label already resolved";
|
||||
throw OaknutException{ExceptionType::LabelRedefinition};
|
||||
|
||||
const auto target_addr = Policy::current_address();
|
||||
label.m_addr = target_addr;
|
||||
|
@ -169,8 +170,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Convenience function for moving pointers to registers
|
||||
void MOVP2R(XReg xd, const void* addr) {
|
||||
// Convenience function for moving pointers to registers
|
||||
void MOVP2R(XReg xd, const void* addr)
|
||||
{
|
||||
int64_t diff = reinterpret_cast<uint64_t>(addr) - Policy::current_address();
|
||||
if (diff >= -0xF'FFFF && diff <= 0xF'FFFF) {
|
||||
ADR(xd, addr);
|
||||
|
@ -184,7 +186,7 @@ public:
|
|||
void align(std::size_t alignment)
|
||||
{
|
||||
if (alignment < 4 || (alignment & (alignment - 1)) != 0)
|
||||
throw "invalid alignment";
|
||||
throw OaknutException{ExceptionType::InvalidAlignment};
|
||||
|
||||
while (Policy::template ptr<std::uintptr_t>() & (alignment - 1)) {
|
||||
NOP();
|
||||
|
|
44
include/oaknut/oaknut_exception.hpp
Normal file
44
include/oaknut/oaknut_exception.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: Copyright (c) 2023 merryhime <https://mary.rs>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace oaknut {
|
||||
|
||||
enum class ExceptionType {
|
||||
#define OAKNUT_EXCEPTION(tag, str) tag,
|
||||
#include "oaknut/impl/oaknut_exception.inc.hpp"
|
||||
#undef OAKNUT_EXCEPTION
|
||||
};
|
||||
|
||||
inline const char* to_string(ExceptionType et)
|
||||
{
|
||||
switch (et) {
|
||||
#define OAKNUT_EXCEPTION(tag, str) \
|
||||
case ExceptionType::tag: \
|
||||
return str;
|
||||
#include "oaknut/impl/oaknut_exception.inc.hpp"
|
||||
#undef OAKNUT_EXCEPTION
|
||||
default:
|
||||
return "unknown ExceptionType";
|
||||
}
|
||||
}
|
||||
|
||||
class OaknutException : public std::exception {
|
||||
public:
|
||||
explicit OaknutException(ExceptionType et)
|
||||
: type{et}
|
||||
{}
|
||||
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return to_string(type);
|
||||
}
|
||||
|
||||
private:
|
||||
ExceptionType type;
|
||||
};
|
||||
|
||||
} // namespace oaknut
|
|
@ -187,9 +187,8 @@ TEST_CASE("MOVP2R")
|
|||
{
|
||||
CodeBlock mem{4096};
|
||||
|
||||
for (int i = 0; i < 0x200'0000; i++)
|
||||
{
|
||||
const std::int64_t diff = RandInt<std::int64_t>(std::numeric_limits<std::int64_t>::min(),
|
||||
for (int i = 0; i < 0x200'0000; i++) {
|
||||
const std::int64_t diff = RandInt<std::int64_t>(std::numeric_limits<std::int64_t>::min(),
|
||||
std::numeric_limits<std::int64_t>::max());
|
||||
const std::intptr_t value = reinterpret_cast<std::intptr_t>(mem.ptr()) + diff;
|
||||
|
||||
|
|
Loading…
Reference in a new issue