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

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

#include <syscall.h>
#include "../gen/LINKG.h"
#include <frame.h>			# constants defined here could not
					# be used without strange as errors
					# if you want, feel free to try
	.globl	FPaGET0
	.globl	FPaPUT0
	.globl  fpget
	.globl  fpput
	.globl	__compat
	.text
	.align	2
fpget:	.set	FPaGET0,fpget+0x8a000000 /* bala fpget */
	get	r0,$fp_emaddr+2		# contains addr of emulator
	lhs	r0,0(r0)		# get low half of val stored
	ci	r0,1			# first time thru, if 1
	jnl	1f			# emulator or system call
	brx	r15			# else, FPA is there, so return
	l	r2,0(r3)		# doing load from FPA
	TTNOFRM

fpput:	.set	FPaPUT0,fpput+0x8a000000 /* bala fpput */
	get	r0,$fp_emaddr+2		# contains addr of emulator
	lhs	r0,0(r0)		# get low half of val stored
	ci	r0,1			# first time thru, if 1
	jnl	2f			# emulator or system call
	brx	r15			# else, FPA is there, so return
	st	r2,0(r3)		# doing load from FPA
	TTNOFRM

 # following is to fool the loader into thinking that __compat is a C
 # function, hence should not be loaded if there is a .comm __compat 
 # elsewhere (e.g. fpglue.s), but only if the fpget/fpput are used.
	.globl	_._compat
_._compat: tgte	r1,r1			# we should NEVER be called!
	.data
	.align	2
fp_emaddr:	.long	1		# init to 1, later 0(FPA) or emulator
__compat:	.long	1

	.text
1:	je	3f			# first time, do system call
2:	je	5f			# first time, do system call
	st	r15,-4(sp)		# save regs across call
	st	r3,-8(sp)		# save regs across call
	st	r4,-12(sp)		# save regs across call
	cal	sp,-100(sp)		# move stack pointer
	get	r4,$fp_emaddr		# addr of emulator dp
	get	r4,0(r4)		# emulator dp
	mr	r0,r4
	get	r4,0(r4)		# addr of emulator
	balrx	r15,r4			# call emulator
	st	r5,100-16(sp)		# save regs across call
	cal	sp,100(sp)		# replace stack pointer
	l	r15,-4(sp)		# restore regs after call
	l	r3,-8(sp)		# restore regs after call
	l	r4,-12(sp)		# restore regs after call
	brx	r15			# return
	l	r5,-16(sp)		# restore regs after call
	.short	0xdf07			# trace table
	.short	0xdf38			# trace table
	.short	0x0119			# trace table

3:
	st	r2,-4(sp)		# save registers
	st	r3,-8(sp)		# save registers
	svc	SYS_getfpemulator(r0)	# addr of emulator dp, ptr to 0 if FPA
	l	r3,0(r2)		# 0 if FPA
	ci	r3,0
	jnz	4f			# emulator
	get	r2,$0			# FPA
4:
	get	r3,$fp_emaddr		# get address to store into
	st	r2,0(r3)		# save address of emulator (or 0)
	l	r2,-4(sp)		# restore registers
	l	r3,-8(sp)		# restore registers
	j	fpget			# start getfrom again
	TTNOFRM

5:
	st	r2,-4(sp)		# save registers
	st	r3,-8(sp)		# save registers
	svc	SYS_getfpemulator(r0)	# addr of emulator dp, ptr to 0 if FPA
	l	r3,0(r2)		# 0 if FPA
	ci	r3,0
	jnz	6f			# emulator
	get	r2,$0			# FPA
6:
	get	r3,$fp_emaddr		# get address to store into
	st	r2,0(r3)		# save address of emulator (or 0)
	l	r2,-4(sp)		# restore registers
	l	r3,-8(sp)		# restore registers
	j	fpput			# start putinto again
	TTNOFRM
