0001
0002
0003
0004
0005
0006 #include "basic_asm.h"
0007 #include "fpu_asm.h"
0008
0009 FUNC_START(check_fpu)
0010 mr r4,r3
0011 li r3,1 # assume a bad result
0012 lfd f0,0(r4)
0013 fcmpu cr1,f0,f14
0014 bne cr1,1f
0015 lfd f0,8(r4)
0016 fcmpu cr1,f0,f15
0017 bne cr1,1f
0018 lfd f0,16(r4)
0019 fcmpu cr1,f0,f16
0020 bne cr1,1f
0021 lfd f0,24(r4)
0022 fcmpu cr1,f0,f17
0023 bne cr1,1f
0024 lfd f0,32(r4)
0025 fcmpu cr1,f0,f18
0026 bne cr1,1f
0027 lfd f0,40(r4)
0028 fcmpu cr1,f0,f19
0029 bne cr1,1f
0030 lfd f0,48(r4)
0031 fcmpu cr1,f0,f20
0032 bne cr1,1f
0033 lfd f0,56(r4)
0034 fcmpu cr1,f0,f21
0035 bne cr1,1f
0036 lfd f0,64(r4)
0037 fcmpu cr1,f0,f22
0038 bne cr1,1f
0039 lfd f0,72(r4)
0040 fcmpu cr1,f0,f23
0041 bne cr1,1f
0042 lfd f0,80(r4)
0043 fcmpu cr1,f0,f24
0044 bne cr1,1f
0045 lfd f0,88(r4)
0046 fcmpu cr1,f0,f25
0047 bne cr1,1f
0048 lfd f0,96(r4)
0049 fcmpu cr1,f0,f26
0050 bne cr1,1f
0051 lfd f0,104(r4)
0052 fcmpu cr1,f0,f27
0053 bne cr1,1f
0054 lfd f0,112(r4)
0055 fcmpu cr1,f0,f28
0056 bne cr1,1f
0057 lfd f0,120(r4)
0058 fcmpu cr1,f0,f29
0059 bne cr1,1f
0060 lfd f0,128(r4)
0061 fcmpu cr1,f0,f30
0062 bne cr1,1f
0063 lfd f0,136(r4)
0064 fcmpu cr1,f0,f31
0065 bne cr1,1f
0066 li r3,0 # Success!!!
0067 1: blr
0068
0069 FUNC_START(test_fpu)
0070 # r3 holds pointer to where to put the result of fork
0071 # r4 holds pointer to the pid
0072 # f14-f31 are non volatiles
0073 PUSH_BASIC_STACK(256)
0074 PUSH_FPU(256)
0075 std r3,STACK_FRAME_PARAM(0)(sp) # Address of darray
0076 std r4,STACK_FRAME_PARAM(1)(sp) # Address of pid
0077
0078 bl load_fpu
0079 nop
0080 li r0,__NR_fork
0081 sc
0082
0083 # pass the result of the fork to the caller
0084 ld r9,STACK_FRAME_PARAM(1)(sp)
0085 std r3,0(r9)
0086
0087 ld r3,STACK_FRAME_PARAM(0)(sp)
0088 bl check_fpu
0089 nop
0090
0091 POP_FPU(256)
0092 POP_BASIC_STACK(256)
0093 blr
0094 FUNC_END(test_fpu)
0095
0096 # int preempt_fpu(double *darray, int *threads_running, int *running)
0097 # On starting will (atomically) decrement not_ready as a signal that the FPU
0098 # has been loaded with darray. Will proceed to check the validity of the FPU
0099 # registers while running is not zero.
0100 FUNC_START(preempt_fpu)
0101 PUSH_BASIC_STACK(256)
0102 PUSH_FPU(256)
0103 std r3,STACK_FRAME_PARAM(0)(sp) # double *darray
0104 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
0105 std r5,STACK_FRAME_PARAM(2)(sp) # int *running
0106
0107 bl load_fpu
0108 nop
0109
0110 sync
0111 # Atomic DEC
0112 ld r3,STACK_FRAME_PARAM(1)(sp)
0113 1: lwarx r4,0,r3
0114 addi r4,r4,-1
0115 stwcx. r4,0,r3
0116 bne- 1b
0117
0118 2: ld r3,STACK_FRAME_PARAM(0)(sp)
0119 bl check_fpu
0120 nop
0121 cmpdi r3,0
0122 bne 3f
0123 ld r4,STACK_FRAME_PARAM(2)(sp)
0124 ld r5,0(r4)
0125 cmpwi r5,0
0126 bne 2b
0127
0128 3: POP_FPU(256)
0129 POP_BASIC_STACK(256)
0130 blr
0131 FUNC_END(preempt_fpu)