OSDN Git Service

* trans.h (struct gfc_ss): New field nested_ss.
[pf3gnuchains/gcc-fork.git] / gcc / ada / sigtramp-ppcvxw.c
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                             S I G T R A M P                              *
6  *                                                                          *
7  *                         Asm Implementation File                          *
8  *                                                                          *
9  *            Copyright (C) 2011, Free Software Foundation, Inc.            *
10  *                                                                          *
11  * GNAT is free software;  you can  redistribute it  and/or modify it under *
12  * terms of the  GNU General Public License as published  by the Free Soft- *
13  * ware  Foundation;  either version 3,  or (at your option) any later ver- *
14  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
15  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
16  * or FITNESS FOR A PARTICULAR PURPOSE.                                     *
17  *                                                                          *
18  * As a special exception under Section 7 of GPL version 3, you are granted *
19  * additional permissions described in the GCC Runtime Library Exception,   *
20  * version 3.1, as published by the Free Software Foundation.               *
21  *                                                                          *
22  * In particular,  you can freely  distribute your programs  built with the *
23  * GNAT Pro compiler, including any required library run-time units,  using *
24  * any licensing terms  of your choosing.  See the AdaCore Software License *
25  * for full details.                                                        *
26  *                                                                          *
27  * GNAT was originally developed  by the GNAT team at  New York University. *
28  * Extensive contributions were provided by Ada Core Technologies Inc.      *
29  *                                                                          *
30  ****************************************************************************/
31
32 /**********************************************************
33  * PowerPC-VxWorks version of the __gnat_sigtramp service *
34  **********************************************************/
35
36 #include "sigtramp.h"
37
38 #include <vxWorks.h>
39 #include <arch/../regs.h>
40 #include <sigLib.h>
41
42 /* ----------------------
43    -- General comments --
44    ----------------------
45
46    Stubs are generated from toplevel asms and .cfi directives, much simpler
47    to use and check for correctness than manual encodings of CFI byte
48    sequences.  The general idea is to establish CFA as sigcontext->sc_pregs
49    and state where to find the registers as offsets from there.
50
51    As of today, we support a single stub, providing CFI info for common
52    registers (GPRs, LR, ...). We might need variants with support for floating
53    point or altivec registers as well at some point.
54
55    Checking which variant should apply and getting at sc_pregs is simpler
56    to express in C (we can't use offsetof in toplevel asms and hardcoding
57    constants is not workable with the flurry of VxWorks variants), so this
58    is the choice for our toplevel interface.  */
59
60 /* -----------------------------------------
61    -- Protypes for our internal asm stubs --
62    -----------------------------------------
63
64    SC_PREGS is always expected to be SIGCONTEXT->sc_pregs.  Eventhough our
65    symbols will remain local, the prototype claims "extern" and not
66    "static" to prevent compiler complaints about a symbol used but never
67    defined.  */
68
69 /* sigtramp stub providing CFI info for common registers.  */
70
71 extern void __gnat_sigtramp_common
72 (int signo, void *siginfo, void *sigcontext,
73  sighandler_t * handler, void * sc_pregs);
74
75
76 /* -------------------------------------
77    -- Common interface implementation --
78    -------------------------------------
79
80    We enforce optimization to minimize the overhead of the extra layer.  */
81
82 void __gnat_sigtramp (int signo, void *si, void *sc,
83                       sighandler_t * handler)
84      __attribute__((optimize(2)));
85
86 void __gnat_sigtramp (int signo, void *si, void *sc,
87                       sighandler_t * handler)
88 {
89   struct sigcontext * sctx = (struct sigcontext *) sc;
90
91   __gnat_sigtramp_common (signo, si, sctx, handler, sctx->sc_pregs);
92 }
93
94
95 /* ---------------------------
96    -- And now the asm stubs --
97    ---------------------------
98
99    They all have a common structure with blocks of asm sequences queued one
100    after the others.  Typically:
101
102    SYMBOL_START
103
104    CFI_DIRECTIVES
105      CFI_DEF_CFA,
106      CFI_COMMON_REGISTERS,
107      ...
108
109    STUB_BODY
110      asm code to establish frame, setup the cfa reg value,
111      call the real signal handler, ...
112
113    SYMBOL_END
114 */
115
116 /*--------------------------------
117   -- Misc constants and helpers --
118   -------------------------------- */
119
120 /* REGNO constants, dwarf column numbers for registers of interest.  */
121
122 #define REGNO_LR  65
123 #define REGNO_XER 76
124 #define REGNO_CR  70
125 #define REGNO_GR(N) (N)
126
127 #define REGNO_PC  67  /* ARG_POINTER_REGNUM  */
128
129 /* asm string contruction helpers.  */
130
131 #define STR(TEXT) #TEXT
132 /* stringify expanded TEXT, surrounding it with double quotes.  */
133
134 #define S(E) STR(E)
135 /* stringify E, which will resolve as text but may contain macros
136    still to be expanded.  */
137
138 /* asm (TEXT) outputs <tab>TEXT. These facilitate the output of
139    multine contents:  */
140 #define TAB(S) "\t" S
141 #define CR(S)  S "\n"
142 #define TCR(S) TAB(CR(S))
143
144 /*------------------------------
145   -- Stub construction blocks --
146   ------------------------------ */
147
148 /* CFA setup block
149    ---------------
150    Only non-volatile registers are suitable for a CFA base.  We use r14
151    here and set it to the value we need in stub body that follows.  */
152
153 #define CFI_DEF_CFA \
154 CR(".cfi_def_cfa 14, 0")
155
156 /* Register location blocks
157    ------------------------
158    Rules to find registers of interest from the CFA. This should
159    comprise all the non-volatile registers relevant to the interrupted
160    context.  */
161
162 #define COMMON_CFI(REG) \
163   ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
164
165 #define CFI_COMMON_REGS \
166 CR("# CFI for common registers\n") \
167 TCR(COMMON_CFI(GR(1)))  \
168 TCR(COMMON_CFI(GR(14))) \
169 TCR(COMMON_CFI(GR(15))) \
170 TCR(COMMON_CFI(GR(16))) \
171 TCR(COMMON_CFI(GR(17))) \
172 TCR(COMMON_CFI(GR(18))) \
173 TCR(COMMON_CFI(GR(19))) \
174 TCR(COMMON_CFI(GR(20))) \
175 TCR(COMMON_CFI(GR(21))) \
176 TCR(COMMON_CFI(GR(22))) \
177 TCR(COMMON_CFI(GR(23))) \
178 TCR(COMMON_CFI(GR(24))) \
179 TCR(COMMON_CFI(GR(25))) \
180 TCR(COMMON_CFI(GR(26))) \
181 TCR(COMMON_CFI(GR(27))) \
182 TCR(COMMON_CFI(GR(28))) \
183 TCR(COMMON_CFI(GR(29))) \
184 TCR(COMMON_CFI(GR(30))) \
185 TCR(COMMON_CFI(GR(31))) \
186 TCR(COMMON_CFI(LR)) \
187 TCR(COMMON_CFI(CR)) \
188 TCR(COMMON_CFI(PC)) \
189 TCR(".cfi_return_column " S(REGNO_PC))
190
191 /* Trampoline body block
192    ---------------------  */
193
194 #define SIGTRAMP_BODY \
195 CR("") \
196 TCR("# Allocate frame and save the non-volatile") \
197 TCR("# registers we're going to modify") \
198 TCR("stwu %r1,-16(%r1)")  \
199 TCR("mflr %r0") \
200 TCR("stw %r0,20(%r1)")  \
201 TCR("stw %r14,8(%r1)")  \
202 TCR("")                 \
203 TCR("# Setup r14 = sc_pregs, that we'll retrieve as our CFA value") \
204 TCR("mr %r14, %r7") \
205 TCR("")                 \
206 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
207 TCR("# arguments are the same as those we received in r3, r4 and r5") \
208 TCR("mtctr %r6") \
209 TCR("bctrl")    \
210 TCR("")         \
211 TCR("# Restore our callee-saved items, release our frame and return") \
212 TCR("lwz %r14,8(%r1)")  \
213 TCR("lwz %r0,20(%r1)")  \
214 TCR("mtlr %r0")         \
215 TCR("")                 \
216 TCR("addi %r1,%r1,16")  \
217 TCR("blr")
218
219 /* Symbol definition block
220    -----------------------  */
221
222 #define SIGTRAMP_START(SYM) \
223 CR("# " S(SYM) " cfi trampoline") \
224 TCR(".type " S(SYM) ", @function") \
225 CR("") \
226 CR(S(SYM) ":") \
227 TCR(".cfi_startproc") \
228 TCR(".cfi_signal_frame")
229
230 /* Symbol termination block
231    ------------------------  */
232
233 #define SIGTRAMP_END(SYM) \
234 CR(".cfi_endproc") \
235 TCR(".size " S(SYM) ", .-" S(SYM))
236
237 /*----------------------------
238   -- And now, the real code --
239   ---------------------------- */
240
241 /* Text section start.  The compiler isn't aware of that switch.  */
242
243 asm (".text\n"
244      TCR(".align 2"));
245
246 /* sigtramp stub for common registers.  */
247
248 #define TRAMP_COMMON __gnat_sigtramp_common
249
250 asm (SIGTRAMP_START(TRAMP_COMMON));
251 asm (CFI_DEF_CFA);
252 asm (CFI_COMMON_REGS);
253 asm (SIGTRAMP_BODY);
254 asm (SIGTRAMP_END(TRAMP_COMMON));
255
256