Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 188 lines (155 sloc) 4.239 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
#include "../includes/ghcconfig.h"

/* ******************************** PowerPC ******************************** */

#if defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
#if !(defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS))
    /* The following code applies, with some differences,
       to all powerpc platforms except for powerpc32-linux,
       whose calling convention is annoyingly complex.
    */


    /* The code is "almost" the same for
       32-bit and for 64-bit
    */
#if defined(powerpc64_HOST_ARCH)
#define WS 8
#define LOAD ld
#define STORE std
#else
#define WS 4
#define LOAD lwz
#define STORE stw
#endif

    /* Some info about stack frame layout */
#define LINK_SLOT (2*WS)
#define LINKAGE_AREA_SIZE (6*WS)

    /* The following defines mirror struct AdjustorStub
       from Adjustor.c. Make sure to keep these in sync.
    */
#if defined(powerpc_HOST_ARCH) && defined(darwin_HOST_OS)
#define HEADER_WORDS 6
#elif defined(powerpc64_HOST_ARCH) && defined(darwin_HOST_OS)
#else
#define HEADER_WORDS 3
#endif

#define HPTR_OFF ((HEADER_WORDS )*WS)
#define WPTR_OFF ((HEADER_WORDS + 1)*WS)
#define FRAMESIZE_OFF ((HEADER_WORDS + 2)*WS)
#define EXTRA_WORDS_OFF ((HEADER_WORDS + 3)*WS)

    /* Darwin insists on register names, everyone else prefers
       to use numbers. */
#if !defined(darwin_HOST_OS)
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12

#define r30 30
#define r31 31
#endif


.text
#if LEADING_UNDERSCORE
    .globl _adjustorCode
_adjustorCode:
#else
    .globl adjustorCode
        /* Note that we don't build a function descriptor
           for AIX-derived ABIs here. This will happen at runtime
           in createAdjustor().
        */
adjustorCode:
#endif
    /* On entry, r2 will point to the AdjustorStub data structure. */

        /* save the link */
    mflr r0
    STORE r0, LINK_SLOT(r1)
    
        /* set up stack frame */
    LOAD r12, FRAMESIZE_OFF(r2)
#ifdef powerpc64_HOST_ARCH
    stdux r1, r1, r12
#else
    stwux r1, r1, r12
#endif

        /* Save some regs so that we can use them.
           Note that we use the "Red Zone" below the stack pointer.
        */
    STORE r31, -WS(r1)
    STORE r30, -2*WS(r1)

    mr r31, r1
    subf r30, r12, r31

    LOAD r12, EXTRA_WORDS_OFF(r2)
    mtctr r12
    b 2f
1:
    LOAD r0, LINKAGE_AREA_SIZE + 8*WS(r30)
    STORE r0, LINKAGE_AREA_SIZE + 10*WS(r31)
    addi r30, r30, WS
    addi r31, r31, WS
2:
    bdnz 1b

        /* Restore r30 and r31 now.
        */
    LOAD r31, -WS(r1)
    LOAD r30, -2*WS(r1)

    STORE r10, LINKAGE_AREA_SIZE + 9*WS(r1)
    STORE r9, LINKAGE_AREA_SIZE + 8*WS(r1)
    mr r10, r8
    mr r9, r7
    mr r8, r6
    mr r7, r5
    mr r6, r4
    mr r5, r3

    LOAD r3, HPTR_OFF(r2)

    LOAD r12, WPTR_OFF(r2)
#if defined(darwin_HOST_OS)
    mtctr r12
#else
    LOAD r0, 0(r12)
        /* The function we're calling will never be a nested function,
           so we don't load r11.
        */
    mtctr r0
    LOAD r2, WS(r12)
#endif
    bctrl

    LOAD r1, 0(r1)
    LOAD r0, LINK_SLOT(r1)
    mtlr r0
    blr
#endif

/* ********************************* i386 ********************************** */

#elif defined(i386_HOST_ARCH) && defined(darwin_HOST_OS)

#define WS 4
#define RETVAL_OFF 5
#define HEADER_BYTES 8

#define HPTR_OFF HEADER_BYTES
#define WPTR_OFF (HEADER_BYTES + 1*WS)
#define FRAMESIZE_OFF (HEADER_BYTES + 2*WS)
#define ARGWORDS_OFF (HEADER_BYTES + 3*WS)

    .globl _adjustorCode
_adjustorCode:
    popl %eax
    subl $RETVAL_OFF, %eax
    
    pushl %ebp
    movl %esp, %ebp
    
    subl FRAMESIZE_OFF(%eax), %esp

    pushl %esi
    pushl %edi
        
    leal 8(%ebp), %esi
    leal 12(%esp), %edi
    movl ARGWORDS_OFF(%eax), %ecx
    rep
    movsl
    
    popl %edi
    popl %esi
    
    pushl HPTR_OFF(%eax)
    call *WPTR_OFF(%eax)
    
    leave
    ret
#endif
Something went wrong with that request. Please try again.