Skip to content
Snippets Groups Projects
Commit 4424f6ba authored by tertu marybig's avatar tertu marybig
Browse files

Remove FixedMul and FixedDiv2 asm implementations

Actually works this time
parent 923e6f31
No related branches found
No related tags found
2 merge requests!2074Kill ASM,!1632Remove FixedMul and FixedDiv2 asm implementations
...@@ -21,50 +21,6 @@ ...@@ -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
......
...@@ -53,127 +53,35 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f) ...@@ -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 = \
"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) \return a*b>>FRACBITS
{
fixed_t ret;
asm
(
"movl %1,%%edx;" // these two instructions allow the next two to pair, on the Pentium processor.
"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 */
#elif defined (__GNUC__) && defined (__ppc__) && !defined(NOASM) && 0 // WII: PPC CPU FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedMul(fixed_t a, fixed_t b)
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
{ {
fixed_t ret, hi, lo; // Need to cast to unsigned before shifting to avoid undefined behaviour
asm // for negative integers
( return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
"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 /** \brief The FixedDiv2 function
#elif defined (__GNUC__) && defined (__mips__) && !defined(NOASM) && 0 // PSP: MIPS CPU
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 \param a fixed_t number
#elif defined (__GNUC__) && defined (__sh__) && 0 // DC: SH4 CPU \param b fixed_t number
#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__ \return a/b * FRACUNIT
FUNCMATH fixed_t FixedMul(fixed_t a, fixed_t b);
#endif
#ifdef __USE_C_FIXEDDIV__ */
FUNCMATH fixed_t FixedDiv2(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!
// That is the caller's responsibility.
return (fixed_t)(((INT64)a * FRACUNIT) / b);
}
/** \brief The FixedInt function /** \brief The FixedInt function
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment