fp8087.s

来自「minux的源代码,一个非常小的操作系统」· S 代码 · 共 616 行

S
616
字号
.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8
.define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8
.define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8
.define .cmf4, .cmf8
.sect .text; .sect .rom; .sect .data; .sect .bss

!	$Header: fp8087.s,v 1.2 89/11/28 12:51:35 ceriel Exp $

!	Implement interface to floating point package for Intel 8087

	.sect .rom
one:
	.data2	1
two:
	.data2	2
bigmin:
	.data2	0, -32768

	.sect .text
.adf4:
	mov	bx,sp
	wait
	flds	2(bx)
	wait
	fadds	6(bx)
	wait
	fstps	6(bx)
	wait
	ret
.adf8:
	mov	bx,sp
	wait
	fldd	2(bx)
	wait
	faddd	10(bx)
	wait
	fstpd	10(bx)
	wait
	ret

.sbf4:
	mov	bx,sp
	wait
	flds	6(bx)
	wait
	fsubs	2(bx)
	wait
	fstps	6(bx)
	wait
	ret

.sbf8:
	mov	bx,sp
	wait
	fldd	10(bx)
	wait
	fsubd	2(bx)
	wait
	fstpd	10(bx)
	wait
	ret

.mlf4:
	mov	bx,sp
	wait
	flds	2(bx)
	wait
	fmuls	6(bx)
	wait
	fstps	6(bx)
	wait
	ret
.mlf8:
	mov	bx,sp
	wait
	fldd	2(bx)
	wait
	fmuld	10(bx)
	wait
	fstpd	10(bx)
	wait
	ret

.dvf4:
	mov	bx,sp
	wait
	flds	6(bx)
	wait
	fdivs	2(bx)
	wait
	fstps	6(bx)
	wait
	ret

.dvf8:
	mov	bx,sp
	wait
	fldd	10(bx)
	wait
	fdivd	2(bx)
	wait
	fstpd	10(bx)
	wait
	ret

.ngf4:
	mov	bx,sp
	wait
	flds	2(bx)
	wait
	fchs
	wait
	fstps	2(bx)
	wait
	ret

.ngf8:
	mov	bx,sp
	wait
	fldd	2(bx)
	wait
	fchs
	wait
	fstpd	2(bx)
	wait
	ret

.fif4:
	mov	bx,sp
	push	bx		! make room for FP status word
	wait
	flds	4(bx)
	wait
	fmuls	8(bx)		! multiply
	wait
	fld	st		! copy result
	wait
	ftst			! test sign; handle negative separately
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf			! result of test in condition codes
	jb	1f
	frndint			! this one rounds (?)
	wait
	fcom	st(1)		! compare with original; if <=, then OK
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	jbe	2f
	fisubs	one		! else subtract 1
	wait
	jmp	2f
1:				! here, negative case
	frndint			! this one rounds (?)
	wait
	fcom	st(1)		! compare with original; if >=, then OK
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	jae	2f
	fiadds	one		! else add 1
	wait
2:
	fsub	st(1),st	! subtract integer part
	wait
	mov	bx,2(bx)
	fstps	(bx)
	wait
	fstps	4(bx)
	wait
	pop	bx
	ret

.fif8:
	mov	bx,sp
	push	bx		! make room for FP status word
	wait
	fldd	4(bx)
	wait
	fmuld	12(bx)		! multiply
	wait
	fld	st		! and copy result
	wait
	ftst			! test sign; handle negative separately
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf			! result of test in condition codes
	jb	1f
	frndint			! this one rounds (?)
	wait
	fcom	st(1)		! compare with original; if <=, then OK
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	jbe	2f
	fisubs	one		! else subtract 1
	wait
	jmp	2f
1:				! here, negative case
	frndint			! this one rounds (?)
	wait
	fcom	st(1)		! compare with original; if >=, then OK
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	jae	2f
	fiadds	one		! else add 1
	wait
2:
	fsub	st(1),st	! subtract integer part
	mov	bx,2(bx)
	fstpd	(bx)
	wait
	fstpd	8(bx)
	wait
	pop	bx
	ret

