From c3276b205549f20df958f5452467e384814baf36 Mon Sep 17 00:00:00 2001 From: Kai Date: Sun, 7 Jul 2019 17:18:46 +0200 Subject: [PATCH] [ltsmaster] Add support for z/Architecture aka SystemZ Requires additions are: - core.thread - rt.sections_elf_shared - rt.sections_ldc --- src/core/thread.d | 14 ++++++++++++++ src/rt/sections_elf_shared.d | 18 +++++++++++++++++- src/rt/sections_ldc.d | 13 ++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 05d4f007c8..0e8e23dc12 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -2515,6 +2515,16 @@ else sd $$22, 48($0); sd $$23, 56($0)`, "r", regs.ptr); } + else version (SystemZ) + { + import ldc.llvmasm; + + // Callee-save registers, according to S/390 ELF Application + // Binary Interface Supplement, chapter 1, page 9. + size_t[9] regs = void; + __asm(`stm %r6, %r13, $0; + st %r15, 64+$0`, "=*m", regs.ptr); + } else { static assert(false, "Architecture not supported."); @@ -3262,6 +3272,10 @@ private void* getStackTop() nothrow { return __asm!(void *)("move $0, $$sp", "=r"); } + else version (SystemZ) + { + return __asm!(void *)("lr $0, %r15", "=r"); + } else { import ldc.intrinsics; diff --git a/src/rt/sections_elf_shared.d b/src/rt/sections_elf_shared.d index 3f8b2030ef..f6d7a40042 100644 --- a/src/rt/sections_elf_shared.d +++ b/src/rt/sections_elf_shared.d @@ -938,6 +938,10 @@ version(LDC) extern(C) void* __tls_get_addr_opt(tls_index* ti); alias __tls_get_addr = __tls_get_addr_opt; } + else version(SystemZ) + { + extern(C) void* __tls_get_addr_internal(tls_index* ti); + } else extern(C) void* __tls_get_addr(tls_index* ti); } @@ -969,6 +973,8 @@ else version(MIPS32) enum TLS_DTV_OFFSET = 0x8000; else version(MIPS64) enum TLS_DTV_OFFSET = 0x8000; +else version(SystemZ) + enum TLS_DTV_OFFSET = 0x; else static assert( false, "Platform not supported." ); @@ -1006,6 +1012,16 @@ void[] getTLSRange(size_t mod, size_t sz) // base offset auto ti = tls_index(mod, 0); - return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; + version (SystemZ) + { + import ldc.llvmasm; + auto adr = cast(void *)__tls_get_addr_internal(&ti) + + __asm!ulong("ear $0,%a0; sllg $0,$0,32; ear $0,%a1", "=r"); + return adr[0 .. sz]; + } + else + { + return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; + } } } diff --git a/src/rt/sections_ldc.d b/src/rt/sections_ldc.d index 64acb8f576..97adb3622b 100644 --- a/src/rt/sections_ldc.d +++ b/src/rt/sections_ldc.d @@ -330,6 +330,7 @@ private } extern(C) void* __tls_get_addr(tls_index* ti); + extern(C) void* __tls_get_addr_internal(tls_index* ti); /* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of * each TLS block. This is at least true for PowerPC and Mips platforms. @@ -349,7 +350,17 @@ private { if (pdso._tlsMod == 0) return null; auto ti = tls_index(pdso._tlsMod, 0); - return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. pdso._tlsSize]; + version (SystemZ) + { + import ldc.llvmasm; + auto adr = cast(void *)__tls_get_addr_internal(&ti) + + __asm!ulong("ear $0,%a0; sllg $0,$0,32; ear $0,%a1", "=r"); + return adr[0 .. pdso._tlsSize]; + } + else + { + return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. pdso._tlsSize]; + } } } }