12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
201127f1eSCyril Bur/*
301127f1eSCyril Bur * Copyright 2015, Cyril Bur, IBM Corp.
401127f1eSCyril Bur */
501127f1eSCyril Bur
615ec3997SSimon Guo#include "basic_asm.h"
715ec3997SSimon Guo#include "fpu_asm.h"
801127f1eSCyril Bur
901127f1eSCyril BurFUNC_START(check_fpu)
1001127f1eSCyril Bur	mr r4,r3
1101127f1eSCyril Bur	li	r3,1 # assume a bad result
1201127f1eSCyril Bur	lfd	f0,0(r4)
1301127f1eSCyril Bur	fcmpu	cr1,f0,f14
1401127f1eSCyril Bur	bne	cr1,1f
1501127f1eSCyril Bur	lfd	f0,8(r4)
1601127f1eSCyril Bur	fcmpu	cr1,f0,f15
1701127f1eSCyril Bur	bne	cr1,1f
1801127f1eSCyril Bur	lfd	f0,16(r4)
1901127f1eSCyril Bur	fcmpu	cr1,f0,f16
2001127f1eSCyril Bur	bne	cr1,1f
2101127f1eSCyril Bur	lfd	f0,24(r4)
2201127f1eSCyril Bur	fcmpu	cr1,f0,f17
2301127f1eSCyril Bur	bne	cr1,1f
2401127f1eSCyril Bur	lfd	f0,32(r4)
2501127f1eSCyril Bur	fcmpu	cr1,f0,f18
2601127f1eSCyril Bur	bne	cr1,1f
2701127f1eSCyril Bur	lfd	f0,40(r4)
2801127f1eSCyril Bur	fcmpu	cr1,f0,f19
2901127f1eSCyril Bur	bne	cr1,1f
3001127f1eSCyril Bur	lfd	f0,48(r4)
3101127f1eSCyril Bur	fcmpu	cr1,f0,f20
3201127f1eSCyril Bur	bne	cr1,1f
3301127f1eSCyril Bur	lfd	f0,56(r4)
3401127f1eSCyril Bur	fcmpu	cr1,f0,f21
3501127f1eSCyril Bur	bne	cr1,1f
3601127f1eSCyril Bur	lfd	f0,64(r4)
3701127f1eSCyril Bur	fcmpu	cr1,f0,f22
3801127f1eSCyril Bur	bne	cr1,1f
3901127f1eSCyril Bur	lfd	f0,72(r4)
4001127f1eSCyril Bur	fcmpu	cr1,f0,f23
4101127f1eSCyril Bur	bne	cr1,1f
4201127f1eSCyril Bur	lfd	f0,80(r4)
4301127f1eSCyril Bur	fcmpu	cr1,f0,f24
4401127f1eSCyril Bur	bne	cr1,1f
4501127f1eSCyril Bur	lfd	f0,88(r4)
4601127f1eSCyril Bur	fcmpu	cr1,f0,f25
4701127f1eSCyril Bur	bne	cr1,1f
4801127f1eSCyril Bur	lfd	f0,96(r4)
4901127f1eSCyril Bur	fcmpu	cr1,f0,f26
5001127f1eSCyril Bur	bne	cr1,1f
5101127f1eSCyril Bur	lfd	f0,104(r4)
5201127f1eSCyril Bur	fcmpu	cr1,f0,f27
5301127f1eSCyril Bur	bne	cr1,1f
5401127f1eSCyril Bur	lfd	f0,112(r4)
5501127f1eSCyril Bur	fcmpu	cr1,f0,f28
5601127f1eSCyril Bur	bne	cr1,1f
5701127f1eSCyril Bur	lfd	f0,120(r4)
5801127f1eSCyril Bur	fcmpu	cr1,f0,f29
5901127f1eSCyril Bur	bne	cr1,1f
6001127f1eSCyril Bur	lfd	f0,128(r4)
6101127f1eSCyril Bur	fcmpu	cr1,f0,f30
6201127f1eSCyril Bur	bne	cr1,1f
6301127f1eSCyril Bur	lfd	f0,136(r4)
6401127f1eSCyril Bur	fcmpu	cr1,f0,f31
6501127f1eSCyril Bur	bne	cr1,1f
6601127f1eSCyril Bur	li	r3,0 # Success!!!
6701127f1eSCyril Bur1:	blr
6801127f1eSCyril Bur
6901127f1eSCyril BurFUNC_START(test_fpu)
7001127f1eSCyril Bur	# r3 holds pointer to where to put the result of fork
7101127f1eSCyril Bur	# r4 holds pointer to the pid
7201127f1eSCyril Bur	# f14-f31 are non volatiles
7301127f1eSCyril Bur	PUSH_BASIC_STACK(256)
74be4a9f56SCyril Bur	PUSH_FPU(256)
7501127f1eSCyril Bur	std	r3,STACK_FRAME_PARAM(0)(sp) # Address of darray
7601127f1eSCyril Bur	std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid
7701127f1eSCyril Bur
7801127f1eSCyril Bur	bl load_fpu
7901127f1eSCyril Bur	nop
8001127f1eSCyril Bur	li	r0,__NR_fork
8101127f1eSCyril Bur	sc
8201127f1eSCyril Bur
8301127f1eSCyril Bur	# pass the result of the fork to the caller
8401127f1eSCyril Bur	ld	r9,STACK_FRAME_PARAM(1)(sp)
8501127f1eSCyril Bur	std	r3,0(r9)
8601127f1eSCyril Bur
8701127f1eSCyril Bur	ld r3,STACK_FRAME_PARAM(0)(sp)
8801127f1eSCyril Bur	bl check_fpu
8901127f1eSCyril Bur	nop
9001127f1eSCyril Bur
91be4a9f56SCyril Bur	POP_FPU(256)
9201127f1eSCyril Bur	POP_BASIC_STACK(256)
9301127f1eSCyril Bur	blr
9401127f1eSCyril BurFUNC_END(test_fpu)
95e5ab8be6SCyril Bur
96e5ab8be6SCyril Bur# int preempt_fpu(double *darray, int *threads_running, int *running)
97e5ab8be6SCyril Bur# On starting will (atomically) decrement not_ready as a signal that the FPU
98e5ab8be6SCyril Bur# has been loaded with darray. Will proceed to check the validity of the FPU
99e5ab8be6SCyril Bur# registers while running is not zero.
100e5ab8be6SCyril BurFUNC_START(preempt_fpu)
101e5ab8be6SCyril Bur	PUSH_BASIC_STACK(256)
102be4a9f56SCyril Bur	PUSH_FPU(256)
103e5ab8be6SCyril Bur	std r3,STACK_FRAME_PARAM(0)(sp) # double *darray
104e5ab8be6SCyril Bur	std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
105e5ab8be6SCyril Bur	std r5,STACK_FRAME_PARAM(2)(sp) # int *running
106e5ab8be6SCyril Bur
107e5ab8be6SCyril Bur	bl load_fpu
108e5ab8be6SCyril Bur	nop
109e5ab8be6SCyril Bur
110e5ab8be6SCyril Bur	sync
111e5ab8be6SCyril Bur	# Atomic DEC
112e5ab8be6SCyril Bur	ld r3,STACK_FRAME_PARAM(1)(sp)
113e5ab8be6SCyril Bur1:	lwarx r4,0,r3
114e5ab8be6SCyril Bur	addi r4,r4,-1
115e5ab8be6SCyril Bur	stwcx. r4,0,r3
116e5ab8be6SCyril Bur	bne- 1b
117e5ab8be6SCyril Bur
118e5ab8be6SCyril Bur2:	ld r3,STACK_FRAME_PARAM(0)(sp)
119e5ab8be6SCyril Bur	bl check_fpu
120e5ab8be6SCyril Bur	nop
121e5ab8be6SCyril Bur	cmpdi r3,0
122e5ab8be6SCyril Bur	bne 3f
123e5ab8be6SCyril Bur	ld r4,STACK_FRAME_PARAM(2)(sp)
124e5ab8be6SCyril Bur	ld r5,0(r4)
125e5ab8be6SCyril Bur	cmpwi r5,0
126e5ab8be6SCyril Bur	bne 2b
127e5ab8be6SCyril Bur
128be4a9f56SCyril Bur3:	POP_FPU(256)
129e5ab8be6SCyril Bur	POP_BASIC_STACK(256)
130e5ab8be6SCyril Bur	blr
131e5ab8be6SCyril BurFUNC_END(preempt_fpu)
132