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

porting to the s390x/SystemZ architecture #4171

Open
sharkcz opened this issue Sep 15, 2022 · 12 comments
Open

porting to the s390x/SystemZ architecture #4171

sharkcz opened this issue Sep 15, 2022 · 12 comments

Comments

@sharkcz
Copy link

sharkcz commented Sep 15, 2022

Because of the requirement for D language compiler to be available across all platforms Fedora supports, I have started to look into what's missing in the s390x support in LDC. I have a dirty/interim patchset to move forward in the build and here is the summary of the changes I made so far:

  • runtime/druntime/src/rt/sections_elf_shared.d
  • runtime/druntime/src/rt/dwarfeh.d is missing the platform's EH register numbers
  • runtime/druntime/src/core/thread/osthread.d
    • needs an implementation of callWithStackShell()
  • runtime/druntime/src/core/threadasm.S
    • needs implementation of fiber_switchContext
    • can be used to carry the implementation of __ibmz_get_tls_offset() needed by getTLSRange()
  • gen/target.cpp - add mapping of real / long double type to LLVM
    It allows me to build the bootstrap compiler, but later fails due some missing __float128 methods/functions in libldc.a.

update 2022-09-16

  • runtime/druntime/src/core/thread/fiber.d - implement initStack()
@sharkcz
Copy link
Author

sharkcz commented Sep 15, 2022

The intention is to use this issue to track the work required and keep the various teams working on it in sync.

@thewilsonator
Copy link
Contributor

Awesome, most of the changes to druntime I assume are independent of LDC (i.e. they could in theory be used by GDC)? If so they should be targeted upstream to dlang/dmd.

@sharkcz
Copy link
Author

sharkcz commented Sep 15, 2022

for the record, those are the linking errors I am seeing