.fef4:
				! this could be simpler, if only the
				! fxtract instruction was emulated properly
	mov	bx,sp
	mov	ax,6(bx)
	and	ax,#077600
	je	1f		! zero exponent
	mov	cx,#7
	shr	ax,cl
	sub	ax,#126
	mov	cx,ax		! exponent in cx
	mov	ax,6(bx)
	and	ax,#0100177
	or	ax,#0037400	! load -1 exponent
	mov	dx,4(bx)
	mov	bx,2(bx)
	mov	4(bx),ax
	mov	2(bx),dx
	mov	(bx),cx
	ret
1:				! we get here on zero exp
	mov	ax,6(bx)
	and	ax,#0177
	or	ax,4(bx)
	jne	1f		! zero result
	xor	ax,ax
	mov	bx,2(bx)
	mov	(bx),ax
	mov	2(bx),ax
	mov	4(bx),ax
	ret
1:				! otherwise unnormalized number
	mov	cx,6(bx)
	and	cx,#0100177
	mov	dx,cx
	and	cx,#0x8000
	mov	ax,#-125
2:
	test	dx,#0x80
	jne	1f
	dec	ax
	shl	4(bx),#1
	rcl	dx,#1
	or	dx,cx
	jmp	2b
1:
	mov	cx,4(bx)
	mov	bx,2(bx)
	mov	(bx),ax
	mov	2(bx),cx
	and	dx,#0100177
	or	dx,#0037400	! load -1 exponent
	mov	4(bx),dx
	ret

.fef8:
				! this could be simpler, if only the
				! fxtract instruction was emulated properly
	mov	bx,sp
	mov	ax,10(bx)
	and	ax,#077760
	je	1f		! zero exponent
	mov	cx,#4
	shr	ax,cl
	sub	ax,#1022
	mov	cx,ax		! exponent in cx
	mov	ax,10(bx)
	and	ax,#0100017
	or	ax,#0037740	! load -1 exponent
	push	8(bx)
	push	6(bx)
	push	4(bx)
	mov	bx,2(bx)
	pop	2(bx)
	pop	4(bx)
	pop	6(bx)
	mov	8(bx),ax
	mov	(bx),cx
	ret
1:				! we get here on zero exp
	mov	ax,10(bx)
	and	ax,#017
	or	ax,8(bx)
	or	ax,6(bx)
	or	ax,4(bx)
	jne	1f		! zero result
	xor	ax,ax
	mov	bx,2(bx)
	mov	(bx),ax
	mov	2(bx),ax
	mov	4(bx),ax
	mov	6(bx),ax
	mov	8(bx),ax
	ret
1:				! otherwise unnormalized number
	mov	cx,10(bx)
	and	cx,#0100017
	mov	dx,cx
	and	cx,#0x8000
	mov	ax,#-1021
2:
	test	dx,#0x10
	jne	1f
	dec	ax
	shl	4(bx),#1
	rcl	6(bx),#1
	rcl	8(bx),#1
	rcl	dx,#1
	or	dx,cx
	jmp	2b
1:
	and	dx,#0100017
	or	dx,#0037740	! load -1 exponent
	mov	cx,8(bx)
	push	6(bx)
	push	4(bx)
	mov	bx,2(bx)
	mov	(bx),ax
	mov	8(bx),dx
	mov	6(bx),cx
	pop	2(bx)
	pop	4(bx)
	ret

.cif4:
	mov	bx,sp
	cmp	2(bx),#2
	jne	1f
	wait
	filds	4(bx)
	wait
	fstps	2(bx)
	wait
	ret
1:
	wait
	fildl	4(bx)
	wait
	fstps	4(bx)
	wait
	ret

.cif8:
	mov	bx,sp
	cmp	2(bx),#2
	jne	1f
	wait
	filds	4(bx)
	wait
	fstpd	2(bx)
	wait
	ret
1:
	wait
	fildl	4(bx)
	wait
	fstpd	2(bx)
	wait
	ret

.cuf4:
	mov	bx,sp
	cmp	2(bx),#2
	jne	1f
	mov	ax,4(bx)
	mov	2(bx),ax
	mov	4(bx),#0
	wait
	fildl	2(bx)
	wait
	fstps	2(bx)
	wait
	ret
