/* ------------------------------------------------------------------------- */ /* */ /* Copyright (c) 2003 The Open Group */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining a */ /* copy of this software (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, copy, */ /* modify, merge, publish, distribute, sublicense, and/or sell copies of */ /* the Software, and to permit persons to whom the Software is furnished */ /* to do so, subject to the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be included */ /* in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS */ /* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT */ /* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR */ /* THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* */ /* ------------------------------------------------------------------------- */ /* */ /* File revision information */ /* */ /* $Source: /tang_cvs/arm4/sdk4/c/include/arm4os.h,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2004/03/04 09:24:49 $ */ /* */ /* ------------------------------------------------------------------------- */ /* arm4os.h - ARM4 SDK operating system and compiler specific header file */ /* */ /* The arm4os.h header file hides OS and compiler specifics from the */ /* actual ARM4 interface found in the arm4.h header file. It is meant to */ /* facilitate the adaption of additional compiler/os combinations. */ /* */ /* Currently, the following platform/compiler combinations are supported and */ /* tested: */ /* */ /* Platform Compiler */ /* ------------------------------------------------------------------------- */ /* Linux 2.4.x (x86) gcc (2.95, 3.3) GNU C/C++ Compiler */ /* Linux 2.4.x (ppc) gcc (2.95, 3.2) GNU C/C++ Compiler */ /* Linux 2.4.x (x86) icc (7.0) Intel C++ Compiler */ /* Solaris 8 (sparc) cc (5.3) Sun WorkShop 6 C Compiler */ /* Solaris 8 (sparc) CC (5.3) Sun WorkShop 6 C++ Compiler */ /* Solaris 8 (sparc) gcc (2.95) GNU C/C++ Compiler */ /* OSF1 V5.0 Tru64 (alpha) cc (6.1) Compaq C Compiler */ /* OSF1 V5.0 Tru64 (alpha) gcc (2.95) GNU C/C++ Compiler */ /* Windows 2000 (x86) MSVC (6.0) Microsoft VisualC++ */ /* */ /* The following mechanisms are implemented in this header file: */ /* */ /* 1. Determine the native compiler type for 8, 16, 32 and 64 bit integers. */ /* Macros: ARM4_INT8, ARM4_UINT8, ARM4_INT16, ARM4_UINT16, ARM4_INT32, */ /* ARM4_UINT32, ARM4_INT64, ARM_UINT64 and ARM4_CHAR. */ /* 2. Special handling for exporting function symbols to support different */ /* shared library scenarios. Set-up of specific function calling */ /* conventions. */ /* Macros: ARM4_API_CALL, ARM4_API_CALLVA, ARM4_API_DYNAMIC */ /* 3. Determine compiler inlining support, if any, and setting of the */ /* appropriate keyword for the compier used. */ /* Macros: ARM4_INLINE */ /* ------------------------------------------------------------------------- */ #ifndef ARM4OS_H_INCLUDED #define ARM4OS_H_INCLUDED /* ------------------------------------------------------------------------- */ /* Consolidate known OS platform identifiers first. */ /* ------------------------------------------------------------------------- */ #if defined(WIN32) || defined(__WIN32__) #if !defined(_WIN32) #define _WIN32 #endif #endif #if defined(WIN64) || defined(__WIN64__) #if !defined(_WIN64) #define _WIN64 #endif #endif /* ------------------------------------------------------------------------- */ /* ------------- Step 1: determine 32 and 64 bit integer types ------------- */ /* ------------------ (compiler/target platform dependent) ----------------- */ /* ------------------------------------------------------------------------- */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L /* C99 standard defines all types required for us. */ #ifdef __cplusplus #include #else #include #endif #define ARM4_CHAR char #define ARM4_INT8 int8_t #define ARM4_INT16 int16_t #define ARM4_INT32 int32_t #define ARM4_INT64 int64_t #define ARM4_UINT8 uint8_t #define ARM4_UINT16 uint16_t #define ARM4_UINT32 uint32_t #define ARM4_UINT64 uint64_t #else /* Needed to find out appropriate int32 and int64 types, limit.h is an */ /* ANSI-C header file. Thus any ANSI-C compliant compiler works. */ #ifdef __cplusplus #include #else #include #endif /* set-up arm_int32_t type */ #if INT_MAX == 2147483647l #define ARM4_INT32 int #elif LONG_MAX == 2147483647l #define ARM4_INT32 long #else #error "can't determine 32bit integer type" #endif /* INT_MAX == 2147483647l */ #ifndef ARM4_UINT32 #define ARM4_UINT32 unsigned ARM4_INT32 #endif /* !ARM4_UINT32 */ /* now find appropriate 64 bit integer type */ #ifndef ARM4_INT64 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__WATCOMC__) /* MSVC and compatible compiler native 64 bit types */ #define ARM4_INT64 __int64 #elif (defined(LLONG_MAX) && LLONG_MAX > 2147483647l) || \ (defined(LONGLONG_MAX) && LONGLONG_MAX > 2147483647l) /* LLONG_MAX and LONGLONG_MAX indicate usage of long long 64 bit types */ #define ARM4_INT64 long long #elif (defined(__GNUC__) && \ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))) /* GNU supports long long. To be safe just use current V 2.95 or V3.x */ /* Older versions have to be checked first! */ #define ARM4_INT64 long long #elif defined(__INTEL_COMPILER) /* INTEL C compiler for Windows/Linux supports long long. */ #define ARM4_INT64 long long #elif defined(__hpux) /* hpux uses *int64_t */ #define ARM4_INT64 int64_t #define ARM4_UINT64 uint64_t #elif LONG_MAX > 2147483647l /* on 64-bit systems the normal long type could actually be a 64-bit type */ #define ARM4_INT64 long #else /* Raise a compile-time error if unsure. Note that assuming "long long" */ /* for int64 might get past the compilation but may cause run-time problems */ /* if it is not exactly 64-bit. */ #error "can't determine 64bit integer type" #endif /* _MSC_VER ... */ #endif /* ARM4_INT64 */ /* if ARM4_UINT64 isn't set, use ARM4_INT64 combined with unsigned keyword. */ #ifndef ARM4_UINT64 #define ARM4_UINT64 unsigned ARM4_INT64 #endif /* !ARM4_UINT64 */ /* define standard character and integer defintions if not set previously. */ #ifndef ARM4_CHAR #define ARM4_CHAR char #endif #ifndef ARM4_INT8 #define ARM4_INT8 signed char #endif #ifndef ARM4_UINT8 #define ARM4_UINT8 unsigned char #endif #ifndef ARM4_INT16 #define ARM4_INT16 signed short #endif #ifndef ARM4_UINT16 #define ARM4_UINT16 unsigned short #endif #endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L */ #if defined(_WIN32) || defined(_WIN64) #define ARM4_LLCONST(x) ((arm_int64_t) (x)) #define ARM4_ULLCONST(x) ((arm_uint64_t) (x)) #else #define ARM4_LLCONST(x) x##ll #define ARM4_ULLCONST(x) x##ull #endif /* ------------------------------------------------------------------------- */ /* ---------------------- Step 2: API function export ---------------------- */ /* ------------------ (compiler/target platform dependent) ----------------- */ /* ------------------------------------------------------------------------- */ /* Each OS platform needs to define the API calling convention for itself, */ /* and make sure the proper compiler keywords are used. */ /* ARM4_API_CALL is for API calls with fixed # of parameters, while */ /* ARM4_API_VACALL is for API calls with variable # of parameters. */ #if defined(_WIN32) || defined(_WIN64) /* For 32-bit and 64-bit Windows, "stdcall" (pascal) calling convention is */ /* explicitly chosen for ARM4_API_CALL to save a few instructions per call. */ #if defined(__GNUC__) #define ARM4_API_CALL __attribute__((stdcall)) #define ARM4_API_VACALL __attribute__((cdecl)) #else /* If a compiler does not support __stdcall or __cdecl, it will generate */ /* compile time errors when encountering these modifiers. Most compilers, */ /* e.g. _MSC_VER, __WATCOMC__, __BORLANDC__ and __MWERKS__ do support both. */ /* __INTEL_COMPILER knows both, too. */ #define ARM4_API_CALL __stdcall #define ARM4_API_VACALL __cdecl #endif #endif /* _WIN32 || _WIN64 */ #if defined(linux) #if defined(__GNUC__) #if defined(__i386__) #define ARM4_API_CALL __attribute__((stdcall)) #define ARM4_API_VACALL __attribute__((cdecl)) #endif #elif !defined(__INTEL_COMPILER) /* On linux the intel compiler doesn't support __stdcall !?!*/ #define ARM4_API_CALL __stdcall #define ARM4_API_VACALL __cdecl #endif #endif /* linux */ /* For other OS platforms, the compiler's default calling convention is used */ /* and, hopefully, this won't cause link-time or run-time problems. */ #if !defined(ARM4_API_CALL) #define ARM4_API_CALL #define ARM4_API_VACALL #endif /* Set up the ARM4_API_DYNAMIC definition here so the ARM library can be */ /* built correctly as a shared library or DLL. Note the return type of the */ /* API call must be specified as an argument to this macro because MSVC */ /* needs the __declspec() before and __stdcall keyword after the return type.*/ /* */ /* Note that dllexport and dllimport are needed only for _WIN32 or _WIN64. */ /* It is recommended that ARM agent providers for Windows explicitly use an */ /* libarm4.def to spell out the exact name of the exports, such that */ /* applications can do a GetProcAddress() without problems. Note that in the */ /* case of a compiler not supporting __declspec(), compile time errors are */ /* to be expected. */ #if !(defined(_WIN32) || defined(_WIN64)) || defined(ARM4_NODLL) #define ARM4_API_DYNAMIC(type) extern type ARM4_API_CALL #elif defined(__GNUC__) #if defined(ARM4_BUILD_DLL) #define ARM4_API_DYNAMIC(type) __attribute__((dllexport)) type ARM4_API_CALL #else #define ARM4_API_DYNAMIC(type) __attribute__((dllimport)) type ARM4_API_CALL #endif #else #if defined(ARM4_BUILD_DLL) #define ARM4_API_DYNAMIC(type) __declspec(dllexport) type ARM4_API_CALL #else #define ARM4_API_DYNAMIC(type) __declspec(dllimport) type ARM4_API_CALL #endif /* __GNUC__ */ #endif /* !defined(_WIN32) || ... */ #define ARM4_API_STATIC(type) type ARM4_API_CALL #define ARM4_API_VASTATIC(type) type ARM4_API_VACALL /* ------------------------------------------------------------------------- */ /* ------------------------ Step 3: inlining support ----------------------- */ /* ---------------------------- (compiler dependent) ----------------------- */ /* ------------------------------------------------------------------------- */ /* determine correct inline keyword */ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L) || \ defined(__cplusplus) /* C99 C compliant and C++ compilers use the inline keyword */ #define ARM4_INLINE inline #elif defined(__GNUC__) /* GNU C supports inlining */ #if __GNUC__ > 2 #define ARM4_INLINE static __attribute__((always_inline)) __inline__ #else #define ARM4_INLINE static __inline__ #endif #elif defined(_MSC_VER) /* MSVC supports inlining */ #define ARM4_INLINE __inline #elif defined(__INTEL_COMPILER) /* INTEL compiler can take both inline or __inline */ #define ARM4_INLINE __inline #elif defined(__DECC) /* Compaq C V6.1 cc compiler can take __inline */ #define ARM4_INLINE __inline /* any other compiler specific inline support should be */ /* placed here. */ #else /* not sure if the current compiler supports inlining, so */ /* use the default keyword. Compile time errors will result */ /* if the compiler does not support the default keyword. */ #define ARM4_INLINE inline #endif /* (defined(__STD_VERSION__) && ... */ /* ------------------------------------------------------------------------- */ #endif /* !ARM4OS_H_INCLUDED */