Initial import
[external/libunwind.git] / tests / ia64-test-rbs-asm.S
1 /* libunwind - a platform-independent unwind library
2    Copyright (C) 2003 Hewlett-Packard Co
3         Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of libunwind.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25
26 #include "ia64-test-rbs.h"
27
28         .common stackmem, NSTACKS*STACK_SIZE, 16
29
30         .text
31
32 #define SAVED_SP_OFF             0
33 #define SAVED_RP_OFF             8
34 #define SAVED_PFS_OFF           16
35 #define SAVED_RNAT_OFF          24
36 #define SAVED_BSP_OFF           32
37 #define SAVED_BSPSTORE_OFF      40
38 #define FRAME_SIZE              48
39
40 #define SPILL(n)                                                             \
41         /* int rbs_spill_#n(long iteration, int (*next_func[])()) */         \
42         .globl rbs_spill_##n;                                                \
43         .proc rbs_spill_##n;                                                 \
44 rbs_spill_##n:                                                               \
45         .prologue;                                                           \
46         alloc r18 = ar.pfs, 2, (n)-2, 2, 0;/* read ar.pfs */                 \
47         /* first, calculate address of new stack: */                         \
48         addl r2 = @ltoff(stackmem), gp;                                      \
49         add r8 = 1, in0;                                                     \
50         ;;                                                                   \
51         ld8 r2 = [r2];                  /* r2 = &stackmem */                 \
52         shl r3 = in0, STACK_SIZE_SHIFT;                                      \
53         shladd r8 = r8, 3, in1;         /* r8 = &next_func[iteration+1] */   \
54         ;;                                                                   \
55         ld8 r8 = [r8];                  /* r8 = next_func[iteration+1] */    \
56         add r2 = r2, r3;                /* r2 = stackmem[iteration] */       \
57         ;;                                                                   \
58         ld8 r9 = [r8], 8;;              /* r9 = target's entry-point */      \
59         ld8 gp = [r8];                  /* r22 = target's gp */              \
60         addl r3 = STACK_SIZE-FRAME_SIZE, r2; /* r3 = &stackframe */          \
61         ;;                                                                   \
62         mov b6 = r9;                                                         \
63         st8 [r3] = sp;                                                       \
64         .vframesp SAVED_SP_OFF+16;                                           \
65         adds sp = -16, r3;              /* switch the memory stack */        \
66         ;;                                                                   \
67         adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3;                         \
68         mov r16 = rp;                                                        \
69         ;;                                                                   \
70         .savesp rp, SAVED_RP_OFF+16;                                         \
71         st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF);                      \
72         ;;                                                                   \
73         .savesp ar.pfs, SAVED_PFS_OFF+16;                                    \
74         st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF);                     \
75         mov r16 = ar.bsp;                                                    \
76         mov r17 = ar.bspstore;                                               \
77         mov r18 = ar.rnat;                                                   \
78         ;;                                                                   \
79         .savesp ar.bsp, SAVED_BSP_OFF+16;                                    \
80         st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF);                \
81         ;;                                                                   \
82         .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16;                          \
83         st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF);               \
84         mov out1 = in1;                                                      \
85         ;;                                                                   \
86         .savesp ar.rnat, SAVED_RNAT_OFF+16;                                  \
87         st8 [r3] = r18;                                                      \
88         .body;                                                               \
89         mov ar.bspstore = r2;           /* switch the backing store */       \
90         adds out0 = 1, in0;                                                  \
91         ;;                                                                   \
92         br.call.sptk.many rp = b6;                                           \
93 1:      /* switch back to stack: */                                          \
94         adds r3 = SAVED_SP_OFF+16, sp;                                       \
95         cmp.ge p8, p0 = r8, r0;                                              \
96         ;;                                                                   \
97 (p8)    add r8 = 1, r8;                                                      \
98         ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);;   /* saved sp */       \
99         ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);;  /* saved rp */       \
100         ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);;/* saved pfs */      \
101         ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);;/* saved rnat */     \
102         ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);;/* saved bsp */  \
103         ld8 r21 = [r3];;                                /* saved bspstore */ \
104         mov rp = r17;                                                        \
105         mov ar.pfs = r18;                                                    \
106         shl r3 = in0, STACK_SIZE_SHIFT;                                      \
107         addl r2 = @ltoff(stackmem), gp;;                                     \
108         ld8 r2 = [r2];;                 /* r2 = &stackmem */                 \
109         add r2 = r2, r3;                /* r2 = stackmem[iteration] */       \
110         mov r3 = ar.bsp;;                                                    \
111         sub r2 = r3, r2;;               /* r2 = dirty_size */                \
112         shl r2 = r2, 16;;                                                    \
113         mov ar.rsc = r2;;                                                    \
114         alloc r3 = ar.pfs, 0, 0, 0, 0;;                                      \
115         loadrs;;                                                             \
116         mov ar.bspstore = r21;; /* this also restores ar.bsp */              \
117         mov ar.rnat = r19;                                                   \
118         .restore sp;                                                         \
119         mov sp = r16;                                                        \
120         br.ret.sptk.many rp;                                                 \
121         .endp rbs_spill_##n
122
123                         SPILL(2);  SPILL(3)
124   SPILL(4);  SPILL(5);  SPILL(6);  SPILL(7)
125   SPILL(8);  SPILL(9); SPILL(10); SPILL(11)
126  SPILL(12); SPILL(13); SPILL(14); SPILL(15)
127  SPILL(16); SPILL(17); SPILL(18); SPILL(19)
128  SPILL(20); SPILL(21); SPILL(22); SPILL(23)
129  SPILL(24); SPILL(25); SPILL(26); SPILL(27)
130  SPILL(28); SPILL(29); SPILL(30); SPILL(31)
131  SPILL(32); SPILL(33); SPILL(34); SPILL(35)
132  SPILL(36); SPILL(37); SPILL(38); SPILL(39)
133  SPILL(40); SPILL(41); SPILL(42); SPILL(43)
134  SPILL(44); SPILL(45); SPILL(46); SPILL(47)
135  SPILL(48); SPILL(49); SPILL(50); SPILL(51)
136  SPILL(52); SPILL(53); SPILL(54); SPILL(55)
137  SPILL(56); SPILL(57); SPILL(58); SPILL(59)
138  SPILL(60); SPILL(61); SPILL(62); SPILL(63)
139  SPILL(64); SPILL(65); SPILL(66); SPILL(67)
140  SPILL(68); SPILL(69); SPILL(70); SPILL(71)
141  SPILL(72); SPILL(73); SPILL(74); SPILL(75)
142  SPILL(76); SPILL(77); SPILL(78); SPILL(79)
143  SPILL(80); SPILL(81); SPILL(82); SPILL(83)
144  SPILL(84); SPILL(85); SPILL(86); SPILL(87)
145  SPILL(88); SPILL(89); SPILL(90); SPILL(91)
146  SPILL(92); SPILL(93); SPILL(94)
147
148 #define LD_LOC(n)                               \
149         ld4 loc##n = [in1], 4;;                 \
150         cmp.eq p8, p9 = r0, loc##n;;            \
151 (p9)    or loc##n = loc##n, r8;                 \
152 (p8)    ld4.s loc##n = [r0]
153
154 #define CK_LOC(n)                               \
155         ld4 r16 = [in1], 4;;                    \
156         cmp.eq p8, p9 = r0, r16;                \
157         or r16 = r16, r9;;                      \
158 (p8)    tnat.z p10, p0 = loc##n;                \
159 (p9)    cmp.ne p10, p0 = r16, loc##n;           \
160         ;;                                      \
161 (p10)   mov r8 = -n;                            \
162 (p10)   br.cond.spnt.many .fail
163
164         /* int loadup(long iteration, int *values, next_func[]) */
165
166         .global loadup
167         .proc loadup
168 loadup:
169         .prologue
170         .save ar.pfs, r36
171         alloc loc1 = ar.pfs, 3, 90, 3, 0
172         .save rp, loc0
173         mov loc0 = rp
174         .body
175         cmp.eq p6, p7 = 1, in0
176         ;;
177         mov ar.rsc = 0          // put RSE into enforced lazy mode
178 (p6)    mov out1 = in2
179 (p7)    mov out2 = in2
180
181 (p6)    ld8 r17 = [in2]         // get address of function descriptor
182 (p7)    add out0 = -1, in0
183 (p7)    mov out1 = in1
184
185         ;;
186 (p6)    ld8 r16 = [r17], 8      // load entry point
187         shl r8 = in0, 32        // store iteration # in top 32 bits
188         mov r18 = in1
189         ;;
190 (p6)    ld8 r1 = [r17]          // load gp
191 (p6)    mov b6 = r16
192
193 (p6)    mov out0 = 0
194         ;;
195         LD_LOC( 2); LD_LOC( 3)
196         LD_LOC( 4); LD_LOC( 5); LD_LOC( 6); LD_LOC( 7)
197         LD_LOC( 8); LD_LOC( 9); LD_LOC(10); LD_LOC(11)
198         LD_LOC(12); LD_LOC(13); LD_LOC(14); LD_LOC(15)
199         LD_LOC(16); LD_LOC(17); LD_LOC(18); LD_LOC(19)
200         LD_LOC(20); LD_LOC(21); LD_LOC(22); LD_LOC(23)
201         LD_LOC(24); LD_LOC(25); LD_LOC(26); LD_LOC(27)
202         LD_LOC(28); LD_LOC(29); LD_LOC(30); LD_LOC(31)
203         LD_LOC(32); LD_LOC(33); LD_LOC(34); LD_LOC(35)
204         LD_LOC(36); LD_LOC(37); LD_LOC(38); LD_LOC(39)
205         LD_LOC(40); LD_LOC(41); LD_LOC(42); LD_LOC(43)
206         LD_LOC(44); LD_LOC(45); LD_LOC(46); LD_LOC(47)
207         LD_LOC(48); LD_LOC(49); LD_LOC(50); LD_LOC(51)
208         LD_LOC(52); LD_LOC(53); LD_LOC(54); LD_LOC(55)
209         LD_LOC(56); LD_LOC(57); LD_LOC(58); LD_LOC(59)
210         LD_LOC(60); LD_LOC(61); LD_LOC(62); LD_LOC(63)
211         LD_LOC(64); LD_LOC(65); LD_LOC(66); LD_LOC(67)
212         LD_LOC(68); LD_LOC(69); LD_LOC(70); LD_LOC(71)
213         LD_LOC(72); LD_LOC(73); LD_LOC(74); LD_LOC(75)
214         LD_LOC(76); LD_LOC(77); LD_LOC(78); LD_LOC(79)
215         LD_LOC(80); LD_LOC(81); LD_LOC(82); LD_LOC(83)
216         LD_LOC(84); LD_LOC(85); LD_LOC(86); LD_LOC(87)
217         LD_LOC(88); LD_LOC(89)
218         ;;
219 {       .mbb
220         mov in1 = r18
221 (p6)    br.call.sptk.many rp = b6
222 (p7)    br.call.sptk.many rp = loadup
223 }
224         cmp.lt p8, p9 = r8, r0
225         shl r9 = in0, 32        // store iteration # in top 32 bits
226 (p8)    br.cond.spnt.few .fail
227         ;;
228         add r8 = 1, r8
229         CK_LOC( 2); CK_LOC( 3)
230         CK_LOC( 4); CK_LOC( 5); CK_LOC( 6); CK_LOC( 7)
231         CK_LOC( 8); CK_LOC( 9); CK_LOC(10); CK_LOC(11)
232         CK_LOC(12); CK_LOC(13); CK_LOC(14); CK_LOC(15)
233         CK_LOC(16); CK_LOC(17); CK_LOC(18); CK_LOC(19)
234         CK_LOC(20); CK_LOC(21); CK_LOC(22); CK_LOC(23)
235         CK_LOC(24); CK_LOC(25); CK_LOC(26); CK_LOC(27)
236         CK_LOC(28); CK_LOC(29); CK_LOC(30); CK_LOC(31)
237         CK_LOC(32); CK_LOC(33); CK_LOC(34); CK_LOC(35)
238         CK_LOC(36); CK_LOC(37); CK_LOC(38); CK_LOC(39)
239         CK_LOC(40); CK_LOC(41); CK_LOC(42); CK_LOC(43)
240         CK_LOC(44); CK_LOC(45); CK_LOC(46); CK_LOC(47)
241         CK_LOC(48); CK_LOC(49); CK_LOC(50); CK_LOC(51)
242         CK_LOC(52); CK_LOC(53); CK_LOC(54); CK_LOC(55)
243         CK_LOC(56); CK_LOC(57); CK_LOC(58); CK_LOC(59)
244         CK_LOC(60); CK_LOC(61); CK_LOC(62); CK_LOC(63)
245         CK_LOC(64); CK_LOC(65); CK_LOC(66); CK_LOC(67)
246         CK_LOC(68); CK_LOC(69); CK_LOC(70); CK_LOC(71)
247         CK_LOC(72); CK_LOC(73); CK_LOC(74); CK_LOC(75)
248         CK_LOC(76); CK_LOC(77); CK_LOC(78); CK_LOC(79)
249         CK_LOC(80); CK_LOC(81); CK_LOC(82); CK_LOC(83)
250         CK_LOC(84); CK_LOC(85); CK_LOC(86); CK_LOC(87)
251         CK_LOC(88); CK_LOC(89)
252 .fail:
253         mov rp = loc0
254         mov ar.pfs = loc1
255         br.ret.sptk.many rp
256         .endp loadup
257
258         .global resumption_point_label
259         .proc resumption_point
260 resumption_point:
261 resumption_point_label:
262         .prologue
263         .save rp, r16
264         .save ar.pfs, r0
265         .body
266         mov r8 = r15
267         mov b6 = r16
268         ;;
269         br.cond.sptk.many b6
270         .endp resumption_point
271
272 #ifdef __linux__
273         /* We do not need executable stack.  */
274         .section        .note.GNU-stack,"",@progbits
275 #endif