/* $Header: process.s,v 1.2 88/12/19 22:25:18 vasilis Exp $ */
/* $Source: /afs/andrew.cmu.edu/usr7/kazar/afs/lwp/RCS/process.s,v $ */

/*
 * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
#include <afs/param.h>

#ifdef sun
/*
#
#	Information Technology Center
#	Carnegie-Mellon University
#
#
*/
	.data

/*
#
#	Process assembly language assist for Sun's.
#
*/

	.text
	.even

/*
#
# struct savearea {
#	char	*topstack;
# }
#
*/

	.globl	_PRE_Block

topstack =	0

/* Stuff to allow saving/restoring registers */
nregs	=	13
regs	=	0x3ffe			| d1-d7 & a0-a5

/*
# savecontext(f, area1, newsp)
#     int (*f)(); struct savearea *area1; char *newsp;
*/

/* Stack offsets of arguments */
f	=	8
area1	=	12
newsp	=	16

	.globl	_savecontext
_savecontext:
	movb	#1,_PRE_Block		| Don't allow any interrupt finagling
	link	a6,#-(nregs*4)		| Save frame pointer & ...
					| ... allocate space for nregs registers
/* Save registers */
	moveml	#regs,sp@

	movl	a6@(area1),a0		| a0 = base of savearea
	movl	sp,a0@(topstack)	| area->topstack = sp
	movl	a6@(newsp),d0		| Get new sp
	jeq	1$			| If newsp == 0, no stack switch
	movl	d0,sp			| Switch to new stack
1$:
	movl	a6@(f),a0		| a0 = f
	jbsr	a0@			| f()

/* It is impossible to be here, so abort() */

	jbsr	_abort

/*
# returnto(area2)
#     struct savearea *area2;
*/

/* Stack offset of argument */
area2	=	8

	.globl _returnto
_returnto:
	link	a6,#0
	movl	a6@(area2),a0		| Base of savearea
	movl	a0@(topstack),sp	| Restore sp
/* Restore registers */
	moveml	sp@,#regs

	addl	#(nregs*4),sp
	movl	sp,a6			| Argghh...be careful here
	unlk	a6
	clrb	_PRE_Block
	rts				| Return to previous process
#endif
#ifdef ibm032
|
|	Information Technology Center
|	Carnegie-Mellon University
|
|
	.data
	.globl	.oVncs
	.set		.oVncs,0

	.globl	_savecontext
_savecontext:
	.long		_.savecontext

	.globl	_returnto
_returnto:
	.long		_.returnto

|
|	Process assembly language assist for Sailboats.
|

	.text
	.align 2

|
| struct savearea {
|	char	*topstack;
| }
|

| Offsets of fields
.set topstack,0

| Stuff to allow saving/restoring registers
.set regspace,64
.set freg,0

|
| savecontext(f, area1, newsp)
|    int (*f)(); struct savearea *area1; char *newsp;
|

	.globl	_.savecontext
_.savecontext:
	ai	sp,sp,-regspace		| Save frame pointer & ...
					| ... allocate space for 16 registers
| Save registers
	stm	r0,0(sp)			| Change this if save fewer regs.
| Set preemption semaphore
	get	r6,$1
	get	r7,$_PRE_Block
	putc	r6,0(r7)			| PRE_Block = 1
| r3 = base of savearea
	put	sp,topstack(r3)		| area1->topstack = sp
| New sp is in r4.
	cis	r4,0
	be	L1			| If newsp == 0, no stack switch
	cas	sp,r4,r0			| Switch to new stack
L1:
	get	r6,0(r2)			| r2 = _f
	balrx	r15,r6			| f()
	cas	r0,r2,r0

|
| returnto(area2)
|     struct savearea *area2;
|

	.globl _.returnto
_.returnto:
	get	sp,topstack(r2)
| Now in the context of the savecontext stack to be restored.
| Start with the registers...
| Clear preemption semaphore
	get	r6,$0
	get	r7,$_PRE_Block
	putc	r6,0(r7)			| PRE_Block = 0
	lm	r0,0(sp)		| Change if saving fewer regs.
	brx	r15		| Return to previous process
	ai	sp,sp,regspace
 .data
 .ltorg
