| 1 | #include "../includes/ghcconfig.h" |
|---|
| 2 | |
|---|
| 3 | /* ******************************** PowerPC ******************************** */ |
|---|
| 4 | |
|---|
| 5 | #if defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH) |
|---|
| 6 | #if !(defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS)) |
|---|
| 7 | /* The following code applies, with some differences, |
|---|
| 8 | to all powerpc platforms except for powerpc32-linux, |
|---|
| 9 | whose calling convention is annoyingly complex. |
|---|
| 10 | */ |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | /* The code is "almost" the same for |
|---|
| 14 | 32-bit and for 64-bit |
|---|
| 15 | */ |
|---|
| 16 | #if defined(powerpc64_HOST_ARCH) |
|---|
| 17 | #define WS 8 |
|---|
| 18 | #define LOAD ld |
|---|
| 19 | #define STORE std |
|---|
| 20 | #else |
|---|
| 21 | #define WS 4 |
|---|
| 22 | #define LOAD lwz |
|---|
| 23 | #define STORE stw |
|---|
| 24 | #endif |
|---|
| 25 | |
|---|
| 26 | /* Some info about stack frame layout */ |
|---|
| 27 | #define LINK_SLOT (2*WS) |
|---|
| 28 | #define LINKAGE_AREA_SIZE (6*WS) |
|---|
| 29 | |
|---|
| 30 | /* The following defines mirror struct AdjustorStub |
|---|
| 31 | from Adjustor.c. Make sure to keep these in sync. |
|---|
| 32 | */ |
|---|
| 33 | #if defined(powerpc_HOST_ARCH) && defined(darwin_HOST_OS) |
|---|
| 34 | #define HEADER_WORDS 6 |
|---|
| 35 | #elif defined(powerpc64_HOST_ARCH) && defined(darwin_HOST_OS) |
|---|
| 36 | #else |
|---|
| 37 | #define HEADER_WORDS 3 |
|---|
| 38 | #endif |
|---|
| 39 | |
|---|
| 40 | #define HPTR_OFF ((HEADER_WORDS )*WS) |
|---|
| 41 | #define WPTR_OFF ((HEADER_WORDS + 1)*WS) |
|---|
| 42 | #define FRAMESIZE_OFF ((HEADER_WORDS + 2)*WS) |
|---|
| 43 | #define EXTRA_WORDS_OFF ((HEADER_WORDS + 3)*WS) |
|---|
| 44 | |
|---|
| 45 | /* Darwin insists on register names, everyone else prefers |
|---|
| 46 | to use numbers. */ |
|---|
| 47 | #if !defined(darwin_HOST_OS) |
|---|
| 48 | #define r0 0 |
|---|
| 49 | #define r1 1 |
|---|
| 50 | #define r2 2 |
|---|
| 51 | #define r3 3 |
|---|
| 52 | #define r4 4 |
|---|
| 53 | #define r5 5 |
|---|
| 54 | #define r6 6 |
|---|
| 55 | #define r7 7 |
|---|
| 56 | #define r8 8 |
|---|
| 57 | #define r9 9 |
|---|
| 58 | #define r10 10 |
|---|
| 59 | #define r11 11 |
|---|
| 60 | #define r12 12 |
|---|
| 61 | |
|---|
| 62 | #define r30 30 |
|---|
| 63 | #define r31 31 |
|---|
| 64 | #endif |
|---|
| 65 | |
|---|
| 66 | |
|---|
| 67 | .text |
|---|
| 68 | #if LEADING_UNDERSCORE |
|---|
| 69 | .globl _adjustorCode |
|---|
| 70 | _adjustorCode: |
|---|
| 71 | #else |
|---|
| 72 | .globl adjustorCode |
|---|
| 73 | /* Note that we don't build a function descriptor |
|---|
| 74 | for AIX-derived ABIs here. This will happen at runtime |
|---|
| 75 | in createAdjustor(). |
|---|
| 76 | */ |
|---|
| 77 | adjustorCode: |
|---|
| 78 | #endif |
|---|
| 79 | /* On entry, r2 will point to the AdjustorStub data structure. */ |
|---|
| 80 | |
|---|
| 81 | /* save the link */ |
|---|
| 82 | mflr r0 |
|---|
| 83 | STORE r0, LINK_SLOT(r1) |
|---|
| 84 | |
|---|
| 85 | /* set up stack frame */ |
|---|
| 86 | LOAD r12, FRAMESIZE_OFF(r2) |
|---|
| 87 | #ifdef powerpc64_HOST_ARCH |
|---|
| 88 | stdux r1, r1, r12 |
|---|
| 89 | #else |
|---|
| 90 | stwux r1, r1, r12 |
|---|
| 91 | #endif |
|---|
| 92 | |
|---|
| 93 | /* Save some regs so that we can use them. |
|---|
| 94 | Note that we use the "Red Zone" below the stack pointer. |
|---|
| 95 | */ |
|---|
| 96 | STORE r31, -WS(r1) |
|---|
| 97 | STORE r30, -2*WS(r1) |
|---|
| 98 | |
|---|
| 99 | mr r31, r1 |
|---|
| 100 | subf r30, r12, r31 |
|---|
| 101 | |
|---|
| 102 | LOAD r12, EXTRA_WORDS_OFF(r2) |
|---|
| 103 | mtctr r12 |
|---|
| 104 | b 2f |
|---|
| 105 | 1: |
|---|
| 106 | LOAD r0, LINKAGE_AREA_SIZE + 8*WS(r30) |
|---|
| 107 | STORE r0, LINKAGE_AREA_SIZE + 10*WS(r31) |
|---|
| 108 | addi r30, r30, WS |
|---|
| 109 | addi r31, r31, WS |
|---|
| 110 | 2: |
|---|
| 111 | bdnz 1b |
|---|
| 112 | |
|---|
| 113 | /* Restore r30 and r31 now. |
|---|
| 114 | */ |
|---|
| 115 | LOAD r31, -WS(r1) |
|---|
| 116 | LOAD r30, -2*WS(r1) |
|---|
| 117 | |
|---|
| 118 | STORE r10, LINKAGE_AREA_SIZE + 9*WS(r1) |
|---|
| 119 | STORE r9, LINKAGE_AREA_SIZE + 8*WS(r1) |
|---|
| 120 | mr r10, r8 |
|---|
| 121 | mr r9, r7 |
|---|
| 122 | mr r8, r6 |
|---|
| 123 | mr r7, r5 |
|---|
| 124 | mr r6, r4 |
|---|
| 125 | mr r5, r3 |
|---|
| 126 | |
|---|
| 127 | LOAD r3, HPTR_OFF(r2) |
|---|
| 128 | |
|---|
| 129 | LOAD r12, WPTR_OFF(r2) |
|---|
| 130 | #if defined(darwin_HOST_OS) |
|---|
| 131 | mtctr r12 |
|---|
| 132 | #else |
|---|
| 133 | LOAD r0, 0(r12) |
|---|
| 134 | /* The function we're calling will never be a nested function, |
|---|
| 135 | so we don't load r11. |
|---|
| 136 | */ |
|---|
| 137 | mtctr r0 |
|---|
| 138 | LOAD r2, WS(r12) |
|---|
| 139 | #endif |
|---|
| 140 | bctrl |
|---|
| 141 | |
|---|
| 142 | LOAD r1, 0(r1) |
|---|
| 143 | LOAD r0, LINK_SLOT(r1) |
|---|
| 144 | mtlr r0 |
|---|
| 145 | blr |
|---|
| 146 | #endif |
|---|
| 147 | |
|---|
| 148 | /* ********************************* i386 ********************************** */ |
|---|
| 149 | |
|---|
| 150 | #elif defined(i386_HOST_ARCH) |
|---|
| 151 | |
|---|
| 152 | #define WS 4 |
|---|
| 153 | #define RETVAL_OFF 5 |
|---|
| 154 | #define HEADER_BYTES 8 |
|---|
| 155 | |
|---|
| 156 | #define HPTR_OFF HEADER_BYTES |
|---|
| 157 | #define WPTR_OFF (HEADER_BYTES + 1*WS) |
|---|
| 158 | #define FRAMESIZE_OFF (HEADER_BYTES + 2*WS) |
|---|
| 159 | #define ARGWORDS_OFF (HEADER_BYTES + 3*WS) |
|---|
| 160 | |
|---|
| 161 | #ifdef LEADING_UNDERSCORE |
|---|
| 162 | .globl _adjustorCode |
|---|
| 163 | _adjustorCode: |
|---|
| 164 | #else |
|---|
| 165 | .globl adjustorCode |
|---|
| 166 | adjustorCode: |
|---|
| 167 | #endif |
|---|
| 168 | popl %eax |
|---|
| 169 | subl $RETVAL_OFF, %eax |
|---|
| 170 | |
|---|
| 171 | pushl %ebp |
|---|
| 172 | movl %esp, %ebp |
|---|
| 173 | |
|---|
| 174 | subl FRAMESIZE_OFF(%eax), %esp |
|---|
| 175 | |
|---|
| 176 | pushl %esi |
|---|
| 177 | pushl %edi |
|---|
| 178 | |
|---|
| 179 | leal 8(%ebp), %esi |
|---|
| 180 | leal 12(%esp), %edi |
|---|
| 181 | movl ARGWORDS_OFF(%eax), %ecx |
|---|
| 182 | rep |
|---|
| 183 | movsl |
|---|
| 184 | |
|---|
| 185 | popl %edi |
|---|
| 186 | popl %esi |
|---|
| 187 | |
|---|
| 188 | pushl HPTR_OFF(%eax) |
|---|
| 189 | call *WPTR_OFF(%eax) |
|---|
| 190 | |
|---|
| 191 | leave |
|---|
| 192 | ret |
|---|
| 193 | #endif |
|---|
| 194 | |
|---|
| 195 | /* mark stack as nonexecutable */ |
|---|
| 196 | #if defined(__linux__) && defined(__ELF__) |
|---|
| 197 | .section .note.GNU-stack,"",@progbits |
|---|
| 198 | #endif |
|---|