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