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