/* --- Copyright University of Sussex 1992. All rights reserved. ----------
 * File:	C.hppa/src/alisp.s
 * Purpose:	Assembler support for Common Lisp for HP PA-RISC 1.1
 * Author:	Julian Clinton, January 1993
 */


#_<

#_INCLUDE 'declare.ph'

>_#


#_INCLUDE 'asm_macros.h'

/************************* wrapping structures ************************/

	.code
	.word	Lcode_end-Lcode_start, C_LAB(Sys$-objmod_pad_key)
Lcode_start
	.data
	.word	Ldata_end-Ldata_start, C_LAB(Sys$-objmod_pad_key)
Ldata_start

/**********************************************************************/


	.code

;;; _SETSTKLEN:
;;;	adjusts the number of results returned by a Lisp function.
;;;	The subroutine takes the length of the userstack before the function
;;;	call and the number of results expected (both as popints).
;;;	The actual stacklength is adjusted to fit either by erasing items
;;;	or by pushing -nil-.

;;; Call:
;;;	_setstklen(SAVED_STACKLENGTH, NRESULTS);

;;; Registers used:
;;;	%t1	SAVED_STACKLENGTH
;;;	%t2	NRESULTS
;;;	%t3	desired stacklength
;;;	%arg0	desired stack pointer

;;; Usage:
;;;	implements the I_SETSTACKLENGTH instruction. Where NRESULTS is
;;;	available to the run-time assembler, the code for SETSTKLEN is
;;;	expanded inline and a jump made direct to SETSTKLEN_DIFF
;;;	if necessary.

DEF_C_LAB (_setstklen)

	ldwm		4(%usp), %t2
	ldwm		4(%usp), %t1

	;;; Load _userhi to %arg0
	ldw		_SVB_OFFS(_userhi)(%svb), %arg0

	;;; Compute desired stacklength (SAVED_STACKLENGTH + NRESULTS) in %t3
	;;; The two arguments are in popint words; subtracting 6 from the
	;;; total converts to sysint bytes.
	add		%t2, %t1, %t3
	addi		-6, %t3, %t3

	;;; Compute the desired stack pointer (_userhi - desired_length)
	;;; in %arg0
	sub		%arg0, %t3, %arg0

	;;; Compare desired and actual stack pointers: if same then exit
	comb,=,n	%arg0, %usp, L$3

DEF_C_LAB (_setstklen_diff)

	;;; Desired and actual stack pointers are different:
	;;; push (if stack too short) or pop results (if too long)
	comb,<<,n	%usp, %arg0, L$2

	;;; Actual stack is too short: push nils until the desired size
	;;; is reached
	LDA32		C_LAB(nil), %t3
	stwm		%t3, -4(%usp)

L$1	;;; Repeat

	comb,<<,n	%arg0, %usp, L$1
	stwm		%t3, -4(%usp)		;;; branch delay slot

	;;; Now exit
	RETE
	nop

L$2	;;; Actual stack is too long: erase the extra results simply by
	;;; setting USP to the desired value
	RETE
	copy		%arg0, %usp		;;; branch delay slot

L$3	;;; Everything okay so exit
	RETE
	nop



	.code
	.import		C_LAB(Sys$-objmod_pad_key), data
	.import   	C_LAB(nil), data


/***************** end labels for wrapping structures *****************/

	.code
	.align  8
Lcode_end
	.data
	.align  8
Ldata_end

/**********************************************************************/
