xref: /linux/tools/testing/selftests/powerpc/math/fpu_asm.S (revision 06d07429858317ded2db7986113a9e0129cd599b)
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