~ubuntu-branches/ubuntu/precise/eglibc/precise-201308281639

« back to all changes in this revision

Viewing changes to ports/sysdeps/unix/sysv/linux/tile/setcontext.S

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-02-08 01:58:09 UTC
  • mfrom: (1.5.3) (288.1.12 precise)
  • Revision ID: package-import@ubuntu.com-20120208015809-ulscst7uteq3e22z
Tags: 2.15~pre6-0ubuntu10
Merge from Debian (r5151, 2.13-26).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2011 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
 
4
 
 
5
   The GNU C Library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Lesser General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2.1 of the License, or (at your option) any later version.
 
9
 
 
10
   The GNU C Library is distributed in the hope that it will be useful,
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   Lesser General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Lesser General Public
 
16
   License along with the GNU C Library; if not, write to the Free
 
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
18
   02111-1307 USA.  */
 
19
 
 
20
#include <sysdep.h>
 
21
#include <asm/errno.h>
 
22
#include <arch/spr_def.h>
 
23
#include <arch/abi.h>
 
24
 
 
25
#include "ucontext_i.h"
 
26
 
 
27
/* PL to return to via iret in setcontext */
 
28
#define RETURN_PL 0
 
29
 
 
30
/* int setcontext (const ucontext_t *ucp) */
 
31
 
 
32
        .text
 
33
ENTRY (__setcontext)
 
34
        FEEDBACK_ENTER(__setcontext)
 
35
 
 
36
        /* See if this is a true signal context (flags == 0).
 
37
           If so, restore by invoking rt_sigreturn().  */
 
38
#if UC_FLAGS_OFFSET != 0
 
39
# error "Add offset to r0 prior to load."
 
40
#endif
 
41
        LD r10, r0
 
42
        {
 
43
         BEQZ r10, .Lsigreturn
 
44
         addi r10, r10, -1  /* Confirm that it has value "1".  */
 
45
        }
 
46
        BNEZ r10, .Lbadcontext
 
47
 
 
48
        /* Save lr and r0 briefly on the stack and set the signal mask:
 
49
           rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG / 8).  */
 
50
        {
 
51
         ST sp, lr
 
52
         ADDI_PTR r11, sp, -(2 * REGSIZE)
 
53
         move r10, sp
 
54
        }
 
55
        cfi_offset (lr, 0)
 
56
        {
 
57
         ST r11, r10
 
58
         ADDI_PTR r10, sp, -REGSIZE
 
59
         ADDI_PTR sp, sp, -(3 * REGSIZE)
 
60
        }
 
61
        cfi_def_cfa_offset (3 * REGSIZE)
 
62
        {
 
63
         ST r10, r0
 
64
         ADDLI_PTR r1, r0, UC_SIGMASK_OFFSET
 
65
        }
 
66
        cfi_offset (r0, -REGSIZE)
 
67
        {
 
68
         movei r3, _NSIG / 8
 
69
         movei r2, 0
 
70
        }
 
71
        {
 
72
         movei r0, SIG_SETMASK
 
73
         moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigprocmask
 
74
        }
 
75
        swint1
 
76
        {
 
77
         ADDI_PTR sp, sp, 3 * REGSIZE
 
78
         ADDI_PTR r11, sp, 2 * REGSIZE  /* Restore uc_context to r11. */
 
79
        }
 
80
        cfi_def_cfa_offset (0)
 
81
        LD lr, sp
 
82
        LD r11, r11
 
83
        {
 
84
         ADDI_PTR r10, r11, UC_REG(0)
 
85
         BNEZ r1, .Lsyscall_error
 
86
        }
 
87
 
 
88
        /* Restore the argument registers; note they will be random
 
89
           unless makecontext() has been called.  */
 
90
        { LD r0, r10; ADDI_PTR r10, r10, REGSIZE }
 
91
        { LD r1, r10; ADDI_PTR r10, r10, REGSIZE }
 
92
        { LD r2, r10; ADDI_PTR r10, r10, REGSIZE }
 
93
        { LD r3, r10; ADDI_PTR r10, r10, REGSIZE }
 
94
        { LD r4, r10; ADDI_PTR r10, r10, REGSIZE }
 
95
        { LD r5, r10; ADDI_PTR r10, r10, REGSIZE }
 
96
        { LD r6, r10; ADDI_PTR r10, r10, REGSIZE }
 
97
        { LD r7, r10; ADDI_PTR r10, r10, REGSIZE }
 
98
        { LD r8, r10; ADDI_PTR r10, r10, REGSIZE }
 
99
        { LD r9, r10; ADDLI_PTR r10, r10, UC_REG(30) - UC_REG(9) }
 
100
 
 
101
        /* Restore the callee-saved GPRs.  */
 
102
        { LD r30, r10; ADDI_PTR r10, r10, REGSIZE }
 
103
        { LD r31, r10; ADDI_PTR r10, r10, REGSIZE }
 
104
        { LD r32, r10; ADDI_PTR r10, r10, REGSIZE }
 
105
        { LD r33, r10; ADDI_PTR r10, r10, REGSIZE }
 
106
        { LD r34, r10; ADDI_PTR r10, r10, REGSIZE }
 
