From a8ea1a5dd0c6d58fe5ac9798fc04f3bce51696aa Mon Sep 17 00:00:00 2001 From: kai Date: Thu, 9 May 2013 17:36:30 +0200 Subject: [PATCH] Add external implemented callWithStackShell for Linux/PPC64. This is required for the garbage collector. --- src/core/thread.d | 129 +++++++++++++++++++++++-------------------- src/core/threadasm.S | 122 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 188 insertions(+), 63 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 2811c00f73e..bef1c92118f 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -1906,88 +1906,95 @@ shared static ~this() // Used for needLock below. private __gshared bool multiThreadedFlag = false; +version (PPC64) version = ExternStackShell; -// Calls the given delegate, passing the current thread's stack pointer to it. -private void callWithStackShell(scope void delegate(void* sp) fn) -in +version (ExternStackShell) { - assert(fn); + extern(D) public void callWithStackShell(scope void delegate(void* sp) fn); } -body +else { - // The purpose of the 'shell' is to ensure all the registers get - // put on the stack so they'll be scanned. We only need to push - // the callee-save registers. - void *sp = void; - - version (GNU) + // Calls the given delegate, passing the current thread's stack pointer to it. + private void callWithStackShell(scope void delegate(void* sp) fn) + in { - __builtin_unwind_init(); - sp = &sp; + assert(fn); } - else version (AsmX86_Posix) + body { - size_t[3] regs = void; - asm + // The purpose of the 'shell' is to ensure all the registers get + // put on the stack so they'll be scanned. We only need to push + // the callee-save registers. + void *sp = void; + + version (GNU) { - mov [regs + 0 * 4], EBX; - mov [regs + 1 * 4], ESI; - mov [regs + 2 * 4], EDI; + __builtin_unwind_init(); + sp = &sp; + } + else version (AsmX86_Posix) + { + size_t[3] regs = void; + asm + { + mov [regs + 0 * 4], EBX; + mov [regs + 1 * 4], ESI; + mov [regs + 2 * 4], EDI; - mov sp[EBP], ESP; + mov sp[EBP], ESP; + } } - } - else version (AsmX86_Windows) - { - size_t[3] regs = void; - asm + else version (AsmX86_Windows) { - mov [regs + 0 * 4], EBX; - mov [regs + 1 * 4], ESI; - mov [regs + 2 * 4], EDI; + size_t[3] regs = void; + asm + { + mov [regs + 0 * 4], EBX; + mov [regs + 1 * 4], ESI; + mov [regs + 2 * 4], EDI; - mov sp[EBP], ESP; + mov sp[EBP], ESP; + } } - } - else version (AsmX86_64_Posix) - { - size_t[5] regs = void; - asm + else version (AsmX86_64_Posix) { - mov [regs + 0 * 8], RBX; - mov [regs + 1 * 8], R12; - mov [regs + 2 * 8], R13; - mov [regs + 3 * 8], R14; - mov [regs + 4 * 8], R15; + size_t[5] regs = void; + asm + { + mov [regs + 0 * 8], RBX; + mov [regs + 1 * 8], R12; + mov [regs + 2 * 8], R13; + mov [regs + 3 * 8], R14; + mov [regs + 4 * 8], R15; - mov sp[RBP], RSP; + mov sp[RBP], RSP; + } } - } - else version (AsmX86_64_Windows) - { - size_t[7] regs = void; - asm + else version (AsmX86_64_Windows) { - mov [regs + 0 * 8], RBX; - mov [regs + 1 * 8], RSI; - mov [regs + 2 * 8], RDI; - mov [regs + 3 * 8], R12; - mov [regs + 4 * 8], R13; - mov [regs + 5 * 8], R14; - mov [regs + 6 * 8], R15; - - mov sp[RBP], RSP; + size_t[7] regs = void; + asm + { + mov [regs + 0 * 8], RBX; + mov [regs + 1 * 8], RSI; + mov [regs + 2 * 8], RDI; + mov [regs + 3 * 8], R12; + mov [regs + 4 * 8], R13; + mov [regs + 5 * 8], R14; + mov [regs + 6 * 8], R15; + + mov sp[RBP], RSP; + } + } + else + { + static assert(false, "Architecture not supported."); } - } - else - { - static assert(false, "Architecture not supported."); - } - fn(sp); + fn(sp); + } } - // Used for suspendAll/resumeAll below. private __gshared uint suspendDepth = 0; diff --git a/src/core/threadasm.S b/src/core/threadasm.S index 9acd493513d..58342b6d85f 100644 --- a/src/core/threadasm.S +++ b/src/core/threadasm.S @@ -3,7 +3,7 @@ * * Copyright: Copyright Mikola Lysenko 2005 - 2012. * License: Boost License 1.0. - * Authors: Mikola Lysenko, Martin Nowak + * Authors: Mikola Lysenko, Martin Nowak, Kai Nacke */ /* @@ -16,7 +16,125 @@ /************************************************************************************ * POWER PC ASM BITS ************************************************************************************/ -#if defined( __ppc__ ) || defined( __PPC__ ) || defined( __powerpc__ ) +#if defined( __PPC64__ ) + + + .text + .globl _D4core6thread18callWithStackShellFMDFPvZvZv + .align 2 + .type _D4core6thread18callWithStackShellFMDFPvZvZv,@function + .section .opd,"aw",@progbits +_D4core6thread18callWithStackShellFMDFPvZvZv: + .align 3 + .quad .L._D4core6thread18callWithStackShellFMDFPvZvZv + .quad .TOC.@tocbase + .quad 0 + .text +/* + * Called with: + * r3: pointer context + * r4: pointer to function + */ +.L._D4core6thread18callWithStackShellFMDFPvZvZv: + .cfi_startproc + mflr 0 + std 0, 16(1) // save LR + stdu 1, -256(1) // stack size: 18*8 + 112 = 256 + .cfi_def_cfa_offset 256 + .cfi_offset lr, 16 + + /* Save r14-r31 in general register save area */ + std 14, (112 + 0 * 8)(1) + std 15, (112 + 1 * 8)(1) + std 16, (112 + 2 * 8)(1) + std 17, (112 + 3 * 8)(1) + std 18, (112 + 4 * 8)(1) + std 19, (112 + 5 * 8)(1) + std 20, (112 + 6 * 8)(1) + std 21, (112 + 7 * 8)(1) + std 22, (112 + 8 * 8)(1) + std 23, (112 + 9 * 8)(1) + std 24, (112 + 10 * 8)(1) + std 25, (112 + 11 * 8)(1) + std 26, (112 + 12 * 8)(1) + std 27, (112 + 13 * 8)(1) + std 28, (112 + 14 * 8)(1) + std 29, (112 + 15 * 8)(1) + std 30, (112 + 16 * 8)(1) + std 31, (112 + 17 * 8)(1) + + /* Save r3-r10 in parameter save area of caller */ + std 3, (256 + 48 + 0 * 8)(1) + std 4, (256 + 48 + 1 * 8)(1) + std 5, (256 + 48 + 2 * 8)(1) + std 6, (256 + 48 + 3 * 8)(1) + std 7, (256 + 48 + 4 * 8)(1) + std 8, (256 + 48 + 5 * 8)(1) + std 9, (256 + 48 + 6 * 8)(1) + std 10, (256 + 48 + 7 * 8)(1) + + /* Save r2 in TOC save area */ + std 2, 40(1) + + /* Do not save r11, r12 and r13. */ + + /* Call delegate: + * r3: pointer to context + * r4: pointer to stack + */ + mr 5, 4 + mr 4, 1 + ld 6, 0(5) + ld 11, 16(5) + ld 2, 8(5) + mtctr 6 + bctrl + nop + + /* Restore r2 from TOC save area */ + ld 2, 40(1) + + /* Restore r3-r10 from local variable space */ + ld 3, (256 + 48 + 0 * 8)(1) + ld 4, (256 + 48 + 1 * 8)(1) + ld 5, (256 + 48 + 2 * 8)(1) + ld 6, (256 + 48 + 3 * 8)(1) + ld 7, (256 + 48 + 4 * 8)(1) + ld 8, (256 + 48 + 5 * 8)(1) + ld 9, (256 + 48 + 6 * 8)(1) + ld 10, (256 + 48 + 7 * 8)(1) + + /* Restore r14-r31 from general register save area */ + ld 14, (112 + 0 * 8)(1) + ld 15, (112 + 1 * 8)(1) + ld 16, (112 + 2 * 8)(1) + ld 17, (112 + 3 * 8)(1) + ld 18, (112 + 4 * 8)(1) + ld 19, (112 + 5 * 8)(1) + ld 20, (112 + 6 * 8)(1) + ld 21, (112 + 7 * 8)(1) + ld 22, (112 + 8 * 8)(1) + ld 23, (112 + 9 * 8)(1) + ld 24, (112 + 10 * 8)(1) + ld 25, (112 + 11 * 8)(1) + ld 26, (112 + 12 * 8)(1) + ld 27, (112 + 13 * 8)(1) + ld 28, (112 + 14 * 8)(1) + ld 29, (112 + 15 * 8)(1) + ld 30, (112 + 16 * 8)(1) + ld 31, (112 + 17 * 8)(1) + + addi 1, 1, 256 + ld 0, 16(1) + mtlr 0 + blr + .long 0 + .quad 0 +.Lend: + .size _D4core6thread18callWithStackShellFMDFPvZvZv, .Lend-.L._D4core6thread18callWithStackShellFMDFPvZvZv + .cfi_endproc + +#elif defined( __ppc__ ) || defined( __PPC__ ) || defined( __powerpc__ ) /**