5c73b0c25ef40ef8a9e6d81093ad1782ced5bbf9
[gcc.git] / gcc / config / ia64 / linux.h
1 /* Definitions for ia64-linux target. */
2
3 /* This macro is a C statement to print on `stderr' a string describing the
4 particular machine description choice. */
5
6 #define TARGET_VERSION fprintf (stderr, " (IA-64) Linux");
7
8 /* This is for -profile to use -lc_p instead of -lc. */
9 #undef CC1_SPEC
10 #define CC1_SPEC "%{profile:-p} %{G*}"
11
12 /* Target OS builtins. */
13 #define TARGET_OS_CPP_BUILTINS() \
14 do { \
15 LINUX_TARGET_OS_CPP_BUILTINS(); \
16 builtin_define("_LONGLONG"); \
17 } while (0)
18
19 /* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
20 #undef STARTFILE_SPEC
21 #ifdef HAVE_LD_PIE
22 #define STARTFILE_SPEC \
23 "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
24 crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
25 #else
26 #define STARTFILE_SPEC \
27 "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}}\
28 crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
29 #endif
30
31 /* Similar to standard Linux, but adding -ffast-math support. */
32 #undef ENDFILE_SPEC
33 #define ENDFILE_SPEC \
34 "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
35 %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
36
37 /* Define this for shared library support because it isn't in the main
38 linux.h file. */
39
40 #undef LINK_SPEC
41 #define LINK_SPEC "\
42 %{shared:-shared} \
43 %{!shared: \
44 %{!static: \
45 %{rdynamic:-export-dynamic} \
46 %{!dynamic-linker:-dynamic-linker /lib/ld-linux-ia64.so.2}} \
47 %{static:-static}}"
48
49
50 #define JMP_BUF_SIZE 76
51
52 /* Override linux.h LINK_EH_SPEC definition.
53 Signalize that because we have fde-glibc, we don't need all C shared libs
54 linked against -lgcc_s. */
55 #undef LINK_EH_SPEC
56 #define LINK_EH_SPEC ""
57
58 /* Do code reading to identify a signal frame, and set the frame
59 state data appropriately. See unwind-dw2.c for the structs. */
60
61 /* This works only for glibc-2.3 and later, because sigcontext is different
62 in glibc-2.2.4. */
63
64 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
65
66 #ifdef IN_LIBGCC2
67 #include <signal.h>
68 #include <sys/ucontext.h>
69
70 #define IA64_GATE_AREA_START 0xa000000000000100LL
71 #define IA64_GATE_AREA_END 0xa000000000030000LL
72
73 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
74 if ((CONTEXT)->rp >= IA64_GATE_AREA_START \
75 && (CONTEXT)->rp < IA64_GATE_AREA_END) \
76 { \
77 struct sigframe { \
78 char scratch[16]; \
79 unsigned long sig_number; \
80 struct siginfo *info; \
81 struct sigcontext *sc; \
82 } *frame_ = (struct sigframe *)(CONTEXT)->psp; \
83 struct sigcontext *sc_ = frame_->sc; \
84 \
85 /* Restore scratch registers in case the unwinder needs to \
86 refer to a value stored in one of them. */ \
87 { \
88 int i_; \
89 \
90 for (i_ = 2; i_ < 4; i_++) \
91 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
92 for (i_ = 8; i_ < 12; i_++) \
93 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
94 for (i_ = 14; i_ < 32; i_++) \
95 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
96 } \
97 \
98 (CONTEXT)->fpsr_loc = &(sc_->sc_ar_fpsr); \
99 (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
100 (CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
101 (CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
102 (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
103 (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
104 (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
105 (CONTEXT)->pr = sc_->sc_pr; \
106 (CONTEXT)->psp = sc_->sc_gr[12]; \
107 (CONTEXT)->gp = sc_->sc_gr[1]; \
108 /* Signal frame doesn't have an associated reg. stack frame \
109 other than what we adjust for below. */ \
110 (FS) -> no_reg_stack_frame = 1; \
111 \
112 if (sc_->sc_rbs_base) \
113 { \
114 /* Need to switch from alternate register backing store. */ \
115 long ndirty, loadrs = sc_->sc_loadrs >> 16; \
116 unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
117 unsigned long bspstore; \
118 unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
119 \
120 ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
121 (unsigned long *) (CONTEXT)->bsp);\
122 bspstore = (unsigned long) \
123 ia64_rse_skip_regs (ar_bsp, -ndirty); \
124 ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
125 sc_->sc_ar_rnat); \
126 } \
127 \
128 /* Don't touch the branch registers o.t. b0, b6 and b7. \
129 The kernel doesn't pass the preserved branch registers \
130 in the sigcontext but leaves them intact, so there's no \
131 need to do anything with them here. */ \
132 { \
133 unsigned long sof = sc_->sc_cfm & 0x7f; \
134 (CONTEXT)->bsp = (unsigned long) \
135 ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
136 } \
137 \
138 (FS)->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL; \
139 (FS)->curr.reg[UNW_REG_RP].val \
140 = (unsigned long)&(sc_->sc_ip) - (CONTEXT)->psp; \
141 (FS)->curr.reg[UNW_REG_RP].when = -1; \
142 \
143 goto SUCCESS; \
144 }
145
146 #define MD_HANDLE_UNWABI(CONTEXT, FS) \
147 if ((FS)->unwabi == ((3 << 8) | 's') \
148 || (FS)->unwabi == ((0 << 8) | 's')) \
149 { \
150 struct sigframe { \
151 char scratch[16]; \
152 unsigned long sig_number; \
153 struct siginfo *info; \
154 struct sigcontext *sc; \
155 } *frame_ = (struct sigframe *)(CONTEXT)->psp; \
156 struct sigcontext *sc_ = frame_->sc; \
157 \
158 /* Restore scratch registers in case the unwinder needs to \
159 refer to a value stored in one of them. */ \
160 { \
161 int i_; \
162 \
163 for (i_ = 2; i_ < 4; i_++) \
164 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
165 for (i_ = 8; i_ < 12; i_++) \
166 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
167 for (i_ = 14; i_ < 32; i_++) \
168 (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
169 } \
170 \
171 (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
172 (CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
173 (CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
174 (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
175 (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
176 (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
177 (CONTEXT)->pr = sc_->sc_pr; \
178 (CONTEXT)->gp = sc_->sc_gr[1]; \
179 /* Signal frame doesn't have an associated reg. stack frame \
180 other than what we adjust for below. */ \
181 (FS) -> no_reg_stack_frame = 1; \
182 \
183 if (sc_->sc_rbs_base) \
184 { \
185 /* Need to switch from alternate register backing store. */ \
186 long ndirty, loadrs = sc_->sc_loadrs >> 16; \
187 unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
188 unsigned long bspstore; \
189 unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
190 \
191 ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
192 (unsigned long *) (CONTEXT)->bsp);\
193 bspstore = (unsigned long) \
194 ia64_rse_skip_regs (ar_bsp, -ndirty); \
195 ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
196 sc_->sc_ar_rnat); \
197 } \
198 \
199 /* Don't touch the branch registers o.t. b0, b6 and b7. \
200 The kernel doesn't pass the preserved branch registers \
201 in the sigcontext but leaves them intact, so there's no \
202 need to do anything with them here. */ \
203 { \
204 unsigned long sof = sc_->sc_cfm & 0x7f; \
205 (CONTEXT)->bsp = (unsigned long) \
206 ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
207 } \
208 \
209 /* pfs_loc already set above. Without this pfs_loc would point \
210 incorrectly to sc_cfm instead of sc_ar_pfs. */ \
211 (FS)->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE; \
212 }
213
214 #endif /* IN_LIBGCC2 */
215 #endif /* glibc-2.3 or better */