162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2015, Cyril Bur, IBM Corp. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "basic_asm.h" 762306a36Sopenharmony_ci#include "fpu_asm.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciFUNC_START(check_fpu) 1062306a36Sopenharmony_ci mr r4,r3 1162306a36Sopenharmony_ci li r3,1 # assume a bad result 1262306a36Sopenharmony_ci lfd f0,0(r4) 1362306a36Sopenharmony_ci fcmpu cr1,f0,f14 1462306a36Sopenharmony_ci bne cr1,1f 1562306a36Sopenharmony_ci lfd f0,8(r4) 1662306a36Sopenharmony_ci fcmpu cr1,f0,f15 1762306a36Sopenharmony_ci bne cr1,1f 1862306a36Sopenharmony_ci lfd f0,16(r4) 1962306a36Sopenharmony_ci fcmpu cr1,f0,f16 2062306a36Sopenharmony_ci bne cr1,1f 2162306a36Sopenharmony_ci lfd f0,24(r4) 2262306a36Sopenharmony_ci fcmpu cr1,f0,f17 2362306a36Sopenharmony_ci bne cr1,1f 2462306a36Sopenharmony_ci lfd f0,32(r4) 2562306a36Sopenharmony_ci fcmpu cr1,f0,f18 2662306a36Sopenharmony_ci bne cr1,1f 2762306a36Sopenharmony_ci lfd f0,40(r4) 2862306a36Sopenharmony_ci fcmpu cr1,f0,f19 2962306a36Sopenharmony_ci bne cr1,1f 3062306a36Sopenharmony_ci lfd f0,48(r4) 3162306a36Sopenharmony_ci fcmpu cr1,f0,f20 3262306a36Sopenharmony_ci bne cr1,1f 3362306a36Sopenharmony_ci lfd f0,56(r4) 3462306a36Sopenharmony_ci fcmpu cr1,f0,f21 3562306a36Sopenharmony_ci bne cr1,1f 3662306a36Sopenharmony_ci lfd f0,64(r4) 3762306a36Sopenharmony_ci fcmpu cr1,f0,f22 3862306a36Sopenharmony_ci bne cr1,1f 3962306a36Sopenharmony_ci lfd f0,72(r4) 4062306a36Sopenharmony_ci fcmpu cr1,f0,f23 4162306a36Sopenharmony_ci bne cr1,1f 4262306a36Sopenharmony_ci lfd f0,80(r4) 4362306a36Sopenharmony_ci fcmpu cr1,f0,f24 4462306a36Sopenharmony_ci bne cr1,1f 4562306a36Sopenharmony_ci lfd f0,88(r4) 4662306a36Sopenharmony_ci fcmpu cr1,f0,f25 4762306a36Sopenharmony_ci bne cr1,1f 4862306a36Sopenharmony_ci lfd f0,96(r4) 4962306a36Sopenharmony_ci fcmpu cr1,f0,f26 5062306a36Sopenharmony_ci bne cr1,1f 5162306a36Sopenharmony_ci lfd f0,104(r4) 5262306a36Sopenharmony_ci fcmpu cr1,f0,f27 5362306a36Sopenharmony_ci bne cr1,1f 5462306a36Sopenharmony_ci lfd f0,112(r4) 5562306a36Sopenharmony_ci fcmpu cr1,f0,f28 5662306a36Sopenharmony_ci bne cr1,1f 5762306a36Sopenharmony_ci lfd f0,120(r4) 5862306a36Sopenharmony_ci fcmpu cr1,f0,f29 5962306a36Sopenharmony_ci bne cr1,1f 6062306a36Sopenharmony_ci lfd f0,128(r4) 6162306a36Sopenharmony_ci fcmpu cr1,f0,f30 6262306a36Sopenharmony_ci bne cr1,1f 6362306a36Sopenharmony_ci lfd f0,136(r4) 6462306a36Sopenharmony_ci fcmpu cr1,f0,f31 6562306a36Sopenharmony_ci bne cr1,1f 6662306a36Sopenharmony_ci li r3,0 # Success!!! 6762306a36Sopenharmony_ci1: blr 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciFUNC_START(test_fpu) 7062306a36Sopenharmony_ci # r3 holds pointer to where to put the result of fork 7162306a36Sopenharmony_ci # r4 holds pointer to the pid 7262306a36Sopenharmony_ci # f14-f31 are non volatiles 7362306a36Sopenharmony_ci PUSH_BASIC_STACK(256) 7462306a36Sopenharmony_ci PUSH_FPU(256) 7562306a36Sopenharmony_ci std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray 7662306a36Sopenharmony_ci std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci bl load_fpu 7962306a36Sopenharmony_ci nop 8062306a36Sopenharmony_ci li r0,__NR_fork 8162306a36Sopenharmony_ci sc 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci # pass the result of the fork to the caller 8462306a36Sopenharmony_ci ld r9,STACK_FRAME_PARAM(1)(sp) 8562306a36Sopenharmony_ci std r3,0(r9) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci ld r3,STACK_FRAME_PARAM(0)(sp) 8862306a36Sopenharmony_ci bl check_fpu 8962306a36Sopenharmony_ci nop 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci POP_FPU(256) 9262306a36Sopenharmony_ci POP_BASIC_STACK(256) 9362306a36Sopenharmony_ci blr 9462306a36Sopenharmony_ciFUNC_END(test_fpu) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci# int preempt_fpu(double *darray, int *threads_running, int *running) 9762306a36Sopenharmony_ci# On starting will (atomically) decrement not_ready as a signal that the FPU 9862306a36Sopenharmony_ci# has been loaded with darray. Will proceed to check the validity of the FPU 9962306a36Sopenharmony_ci# registers while running is not zero. 10062306a36Sopenharmony_ciFUNC_START(preempt_fpu) 10162306a36Sopenharmony_ci PUSH_BASIC_STACK(256) 10262306a36Sopenharmony_ci PUSH_FPU(256) 10362306a36Sopenharmony_ci std r3,STACK_FRAME_PARAM(0)(sp) # double *darray 10462306a36Sopenharmony_ci std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting 10562306a36Sopenharmony_ci std r5,STACK_FRAME_PARAM(2)(sp) # int *running 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci bl load_fpu 10862306a36Sopenharmony_ci nop 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci sync 11162306a36Sopenharmony_ci # Atomic DEC 11262306a36Sopenharmony_ci ld r3,STACK_FRAME_PARAM(1)(sp) 11362306a36Sopenharmony_ci1: lwarx r4,0,r3 11462306a36Sopenharmony_ci addi r4,r4,-1 11562306a36Sopenharmony_ci stwcx. r4,0,r3 11662306a36Sopenharmony_ci bne- 1b 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci2: ld r3,STACK_FRAME_PARAM(0)(sp) 11962306a36Sopenharmony_ci bl check_fpu 12062306a36Sopenharmony_ci nop 12162306a36Sopenharmony_ci cmpdi r3,0 12262306a36Sopenharmony_ci bne 3f 12362306a36Sopenharmony_ci ld r4,STACK_FRAME_PARAM(2)(sp) 12462306a36Sopenharmony_ci ld r5,0(r4) 12562306a36Sopenharmony_ci cmpwi r5,0 12662306a36Sopenharmony_ci bne 2b 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci3: POP_FPU(256) 12962306a36Sopenharmony_ci POP_BASIC_STACK(256) 13062306a36Sopenharmony_ci blr 13162306a36Sopenharmony_ciFUNC_END(preempt_fpu) 132