#endif

#ifdef AFS_AIX_ENV
/*
#
#	Information Technology Center
#	Carnegie-Mellon University
#
*/
/*
#
#	Process assembly language assist for Sailboats.
#
*/

	.text
	.globl	.savecontext
	.align 1

/*
#
# struct savearea {
#	char	*topstack;
# }
#
*/


/*# Offsets of fields*/
.set topstack,0

/*# Stuff to allow saving/restoring registers*/
.set regspace,64
.set freg,0

/*
#
# savecontext(f, area1, newsp)
#    int (*f)(); struct savearea *area1; char *newsp;
#
*/

.savecontext:
	ai	1,1,-regspace		# Save frame pointer & ...
					# ... allocate space for 16 registers
/*# Save registers*/
	stm	0,0(1)			# Change this if save fewer regs.
	lr	14,0
/*# Set preemption semaphore*/
	lis	6,1
	l	7,4(14)
	stc	6,0(7)
/*# r3 = base of savearea*/
	st	1,topstack(3)		# area1->topstack = sp
/*# New sp is in r4.*/
	ci	4,0
	beq	L1			# If newsp == 0, no stack switch
	cas	1,4,0			# Switch to new stack
L1:
	l	6,0(2)			# r2 = _f
	balrx	15,6			# f()
	cas	0,2,0
	.data	3
	.globl	_savecontext
_savecontext:
	.long	.savecontext
	.long	_PRE_Block
/*
#
# returnto(area2)
#     struct savearea *area2;
#
*/

	.text
	.globl	.returnto
	.align 1
.returnto:
	l	1,topstack(2)
/*
# Now in the context of the savecontext stack to be restored.
# Start with the registers...
# Clear preemption semaphore
*/
	lr	14,0
	lis	6,0
	l	7,4(14)
	stc	6,0(7)
	lm	0,0(1)		# Change if saving fewer regs.
	brx	15		# Return to previous process
	ai	1,1,regspace
	.data	3
	.globl	_returnto
_returnto:
	.long	.returnto
	.long	_PRE_Block
#endif AFS_AIX_ENV

#ifdef vax
/*
#
#	Information Technology Center
#	Carnegie-Mellon University
#
#
*/
	.data

/*
#
#	Transcribed for Vaxen by M. Satyanarayanan, September 1985
#	Algorithm: "Monkey see, monkey do"
#
*/

	.text

/*
#
# struct savearea {
#	char	*topstack;
# }
#
*/

	.set	topstack,0

/* Stuff to allow saving/restoring registers */

/*
# savecontext(f, area1, newsp)
#     int (*f)(); struct savearea *area1; char *newsp;
*/

/* Stack offsets of arguments */
	.set	f,4
	.set	area1,8
	.set	newsp,12

.globl	_PRE_Block
.globl	_savecontext

_savecontext:
	.word 0x0ffc	# Save regs R2-R11
	movb	$1,_PRE_Block		# Critical section for preemption code
   	pushl	ap			# save old ap
	pushl	fp			# save old fp    
	movl	area1(ap),r0		# r0 = base of savearea
	movl	sp,topstack(r0)		# area->topstack = sp
	movl	newsp(ap),r0		# Get new sp
	beql	L1			# if new sp is 0, don't change stacks
	movl	r0,sp			# else switch to new stack
L1:
	movl	f(ap),r1		# r1 = f
	calls	$0,0(r1)		# f()

/* It is impossible to be here, so abort() */

	calls	$0,_abort

/*
# returnto(area2)
#     struct savearea *area2;
*/

/* Stack offset of argument */
	.set	area2,4

	.globl _returnto
_returnto:
	.word	0x0			# Who cares about these regs?
	movl	area2(ap),r0		# r0 = address of area2
	movl	topstack(r0),sp		# Restore sp
	movl	(sp)+,fp		# Restore fp
	movl	(sp)+,ap		# ,,,,
	clrb	_PRE_Block		# End of preemption critical section
	ret

	pushl	$1234			# I will gloat, Kazar
	calls	$0,_abort
#endif
