2008-04-26 00:39:44 -07:00
|
|
|
#include <math.h>
|
|
|
|
|
2001-08-08 06:14:20 +00:00
|
|
|
#include "3dc.h"
|
2015-02-14 12:00:00 +01:00
|
|
|
#include "mathline.h"
|
2001-08-08 06:14:20 +00:00
|
|
|
|
|
|
|
void ADD_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c);
|
|
|
|
void ADD_LL_PP(LONGLONGCH *c, LONGLONGCH *a);
|
|
|
|
void SUB_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c);
|
|
|
|
void SUB_LL_MM(LONGLONGCH *c, LONGLONGCH *a);
|
|
|
|
void MUL_I_WIDE(int a, int b, LONGLONGCH *c);
|
|
|
|
int CMP_LL(LONGLONGCH *a, LONGLONGCH *b);
|
|
|
|
void EQUALS_LL(LONGLONGCH *a, LONGLONGCH *b);
|
|
|
|
void NEG_LL(LONGLONGCH *a);
|
|
|
|
void ASR_LL(LONGLONGCH *a, int shift);
|
|
|
|
void IntToLL(LONGLONGCH *a, int *b);
|
|
|
|
int DIV_FIXED(int a, int b);
|
|
|
|
|
|
|
|
int NarrowDivide(LONGLONGCH *a, int b);
|
|
|
|
int WideMulNarrowDiv(int a, int b, int c);
|
|
|
|
void RotateVector_ASM(VECTORCH *v, MATRIXCH *m);
|
|
|
|
void RotateAndCopyVector_ASM(VECTORCH *v1, VECTORCH *v2, MATRIXCH *m);
|
|
|
|
|
2008-04-26 00:39:44 -07:00
|
|
|
#undef ASM386
|
|
|
|
|
|
|
|
#if !defined(ASM386)
|
2008-05-06 22:57:13 -07:00
|
|
|
static __int64 ConvertToLongLong(const LONGLONGCH* llch)
|
2008-04-26 00:39:44 -07:00
|
|
|
{
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 ll;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
ll = ((__int64)llch->hi32 << 32) | ((__int64)llch->lo32 << 0);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
return ll;
|
|
|
|
}
|
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
static void ConvertFromLongLong(LONGLONGCH* llch, const __int64* ll)
|
2008-04-26 00:39:44 -07:00
|
|
|
{
|
|
|
|
llch->lo32 = (unsigned int)((*ll>> 0) & 0xffffffff);
|
|
|
|
llch->hi32 = ( signed int)((*ll>>32) & 0xffffffff);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-08-08 06:14:20 +00:00
|
|
|
void ADD_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,a
|
|
|
|
mov edi,b
|
|
|
|
mov ebx,c
|
|
|
|
mov eax,[esi]
|
|
|
|
mov edx,[esi+4]
|
|
|
|
add eax,[edi]
|
|
|
|
adc edx,[edi+4]
|
|
|
|
mov [ebx],eax
|
|
|
|
mov [ebx+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
int dummy1, dummy2;
|
|
|
|
__asm__("movl 0(%%esi), %0 \n\t"
|
|
|
|
"movl 4(%%esi), %1 \n\t"
|
|
|
|
"addl 0(%%edi), %0 \n\t"
|
|
|
|
"adcl 4(%%edi), %1 \n\t"
|
|
|
|
"movl %0, 0(%%ebx) \n\t"
|
|
|
|
"movl %1, 4(%%ebx) \n\t"
|
|
|
|
: "=&r" (dummy1), "=&r" (dummy2)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "S" (a), "D" (b), "b" (c)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "memory", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
|
|
__asm__("movl 0(%%esi), %%eax \n\t"
|
|
|
|
"movl 4(%%esi), %%edx \n\t"
|
|
|
|
"addl 0(%%edi), %%eax \n\t"
|
|
|
|
"adcl 4(%%edi), %%edx \n\t"
|
|
|
|
: "=a" (c->lo32), "=d" (c->hi32)
|
|
|
|
: "S" (a), "D" (b)
|
|
|
|
);
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = ConvertToLongLong(a);
|
|
|
|
__int64 bb = ConvertToLongLong(b);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = aa + bb;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
ConvertFromLongLong(c, &cc);
|
|
|
|
#endif
|
|
|
|
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ADD ++ */
|
|
|
|
|
|
|
|
void ADD_LL_PP(LONGLONGCH *c, LONGLONGCH *a)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov edi,c
|
|
|
|
mov esi,a
|
|
|
|
mov eax,[esi]
|
2002-09-07 00:26:23 +00:00
|
|
|
mov edx,[esi+4]
|
2001-08-08 06:14:20 +00:00
|
|
|
add [edi],eax
|
|
|
|
adc [edi+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
int dummy1, dummy2;
|
|
|
|
__asm__("movl 0(%%esi), %0 \n\t"
|
|
|
|
"movl 4(%%esi), %1 \n\t"
|
|
|
|
"addl %0, 0(%%edi) \n\t"
|
|
|
|
"adcl %1, 4(%%edi) \n\t"
|
|
|
|
: "=&r" (dummy1), "=&r" (dummy2)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "D" (c), "S" (a)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "memory", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = ConvertToLongLong(c);
|
|
|
|
__int64 aa = ConvertToLongLong(a);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
cc += aa;
|
|
|
|
|
|
|
|
ConvertFromLongLong(c, &cc);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* SUB */
|
|
|
|
|
|
|
|
void SUB_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,a
|
|
|
|
mov edi,b
|
|
|
|
mov ebx,c
|
|
|
|
mov eax,[esi]
|
|
|
|
mov edx,[esi+4]
|
|
|
|
sub eax,[edi]
|
|
|
|
sbb edx,[edi+4]
|
|
|
|
mov [ebx],eax
|
|
|
|
mov [ebx+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
int dummy1, dummy2;
|
|
|
|
__asm__("movl 0(%%esi), %0 \n\t"
|
|
|
|
"movl 4(%%esi), %1 \n\t"
|
|
|
|
"subl 0(%%edi), %0 \n\t"
|
|
|
|
"sbbl 4(%%edi), %1 \n\t"
|
|
|
|
"movl %0, 0(%%ebx) \n\t"
|
|
|
|
"movl %1, 4(%%ebx) \n\t"
|
|
|
|
: "=&r" (dummy1), "=&r" (dummy2)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "S" (a), "D" (b), "b" (c)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "memory", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = ConvertToLongLong(a);
|
|
|
|
__int64 bb = ConvertToLongLong(b);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = aa - bb;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
ConvertFromLongLong(c, &cc);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* SUB -- */
|
|
|
|
|
|
|
|
void SUB_LL_MM(LONGLONGCH *c, LONGLONGCH *a)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov edi,c
|
|
|
|
mov esi,a
|
|
|
|
mov eax,[esi]
|
|
|
|
mov edx,[esi+4]
|
|
|
|
sub [edi],eax
|
|
|
|
sbb [edi+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
int dummy1, dummy2;
|
|
|
|
__asm__("movl 0(%%esi), %0 \n\t"
|
|
|
|
"movl 4(%%esi), %1 \n\t"
|
|
|
|
"subl %0, 0(%%edi) \n\t"
|
|
|
|
"sbbl %1, 4(%%edi) \n\t"
|
|
|
|
: "=&r" (dummy1), "=&r" (dummy2)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "D" (c), "S" (a)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "memory", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = ConvertToLongLong(c);
|
|
|
|
__int64 aa = ConvertToLongLong(a);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
cc -= aa;
|
|
|
|
|
|
|
|
ConvertFromLongLong(c, &cc);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
MUL
|
|
|
|
|
|
|
|
This is the multiply we use, the 32 x 32 = 64 widening version
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void MUL_I_WIDE(int a, int b, LONGLONGCH *c)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov eax,a
|
|
|
|
mov ebx,c
|
|
|
|
imul b
|
|
|
|
mov [ebx],eax
|
|
|
|
mov [ebx+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
unsigned int d1;
|
|
|
|
__asm__("imull %3 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"movl %%eax, 0(%%ebx) \n\t"
|
|
|
|
"movl %%edx, 4(%%ebx) \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
: "=a" (d1)
|
|
|
|
: "0" (a), "b" (c), "m" (b)
|
|
|
|
: "%edx", "memory", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = (__int64) a;
|
|
|
|
__int64 bb = (__int64) b;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = aa * bb;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
ConvertFromLongLong(c, &cc);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
CMP
|
|
|
|
|
|
|
|
This substitutes for ==, >, <, >=, <=
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int CMP_LL(LONGLONGCH *a, LONGLONGCH *b)
|
|
|
|
{
|
|
|
|
/*
|
2001-08-15 20:09:25 +00:00
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov ebx,a
|
|
|
|
mov ecx,b
|
|
|
|
mov eax,[ebx]
|
|
|
|
mov edx,[ebx+4]
|
|
|
|
sub eax,[ecx]
|
|
|
|
sbb edx,[ecx+4]
|
|
|
|
and edx,edx
|
|
|
|
jne llnz
|
|
|
|
and eax,eax
|
|
|
|
je llgs
|
|
|
|
llnz:
|
|
|
|
mov retval,1
|
|
|
|
and edx,edx
|
|
|
|
jge llgs
|
|
|
|
neg retval
|
|
|
|
llgs:
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2003-05-21 03:38:50 +00:00
|
|
|
int retval;
|
|
|
|
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("movl 0(%%ebx), %%eax \n\t"
|
|
|
|
"movl 4(%%ebx), %%edx \n\t"
|
|
|
|
"subl 0(%%ecx), %%eax \n\t"
|
|
|
|
"sbbl 4(%%ecx), %%edx \n\t"
|
2001-08-08 22:42:43 +00:00
|
|
|
"xorl %%ebx, %%ebx \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"andl %%edx, %%edx \n\t"
|
2003-05-21 03:38:50 +00:00
|
|
|
"jne 0f \n\t" /* llnz */
|
2001-08-08 06:14:20 +00:00
|
|
|
"andl %%eax, %%eax \n\t"
|
2003-05-21 03:38:50 +00:00
|
|
|
"je 1f \n" /* llgs */
|
2001-08-08 06:14:20 +00:00
|
|
|
"0: \n\t" /* llnz */
|
2001-08-08 22:42:43 +00:00
|
|
|
"movl $1, %%ebx \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"andl %%edx, %%edx \n\t"
|
2003-05-21 03:38:50 +00:00
|
|
|
"jge 1f \n\t" /* llgs */
|
2001-08-08 22:42:43 +00:00
|
|
|
"negl %%ebx \n"
|
2001-08-08 06:14:20 +00:00
|
|
|
"1: \n\t" /* llgs */
|
2001-08-08 22:42:43 +00:00
|
|
|
: "=b" (retval)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "b" (a), "c" (b)
|
|
|
|
: "%eax", "%edx", "memory", "cc"
|
|
|
|
);
|
|
|
|
|
|
|
|
return retval;
|
2001-08-15 20:09:25 +00:00
|
|
|
#else
|
|
|
|
if (a->hi32 > b->hi32)
|
|
|
|
return 1;
|
|
|
|
else if (a->hi32 < b->hi32)
|
|
|
|
return -1;
|
|
|
|
else if (a->lo32 > b->lo32)
|
|
|
|
return 1;
|
|
|
|
else if (a->lo32 < b->lo32)
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EQUALS */
|
|
|
|
|
|
|
|
void EQUALS_LL(LONGLONGCH *a, LONGLONGCH *b)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov edi,a
|
|
|
|
mov esi,b
|
|
|
|
mov eax,[esi]
|
|
|
|
mov edx,[esi+4]
|
|
|
|
mov [edi],eax
|
|
|
|
mov [edi+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("movl 0(%%esi), %%eax \n\t"
|
|
|
|
"movl 4(%%esi), %%edx \n\t"
|
|
|
|
"movl %%eax, 0(%%edi) \n\t"
|
|
|
|
"movl %%edx, 4(%%edi) \n\t"
|
|
|
|
:
|
|
|
|
: "D" (a), "S" (b)
|
|
|
|
: "%eax", "%edx", "memory"
|
|
|
|
);
|
2001-08-15 20:09:25 +00:00
|
|
|
#else
|
|
|
|
*a = *b;
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* NEGATE */
|
|
|
|
|
|
|
|
void NEG_LL(LONGLONGCH *a)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,a
|
|
|
|
not dword ptr[esi]
|
|
|
|
not dword ptr[esi+4]
|
|
|
|
add dword ptr[esi],1
|
|
|
|
adc dword ptr[esi+4],0
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("notl 0(%%esi) \n\t"
|
|
|
|
"notl 4(%%esi) \n\t"
|
|
|
|
"addl $1, 0(%%esi) \n\t"
|
|
|
|
"adcl $0, 4(%%esi) \n\t"
|
|
|
|
:
|
|
|
|
: "S" (a)
|
|
|
|
: "memory", "cc"
|
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = ConvertToLongLong(a);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
aa = -aa;
|
|
|
|
|
|
|
|
ConvertFromLongLong(a, &aa);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ASR */
|
|
|
|
|
|
|
|
void ASR_LL(LONGLONGCH *a, int shift)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,a
|
|
|
|
mov eax,shift
|
|
|
|
and eax,eax
|
|
|
|
jle asrdn
|
|
|
|
asrlp:
|
|
|
|
sar dword ptr[esi+4],1
|
|
|
|
rcr dword ptr[esi],1
|
|
|
|
dec eax
|
|
|
|
jne asrlp
|
|
|
|
asrdn:
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2002-09-07 00:26:23 +00:00
|
|
|
unsigned int d1;
|
|
|
|
__asm__ volatile
|
|
|
|
("andl %0, %0 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"jle 0 \n" /* asrdn */
|
|
|
|
"1: \n\t" /* asrlp */
|
|
|
|
"sarl $1, 4(%%esi) \n\t"
|
|
|
|
"rcrl $1, 0(%%esi) \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
"decl %0 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"jne 1 \n"
|
|
|
|
"0: \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
: "=&r" (d1)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "S" (a), "a" (shift)
|
|
|
|
: "memory", "cc"
|
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = ConvertToLongLong(a);
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
aa >>= shift;
|
2001-08-08 06:14:20 +00:00
|
|
|
|
2008-04-26 00:39:44 -07:00
|
|
|
ConvertFromLongLong(a, &aa);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert int to LONGLONGCH */
|
|
|
|
|
|
|
|
void IntToLL(LONGLONGCH *a, int *b)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,b
|
|
|
|
mov edi,a
|
|
|
|
mov eax,[esi]
|
|
|
|
cdq
|
|
|
|
mov [edi],eax
|
|
|
|
mov [edi+4],edx
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("movl 0(%%esi), %%eax \n\t"
|
|
|
|
"cdq \n\t"
|
|
|
|
"movl %%eax, 0(%%edi) \n\t"
|
|
|
|
"movl %%edx, 4(%%edi) \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
:
|
2001-08-08 06:14:20 +00:00
|
|
|
: "S" (b), "D" (a)
|
|
|
|
: "%eax", "%edx", "memory", "cc"
|
|
|
|
);
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = (__int64) *b;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
ConvertFromLongLong(a, &aa);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
2015-02-14 12:00:00 +01:00
|
|
|
//
|
|
|
|
// Fixed Point Multiply - MUL_FIXED
|
|
|
|
// See mathline.h
|
|
|
|
//
|
2001-08-08 06:14:20 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Fixed Point Divide - returns a / b
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int DIV_FIXED(int a, int b)
|
|
|
|
{
|
2002-09-07 00:26:23 +00:00
|
|
|
if (b == 0) printf("DEBUG THIS: a = %d, b = %d\n", a, b);
|
2001-08-12 02:30:17 +00:00
|
|
|
|
|
|
|
if (b == 0) return 0; /* TODO: debug this! (start with alien on ferarco) */
|
2001-08-08 06:14:20 +00:00
|
|
|
/*
|
2008-04-26 00:39:44 -07:00
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov eax,a
|
|
|
|
cdq
|
|
|
|
rol eax,16
|
|
|
|
mov dx,ax
|
|
|
|
xor ax,ax
|
|
|
|
idiv b
|
|
|
|
mov retval,eax
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("cdq \n\t"
|
|
|
|
"roll $16, %%eax \n\t"
|
|
|
|
"mov %%ax, %%dx \n\t"
|
|
|
|
"xor %%ax, %%ax \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
"idivl %2 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
: "=a" (retval)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "0" (a), "m" (b)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "%edx", "cc"
|
|
|
|
);
|
|
|
|
return retval;
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
{
|
|
|
|
__int64 aa = (__int64) a;
|
|
|
|
__int64 bb = (__int64) b;
|
|
|
|
__int64 cc = (aa << 16) / bb;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
return (int) (cc & 0xffffffff);
|
2008-05-06 22:57:13 -07:00
|
|
|
}
|
2008-04-26 00:39:44 -07:00
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Multiply and Divide Functions.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
A Narrowing 64/32 Division
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int NarrowDivide(LONGLONGCH *a, int b)
|
|
|
|
{
|
|
|
|
/*
|
2008-04-26 00:39:44 -07:00
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov esi,a
|
|
|
|
mov eax,[esi]
|
|
|
|
mov edx,[esi+4]
|
|
|
|
idiv b
|
|
|
|
mov retval,eax
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
__asm__("movl 0(%%esi), %%eax \n\t"
|
|
|
|
"movl 4(%%esi), %%edx \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
"idivl %2 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
: "=a" (retval)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "S" (a), "m" (b)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "%edx", "cc"
|
|
|
|
);
|
|
|
|
return retval;
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = ConvertToLongLong(a);
|
|
|
|
__int64 bb = (__int64) b;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 cc = aa / bb;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
return (int) (cc & 0xffffffff);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
This function performs a Widening Multiply followed by a Narrowing Divide.
|
|
|
|
|
|
|
|
a = (a * b) / c
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int WideMulNarrowDiv(int a, int b, int c)
|
|
|
|
{
|
|
|
|
/*
|
2008-04-26 00:39:44 -07:00
|
|
|
int retval;
|
2001-08-08 06:14:20 +00:00
|
|
|
_asm
|
|
|
|
{
|
|
|
|
mov eax,a
|
|
|
|
imul b
|
|
|
|
idiv c
|
|
|
|
mov retval,eax
|
|
|
|
}
|
|
|
|
*/
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
|
|
|
int retval;
|
2002-09-07 00:26:23 +00:00
|
|
|
__asm__("imull %2 \n\t"
|
|
|
|
"idivl %3 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
: "=a" (retval)
|
2002-09-07 00:26:23 +00:00
|
|
|
: "0" (a), "m" (b), "m" (c)
|
2001-08-24 05:19:50 +00:00
|
|
|
: "%edx", "cc"
|
2001-08-08 06:14:20 +00:00
|
|
|
);
|
|
|
|
return retval;
|
2008-04-26 00:39:44 -07:00
|
|
|
#else
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 aa = (__int64) a;
|
|
|
|
__int64 bb = (__int64) b;
|
|
|
|
__int64 cc = (__int64) c;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
2008-05-06 22:57:13 -07:00
|
|
|
__int64 dd = (aa * bb) / cc;
|
2008-04-26 00:39:44 -07:00
|
|
|
|
|
|
|
return (int) (dd & 0xffffffff);
|
|
|
|
#endif
|
2001-08-08 06:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Square Root
|
|
|
|
|
|
|
|
Returns the Square Root of a 32-bit number
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int SqRoot32(int A)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
_asm
|
|
|
|
{
|
|
|
|
finit
|
|
|
|
fild A
|
|
|
|
fsqrt
|
|
|
|
fistp temp2
|
|
|
|
fwait
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2008-04-26 00:39:44 -07:00
|
|
|
#if defined(ASM386)
|
|
|
|
static volatile int sqrt_temp;
|
2002-09-07 00:26:23 +00:00
|
|
|
__asm__ volatile
|
|
|
|
("finit \n\t"
|
|
|
|
"fildl %0 \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"fsqrt \n\t"
|
2002-09-07 00:26:23 +00:00
|
|
|
"fistpl sqrt_temp \n\t"
|
2001-08-08 06:14:20 +00:00
|
|
|
"fwait \n\t"
|
|
|
|
:
|
2002-09-07 00:26:23 +00:00
|
|
|
: "m" (A)
|
2001-08-08 06:14:20 +00:00
|
|
|
: "memory", "cc"
|
|
|
|
);
|
|
|
|
|
2002-09-07 00:26:23 +00:00
|
|
|
return sqrt_temp;
|
2007-01-12 08:19:57 +00:00
|
|
|
#else
|
2015-02-14 12:00:00 +01:00
|
|
|
float fA = A;
|
|
|
|
return lrintf(sqrtf(fA));
|
2001-08-09 06:23:42 +00:00
|
|
|
#endif
|
|
|
|
}
|