-
Notifications
You must be signed in to change notification settings - Fork 0
/
M_FIXED.H
89 lines (76 loc) · 2.06 KB
/
M_FIXED.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Fixed point arithemtics, implementation.
#ifndef __M_FIXED__
#define __M_FIXED__
#include "doomtype.h"
//
// Fixed point, 32bit as 16.16.
//
#define FRACBITS 16
#define FRACUNIT (1<<FRACBITS)
typedef int fixed_t;
#define FIXED_TO_FLOAT(x) (((float)x) / 65536.0)
//
// Declare those functions:
/*
fixed_t FixedMul (fixed_t a, fixed_t b);
fixed_t FixedDiv (fixed_t a, fixed_t b);
fixed_t FixedDiv2 (fixed_t a, fixed_t b);
*/
#ifdef __WIN32__
//Microsoft VisualC++
fixed_t __cdecl FixedMul (fixed_t a, fixed_t b);
//fixed_t FixedDiv (fixed_t a, fixed_t b);
fixed_t __cdecl FixedDiv2 (fixed_t a, fixed_t b);
#else
#ifdef __WATCOMC__
#pragma aux FixedMul = \
"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]
#else
//DJGPP
static inline fixed_t FixedMul (fixed_t a, fixed_t b) //asm
{
fixed_t ret;
asm (
"imull %%edx \n"
"shrdl $16, %%edx,%%eax \n"
: "=a" (ret)
: "a" (a), "d" (b)
: "%edx" );
return ret;
}
static inline fixed_t FixedDiv2 (fixed_t a, fixed_t b)
{
fixed_t ret;
asm (
"movl %%eax,%%edx \n" // these two instructions allow the next
"sarl $31,%%edx \n" // two to pair, on the Pentium processor.
"shldl $16,%%eax,%%edx \n"
"sall $16,%%eax \n"
"idivl %%ecx \n"
: "=a" (ret)
: "a" (a), "c" (b)
: "%edx" );
return ret;
}
#endif
#endif
static inline fixed_t FixedDiv (fixed_t a, fixed_t b)
{
//I_Error("<a: %ld, b: %ld>",(long)a,(long)b);
if ( (abs(a)>>14) >= abs(b))
return (a^b)<0 ? MININT : MAXINT;
return FixedDiv2 (a,b);
}
#endif //m_fixed.h