Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
13FUNC_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!!!
711: blr
72
73FUNC_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
98FUNC_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.
104FUNC_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)
1171: lwarx r4,0,r3
118 addi r4,r4,-1
119 stwcx. r4,0,r3
120 bne- 1b
121
1222: 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
1323: POP_FPU(256)
133 POP_BASIC_STACK(256)
134 blr
135FUNC_END(preempt_fpu)