mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-12-21 02:10:39 +00:00
Remove FixedMul and FixedDiv2 asm implementations
Actually works this time
This commit is contained in:
parent
923e6f31aa
commit
4424f6ba9a
2 changed files with 22 additions and 158 deletions
|
@ -21,50 +21,6 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
|
|
||||||
#ifdef __USE_C_FIXEDMUL__
|
|
||||||
|
|
||||||
/** \brief The FixedMul function
|
|
||||||
|
|
||||||
\param a fixed_t number
|
|
||||||
\param b fixed_t number
|
|
||||||
|
|
||||||
\return a*b>>FRACBITS
|
|
||||||
|
|
||||||
*/
|
|
||||||
fixed_t FixedMul(fixed_t a, fixed_t b)
|
|
||||||
{
|
|
||||||
// Need to cast to unsigned before shifting to avoid undefined behaviour
|
|
||||||
// for negative integers
|
|
||||||
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //__USE_C_FIXEDMUL__
|
|
||||||
|
|
||||||
#ifdef __USE_C_FIXEDDIV__
|
|
||||||
/** \brief The FixedDiv2 function
|
|
||||||
|
|
||||||
\param a fixed_t number
|
|
||||||
\param b fixed_t number
|
|
||||||
|
|
||||||
\return a/b * FRACUNIT
|
|
||||||
|
|
||||||
*/
|
|
||||||
fixed_t FixedDiv2(fixed_t a, fixed_t b)
|
|
||||||
{
|
|
||||||
INT64 ret;
|
|
||||||
|
|
||||||
if (b == 0)
|
|
||||||
I_Error("FixedDiv: divide by zero");
|
|
||||||
|
|
||||||
ret = (((INT64)a * FRACUNIT)) / b;
|
|
||||||
|
|
||||||
if ((ret > INT32_MAX) || (ret < INT32_MIN))
|
|
||||||
I_Error("FixedDiv: divide by zero");
|
|
||||||
return (fixed_t)ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __USE_C_FIXEDDIV__
|
|
||||||
|
|
||||||
fixed_t FixedSqrt(fixed_t x)
|
fixed_t FixedSqrt(fixed_t x)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SQRT
|
#ifdef HAVE_SQRT
|
||||||
|
|
136
src/m_fixed.h
136
src/m_fixed.h
|
@ -53,127 +53,35 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
|
||||||
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
|
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
|
||||||
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
|
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
|
||||||
|
|
||||||
|
/** \brief The FixedMul function
|
||||||
|
|
||||||
#if defined (__WATCOMC__) && FRACBITS == 16
|
\param a fixed_t number
|
||||||
#pragma aux FixedMul = \
|
\param b fixed_t number
|
||||||
"imul ebx", \
|
|
||||||
"shrd eax,edx,16" \
|
|
||||||
parm [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax edx]
|
|
||||||
|
|
||||||
#pragma aux FixedDiv2 = \
|
\return a*b>>FRACBITS
|
||||||
"cdq", \
|
|
||||||
"shld edx,eax,16", \
|
|
||||||
"sal eax,16", \
|
|
||||||
"idiv ebx" \
|
|
||||||
parm [eax] [ebx] \
|
|
||||||
value [eax] \
|
|
||||||
modify exact [eax edx]
|
|
||||||
#elif defined (__GNUC__) && defined (__i386__) && !defined (NOASM)
|
|
||||||
// i386 linux, cygwin or mingw
|
|
||||||
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
|
|
||||||
{
|
|
||||||
fixed_t ret;
|
|
||||||
asm
|
|
||||||
(
|
|
||||||
"imull %2;" // a*b
|
|
||||||
"shrdl %3,%%edx,%0;" // shift logical right FRACBITS bits
|
|
||||||
:"=a" (ret) // eax is always the result and the first operand (%0,%1)
|
|
||||||
:"0" (a), "r" (b) // and %2 is what we use imull on with what in %1
|
|
||||||
, "I" (FRACBITS) // %3 holds FRACBITS (normally 16)
|
|
||||||
:"cc", "%edx" // edx and condition codes clobbered
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNCMATH FUNCINLINE static inline fixed_t FixedDiv2(fixed_t a, fixed_t b)
|
*/
|
||||||
{
|
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedMul(fixed_t a, fixed_t b)
|
||||||
fixed_t ret;
|
{
|
||||||
asm
|
// Need to cast to unsigned before shifting to avoid undefined behaviour
|
||||||
(
|
// for negative integers
|
||||||
"movl %1,%%edx;" // these two instructions allow the next two to pair, on the Pentium processor.
|
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
|
||||||
"sarl $31,%%edx;" // shift arithmetic right 31 on EDX
|
}
|
||||||
"shldl %3,%1,%%edx;" // DP shift logical left FRACBITS on EDX
|
|
||||||
"sall %3,%0;" // shift arithmetic left FRACBITS on EAX
|
|
||||||
"idivl %2;" // EDX/b = EAX
|
|
||||||
: "=a" (ret)
|
|
||||||
: "0" (a), "r" (b)
|
|
||||||
, "I" (FRACBITS)
|
|
||||||
: "%edx"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#elif defined (__GNUC__) && defined (__arm__) && !defined(__thumb__) && !defined(NOASM) //ARMv4 ASM
|
|
||||||
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // let abuse smull
|
|
||||||
{
|
|
||||||
fixed_t ret;
|
|
||||||
asm
|
|
||||||
(
|
|
||||||
"smull %[lo], r1, %[a], %[b];"
|
|
||||||
"mov %[lo], %[lo], lsr %3;"
|
|
||||||
"orr %[lo], %[lo], r1, lsl %3;"
|
|
||||||
: [lo] "=&r" (ret) // rhi, rlo and rm must be distinct registers
|
|
||||||
: [a] "r" (a), [b] "r" (b)
|
|
||||||
, "i" (FRACBITS)
|
|
||||||
: "r1"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __USE_C_FIXEDDIV__ // no double or asm div in ARM land
|
/** \brief The FixedDiv2 function
|
||||||
#elif defined (__GNUC__) && defined (__ppc__) && !defined(NOASM) && 0 // WII: PPC CPU
|
|
||||||
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
|
|
||||||
{
|
|
||||||
fixed_t ret, hi, lo;
|
|
||||||
asm
|
|
||||||
(
|
|
||||||
"mullw %0, %2, %3;"
|
|
||||||
"mulhw %1, %2, %3"
|
|
||||||
: "=r" (hi), "=r" (lo)
|
|
||||||
: "r" (a), "r" (b)
|
|
||||||
, "I" (FRACBITS)
|
|
||||||
);
|
|
||||||
ret = (INT64)((hi>>FRACBITS)+lo)<<FRACBITS;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __USE_C_FIXEDDIV__// Alam: I am lazy
|
\param a fixed_t number
|
||||||
#elif defined (__GNUC__) && defined (__mips__) && !defined(NOASM) && 0 // PSP: MIPS CPU
|
\param b fixed_t number
|
||||||
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
|
|
||||||
{
|
|
||||||
fixed_t ret;
|
|
||||||
asm
|
|
||||||
(
|
|
||||||
"mult %3, %4;" // a*b=h<32+l
|
|
||||||
: "=r" (ret), "=l" (a), "=h" (b) //todo: abuse shr opcode
|
|
||||||
: "0" (a), "r" (b)
|
|
||||||
, "I" (FRACBITS)
|
|
||||||
//: "+l", "+h"
|
|
||||||
);
|
|
||||||
ret = (INT64)((a>>FRACBITS)+b)<<FRACBITS;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __USE_C_FIXEDDIV__ // no 64b asm div in MIPS land
|
\return a/b * FRACUNIT
|
||||||
#elif defined (__GNUC__) && defined (__sh__) && 0 // DC: SH4 CPU
|
|
||||||
#elif defined (__GNUC__) && defined (__m68k__) && 0 // DEAD: Motorola 6800 CPU
|
|
||||||
#elif defined (_MSC_VER) && defined(USEASM) && FRACBITS == 16
|
|
||||||
// Microsoft Visual C++ (no asm inline)
|
|
||||||
fixed_t __cdecl FixedMul(fixed_t a, fixed_t b);
|
|
||||||
fixed_t __cdecl FixedDiv2(fixed_t a, fixed_t b);
|
|
||||||
#else
|
|
||||||
#define __USE_C_FIXEDMUL__
|
|
||||||
#define __USE_C_FIXEDDIV__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __USE_C_FIXEDMUL__
|
*/
|
||||||
FUNCMATH fixed_t FixedMul(fixed_t a, fixed_t b);
|
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv2(fixed_t a, fixed_t b)
|
||||||
#endif
|
{
|
||||||
|
// This does not check for division overflow or division by 0!
|
||||||
#ifdef __USE_C_FIXEDDIV__
|
// That is the caller's responsibility.
|
||||||
FUNCMATH fixed_t FixedDiv2(fixed_t a, fixed_t b);
|
return (fixed_t)(((INT64)a * FRACUNIT) / b);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
/** \brief The FixedInt function
|
/** \brief The FixedInt function
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue