	.file	"log.s"
/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

/       Copyright (c) 1984 AT&T
/         All Rights Reserved

/       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
/       The copyright notice above does not evidence any
/       actual or intended publication of such source code.

/	Double precision logarithm routines (both natural and base 10).

	
/	.string "(c) Copyright Weitek 1987.  All rights reserved."

#include "1167defs.h"
#include "sys.s"

LOGERR1:
	.byte	0x6c,0x6f,0x67,0x00
LOGERR2:
	.byte	0x6c,0x6f,0x67,0x3a,0x20,0x44,0x4f,0x4d,0x41
	.byte	0x49,0x4e,0x20,0x65,0x72,0x72,0x6f,0x72,0x0a
	.byte	0x00
LOGERR3:
	.byte	0x6c,0x6f,0x67,0x3a,0x20,0x53,0x49,0x4e,0x47
	.byte	0x20,0x65,0x72,0x72,0x6f,0x72,0x0a,0x00
LOG10ERR1:
	.byte	0x6c,0x6f,0x67,0x31,0x30,0x00
LOG10ERR2:
	.byte	0x6c,0x6f,0x67,0x31,0x30,0x3a,0x20,0x44,0x4f,0x4d
	.byte	0x41,0x49,0x4e,0x20,0x65,0x72,0x72,0x6f,0x72,0x0a
	.byte	0x00
LOG10ERR3:
	.byte	0x6c,0x6f,0x67,0x31,0x30,0x3a,0x20,0x53,0x49
	.byte	0x4e,0x47,0x20,0x65,0x72,0x72,0x6f,0x72,0x0a
	.byte	0x00
	.data
	.align	2

ENTRY(log)
	movb	$0x0,%dl			/Set the operation flag to log
log_work:
	movl	4(%esp), %eax		
	movl	%eax, LOADD|[[FP4|1]<<2]
	movl	8(%esp), %eax
	andl	$ 0x000fffff, %eax
	addl	$ 0x3ff00000, %eax
	movl	%eax, LOADD|[FP4<<2]
	andl	$ 0xffff8000, %eax
	addl	$ 0x00008000, %eax
	andl	$ 0xffff7fff, %eax
	movl	$ 0x00000000, LOADD|[[FP2|1]<<2]
	movl	%eax, LOADD|[FP2<<2]
	movb	%al, SUBD|[[FP4&0x1c]<<5]|[FP4&3]|[FP2<<2]
	movl	$ 0x00000000, LOADD|[FP1<<2]
	movl	%eax, ADDD|[FP4<<2]
	movb	%al, ADDD|[[FP2&0x1c]<<5]|[FP2&3]|[FP2<<2]		
	movb	%al, DIVD|[[FP2&0x1c]<<5]|[FP2&3]|[FP4<<2]

	movl	8(%esp), %eax		
	movl	%eax, %ecx
	andl	$ 0x000f8000, %ecx
	addl	$ 0x00008000, %ecx
	shrl	$ 16, %ecx

	andl	$ 0x7ff00000|0x80000000, %eax
	jle	not_positive
	shrl	$ 20, %eax
	cmpl	$ 8, %ecx
	sbbl	$ 1023-1, %eax

	pushl	%edx
	movl	table(, %ecx, 8), %edx
	movl	table+4(, %ecx, 8), %ecx

	movb	%al, ABSD|[[FP4&0x1c]<<5]|[FP4&3]|[FP6<<2]		
	movb	%al, MULD|[[FP6&0x1c]<<5]|[FP6&3]|[FP6<<2]
	movb	%al, ABSD|[[FP6&0x1c]<<5]|[FP6&3]|[FP2<<2]
	movl	$ 0x1a5d9e7f, LOADD|[FP1<<2]
	movl	$ 0x3f624adf, MULD|[FP2<<2]
	movl	$ 0x88c97f94, LOADD|[FP1<<2]
	movl	$ 0x3f899999, ADDD|[FP2<<2]
	movb	%al, MULD|[[FP6&0x1c]<<5]|[FP6&3]|[FP2<<2]
	movl	$ 0x55556f94, LOADD|[FP1<<2]
	movl	$ 0x3fb55555, ADDD|[FP2<<2]
	movb	%al, MULD|[[FP6&0x1c]<<5]|[FP6&3]|[FP2<<2]
	movb	%al, MULD|[[FP4&0x1c]<<5]|[FP4&3]|[FP2<<2]
	movb	%al, ADDD|[[FP4&0x1c]<<5]|[FP4&3]|[FP2<<2]

	movl	%edx, LOADD|[FP1<<2]
	movl	%ecx, ADDD|[FP2<<2]	

	movl	%eax, FLOATD|[FP4<<2]		
	movl	$ 0xfefa39ef, LOADD|[FP1<<2]
	movl	$ 0x3fe62e42, MULD|[FP4<<2]
	popl	%edx
	movb	%al, ADDD|[[FP4&0x1c]<<5]|[FP4&3]|[FP2<<2]
	/testw	$0x1,%dl	/see if this is the log function
	.byte	0x66,0xf7,0xc2,0x01,0x00
	jz	log_ret
	jmp	log10_ret
log_ret:
	ret

not_positive:
	/testw	$0x1,%dl	/* see if this is the log function */
	.byte	0x66,0xf7,0xc2,0x01,0x00
	jz	log_err		/* yes this is a log function, jmp */
	wloadl	4(%esp),%fp2
	wtstl	%fp2			/argument < 0
	wstctx	%eax			/save contentes of control reg
	sahf
	jne	log10_neg_arg		/argument is < 0, jmp
	subl	$0x20,%esp		/allocate struct exception exc
	wstorl	%fp2,0x8(%esp)		/exc.arg1 = x
	movl	$0x2,(%esp)		/exc.type = SING
	movl	$LOG10ERR1,0x4(%esp)	/exc.name = "log10"
	wloadl	_maxdouble,%fp4		/exc.retval = -HUGE_VAL
	wnegl	%fp4,%fp2
	wstorl	%fp2,0x18(%esp)
	leal	(%esp),%eax
	pushl	%eax
	call	matherr
	popl	%ecx
	testl	%eax,%eax
	jne	log_exit

	pushl	$0x12			/length of err string
	pushl	$LOG10ERR3		/"log10: SING error\n"
	pushl	$0x2			/ write to stderr
	call	write
	addl	$0xc,%esp
	movl	$0x21,errno		/errno = EDOM
	jmp	log_exit
	
log10_neg_arg:
	subl	$0x20,%esp		/allocate struct exception exc
	wstorl	%fp2,0x8(%esp)		/exc.arg1 = x
	movl	$0x1,(%esp)		/exc.type = DOMAIN
	movl	$LOG10ERR1,0x4(%esp)	/exc.name = "log10"
	wloadl	_maxdouble,%fp4		/exc.retval = -HUGE_VAL
	wnegl	%fp4,%fp2
	wstorl	%fp2,0x18(%esp)
	leal	(%esp),%eax
	pushl	%eax
	call	matherr
	popl	%ecx
	testl	%eax,%eax
	jne	log_exit

	pushl	$0x14			/length of err string
	pushl	$LOG10ERR2		/"log10: DOMAIN error"
	pushl	$0x2			/write to stderr
	call	write
	addl	$0xc,%esp
	movl	$0x21,errno		/errno = EDOM
	jmp	log_exit


log_err:
	wloadl	4(%esp),%fp2
	wtstl	%fp2			/argument < 0
	wstctx	%eax			/save contents of control reg
	sahf
	jne	log_neg_arg		/argument is < 0, jmp
	subl	$0x20,%esp		/allocate struct exception exc
	wstorl	%fp2,0x8(%esp)		/exc.arg1 = x
	movl	$0x2,(%esp)		/exc.type = SING
	movl	$LOGERR1,0x4(%esp)	/exc.name = "log"
	wloadl	_maxdouble,%fp4		/exc.retval = -HUGE_VAL
	wnegl	%fp4,%fp2
	wstorl	%fp2,0x18(%esp)
	leal	(%esp),%eax
	pushl	%eax
	call	matherr
	popl	%ecx
	testl	%eax,%eax
	jne	log_exit

	pushl	$0x10			/length of err string
	pushl	$LOGERR3		/"log: SING error\n"
	pushl	$0x2			/write to stderr
	call	write
	addl	$0xc,%esp
	movl	$0x21,errno		/errno = EDOM
	jmp	log_exit

log_neg_arg:
	subl	$0x20,%esp		/allocate struct exception exc
	wstorl	%fp2,0x8(%esp)		/exc.arg1 = x
	movl	$0x1,(%esp)		/exc.type = DOMAIN
	movl	$LOGERR1,0x4(%esp)	/exc.name = "log"
	wloadl	_maxdouble,%fp4		/exc.retval = -HUGE_VAL
	wnegl	%fp4,%fp2
	wstorl	%fp2,0x18(%esp)
	leal	(%esp),%eax
	pushl	%eax
	call	matherr
	popl	%ecx
	testl	%eax,%eax
	jne	log_exit

	pushl	$0x12			/length of err string
	pushl	$LOGERR2		/"log: DOMAIN error"
	pushl	$0x2			/write to stderr
	call	write
	addl	$0xc,%esp
	movl	$0x21,errno		/errno = EDOM
log_exit:
	wloadl	0x18(%esp),%fp2		/return exc.retval
	addl	$0x20,%esp		/deallocate struct exception exc
	ret


table:
	.long	0x00000000, 0x00000000, 0xc01162a6, 0x3faf0a30
	.long	0x6e2af2e6, 0x3fbe2707, 0x70a793d4, 0x3fc5ff30
	.long	0xc79a9a22, 0x3fcc8ff7, 0xababa60e, 0x3fd1675c
	.long	0xc21c5ec2, 0x3fd4618b, 0xf6bbd007, 0x3fd739d7
	.long	0x1134db92, 0xbfd26962, 0x6cb3b379, 0xbfcf991c
	.long	0x3c8ad9e3, 0xbfca93ed, 0x6b543db2, 0xbfc5bf40
	.long	0x8227e47c, 0xbfc1178e, 0x5d594989, 0xbfb9335e
	.long	0xb59e3a07, 0xbfb08598, 0x89e74444, 0xbfa0415d
	.long	0x00000000, 0x00000000

ENTRY(log10)
	movb	$0x1,%dl			/Set the operation flag to log10
	jmp	log_work
log10_ret:
	movl	$ 0x1526e50e, LOADD|[FP1<<2]
	movl	$ 0x3fdbcb7b, MULD|[FP2<<2]
	ret
