mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
Switch to standalone sysroot for semantics compilation
This commit is contained in:
committed by
Kyle Elliott
parent
50ac24a35d
commit
ac78aa9dca
+1
-1
@@ -28,7 +28,7 @@ compile_commands.json
|
||||
.cache
|
||||
deps/*
|
||||
third_party/*
|
||||
build/*
|
||||
build*/
|
||||
remill-build/*
|
||||
generated/*
|
||||
gtest_build/*
|
||||
|
||||
+19
-19
@@ -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}")
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
|
||||
#include "remill/Arch/AArch32/Runtime/State.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
|
||||
#include "remill/Arch/Runtime/Float.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
|
||||
#include "remill/Arch/Runtime/Float.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user