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
69
70// int check_all_fprs(double darray[32])
71FUNC_START(check_all_fprs)
72 PUSH_BASIC_STACK(8)
73 mr r4, r3 // r4 = darray
74 li r3, 1 // prepare for failure
75
76 stfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // backup f31
77
78 // Check regs f0-f30, using f31 as scratch
79 .set i, 0
80 .rept 31
81 lfd f31, (8 * i)(r4) // load expected value
82 fcmpu cr0, i, f31 // compare
83 bne cr0, 1f // bail if mismatch
84 .set i, i + 1
85 .endr
86
87 lfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // reload f31
88 stfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // backup f30
89
90 lfd f30, (8 * 31)(r4) // load expected value of f31
91 fcmpu cr0, f30, f31 // compare
92 bne cr0, 1f // bail if mismatch
93
94 lfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // reload f30
95
96 // Success
97 li r3, 0
98
991: POP_BASIC_STACK(8)
100 blr
101FUNC_END(check_all_fprs)
102
103FUNC_START(test_fpu)
104 # r3 holds pointer to where to put the result of fork
105 # r4 holds pointer to the pid
106 # f14-f31 are non volatiles
107 PUSH_BASIC_STACK(256)
108 PUSH_FPU(256)
109 std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray
110 std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid
111
112 // Load FPRs with expected values
113 OP_REGS lfd, 8, 0, 31, r3
114
115 li r0,__NR_fork
116 sc
117
118 # pass the result of the fork to the caller
119 ld r9,STACK_FRAME_PARAM(1)(sp)
120 std r3,0(r9)
121
122 ld r3,STACK_FRAME_PARAM(0)(sp)
123 bl check_all_fprs
124 nop
125
126 POP_FPU(256)
127 POP_BASIC_STACK(256)
128 blr
129FUNC_END(test_fpu)
130
131# int preempt_fpu(double *darray, int *threads_running, int *running)
132# On starting will (atomically) decrement not_ready as a signal that the FPU
133# has been loaded with darray. Will proceed to check the validity of the FPU
134# registers while running is not zero.
135FUNC_START(preempt_fpu)
136 PUSH_BASIC_STACK(256)
137 PUSH_FPU(256)
138 std r3,STACK_FRAME_PARAM(0)(sp) # double *darray
139 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
140 std r5,STACK_FRAME_PARAM(2)(sp) # int *running
141
142 // Load FPRs with expected values
143 OP_REGS lfd, 8, 0, 31, r3
144
145 sync
146 # Atomic DEC
147 ld r3,STACK_FRAME_PARAM(1)(sp)
1481: lwarx r4,0,r3
149 addi r4,r4,-1
150 stwcx. r4,0,r3
151 bne- 1b
152
1532: ld r3,STACK_FRAME_PARAM(0)(sp)
154 bl check_all_fprs
155 cmpdi r3,0
156 bne 3f
157 ld r4,STACK_FRAME_PARAM(2)(sp)
158 ld r5,0(r4)
159 cmpwi r5,0
160 bne 2b
161
1623: POP_FPU(256)
163 POP_BASIC_STACK(256)
164 blr
165FUNC_END(preempt_fpu)