OSDN Git Service

* config/s390/s390.h (EH_RETURN_HANDLER_RTX): Compute offset
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / linux.h
1 /* Definitions for Linux for S/390.
2    Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3    Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4                   Ulrich Weigand (uweigand@de.ibm.com).
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23 #ifndef _LINUX_H
24 #define _LINUX_H
25
26 /* Target specific version string.  */
27
28 #ifdef DEFAULT_TARGET_64BIT
29 #undef  TARGET_VERSION
30 #define TARGET_VERSION fprintf (stderr, " (Linux for zSeries)");
31 #else
32 #undef  TARGET_VERSION
33 #define TARGET_VERSION fprintf (stderr, " (Linux for S/390)");
34 #endif
35
36
37 /* Target specific type definitions.  */
38
39 /* ??? Do we really want long as size_t on 31-bit?  */
40 #undef  SIZE_TYPE
41 #define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "long unsigned int")
42 #undef  PTRDIFF_TYPE
43 #define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
44
45 #undef  WCHAR_TYPE
46 #define WCHAR_TYPE "int"
47 #undef  WCHAR_TYPE_SIZE
48 #define WCHAR_TYPE_SIZE 32
49
50
51 /* Target specific preprocessor settings.  */
52
53 #define TARGET_OS_CPP_BUILTINS()                \
54   do                                            \
55     {                                           \
56       builtin_define_std ("linux");             \
57       builtin_define_std ("unix");              \
58       builtin_assert ("system=linux");          \
59       builtin_assert ("system=unix");           \
60       builtin_define ("__gnu_linux__");         \
61       if (flag_pic)                             \
62         {                                       \
63           builtin_define ("__PIC__");           \
64           builtin_define ("__pic__");           \
65         }                                       \
66     }                                           \
67   while (0)
68
69
70 /* Target specific assembler settings.  */
71
72 #undef  ASM_SPEC
73 #define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*}"
74
75
76 /* Target specific linker settings.  */
77
78 #ifdef DEFAULT_TARGET_64BIT
79 #define MULTILIB_DEFAULTS { "m64" }
80 #else
81 #define MULTILIB_DEFAULTS { "m31" }
82 #endif
83
84 #undef  LINK_SPEC
85 #define LINK_SPEC \
86   "%{m31:-m elf_s390}%{m64:-m elf64_s390} \
87    %{shared:-shared} \
88    %{!shared: \
89       %{static:-static} \
90       %{!static: \
91         %{rdynamic:-export-dynamic} \
92         %{!dynamic-linker: \
93           %{m31:-dynamic-linker /lib/ld.so.1} \
94           %{m64:-dynamic-linker /lib/ld64.so.1}}}}"
95
96
97 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
98
99 /* Do code reading to identify a signal frame, and set the frame
100    state data appropriately.  See unwind-dw2.c for the structs.  */
101
102 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)               \
103   do {                                                                  \
104     unsigned char *pc_ = (CONTEXT)->ra;                                 \
105     long new_cfa_;                                                      \
106     int i_;                                                             \
107                                                                         \
108     typedef struct                                                      \
109       {                                                                 \
110         unsigned long psw_mask;                                         \
111         unsigned long psw_addr;                                         \
112         unsigned long gprs[16];                                         \
113         unsigned int  acrs[16];                                         \
114         unsigned int  fpc;                                              \
115         unsigned int  __pad;                                            \
116         double        fprs[16];                                         \
117       } __attribute__ ((__aligned__ (8))) sigregs_;                     \
118                                                                         \
119     sigregs_ *regs_;                                                    \
120                                                                         \
121     /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */                \
122     if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173))             \
123       break;                                                            \
124                                                                         \
125     /* New-style RT frame:                                              \
126         retcode + alignment (8 bytes)                                   \
127         siginfo (128 bytes)                                             \
128         ucontext (contains sigregs)  */                                 \
129     if ((CONTEXT)->ra == (CONTEXT)->cfa)                                \
130       {                                                                 \
131         struct ucontext_                                                \
132           {                                                             \
133             unsigned long     uc_flags;                                 \
134             struct ucontext_ *uc_link;                                  \
135             unsigned long     uc_stack[3];                              \
136             sigregs_          uc_mcontext;                              \
137           } *uc_ = (CONTEXT)->cfa + 8 + 128;                            \
138                                                                         \
139         regs_ = &uc_->uc_mcontext;                                      \
140       }                                                                 \
141                                                                         \
142     /* Old-style RT frame and all non-RT frames:                        \
143         old signal mask (8 bytes)                                       \
144         pointer to sigregs  */                                          \
145     else                                                                \
146       {                                                                 \
147         regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8);                     \
148       }                                                                 \
149                                                                         \
150     new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32;                  \
151     (FS)->cfa_how = CFA_REG_OFFSET;                                     \
152     (FS)->cfa_reg = 15;                                                 \
153     (FS)->cfa_offset =                                                  \
154       new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32;          \
155                                                                         \
156     for (i_ = 0; i_ < 16; i_++)                                         \
157       {                                                                 \
158         (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                      \
159         (FS)->regs.reg[i_].loc.offset =                                 \
160           (long)&regs_->gprs[i_] - new_cfa_;                            \
161       }                                                                 \
162     for (i_ = 0; i_ < 16; i_++)                                         \
163       {                                                                 \
164         (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET;                   \
165         (FS)->regs.reg[16+i_].loc.offset =                              \
166           (long)&regs_->fprs[i_] - new_cfa_;                            \
167       }                                                                 \
168                                                                         \
169     /* Load return addr from PSW into dummy register 32.  */            \
170     (FS)->regs.reg[32].how = REG_SAVED_OFFSET;                          \
171     (FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_;  \
172     (FS)->retaddr_column = 32;                                          \
173                                                                         \
174     goto SUCCESS;                                                       \
175   } while (0)
176
177 #endif