home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.mac.programmer
- Path: sparky!uunet!mcsun!fuug!funic!nntp.hut.fi!vipunen.hut.fi!jmunkki
- From: jmunkki@vipunen.hut.fi (Juri Munkki)
- Subject: Re: 64-bit multiply and divide on 68000
- Message-ID: <1992Nov22.105122.4558@nntp.hut.fi>
- Keywords: 68000 Assembler Math discrete
- Sender: usenet@nntp.hut.fi (Usenet pseudouser id)
- Nntp-Posting-Host: vipunen.hut.fi
- Reply-To: jmunkki@vipunen.hut.fi (Juri Munkki)
- Organization: Helsinki University of Technology
- References: <By3BM7.InD@world.std.com>
- Date: Sun, 22 Nov 1992 10:51:22 GMT
- Lines: 114
-
- In article <By3BM7.InD@world.std.com> squeegee@world.std.com (Stephen C. Gilardi) writes:
- >I need to calculate a linear interpolation rapidly. The equation is
- >
- > y = x * numer / denom,
- >
- >where y, numer, and denom are 32-bit unsigned longs and x is a 16-bit
- >unsigned short.
- >
- >On the 68020, I can use the built-in "long" multiply and divide instructions.
- >However on the 68000 it's more involved.
- >
- >I found 68000 code in a book to do the 64-bit unsigned multiply. I'd
- >like to have the divide in assembly language as well.
- >
- >Does anyone have such a routine, or a reference to where I can find one?
-
- I'm also interested in a good division routine for the 68K. Here's a routine
- that does essentially what you wanted to do and a bit more. It uses 32 bit
- fixed point numbers. I would very much like to see an improved division
- routine. I wasn't able to figure out anything better on my own and since
- my main target processor is the 68030, this version is not used all that
- often.
-
- Since your x is a short, you will save quite a bit of time by using that
- knowledge to optimize the code.
-
- Fixed FMulDiv68000(a,b,c)
- Fixed a,b,c;
- {
- asm {
- movem.l D3-D5,-(sp)
- move.l a,D0
- bpl.s @positive_a
- neg.l c
- neg.l D0
- @positive_a
- move.l b,D1
- bpl.s @positive_b
- neg.l D1
- neg.l c
- @positive_b
- move.w D1,D2
- mulu.w D0,D2 ; D2 = Lo * Lo
-
- move.w D1,D3
- swap D0
- mulu.w D0,D3 ; D3 = Hi * Lo
-
- swap D1
- move.w D1,D4
- mulu.w D0,D4 ; D4 = Hi * Hi
-
- swap D0
- mulu.w D0,D1 ; D1 = Lo * Hi
-
- clr.l D5
- move.w D3,D5
- swap D5
- clr.w D3
- swap D3
- add.l D5,D2 ; 64 bit addition Hi*Hi:Lo*Lo += Hi*Lo
- addx.l D3,D4
-
- clr.l D5
- move.w D1,D5
- swap D5
- clr.w D1
- swap D1
- add.l D5,D2 ; 64 bit addition Hi*Hi:Lo*Lo+Hi*Lo += Lo*Hi
- addx.l D1,D4 ; Result is now in D4:D2
-
- add.l D2,D2
- addx.l D4,D4
-
- move.l c,D1
- bpl.s @positive_c
- neg.l D1
- @positive_c
- moveq.l #1,D0
- bra.s @divloop
- @divok
- lsl.l #1,D0
- bcs.s @divdone
- add.l D2,D2
- addx.l D4,D4
- @divloop
- sub.l D1,D4
- bcc.s @divok
-
- addx.l D0,D0
- bcs.s @divdone
-
- add.l D1,D4
- add.l D2,D2
- addx.l D4,D4
- bra.s @divloop
-
- @divdone
- move.l c,D1
- bpl.s @positive_result
-
- addq.l #1,D0
- bra.s @done
- @positive_result
- eor.l #-1,D0
- @done
- movem.l (sp)+,D3-D5
- }
- }
-
-
- --
- Juri Munkki Windsurf: fast sailing
- jmunkki@hut.fi Macintosh: fast software
-