1 /*****************************************************************************
2 *
3 * XVID MPEG-4 VIDEO CODEC
4 * - Portable macros, types and inlined assembly -
5 *
6 * Copyright(C) 2002-2010 Michael Militzer <isibaar@xvid.org>
7 * 2002-2003 Peter Ross <pross@xvid.org>
8 * 2002-2003 Edouard Gomez <ed.gomez@free.fr>
9 *
10 * This program is free software ; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation ; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY ; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program ; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * $Id: portab.h 2145 2016-10-18 22:01:13Z Isibaar $
25 *
26 ****************************************************************************/
27
28 #ifndef _PORTAB_H_
29 #define _PORTAB_H_
30
31 /*****************************************************************************
32 * Common things
33 ****************************************************************************/
34
35 /* Buffer size for msvc implementation because it outputs to DebugOutput */
36 #if defined(_DEBUG)
37 extern unsigned int xvid_debug;
38 #define DPRINTF_BUF_SZ 1024
39 #endif
40
41 /*****************************************************************************
42 * Types used in Xvid sources
43 ****************************************************************************/
44
45 /*----------------------------------------------------------------------------
46 | For MSVC
47 *---------------------------------------------------------------------------*/
48
49 #if defined(_MSC_VER) || defined (__WATCOMC__)
50 # define int8_t char
51 # define uint8_t unsigned char
52 # define int16_t short
53 # define uint16_t unsigned short
54 # define int32_t int
55 # define uint32_t unsigned int
56 # define int64_t __int64
57 # define uint64_t unsigned __int64
58
59 /*----------------------------------------------------------------------------
60 | For all other compilers, use the standard header file
61 | (compiler should be ISO C99 compatible, perhaps ISO C89 is enough)
62 *---------------------------------------------------------------------------*/
63
64 #else
65
66 # include <inttypes.h>
67
68 #endif
69
70 /*****************************************************************************
71 * Some things that are OS dependant
72 ****************************************************************************/
73
74 #ifdef WIN32
75
76 # include <windows.h>
77 # define pthread_t HANDLE
78 # define pthread_create(t,u,f,d) *(t)=CreateThread(NULL,0,f,d,0,NULL)
79 # define pthread_join(t,s) { WaitForSingleObject(t,INFINITE); \
80 CloseHandle(t); }
81 # define sched_yield() Sleep(0);
pthread_num_processors_np()82 static __inline int pthread_num_processors_np()
83 {
84 DWORD p_aff, s_aff, r = 0;
85 GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR) &p_aff, (PDWORD_PTR) &s_aff);
86 for(; p_aff != 0; p_aff>>=1) r += p_aff&1;
87 return r;
88 }
89
90 #elif defined(__amigaos4__)
91
92 # include <pthread.h>
93 # include <proto/exec.h>
94
amiga_yield(void)95 static __inline void amiga_yield(void)
96 {
97 /* SetTaskPri() on the currently running task triggers a reschedule */
98 struct Task *me = IExec->FindTask(NULL);
99 IExec->SetTaskPri(me, me->tc_Node.ln_Pri);
100 }
101 # define sched_yield() amiga_yield()
102
103 #elif defined(SYS_BEOS)
104
105 # include <kernel/OS.h>
106 # define pthread_t thread_id
107 # define pthread_create(t,u,f,d) { *(t)=spawn_thread(f,"",10,d); \
108 resume_thread(*(t)); }
109 # define pthread_join(t,s) wait_for_thread(t,(long*)s)
110 # define sched_yield() snooze(0) /* is this correct? */
111
112 #else
113 # include <pthread.h>
114 #endif
115
116 /*****************************************************************************
117 * Some things that are only architecture dependant
118 ****************************************************************************/
119
120 #if defined(ARCH_IS_32BIT)
121 # define CACHE_LINE 64
122 # define ptr_t uint32_t
123 # define intptr_t int32_t
124 # define _INTPTR_T_DEFINED
125 # if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
126 # include <stdarg.h>
127 # else
128 # define uintptr_t uint32_t
129 # endif
130 #elif defined(ARCH_IS_64BIT)
131 # define CACHE_LINE 64
132 # define ptr_t uint64_t
133 # define intptr_t int64_t
134 # define _INTPTR_T_DEFINED
135 # if defined (_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
136 # include <stdarg.h>
137 # else
138 # define uintptr_t uint64_t
139 # endif
140 #else
141 # error You are trying to compile Xvid without defining address bus size.
142 #endif
143
144 /*****************************************************************************
145 * Things that must be sorted by compiler and then by architecture
146 ****************************************************************************/
147
148 /*****************************************************************************
149 * MSVC compiler specific macros, functions
150 ****************************************************************************/
151
152 #if defined(_MSC_VER)
153
154 /*----------------------------------------------------------------------------
155 | Common msvc stuff
156 *---------------------------------------------------------------------------*/
157
158 # include <windows.h>
159 # include <stdio.h>
160
161 /* Non ANSI mapping */
162 # define snprintf _snprintf
163 # define vsnprintf _vsnprintf
164
165 /*
166 * This function must be declared/defined all the time because MSVC does
167 * not support C99 variable arguments macros.
168 *
169 * Btw, if the MS compiler does its job well, it should remove the nop
170 * DPRINTF function when not compiling in _DEBUG mode
171 */
172 # ifdef _DEBUG
DPRINTF(int level,char * fmt,...)173 static __inline void DPRINTF(int level, char *fmt, ...)
174 {
175 if (xvid_debug & level) {
176 va_list args;
177 char buf[DPRINTF_BUF_SZ];
178 va_start(args, fmt);
179 vsprintf(buf, fmt, args);
180 va_end(args);
181 OutputDebugStringA(buf);
182 fprintf(stderr, "%s", buf);
183 }
184 }
185 # else
DPRINTF(int level,char * fmt,...)186 static __inline void DPRINTF(int level, char *fmt, ...) {}
187 # endif
188
189 # if _MSC_VER <= 1200
190 # define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \
191 type name##_storage[(sizex)*(sizey)+(alignment)-1]; \
192 type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1))
193 # else
194 # define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \
195 __declspec(align(alignment)) type name[(sizex)*(sizey)]
196 # endif
197
198
199 /*----------------------------------------------------------------------------
200 | msvc x86 specific macros/functions
201 *---------------------------------------------------------------------------*/
202 # if defined(ARCH_IS_IA32)
203 # define BSWAP(a) __asm mov eax,a __asm bswap eax __asm mov a, eax
204
read_counter(void)205 static __inline int64_t read_counter(void)
206 {
207 int64_t ts;
208 uint32_t ts1, ts2;
209 __asm {
210 rdtsc
211 mov ts1, eax
212 mov ts2, edx
213 }
214 ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1);
215 return ts;
216 }
217
218 # elif defined(ARCH_IS_X86_64)
219
220 # include <intrin.h>
221
222 # define BSWAP(a) ((a) = _byteswap_ulong(a))
223
read_counter(void)224 static __inline int64_t read_counter(void) { return __rdtsc(); }
225
226 /*----------------------------------------------------------------------------
227 | msvc GENERIC (plain C only) - Probably alpha or some embedded device
228 *---------------------------------------------------------------------------*/
229 # elif defined(ARCH_IS_GENERIC)
230 # define BSWAP(a) \
231 ((a) = (((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | \
232 (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
233
234 # include <time.h>
read_counter(void)235 static __inline int64_t read_counter(void)
236 {
237 return (int64_t)clock();
238 }
239
240 /*----------------------------------------------------------------------------
241 | msvc Not given architecture - This is probably an user who tries to build
242 | Xvid the wrong way.
243 *---------------------------------------------------------------------------*/
244 # else
245 # error You are trying to compile Xvid without defining the architecture type.
246 # endif
247
248
249
250
251 /*****************************************************************************
252 * GNU CC compiler stuff
253 ****************************************************************************/
254
255 #elif defined(__GNUC__) || defined(__ICC) /* Compiler test */
256
257 /*----------------------------------------------------------------------------
258 | Common gcc stuff
259 *---------------------------------------------------------------------------*/
260
261 /*
262 * As gcc is (mostly) C99 compliant, we define DPRINTF only if it's realy needed
263 * and it's a macro calling fprintf directly
264 */
265 # ifdef _DEBUG
266
267 /* Needed for all debuf fprintf calls */
268 # include <stdio.h>
269 # include <stdarg.h>
270
DPRINTF(int level,char * format,...)271 static __inline void DPRINTF(int level, char *format, ...)
272 {
273 va_list args;
274 va_start(args, format);
275 if(xvid_debug & level) {
276 vfprintf(stderr, format, args);
277 }
278 va_end(args);
279 }
280
281 # else /* _DEBUG */
DPRINTF(int level,char * format,...)282 static __inline void DPRINTF(int level, char *format, ...) {}
283 # endif /* _DEBUG */
284
285
286 # define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \
287 type name##_storage[(sizex)*(sizey)+(alignment)-1]; \
288 type * name = (type *) (((ptr_t) name##_storage+(alignment - 1)) & ~((ptr_t)(alignment)-1))
289
290 /*----------------------------------------------------------------------------
291 | gcc IA32 specific macros/functions
292 *---------------------------------------------------------------------------*/
293 # if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
294 # define BSWAP(a) __asm__ ( "bswapl %0\n" : "=r" (a) : "0" (a) );
295
read_counter(void)296 static __inline int64_t read_counter(void)
297 {
298 int64_t ts;
299 uint32_t ts1, ts2;
300 __asm__ __volatile__("rdtsc\n\t":"=a"(ts1), "=d"(ts2));
301 ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1);
302 return ts;
303 }
304
305 /*----------------------------------------------------------------------------
306 | gcc PPC and PPC Altivec specific macros/functions
307 *---------------------------------------------------------------------------*/
308 # elif defined(ARCH_IS_PPC)
309
310 # if defined(HAVE_ALTIVEC_PARENTHESES_DECL)
311 # define AVV(x...) (x)
312 # elif defined(HAVE_ALTIVEC_BRACES_DECL)
313 # define AVV(x...) {x}
314 # else
315 # error Trying to compile PPC target without a vector declaration type.
316 # endif
317
318 # define BSWAP(a) __asm__ __volatile__ \
319 ( "lwbrx %0,0,%1; eieio" : "=r" (a) : "r" (&(a)), "m" (a));
320
get_tbl(void)321 static __inline unsigned long get_tbl(void)
322 {
323 unsigned long tbl;
324 asm volatile ("mftb %0":"=r" (tbl));
325 return tbl;
326 }
327
get_tbu(void)328 static __inline unsigned long get_tbu(void)
329 {
330 unsigned long tbl;
331 asm volatile ("mftbu %0":"=r" (tbl));
332 return tbl;
333 }
334
read_counter(void)335 static __inline int64_t read_counter(void)
336 {
337 unsigned long tb, tu;
338 do {
339 tu = get_tbu();
340 tb = get_tbl();
341 }while (tb != get_tbl());
342 return (((int64_t) tu) << 32) | (int64_t) tb;
343 }
344
345 /*----------------------------------------------------------------------------
346 | gcc IA64 specific macros/functions
347 *---------------------------------------------------------------------------*/
348 # elif defined(ARCH_IS_IA64)
349 # define BSWAP(a) __asm__ __volatile__ \
350 ("mux1 %0 = %1, @rev" ";;" \
351 "shr.u %0 = %0, 32" : "=r" (a) : "r" (a));
352
read_counter(void)353 static __inline int64_t read_counter(void)
354 {
355 unsigned long result;
356 __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
357 return result;
358 }
359
360 /*----------------------------------------------------------------------------
361 | gcc GENERIC (plain C only) specific macros/functions
362 *---------------------------------------------------------------------------*/
363 # elif defined(ARCH_IS_GENERIC)
364 # define BSWAP(a) \
365 ((a) = (((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | \
366 (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
367
368 # include <time.h>
read_counter(void)369 static __inline int64_t read_counter(void)
370 {
371 return (int64_t)clock();
372 }
373
374 /*----------------------------------------------------------------------------
375 | gcc Not given architecture - This is probably an user who tries to build
376 | Xvid the wrong way.
377 *---------------------------------------------------------------------------*/
378 # else
379 # error You are trying to compile Xvid without defining the architecture type.
380 # endif
381
382
383
384
385 /*****************************************************************************
386 * Open WATCOM C/C++ compiler
387 ****************************************************************************/
388
389 #elif defined(__WATCOMC__)
390
391 # include <stdio.h>
392 # include <stdarg.h>
393
394 # ifdef _DEBUG
DPRINTF(int level,char * fmt,...)395 static __inline void DPRINTF(int level, char *fmt, ...)
396 {
397 if (xvid_debug & level) {
398 va_list args;
399 char buf[DPRINTF_BUF_SZ];
400 va_start(args, fmt);
401 vsprintf(buf, fmt, args);
402 va_end(args);
403 fprintf(stderr, "%s", buf);
404 }
405 }
406 # else /* _DEBUG */
DPRINTF(int level,char * format,...)407 static __inline void DPRINTF(int level, char *format, ...) {}
408 # endif /* _DEBUG */
409
410 # define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \
411 type name##_storage[(sizex)*(sizey)+(alignment)-1]; \
412 type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1))
413
414 /*----------------------------------------------------------------------------
415 | watcom ia32 specific macros/functions
416 *---------------------------------------------------------------------------*/
417 # if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
418
419 # define BSWAP(a) __asm mov eax,a __asm bswap eax __asm mov a, eax
420
read_counter(void)421 static __inline int64_t read_counter(void)
422 {
423 uint64_t ts;
424 uint32_t ts1, ts2;
425 __asm {
426 rdtsc
427 mov ts1, eax
428 mov ts2, edx
429 }
430 ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1);
431 return ts;
432 }
433
434 /*----------------------------------------------------------------------------
435 | watcom GENERIC (plain C only) specific macros/functions.
436 *---------------------------------------------------------------------------*/
437 # elif defined(ARCH_IS_GENERIC)
438
439 # define BSWAP(x) \
440 x = ((((x) & 0xff000000) >> 24) | \
441 (((x) & 0x00ff0000) >> 8) | \
442 (((x) & 0x0000ff00) << 8) | \
443 (((x) & 0x000000ff) << 24))
444
read_counter()445 static int64_t read_counter() { return 0; }
446
447 /*----------------------------------------------------------------------------
448 | watcom Not given architecture - This is probably an user who tries to build
449 | Xvid the wrong way.
450 *---------------------------------------------------------------------------*/
451 # else
452 # error You are trying to compile Xvid without defining the architecture type.
453 # endif
454
455
456 /*****************************************************************************
457 * Unknown compiler
458 ****************************************************************************/
459 #else /* Compiler test */
460
461 /*
462 * Ok we know nothing about the compiler, so we fallback to ANSI C
463 * features, so every compiler should be happy and compile the code.
464 *
465 * This is (mostly) equivalent to ARCH_IS_GENERIC.
466 */
467
468 # ifdef _DEBUG
469
470 /* Needed for all debuf fprintf calls */
471 # include <stdio.h>
472 # include <stdarg.h>
473
DPRINTF(int level,char * format,...)474 static __inline void DPRINTF(int level, char *format, ...)
475 {
476 va_list args;
477 va_start(args, format);
478 if(xvid_debug & level) {
479 vfprintf(stderr, format, args);
480 }
481 va_end(args);
482 }
483
484 # else /* _DEBUG */
DPRINTF(int level,char * format,...)485 static __inline void DPRINTF(int level, char *format, ...) {}
486 # endif /* _DEBUG */
487
488 # define BSWAP(a) \
489 ((a) = (((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | \
490 (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
491
492 # include <time.h>
read_counter(void)493 static __inline int64_t read_counter(void)
494 {
495 return (int64_t)clock();
496 }
497
498 # define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \
499 type name[(sizex)*(sizey)]
500
501 #endif /* Compiler test */
502
503
504 #endif /* PORTAB_H */
505