107
        { LD r35, r10; ADDI_PTR r10, r10, REGSIZE }
 
108
        { LD r36, r10; ADDI_PTR r10, r10, REGSIZE }
 
109
        { LD r37, r10; ADDI_PTR r10, r10, REGSIZE }
 
110
        { LD r38, r10; ADDI_PTR r10, r10, REGSIZE }
 
111
        { LD r39, r10; ADDI_PTR r10, r10, REGSIZE }
 
112
        { LD r40, r10; ADDI_PTR r10, r10, REGSIZE }
 
113
        { LD r41, r10; ADDI_PTR r10, r10, REGSIZE }
 
114
        { LD r42, r10; ADDI_PTR r10, r10, REGSIZE }
 
115
        { LD r43, r10; ADDI_PTR r10, r10, REGSIZE }
 
116
        { LD r44, r10; ADDI_PTR r10, r10, REGSIZE }
 
117
        { LD r45, r10; ADDI_PTR r10, r10, REGSIZE }
 
118
        { LD r46, r10; ADDI_PTR r10, r10, REGSIZE }
 
119
        { LD r47, r10; ADDI_PTR r10, r10, REGSIZE }
 
120
        { LD r48, r10; ADDI_PTR r10, r10, REGSIZE }
 
121
        { LD r49, r10; ADDI_PTR r10, r10, REGSIZE }
 
122
        { LD r50, r10; ADDI_PTR r10, r10, REGSIZE }
 
123
        { LD r51, r10; ADDI_PTR r10, r10, REGSIZE }
 
124
        { LD r52, r10; ADDI_PTR r10, r10, REGSIZE * 2 }
 
125
        /* Skip tp since it must not change for a given thread.  */
 
126
        { LD sp, r10;  ADDI_PTR r10, r10, REGSIZE }
 
127
        { LD lr, r10;  ADDI_PTR r10, r10, REGSIZE }
 
128
        { LD r11, r10; ADDI_PTR r10, r10, REGSIZE }
 
129
 
 
130
        /* Construct an iret context; we set ICS so we can validly load
 
131
           EX_CONTEXT for iret without being interrupted halfway through.  */
 
132
        {
 
133
         LD r12, r10
 
134
         movei r13, 1
 
135
        }
 
136
        {
 
137
         mtspr INTERRUPT_CRITICAL_SECTION, r13
 
138
         shli r12, r12, SPR_EX_CONTEXT_0_1__ICS_SHIFT
 
139
        }
 
140
        {
 
141
         mtspr EX_CONTEXT_0_0, r11
 
142
         ori r12, r12, RETURN_PL
 
143
        }
 
144
        mtspr EX_CONTEXT_0_1, r12
 
145
        iret
 
146
        jrp lr    /* keep the backtracer happy */
 
147
        
 
148
.Lsigreturn:
 
149
        /* This is a context obtained from a signal handler.
 
150
           Perform a full restore by pushing the context
 
151
           passed onto a simulated signal frame on the stack
 
152
           and call the signal return syscall as if a signal
 
153
           handler exited normally.  */
 
154
        {
 
155
         ADDLI_PTR sp, sp, -(C_ABI_SAVE_AREA_SIZE + SI_MAX_SIZE + UC_SIZE)
 
156
         ADDLI_PTR r1, sp, -UC_SIZE
 
157
        }
 
158
        cfi_def_cfa_offset (C_ABI_SAVE_AREA_SIZE + SI_MAX_SIZE + UC_SIZE)
 
159
        moveli r2, UC_SIZE / REGSIZE
 
160
0:      {
 
161
         LD r10, r0
 
162
         ADDI_PTR r0, r0, REGSIZE
 
163
        }
 
164
        {
 
165
         ST r1, r10
 
166
         ADDI_PTR r1, r1, REGSIZE
 
167
         addi r2, r2, -1
 
168
        }
 
169
        BNEZ r2, 0b
 
170
        moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigreturn
 
171
        swint1
 
172
 
 
173
        /* Restore the stack and fall through to the error
 
174
           path.  Successful rt_sigreturn never returns to
 
175
           its calling place.  */
 
176
        ADDLI_PTR sp, sp, (C_ABI_SAVE_AREA_SIZE + SI_MAX_SIZE + UC_SIZE)
 
177
        cfi_def_cfa_offset (0)
 
178
 
 
179
.Lsyscall_error:
 
180
        j SYSCALL_ERROR_NAME
 
181
 
 
182
.Lbadcontext:
 
183
        {
 
184
         movei r1, EINVAL
 
185
         j SYSCALL_ERROR_NAME
 
186
        }
 
187
 
 
188
END (__setcontext)
 
189
 
 
190
.hidden __setcontext
 
191
weak_alias (__setcontext, setcontext)
 
192
 
 
193
ENTRY (__startcontext)
 
194
        FEEDBACK_ENTER(__startcontext)
 
195
        BEQZ r30, 1f
 
196
        {
 
197
         move r0, r30
 
198
         jal __setcontext
 
199
        }
 
200
1:      j HIDDEN_JUMPTARGET(exit)
 
201
END (__startcontext)
 
202
.hidden __startcontext