mirror of
https://git.eden-emu.dev/eden-emu/dynarmic
synced 2026-02-04 10:51:21 +01:00
externals: Update all externals + Migrate to git submodules
This commit is contained in:
27
.gitmodules
vendored
Normal file
27
.gitmodules
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
[submodule "biscuit"]
|
||||
path = externals/biscuit
|
||||
url = https://github.com/lioncash/biscuit.git
|
||||
[submodule "catch"]
|
||||
path = externals/catch
|
||||
url = https://github.com/catchorg/Catch2.git
|
||||
[submodule "fmt"]
|
||||
path = externals/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
[submodule "mcl"]
|
||||
path = externals/mcl
|
||||
url = https://github.com/merryhime/mcl.git
|
||||
[submodule "oaknut"]
|
||||
path = externals/oaknut
|
||||
url = https://github.com/merryhime/oaknut.git
|
||||
[submodule "robin-map"]
|
||||
path = externals/robin-map
|
||||
url = https://github.com/Tessil/robin-map.git
|
||||
[submodule "xbyak"]
|
||||
path = externals/xbyak
|
||||
url = https://github.com/herumi/xbyak.git
|
||||
[submodule "zycore"]
|
||||
path = externals/zycore
|
||||
url = https://github.com/zyantific/zycore-c.git
|
||||
[submodule "zydis"]
|
||||
path = externals/zydis
|
||||
url = https://github.com/zyantific/zydis.git
|
||||
40
externals/README.md
vendored
40
externals/README.md
vendored
@@ -1,40 +0,0 @@
|
||||
This repository uses subtrees to manage some of its externals.
|
||||
|
||||
## Initial setup
|
||||
|
||||
```
|
||||
git remote add externals-biscuit https://github.com/lioncash/biscuit.git --no-tags
|
||||
git remote add externals-catch https://github.com/catchorg/Catch2.git --no-tags
|
||||
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
|
||||
git remote add externals-mcl https://github.com/merryhime/mcl.git --no-tags
|
||||
git remote add externals-oaknut https://github.com/merryhime/oaknut.git --no-tags
|
||||
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
|
||||
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
|
||||
git remote add externals-zycore https://github.com/zyantific/zycore-c.git --no-tags
|
||||
git remote add externals-zydis https://github.com/zyantific/zydis.git --no-tags
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
Change `<ref>` to refer to the appropriate git reference.
|
||||
|
||||
```
|
||||
git fetch externals-biscuit
|
||||
git fetch externals-catch
|
||||
git fetch externals-fmt
|
||||
git fetch externals-mcl
|
||||
git fetch externals-oaknut
|
||||
git fetch externals-robin-map
|
||||
git fetch externals-xbyak
|
||||
git fetch externals-zycore
|
||||
git fetch externals-zydis
|
||||
git subtree pull --squash --prefix=externals/biscuit externals-biscuit <ref>
|
||||
git subtree pull --squash --prefix=externals/catch externals-catch <ref>
|
||||
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
|
||||
git subtree pull --squash --prefix=externals/mcl externals-mcl <ref>
|
||||
git subtree pull --squash --prefix=externals/oaknut externals-oaknut <ref>
|
||||
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
|
||||
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>
|
||||
git subtree pull --squash --prefix=externals/zycore externals-zycore <ref>
|
||||
git subtree pull --squash --prefix=externals/zydis externals-zydis <ref>
|
||||
```
|
||||
1
externals/biscuit
vendored
Submodule
1
externals/biscuit
vendored
Submodule
Submodule externals/biscuit added at 8bd0f7538b
@@ -1,45 +0,0 @@
|
||||
name: Build and Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
cpu_detection: [0, 1]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Install build dependencies
|
||||
if: ${{matrix.os == 'ubuntu-latest'}}
|
||||
run: sudo apt-get install llvm ninja-build
|
||||
|
||||
- name: Install build dependencies
|
||||
if: ${{matrix.os == 'macos-latest'}}
|
||||
run: |
|
||||
brew install llvm ninja
|
||||
echo "/usr/local/opt/llvm/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Checkout biscuit repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >
|
||||
cmake
|
||||
-B ${{github.workspace}}/build
|
||||
-G Ninja
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: ninja
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: ctest --extra-verbose -C ${{env.BUILD_TYPE}}
|
||||
3
externals/biscuit/.gitignore
vendored
3
externals/biscuit/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
# Built files
|
||||
build/
|
||||
build-*/
|
||||
17
externals/biscuit/CMakeLists.txt
vendored
17
externals/biscuit/CMakeLists.txt
vendored
@@ -1,17 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(biscuit VERSION 0.14.0)
|
||||
|
||||
include(CTest)
|
||||
|
||||
option(BISCUIT_CODE_BUFFER_MMAP "Use mmap for handling code buffers instead of new" OFF)
|
||||
|
||||
# Source directories
|
||||
add_subdirectory(src)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
12
externals/biscuit/LICENSE.md
vendored
12
externals/biscuit/LICENSE.md
vendored
@@ -1,12 +0,0 @@
|
||||
Copyright 2021 Lioncash/Lioncache
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
157
externals/biscuit/README.md
vendored
157
externals/biscuit/README.md
vendored
@@ -1,157 +0,0 @@
|
||||
# Biscuit: RISC-V Runtime Code Generation Library
|
||||
|
||||
*RISC it for the biscuit*
|
||||
|
||||
## About
|
||||
|
||||
An experimental runtime code generator for RISC-V.
|
||||
|
||||
This allows for runtime code generation of RISC-V instructions. Similar
|
||||
to how [Xbyak](https://github.com/herumi/xbyak) allows for runtime code generation of x86 instructions.
|
||||
|
||||
|
||||
## Implemented ISA Features
|
||||
|
||||
Includes both 32-bit and 64-bit instructions in the following:
|
||||
|
||||
| Feature | Version |
|
||||
|:----------|:-------:|
|
||||
| A | 2.1 |
|
||||
| B | 1.0 |
|
||||
| C | 2.0 |
|
||||
| D | 2.2 |
|
||||
| F | 2.2 |
|
||||
| H | 1.0 |
|
||||
| K | 1.0.1 |
|
||||
| M | 2.0 |
|
||||
| N | 1.1 |
|
||||
| Q | 2.2 |
|
||||
| RV32I | 2.1 |
|
||||
| RV64I | 2.1 |
|
||||
| S | 1.12 |
|
||||
| V | 1.0 |
|
||||
| Sstc | 0.5.4 |
|
||||
| Zacas | 1.0 |
|
||||
| Zawrs | 1.01 |
|
||||
| Zcb | 1.0.4 |
|
||||
| Zcmp | 1.0.4 |
|
||||
| Zcmt | 1.0.4 |
|
||||
| Zfa | 1.0 |
|
||||
| Zfbfmin | 1.0 rc2 |
|
||||
| Zfh | 1.0 |
|
||||
| Zfhmin | 1.0 |
|
||||
| Zicbom | 1.0 |
|
||||
| Zicbop | 1.0 |
|
||||
| Zicboz | 1.0 |
|
||||
| Zicond | 1.0.1 |
|
||||
| Zicsr | 2.0 |
|
||||
| Zifencei | 2.0 |
|
||||
| Zihintntl | 1.0 |
|
||||
| Zvbb | 1.0 |
|
||||
| Zvbc | 1.0 |
|
||||
| Zvfbfmin | 1.0 rc2 |
|
||||
| Zvfbfwma | 1.0 rc2 |
|
||||
| Zvkn | 1.0 |
|
||||
|
||||
Note that usually only extensions considered ratified will be implemented
|
||||
as non-ratified documents are considerably more likely to have
|
||||
large changes made to them, which makes maintaining instruction
|
||||
APIs a little annoying.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Biscuit requires no external dependencies for its library other than the C++ standard library.
|
||||
The tests, however, use the Catch2 testing library. This is included in tree so there's no need
|
||||
to worry about installing it yourself if you wish to run said tests.
|
||||
|
||||
|
||||
## Building Biscuit
|
||||
|
||||
1. Generate the build files for the project with CMake
|
||||
2. Hit the build button in your IDE of choice, or run the relevant console command to build for the CMake generator you've chosen.
|
||||
3. Done.
|
||||
|
||||
|
||||
## Running Tests
|
||||
|
||||
1. Generate the build files for the project with CMake
|
||||
2. Build the tests
|
||||
3. Run the test executable directly, or enter `ctest` into your terminal.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
The library is licensed under the MIT license.
|
||||
|
||||
While it's not a requirement whatsoever, it'd be pretty neat if you told me that you found the library useful :-)
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
The following is an adapted equivalent of the `strlen` implementation within the RISC-V bit manipulation extension specification.
|
||||
For brevity, it has been condensed to only handle little-endian platforms.
|
||||
|
||||
```cpp
|
||||
// We prepare some contiguous buffer and give the pointer to the beginning
|
||||
// of the data and the total size of the buffer in bytes to the assembler.
|
||||
|
||||
void strlen_example(uint8_t* buffer, size_t buffer_size) {
|
||||
using namespace biscuit;
|
||||
|
||||
constexpr int ptrlog = 3;
|
||||
constexpr int szreg = 8;
|
||||
|
||||
Assembler as(buffer, buffer_size);
|
||||
Label done;
|
||||
Label loop;
|
||||
|
||||
as.ANDI(a3, a0, szreg - 1); // Offset
|
||||
as.ANDI(a1, a0, 0xFF8); // Align pointer
|
||||
|
||||
as.LI(a4, szreg);
|
||||
as.SUB(a4, a4, a3); // XLEN - offset
|
||||
as.SLLI(a3, a3, ptrlog); // offset * 8
|
||||
as.LD(a2, 0, a1); // Chunk
|
||||
|
||||
//
|
||||
// Shift the partial/unaligned chunk we loaded to remove the bytes
|
||||
// from before the start of the string, adding NUL bytes at the end.
|
||||
//
|
||||
as.SRL(a2, a2, a3); // chunk >> (offset * 8)
|
||||
as.ORCB(a2, a2);
|
||||
as.NOT(a2, a2);
|
||||
|
||||
// Non-NUL bytes in the string have been expanded to 0x00, while
|
||||
// NUL bytes have become 0xff. Search for the first set bit
|
||||
// (corresponding to a NUL byte in the original chunk).
|
||||
as.CTZ(a2, a2);
|
||||
|
||||
// The first chunk is special: compare against the number of valid
|
||||
// bytes in this chunk.
|
||||
as.SRLI(a0, a2, 3);
|
||||
as.BGTU(a4, a0, &done);
|
||||
as.ADDI(a3, a1, szreg);
|
||||
as.LI(a4, -1);
|
||||
|
||||
// Our critical loop is 4 instructions and processes data in 4 byte
|
||||
// or 8 byte chunks.
|
||||
as.Bind(&loop);
|
||||
|
||||
as.LD(a2, szreg, a1);
|
||||
as.ADDI(a1, a1, szreg);
|
||||
as.ORCB(a2, a2);
|
||||
as.BEQ(a2, a4, &loop);
|
||||
|
||||
as.NOT(a2, a2);
|
||||
as.CTZ(a2, a2);
|
||||
as.SUB(a1, a1, a3);
|
||||
as.ADD(a0, a0, a1);
|
||||
as.SRLI(a2, a2, 3);
|
||||
as.ADD(a0, a0, a2);
|
||||
|
||||
as.Bind(&done);
|
||||
|
||||
as.RET();
|
||||
}
|
||||
```
|
||||
88
externals/biscuit/clang-format
vendored
88
externals/biscuit/clang-format
vendored
@@ -1,88 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^\<[^Q][^/.>]*\>'
|
||||
Priority: -2
|
||||
- Regex: '^\<'
|
||||
Priority: -1
|
||||
- Regex: '^\"'
|
||||
Priority: 0
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 150
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
||||
@@ -1,5 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
|
||||
|
||||
check_required_components(@PROJECT_NAME@)
|
||||
1
externals/biscuit/examples/CMakeLists.txt
vendored
1
externals/biscuit/examples/CMakeLists.txt
vendored
@@ -1 +0,0 @@
|
||||
add_subdirectory(cpuinfo)
|
||||
@@ -1,3 +0,0 @@
|
||||
add_executable(cpuinfo cpuinfo.cpp)
|
||||
target_link_libraries(cpuinfo biscuit)
|
||||
set_property(TARGET cpuinfo PROPERTY CXX_STANDARD 20)
|
||||
31
externals/biscuit/examples/cpuinfo/cpuinfo.cpp
vendored
31
externals/biscuit/examples/cpuinfo/cpuinfo.cpp
vendored
@@ -1,31 +0,0 @@
|
||||
// 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/assembler.hpp>
|
||||
#include <biscuit/cpuinfo.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
int main()
|
||||
{
|
||||
CPUInfo cpu;
|
||||
|
||||
std::cout << "Has I:" << cpu.Has(RISCVExtension::I) << std::endl;
|
||||
std::cout << "Has M:" << cpu.Has(RISCVExtension::M) << std::endl;
|
||||
std::cout << "Has A:" << cpu.Has(RISCVExtension::A) << std::endl;
|
||||
std::cout << "Has F:" << cpu.Has(RISCVExtension::F) << std::endl;
|
||||
std::cout << "Has D:" << cpu.Has(RISCVExtension::D) << std::endl;
|
||||
std::cout << "Has C:" << cpu.Has(RISCVExtension::C) << std::endl;
|
||||
std::cout << "Has V:" << cpu.Has(RISCVExtension::V) << std::endl;
|
||||
|
||||
if (cpu.Has(RISCVExtension::V)) {
|
||||
std::cout << "VLENB:" << cpu.GetVlenb() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1475
externals/biscuit/include/biscuit/assembler.hpp
vendored
1475
externals/biscuit/include/biscuit/assembler.hpp
vendored
File diff suppressed because it is too large
Load Diff
14
externals/biscuit/include/biscuit/assert.hpp
vendored
14
externals/biscuit/include/biscuit/assert.hpp
vendored
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#define BISCUIT_ASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
std::printf("Assertion failed (%s)\nin %s, function %s line %i\n", \
|
||||
#condition, \
|
||||
__FILE__, __func__, __LINE__); \
|
||||
std::abort(); \
|
||||
} \
|
||||
} while (false)
|
||||
211
externals/biscuit/include/biscuit/code_buffer.hpp
vendored
211
externals/biscuit/include/biscuit/code_buffer.hpp
vendored
@@ -1,211 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#include <biscuit/assert.hpp>
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
/**
|
||||
* An arbitrarily sized buffer that code is written into.
|
||||
*
|
||||
* Also contains other member functions for manipulating
|
||||
* the data within the code buffer.
|
||||
*/
|
||||
class CodeBuffer {
|
||||
public:
|
||||
// Default capacity of 4KB.
|
||||
static constexpr size_t default_capacity = 4096;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param capacity The initial capacity of the code buffer in bytes.
|
||||
*/
|
||||
explicit CodeBuffer(size_t capacity = default_capacity);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param buffer A non-null pointer to an allocated buffer of size `capacity`.
|
||||
* @param capacity The capacity of the memory pointed to by `buffer`.
|
||||
*
|
||||
* @pre The given memory buffer must not be null.
|
||||
* @pre The given memory buffer must be at minimum `capacity` bytes in size.
|
||||
*
|
||||
* @note The caller is responsible for managing the lifetime of the given memory.
|
||||
* CodeBuffer will *not* free the memory once it goes out of scope.
|
||||
*/
|
||||
explicit CodeBuffer(uint8_t* buffer, size_t capacity);
|
||||
|
||||
// Copy constructor and assignment is deleted in order to prevent unintentional memory leaks.
|
||||
CodeBuffer(const CodeBuffer&) = delete;
|
||||
CodeBuffer& operator=(const CodeBuffer&) = delete;
|
||||
|
||||
// Move constructing or moving the buffer in general is allowed, as it's a transfer of control.
|
||||
CodeBuffer(CodeBuffer&& other) noexcept;
|
||||
CodeBuffer& operator=(CodeBuffer&& other) noexcept;
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* If a custom memory buffer is not given to the code buffer,
|
||||
* then the code buffer will automatically free any memory
|
||||
* it had allocated in order to be able to emit code.
|
||||
*/
|
||||
~CodeBuffer() noexcept;
|
||||
|
||||
/// Returns whether or not the memory is managed by the code buffer.
|
||||
[[nodiscard]] bool IsManaged() const noexcept { return m_is_managed; }
|
||||
|
||||
/// Retrieves the current cursor position within the buffer.
|
||||
[[nodiscard]] ptrdiff_t GetCursorOffset() const noexcept {
|
||||
return m_cursor - m_buffer;
|
||||
}
|
||||
|
||||
/// Retrieves the current address of the cursor within the buffer.
|
||||
[[nodiscard]] uintptr_t GetCursorAddress() const noexcept {
|
||||
return GetOffsetAddress(GetCursorOffset());
|
||||
}
|
||||
|
||||
/// Retrieves the cursor pointer
|
||||
[[nodiscard]] uint8_t* GetCursorPointer() noexcept {
|
||||
return GetOffsetPointer(GetCursorOffset());
|
||||
}
|
||||
|
||||
/// Retrieves the cursor pointer
|
||||
[[nodiscard]] const uint8_t* GetCursorPointer() const noexcept {
|
||||
return GetOffsetPointer(GetCursorOffset());
|
||||
}
|
||||
|
||||
/// Retrieves the address of an arbitrary offset within the buffer.
|
||||
[[nodiscard]] uintptr_t GetOffsetAddress(ptrdiff_t offset) const noexcept {
|
||||
return reinterpret_cast<uintptr_t>(GetOffsetPointer(offset));
|
||||
}
|
||||
|
||||
/// Retrieves the pointer to an arbitrary location within the buffer.
|
||||
[[nodiscard]] uint8_t* GetOffsetPointer(ptrdiff_t offset) noexcept {
|
||||
BISCUIT_ASSERT(offset >= 0 && offset <= GetCursorOffset());
|
||||
return m_buffer + offset;
|
||||
}
|
||||
|
||||
/// Retrieves the pointer to an arbitrary location within the buffer.
|
||||
[[nodiscard]] const uint8_t* GetOffsetPointer(ptrdiff_t offset) const noexcept {
|
||||
BISCUIT_ASSERT(offset >= 0 && offset <= GetCursorOffset());
|
||||
return m_buffer + offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows rewinding of the code buffer cursor.
|
||||
*
|
||||
* @param offset The offset to rewind the cursor by.
|
||||
*
|
||||
* @note If no offset is provided, then this function rewinds the
|
||||
* cursor to the beginning of the buffer.
|
||||
*
|
||||
* @note The offset may not be larger than the current cursor offset
|
||||
* and may not be less than the current buffer starting address.
|
||||
*/
|
||||
void RewindCursor(ptrdiff_t offset = 0) noexcept {
|
||||
auto* rewound = m_buffer + offset;
|
||||
BISCUIT_ASSERT(m_buffer <= rewound && rewound <= m_cursor);
|
||||
m_cursor = rewound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the underlying buffer has enough room for the
|
||||
* given number of bytes.
|
||||
*
|
||||
* @param num_bytes The number of bytes to store in the buffer.
|
||||
*/
|
||||
[[nodiscard]] bool HasSpaceFor(size_t num_bytes) const noexcept {
|
||||
return GetRemainingBytes() >= num_bytes;
|
||||
}
|
||||
|
||||
/// Returns the size of the data written to the buffer in bytes.
|
||||
[[nodiscard]] size_t GetSizeInBytes() const noexcept {
|
||||
EnsureBufferRange();
|
||||
return static_cast<size_t>(m_cursor - m_buffer);
|
||||
}
|
||||
|
||||
/// Returns the total number of remaining bytes in the buffer.
|
||||
[[nodiscard]] size_t GetRemainingBytes() const noexcept {
|
||||
EnsureBufferRange();
|
||||
return static_cast<size_t>((m_buffer + m_capacity) - m_cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grows the underlying memory of the code buffer
|
||||
*
|
||||
* @param new_capacity The new capacity of the code buffer in bytes.
|
||||
*
|
||||
* @pre The underlying memory of the code buffer *must* be managed
|
||||
* by the code buffer itself. Attempts to grow the buffer
|
||||
* with memory that is not managed by it will result in
|
||||
* an assertion being hit.
|
||||
*
|
||||
* @note Calling this with a new capacity that is less than or equal
|
||||
* to the current capacity of the buffer will result in
|
||||
* this function doing nothing.
|
||||
*/
|
||||
void Grow(size_t new_capacity);
|
||||
|
||||
/**
|
||||
* Emits a given value into the code buffer.
|
||||
*
|
||||
* @param value The value to emit into the code buffer.
|
||||
* @tparam T A trivially-copyable type.
|
||||
*/
|
||||
template <typename T>
|
||||
void Emit(T value) noexcept {
|
||||
static_assert(std::is_trivially_copyable_v<T>,
|
||||
"It's undefined behavior to memcpy a non-trivially-copyable type.");
|
||||
BISCUIT_ASSERT(HasSpaceFor(sizeof(T)));
|
||||
|
||||
std::memcpy(m_cursor, &value, sizeof(T));
|
||||
m_cursor += sizeof(T);
|
||||
}
|
||||
|
||||
/// Emits a 16-bit value into the code buffer.
|
||||
void Emit16(uint32_t value) noexcept {
|
||||
Emit(static_cast<uint16_t>(value));
|
||||
}
|
||||
|
||||
/// Emits a 32-bit value into the code buffer.
|
||||
void Emit32(uint32_t value) noexcept {
|
||||
Emit(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal code buffer to be executable.
|
||||
*
|
||||
* @note This will make the contained region of memory non-writable
|
||||
* to satisfy operating under W^X contexts. To make the
|
||||
* region writable again, use SetWritable().
|
||||
*/
|
||||
void SetExecutable();
|
||||
|
||||
/**
|
||||
* Sets the internal code buffer to be writable
|
||||
*
|
||||
* @note This will make the contained region of memory non-executable
|
||||
* to satisfy operating under W^X contexts. To make the region
|
||||
* executable again, use SetExecutable().
|
||||
*/
|
||||
void SetWritable();
|
||||
|
||||
private:
|
||||
void EnsureBufferRange() const noexcept {
|
||||
BISCUIT_ASSERT(m_cursor >= m_buffer && m_cursor <= m_buffer + m_capacity);
|
||||
}
|
||||
|
||||
uint8_t* m_buffer = nullptr;
|
||||
uint8_t* m_cursor = nullptr;
|
||||
size_t m_capacity = 0;
|
||||
bool m_is_managed = false;
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
101
externals/biscuit/include/biscuit/cpuinfo.hpp
vendored
101
externals/biscuit/include/biscuit/cpuinfo.hpp
vendored
@@ -1,101 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
#include <biscuit/registers.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(__linux__) && defined(__riscv)
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <asm/hwcap.h>
|
||||
#endif
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_I
|
||||
#define COMPAT_HWCAP_ISA_I (1U << ('I' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_M
|
||||
#define COMPAT_HWCAP_ISA_M (1U << ('M' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_A
|
||||
#define COMPAT_HWCAP_ISA_A (1U << ('A' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_F
|
||||
#define COMPAT_HWCAP_ISA_F (1U << ('F' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_D
|
||||
#define COMPAT_HWCAP_ISA_D (1U << ('D' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_C
|
||||
#define COMPAT_HWCAP_ISA_C (1U << ('C' - 'A'))
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_HWCAP_ISA_V
|
||||
#define COMPAT_HWCAP_ISA_V (1U << ('V' - 'A'))
|
||||
#endif
|
||||
|
||||
enum class RISCVExtension : uint64_t {
|
||||
I = COMPAT_HWCAP_ISA_I,
|
||||
M = COMPAT_HWCAP_ISA_M,
|
||||
A = COMPAT_HWCAP_ISA_A,
|
||||
F = COMPAT_HWCAP_ISA_F,
|
||||
D = COMPAT_HWCAP_ISA_D,
|
||||
C = COMPAT_HWCAP_ISA_C,
|
||||
V = COMPAT_HWCAP_ISA_V
|
||||
};
|
||||
|
||||
template <CSR csr>
|
||||
struct CSRReader : public biscuit::Assembler {
|
||||
// Buffer capacity exactly for 2 instructions.
|
||||
static constexpr size_t capacity = 8;
|
||||
|
||||
CSRReader() : biscuit::Assembler{CSRReader::capacity} {
|
||||
CSRR(a0, csr);
|
||||
RET();
|
||||
}
|
||||
|
||||
// Copy constructor and assignment.
|
||||
CSRReader(const CSRReader&) = delete;
|
||||
CSRReader& operator=(const CSRReader&) = delete;
|
||||
|
||||
// Move constructor and assignment.
|
||||
CSRReader(CSRReader&&) = default;
|
||||
CSRReader& operator=(CSRReader&&) = default;
|
||||
|
||||
template <typename CSRReaderFunc>
|
||||
CSRReaderFunc GetCode() {
|
||||
this->GetCodeBuffer().SetExecutable();
|
||||
return reinterpret_cast<CSRReaderFunc>(this->GetBufferPointer(0));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that detects information about a RISC-V CPU.
|
||||
*/
|
||||
class CPUInfo {
|
||||
public:
|
||||
/**
|
||||
* Checks if a particular RISC-V extension is available.
|
||||
*
|
||||
* @param extension The extension to check.
|
||||
*/
|
||||
bool Has(RISCVExtension extension) const;
|
||||
|
||||
/// Returns the vector register length in bytes.
|
||||
uint32_t GetVlenb() const;
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
443
externals/biscuit/include/biscuit/csr.hpp
vendored
443
externals/biscuit/include/biscuit/csr.hpp
vendored
@@ -1,443 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
// Control and Status Register
|
||||
enum class CSR : uint32_t {
|
||||
// clang-format off
|
||||
|
||||
// User-level CSRs
|
||||
|
||||
UStatus = 0x000, // User status register
|
||||
UIE = 0x004, // User interrupt-enable register
|
||||
UTVEC = 0x005, // User trap handler base address
|
||||
UScratch = 0x040, // Scratch register for user trap handlers
|
||||
UEPC = 0x041, // User exception program counter
|
||||
UCause = 0x042, // User trap cause
|
||||
UTVal = 0x043, // User bad address or instruction
|
||||
UIP = 0x044, // User interrupt pending
|
||||
|
||||
FFlags = 0x001, // Floating-point Accrued Exceptions
|
||||
FRM = 0x002, // Floating-point Dynamic Rounding Mode
|
||||
FCSR = 0x003, // Floating-point Control and Status Register (frm + fflags)
|
||||
|
||||
JVT = 0x017, // Table jump base vector and control register
|
||||
|
||||
Cycle = 0xC00, // Cycle counter for RDCYCLE instruction.
|
||||
Time = 0xC01, // Timer for RDTIME instruction.
|
||||
InstRet = 0xC02, // Instructions retired counter for RDINSTRET instruction.
|
||||
HPMCounter3 = 0xC03, // Performance-monitoring counter.
|
||||
HPMCounter4 = 0xC04, // Performance-monitoring counter.
|
||||
HPMCounter5 = 0xC05, // Performance-monitoring counter.
|
||||
HPMCounter6 = 0xC06, // Performance-monitoring counter.
|
||||
HPMCounter7 = 0xC07, // Performance-monitoring counter.
|
||||
HPMCounter8 = 0xC08, // Performance-monitoring counter.
|
||||
HPMCounter9 = 0xC09, // Performance-monitoring counter.
|
||||
HPMCounter10 = 0xC0A, // Performance-monitoring counter.
|
||||
HPMCounter11 = 0xC0B, // Performance-monitoring counter.
|
||||
HPMCounter12 = 0xC0C, // Performance-monitoring counter.
|
||||
HPMCounter13 = 0xC0D, // Performance-monitoring counter.
|
||||
HPMCounter14 = 0xC0E, // Performance-monitoring counter.
|
||||
HPMCounter15 = 0xC0F, // Performance-monitoring counter.
|
||||
HPMCounter16 = 0xC10, // Performance-monitoring counter.
|
||||
HPMCounter17 = 0xC11, // Performance-monitoring counter.
|
||||
HPMCounter18 = 0xC12, // Performance-monitoring counter.
|
||||
HPMCounter19 = 0xC13, // Performance-monitoring counter.
|
||||
HPMCounter20 = 0xC14, // Performance-monitoring counter.
|
||||
HPMCounter21 = 0xC15, // Performance-monitoring counter.
|
||||
HPMCounter22 = 0xC16, // Performance-monitoring counter.
|
||||
HPMCounter23 = 0xC17, // Performance-monitoring counter.
|
||||
HPMCounter24 = 0xC18, // Performance-monitoring counter.
|
||||
HPMCounter25 = 0xC19, // Performance-monitoring counter.
|
||||
HPMCounter26 = 0xC1A, // Performance-monitoring counter.
|
||||
HPMCounter27 = 0xC1B, // Performance-monitoring counter.
|
||||
HPMCounter28 = 0xC1C, // Performance-monitoring counter.
|
||||
HPMCounter29 = 0xC1D, // Performance-monitoring counter.
|
||||
HPMCounter30 = 0xC1E, // Performance-monitoring counter.
|
||||
HPMCounter31 = 0xC1F, // Performance-monitoring counter.
|
||||
CycleH = 0xC80, // Upper 32 bits of cycle, RV32I only.
|
||||
TimeH = 0xC81, // Upper 32 bits of time, RV32I only.
|
||||
InstRetH = 0xC82, // Upper 32 bits of instret, RV32I only.
|
||||
HPMCounter3H = 0xC83, // Upper 32 bits of HPMCounter3, RV32I only.
|
||||
HPMCounter4H = 0xC84, // Upper 32 bits of HPMCounter4, RV32I only.
|
||||
HPMCounter5H = 0xC85, // Upper 32 bits of HPMCounter5, RV32I only.
|
||||
HPMCounter6H = 0xC86, // Upper 32 bits of HPMCounter6, RV32I only.
|
||||
HPMCounter7H = 0xC87, // Upper 32 bits of HPMCounter7, RV32I only.
|
||||
HPMCounter8H = 0xC88, // Upper 32 bits of HPMCounter8, RV32I only.
|
||||
HPMCounter9H = 0xC89, // Upper 32 bits of HPMCounter9, RV32I only.
|
||||
HPMCounter10H = 0xC8A, // Upper 32 bits of HPMCounter10, RV32I only.
|
||||
HPMCounter11H = 0xC8B, // Upper 32 bits of HPMCounter11, RV32I only.
|
||||
HPMCounter12H = 0xC8C, // Upper 32 bits of HPMCounter12, RV32I only.
|
||||
HPMCounter13H = 0xC8D, // Upper 32 bits of HPMCounter13, RV32I only.
|
||||
HPMCounter14H = 0xC8E, // Upper 32 bits of HPMCounter14, RV32I only.
|
||||
HPMCounter15H = 0xC8F, // Upper 32 bits of HPMCounter15, RV32I only.
|
||||
HPMCounter16H = 0xC90, // Upper 32 bits of HPMCounter16, RV32I only.
|
||||
HPMCounter17H = 0xC91, // Upper 32 bits of HPMCounter17, RV32I only.
|
||||
HPMCounter18H = 0xC92, // Upper 32 bits of HPMCounter18, RV32I only.
|
||||
HPMCounter19H = 0xC93, // Upper 32 bits of HPMCounter19, RV32I only.
|
||||
HPMCounter20H = 0xC94, // Upper 32 bits of HPMCounter20, RV32I only.
|
||||
HPMCounter21H = 0xC95, // Upper 32 bits of HPMCounter21, RV32I only.
|
||||
HPMCounter22H = 0xC96, // Upper 32 bits of HPMCounter22, RV32I only.
|
||||
HPMCounter23H = 0xC97, // Upper 32 bits of HPMCounter23, RV32I only.
|
||||
HPMCounter24H = 0xC98, // Upper 32 bits of HPMCounter24, RV32I only.
|
||||
HPMCounter25H = 0xC99, // Upper 32 bits of HPMCounter25, RV32I only.
|
||||
HPMCounter26H = 0xC9A, // Upper 32 bits of HPMCounter26, RV32I only.
|
||||
HPMCounter27H = 0xC9B, // Upper 32 bits of HPMCounter27, RV32I only.
|
||||
HPMCounter28H = 0xC9C, // Upper 32 bits of HPMCounter28, RV32I only.
|
||||
HPMCounter29H = 0xC9D, // Upper 32 bits of HPMCounter29, RV32I only.
|
||||
HPMCounter30H = 0xC9E, // Upper 32 bits of HPMCounter30, RV32I only.
|
||||
HPMCounter31H = 0xC9F, // Upper 32 bits of HPMCounter31, RV32I only.
|
||||
|
||||
// Supervisor-level CSRs
|
||||
|
||||
SStatus = 0x100, // Supervisor status register
|
||||
SEDeleg = 0x102, // Supervisor exception delegation register
|
||||
SIDeleg = 0x103, // Supervisor interrupt delegation register
|
||||
SIE = 0x104, // Supervisor interrupt-enable register
|
||||
STVec = 0x105, // Supervisor trap handler base address
|
||||
SCounterEn = 0x106, // Supervisor counter enable
|
||||
|
||||
SEnvCfg = 0x10A, // Supervisor environment configuration register
|
||||
|
||||
SScratch = 0x140, // Scratch register for supervisor trap handlers
|
||||
SEPC = 0x141, // Supervisor exception program counter
|
||||
SCause = 0x142, // Supervisor trap cause
|
||||
STVal = 0x143, // Supervisor bad address or instruction
|
||||
SIP = 0x144, // Supervisor interrupt pending.
|
||||
|
||||
SISelect = 0x150, // Supervisor indirect register select
|
||||
SIReg = 0x151, // Supervisor indirect register alias
|
||||
|
||||
StopEI = 0x15C, // Supervisor top external interrupt (only with an IMSIC)
|
||||
StopI = 0xDB0, // Supervisor top interrupt
|
||||
|
||||
SIEH = 0x114, // Upper 32 bits of sie
|
||||
SIPH = 0x154, // Upper 32 bits of sip
|
||||
|
||||
STimeCmp = 0x14D, // Supervisor timer register
|
||||
STimeCmpH = 0x15D, // Supervisor timer register, RV32 only
|
||||
|
||||
SATP = 0x180, // Supervisor address translation and protection
|
||||
|
||||
SContext = 0x5A8, // Supervisor-mode context register
|
||||
|
||||
// Hypervisor-level CSRs
|
||||
|
||||
HStatus = 0x600, // Hypervisor status register
|
||||
HEDeleg = 0x602, // Hypervisor exception delegation register
|
||||
HIDeleg = 0x603, // Hypervisor interrupt delegation register
|
||||
HIE = 0x604, // Hypervisor interrupt-enable register
|
||||
HCounterEn = 0x606, // Hypervisor counter enable
|
||||
HGEIE = 0x607, // Hypervisor guest external interrupt-enable register
|
||||
HVIEN = 0x608, // Hypervisor virtual interrupt enables
|
||||
HVICTL = 0x609, // Hypervisor virtual interrupt control
|
||||
|
||||
HIDelegH = 0x613, // Upper 32 bits of hideleg
|
||||
HVIENH = 0x618, // Upper 32 bits of hvien
|
||||
HVIPH = 0x655, // Upper 32 bits of hvip
|
||||
HVIPrio1H = 0x656, // Upper 32 bits of hviprio1
|
||||
HVIPrio2H = 0x657, // Upper 32 bits of hviprio2
|
||||
VSIEH = 0x214, // Upper 32 bits of vsie
|
||||
VSIPH = 0x254, // Upper 32 bits of vsiph
|
||||
|
||||
HTVal = 0x643, // Hypervisor bad guest physical address
|
||||
HIP = 0x644, // Hypervisor interrupt pending
|
||||
HVIP = 0x645, // Hypervisor virtual interrupt pending
|
||||
HVIPrio1 = 0x646, // Hypervisor VS-level interrupt priorities
|
||||
HVIPrio2 = 0x647, // Hypervisor VS-level interrupt priorities
|
||||
HTInst = 0x64A, // Hypervisor trap instruction (transformed)
|
||||
HGEIP = 0xE12, // Hypervisor guest external interrupt pending
|
||||
|
||||
HEnvCfg = 0x60A, // Hypervisor environment configuration register
|
||||
HEnvCfgH = 0x61A, // Additional hypervisor environment configuration register, RV32 only
|
||||
|
||||
HGATP = 0x680, // Hypervisor guest address translation and protection
|
||||
|
||||
HContext = 0x6A8, // Hypervisor-mode context register
|
||||
|
||||
HTimeDelta = 0x605, // Delta for VS/VU-mode timer
|
||||
HTimeDeltaH = 0x615, // Upper 32 bits of HTimeDelta, HSXLEN=32 only
|
||||
|
||||
VSStatus = 0x200, // Virtual supervisor status register
|
||||
VSIE = 0x204, // Virtual supervisor interrupt-enable register
|
||||
VSTVec = 0x205, // Virtual supervisor trap handler base address
|
||||
VSScratch = 0x240, // Virtual supervisor scratch register
|
||||
VSEPC = 0x241, // Virtual supervisor exception program register
|
||||
VSCause = 0x242, // Virtual supervisor trap cause
|
||||
VSTVal = 0x243, // Virtual supervisor bad address or instruction
|
||||
VSIP = 0x244, // Virtual supervisor interrupt pending
|
||||
|
||||
VSISelect = 0x250, // Virtual supervisor indirect register select
|
||||
VSIReg = 0x251, // Virtual supervisor indirect register alias
|
||||
|
||||
VStopEI = 0x25C, // Virtual supervisor top external interrupt (only with an IMSIC)
|
||||
VStopI = 0xEB0, // Virtual supervisor top interrupt
|
||||
|
||||
VSTimeCmp = 0x24D, // Virtual supervisor timer register
|
||||
VSTimeCmpH = 0x25D, // Virtual supervisor timer register, RV32 only
|
||||
|
||||
VSATP = 0x280, // Virtual supervisor address translation and protection
|
||||
|
||||
// Machine-level CSRs
|
||||
|
||||
MVendorID = 0xF11, // Vendor ID
|
||||
MArchID = 0xF12, // Architecture ID
|
||||
MImpID = 0xF13, // Implementation ID
|
||||
MHartID = 0xF14, // Hardware Thread ID
|
||||
MConfigPtr = 0xF15, // Pointer to configuration data structure
|
||||
|
||||
MStatus = 0x300, // Machine status register
|
||||
MISA = 0x301, // ISA and extensions
|
||||
MEDeleg = 0x302, // Machine exception delegation register
|
||||
MIDeleg = 0x303, // Machine interrupt delegation register
|
||||
MIE = 0x304, // Machine interrupt-enable register
|
||||
MRVec = 0x305, // Machine trap-handler base address
|
||||
MCounterEn = 0x306, // Machine counter enable
|
||||
MVIEN = 0x308, // Machine virtual interrupt enables
|
||||
MVIP = 0x309, // Machine virtual interrupt-pending bits
|
||||
MStatusH = 0x310, // Additional machine status register, RV32 only
|
||||
|
||||
MIDelegH = 0x313, // Upper 32 bits of of mideleg (only with S-mode)
|
||||
MIEH = 0x314, // Upper 32 bits of mie
|
||||
MVIENH = 0x318, // Upper 32 bits of mvien (only with S-mode)
|
||||
MVIPH = 0x319, // Upper 32 bits of mvip (only with S-mode)
|
||||
MIPH = 0x354, // Upper 32 bits of mip
|
||||
|
||||
MScratch = 0x340, // Scratch register for machine trap handlers
|
||||
MEPC = 0x341, // Machine exception program counter
|
||||
MCause = 0x342, // Machine trap cause
|
||||
MTVal = 0x343, // Machine bad address or instruction
|
||||
MIP = 0x344, // Machine interrupt pending
|
||||
MTInst = 0x34A, // Machine trap instruction (transformed)
|
||||
MTVal2 = 0x34B, // Machine bad guest physical address
|
||||
|
||||
MISelect = 0x350, // Machine indirect register select
|
||||
MIReg = 0x351, // Machine indirect register alias
|
||||
|
||||
MTopEI = 0x35C, // Machine top external interrupt (only with an IMSIC)
|
||||
MTopI = 0xFB0, // Machine top interrupt
|
||||
|
||||
MEnvCfg = 0x30A, // Machine environment configuration register
|
||||
MEnvCfgH = 0x31A, // Additional machine environment configuration register, RV32 only
|
||||
MSecCfg = 0x747, // Machine security configuration register
|
||||
MSecCfgH = 0x757, // Additional machine security configuration register, RV32 only
|
||||
|
||||
PMPCfg0 = 0x3A0, // Physical memory protection configuration
|
||||
PMPCfg1 = 0x3A1, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg2 = 0x3A2, // Physical memory protection configuration
|
||||
PMPCfg3 = 0x3A3, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg4 = 0x3A4, // Physical memory protection configuration
|
||||
PMPCfg5 = 0x3A5, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg6 = 0x3A6, // Physical memory protection configuration
|
||||
PMPCfg7 = 0x3A7, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg8 = 0x3A8, // Physical memory protection configuration
|
||||
PMPCfg9 = 0x3A9, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg10 = 0x3AA, // Physical memory protection configuration
|
||||
PMPCfg11 = 0x3AB, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg12 = 0x3AC, // Physical memory protection configuration
|
||||
PMPCfg13 = 0x3AD, // Physical memory protection configuration, RV32 only
|
||||
PMPCfg14 = 0x3AE, // Physical memory protection configuration
|
||||
PMPCfg15 = 0x3AF, // Physical memory protection configuration, RV32 only
|
||||
PMPAddr0 = 0x3B0, // Physical memory protection address register
|
||||
PMPAddr1 = 0x3B1, // Physical memory protection address register
|
||||
PMPAddr2 = 0x3B2, // Physical memory protection address register
|
||||
PMPAddr3 = 0x3B3, // Physical memory protection address register
|
||||
PMPAddr4 = 0x3B4, // Physical memory protection address register
|
||||
PMPAddr5 = 0x3B5, // Physical memory protection address register
|
||||
PMPAddr6 = 0x3B6, // Physical memory protection address register
|
||||
PMPAddr7 = 0x3B7, // Physical memory protection address register
|
||||
PMPAddr8 = 0x3B8, // Physical memory protection address register
|
||||
PMPAddr9 = 0x3B9, // Physical memory protection address register
|
||||
PMPAddr10 = 0x3BA, // Physical memory protection address register
|
||||
PMPAddr11 = 0x3BB, // Physical memory protection address register
|
||||
PMPAddr12 = 0x3BC, // Physical memory protection address register
|
||||
PMPAddr13 = 0x3BD, // Physical memory protection address register
|
||||
PMPAddr14 = 0x3BE, // Physical memory protection address register
|
||||
PMPAddr15 = 0x3BF, // Physical memory protection address register
|
||||
PMPAddr16 = 0x3C0, // Physical memory protection address register
|
||||
PMPAddr17 = 0x3C1, // Physical memory protection address register
|
||||
PMPAddr18 = 0x3C2, // Physical memory protection address register
|
||||
PMPAddr19 = 0x3C3, // Physical memory protection address register
|
||||
PMPAddr20 = 0x3C4, // Physical memory protection address register
|
||||
PMPAddr21 = 0x3C5, // Physical memory protection address register
|
||||
PMPAddr22 = 0x3C6, // Physical memory protection address register
|
||||
PMPAddr23 = 0x3C7, // Physical memory protection address register
|
||||
PMPAddr24 = 0x3C8, // Physical memory protection address register
|
||||
PMPAddr25 = 0x3C9, // Physical memory protection address register
|
||||
PMPAddr26 = 0x3CA, // Physical memory protection address register
|
||||
PMPAddr27 = 0x3CB, // Physical memory protection address register
|
||||
PMPAddr28 = 0x3CC, // Physical memory protection address register
|
||||
PMPAddr29 = 0x3CD, // Physical memory protection address register
|
||||
PMPAddr30 = 0x3CE, // Physical memory protection address register
|
||||
PMPAddr31 = 0x3CF, // Physical memory protection address register
|
||||
PMPAddr32 = 0x3D0, // Physical memory protection address register
|
||||
PMPAddr33 = 0x3D1, // Physical memory protection address register
|
||||
PMPAddr34 = 0x3D2, // Physical memory protection address register
|
||||
PMPAddr35 = 0x3D3, // Physical memory protection address register
|
||||
PMPAddr36 = 0x3D4, // Physical memory protection address register
|
||||
PMPAddr37 = 0x3D5, // Physical memory protection address register
|
||||
PMPAddr38 = 0x3D6, // Physical memory protection address register
|
||||
PMPAddr39 = 0x3D7, // Physical memory protection address register
|
||||
PMPAddr40 = 0x3D8, // Physical memory protection address register
|
||||
PMPAddr41 = 0x3D9, // Physical memory protection address register
|
||||
PMPAddr42 = 0x3DA, // Physical memory protection address register
|
||||
PMPAddr43 = 0x3DB, // Physical memory protection address register
|
||||
PMPAddr44 = 0x3DC, // Physical memory protection address register
|
||||
PMPAddr45 = 0x3DD, // Physical memory protection address register
|
||||
PMPAddr46 = 0x3DE, // Physical memory protection address register
|
||||
PMPAddr47 = 0x3DF, // Physical memory protection address register
|
||||
PMPAddr48 = 0x3E0, // Physical memory protection address register
|
||||
PMPAddr49 = 0x3E1, // Physical memory protection address register
|
||||
PMPAddr50 = 0x3E2, // Physical memory protection address register
|
||||
PMPAddr51 = 0x3E3, // Physical memory protection address register
|
||||
PMPAddr52 = 0x3E4, // Physical memory protection address register
|
||||
PMPAddr53 = 0x3E5, // Physical memory protection address register
|
||||
PMPAddr54 = 0x3E6, // Physical memory protection address register
|
||||
PMPAddr55 = 0x3E7, // Physical memory protection address register
|
||||
PMPAddr56 = 0x3E8, // Physical memory protection address register
|
||||
PMPAddr57 = 0x3E9, // Physical memory protection address register
|
||||
PMPAddr58 = 0x3EA, // Physical memory protection address register
|
||||
PMPAddr59 = 0x3EB, // Physical memory protection address register
|
||||
PMPAddr60 = 0x3EC, // Physical memory protection address register
|
||||
PMPAddr61 = 0x3ED, // Physical memory protection address register
|
||||
PMPAddr62 = 0x3EE, // Physical memory protection address register
|
||||
PMPAddr63 = 0x3EF, // Physical memory protection address register
|
||||
|
||||
MNScratch = 0x740, // Resumable NMI scratch register
|
||||
MNEPC = 0x741, // Resumable NMI program counter
|
||||
MNCause = 0x742, // Resumable NMI cause
|
||||
MNStatus = 0x744, // Resumable NMI status
|
||||
|
||||
MCycle = 0xB00, // Machine cycle counter
|
||||
MInstRet = 0xB02, // Machine instructions-retired counter
|
||||
MHPMCounter3 = 0xB03, // Machine performance-monitoring counter
|
||||
MHPMCounter4 = 0xB04, // Machine performance-monitoring counter
|
||||
MHPMCounter5 = 0xB05, // Machine performance-monitoring counter
|
||||
MHPMCounter6 = 0xB06, // Machine performance-monitoring counter
|
||||
MHPMCounter7 = 0xB07, // Machine performance-monitoring counter
|
||||
MHPMCounter8 = 0xB08, // Machine performance-monitoring counter
|
||||
MHPMCounter9 = 0xB09, // Machine performance-monitoring counter
|
||||
MHPMCounter10 = 0xB0A, // Machine performance-monitoring counter
|
||||
MHPMCounter11 = 0xB0B, // Machine performance-monitoring counter
|
||||
MHPMCounter12 = 0xB0C, // Machine performance-monitoring counter
|
||||
MHPMCounter13 = 0xB0D, // Machine performance-monitoring counter
|
||||
MHPMCounter14 = 0xB0E, // Machine performance-monitoring counter
|
||||
MHPMCounter15 = 0xB0F, // Machine performance-monitoring counter
|
||||
MHPMCounter16 = 0xB10, // Machine performance-monitoring counter
|
||||
MHPMCounter17 = 0xB11, // Machine performance-monitoring counter
|
||||
MHPMCounter18 = 0xB12, // Machine performance-monitoring counter
|
||||
MHPMCounter19 = 0xB13, // Machine performance-monitoring counter
|
||||
MHPMCounter20 = 0xB14, // Machine performance-monitoring counter
|
||||
MHPMCounter21 = 0xB15, // Machine performance-monitoring counter
|
||||
MHPMCounter22 = 0xB16, // Machine performance-monitoring counter
|
||||
MHPMCounter23 = 0xB17, // Machine performance-monitoring counter
|
||||
MHPMCounter24 = 0xB18, // Machine performance-monitoring counter
|
||||
MHPMCounter25 = 0xB19, // Machine performance-monitoring counter
|
||||
MHPMCounter26 = 0xB1A, // Machine performance-monitoring counter
|
||||
MHPMCounter27 = 0xB1B, // Machine performance-monitoring counter
|
||||
MHPMCounter28 = 0xB1C, // Machine performance-monitoring counter
|
||||
MHPMCounter29 = 0xB1D, // Machine performance-monitoring counter
|
||||
MHPMCounter30 = 0xB1E, // Machine performance-monitoring counter
|
||||
MHPMCounter31 = 0xB1F, // Machine performance-monitoring counter
|
||||
|
||||
MCycleH = 0xB80, // Upper 32 bits ofmcycle, RV32I only
|
||||
MInstRetH = 0xB82, // Upper 32 bits ofminstret, RV32I only
|
||||
|
||||
MHPMCounter3H = 0xB83, // Upper 32 bits of MHPMCounter3, RV32I only
|
||||
MHPMCounter4H = 0xB84, // Upper 32 bits of MHPMCounter4, RV32I only
|
||||
MHPMCounter5H = 0xB85, // Upper 32 bits of MHPMCounter5, RV32I only
|
||||
MHPMCounter6H = 0xB86, // Upper 32 bits of MHPMCounter6, RV32I only
|
||||
MHPMCounter7H = 0xB87, // Upper 32 bits of MHPMCounter7, RV32I only
|
||||
MHPMCounter8H = 0xB88, // Upper 32 bits of MHPMCounter8, RV32I only
|
||||
MHPMCounter9H = 0xB89, // Upper 32 bits of MHPMCounter9, RV32I only
|
||||
MHPMCounter10H = 0xB8A, // Upper 32 bits of MHPMCounter10, RV32I only
|
||||
MHPMCounter11H = 0xB8B, // Upper 32 bits of MHPMCounter11, RV32I only
|
||||
MHPMCounter12H = 0xB8C, // Upper 32 bits of MHPMCounter12, RV32I only
|
||||
MHPMCounter13H = 0xB8D, // Upper 32 bits of MHPMCounter13, RV32I only
|
||||
MHPMCounter14H = 0xB8E, // Upper 32 bits of MHPMCounter14, RV32I only
|
||||
MHPMCounter15H = 0xB8F, // Upper 32 bits of MHPMCounter15, RV32I only
|
||||
MHPMCounter16H = 0xB90, // Upper 32 bits of MHPMCounter16, RV32I only
|
||||
MHPMCounter17H = 0xB91, // Upper 32 bits of MHPMCounter17, RV32I only
|
||||
MHPMCounter18H = 0xB92, // Upper 32 bits of MHPMCounter18, RV32I only
|
||||
MHPMCounter19H = 0xB93, // Upper 32 bits of MHPMCounter19, RV32I only
|
||||
MHPMCounter20H = 0xB94, // Upper 32 bits of MHPMCounter20, RV32I only
|
||||
MHPMCounter21H = 0xB95, // Upper 32 bits of MHPMCounter21, RV32I only
|
||||
MHPMCounter22H = 0xB96, // Upper 32 bits of MHPMCounter22, RV32I only
|
||||
MHPMCounter23H = 0xB97, // Upper 32 bits of MHPMCounter23, RV32I only
|
||||
MHPMCounter24H = 0xB98, // Upper 32 bits of MHPMCounter24, RV32I only
|
||||
MHPMCounter25H = 0xB99, // Upper 32 bits of MHPMCounter25, RV32I only
|
||||
MHPMCounter26H = 0xB9A, // Upper 32 bits of MHPMCounter26, RV32I only
|
||||
MHPMCounter27H = 0xB9B, // Upper 32 bits of MHPMCounter27, RV32I only
|
||||
MHPMCounter28H = 0xB9C, // Upper 32 bits of MHPMCounter28, RV32I only
|
||||
MHPMCounter29H = 0xB9D, // Upper 32 bits of MHPMCounter29, RV32I only
|
||||
MHPMCounter30H = 0xB9E, // Upper 32 bits of MHPMCounter30, RV32I only
|
||||
MHPMCounter31H = 0xB9F, // Upper 32 bits of MHPMCounter31, RV32I only
|
||||
|
||||
MCountInhibit = 0x320, // Machine counter-inhibit register
|
||||
|
||||
MCycleCfg = 0x321, // Privilege mode filtering for cycle counter
|
||||
MCycleCfgH = 0x721, // Privilege mode filtering for cycle counter (RV32)
|
||||
MInstRetCfg = 0x322, // Privilege mode filtering for instret counters
|
||||
MInstRetCfgH = 0x722, // Privilege mode filtering for instret counters (RV32)
|
||||
|
||||
MHPMEvent3 = 0x323, // Machine performance-monitoring event selector
|
||||
MHPMEvent4 = 0x324, // Machine performance-monitoring event selector
|
||||
MHPMEvent5 = 0x325, // Machine performance-monitoring event selector
|
||||
MHPMEvent6 = 0x326, // Machine performance-monitoring event selector
|
||||
MHPMEvent7 = 0x327, // Machine performance-monitoring event selector
|
||||
MHPMEvent8 = 0x328, // Machine performance-monitoring event selector
|
||||
MHPMEvent9 = 0x329, // Machine performance-monitoring event selector
|
||||
MHPMEvent10 = 0x32A, // Machine performance-monitoring event selector
|
||||
MHPMEvent11 = 0x32B, // Machine performance-monitoring event selector
|
||||
MHPMEvent12 = 0x32C, // Machine performance-monitoring event selector
|
||||
MHPMEvent13 = 0x32D, // Machine performance-monitoring event selector
|
||||
MHPMEvent14 = 0x32E, // Machine performance-monitoring event selector
|
||||
MHPMEvent15 = 0x32F, // Machine performance-monitoring event selector
|
||||
MHPMEvent16 = 0x330, // Machine performance-monitoring event selector
|
||||
MHPMEvent17 = 0x331, // Machine performance-monitoring event selector
|
||||
MHPMEvent18 = 0x332, // Machine performance-monitoring event selector
|
||||
MHPMEvent19 = 0x333, // Machine performance-monitoring event selector
|
||||
MHPMEvent20 = 0x334, // Machine performance-monitoring event selector
|
||||
MHPMEvent21 = 0x335, // Machine performance-monitoring event selector
|
||||
MHPMEvent22 = 0x336, // Machine performance-monitoring event selector
|
||||
MHPMEvent23 = 0x337, // Machine performance-monitoring event selector
|
||||
MHPMEvent24 = 0x338, // Machine performance-monitoring event selector
|
||||
MHPMEvent25 = 0x339, // Machine performance-monitoring event selector
|
||||
MHPMEvent26 = 0x33A, // Machine performance-monitoring event selector
|
||||
MHPMEvent27 = 0x33B, // Machine performance-monitoring event selector
|
||||
MHPMEvent28 = 0x33C, // Machine performance-monitoring event selector
|
||||
MHPMEvent29 = 0x33D, // Machine performance-monitoring event selector
|
||||
MHPMEvent30 = 0x33E, // Machine performance-monitoring event selector
|
||||
MHPMEvent31 = 0x33F, // Machine performance-monitoring event selector
|
||||
|
||||
TSelect = 0x7A0, // Debug/Trace trigger register select
|
||||
TData1 = 0x7A1, // First Debug/Trace trigger data register
|
||||
TData2 = 0x7A2, // Second Debug/Trace trigger data register
|
||||
TData3 = 0x7A3, // Third Debug/Trace trigger data register
|
||||
MContext = 0x7A8, // Machine-mode context register
|
||||
|
||||
DCSR = 0x7B0, // Debug control and status register
|
||||
DPC = 0x7B1, // Debug PC
|
||||
DScratch0 = 0x7B2, // Debug scratch register 0
|
||||
DScratch1 = 0x7B3, // Debug scratch register 1
|
||||
|
||||
// Scalar Cryptography Entropy Source Extension CSRs
|
||||
|
||||
Seed = 0x015, // Entropy bit provider (up to 16 bits)
|
||||
|
||||
// Vector Extension CSRs
|
||||
|
||||
VStart = 0x008, // Vector start position
|
||||
VXSat = 0x009, // Fixed-Point Saturate Flag
|
||||
VXRM = 0x00A, // Fixed-Point Rounding Mode
|
||||
VCSR = 0x00F, // Vector control and status register
|
||||
VL = 0xC20, // Vector length
|
||||
VType = 0xC21, // Vector data type register
|
||||
VLenb = 0xC22, // Vector register length in bytes
|
||||
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
49
externals/biscuit/include/biscuit/isa.hpp
vendored
49
externals/biscuit/include/biscuit/isa.hpp
vendored
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Source file for general values and data structures
|
||||
// that don't fit a particular criteria related to the ISA.
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
enum class FenceOrder : uint32_t {
|
||||
W = 1, // Write
|
||||
R = 2, // Read
|
||||
O = 4, // Device Output
|
||||
I = 8, // Device Input
|
||||
|
||||
RW = R | W,
|
||||
|
||||
IO = I | O,
|
||||
IR = I | R,
|
||||
IW = I | W,
|
||||
IRW = I | R | W,
|
||||
|
||||
OI = O | I,
|
||||
OR = O | R,
|
||||
OW = O | W,
|
||||
ORW = O | R | W,
|
||||
|
||||
IORW = I | O | R | W,
|
||||
};
|
||||
|
||||
// Atomic ordering
|
||||
enum class Ordering : uint32_t {
|
||||
None = 0, // None
|
||||
RL = 1, // Release
|
||||
AQ = 2, // Acquire
|
||||
AQRL = AQ | RL, // Acquire-Release
|
||||
};
|
||||
|
||||
// Floating-point Rounding Mode
|
||||
enum class RMode : uint32_t {
|
||||
RNE = 0b000, // Round to Nearest, ties to Even
|
||||
RTZ = 0b001, // Round towards Zero
|
||||
RDN = 0b010, // Round Down (towards negative infinity)
|
||||
RUP = 0b011, // Round Up (towards positive infinity)
|
||||
RMM = 0b100, // Round to Nearest, ties to Max Magnitude
|
||||
DYN = 0b111, // Dynamic Rounding Mode
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
173
externals/biscuit/include/biscuit/label.hpp
vendored
173
externals/biscuit/include/biscuit/label.hpp
vendored
@@ -1,173 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <biscuit/assert.hpp>
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
/**
|
||||
* A label is a representation of an address that can be used with branch and jump instructions.
|
||||
*
|
||||
* Labels do not need to be bound to a location immediately. A label can be created
|
||||
* to provide branches with a tentative, undecided location that is then bound
|
||||
* at a later point in time.
|
||||
*
|
||||
* @note Any label that is created, is used with a branch instruction,
|
||||
* but is *not* bound to a location (via Bind() in the assembler)
|
||||
* will result in an assertion being invoked when the label instance's
|
||||
* destructor is executed.
|
||||
*
|
||||
* @note A label may only be bound to one location. Any attempt to rebind
|
||||
* a label that is already bound will result in an assertion being
|
||||
* invoked.
|
||||
*
|
||||
* @par
|
||||
* An example of binding a label:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* Assembler as{...};
|
||||
* Label label;
|
||||
*
|
||||
* as.BNE(x2, x3, &label); // Use the label
|
||||
* as.ADD(x7, x8, x9);
|
||||
* as.XOR(x7, x10, x12);
|
||||
* as.Bind(&label); // Bind the label to a location
|
||||
* @endcode
|
||||
*/
|
||||
class Label {
|
||||
public:
|
||||
using Location = std::optional<ptrdiff_t>;
|
||||
using LocationOffset = Location::value_type;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* This constructor results in a label being constructed that is not
|
||||
* bound to a particular location yet.
|
||||
*/
|
||||
explicit Label() = default;
|
||||
|
||||
/// Destructor
|
||||
~Label() noexcept {
|
||||
// It's a logic bug if something references a label and hasn't been handled.
|
||||
//
|
||||
// This is usually indicative of a scenario where a label is referenced but
|
||||
// hasn't been bound to a location.
|
||||
//
|
||||
BISCUIT_ASSERT(IsResolved());
|
||||
}
|
||||
|
||||
// We disable copying of labels, as this doesn't really make sense to do.
|
||||
// It also presents a problem. When labels are being resolved, if we have
|
||||
// two labels pointing to the same place, resolving the links to this address
|
||||
// are going to clobber each other N times for however many copies of the label
|
||||
// exist.
|
||||
//
|
||||
// This isn't a particularly major problem, since the resolving will still result
|
||||
// in the same end result, but it does make it annoying to think about label interactions
|
||||
// moving forward. Thus, I choose to simply not think about it at all!
|
||||
//
|
||||
Label(const Label&) = delete;
|
||||
Label& operator=(const Label&) = delete;
|
||||
|
||||
// Moving labels on the other hand is totally fine, this is just pushing data around
|
||||
// to another label while invalidating the label having it's data "stolen".
|
||||
Label(Label&&) noexcept = default;
|
||||
Label& operator=(Label&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* Determines whether or not this label instance has a location assigned to it.
|
||||
*
|
||||
* A label is considered bound if it has an assigned location.
|
||||
*/
|
||||
[[nodiscard]] bool IsBound() const noexcept {
|
||||
return m_location.has_value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not this label is resolved.
|
||||
*
|
||||
* A label is considered resolved when all referencing offsets have been handled.
|
||||
*/
|
||||
[[nodiscard]] bool IsResolved() const noexcept {
|
||||
return m_offsets.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not this label is unresolved.
|
||||
*
|
||||
* A label is considered unresolved if it still has any unhandled referencing offsets.
|
||||
*/
|
||||
[[nodiscard]] bool IsUnresolved() const noexcept {
|
||||
return !IsResolved();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the location for this label.
|
||||
*
|
||||
* @note If the returned location is empty, then this label has not been assigned
|
||||
* a location yet.
|
||||
*/
|
||||
[[nodiscard]] Location GetLocation() const noexcept {
|
||||
return m_location;
|
||||
}
|
||||
|
||||
private:
|
||||
// A label instance is inherently bound to the assembler it's
|
||||
// used with, as the offsets within the label set depend on
|
||||
// said assemblers code buffer.
|
||||
friend class Assembler;
|
||||
|
||||
/**
|
||||
* Binds a label to the given location.
|
||||
*
|
||||
* @param offset The instruction offset to bind this label to.
|
||||
*
|
||||
* @pre The label must not have already been bound to a previous location.
|
||||
* Attempting to rebind a label is typically, in almost all scenarios,
|
||||
* the source of bugs.
|
||||
* Attempting to rebind an already bound label will result in an assertion
|
||||
* being triggered.
|
||||
*/
|
||||
void Bind(LocationOffset offset) noexcept {
|
||||
BISCUIT_ASSERT(!IsBound());
|
||||
m_location = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given address as dependent on this label.
|
||||
*
|
||||
* This is used in scenarios where a label exists, but has not yet been
|
||||
* bound to a location yet. It's important to track these addresses,
|
||||
* as we'll need to patch the dependent branch instructions with the
|
||||
* proper offset once the label is finally bound by the assembler.
|
||||
*
|
||||
* During label binding, the offset will be calculated and inserted
|
||||
* into dependent instructions.
|
||||
*/
|
||||
void AddOffset(LocationOffset offset) {
|
||||
// If a label is already bound to a location, then offset tracking
|
||||
// isn't necessary. Tripping this assert means we have a bug somewhere.
|
||||
BISCUIT_ASSERT(!IsBound());
|
||||
BISCUIT_ASSERT(IsNewOffset(offset));
|
||||
|
||||
m_offsets.insert(offset);
|
||||
}
|
||||
|
||||
// Clears all the underlying offsets for this label.
|
||||
void ClearOffsets() noexcept {
|
||||
m_offsets.clear();
|
||||
}
|
||||
|
||||
// Determines whether or not this address has already been added before.
|
||||
[[nodiscard]] bool IsNewOffset(LocationOffset offset) const noexcept {
|
||||
return m_offsets.find(offset) == m_offsets.cend();
|
||||
}
|
||||
|
||||
std::set<LocationOffset> m_offsets;
|
||||
Location m_location;
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
315
externals/biscuit/include/biscuit/registers.hpp
vendored
315
externals/biscuit/include/biscuit/registers.hpp
vendored
@@ -1,315 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <biscuit/assert.hpp>
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
/**
|
||||
* Generic abstraction around a register.
|
||||
*
|
||||
* This is less bug-prone than using raw primitive sizes
|
||||
* in opcode emitter functions, since it provides stronger typing.
|
||||
*/
|
||||
class Register {
|
||||
public:
|
||||
constexpr Register() noexcept = default;
|
||||
|
||||
/// Gets the index for this register.
|
||||
[[nodiscard]] constexpr uint32_t Index() const noexcept {
|
||||
return m_index;
|
||||
}
|
||||
|
||||
friend constexpr bool operator==(Register, Register) = default;
|
||||
friend constexpr auto operator<=>(Register, Register) = default;
|
||||
|
||||
protected:
|
||||
constexpr explicit Register(uint32_t index) noexcept
|
||||
: m_index{index} {}
|
||||
|
||||
private:
|
||||
uint32_t m_index{};
|
||||
};
|
||||
|
||||
/// General purpose register.
|
||||
class GPR final : public Register {
|
||||
public:
|
||||
constexpr GPR() noexcept : Register{0} {}
|
||||
constexpr explicit GPR(uint32_t index) noexcept : Register{index} {}
|
||||
|
||||
friend constexpr bool operator==(GPR, GPR) = default;
|
||||
friend constexpr auto operator<=>(GPR, GPR) = default;
|
||||
};
|
||||
|
||||
/// Floating point register.
|
||||
class FPR final : public Register {
|
||||
public:
|
||||
constexpr FPR() noexcept : Register{0} {}
|
||||
constexpr explicit FPR(uint32_t index) noexcept : Register{index} {}
|
||||
|
||||
friend constexpr bool operator==(FPR, FPR) = default;
|
||||
friend constexpr auto operator<=>(FPR, FPR) = default;
|
||||
};
|
||||
|
||||
/// Vector register.
|
||||
class Vec final : public Register {
|
||||
public:
|
||||
constexpr Vec() noexcept : Register{0} {}
|
||||
constexpr explicit Vec(uint32_t index) noexcept : Register{index} {}
|
||||
|
||||
friend constexpr bool operator==(Vec, Vec) = default;
|
||||
friend constexpr auto operator<=>(Vec, Vec) = default;
|
||||
};
|
||||
|
||||
// General-purpose Registers
|
||||
|
||||
constexpr GPR x0{0};
|
||||
constexpr GPR x1{1};
|
||||
constexpr GPR x2{2};
|
||||
constexpr GPR x3{3};
|
||||
constexpr GPR x4{4};
|
||||
constexpr GPR x5{5};
|
||||
constexpr GPR x6{6};
|
||||
constexpr GPR x7{7};
|
||||
constexpr GPR x8{8};
|
||||
constexpr GPR x9{9};
|
||||
constexpr GPR x10{10};
|
||||
constexpr GPR x11{11};
|
||||
constexpr GPR x12{12};
|
||||
constexpr GPR x13{13};
|
||||
constexpr GPR x14{14};
|
||||
constexpr GPR x15{15};
|
||||
constexpr GPR x16{16};
|
||||
constexpr GPR x17{17};
|
||||
constexpr GPR x18{18};
|
||||
constexpr GPR x19{19};
|
||||
constexpr GPR x20{20};
|
||||
constexpr GPR x21{21};
|
||||
constexpr GPR x22{22};
|
||||
constexpr GPR x23{23};
|
||||
constexpr GPR x24{24};
|
||||
constexpr GPR x25{25};
|
||||
constexpr GPR x26{26};
|
||||
constexpr GPR x27{27};
|
||||
constexpr GPR x28{28};
|
||||
constexpr GPR x29{29};
|
||||
constexpr GPR x30{30};
|
||||
constexpr GPR x31{31};
|
||||
|
||||
// Symbolic General-purpose Register Names
|
||||
|
||||
constexpr GPR zero{x0};
|
||||
|
||||
constexpr GPR ra{x1};
|
||||
constexpr GPR sp{x2};
|
||||
constexpr GPR gp{x3};
|
||||
constexpr GPR tp{x4};
|
||||
constexpr GPR fp{x8};
|
||||
|
||||
constexpr GPR a0{x10};
|
||||
constexpr GPR a1{x11};
|
||||
constexpr GPR a2{x12};
|
||||
constexpr GPR a3{x13};
|
||||
constexpr GPR a4{x14};
|
||||
constexpr GPR a5{x15};
|
||||
constexpr GPR a6{x16};
|
||||
constexpr GPR a7{x17};
|
||||
|
||||
constexpr GPR s0{x8};
|
||||
constexpr GPR s1{x9};
|
||||
constexpr GPR s2{x18};
|
||||
constexpr GPR s3{x19};
|
||||
constexpr GPR s4{x20};
|
||||
constexpr GPR s5{x21};
|
||||
constexpr GPR s6{x22};
|
||||
constexpr GPR s7{x23};
|
||||
constexpr GPR s8{x24};
|
||||
constexpr GPR s9{x25};
|
||||
constexpr GPR s10{x26};
|
||||
constexpr GPR s11{x27};
|
||||
|
||||
constexpr GPR t0{x5};
|
||||
constexpr GPR t1{x6};
|
||||
constexpr GPR t2{x7};
|
||||
constexpr GPR t3{x28};
|
||||
constexpr GPR t4{x29};
|
||||
constexpr GPR t5{x30};
|
||||
constexpr GPR t6{x31};
|
||||
|
||||
// Floating-point registers
|
||||
|
||||
constexpr FPR f0{0};
|
||||
constexpr FPR f1{1};
|
||||
constexpr FPR f2{2};
|
||||
constexpr FPR f3{3};
|
||||
constexpr FPR f4{4};
|
||||
constexpr FPR f5{5};
|
||||
constexpr FPR f6{6};
|
||||
constexpr FPR f7{7};
|
||||
constexpr FPR f8{8};
|
||||
constexpr FPR f9{9};
|
||||
constexpr FPR f10{10};
|
||||
constexpr FPR f11{11};
|
||||
constexpr FPR f12{12};
|
||||
constexpr FPR f13{13};
|
||||
constexpr FPR f14{14};
|
||||
constexpr FPR f15{15};
|
||||
constexpr FPR f16{16};
|
||||
constexpr FPR f17{17};
|
||||
constexpr FPR f18{18};
|
||||
constexpr FPR f19{19};
|
||||
constexpr FPR f20{20};
|
||||
constexpr FPR f21{21};
|
||||
constexpr FPR f22{22};
|
||||
constexpr FPR f23{23};
|
||||
constexpr FPR f24{24};
|
||||
constexpr FPR f25{25};
|
||||
constexpr FPR f26{26};
|
||||
constexpr FPR f27{27};
|
||||
constexpr FPR f28{28};
|
||||
constexpr FPR f29{29};
|
||||
constexpr FPR f30{30};
|
||||
constexpr FPR f31{31};
|
||||
|
||||
// Symbolic Floating-point Register Names
|
||||
|
||||
constexpr FPR fa0{f10};
|
||||
constexpr FPR fa1{f11};
|
||||
constexpr FPR fa2{f12};
|
||||
constexpr FPR fa3{f13};
|
||||
constexpr FPR fa4{f14};
|
||||
constexpr FPR fa5{f15};
|
||||
constexpr FPR fa6{f16};
|
||||
constexpr FPR fa7{f17};
|
||||
|
||||
constexpr FPR ft0{f0};
|
||||
constexpr FPR ft1{f1};
|
||||
constexpr FPR ft2{f2};
|
||||
constexpr FPR ft3{f3};
|
||||
constexpr FPR ft4{f4};
|
||||
constexpr FPR ft5{f5};
|
||||
constexpr FPR ft6{f6};
|
||||
constexpr FPR ft7{f7};
|
||||
constexpr FPR ft8{f28};
|
||||
constexpr FPR ft9{f29};
|
||||
constexpr FPR ft10{f30};
|
||||
constexpr FPR ft11{f31};
|
||||
|
||||
constexpr FPR fs0{f8};
|
||||
constexpr FPR fs1{f9};
|
||||
constexpr FPR fs2{f18};
|
||||
constexpr FPR fs3{f19};
|
||||
constexpr FPR fs4{f20};
|
||||
constexpr FPR fs5{f21};
|
||||
constexpr FPR fs6{f22};
|
||||
constexpr FPR fs7{f23};
|
||||
constexpr FPR fs8{f24};
|
||||
constexpr FPR fs9{f25};
|
||||
constexpr FPR fs10{f26};
|
||||
constexpr FPR fs11{f27};
|
||||
|
||||
// Vector registers (V extension)
|
||||
|
||||
constexpr Vec v0{0};
|
||||
constexpr Vec v1{1};
|
||||
constexpr Vec v2{2};
|
||||
constexpr Vec v3{3};
|
||||
constexpr Vec v4{4};
|
||||
constexpr Vec v5{5};
|
||||
constexpr Vec v6{6};
|
||||
constexpr Vec v7{7};
|
||||
constexpr Vec v8{8};
|
||||
constexpr Vec v9{9};
|
||||
constexpr Vec v10{10};
|
||||
constexpr Vec v11{11};
|
||||
constexpr Vec v12{12};
|
||||
constexpr Vec v13{13};
|
||||
constexpr Vec v14{14};
|
||||
constexpr Vec v15{15};
|
||||
constexpr Vec v16{16};
|
||||
constexpr Vec v17{17};
|
||||
constexpr Vec v18{18};
|
||||
constexpr Vec v19{19};
|
||||
constexpr Vec v20{20};
|
||||
constexpr Vec v21{21};
|
||||
constexpr Vec v22{22};
|
||||
constexpr Vec v23{23};
|
||||
constexpr Vec v24{24};
|
||||
constexpr Vec v25{25};
|
||||
constexpr Vec v26{26};
|
||||
constexpr Vec v27{27};
|
||||
constexpr Vec v28{28};
|
||||
constexpr Vec v29{29};
|
||||
constexpr Vec v30{30};
|
||||
constexpr Vec v31{31};
|
||||
|
||||
// Register utilities
|
||||
|
||||
// Used with compressed stack management instructions
|
||||
// (cm.push, cm.pop, etc) for building up a register list to encode.
|
||||
//
|
||||
// Also enforces that only valid registers are used in the lists.
|
||||
class PushPopList final {
|
||||
public:
|
||||
// Represents an inclusive range ([start, end]) of registers.
|
||||
struct Range final {
|
||||
// Signifies an empty range. Normally this doesn't need to explicitly
|
||||
// be created. Default parameters will usually take care of it.
|
||||
constexpr Range() : start{UINT32_MAX}, end{UINT32_MAX} {}
|
||||
|
||||
// This particular constructor is used for the case of rlist=5
|
||||
// where only ra and s0 get stored.
|
||||
constexpr Range(GPR start_end) noexcept : start{start_end}, end{start_end} {
|
||||
BISCUIT_ASSERT(start_end == s0);
|
||||
}
|
||||
|
||||
constexpr Range(GPR start_, GPR end_) noexcept : start{start_}, end{end_} {
|
||||
BISCUIT_ASSERT(start_ == s0);
|
||||
BISCUIT_ASSERT(IsSRegister(end_));
|
||||
|
||||
// See the Zc spec. The only way for s10 to be used is to also include s11.
|
||||
BISCUIT_ASSERT(end_ != s10);
|
||||
}
|
||||
|
||||
GPR start;
|
||||
GPR end;
|
||||
};
|
||||
|
||||
// Deliberately non-explicit to allow for convenient instantiation at usage sites.
|
||||
// e.g. Rather than CM.POP(PushPopList{ra, {s0, s2}}, 16), we can just have the
|
||||
// usage be transparent like CM.POP({ra, {s0, s2}}, 16). Nice and compact!
|
||||
constexpr PushPopList(GPR ra_reg, const Range& range = {}) noexcept
|
||||
: m_bitmask{BuildBitmask(range)} {
|
||||
BISCUIT_ASSERT(ra_reg == ra);
|
||||
}
|
||||
|
||||
// Gets the built-up bitmask of passed in registers
|
||||
[[nodiscard]] constexpr uint32_t GetBitmask() const noexcept {
|
||||
return m_bitmask;
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] static constexpr uint32_t BuildBitmask(const Range& range) noexcept {
|
||||
if (range.end.Index() == UINT32_MAX) {
|
||||
return 4U;
|
||||
}
|
||||
if (range.end == s11) {
|
||||
return 15U;
|
||||
}
|
||||
if (range.end == s0 || range.end == s1) {
|
||||
return range.end.Index() - 3U;
|
||||
}
|
||||
return range.end.Index() - 11U;
|
||||
}
|
||||
|
||||
// Aside from ra, it's only valid for s0-s11 to show up the register list ranges.
|
||||
[[nodiscard]] static constexpr bool IsSRegister(const GPR gpr) noexcept {
|
||||
return gpr == s0 || gpr == s1 || (gpr >= s2 && gpr <= s11);
|
||||
}
|
||||
|
||||
uint32_t m_bitmask = 0;
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
88
externals/biscuit/include/biscuit/vector.hpp
vendored
88
externals/biscuit/include/biscuit/vector.hpp
vendored
@@ -1,88 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Source file for anything specific to the RISC-V vector extension.
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
/// Describes whether or not an instruction should make use of the mask vector.
|
||||
enum class VecMask : uint32_t {
|
||||
Yes = 0,
|
||||
No = 1,
|
||||
};
|
||||
|
||||
/// Describes the selected element width.
|
||||
enum class SEW : uint32_t {
|
||||
E8 = 0b000, // 8-bit vector elements
|
||||
E16 = 0b001, // 16-bit vector elements
|
||||
E32 = 0b010, // 32-bit vector elements
|
||||
E64 = 0b011, // 64-bit vector elements
|
||||
E128 = 0b100, // 128-bit vector elements
|
||||
E256 = 0b101, // 256-bit vector elements
|
||||
E512 = 0b110, // 512-bit vector elements
|
||||
E1024 = 0b111, // 1024-bit vector elements
|
||||
};
|
||||
|
||||
/// Describes the selected register group multiplier.
|
||||
enum class LMUL : uint32_t {
|
||||
M1 = 0b000, // Group of one vector
|
||||
M2 = 0b001, // Groups of two vectors
|
||||
M4 = 0b010, // Groups of four vectors
|
||||
M8 = 0b011, // Groups of eight vectors
|
||||
MF8 = 0b101, // Fractional vector group (1/8)
|
||||
MF4 = 0b110, // Fractional vector group (1/4)
|
||||
MF2 = 0b111, // Fractional vector group (1/2)
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes whether or not vector masks are agnostic.
|
||||
*
|
||||
* From the RVV spec:
|
||||
*
|
||||
* When a set is marked undisturbed, the corresponding set of
|
||||
* destination elements in a vector register group retain the
|
||||
* value they previously held.
|
||||
*
|
||||
* When a set is marked agnostic, the corresponding set of destination
|
||||
* elements in any vector destination operand can either retain the value
|
||||
* they previously held, or are overwritten with 1s.
|
||||
*
|
||||
* Within a single vector instruction, each destination element can be either
|
||||
* left undisturbed or overwritten with 1s, in any combination, and the pattern
|
||||
* of undisturbed or overwritten with 1s is not required to be deterministic when
|
||||
* the instruction is executed with the same inputs. In addition, except for
|
||||
* mask load instructions, any element in the tail of a mask result can also be
|
||||
* written with the value the mask-producing operation would have calculated with vl=VLMAX
|
||||
*/
|
||||
enum class VMA : uint32_t {
|
||||
No, // Undisturbed
|
||||
Yes, // Agnostic
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes whether or not vector tail elements are agnostic.
|
||||
*
|
||||
* From the RVV spec:
|
||||
*
|
||||
* When a set is marked undisturbed, the corresponding set of
|
||||
* destination elements in a vector register group retain the
|
||||
* value they previously held.
|
||||
*
|
||||
* When a set is marked agnostic, the corresponding set of destination
|
||||
* elements in any vector destination operand can either retain the value
|
||||
* they previously held, or are overwritten with 1s.
|
||||
*
|
||||
* Within a single vector instruction, each destination element can be either
|
||||
* left undisturbed or overwritten with 1s, in any combination, and the pattern
|
||||
* of undisturbed or overwritten with 1s is not required to be deterministic when
|
||||
* the instruction is executed with the same inputs. In addition, except for
|
||||
* mask load instructions, any element in the tail of a mask result can also be
|
||||
* written with the value the mask-producing operation would have calculated with vl=VLMAX
|
||||
*/
|
||||
enum class VTA : uint32_t {
|
||||
No, // Undisturbed
|
||||
Yes, // Agnostic
|
||||
};
|
||||
|
||||
} // namespace biscuit
|
||||
156
externals/biscuit/src/CMakeLists.txt
vendored
156
externals/biscuit/src/CMakeLists.txt
vendored
@@ -1,156 +0,0 @@
|
||||
# Main library
|
||||
|
||||
add_library(biscuit
|
||||
# Source files
|
||||
assembler.cpp
|
||||
assembler_compressed.cpp
|
||||
assembler_crypto.cpp
|
||||
assembler_floating_point.cpp
|
||||
assembler_vector.cpp
|
||||
code_buffer.cpp
|
||||
cpuinfo.cpp
|
||||
|
||||
# Headers
|
||||
assembler_util.hpp
|
||||
"${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)
|
||||
1401
externals/biscuit/src/assembler.cpp
vendored
1401
externals/biscuit/src/assembler.cpp
vendored
File diff suppressed because it is too large
Load Diff
696
externals/biscuit/src/assembler_compressed.cpp
vendored
696
externals/biscuit/src/assembler_compressed.cpp
vendored
@@ -1,696 +0,0 @@
|
||||
#include <biscuit/assert.hpp>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include "assembler_util.hpp"
|
||||
|
||||
// RVC Extension Instructions
|
||||
|
||||
namespace biscuit {
|
||||
namespace {
|
||||
// Emits a compressed branch instruction. These consist of:
|
||||
// funct3 | imm[8|4:3] | rs | imm[7:6|2:1|5] | op
|
||||
void EmitCompressedBranch(CodeBuffer& buffer, uint32_t funct3, int32_t offset, GPR rs, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValidCBTypeImm(offset));
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rs));
|
||||
|
||||
const auto transformed_imm = TransformToCBTypeImm(static_cast<uint32_t>(offset));
|
||||
const auto rs_san = CompressedRegTo3BitEncoding(rs);
|
||||
buffer.Emit16(((funct3 & 0b111) << 13) | transformed_imm | (rs_san << 7) | (op & 0b11));
|
||||
}
|
||||
|
||||
// Emits a compressed jump instruction. These consist of:
|
||||
// funct3 | imm | op
|
||||
void EmitCompressedJump(CodeBuffer& buffer, uint32_t funct3, int32_t offset, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValidCJTypeImm(offset));
|
||||
BISCUIT_ASSERT((offset % 2) == 0);
|
||||
|
||||
buffer.Emit16(TransformToCJTypeImm(static_cast<uint32_t>(offset)) |
|
||||
((funct3 & 0b111) << 13) | (op & 0b11));
|
||||
}
|
||||
|
||||
// Emits a compress immediate instruction. These consist of:
|
||||
// funct3 | imm | rd | imm | op
|
||||
void EmitCompressedImmediate(CodeBuffer& buffer, uint32_t funct3, uint32_t imm, GPR rd, uint32_t op) {
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
|
||||
const auto new_imm = ((imm & 0b11111) << 2) | ((imm & 0b100000) << 7);
|
||||
buffer.Emit16(((funct3 & 0b111) << 13) | new_imm | (rd.Index() << 7) | (op & 0b11));
|
||||
}
|
||||
|
||||
// Emits a compressed load instruction. These consist of:
|
||||
// funct3 | imm | rs1 | imm | rd | op
|
||||
void EmitCompressedLoad(CodeBuffer& buffer, uint32_t funct3, uint32_t imm, GPR rs,
|
||||
Register rd, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rs));
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
|
||||
imm &= 0xF8;
|
||||
|
||||
const auto imm_enc = ((imm & 0x38) << 7) | ((imm & 0xC0) >> 1);
|
||||
const auto rd_san = CompressedRegTo3BitEncoding(rd);
|
||||
const auto rs_san = CompressedRegTo3BitEncoding(rs);
|
||||
buffer.Emit16(((funct3 & 0b111) << 13) | imm_enc | (rs_san << 7) | (rd_san << 2) | (op & 0b11));
|
||||
}
|
||||
|
||||
// Emits a compressed register arithmetic instruction. These consist of:
|
||||
// funct6 | rd | funct2 | rs | op
|
||||
void EmitCompressedRegArith(CodeBuffer& buffer, uint32_t funct6, GPR rd, uint32_t funct2,
|
||||
GPR rs, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rs));
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
|
||||
const auto rd_san = CompressedRegTo3BitEncoding(rd);
|
||||
const auto rs_san = CompressedRegTo3BitEncoding(rs);
|
||||
buffer.Emit16(((funct6 & 0b111111) << 10) | (rd_san << 7) | ((funct2 & 0b11) << 5) |
|
||||
(rs_san << 2) | (op & 0b11));
|
||||
}
|
||||
|
||||
// Emits a compressed store instruction. These consist of:
|
||||
// funct3 | imm | rs1 | imm | rs2 | op
|
||||
void EmitCompressedStore(CodeBuffer& buffer, uint32_t funct3, uint32_t imm, GPR rs1,
|
||||
Register rs2, uint32_t op) {
|
||||
// This has the same format as a compressed load, with rs2 taking the place of rd.
|
||||
// We can reuse the code we've already written to handle this.
|
||||
EmitCompressedLoad(buffer, funct3, imm, rs1, rs2, op);
|
||||
}
|
||||
|
||||
// Emits a compressed wide immediate instruction. These consist of:
|
||||
// funct3 | imm | rd | opcode
|
||||
void EmitCompressedWideImmediate(CodeBuffer& buffer, uint32_t funct3, uint32_t imm,
|
||||
GPR rd, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
|
||||
const auto rd_sanitized = CompressedRegTo3BitEncoding(rd);
|
||||
buffer.Emit16(((funct3 & 0b111) << 13) | ((imm & 0xFF) << 5) |
|
||||
(rd_sanitized << 2) | (op & 0b11));
|
||||
}
|
||||
|
||||
void EmitCLBType(CodeBuffer& buffer, uint32_t funct6, GPR rs, uint32_t uimm, GPR rd,
|
||||
uint32_t op, uint32_t b6) {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rs));
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
BISCUIT_ASSERT(uimm <= 3);
|
||||
|
||||
const auto rd_san = CompressedRegTo3BitEncoding(rd);
|
||||
const auto rs_san = CompressedRegTo3BitEncoding(rs);
|
||||
|
||||
buffer.Emit16((funct6 << 10) | (rs_san << 7) | (b6 << 6) | (uimm << 5) | (rd_san << 2) | op);
|
||||
}
|
||||
|
||||
void EmitCLHType(CodeBuffer& buffer, uint32_t funct6, GPR rs, uint32_t uimm, GPR rd,
|
||||
uint32_t op, uint32_t b6) {
|
||||
BISCUIT_ASSERT((uimm % 2) == 0);
|
||||
BISCUIT_ASSERT(uimm <= 2);
|
||||
|
||||
// Only have 1 bit of encoding space for the immediate.
|
||||
const uint32_t uimm_fixed = uimm >> 1;
|
||||
EmitCLBType(buffer, funct6, rs, uimm_fixed, rd, op, b6);
|
||||
}
|
||||
|
||||
// These have the same layout as the equivalent loads, we just essentially alias
|
||||
// the name of those to provide better intent at the call site.
|
||||
void EmitCSBType(CodeBuffer& buffer, uint32_t funct6, GPR rs, uint32_t uimm, GPR rd, uint32_t op) {
|
||||
EmitCLBType(buffer, funct6, rs, uimm, rd, op, 0);
|
||||
}
|
||||
void EmitCSHType(CodeBuffer& buffer, uint32_t funct6, GPR rs, uint32_t uimm, GPR rd, uint32_t op) {
|
||||
EmitCLHType(buffer, funct6, rs, uimm, rd, op, 0);
|
||||
}
|
||||
|
||||
void EmitCUType(CodeBuffer& buffer, uint32_t funct6, GPR rd, uint32_t funct5, uint32_t op) {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
const auto rd_san = CompressedRegTo3BitEncoding(rd);
|
||||
|
||||
buffer.Emit16((funct6 << 10) | (rd_san << 7) | (funct5 << 2) | op);
|
||||
}
|
||||
|
||||
void EmitCMJTType(CodeBuffer& buffer, uint32_t funct6, uint32_t index, uint32_t op) {
|
||||
buffer.Emit16((funct6 << 10) | (index << 2) | op);
|
||||
}
|
||||
|
||||
void EmitCMMVType(CodeBuffer& buffer, uint32_t funct6, GPR r1s, uint32_t funct2, GPR r2s, uint32_t op) {
|
||||
const auto is_valid_s_register = [](GPR reg) {
|
||||
return reg == s0 || reg == s1 || (reg >= s2 && reg <= s7);
|
||||
};
|
||||
|
||||
BISCUIT_ASSERT(r1s != r2s);
|
||||
BISCUIT_ASSERT(is_valid_s_register(r1s));
|
||||
BISCUIT_ASSERT(is_valid_s_register(r2s));
|
||||
|
||||
const auto r1s_san = r1s.Index() & 0b111;
|
||||
const auto r2s_san = r2s.Index() & 0b111;
|
||||
|
||||
buffer.Emit16((funct6 << 10) | (r1s_san << 7) | (funct2 << 5) | (r2s_san << 2) | op);
|
||||
}
|
||||
|
||||
void EmitCMPPType(CodeBuffer& buffer, uint32_t funct6, uint32_t funct2, PushPopList reglist,
|
||||
int32_t stack_adj, uint32_t op, ArchFeature feature) {
|
||||
BISCUIT_ASSERT(stack_adj % 16 == 0);
|
||||
|
||||
static constexpr std::array stack_adj_bases_rv32{
|
||||
0U, 0U, 0U, 0U, 16U, 16U, 16U, 16U,
|
||||
32U, 32U, 32U, 32U, 48U, 48U, 48U, 64U,
|
||||
};
|
||||
static constexpr std::array stack_adj_bases_rv64{
|
||||
0U, 0U, 0U, 0U, 16U, 16U, 32U, 32U,
|
||||
48U, 48U, 64U, 64U, 80U, 80U, 96U, 112U
|
||||
};
|
||||
|
||||
const auto bitmask = reglist.GetBitmask();
|
||||
const auto stack_adj_base = IsRV64(feature) ? stack_adj_bases_rv64[bitmask]
|
||||
: stack_adj_bases_rv32[bitmask];
|
||||
const auto stack_adj_u = static_cast<uint32_t>(std::abs(stack_adj));
|
||||
const auto spimm = (stack_adj_u - stack_adj_base) / 16U;
|
||||
|
||||
// We can only encode up to three differenct values as the upper spimm bits.
|
||||
// Ensure we catch any cases where we end up going outside of them.
|
||||
BISCUIT_ASSERT(stack_adj_u == stack_adj_base ||
|
||||
stack_adj_u == stack_adj_base + 16 ||
|
||||
stack_adj_u == stack_adj_base + 32 ||
|
||||
stack_adj_u == stack_adj_base + 48);
|
||||
|
||||
buffer.Emit16((funct6 << 10) | (funct2 << 8) | (bitmask << 4) | (spimm << 2) | op);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void Assembler::C_ADD(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(rs != x0);
|
||||
m_buffer.Emit16(0x9002 | (rd.Index() << 7) | (rs.Index() << 2));
|
||||
}
|
||||
|
||||
void Assembler::C_ADDI(GPR rd, int32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(imm != 0);
|
||||
BISCUIT_ASSERT(IsValidSigned6BitImm(imm));
|
||||
EmitCompressedImmediate(m_buffer, 0b000, static_cast<uint32_t>(imm), rd, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_ADDIW(GPR rd, int32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
BISCUIT_ASSERT(IsValidSigned6BitImm(imm));
|
||||
EmitCompressedImmediate(m_buffer, 0b001, static_cast<uint32_t>(imm), rd, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_ADDI4SPN(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(imm != 0);
|
||||
BISCUIT_ASSERT(imm <= 1020);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x030) << 2) |
|
||||
((imm & 0x3C0) >> 4) |
|
||||
((imm & 0x004) >> 1) |
|
||||
((imm & 0x008) >> 3);
|
||||
// clang-format on
|
||||
|
||||
EmitCompressedWideImmediate(m_buffer, 0b000, new_imm, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_ADDW(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
EmitCompressedRegArith(m_buffer, 0b100111, rd, 0b01, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_ADDI16SP(int32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(imm != 0);
|
||||
BISCUIT_ASSERT(imm >= -512 && imm <= 496);
|
||||
BISCUIT_ASSERT(imm % 16 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto uimm = static_cast<uint32_t>(imm);
|
||||
const auto new_imm = ((uimm & 0x020) >> 3) |
|
||||
((uimm & 0x180) >> 4) |
|
||||
((uimm & 0x040) >> 1) |
|
||||
((uimm & 0x010) << 2) |
|
||||
((uimm & 0x200) << 3);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x6000U | new_imm | (x2.Index() << 7) | 0b01U);
|
||||
}
|
||||
|
||||
void Assembler::C_AND(GPR rd, GPR rs) noexcept {
|
||||
EmitCompressedRegArith(m_buffer, 0b100011, rd, 0b11, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_ANDI(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
|
||||
constexpr auto base = 0x8801U;
|
||||
const auto shift_enc = ((imm & 0b11111) << 2) | ((imm & 0b100000) << 7);
|
||||
const auto reg = CompressedRegTo3BitEncoding(rd);
|
||||
|
||||
m_buffer.Emit16(base | shift_enc | (reg << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_BEQZ(GPR rs, int32_t offset) noexcept {
|
||||
EmitCompressedBranch(m_buffer, 0b110, offset, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_BEQZ(GPR rs, Label* label) noexcept {
|
||||
const auto address = LinkAndGetOffset(label);
|
||||
C_BEQZ(rs, static_cast<int32_t>(address));
|
||||
}
|
||||
|
||||
void Assembler::C_BNEZ(GPR rs, int32_t offset) noexcept {
|
||||
EmitCompressedBranch(m_buffer, 0b111, offset, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_BNEZ(GPR rs, Label* label) noexcept {
|
||||
const auto address = LinkAndGetOffset(label);
|
||||
C_BNEZ(rs, static_cast<int32_t>(address));
|
||||
}
|
||||
|
||||
void Assembler::C_EBREAK() noexcept {
|
||||
m_buffer.Emit16(0x9002);
|
||||
}
|
||||
|
||||
void Assembler::C_FLD(FPR rd, uint32_t imm, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32OrRV64(m_features));
|
||||
BISCUIT_ASSERT(imm <= 248);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
EmitCompressedLoad(m_buffer, 0b001, imm, rs, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_FLDSP(FPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32OrRV64(m_features));
|
||||
BISCUIT_ASSERT(imm <= 504);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x018) << 2) |
|
||||
((imm & 0x1C0) >> 4) |
|
||||
((imm & 0x020) << 7);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x2002U | (rd.Index() << 7) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_FLW(FPR rd, uint32_t imm, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
BISCUIT_ASSERT(imm <= 124);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
imm &= 0x7C;
|
||||
const auto new_imm = ((imm & 0b0100) << 5) | (imm & 0x78);
|
||||
EmitCompressedLoad(m_buffer, 0b011, new_imm, rs, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_FLWSP(FPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
BISCUIT_ASSERT(imm <= 252);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x020) << 7) |
|
||||
((imm & 0x0C0) >> 4) |
|
||||
((imm & 0x01C) << 2);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x6002U | (rd.Index() << 7) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_FSD(FPR rs2, uint32_t imm, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32OrRV64(m_features));
|
||||
BISCUIT_ASSERT(imm <= 248);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
EmitCompressedStore(m_buffer, 0b101, imm, rs1, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_FSDSP(FPR rs, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32OrRV64(m_features));
|
||||
BISCUIT_ASSERT(imm <= 504);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x038) << 7) |
|
||||
((imm & 0x1C0) << 1);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0xA002U | (rs.Index() << 2) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_J(Label* label) noexcept {
|
||||
const auto address = LinkAndGetOffset(label);
|
||||
C_J(static_cast<int32_t>(address));
|
||||
}
|
||||
|
||||
void Assembler::C_J(int32_t offset) noexcept {
|
||||
EmitCompressedJump(m_buffer, 0b101, offset, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_JAL(Label* label) noexcept {
|
||||
const auto address = LinkAndGetOffset(label);
|
||||
C_JAL(static_cast<int32_t>(address));
|
||||
}
|
||||
|
||||
void Assembler::C_JAL(int32_t offset) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitCompressedJump(m_buffer, 0b001, offset, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_FSW(FPR rs2, uint32_t imm, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
BISCUIT_ASSERT(imm <= 124);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
imm &= 0x7C;
|
||||
const auto new_imm = ((imm & 0b0100) << 5) | (imm & 0x78);
|
||||
EmitCompressedStore(m_buffer, 0b111, new_imm, rs1, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_FSWSP(FPR rs, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
BISCUIT_ASSERT(imm <= 252);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x0C0) << 1) |
|
||||
((imm & 0x03C) << 7);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0xE002U | (rs.Index() << 2) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_JALR(GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(rs != x0);
|
||||
m_buffer.Emit16(0x9002 | (rs.Index() << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_JR(GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(rs != x0);
|
||||
m_buffer.Emit16(0x8002 | (rs.Index() << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_LD(GPR rd, uint32_t imm, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 248);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
EmitCompressedLoad(m_buffer, 0b011, imm, rs, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_LDSP(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
BISCUIT_ASSERT(imm <= 504);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x018) << 2) |
|
||||
((imm & 0x1C0) >> 4) |
|
||||
((imm & 0x020) << 7);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x6002U | (rd.Index() << 7) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_LI(GPR rd, int32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned6BitImm(imm));
|
||||
EmitCompressedImmediate(m_buffer, 0b010, static_cast<uint32_t>(imm), rd, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_LQ(GPR rd, uint32_t imm, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 496);
|
||||
BISCUIT_ASSERT(imm % 16 == 0);
|
||||
|
||||
imm &= 0x1F0;
|
||||
const auto new_imm = ((imm & 0x100) >> 5) | (imm & 0xF0);
|
||||
EmitCompressedLoad(m_buffer, 0b001, new_imm, rs, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_LQSP(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
BISCUIT_ASSERT(imm <= 1008);
|
||||
BISCUIT_ASSERT(imm % 16 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x020) << 7) |
|
||||
((imm & 0x010) << 2) |
|
||||
((imm & 0x3C0) >> 4);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x2002U | (rd.Index() << 7) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_LUI(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(imm != 0);
|
||||
BISCUIT_ASSERT(rd != x0 && rd != x2);
|
||||
|
||||
const auto new_imm = (imm & 0x3F000) >> 12;
|
||||
EmitCompressedImmediate(m_buffer, 0b011, new_imm, rd, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_LW(GPR rd, uint32_t imm, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(imm <= 124);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
imm &= 0x7C;
|
||||
const auto new_imm = ((imm & 0b0100) << 5) | (imm & 0x78);
|
||||
EmitCompressedLoad(m_buffer, 0b010, new_imm, rs, rd, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_LWSP(GPR rd, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
BISCUIT_ASSERT(imm <= 252);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x020) << 7) |
|
||||
((imm & 0x0C0) >> 4) |
|
||||
((imm & 0x01C) << 2);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0x4002U | (rd.Index() << 7) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_MV(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
BISCUIT_ASSERT(rs != x0);
|
||||
m_buffer.Emit16(0x8002 | (rd.Index() << 7) | (rs.Index() << 2));
|
||||
}
|
||||
|
||||
void Assembler::C_NOP() noexcept {
|
||||
m_buffer.Emit16(1);
|
||||
}
|
||||
|
||||
void Assembler::C_OR(GPR rd, GPR rs) noexcept {
|
||||
EmitCompressedRegArith(m_buffer, 0b100011, rd, 0b10, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_SD(GPR rs2, uint32_t imm, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 248);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
EmitCompressedLoad(m_buffer, 0b111, imm, rs1, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_SDSP(GPR rs, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 504);
|
||||
BISCUIT_ASSERT(imm % 8 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x038) << 7) |
|
||||
((imm & 0x1C0) << 1);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0xE002U | (rs.Index() << 2) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_SLLI(GPR rd, uint32_t shift) noexcept {
|
||||
BISCUIT_ASSERT(rd != x0);
|
||||
BISCUIT_ASSERT(IsValidCompressedShiftAmount(shift));
|
||||
|
||||
// RV128C encodes a 64-bit shift with an encoding of 0.
|
||||
if (shift == 64) {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
const auto shift_enc = ((shift & 0b11111) << 2) | ((shift & 0b100000) << 7);
|
||||
m_buffer.Emit16(0x0002U | shift_enc | (rd.Index() << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_SQ(GPR rs2, uint32_t imm, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 496);
|
||||
BISCUIT_ASSERT(imm % 16 == 0);
|
||||
|
||||
imm &= 0x1F0;
|
||||
const auto new_imm = ((imm & 0x100) >> 5) | (imm & 0xF0);
|
||||
EmitCompressedStore(m_buffer, 0b101, new_imm, rs1, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_SQSP(GPR rs, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
BISCUIT_ASSERT(imm <= 1008);
|
||||
BISCUIT_ASSERT(imm % 16 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x3C0) << 1) |
|
||||
((imm & 0x030) << 7);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0xA002U | (rs.Index() << 2) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_SRAI(GPR rd, uint32_t shift) noexcept {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
BISCUIT_ASSERT(IsValidCompressedShiftAmount(shift));
|
||||
|
||||
// RV128C encodes a 64-bit shift with an encoding of 0.
|
||||
if (shift == 64) {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
constexpr auto base = 0x8401U;
|
||||
const auto shift_enc = ((shift & 0b11111) << 2) | ((shift & 0b100000) << 7);
|
||||
const auto reg = CompressedRegTo3BitEncoding(rd);
|
||||
|
||||
m_buffer.Emit16(base | shift_enc | (reg << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_SRLI(GPR rd, uint32_t shift) noexcept {
|
||||
BISCUIT_ASSERT(IsValid3BitCompressedReg(rd));
|
||||
BISCUIT_ASSERT(IsValidCompressedShiftAmount(shift));
|
||||
|
||||
// RV128C encodes a 64-bit shift with an encoding of 0.
|
||||
if (shift == 64) {
|
||||
BISCUIT_ASSERT(IsRV128(m_features));
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
constexpr auto base = 0x8001U;
|
||||
const auto shift_enc = ((shift & 0b11111) << 2) | ((shift & 0b100000) << 7);
|
||||
const auto reg = CompressedRegTo3BitEncoding(rd);
|
||||
|
||||
m_buffer.Emit16(base | shift_enc | (reg << 7));
|
||||
}
|
||||
|
||||
void Assembler::C_SUB(GPR rd, GPR rs) noexcept {
|
||||
EmitCompressedRegArith(m_buffer, 0b100011, rd, 0b00, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_SUBW(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
EmitCompressedRegArith(m_buffer, 0b100111, rd, 0b00, rs, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_SW(GPR rs2, uint32_t imm, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(imm <= 124);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
imm &= 0x7C;
|
||||
const auto new_imm = ((imm & 0b0100) << 5) | (imm & 0x78);
|
||||
EmitCompressedStore(m_buffer, 0b110, new_imm, rs1, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_SWSP(GPR rs, uint32_t imm) noexcept {
|
||||
BISCUIT_ASSERT(imm <= 252);
|
||||
BISCUIT_ASSERT(imm % 4 == 0);
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x0C0) << 1) |
|
||||
((imm & 0x03C) << 7);
|
||||
// clang-format on
|
||||
|
||||
m_buffer.Emit16(0xC002U | (rs.Index() << 2) | new_imm);
|
||||
}
|
||||
|
||||
void Assembler::C_UNDEF() noexcept {
|
||||
m_buffer.Emit16(0);
|
||||
}
|
||||
|
||||
void Assembler::C_XOR(GPR rd, GPR rs) noexcept {
|
||||
EmitCompressedRegArith(m_buffer, 0b100011, rd, 0b01, rs, 0b01);
|
||||
}
|
||||
|
||||
// Zc Extension Instructions
|
||||
|
||||
void Assembler::C_LBU(GPR rd, uint32_t uimm, GPR rs) noexcept {
|
||||
// C.LBU swaps the ordering of the immediate.
|
||||
const auto uimm_fixed = ((uimm & 0b01) << 1) | ((uimm & 0b10) >> 1);
|
||||
|
||||
EmitCLBType(m_buffer, 0b100000, rs, uimm_fixed, rd, 0b00, 0);
|
||||
}
|
||||
void Assembler::C_LH(GPR rd, uint32_t uimm, GPR rs) noexcept {
|
||||
EmitCLHType(m_buffer, 0b100001, rs, uimm, rd, 0b00, 1);
|
||||
}
|
||||
void Assembler::C_LHU(GPR rd, uint32_t uimm, GPR rs) noexcept {
|
||||
EmitCLHType(m_buffer, 0b100001, rs, uimm, rd, 0b00, 0);
|
||||
}
|
||||
void Assembler::C_SB(GPR rs2, uint32_t uimm, GPR rs1) noexcept {
|
||||
// C.SB swaps the ordering of the immediate.
|
||||
const auto uimm_fixed = ((uimm & 0b01) << 1) | ((uimm & 0b10) >> 1);
|
||||
|
||||
EmitCSBType(m_buffer, 0b100010, rs1, uimm_fixed, rs2, 0b00);
|
||||
}
|
||||
void Assembler::C_SH(GPR rs2, uint32_t uimm, GPR rs1) noexcept {
|
||||
EmitCSHType(m_buffer, 0b100011, rs1, uimm, rs2, 0b00);
|
||||
}
|
||||
|
||||
void Assembler::C_SEXT_B(GPR rd) noexcept {
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11001, 0b01);
|
||||
}
|
||||
void Assembler::C_SEXT_H(GPR rd) noexcept {
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11011, 0b01);
|
||||
}
|
||||
void Assembler::C_ZEXT_B(GPR rd) noexcept {
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11000, 0b01);
|
||||
}
|
||||
void Assembler::C_ZEXT_H(GPR rd) noexcept {
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11010, 0b01);
|
||||
}
|
||||
void Assembler::C_ZEXT_W(GPR rd) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11100, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::C_MUL(GPR rsd, GPR rs2) noexcept {
|
||||
EmitCompressedRegArith(m_buffer, 0b100111, rsd, 0b10, rs2, 0b01);
|
||||
}
|
||||
void Assembler::C_NOT(GPR rd) noexcept {
|
||||
EmitCUType(m_buffer, 0b100111, rd, 0b11101, 0b01);
|
||||
}
|
||||
|
||||
void Assembler::CM_JALT(uint32_t index) noexcept {
|
||||
BISCUIT_ASSERT(index >= 32 && index <= 255);
|
||||
EmitCMJTType(m_buffer, 0b101000, index, 0b10);
|
||||
}
|
||||
void Assembler::CM_JT(uint32_t index) noexcept {
|
||||
BISCUIT_ASSERT(index <= 31);
|
||||
EmitCMJTType(m_buffer, 0b101000, index, 0b10);
|
||||
}
|
||||
|
||||
void Assembler::CM_MVA01S(GPR r1s, GPR r2s) noexcept {
|
||||
EmitCMMVType(m_buffer, 0b101011, r1s, 0b11, r2s, 0b10);
|
||||
}
|
||||
void Assembler::CM_MVSA01(GPR r1s, GPR r2s) noexcept {
|
||||
EmitCMMVType(m_buffer, 0b101011, r1s, 0b01, r2s, 0b10);
|
||||
}
|
||||
|
||||
void Assembler::CM_POP(PushPopList reg_list, int32_t stack_adj) noexcept {
|
||||
BISCUIT_ASSERT(stack_adj > 0);
|
||||
EmitCMPPType(m_buffer, 0b101110, 0b10, reg_list, stack_adj, 0b10, m_features);
|
||||
}
|
||||
void Assembler::CM_POPRET(PushPopList reg_list, int32_t stack_adj) noexcept {
|
||||
BISCUIT_ASSERT(stack_adj > 0);
|
||||
EmitCMPPType(m_buffer, 0b101111, 0b10, reg_list, stack_adj, 0b10, m_features);
|
||||
}
|
||||
void Assembler::CM_POPRETZ(PushPopList reg_list, int32_t stack_adj) noexcept {
|
||||
BISCUIT_ASSERT(stack_adj > 0);
|
||||
EmitCMPPType(m_buffer, 0b101111, 0b00, reg_list, stack_adj, 0b10, m_features);
|
||||
}
|
||||
void Assembler::CM_PUSH(PushPopList reg_list, int32_t stack_adj) noexcept {
|
||||
BISCUIT_ASSERT(stack_adj < 0);
|
||||
EmitCMPPType(m_buffer, 0b101110, 0b00, reg_list, stack_adj, 0b10, m_features);
|
||||
}
|
||||
|
||||
} // namespace biscuit
|
||||
172
externals/biscuit/src/assembler_crypto.cpp
vendored
172
externals/biscuit/src/assembler_crypto.cpp
vendored
@@ -1,172 +0,0 @@
|
||||
#include <biscuit/assert.hpp>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_util.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 {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitAES32Instruction(m_buffer, 0x2A000033, rd, rs1, rs2, bs);
|
||||
}
|
||||
|
||||
void Assembler::AES32DSMI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitAES32Instruction(m_buffer, 0x2E000033, rd, rs1, rs2, bs);
|
||||
}
|
||||
|
||||
void Assembler::AES32ESI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitAES32Instruction(m_buffer, 0x22000033, rd, rs1, rs2, bs);
|
||||
}
|
||||
|
||||
void Assembler::AES32ESMI(GPR rd, GPR rs1, GPR rs2, uint32_t bs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitAES32Instruction(m_buffer, 0x26000033, rd, rs1, rs2, bs);
|
||||
}
|
||||
|
||||
void Assembler::AES64DS(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitAES64Instruction(m_buffer, 0x3A000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::AES64DSM(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitAES64Instruction(m_buffer, 0x3E000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::AES64ES(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitAES64Instruction(m_buffer, 0x32000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::AES64ESM(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitAES64Instruction(m_buffer, 0x36000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::AES64IM(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitAES64Instruction(m_buffer, 0x30001013, rd, rs, x0);
|
||||
}
|
||||
|
||||
void Assembler::AES64KS1I(GPR rd, GPR rs, uint32_t rnum) noexcept {
|
||||
// RVK spec states that rnums 0xB to 0xF are reserved.
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
BISCUIT_ASSERT(rnum <= 0xA);
|
||||
EmitAES64Instruction(m_buffer, 0x31001013, rd, rs, GPR{rnum});
|
||||
}
|
||||
|
||||
void Assembler::AES64KS2(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
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 {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x10601013, rd, rs, x0);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SIG0H(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x5C000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SIG0L(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x54000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SIG1(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x10701013, rd, rs, x0);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SIG1H(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x5E000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SIG1L(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x56000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SUM0(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x10401013, rd, rs, x0);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SUM0R(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x50000033, rd, rs1, rs2);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SUM1(GPR rd, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitSHAInstruction(m_buffer, 0x10501013, rd, rs, x0);
|
||||
}
|
||||
|
||||
void Assembler::SHA512SUM1R(GPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
BISCUIT_ASSERT(IsRV32(m_features));
|
||||
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
|
||||
648
externals/biscuit/src/assembler_floating_point.cpp
vendored
648
externals/biscuit/src/assembler_floating_point.cpp
vendored
@@ -1,648 +0,0 @@
|
||||
#include <biscuit/assert.hpp>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
#include "assembler_util.hpp"
|
||||
|
||||
// Various floating-point-based extension instructions.
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
// RV32F Extension Instructions
|
||||
|
||||
void Assembler::FADD_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000000, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCLASS_S(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110000, f0, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_W(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101000, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_WU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_W_S(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100000, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_WU_S(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FDIV_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001100, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FEQ_S(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLE_S(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLT_S(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLW(FPR rd, int32_t offset, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b010, rd, 0b0000111);
|
||||
}
|
||||
void Assembler::FMADD_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1000011);
|
||||
}
|
||||
void Assembler::FMAX_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMIN_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMSUB_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1000111);
|
||||
}
|
||||
void Assembler::FMUL_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001000, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_W_X(FPR rd, GPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1111000, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_X_W(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110000, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FNMADD_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1001111);
|
||||
}
|
||||
void Assembler::FNMSUB_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1001011);
|
||||
}
|
||||
void Assembler::FSGNJ_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJN_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJX_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSQRT_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0101100, f0, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSUB_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000100, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSW(FPR rs2, int32_t offset, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b010, 0b0100111);
|
||||
}
|
||||
|
||||
void Assembler::FABS_S(FPR rd, FPR rs) noexcept {
|
||||
FSGNJX_S(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FMV_S(FPR rd, FPR rs) noexcept {
|
||||
FSGNJ_S(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FNEG_S(FPR rd, FPR rs) noexcept {
|
||||
FSGNJN_S(rd, rs, rs);
|
||||
}
|
||||
|
||||
// RV64F Extension Instructions
|
||||
|
||||
void Assembler::FCVT_L_S(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_LU_S(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_L(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_LU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
// RV32D Extension Instructions
|
||||
|
||||
void Assembler::FADD_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000001, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCLASS_D(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110001, f0, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_W(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_WU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101001, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_W_D(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_WU_D(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100001, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FDIV_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001101, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FEQ_D(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLE_D(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLT_D(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLD(FPR rd, int32_t offset, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b011, rd, 0b0000111);
|
||||
}
|
||||
void Assembler::FMADD_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1000011);
|
||||
}
|
||||
void Assembler::FMAX_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMIN_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMSUB_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1000111);
|
||||
}
|
||||
void Assembler::FMUL_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001001, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FNMADD_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1001111);
|
||||
}
|
||||
void Assembler::FNMSUB_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1001011);
|
||||
}
|
||||
void Assembler::FSGNJ_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJN_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJX_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSQRT_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0101101, f0, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSUB_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000101, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSD(FPR rs2, int32_t offset, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b011, 0b0100111);
|
||||
}
|
||||
|
||||
void Assembler::FABS_D(FPR rd, FPR rs) noexcept {
|
||||
FSGNJX_D(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FMV_D(FPR rd, FPR rs) noexcept {
|
||||
FSGNJ_D(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FNEG_D(FPR rd, FPR rs) noexcept {
|
||||
FSGNJN_D(rd, rs, rs);
|
||||
}
|
||||
|
||||
// RV64D Extension Instructions
|
||||
|
||||
void Assembler::FCVT_L_D(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_LU_D(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_L(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_LU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_D_X(FPR rd, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
EmitRType(m_buffer, 0b1111001, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_X_D(GPR rd, FPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64OrRV128(m_features));
|
||||
EmitRType(m_buffer, 0b1110001, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
|
||||
// RV32Q Extension Instructions
|
||||
|
||||
void Assembler::FADD_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000011, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCLASS_Q(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110011, f0, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_W(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_WU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_W_Q(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_WU_Q(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FDIV_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001111, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FEQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLE_Q(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLT_Q(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLQ(FPR rd, int32_t offset, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b100, rd, 0b0000111);
|
||||
}
|
||||
void Assembler::FMADD_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1000011);
|
||||
}
|
||||
void Assembler::FMAX_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMIN_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMSUB_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1000111);
|
||||
}
|
||||
void Assembler::FMUL_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001011, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FNMADD_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1001111);
|
||||
}
|
||||
void Assembler::FNMSUB_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1001011);
|
||||
}
|
||||
void Assembler::FSGNJ_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJN_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJX_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSQRT_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0101111, f0, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSUB_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000111, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSQ(FPR rs2, int32_t offset, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b100, 0b0100111);
|
||||
}
|
||||
|
||||
void Assembler::FABS_Q(FPR rd, FPR rs) noexcept {
|
||||
FSGNJX_Q(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FMV_Q(FPR rd, FPR rs) noexcept {
|
||||
FSGNJ_Q(rd, rs, rs);
|
||||
}
|
||||
void Assembler::FNEG_Q(FPR rd, FPR rs) noexcept {
|
||||
FSGNJN_Q(rd, rs, rs);
|
||||
}
|
||||
|
||||
// RV64Q Extension Instructions
|
||||
|
||||
void Assembler::FCVT_L_Q(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_LU_Q(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1100011, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_L(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_LU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
BISCUIT_ASSERT(IsRV64(m_features));
|
||||
EmitRType(m_buffer, 0b1101011, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
// RV32Zfh Extension Instructions
|
||||
|
||||
void Assembler::FADD_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000010, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCLASS_H(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110010, f0, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_D_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_W(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_WU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_Q_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_S_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_W_H(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_WU_H(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FDIV_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001110, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FEQ_H(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLE_H(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLH(FPR rd, int32_t offset, GPR rs) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b001, rd, 0b0000111);
|
||||
}
|
||||
void Assembler::FLT_H(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMADD_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1000011);
|
||||
}
|
||||
void Assembler::FMAX_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMIN_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMSUB_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1000111);
|
||||
}
|
||||
void Assembler::FMUL_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0001010, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_H_X(FPR rd, GPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1111010, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMV_X_H(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110010, f0, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FNMADD_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1001111);
|
||||
}
|
||||
void Assembler::FNMSUB_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept {
|
||||
EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1001011);
|
||||
}
|
||||
void Assembler::FSGNJ_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJN_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b001, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSGNJX_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSH(FPR rs2, int32_t offset, GPR rs1) noexcept {
|
||||
BISCUIT_ASSERT(IsValidSigned12BitImm(offset));
|
||||
EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b001, 0b0100111);
|
||||
}
|
||||
void Assembler::FSQRT_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0101110, f0, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FSUB_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0000110, rs2, rs1, rmode, rd, 0b1010011);
|
||||
}
|
||||
|
||||
// RV64Zfh Extension Instructions
|
||||
|
||||
void Assembler::FCVT_L_H(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100010, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_LU_H(GPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1100010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_L(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101010, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FCVT_H_LU(FPR rd, GPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b1101010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
// Zfa Extension Instructions
|
||||
|
||||
static void FLIImpl(CodeBuffer& buffer, uint32_t funct7, FPR rd, double value) noexcept {
|
||||
static constexpr std::array fli_table{
|
||||
0xBFF0000000000000ULL, // -1.0
|
||||
0x0010000000000000ULL, // Minimum positive normal
|
||||
0x3EF0000000000000ULL, // 1.0 * 2^-16
|
||||
0x3F00000000000000ULL, // 1.0 * 2^-15
|
||||
0x3F70000000000000ULL, // 1.0 * 2^-8
|
||||
0x3F80000000000000ULL, // 1.0 * 2^-7
|
||||
0x3FB0000000000000ULL, // 1.0 * 2^-4
|
||||
0x3FC0000000000000ULL, // 1.0 * 2^-3
|
||||
0x3FD0000000000000ULL, // 0.25
|
||||
0x3FD4000000000000ULL, // 0.3125
|
||||
0x3FD8000000000000ULL, // 0.375
|
||||
0x3FDC000000000000ULL, // 0.4375
|
||||
0x3FE0000000000000ULL, // 0.5
|
||||
0x3FE4000000000000ULL, // 0.625
|
||||
0x3FE8000000000000ULL, // 0.75
|
||||
0x3FEC000000000000ULL, // 0.875
|
||||
0x3FF0000000000000ULL, // 1.0
|
||||
0x3FF4000000000000ULL, // 1.25
|
||||
0x3FF8000000000000ULL, // 1.5
|
||||
0x3FFC000000000000ULL, // 1.75
|
||||
0x4000000000000000ULL, // 2.0
|
||||
0x4004000000000000ULL, // 2.5
|
||||
0x4008000000000000ULL, // 3
|
||||
0x4010000000000000ULL, // 4
|
||||
0x4020000000000000ULL, // 8
|
||||
0x4030000000000000ULL, // 16
|
||||
0x4060000000000000ULL, // 2^7
|
||||
0x4070000000000000ULL, // 2^8
|
||||
0x40E0000000000000ULL, // 2^15
|
||||
0x40F0000000000000ULL, // 2^16
|
||||
0x7FF0000000000000ULL, // +inf
|
||||
0x7FF8000000000000ULL, // Canonical NaN
|
||||
};
|
||||
|
||||
uint64_t ivalue{};
|
||||
std::memcpy(&ivalue, &value, sizeof(uint64_t));
|
||||
|
||||
const auto iter = std::find_if(fli_table.cbegin(), fli_table.cend(), [ivalue](uint64_t entry) {
|
||||
return entry == ivalue;
|
||||
});
|
||||
BISCUIT_ASSERT(iter != fli_table.cend());
|
||||
|
||||
const auto index = static_cast<uint32_t>(std::distance(fli_table.cbegin(), iter));
|
||||
EmitRType(buffer, funct7, f1, GPR{index}, 0b000, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FLI_D(FPR rd, double value) noexcept {
|
||||
FLIImpl(m_buffer, 0b1111001, rd, value);
|
||||
}
|
||||
void Assembler::FLI_H(FPR rd, double value) noexcept {
|
||||
FLIImpl(m_buffer, 0b1111010, rd, value);
|
||||
}
|
||||
void Assembler::FLI_S(FPR rd, double value) noexcept {
|
||||
FLIImpl(m_buffer, 0b1111000, rd, value);
|
||||
}
|
||||
|
||||
void Assembler::FMINM_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMINM_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMINM_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMINM_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b010, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FMAXM_D(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b011, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMAXM_H(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b011, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMAXM_Q(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b011, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMAXM_S(FPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b011, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FROUND_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100001, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUND_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUND_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100011, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUND_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FROUNDNX_D(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100001, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUNDNX_H(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUNDNX_Q(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100011, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FROUNDNX_S(FPR rd, FPR rs1, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FCVTMOD_W_D(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1100001, f8, rs1, static_cast<uint32_t>(RMode::RTZ), rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FMVH_X_D(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110001, f1, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMVH_X_Q(GPR rd, FPR rs1) noexcept {
|
||||
EmitRType(m_buffer, 0b1110011, f1, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMVP_D_X(FPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1011001, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FMVP_Q_X(FPR rd, GPR rs1, GPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1011011, rs2, rs1, 0b000, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FLEQ_D(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b100, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLTQ_D(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b101, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FLEQ_H(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b100, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLTQ_H(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b101, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FLEQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b100, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLTQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b101, rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FLEQ_S(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b100, rd, 0b1010011);
|
||||
}
|
||||
void Assembler::FLTQ_S(GPR rd, FPR rs1, FPR rs2) noexcept {
|
||||
EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b101, rd, 0b1010011);
|
||||
}
|
||||
|
||||
// Zfbfmin, Zvfbfmin, Zvfbfwma Extension Instructions
|
||||
|
||||
void Assembler::FCVT_BF16_S(FPR rd, FPR rs, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100010, f8, rs, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
void Assembler::FCVT_S_BF16(FPR rd, FPR rs, RMode rmode) noexcept {
|
||||
EmitRType(m_buffer, 0b0100000, f6, rs, static_cast<uint32_t>(rmode), rd, 0b1010011);
|
||||
}
|
||||
|
||||
} // namespace biscuit
|
||||
224
externals/biscuit/src/assembler_util.hpp
vendored
224
externals/biscuit/src/assembler_util.hpp
vendored
@@ -1,224 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <biscuit/assert.hpp>
|
||||
#include <biscuit/code_buffer.hpp>
|
||||
#include <biscuit/registers.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
// Generic internal utility header for various helper functions related
|
||||
// to encoding instructions.
|
||||
|
||||
namespace biscuit {
|
||||
// Determines if a value lies within the range of a 6-bit immediate.
|
||||
[[nodiscard]] constexpr bool IsValidSigned6BitImm(ptrdiff_t value) {
|
||||
return value >= -32 && value <= 31;
|
||||
}
|
||||
|
||||
// S-type and I-type immediates are 12 bits in size
|
||||
[[nodiscard]] constexpr bool IsValidSigned12BitImm(ptrdiff_t value) {
|
||||
return value >= -2048 && value <= 2047;
|
||||
}
|
||||
|
||||
// B-type immediates only provide -4KiB to +4KiB range branches.
|
||||
[[nodiscard]] constexpr bool IsValidBTypeImm(ptrdiff_t value) {
|
||||
return value >= -4096 && value <= 4095;
|
||||
}
|
||||
|
||||
// J-type immediates only provide -1MiB to +1MiB range branches.
|
||||
[[nodiscard]] constexpr bool IsValidJTypeImm(ptrdiff_t value) {
|
||||
return value >= -0x80000 && value <= 0x7FFFF;
|
||||
}
|
||||
|
||||
// CB-type immediates only provide -256B to +256B range branches.
|
||||
[[nodiscard]] constexpr bool IsValidCBTypeImm(ptrdiff_t value) {
|
||||
return value >= -256 && value <= 255;
|
||||
}
|
||||
|
||||
// CJ-type immediates only provide -2KiB to +2KiB range branches.
|
||||
[[nodiscard]] constexpr bool IsValidCJTypeImm(ptrdiff_t value) {
|
||||
return IsValidSigned12BitImm(value);
|
||||
}
|
||||
|
||||
// Determines whether or not the register fits in 3-bit compressed encoding.
|
||||
[[nodiscard]] constexpr bool IsValid3BitCompressedReg(Register reg) {
|
||||
const auto index = reg.Index();
|
||||
return index >= 8 && index <= 15;
|
||||
}
|
||||
|
||||
// Determines whether or not the given shift amount is valid for a compressed shift instruction
|
||||
[[nodiscard]] constexpr bool IsValidCompressedShiftAmount(uint32_t shift) {
|
||||
return shift > 0 && shift <= 64;
|
||||
}
|
||||
|
||||
// Turns a compressed register into its encoding.
|
||||
[[nodiscard]] constexpr uint32_t CompressedRegTo3BitEncoding(Register reg) {
|
||||
return reg.Index() - 8;
|
||||
}
|
||||
|
||||
// Transforms a regular value into an immediate encoded in a B-type instruction.
|
||||
[[nodiscard]] constexpr uint32_t TransformToBTypeImm(uint32_t imm) {
|
||||
// clang-format off
|
||||
return ((imm & 0x07E0) << 20) |
|
||||
((imm & 0x1000) << 19) |
|
||||
((imm & 0x001E) << 7) |
|
||||
((imm & 0x0800) >> 4);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Transforms a regular value into an immediate encoded in a J-type instruction.
|
||||
[[nodiscard]] constexpr uint32_t TransformToJTypeImm(uint32_t imm) {
|
||||
// clang-format off
|
||||
return ((imm & 0x0FF000) >> 0) |
|
||||
((imm & 0x000800) << 9) |
|
||||
((imm & 0x0007FE) << 20) |
|
||||
((imm & 0x100000) << 11);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Transforms a regular value into an immediate encoded in a CB-type instruction.
|
||||
[[nodiscard]] constexpr uint32_t TransformToCBTypeImm(uint32_t imm) {
|
||||
// clang-format off
|
||||
return ((imm & 0x0C0) >> 1) |
|
||||
((imm & 0x006) << 2) |
|
||||
((imm & 0x020) >> 3) |
|
||||
((imm & 0x018) << 7) |
|
||||
((imm & 0x100) << 4);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Transforms a regular value into an immediate encoded in a CJ-type instruction.
|
||||
[[nodiscard]] constexpr uint32_t TransformToCJTypeImm(uint32_t imm) {
|
||||
// clang-format off
|
||||
return ((imm & 0x800) << 1) |
|
||||
((imm & 0x010) << 7) |
|
||||
((imm & 0x300) << 1) |
|
||||
((imm & 0x400) >> 2) |
|
||||
((imm & 0x040) << 1) |
|
||||
((imm & 0x080) >> 1) |
|
||||
((imm & 0x00E) << 4) |
|
||||
((imm & 0x020) >> 3);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Emits a B type RISC-V instruction. These consist of:
|
||||
// imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1] | imm[11] | opcode
|
||||
inline void EmitBType(CodeBuffer& buffer, uint32_t imm, GPR rs2, GPR rs1,
|
||||
uint32_t funct3, uint32_t opcode) {
|
||||
imm &= 0x1FFE;
|
||||
|
||||
buffer.Emit32(TransformToBTypeImm(imm) | (rs2.Index() << 20) | (rs1.Index() << 15) |
|
||||
((funct3 & 0b111) << 12) | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits a I type RISC-V instruction. These consist of:
|
||||
// imm[11:0] | rs1 | funct3 | rd | opcode
|
||||
inline void EmitIType(CodeBuffer& buffer, uint32_t imm, Register rs1, uint32_t funct3,
|
||||
Register rd, uint32_t opcode) {
|
||||
imm &= 0xFFF;
|
||||
|
||||
buffer.Emit32((imm << 20) | (rs1.Index() << 15) | ((funct3 & 0b111) << 12) |
|
||||
(rd.Index() << 7) | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits a J type RISC-V instruction. These consist of:
|
||||
// imm[20|10:1|11|19:12] | rd | opcode
|
||||
inline void EmitJType(CodeBuffer& buffer, uint32_t imm, GPR rd, uint32_t opcode) {
|
||||
imm &= 0x1FFFFE;
|
||||
|
||||
buffer.Emit32(TransformToJTypeImm(imm) | rd.Index() << 7 | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits a R type RISC instruction. These consist of:
|
||||
// funct7 | rs2 | rs1 | funct3 | rd | opcode
|
||||
inline void EmitRType(CodeBuffer& buffer, uint32_t funct7, Register rs2, Register rs1,
|
||||
uint32_t funct3, Register rd, uint32_t opcode) {
|
||||
// clang-format off
|
||||
const auto value = ((funct7 & 0xFF) << 25) |
|
||||
(rs2.Index() << 20) |
|
||||
(rs1.Index() << 15) |
|
||||
((funct3 & 0b111) << 12) |
|
||||
(rd.Index() << 7) |
|
||||
(opcode & 0x7F);
|
||||
// clang-format off
|
||||
|
||||
buffer.Emit32(value);
|
||||
}
|
||||
|
||||
// Emits a R type RISC instruction. These consist of:
|
||||
// funct7 | rs2 | rs1 | funct3 | rd | opcode
|
||||
inline void EmitRType(CodeBuffer& buffer, uint32_t funct7, FPR rs2, FPR rs1, RMode funct3,
|
||||
FPR rd, uint32_t opcode) {
|
||||
EmitRType(buffer, funct7, rs2, rs1, static_cast<uint32_t>(funct3), rd, opcode);
|
||||
}
|
||||
|
||||
// Emits a R4 type RISC instruction. These consist of:
|
||||
// rs3 | funct2 | rs2 | rs1 | funct3 | rd | opcode
|
||||
inline void EmitR4Type(CodeBuffer& buffer, FPR rs3, uint32_t funct2, FPR rs2, FPR rs1,
|
||||
RMode funct3, FPR rd, uint32_t opcode) {
|
||||
const auto reg_bits = (rs3.Index() << 27) | (rs2.Index() << 20) | (rs1.Index() << 15) | (rd.Index() << 7);
|
||||
const auto funct_bits = ((funct2 & 0b11) << 25) | (static_cast<uint32_t>(funct3) << 12);
|
||||
buffer.Emit32(reg_bits | funct_bits | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits a S type RISC-V instruction. These consist of:
|
||||
// imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode
|
||||
inline void EmitSType(CodeBuffer& buffer, uint32_t imm, Register rs2, GPR rs1,
|
||||
uint32_t funct3, uint32_t opcode) {
|
||||
imm &= 0xFFF;
|
||||
|
||||
// clang-format off
|
||||
const auto new_imm = ((imm & 0x01F) << 7) |
|
||||
((imm & 0xFE0) << 20);
|
||||
// clang-format on
|
||||
|
||||
buffer.Emit32(new_imm | (rs2.Index() << 20) | (rs1.Index() << 15) |
|
||||
((funct3 & 0b111) << 12) | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits a U type RISC-V instruction. These consist of:
|
||||
// imm[31:12] | rd | opcode
|
||||
inline void EmitUType(CodeBuffer& buffer, uint32_t imm, GPR rd, uint32_t opcode) {
|
||||
buffer.Emit32((imm & 0x000FFFFF) << 12 | rd.Index() << 7 | (opcode & 0x7F));
|
||||
}
|
||||
|
||||
// Emits an atomic instruction.
|
||||
inline void EmitAtomic(CodeBuffer& buffer, uint32_t funct5, Ordering ordering, GPR rs2, GPR rs1,
|
||||
uint32_t funct3, GPR rd, uint32_t opcode) noexcept {
|
||||
const auto funct7 = (funct5 << 2) | static_cast<uint32_t>(ordering);
|
||||
EmitRType(buffer, funct7, rs2, rs1, funct3, rd, opcode);
|
||||
}
|
||||
|
||||
// Emits a fence instruction
|
||||
inline void EmitFENCE(CodeBuffer& buffer, uint32_t fm, FenceOrder pred, FenceOrder succ,
|
||||
GPR rs, uint32_t funct3, GPR rd, uint32_t opcode) noexcept {
|
||||
// clang-format off
|
||||
buffer.Emit32(((fm & 0b1111) << 28) |
|
||||
(static_cast<uint32_t>(pred) << 24) |
|
||||
(static_cast<uint32_t>(succ) << 20) |
|
||||
(rs.Index() << 15) |
|
||||
((funct3 & 0b111) << 12) |
|
||||
(rd.Index() << 7) |
|
||||
(opcode & 0x7F));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Internal helpers for siloing away particular comparisons for behavior.
|
||||
constexpr bool IsRV32(ArchFeature feature) {
|
||||
return feature == ArchFeature::RV32;
|
||||
}
|
||||
constexpr bool IsRV64(ArchFeature feature) {
|
||||
return feature == ArchFeature::RV64;
|
||||
}
|
||||
constexpr bool IsRV128(ArchFeature feature) {
|
||||
return feature == ArchFeature::RV128;
|
||||
}
|
||||
constexpr bool IsRV32OrRV64(ArchFeature feature) {
|
||||
return IsRV32(feature) || IsRV64(feature);
|
||||
}
|
||||
constexpr bool IsRV64OrRV128(ArchFeature feature) {
|
||||
return IsRV64(feature) || IsRV128(feature);
|
||||
}
|
||||
|
||||
} // namespace biscuit
|
||||
2146
externals/biscuit/src/assembler_vector.cpp
vendored
2146
externals/biscuit/src/assembler_vector.cpp
vendored
File diff suppressed because it is too large
Load Diff
111
externals/biscuit/src/code_buffer.cpp
vendored
111
externals/biscuit/src/code_buffer.cpp
vendored
@@ -1,111 +0,0 @@
|
||||
#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
|
||||
39
externals/biscuit/src/cpuinfo.cpp
vendored
39
externals/biscuit/src/cpuinfo.cpp
vendored
@@ -1,39 +0,0 @@
|
||||
// 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
|
||||
76
externals/biscuit/tests/CMakeLists.txt
vendored
76
externals/biscuit/tests/CMakeLists.txt
vendored
@@ -1,76 +0,0 @@
|
||||
project(biscuit_tests)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/assembler_bfloat_tests.cpp
|
||||
src/assembler_branch_tests.cpp
|
||||
src/assembler_cmo_tests.cpp
|
||||
src/assembler_privileged_tests.cpp
|
||||
src/assembler_rv32i_tests.cpp
|
||||
src/assembler_rv64i_tests.cpp
|
||||
src/assembler_rva_tests.cpp
|
||||
src/assembler_rvb_tests.cpp
|
||||
src/assembler_rvc_tests.cpp
|
||||
src/assembler_rvd_tests.cpp
|
||||
src/assembler_rvf_tests.cpp
|
||||
src/assembler_rvk_tests.cpp
|
||||
src/assembler_rvm_tests.cpp
|
||||
src/assembler_rvq_tests.cpp
|
||||
src/assembler_rvv_tests.cpp
|
||||
src/assembler_vector_crypto_tests.cpp
|
||||
src/assembler_zacas_tests.cpp
|
||||
src/assembler_zawrs_tests.cpp
|
||||
src/assembler_zc_tests.cpp
|
||||
src/assembler_zfa_tests.cpp
|
||||
src/assembler_zicond_tests.cpp
|
||||
src/assembler_zicsr_tests.cpp
|
||||
src/assembler_zihintntl_tests.cpp
|
||||
src/main.cpp
|
||||
|
||||
src/assembler_test_utils.hpp
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
externals/
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
biscuit
|
||||
)
|
||||
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
cxx_std_20
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(${PROJECT_NAME}
|
||||
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
|
||||
/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'
|
||||
)
|
||||
endif()
|
||||
|
||||
add_test(biscuit_tests_ctest ${PROJECT_NAME})
|
||||
17976
externals/biscuit/tests/externals/catch/catch.hpp
vendored
17976
externals/biscuit/tests/externals/catch/catch.hpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,95 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("FCVT.BF16.S", "[Zfbfmin]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_BF16_S(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x44838FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_BF16_S(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4483CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_BF16_S(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4483FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.S.BF16", "[Zfbfmin]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_S_BF16(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x40638FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_BF16(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4063CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_BF16(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4063FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("VFNCVTBF16.F.F.W", "[Zvfbfmin]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.VFNCVTBF16_F_F_W(v31, v7, VecMask::Yes);
|
||||
REQUIRE(value == 0x487E9FD7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VFNCVTBF16_F_F_W(v31, v7, VecMask::No);
|
||||
REQUIRE(value == 0x4A7E9FD7);
|
||||
}
|
||||
|
||||
TEST_CASE("VFWCVTBF16.F.F.V", "[Zvfbfmin]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.VFWCVTBF16_F_F_V(v31, v7, VecMask::Yes);
|
||||
REQUIRE(value == 0x48769FD7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VFWCVTBF16_F_F_V(v31, v7, VecMask::No);
|
||||
REQUIRE(value == 0x4A769FD7);
|
||||
}
|
||||
|
||||
TEST_CASE("VFWMACCBF16.VF", "[Zvfbfwma]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.VFWMACCBF16(v31, f7, v20, VecMask::Yes);
|
||||
REQUIRE(value == 0xED43DFD7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VFWMACCBF16(v31, f7, v20, VecMask::No);
|
||||
REQUIRE(value == 0xEF43DFD7);
|
||||
}
|
||||
|
||||
TEST_CASE("VFWMACCBF16.VV", "[Zvfbfwma]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.VFWMACCBF16(v31, v7, v20, VecMask::Yes);
|
||||
REQUIRE(value == 0xED439FD7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VFWMACCBF16(v31, v7, v20, VecMask::No);
|
||||
REQUIRE(value == 0xEF439FD7);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("Branch to Self", "[branch]") {
|
||||
uint32_t data;
|
||||
auto as = MakeAssembler32(data);
|
||||
|
||||
// Simple branch to self with a jump instruction.
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.J(&label);
|
||||
REQUIRE(data == 0x0000006F);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
// Simple branch to self with a compressed jump instruction.
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.C_J(&label);
|
||||
REQUIRE((data & 0xFFFF) == 0xA001);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
// Simple branch to self with a conditional branch instruction.
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.BNE(x3, x4, &label);
|
||||
REQUIRE(data == 0x00419063);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
// Simple branch to self with a compressed branch instruction.
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.C_BNEZ(x15, &label);
|
||||
REQUIRE((data & 0xFFFF) == 0xE381);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Branch with Instructions Between", "[branch]") {
|
||||
std::array<uint32_t, 20> data{};
|
||||
auto as = MakeAssembler32(data);
|
||||
|
||||
// Simple branch backward
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.ADD(x1, x2, x3);
|
||||
as.SUB(x2, x4, x3);
|
||||
as.J(&label);
|
||||
REQUIRE(data[2] == 0xFF9FF06F);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
data.fill(0);
|
||||
|
||||
// Simple branch forward
|
||||
{
|
||||
Label label;
|
||||
as.J(&label);
|
||||
as.ADD(x1, x2, x3);
|
||||
as.SUB(x2, x4, x3);
|
||||
as.Bind(&label);
|
||||
REQUIRE(data[0] == 0x00C0006F);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
data.fill(0);
|
||||
|
||||
// Simple branch backward (compressed)
|
||||
{
|
||||
Label label;
|
||||
as.Bind(&label);
|
||||
as.ADD(x1, x2, x3);
|
||||
as.SUB(x2, x4, x3);
|
||||
as.C_J(&label);
|
||||
REQUIRE((data[2] & 0xFFFF) == 0xBFC5);
|
||||
}
|
||||
|
||||
as.RewindBuffer();
|
||||
data.fill(0);
|
||||
|
||||
// Simple branch forward (compressed)
|
||||
{
|
||||
Label label;
|
||||
as.C_J(&label);
|
||||
as.ADD(x1, x2, x3);
|
||||
as.SUB(x2, x4, x3);
|
||||
as.Bind(&label);
|
||||
REQUIRE((data[0] & 0xFFFF) == 0xA0A1);
|
||||
}
|
||||
}
|
||||
113
externals/biscuit/tests/src/assembler_cmo_tests.cpp
vendored
113
externals/biscuit/tests/src/assembler_cmo_tests.cpp
vendored
@@ -1,113 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("CBO.CLEAN", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CBO_CLEAN(x0);
|
||||
REQUIRE(value == 0x0010200F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CBO_CLEAN(x31);
|
||||
REQUIRE(value == 0x001FA00F);
|
||||
}
|
||||
|
||||
TEST_CASE("CBO.FLUSH", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CBO_FLUSH(x0);
|
||||
REQUIRE(value == 0x0020200F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CBO_FLUSH(x31);
|
||||
REQUIRE(value == 0x002FA00F);
|
||||
}
|
||||
|
||||
TEST_CASE("CBO.INVAL", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CBO_INVAL(x0);
|
||||
REQUIRE(value == 0x0000200F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CBO_INVAL(x31);
|
||||
REQUIRE(value == 0x000FA00F);
|
||||
}
|
||||
|
||||
TEST_CASE("CBO.ZERO", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CBO_ZERO(x0);
|
||||
REQUIRE(value == 0x0040200F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CBO_ZERO(x31);
|
||||
REQUIRE(value == 0x004FA00F);
|
||||
}
|
||||
|
||||
TEST_CASE("PREFETCH.I", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PREFETCH_I(x0);
|
||||
REQUIRE(value == 0x00006013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_I(x31, 2016);
|
||||
REQUIRE(value == 0x7E0FE013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_I(x31, -2016);
|
||||
REQUIRE(value == 0x820FE013);
|
||||
}
|
||||
|
||||
TEST_CASE("PREFETCH.R", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PREFETCH_R(x0);
|
||||
REQUIRE(value == 0x00106013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_R(x31, 2016);
|
||||
REQUIRE(value == 0x7E1FE013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_R(x31, -2016);
|
||||
REQUIRE(value == 0x821FE013);
|
||||
}
|
||||
|
||||
TEST_CASE("PREFETCH.W", "[cmo]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PREFETCH_W(x0);
|
||||
REQUIRE(value == 0x00306013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_W(x31, 2016);
|
||||
REQUIRE(value == 0x7E3FE013);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.PREFETCH_W(x31, -2016);
|
||||
REQUIRE(value == 0x823FE013);
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("HFENCE.VVMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HFENCE_VVMA(x0, x0);
|
||||
REQUIRE(value == 0x22000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HFENCE_VVMA(x15, x15);
|
||||
REQUIRE(value == 0x22F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("HFENCE.GVMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HFENCE_GVMA(x0, x0);
|
||||
REQUIRE(value == 0x62000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HFENCE_GVMA(x15, x15);
|
||||
REQUIRE(value == 0x62F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("HINVAL.VVMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HINVAL_VVMA(x0, x0);
|
||||
REQUIRE(value == 0x26000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HINVAL_VVMA(x15, x15);
|
||||
REQUIRE(value == 0x26F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("HINVAL.GVMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HINVAL_GVMA(x0, x0);
|
||||
REQUIRE(value == 0x66000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HINVAL_GVMA(x15, x15);
|
||||
REQUIRE(value == 0x66F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.B", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLV_B(x0, x0);
|
||||
REQUIRE(value == 0x60004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_B(x15, x14);
|
||||
REQUIRE(value == 0x600747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.BU", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLV_BU(x0, x0);
|
||||
REQUIRE(value == 0x60104073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_BU(x15, x14);
|
||||
REQUIRE(value == 0x601747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.D", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.HLV_D(x0, x0);
|
||||
REQUIRE(value == 0x6C004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_D(x15, x14);
|
||||
REQUIRE(value == 0x6C0747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.H", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLV_H(x0, x0);
|
||||
REQUIRE(value == 0x64004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_H(x15, x14);
|
||||
REQUIRE(value == 0x640747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.HU", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLV_HU(x0, x0);
|
||||
REQUIRE(value == 0x64104073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_HU(x15, x14);
|
||||
REQUIRE(value == 0x641747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.W", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLV_W(x0, x0);
|
||||
REQUIRE(value == 0x68004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_W(x15, x14);
|
||||
REQUIRE(value == 0x680747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLV.WU", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.HLV_WU(x0, x0);
|
||||
REQUIRE(value == 0x68104073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLV_WU(x15, x14);
|
||||
REQUIRE(value == 0x681747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLVX.HU", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLVX_HU(x0, x0);
|
||||
REQUIRE(value == 0x64304073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLVX_HU(x15, x14);
|
||||
REQUIRE(value == 0x643747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HLVX.WU", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HLVX_WU(x0, x0);
|
||||
REQUIRE(value == 0x68304073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HLVX_WU(x15, x14);
|
||||
REQUIRE(value == 0x683747F3);
|
||||
}
|
||||
|
||||
TEST_CASE("HSV.B", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HSV_B(x0, x0);
|
||||
REQUIRE(value == 0x62004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HSV_B(x15, x14);
|
||||
REQUIRE(value == 0x62F74073);
|
||||
}
|
||||
|
||||
TEST_CASE("HSV.D", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.HSV_D(x0, x0);
|
||||
REQUIRE(value == 0x6E004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HSV_D(x15, x14);
|
||||
REQUIRE(value == 0x6EF74073);
|
||||
}
|
||||
|
||||
TEST_CASE("HSV.H", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HSV_H(x0, x0);
|
||||
REQUIRE(value == 0x66004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HSV_H(x15, x14);
|
||||
REQUIRE(value == 0x66F74073);
|
||||
}
|
||||
|
||||
TEST_CASE("HSV.W", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.HSV_W(x0, x0);
|
||||
REQUIRE(value == 0x6A004073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.HSV_W(x15, x14);
|
||||
REQUIRE(value == 0x6AF74073);
|
||||
}
|
||||
|
||||
TEST_CASE("MRET", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MRET();
|
||||
REQUIRE(value == 0x30200073);
|
||||
}
|
||||
|
||||
TEST_CASE("SFENCE.INVAL.IR", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SFENCE_INVAL_IR();
|
||||
REQUIRE(value == 0x18100073);
|
||||
}
|
||||
|
||||
TEST_CASE("SFENCE.VMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SFENCE_VMA(x0, x0);
|
||||
REQUIRE(value == 0x12000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SFENCE_VMA(x15, x15);
|
||||
REQUIRE(value == 0x12F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("SFENCE.W.INVAL", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SFENCE_W_INVAL();
|
||||
REQUIRE(value == 0x18000073);
|
||||
}
|
||||
|
||||
TEST_CASE("SINVAL.VMA", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SINVAL_VMA(x0, x0);
|
||||
REQUIRE(value == 0x16000073);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SINVAL_VMA(x15, x15);
|
||||
REQUIRE(value == 0x16F78073);
|
||||
}
|
||||
|
||||
TEST_CASE("SRET", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SRET();
|
||||
REQUIRE(value == 0x10200073);
|
||||
}
|
||||
|
||||
TEST_CASE("URET", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.URET();
|
||||
REQUIRE(value == 0x00200073);
|
||||
}
|
||||
|
||||
TEST_CASE("WFI", "[rvpriv]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.WFI();
|
||||
REQUIRE(value == 0x10500073);
|
||||
}
|
||||
@@ -1,769 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("ADD", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ADD(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F783B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADD(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADD(x0, x0, x0);
|
||||
REQUIRE(value == 0x00000033);
|
||||
}
|
||||
|
||||
TEST_CASE("ADDI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ADDI(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400F8793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDI(x15, x31, 2048);
|
||||
REQUIRE(value == 0x800F8793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDI(x15, x31, 4095);
|
||||
REQUIRE(value == 0xFFFF8793);
|
||||
}
|
||||
|
||||
TEST_CASE("AND", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AND(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7F3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AND(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFFFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AND(x0, x0, x0);
|
||||
REQUIRE(value == 0x00007033);
|
||||
}
|
||||
|
||||
TEST_CASE("ANDI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ANDI(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400FF793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ANDI(x15, x31, 2048);
|
||||
REQUIRE(value == 0x800FF793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ANDI(x15, x31, 4095);
|
||||
REQUIRE(value == 0xFFFFF793);
|
||||
}
|
||||
|
||||
TEST_CASE("AUIPC", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AUIPC(x31, -1);
|
||||
REQUIRE(value == 0xFFFFFF97);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AUIPC(x31, 0);
|
||||
REQUIRE(value == 0x00000F97);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AUIPC(x31, 0x00FF00FF);
|
||||
REQUIRE(value == 0xF00FFF97);
|
||||
}
|
||||
|
||||
TEST_CASE("BEQ", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BEQ(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF78863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEQ(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF78FE3);
|
||||
}
|
||||
|
||||
TEST_CASE("BGE", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BGE(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF7D863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BGE(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF7DFE3);
|
||||
}
|
||||
|
||||
TEST_CASE("BGEU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BGEU(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF7F863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BGEU(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF7FFE3);
|
||||
}
|
||||
|
||||
TEST_CASE("BNE", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BNE(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF79863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BNE(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF79FE3);
|
||||
}
|
||||
|
||||
TEST_CASE("BLT", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BLT(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF7C863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BLT(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF7CFE3);
|
||||
}
|
||||
|
||||
TEST_CASE("BLTU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BLTU(x15, x31, 2000);
|
||||
REQUIRE(value == 0x7DF7E863);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BLTU(x15, x31, -2);
|
||||
REQUIRE(value == 0xFFF7EFE3);
|
||||
}
|
||||
|
||||
TEST_CASE("CALL", "[rv32i]") {
|
||||
std::array<uint32_t, 2> vals{};
|
||||
auto as = MakeAssembler32(vals);
|
||||
|
||||
const auto compare_vals = [&vals](uint32_t val_1, uint32_t val_2) {
|
||||
REQUIRE(vals[0] == val_1);
|
||||
REQUIRE(vals[1] == val_2);
|
||||
};
|
||||
|
||||
as.CALL(-1);
|
||||
compare_vals(0x00000097, 0xFFF080E7);
|
||||
}
|
||||
|
||||
TEST_CASE("EBREAK", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.EBREAK();
|
||||
REQUIRE(value == 0x00100073);
|
||||
}
|
||||
|
||||
TEST_CASE("ECALL", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ECALL();
|
||||
REQUIRE(value == 0x00000073);
|
||||
}
|
||||
|
||||
TEST_CASE("FENCE", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FENCE(FenceOrder::IORW, FenceOrder::IORW);
|
||||
REQUIRE(value == 0x0FF0000F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FENCETSO();
|
||||
REQUIRE(value == 0x8330000F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FENCEI();
|
||||
REQUIRE(value == 0x0000100F);
|
||||
}
|
||||
|
||||
TEST_CASE("JAL", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.JAL(x31, 0xFFFFFFFF);
|
||||
REQUIRE(value == 0xFFFFFFEF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.JAL(x31, 2000);
|
||||
REQUIRE(value == 0x7D000FEF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.JAL(x31, 100000);
|
||||
REQUIRE(value == 0x6A018FEF);
|
||||
}
|
||||
|
||||
TEST_CASE("JALR", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.JALR(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400F87E7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.JALR(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600F87E7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.JALR(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFF87E7);
|
||||
}
|
||||
|
||||
TEST_CASE("LB", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LB(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400F8783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LB(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600F8783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LB(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFF8783);
|
||||
}
|
||||
|
||||
TEST_CASE("LBU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LBU(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400FC783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LBU(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600FC783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LBU(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFC783);
|
||||
}
|
||||
|
||||
TEST_CASE("LH", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LH(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400F9783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LH(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600F9783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LH(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFF9783);
|
||||
}
|
||||
|
||||
TEST_CASE("LHU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LHU(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400FD783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LHU(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600FD783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LHU(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFD783);
|
||||
}
|
||||
|
||||
TEST_CASE("LI", "[rv32i]") {
|
||||
std::array<uint32_t, 2> vals{};
|
||||
auto as = MakeAssembler32(vals);
|
||||
|
||||
const auto compare_vals = [&vals](uint32_t val_1, uint32_t val_2) {
|
||||
REQUIRE(vals[0] == val_1);
|
||||
REQUIRE(vals[1] == val_2);
|
||||
};
|
||||
|
||||
///////// Single ADDI cases
|
||||
|
||||
as.LI(x1, 0);
|
||||
// addi x1, x0, 0
|
||||
compare_vals(0x00000093, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, -1);
|
||||
// addi x1, x0, -1
|
||||
compare_vals(0xFFF00093, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, 42);
|
||||
// addi x1, x0, 42
|
||||
compare_vals(0x02A00093, 0x000000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, 0x7ff);
|
||||
// addi x1, x0, 2047
|
||||
compare_vals(0x7FF00093, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// Single LUI cases
|
||||
|
||||
as.LI(x1, 0x2A000);
|
||||
// lui x1, 42
|
||||
compare_vals(0x0002A0B7, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, ~0xFFF);
|
||||
// lui x1, -1
|
||||
compare_vals(0xFFFFF0B7, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, INT32_MIN);
|
||||
// lui x1, -524288
|
||||
compare_vals(0x800000B7, 0x00000000);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// Full LUI+ADDI cases
|
||||
|
||||
as.LI(x1, 0x11111111);
|
||||
// lui x1, 69905
|
||||
// addi x1, x1, 273
|
||||
compare_vals(0x111110B7, 0x11108093);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, INT32_MAX);
|
||||
// lui x1, -524288
|
||||
// addi x1, x1, -1
|
||||
compare_vals(0x800000B7, 0xFFF08093);
|
||||
}
|
||||
|
||||
TEST_CASE("LUI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LUI(x10, 0xFFFFFFFF);
|
||||
REQUIRE(value == 0xFFFFF537);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LUI(x10, 0xFFF7FFFF);
|
||||
REQUIRE(value == 0x7FFFF537);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LUI(x31, 0xFFFFFFFF);
|
||||
REQUIRE(value == 0xFFFFFFB7);
|
||||
}
|
||||
|
||||
TEST_CASE("LW", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LW(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400FA783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LW(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600FA783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LW(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFA783);
|
||||
}
|
||||
|
||||
TEST_CASE("OR", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.OR(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7E3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.OR(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFEFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.OR(x0, x0, x0);
|
||||
REQUIRE(value == 0x00006033);
|
||||
}
|
||||
|
||||
TEST_CASE("ORI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ORI(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400FE793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ORI(x15, x31, 2048);
|
||||
REQUIRE(value == 0x800FE793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ORI(x15, x31, 4095);
|
||||
REQUIRE(value == 0xFFFFE793);
|
||||
}
|
||||
|
||||
TEST_CASE("PAUSE", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PAUSE();
|
||||
REQUIRE(value == 0x0100000F);
|
||||
}
|
||||
|
||||
TEST_CASE("SB", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SB(x31, 1024, x15);
|
||||
REQUIRE(value == 0x41F78023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SB(x31, 1536, x15);
|
||||
REQUIRE(value == 0x61F78023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SB(x31, -1, x15);
|
||||
REQUIRE(value == 0xFFF78FA3);
|
||||
}
|
||||
|
||||
TEST_CASE("SH", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SH(x31, 1024, x15);
|
||||
REQUIRE(value == 0x41F79023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SH(x31, 1536, x15);
|
||||
REQUIRE(value == 0x61F79023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SH(x31, -1, x15);
|
||||
REQUIRE(value == 0xFFF79FA3);
|
||||
}
|
||||
|
||||
TEST_CASE("SLL", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLL(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F793B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLL(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FF9FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLL(x0, x0, x0);
|
||||
REQUIRE(value == 0x00001033);
|
||||
}
|
||||
|
||||
TEST_CASE("SLLI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLLI(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A79F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLI(x31, x15, 20);
|
||||
REQUIRE(value == 0x01479F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLI(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F79F93);
|
||||
}
|
||||
|
||||
TEST_CASE("SLT", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLT(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7A3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLT(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFAFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLT(x0, x0, x0);
|
||||
REQUIRE(value == 0x00002033);
|
||||
}
|
||||
|
||||
TEST_CASE("SLTI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLTI(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400FA793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTI(x15, x31, -2048);
|
||||
REQUIRE(value == 0x800FA793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTI(x15, x31, -1);
|
||||
REQUIRE(value == 0xFFFFA793);
|
||||
}
|
||||
|
||||
TEST_CASE("SLTIU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLTIU(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400FB793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTIU(x15, x31, -2048);
|
||||
REQUIRE(value == 0x800FB793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTIU(x15, x31, -1);
|
||||
REQUIRE(value == 0xFFFFB793);
|
||||
}
|
||||
|
||||
TEST_CASE("SLTU", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SLTU(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7B3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTU(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFBFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLTU(x0, x0, x0);
|
||||
REQUIRE(value == 0x00003033);
|
||||
}
|
||||
|
||||
TEST_CASE("SRA", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SRA(x7, x15, x31);
|
||||
REQUIRE(value == 0x41F7D3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRA(x31, x31, x31);
|
||||
REQUIRE(value == 0x41FFDFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRA(x0, x0, x0);
|
||||
REQUIRE(value == 0x40005033);
|
||||
}
|
||||
|
||||
TEST_CASE("SRAI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SRAI(x31, x15, 10);
|
||||
REQUIRE(value == 0x40A7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAI(x31, x15, 20);
|
||||
REQUIRE(value == 0x4147DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAI(x31, x15, 31);
|
||||
REQUIRE(value == 0x41F7DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("SRL", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SRL(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7D3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRL(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFDFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRL(x0, x0, x0);
|
||||
REQUIRE(value == 0x00005033);
|
||||
}
|
||||
|
||||
TEST_CASE("SRLI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SRLI(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLI(x31, x15, 20);
|
||||
REQUIRE(value == 0x0147DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLI(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F7DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("SUB", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SUB(x7, x15, x31);
|
||||
REQUIRE(value == 0x41F783B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SUB(x31, x31, x31);
|
||||
REQUIRE(value == 0x41FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SUB(x0, x0, x0);
|
||||
REQUIRE(value == 0x40000033);
|
||||
}
|
||||
|
||||
TEST_CASE("SW", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SW(x31, 1024, x15);
|
||||
REQUIRE(value == 0x41F7A023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SW(x31, 1536, x15);
|
||||
REQUIRE(value == 0x61F7A023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SW(x31, -1, x15);
|
||||
REQUIRE(value == 0xFFF7AFA3);
|
||||
}
|
||||
|
||||
TEST_CASE("XOR", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.XOR(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7C3B3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XOR(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFCFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XOR(x0, x0, x0);
|
||||
REQUIRE(value == 0x00004033);
|
||||
}
|
||||
|
||||
TEST_CASE("XORI", "[rv32i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.XORI(x15, x31, 1024);
|
||||
REQUIRE(value == 0x400FC793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XORI(x15, x31, 2048);
|
||||
REQUIRE(value == 0x800FC793);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XORI(x15, x31, 4095);
|
||||
REQUIRE(value == 0xFFFFC793);
|
||||
}
|
||||
@@ -1,436 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("ADDIW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.ADDIW(x31, x15, 1024);
|
||||
REQUIRE(value == 0x40078F9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDIW(x31, x15, 2048);
|
||||
REQUIRE(value == 0x80078F9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDIW(x31, x15, 4095);
|
||||
REQUIRE(value == 0xFFF78F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("ADDW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.ADDW(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F783BB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDW(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FF8FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ADDW(x0, x0, x0);
|
||||
REQUIRE(value == 0x0000003B);
|
||||
}
|
||||
|
||||
TEST_CASE("LWU", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.LWU(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400FE783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LWU(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600FE783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LWU(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFE783);
|
||||
}
|
||||
|
||||
TEST_CASE("LD", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.LD(x15, 1024, x31);
|
||||
REQUIRE(value == 0x400FB783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LD(x15, 1536, x31);
|
||||
REQUIRE(value == 0x600FB783);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LD(x15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFB783);
|
||||
}
|
||||
|
||||
TEST_CASE("LI (RV64)", "[rv64i]") {
|
||||
// Up to 8 instructions can be generated
|
||||
std::array<uint32_t, 8> vals{};
|
||||
auto as = MakeAssembler64(vals);
|
||||
|
||||
const auto compare_vals = [&vals]<typename... Args>(const Args&... args) {
|
||||
static_assert(sizeof...(args) <= vals.size());
|
||||
|
||||
size_t i = 0;
|
||||
for (const auto arg : {args...}) {
|
||||
REQUIRE(vals[i] == arg);
|
||||
i++;
|
||||
}
|
||||
};
|
||||
|
||||
///////// Single ADDIW cases
|
||||
|
||||
as.LI(x1, 0);
|
||||
// addiw x1, x0, 0
|
||||
compare_vals(0x0000009BU, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, -1);
|
||||
// addiw x1, x0, -1
|
||||
compare_vals(0xFFF0009BU, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, 42);
|
||||
// addiw x1, x0, 42
|
||||
compare_vals(0x02A0009BU, 0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, 0x7ff);
|
||||
// addiw x1, x0, 2047
|
||||
compare_vals(0x7FF0009BU, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// Single LUI cases
|
||||
|
||||
as.LI(x1, 0x2A000);
|
||||
// lui x1, 42
|
||||
compare_vals(0x0002A0B7U, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, ~0xFFF);
|
||||
// lui x1, -1
|
||||
compare_vals(0xFFFFF0B7U, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, INT32_MIN);
|
||||
// lui x1, -524288
|
||||
compare_vals(0x800000B7U, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// LUI+ADDIW cases
|
||||
|
||||
as.LI(x1, 0x11111111);
|
||||
// lui x1, 69905
|
||||
// addiw x1, x1, 273
|
||||
compare_vals(0x111110B7U, 0x1110809BU, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, INT32_MAX);
|
||||
// lui x1, -524288
|
||||
// addiw x1, x1, -1
|
||||
compare_vals(0x800000B7U, 0xFFF0809BU, 0x00000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// ADDIW+SLLI cases
|
||||
|
||||
as.LI(x1, 0x7FF0000000ULL);
|
||||
// addiw x1, x0, 2047
|
||||
// slli x1, x1, 28
|
||||
compare_vals(0x7FF0009BU, 0x01C09093U, 0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
as.LI(x1, 0xABC00000ULL);
|
||||
// addiw x1, x0, 687
|
||||
// slli x1, x1, 22
|
||||
compare_vals(0x2AF0009BU, 0x01609093U, 0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// LUI+ADDIW+SLLI cases
|
||||
|
||||
as.LI(x1, 0x7FFFFFFF0000ULL);
|
||||
// lui x1, -524288
|
||||
// addiw x1, x1, -1
|
||||
// slli x1, x1, 16
|
||||
compare_vals(0x800000B7U, 0xFFF0809BU, 0x01009093U, 0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// LUI+ADDIW+SLLI+ADDI cases
|
||||
|
||||
as.LI(x1, 0x7FFFFFFF0123);
|
||||
// lui x1, -524288
|
||||
// addiw x1, x1, -1
|
||||
// slli x1, x1, 16
|
||||
// addi x1, x1, 291
|
||||
compare_vals(0x800000B7U, 0xfff0809BU, 0x01009093U, 0x12308093U,
|
||||
0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// ADDIW+SLLI+ADDI+SLLI+ADDI cases
|
||||
|
||||
as.LI(x1, 0x8000000080000001ULL);
|
||||
// addiw x1, x0, -1
|
||||
// slli x1, x1, 32
|
||||
// addi x1, x1, 1
|
||||
// slli x1, x1, 31
|
||||
// addi x1, x1, 1
|
||||
compare_vals(0xFFF0009BU, 0x02009093U, 0x00108093U, 0x01F09093U,
|
||||
0x00108093U, 0x000000000U);
|
||||
as.RewindBuffer();
|
||||
vals = {};
|
||||
|
||||
///////// Full LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI cases
|
||||
|
||||
as.LI(x1, 0x80808000808080F1ULL);
|
||||
// lui x1, -16
|
||||
// addiw x1, x1, 257
|
||||
// slli x1, x1, 16
|
||||
// addi x1, x1, 1
|
||||
// slli x1, x1, 16
|
||||
// addi x1, x1, 257
|
||||
// slli x1, x1, 15
|
||||
// addi x1, x1, 241
|
||||
compare_vals(0xFFFF00B7U, 0x1010809BU, 0x01009093U, 0x00108093U,
|
||||
0x01009093U, 0x10108093U, 0x00F09093U, 0x0F108093U);
|
||||
}
|
||||
|
||||
TEST_CASE("SD", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SD(x15, 1024, x31);
|
||||
REQUIRE(value == 0x40FFB023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SD(x15, 1536, x31);
|
||||
REQUIRE(value == 0x60FFB023);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SD(x15, -1, x31);
|
||||
REQUIRE(value == 0xFEFFBFA3);
|
||||
}
|
||||
|
||||
TEST_CASE("SLLI (RV64)", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SLLI(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A79F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLI(x31, x15, 20);
|
||||
REQUIRE(value == 0x01479F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLI(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F79F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLI(x31, x15, 63);
|
||||
REQUIRE(value == 0x03F79F93);
|
||||
}
|
||||
|
||||
TEST_CASE("SLLIW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SLLIW(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A79F9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLIW(x31, x15, 20);
|
||||
REQUIRE(value == 0x01479F9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLIW(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F79F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("SLLW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SLLW(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F793BB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLW(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FF9FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLW(x0, x0, x0);
|
||||
REQUIRE(value == 0x0000103B);
|
||||
}
|
||||
|
||||
TEST_CASE("SRAI (RV64)", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRAI(x31, x15, 10);
|
||||
REQUIRE(value == 0x40A7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAI(x31, x15, 20);
|
||||
REQUIRE(value == 0x4147DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAI(x31, x15, 31);
|
||||
REQUIRE(value == 0x41F7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAI(x31, x15, 63);
|
||||
REQUIRE(value == 0x43F7DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("SRAIW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRAIW(x31, x15, 10);
|
||||
REQUIRE(value == 0x40A7DF9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAIW(x31, x15, 20);
|
||||
REQUIRE(value == 0x4147DF9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAIW(x31, x15, 31);
|
||||
REQUIRE(value == 0x41F7DF9B);
|
||||
}
|
||||
|
||||
TEST_CASE("SRAW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRAW(x7, x15, x31);
|
||||
REQUIRE(value == 0x41F7D3BB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAW(x31, x31, x31);
|
||||
REQUIRE(value == 0x41FFDFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRAW(x0, x0, x0);
|
||||
REQUIRE(value == 0x4000503B);
|
||||
}
|
||||
|
||||
TEST_CASE("SRLI (RV64)", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRLI(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLI(x31, x15, 20);
|
||||
REQUIRE(value == 0x0147DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLI(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F7DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLI(x31, x15, 63);
|
||||
REQUIRE(value == 0x03F7DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("SRLIW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRLIW(x31, x15, 10);
|
||||
REQUIRE(value == 0x00A7DF9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLIW(x31, x15, 20);
|
||||
REQUIRE(value == 0x0147DF9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLIW(x31, x15, 31);
|
||||
REQUIRE(value == 0x01F7DF9B);
|
||||
}
|
||||
|
||||
TEST_CASE("SRLW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SRLW(x7, x15, x31);
|
||||
REQUIRE(value == 0x01F7D3BB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLW(x31, x31, x31);
|
||||
REQUIRE(value == 0x01FFDFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SRLW(x0, x0, x0);
|
||||
REQUIRE(value == 0x0000503B);
|
||||
}
|
||||
|
||||
TEST_CASE("SUBW", "[rv64i]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SUBW(x7, x15, x31);
|
||||
REQUIRE(value == 0x41F783BB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SUBW(x31, x31, x31);
|
||||
REQUIRE(value == 0x41FF8FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SUBW(x0, x0, x0);
|
||||
REQUIRE(value == 0x4000003B);
|
||||
}
|
||||
513
externals/biscuit/tests/src/assembler_rva_tests.cpp
vendored
513
externals/biscuit/tests/src/assembler_rva_tests.cpp
vendored
@@ -1,513 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("AMOADD.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOADD_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x0077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x0477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOADD.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOADD_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x0077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x0477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOADD_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOAND.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOAND_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x6077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x6477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x6277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x6677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOAND.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOAND_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x6077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x6477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x6277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOAND_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x6677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMAX.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOMAX_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xA077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xA477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xA277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xA677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMAX.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOMAX_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xA077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xA477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xA277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAX_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xA677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMAXU.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOMAXU_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xE077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xE477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xE277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xE677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMAXU.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOMAXU_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xE077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xE477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xE277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMAXU_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xE677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMIN.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOMIN_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x8077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x8477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x8277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x8677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMIN.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOMIN_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x8077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x8477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x8277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMIN_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x8677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMINU.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOMINU_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xC077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xC477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xC277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xC677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOMINU.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOMINU_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0xC077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0xC477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0xC277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOMINU_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0xC677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOOR.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOOR_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x4077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x4477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x4277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x4677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOOR.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOOR_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x4077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x4477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x4277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOOR_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x4677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOSWAP.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOSWAP_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x0877BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x0C77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0A77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0E77BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOSWAP.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOSWAP_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x0877AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x0C77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0A77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOSWAP_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x0E77AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOXOR.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOXOR_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x2077BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x2477BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2277BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2677BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOXOR.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AMOXOR_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x2077AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x2477AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2277AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOXOR_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2677AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("LR.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.LR_D(Ordering::None, x31, x15);
|
||||
REQUIRE(value == 0x1007BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_D(Ordering::AQ, x31, x15);
|
||||
REQUIRE(value == 0x1407BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_D(Ordering::RL, x31, x15);
|
||||
REQUIRE(value == 0x1207BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_D(Ordering::AQRL, x31, x15);
|
||||
REQUIRE(value == 0x1607BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("LR.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.LR_W(Ordering::None, x31, x15);
|
||||
REQUIRE(value == 0x1007AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_W(Ordering::AQ, x31, x15);
|
||||
REQUIRE(value == 0x1407AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_W(Ordering::RL, x31, x15);
|
||||
REQUIRE(value == 0x1207AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.LR_W(Ordering::AQRL, x31, x15);
|
||||
REQUIRE(value == 0x1607AFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("SC.D", "[rv64a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SC_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x1877BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x1C77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x1A77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x1E77BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("SC.W", "[rv32a]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SC_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x1877AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x1C77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x1A77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SC_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x1E77AFAF);
|
||||
}
|
||||
610
externals/biscuit/tests/src/assembler_rvb_tests.cpp
vendored
610
externals/biscuit/tests/src/assembler_rvb_tests.cpp
vendored
@@ -1,610 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("ADD.UW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.ADDUW(x31, x7, x15);
|
||||
REQUIRE(value == 0x08F38FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
// Pseudo instruction
|
||||
|
||||
as.ZEXTW(x31, x7);
|
||||
REQUIRE(value == 0x08038FBB);
|
||||
}
|
||||
|
||||
TEST_CASE("ANDN", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ANDN(x31, x7, x15);
|
||||
REQUIRE(value == 0x40F3FFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BCLR", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BCLR(x31, x7, x15);
|
||||
REQUIRE(value == 0x48F39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BCLRI", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BCLRI(x31, x7, 0);
|
||||
REQUIRE(value == 0x48039F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BCLRI(x31, x7, 15);
|
||||
REQUIRE(value == 0x48F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BCLRI(x31, x7, 31);
|
||||
REQUIRE(value == 0x49F39F93);
|
||||
}
|
||||
|
||||
TEST_CASE("BCLRI (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.BCLRI(x31, x7, 0);
|
||||
REQUIRE(value == 0x48039F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BCLRI(x31, x7, 15);
|
||||
REQUIRE(value == 0x48F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BCLRI(x31, x7, 31);
|
||||
REQUIRE(value == 0x49F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BCLRI(x31, x7, 63);
|
||||
REQUIRE(value == 0x4BF39F93);
|
||||
}
|
||||
|
||||
TEST_CASE("BEXT", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BEXT(x31, x7, x15);
|
||||
REQUIRE(value == 0x48F3DFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BEXTI", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BEXTI(x31, x7, 0);
|
||||
REQUIRE(value == 0x4803DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEXTI(x31, x7, 15);
|
||||
REQUIRE(value == 0x48F3DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEXTI(x31, x7, 31);
|
||||
REQUIRE(value == 0x49F3DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("BEXTI (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.BEXTI(x31, x7, 0);
|
||||
REQUIRE(value == 0x4803DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEXTI(x31, x7, 15);
|
||||
REQUIRE(value == 0x48F3DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEXTI(x31, x7, 31);
|
||||
REQUIRE(value == 0x49F3DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BEXTI(x31, x7, 63);
|
||||
REQUIRE(value == 0x4BF3DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("BINV", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BINV(x31, x7, x15);
|
||||
REQUIRE(value == 0x68F39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BINVI", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BINVI(x31, x7, 0);
|
||||
REQUIRE(value == 0x68039F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BINVI(x31, x7, 15);
|
||||
REQUIRE(value == 0x68F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BINVI(x31, x7, 31);
|
||||
REQUIRE(value == 0x69F39F93);
|
||||
}
|
||||
|
||||
TEST_CASE("BINVI (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.BINVI(x31, x7, 0);
|
||||
REQUIRE(value == 0x68039F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BINVI(x31, x7, 15);
|
||||
REQUIRE(value == 0x68F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BINVI(x31, x7, 31);
|
||||
REQUIRE(value == 0x69F39F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BINVI(x31, x7, 63);
|
||||
REQUIRE(value == 0x6BF39F93);
|
||||
}
|
||||
|
||||
TEST_CASE("BREV8", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BREV8(x31, x31);
|
||||
REQUIRE(value == 0x687FDF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BREV8(x1, x2);
|
||||
REQUIRE(value == 0x68715093);
|
||||
}
|
||||
|
||||
TEST_CASE("BSET", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BSET(x31, x7, x15);
|
||||
REQUIRE(value == 0x28F39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BSETI", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.BSETI(x31, x7, 0);
|
||||
REQUIRE(value == 0x28039FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BSETI(x31, x7, 15);
|
||||
REQUIRE(value == 0x28F39FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BSETI(x31, x7, 31);
|
||||
REQUIRE(value == 0x29F39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("BSETI (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.BSETI(x31, x7, 0);
|
||||
REQUIRE(value == 0x28039FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BSETI(x31, x7, 15);
|
||||
REQUIRE(value == 0x28F39FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BSETI(x31, x7, 31);
|
||||
REQUIRE(value == 0x29F39FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.BSETI(x31, x7, 63);
|
||||
REQUIRE(value == 0x2BF39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("CLMUL", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CLMUL(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("CLMULH", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CLMULH(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3BFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("CLMULR", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CLMULR(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3AFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("CLZ", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CLZ(x31, x7);
|
||||
REQUIRE(value == 0x60039F93);
|
||||
}
|
||||
|
||||
TEST_CASE("CLZW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CLZW(x31, x7);
|
||||
REQUIRE(value == 0x60039F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("CPOP", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CPOP(x31, x7);
|
||||
REQUIRE(value == 0x60239F93);
|
||||
}
|
||||
|
||||
TEST_CASE("CPOPW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CPOPW(x31, x7);
|
||||
REQUIRE(value == 0x60239F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("CTZ", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CTZ(x31, x7);
|
||||
REQUIRE(value == 0x60139F93);
|
||||
}
|
||||
|
||||
TEST_CASE("CTZW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CTZW(x31, x7);
|
||||
REQUIRE(value == 0x60139F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("MAX", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MAX(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3EFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("MAXU", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MAXU(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3FFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("MIN", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MIN(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3CFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("MINU", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MINU(x31, x7, x15);
|
||||
REQUIRE(value == 0x0AF3DFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("ORC.B", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ORCB(x31, x7);
|
||||
REQUIRE(value == 0x2873DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("ORN", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ORN(x31, x7, x15);
|
||||
REQUIRE(value == 0x40F3EFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("PACK", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PACK(x31, x7, x2);
|
||||
REQUIRE(value == 0x0823CFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("PACKH", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.PACKH(x31, x7, x2);
|
||||
REQUIRE(value == 0x0823FFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("PACKW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.PACKW(x31, x7, x2);
|
||||
REQUIRE(value == 0x0823CFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("REV8", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.REV8(x31, x7);
|
||||
REQUIRE(value == 0x6983DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("REV8 (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.REV8(x31, x7);
|
||||
REQUIRE(value == 0x6B83DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("ROL", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ROL(x31, x7, x15);
|
||||
REQUIRE(value == 0x60F39FB3);
|
||||
}
|
||||
|
||||
TEST_CASE("ROLW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.ROLW(x31, x7, x15);
|
||||
REQUIRE(value == 0x60F39FBB);
|
||||
}
|
||||
|
||||
TEST_CASE("ROR", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ROR(x31, x7, x15);
|
||||
REQUIRE(value == 0x60F3DFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("RORW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.RORW(x31, x7, x15);
|
||||
REQUIRE(value == 0x60F3DFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("RORI", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.RORI(x31, x7, 0);
|
||||
REQUIRE(value == 0x6003DF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.RORI(x31, x7, 63);
|
||||
REQUIRE(value == 0x63F3DF93);
|
||||
}
|
||||
|
||||
TEST_CASE("RORIW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.RORIW(x31, x7, 0);
|
||||
REQUIRE(value == 0x6003DF9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.RORIW(x31, x7, 63);
|
||||
REQUIRE(value == 0x63F3DF9B);
|
||||
}
|
||||
|
||||
TEST_CASE("SEXT.B", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SEXTB(x31, x7);
|
||||
REQUIRE(value == 0x60439F93);
|
||||
}
|
||||
|
||||
TEST_CASE("SEXT.H", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SEXTH(x31, x7);
|
||||
REQUIRE(value == 0x60539F93);
|
||||
}
|
||||
|
||||
TEST_CASE("SH1ADD", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SH1ADD(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3AFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("SH1ADD.UW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SH1ADDUW(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3AFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("SH2ADD", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SH2ADD(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3CFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("SH2ADD.UW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SH2ADDUW(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3CFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("SH3ADD", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SH3ADD(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3EFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("SH3ADD.UW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SH3ADDUW(x31, x7, x15);
|
||||
REQUIRE(value == 0x20F3EFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("SLLI.UW", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SLLIUW(x31, x7, 0);
|
||||
REQUIRE(value == 0x08039F9B);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SLLIUW(x31, x7, 63);
|
||||
REQUIRE(value == 0x0BF39F9B);
|
||||
}
|
||||
|
||||
TEST_CASE("UNZIP", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.UNZIP(x31, x31);
|
||||
REQUIRE(value == 0x09FFDF93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.UNZIP(x1, x2);
|
||||
REQUIRE(value == 0x09F15093);
|
||||
}
|
||||
|
||||
TEST_CASE("XNOR", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.XNOR(x31, x7, x15);
|
||||
REQUIRE(value == 0x40F3CFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("XPERM4", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.XPERM4(x31, x31, x31);
|
||||
REQUIRE(value == 0x29FFAFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XPERM4(x1, x2, x3);
|
||||
REQUIRE(value == 0x283120B3);
|
||||
}
|
||||
|
||||
TEST_CASE("XPERM8", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.XPERM8(x31, x31, x31);
|
||||
REQUIRE(value == 0x29FFCFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.XPERM8(x1, x2, x3);
|
||||
REQUIRE(value == 0x283140B3);
|
||||
}
|
||||
|
||||
TEST_CASE("ZEXT.H", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ZEXTH(x31, x7);
|
||||
REQUIRE(value == 0x0803CFB3);
|
||||
}
|
||||
|
||||
TEST_CASE("ZEXT.H (RV64)", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.ZEXTH(x31, x7);
|
||||
REQUIRE(value == 0x0803CFBB);
|
||||
}
|
||||
|
||||
TEST_CASE("ZIP", "[rvb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.ZIP(x31, x31);
|
||||
REQUIRE(value == 0x09EF9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.ZIP(x1, x2);
|
||||
REQUIRE(value == 0x09E11093);
|
||||
}
|
||||
595
externals/biscuit/tests/src/assembler_rvc_tests.cpp
vendored
595
externals/biscuit/tests/src/assembler_rvc_tests.cpp
vendored
@@ -1,595 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("C.ADD", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_ADD(x31, x31);
|
||||
REQUIRE(value == 0x9FFE);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADD(x15, x8);
|
||||
REQUIRE(value == 0x97A2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ADDI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_ADDI(x15, -1);
|
||||
REQUIRE(value == 0x17FD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDI(x15, -32);
|
||||
REQUIRE(value == 0x1781);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDI(x15, 31);
|
||||
REQUIRE(value == 0x07FD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ADDIW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_ADDIW(x15, -1);
|
||||
REQUIRE(value == 0x37FD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDIW(x15, -32);
|
||||
REQUIRE(value == 0x3781);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDIW(x15, 31);
|
||||
REQUIRE(value == 0x27FD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ADDI4SPN", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_ADDI4SPN(x15, 252);
|
||||
REQUIRE(value == 0x19FC);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDI4SPN(x8, 1020);
|
||||
REQUIRE(value == 0x1FE0);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDI4SPN(x15, 1020);
|
||||
REQUIRE(value == 0x1FFC);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ADDI16SP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_ADDI16SP(16);
|
||||
REQUIRE(value == 0x6141);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDI16SP(64);
|
||||
REQUIRE(value == 0x6121);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ADDW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_ADDW(x15, x15);
|
||||
REQUIRE(value == 0x9FBD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ADDW(x15, x8);
|
||||
REQUIRE(value == 0x9FA1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.AND", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_AND(x15, x15);
|
||||
REQUIRE(value == 0x8FFD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_AND(x15, x8);
|
||||
REQUIRE(value == 0x8FE1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ANDI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_ANDI(x15, 16);
|
||||
REQUIRE(value == 0x8BC1);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ANDI(x15, 31);
|
||||
REQUIRE(value == 0x8BFD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.EBREAK", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_EBREAK();
|
||||
REQUIRE(value == 0x9002);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FLD", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FLD(f15, 8, x15);
|
||||
REQUIRE(value == 0x279C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FLD(f15, 24, x15);
|
||||
REQUIRE(value == 0x2F9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FLDSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FLDSP(f15, 8);
|
||||
REQUIRE(value == 0x27A2);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FLDSP(f15, 24);
|
||||
REQUIRE(value == 0x27E2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FLW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FLW(f15, 16, x15);
|
||||
REQUIRE(value == 0x6B9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FLW(f15, 24, x15);
|
||||
REQUIRE(value == 0x6F9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FLWSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FLWSP(f15, 16);
|
||||
REQUIRE(value == 0x67C2);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FLWSP(f15, 24);
|
||||
REQUIRE(value == 0x67E2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FSD", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FSD(f15, 8, x15);
|
||||
REQUIRE(value == 0xA79C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FSD(f15, 24, x15);
|
||||
REQUIRE(value == 0xAF9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FSDSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FSDSP(f15, 8);
|
||||
REQUIRE(value == 0xA43E);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FSDSP(f15, 24);
|
||||
REQUIRE(value == 0xAC3E);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FSW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FSW(f15, 16, x15);
|
||||
REQUIRE(value == 0xEB9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FSW(f15, 24, x15);
|
||||
REQUIRE(value == 0xEF9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.FSWSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_FSWSP(f15, 16);
|
||||
REQUIRE(value == 0xE83E);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_FSWSP(f15, 24);
|
||||
REQUIRE(value == 0xEC3E);
|
||||
}
|
||||
|
||||
TEST_CASE("C.JALR", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_JALR(x31);
|
||||
REQUIRE(value == 0x9F82);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_JALR(x15);
|
||||
REQUIRE(value == 0x9782);
|
||||
}
|
||||
|
||||
TEST_CASE("C.JR", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_JR(x31);
|
||||
REQUIRE(value == 0x8F82);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_JR(x15);
|
||||
REQUIRE(value == 0x8782);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LD", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_LD(x15, 8, x15);
|
||||
REQUIRE(value == 0x679C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LD(x15, 24, x15);
|
||||
REQUIRE(value == 0x6F9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LDSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_LDSP(x15, 8);
|
||||
REQUIRE(value == 0x67A2);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LDSP(x15, 24);
|
||||
REQUIRE(value == 0x67E2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_LI(x15, -1);
|
||||
REQUIRE(value == 0x57FD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LI(x15, -32);
|
||||
REQUIRE(value == 0x5781);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LI(x15, 31);
|
||||
REQUIRE(value == 0x47FD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LQ", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_LQ(x15, 16, x15);
|
||||
REQUIRE(value == 0x2B9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LQ(x15, 256, x15);
|
||||
REQUIRE(value == 0x279C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LQSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_LQSP(x15, 16);
|
||||
REQUIRE(value == 0x27C2);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LQSP(x15, 256);
|
||||
REQUIRE(value == 0x2792);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LUI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_LUI(x15, 0x3F000);
|
||||
REQUIRE(value == 0x77FD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LUI(x15, 0x0F000);
|
||||
REQUIRE(value == 0x67BD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_LW(x15, 16, x15);
|
||||
REQUIRE(value == 0x4B9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LW(x15, 24, x15);
|
||||
REQUIRE(value == 0x4F9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LWSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_LWSP(x15, 16);
|
||||
REQUIRE(value == 0x47C2);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LWSP(x15, 24);
|
||||
REQUIRE(value == 0x47E2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.MV", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_MV(x31, x31);
|
||||
REQUIRE(value == 0x8FFE);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_MV(x15, x8);
|
||||
REQUIRE(value == 0x87A2);
|
||||
}
|
||||
|
||||
TEST_CASE("C.NOP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_NOP();
|
||||
REQUIRE(value == 0x0001);
|
||||
}
|
||||
|
||||
TEST_CASE("C.OR", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_OR(x15, x15);
|
||||
REQUIRE(value == 0x8FDD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_OR(x15, x8);
|
||||
REQUIRE(value == 0x8FC1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SD", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SD(x15, 8, x15);
|
||||
REQUIRE(value == 0xE79C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SD(x15, 24, x15);
|
||||
REQUIRE(value == 0xEF9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SDSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SDSP(x15, 8);
|
||||
REQUIRE(value == 0xE43E);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SDSP(x15, 24);
|
||||
REQUIRE(value == 0xEC3E);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SLLI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SLLI(x15, 15);
|
||||
REQUIRE(value == 0x07BE);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SLLI(x15, 31);
|
||||
REQUIRE(value == 0x07FE);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SLLI (RV128)", "[rv128c]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_SLLI(x15, 64);
|
||||
REQUIRE(value == 0x0782);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SQ", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_SQ(x15, 16, x15);
|
||||
REQUIRE(value == 0xAB9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SQ(x15, 256, x15);
|
||||
REQUIRE(value == 0xA79C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SQSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_SQSP(x15, 16);
|
||||
REQUIRE(value == 0xA83E);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SQSP(x15, 256);
|
||||
REQUIRE(value == 0xA23E);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SRAI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SRAI(x15, 16);
|
||||
REQUIRE(value == 0x87C1);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SRAI(x15, 31);
|
||||
REQUIRE(value == 0x87FD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SRAI (RV128)", "[rv128c]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_SRAI(x15, 64);
|
||||
REQUIRE(value == 0x8781);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SRLI", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SRLI(x15, 16);
|
||||
REQUIRE(value == 0x83C1);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SRLI(x15, 31);
|
||||
REQUIRE(value == 0x83FD);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SRLI (RV128)", "[rv128c]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler128(value);
|
||||
|
||||
as.C_SRLI(x15, 64);
|
||||
REQUIRE(value == 0x8381);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SUB", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SUB(x15, x15);
|
||||
REQUIRE(value == 0x8F9D);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SUB(x15, x8);
|
||||
REQUIRE(value == 0x8F81);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SUBW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SUBW(x15, x15);
|
||||
REQUIRE(value == 0x9F9D);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SUBW(x15, x8);
|
||||
REQUIRE(value == 0x9F81);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SW", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SW(x15, 16, x15);
|
||||
REQUIRE(value == 0xCB9C);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SW(x15, 24, x15);
|
||||
REQUIRE(value == 0xCF9C);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SWSP", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_SWSP(x15, 16);
|
||||
REQUIRE(value == 0xC83E);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SWSP(x15, 24);
|
||||
REQUIRE(value == 0xCC3E);
|
||||
}
|
||||
|
||||
TEST_CASE("C.UNDEF", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_UNDEF();
|
||||
REQUIRE(value == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("C.XOR", "[rvc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.C_XOR(x15, x15);
|
||||
REQUIRE(value == 0x8FBD);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_XOR(x15, x8);
|
||||
REQUIRE(value == 0x8FA1);
|
||||
}
|
||||
528
externals/biscuit/tests/src/assembler_rvd_tests.cpp
vendored
528
externals/biscuit/tests/src/assembler_rvd_tests.cpp
vendored
@@ -1,528 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("FADD.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FADD_D(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x03A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FADD_D(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x03A3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FADD_D(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x03A3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCLASS.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCLASS_D(x31, f7);
|
||||
REQUIRE(value == 0xE2039FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCLASS_D(x7, f31);
|
||||
REQUIRE(value == 0xE20F93D3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.S", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_D_S(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x42038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_S(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4203CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_S(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4203FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.W", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_D_W(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD2038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_W(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD203CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_W(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD203FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.WU", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_D_WU(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD2138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_WU(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD213CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_WU(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD213FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.L.D", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_L_D(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC2238FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_L_D(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC223CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_L_D(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC223FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.LU.D", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_LU_D(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC2338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_LU_D(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC233CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_LU_D(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC233FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.L", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_D_L(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD2238FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_L(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD223CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_L(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD223FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.LU", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_D_LU(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD2338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_LU(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD233CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_LU(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD233FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.W.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_W_D(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC2038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_W_D(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC203CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_W_D(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC203FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.WU.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_WU_D(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC2138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_WU_D(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC213CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_WU_D(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC213FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.S.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_S_D(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x40138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_D(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4013CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_D(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4013FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FDIV.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FDIV_D(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x1BA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FDIV_D(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x1BA3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FDIV_D(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x1BA3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FEQ.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FEQ_D(x31, f7, f26);
|
||||
REQUIRE(value == 0xA3A3AFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FEQ_D(x31, f26, f7);
|
||||
REQUIRE(value == 0xA27D2FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLE.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLE_D(x31, f7, f26);
|
||||
REQUIRE(value == 0xA3A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLE_D(x31, f26, f7);
|
||||
REQUIRE(value == 0xA27D0FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLT.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLT_D(x31, f7, f26);
|
||||
REQUIRE(value == 0xA3A39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLT_D(x31, f26, f7);
|
||||
REQUIRE(value == 0xA27D1FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLD", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLD(f15, 1024, x31);
|
||||
REQUIRE(value == 0x400FB787);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLD(f15, 1536, x31);
|
||||
REQUIRE(value == 0x600FB787);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLD(f15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFB787);
|
||||
}
|
||||
|
||||
TEST_CASE("FMADD.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMADD_D(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD27F87C3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMADD_D(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD27FC7C3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMADD_D(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD27FF7C3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAX.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMAX_D(f31, f7, f26);
|
||||
REQUIRE(value == 0x2BA39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMAX_D(f31, f31, f31);
|
||||
REQUIRE(value == 0x2BFF9FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMIN.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMIN_D(f31, f7, f26);
|
||||
REQUIRE(value == 0x2BA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMIN_D(f31, f31, f31);
|
||||
REQUIRE(value == 0x2BFF8FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMSUB.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMSUB_D(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD27F87C7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMSUB_D(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD27FC7C7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMSUB_D(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD27FF7C7);
|
||||
}
|
||||
|
||||
TEST_CASE("FMUL.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMUL_D(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x13A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMUL_D(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x13A3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMUL_D(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x13A3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMV.D.X", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMV_D_X(f31, x7);
|
||||
REQUIRE(value == 0xF2038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMV_D_X(f7, x31);
|
||||
REQUIRE(value == 0xF20F83D3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMV.X.D", "[rv64d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMV_X_D(x31, f7);
|
||||
REQUIRE(value == 0xE2038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMV_X_D(x7, f31);
|
||||
REQUIRE(value == 0xE20F83D3);
|
||||
}
|
||||
|
||||
TEST_CASE("FNMADD.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FNMADD_D(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD27F87CF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMADD_D(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD27FC7CF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMADD_D(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD27FF7CF);
|
||||
}
|
||||
|
||||
TEST_CASE("FNMSUB.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FNMSUB_D(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD27F87CB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMSUB_D(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD27FC7CB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMSUB_D(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD27FF7CB);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJ.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJ_D(f31, f7, f26);
|
||||
REQUIRE(value == 0x23A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJ_D(f31, f31, f31);
|
||||
REQUIRE(value == 0x23FF8FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJN.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJN_D(f31, f7, f26);
|
||||
REQUIRE(value == 0x23A39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJN_D(f31, f31, f31);
|
||||
REQUIRE(value == 0x23FF9FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJX.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJX_D(f31, f7, f26);
|
||||
REQUIRE(value == 0x23A3AFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJX_D(f31, f31, f31);
|
||||
REQUIRE(value == 0x23FFAFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSQRT.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSQRT_D(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x5A038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQRT_D(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x5A03CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQRT_D(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x5A03FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSUB.D", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSUB_D(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x0BA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSUB_D(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x0BA3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSUB_D(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x0BA3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSD", "[rv32d]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSD(f31, 1024, x15);
|
||||
REQUIRE(value == 0x41F7B027);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSD(f31, 1536, x15);
|
||||
REQUIRE(value == 0x61F7B027);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSD(f31, -1, x15);
|
||||
REQUIRE(value == 0xFFF7BFA7);
|
||||
}
|
||||
1085
externals/biscuit/tests/src/assembler_rvf_tests.cpp
vendored
1085
externals/biscuit/tests/src/assembler_rvf_tests.cpp
vendored
File diff suppressed because it is too large
Load Diff
384
externals/biscuit/tests/src/assembler_rvk_tests.cpp
vendored
384
externals/biscuit/tests/src/assembler_rvk_tests.cpp
vendored
@@ -1,384 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("AES32DSI", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AES32DSI(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xEBFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES32DSI(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xAA3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES32DSMI", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AES32DSMI(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xEFFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES32DSMI(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xAE3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES32ESI", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AES32ESI(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xE3FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES32ESI(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xA23100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES32ESMI", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.AES32ESMI(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xE7FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES32ESMI(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xA63100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64DS", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64DS(x31, x31, x31);
|
||||
REQUIRE(value == 0x3BFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64DS(x1, x2, x3);
|
||||
REQUIRE(value == 0x3A3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64DSM", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64DSM(x31, x31, x31);
|
||||
REQUIRE(value == 0x3FFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64DSM(x1, x2, x3);
|
||||
REQUIRE(value == 0x3E3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64ES", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64ES(x31, x31, x31);
|
||||
REQUIRE(value == 0x33FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64ES(x1, x2, x3);
|
||||
REQUIRE(value == 0x323100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64ESM", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64ESM(x31, x31, x31);
|
||||
REQUIRE(value == 0x37FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64ESM(x1, x2, x3);
|
||||
REQUIRE(value == 0x363100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64IM", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64IM(x31, x31);
|
||||
REQUIRE(value == 0x300F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64IM(x1, x2);
|
||||
REQUIRE(value == 0x30011093);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64KS1I", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64KS1I(x31, x31, 0xA);
|
||||
REQUIRE(value == 0x31AF9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64KS1I(x1, x2, 0x5);
|
||||
REQUIRE(value == 0x31511093);
|
||||
}
|
||||
|
||||
TEST_CASE("AES64KS2", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AES64KS2(x31, x31, x31);
|
||||
REQUIRE(value == 0x7FFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AES64KS2(x1, x2, x3);
|
||||
REQUIRE(value == 0x7E3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA256SIG0", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA256SIG0(x31, x31);
|
||||
REQUIRE(value == 0x102F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA256SIG0(x1, x2);
|
||||
REQUIRE(value == 0x10211093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA256SIG1", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA256SIG1(x31, x31);
|
||||
REQUIRE(value == 0x103F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA256SIG1(x1, x2);
|
||||
REQUIRE(value == 0x10311093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA256SUM0", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA256SUM0(x31, x31);
|
||||
REQUIRE(value == 0x100F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA256SUM0(x1, x2);
|
||||
REQUIRE(value == 0x10011093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA256SUM1", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA256SUM1(x31, x31);
|
||||
REQUIRE(value == 0x101F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA256SUM1(x1, x2);
|
||||
REQUIRE(value == 0x10111093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG0", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA512SIG0(x31, x31);
|
||||
REQUIRE(value == 0x106F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG0(x1, x2);
|
||||
REQUIRE(value == 0x10611093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG0H", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SIG0H(x31, x31, x31);
|
||||
REQUIRE(value == 0x5DFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG0H(x1, x2, x3);
|
||||
REQUIRE(value == 0x5C3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG0L", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SIG0L(x31, x31, x31);
|
||||
REQUIRE(value == 0x55FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG0L(x1, x2, x3);
|
||||
REQUIRE(value == 0x543100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG1", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA512SIG1(x31, x31);
|
||||
REQUIRE(value == 0x107F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG1(x1, x2);
|
||||
REQUIRE(value == 0x10711093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG1H", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SIG1H(x31, x31, x31);
|
||||
REQUIRE(value == 0x5FFF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG1H(x1, x2, x3);
|
||||
REQUIRE(value == 0x5E3100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SIG1L", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SIG1L(x31, x31, x31);
|
||||
REQUIRE(value == 0x57FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SIG1L(x1, x2, x3);
|
||||
REQUIRE(value == 0x563100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SUM0", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA512SUM0(x31, x31);
|
||||
REQUIRE(value == 0x104F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SUM0(x1, x2);
|
||||
REQUIRE(value == 0x10411093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SUM0R", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SUM0R(x31, x31, x31);
|
||||
REQUIRE(value == 0x51FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SUM0R(x1, x2, x3);
|
||||
REQUIRE(value == 0x503100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SUM1", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SHA512SUM1(x31, x31);
|
||||
REQUIRE(value == 0x105F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SUM1(x1, x2);
|
||||
REQUIRE(value == 0x10511093);
|
||||
}
|
||||
|
||||
TEST_CASE("SHA512SUM1R", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.SHA512SUM1R(x31, x31, x31);
|
||||
REQUIRE(value == 0x53FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SHA512SUM1R(x1, x2, x3);
|
||||
REQUIRE(value == 0x523100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SM3P0", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SM3P0(x31, x31);
|
||||
REQUIRE(value == 0x108F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SM3P0(x1, x2);
|
||||
REQUIRE(value == 0x10811093);
|
||||
}
|
||||
|
||||
TEST_CASE("SM3P1", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SM3P1(x31, x31);
|
||||
REQUIRE(value == 0x109F9F93);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SM3P1(x1, x2);
|
||||
REQUIRE(value == 0x10911093);
|
||||
}
|
||||
|
||||
TEST_CASE("SM4ED", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SM4ED(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xF1FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SM4ED(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xB03100B3);
|
||||
}
|
||||
|
||||
TEST_CASE("SM4KS", "[rvk]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.SM4KS(x31, x31, x31, 0b11);
|
||||
REQUIRE(value == 0xF5FF8FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.SM4KS(x1, x2, x3, 0b10);
|
||||
REQUIRE(value == 0xB43100B3);
|
||||
}
|
||||
241
externals/biscuit/tests/src/assembler_rvm_tests.cpp
vendored
241
externals/biscuit/tests/src/assembler_rvm_tests.cpp
vendored
@@ -1,241 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("DIV", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.DIV(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347CFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIV(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA4FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIV(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFCA33);
|
||||
}
|
||||
|
||||
TEST_CASE("DIVW", "[rv64m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.DIVW(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347CFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVW(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA4FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVW(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFCA3B);
|
||||
}
|
||||
|
||||
TEST_CASE("DIVU", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.DIVU(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347DFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVU(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA5FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVU(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFDA33);
|
||||
}
|
||||
|
||||
TEST_CASE("DIVUW", "[rv64m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.DIVUW(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347DFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVUW(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA5FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.DIVUW(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFDA3B);
|
||||
}
|
||||
|
||||
TEST_CASE("MUL", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MUL(x31, x15, x20);
|
||||
REQUIRE(value == 0x03478FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MUL(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA0FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MUL(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FF8A33);
|
||||
}
|
||||
|
||||
TEST_CASE("MULH", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MULH(x31, x15, x20);
|
||||
REQUIRE(value == 0x03479FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULH(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA1FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULH(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FF9A33);
|
||||
}
|
||||
|
||||
TEST_CASE("MULW", "[rv64m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.MULW(x31, x15, x20);
|
||||
REQUIRE(value == 0x03478FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULW(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA0FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULW(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FF8A3B);
|
||||
}
|
||||
|
||||
TEST_CASE("MULHSU", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MULHSU(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347AFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULHSU(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA2FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULHSU(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFAA33);
|
||||
}
|
||||
|
||||
TEST_CASE("MULHU", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.MULHU(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347BFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULHU(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA3FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.MULHU(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFBA33);
|
||||
}
|
||||
|
||||
TEST_CASE("REM", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.REM(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347EFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REM(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA6FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REM(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFEA33);
|
||||
}
|
||||
|
||||
TEST_CASE("REMW", "[rv64m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.REMW(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347EFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMW(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA6FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMW(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFEA3B);
|
||||
}
|
||||
|
||||
TEST_CASE("REMU", "[rv32m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.REMU(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347FFB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMU(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA7FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMU(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFFA33);
|
||||
}
|
||||
|
||||
TEST_CASE("REMUW", "[rv64m]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.REMUW(x31, x15, x20);
|
||||
REQUIRE(value == 0x0347FFBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMUW(x31, x20, x15);
|
||||
REQUIRE(value == 0x02FA7FBB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.REMUW(x20, x31, x15);
|
||||
REQUIRE(value == 0x02FFFA3B);
|
||||
}
|
||||
538
externals/biscuit/tests/src/assembler_rvq_tests.cpp
vendored
538
externals/biscuit/tests/src/assembler_rvq_tests.cpp
vendored
@@ -1,538 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("FADD.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FADD_Q(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x07A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FADD_Q(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x07A3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FADD_Q(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x07A3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCLASS.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCLASS_Q(x31, f7);
|
||||
REQUIRE(value == 0xE6039FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCLASS_Q(x7, f31);
|
||||
REQUIRE(value == 0xE60F93D3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.D", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_Q_D(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x46138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_D(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4613CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_D(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4613FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.S", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_Q_S(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x46038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_S(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4603CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_S(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4603FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.W", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_Q_W(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD6038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_W(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD603CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_W(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD603FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.WU", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_Q_WU(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD6138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_WU(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD613CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_WU(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD613FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.L.Q", "[rv64q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_L_Q(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC6238FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_L_Q(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC623CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_L_Q(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC623FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.LU.Q", "[rv64q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_LU_Q(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC6338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_LU_Q(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC633CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_LU_Q(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC633FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.L", "[rv64q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_Q_L(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD6238FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_L(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD623CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_L(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD623FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.Q.LU", "[rv64q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVT_Q_LU(f31, x7, RMode::RNE);
|
||||
REQUIRE(value == 0xD6338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_LU(f31, x7, RMode::RMM);
|
||||
REQUIRE(value == 0xD633CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_Q_LU(f31, x7, RMode::DYN);
|
||||
REQUIRE(value == 0xD633FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.W.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_W_Q(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC6038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_W_Q(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC603CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_W_Q(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC603FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.WU.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_WU_Q(x31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0xC6138FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_WU_Q(x31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0xC613CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_WU_Q(x31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0xC613FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.D.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_D_Q(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x42338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_Q(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4233CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_D_Q(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4233FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVT.S.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FCVT_S_Q(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x40338FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_Q(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4033CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FCVT_S_Q(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4033FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FDIV.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FDIV_Q(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x1FA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FDIV_Q(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x1FA3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FDIV_Q(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x1FA3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FEQ.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FEQ_Q(x31, f7, f26);
|
||||
REQUIRE(value == 0xA7A3AFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FEQ_Q(x31, f26, f7);
|
||||
REQUIRE(value == 0xA67D2FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLE.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLE_Q(x31, f7, f26);
|
||||
REQUIRE(value == 0xA7A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLE_Q(x31, f26, f7);
|
||||
REQUIRE(value == 0xA67D0FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLT.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLT_Q(x31, f7, f26);
|
||||
REQUIRE(value == 0xA7A39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLT_Q(x31, f26, f7);
|
||||
REQUIRE(value == 0xA67D1FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLQ", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FLQ(f15, 1024, x31);
|
||||
REQUIRE(value == 0x400FC787);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLQ(f15, 1536, x31);
|
||||
REQUIRE(value == 0x600FC787);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FLQ(f15, -1, x31);
|
||||
REQUIRE(value == 0xFFFFC787);
|
||||
}
|
||||
|
||||
TEST_CASE("FMADD.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMADD_Q(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD67F87C3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMADD_Q(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD67FC7C3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMADD_Q(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD67FF7C3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAX.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMAX_Q(f31, f7, f26);
|
||||
REQUIRE(value == 0x2FA39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMAX_Q(f31, f31, f31);
|
||||
REQUIRE(value == 0x2FFF9FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMIN.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMIN_Q(f31, f7, f26);
|
||||
REQUIRE(value == 0x2FA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMIN_Q(f31, f31, f31);
|
||||
REQUIRE(value == 0x2FFF8FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMSUB.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMSUB_Q(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD67F87C7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMSUB_Q(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD67FC7C7);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMSUB_Q(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD67FF7C7);
|
||||
}
|
||||
|
||||
TEST_CASE("FMUL.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMUL_Q(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x17A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMUL_Q(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x17A3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FMUL_Q(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x17A3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FNMADD.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FNMADD_Q(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD67F87CF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMADD_Q(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD67FC7CF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMADD_Q(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD67FF7CF);
|
||||
}
|
||||
|
||||
TEST_CASE("FNMSUB.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FNMSUB_Q(f15, f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0xD67F87CB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMSUB_Q(f15, f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0xD67FC7CB);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FNMSUB_Q(f15, f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0xD67FF7CB);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJ.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJ_Q(f31, f7, f26);
|
||||
REQUIRE(value == 0x27A38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJ_Q(f31, f31, f31);
|
||||
REQUIRE(value == 0x27FF8FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJN.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJN_Q(f31, f7, f26);
|
||||
REQUIRE(value == 0x27A39FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJN_Q(f31, f31, f31);
|
||||
REQUIRE(value == 0x27FF9FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSGNJX.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSGNJX_Q(f31, f7, f26);
|
||||
REQUIRE(value == 0x27A3AFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSGNJX_Q(f31, f31, f31);
|
||||
REQUIRE(value == 0x27FFAFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSQRT.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSQRT_Q(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x5E038FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQRT_Q(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x5E03CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQRT_Q(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x5E03FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSUB.Q", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSUB_Q(f31, f7, f26, RMode::RNE);
|
||||
REQUIRE(value == 0x0FA38FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSUB_Q(f31, f7, f26, RMode::RMM);
|
||||
REQUIRE(value == 0x0FA3CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSUB_Q(f31, f7, f26, RMode::DYN);
|
||||
REQUIRE(value == 0x0FA3FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FSQ", "[rv32q]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FSQ(f31, 1024, x15);
|
||||
REQUIRE(value == 0x41F7C027);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQ(f31, 1536, x15);
|
||||
REQUIRE(value == 0x61F7C027);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FSQ(f31, -1, x15);
|
||||
REQUIRE(value == 0xFFF7CFA7);
|
||||
}
|
||||
5334
externals/biscuit/tests/src/assembler_rvv_tests.cpp
vendored
5334
externals/biscuit/tests/src/assembler_rvv_tests.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace biscuit {
|
||||
|
||||
template <typename T>
|
||||
inline Assembler MakeAssembler32(T& buffer) {
|
||||
return Assembler{reinterpret_cast<uint8_t*>(&buffer), sizeof(buffer), ArchFeature::RV32};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Assembler MakeAssembler64(T& buffer) {
|
||||
return Assembler{reinterpret_cast<uint8_t*>(&buffer), sizeof(buffer), ArchFeature::RV64};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Assembler MakeAssembler128(T& buffer) {
|
||||
return Assembler{reinterpret_cast<uint8_t*>(&buffer), sizeof(buffer), ArchFeature::RV128};
|
||||
}
|
||||
|
||||
} // namespace biscuit
|
||||
@@ -1,495 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("VANDN.VV", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VANDN(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0x04C50A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VANDN(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0x06C50A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VANDN.VX", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VANDN(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0x04C54A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VANDN(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0x06C54A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VBREV.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VBREV(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C52A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VBREV(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC52A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VBREV8.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VBREV8(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C42A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VBREV8(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC42A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VREV8.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VREV8(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C4AA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VREV8(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC4AA57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCLZ.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCLZ(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C62A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCLZ(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC62A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCTZ.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCTZ(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C6AA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCTZ(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC6AA57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCPOP.V", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCPOP(v20, v12, VecMask::Yes);
|
||||
REQUIRE(value == 0x48C72A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCPOP(v20, v12, VecMask::No);
|
||||
REQUIRE(value == 0x4AC72A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VROL.VV", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VROL(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0x54C50A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROL(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0x56C50A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VROL.VX", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VROL(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0x54C54A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROL(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0x56C54A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VROR.VV", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VROR(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0x50C50A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROR(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0x52C50A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VROR.VX", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VROR(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0x50C54A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROR(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0x52C54A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VROR.VI", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VROR(v20, v12, 63, VecMask::Yes);
|
||||
REQUIRE(value == 0x54CFBA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROR(v20, v12, 31, VecMask::Yes);
|
||||
REQUIRE(value == 0x50CFBA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROR(v20, v12, 63, VecMask::No);
|
||||
REQUIRE(value == 0x56CFBA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VROR(v20, v12, 31, VecMask::No);
|
||||
REQUIRE(value == 0x52CFBA57);
|
||||
}
|
||||
|
||||
TEST_CASE("VWSLL.VV", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VWSLL(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0xD4C50A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VWSLL(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0xD6C50A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VWSLL.VX", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VWSLL(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0xD4C54A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VWSLL(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0xD6C54A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VWSLL.VI", "[Zvbb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VWSLL(v20, v12, 31, VecMask::Yes);
|
||||
REQUIRE(value == 0xD4CFBA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VWSLL(v20, v12, 15, VecMask::Yes);
|
||||
REQUIRE(value == 0xD4C7BA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VWSLL(v20, v12, 31, VecMask::No);
|
||||
REQUIRE(value == 0xD6CFBA57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VWSLL(v20, v12, 15, VecMask::No);
|
||||
REQUIRE(value == 0xD6C7BA57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCLMUL.VV", "[Zvbc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCLMUL(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0x30C52A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCLMUL(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0x32C52A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCLMUL.VX", "[Zvbc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCLMUL(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0x30C56A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCLMUL(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0x32C56A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCLMULH.VV", "[Zvbc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCLMULH(v20, v12, v10, VecMask::Yes);
|
||||
REQUIRE(value == 0x34C52A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCLMULH(v20, v12, v10, VecMask::No);
|
||||
REQUIRE(value == 0x36C52A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VCLMULH.VX", "[Zvbc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VCLMULH(v20, v12, x10, VecMask::Yes);
|
||||
REQUIRE(value == 0x34C56A57);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.VCLMULH(v20, v12, x10, VecMask::No);
|
||||
REQUIRE(value == 0x36C56A57);
|
||||
}
|
||||
|
||||
TEST_CASE("VGHSH.VV", "[Zvkg]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VGHSH(v20, v12, v10);
|
||||
REQUIRE(value == 0xB2C52A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VGMUL.VV", "[Zvkg]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VGMUL(v20, v12);
|
||||
REQUIRE(value == 0xA2C8AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESDF.VV", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESDF_VV(v20, v12);
|
||||
REQUIRE(value == 0xA2C0AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESDF.VS", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESDF_VS(v20, v12);
|
||||
REQUIRE(value == 0xA6C0AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESDM.VV", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESDM_VV(v20, v12);
|
||||
REQUIRE(value == 0xA2C02A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESDM.VS", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESDM_VS(v20, v12);
|
||||
REQUIRE(value == 0xA6C02A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESEF.VV", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESEF_VV(v20, v12);
|
||||
REQUIRE(value == 0xA2C1AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESEF.VS", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESEF_VS(v20, v12);
|
||||
REQUIRE(value == 0xA6C1AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESEM.VV", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESEM_VV(v20, v12);
|
||||
REQUIRE(value == 0xA2C12A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESEM.VS", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESEM_VS(v20, v12);
|
||||
REQUIRE(value == 0xA6C12A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESKF1.VI", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
// Test mapping of out of range indices
|
||||
for (const uint32_t idx : {0U, 11U, 12U, 13U, 14U, 15U}) {
|
||||
as.VAESKF1(v20, v12, idx);
|
||||
|
||||
const auto op_base = 0x8AC02A77U;
|
||||
const auto inverted_b3 = idx ^ 0b1000;
|
||||
const auto verify = op_base | (inverted_b3 << 15);
|
||||
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
as.VAESKF1(v20, v12, 8);
|
||||
REQUIRE(value == 0x8AC42A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESKF2.VI", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
// Test mapping of out of range indices
|
||||
for (const uint32_t idx : {0U, 1U, 15U}) {
|
||||
as.VAESKF2(v20, v12, idx);
|
||||
|
||||
const auto op_base = 0xAAC02A77;
|
||||
const auto inverted_b3 = idx ^ 0b1000;
|
||||
const auto verify = op_base | (inverted_b3 << 15);
|
||||
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
as.VAESKF2(v20, v12, 8);
|
||||
REQUIRE(value == 0xAAC42A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VAESZ.VS", "[Zvkned]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VAESZ(v20, v12);
|
||||
REQUIRE(value == 0xA6C3AA77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSHA2MS.VV", "[Zvknhb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSHA2MS(v20, v12, v10);
|
||||
REQUIRE(value == 0xB6C52A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSHA2CH.VV", "[Zvknhb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSHA2CH(v20, v12, v10);
|
||||
REQUIRE(value == 0xBAC52A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSHA2CL.VV", "[Zvknhb]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSHA2CL(v20, v12, v10);
|
||||
REQUIRE(value == 0xBEC52A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSM4K.VI", "[Zvksed]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (uint32_t i = 0; i <= 7; i++) {
|
||||
as.VSM4K(v20, v12, i);
|
||||
|
||||
const auto op_base = 0x86C02A77U;
|
||||
const auto verify = op_base | (i << 15);
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("VSM4R.VV", "[Zvksed]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSM4R_VV(v20, v12);
|
||||
REQUIRE(value == 0xA2C82A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSM4R.VS", "[Zvksed]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSM4R_VS(v20, v12);
|
||||
REQUIRE(value == 0xA6C82A77);
|
||||
}
|
||||
|
||||
TEST_CASE("VSM3C.VI", "[Zvksh]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (uint32_t i = 0; i <= 31; i++) {
|
||||
as.VSM3C(v20, v12, i);
|
||||
|
||||
const auto op_base = 0xAEC02A77U;
|
||||
const auto verify = op_base | (i << 15);
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("VSM3ME.VV", "[Zvksh]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.VSM3ME(v20, v12, v10);
|
||||
REQUIRE(value == 0x82C52A77);
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("AMOCAS.D", "[Zacas]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOCAS_D(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x2877BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_D(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x2C77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_D(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2A77BFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_D(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2E77BFAF);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOCAS.Q", "[Zacas]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOCAS_Q(Ordering::None, x30, x6, x14);
|
||||
REQUIRE(value == 0x28674F2F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_Q(Ordering::AQ, x30, x6, x14);
|
||||
REQUIRE(value == 0x2C674F2F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_Q(Ordering::RL, x30, x6, x14);
|
||||
REQUIRE(value == 0x2A674F2F);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_Q(Ordering::AQRL, x30, x6, x14);
|
||||
REQUIRE(value == 0x2E674F2F);
|
||||
}
|
||||
|
||||
TEST_CASE("AMOCAS.W", "[Zacas]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.AMOCAS_W(Ordering::None, x31, x7, x15);
|
||||
REQUIRE(value == 0x2877AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_W(Ordering::AQ, x31, x7, x15);
|
||||
REQUIRE(value == 0x2C77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_W(Ordering::RL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2A77AFAF);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.AMOCAS_W(Ordering::AQRL, x31, x7, x15);
|
||||
REQUIRE(value == 0x2E77AFAF);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("WRS.NTO", "[Zawrs]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.WRS_NTO();
|
||||
REQUIRE(value == 0x00D00073);
|
||||
}
|
||||
|
||||
TEST_CASE("WRS.STO", "[Zawrs]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.WRS_STO();
|
||||
REQUIRE(value == 0x01D00073);
|
||||
}
|
||||
457
externals/biscuit/tests/src/assembler_zc_tests.cpp
vendored
457
externals/biscuit/tests/src/assembler_zc_tests.cpp
vendored
@@ -1,457 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("C.LBU", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_LBU(x12, 0, x15);
|
||||
REQUIRE(value == 0x8390U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LBU(x12, 1, x15);
|
||||
REQUIRE(value == 0x83D0U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LBU(x12, 2, x15);
|
||||
REQUIRE(value == 0x83B0U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LBU(x12, 3, x15);
|
||||
REQUIRE(value == 0x83F0U);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LH", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_LH(x12, 0, x15);
|
||||
REQUIRE(value == 0x87D0U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LH(x12, 2, x15);
|
||||
REQUIRE(value == 0x87F0U);
|
||||
}
|
||||
|
||||
TEST_CASE("C.LHU", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_LHU(x12, 0, x15);
|
||||
REQUIRE(value == 0x8790U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_LHU(x12, 2, x15);
|
||||
REQUIRE(value == 0x87B0U);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SB", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SB(x12, 0, x15);
|
||||
REQUIRE(value == 0x8B90U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SB(x12, 1, x15);
|
||||
REQUIRE(value == 0x8BD0U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SB(x12, 2, x15);
|
||||
REQUIRE(value == 0x8BB0U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SB(x12, 3, x15);
|
||||
REQUIRE(value == 0x8BF0U);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SH", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SH(x12, 0, x15);
|
||||
REQUIRE(value == 0x8F90U);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SH(x12, 2, x15);
|
||||
REQUIRE(value == 0x8FB0U);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SEXT.B", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SEXT_B(x12);
|
||||
REQUIRE(value == 0x9E65);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SEXT_B(x15);
|
||||
REQUIRE(value == 0x9FE5);
|
||||
}
|
||||
|
||||
TEST_CASE("C.SEXT.H", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_SEXT_H(x12);
|
||||
REQUIRE(value == 0x9E6D);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_SEXT_H(x15);
|
||||
REQUIRE(value == 0x9FED);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ZEXT.B", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_ZEXT_B(x12);
|
||||
REQUIRE(value == 0x9E61);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ZEXT_B(x15);
|
||||
REQUIRE(value == 0x9FE1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ZEXT.H", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_ZEXT_H(x12);
|
||||
REQUIRE(value == 0x9E69);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ZEXT_H(x15);
|
||||
REQUIRE(value == 0x9FE9);
|
||||
}
|
||||
|
||||
TEST_CASE("C.ZEXT.W", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_ZEXT_W(x12);
|
||||
REQUIRE(value == 0x9E71);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_ZEXT_W(x15);
|
||||
REQUIRE(value == 0x9FF1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.MUL", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_MUL(x12, x15);
|
||||
REQUIRE(value == 0x9E5D);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_MUL(x15, x12);
|
||||
REQUIRE(value == 0x9FD1);
|
||||
}
|
||||
|
||||
TEST_CASE("C.NOT", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_NOT(x12);
|
||||
REQUIRE(value == 0x9E75);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.C_NOT(x15);
|
||||
REQUIRE(value == 0x9FF5);
|
||||
}
|
||||
|
||||
TEST_CASE("CM.MVA01S", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_MVA01S(s7, s6);
|
||||
REQUIRE(value == 0xAFFA);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CM_MVA01S(s3, s4);
|
||||
REQUIRE(value == 0xADF2);
|
||||
}
|
||||
|
||||
TEST_CASE("CM.MVSA01", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_MVSA01(s7, s6);
|
||||
REQUIRE(value == 0xAFBA);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CM_MVSA01(s3, s4);
|
||||
REQUIRE(value == 0xADB2);
|
||||
}
|
||||
|
||||
TEST_CASE("CM.JALT", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (uint32_t i = 32; i <= 255; i++) {
|
||||
const uint32_t op_base = 0xA002;
|
||||
const uint32_t op = op_base | (i << 2);
|
||||
|
||||
as.CM_JALT(i);
|
||||
REQUIRE(value == op);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.JT", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (uint32_t i = 0; i <= 31; i++) {
|
||||
const uint32_t op_base = 0xA002;
|
||||
const uint32_t op = op_base | (i << 2);
|
||||
|
||||
as.CM_JT(i);
|
||||
REQUIRE(value == op);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array stack_adj_bases_rv32{
|
||||
0, 0, 0, 0, 16, 16, 16, 16,
|
||||
32, 32, 32, 32, 48, 48, 48, 64,
|
||||
};
|
||||
constexpr std::array stack_adj_bases_rv64{
|
||||
0, 0, 0, 0, 16, 16, 32, 32,
|
||||
48, 48, 64, 64, 80, 80, 96, 112,
|
||||
};
|
||||
|
||||
TEST_CASE("CM.POP", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_POP({ra}, 16);
|
||||
REQUIRE(value == 0xBA42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBA02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv64[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POP({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.POP (RV32)", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CM_POP({ra}, 16);
|
||||
REQUIRE(value == 0xBA42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBA02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv32[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POP({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.POPRET", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_POPRET({ra}, 16);
|
||||
REQUIRE(value == 0xBE42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBE02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv64[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POPRET({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.POPRET (RV32)", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CM_POPRET({ra}, 16);
|
||||
REQUIRE(value == 0xBE42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBE02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv32[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POPRET({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.POPRETZ", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_POPRETZ({ra}, 16);
|
||||
REQUIRE(value == 0xBC42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBC02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv64[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POPRETZ({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.POPRETZ (RV32)", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CM_POPRETZ({ra}, 16);
|
||||
REQUIRE(value == 0xBC42);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xBC02U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv32[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_POPRETZ({ra, {s0, sreg}}, stack_adj_base + (16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.PUSH", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CM_PUSH({ra}, -16);
|
||||
REQUIRE(value == 0xB842);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xB802U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv64[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_PUSH({ra, {s0, sreg}}, -stack_adj_base + (-16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CM.PUSH (RV32)", "[Zc]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.CM_PUSH({ra}, -16);
|
||||
REQUIRE(value == 0xB842);
|
||||
as.RewindBuffer();
|
||||
|
||||
// s10 intentionally omitted, since no direct encoding for it exists.
|
||||
uint32_t rlist = 5;
|
||||
for (const GPR sreg : {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s11}) {
|
||||
const auto op_base = 0xB802U;
|
||||
const auto stack_adj_base = stack_adj_bases_rv32[rlist];
|
||||
|
||||
for (int32_t i = 0; i <= 3; i++) {
|
||||
const auto op = op_base | (rlist << 4) | uint32_t(i) << 2;
|
||||
|
||||
as.CM_PUSH({ra, {s0, sreg}}, -stack_adj_base + (-16 * i));
|
||||
REQUIRE(value == op);
|
||||
as.RewindBuffer();
|
||||
}
|
||||
|
||||
rlist++;
|
||||
}
|
||||
}
|
||||
414
externals/biscuit/tests/src/assembler_zfa_tests.cpp
vendored
414
externals/biscuit/tests/src/assembler_zfa_tests.cpp
vendored
@@ -1,414 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
static constexpr std::array fli_constants{
|
||||
0xBFF0000000000000ULL, // -1.0
|
||||
0x0010000000000000ULL, // Minimum positive normal
|
||||
0x3EF0000000000000ULL, // 1.0 * 2^-16
|
||||
0x3F00000000000000ULL, // 1.0 * 2^-15
|
||||
0x3F70000000000000ULL, // 1.0 * 2^-8
|
||||
0x3F80000000000000ULL, // 1.0 * 2^-7
|
||||
0x3FB0000000000000ULL, // 1.0 * 2^-4
|
||||
0x3FC0000000000000ULL, // 1.0 * 2^-3
|
||||
0x3FD0000000000000ULL, // 0.25
|
||||
0x3FD4000000000000ULL, // 0.3125
|
||||
0x3FD8000000000000ULL, // 0.375
|
||||
0x3FDC000000000000ULL, // 0.4375
|
||||
0x3FE0000000000000ULL, // 0.5
|
||||
0x3FE4000000000000ULL, // 0.625
|
||||
0x3FE8000000000000ULL, // 0.75
|
||||
0x3FEC000000000000ULL, // 0.875
|
||||
0x3FF0000000000000ULL, // 1.0
|
||||
0x3FF4000000000000ULL, // 1.25
|
||||
0x3FF8000000000000ULL, // 1.5
|
||||
0x3FFC000000000000ULL, // 1.75
|
||||
0x4000000000000000ULL, // 2.0
|
||||
0x4004000000000000ULL, // 2.5
|
||||
0x4008000000000000ULL, // 3
|
||||
0x4010000000000000ULL, // 4
|
||||
0x4020000000000000ULL, // 8
|
||||
0x4030000000000000ULL, // 16
|
||||
0x4060000000000000ULL, // 2^7
|
||||
0x4070000000000000ULL, // 2^8
|
||||
0x40E0000000000000ULL, // 2^15
|
||||
0x40F0000000000000ULL, // 2^16
|
||||
0x7FF0000000000000ULL, // +inf
|
||||
0x7FF8000000000000ULL, // Canonical NaN
|
||||
};
|
||||
|
||||
TEST_CASE("FLI.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (size_t i = 0; i < fli_constants.size(); i++) {
|
||||
const auto constant = fli_constants[i];
|
||||
double fconstant{};
|
||||
std::memcpy(&fconstant, &constant, sizeof(fconstant));
|
||||
|
||||
as.FLI_D(f10, fconstant);
|
||||
|
||||
const auto op_base = 0xF2100553;
|
||||
const auto verify = op_base | (i << 15);
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FLI.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (size_t i = 0; i < fli_constants.size(); i++) {
|
||||
const auto constant = fli_constants[i];
|
||||
double fconstant{};
|
||||
std::memcpy(&fconstant, &constant, sizeof(fconstant));
|
||||
|
||||
as.FLI_H(f10, fconstant);
|
||||
|
||||
const auto op_base = 0xF4100553;
|
||||
const auto verify = op_base | (i << 15);
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FLI.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
for (size_t i = 0; i < fli_constants.size(); i++) {
|
||||
const auto constant = fli_constants[i];
|
||||
double fconstant{};
|
||||
std::memcpy(&fconstant, &constant, sizeof(fconstant));
|
||||
|
||||
as.FLI_S(f10, fconstant);
|
||||
|
||||
const auto op_base = 0xF0100553;
|
||||
const auto verify = op_base | (i << 15);
|
||||
REQUIRE(value == verify);
|
||||
|
||||
as.RewindBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FMINM.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMINM_D(f20, f12, f10);
|
||||
REQUIRE(value == 0x2AA62A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMINM.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMINM_H(f20, f12, f10);
|
||||
REQUIRE(value == 0x2CA62A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMINM.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMINM_Q(f20, f12, f10);
|
||||
REQUIRE(value == 0x2EA62A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMINM.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMINM_S(f20, f12, f10);
|
||||
REQUIRE(value == 0x28A62A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAXM.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMAXM_D(f20, f12, f10);
|
||||
REQUIRE(value == 0x2AA63A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAXM.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMAXM_H(f20, f12, f10);
|
||||
REQUIRE(value == 0x2CA63A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAXM.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMAXM_Q(f20, f12, f10);
|
||||
REQUIRE(value == 0x2EA63A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FMAXM.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMAXM_S(f20, f12, f10);
|
||||
REQUIRE(value == 0x28A63A53);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUND.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUND_D(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x42438FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_D(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4243CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_D(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4243FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUND.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUND_H(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x44438FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_H(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4443CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_H(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4443FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUND.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUND_Q(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x46438FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_Q(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4643CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_Q(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4643FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUND.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUND_S(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x40438FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_S(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4043CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUND_S(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4043FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUNDNX.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUNDNX_D(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x42538FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_D(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4253CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_D(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4253FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUNDNX.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUNDNX_H(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x44538FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_H(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4453CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_H(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4453FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUNDNX.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUNDNX_Q(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x46538FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_Q(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4653CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_Q(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4653FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FROUNDNX.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FROUNDNX_S(f31, f7, RMode::RNE);
|
||||
REQUIRE(value == 0x40538FD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_S(f31, f7, RMode::RMM);
|
||||
REQUIRE(value == 0x4053CFD3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.FROUNDNX_S(f31, f7, RMode::DYN);
|
||||
REQUIRE(value == 0x4053FFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FCVTMOD.W.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FCVTMOD_W_D(x31, f7);
|
||||
REQUIRE(value == 0xC2839FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMVH.X.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMVH_X_D(x31, f7);
|
||||
REQUIRE(value == 0xE2138FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMVH.X.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMVH_X_Q(x31, f7);
|
||||
REQUIRE(value == 0xE6138FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMVP.D.X", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler32(value);
|
||||
|
||||
as.FMVP_D_X(f31, x7, x8);
|
||||
REQUIRE(value == 0xB2838FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FMVP.Q.X", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FMVP_Q_X(f31, x7, x8);
|
||||
REQUIRE(value == 0xB6838FD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLEQ.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLEQ_D(x31, f7, f15);
|
||||
REQUIRE(value == 0xA2F3CFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLTQ.D", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLTQ_D(x31, f7, f15);
|
||||
REQUIRE(value == 0xA2F3DFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLEQ.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLEQ_H(x31, f7, f15);
|
||||
REQUIRE(value == 0xA4F3CFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLTQ.H", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLTQ_H(x31, f7, f15);
|
||||
REQUIRE(value == 0xA4F3DFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLEQ.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLEQ_Q(x31, f7, f15);
|
||||
REQUIRE(value == 0xA6F3CFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLTQ.Q", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLTQ_Q(x31, f7, f15);
|
||||
REQUIRE(value == 0xA6F3DFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLEQ.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLEQ_S(x31, f7, f15);
|
||||
REQUIRE(value == 0xA0F3CFD3);
|
||||
}
|
||||
|
||||
TEST_CASE("FLTQ.S", "[Zfa]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.FLTQ_S(x31, f7, f15);
|
||||
REQUIRE(value == 0xA0F3DFD3);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("CZERO.EQZ", "[Zicond]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CZERO_EQZ(x31, x30, x29);
|
||||
REQUIRE(value == 0x0FDF5FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CZERO_EQZ(x1, x2, x3);
|
||||
REQUIRE(value == 0x0E3150B3);
|
||||
}
|
||||
|
||||
TEST_CASE("CZERO.NEZ", "[Zicond]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CZERO_NEZ(x31, x30, x29);
|
||||
REQUIRE(value == 0x0FDF7FB3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CZERO_NEZ(x1, x2, x3);
|
||||
REQUIRE(value == 0x0E3170B3);
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("CSRRC", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRC(x31, CSR::Cycle, x15);
|
||||
REQUIRE(value == 0xC007BFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRC(x31, CSR::FFlags, x15);
|
||||
REQUIRE(value == 0x0017BFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRC(x31, CSR::FRM, x15);
|
||||
REQUIRE(value == 0x0027BFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRC(x31, CSR::FCSR, x15);
|
||||
REQUIRE(value == 0x0037BFF3);
|
||||
}
|
||||
|
||||
TEST_CASE("CSRRCI", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRCI(x31, CSR::Cycle, 0);
|
||||
REQUIRE(value == 0xC0007FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRCI(x31, CSR::FFlags, 0x1F);
|
||||
REQUIRE(value == 0x001FFFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRCI(x31, CSR::FRM, 0x7);
|
||||
REQUIRE(value == 0x0023FFF3);
|
||||
}
|
||||
|
||||
TEST_CASE("CSRRS", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRS(x31, CSR::Cycle, x15);
|
||||
REQUIRE(value == 0xC007AFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRS(x31, CSR::FFlags, x15);
|
||||
REQUIRE(value == 0x0017AFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRS(x31, CSR::FRM, x15);
|
||||
REQUIRE(value == 0x0027AFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRS(x31, CSR::FCSR, x15);
|
||||
REQUIRE(value == 0x0037AFF3);
|
||||
}
|
||||
|
||||
TEST_CASE("CSRRSI", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRSI(x31, CSR::Cycle, 0);
|
||||
REQUIRE(value == 0xC0006FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRSI(x31, CSR::FFlags, 0x1F);
|
||||
REQUIRE(value == 0x001FEFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRSI(x31, CSR::FRM, 0x7);
|
||||
REQUIRE(value == 0x0023EFF3);
|
||||
}
|
||||
|
||||
TEST_CASE("CSRRW", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRW(x31, CSR::Cycle, x15);
|
||||
REQUIRE(value == 0xC0079FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRW(x31, CSR::FFlags, x15);
|
||||
REQUIRE(value == 0x00179FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRW(x31, CSR::FRM, x15);
|
||||
REQUIRE(value == 0x00279FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRW(x31, CSR::FCSR, x15);
|
||||
REQUIRE(value == 0x00379FF3);
|
||||
}
|
||||
|
||||
TEST_CASE("CSRRWI", "[Zicsr]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.CSRRWI(x31, CSR::Cycle, 0);
|
||||
REQUIRE(value == 0xC0005FF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRWI(x31, CSR::FFlags, 0x1F);
|
||||
REQUIRE(value == 0x001FDFF3);
|
||||
|
||||
as.RewindBuffer();
|
||||
|
||||
as.CSRRWI(x31, CSR::FRM, 0x7);
|
||||
REQUIRE(value == 0x0023DFF3);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <biscuit/assembler.hpp>
|
||||
|
||||
#include "assembler_test_utils.hpp"
|
||||
|
||||
using namespace biscuit;
|
||||
|
||||
TEST_CASE("C.NTL.ALL", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_NTL_ALL();
|
||||
REQUIRE(value == 0x9016);
|
||||
}
|
||||
|
||||
TEST_CASE("C.NTL.S1", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_NTL_S1();
|
||||
REQUIRE(value == 0x9012);
|
||||
}
|
||||
|
||||
TEST_CASE("C.NTL.P1", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_NTL_P1();
|
||||
REQUIRE(value == 0x900A);
|
||||
}
|
||||
|
||||
TEST_CASE("C.NTL.PALL", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.C_NTL_PALL();
|
||||
REQUIRE(value == 0x900E);
|
||||
}
|
||||
|
||||
TEST_CASE("NTL.ALL", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.NTL_ALL();
|
||||
REQUIRE(value == 0x00500033);
|
||||
}
|
||||
|
||||
TEST_CASE("NTL.S1", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.NTL_S1();
|
||||
REQUIRE(value == 0x00400033);
|
||||
}
|
||||
|
||||
TEST_CASE("NTL.P1", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.NTL_P1();
|
||||
REQUIRE(value == 0x00200033);
|
||||
}
|
||||
|
||||
TEST_CASE("NTL.PALL", "[Zihintntl]") {
|
||||
uint32_t value = 0;
|
||||
auto as = MakeAssembler64(value);
|
||||
|
||||
as.NTL_PALL();
|
||||
REQUIRE(value == 0x00300033);
|
||||
}
|
||||
2
externals/biscuit/tests/src/main.cpp
vendored
2
externals/biscuit/tests/src/main.cpp
vendored
@@ -1,2 +0,0 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch/catch.hpp>
|
||||
1
externals/catch
vendored
Submodule
1
externals/catch
vendored
Submodule
Submodule externals/catch added at 76f70b1403
10
externals/catch/.bazelrc
vendored
10
externals/catch/.bazelrc
vendored
@@ -1,10 +0,0 @@
|
||||
build --enable_platform_specific_config
|
||||
|
||||
build:gcc9 --cxxopt=-std=c++2a
|
||||
build:gcc11 --cxxopt=-std=c++2a
|
||||
build:clang13 --cxxopt=-std=c++17
|
||||
build:vs2019 --cxxopt=/std:c++17
|
||||
build:vs2022 --cxxopt=/std:c++17
|
||||
|
||||
build:windows --config=vs2022
|
||||
build:linux --config=gcc11
|
||||
45
externals/catch/.clang-format
vendored
45
externals/catch/.clang-format
vendored
@@ -1,45 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
Standard: c++14
|
||||
|
||||
# Note that we cannot use IncludeIsMainRegex functionality, because it
|
||||
# does not support includes in angle brackets (<>)
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: <catch2/.*\.hpp>
|
||||
Priority: 1
|
||||
- Regex: <.*/.*\.hpp>
|
||||
Priority: 2
|
||||
- Regex: <.*>
|
||||
Priority: 3
|
||||
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
|
||||
AccessModifierOffset: "-4"
|
||||
AlignEscapedNewlines: Left
|
||||
AllowAllConstructorInitializersOnNextLine: "true"
|
||||
BinPackArguments: "false"
|
||||
BinPackParameters: "false"
|
||||
BreakConstructorInitializers: AfterColon
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: "true"
|
||||
DerivePointerAlignment: "false"
|
||||
FixNamespaceComments: "true"
|
||||
IndentCaseLabels: "false"
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: "4"
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
SpaceBeforeCtorInitializerColon: "false"
|
||||
SpaceInEmptyParentheses: "false"
|
||||
SpacesInParentheses: "true"
|
||||
TabWidth: "4"
|
||||
UseTab: Never
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SortUsingDeclarations: true
|
||||
ReflowComments: true
|
||||
94
externals/catch/.conan/build.py
vendored
94
externals/catch/.conan/build.py
vendored
@@ -1,94 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import re
|
||||
from cpt.packager import ConanMultiPackager
|
||||
from cpt.ci_manager import CIManager
|
||||
from cpt.printer import Printer
|
||||
|
||||
|
||||
class BuilderSettings(object):
|
||||
@property
|
||||
def username(self):
|
||||
""" Set catchorg as package's owner
|
||||
"""
|
||||
return os.getenv("CONAN_USERNAME", "catchorg")
|
||||
|
||||
@property
|
||||
def login_username(self):
|
||||
""" Set Bintray login username
|
||||
"""
|
||||
return os.getenv("CONAN_LOGIN_USERNAME", "horenmar")
|
||||
|
||||
@property
|
||||
def upload(self):
|
||||
""" Set Catch2 repository to be used on upload.
|
||||
The upload server address could be customized by env var
|
||||
CONAN_UPLOAD. If not defined, the method will check the branch name.
|
||||
Only devel or CONAN_STABLE_BRANCH_PATTERN will be accepted.
|
||||
The devel branch will be pushed to testing channel, because it does
|
||||
not match the stable pattern. Otherwise it will upload to stable
|
||||
channel.
|
||||
"""
|
||||
return os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/catchorg/catch2")
|
||||
|
||||
@property
|
||||
def upload_only_when_stable(self):
|
||||
""" Force to upload when running over tag branch
|
||||
"""
|
||||
return os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", "True").lower() in ["true", "1", "yes"]
|
||||
|
||||
@property
|
||||
def stable_branch_pattern(self):
|
||||
""" Only upload the package the branch name is like a tag
|
||||
"""
|
||||
return os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+")
|
||||
|
||||
@property
|
||||
def reference(self):
|
||||
""" Read project version from branch create Conan reference
|
||||
"""
|
||||
return os.getenv("CONAN_REFERENCE", "catch2/{}".format(self._version))
|
||||
|
||||
@property
|
||||
def channel(self):
|
||||
""" Default Conan package channel when not stable
|
||||
"""
|
||||
return os.getenv("CONAN_CHANNEL", "testing")
|
||||
|
||||
@property
|
||||
def _version(self):
|
||||
""" Get version name from cmake file
|
||||
"""
|
||||
pattern = re.compile(r"project\(Catch2 LANGUAGES CXX VERSION (\d+\.\d+\.\d+)\)")
|
||||
version = "latest"
|
||||
with open("CMakeLists.txt") as file:
|
||||
for line in file:
|
||||
result = pattern.search(line)
|
||||
if result:
|
||||
version = result.group(1)
|
||||
return version
|
||||
|
||||
@property
|
||||
def _branch(self):
|
||||
""" Get branch name from CI manager
|
||||
"""
|
||||
printer = Printer(None)
|
||||
ci_manager = CIManager(printer)
|
||||
return ci_manager.get_branch()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
settings = BuilderSettings()
|
||||
builder = ConanMultiPackager(
|
||||
reference=settings.reference,
|
||||
channel=settings.channel,
|
||||
upload=settings.upload,
|
||||
upload_only_when_stable=False,
|
||||
stable_branch_pattern=settings.stable_branch_pattern,
|
||||
login_username=settings.login_username,
|
||||
username=settings.username,
|
||||
test_folder=os.path.join(".conan", "test_package"))
|
||||
builder.add()
|
||||
builder.run()
|
||||
@@ -1,12 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.2.0)
|
||||
project(test_package CXX)
|
||||
|
||||
include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
|
||||
conan_basic_setup()
|
||||
|
||||
find_package(Catch2 REQUIRED CONFIG)
|
||||
|
||||
add_executable(${PROJECT_NAME} test_package.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Catch2::Catch2WithMain)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14)
|
||||
20
externals/catch/.conan/test_package/conanfile.py
vendored
20
externals/catch/.conan/test_package/conanfile.py
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from conans import ConanFile, CMake
|
||||
import os
|
||||
|
||||
|
||||
class TestPackageConan(ConanFile):
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "cmake_find_package_multi", "cmake"
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def test(self):
|
||||
assert os.path.isfile(os.path.join(
|
||||
self.deps_cpp_info["catch2"].rootpath, "licenses", "LICENSE.txt"))
|
||||
bin_path = os.path.join("bin", "test_package")
|
||||
self.run("%s -s" % bin_path, run_environment=True)
|
||||
@@ -1,13 +0,0 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
int Factorial( int number ) {
|
||||
return number <= 1 ? 1 : Factorial( number - 1 ) * number;
|
||||
}
|
||||
|
||||
TEST_CASE( "Factorial Tests", "[single-file]" ) {
|
||||
REQUIRE( Factorial(0) == 1 );
|
||||
REQUIRE( Factorial(1) == 1 );
|
||||
REQUIRE( Factorial(2) == 2 );
|
||||
REQUIRE( Factorial(3) == 6 );
|
||||
REQUIRE( Factorial(10) == 3628800 );
|
||||
}
|
||||
22
externals/catch/.gitattributes
vendored
22
externals/catch/.gitattributes
vendored
@@ -1,22 +0,0 @@
|
||||
# This sets the default behaviour, overriding core.autocrlf
|
||||
* text=auto
|
||||
|
||||
# All source files should have unix line-endings in the repository,
|
||||
# but convert to native line-endings on checkout
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hpp text
|
||||
|
||||
# Windows specific files should retain windows line-endings
|
||||
*.sln text eol=crlf
|
||||
|
||||
# Keep executable scripts with LFs so they can be run after being
|
||||
# checked out on Windows
|
||||
*.py text eol=lf
|
||||
|
||||
|
||||
# Keep the single include header with LFs to make sure it is uploaded,
|
||||
# hashed etc with LF
|
||||
single_include/**/*.hpp eol=lf
|
||||
# Also keep the LICENCE file with LFs for the same reason
|
||||
LICENCE.txt eol=lf
|
||||
2
externals/catch/.github/FUNDING.yml
vendored
2
externals/catch/.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
||||
github: "horenmar"
|
||||
custom: "https://www.paypal.me/horenmar"
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create an issue that documents a bug
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Reproduction steps**
|
||||
Steps to reproduce the bug.
|
||||
<!-- Usually this means a small and self-contained piece of code that uses Catch and specifying compiler flags if relevant. -->
|
||||
|
||||
|
||||
**Platform information:**
|
||||
<!-- Fill in any extra information that might be important for your issue. -->
|
||||
- OS: **Windows NT**
|
||||
- Compiler+version: **GCC v2.9.5**
|
||||
- Catch version: **v1.2.3**
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Create an issue that requests a feature or other improvement
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
Describe the feature/change you request and why do you want it.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
28
externals/catch/.github/pull_request_template.md
vendored
28
externals/catch/.github/pull_request_template.md
vendored
@@ -1,28 +0,0 @@
|
||||
<!--
|
||||
Please do not submit pull requests changing the `version.hpp`
|
||||
or the single-include `catch.hpp` file, these are changed
|
||||
only when a new release is made.
|
||||
|
||||
Before submitting a PR you should probably read the contributor documentation
|
||||
at docs/contributing.md. It will tell you how to properly test your changes.
|
||||
-->
|
||||
|
||||
|
||||
## Description
|
||||
<!--
|
||||
Describe the what and the why of your pull request. Remember that these two
|
||||
are usually a bit different. As an example, if you have made various changes
|
||||
to decrease the number of new strings allocated, that's what. The why probably
|
||||
was that you have a large set of tests and found that this speeds them up.
|
||||
-->
|
||||
|
||||
## GitHub Issues
|
||||
<!--
|
||||
If this PR was motivated by some existing issues, reference them here.
|
||||
|
||||
If it is a simple bug-fix, please also add a line like 'Closes #123'
|
||||
to your commit message, so that it is automatically closed.
|
||||
If it is not, don't, as it might take several iterations for a feature
|
||||
to be done properly. If in doubt, leave it open and reference it in the
|
||||
PR itself, so that maintainers can decide.
|
||||
-->
|
||||
@@ -1,24 +0,0 @@
|
||||
name: Bazel build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build_and_test_ubuntu:
|
||||
name: Linux Ubuntu 22.04 Bazel build <GCC 11.2.0>
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
compilation_mode: [fastbuild, dbg, opt]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Mount bazel cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: "/home/runner/.cache/bazel"
|
||||
key: bazel-ubuntu22-gcc11
|
||||
|
||||
- name: Build Catch2
|
||||
run: |
|
||||
bazelisk build --compilation_mode=${{matrix.compilation_mode}} //...
|
||||
@@ -1,45 +0,0 @@
|
||||
name: Linux builds (meson)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: meson ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}}
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
- g++-11
|
||||
- clang++-11
|
||||
build_type: [debug, release]
|
||||
std: [14, 17]
|
||||
include:
|
||||
- cxx: clang++-11
|
||||
other_pkgs: clang-11
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y meson ninja-build ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure build
|
||||
env:
|
||||
CXX: ${{matrix.cxx}}
|
||||
CXXFLAGS: -std=c++${{matrix.std}} ${{matrix.cxxflags}}
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
meson -Dbuildtype=${{matrix.build_type}} ${{runner.workspace}}/meson-build
|
||||
|
||||
- name: Build tests + lib
|
||||
working-directory: ${{runner.workspace}}/meson-build
|
||||
run: ninja
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ${{runner.workspace}}/meson-build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: |
|
||||
meson test --verbose
|
||||
@@ -1,106 +0,0 @@
|
||||
# The builds in this file are more complex (e.g. they need custom CMake
|
||||
# configuration) and thus are unsuitable to the simple build matrix
|
||||
# approach used in simple-builds
|
||||
name: Linux builds (complex)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{matrix.build_description}}, ${{matrix.cxx}}, C++${{matrix.std}} ${{matrix.build_type}}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
# We add builds one by one in this case, because there are no
|
||||
# dimensions that are shared across the builds
|
||||
include:
|
||||
|
||||
# Single surrogate header build
|
||||
- cxx: clang++-10
|
||||
build_description: Surrogates build
|
||||
build_type: Debug
|
||||
std: 14
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_BUILD_SURROGATES=ON
|
||||
|
||||
# Extras and examples with gcc-7
|
||||
- cxx: g++-7
|
||||
build_description: Extras + Examples
|
||||
build_type: Debug
|
||||
std: 14
|
||||
other_pkgs: g++-7
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
- cxx: g++-7
|
||||
build_description: Extras + Examples
|
||||
build_type: Release
|
||||
std: 14
|
||||
other_pkgs: g++-7
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
|
||||
# Extras and examples with Clang-10
|
||||
- cxx: clang++-10
|
||||
build_description: Extras + Examples
|
||||
build_type: Debug
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
- cxx: clang++-10
|
||||
build_description: Extras + Examples
|
||||
build_type: Release
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
|
||||
# Configure tests with Clang-10
|
||||
- cxx: clang++-10
|
||||
build_description: CMake configuration tests
|
||||
build_type: Debug
|
||||
std: 14
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_ENABLE_CONFIGURE_TESTS=ON
|
||||
|
||||
# Valgrind test Clang-10
|
||||
- cxx: clang++-10
|
||||
build_description: Valgrind tests
|
||||
build_type: Debug
|
||||
std: 14
|
||||
other_pkgs: clang-10 valgrind
|
||||
cmake_configurations: -DMEMORYCHECK_COMMAND=`which valgrind` -DMEMORYCHECK_COMMAND_OPTIONS="-q --track-origins=yes --leak-check=full --num-callers=50 --show-leak-kinds=definite --error-exitcode=1"
|
||||
other_ctest_args: -T memcheck -LE uses-python
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
env:
|
||||
CXX: ${{matrix.cxx}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}}
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
cmake -Bbuild -H$GITHUB_WORKSPACE \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
-DCMAKE_CXX_EXTENSIONS=OFF \
|
||||
-DCATCH_DEVELOPMENT_BUILD=ON \
|
||||
${{matrix.cmake_configurations}} \
|
||||
-G Ninja
|
||||
|
||||
- name: Build tests + lib
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ninja
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: ctest -C ${{matrix.build_type}} -j 2 ${{matrix.other_ctest_args}}
|
||||
@@ -1,124 +0,0 @@
|
||||
name: Linux builds (basic)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
- g++-5
|
||||
- g++-6
|
||||
- g++-7
|
||||
- g++-8
|
||||
- g++-9
|
||||
- g++-10
|
||||
- clang++-6.0
|
||||
- clang++-7
|
||||
- clang++-8
|
||||
- clang++-9
|
||||
- clang++-10
|
||||
build_type: [Debug, Release]
|
||||
std: [14]
|
||||
include:
|
||||
- cxx: g++-5
|
||||
other_pkgs: g++-5
|
||||
- cxx: g++-6
|
||||
other_pkgs: g++-6
|
||||
- cxx: g++-7
|
||||
other_pkgs: g++-7
|
||||
- cxx: g++-8
|
||||
other_pkgs: g++-8
|
||||
- cxx: g++-9
|
||||
other_pkgs: g++-9
|
||||
- cxx: g++-10
|
||||
other_pkgs: g++-10
|
||||
- cxx: clang++-6.0
|
||||
other_pkgs: clang-6.0
|
||||
- cxx: clang++-7
|
||||
other_pkgs: clang-7
|
||||
- cxx: clang++-8
|
||||
other_pkgs: clang-8
|
||||
- cxx: clang++-9
|
||||
other_pkgs: clang-9
|
||||
- cxx: clang++-10
|
||||
other_pkgs: clang-10
|
||||
# Clang 6 + C++17
|
||||
# does not work with the default libstdc++ version thanks
|
||||
# to a disagreement on variant implementation.
|
||||
# - cxx: clang++-6.0
|
||||
# build_type: Debug
|
||||
# std: 17
|
||||
# other_pkgs: clang-6.0
|
||||
# - cxx: clang++-6.0
|
||||
# build_type: Release
|
||||
# std: 17
|
||||
# other_pkgs: clang-6.0
|
||||
# Clang 10 + C++17
|
||||
- cxx: clang++-10
|
||||
build_type: Debug
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
- cxx: clang++-10
|
||||
build_type: Release
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
- cxx: clang++-10
|
||||
build_type: Debug
|
||||
std: 20
|
||||
other_pkgs: clang-10
|
||||
- cxx: clang++-10
|
||||
build_type: Release
|
||||
std: 20
|
||||
other_pkgs: clang-10
|
||||
- cxx: g++-10
|
||||
build_type: Debug
|
||||
std: 20
|
||||
other_pkgs: g++-10
|
||||
- cxx: g++-10
|
||||
build_type: Release
|
||||
std: 20
|
||||
other_pkgs: g++-10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Add repositories for older GCC
|
||||
run: |
|
||||
sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic main'
|
||||
sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
if: ${{ matrix.cxx == 'g++-5' || matrix.cxx == 'g++-6' }}
|
||||
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ninja-build ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
env:
|
||||
CXX: ${{matrix.cxx}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}}
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
cmake -Bbuild -H$GITHUB_WORKSPACE \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
-DCMAKE_CXX_EXTENSIONS=OFF \
|
||||
-DCATCH_DEVELOPMENT_BUILD=ON \
|
||||
-G Ninja
|
||||
|
||||
- name: Build tests + lib
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ninja
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: ctest -C ${{matrix.build_type}} -j 2
|
||||
51
externals/catch/.github/workflows/mac-builds.yml
vendored
51
externals/catch/.github/workflows/mac-builds.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: Mac builds
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# macos-12 updated to a toolchain that crashes when linking the
|
||||
# test binary. This seems to be a known bug in that version,
|
||||
# and will eventually get fixed in an update. After that, we can go
|
||||
# back to newer macos images.
|
||||
runs-on: macos-11
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
- g++-11
|
||||
- clang++
|
||||
build_type: [Debug, Release]
|
||||
std: [14, 17]
|
||||
include:
|
||||
- build_type: Debug
|
||||
examples: ON
|
||||
extra_tests: ON
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
env:
|
||||
CXX: ${{matrix.cxx}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}}
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
cmake -Bbuild -H$GITHUB_WORKSPACE \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
-DCATCH_DEVELOPMENT_BUILD=ON \
|
||||
-DCATCH_BUILD_EXAMPLES=${{matrix.examples}} \
|
||||
-DCATCH_BUILD_EXTRA_TESTS=${{matrix.examples}}
|
||||
|
||||
- name: Build tests + lib
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make -j `sysctl -n hw.ncpu`
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ctest -C ${{matrix.build_type}} -j `sysctl -n hw.ncpu`
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Check header guards
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Set the type of machine to run on
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Dependencies
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Install checkguard
|
||||
run: pip install guardonce
|
||||
|
||||
- name: Check that include guards are properly named
|
||||
run: |
|
||||
wrong_files=$(checkguard -r src/catch2/ -p "name | append _INCLUDED | upper")
|
||||
if [[ $wrong_files ]]; then
|
||||
echo "Files with wrong header guard:"
|
||||
echo $wrong_files
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Check that there are no duplicated filenames
|
||||
run: |
|
||||
./tools/scripts/checkDuplicateFilenames.py
|
||||
|
||||
- name: Check that all source files have the correct license header
|
||||
run: |
|
||||
./tools/scripts/checkLicense.py
|
||||
@@ -1,37 +0,0 @@
|
||||
name: Windows builds (basic)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{matrix.os}}, ${{matrix.std}}, ${{matrix.build_type}}, ${{matrix.platform}}
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-2019, windows-2022]
|
||||
platform: [Win32, x64]
|
||||
build_type: [Debug, Release]
|
||||
std: [14, 17]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: |
|
||||
cmake -S $Env:GITHUB_WORKSPACE `
|
||||
-B ${{runner.workspace}}/build `
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} `
|
||||
-A ${{matrix.platform}} `
|
||||
--preset all-tests
|
||||
|
||||
- name: Build tests
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: cmake --build build --config ${{matrix.build_type}} --parallel %NUMBER_OF_PROCESSORS%
|
||||
shell: cmd
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
run: ctest -C ${{matrix.build_type}} -j %NUMBER_OF_PROCESSORS%
|
||||
shell: cmd
|
||||
37
externals/catch/.gitignore
vendored
37
externals/catch/.gitignore
vendored
@@ -1,37 +0,0 @@
|
||||
*.build
|
||||
!meson.build
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
*.ncb
|
||||
*.suo
|
||||
Debug
|
||||
Release
|
||||
*.user
|
||||
*.xcuserstate
|
||||
.DS_Store
|
||||
xcuserdata
|
||||
CatchSelfTest.xcscheme
|
||||
Breakpoints.xcbkptlist
|
||||
UpgradeLog.XML
|
||||
Resources/DWARF
|
||||
projects/Generated
|
||||
*.pyc
|
||||
DerivedData
|
||||
*.xccheckout
|
||||
Build
|
||||
.idea
|
||||
.vs
|
||||
.vscode
|
||||
cmake-build-*
|
||||
benchmark-dir
|
||||
.conan/test_package/build
|
||||
bazel-*
|
||||
build-fuzzers
|
||||
debug-build
|
||||
.vscode
|
||||
msvc-sln*
|
||||
# Currently we use Doxygen for dep graphs and the full docs are only slowly
|
||||
# being filled in, so we definitely do not want git to deal with the docs.
|
||||
docs/doxygen
|
||||
*.cache
|
||||
compile_commands.json
|
||||
95
externals/catch/BUILD.bazel
vendored
95
externals/catch/BUILD.bazel
vendored
@@ -1,95 +0,0 @@
|
||||
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
||||
|
||||
expand_template(
|
||||
name = "catch_user_config",
|
||||
out = "catch2/catch_user_config.hpp",
|
||||
substitutions = {
|
||||
"@CATCH_CONFIG_CONSOLE_WIDTH@": "80",
|
||||
"@CATCH_CONFIG_DEFAULT_REPORTER@": "console",
|
||||
"#cmakedefine CATCH_CONFIG_ANDROID_LOGWRITE": "",
|
||||
"#cmakedefine CATCH_CONFIG_BAZEL_SUPPORT": "#define CATCH_CONFIG_BAZEL_SUPPORT",
|
||||
"#cmakedefine CATCH_CONFIG_COLOUR_WIN32": "",
|
||||
"#cmakedefine CATCH_CONFIG_COUNTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP11_TO_STRING": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_BYTE": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_OPTIONAL": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_STRING_VIEW": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_CPP17_VARIANT": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE_STRINGIFICATION": "",
|
||||
"#cmakedefine CATCH_CONFIG_DISABLE": "",
|
||||
"#cmakedefine CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS": "",
|
||||
"#cmakedefine CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER": "",
|
||||
"#cmakedefine CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER": "",
|
||||
"#cmakedefine CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER": "",
|
||||
"#cmakedefine CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER": "",
|
||||
"#cmakedefine CATCH_CONFIG_EXPERIMENTAL_REDIRECT": "",
|
||||
"#cmakedefine CATCH_CONFIG_FALLBACK_STRINGIFIER @CATCH_CONFIG_FALLBACK_STRINGIFIER@": "",
|
||||
"#cmakedefine CATCH_CONFIG_FAST_COMPILE": "",
|
||||
"#cmakedefine CATCH_CONFIG_GETENV": "",
|
||||
"#cmakedefine CATCH_CONFIG_GLOBAL_NEXTAFTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_ANDROID_LOGWRITE": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_COLOUR_WIN32": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_COUNTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP11_TO_STRING": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_BYTE": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_OPTIONAL": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_STRING_VIEW": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_CPP17_VARIANT": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_GETENV": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_GLOBAL_NEXTAFTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_POSIX_SIGNALS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_USE_ASYNC": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_WCHAR": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_WINDOWS_SEH": "",
|
||||
"#cmakedefine CATCH_CONFIG_NOSTDOUT": "",
|
||||
"#cmakedefine CATCH_CONFIG_POSIX_SIGNALS": "",
|
||||
"#cmakedefine CATCH_CONFIG_PREFIX_ALL": "",
|
||||
"#cmakedefine CATCH_CONFIG_PREFIX_MESSAGES": "",
|
||||
"#cmakedefine CATCH_CONFIG_SHARED_LIBRARY": "",
|
||||
"#cmakedefine CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||
"#cmakedefine CATCH_CONFIG_USE_ASYNC": "",
|
||||
"#cmakedefine CATCH_CONFIG_WCHAR": "",
|
||||
"#cmakedefine CATCH_CONFIG_WINDOWS_CRTDBG": "",
|
||||
"#cmakedefine CATCH_CONFIG_WINDOWS_SEH": "",
|
||||
},
|
||||
template = "src/catch2/catch_user_config.hpp.in",
|
||||
)
|
||||
|
||||
# Generated header library, modifies the include prefix to account for
|
||||
# generation path so that we can include <catch2/catch_user_config.hpp>
|
||||
# correctly.
|
||||
cc_library(
|
||||
name = "catch2_generated",
|
||||
hdrs = ["catch2/catch_user_config.hpp"],
|
||||
include_prefix = ".", # to manipulate -I of dependenices
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Static library, without main.
|
||||
cc_library(
|
||||
name = "catch2",
|
||||
srcs = glob(
|
||||
["src/catch2/**/*.cpp"],
|
||||
exclude = ["src/catch2/internal/catch_main.cpp"],
|
||||
),
|
||||
hdrs = glob(["src/catch2/**/*.hpp"]),
|
||||
includes = ["src/"],
|
||||
linkstatic = True,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":catch2_generated"],
|
||||
)
|
||||
|
||||
# Static library, with main.
|
||||
cc_library(
|
||||
name = "catch2_main",
|
||||
srcs = ["src/catch2/internal/catch_main.cpp"],
|
||||
includes = ["src/"],
|
||||
linkstatic = True,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":catch2"],
|
||||
)
|
||||
10
externals/catch/CMake/Catch2Config.cmake.in
vendored
10
externals/catch/CMake/Catch2Config.cmake.in
vendored
@@ -1,10 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
|
||||
# Avoid repeatedly including the targets
|
||||
if(NOT TARGET Catch2::Catch2)
|
||||
# Provide path for scripts
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Catch2Targets.cmake)
|
||||
endif()
|
||||
89
externals/catch/CMake/CatchConfigOptions.cmake
vendored
89
externals/catch/CMake/CatchConfigOptions.cmake
vendored
@@ -1,89 +0,0 @@
|
||||
|
||||
# Copyright Catch2 Authors
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE.txt or copy at
|
||||
# https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
##
|
||||
# This file contains options that are materialized into the Catch2
|
||||
# compiled library. All of them default to OFF, as even the positive
|
||||
# forms correspond to the user _forcing_ them to ON, while being OFF
|
||||
# means that Catch2 can use its own autodetection.
|
||||
#
|
||||
# For detailed docs look into docs/configuration.md
|
||||
|
||||
|
||||
macro(AddOverridableConfigOption OptionBaseName)
|
||||
option(CATCH_CONFIG_${OptionBaseName} "Read docs/configuration.md for details" OFF)
|
||||
option(CATCH_CONFIG_NO_${OptionBaseName} "Read docs/configuration.md for details" OFF)
|
||||
mark_as_advanced(CATCH_CONFIG_${OptionBaseName} CATCH_CONFIG_NO_${OptionBaseName})
|
||||
endmacro()
|
||||
|
||||
macro(AddConfigOption OptionBaseName)
|
||||
option(CATCH_CONFIG_${OptionBaseName} "Read docs/configuration.md for details" OFF)
|
||||
mark_as_advanced(CATCH_CONFIG_${OptionBaseName})
|
||||
endmacro()
|
||||
|
||||
set(_OverridableOptions
|
||||
"ANDROID_LOGWRITE"
|
||||
"BAZEL_SUPPORT"
|
||||
"COLOUR_WIN32"
|
||||
"COUNTER"
|
||||
"CPP11_TO_STRING"
|
||||
"CPP17_BYTE"
|
||||
"CPP17_OPTIONAL"
|
||||
"CPP17_STRING_VIEW"
|
||||
"CPP17_UNCAUGHT_EXCEPTIONS"
|
||||
"CPP17_VARIANT"
|
||||
"GLOBAL_NEXTAFTER"
|
||||
"POSIX_SIGNALS"
|
||||
"USE_ASYNC"
|
||||
"WCHAR"
|
||||
"WINDOWS_SEH"
|
||||
"GETENV"
|
||||
"EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT"
|
||||
)
|
||||
|
||||
foreach(OptionName ${_OverridableOptions})
|
||||
AddOverridableConfigOption(${OptionName})
|
||||
endforeach()
|
||||
|
||||
set(_OtherConfigOptions
|
||||
"DISABLE_EXCEPTIONS"
|
||||
"DISABLE_EXCEPTIONS_CUSTOM_HANDLER"
|
||||
"DISABLE"
|
||||
"DISABLE_STRINGIFICATION"
|
||||
"ENABLE_ALL_STRINGMAKERS"
|
||||
"ENABLE_OPTIONAL_STRINGMAKER"
|
||||
"ENABLE_PAIR_STRINGMAKER"
|
||||
"ENABLE_TUPLE_STRINGMAKER"
|
||||
"ENABLE_VARIANT_STRINGMAKER"
|
||||
"EXPERIMENTAL_REDIRECT"
|
||||
"FAST_COMPILE"
|
||||
"NOSTDOUT"
|
||||
"PREFIX_ALL"
|
||||
"PREFIX_MESSAGES"
|
||||
"WINDOWS_CRTDBG"
|
||||
)
|
||||
|
||||
|
||||
foreach(OptionName ${_OtherConfigOptions})
|
||||
AddConfigOption(${OptionName})
|
||||
endforeach()
|
||||
if(DEFINED BUILD_SHARED_LIBS)
|
||||
set(CATCH_CONFIG_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
|
||||
else()
|
||||
set(CATCH_CONFIG_SHARED_LIBRARY "")
|
||||
endif()
|
||||
|
||||
set(CATCH_CONFIG_DEFAULT_REPORTER "console" CACHE STRING "Read docs/configuration.md for details. The name of the reporter should be without quotes.")
|
||||
set(CATCH_CONFIG_CONSOLE_WIDTH "80" CACHE STRING "Read docs/configuration.md for details. Must form a valid integer literal.")
|
||||
|
||||
mark_as_advanced(CATCH_CONFIG_SHARED_LIBRARY CATCH_CONFIG_DEFAULT_REPORTER CATCH_CONFIG_CONSOLE_WIDTH)
|
||||
|
||||
# There is no good way to both turn this into a CMake cache variable,
|
||||
# and keep reasonable default semantics inside the project. Thus we do
|
||||
# not define it and users have to provide it as an outside variable.
|
||||
#set(CATCH_CONFIG_FALLBACK_STRINGIFIER "" CACHE STRING "Read docs/configuration.md for details.")
|
||||
120
externals/catch/CMake/CatchMiscFunctions.cmake
vendored
120
externals/catch/CMake/CatchMiscFunctions.cmake
vendored
@@ -1,120 +0,0 @@
|
||||
|
||||
# Copyright Catch2 Authors
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE.txt or copy at
|
||||
# https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
function(add_cxx_flag_if_supported_to_targets flagname targets)
|
||||
string(MAKE_C_IDENTIFIER ${flagname} flag_identifier )
|
||||
check_cxx_compiler_flag("${flagname}" HAVE_FLAG_${flag_identifier})
|
||||
|
||||
if (HAVE_FLAG_${flag_identifier})
|
||||
foreach(target ${targets})
|
||||
target_compile_options(${target} PRIVATE ${flagname})
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Assumes that it is only called for development builds, where warnings
|
||||
# and Werror is desired, so it also enables Werror.
|
||||
function(add_warnings_to_targets targets)
|
||||
LIST(LENGTH targets TARGETS_LEN)
|
||||
# For now we just assume 2 possibilities: msvc and msvc-like compilers,
|
||||
# and other.
|
||||
if (MSVC)
|
||||
foreach(target ${targets})
|
||||
# Force MSVC to consider everything as encoded in utf-8
|
||||
target_compile_options( ${target} PRIVATE /utf-8 )
|
||||
# Enable Werror equivalent
|
||||
if (CATCH_ENABLE_WERROR)
|
||||
target_compile_options( ${target} PRIVATE /WX )
|
||||
endif()
|
||||
|
||||
# MSVC is currently handled specially
|
||||
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
|
||||
STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
|
||||
target_compile_options( ${target} PRIVATE /w44265 /w44061 /w44062 /w45038 )
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
set(CHECKED_WARNING_FLAGS
|
||||
"-Wabsolute-value"
|
||||
"-Wall"
|
||||
"-Wcall-to-pure-virtual-from-ctor-dtor"
|
||||
"-Wcast-align"
|
||||
"-Wcatch-value"
|
||||
"-Wdangling"
|
||||
"-Wdeprecated"
|
||||
"-Wdeprecated-register"
|
||||
"-Wexceptions"
|
||||
"-Wexit-time-destructors"
|
||||
"-Wextra"
|
||||
"-Wextra-semi"
|
||||
"-Wfloat-equal"
|
||||
"-Wglobal-constructors"
|
||||
"-Winit-self"
|
||||
"-Wmisleading-indentation"
|
||||
"-Wmismatched-new-delete"
|
||||
"-Wmismatched-return-types"
|
||||
"-Wmismatched-tags"
|
||||
"-Wmissing-braces"
|
||||
"-Wmissing-declarations"
|
||||
"-Wmissing-noreturn"
|
||||
"-Wmissing-prototypes"
|
||||
"-Wmissing-variable-declarations"
|
||||
"-Wnull-dereference"
|
||||
"-Wold-style-cast"
|
||||
"-Woverloaded-virtual"
|
||||
"-Wparentheses"
|
||||
"-Wpedantic"
|
||||
"-Wredundant-decls"
|
||||
"-Wreorder"
|
||||
"-Wreturn-std-move"
|
||||
"-Wshadow"
|
||||
"-Wstrict-aliasing"
|
||||
"-Wsuggest-destructor-override"
|
||||
"-Wsuggest-override"
|
||||
"-Wundef"
|
||||
"-Wuninitialized"
|
||||
"-Wunneeded-internal-declaration"
|
||||
"-Wunreachable-code-aggressive"
|
||||
"-Wunused"
|
||||
"-Wunused-function"
|
||||
"-Wunused-parameter"
|
||||
"-Wvla"
|
||||
"-Wweak-vtables"
|
||||
|
||||
# This is a useful warning, but our tests sometimes rely on
|
||||
# functions being present, but not picked (e.g. various checks
|
||||
# for stringification implementation ordering).
|
||||
# Ergo, we should use it every now and then, but we cannot
|
||||
# enable it by default.
|
||||
# "-Wunused-member-function"
|
||||
)
|
||||
foreach(warning ${CHECKED_WARNING_FLAGS})
|
||||
add_cxx_flag_if_supported_to_targets(${warning} "${targets}")
|
||||
endforeach()
|
||||
|
||||
if (CATCH_ENABLE_WERROR)
|
||||
foreach(target ${targets})
|
||||
# Enable Werror equivalent
|
||||
target_compile_options( ${target} PRIVATE -Werror )
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Adds flags required for reproducible build to the target
|
||||
# Currently only supports GCC and Clang
|
||||
function(add_build_reproducibility_settings target)
|
||||
# Make the build reproducible on versions of g++ and clang that supports -ffile-prefix-map
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||
add_cxx_flag_if_supported_to_targets("-ffile-prefix-map=${CATCH_DIR}/=" "${target}")
|
||||
endif()
|
||||
endfunction()
|
||||
157
externals/catch/CMake/FindGcov.cmake
vendored
157
externals/catch/CMake/FindGcov.cmake
vendored
@@ -1,157 +0,0 @@
|
||||
# This file is part of CMake-codecov.
|
||||
#
|
||||
# Copyright (c)
|
||||
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
|
||||
#
|
||||
# See the LICENSE file in the package base directory for details
|
||||
#
|
||||
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
|
||||
#
|
||||
|
||||
|
||||
# include required Modules
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
|
||||
# Search for gcov binary.
|
||||
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
|
||||
set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
|
||||
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach (LANG ${ENABLED_LANGUAGES})
|
||||
# Gcov evaluation is dependent on the used compiler. Check gcov support for
|
||||
# each compiler that is used. If gcov binary was already found for this
|
||||
# compiler, do not try to find it again.
|
||||
if (NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN)
|
||||
get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH)
|
||||
|
||||
if ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU")
|
||||
# Some distributions like OSX (homebrew) ship gcov with the compiler
|
||||
# version appended as gcov-x. To find this binary we'll build the
|
||||
# suggested binary name with the compiler version.
|
||||
string(REGEX MATCH "^[0-9]+" GCC_VERSION
|
||||
"${CMAKE_${LANG}_COMPILER_VERSION}")
|
||||
|
||||
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
|
||||
HINTS ${COMPILER_PATH})
|
||||
|
||||
elseif ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang")
|
||||
# Some distributions like Debian ship llvm-cov with the compiler
|
||||
# version appended as llvm-cov-x.y. To find this binary we'll build
|
||||
# the suggested binary name with the compiler version.
|
||||
string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION
|
||||
"${CMAKE_${LANG}_COMPILER_VERSION}")
|
||||
|
||||
# llvm-cov prior version 3.5 seems to be not working with coverage
|
||||
# evaluation tools, but these versions are compatible with the gcc
|
||||
# gcov tool.
|
||||
if(LLVM_VERSION VERSION_GREATER 3.4)
|
||||
find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
|
||||
"llvm-cov" HINTS ${COMPILER_PATH})
|
||||
mark_as_advanced(LLVM_COV_BIN)
|
||||
|
||||
if (LLVM_COV_BIN)
|
||||
find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS
|
||||
${CMAKE_MODULE_PATH})
|
||||
if (LLVM_COV_WRAPPER)
|
||||
set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "")
|
||||
|
||||
# set additional parameters
|
||||
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV
|
||||
"LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING
|
||||
"Environment variables for llvm-cov-wrapper.")
|
||||
mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT GCOV_BIN)
|
||||
# Fall back to gcov binary if llvm-cov was not found or is
|
||||
# incompatible. This is the default on OSX, but may crash on
|
||||
# recent Linux versions.
|
||||
find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
if (GCOV_BIN)
|
||||
set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING
|
||||
"${LANG} gcov binary.")
|
||||
|
||||
if (NOT CMAKE_REQUIRED_QUIET)
|
||||
message("-- Found gcov evaluation for "
|
||||
"${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}")
|
||||
endif()
|
||||
|
||||
unset(GCOV_BIN CACHE)
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
|
||||
|
||||
|
||||
# Add a new global target for all gcov targets. This target could be used to
|
||||
# generate the gcov files for the whole project instead of calling <TARGET>-gcov
|
||||
# for each target.
|
||||
if (NOT TARGET gcov)
|
||||
add_custom_target(gcov)
|
||||
endif (NOT TARGET gcov)
|
||||
|
||||
|
||||
|
||||
# This function will add gcov evaluation for target <TNAME>. Only sources of
|
||||
# this target will be evaluated and no dependencies will be added. It will call
|
||||
# Gcov on any source file of <TNAME> once and store the gcov file in the same
|
||||
# directory.
|
||||
function (add_gcov_target TNAME)
|
||||
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
|
||||
|
||||
# We don't have to check, if the target has support for coverage, thus this
|
||||
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
|
||||
# have to determine which gcov binary to use.
|
||||
get_target_property(TSOURCES ${TNAME} SOURCES)
|
||||
set(SOURCES "")
|
||||
set(TCOMPILER "")
|
||||
foreach (FILE ${TSOURCES})
|
||||
codecov_path_of_source(${FILE} FILE)
|
||||
if (NOT "${FILE}" STREQUAL "")
|
||||
codecov_lang_of_source(${FILE} LANG)
|
||||
if (NOT "${LANG}" STREQUAL "")
|
||||
list(APPEND SOURCES "${FILE}")
|
||||
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# If no gcov binary was found, coverage data can't be evaluated.
|
||||
if (NOT GCOV_${TCOMPILER}_BIN)
|
||||
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
|
||||
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
|
||||
|
||||
|
||||
set(BUFFER "")
|
||||
foreach(FILE ${SOURCES})
|
||||
get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH)
|
||||
|
||||
# call gcov
|
||||
add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov
|
||||
COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null
|
||||
DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno
|
||||
WORKING_DIRECTORY ${FILE_PATH}
|
||||
)
|
||||
|
||||
list(APPEND BUFFER ${TDIR}/${FILE}.gcov)
|
||||
endforeach()
|
||||
|
||||
|
||||
# add target for gcov evaluation of <TNAME>
|
||||
add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER})
|
||||
|
||||
# add evaluation target to the global gcov target.
|
||||
add_dependencies(gcov ${TNAME}-gcov)
|
||||
endfunction (add_gcov_target)
|
||||
354
externals/catch/CMake/FindLcov.cmake
vendored
354
externals/catch/CMake/FindLcov.cmake
vendored
@@ -1,354 +0,0 @@
|
||||
# This file is part of CMake-codecov.
|
||||
#
|
||||
# Copyright (c)
|
||||
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
|
||||
#
|
||||
# See the LICENSE file in the package base directory for details
|
||||
#
|
||||
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
|
||||
#
|
||||
|
||||
|
||||
# configuration
|
||||
set(LCOV_DATA_PATH "${CMAKE_BINARY_DIR}/lcov/data")
|
||||
set(LCOV_DATA_PATH_INIT "${LCOV_DATA_PATH}/init")
|
||||
set(LCOV_DATA_PATH_CAPTURE "${LCOV_DATA_PATH}/capture")
|
||||
set(LCOV_HTML_PATH "${CMAKE_BINARY_DIR}/lcov/html")
|
||||
|
||||
|
||||
|
||||
|
||||
# Search for Gcov which is used by Lcov.
|
||||
find_package(Gcov)
|
||||
|
||||
|
||||
|
||||
|
||||
# This function will add lcov evaluation for target <TNAME>. Only sources of
|
||||
# this target will be evaluated and no dependencies will be added. It will call
|
||||
# geninfo on any source file of <TNAME> once and store the info file in the same
|
||||
# directory.
|
||||
#
|
||||
# Note: This function is only a wrapper to define this function always, even if
|
||||
# coverage is not supported by the compiler or disabled. This function must
|
||||
# be defined here, because the module will be exited, if there is no coverage
|
||||
# support by the compiler or it is disabled by the user.
|
||||
function (add_lcov_target TNAME)
|
||||
if (LCOV_FOUND)
|
||||
# capture initial coverage data
|
||||
lcov_capture_initial_tgt(${TNAME})
|
||||
|
||||
# capture coverage data after execution
|
||||
lcov_capture_tgt(${TNAME})
|
||||
endif ()
|
||||
endfunction (add_lcov_target)
|
||||
|
||||
|
||||
|
||||
|
||||
# include required Modules
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
# Search for required lcov binaries.
|
||||
find_program(LCOV_BIN lcov)
|
||||
find_program(GENINFO_BIN geninfo)
|
||||
find_program(GENHTML_BIN genhtml)
|
||||
find_package_handle_standard_args(lcov
|
||||
REQUIRED_VARS LCOV_BIN GENINFO_BIN GENHTML_BIN
|
||||
)
|
||||
|
||||
# enable genhtml C++ demangeling, if c++filt is found.
|
||||
set(GENHTML_CPPFILT_FLAG "")
|
||||
find_program(CPPFILT_BIN c++filt)
|
||||
if (NOT CPPFILT_BIN STREQUAL "")
|
||||
set(GENHTML_CPPFILT_FLAG "--demangle-cpp")
|
||||
endif (NOT CPPFILT_BIN STREQUAL "")
|
||||
|
||||
# enable no-external flag for lcov, if available.
|
||||
if (GENINFO_BIN AND NOT DEFINED GENINFO_EXTERN_FLAG)
|
||||
set(FLAG "")
|
||||
execute_process(COMMAND ${GENINFO_BIN} --help OUTPUT_VARIABLE GENINFO_HELP)
|
||||
string(REGEX MATCH "external" GENINFO_RES "${GENINFO_HELP}")
|
||||
if (GENINFO_RES)
|
||||
set(FLAG "--no-external")
|
||||
endif ()
|
||||
|
||||
set(GENINFO_EXTERN_FLAG "${FLAG}"
|
||||
CACHE STRING "Geninfo flag to exclude system sources.")
|
||||
endif ()
|
||||
|
||||
# If Lcov was not found, exit module now.
|
||||
if (NOT LCOV_FOUND)
|
||||
return()
|
||||
endif (NOT LCOV_FOUND)
|
||||
|
||||
|
||||
|
||||
|
||||
# Create directories to be used.
|
||||
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_INIT})
|
||||
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_CAPTURE})
|
||||
|
||||
set(LCOV_REMOVE_PATTERNS "")
|
||||
|
||||
# This function will merge lcov files to a single target file. Additional lcov
|
||||
# flags may be set with setting LCOV_EXTRA_FLAGS before calling this function.
|
||||
function (lcov_merge_files OUTFILE ...)
|
||||
# Remove ${OUTFILE} from ${ARGV} and generate lcov parameters with files.
|
||||
list(REMOVE_AT ARGV 0)
|
||||
|
||||
# Generate merged file.
|
||||
string(REPLACE "${CMAKE_BINARY_DIR}/" "" FILE_REL "${OUTFILE}")
|
||||
add_custom_command(OUTPUT "${OUTFILE}.raw"
|
||||
COMMAND cat ${ARGV} > ${OUTFILE}.raw
|
||||
DEPENDS ${ARGV}
|
||||
COMMENT "Generating ${FILE_REL}"
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT "${OUTFILE}"
|
||||
COMMAND ${LCOV_BIN} --quiet -a ${OUTFILE}.raw --output-file ${OUTFILE}
|
||||
--base-directory ${PROJECT_SOURCE_DIR} ${LCOV_EXTRA_FLAGS}
|
||||
COMMAND ${LCOV_BIN} --quiet -r ${OUTFILE} ${LCOV_REMOVE_PATTERNS}
|
||||
--output-file ${OUTFILE} ${LCOV_EXTRA_FLAGS}
|
||||
DEPENDS ${OUTFILE}.raw
|
||||
COMMENT "Post-processing ${FILE_REL}"
|
||||
)
|
||||
endfunction ()
|
||||
|
||||
|
||||
|
||||
|
||||
# Add a new global target to generate initial coverage reports for all targets.
|
||||
# This target will be used to generate the global initial info file, which is
|
||||
# used to gather even empty report data.
|
||||
if (NOT TARGET lcov-capture-init)
|
||||
add_custom_target(lcov-capture-init)
|
||||
set(LCOV_CAPTURE_INIT_FILES "" CACHE INTERNAL "")
|
||||
endif (NOT TARGET lcov-capture-init)
|
||||
|
||||
|
||||
# This function will add initial capture of coverage data for target <TNAME>,
|
||||
# which is needed to get also data for objects, which were not loaded at
|
||||
# execution time. It will call geninfo for every source file of <TNAME> once and
|
||||
# store the info file in the same directory.
|
||||
function (lcov_capture_initial_tgt TNAME)
|
||||
# We don't have to check, if the target has support for coverage, thus this
|
||||
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
|
||||
# have to determine which gcov binary to use.
|
||||
get_target_property(TSOURCES ${TNAME} SOURCES)
|
||||
set(SOURCES "")
|
||||
set(TCOMPILER "")
|
||||
foreach (FILE ${TSOURCES})
|
||||
codecov_path_of_source(${FILE} FILE)
|
||||
if (NOT "${FILE}" STREQUAL "")
|
||||
codecov_lang_of_source(${FILE} LANG)
|
||||
if (NOT "${LANG}" STREQUAL "")
|
||||
list(APPEND SOURCES "${FILE}")
|
||||
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# If no gcov binary was found, coverage data can't be evaluated.
|
||||
if (NOT GCOV_${TCOMPILER}_BIN)
|
||||
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
|
||||
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
|
||||
|
||||
|
||||
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
|
||||
set(GENINFO_FILES "")
|
||||
foreach(FILE ${SOURCES})
|
||||
# generate empty coverage files
|
||||
set(OUTFILE "${TDIR}/${FILE}.info.init")
|
||||
list(APPEND GENINFO_FILES ${OUTFILE})
|
||||
|
||||
add_custom_command(OUTPUT ${OUTFILE} COMMAND ${GCOV_ENV} ${GENINFO_BIN}
|
||||
--quiet --base-directory ${PROJECT_SOURCE_DIR} --initial
|
||||
--gcov-tool ${GCOV_BIN} --output-filename ${OUTFILE}
|
||||
${GENINFO_EXTERN_FLAG} ${TDIR}/${FILE}.gcno
|
||||
DEPENDS ${TNAME}
|
||||
COMMENT "Capturing initial coverage data for ${FILE}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Concatenate all files generated by geninfo to a single file per target.
|
||||
set(OUTFILE "${LCOV_DATA_PATH_INIT}/${TNAME}.info")
|
||||
set(LCOV_EXTRA_FLAGS "--initial")
|
||||
lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
|
||||
add_custom_target(${TNAME}-capture-init ALL DEPENDS ${OUTFILE})
|
||||
|
||||
# add geninfo file generation to global lcov-geninfo target
|
||||
add_dependencies(lcov-capture-init ${TNAME}-capture-init)
|
||||
set(LCOV_CAPTURE_INIT_FILES "${LCOV_CAPTURE_INIT_FILES}"
|
||||
"${OUTFILE}" CACHE INTERNAL ""
|
||||
)
|
||||
endfunction (lcov_capture_initial_tgt)
|
||||
|
||||
|
||||
# This function will generate the global info file for all targets. It has to be
|
||||
# called after all other CMake functions in the root CMakeLists.txt file, to get
|
||||
# a full list of all targets that generate coverage data.
|
||||
function (lcov_capture_initial)
|
||||
# Skip this function (and do not create the following targets), if there are
|
||||
# no input files.
|
||||
if ("${LCOV_CAPTURE_INIT_FILES}" STREQUAL "")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
# Add a new target to merge the files of all targets.
|
||||
set(OUTFILE "${LCOV_DATA_PATH_INIT}/all_targets.info")
|
||||
lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_INIT_FILES})
|
||||
add_custom_target(lcov-geninfo-init ALL DEPENDS ${OUTFILE}
|
||||
lcov-capture-init
|
||||
)
|
||||
endfunction (lcov_capture_initial)
|
||||
|
||||
|
||||
|
||||
|
||||
# Add a new global target to generate coverage reports for all targets. This
|
||||
# target will be used to generate the global info file.
|
||||
if (NOT TARGET lcov-capture)
|
||||
add_custom_target(lcov-capture)
|
||||
set(LCOV_CAPTURE_FILES "" CACHE INTERNAL "")
|
||||
endif (NOT TARGET lcov-capture)
|
||||
|
||||
|
||||
# This function will add capture of coverage data for target <TNAME>, which is
|
||||
# needed to get also data for objects, which were not loaded at execution time.
|
||||
# It will call geninfo for every source file of <TNAME> once and store the info
|
||||
# file in the same directory.
|
||||
function (lcov_capture_tgt TNAME)
|
||||
# We don't have to check, if the target has support for coverage, thus this
|
||||
# will be checked by add_coverage_target in Findcoverage.cmake. Instead we
|
||||
# have to determine which gcov binary to use.
|
||||
get_target_property(TSOURCES ${TNAME} SOURCES)
|
||||
set(SOURCES "")
|
||||
set(TCOMPILER "")
|
||||
foreach (FILE ${TSOURCES})
|
||||
codecov_path_of_source(${FILE} FILE)
|
||||
if (NOT "${FILE}" STREQUAL "")
|
||||
codecov_lang_of_source(${FILE} LANG)
|
||||
if (NOT "${LANG}" STREQUAL "")
|
||||
list(APPEND SOURCES "${FILE}")
|
||||
set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# If no gcov binary was found, coverage data can't be evaluated.
|
||||
if (NOT GCOV_${TCOMPILER}_BIN)
|
||||
message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
|
||||
set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
|
||||
|
||||
|
||||
set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
|
||||
set(GENINFO_FILES "")
|
||||
foreach(FILE ${SOURCES})
|
||||
# Generate coverage files. If no .gcda file was generated during
|
||||
# execution, the empty coverage file will be used instead.
|
||||
set(OUTFILE "${TDIR}/${FILE}.info")
|
||||
list(APPEND GENINFO_FILES ${OUTFILE})
|
||||
|
||||
add_custom_command(OUTPUT ${OUTFILE}
|
||||
COMMAND test -f "${TDIR}/${FILE}.gcda"
|
||||
&& ${GCOV_ENV} ${GENINFO_BIN} --quiet --base-directory
|
||||
${PROJECT_SOURCE_DIR} --gcov-tool ${GCOV_BIN}
|
||||
--output-filename ${OUTFILE} ${GENINFO_EXTERN_FLAG}
|
||||
${TDIR}/${FILE}.gcda
|
||||
|| cp ${OUTFILE}.init ${OUTFILE}
|
||||
DEPENDS ${TNAME} ${TNAME}-capture-init
|
||||
COMMENT "Capturing coverage data for ${FILE}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Concatenate all files generated by geninfo to a single file per target.
|
||||
set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/${TNAME}.info")
|
||||
lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
|
||||
add_custom_target(${TNAME}-geninfo DEPENDS ${OUTFILE})
|
||||
|
||||
# add geninfo file generation to global lcov-capture target
|
||||
add_dependencies(lcov-capture ${TNAME}-geninfo)
|
||||
set(LCOV_CAPTURE_FILES "${LCOV_CAPTURE_FILES}" "${OUTFILE}" CACHE INTERNAL
|
||||
""
|
||||
)
|
||||
|
||||
# Add target for generating html output for this target only.
|
||||
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/${TNAME})
|
||||
add_custom_target(${TNAME}-genhtml
|
||||
COMMAND ${GENHTML_BIN} --quiet --sort --prefix ${PROJECT_SOURCE_DIR}
|
||||
--baseline-file ${LCOV_DATA_PATH_INIT}/${TNAME}.info
|
||||
--output-directory ${LCOV_HTML_PATH}/${TNAME}
|
||||
--title "${CMAKE_PROJECT_NAME} - target ${TNAME}"
|
||||
${GENHTML_CPPFILT_FLAG} ${OUTFILE}
|
||||
DEPENDS ${TNAME}-geninfo ${TNAME}-capture-init
|
||||
)
|
||||
endfunction (lcov_capture_tgt)
|
||||
|
||||
|
||||
# This function will generate the global info file for all targets. It has to be
|
||||
# called after all other CMake functions in the root CMakeLists.txt file, to get
|
||||
# a full list of all targets that generate coverage data.
|
||||
function (lcov_capture)
|
||||
# Skip this function (and do not create the following targets), if there are
|
||||
# no input files.
|
||||
if ("${LCOV_CAPTURE_FILES}" STREQUAL "")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
# Add a new target to merge the files of all targets.
|
||||
set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/all_targets.info")
|
||||
lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_FILES})
|
||||
add_custom_target(lcov-geninfo DEPENDS ${OUTFILE} lcov-capture)
|
||||
|
||||
# Add a new global target for all lcov targets. This target could be used to
|
||||
# generate the lcov html output for the whole project instead of calling
|
||||
# <TARGET>-geninfo and <TARGET>-genhtml for each target. It will also be
|
||||
# used to generate a html site for all project data together instead of one
|
||||
# for each target.
|
||||
if (NOT TARGET lcov)
|
||||
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/all_targets)
|
||||
add_custom_target(lcov
|
||||
COMMAND ${GENHTML_BIN} --quiet --sort
|
||||
--baseline-file ${LCOV_DATA_PATH_INIT}/all_targets.info
|
||||
--output-directory ${LCOV_HTML_PATH}/all_targets
|
||||
--title "${CMAKE_PROJECT_NAME}" --prefix "${PROJECT_SOURCE_DIR}"
|
||||
${GENHTML_CPPFILT_FLAG} ${OUTFILE}
|
||||
DEPENDS lcov-geninfo-init lcov-geninfo
|
||||
)
|
||||
endif ()
|
||||
endfunction (lcov_capture)
|
||||
|
||||
|
||||
|
||||
|
||||
# Add a new global target to generate the lcov html report for the whole project
|
||||
# instead of calling <TARGET>-genhtml for each target (to create an own report
|
||||
# for each target). Instead of the lcov target it does not require geninfo for
|
||||
# all targets, so you have to call <TARGET>-geninfo to generate the info files
|
||||
# the targets you'd like to have in your report or lcov-geninfo for generating
|
||||
# info files for all targets before calling lcov-genhtml.
|
||||
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/selected_targets)
|
||||
if (NOT TARGET lcov-genhtml)
|
||||
add_custom_target(lcov-genhtml
|
||||
COMMAND ${GENHTML_BIN}
|
||||
--quiet
|
||||
--output-directory ${LCOV_HTML_PATH}/selected_targets
|
||||
--title \"${CMAKE_PROJECT_NAME} - targets `find
|
||||
${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
|
||||
\"all_targets.info\" -exec basename {} .info \\\;`\"
|
||||
--prefix ${PROJECT_SOURCE_DIR}
|
||||
--sort
|
||||
${GENHTML_CPPFILT_FLAG}
|
||||
`find ${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
|
||||
\"all_targets.info\"`
|
||||
)
|
||||
endif (NOT TARGET lcov-genhtml)
|
||||
258
externals/catch/CMake/Findcodecov.cmake
vendored
258
externals/catch/CMake/Findcodecov.cmake
vendored
@@ -1,258 +0,0 @@
|
||||
# This file is part of CMake-codecov.
|
||||
#
|
||||
# Copyright (c)
|
||||
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
|
||||
#
|
||||
# See the LICENSE file in the package base directory for details
|
||||
#
|
||||
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
|
||||
#
|
||||
|
||||
|
||||
# Add an option to choose, if coverage should be enabled or not. If enabled
|
||||
# marked targets will be build with coverage support and appropriate targets
|
||||
# will be added. If disabled coverage will be ignored for *ALL* targets.
|
||||
option(ENABLE_COVERAGE "Enable coverage build." OFF)
|
||||
|
||||
set(COVERAGE_FLAG_CANDIDATES
|
||||
# gcc and clang
|
||||
"-O0 -g -fprofile-arcs -ftest-coverage"
|
||||
|
||||
# gcc and clang fallback
|
||||
"-O0 -g --coverage"
|
||||
)
|
||||
|
||||
|
||||
# Add coverage support for target ${TNAME} and register target for coverage
|
||||
# evaluation. If coverage is disabled or not supported, this function will
|
||||
# simply do nothing.
|
||||
#
|
||||
# Note: This function is only a wrapper to define this function always, even if
|
||||
# coverage is not supported by the compiler or disabled. This function must
|
||||
# be defined here, because the module will be exited, if there is no coverage
|
||||
# support by the compiler or it is disabled by the user.
|
||||
function (add_coverage TNAME)
|
||||
# only add coverage for target, if coverage is support and enabled.
|
||||
if (ENABLE_COVERAGE)
|
||||
foreach (TNAME ${ARGV})
|
||||
add_coverage_target(${TNAME})
|
||||
endforeach ()
|
||||
endif ()
|
||||
endfunction (add_coverage)
|
||||
|
||||
|
||||
# Add global target to gather coverage information after all targets have been
|
||||
# added. Other evaluation functions could be added here, after checks for the
|
||||
# specific module have been passed.
|
||||
#
|
||||
# Note: This function is only a wrapper to define this function always, even if
|
||||
# coverage is not supported by the compiler or disabled. This function must
|
||||
# be defined here, because the module will be exited, if there is no coverage
|
||||
# support by the compiler or it is disabled by the user.
|
||||
function (coverage_evaluate)
|
||||
# add lcov evaluation
|
||||
if (LCOV_FOUND)
|
||||
lcov_capture_initial()
|
||||
lcov_capture()
|
||||
endif (LCOV_FOUND)
|
||||
endfunction ()
|
||||
|
||||
|
||||
# Exit this module, if coverage is disabled. add_coverage is defined before this
|
||||
# return, so this module can be exited now safely without breaking any build-
|
||||
# scripts.
|
||||
if (NOT ENABLE_COVERAGE)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
|
||||
# Find the reuired flags foreach language.
|
||||
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
|
||||
set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
|
||||
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach (LANG ${ENABLED_LANGUAGES})
|
||||
# Coverage flags are not dependent on language, but the used compiler. So
|
||||
# instead of searching flags foreach language, search flags foreach compiler
|
||||
# used.
|
||||
set(COMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
if (NOT COVERAGE_${COMPILER}_FLAGS)
|
||||
foreach (FLAG ${COVERAGE_FLAG_CANDIDATES})
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Try ${COMPILER} code coverage flag = [${FLAG}]")
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
unset(COVERAGE_FLAG_DETECTED CACHE)
|
||||
|
||||
if (${LANG} STREQUAL "C")
|
||||
include(CheckCCompilerFlag)
|
||||
check_c_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED)
|
||||
|
||||
elseif (${LANG} STREQUAL "CXX")
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED)
|
||||
|
||||
elseif (${LANG} STREQUAL "Fortran")
|
||||
# CheckFortranCompilerFlag was introduced in CMake 3.x. To be
|
||||
# compatible with older Cmake versions, we will check if this
|
||||
# module is present before we use it. Otherwise we will define
|
||||
# Fortran coverage support as not available.
|
||||
include(CheckFortranCompilerFlag OPTIONAL
|
||||
RESULT_VARIABLE INCLUDED)
|
||||
if (INCLUDED)
|
||||
check_fortran_compiler_flag("${FLAG}"
|
||||
COVERAGE_FLAG_DETECTED)
|
||||
elseif (NOT CMAKE_REQUIRED_QUIET)
|
||||
message("-- Performing Test COVERAGE_FLAG_DETECTED")
|
||||
message("-- Performing Test COVERAGE_FLAG_DETECTED - Failed"
|
||||
" (Check not supported)")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (COVERAGE_FLAG_DETECTED)
|
||||
set(COVERAGE_${COMPILER}_FLAGS "${FLAG}"
|
||||
CACHE STRING "${COMPILER} flags for code coverage.")
|
||||
mark_as_advanced(COVERAGE_${COMPILER}_FLAGS)
|
||||
break()
|
||||
else ()
|
||||
message(WARNING "Code coverage is not available for ${COMPILER}"
|
||||
" compiler. Targets using this compiler will be "
|
||||
"compiled without it.")
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
|
||||
|
||||
|
||||
|
||||
|
||||
# Helper function to get the language of a source file.
|
||||
function (codecov_lang_of_source FILE RETURN_VAR)
|
||||
get_filename_component(FILE_EXT "${FILE}" EXT)
|
||||
string(TOLOWER "${FILE_EXT}" FILE_EXT)
|
||||
string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
|
||||
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach (LANG ${ENABLED_LANGUAGES})
|
||||
list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP)
|
||||
if (NOT ${TEMP} EQUAL -1)
|
||||
set(${RETURN_VAR} "${LANG}" PARENT_SCOPE)
|
||||
return()
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
set(${RETURN_VAR} "" PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
|
||||
# Helper function to get the relative path of the source file destination path.
|
||||
# This path is needed by FindGcov and FindLcov cmake files to locate the
|
||||
# captured data.
|
||||
function (codecov_path_of_source FILE RETURN_VAR)
|
||||
string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _source ${FILE})
|
||||
|
||||
# If expression was found, SOURCEFILE is a generator-expression for an
|
||||
# object library. Currently we found no way to call this function automatic
|
||||
# for the referenced target, so it must be called in the directoryso of the
|
||||
# object library definition.
|
||||
if (NOT "${_source}" STREQUAL "")
|
||||
set(${RETURN_VAR} "" PARENT_SCOPE)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
|
||||
string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" FILE "${FILE}")
|
||||
if(IS_ABSOLUTE ${FILE})
|
||||
file(RELATIVE_PATH FILE ${CMAKE_CURRENT_SOURCE_DIR} ${FILE})
|
||||
endif()
|
||||
|
||||
# get the right path for file
|
||||
string(REPLACE ".." "__" PATH "${FILE}")
|
||||
|
||||
set(${RETURN_VAR} "${PATH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
||||
|
||||
# Add coverage support for target ${TNAME} and register target for coverage
|
||||
# evaluation.
|
||||
function(add_coverage_target TNAME)
|
||||
# Check if all sources for target use the same compiler. If a target uses
|
||||
# e.g. C and Fortran mixed and uses different compilers (e.g. clang and
|
||||
# gfortran) this can trigger huge problems, because different compilers may
|
||||
# use different implementations for code coverage.
|
||||
get_target_property(TSOURCES ${TNAME} SOURCES)
|
||||
set(TARGET_COMPILER "")
|
||||
set(ADDITIONAL_FILES "")
|
||||
foreach (FILE ${TSOURCES})
|
||||
# If expression was found, FILE is a generator-expression for an object
|
||||
# library. Object libraries will be ignored.
|
||||
string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE})
|
||||
if ("${_file}" STREQUAL "")
|
||||
codecov_lang_of_source(${FILE} LANG)
|
||||
if (LANG)
|
||||
list(APPEND TARGET_COMPILER ${CMAKE_${LANG}_COMPILER_ID})
|
||||
|
||||
list(APPEND ADDITIONAL_FILES "${FILE}.gcno")
|
||||
list(APPEND ADDITIONAL_FILES "${FILE}.gcda")
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
list(REMOVE_DUPLICATES TARGET_COMPILER)
|
||||
list(LENGTH TARGET_COMPILER NUM_COMPILERS)
|
||||
|
||||
if (NUM_COMPILERS GREATER 1)
|
||||
message(WARNING "Can't use code coverage for target ${TNAME}, because "
|
||||
"it will be compiled by incompatible compilers. Target will be "
|
||||
"compiled without code coverage.")
|
||||
return()
|
||||
|
||||
elseif (NUM_COMPILERS EQUAL 0)
|
||||
message(WARNING "Can't use code coverage for target ${TNAME}, because "
|
||||
"it uses an unknown compiler. Target will be compiled without "
|
||||
"code coverage.")
|
||||
return()
|
||||
|
||||
elseif (NOT DEFINED "COVERAGE_${TARGET_COMPILER}_FLAGS")
|
||||
# A warning has been printed before, so just return if flags for this
|
||||
# compiler aren't available.
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
# enable coverage for target
|
||||
set_property(TARGET ${TNAME} APPEND_STRING
|
||||
PROPERTY COMPILE_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}")
|
||||
set_property(TARGET ${TNAME} APPEND_STRING
|
||||
PROPERTY LINK_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}")
|
||||
|
||||
|
||||
# Add gcov files generated by compiler to clean target.
|
||||
set(CLEAN_FILES "")
|
||||
foreach (FILE ${ADDITIONAL_FILES})
|
||||
codecov_path_of_source(${FILE} FILE)
|
||||
list(APPEND CLEAN_FILES "CMakeFiles/${TNAME}.dir/${FILE}")
|
||||
endforeach()
|
||||
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${CLEAN_FILES}")
|
||||
|
||||
|
||||
add_gcov_target(${TNAME})
|
||||
add_lcov_target(${TNAME})
|
||||
endfunction(add_coverage_target)
|
||||
|
||||
|
||||
|
||||
|
||||
# Include modules for parsing the collected data and output it in a readable
|
||||
# format (like gcov and lcov).
|
||||
find_package(Gcov)
|
||||
find_package(Lcov)
|
||||
10
externals/catch/CMake/catch2-with-main.pc.in
vendored
10
externals/catch/CMake/catch2-with-main.pc.in
vendored
@@ -1,10 +0,0 @@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
pkg_version=@Catch2_VERSION@
|
||||
|
||||
Name: Catch2-With-Main
|
||||
Description: A modern, C++-native test framework for C++14 and above (links in default main)
|
||||
Version: ${pkg_version}
|
||||
Requires: catch2 = ${pkg_version}
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lCatch2Main
|
||||
11
externals/catch/CMake/catch2.pc.in
vendored
11
externals/catch/CMake/catch2.pc.in
vendored
@@ -1,11 +0,0 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
|
||||
Name: Catch2
|
||||
Description: A modern, C++-native, test framework for C++14 and above
|
||||
URL: https://github.com/catchorg/Catch2
|
||||
Version: @Catch2_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lCatch2
|
||||
56
externals/catch/CMake/llvm-cov-wrapper
vendored
56
externals/catch/CMake/llvm-cov-wrapper
vendored
@@ -1,56 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This file is part of CMake-codecov.
|
||||
#
|
||||
# Copyright (c)
|
||||
# 2015-2017 RWTH Aachen University, Federal Republic of Germany
|
||||
#
|
||||
# See the LICENSE file in the package base directory for details
|
||||
#
|
||||
# Written by Alexander Haase, alexander.haase@rwth-aachen.de
|
||||
#
|
||||
|
||||
if [ -z "$LLVM_COV_BIN" ]
|
||||
then
|
||||
echo "LLVM_COV_BIN not set!" >& 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Get LLVM version to find out.
|
||||
LLVM_VERSION=$($LLVM_COV_BIN -version | grep -i "LLVM version" \
|
||||
| sed "s/^\([A-Za-z ]*\)\([0-9]\).\([0-9]\).*$/\2.\3/g")
|
||||
|
||||
if [ "$1" = "-v" ]
|
||||
then
|
||||
echo "llvm-cov-wrapper $LLVM_VERSION"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$LLVM_VERSION" ]
|
||||
then
|
||||
MAJOR=$(echo $LLVM_VERSION | cut -d'.' -f1)
|
||||
MINOR=$(echo $LLVM_VERSION | cut -d'.' -f2)
|
||||
|
||||
if [ $MAJOR -eq 3 ] && [ $MINOR -le 4 ]
|
||||
then
|
||||
if [ -f "$1" ]
|
||||
then
|
||||
filename=$(basename "$1")
|
||||
extension="${filename##*.}"
|
||||
|
||||
case "$extension" in
|
||||
"gcno") exec $LLVM_COV_BIN --gcno="$1" ;;
|
||||
"gcda") exec $LLVM_COV_BIN --gcda="$1" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $MAJOR -eq 3 ] && [ $MINOR -le 5 ]
|
||||
then
|
||||
exec $LLVM_COV_BIN $@
|
||||
fi
|
||||
fi
|
||||
|
||||
exec $LLVM_COV_BIN gcov $@
|
||||
202
externals/catch/CMakeLists.txt
vendored
202
externals/catch/CMakeLists.txt
vendored
@@ -1,202 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# detect if Catch is being bundled,
|
||||
# disable testsuite in that case
|
||||
if(NOT DEFINED PROJECT_NAME)
|
||||
set(NOT_SUBPROJECT ON)
|
||||
else()
|
||||
set(NOT_SUBPROJECT OFF)
|
||||
endif()
|
||||
|
||||
option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
|
||||
option(CATCH_INSTALL_EXTRAS "Install extras (CMake scripts, debugger helpers) alongside library" ON)
|
||||
option(CATCH_DEVELOPMENT_BUILD "Build tests, enable warnings, enable Werror, etc" OFF)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
cmake_dependent_option(CATCH_BUILD_TESTING "Build the SelfTest project" ON "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_EXAMPLES "Build code examples" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_FUZZERS "Build fuzzers" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_WERROR "Enables Werror during build" ON "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_SURROGATES "Enable generating and building surrogate TUs for the main headers" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_CONFIGURE_TESTS "Enable CMake configuration tests. WARNING: VERY EXPENSIVE" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_CMAKE_HELPER_TESTS "Enable CMake helper tests. WARNING: VERY EXPENSIVE" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
|
||||
|
||||
# Catch2's build breaks if done in-tree. You probably should not build
|
||||
# things in tree anyway, but we can allow projects that include Catch2
|
||||
# as a subproject to build in-tree as long as it is not in our tree.
|
||||
if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt")
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.5.0 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||
# we do not target yet.
|
||||
# HOMEPAGE_URL "https://github.com/catchorg/Catch2"
|
||||
DESCRIPTION "A modern, C++-native, unit test framework."
|
||||
)
|
||||
|
||||
|
||||
# Provide path for scripts. We first add path to the scripts we don't use,
|
||||
# but projects including us might, and set the path up to parent scope.
|
||||
# Then we also add path that we use to configure the project, but is of
|
||||
# no use to top level projects.
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/extras")
|
||||
if (NOT NOT_SUBPROJECT)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
|
||||
endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CatchConfigOptions)
|
||||
if(CATCH_DEVELOPMENT_BUILD)
|
||||
include(CTest)
|
||||
endif()
|
||||
|
||||
# This variable is used in some subdirectories, so we need it here, rather
|
||||
# than later in the install block
|
||||
set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
|
||||
|
||||
# We have some Windows builds that test `wmain` entry point,
|
||||
# and we need this change to be present in all binaries that
|
||||
# are built during these tests, so this is required here, before
|
||||
# the subdirectories are added.
|
||||
if(CATCH_TEST_USE_WMAIN)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
|
||||
endif()
|
||||
|
||||
|
||||
# Basic paths
|
||||
set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(SOURCES_DIR ${CATCH_DIR}/src/catch2)
|
||||
set(SELF_TEST_DIR ${CATCH_DIR}/tests/SelfTest)
|
||||
set(BENCHMARK_DIR ${CATCH_DIR}/tests/Benchmark)
|
||||
set(EXAMPLES_DIR ${CATCH_DIR}/examples)
|
||||
|
||||
# We need to bring-in the variables defined there to this scope
|
||||
add_subdirectory(src)
|
||||
|
||||
# Build tests only if requested
|
||||
if (BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT)
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
if (NOT PYTHONINTERP_FOUND)
|
||||
message(FATAL_ERROR "Python not found, but required for tests")
|
||||
endif()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(CATCH_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(CATCH_BUILD_EXTRA_TESTS)
|
||||
add_subdirectory(tests/ExtraTests)
|
||||
endif()
|
||||
|
||||
if(CATCH_BUILD_FUZZERS)
|
||||
add_subdirectory(fuzzing)
|
||||
endif()
|
||||
|
||||
if (CATCH_DEVELOPMENT_BUILD)
|
||||
add_warnings_to_targets("${CATCH_WARNING_TARGETS}")
|
||||
endif()
|
||||
|
||||
# Only perform the installation steps when Catch is not being used as
|
||||
# a subproject via `add_subdirectory`, or the destinations will break,
|
||||
# see https://github.com/catchorg/Catch2/issues/1373
|
||||
if (NOT_SUBPROJECT)
|
||||
configure_package_config_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/CMake/Catch2Config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake
|
||||
INSTALL_DESTINATION
|
||||
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||
)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
||||
COMPATIBILITY
|
||||
SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
|
||||
DESTINATION
|
||||
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||
)
|
||||
|
||||
# Install documentation
|
||||
if(CATCH_INSTALL_DOCS)
|
||||
install(
|
||||
DIRECTORY
|
||||
docs/
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_DOCDIR}"
|
||||
PATTERN "doxygen" EXCLUDE
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CATCH_INSTALL_EXTRAS)
|
||||
# Install CMake scripts
|
||||
install(
|
||||
FILES
|
||||
"extras/ParseAndAddCatchTests.cmake"
|
||||
"extras/Catch.cmake"
|
||||
"extras/CatchAddTests.cmake"
|
||||
"extras/CatchShardTests.cmake"
|
||||
"extras/CatchShardTestsImpl.cmake"
|
||||
DESTINATION
|
||||
${CATCH_CMAKE_CONFIG_DESTINATION}
|
||||
)
|
||||
|
||||
# Install debugger helpers
|
||||
install(
|
||||
FILES
|
||||
"extras/gdbinit"
|
||||
"extras/lldbinit"
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATAROOTDIR}/Catch2
|
||||
)
|
||||
endif()
|
||||
|
||||
## Provide some pkg-config integration
|
||||
set(PKGCONFIG_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
|
||||
CACHE PATH "Path where catch2.pc is installed"
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/catch2.pc
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2-with-main.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/catch2-with-main.pc
|
||||
@ONLY
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/catch2.pc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/catch2-with-main.pc"
|
||||
DESTINATION
|
||||
${PKGCONFIG_INSTALL_DIR}
|
||||
)
|
||||
|
||||
# CPack/CMake started taking the package version from project version 3.12
|
||||
# So we need to set the version manually for older CMake versions
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
|
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "https://github.com/catchorg/Catch2/")
|
||||
|
||||
|
||||
include( CPack )
|
||||
|
||||
endif(NOT_SUBPROJECT)
|
||||
26
externals/catch/CMakePresets.json
vendored
26
externals/catch/CMakePresets.json
vendored
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "basic-tests",
|
||||
"displayName": "Basic development build",
|
||||
"description": "Enables development build with basic tests that are cheap to build and run",
|
||||
"cacheVariables": {
|
||||
"CATCH_DEVELOPMENT_BUILD": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "all-tests",
|
||||
"inherits": "basic-tests",
|
||||
"displayName": "Full development build",
|
||||
"description": "Enables development build with examples and ALL tests",
|
||||
"cacheVariables": {
|
||||
"CATCH_BUILD_EXAMPLES": "ON",
|
||||
"CATCH_BUILD_EXTRA_TESTS": "ON",
|
||||
"CATCH_BUILD_SURROGATES": "ON",
|
||||
"CATCH_ENABLE_CONFIGURE_TESTS": "ON",
|
||||
"CATCH_ENABLE_CMAKE_HELPER_TESTS": "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
46
externals/catch/CODE_OF_CONDUCT.md
vendored
46
externals/catch/CODE_OF_CONDUCT.md
vendored
@@ -1,46 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at github@philnash.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
2484
externals/catch/Doxyfile
vendored
2484
externals/catch/Doxyfile
vendored
File diff suppressed because it is too large
Load Diff
23
externals/catch/LICENSE.txt
vendored
23
externals/catch/LICENSE.txt
vendored
@@ -1,23 +0,0 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
103
externals/catch/README.md
vendored
103
externals/catch/README.md
vendored
@@ -1,103 +0,0 @@
|
||||
<a id="top"></a>
|
||||

|
||||
|
||||
[](https://github.com/catchorg/catch2/releases)
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/linux-simple-builds.yml)
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/linux-other-builds.yml)
|
||||
[](https://github.com/catchorg/Catch2/actions/workflows/mac-builds.yml)
|
||||
[](https://ci.appveyor.com/project/catchorg/catch2)
|
||||
[](https://codecov.io/gh/catchorg/Catch2)
|
||||
[](https://godbolt.org/z/EdoY15q9G)
|
||||
[](https://discord.gg/4CWS9zD)
|
||||
|
||||
|
||||
## What is Catch2?
|
||||
|
||||
Catch2 is mainly a unit testing framework for C++, but it also
|
||||
provides basic micro-benchmarking features, and simple BDD macros.
|
||||
|
||||
Catch2's main advantage is that using it is both simple and natural.
|
||||
Test names do not have to be valid identifiers, assertions look like
|
||||
normal C++ boolean expressions, and sections provide a nice and local way
|
||||
to share set-up and tear-down code in tests.
|
||||
|
||||
**Example unit test**
|
||||
```cpp
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t factorial( uint32_t number ) {
|
||||
return number <= 1 ? number : factorial(number-1) * number;
|
||||
}
|
||||
|
||||
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||
REQUIRE( factorial( 1) == 1 );
|
||||
REQUIRE( factorial( 2) == 2 );
|
||||
REQUIRE( factorial( 3) == 6 );
|
||||
REQUIRE( factorial(10) == 3'628'800 );
|
||||
}
|
||||
```
|
||||
|
||||
**Example microbenchmark**
|
||||
```cpp
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/benchmark/catch_benchmark.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint64_t fibonacci(uint64_t number) {
|
||||
return number < 2 ? number : fibonacci(number - 1) + fibonacci(number - 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Benchmark Fibonacci", "[!benchmark]") {
|
||||
REQUIRE(fibonacci(5) == 5);
|
||||
|
||||
REQUIRE(fibonacci(20) == 6'765);
|
||||
BENCHMARK("fibonacci 20") {
|
||||
return fibonacci(20);
|
||||
};
|
||||
|
||||
REQUIRE(fibonacci(25) == 75'025);
|
||||
BENCHMARK("fibonacci 25") {
|
||||
return fibonacci(25);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
_Note that benchmarks are not run by default, so you need to run it explicitly
|
||||
with the `[!benchmark]` tag._
|
||||
|
||||
|
||||
## Catch2 v3 has been released!
|
||||
|
||||
You are on the `devel` branch, where the v3 version is being developed.
|
||||
v3 brings a bunch of significant changes, the big one being that Catch2
|
||||
is no longer a single-header library. Catch2 now behaves as a normal
|
||||
library, with multiple headers and separately compiled implementation.
|
||||
|
||||
The documentation is slowly being updated to take these changes into
|
||||
account, but this work is currently still ongoing.
|
||||
|
||||
For migrating from the v2 releases to v3, you should look at [our
|
||||
documentation](docs/migrate-v2-to-v3.md#top). It provides a simple
|
||||
guidelines on getting started, and collects most common migration
|
||||
problems.
|
||||
|
||||
For the previous major version of Catch2 [look into the `v2.x` branch
|
||||
here on GitHub](https://github.com/catchorg/Catch2/tree/v2.x).
|
||||
|
||||
|
||||
## How to use it
|
||||
This documentation comprises these three parts:
|
||||
|
||||
* [Why do we need yet another C++ Test Framework?](docs/why-catch.md#top)
|
||||
* [Tutorial](docs/tutorial.md#top) - getting started
|
||||
* [Reference section](docs/Readme.md#top) - all the details
|
||||
|
||||
|
||||
## More
|
||||
* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
|
||||
* For discussion or questions please use [our Discord](https://discord.gg/4CWS9zD)
|
||||
* See who else is using Catch2 in [Open Source Software](docs/opensource-users.md#top)
|
||||
or [commercially](docs/commercial-users.md#top).
|
||||
19
externals/catch/SECURITY.md
vendored
19
externals/catch/SECURITY.md
vendored
@@ -1,19 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
* Versions 1.x (branch Catch1.x) are no longer supported.
|
||||
* Versions 2.x (branch v2.x) are currently supported.
|
||||
* `devel` branch serves for stable-ish development and is supported,
|
||||
but branches `devel-*` are considered short lived and are not supported separately.
|
||||
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Due to its nature as a _unit_ test framework, Catch2 shouldn't interact
|
||||
with untrusted inputs and there shouldn't be many security vulnerabilities
|
||||
in it.
|
||||
|
||||
However, if you find one you send email to martin <dot> horenovsky <at>
|
||||
gmail <dot> com. If you want to encrypt the email, my pgp key is
|
||||
`E29C 46F3 B8A7 5028 6079 3B7D ECC9 C20E 314B 2360`.
|
||||
16
externals/catch/WORKSPACE.bazel
vendored
16
externals/catch/WORKSPACE.bazel
vendored
@@ -1,16 +0,0 @@
|
||||
workspace(name = "catch2")
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
|
||||
|
||||
bazel_skylib_workspace()
|
||||
72
externals/catch/appveyor.yml
vendored
72
externals/catch/appveyor.yml
vendored
@@ -1,72 +0,0 @@
|
||||
version: "{build}-{branch}"
|
||||
|
||||
# If we ever get a backlog larger than clone_depth, builds will fail
|
||||
# spuriously. I do not think we will ever get 20 deep commits deep though.
|
||||
clone_depth: 20
|
||||
|
||||
# We want to build everything, except for branches that are explicitly
|
||||
# for messing around with travis.
|
||||
branches:
|
||||
except:
|
||||
- /dev-travis.+/
|
||||
|
||||
|
||||
# We need a more up to date pip because Python 2.7 is EOL soon
|
||||
init:
|
||||
- set PATH=C:\Python35;C:\Python35\Scripts;%PATH%
|
||||
|
||||
|
||||
install:
|
||||
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { pip --disable-pip-version-check install codecov }
|
||||
# This removes our changes to PATH. Keep this step last!
|
||||
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { .\tools\misc\installOpenCppCoverage.ps1 }
|
||||
|
||||
|
||||
before_build:
|
||||
# We need to modify PATH again, because it was reset since the "init" step
|
||||
- set PATH=C:\Python35;C:\Python35\Scripts;%PATH%
|
||||
- set CXXFLAGS=%additional_flags%
|
||||
# If we are building examples/extra-tests, we need to regenerate the amalgamated files
|
||||
- cmd: if "%examples%"=="1" ( python .\tools\scripts\generateAmalgamatedFiles.py )
|
||||
# Indirection because appveyor doesn't handle multiline batch scripts properly
|
||||
# https://stackoverflow.com/questions/37627248/how-to-split-a-command-over-multiple-lines-in-appveyor-yml/37647169#37647169
|
||||
# https://help.appveyor.com/discussions/questions/3888-multi-line-cmd-or-powershell-warning-ignore
|
||||
- cmd: .\tools\misc\appveyorBuildConfigurationScript.bat
|
||||
|
||||
|
||||
# build with MSBuild
|
||||
build:
|
||||
project: Build\Catch2.sln # path to Visual Studio solution or project
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
verbosity: normal # MSBuild verbosity level {quiet|minimal|normal|detailed}
|
||||
|
||||
test_script:
|
||||
- set CTEST_OUTPUT_ON_FAILURE=1
|
||||
- cmd: .\tools\misc\appveyorTestRunScript.bat
|
||||
|
||||
|
||||
# Sadly we cannot use the standard "dimensions" based approach towards
|
||||
# specifying the different builds, as there is no way to add one-offs
|
||||
# builds afterwards. This means that we will painfully specify each
|
||||
# build explicitly.
|
||||
environment:
|
||||
matrix:
|
||||
- FLAVOR: VS 2019 x64 Debug Coverage Examples
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
examples: 1
|
||||
coverage: 1
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2019 x64 Debug WMain
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
wmain: 1
|
||||
additional_flags: "/D_UNICODE /DUNICODE"
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2019 x64 Debug Latest Strict
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
22
externals/catch/codecov.yml
vendored
22
externals/catch/codecov.yml
vendored
@@ -1,22 +0,0 @@
|
||||
coverage:
|
||||
precision: 2
|
||||
round: nearest
|
||||
range: "60...90"
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 2%
|
||||
patch:
|
||||
default:
|
||||
target: 80%
|
||||
ignore:
|
||||
- "**/external/clara.hpp"
|
||||
- "tests"
|
||||
|
||||
|
||||
codecov:
|
||||
branch: devel
|
||||
max_report_age: off
|
||||
|
||||
comment:
|
||||
layout: "diff"
|
||||
60
externals/catch/conanfile.py
vendored
60
externals/catch/conanfile.py
vendored
@@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
from conans import ConanFile, CMake, tools
|
||||
|
||||
class CatchConan(ConanFile):
|
||||
name = "catch2"
|
||||
description = "A modern, C++-native, framework for unit-tests, TDD and BDD"
|
||||
topics = ("conan", "catch2", "unit-test", "tdd", "bdd")
|
||||
url = "https://github.com/catchorg/Catch2"
|
||||
homepage = url
|
||||
license = "BSL-1.0"
|
||||
|
||||
exports = "LICENSE.txt"
|
||||
exports_sources = ("src/*", "CMakeLists.txt", "CMake/*", "extras/*")
|
||||
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
|
||||
generators = "cmake"
|
||||
|
||||
def _configure_cmake(self):
|
||||
cmake = CMake(self)
|
||||
cmake.definitions["BUILD_TESTING"] = "OFF"
|
||||
cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
|
||||
cmake.definitions["CATCH_INSTALL_EXTRAS"] = "ON"
|
||||
cmake.configure(build_folder="build")
|
||||
return cmake
|
||||
|
||||
def build(self):
|
||||
# We need this workaround until the toolchains feature
|
||||
# to inject stuff like MD/MT
|
||||
line_to_replace = 'list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")'
|
||||
tools.replace_in_file("CMakeLists.txt", line_to_replace,
|
||||
'''{}
|
||||
include("{}/conanbuildinfo.cmake")
|
||||
conan_basic_setup()'''.format(line_to_replace, self.install_folder.replace("\\", "/")))
|
||||
|
||||
cmake = self._configure_cmake()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
self.copy(pattern="LICENSE.txt", dst="licenses")
|
||||
cmake = self._configure_cmake()
|
||||
cmake.install()
|
||||
|
||||
def package_info(self):
|
||||
lib_suffix = "d" if self.settings.build_type == "Debug" else ""
|
||||
|
||||
self.cpp_info.names["cmake_find_package"] = "Catch2"
|
||||
self.cpp_info.names["cmake_find_package_multi"] = "Catch2"
|
||||
# Catch2
|
||||
self.cpp_info.components["catch2base"].names["cmake_find_package"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].names["cmake_find_package_multi"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].names["pkg_config"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix]
|
||||
self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2")
|
||||
# Catch2WithMain
|
||||
self.cpp_info.components["catch2main"].names["cmake_find_package"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].names["cmake_find_package_multi"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].names["pkg_config"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].libs = ["Catch2Main" + lib_suffix]
|
||||
self.cpp_info.components["catch2main"].requires = ["catch2base"]
|
||||
BIN
externals/catch/data/artwork/catch2-c-logo.png
vendored
BIN
externals/catch/data/artwork/catch2-c-logo.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user