1:
	wait
	fildl	4(bx)
	wait
	cmp	6(bx),#0
	jge	1f
2:
	wait
	fisubl	bigmin
	wait
	fisubl	bigmin
1:
	wait
	fstps	4(bx)
	wait
	ret

.cuf8:
	mov	bx,sp
	cmp	2(bx),#2
	jne	1f
	mov	6(bx),#0
1:
	wait
	fildl	4(bx)
	wait
	cmp	6(bx),#0
	jge	1f
2:
	wait
	fisubl	bigmin
	wait
	fisubl	bigmin
1:
	wait
	fstpd	2(bx)
	wait
	ret

.cfi:
	mov	bx,sp
	push	bx
	wait
	fstcw	-2(bx)
	wait
	mov	dx,-2(bx)
	or	-2(bx),#0xc00	! truncating mode
	wait
	fldcw	-2(bx)
	pop	ax
	cmp	4(bx),#4
	jne	2f
				! loc 4 loc ? cfi
	wait
	flds	6(bx)
	wait
	fistpl	6(bx)
	wait
	cmp	2(bx),#2
	jne	1f
	mov	ax,6(bx)
1:
	mov	4(bx),dx
	wait
	fldcw	4(bx)
	wait
	ret
2:
				! loc 8 loc ? cfi
	wait
	fldd	6(bx)
	wait
	fistpl	10(bx)
	wait
	cmp	2(bx),#2
	jne	1b
	mov	ax,10(bx)
	jmp	1b

.cfu:
	mov	bx,sp
	push	bx
	wait
	fstcw	-2(bx)
	wait
	mov	dx,-2(bx)
	and	-2(bx),#0xf3ff
	or	-2(bx),#0x400	! to -infinity
	wait
	fldcw	-2(bx)
	wait
	pop	ax
	cmp	4(bx),#4
	jne	2f
				! loc 4 loc ? cfu
	flds	6(bx)
	wait
	fabs			! ???
	wait
	fiaddl	bigmin
	fistpl	6(bx)
	wait
	mov	ax,8(bx)
	sub	ax,bigmin+2
	mov	8(bx),ax
	cmp	2(bx),#2
	jne	1f
	mov	ax,6(bx)
1:
	mov	4(bx),dx
	wait
	fldcw	4(bx)
	wait
	ret
2:
	wait
				! loc 8 loc ? cfu
	fldd	6(bx)
	wait
	fabs			! ???
	wait
	fiaddl	bigmin
	fistpl	10(bx)
	wait
	mov	ax,12(bx)
	sub	ax,bigmin+2
	mov	12(bx),ax
	cmp	2(bx),#2
	jne	1b
	mov	ax,10(bx)
	jmp	1b

.cff4:
	mov	bx,sp
	wait
	fldd	2(bx)
	wait
	fstcw	2(bx)
	wait
	mov	dx,2(bx)
	and	2(bx),#0xf3ff	! set to rounding mode
	wait
	fldcw	2(bx)
	wait
	fstps	6(bx)
	mov	2(bx),dx
	wait
	fldcw	2(bx)
	wait
	ret

.cff8:
	mov	bx,sp
	wait
	flds	2(bx)
	wait
	fstpd	2(bx)
	wait
	ret

.cmf4:
	mov	bx,sp
	push	bx		! room for 8087 status word
	xor	cx,cx
	wait
	flds	6(bx)
	wait
	flds	2(bx)
	wait
	fcompp			! compare and pop operands
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	je	1f
	jb	2f
	dec	cx
	jmp	1f
2:
	inc	cx
1:
	mov	ax,cx
	pop	bx
	ret


.cmf8:
	mov	bx,sp
	push	bx		! room for 8087 status word
	xor	cx,cx
	wait
	fldd	10(bx)
	wait
	fldd	2(bx)
	wait
	fcompp			! compare and pop operands
	wait
	fstsw	-2(bx)
	wait
	mov	ax,-2(bx)
	sahf
	je	1f
	jb	2f
	dec	cx
	jmp	1f
2:
	inc	cx
1:
	mov	ax,cx
	pop	bx
	ret

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?