]>
Commit | Line | Data |
---|---|---|
956d6950 | 1 | /* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF. |
42df2193 | 2 | Copyright 1996, 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. |
bfe87013 DE |
3 | Contributed by David S. Miller (davem@caip.rutgers.edu) |
4 | ||
de0a398e | 5 | This file is part of GCC. |
bfe87013 | 6 | |
de0a398e | 7 | GCC is free software; you can redistribute it and/or modify |
bfe87013 DE |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
de0a398e | 12 | GCC is distributed in the hope that it will be useful, |
bfe87013 DE |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
de0a398e | 18 | along with GCC; see the file COPYING. If not, write to |
bfe87013 DE |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
9b8466f4 NB |
22 | #define TARGET_OS_CPP_BUILTINS() \ |
23 | do \ | |
24 | { \ | |
25 | builtin_define_std ("unix"); \ | |
26 | builtin_define_std ("linux"); \ | |
27 | builtin_define ("_LONGLONG"); \ | |
28 | builtin_define ("__gnu_linux__"); \ | |
9b8466f4 NB |
29 | builtin_assert ("system=unix"); \ |
30 | builtin_assert ("system=posix"); \ | |
31 | } \ | |
32 | while (0) | |
33 | ||
80ffc95e | 34 | /* Don't assume anything about the header files. */ |
bfe87013 DE |
35 | #define NO_IMPLICIT_EXTERN_C |
36 | ||
bfe87013 DE |
37 | #undef MD_EXEC_PREFIX |
38 | #undef MD_STARTFILE_PREFIX | |
39 | ||
345a6161 DM |
40 | #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc |
41 | /* A 64 bit v9 compiler with stack-bias, | |
42 | in a Medium/Low code model environment. */ | |
43 | ||
44 | #undef TARGET_DEFAULT | |
45 | #define TARGET_DEFAULT \ | |
46 | (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \ | |
33074e5f | 47 | + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128) |
345a6161 DM |
48 | #endif |
49 | ||
a0a301fc DE |
50 | #undef ASM_CPU_DEFAULT_SPEC |
51 | #define ASM_CPU_DEFAULT_SPEC "-Av9a" | |
bfe87013 | 52 | |
4710d3eb JJ |
53 | #ifdef SPARC_BI_ARCH |
54 | ||
55 | #undef CPP_ARCH32_SPEC | |
9b8466f4 | 56 | #define CPP_ARCH32_SPEC "%{mlong-double-128:-D__LONG_DOUBLE_128__}" |
4710d3eb JJ |
57 | |
58 | #endif | |
59 | ||
956d6950 JL |
60 | /* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add |
61 | the GNU/Linux magical crtbegin.o file (see crtstuff.c) which | |
bfe87013 | 62 | provides part of the support for getting C++ file-scope static |
80ffc95e | 63 | object constructed before entering `main'. */ |
bfe87013 DE |
64 | |
65 | #undef STARTFILE_SPEC | |
345a6161 | 66 | |
24a4dd31 | 67 | #ifdef HAVE_LD_PIE |
5bbcd587 | 68 | #define STARTFILE_SPEC \ |
24a4dd31 JJ |
69 | "%{!shared:%{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\ |
70 | crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}" | |
71 | #else | |
72 | #define STARTFILE_SPEC \ | |
73 | "%{!shared:%{pg|p:gcrt1.o%s;:crt1.o%s}}\ | |
74 | crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}" | |
75 | #endif | |
bfe87013 | 76 | |
956d6950 JL |
77 | /* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on |
78 | the GNU/Linux magical crtend.o file (see crtstuff.c) which | |
bfe87013 DE |
79 | provides part of the support for getting C++ file-scope static |
80 | object constructed before entering `main', followed by a normal | |
956d6950 | 81 | GNU/Linux "finalizer" file, `crtn.o'. */ |
bfe87013 DE |
82 | |
83 | #undef ENDFILE_SPEC | |
345a6161 | 84 | |
5bbcd587 | 85 | #define ENDFILE_SPEC \ |
24a4dd31 | 86 | "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s\ |
5bbcd587 | 87 | %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}" |
345a6161 | 88 | |
2be1602e DM |
89 | /* The GNU C++ standard library requires that these macros be defined. */ |
90 | #undef CPLUSPLUS_CPP_SPEC | |
91 | #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" | |
92 | ||
345a6161 DM |
93 | #undef TARGET_VERSION |
94 | #define TARGET_VERSION fprintf (stderr, " (sparc64 GNU/Linux with ELF)"); | |
a0a301fc DE |
95 | |
96 | /* The default code model. */ | |
97 | #undef SPARC_DEFAULT_CMODEL | |
be3f1ff5 | 98 | #define SPARC_DEFAULT_CMODEL CM_MEDLOW |
bfe87013 | 99 | |
4710d3eb | 100 | #undef SUBTARGET_SWITCHES |
047142d3 PT |
101 | #define SUBTARGET_SWITCHES \ |
102 | {"long-double-64", -MASK_LONG_DOUBLE_128, N_("Use 64 bit long doubles") }, \ | |
103 | {"long-double-128", MASK_LONG_DOUBLE_128, N_("Use 128 bit long doubles") }, | |
4710d3eb | 104 | |
bfe87013 | 105 | #undef WCHAR_TYPE |
247cfc5c JJ |
106 | #define WCHAR_TYPE "int" |
107 | ||
bfe87013 | 108 | #undef WCHAR_TYPE_SIZE |
247cfc5c JJ |
109 | #define WCHAR_TYPE_SIZE 32 |
110 | ||
ba31d94e | 111 | /* Define for support of TFmode long double. |
56149abc | 112 | SPARC ABI says that long double is 4 words. */ |
a0a301fc | 113 | #undef LONG_DOUBLE_TYPE_SIZE |
4710d3eb JJ |
114 | #define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64) |
115 | ||
116 | /* Constant which presents upper bound of the above value. */ | |
117 | #undef MAX_LONG_DOUBLE_TYPE_SIZE | |
118 | #define MAX_LONG_DOUBLE_TYPE_SIZE 128 | |
119 | ||
120 | /* Define this to set long double type size to use in libgcc2.c, which can | |
121 | not depend on target_flags. */ | |
122 | #if defined(__arch64__) || defined(__LONG_DOUBLE_128__) | |
123 | #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 | |
124 | #else | |
125 | #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 | |
126 | #endif | |
345a6161 | 127 | |
a0a301fc DE |
128 | #undef CPP_SUBTARGET_SPEC |
129 | #define CPP_SUBTARGET_SPEC "\ | |
24a4dd31 | 130 | %{fPIC|fpic|fPIE|fpie:-D__PIC__ -D__pic__} \ |
bfe87013 | 131 | %{posix:-D_POSIX_SOURCE} \ |
afc96791 | 132 | %{pthread:-D_REENTRANT} \ |
bfe87013 | 133 | " |
afc96791 | 134 | |
bfe87013 DE |
135 | #undef LIB_SPEC |
136 | #define LIB_SPEC \ | |
17772b2a JJ |
137 | "%{pthread:-lpthread} \ |
138 | %{shared:-lc} \ | |
139 | %{!shared: %{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" | |
bfe87013 | 140 | |
956d6950 | 141 | /* Provide a LINK_SPEC appropriate for GNU/Linux. Here we provide support |
bfe87013 DE |
142 | for the special GCC options -static and -shared, which allow us to |
143 | link things in one of these three modes by applying the appropriate | |
144 | combinations of options at link-time. We like to support here for | |
145 | as many of the other GNU linker options as possible. But I don't | |
146 | have the time to search for those flags. I am sure how to add | |
147 | support for -soname shared_object_name. H.J. | |
148 | ||
149 | I took out %{v:%{!V:-V}}. It is too much :-(. They can use | |
150 | -Wl,-V. | |
151 | ||
152 | When the -shared link option is used a final link is not being | |
153 | done. */ | |
154 | ||
80ffc95e | 155 | /* If ELF is the default format, we should not use /lib/elf. */ |
bfe87013 | 156 | |
345a6161 DM |
157 | #ifdef SPARC_BI_ARCH |
158 | ||
159 | #undef SUBTARGET_EXTRA_SPECS | |
160 | #define SUBTARGET_EXTRA_SPECS \ | |
161 | { "link_arch32", LINK_ARCH32_SPEC }, \ | |
162 | { "link_arch64", LINK_ARCH64_SPEC }, \ | |
163 | { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ | |
164 | { "link_arch", LINK_ARCH_SPEC }, | |
165 | ||
166 | #define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ | |
167 | %{!shared: \ | |
168 | %{!ibcs: \ | |
169 | %{!static: \ | |
170 | %{rdynamic:-export-dynamic} \ | |
171 | %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | |
172 | %{static:-static}}} \ | |
173 | " | |
174 | ||
175 | #define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ | |
176 | %{!shared: \ | |
177 | %{!ibcs: \ | |
178 | %{!static: \ | |
179 | %{rdynamic:-export-dynamic} \ | |
180 | %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \ | |
181 | %{static:-static}}} \ | |
182 | " | |
183 | ||
184 | #define LINK_ARCH_SPEC "\ | |
185 | %{m32:%(link_arch32)} \ | |
186 | %{m64:%(link_arch64)} \ | |
187 | %{!m32:%{!m64:%(link_arch_default)}} \ | |
188 | " | |
189 | ||
190 | #define LINK_ARCH_DEFAULT_SPEC \ | |
191 | (DEFAULT_ARCH32_P ? LINK_ARCH32_SPEC : LINK_ARCH64_SPEC) | |
192 | ||
bfe87013 | 193 | #undef LINK_SPEC |
345a6161 DM |
194 | #define LINK_SPEC "\ |
195 | %(link_arch) \ | |
196 | %{mlittle-endian:-EL} \ | |
e95b1e6a | 197 | %{!mno-relax:%{!r:-relax}} \ |
345a6161 DM |
198 | " |
199 | ||
200 | #undef CC1_SPEC | |
201 | #if DEFAULT_ARCH32_P | |
202 | #define CC1_SPEC "\ | |
203 | %{sun4:} %{target:} \ | |
204 | %{mcypress:-mcpu=cypress} \ | |
205 | %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ | |
206 | %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ | |
d6964c30 | 207 | %{m32:%{m64:%emay not use both -m32 and -m64}} \ |
4710d3eb | 208 | %{m64:-mptr64 -mstack-bias -mlong-double-128 \ |
247cfc5c JJ |
209 | %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:-mcpu=ultrasparc}}}}}}} \ |
210 | %{!mno-vis:%{!mcpu=v9:-mvis}}} \ | |
345a6161 DM |
211 | " |
212 | #else | |
213 | #define CC1_SPEC "\ | |
214 | %{sun4:} %{target:} \ | |
215 | %{mcypress:-mcpu=cypress} \ | |
216 | %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ | |
217 | %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ | |
d6964c30 | 218 | %{m32:%{m64:%emay not use both -m32 and -m64}} \ |
4710d3eb | 219 | %{m32:-mptr32 -mno-stack-bias %{!mlong-double-128:-mlong-double-64} \ |
b25c3a22 | 220 | %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:-mcpu=cypress}}}}}}}} \ |
9ce13279 | 221 | %{!m32:%{!mcpu*:-mcpu=ultrasparc}} \ |
247cfc5c | 222 | %{!mno-vis:%{!m32:%{!mcpu=v9:-mvis}}} \ |
345a6161 DM |
223 | " |
224 | #endif | |
225 | ||
226 | #if DEFAULT_ARCH32_P | |
227 | #define MULTILIB_DEFAULTS { "m32" } | |
228 | #else | |
229 | #define MULTILIB_DEFAULTS { "m64" } | |
230 | #endif | |
231 | ||
232 | #else /* !SPARC_BI_ARCH */ | |
233 | ||
234 | #undef LINK_SPEC | |
e95b1e6a | 235 | #define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ |
bfe87013 DE |
236 | %{!shared: \ |
237 | %{!ibcs: \ | |
238 | %{!static: \ | |
239 | %{rdynamic:-export-dynamic} \ | |
345a6161 | 240 | %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \ |
bfe87013 DE |
241 | %{static:-static}}} \ |
242 | %{mlittle-endian:-EL} \ | |
e95b1e6a | 243 | %{!mno-relax:%{!r:-relax}} \ |
bfe87013 DE |
244 | " |
245 | ||
345a6161 DM |
246 | #endif /* !SPARC_BI_ARCH */ |
247 | ||
bfe87013 | 248 | /* The sun bundled assembler doesn't accept -Yd, (and neither does gas). |
80ffc95e | 249 | It's safe to pass -s always, even if -g is not used. */ |
bfe87013 DE |
250 | #undef ASM_SPEC |
251 | #define ASM_SPEC "\ | |
252 | %{V} \ | |
253 | %{v:%{!V:-V}} \ | |
254 | %{!Qn:-Qy} \ | |
255 | %{n} \ | |
256 | %{T} \ | |
257 | %{Ym,*} \ | |
258 | %{Wa,*:%*} \ | |
24a4dd31 | 259 | -s %{fpic|fPIC|fpie|fPIE:-K PIC} \ |
bfe87013 | 260 | %{mlittle-endian:-EL} \ |
e95b1e6a | 261 | %(asm_cpu) %(asm_arch) %(asm_relax)" |
bfe87013 DE |
262 | |
263 | /* Same as sparc.h */ | |
264 | #undef DBX_REGISTER_NUMBER | |
265 | #define DBX_REGISTER_NUMBER(REGNO) (REGNO) | |
266 | ||
267 | /* System V Release 4 uses DWARF debugging info. Buf DWARF1 doesn't do | |
268 | 64-bit anything, so we use DWARF2. */ | |
269 | ||
bfe87013 | 270 | #undef DWARF_DEBUGGING_INFO |
23532de9 JT |
271 | #define DWARF2_DEBUGGING_INFO 1 |
272 | #define DBX_DEBUGGING_INFO 1 | |
bfe87013 | 273 | |
bfe87013 DE |
274 | #undef ASM_OUTPUT_ALIGNED_LOCAL |
275 | #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ | |
276 | do { \ | |
277 | fputs ("\t.local\t", (FILE)); \ | |
278 | assemble_name ((FILE), (NAME)); \ | |
279 | putc ('\n', (FILE)); \ | |
280 | ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \ | |
281 | } while (0) | |
282 | ||
283 | #undef COMMON_ASM_OP | |
471b6f1b | 284 | #define COMMON_ASM_OP "\t.common\t" |
bfe87013 | 285 | |
59f96879 RH |
286 | #undef LOCAL_LABEL_PREFIX |
287 | #define LOCAL_LABEL_PREFIX "." | |
288 | ||
bfe87013 DE |
289 | /* This is how to output a reference to an internal numbered label where |
290 | PREFIX is the class of label and NUM is the number within the class. */ | |
291 | ||
292 | #undef ASM_OUTPUT_INTERNAL_LABELREF | |
293 | #define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \ | |
294 | fprintf (FILE, ".L%s%d", PREFIX, NUM) | |
295 | ||
296 | /* This is how to store into the string LABEL | |
297 | the symbol_ref name of an internal numbered label where | |
298 | PREFIX is the class of label and NUM is the number within the class. | |
299 | This is suitable for output with `assemble_name'. */ | |
300 | ||
301 | #undef ASM_GENERATE_INTERNAL_LABEL | |
302 | #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ | |
e59f7d3d | 303 | sprintf (LABEL, "*.L%s%ld", PREFIX, (long)(NUM)) |
bfe87013 | 304 | |
bfe87013 DE |
305 | /* DWARF bits. */ |
306 | ||
307 | /* Follow Irix 6 and not the Dwarf2 draft in using 64-bit offsets. | |
d6a7951f | 308 | Obviously the Dwarf2 folks haven't tried to actually build systems |
bfe87013 DE |
309 | with their spec. On a 64-bit system, only 64-bit relocs become |
310 | RELATIVE relocations. */ | |
311 | ||
312 | /* #define DWARF_OFFSET_SIZE PTR_SIZE */ | |
275b60d6 JJ |
313 | |
314 | #if defined(HAVE_LD_EH_FRAME_HDR) | |
315 | #define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " | |
316 | #endif | |
f7e0e539 | 317 | \f |
5751a10b JJ |
318 | #ifdef HAVE_AS_TLS |
319 | #undef TARGET_SUN_TLS | |
320 | #undef TARGET_GNU_TLS | |
321 | #define TARGET_SUN_TLS 0 | |
322 | #define TARGET_GNU_TLS 1 | |
323 | #endif | |
324 | \f | |
b5de1a27 DM |
325 | /* Don't be different from other Linux platforms in this regard. */ |
326 | #define HANDLE_PRAGMA_PACK_PUSH_POP | |
7a31a340 DM |
327 | |
328 | /* We use GNU ld so undefine this so that attribute((init_priority)) works. */ | |
329 | #undef CTORS_SECTION_ASM_OP | |
330 | #undef DTORS_SECTION_ASM_OP | |
db430d26 | 331 | |
a5fe455b | 332 | #define TARGET_ASM_FILE_END file_end_indicate_exec_stack |
3edc56a9 | 333 | |
d00eacab | 334 | #undef LINK_GCC_C_SEQUENCE_SPEC |
42df2193 JJ |
335 | #define LINK_GCC_C_SEQUENCE_SPEC \ |
336 | "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" | |
337 | ||
db430d26 DM |
338 | /* Do code reading to identify a signal frame, and set the frame |
339 | state data appropriately. See unwind-dw2.c for the structs. */ | |
340 | ||
db430d26 DM |
341 | /* Handle multilib correctly. */ |
342 | #if defined(__arch64__) | |
56149abc | 343 | /* 64-bit SPARC version */ |
db430d26 DM |
344 | #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ |
345 | do { \ | |
346 | unsigned int *pc_ = (CONTEXT)->ra; \ | |
347 | long new_cfa_, i_; \ | |
348 | long regs_off_, fpu_save_off_; \ | |
349 | long this_cfa_, fpu_save_; \ | |
350 | \ | |
351 | if (pc_[0] != 0x82102065 /* mov NR_rt_sigreturn, %g1 */ \ | |
352 | || pc_[1] != 0x91d0206d) /* ta 0x6d */ \ | |
353 | break; \ | |
354 | regs_off_ = 192 + 128; \ | |
355 | fpu_save_off_ = regs_off_ + (16 * 8) + (3 * 8) + (2 * 4); \ | |
356 | this_cfa_ = (long) (CONTEXT)->cfa; \ | |
357 | new_cfa_ = *(long *)(((CONTEXT)->cfa) + (regs_off_ + (14 * 8))); \ | |
3ef3f384 | 358 | new_cfa_ += 2047; /* Stack bias */ \ |
db430d26 DM |
359 | fpu_save_ = *(long *)((this_cfa_) + (fpu_save_off_)); \ |
360 | (FS)->cfa_how = CFA_REG_OFFSET; \ | |
361 | (FS)->cfa_reg = 14; \ | |
362 | (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ | |
363 | for (i_ = 1; i_ < 16; ++i_) \ | |
364 | { \ | |
db430d26 DM |
365 | (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \ |
366 | (FS)->regs.reg[i_].loc.offset = \ | |
367 | this_cfa_ + (regs_off_ + (i_ * 8)) - new_cfa_; \ | |
368 | } \ | |
369 | for (i_ = 0; i_ < 16; ++i_) \ | |
370 | { \ | |
371 | (FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \ | |
372 | (FS)->regs.reg[i_ + 16].loc.offset = \ | |
373 | this_cfa_ + (i_ * 8) - new_cfa_; \ | |
374 | } \ | |
375 | if (fpu_save_) \ | |
376 | { \ | |
377 | for (i_ = 0; i_ < 64; ++i_) \ | |
378 | { \ | |
379 | if (i_ > 32 && (i_ & 0x1)) \ | |
380 | continue; \ | |
381 | (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \ | |
382 | (FS)->regs.reg[i_ + 32].loc.offset = \ | |
383 | (fpu_save_ + (i_ * 4)) - new_cfa_; \ | |
384 | } \ | |
385 | } \ | |
386 | /* Stick return address into %g0, same trick Alpha uses. */ \ | |
387 | (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ | |
388 | (FS)->regs.reg[0].loc.offset = \ | |
389 | this_cfa_ + (regs_off_ + (16 * 8) + 8) - new_cfa_; \ | |
390 | (FS)->retaddr_column = 0; \ | |
391 | goto SUCCESS; \ | |
392 | } while (0) | |
393 | #else | |
56149abc | 394 | /* 32-bit SPARC version */ |
db430d26 DM |
395 | #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ |
396 | do { \ | |
397 | unsigned int *pc_ = (CONTEXT)->ra; \ | |
398 | int new_cfa_, i_, oldstyle_; \ | |
399 | int regs_off_, fpu_save_off_; \ | |
400 | int fpu_save_, this_cfa_; \ | |
401 | \ | |
402 | if (pc_[1] != 0x91d02010) /* ta 0x10 */ \ | |
403 | break; \ | |
404 | if (pc_[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ \ | |
405 | oldstyle_ = 1; \ | |
406 | else if (pc_[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ \ | |
407 | oldstyle_ = 0; \ | |
408 | else \ | |
409 | break; \ | |
410 | if (oldstyle_) \ | |
411 | { \ | |
412 | regs_off_ = 96; \ | |
413 | fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4); \ | |
414 | } \ | |
415 | else \ | |
416 | { \ | |
417 | regs_off_ = 96 + 128; \ | |
418 | fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4); \ | |
419 | } \ | |
420 | this_cfa_ = (int) (CONTEXT)->cfa; \ | |
421 | new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4))); \ | |
422 | fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_)); \ | |
423 | (FS)->cfa_how = CFA_REG_OFFSET; \ | |
424 | (FS)->cfa_reg = 14; \ | |
425 | (FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa; \ | |
426 | for (i_ = 1; i_ < 16; ++i_) \ | |
427 | { \ | |
428 | if (i_ == 14) \ | |
429 | continue; \ | |
430 | (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \ | |
431 | (FS)->regs.reg[i_].loc.offset = \ | |
432 | this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_; \ | |
433 | } \ | |
434 | for (i_ = 0; i_ < 16; ++i_) \ | |
435 | { \ | |
436 | (FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \ | |
437 | (FS)->regs.reg[i_ + 16].loc.offset = \ | |
438 | this_cfa_ + (i_ * 4) - new_cfa_; \ | |
439 | } \ | |
440 | if (fpu_save_) \ | |
441 | { \ | |
442 | for (i_ = 0; i_ < 32; ++i_) \ | |
443 | { \ | |
444 | (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \ | |
445 | (FS)->regs.reg[i_ + 32].loc.offset = \ | |
446 | (fpu_save_ + (i_ * 4)) - new_cfa_; \ | |
447 | } \ | |
448 | } \ | |
449 | /* Stick return address into %g0, same trick Alpha uses. */ \ | |
450 | (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ | |
451 | (FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_; \ | |
452 | (FS)->retaddr_column = 0; \ | |
453 | goto SUCCESS; \ | |
454 | } while (0) | |
455 | #endif |