1 /* Copyright 2000 Kjetil S. Matheussen
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version 2
6 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 # include <proto/utility.h>
34 #include "PEQ_calc_64bit_proc.h"
37 /**************************************
39 Returns a*b/c. a*b may be bigger
40 than a 32 bit variable can hold.
43 The 68020 and higher versions is
44 defined in the 64bit.a file.
45 (a bit smaller, that one. :)
46 Probably noone that is ever going
47 to use this routine (very unlikely
48 that anyone wants to use the
49 program on an 000), but I wrote
50 this before I knew there was an asm
51 routines that does this directly.
54 This function is VERY hard and
58 68060 version allso uses this function.
59 muls and divs is emulated on an
60 060, so this function is twice
61 as fast as the other one.
62 **************************************/
64 int Mul32Div64_000(const int a
,const int b
,const int c
){
67 unsigned long l32
=UMult64((unsigned long)abs(a
),(unsigned long)abs(b
));
68 unsigned long m32
=getreg(REG_D1
);
70 unsigned long l32
=(unsigned long)abs(a
)/(unsigned long)abs(b
);
71 unsigned long m32
=(unsigned long)abs(a
)%(unsigned long)abs(b
);
78 if( m32
==0 && ( (1<<31 & l32
)==0 ) ){
79 return (a
<0)^(b
<0) ? -(int)(l32
)/c
: (int)(l32
)/c
;
81 // printf("storre\n");
83 uc
=(unsigned long)abs(c
);
86 result
=UDivMod32(1<<31,uc
);
87 modulo
=getreg(REG_D1
);
98 result
=(result
+1)*m32
;
104 m32
=UDivMod32(m32
*modulo
,uc
);
105 modulo
=getreg(REG_D1
);
107 l32
=UDivMod32(l32
,uc
);
108 modulo
+=getreg(REG_D1
);
111 modulo
=(m32
*modulo
)&uc
;
120 result
+ m32
+ l32
+ (modulo
>=uc
)
122 result
+ m32
+ l32
+ (modulo
>=uc
)
134 for(a=25000;a<25010;a++){
136 for(b=184000;b<185000;b++){
137 for(c=200000;c<200100;c++){
138 d+=Mul32Div64_000(a,b,c);
145 for(a=25000;a<25010;a++){
147 for(b=184000;b<185000;b++){
148 for(c=200000;c<200100;c++){
149 d+=Mul32Div64_020(a,b,c);
155 // printf("d: %d, %x\n",16383*-20569/185620,Mul32Div64(a,b,c));