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 69e5d00aaaSMichael Ellerman 70e5d00aaaSMichael Ellerman// int check_all_fprs(double darray[32]) 71e5d00aaaSMichael EllermanFUNC_START(check_all_fprs) 72e5d00aaaSMichael Ellerman PUSH_BASIC_STACK(8) 73e5d00aaaSMichael Ellerman mr r4, r3 // r4 = darray 74e5d00aaaSMichael Ellerman li r3, 1 // prepare for failure 75e5d00aaaSMichael Ellerman 76e5d00aaaSMichael Ellerman stfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // backup f31 77e5d00aaaSMichael Ellerman 78e5d00aaaSMichael Ellerman // Check regs f0-f30, using f31 as scratch 79e5d00aaaSMichael Ellerman .set i, 0 80e5d00aaaSMichael Ellerman .rept 31 81e5d00aaaSMichael Ellerman lfd f31, (8 * i)(r4) // load expected value 82e5d00aaaSMichael Ellerman fcmpu cr0, i, f31 // compare 83e5d00aaaSMichael Ellerman bne cr0, 1f // bail if mismatch 84e5d00aaaSMichael Ellerman .set i, i + 1 85e5d00aaaSMichael Ellerman .endr 86e5d00aaaSMichael Ellerman 87e5d00aaaSMichael Ellerman lfd f31, STACK_FRAME_LOCAL(0, 0)(sp) // reload f31 88e5d00aaaSMichael Ellerman stfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // backup f30 89e5d00aaaSMichael Ellerman 90e5d00aaaSMichael Ellerman lfd f30, (8 * 31)(r4) // load expected value of f31 91e5d00aaaSMichael Ellerman fcmpu cr0, f30, f31 // compare 92e5d00aaaSMichael Ellerman bne cr0, 1f // bail if mismatch 93e5d00aaaSMichael Ellerman 94e5d00aaaSMichael Ellerman lfd f30, STACK_FRAME_LOCAL(0, 0)(sp) // reload f30 95e5d00aaaSMichael Ellerman 96e5d00aaaSMichael Ellerman // Success 97e5d00aaaSMichael Ellerman li r3, 0 98e5d00aaaSMichael Ellerman 99e5d00aaaSMichael Ellerman1: POP_BASIC_STACK(8) 100e5d00aaaSMichael Ellerman blr 101e5d00aaaSMichael EllermanFUNC_END(check_all_fprs) 102e5d00aaaSMichael Ellerman 10301127f1eSCyril BurFUNC_START(test_fpu) 10401127f1eSCyril Bur # r3 holds pointer to where to put the result of fork 10501127f1eSCyril Bur # r4 holds pointer to the pid 10601127f1eSCyril Bur # f14-f31 are non volatiles 10701127f1eSCyril Bur PUSH_BASIC_STACK(256) 108be4a9f56SCyril Bur PUSH_FPU(256) 10901127f1eSCyril Bur std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray 11001127f1eSCyril Bur std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid 11101127f1eSCyril Bur 112*1bdf2258SMichael Ellerman // Load FPRs with expected values 113*1bdf2258SMichael Ellerman OP_REGS lfd, 8, 0, 31, r3 114*1bdf2258SMichael Ellerman 11501127f1eSCyril Bur li r0,__NR_fork 11601127f1eSCyril Bur sc 11701127f1eSCyril Bur 11801127f1eSCyril Bur # pass the result of the fork to the caller 11901127f1eSCyril Bur ld r9,STACK_FRAME_PARAM(1)(sp) 12001127f1eSCyril Bur std r3,0(r9) 12101127f1eSCyril Bur 12201127f1eSCyril Bur ld r3,STACK_FRAME_PARAM(0)(sp) 123*1bdf2258SMichael Ellerman bl check_all_fprs 12401127f1eSCyril Bur nop 12501127f1eSCyril Bur 126be4a9f56SCyril Bur POP_FPU(256) 12701127f1eSCyril Bur POP_BASIC_STACK(256) 12801127f1eSCyril Bur blr 12901127f1eSCyril BurFUNC_END(test_fpu) 130e5ab8be6SCyril Bur 131e5ab8be6SCyril Bur# int preempt_fpu(double *darray, int *threads_running, int *running) 132e5ab8be6SCyril Bur# On starting will (atomically) decrement not_ready as a signal that the FPU 133e5ab8be6SCyril Bur# has been loaded with darray. Will proceed to check the validity of the FPU 134e5ab8be6SCyril Bur# registers while running is not zero. 135e5ab8be6SCyril BurFUNC_START(preempt_fpu) 136e5ab8be6SCyril Bur PUSH_BASIC_STACK(256) 137be4a9f56SCyril Bur PUSH_FPU(256) 138e5ab8be6SCyril Bur std r3,STACK_FRAME_PARAM(0)(sp) # double *darray 139e5ab8be6SCyril Bur std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting 140e5ab8be6SCyril Bur std r5,STACK_FRAME_PARAM(2)(sp) # int *running 141e5ab8be6SCyril Bur 142e5d00aaaSMichael Ellerman // Load FPRs with expected values 143e5d00aaaSMichael Ellerman OP_REGS lfd, 8, 0, 31, r3 144e5ab8be6SCyril Bur 145e5ab8be6SCyril Bur sync 146e5ab8be6SCyril Bur # Atomic DEC 147e5ab8be6SCyril Bur ld r3,STACK_FRAME_PARAM(1)(sp) 148e5ab8be6SCyril Bur1: lwarx r4,0,r3 149e5ab8be6SCyril Bur addi r4,r4,-1 150e5ab8be6SCyril Bur stwcx. r4,0,r3 151e5ab8be6SCyril Bur bne- 1b 152e5ab8be6SCyril Bur 153e5ab8be6SCyril Bur2: ld r3,STACK_FRAME_PARAM(0)(sp) 154e5d00aaaSMichael Ellerman bl check_all_fprs 155e5ab8be6SCyril Bur cmpdi r3,0 156e5ab8be6SCyril Bur bne 3f 157e5ab8be6SCyril Bur ld r4,STACK_FRAME_PARAM(2)(sp) 158e5ab8be6SCyril Bur ld r5,0(r4) 159e5ab8be6SCyril Bur cmpwi r5,0 160e5ab8be6SCyril Bur bne 2b 161e5ab8be6SCyril Bur 162be4a9f56SCyril Bur3: POP_FPU(256) 163e5ab8be6SCyril Bur POP_BASIC_STACK(256) 164e5ab8be6SCyril Bur blr 165e5ab8be6SCyril BurFUNC_END(preempt_fpu) 166