/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:fpfpx2.s 12.0$ */
/* $ACIS:fpfpx2.s 12.0$ */
/* $Source: /ibm/acis/usr/src/lib/libc/ca/gen/RCS/fpfpx2.s,v $ */

	.data
rcsid:	.asciz	"$Header:fpfpx2.s 12.0$"
	.text

	.globl	.oVncs
	.set	.oVncs,0

 #
 # fpstmX -- store multiple for floating point registers
 #	(store registers X through 5)
 #	r12 - save area
 #	r10,r11 - scratch
 # (LISA: r0 - scratch or not????)
 # NOTE! in order to preserve all other registers, these routines
 #	assume the stack is available to them (that is, they assume
 #	they can use a small amount of stack space at lower addresses
 #	from the stack pointer) SO if called from the prologue of a
 #	routine, it should be done AFTER the routine bumps its stack
 #	pointer; from an epilogue, BEFORE the stack pointer is replaced
 #

	.globl fpstm5
fpstm5:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff02f280	# fpa register 10 or hi half of em reg 5
	j	fpstX

	.globl fpstm4
fpstm4:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff02f200	# fpa register  8 or hi half of em reg 4
	j	fpstX

	.globl fpstm3
fpstm3:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff02f180	# fpa register  6 or hi half of em reg 4
	j	fpstX

	.globl fpstm2
fpstm2:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff02f100	# fpa register  4 or hi half of em reg 2

fpstX:	st	r2,-8(sp)	# save registers
	st	r15,-12(sp)	# save registers
	cal	sp,-100(sp)	# bump stack pointer
	mr	r10,r12		# use r10 to move through save area
	get	r11,$0xff02f300	# fpa register 12 or hi half of register 6
				# which is place to stop

stloop: .long	FPaGET0		# get half of floating point register
	ai	r10,4		# move forward through save area
	ai	r3,0x40		# next floating point address
	c	r3,r11		# fpa register 12 or hi half of register 6
	bnex	stloop		# not there yet, continue storing
	st	r2,-4(r10)	# put half of floating point val into save area

	l	r11,0(r14)	# from data ptr, get addr of routine
	lh	r11,0(r11)	# hi halfword of "stm rX" instruction
	sri	r11,4		# which rX?
	nilz	r11,r11,0xf
	sfi	r11,r11,17	# num. of words from here to reserved area
	sli	r11,2		# now number of bytes!
	cas	r10,r10,r11	# add to end of save area

	.long	FPaGET0		# r3 is already right instr (hi of fr6)
	st	r2,0(r10)	# hi half of fr6 into reserved area
	ai	r3,0x40		# next floating point address
	.long	FPaGET0		# get lo half of fr6
	st	r2,4(r10)	# lo half of fr6 into reserved area

	cal	sp,100(sp)	# original stack pointer
	l	r15,-12(sp)	# restore registers
	l	r2,-8(sp)	# restore registers
	brx	r15		# return
	l	r3,-4(sp)	# restore registers

	.align 2; .byte 0xdf, 2	, 0xdf, 0;

	.globl fplm5
fplm5:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff025028	# fpa register 10 or hi half of em reg 5
	j	fpldX

	.globl fplm4
fplm4:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff025020	# fpa register  8 or hi half of em reg 4
	j	fpldX

	.globl fplm3
fplm3:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff025018	# fpa register  6 or hi half of em reg 3
	j	fpldX

	.globl fplm2
fplm2:
	st	r3,-4(sp)	# save registers
	get	r3,$0xff025010	# fpa register  4 or hi half of em reg 2

fpldX:	st	r2,-8(sp)	# save registers
	st	r15,-12(sp)	# save registers
	cal	sp,-100(sp)	# bump stack pointer
	mr	r10,r12		# use r10 to move through save area
	get	r11,$0xff025030	# fpa register 12 or hi half of register 6
				# which is place to stop

ldloop: l	r2,0(r10)	# get half of floating point val and
	.long	FPaPUT0		# put into floating point register 
	ai	r10,4		# move forward through save area
	ai	r3,0x04		# next floating point address
	c	r3,r11		# fpa register 12 or hi half of register 6
	jne	ldloop		# not there yet, continue loading

	l	r11,0(r14)	# from data ptr, get addr of routine
	lh	r11,0(r11)	# hi halfword of "stm rX" instruction
	sri	r11,4		# which rX?
	nilz	r11,r11,0xf
	sfi	r11,r11,17	# num. of words from here to reserved area
	sli	r11,2		# now number of bytes!
	cas	r10,r10,r11	# add to end of save area

	l	r2,0(r10)	# hi half of fr6 from reserved area
	.long	FPaPUT0		# r3 is already right instr (hi of fr6)
	ai	r3,0x04		# next floating point address
	l	r2,4(r10)	# lo half of fr6 from reserved area
	.long	FPaPUT0		# put into lo half of fr6

	cal	sp,100(sp)	# original stack pointer
	l	r15,-12(sp)	# restore registers
	l	r2,-8(sp)	# restore registers 
	brx	r15		# return
	l	r3,-4(sp)	# restore registers

	.align 2; .byte 0xdf, 2	, 0xdf, 0;

