Mail Archives: djgpp/1996/08/30/00:05:42
Xref: | news2.mv.net comp.os.msdos.djgpp:8052
|
From: | korpela AT islay DOT ssl DOT berkeley DOT edu (Eric J. Korpela)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Re: Using inline as to multiply two fixed point #'s
|
Date: | 30 Aug 1996 00:34:05 GMT
|
Organization: | Cal Berkeley-- Space Sciences Lab
|
Lines: | 81
|
Message-ID: | <505ctt$aa2@agate.berkeley.edu>
|
References: | <502b8n$eh6 AT crab DOT rutgers DOT edu>
|
NNTP-Posting-Host: | islay.ssl.berkeley.edu
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
In article <502b8n$eh6 AT crab DOT rutgers DOT edu>,
Roger Cowley <cowley AT crab DOT rutgers DOT edu> wrote:
>Allright, so I need functions to multiply and divide fixed point
>numbers, but I'm having problems with djgpp and inline assembly.
Isn't everyone? :) (Just kidding. I love both DJGPP and gas.)
>
>fixed is just typedef long fixed
>
>say x,y, and z are all fixed
>
>x = (fixed)(65536 * 2.3);
>y = (fixed)(65536 * 3.2);
>
>asm("
> mov _x,%eax
> imul _y
> mov %eax,_z
> ");
>
>Now, there are of course complications. Yes I made x,y,and z global
>so the inline assembler could use them.
The first thing to do is to stop doing that. You don't need global variables
to use them in inline assembly. Global variable are a pain in the butt.
Global variables make code non-reentrant. Used the Extended assembly format.
It's not that hard. See http://www.rt66.com/~brennan/djgpp/djgpp_asm.html.
Here's how I would write your function.....
inline fixed mul_fixed(fixed x, fixed y)
{
fixed z;
asm(
"imul %1 "
"shll $16,%%edx " /* renormalize */
"shrl $16,%0 "
"andl $0xffff0000,%%edx "
"addl %%edx,%0 " /* result is in %0 14 clocks later */
: "=a" (z) /* store the output (%eax) in the variable z */
: "b" (y), /* load the %ebx register with variable y */
"0" (x) /* load the %eax register with variable x */
: "edx" /* %edx gets clobbered */
);
return (z);
}
> But here's where I get
>tripped up: a long times a long is 64 bit...so this is a 32-bit
>expanding multiply whose result is 64-bit, right? How do I use the
>imul instruction correctly in this case, and how do I dump my result
>into z?
You appear to be forgetting to renormalize after your multiplication.
(You also have to do it before division.) In c what you'd want to
write is.....
z=(fixed)((((long long)x)*y)/65536);
for division you need to write
z=(fixed)((((long long)x)*65536)/y);
The big question is "Why use fixed point?" The above takes 16 clocks
(1 load, 14 execute, 1 store) + call overhead on a pentium. If you
use floating point it would take 5 cycles (1 load, 3 execute, 1 store)
+ call overhead. Even on a 486 it's 21-50 (fixed) versus 25 (fp).
Eric
Eric
--
Eric Korpela | An object at rest can never be
korpela AT ssl DOT berkeley DOT edu | stopped.
<a href="http://www.cs.indiana.edu/finger/mofo.ssl.berkeley.edu/korpela/w">
Click here for more info.</a>
- Raw text -