diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2473,6 +2473,13 @@ This specifies pointer types with the specified address spaces as :ref:`Non-Integral Pointer Type ` s. The ``0`` address space cannot be specified as non-integral. +``fe::`` + This specifies the size of floating point environment. The first element, + , specifies the size required to store control modes. It corresponds + to the size of ``femode_t` used in C library. The second element, , + specifies the the size, required to store full floating point environment, + it corresponds to the size of ``fenv_t`` used in C library. If is + omitted, it is assumed to be the same as . On every specification that takes a ``:``, specifying the ```` alignment is optional. If omitted, the preceding ``:`` diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -124,6 +124,8 @@ MaybeAlign StackNaturalAlign; unsigned ProgramAddrSpace; unsigned DefaultGlobalsAddrSpace; + unsigned FPControlModeSize; + unsigned FPEnvironmentSize; MaybeAlign FunctionPtrAlign; FunctionPtrAlignType TheFunctionPtrAlignType; @@ -216,6 +218,8 @@ TheFunctionPtrAlignType = DL.TheFunctionPtrAlignType; ProgramAddrSpace = DL.ProgramAddrSpace; DefaultGlobalsAddrSpace = DL.DefaultGlobalsAddrSpace; + FPControlModeSize = DL.FPControlModeSize; + FPEnvironmentSize = DL.FPEnvironmentSize; ManglingMode = DL.ManglingMode; LegalIntWidths = DL.LegalIntWidths; Alignments = DL.Alignments; @@ -293,6 +297,9 @@ return DefaultGlobalsAddrSpace; } + unsigned getFPControlModeSize() const { return FPControlModeSize; } + unsigned getFPEnvironmentSize() const { return FPEnvironmentSize; } + bool hasMicrosoftFastStdCallMangling() const { return ManglingMode == MM_WinCOFFX86; } diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -184,6 +184,8 @@ StackNaturalAlign.reset(); ProgramAddrSpace = 0; DefaultGlobalsAddrSpace = 0; + FPControlModeSize = 0; + FPEnvironmentSize = 0; FunctionPtrAlign.reset(); TheFunctionPtrAlignType = FunctionPtrAlignType::Independent; ManglingMode = MM_None; @@ -286,6 +288,29 @@ continue; } + if (Tok == "fe") { + if (Rest.empty()) + report_fatal_error("Missing size specification for FP environment in " + "datalayout string"); + if (Error Err = split(Rest, ':', Split)) + return Err; + Rest = Split.second; + if (Error Err = getInt(Split.first, FPControlModeSize)) + return Err; + if (!Rest.empty()) { + if (Error Err = split(Rest, ':', Split)) + return Err; + Rest = Split.second; + if (Error Err = getInt(Split.first, FPEnvironmentSize)) + return Err; + } else { + FPEnvironmentSize = FPControlModeSize; + } + if (!Rest.empty()) + report_fatal_error("Extra item in FP environment specification"); + continue; + } + char Specifier = Tok.front(); Tok = Tok.substr(1); @@ -538,6 +563,8 @@ StackNaturalAlign == Other.StackNaturalAlign && ProgramAddrSpace == Other.ProgramAddrSpace && DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace && + FPControlModeSize == Other.FPControlModeSize && + FPEnvironmentSize == Other.FPEnvironmentSize && FunctionPtrAlign == Other.FunctionPtrAlign && TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType && ManglingMode == Other.ManglingMode && diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp --- a/llvm/unittests/IR/DataLayoutTest.cpp +++ b/llvm/unittests/IR/DataLayoutTest.cpp @@ -89,4 +89,15 @@ EXPECT_EQ(ExplicitGlobal2->getAddressSpace(), 123u); } +TEST(DataLayoutTest, FPEnvironmentProperties) { + EXPECT_EQ(0U, DataLayout("").getFPControlModeSize()); + EXPECT_EQ(0U, DataLayout("").getFPEnvironmentSize()); + EXPECT_EQ(0U, DataLayout("fe:0").getFPControlModeSize()); + EXPECT_EQ(0U, DataLayout("fe:0").getFPEnvironmentSize()); + EXPECT_EQ(32U, DataLayout("fe:32").getFPControlModeSize()); + EXPECT_EQ(32U, DataLayout("fe:32").getFPEnvironmentSize()); + EXPECT_EQ(32U, DataLayout("fe:32:64").getFPControlModeSize()); + EXPECT_EQ(64U, DataLayout("fe:32:64").getFPEnvironmentSize()); +} + } // anonymous namespace