Index: tools/llvm-exegesis/lib/CMakeLists.txt =================================================================== --- tools/llvm-exegesis/lib/CMakeLists.txt +++ tools/llvm-exegesis/lib/CMakeLists.txt @@ -19,6 +19,7 @@ MCInstrDescView.cpp PerfHelper.cpp RegisterAliasing.cpp + RegisterValue.cpp Target.cpp Uops.cpp ) Index: tools/llvm-exegesis/lib/RegisterValue.h =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/RegisterValue.h @@ -0,0 +1,38 @@ +//===-- RegisterValue.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Defines a Target independent value for a Register. This is useful to explore +/// the influence of the instruction input values on its execution time. +/// +//===----------------------------------------------------------------------===// + +#include + +namespace exegesis { + +enum class PredefinedValues { + POS_ZERO, // Positive zero + NEG_ZERO, // Negative zero + ONE, // 1.0 + TWO, // 2.0 + INF, // Infinity + QNAN, // Quiet NaN + ULP, // One Unit in the last place + SMALLEST = ULP, // The minimum subnormal number + SMALLEST_NORM, // The minimum normal number + LARGEST, // The maximum normal number + ONE_PLUS_ULP, // The value just after 1.0 +}; + +llvm::APInt bitcastFloatValue(const llvm::fltSemantics &FltSemantics, + PredefinedValues Value); + +} // namespace exegesis Index: tools/llvm-exegesis/lib/RegisterValue.cpp =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/RegisterValue.cpp @@ -0,0 +1,48 @@ +//===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterValue.h" +#include "llvm/ADT/APFloat.h" + +namespace exegesis { + +static llvm::APFloat getFloatValue(const llvm::fltSemantics &FltSemantics, + PredefinedValues Value) { + switch (Value) { + case PredefinedValues::POS_ZERO: + return llvm::APFloat::getZero(FltSemantics); + case PredefinedValues::NEG_ZERO: + return llvm::APFloat::getZero(FltSemantics, true); + case PredefinedValues::ONE: + return llvm::APFloat(FltSemantics, "1"); + case PredefinedValues::TWO: + return llvm::APFloat(FltSemantics, "2"); + case PredefinedValues::INF: + return llvm::APFloat::getInf(FltSemantics); + case PredefinedValues::QNAN: + return llvm::APFloat::getQNaN(FltSemantics); + case PredefinedValues::SMALLEST_NORM: + return llvm::APFloat::getSmallestNormalized(FltSemantics); + case PredefinedValues::LARGEST: + return llvm::APFloat::getLargest(FltSemantics); + case PredefinedValues::ULP: + return llvm::APFloat::getSmallest(FltSemantics); + case PredefinedValues::ONE_PLUS_ULP: + auto Output = getFloatValue(FltSemantics, PredefinedValues::ONE); + Output.next(false); + return Output; + } +} + +llvm::APInt bitcastFloatValue(const llvm::fltSemantics &FltSemantics, + PredefinedValues Value) { + return getFloatValue(FltSemantics, Value).bitcastToAPInt(); +} + +} // namespace exegesis Index: unittests/tools/llvm-exegesis/CMakeLists.txt =================================================================== --- unittests/tools/llvm-exegesis/CMakeLists.txt +++ unittests/tools/llvm-exegesis/CMakeLists.txt @@ -15,6 +15,7 @@ BenchmarkRunnerTest.cpp ClusteringTest.cpp PerfHelperTest.cpp + RegisterValueTest.cpp ) target_link_libraries(LLVMExegesisTests PRIVATE LLVMExegesis) Index: unittests/tools/llvm-exegesis/RegisterValueTest.cpp =================================================================== --- /dev/null +++ unittests/tools/llvm-exegesis/RegisterValueTest.cpp @@ -0,0 +1,71 @@ +//===-- RegisterValueTest.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterValue.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace exegesis { + +namespace { + +#define CHECK(EXPECTED, ACTUAL) \ + EXPECT_EQ(llvm::APInt(SizeInBits, EXPECTED, 16), \ + bitcastFloatValue(Semantic, PredefinedValues::ACTUAL)) + +TEST(RegisterValueTest, Half) { + const size_t SizeInBits = 16; + const auto &Semantic = llvm::APFloatBase::IEEEhalf(); + CHECK("0000", POS_ZERO); + CHECK("8000", NEG_ZERO); + CHECK("3C00", ONE); + CHECK("4000", TWO); + CHECK("7C00", INF); + CHECK("7E00", QNAN); + CHECK("7BFF", LARGEST); + CHECK("0400", SMALLEST_NORM); + CHECK("0001", SMALLEST); + CHECK("0001", ULP); + CHECK("3C01", ONE_PLUS_ULP); +} + +TEST(RegisterValueTest, Single) { + const size_t SizeInBits = 32; + const auto &Semantic = llvm::APFloatBase::IEEEsingle(); + CHECK("00000000", POS_ZERO); + CHECK("80000000", NEG_ZERO); + CHECK("3F800000", ONE); + CHECK("40000000", TWO); + CHECK("7F800000", INF); + CHECK("7FC00000", QNAN); + CHECK("7F7FFFFF", LARGEST); + CHECK("00800000", SMALLEST_NORM); + CHECK("00000001", SMALLEST); + CHECK("00000001", ULP); + CHECK("3F800001", ONE_PLUS_ULP); +} + +TEST(RegisterValueTest, Double) { + const size_t SizeInBits = 64; + const auto &Semantic = llvm::APFloatBase::IEEEdouble(); + CHECK("0000000000000000", POS_ZERO); + CHECK("8000000000000000", NEG_ZERO); + CHECK("3FF0000000000000", ONE); + CHECK("4000000000000000", TWO); + CHECK("7FF0000000000000", INF); + CHECK("7FF8000000000000", QNAN); + CHECK("7FEFFFFFFFFFFFFF", LARGEST); + CHECK("0010000000000000", SMALLEST_NORM); + CHECK("0000000000000001", SMALLEST); + CHECK("0000000000000001", ULP); + CHECK("3FF0000000000001", ONE_PLUS_ULP); +} + +} // namespace +} // namespace exegesis