1 /* libunwind - a platform-independent unwind library
2 Copyright (C) 2003 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of libunwind.
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:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
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. */
26 #include "ia64-test-rbs.h"
28 .common stackmem, NSTACKS*STACK_SIZE, 16
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
41 /* int rbs_spill_#n(long iteration, int (*next_func[])()) */ \
42 .globl rbs_spill_##n; \
43 .proc rbs_spill_##n; \
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; \
51 ld8 r2 = [r2]; /* r2 = &stackmem */ \
52 shl r3 = in0, STACK_SIZE_SHIFT; \
53 shladd r8 = r8, 3, in1; /* r8 = &next_func[iteration+1] */ \
55 ld8 r8 = [r8]; /* r8 = next_func[iteration+1] */ \
56 add r2 = r2, r3; /* r2 = stackmem[iteration] */ \
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 */ \
64 .vframesp SAVED_SP_OFF+16; \
65 adds sp = -16, r3; /* switch the memory stack */ \
67 adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3; \
70 .savesp rp, SAVED_RP_OFF+16; \
71 st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF); \
73 .savesp ar.pfs, SAVED_PFS_OFF+16; \
74 st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF); \
76 mov r17 = ar.bspstore; \
79 .savesp ar.bsp, SAVED_BSP_OFF+16; \
80 st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF); \
82 .savesp ar.bspstore, SAVED_BSPSTORE_OFF+16; \
83 st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF); \
86 .savesp ar.rnat, SAVED_RNAT_OFF+16; \
89 mov ar.bspstore = r2; /* switch the backing store */ \
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; \
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 */ \
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] */ \
111 sub r2 = r3, r2;; /* r2 = dirty_size */ \
114 alloc r3 = ar.pfs, 0, 0, 0, 0;; \
116 mov ar.bspstore = r21;; /* this also restores ar.bsp */ \
120 br.ret.sptk.many rp; \
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)
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]
155 ld4 r16 = [in1], 4;; \
156 cmp.eq p8, p9 = r0, r16; \
158 (p8) tnat.z p10, p0 = loc##n; \
159 (p9) cmp.ne p10, p0 = r16, loc##n; \
162 (p10) br.cond.spnt.many .fail
164 /* int loadup(long iteration, int *values, next_func[]) */
171 alloc loc1 = ar.pfs, 3, 90, 3, 0
175 cmp.eq p6, p7 = 1, in0
177 mov ar.rsc = 0 // put RSE into enforced lazy mode
181 (p6) ld8 r17 = [in2] // get address of function descriptor
182 (p7) add out0 = -1, in0
186 (p6) ld8 r16 = [r17], 8 // load entry point
187 shl r8 = in0, 32 // store iteration # in top 32 bits
190 (p6) ld8 r1 = [r17] // load gp
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)
221 (p6) br.call.sptk.many rp = b6
222 (p7) br.call.sptk.many rp = loadup
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
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)
258 .global resumption_point_label
259 .proc resumption_point
261 resumption_point_label:
270 .endp resumption_point
273 /* We do not need executable stack. */
274 .section .note.GNU-stack,"",@progbits