82 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| .define .mlu
 | |
| .sect .text
 | |
| .sect .rom
 | |
| .sect .data
 | |
| .sect .bss
 | |
| 
 | |
|  ! unsigned long mulitply
 | |
|  !-----------------------------------------------------------------------------
 | |
|  ! rewritten by Kai-Uwe Bloem (i5110401@dbstu1.bitnet) for speed.
 | |
|  !   #1  01/12/90  initial revision
 | |
|  !-----------------------------------------------------------------------------
 | |
|  !   3 cases worth to recognize :
 | |
|  !	1) both the upper word of u and v are zero
 | |
|  !	    => 1 mult : Low*Low
 | |
|  !	2) only one of the upper words is zero
 | |
|  !	    => 2 mult : Low*HighLow
 | |
|  !	3) both upper words are not zero
 | |
|  !	    => 4 mult : HighLow*HighLow
 | |
|  !   there are other cases (e.g. lower word is zero but high word is not, or
 | |
|  !   one operand is all zero). However, this seems not to be very common, so
 | |
|  !   they are ignored for the price of superfluous multiplications in these
 | |
|  !   cases.
 | |
|  !-----------------------------------------------------------------------------
 | |
| 
 | |
|  ! entry : d0 multiplicand
 | |
|  !         d1 multiplier
 | |
|  ! exit  : d0 high order result
 | |
|  !         d1 low order result
 | |
|  !         d2,a0,a1 : destroyed
 | |
| 
 | |
| 	.sect .text
 | |
| .mlu:
 | |
| 	move.l	(sp)+,a1	! return address
 | |
| 	move.l	d3,a0		! save register
 | |
| 	movem.w	(sp)+,d0-d3	! get v and u
 | |
| 	tst.w	d0
 | |
| 	bne	1f		! case 2) or 3)
 | |
| 	tst.w	d2
 | |
| 	bne	2f		! case 2)
 | |
| ! === case 1: _l x _l ===
 | |
| 	mulu	d3,d1		! r.l = u.l x v.l
 | |
| 	move.l	a0,d3		! (r.h is already zero)
 | |
| 	jmp	(a1)		! return
 | |
| ! === possibly case 2) or case 3) ===
 | |
| 1:
 | |
| 	tst.w	d2
 | |
| 	bne	3f		! case 3)
 | |
| ! === case 2: _l x hl ===
 | |
| 	exg	d0,d2		! exchange u and v
 | |
| 	exg	d1,d3		! (minimizes number of distinct cases)
 | |
| 2:
 | |
| 	mulu	d1,d2		! a = v.l x u.h
 | |
| 	mulu	d3,d1		! r.l = v.l x u.l
 | |
| 	swap	d2		! a = a << 16
 | |
| 	clr.l	d3
 | |
| 	move.w	d2,d3
 | |
| 	clr.w	d2
 | |
| 	add.l	d2,d1		! r += a
 | |
| 	addx.l	d3,d0
 | |
| 	move.l	a0,d3		! return
 | |
| 	jmp	(a1)
 | |
| ! === case 3: hl x hl ===
 | |
| 3:
 | |
| 	move.l	d4,-(sp)	! need more registers
 | |
| 	move.w	d2,d4
 | |
| 	mulu	d1,d4		! a = v.l x u.h
 | |
| 	mulu	d3,d1		! r.l = u.l x v.l
 | |
| 	mulu	d0,d3		! b = v.h x u.l
 | |
| 	mulu	d2,d0		! r.h = u.h x v.h
 | |
| 	swap	d1		! (just for simplicity)
 | |
| 	add.w	d4,d1		! r += a << 16
 | |
| 	clr.w	d4
 | |
| 	swap	d4
 | |
| 	addx.l	d4,d0
 | |
| 	add.w	d3,d1		! r += b << 16
 | |
| 	clr.w	d3
 | |
| 	swap	d3
 | |
| 	addx.l	d3,d0
 | |
| 	swap	d1
 | |
| 	move.l	(sp)+,d4	! return
 | |
| 	move.l	a0,d3
 | |
| 	jmp	(a1)
 |