Merge tag 'powerpc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / tools / testing / selftests / powerpc / math / fpu_asm.S
1 /*
2  * Copyright 2015, Cyril Bur, IBM Corp.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version
7  * 2 of the License, or (at your option) any later version.
8  */
9
10 #include "../basic_asm.h"
11 #include "../fpu_asm.h"
12
13 FUNC_START(check_fpu)
14         mr r4,r3
15         li      r3,1 # assume a bad result
16         lfd     f0,0(r4)
17         fcmpu   cr1,f0,f14
18         bne     cr1,1f
19         lfd     f0,8(r4)
20         fcmpu   cr1,f0,f15
21         bne     cr1,1f
22         lfd     f0,16(r4)
23         fcmpu   cr1,f0,f16
24         bne     cr1,1f
25         lfd     f0,24(r4)
26         fcmpu   cr1,f0,f17
27         bne     cr1,1f
28         lfd     f0,32(r4)
29         fcmpu   cr1,f0,f18
30         bne     cr1,1f
31         lfd     f0,40(r4)
32         fcmpu   cr1,f0,f19
33         bne     cr1,1f
34         lfd     f0,48(r4)
35         fcmpu   cr1,f0,f20
36         bne     cr1,1f
37         lfd     f0,56(r4)
38         fcmpu   cr1,f0,f21
39         bne     cr1,1f
40         lfd     f0,64(r4)
41         fcmpu   cr1,f0,f22
42         bne     cr1,1f
43         lfd     f0,72(r4)
44         fcmpu   cr1,f0,f23
45         bne     cr1,1f
46         lfd     f0,80(r4)
47         fcmpu   cr1,f0,f24
48         bne     cr1,1f
49         lfd     f0,88(r4)
50         fcmpu   cr1,f0,f25
51         bne     cr1,1f
52         lfd     f0,96(r4)
53         fcmpu   cr1,f0,f26
54         bne     cr1,1f
55         lfd     f0,104(r4)
56         fcmpu   cr1,f0,f27
57         bne     cr1,1f
58         lfd     f0,112(r4)
59         fcmpu   cr1,f0,f28
60         bne     cr1,1f
61         lfd     f0,120(r4)
62         fcmpu   cr1,f0,f29
63         bne     cr1,1f
64         lfd     f0,128(r4)
65         fcmpu   cr1,f0,f30
66         bne     cr1,1f
67         lfd     f0,136(r4)
68         fcmpu   cr1,f0,f31
69         bne     cr1,1f
70         li      r3,0 # Success!!!
71 1:      blr
72
73 FUNC_START(test_fpu)
74         # r3 holds pointer to where to put the result of fork
75         # r4 holds pointer to the pid
76         # f14-f31 are non volatiles
77         PUSH_BASIC_STACK(256)
78         PUSH_FPU(256)
79         std     r3,STACK_FRAME_PARAM(0)(sp) # Address of darray
80         std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid
81
82         bl load_fpu
83         nop
84         li      r0,__NR_fork
85         sc
86
87         # pass the result of the fork to the caller
88         ld      r9,STACK_FRAME_PARAM(1)(sp)
89         std     r3,0(r9)
90
91         ld r3,STACK_FRAME_PARAM(0)(sp)
92         bl check_fpu
93         nop
94
95         POP_FPU(256)
96         POP_BASIC_STACK(256)
97         blr
98 FUNC_END(test_fpu)
99
100 # int preempt_fpu(double *darray, int *threads_running, int *running)
101 # On starting will (atomically) decrement not_ready as a signal that the FPU
102 # has been loaded with darray. Will proceed to check the validity of the FPU
103 # registers while running is not zero.
104 FUNC_START(preempt_fpu)
105         PUSH_BASIC_STACK(256)
106         PUSH_FPU(256)
107         std r3,STACK_FRAME_PARAM(0)(sp) # double *darray
108         std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
109         std r5,STACK_FRAME_PARAM(2)(sp) # int *running
110
111         bl load_fpu
112         nop
113
114         sync
115         # Atomic DEC
116         ld r3,STACK_FRAME_PARAM(1)(sp)
117 1:      lwarx r4,0,r3
118         addi r4,r4,-1
119         stwcx. r4,0,r3
120         bne- 1b
121
122 2:      ld r3,STACK_FRAME_PARAM(0)(sp)
123         bl check_fpu
124         nop
125         cmpdi r3,0
126         bne 3f
127         ld r4,STACK_FRAME_PARAM(2)(sp)
128         ld r5,0(r4)
129         cmpwi r5,0
130         bne 2b
131
132 3:      POP_FPU(256)
133         POP_BASIC_STACK(256)
134         blr
135 FUNC_END(preempt_fpu)