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 "vsx_asm.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#long check_vsx(vector int *r3);
1062306a36Sopenharmony_ci#This function wraps storeing VSX regs to the end of an array and a
1162306a36Sopenharmony_ci#call to a comparison function in C which boils down to a memcmp()
1262306a36Sopenharmony_ciFUNC_START(check_vsx)
1362306a36Sopenharmony_ci	PUSH_BASIC_STACK(32)
1462306a36Sopenharmony_ci	std	r3,STACK_FRAME_PARAM(0)(sp)
1562306a36Sopenharmony_ci	addi r3, r3, 16 * 12 #Second half of array
1662306a36Sopenharmony_ci	bl store_vsx
1762306a36Sopenharmony_ci	ld r3,STACK_FRAME_PARAM(0)(sp)
1862306a36Sopenharmony_ci	bl vsx_memcmp
1962306a36Sopenharmony_ci	POP_BASIC_STACK(32)
2062306a36Sopenharmony_ci	blr
2162306a36Sopenharmony_ciFUNC_END(check_vsx)
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci# int preempt_vmx(vector int *varray, int *threads_starting,
2462306a36Sopenharmony_ci#                 int *running);
2562306a36Sopenharmony_ci# On starting will (atomically) decrement threads_starting as a signal
2662306a36Sopenharmony_ci# that the VMX have been loaded with varray. Will proceed to check the
2762306a36Sopenharmony_ci# validity of the VMX registers while running is not zero.
2862306a36Sopenharmony_ciFUNC_START(preempt_vsx)
2962306a36Sopenharmony_ci	PUSH_BASIC_STACK(512)
3062306a36Sopenharmony_ci	std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
3162306a36Sopenharmony_ci	std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
3262306a36Sopenharmony_ci	std r5,STACK_FRAME_PARAM(2)(sp) # int *running
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	bl load_vsx
3562306a36Sopenharmony_ci	nop
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	sync
3862306a36Sopenharmony_ci	# Atomic DEC
3962306a36Sopenharmony_ci	ld r3,STACK_FRAME_PARAM(1)(sp)
4062306a36Sopenharmony_ci1:	lwarx r4,0,r3
4162306a36Sopenharmony_ci	addi r4,r4,-1
4262306a36Sopenharmony_ci	stwcx. r4,0,r3
4362306a36Sopenharmony_ci	bne- 1b
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci2:	ld r3,STACK_FRAME_PARAM(0)(sp)
4662306a36Sopenharmony_ci	bl check_vsx
4762306a36Sopenharmony_ci	nop
4862306a36Sopenharmony_ci	cmpdi r3,0
4962306a36Sopenharmony_ci	bne 3f
5062306a36Sopenharmony_ci	ld r4,STACK_FRAME_PARAM(2)(sp)
5162306a36Sopenharmony_ci	ld r5,0(r4)
5262306a36Sopenharmony_ci	cmpwi r5,0
5362306a36Sopenharmony_ci	bne 2b
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci3:	POP_BASIC_STACK(512)
5662306a36Sopenharmony_ci	blr
5762306a36Sopenharmony_ciFUNC_END(preempt_vsx)
58