Skip to content

Commit

Permalink
Merge pull request #1359 from psi-func/aarch64/fp_operand_support
Browse files Browse the repository at this point in the history
Aarch64 floating point operands support
  • Loading branch information
JonathanSalwan authored Sep 6, 2024
2 parents 4770a26 + 2f91206 commit f675ce2
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 2 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
17 changes: 16 additions & 1 deletion src/libtriton/arch/arm/aarch64/aarch64Cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,23 @@ namespace triton {
break;
}

case triton::extlibs::capstone::ARM64_OP_FP: {
if (size == 0) {
throw triton::exceptions::Disassembly("Aarch64Cpu::disassembly(): Cannot correctly decode FP operand");
}

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

/* Set Shift type and value */
imm.setShiftType(this->capstoneShiftToTritonShift(op->shift.type));
imm.setShiftValue(op->shift.value);

inst.operands.push_back(triton::arch::OperandWrapper(imm));
}
break;

default:
/* NOTE: FP, CIMM, and missing one are not supported yet. */
/* NOTE: CIMM, and missing one are not supported yet. */
throw triton::exceptions::Disassembly("AArch64Cpu::disassembly(): Invalid operand.");
} // switch
} // for operand
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 */
4 changes: 4 additions & 0 deletions src/testers/aarch64/unicorn_test_aarch64.py
Original file line number Diff line number Diff line change
Expand Up @@ -2156,6 +2156,10 @@
#(b"\x00\x00\xaf\x9e", "fmov v0.D[1], x0"), # working on capstone next branch
(b"\x40\x03\x67\x9e", "fmov d0, x26"),
(b"\x02\x00\x66\x9e", "fmov x2, d0"),
(b"\x00\x10\x20\x1e", "fmov s0, #2.0"),
(b"\x03\x10\x2e\x1e", "fmov s3, #1.0"),
(b"\x01\x90\x61\x1e", "fmov d1, #3.5"),
#(b"\x04\x90\xe0\x1e", "fmov h4, #2.5"), # unicorn not implement f16 ops
]

def emu_with_unicorn(opcode, istate):
Expand Down

0 comments on commit f675ce2

Please sign in to comment.