Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIPS/libunwind: Use -mfp64 if compiler is FPXX #68521

Merged
merged 1 commit into from
Feb 8, 2024

Conversation

wzssyqa
Copy link
Contributor

@wzssyqa wzssyqa commented Oct 8, 2023

Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is that, FP64 and FP32 have different way to save/restore FPRs. If libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0 (FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
FPXX + FP32 -> FP32
FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64 APPs, and if it is built as FP32, it will interoperatable with FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are FP32.

So if the compiler is FPXX, which is the default value of most toolchain, let's switch it to FP64.

@wzssyqa wzssyqa requested a review from a team as a code owner October 8, 2023 11:22
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 8, 2023

@llvm/pr-subscribers-libunwind

Changes

Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is that, FP64 and FP32 have different way to save/restore FPRs. If libunwind is built as FPXX, we have no idea which one should we use.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64 APPs, and if it is built as FP32, it will interoperatable with FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are FP32.

So if the compiler is FPXX, which is the default value of most toolchain, let's switch it to FP64.


Full diff: https://github.com/llvm/llvm-project/pull/68521.diff

1 Files Affected:

  • (modified) libunwind/CMakeLists.txt (+19)
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index 84f8ce296a7410b..387d4b43b5746a6 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -21,6 +21,7 @@ set(LIBUNWIND_LIBCXX_PATH "${CMAKE_CURRENT_LIST_DIR}/../libcxx" CACHE PATH
         "Specify path to libc++ source.")
 
 include(GNUInstallDirs)
+include(CheckSymbolExists)
 
 #===============================================================================
 # Setup CMake Options
@@ -101,6 +102,20 @@ endif()
 option(LIBUNWIND_HIDE_SYMBOLS
   "Do not export any symbols from the static library." ${LIBUNWIND_DEFAULT_HIDE_SYMBOLS})
 
+# If toolchain is FPXX, we switch to FP64 to save the full FPRs. See:
+# https://web.archive.org/web/20180828210612/https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
+check_symbol_exists(__mips_hard_float "" __MIPSHF)
+check_symbol_exists(_ABIO32 "" __MIPS_O32)
+if (__MIPSHF AND __MIPS_O32)
+  file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/mips_is_fpxx.c
+    "#if __mips_fpr != 0\n"
+    "# error\n"
+    "#endif\n")
+  try_compile(MIPS_FPABI_FPXX ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/mips_is_fpxx.c
+    CMAKE_FLAGS -DCMAKE_C_LINK_EXECUTABLE='echo')
+endif()
+
 #===============================================================================
 # Configure System
 #===============================================================================
@@ -184,6 +199,10 @@ if (WIN32)
   add_compile_flags_if_supported(-Wno-dll-attribute-on-redeclaration)
 endif()
 
+if (MIPS_FPABI_FPXX)
+  add_compile_flags(-mfp64)
+endif()
+
 # Get feature flags.
 # Exceptions
 # Catches C++ exceptions only and tells the compiler to assume that extern C

@wzssyqa
Copy link
Contributor Author

wzssyqa commented Nov 9, 2023

@brad0 can you have a look at this PR?

@brad0
Copy link
Contributor

brad0 commented Nov 11, 2023

Probably not the best person to ask.

Let's see what MaskRay says.

@MaskRay

Libunwind supports FP64 and FP32 modes, but not FPXX.
The reason is that, FP64 and FP32 have different way to save/restore
FPRs. If libunwind is built as FPXX, we have no idea which one should
we use.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are FP32.

So if the compiler is FPXX, which is the default value of most toolchain,
let's switch it to FP64.
@MaskRay
Copy link
Member

MaskRay commented Feb 6, 2024

Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is that, FP64 and FP32 have different way to save/restore FPRs. If libunwind is built as FPXX, we have no idea which one should we use.

Can you edit the description to name the code that doesn't support FPXX?

@wzssyqa
Copy link
Contributor Author

wzssyqa commented Feb 6, 2024 via email

@wzssyqa wzssyqa merged commit 4520b47 into llvm:main Feb 8, 2024
49 of 50 checks passed
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 8, 2024
Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is
that, FP64 and FP32 have different way to save/restore FPRs. If
libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0
(FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
    FPXX + FP32 -> FP32
    FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are
FP32.

So if the compiler is FPXX, which is the default value of most
toolchain, let's switch it to FP64.

Co-authored-by: YunQiang Su <[email protected]>
(cherry picked from commit 4520b47)
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 9, 2024
Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is
that, FP64 and FP32 have different way to save/restore FPRs. If
libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0
(FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
    FPXX + FP32 -> FP32
    FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are
FP32.

So if the compiler is FPXX, which is the default value of most
toolchain, let's switch it to FP64.

Co-authored-by: YunQiang Su <[email protected]>
(cherry picked from commit 4520b47)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is
that, FP64 and FP32 have different way to save/restore FPRs. If
libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0
(FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
    FPXX + FP32 -> FP32
    FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are
FP32.

So if the compiler is FPXX, which is the default value of most
toolchain, let's switch it to FP64.

Co-authored-by: YunQiang Su <[email protected]>
(cherry picked from commit 4520b47)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is
that, FP64 and FP32 have different way to save/restore FPRs. If
libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0
(FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
    FPXX + FP32 -> FP32
    FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are
FP32.

So if the compiler is FPXX, which is the default value of most
toolchain, let's switch it to FP64.

Co-authored-by: YunQiang Su <[email protected]>
(cherry picked from commit 4520b47)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
Libunwind supports FP64 and FP32 modes, but not FPXX. The reason is
that, FP64 and FP32 have different way to save/restore FPRs. If
libunwind is built as FPXX, we have no idea which one should we use.

It's not due to the code bug, but rather the nature of FPXX.
FPXX is an ABI which uses only a common subset of FR=1(FP64) and FR=0
(FP32).
So that FPXX binaries can link with both FP64 and FP32 ones, aka.
    FPXX + FP32 -> FP32
    FPXX + FP64 -> FP64

While for libunwind, we should save/restore all of FPRs. If we use FPXX,
we can only save/restore a common subset of FPRs, instead of superset.

If libunwind is built as FP64, it will interoperatable with FPXX/FP64
APPs, and if it is built as FP32, it will interoperatable with
FP32/FPXX. Currently most of O32 APPs are FPXX or FP64, while few are
FP32.

So if the compiler is FPXX, which is the default value of most
toolchain, let's switch it to FP64.

Co-authored-by: YunQiang Su <[email protected]>
(cherry picked from commit 4520b47)
@pointhex pointhex mentioned this pull request May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants