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