A few typofixes
[ghc.git] / rts / AdjustorAsm.S
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 #define HEADER_WORDS   3
34
35 #define HPTR_OFF        ((HEADER_WORDS    )*WS)
36 #define WPTR_OFF        ((HEADER_WORDS + 1)*WS)
37 #define FRAMESIZE_OFF   ((HEADER_WORDS + 2)*WS)
38 #define EXTRA_WORDS_OFF ((HEADER_WORDS + 3)*WS)
39
40 #if defined(aix_HOST_OS)
41 /* IBM's assembler needs a different pseudo-op to declare a .text section */
42 .csect .text[PR]
43 #else
44 .text
45 #endif
46 #if LEADING_UNDERSCORE
47     .globl _adjustorCode
48 _adjustorCode:
49 #else
50     .globl adjustorCode
51         /* Note that we don't build a function descriptor
52            for AIX-derived ABIs here. This will happen at runtime
53            in createAdjustor().
54         */
55 adjustorCode:
56 #endif
57     /* On entry, r2 will point to the AdjustorStub data structure. */
58
59         /* save the link */
60     mflr    0
61     STORE   0, LINK_SLOT(1)
62     
63         /* set up stack frame */
64     LOAD    12, FRAMESIZE_OFF(2)
65 #if defined(powerpc64_HOST_ARCH)
66     stdux   1, 1, 12
67 #else   
68     stwux   1, 1, 12
69 #endif
70
71         /* Save some regs so that we can use them.
72            Note that we use the "Red Zone" below the stack pointer.
73         */
74     STORE   31, -WS(1)
75     STORE   30, -2*WS(1)
76
77     mr      31, 1
78     subf    30, 12, 31
79
80     LOAD    12, EXTRA_WORDS_OFF(2)
81     mtctr   12
82     b       L2
83 L1:
84     LOAD    0, LINKAGE_AREA_SIZE +  8*WS(30)
85     STORE   0, LINKAGE_AREA_SIZE + 10*WS(31)
86     addi    30, 30, WS
87     addi    31, 31, WS
88 L2:
89     bdnz    L1
90
91         /* Restore r30 and r31 now.
92         */
93     LOAD    31, -WS(1)
94     LOAD    30, -2*WS(1)
95
96     STORE   10, LINKAGE_AREA_SIZE + 9*WS(1)
97     STORE   9,  LINKAGE_AREA_SIZE + 8*WS(1)
98     mr      10, 8
99     mr      9, 7
100     mr      8, 6
101     mr      7, 5
102     mr      6, 4
103     mr      5, 3
104
105     LOAD    3, HPTR_OFF(2)
106
107     LOAD    12, WPTR_OFF(2)
108     LOAD    0, 0(12)
109         /* The function we're calling will never be a nested function,
110            so we don't load r11. 
111         */
112     mtctr   0
113     LOAD    2, WS(12)
114     bctrl
115
116     LOAD    1, 0(1)
117     LOAD    0, LINK_SLOT(1)
118     mtlr    0
119     blr
120 #endif
121
122 /* ********************************* i386 ********************************** */
123
124 #elif defined(i386_HOST_ARCH)
125
126 #define WS              4
127 #define RETVAL_OFF      5
128 #define HEADER_BYTES    8
129
130 #define HPTR_OFF        HEADER_BYTES
131 #define WPTR_OFF        (HEADER_BYTES + 1*WS)
132 #define FRAMESIZE_OFF   (HEADER_BYTES + 2*WS)
133 #define ARGWORDS_OFF    (HEADER_BYTES + 3*WS)
134
135 #if defined(LEADING_UNDERSCORE)
136     .globl _adjustorCode
137 _adjustorCode:
138 #else
139     .globl adjustorCode
140 adjustorCode:
141 #endif
142     popl    %eax
143     subl    $RETVAL_OFF, %eax
144     
145     pushl   %ebp
146     movl    %esp, %ebp
147     
148     subl    FRAMESIZE_OFF(%eax), %esp
149
150     pushl   %esi
151     pushl   %edi
152         
153     leal    8(%ebp), %esi
154     leal    12(%esp), %edi
155     movl    ARGWORDS_OFF(%eax), %ecx
156     rep
157     movsl
158     
159     popl    %edi
160     popl    %esi
161     
162     pushl   HPTR_OFF(%eax)
163     call    *WPTR_OFF(%eax)
164     
165     leave
166     ret
167 #endif
168
169 /* mark stack as nonexecutable */
170 #if defined(__linux__) && defined(__ELF__)
171 .section .note.GNU-stack,"",@progbits
172 #endif