Switch to standalone sysroot for semantics compilation

This commit is contained in:
Duncan Ogilvie
2025-11-05 20:46:01 -05:00
committed by Kyle Elliott
parent 50ac24a35d
commit ac78aa9dca
26 changed files with 543 additions and 62 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ compile_commands.json
.cache
deps/*
third_party/*
build/*
build*/
remill-build/*
generated/*
gtest_build/*
+19 -19
View File
@@ -2,11 +2,13 @@
# compiler detection
#
if(DEFINED CMAKE_OSX_SYSROOT)
set(EXTRA_BC_SYSROOT -isysroot ${CMAKE_OSX_SYSROOT})
endif()
# NOTE: This is a fake sysroot, with just enough to build the semantics
set(BC_SYSROOT "${PROJECT_SOURCE_DIR}/include/remill/Arch/Runtime/sysroot")
set(DEFAULT_BC_COMPILER_FLAGS
"--sysroot=${BC_SYSROOT}"
-nostdinc++
-isystem "${BC_SYSROOT}"
-emit-llvm -Wno-unknown-warning-option -Wall -Wshadow
-Wconversion -Wpadded -pedantic -Wshorten-64-to-32 -Wgnu-alignof-expression
-Wno-gnu-anonymous-struct -Wno-return-type-c-linkage
@@ -19,7 +21,6 @@ set(DEFAULT_BC_COMPILER_FLAGS
-Wno-unused-function -Wgnu-inline-cpp-without-extern
-Wno-pass-failed=transform-warning
-std=c++17
${EXTRA_BC_SYSROOT}
)
find_package(Clang CONFIG REQUIRED)
@@ -52,6 +53,8 @@ endif()
set(add_runtime_usage "add_runtime(target_name SOURCES <src1 src2> ADDRESS_SIZE <size> DEFINITIONS <def1 def2> BCFLAGS <bcflag1 bcflag2> LINKERFLAGS <lnkflag1 lnkflag2> INCLUDEDIRECTORIES <path1 path2> INSTALLDESTINATION <path> DEPENDENCIES <dependency1 dependency2>")
function(add_runtime target_name)
set(BUILD_COMMANDS "")
if(NOT DEFINED CMAKE_BC_COMPILER)
message(FATAL_ERROR "The bitcode compiler was not found!")
endif()
@@ -176,28 +179,22 @@ function(add_runtime target_name)
set(additional_windows_settings "-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH")
endif()
# The hyper call implementation contains inline assembly for each architecture so we'll need to
# cross-compile for the runtime architecture.
if(${source_file} STREQUAL ${hyper_call_source})
# Some architectures add an explicit target for the host to successfully
# compile with 32 bits (like AArch64 to arm), however, we don't want that
# to interfere with the hyper call crosscompile
list(FILTER bc_flag_list EXCLUDE REGEX "--target=.*")
set(target_decl "-target" "${arch}-none-eabi")
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(target_decl "-target" "x86_64-apple-macosx11.0.0")
# Only arm32 has eabihf (hard float)
if("${arch}" STREQUAL "arm")
set(target_decl "-target" "${arch}-none-eabihf")
else()
unset(target_decl)
set(target_decl "-target" "${arch}-none-elf")
endif()
add_custom_command(OUTPUT "${absolute_output_file_path}"
COMMAND "${CMAKE_BC_COMPILER}" ${include_directory_list} ${additional_windows_settings} ${target_decl} "-DADDRESS_SIZE_BITS=${address_size}" ${definition_list} ${DEFAULT_BC_COMPILER_FLAGS} ${bc_flag_list} ${source_file_option_list} -c "${absolute_source_file_path}" -o "${absolute_output_file_path}"
COMMAND "${CMAKE_BC_COMPILER}" ${include_directory_list} ${additional_windows_settings} ${target_decl} "-DADDRESS_SIZE_BITS=${address_size}" ${definition_list} ${DEFAULT_BC_COMPILER_FLAGS} ${bc_flag_list} ${source_file_option_list} -c "${absolute_source_file_path}" -o "${absolute_output_file_path}"
MAIN_DEPENDENCY "${absolute_source_file_path}"
${dependency_list_directive}
COMMENT "Building BC object ${absolute_output_file_path}"
COMMENT "Building BC object: \"${CMAKE_BC_COMPILER}\" ${include_directory_list} ${additional_windows_settings} ${target_decl} \"-DADDRESS_SIZE_BITS=${address_size}\" ${definition_list} ${DEFAULT_BC_COMPILER_FLAGS} ${bc_flag_list} ${source_file_option_list} -c \"${absolute_source_file_path}\" -o \"${absolute_output_file_path}\""
)
set(BUILD_COMMANDS "${BUILD_COMMANDS}\"${CMAKE_BC_COMPILER}\" ${include_directory_list} ${additional_windows_settings} ${target_decl} \"-DADDRESS_SIZE_BITS=${address_size}\" ${definition_list} ${DEFAULT_BC_COMPILER_FLAGS} ${bc_flag_list} ${source_file_option_list} -c \"${absolute_source_file_path}\" -o \"${absolute_output_file_path}\"\n")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${absolute_output_file_path}")
list(APPEND bitcode_file_list "${absolute_output_file_path}")
endforeach()
@@ -213,6 +210,9 @@ function(add_runtime target_name)
DEPENDS ${bitcode_file_list}
COMMENT "Linking BC runtime ${absolute_target_path}"
)
set(BUILD_COMMANDS "${BUILD_COMMANDS}\"${CMAKE_BC_LINKER}\" ${linker_flag_list} ${bitcode_file_list} -o \"${absolute_target_path}\"\n")
string(REPLACE ";" " " BUILD_COMMANDS "${BUILD_COMMANDS}")
file(WRITE "${CMAKE_BINARY_DIR}/runtimes/${target_name}.txt" "${BUILD_COMMANDS}")
set(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${absolute_target_path}")
+1 -1
View File
@@ -35,7 +35,7 @@ class Arch;
struct Register;
class OperandExpression;
enum ArchName : unsigned;
enum ArchName : uint32_t;
struct LLVMOpExpr {
unsigned llvm_opcode;
@@ -0,0 +1,17 @@
#pragma once
namespace std {
// http://www.en.cppreference.com/w/cpp/algorithm/min.html
template <class T>
const T &min(const T &a, const T &b) {
return (b < a) ? b : a;
}
// http://www.en.cppreference.com/w/cpp/algorithm/max.html
template <class T>
const T &max(const T &a, const T &b) {
return (a < b) ? b : a;
}
} // namespace std
+134
View File
@@ -0,0 +1,134 @@
#pragma once
#ifndef __clang__
# error Unsupported compiler!
#endif
// NOTE: These values have to match the hardware for correct semantics
#if defined(__arm__)
# define FE_INVALID 1
# define FE_DIVBYZERO 2
# define FE_OVERFLOW 4
# define FE_UNDERFLOW 8
# define FE_INEXACT 16
# define FE_ALL_EXCEPT 31
# define FE_TONEAREST 0
# define FE_DOWNWARD 0x800000
# define FE_UPWARD 0x400000
# define FE_TOWARDZERO 0xc00000
#elif defined(__aarch64__)
# define FE_INVALID 1
# define FE_DIVBYZERO 2
# define FE_OVERFLOW 4
# define FE_UNDERFLOW 8
# define FE_INEXACT 16
# define FE_ALL_EXCEPT 31
# define FE_TONEAREST 0
# define FE_DOWNWARD 0x800000
# define FE_UPWARD 0x400000
# define FE_TOWARDZERO 0xc00000
#elif defined(__powerpc__)
# define FE_INEXACT 0x02000000
# define FE_DIVBYZERO 0x04000000
# define FE_UNDERFLOW 0x08000000
# define FE_OVERFLOW 0x10000000
# define FE_INVALID 0x20000000
# define FE_ALL_EXCEPT 0x3e000000
# define FE_TONEAREST 0
# define FE_TOWARDZERO 1
# define FE_UPWARD 2
# define FE_DOWNWARD 3
#elif defined(__sparc__)
# define FE_INVALID (1 << 9)
# define FE_OVERFLOW (1 << 8)
# define FE_UNDERFLOW (1 << 7)
# define FE_DIVBYZERO (1 << 6)
# define FE_INEXACT (1 << 5)
# define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
# define FE_TONEAREST (0 << 30)
# define FE_TOWARDZERO (1 << 30)
# define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */
# define FE_DOWNWARD (-0x40000000) /* (3 << 30) */
#elif defined(__sparc64__)
# define FE_INVALID (1 << 9)
# define FE_OVERFLOW (1 << 8)
# define FE_UNDERFLOW (1 << 7)
# define FE_DIVBYZERO (1 << 6)
# define FE_INEXACT (1 << 5)
# define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
# define FE_TONEAREST (0 << 30)
# define FE_TOWARDZERO (1 << 30)
# define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */
# define FE_DOWNWARD (-0x40000000) /* (3 << 30) */
#elif defined(__i386__)
# define FE_INVALID 1
# define __FE_DENORM 2
# define FE_DIVBYZERO 4
# define FE_OVERFLOW 8
# define FE_UNDERFLOW 16
# define FE_INEXACT 32
# define FE_ALL_EXCEPT 63
# define FE_TONEAREST 0
# define FE_DOWNWARD 0x400
# define FE_UPWARD 0x800
# define FE_TOWARDZERO 0xc00
#elif defined(__x86_64__)
# define FE_INVALID 1
# define __FE_DENORM 2
# define FE_DIVBYZERO 4
# define FE_OVERFLOW 8
# define FE_UNDERFLOW 16
# define FE_INEXACT 32
# define FE_ALL_EXCEPT 63
# define FE_TONEAREST 0
# define FE_DOWNWARD 0x400
# define FE_UPWARD 0x800
# define FE_TOWARDZERO 0xc00
#else
# error Unsupported architecture!
#endif
// TODO: actually implement these functions?
namespace std {
// https://en.cppreference.com/w/cpp/numeric/fenv/feround
int fesetround(int round);
int fegetround();
// https://en.cppreference.com/w/cpp/numeric/fenv/fetestexcept
int fetestexcept(int excepts);
// https://en.cppreference.com/w/c/numeric/fenv/feraiseexcept
int feraiseexcept(int excepts);
// https://en.cppreference.com/w/c/numeric/fenv/feclearexcept.html
int feclearexcept(int excepts);
} // namespace std
+96
View File
@@ -0,0 +1,96 @@
#pragma once
// https://en.cppreference.com/w/cpp/numeric/math/FP_categories
#define FP_NAN 0
#define FP_INFINITE 1
#define FP_ZERO 2
#define FP_SUBNORMAL 3
#define FP_NORMAL 4
// https://en.cppreference.com/w/cpp/numeric/math/NAN
#define NAN (__builtin_nanf(""))
namespace std {
// https://en.cppreference.com/w/cpp/numeric/math/signbit
constexpr bool signbit(float __x) {
return __builtin_signbit(__x);
}
constexpr bool signbit(double __x) {
return __builtin_signbit(__x);
}
constexpr bool signbit(long double __x) {
return __builtin_signbit(__x);
}
// https://en.cppreference.com/w/cpp/numeric/math/fpclassify
constexpr int fpclassify(float __x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, __x);
}
constexpr int fpclassify(double __x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, __x);
}
constexpr int fpclassify(long double __x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, __x);
}
// https://en.cppreference.com/w/cpp/numeric/math/isnan
constexpr bool isnan(float num) {
return __builtin_isnan(num);
}
constexpr bool isnan(double num) {
return __builtin_isnan(num);
}
constexpr bool isnan(long double num) {
return __builtin_isnan(num);
}
// https://en.cppreference.com/w/cpp/numeric/math/fabs
constexpr float fabs(float num) {
return __builtin_fabsf(num);
}
constexpr double fabs(double num) {
return __builtin_fabs(num);
}
constexpr long double fabs(long double num) {
return __builtin_fabsl(num);
}
// https://en.cppreference.com/w/cpp/numeric/math/sqrt
constexpr float sqrt(float num) {
return __builtin_sqrtf(num);
}
constexpr double sqrt(double num) {
return __builtin_sqrt(num);
}
constexpr long double sqrt(long double num) {
return __builtin_sqrtl(num);
}
// https://en.cppreference.com/w/cpp/numeric/math/isunordered
constexpr bool isunordered(float x, float y) {
return __builtin_isunordered(x, y);
}
constexpr bool isunordered(double x, double y) {
return __builtin_isunordered(x, y);
}
constexpr bool isunordered(long double x, long double y) {
return __builtin_isunordered(x, y);
}
} // namespace std
@@ -0,0 +1,9 @@
#pragma once
#include <stddef.h>
namespace std {
using size_t = ::size_t;
}
@@ -0,0 +1,3 @@
#pragma once
#include <stdint.h>
@@ -0,0 +1,87 @@
#pragma once
#include <cstdint>
#include <type_traits>
namespace std {
// Type trait to check if T is a fixed-width integer type
template <typename T>
struct is_fixed_width_int : false_type {};
template <>
struct is_fixed_width_int<int8_t> : true_type {};
template <>
struct is_fixed_width_int<int16_t> : true_type {};
template <>
struct is_fixed_width_int<int32_t> : true_type {};
template <>
struct is_fixed_width_int<int64_t> : true_type {};
template <>
struct is_fixed_width_int<uint8_t> : true_type {};
template <>
struct is_fixed_width_int<uint16_t> : true_type {};
template <>
struct is_fixed_width_int<uint32_t> : true_type {};
template <>
struct is_fixed_width_int<uint64_t> : true_type {};
template <typename T>
inline constexpr bool is_fixed_width_int_v = is_fixed_width_int<T>::value;
// Forward declaration
template <typename T, typename Enable = void>
struct numeric_limits;
// Specialization 1: Fixed-width integers (using bit manipulation)
template <typename T>
struct numeric_limits<T,
typename enable_if<is_fixed_width_int<T>::value>::type> {
static constexpr T min() noexcept {
if constexpr (is_unsigned<T>::value) {
return T(0);
} else {
// Signed min: set only the sign bit
return static_cast<T>(T(1) << (sizeof(T) * 8 - 1));
}
}
static constexpr T max() noexcept {
if constexpr (is_unsigned<T>::value) {
// Unsigned max: all bits set
return static_cast<T>(~T(0));
} else {
// Signed max: all bits except sign bit
return static_cast<T>(~min());
}
}
};
// Specialization 2: Floating-point types (float, double, long double)
template <typename T>
struct numeric_limits<T,
typename enable_if<is_floating_point<T>::value>::type> {
// min() returns smallest positive normalized value (standard behavior)
static constexpr T min() noexcept {
if constexpr (is_same<T, float>::value) {
return __FLT_MIN__;
} else if constexpr (is_same<T, double>::value) {
return __DBL_MIN__;
} else { // long double
return __LDBL_MIN__;
}
}
// max() returns largest finite value
static constexpr T max() noexcept {
if constexpr (is_same<T, float>::value) {
return __FLT_MAX__;
} else if constexpr (is_same<T, double>::value) {
return __DBL_MAX__;
} else { // long double
return __LDBL_MAX__;
}
}
};
} // namespace std
@@ -0,0 +1,155 @@
#pragma once
// https://en.cppreference.com/w/cpp/header/type_traits.html
namespace std {
template <class T, T v>
struct integral_constant {
static constexpr T value = v;
using value_type = T;
using type = integral_constant; // using injected-class-name
constexpr operator value_type() const noexcept {
return value;
}
constexpr value_type operator()() const noexcept {
return value;
} // since c++14
};
using true_type = std::integral_constant<bool, true>;
using false_type = std::integral_constant<bool, false>;
template <class T, class U>
struct is_same : std::false_type {};
template <class T>
struct is_same<T, T> : std::true_type {};
template <class T>
struct remove_cv {
typedef T type;
};
template <class T>
struct remove_cv<const T> {
typedef T type;
};
template <class T>
struct remove_cv<volatile T> {
typedef T type;
};
template <class T>
struct remove_cv<const volatile T> {
typedef T type;
};
template <class T>
struct remove_const {
typedef T type;
};
template <class T>
struct remove_const<const T> {
typedef T type;
};
template <class T>
struct remove_volatile {
typedef T type;
};
template <class T>
struct remove_volatile<volatile T> {
typedef T type;
};
template <class T>
struct is_floating_point
: std::integral_constant<
bool,
// Note: standard floating-point types
std::is_same<float, typename std::remove_cv<T>::type>::value ||
std::is_same<double, typename std::remove_cv<T>::type>::value ||
std::is_same<long double,
typename std::remove_cv<T>::type>::value> {};
// Base template - defaults to false
template <typename T>
struct is_integral : std::false_type {};
// Specializations for each integral type (set to true)
template <>
struct is_integral<bool> : std::true_type {};
template <>
struct is_integral<char> : std::true_type {};
template <>
struct is_integral<signed char> : std::true_type {};
template <>
struct is_integral<unsigned char> : std::true_type {};
template <>
struct is_integral<wchar_t> : std::true_type {};
template <>
struct is_integral<char16_t> : std::true_type {};
template <>
struct is_integral<char32_t> : std::true_type {};
template <>
struct is_integral<short> : std::true_type {};
template <>
struct is_integral<unsigned short> : std::true_type {};
template <>
struct is_integral<int> : std::true_type {};
template <>
struct is_integral<unsigned int> : std::true_type {};
template <>
struct is_integral<long> : std::true_type {};
template <>
struct is_integral<unsigned long> : std::true_type {};
template <>
struct is_integral<long long> : std::true_type {};
template <>
struct is_integral<unsigned long long> : std::true_type {};
// Handle cv-qualifiers (const, volatile)
template <typename T>
struct is_integral<const T> : is_integral<T> {};
template <typename T>
struct is_integral<volatile T> : is_integral<T> {};
template <typename T>
struct is_integral<const volatile T> : is_integral<T> {};
template <class T>
struct is_arithmetic
: std::integral_constant<bool, std::is_integral<T>::value ||
std::is_floating_point<T>::value> {};
namespace detail {
template <typename T, bool = std::is_arithmetic<T>::value>
struct is_signed : std::integral_constant<bool, T(-1) < T(0)> {};
template <typename T>
struct is_signed<T, false> : std::false_type {};
} // namespace detail
template <typename T>
struct is_signed : detail::is_signed<T>::type {};
namespace detail {
template <typename T, bool = std::is_arithmetic<T>::value>
struct is_unsigned : std::integral_constant<bool, T(0) < T(-1)> {};
template <typename T>
struct is_unsigned<T, false> : std::false_type {};
} // namespace detail
template <typename T>
struct is_unsigned : detail::is_unsigned<T>::type {};
template <bool B, class T = void>
struct enable_if {};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
} // namespace std
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/AArch32/Runtime/State.h"
-8
View File
@@ -28,14 +28,6 @@ set_source_files_properties(BasicBlock.cpp PROPERTIES COMPILE_FLAGS "-O0 -g3")
function(add_runtime_helper target_name little_endian)
message(" > Generating runtime target: ${target_name}")
# necessary to build code as 32-bit
# on aarch64
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)" AND "${PLATFORM_NAME}" STREQUAL "linux")
set(arch_flags "--target=arm-linux-gnueabihf")
else()
set(arch_flags "-m32")
endif()
add_runtime(${target_name}
SOURCES ${ARMRUNTIME_SOURCEFILES}
ADDRESS_SIZE 32
@@ -15,11 +15,9 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
// clang-format off
#include "remill/Arch/Name.h"
#include "remill/Arch/Runtime/Float.h"
#include "remill/Arch/Runtime/Intrinsics.h"
#include "remill/Arch/Runtime/Operators.h"
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/AArch64/Runtime/State.h"
@@ -15,11 +15,9 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
// clang-format off
#include "remill/Arch/Name.h"
#include "remill/Arch/Runtime/Float.h"
#include "remill/Arch/Runtime/Intrinsics.h"
#include "remill/Arch/Runtime/Operators.h"
+2 -2
View File
@@ -436,14 +436,14 @@ DEF_SEM(FCMP_DZ, V64 src1) {
DEF_SEM(FABS_S, V128W dst, V32 src) {
auto val = FExtractV32(FReadV32(src), 0);
auto result = static_cast<float32_t>(fabs(val));
auto result = static_cast<float32_t>(std::fabs(val));
FWriteV32(dst, result);
return memory;
}
DEF_SEM(FABS_D, V128W dst, V64 src) {
auto val = FExtractV64(FReadV64(src), 0);
auto result = static_cast<float64_t>(fabs(val));
auto result = static_cast<float64_t>(std::fabs(val));
FWriteV64(dst, result);
return memory;
}
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/Runtime/Float.h"
+1 -9
View File
@@ -32,19 +32,11 @@ endif(REMILL_BARRIER_AS_NOP)
function(add_runtime_helper target_name little_endian)
message(" > Generating runtime target: ${target_name}")
# necessary to build code as 32-bit
# on aarch64
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)" AND "${PLATFORM_NAME}" STREQUAL "linux")
set(arch_flags "--target=arm-linux-gnueabihf")
else()
set(arch_flags "-m32")
endif()
add_runtime(${target_name}
SOURCES ${SPARC32RUNTIME_SOURCEFILES}
ADDRESS_SIZE 32
DEFINITIONS "LITTLE_ENDIAN=${little_endian}" "REMILL_DISABLE_INT128=1"
BCFLAGS "${arch_flags}" "${EXTRA_BC_FLAGS}"
BCFLAGS "${EXTRA_BC_FLAGS}"
INCLUDEDIRECTORIES "${REMILL_INCLUDE_DIR}" "${REMILL_SOURCE_DIR}"
INSTALLDESTINATION "${REMILL_INSTALL_SEMANTICS_DIR}"
ARCH sparc
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/Runtime/Float.h"
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/Runtime/Float.h"
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/Runtime/Float.h"
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include "remill/Arch/Runtime/Float.h"
+1
View File
@@ -41,6 +41,7 @@ function(add_runtime_helper target_name address_bit_size enable_avx enable_avx51
INCLUDEDIRECTORIES "${REMILL_INCLUDE_DIR}" "${REMILL_SOURCE_DIR}"
INSTALLDESTINATION "${REMILL_INSTALL_SEMANTICS_DIR}"
ARCH ${x86_arch}
BCFLAGS -mlong-double-80
DEPENDENCIES
"${REMILL_INCLUDE_DIR}/remill/Arch/Runtime/Float.h"
-1
View File
@@ -15,7 +15,6 @@
*/
#include <algorithm>
#include <bitset>
#include <cmath>
// clang-format off
+13 -6
View File
@@ -662,19 +662,26 @@ union StringCompareControl {
static_assert(1 == sizeof(StringCompareControl),
"Invalid packing of `StringCompareControl`.");
// https://godbolt.org/z/fa4vGfoxd
template <size_t x, size_t y>
class BitMatrix : std::bitset<x * y> {
class BitMatrix {
public:
ALWAYS_INLINE bool Test(size_t i, size_t j) const {
return this->operator[]((x * i) + j);
size_t pos = (x * i) + j;
return (data[pos / 8] >> (pos % 8)) & 1;
}
ALWAYS_INLINE void Set(size_t i, size_t j, bool val) {
this->operator[]((x * i) + j) = val;
size_t pos = (x * i) + j;
if (val) {
data[pos / 8] |= (uint8_t(1) << (pos % 8));
} else {
data[pos / 8] &= ~(uint8_t(1) << (pos % 8));
}
}
private:
bool rows[x][y];
uint8_t data[(x * y + 7) / 8] = {};
};
// src1 is a char set, src2 is a string. We set a bit of `int_res_1` to `1`
@@ -2011,7 +2018,7 @@ DEF_SEM(LDMXCSR, M32 src) {
} else {
rounding_mode = FE_TOWARDZERO;
}
fesetround(rounding_mode);
std::fesetround(rounding_mode);
// TODO: set FPU precision based on MXCSR precision flag (csr.pe)
@@ -2025,7 +2032,7 @@ DEF_SEM(STMXCSR, M32W dst) {
csr.pe = 0;
// Store the current FPU rounding mode:
switch (fegetround()) {
switch (std::fegetround()) {
default:
case FE_TONEAREST:
csr.rp = 0;
+4 -4
View File
@@ -400,12 +400,12 @@ DEF_FPU_SEM(FPU_NOP) {
}
DEF_SEM(DoFWAIT) {
feraiseexcept(fetestexcept(FE_ALL_EXCEPT));
std::feraiseexcept(std::fetestexcept(FE_ALL_EXCEPT));
return memory;
}
DEF_SEM(DoFNCLEX) {
feclearexcept(FE_ALL_EXCEPT);
std::feclearexcept(FE_ALL_EXCEPT);
state.sw.pe = 0;
state.sw.ue = 0;
state.sw.oe = 0;
@@ -1311,7 +1311,7 @@ DEF_SEM(FNSTCW, M16W dst) {
auto &cw = state.x87.fxsave.cwd;
cw.pc = kPrecisionSingle;
switch (fegetround()) {
switch (std::fegetround()) {
default:
case FE_TONEAREST: cw.rc = kFPURoundToNearestEven; break;
case FE_DOWNWARD: cw.rc = kFPURoundDownNegInf; break;
@@ -1336,7 +1336,7 @@ DEF_SEM(FLDCW, M16 cwd) {
case kFPURoundToZero: rounding_mode = FE_TOWARDZERO; break;
}
fesetround(rounding_mode);
std::fesetround(rounding_mode);
return memory;
}