update from main archive 970124
[glibc.git] / sysdeps / unix / sysv / linux / sparc / __sigtrampoline.S
blob4fea850ee3109730a597edd1e45cb17eb73fd929
1 /* Userland trampoline code for sigaction on Linux/SPARC        */
2 /* (C) 1996, 1997 Free Software Foundation, Inc.                */
3 /* This file is part of the GNU C Library.                      */
4 /* Contributed by Miguel de Icaza (miguel@gnu.ai.mit.edu)       */
5 /* Many thanks go to David Miller for explaining all this to me */
6 /* miguel@nuclecu.unam.mx                                       */
7 /* Sources:      David Miller, 4.4BSD/SPARC code                */
9 #include <sysdep.h>
11 /* For REGWIN_SZ */
12 #include <asm/ptrace.h>
13 #include <asm/psr.h>
15 /* The C compiler frame size */
16 #define CCFSZ  96
18         .text
20 ENTRY(____sparc_signal_trampoline)
21         .global SYMBOL_NAME(____sig_table)
23         /* Make room for 32 %f registers + %fsr
24          * this is 132 bytes + alignement = 136
25          * 96 is the C frame size
26          */
27         save    %sp,-136-CCFSZ,%sp
29         /* save regular registers */
30         mov     %g2,%l2
31         mov     %g3,%l3
32         mov     %g4,%l4
33         mov     %g5,%l5
34         mov     %g6,%l6
35         mov     %g7,%l7
37         /* save fpu registers */
38         ld      [%fp+64+16+20],%l0      /* load the psr from sigcontext */
39         sethi   %hi(PSR_EF),%l1
40         andcc   %l0,%l1,%l0             /* is floating point enabled?   */
41         be      1f
42         rd      %y,%l1                  /* save y anyways */
44         /* save fpu registers */
45         st      %fsr, [%sp + CCFSZ + 0]
46         std     %f0, [%sp + CCFSZ + 8]
47         std     %f2, [%sp + CCFSZ + 16]
48         std     %f4, [%sp + CCFSZ + 24]
49         std     %f6, [%sp + CCFSZ + 32]
50         std     %f8, [%sp + CCFSZ + 40]
51         std     %f10, [%sp + CCFSZ + 48]
52         std     %f12, [%sp + CCFSZ + 56]
53         std     %f14, [%sp + CCFSZ + 64]
54         std     %f16, [%sp + CCFSZ + 72]
55         std     %f18, [%sp + CCFSZ + 80]
56         std     %f20, [%sp + CCFSZ + 88]
57         std     %f22, [%sp + CCFSZ + 96]
58         std     %f24, [%sp + CCFSZ + 104]
59         std     %f26, [%sp + CCFSZ + 112]
60         std     %f28, [%sp + CCFSZ + 120]
61         std     %f30, [%sp + CCFSZ + 128]
64         /* Load signal number */
65         ld      [%fp + REGWIN_SZ],%o0
66         mov     %fp,%o1
67         mov     0xfea,%o2
69         /* Sanity check */
70         cmp     %o0,33
71         bl      1f
72         or      %g0,%g0,%g1     /*Call sys_setup */
73         t       0x10
75 #ifdef __PIC__
76         /* Save return address */
77         mov     %o7,%o4
78 ___sxx:
79         call    ___syy
80         nop
81 ___syy:
82         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
83         or      %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5
84         add     %o7,%o5,%o5
85         /* restore return address */
86         mov     %o4,%o7
87         mov     %o5,%o4
88         /* o4 has the GOT pointer */
89 #endif
90         sethi   %hi(SYMBOL_NAME(____sig_table)),%o5
91         or      %o5,%lo(SYMBOL_NAME(____sig_table)),%o5
92 #ifdef __PIC__
93         add     %o5,%o4,%o4
94         ld      [%o4],%o5
95 #endif
96         sll     %o0,2,%o4
97         add     %o5,%o4,%o4
98         ld      [%o4],%o4
99         ld      [%fp + REGWIN_SZ + 4],%o1         /* Load subcode */
100         ld      [%fp + REGWIN_SZ + 8],%o2         /* pointer to sigcontext */
101         call    %o4
102         ld      [%fp + REGWIN_SZ + 12],%o3        /* Address where signal occurred */
104         /* handler returned, restore state */
105         tst     %l0
106         be      1f
107         wr      %l1,%g0,%y
109         /* fpu restoration */
110         ld      [%sp + CCFSZ + 0], %fsr
111         ldd     [%sp + CCFSZ + 8], %f0
112         ldd     [%sp + CCFSZ + 16], %f2
113         ldd     [%sp + CCFSZ + 24], %f4
114         ldd     [%sp + CCFSZ + 32], %f6
115         ldd     [%sp + CCFSZ + 40], %f8
116         ldd     [%sp + CCFSZ + 48], %f10
117         ldd     [%sp + CCFSZ + 56], %f12
118         ldd     [%sp + CCFSZ + 64], %f14
119         ldd     [%sp + CCFSZ + 72], %f16
120         ldd     [%sp + CCFSZ + 80], %f18
121         ldd     [%sp + CCFSZ + 88], %f20
122         ldd     [%sp + CCFSZ + 96], %f22
123         ldd     [%sp + CCFSZ + 104], %f24
124         ldd     [%sp + CCFSZ + 112], %f26
125         ldd     [%sp + CCFSZ + 120], %f28
126         ldd     [%sp + CCFSZ + 128], %f30
129         mov     %l2,%g2
130         mov     %l3,%g3
131         mov     %l4,%g4
132         mov     %l5,%g5
133         mov     %l6,%g6
134         mov     %l7,%g7
136         /* call sigreturn */
137         restore %g0,SYS_sigreturn,%g1    /* register back and set syscall */
138         add     %sp,64+16,%o0
139         t       0x10
140         /* if we return, sysreturn failed */
141         mov     SYS_exit,%g1
142         t       0x10