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)
132