mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 07:37:38 +01:00
(Logical change 1.47)
This commit is contained in:
parent
9b16424457
commit
894b96b95a
3 changed files with 306 additions and 0 deletions
|
@ -0,0 +1,205 @@
|
|||
/* libunwind - a platform-independent unwind library
|
||||
Copyright (C) 2003 Hewlett-Packard Co
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of libunwind.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#include "ia64-test-rbs.h"
|
||||
|
||||
.common stackmem, NSTACKS*STACK_SIZE, 16
|
||||
|
||||
.text
|
||||
|
||||
#define SAVED_SP_OFF 0
|
||||
#define SAVED_RP_OFF 8
|
||||
#define SAVED_PFS_OFF 16
|
||||
#define SAVED_RNAT_OFF 24
|
||||
#define SAVED_BSP_OFF 32
|
||||
#define SAVED_BSPSTORE_OFF 40
|
||||
#define FRAME_SIZE 48
|
||||
|
||||
#define SPILL(n) \
|
||||
/* void rbs_spill_#n(long iteration, void (*next_func[])()) */ \
|
||||
.globl rbs_spill_##n; \
|
||||
.proc rbs_spill_##n; \
|
||||
rbs_spill_##n: \
|
||||
.prologue; \
|
||||
alloc r18 = ar.pfs, 2, (n)-2, 2, 0;/* read ar.pfs */ \
|
||||
/* first, calculate address of new stack: */ \
|
||||
addl r2 = @ltoff(stackmem), gp; \
|
||||
shladd r8 = in0, 3, in1; /* r8 = &next_func[iteration] */ \
|
||||
;; \
|
||||
ld8 r2 = [r2]; /* r2 = &stackmem */ \
|
||||
ld8 r8 = [r8]; /* r8 = next_func[iteration] */ \
|
||||
shl r3 = in0, STACK_SIZE_SHIFT; \
|
||||
;; \
|
||||
ld8 r9 = [r8], 8;; /* r9 = target's entry-point */ \
|
||||
ld8 gp = [r8]; /* r22 = target's gp */ \
|
||||
add r2 = r2, r3; /* r2 = stackmem[iteration] */ \
|
||||
;; \
|
||||
mov b6 = r9; \
|
||||
addl r3 = STACK_SIZE-FRAME_SIZE, r2; /* r3 = &stackframe */ \
|
||||
;; \
|
||||
st8 [r3] = sp; \
|
||||
.vframesp SAVED_SP_OFF+16; \
|
||||
adds sp = -16, r3; /* switch the memory stack */ \
|
||||
;; \
|
||||
adds r3 = (SAVED_RP_OFF - SAVED_SP_OFF), r3; \
|
||||
mov r16 = rp; \
|
||||
;; \
|
||||
.savesp rp, SAVED_RP_OFF+16; \
|
||||
st8 [r3] = r16, (SAVED_PFS_OFF - SAVED_RP_OFF); \
|
||||
;; \
|
||||
.savesp ar.pfs, SAVED_PFS_OFF+16; \
|
||||
st8 [r3] = r18, (SAVED_BSP_OFF - SAVED_PFS_OFF); \
|
||||
mov r16 = ar.bsp; \
|
||||
mov r17 = ar.bspstore; \
|
||||
mov r18 = ar.rnat; \
|
||||
;; \
|
||||
.savesp ar.bsp, SAVED_BSP_OFF+16; \
|
||||
st8 [r3] = r16, (SAVED_BSPSTORE_OFF - SAVED_BSP_OFF); \
|
||||
;; \
|
||||
.savesp ar.bspstore, SAVED_BSPSTORE_OFF+16; \
|
||||
st8 [r3] = r17, (SAVED_RNAT_OFF - SAVED_BSPSTORE_OFF); \
|
||||
mov out1 = in1; \
|
||||
;; \
|
||||
.savesp ar.rnat, SAVED_RNAT_OFF+16; \
|
||||
st8 [r3] = r18; \
|
||||
.body; \
|
||||
mov ar.bspstore = r2; /* switch the backing store */ \
|
||||
adds out0 = 1, in0; \
|
||||
;; \
|
||||
br.call.sptk.many rp = b6; \
|
||||
1: /* switch back to stack: */ \
|
||||
adds r3 = SAVED_SP_OFF+16, sp; \
|
||||
;; \
|
||||
ld8 r16 = [r3], (SAVED_RP_OFF-SAVED_SP_OFF);; /* saved sp */ \
|
||||
ld8 r17 = [r3], (SAVED_PFS_OFF-SAVED_RP_OFF);; /* saved rp */ \
|
||||
ld8 r18 = [r3], (SAVED_RNAT_OFF-SAVED_PFS_OFF);;/* saved pfs */ \
|
||||
ld8 r19 = [r3], (SAVED_BSP_OFF-SAVED_RNAT_OFF);;/* saved rnat */ \
|
||||
ld8 r20 = [r3], (SAVED_BSPSTORE_OFF-SAVED_BSP_OFF);;/* saved bsp */ \
|
||||
ld8 r21 = [r3];; /* saved bspstore */ \
|
||||
mov rp = r17; \
|
||||
mov ar.pfs = r18; \
|
||||
mov ar.bspstore = r21; /* this also restores ar.bsp */ \
|
||||
;; \
|
||||
mov ar.rnat = r19; \
|
||||
.restore sp; \
|
||||
mov sp = r16; \
|
||||
br.ret.sptk.many rp; \
|
||||
.endp rbs_spill_##n
|
||||
|
||||
SPILL(2); SPILL(3)
|
||||
SPILL(4); SPILL(5); SPILL(6); SPILL(7)
|
||||
SPILL(8); SPILL(9); SPILL(10); SPILL(11)
|
||||
SPILL(12); SPILL(13); SPILL(14); SPILL(15)
|
||||
SPILL(16); SPILL(17); SPILL(18); SPILL(19)
|
||||
SPILL(20); SPILL(21); SPILL(22); SPILL(23)
|
||||
SPILL(24); SPILL(25); SPILL(26); SPILL(27)
|
||||
SPILL(28); SPILL(29); SPILL(30); SPILL(31)
|
||||
SPILL(32); SPILL(33); SPILL(34); SPILL(35)
|
||||
SPILL(36); SPILL(37); SPILL(38); SPILL(39)
|
||||
SPILL(40); SPILL(41); SPILL(42); SPILL(43)
|
||||
SPILL(44); SPILL(45); SPILL(46); SPILL(47)
|
||||
SPILL(48); SPILL(49); SPILL(50); SPILL(51)
|
||||
SPILL(52); SPILL(53); SPILL(54); SPILL(55)
|
||||
SPILL(56); SPILL(57); SPILL(58); SPILL(59)
|
||||
SPILL(60); SPILL(61); SPILL(62); SPILL(63)
|
||||
SPILL(64); SPILL(65); SPILL(66); SPILL(67)
|
||||
SPILL(68); SPILL(69); SPILL(70); SPILL(71)
|
||||
SPILL(72); SPILL(73); SPILL(74); SPILL(75)
|
||||
SPILL(76); SPILL(77); SPILL(78); SPILL(79)
|
||||
SPILL(80); SPILL(81); SPILL(82); SPILL(83)
|
||||
SPILL(84); SPILL(85); SPILL(86); SPILL(87)
|
||||
SPILL(88); SPILL(89); SPILL(90); SPILL(91)
|
||||
SPILL(92); SPILL(93); SPILL(94)
|
||||
|
||||
#define LD_LOC(n) \
|
||||
ld4 loc##n = [in1], 8;; \
|
||||
cmp.eq p8, p9 = r0, loc##n;; \
|
||||
(p9) or loc##n = loc##n, r8; \
|
||||
(p8) ld4.s loc##n = [r0]
|
||||
|
||||
/* void loadup (long iteration, int *values, next_func[]) */
|
||||
|
||||
.global loadup
|
||||
.proc loadup
|
||||
loadup:
|
||||
.prologue
|
||||
.save ar.pfs, r34
|
||||
alloc loc1 = ar.pfs, 3, 90, 3, 0
|
||||
.save rp, loc0
|
||||
mov loc0 = rp
|
||||
.body
|
||||
cmp.eq p6, p7 = 1, in0
|
||||
;;
|
||||
mov ar.rsc = 0 // put RSE into enforced lazy mode
|
||||
(p6) mov out1 = in2
|
||||
(p7) mov out2 = in2
|
||||
|
||||
(p6) ld8 r17 = [in2] // get address of function descriptor
|
||||
(p7) add out0 = -1, in0
|
||||
(p7) mov out1 = in1
|
||||
|
||||
;;
|
||||
(p6) ld8 r16 = [r17], 8 // load entry point
|
||||
shl r8 = in0, 32 // store iteration # in top 32 bits
|
||||
;;
|
||||
(p6) ld8 r1 = [r17] // load gp
|
||||
(p6) mov b6 = r16
|
||||
|
||||
(p6) mov out0 = 0
|
||||
;;
|
||||
LD_LOC( 2); LD_LOC( 3)
|
||||
LD_LOC( 4); LD_LOC( 5); LD_LOC( 6); LD_LOC( 7)
|
||||
LD_LOC( 8); LD_LOC( 9); LD_LOC(10); LD_LOC(11)
|
||||
LD_LOC(12); LD_LOC(13); LD_LOC(14); LD_LOC(15)
|
||||
LD_LOC(16); LD_LOC(17); LD_LOC(18); LD_LOC(19)
|
||||
LD_LOC(20); LD_LOC(21); LD_LOC(22); LD_LOC(23)
|
||||
LD_LOC(24); LD_LOC(25); LD_LOC(26); LD_LOC(27)
|
||||
LD_LOC(28); LD_LOC(29); LD_LOC(30); LD_LOC(31)
|
||||
LD_LOC(32); LD_LOC(33); LD_LOC(34); LD_LOC(35)
|
||||
LD_LOC(36); LD_LOC(37); LD_LOC(38); LD_LOC(39)
|
||||
LD_LOC(40); LD_LOC(41); LD_LOC(42); LD_LOC(43)
|
||||
LD_LOC(44); LD_LOC(45); LD_LOC(46); LD_LOC(47)
|
||||
LD_LOC(48); LD_LOC(49); LD_LOC(50); LD_LOC(51)
|
||||
LD_LOC(52); LD_LOC(53); LD_LOC(54); LD_LOC(55)
|
||||
LD_LOC(56); LD_LOC(57); LD_LOC(58); LD_LOC(59)
|
||||
LD_LOC(60); LD_LOC(61); LD_LOC(62); LD_LOC(63)
|
||||
LD_LOC(64); LD_LOC(65); LD_LOC(66); LD_LOC(67)
|
||||
LD_LOC(68); LD_LOC(69); LD_LOC(70); LD_LOC(71)
|
||||
LD_LOC(72); LD_LOC(73); LD_LOC(74); LD_LOC(75)
|
||||
LD_LOC(76); LD_LOC(77); LD_LOC(78); LD_LOC(79)
|
||||
LD_LOC(80); LD_LOC(81); LD_LOC(82); LD_LOC(83)
|
||||
LD_LOC(84); LD_LOC(85); LD_LOC(86); LD_LOC(87)
|
||||
LD_LOC(88); LD_LOC(89)
|
||||
;;
|
||||
{ .mbb
|
||||
(p6) br.call.sptk.many rp = b6
|
||||
(p7) br.call.sptk.many rp = loadup
|
||||
}
|
||||
;;
|
||||
|
||||
mov rp = loc0
|
||||
mov ar.pfs = loc1
|
||||
br.ret.sptk.many rp
|
||||
.endp loadup
|
|
@ -0,0 +1,98 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
|
||||
#define panic(args...) \
|
||||
do { fprintf (stderr, args); ++nerrors; return; } while (0)
|
||||
|
||||
/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64
|
||||
implementations to at most 2048 physical stacked registers
|
||||
(actually, slightly less than that, because loadrs also counts RNaT
|
||||
slots). Since we can dirty 95 stacked registers per recursion, we
|
||||
need to recurse RECURSION_DEPTH times to ensure all physical
|
||||
stacked registers are in use. */
|
||||
#define MAX_PHYS_STACKED 2048
|
||||
#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 94) / 95)
|
||||
|
||||
typedef void spill_func_t (long iteration, void (*next_func[])());
|
||||
|
||||
extern void loadup (long iteration, int *values, void (*next_func[])());
|
||||
|
||||
#define DCL(n) \
|
||||
extern void rbs_spill_##n (long iteration, void (*next_func[])())
|
||||
DCL(2); DCL(3); DCL(4); DCL(5); DCL(6); DCL(7);
|
||||
DCL(8); DCL(9); DCL(10); DCL(11); DCL(12); DCL(13); DCL(14); DCL(15);
|
||||
DCL(16); DCL(17); DCL(18); DCL(19); DCL(20); DCL(21); DCL(22); DCL(23);
|
||||
DCL(24); DCL(25); DCL(26); DCL(27); DCL(28); DCL(29); DCL(30); DCL(31);
|
||||
DCL(32); DCL(33); DCL(34); DCL(35); DCL(36); DCL(37); DCL(38); DCL(39);
|
||||
DCL(40); DCL(41); DCL(42); DCL(43); DCL(44); DCL(45); DCL(46); DCL(47);
|
||||
DCL(48); DCL(49); DCL(50); DCL(51); DCL(52); DCL(53); DCL(54); DCL(55);
|
||||
DCL(56); DCL(57); DCL(58); DCL(59); DCL(60); DCL(61); DCL(62); DCL(63);
|
||||
DCL(64); DCL(65); DCL(66); DCL(67); DCL(68); DCL(69); DCL(70); DCL(71);
|
||||
DCL(72); DCL(73); DCL(74); DCL(75); DCL(76); DCL(77); DCL(78); DCL(79);
|
||||
DCL(80); DCL(81); DCL(82); DCL(83); DCL(84); DCL(85); DCL(86); DCL(87);
|
||||
DCL(88); DCL(89); DCL(90); DCL(91); DCL(92); DCL(93); DCL(94);
|
||||
|
||||
#define SPL(n) rbs_spill_##n
|
||||
spill_func_t *spill_funcs[] =
|
||||
{
|
||||
SPL(2), SPL(3), SPL(4), SPL(5), SPL(6), SPL(7),
|
||||
SPL(8), SPL(9), SPL(10), SPL(11), SPL(12), SPL(13), SPL(14), SPL(15),
|
||||
SPL(16), SPL(17), SPL(18), SPL(19), SPL(20), SPL(21), SPL(22), SPL(23),
|
||||
SPL(24), SPL(25), SPL(26), SPL(27), SPL(28), SPL(29), SPL(30), SPL(31),
|
||||
SPL(32), SPL(33), SPL(34), SPL(35), SPL(36), SPL(37), SPL(38), SPL(39),
|
||||
SPL(40), SPL(41), SPL(42), SPL(43), SPL(44), SPL(45), SPL(46), SPL(47),
|
||||
SPL(48), SPL(49), SPL(50), SPL(51), SPL(52), SPL(53), SPL(54), SPL(55),
|
||||
SPL(56), SPL(57), SPL(58), SPL(59), SPL(60), SPL(61), SPL(62), SPL(63),
|
||||
SPL(64), SPL(65), SPL(66), SPL(67), SPL(68), SPL(69), SPL(70), SPL(71),
|
||||
SPL(72), SPL(73), SPL(74), SPL(75), SPL(76), SPL(77), SPL(78), SPL(79),
|
||||
SPL(80), SPL(81), SPL(82), SPL(83), SPL(84), SPL(85), SPL(86), SPL(87),
|
||||
SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94)
|
||||
};
|
||||
|
||||
static long nerrors;
|
||||
static long unwind_count;
|
||||
|
||||
static void
|
||||
unwind_and_resume (long iteration, void (*next_func[])())
|
||||
{
|
||||
unw_context_t uc;
|
||||
unw_cursor_t c;
|
||||
int i, ret;
|
||||
|
||||
printf ("%s: iteration=%ld, next_func=%p\n",
|
||||
__FUNCTION__, iteration, next_func);
|
||||
|
||||
unw_getcontext (&uc);
|
||||
if ((ret = unw_init_local (&c, &uc)) < 0)
|
||||
panic ("unw_init_local (ret=%d)", ret);
|
||||
|
||||
for (i = 0; i < unwind_count; ++i)
|
||||
if ((ret = unw_step (&c)) < 0)
|
||||
panic ("unw_step (ret=%d)", ret);
|
||||
|
||||
ret = unw_resume (&c);
|
||||
panic ("unw_resume() returned (ret=%d)!!\n", ret);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
spill_func_t *test1[16];
|
||||
int i, reg_values[88];
|
||||
|
||||
for (i = 0; i < (int) (sizeof (reg_values) / sizeof (reg_values[0])); ++i)
|
||||
reg_values[i] = random ();
|
||||
|
||||
test1[0] = SPL (3);
|
||||
test1[1] = SPL (10);
|
||||
test1[2] = SPL (5);
|
||||
test1[3] = SPL (17);
|
||||
test1[4] = unwind_and_resume;
|
||||
unwind_count = 6;
|
||||
loadup (RECURSION_DEPTH, reg_values, test1);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#define NSTACKS 128
|
||||
#define STACK_SIZE_SHIFT 17
|
||||
#define STACK_SIZE (1 << STACK_SIZE_SHIFT)
|
Loading…
Reference in a new issue