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