Skip to content

Commit

Permalink
+ move fp operand feature to Imm ctor
Browse files Browse the repository at this point in the history
  • Loading branch information
psi-func committed Sep 5, 2024
1 parent 9887eb7 commit 2f91206
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 51 deletions.
6 changes: 6 additions & 0 deletions src/libtriton/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ set(LIBTRITON_SOURCE_FILES
stubs/x8664-ms-libc.cpp
stubs/x8664-systemv-libc.cpp
utils/coreUtils.cpp
utils/softfloat.cpp
)

# Define all header files
Expand Down Expand Up @@ -106,6 +107,7 @@ set(LIBTRITON_HEADER_FILES
includes/triton/comparableFunctor.hpp
includes/triton/context.hpp
includes/triton/coreUtils.hpp
includes/triton/softfloat.hpp
includes/triton/cpuInterface.hpp
includes/triton/cpuSize.hpp
includes/triton/dllexport.hpp
Expand Down Expand Up @@ -157,6 +159,10 @@ set(LIBTRITON_HEADER_FILES
includes/triton/z3ToTriton.hpp
)

set_source_files_properties(utils/softfloat.cpp PROPERTIES COMPILE_DEFINITIONS
${CMAKE_CXX_BYTE_ORDER}
)

# Define all resource files
set(LIBTRITON_RESOURCE_FILES
includes/triton/version.hpp.in
Expand Down
51 changes: 1 addition & 50 deletions src/libtriton/arch/arm/aarch64/aarch64Cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,56 +536,7 @@ namespace triton {
throw triton::exceptions::Disassembly("Aarch64Cpu::disassembly(): Cannot correctly decode FP operand");
}

auto encode_fp_imm = [size](double fp_value) {
static_assert(sizeof(float) == sizeof(triton::uint32), "Unexpected float type size");
static_assert(sizeof(double) == sizeof(triton::uint64), "Unexpected double type size");

auto IEEE754_f32_to_f16 = [](float value) -> uint16_t {
uint32_t f;
std::memcpy(&f, &value, sizeof(uint32_t));
uint16_t sign = (f >> 16) & 0x8000;
int16_t exponent = ((f >> 23) & 0xff) - 127 + 15;
uint16_t mantissa = (f >> 13) & 0x3ff;

if (exponent <= 0) {
if (exponent < -10) {
return sign;
}
mantissa = (mantissa | 0x400) >> (1 - exponent);
return sign | mantissa;
} else if (exponent == 0xff - (127 - 15)) {
if (mantissa) {
return sign | 0x7fff;
} else {
return sign | 0x7c00;
}
} else if (exponent > 30) {
return sign | 0x7c00;
}
return sign | (exponent << 10) | mantissa;
};

if (size == sizeof(double)) {
triton::uint64 result;
std::memcpy(&result, &fp_value, sizeof(double));
return result;
}
else if (size == sizeof(float)) {
float converted = static_cast<float>(fp_value);
triton::uint32 conv_repr;
std::memcpy(&conv_repr, &converted, sizeof(float));
// just zero extended value
return static_cast<triton::uint64>(conv_repr);
}
else if (size == 2) { // half-precision
float value = static_cast<float>(fp_value);
return static_cast<triton::uint64>(IEEE754_f32_to_f16(value));
}

throw triton::exceptions::Disassembly("AArch64Cpu::disassembly(): Invalid operand.");
};

Immediate imm{encode_fp_imm(op->fp), size};
Immediate imm{op->fp, size, this->getEndianness()};

/* Set Shift type and value */
imm.setShiftType(this->capstoneShiftToTritonShift(op->shift.type));
Expand Down
45 changes: 44 additions & 1 deletion src/libtriton/arch/immediate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
** This program is under the terms of the Apache License 2.0.
*/

#include <triton/immediate.hpp>
#include <triton/cpuSize.hpp>
#include <triton/exceptions.hpp>
#include <triton/immediate.hpp>
#include <triton/softfloat.hpp>
#include <triton/coreUtils.hpp>

#ifdef LITTLE_ENDIAN // provided by CMake
constexpr auto sys_endianness = triton::arch::LE_ENDIANNESS;
#else
constexpr auto sys_endianness = triton::arch::BE_ENDIANNESS;
#endif


namespace triton {
Expand All @@ -23,6 +30,42 @@ namespace triton {
this->setValue(value, size);
}

Immediate::Immediate(double value, triton::uint32 size /* bytes */, triton::arch::endianness_e platform_endianness) {
triton::uint64 imm_value;

auto need_swap = sys_endianness != platform_endianness;

if (size == sizeof(double)) {
static_assert(sizeof(double) == sizeof(triton::uint64),
"Unexpected double type size");
std::memcpy(&imm_value, &value, sizeof(double));
if (need_swap) {
imm_value = utils::byteswap(imm_value);
}
}
else if (size == sizeof(float)) { // single-precision
float fvalue = static_cast<float>(value);
triton::uint32 repr;
static_assert(sizeof(float) == sizeof(uint32_t),
"Unexpected float type size");
std::memcpy(&repr, &fvalue, sizeof(float));

imm_value = need_swap ? static_cast<triton::uint64>(utils::byteswap(repr))
: static_cast<triton::uint64>(repr);
} else if (size == 2) { // half-precision
float fvalue = static_cast<float>(value);
triton::uint16 repr = sf::f32_to_f16(fvalue);
imm_value = need_swap ? static_cast<triton::uint64>(utils::byteswap(repr))
: static_cast<triton::uint64>(repr);

}
else {
throw triton::exceptions::Immediate("Immediate::Immediate(double): Invalid encoding size.");
}

this->setValue(imm_value, size);
}


Immediate::Immediate(const Immediate& other)
: BitsVector(other),
Expand Down
14 changes: 14 additions & 0 deletions src/libtriton/includes/triton/coreUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <sstream>
#include <string>
#include <algorithm>
#include <type_traits>

#include <triton/config.hpp>
Expand Down Expand Up @@ -81,6 +82,19 @@ namespace triton {
template <> TRITON_EXPORT triton::uint80 cast(const triton::uint512& value);
template <> TRITON_EXPORT triton::uint512 cast(const triton::uint80& value);

template <typename T>
std::enable_if_t<
std::is_unsigned_v<T>,
T>
byteswap(T value) {
std::array<std::byte, sizeof(value)> repr;
std::memcpy(&repr, &value, sizeof(value));
std::reverse(repr.begin(), repr.end());
T result;
std::memcpy(&result, &repr, sizeof(result));
return result;
}

/*! @} End of utils namespace */
};
/*! @} End of triton namespace */
Expand Down
3 changes: 3 additions & 0 deletions src/libtriton/includes/triton/immediate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ namespace triton {
//! Constructor.
TRITON_EXPORT Immediate(triton::uint64 value, triton::uint32 size /* bytes*/);

//! Constructor.
TRITON_EXPORT Immediate(double value, triton::uint32 size /* bytes */, triton::arch::endianness_e platform_endianness);

//! Constructor by copy.
TRITON_EXPORT Immediate(const Immediate& other);

Expand Down
34 changes: 34 additions & 0 deletions src/libtriton/includes/triton/softfloat.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! \file
/*
** Copyright (C) - Triton
**
** This program is under the terms of the Apache License 2.0.
*/

#ifndef TRITON_SOFTFLOAT_HPP
#define TRITON_SOFTFLOAT_HPP

#include <cstdint>

//! The Triton namespace
namespace triton {
/*!
* \addtogroup triton
* @{
*/
//! The Softfloat namespace
namespace sf {
/*!
* \ingroup triton
* \addtogroup softfloat
* @{
*/

//! Cast 32-bit floating point value to 16-bit according to IEEE-754
auto f32_to_f16(float value) -> uint16_t;

}

}

#endif /* TRITON_SOFTFLOAT_HPP */
42 changes: 42 additions & 0 deletions src/libtriton/utils/softfloat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! \file
/*
** Copyright (C) - Triton
**
** This program is under the terms of the Apache License 2.0.
*/

#include <triton/softfloat.hpp>

#include <cstring>

namespace triton {
namespace sf {

auto f32_to_f16(float value) -> uint16_t {
uint32_t f;
static_assert(sizeof(float) == sizeof(uint32_t),
"Unexpected float type size");
std::memcpy(&f, &value, sizeof(uint32_t));
uint16_t sign = (f >> 16) & 0x8000;
int16_t exponent = ((f >> 23) & 0xff) - 127 + 15;
uint16_t mantissa = (f >> 13) & 0x3ff;
if (exponent <= 0) {
if (exponent < -10) {
return sign;
}
mantissa = (mantissa | 0x400) >> (1 - exponent);
return sign | mantissa;
} else if (exponent == 0xff - (127 - 15)) {
if (mantissa) {
return sign | 0x7fff;
} else {
return sign | 0x7c00;
}
} else if (exponent > 30) {
return sign | 0x7c00;
}
return sign | (exponent << 10) | mantissa;
}

} /* sf namespace */
} /* triton namespace */

0 comments on commit 2f91206

Please sign in to comment.