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 / vmx_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 "../vmx_asm.h"
12
13 # Should be safe from C, only touches r4, r5 and v0,v1,v2
14 FUNC_START(check_vmx)
15         PUSH_BASIC_STACK(32)
16         mr r4,r3
17         li      r3,1 # assume a bad result
18         li      r5,0
19         lvx     v0,r5,r4
20         vcmpequd.       v1,v0,v20
21         vmr     v2,v1
22
23         addi    r5,r5,16
24         lvx     v0,r5,r4
25         vcmpequd.       v1,v0,v21
26         vand    v2,v2,v1
27
28         addi    r5,r5,16
29         lvx     v0,r5,r4
30         vcmpequd.       v1,v0,v22
31         vand    v2,v2,v1
32
33         addi    r5,r5,16
34         lvx     v0,r5,r4
35         vcmpequd.       v1,v0,v23
36         vand    v2,v2,v1
37
38         addi    r5,r5,16
39         lvx     v0,r5,r4
40         vcmpequd.       v1,v0,v24
41         vand    v2,v2,v1
42
43         addi    r5,r5,16
44         lvx     v0,r5,r4
45         vcmpequd.       v1,v0,v25
46         vand    v2,v2,v1
47
48         addi    r5,r5,16
49         lvx     v0,r5,r4
50         vcmpequd.       v1,v0,v26
51         vand    v2,v2,v1
52
53         addi    r5,r5,16
54         lvx     v0,r5,r4
55         vcmpequd.       v1,v0,v27
56         vand    v2,v2,v1
57
58         addi    r5,r5,16
59         lvx     v0,r5,r4
60         vcmpequd.       v1,v0,v28
61         vand    v2,v2,v1
62
63         addi    r5,r5,16
64         lvx     v0,r5,r4
65         vcmpequd.       v1,v0,v29
66         vand    v2,v2,v1
67
68         addi    r5,r5,16
69         lvx     v0,r5,r4
70         vcmpequd.       v1,v0,v30
71         vand    v2,v2,v1
72
73         addi    r5,r5,16
74         lvx     v0,r5,r4
75         vcmpequd.       v1,v0,v31
76         vand    v2,v2,v1
77
78         li      r5,STACK_FRAME_LOCAL(0,0)
79         stvx    v2,r5,sp
80         ldx     r0,r5,sp
81         cmpdi   r0,0xffffffffffffffff
82         bne     1f
83         li      r3,0
84 1:      POP_BASIC_STACK(32)
85         blr
86 FUNC_END(check_vmx)
87
88 # Safe from C
89 FUNC_START(test_vmx)
90         # r3 holds pointer to where to put the result of fork
91         # r4 holds pointer to the pid
92         # v20-v31 are non-volatile
93         PUSH_BASIC_STACK(512)
94         std     r3,STACK_FRAME_PARAM(0)(sp) # Address of varray
95         std r4,STACK_FRAME_PARAM(1)(sp) # address of pid
96         PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)
97
98         bl load_vmx
99         nop
100
101         li      r0,__NR_fork
102         sc
103         # Pass the result of fork back to the caller
104         ld      r9,STACK_FRAME_PARAM(1)(sp)
105         std     r3,0(r9)
106
107         ld r3,STACK_FRAME_PARAM(0)(sp)
108         bl check_vmx
109         nop
110
111         POP_VMX(STACK_FRAME_LOCAL(2,0),r4)
112         POP_BASIC_STACK(512)
113         blr
114 FUNC_END(test_vmx)
115
116 # int preempt_vmx(vector int *varray, int *threads_starting, int *running)
117 # On starting will (atomically) decrement threads_starting as a signal that
118 # the VMX have been loaded with varray. Will proceed to check the validity of
119 # the VMX registers while running is not zero.
120 FUNC_START(preempt_vmx)
121         PUSH_BASIC_STACK(512)
122         std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
123         std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
124         std r5,STACK_FRAME_PARAM(2)(sp) # int *running
125         # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0)
126         PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4)
127
128         bl load_vmx
129         nop
130
131         sync
132         # Atomic DEC
133         ld r3,STACK_FRAME_PARAM(1)(sp)
134 1:      lwarx r4,0,r3
135         addi r4,r4,-1
136         stwcx. r4,0,r3
137         bne- 1b
138
139 2:      ld r3,STACK_FRAME_PARAM(0)(sp)
140         bl check_vmx
141         nop
142         cmpdi r3,0
143         bne 3f
144         ld r4,STACK_FRAME_PARAM(2)(sp)
145         ld r5,0(r4)
146         cmpwi r5,0
147         bne 2b
148
149 3:      POP_VMX(STACK_FRAME_LOCAL(4,0),r4)
150         POP_BASIC_STACK(512)
151         blr
152 FUNC_END(preempt_vmx)