dep: Add biscuit and riscv-disas

This commit is contained in:
Stenzek
2023-05-30 00:11:06 +10:00
parent c561400a47
commit 49a4901c78
26 changed files with 10449 additions and 0 deletions

View File

@ -0,0 +1,153 @@
# Main library
add_library(biscuit
# Source files
assembler.cpp
assembler_crypto.cpp
assembler_vector.cpp
code_buffer.cpp
cpuinfo.cpp
# Headers
"${PROJECT_SOURCE_DIR}/include/biscuit/assembler.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/assert.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/code_buffer.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/csr.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/isa.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/label.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/registers.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/vector.hpp"
"${PROJECT_SOURCE_DIR}/include/biscuit/cpuinfo.hpp"
)
add_library(biscuit::biscuit ALIAS biscuit)
target_include_directories(biscuit
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_features(biscuit
PRIVATE
cxx_std_20
)
if (MSVC)
target_compile_options(biscuit
PRIVATE
/MP
/Zi
/Zo
/permissive-
/EHsc
/utf-8
/volatile:iso
/Zc:externConstexpr
/Zc:inline
/Zc:throwingNew
# Warnings
/W4
/we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled
/we4101 # 'identifier': unreferenced local variable
/we4265 # 'class': class has virtual functions, but destructor is not virtual
/we4287 # 'operator' : unsigned/negative constant mismatch
/we4365 # 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
/we4388 # signed/unsigned mismatch
/we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
/we4555 # Expression has no effect; expected expression with side-effect
/we4715 # 'function': not all control paths return a value
/we4834 # Discarding return value of function with 'nodiscard' attribute
/we5038 # data member 'member1' will be initialized after data member 'member2'
)
elseif (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
target_compile_options(biscuit
PRIVATE
-Wall
-Wextra
-Wconversion
-Wsign-conversion
-Werror=array-bounds
-Werror=cast-qual
-Werror=ignored-qualifiers
-Werror=implicit-fallthrough
-Werror=sign-compare
-Werror=reorder
-Werror=uninitialized
-Werror=unused-function
-Werror=unused-result
-Werror=unused-variable
)
endif()
if (BISCUIT_CODE_BUFFER_MMAP)
target_compile_definitions(biscuit
PRIVATE
-DBISCUIT_CODE_BUFFER_MMAP
)
endif()
# Install target
include(GNUInstallDirs)
set(BISCUIT_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/biscuit")
# Set install target and relevant includes.
install(TARGETS biscuit
EXPORT biscuit-targets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
# Export targets to a script
install(EXPORT biscuit-targets
FILE
biscuit-targets.cmake
NAMESPACE
biscuit::
DESTINATION
"${BISCUIT_INSTALL_CONFIGDIR}"
)
# Now create the config version script
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/biscuit-config-version.cmake"
VERSION
${PROJECT_VERSION}
COMPATIBILITY
SameMajorVersion
)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/biscuit-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/biscuit-config.cmake"
INSTALL_DESTINATION "${BISCUIT_INSTALL_CONFIGDIR}"
)
# Now install the config and version files.
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/biscuit-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/biscuit-config-version.cmake"
DESTINATION "${BISCUIT_INSTALL_CONFIGDIR}"
)
# Export library from the build tree.
export(EXPORT biscuit-targets
FILE
"${CMAKE_CURRENT_BINARY_DIR}/biscuit-targets.cmake"
NAMESPACE
biscuit::
)
export(PACKAGE biscuit)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
#include <biscuit/assert.hpp>
#include <biscuit/assembler.hpp>
namespace biscuit {
namespace {
void EmitAES32Instruction(CodeBuffer& buffer, uint32_t op, GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
BISCUIT_ASSERT(bs <= 0b11);
buffer.Emit32(op | (bs << 30) | (rs2.Index() << 20) |
(rs1.Index() << 15) | (rd.Index() << 7));
}
void EmitSM4Instruction(CodeBuffer& buffer, uint32_t op, GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
// Same behavior, function exists for a better contextual name.
EmitAES32Instruction(buffer, op, rd, rs1, rs2, bs);
}
void EmitAES64Instruction(CodeBuffer& buffer, uint32_t op, GPR rd, GPR rs1, GPR rs2) noexcept {
buffer.Emit32(op | (rs2.Index() << 20) | (rs1.Index() << 15) | (rd.Index() << 7));
}
void EmitSHAInstruction(CodeBuffer& buffer, uint32_t op, GPR rd, GPR rs1, GPR rs2) noexcept {
// Same behavior, function exists for a better contextual name.
EmitAES64Instruction(buffer, op, rd, rs1, rs2);
}
void EmitSM3Instruction(CodeBuffer& buffer, uint32_t op, GPR rd, GPR rs) noexcept {
// Same behavior, function exists for a better contextual name.
EmitAES64Instruction(buffer, op, rd, rs, x0);
}
} // Anonymous namespace
void Assembler::AES32DSI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitAES32Instruction(m_buffer, 0x2A000033, rd, rs1, rs2, bs);
}
void Assembler::AES32DSMI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitAES32Instruction(m_buffer, 0x2E000033, rd, rs1, rs2, bs);
}
void Assembler::AES32ESI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitAES32Instruction(m_buffer, 0x22000033, rd, rs1, rs2, bs);
}
void Assembler::AES32ESMI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitAES32Instruction(m_buffer, 0x26000033, rd, rs1, rs2, bs);
}
void Assembler::AES64DS(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitAES64Instruction(m_buffer, 0x3A000033, rd, rs1, rs2);
}
void Assembler::AES64DSM(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitAES64Instruction(m_buffer, 0x3E000033, rd, rs1, rs2);
}
void Assembler::AES64ES(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitAES64Instruction(m_buffer, 0x32000033, rd, rs1, rs2);
}
void Assembler::AES64ESM(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitAES64Instruction(m_buffer, 0x36000033, rd, rs1, rs2);
}
void Assembler::AES64IM(GPR rd, GPR rs) noexcept {
EmitAES64Instruction(m_buffer, 0x30001013, rd, rs, x0);
}
void Assembler::AES64KS1I(GPR rd, GPR rs, uint32_t rnum) noexcept {
// RVK spec states that 0xB to 0xF are reserved.
BISCUIT_ASSERT(rnum <= 0xA);
EmitAES64Instruction(m_buffer, 0x31001013, rd, rs, GPR{rnum});
}
void Assembler::AES64KS2(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitAES64Instruction(m_buffer, 0x7E000033, rd, rs1, rs2);
}
void Assembler::SHA256SIG0(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10201013, rd, rs, x0);
}
void Assembler::SHA256SIG1(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10301013, rd, rs, x0);
}
void Assembler::SHA256SUM0(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10001013, rd, rs, x0);
}
void Assembler::SHA256SUM1(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10101013, rd, rs, x0);
}
void Assembler::SHA512SIG0(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10601013, rd, rs, x0);
}
void Assembler::SHA512SIG0H(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x5C000033, rd, rs1, rs2);
}
void Assembler::SHA512SIG0L(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x54000033, rd, rs1, rs2);
}
void Assembler::SHA512SIG1(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10701013, rd, rs, x0);
}
void Assembler::SHA512SIG1H(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x5E000033, rd, rs1, rs2);
}
void Assembler::SHA512SIG1L(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x56000033, rd, rs1, rs2);
}
void Assembler::SHA512SUM0(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10401013, rd, rs, x0);
}
void Assembler::SHA512SUM0R(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x50000033, rd, rs1, rs2);
}
void Assembler::SHA512SUM1(GPR rd, GPR rs) noexcept {
EmitSHAInstruction(m_buffer, 0x10501013, rd, rs, x0);
}
void Assembler::SHA512SUM1R(GPR rd, GPR rs1, GPR rs2) noexcept {
EmitSHAInstruction(m_buffer, 0x52000033, rd, rs1, rs2);
}
void Assembler::SM3P0(GPR rd, GPR rs) noexcept {
EmitSM3Instruction(m_buffer, 0x10801013, rd, rs);
}
void Assembler::SM3P1(GPR rd, GPR rs) noexcept {
EmitSM3Instruction(m_buffer, 0x10901013, rd, rs);
}
void Assembler::SM4ED(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitSM4Instruction(m_buffer, 0x30000033, rd, rs1, rs2, bs);
}
void Assembler::SM4KS(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
EmitSM4Instruction(m_buffer, 0x34000033, rd, rs1, rs2, bs);
}
} // namespace biscuit

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,111 @@
#include <biscuit/assert.hpp>
#include <biscuit/code_buffer.hpp>
#include <cstring>
#include <utility>
#ifdef BISCUIT_CODE_BUFFER_MMAP
#include <sys/mman.h>
#endif
namespace biscuit {
CodeBuffer::CodeBuffer(size_t capacity)
: m_capacity{capacity}, m_is_managed{true} {
if (capacity == 0) {
return;
}
#ifdef BISCUIT_CODE_BUFFER_MMAP
m_buffer = static_cast<uint8_t*>(mmap(nullptr, capacity,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0));
BISCUIT_ASSERT(m_buffer != nullptr);
#else
m_buffer = new uint8_t[capacity]();
#endif
m_cursor = m_buffer;
}
CodeBuffer::CodeBuffer(uint8_t* buffer, size_t capacity)
: m_buffer{buffer}, m_cursor{buffer}, m_capacity{capacity} {
BISCUIT_ASSERT(buffer != nullptr);
}
CodeBuffer::CodeBuffer(CodeBuffer&& other) noexcept
: m_buffer{std::exchange(other.m_buffer, nullptr)}
, m_cursor{std::exchange(other.m_cursor, nullptr)}
, m_capacity{std::exchange(other.m_capacity, size_t{0})}
, m_is_managed{std::exchange(other.m_is_managed, false)} {}
CodeBuffer& CodeBuffer::operator=(CodeBuffer&& other) noexcept {
if (this == &other) {
return *this;
}
std::swap(m_buffer, other.m_buffer);
std::swap(m_cursor, other.m_cursor);
std::swap(m_capacity, other.m_capacity);
std::swap(m_is_managed, other.m_is_managed);
return *this;
}
CodeBuffer::~CodeBuffer() noexcept {
if (!m_is_managed) {
return;
}
#ifdef BISCUIT_CODE_BUFFER_MMAP
munmap(m_buffer, m_capacity);
#else
delete[] m_buffer;
#endif
}
void CodeBuffer::Grow(size_t new_capacity) {
BISCUIT_ASSERT(IsManaged());
// No-op, just return.
if (new_capacity <= m_capacity) {
return;
}
const auto cursor_offset = GetCursorOffset();
#ifdef BISCUIT_CODE_BUFFER_MMAP
auto* new_buffer = static_cast<uint8_t*>(mremap(m_buffer, m_capacity, new_capacity, MREMAP_MAYMOVE));
BISCUIT_ASSERT(new_buffer != nullptr);
#else
auto* new_buffer = new uint8_t[new_capacity]();
std::memcpy(new_buffer, m_buffer, m_capacity);
delete[] m_buffer;
#endif
m_buffer = new_buffer;
m_capacity = new_capacity;
m_cursor = m_buffer + cursor_offset;
}
void CodeBuffer::SetExecutable() {
#ifdef BISCUIT_CODE_BUFFER_MMAP
const auto result = mprotect(m_buffer, m_capacity, PROT_READ | PROT_EXEC);
BISCUIT_ASSERT(result == 0);
#else
// Unimplemented/Unnecessary for new
BISCUIT_ASSERT(false);
#endif
}
void CodeBuffer::SetWritable() {
#ifdef BISCUIT_CODE_BUFFER_MMAP
const auto result = mprotect(m_buffer, m_capacity, PROT_READ | PROT_WRITE);
BISCUIT_ASSERT(result == 0);
#else
// Unimplemented/Unnecessary for new
BISCUIT_ASSERT(false);
#endif
}
} // namespace biscuit

View File

@ -0,0 +1,39 @@
// Copyright (c), 2022, KNS Group LLC (YADRO)
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
#include <biscuit/cpuinfo.hpp>
namespace biscuit {
bool CPUInfo::Has(RISCVExtension extension) const {
#if defined(__linux__) && defined(__riscv)
const static uint64_t features = getauxval(AT_HWCAP) & (
COMPAT_HWCAP_ISA_I |
COMPAT_HWCAP_ISA_M |
COMPAT_HWCAP_ISA_A |
COMPAT_HWCAP_ISA_F |
COMPAT_HWCAP_ISA_D |
COMPAT_HWCAP_ISA_C |
COMPAT_HWCAP_ISA_V
);
#else
const static uint64_t features = 0;
#endif
return (features & static_cast<uint64_t>(extension)) != 0;
}
uint32_t CPUInfo::GetVlenb() const {
if(Has(RISCVExtension::V)) {
static CSRReader<CSR::VLenb> csrReader;
const static auto getVLEN = csrReader.GetCode<uint32_t (*)()>();
return getVLEN();
}
return 0;
}
} // namespace biscuit