import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / sparc64 / lib / VISsave.S
1 /* $Id: VISsave.S,v 1.5 2001/03/08 22:08:51 davem Exp $
2  * VISsave.S: Code for saving FPU register state for
3  *            VIS routines. One should not call this directly,
4  *            but use macros provided in <asm/visasm.h>.
5  *
6  * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
7  */
8
9 #include <asm/asi.h>
10 #include <asm/page.h>
11 #include <asm/ptrace.h>
12 #include <asm/visasm.h>
13
14         .text
15         .globl          VISenter, VISenterhalf
16
17         /* On entry: %o5=current FPRS value, %g7 is callers address */
18         /* May clobber %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
19
20         .align          32
21 VISenter:
22         ldub            [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1
23         brnz,a,pn       %g1, 1f
24          cmp            %g1, 1
25         stb             %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
26         stx             %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
27 9:      jmpl            %g7 + %g0, %g0
28          nop
29 1:      bne,pn          %icc, 2f
30
31          srl            %g1, 1, %g1
32 vis1:   ldub            [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
33         stx             %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
34         or              %g3, %o5, %g3
35         stb             %g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
36         rd              %gsr, %g3
37         clr             %g1
38         ba,pt           %xcc, 3f
39
40          stx            %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
41 2:      add             %g6, %g1, %g3
42         cmp             %o5, FPRS_DU
43         be,pn           %icc, 6f
44          sll            %g1, 3, %g1
45         stb             %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
46         rd              %gsr, %g2
47         add             %g6, %g1, %g3
48         stx             %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
49
50         add             %g6, %g1, %g2
51         stx             %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
52         sll             %g1, 5, %g1
53 3:      andcc           %o5, FPRS_DL|FPRS_DU, %g0
54         be,pn           %icc, 9b
55          add            %g6, AOFF_task_fpregs, %g2
56         andcc           %o5, FPRS_DL, %g0
57         membar          #StoreStore | #LoadStore
58
59         be,pn           %icc, 4f
60          add            %g6, AOFF_task_fpregs+0x40, %g3
61         stda            %f0, [%g2 + %g1] ASI_BLK_P
62         stda            %f16, [%g3 + %g1] ASI_BLK_P
63         andcc           %o5, FPRS_DU, %g0
64         be,pn           %icc, 5f
65 4:       add            %g1, 128, %g1
66         stda            %f32, [%g2 + %g1] ASI_BLK_P
67
68         stda            %f48, [%g3 + %g1] ASI_BLK_P
69 5:      membar          #Sync
70         jmpl            %g7 + %g0, %g0
71          nop
72
73 6:      ldub            [%g3 + AOFF_task_thread + AOFF_thread_fpsaved], %o5
74         or              %o5, FPRS_DU, %o5
75         add             %g6, AOFF_task_fpregs+0x80, %g2
76         stb             %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
77
78         sll             %g1, 5, %g1
79         add             %g6, AOFF_task_fpregs+0xc0, %g3
80         wr              %g0, FPRS_FEF, %fprs
81         membar          #StoreStore | #LoadStore
82         stda            %f32, [%g2 + %g1] ASI_BLK_P
83         stda            %f48, [%g3 + %g1] ASI_BLK_P
84         membar          #Sync
85         jmpl            %g7 + %g0, %g0
86
87          nop
88
89         .align          32
90 VISenterhalf:
91         ldub            [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1
92         brnz,a,pn       %g1, 1f
93          cmp            %g1, 1
94         stb             %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
95         stx             %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
96         clr             %o5
97         jmpl            %g7 + %g0, %g0
98          wr             %g0, FPRS_FEF, %fprs
99
100 1:      bne,pn          %icc, 2f
101          srl            %g1, 1, %g1
102         ba,pt           %xcc, vis1
103          sub            %g7, 8, %g7
104 2:      addcc           %g6, %g1, %g3
105         sll             %g1, 3, %g1
106         andn            %o5, FPRS_DU, %g2
107         stb             %g2, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
108
109         rd              %gsr, %g2
110         add             %g6, %g1, %g3
111         stx             %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
112         add             %g6, %g1, %g2
113         stx             %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
114         sll             %g1, 5, %g1
115 3:      andcc           %o5, FPRS_DL, %g0
116         be,pn           %icc, 4f
117          add            %g6, AOFF_task_fpregs, %g2
118
119         membar          #StoreStore | #LoadStore
120         add             %g6, AOFF_task_fpregs+0x40, %g3
121         stda            %f0, [%g2 + %g1] ASI_BLK_P
122         stda            %f16, [%g3 + %g1] ASI_BLK_P
123         membar          #Sync
124 4:      and             %o5, FPRS_DU, %o5
125         jmpl            %g7 + %g0, %g0
126          wr             %o5, FPRS_FEF, %fprs