/
/ Floating point add and subtract.
/

	.globl	__fadd
	.globl	__fsub

/
/ __fadd.
/ __fsub.
/ Floating point add and subtract.
/ Just like the FADD SP and FSUB SP
/ instructions in the FIS.
/

__fsub:	tst	2(sp)
	beq	__fadd
	add	$100000,2(sp)

__fadd:	jsr	r0,__fsav

	clr	F_SIGN(sp)

	clr	r3
	asl	F_B+2(sp)
	rol	F_B(sp)
	bisb	F_B+1(sp),r3
	bne	0f
	jmp	__frta

0:	rol	F_SIGN(sp)

	clr	r2
	asl	F_A+2(sp)
	rol	F_A(sp)
	bisb	F_A+1(sp),r2
	bne	0f
	ror	F_SIGN(sp)
	ror	F_B(sp)
	ror	F_B+2(sp)
	jmp	__frtb

0:	rolb	F_SIGN+1(sp)
	movb	$1,F_A+1(sp)
	movb	$1,F_B+1(sp)

/
/ Load r0-r1 with the fraction
/ to be shifted.
/ Load r2 with shift count.
/ Load r3 with the result exponant.
/

	sub	r3,r2
	bgt	0f
	mov	F_A(sp),r0
	mov	F_A+2(sp),r1
	mov	F_B(sp),F_A(sp)
	mov	F_B+2(sp),F_A+2(sp)
	neg	r2
	br	1f

0:	add	r2,r3
	mov	F_B(sp),r0
	mov	F_B+2(sp),r1
	swab	F_SIGN(sp)

1:	cmpb	F_SIGN(sp),F_SIGN+1(sp)
	beq	0f
	neg	r0
	neg	r1
	sbc	r0

/
/ Allign.
/ If the same, skip this.
/ If different by >25, just return
/ the larger one.
/

0:	tst	r2
	beq	1f

	cmp	r2,$25.
	ble	0f
	mov	F_A(sp),r0
	mov	F_A+2(sp),r1
	br	2f

0:	asr	r0
	ror	r1
	dec	r2
	bne	0b

/
/ Add.
/ If the signs are the same
/ normalisation is fast.
/ Otherwise normalise the hard
/ way.
/

1:	add	F_A(sp),r0
	add	F_A+2(sp),r1
	adc	r0

2:	cmpb	F_SIGN(sp),F_SIGN+1(sp)
	bne	0f
	bit	$1000,r0
	beq	2f
	asr	r0
	ror	r1
	inc	r3
	br	2f

0:	tst	r0
	beq	0f
	bgt	1f
	neg	r0
	neg	r1
	sbc	r0
	swab	F_SIGN(sp)
	br	1f

0:	tst	r1
	beq	3f

1:	bit	r0,$400
	bne	2f
	asl	r1
	rol	r0
	dec	r3
	br	1b

/
/ Range check exponant.
/ Pack the result.
/

2:	tst	r3
	bgt	0f
	jsr	pc,__fufl

3:	clr	r3
	clr	r1
	br	1f

0:	cmp	r3,$377
	blos	0f
	jsr	pc,__fofl
	mov	$77777,r3
	mov	$177777,r1
	br	1f

0:	swab	r3
	bisb	r0,r3
	ror	F_SIGN(sp)
	ror	r3
	ror	r1

1:	mov	r3,F_A(sp)
	mov	r1,F_A+2(sp)

	jmp	__frta
