Home | History | Annotate | Download | only in tests
      1 /* libunwind - a platform-independent unwind library
      2    Copyright (C) 2003 Hewlett-Packard Co
      3 	Contributed by David Mosberger-Tang <davidm (at) 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
    276