lhmouse wrote:

Yes this PR is complicated and includes many pieces of changes scattering 
around here and there. I'm switching my plan to implement x87 long double in 
the ARm64EC backend. Once that is done, I'll file another PR.

<details>
<summary>My current change set to Clang seems minimal:</summary>

```diff
diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 7ddf9d87ad16..01da8b879df0 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -206,6 +206,10 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple 
&Triple,
     this->MCountName = "\01_mcount";
   else if (Triple.getOS() == llvm::Triple::UnknownOS)
     this->MCountName = Triple.isGNUEnvironment() ? "\01_mcount" : "mcount";
+
+  // This should be compatible with x86-64.
+  if (Triple.isWindowsArm64EC() && !Triple.isWindowsMSVCEnvironment())
+    HasFloat128 = true;
 }
 
 StringRef AArch64TargetInfo::getABI() const { return ABI; }
@@ -450,6 +454,11 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
&Opts,
   if (T.isLFI())
     Builder.defineMacro("__LFI__");
 
+  if (HasFloat128) {
+    Builder.defineMacro("__FLOAT128__");
+    Builder.defineMacro("__SIZEOF_FLOAT128__", "16");
+  }
+
   // Inline assembly supports AArch64 flag outputs.
   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
 
@@ -1831,6 +1840,14 @@ WindowsARM64TargetInfo::WindowsARM64TargetInfo(const 
llvm::Triple &Triple,
   SizeType = UnsignedLongLong;
   PtrDiffType = SignedLongLong;
   IntPtrType = SignedLongLong;
+
+  if (Triple.isWindowsArm64EC() && !Triple.isWindowsMSVCEnvironment()) {
+    // arm64ec-w64-mingw32 should be interoperable with x86_64-w64-mingw32,
+    // which by default has `long double` as the x87-specific extended
+    // precision format.
+    LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
+    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
+  }
 }
 
 TargetInfo::BuiltinVaListKind
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp 
b/clang/lib/CodeGen/Targets/AArch64.cpp
index e493f717af58..1003a0fd7c84 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -383,6 +383,13 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType 
Ty, bool IsVariadicFn,
         Ty, IsNamedArg);
   }
 
+  // ARM64EC supports the x87 `long double` type, which is passed as a 128-bit
+  // integer image.
+  if (getTarget().getTriple().isWindowsArm64EC() &&
+      Ty->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+      &getTarget().getLongDoubleFormat() == 
&llvm::APFloat::x87DoubleExtended())
+    return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 128));
+
   // Handle illegal vector types here.
   if (isIllegalVectorType(Ty))
     return coerceIllegalVector(Ty, NSRN, NPRN);
@@ -557,6 +564,13 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType 
RetTy,
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
+  // ARM64EC supports the x87 `long double` type, which is returned as a
+  // 128-bit integer image.
+  if (getTarget().getTriple().isWindowsArm64EC() &&
+      RetTy->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+      &getTarget().getLongDoubleFormat() == 
&llvm::APFloat::x87DoubleExtended())
+    return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 128));
+
   if (const auto *VT = RetTy->getAs<VectorType>()) {
     if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
         VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 1bce61d2cfbe..b97e1faf3635 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6347,6 +6347,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
     else if (TC.getTriple().isPPC() &&
              (A->getOption().getID() != options::OPT_mlong_double_80))
       A->render(Args, CmdArgs);
+    else if (TC.getTriple().isWindowsArm64EC() &&
+             !TC.getTriple().isWindowsMSVCEnvironment())
+      A->render(Args, CmdArgs);
     else
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
```
</details>


https://github.com/llvm/llvm-project/pull/237057
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to