...
[ 50%] Linking CXX executable bin/ldc2
/usr/bin/cmake -E cmake_link_script CMakeFiles/ldc2.dir/link.txt --verbose=1
/usr/bin/g++ -O2  -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS  -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -march=zEC12 -mtune=z13 -fasynchronous-unwind-tables -fstack-clash-protection -fno-strict-aliasing -DDMDV2 -Wl,-z,relro -Wl,--as-needed   -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 obj/ldc2.o -o bin/ldc2  lib64/libldc.a -lLLVM-14 -L/usr/lib64 -Wl,--export-dynamic -L/home/sharkcz/ldc/ldc-1.30.0-src/build-bootstrap/lib -lphobos2-ldc -ldruntime-ldc -Wl,--gc-sections -lrt -ldl -lpthread -lm -ldl 
/usr/bin/ld: lib64/libldc.a(asmstmt.cpp.o): in function `AsmParserx8664::AsmProcessor::parsePrimaryExp()':
/home/sharkcz/ldc/ldc-1.30.0-src/gen/asm-x86.h:3659: undefined reference to `RealExp::create(Loc const&, __float128, Type*)'
/usr/bin/ld: lib64/libldc.a(asmstmt.cpp.o): in function `AsmParserx8632::AsmProcessor::parsePrimaryExp()':
/home/sharkcz/ldc/ldc-1.30.0-src/gen/asm-x86.h:3659: undefined reference to `RealExp::create(Loc const&, __float128, Type*)'
/usr/bin/ld: lib64/libldc.a(logger.cpp.o): in function `Logger::attention(Loc const&, char const*, ...)':
/home/sharkcz/ldc/ldc-1.30.0-src/gen/logger.cpp:120: undefined reference to `vwarning(Loc const&, char const*, __va_list_tag*)'
/usr/bin/ld: obj/ldc2.o: in function `Token::toChars() const':
timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x13a): undefined reference to `CTFloat::sprint(char*, char, long double)'
/usr/bin/ld: timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x188): undefined reference to `CTFloat::sprint(char*, char, long double)'
/usr/bin/ld: timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x1bc): undefined reference to `CTFloat::sprint(char*, char, long double)'
/usr/bin/ld: timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x20a): undefined reference to `CTFloat::sprint(char*, char, long double)'
/usr/bin/ld: timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x25e): undefined reference to `CTFloat::sprint(char*, char, long double)'
/usr/bin/ld: obj/ldc2.o:timetrace_sema.d:(.text._ZNK5Token7toCharsEv+0x2ac): more undefined references to `CTFloat::sprint(char*, char, long double)' follow
/usr/bin/ld: lib64/libldc.a(ctfloat.cpp.o): in function `CTFloat::sprint(char*, char, __float128)':
/home/sharkcz/ldc/ldc-1.30.0-src/gen/ctfloat.cpp:138: undefined reference to `CTFloat::isNaN(__float128)'
/usr/bin/ld: /home/sharkcz/ldc/ldc-1.30.0-src/gen/ctfloat.cpp:150: undefined reference to `CTFloat::isInfinity(__float128)'
/usr/bin/ld: /home/sharkcz/ldc/ldc-1.30.0-src/gen/ctfloat.cpp:140: undefined reference to `CTFloat::copysign(__float128, __float128)'
collect2: error: ld returned 1 exit status

@sharkcz
Copy link
Author

sharkcz commented Sep 15, 2022

Awesome, most of the changes to druntime I assume are independent of LDC (i.e. they could in theory be used by GDC)? If so they should be targeted upstream to dlang/dmd.

ack

@kinke
Copy link
Member

kinke commented Sep 15, 2022

Thx for taking this on! - I assume you've already handled

// FIXME: PowerPC, SystemZ, ...
From the posted linker errors, it looks like C++ mangles it as __float128, while the host compiler (LDC I assume) mangles it as long double. The extern(C++) mangle can be changed here:
case Tfloat80: c = 'e'; break;
(to 'g' apparently).

@sharkcz
Copy link
Author

sharkcz commented Sep 15, 2022

Thx for taking this on! - I assume you've already handled

// FIXME: PowerPC, SystemZ, ...

yes, I did, as

@@ -60,6 +60,10 @@ llvm::Type *getRealType(const llvm::Trip
   case Triple::riscv64:
     return LLType::getFP128Ty(ctx);
     
+  case Triple::ppc64le:
+  case Triple::systemz:
+    return LLType::getFP128Ty(ctx);
+    
   default:
     // 64-bit double precision for all other targets
     // FIXME: PowerPC, SystemZ, ...

From the posted linker errors, it looks like C++ mangles it as __float128, while the host compiler (LDC I assume) mangles it as long double. The extern(C++) mangle can be changed here:

case Tfloat80: c = 'e'; break;

(to 'g' apparently).

long double is mapped to the ieeequad aka float128 for C/C++ (AFAIK true for both ppc64le and s390x in Fedora)

@sharkcz
Copy link
Author

sharkcz commented Sep 15, 2022

but let's the s390x toolchains guys to chime in ...

@sharkcz
Copy link
Author

sharkcz commented Sep 16, 2022

and there is progress, no more missing __float128 methods, https://github.com/ldc-developers/ldc/blob/master/gen/target.cpp#L232 needed a "fix". I am down to

/usr/bin/g++ -O2  -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS  -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -march=zEC12 -mtune=z13 -fasynchronous-unwind-tables -fstack-clash-protection -fno-strict-aliasing -DDMDV2 -Wl,-z,relro -Wl,--as-needed   -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 obj/ldc2.o -o bin/ldc2  lib64/libldc.a -lLLVM-14 -L/usr/lib64 -Wl,--export-dynamic -L/home/sharkcz/ldc/ldc-1.30.0-src/build-bootstrap/lib -lphobos2-ldc -ldruntime-ldc -Wl,--gc-sections -lrt -ldl -lpthread -lm -ldl 
/usr/bin/ld: lib64/libldc.a(logger.cpp.o): in function `Logger::attention(Loc const&, char const*, ...)':
/home/sharkcz/ldc/ldc-1.30.0-src/gen/logger.cpp:120: undefined reference to `vwarning(Loc const&, char const*, __va_list_tag*)'
collect2: error: ld returned 1 exit status

@kinke
Copy link
Member

kinke commented Sep 16, 2022

and there is progress

👍

gen/logger.cpp:120: undefined reference to `vwarning(Loc const&, char const*, __va_list_tag*)'

Okay so the SysZ C ABI seems to use some __va_list_tag type for va_list then; the SysV x86_64 has a same-named special struct. - Getting this right requires work in druntime (e.g. https://github.com/ldc-developers/druntime/blob/7847bb984b0802bff989c1544a2964d0ca40e299/src/core/stdc/stdarg.d#L135) and the compiler (some TargetABI implementation, like e.g. https://github.com/ldc-developers/ldc/blob/master/gen/abi-aarch64.cpp); getting C[++] interop right requires a TargetABI implementation anyway.

In order not to have to implement a proper ABI right from the start, I would focus on using an apparently working GDC as host compiler, and try to incrementally fix the failing tests, which include various ABI, varargs and C[++] interop tests. LDC itself as mixed D/C++ code base is significantly harder to get working than a regular D-only project, where the ABI doesn't really matter yet. Edit: I.e., most tests need to pass before LDC can build itself for a new platform.

@kalev
Copy link
Contributor

kalev commented Aug 21, 2023

Did you ever end up submitting any of the s390x fixes upstream? Even if the work is incomplete, it would be nice to get some of the fixes in so that other people could pick up the work more easily.

@kalev
Copy link
Contributor

kalev commented Jan 3, 2025

@sharkcz There is an s390x PR now at #4810 - any chance you could look it over and see if it seems sane from Fedora's s390x perspective?

@sharkcz
Copy link
Author

sharkcz commented Jan 3, 2025

@sharkcz There is an s390x PR now at #4810 - any chance you could look it over and see if it seems sane from Fedora's s390x perspective?

sure, I will take a look and will talk to the IBM team as well in case they are not aware (yet).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants