5e349f8416ee22539b4e1eee99f7e4599765cbd8
[mono.git] / mono / sgen / sgen-archdep.h
1 /*
2  * sgen-archdep.h: Architecture dependent parts of SGen.
3  *
4  * Copyright 2001-2003 Ximian, Inc
5  * Copyright 2003-2010 Novell, Inc.
6  * Copyright (C) 2012 Xamarin Inc
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License 2.0 as published by the Free Software Foundation;
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License 2.0 along with this library; if not, write to the Free
19  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 #ifndef __MONO_SGENARCHDEP_H__
22 #define __MONO_SGENARCHDEP_H__
23
24 #include <mono/utils/mono-context.h>
25
26 /*
27  * Define either USE_MONO_CTX, or
28  * ARCH_SIGCTX_SP/ARCH_SIGCTX_IP/ARCH_STORE_REGS/ARCH_COPY_SIGCTX_REGS.
29  * Define ARCH_NUM_REGS to be the number of general registers in MonoContext, or the
30  * number of registers stored by ARCH_STORE_REGS.
31  */
32
33 #if defined(MONO_CROSS_COMPILE)
34
35 #define REDZONE_SIZE    0
36
37 #define ARCH_NUM_REGS 0
38 #define ARCH_STORE_REGS(ptr)
39 #define ARCH_SIGCTX_SP(ctx) NULL
40 #define ARCH_SIGCTX_IP(ctx) NULL
41 #define ARCH_COPY_SIGCTX_REGS(a,ctx)
42
43 #elif defined(TARGET_X86)
44
45 #define REDZONE_SIZE    0
46
47 #define ARCH_NUM_REGS 8
48
49 #ifndef MONO_ARCH_HAS_MONO_CONTEXT
50 #error 0
51 #endif
52
53 #define USE_MONO_CTX
54
55 #elif defined(TARGET_AMD64)
56
57 #define REDZONE_SIZE    128
58
59 #define ARCH_NUM_REGS 16
60 #define USE_MONO_CTX
61
62 #elif defined(TARGET_POWERPC)
63
64 #define REDZONE_SIZE    224
65
66 #define ARCH_NUM_REGS 32
67 #ifdef __APPLE__
68 #define ARCH_STORE_REGS(ptr)    \
69         __asm__ __volatile__(   \
70                 "stmw r0, 0(%0)\n"      \
71                 :                       \
72                 : "b" (ptr)             \
73         )
74 #else
75 #define ARCH_STORE_REGS(ptr)    \
76         __asm__ __volatile__(   \
77                 "stmw 0, 0(%0)\n"       \
78                 :                       \
79                 : "b" (ptr)             \
80         )
81 #endif
82 #define ARCH_SIGCTX_SP(ctx)     (UCONTEXT_REG_Rn((ctx), 1))
83 #define ARCH_SIGCTX_IP(ctx)     (UCONTEXT_REG_NIP((ctx)))
84 #define ARCH_COPY_SIGCTX_REGS(a,ctx) do {       \
85         int __i;        \
86         for (__i = 0; __i < 32; ++__i)  \
87                 ((a)[__i]) = (gpointer) UCONTEXT_REG_Rn((ctx), __i);    \
88         } while (0)
89
90 /* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
91    architectures is 64k.  */
92 #if defined(TARGET_POWERPC64)
93 #define ARCH_MIN_MS_BLOCK_SIZE  (64*1024)
94 #define ARCH_MIN_MS_BLOCK_SIZE_SHIFT    16
95 #endif
96
97 #elif defined(TARGET_ARM)
98
99 #define REDZONE_SIZE    0
100 #define USE_MONO_CTX
101
102 /* We dont store ip, sp */
103 #define ARCH_NUM_REGS 14
104
105 #elif defined(TARGET_ARM64)
106
107 #ifdef __linux__
108 #define REDZONE_SIZE    0
109 #elif defined(__APPLE__)
110 #define REDZONE_SIZE    128
111 #else
112 #error "Not implemented."
113 #endif
114 #define USE_MONO_CTX
115 #define ARCH_NUM_REGS 31
116
117 #elif defined(__mips__)
118
119 #define REDZONE_SIZE    0
120
121 #define USE_MONO_CTX
122 #define ARCH_NUM_REGS 32
123
124 #elif defined(__s390x__)
125
126 #define REDZONE_SIZE    0
127
128 #define USE_MONO_CTX
129 #define ARCH_NUM_REGS 16        
130
131 #elif defined(__sparc__)
132
133 #define REDZONE_SIZE    0
134
135 /* Don't bother with %g0 (%r0), it's always hard-coded to zero */
136 #define ARCH_NUM_REGS 15        
137 #ifdef __sparcv9
138 #define ARCH_STORE_REGS(ptr)    \
139         __asm__ __volatile__(   \
140                 "st %%g1,[%0]\n\t"      \
141                 "st %%g2,[%0+0x08]\n\t" \
142                 "st %%g3,[%0+0x10]\n\t" \
143                 "st %%g4,[%0+0x18]\n\t" \
144                 "st %%g5,[%0+0x20]\n\t" \
145                 "st %%g6,[%0+0x28]\n\t" \
146                 "st %%g7,[%0+0x30]\n\t" \
147                 "st %%o0,[%0+0x38]\n\t" \
148                 "st %%o1,[%0+0x40]\n\t" \
149                 "st %%o2,[%0+0x48]\n\t" \
150                 "st %%o3,[%0+0x50]\n\t" \
151                 "st %%o4,[%0+0x58]\n\t" \
152                 "st %%o5,[%0+0x60]\n\t" \
153                 "st %%o6,[%0+0x68]\n\t" \
154                 "st %%o7,[%0+0x70]\n\t" \
155                 :                       \
156                 : "r" (ptr)             \
157                 : "memory"                      \
158         )
159 #else
160 #define ARCH_STORE_REGS(ptr)    \
161         __asm__ __volatile__(   \
162                 "st %%g1,[%0]\n\t"      \
163                 "st %%g2,[%0+0x04]\n\t" \
164                 "st %%g3,[%0+0x08]\n\t" \
165                 "st %%g4,[%0+0x0c]\n\t" \
166                 "st %%g5,[%0+0x10]\n\t" \
167                 "st %%g6,[%0+0x14]\n\t" \
168                 "st %%g7,[%0+0x18]\n\t" \
169                 "st %%o0,[%0+0x1c]\n\t" \
170                 "st %%o1,[%0+0x20]\n\t" \
171                 "st %%o2,[%0+0x24]\n\t" \
172                 "st %%o3,[%0+0x28]\n\t" \
173                 "st %%o4,[%0+0x2c]\n\t" \
174                 "st %%o5,[%0+0x30]\n\t" \
175                 "st %%o6,[%0+0x34]\n\t" \
176                 "st %%o7,[%0+0x38]\n\t" \
177                 :                       \
178                 : "r" (ptr)             \
179                 : "memory"                      \
180         )
181 #endif
182
183 #ifndef REG_SP
184 #define REG_SP REG_O6
185 #endif
186
187 #define ARCH_SIGCTX_SP(ctx)     (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_SP])
188 #define ARCH_SIGCTX_IP(ctx)     (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_PC])
189 #define ARCH_COPY_SIGCTX_REGS(a,ctx) do {       \
190         (a)[0] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G1]);        \
191         (a)[1] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G2]);        \
192         (a)[2] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G3]);        \
193         (a)[3] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G4]);        \
194         (a)[4] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G5]);        \
195         (a)[5] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G6]);        \
196         (a)[6] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G7]);        \
197         (a)[7] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O0]);        \
198         (a)[8] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O1]);        \
199         (a)[9] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O2]);        \
200         (a)[10] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O3]);       \
201         (a)[11] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O4]);       \
202         (a)[12] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O5]);       \
203         (a)[13] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O6]);       \
204         (a)[14] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O7]);       \
205         } while (0)
206
207 #endif
208
209 #endif /* __MONO_SGENARCHDEP_H__ */