1 /* OpenCP Module Player
2  * copyright (c) '94-'98 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3  *
4  * DOS4GFIX initialisation handlers
5  *
6  * revision history: (please note changes here)
7  *  -nb980510   Niklas Beisert <nbeisert@physik.tu-muenchen.de>
8  *    -first release
9  *  -kb98????   Tammo Hinrichs <opencp@gmx.net>                 (?)
10  *    -some bugfix(?)
11  *  -fd981205   Felix Domke <tmbinc@gmx.net>
12  *    -KB's "bugfix" doesn't work with Watcom106
13  *  -ss040613   Stian Skjelstad <stian@nixia.no>
14  *    -Redone to use gcc assembler inline and posix libc
15  *  -ss040908   Stian Skjelstad <stian@nixia.no>
16  *    -Made the assembler inlines optimize-safe
17  */
18 
19 #ifndef IMSRTNS__H
20 #define IMSRTNS__H
21 
22 /* Assembler optimization per cpu we can wait with.... */
23 
24 #define memsetb(dst, what, len) memset(dst, what, len*1) /* let the compiler handle this */
25 #define memcpyb(dst, src, len) memcpy(dst, src, len) /* let the compiler handle this */
26 #define memcpyf(dst, src, len) memcpy(dst, src, len*sizeof(float)) /* let the compiler handle this.. even this one... not even used yet */
27 #define memmovel(dst, src, n) memmove(dst, src, (n)*4)
28 
29 #ifdef I386_ASM
30 
imuldiv(int32_t a,int32_t b,int32_t c)31 static inline int32_t imuldiv(int32_t a,int32_t b,int32_t c)
32 {
33 #ifdef __PIC__
34 	int d0, d1;
35 	register int32_t retval;
36 	__asm__ __volatile__(
37 		"pushl %%ebx\n"
38 		"movl %%ecx, %%ebx\n"
39 		"imul %%edx\n"
40 		"idiv %%ebx\n"
41 		"popl %%ebx\n"
42 		:"=a"(retval), "=&d"(d0), "=&c"(d1)
43 		:"0"(a), "1"(b), "2"(c)
44 	);
45 	return retval;
46 #else
47 	int d0, d1;
48 	register int32_t retval;
49 	__asm__ __volatile__(
50 		"imul %%edx\n"
51 		"idiv %%ebx\n"
52 		:"=a"(retval), "=&d"(d0), "=&b"(d1)
53 		:"0"(a), "1"(b), "2"(c)
54 	);
55 	return retval;
56 #endif
57 }
58 
umuldiv(uint32_t a,uint32_t b,uint32_t c)59 static inline uint32_t umuldiv(uint32_t a,uint32_t b,uint32_t c)
60 {
61 #ifdef __PIC__
62 	int d0, d1;
63 	register uint32_t retval;
64 	__asm__ __volatile__
65 	(
66 		"pushl %%ebx\n"
67 		"movl %%ecx, %%ebx\n"
68 		"mul %%edx\n"
69 		"div %%ebx\n"
70 		"popl %%ebx\n"
71 		:"=a"(retval), "=&d"(d0), "=&c"(d1)
72 		:"0"(a), "1"(b), "2"(c)
73 	);
74 	return retval;
75 #else
76 	int d0, d1;
77 	register uint32_t retval;
78 	__asm__ __volatile__
79 	(
80 		"mul %%edx\n"
81 		"div %%ebx\n"
82 		:"=a"(retval), "=&d"(d0), "=&b"(d1)
83 		:"0"(a), "1"(b), "2"(c)
84 	);
85 	return retval;
86 #endif
87 }
88 
imulshr16(int32_t a,int32_t b)89 static inline int32_t imulshr16(int32_t a,int32_t b)
90 {
91 	int d0;
92 	register int32_t retval;
93 	__asm__ __volatile__
94 	(
95 		"imul %%edx\n"
96 		"shrd $16,%%edx,%%eax\n"
97 		:"=a"(retval), "=&d"(d0)
98 		:"0"(a), "1"(b)
99 	);
100 	return retval;
101 }
102 
umulshr16(uint32_t a,uint32_t b)103 static inline uint32_t umulshr16(uint32_t a,uint32_t b)
104 {
105 	int d0;
106 	register uint32_t retval;
107 	__asm__ __volatile__
108 	(
109 		"mul %%edx\n"
110 		"shrd $16,%%edx,%%eax\n"
111 		:"=a"(retval), "=&d"(d0)
112 		:"0"(a), "1"(b)
113 	);
114 	return retval;
115 }
116 
umldivrnd(uint32_t a,uint32_t b,uint32_t c)117 static inline uint32_t umldivrnd(uint32_t a,uint32_t b,uint32_t c)
118 {
119 	int d0, d1;
120 	register uint32_t retval;
121 	__asm__ __volatile__
122 	(
123 		"mul %%edx\n"
124 		"movl %%ecx,%%ebx\n"
125 		"shrl $1,%%ebx\n"
126 		"addl %%ebx,%%eax\n"
127 		"adc $0,%%edx\n"
128 		"div %%ecx\n"
129 		:"=a"(retval), "=&d"(d0), "=&c"(d1)
130 		:"0"(a), "1"(b), "2"(c)
131 		:"ebx"
132 	);
133 	return retval;
134 }
135 
memsetd(void * dst,uint32_t what,uint32_t len)136 static inline void memsetd(void *dst, uint32_t what, uint32_t len)
137 {
138 	int d0, d1, d2;
139 	__asm__ __volatile__
140 	(
141 		"rep stosl\n"
142 		: "=&D"(d0), "=&a"(d1), "=&c"(d2)
143 		: "0" (dst), "1" (what), "2" (len)
144 		: "memory"
145 	);
146 }
147 
memsetw(void * dst,uint16_t what,uint32_t len)148 static inline void memsetw(void *dst, uint16_t what, uint32_t len)
149 {
150 	short d1;
151 	int d0, d2;
152 	__asm__ __volatile__
153 	(
154 		"rep stosw\n"
155 		: "=&D"(d0), "=&a"(d1), "=&c"(d2)
156 		: "0" (dst), "1" (what), "2" (len)
157 		: "memory"
158 	);
159 }
160 
161 #else
162 
imuldiv(int32_t a,int32_t b,int32_t c)163 static inline int32_t imuldiv(int32_t a,int32_t b,int32_t c)
164 {
165 	int64_t temp = (int64_t)a*(int64_t)b;
166 	return temp/c;
167 }
168 
umuldiv(uint32_t a,uint32_t b,uint32_t c)169 static inline uint32_t umuldiv(uint32_t a,uint32_t b,uint32_t c)
170 {
171 	uint64_t temp = (uint64_t)a*(uint64_t)b;
172 	return temp/c;
173 }
174 
imulshr16(int32_t a,int32_t b)175 static inline int32_t imulshr16(int32_t a,int32_t b)
176 {
177 	int64_t temp = (int64_t)a*(int64_t)b;
178 	return temp>>16;
179 }
180 
umulshr16(uint32_t a,uint32_t b)181 static inline uint32_t umulshr16(uint32_t a,uint32_t b)
182 {
183 	uint64_t temp = (uint64_t)a*(uint64_t)b;
184 	return temp>>16;
185 }
186 
187 #define umldivrnd(mul1, mul2, divby) umuldiv(mul1, mul2, divby) /* dirty */
188 
189 #define memsetd(dst, what, len) {int i;uint32_t *tmp_dst=(uint32_t *)(dst);for(i=(len);i;i--)*tmp_dst++=(uint32_t)(what);} while(0)
190 #define memsetw(dst, what, len) {int i;uint16_t *tmp_dst=(uint16_t *)(dst);for(i=(len);i;i--)*tmp_dst++=(uint16_t)(what);} while(0)
191 
192 #endif
193 
194 
195 #endif
196