| 1 | /* ------------------------------------------------------------------------- */ |
|---|
| 2 | /* */ |
|---|
| 3 | /* Copyright (c) 2003 The Open Group */ |
|---|
| 4 | /* */ |
|---|
| 5 | /* Permission is hereby granted, free of charge, to any person obtaining a */ |
|---|
| 6 | /* copy of this software (the "Software"), to deal in the Software without */ |
|---|
| 7 | /* restriction, including without limitation the rights to use, copy, */ |
|---|
| 8 | /* modify, merge, publish, distribute, sublicense, and/or sell copies of */ |
|---|
| 9 | /* the Software, and to permit persons to whom the Software is furnished */ |
|---|
| 10 | /* to do so, subject to the following conditions: */ |
|---|
| 11 | /* */ |
|---|
| 12 | /* The above copyright notice and this permission notice shall be included */ |
|---|
| 13 | /* in all copies or substantial portions of the Software. */ |
|---|
| 14 | /* */ |
|---|
| 15 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS */ |
|---|
| 16 | /* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
|---|
| 17 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
|---|
| 18 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
|---|
| 19 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT */ |
|---|
| 20 | /* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR */ |
|---|
| 21 | /* THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|---|
| 22 | /* */ |
|---|
| 23 | /* ------------------------------------------------------------------------- */ |
|---|
| 24 | /* */ |
|---|
| 25 | /* File revision information */ |
|---|
| 26 | /* */ |
|---|
| 27 | /* $Source: /tang_cvs/arm4/sdk4/c/include/arm4os.h,v $ */ |
|---|
| 28 | /* $Revision: 1.4 $ */ |
|---|
| 29 | /* $Date: 2004/03/04 09:24:49 $ */ |
|---|
| 30 | /* */ |
|---|
| 31 | /* ------------------------------------------------------------------------- */ |
|---|
| 32 | /* arm4os.h - ARM4 SDK operating system and compiler specific header file */ |
|---|
| 33 | /* */ |
|---|
| 34 | /* The arm4os.h header file hides OS and compiler specifics from the */ |
|---|
| 35 | /* actual ARM4 interface found in the arm4.h header file. It is meant to */ |
|---|
| 36 | /* facilitate the adaption of additional compiler/os combinations. */ |
|---|
| 37 | /* */ |
|---|
| 38 | /* Currently, the following platform/compiler combinations are supported and */ |
|---|
| 39 | /* tested: */ |
|---|
| 40 | /* */ |
|---|
| 41 | /* Platform Compiler */ |
|---|
| 42 | /* ------------------------------------------------------------------------- */ |
|---|
| 43 | /* Linux 2.4.x (x86) gcc (2.95, 3.3) GNU C/C++ Compiler */ |
|---|
| 44 | /* Linux 2.4.x (ppc) gcc (2.95, 3.2) GNU C/C++ Compiler */ |
|---|
| 45 | /* Linux 2.4.x (x86) icc (7.0) Intel C++ Compiler */ |
|---|
| 46 | /* Solaris 8 (sparc) cc (5.3) Sun WorkShop 6 C Compiler */ |
|---|
| 47 | /* Solaris 8 (sparc) CC (5.3) Sun WorkShop 6 C++ Compiler */ |
|---|
| 48 | /* Solaris 8 (sparc) gcc (2.95) GNU C/C++ Compiler */ |
|---|
| 49 | /* OSF1 V5.0 Tru64 (alpha) cc (6.1) Compaq C Compiler */ |
|---|
| 50 | /* OSF1 V5.0 Tru64 (alpha) gcc (2.95) GNU C/C++ Compiler */ |
|---|
| 51 | /* Windows 2000 (x86) MSVC (6.0) Microsoft VisualC++ */ |
|---|
| 52 | /* */ |
|---|
| 53 | /* The following mechanisms are implemented in this header file: */ |
|---|
| 54 | /* */ |
|---|
| 55 | /* 1. Determine the native compiler type for 8, 16, 32 and 64 bit integers. */ |
|---|
| 56 | /* Macros: ARM4_INT8, ARM4_UINT8, ARM4_INT16, ARM4_UINT16, ARM4_INT32, */ |
|---|
| 57 | /* ARM4_UINT32, ARM4_INT64, ARM_UINT64 and ARM4_CHAR. */ |
|---|
| 58 | /* 2. Special handling for exporting function symbols to support different */ |
|---|
| 59 | /* shared library scenarios. Set-up of specific function calling */ |
|---|
| 60 | /* conventions. */ |
|---|
| 61 | /* Macros: ARM4_API_CALL, ARM4_API_CALLVA, ARM4_API_DYNAMIC */ |
|---|
| 62 | /* 3. Determine compiler inlining support, if any, and setting of the */ |
|---|
| 63 | /* appropriate keyword for the compier used. */ |
|---|
| 64 | /* Macros: ARM4_INLINE */ |
|---|
| 65 | /* ------------------------------------------------------------------------- */ |
|---|
| 66 | |
|---|
| 67 | #ifndef ARM4OS_H_INCLUDED |
|---|
| 68 | #define ARM4OS_H_INCLUDED |
|---|
| 69 | |
|---|
| 70 | /* ------------------------------------------------------------------------- */ |
|---|
| 71 | /* Consolidate known OS platform identifiers first. */ |
|---|
| 72 | /* ------------------------------------------------------------------------- */ |
|---|
| 73 | |
|---|
| 74 | #if defined(WIN32) || defined(__WIN32__) |
|---|
| 75 | #if !defined(_WIN32) |
|---|
| 76 | #define _WIN32 |
|---|
| 77 | #endif |
|---|
| 78 | #endif |
|---|
| 79 | |
|---|
| 80 | #if defined(WIN64) || defined(__WIN64__) |
|---|
| 81 | #if !defined(_WIN64) |
|---|
| 82 | #define _WIN64 |
|---|
| 83 | #endif |
|---|
| 84 | #endif |
|---|
| 85 | |
|---|
| 86 | /* ------------------------------------------------------------------------- */ |
|---|
| 87 | /* ------------- Step 1: determine 32 and 64 bit integer types ------------- */ |
|---|
| 88 | /* ------------------ (compiler/target platform dependent) ----------------- */ |
|---|
| 89 | /* ------------------------------------------------------------------------- */ |
|---|
| 90 | |
|---|
| 91 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L |
|---|
| 92 | |
|---|
| 93 | /* C99 standard defines all types required for us. */ |
|---|
| 94 | #ifdef __cplusplus |
|---|
| 95 | #include <cstdint> |
|---|
| 96 | #else |
|---|
| 97 | #include <stdint.h> |
|---|
| 98 | #endif |
|---|
| 99 | |
|---|
| 100 | #define ARM4_CHAR char |
|---|
| 101 | |
|---|
| 102 | #define ARM4_INT8 int8_t |
|---|
| 103 | #define ARM4_INT16 int16_t |
|---|
| 104 | #define ARM4_INT32 int32_t |
|---|
| 105 | #define ARM4_INT64 int64_t |
|---|
| 106 | |
|---|
| 107 | #define ARM4_UINT8 uint8_t |
|---|
| 108 | #define ARM4_UINT16 uint16_t |
|---|
| 109 | #define ARM4_UINT32 uint32_t |
|---|
| 110 | #define ARM4_UINT64 uint64_t |
|---|
| 111 | |
|---|
| 112 | #else |
|---|
| 113 | |
|---|
| 114 | /* Needed to find out appropriate int32 and int64 types, limit.h is an */ |
|---|
| 115 | /* ANSI-C header file. Thus any ANSI-C compliant compiler works. */ |
|---|
| 116 | #ifdef __cplusplus |
|---|
| 117 | #include <climits> |
|---|
| 118 | #else |
|---|
| 119 | #include <limits.h> |
|---|
| 120 | #endif |
|---|
| 121 | |
|---|
| 122 | /* set-up arm_int32_t type */ |
|---|
| 123 | #if INT_MAX == 2147483647l |
|---|
| 124 | #define ARM4_INT32 int |
|---|
| 125 | #elif LONG_MAX == 2147483647l |
|---|
| 126 | #define ARM4_INT32 long |
|---|
| 127 | #else |
|---|
| 128 | #error "can't determine 32bit integer type" |
|---|
| 129 | #endif /* INT_MAX == 2147483647l */ |
|---|
| 130 | |
|---|
| 131 | #ifndef ARM4_UINT32 |
|---|
| 132 | #define ARM4_UINT32 unsigned ARM4_INT32 |
|---|
| 133 | #endif /* !ARM4_UINT32 */ |
|---|
| 134 | |
|---|
| 135 | /* now find appropriate 64 bit integer type */ |
|---|
| 136 | #ifndef ARM4_INT64 |
|---|
| 137 | |
|---|
| 138 | #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__WATCOMC__) |
|---|
| 139 | /* MSVC and compatible compiler native 64 bit types */ |
|---|
| 140 | #define ARM4_INT64 __int64 |
|---|
| 141 | |
|---|
| 142 | #elif (defined(LLONG_MAX) && LLONG_MAX > 2147483647l) || \ |
|---|
| 143 | (defined(LONGLONG_MAX) && LONGLONG_MAX > 2147483647l) |
|---|
| 144 | /* LLONG_MAX and LONGLONG_MAX indicate usage of long long 64 bit types */ |
|---|
| 145 | #define ARM4_INT64 long long |
|---|
| 146 | |
|---|
| 147 | #elif (defined(__GNUC__) && \ |
|---|
| 148 | (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))) |
|---|
| 149 | /* GNU supports long long. To be safe just use current V 2.95 or V3.x */ |
|---|
| 150 | /* Older versions have to be checked first! */ |
|---|
| 151 | #define ARM4_INT64 long long |
|---|
| 152 | |
|---|
| 153 | #elif defined(__INTEL_COMPILER) |
|---|
| 154 | /* INTEL C compiler for Windows/Linux supports long long. */ |
|---|
| 155 | #define ARM4_INT64 long long |
|---|
| 156 | |
|---|
| 157 | #elif defined(__hpux) |
|---|
| 158 | /* hpux uses *int64_t */ |
|---|
| 159 | #define ARM4_INT64 int64_t |
|---|
| 160 | #define ARM4_UINT64 uint64_t |
|---|
| 161 | |
|---|
| 162 | #elif LONG_MAX > 2147483647l |
|---|
| 163 | /* on 64-bit systems the normal long type could actually be a 64-bit type */ |
|---|
| 164 | #define ARM4_INT64 long |
|---|
| 165 | |
|---|
| 166 | #else |
|---|
| 167 | /* Raise a compile-time error if unsure. Note that assuming "long long" */ |
|---|
| 168 | /* for int64 might get past the compilation but may cause run-time problems */ |
|---|
| 169 | /* if it is not exactly 64-bit. */ |
|---|
| 170 | #error "can't determine 64bit integer type" |
|---|
| 171 | |
|---|
| 172 | #endif /* _MSC_VER ... */ |
|---|
| 173 | #endif /* ARM4_INT64 */ |
|---|
| 174 | |
|---|
| 175 | /* if ARM4_UINT64 isn't set, use ARM4_INT64 combined with unsigned keyword. */ |
|---|
| 176 | #ifndef ARM4_UINT64 |
|---|
| 177 | #define ARM4_UINT64 unsigned ARM4_INT64 |
|---|
| 178 | #endif /* !ARM4_UINT64 */ |
|---|
| 179 | |
|---|
| 180 | |
|---|
| 181 | /* define standard character and integer defintions if not set previously. */ |
|---|
| 182 | #ifndef ARM4_CHAR |
|---|
| 183 | #define ARM4_CHAR char |
|---|
| 184 | #endif |
|---|
| 185 | |
|---|
| 186 | #ifndef ARM4_INT8 |
|---|
| 187 | #define ARM4_INT8 signed char |
|---|
| 188 | #endif |
|---|
| 189 | |
|---|
| 190 | #ifndef ARM4_UINT8 |
|---|
| 191 | #define ARM4_UINT8 unsigned char |
|---|
| 192 | #endif |
|---|
| 193 | |
|---|
| 194 | #ifndef ARM4_INT16 |
|---|
| 195 | #define ARM4_INT16 signed short |
|---|
| 196 | #endif |
|---|
| 197 | |
|---|
| 198 | #ifndef ARM4_UINT16 |
|---|
| 199 | #define ARM4_UINT16 unsigned short |
|---|
| 200 | #endif |
|---|
| 201 | |
|---|
| 202 | #endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L */ |
|---|
| 203 | |
|---|
| 204 | #if defined(_WIN32) || defined(_WIN64) |
|---|
| 205 | #define ARM4_LLCONST(x) ((arm_int64_t) (x)) |
|---|
| 206 | #define ARM4_ULLCONST(x) ((arm_uint64_t) (x)) |
|---|
| 207 | #else |
|---|
| 208 | #define ARM4_LLCONST(x) x##ll |
|---|
| 209 | #define ARM4_ULLCONST(x) x##ull |
|---|
| 210 | #endif |
|---|
| 211 | |
|---|
| 212 | /* ------------------------------------------------------------------------- */ |
|---|
| 213 | /* ---------------------- Step 2: API function export ---------------------- */ |
|---|
| 214 | /* ------------------ (compiler/target platform dependent) ----------------- */ |
|---|
| 215 | /* ------------------------------------------------------------------------- */ |
|---|
| 216 | |
|---|
| 217 | /* Each OS platform needs to define the API calling convention for itself, */ |
|---|
| 218 | /* and make sure the proper compiler keywords are used. */ |
|---|
| 219 | /* ARM4_API_CALL is for API calls with fixed # of parameters, while */ |
|---|
| 220 | /* ARM4_API_VACALL is for API calls with variable # of parameters. */ |
|---|
| 221 | |
|---|
| 222 | #if defined(_WIN32) || defined(_WIN64) |
|---|
| 223 | /* For 32-bit and 64-bit Windows, "stdcall" (pascal) calling convention is */ |
|---|
| 224 | /* explicitly chosen for ARM4_API_CALL to save a few instructions per call. */ |
|---|
| 225 | #if defined(__GNUC__) |
|---|
| 226 | #define ARM4_API_CALL __attribute__((stdcall)) |
|---|
| 227 | #define ARM4_API_VACALL __attribute__((cdecl)) |
|---|
| 228 | #else |
|---|
| 229 | /* If a compiler does not support __stdcall or __cdecl, it will generate */ |
|---|
| 230 | /* compile time errors when encountering these modifiers. Most compilers, */ |
|---|
| 231 | /* e.g. _MSC_VER, __WATCOMC__, __BORLANDC__ and __MWERKS__ do support both. */ |
|---|
| 232 | /* __INTEL_COMPILER knows both, too. */ |
|---|
| 233 | #define ARM4_API_CALL __stdcall |
|---|
| 234 | #define ARM4_API_VACALL __cdecl |
|---|
| 235 | #endif |
|---|
| 236 | #endif /* _WIN32 || _WIN64 */ |
|---|
| 237 | |
|---|
| 238 | #if defined(linux) |
|---|
| 239 | |
|---|
| 240 | #if defined(__GNUC__) |
|---|
| 241 | |
|---|
| 242 | #if defined(__i386__) |
|---|
| 243 | #define ARM4_API_CALL __attribute__((stdcall)) |
|---|
| 244 | #define ARM4_API_VACALL __attribute__((cdecl)) |
|---|
| 245 | #endif |
|---|
| 246 | |
|---|
| 247 | #elif !defined(__INTEL_COMPILER) |
|---|
| 248 | /* On linux the intel compiler doesn't support __stdcall !?!*/ |
|---|
| 249 | #define ARM4_API_CALL __stdcall |
|---|
| 250 | #define ARM4_API_VACALL __cdecl |
|---|
| 251 | |
|---|
| 252 | #endif |
|---|
| 253 | #endif /* linux */ |
|---|
| 254 | |
|---|
| 255 | /* For other OS platforms, the compiler's default calling convention is used */ |
|---|
| 256 | /* and, hopefully, this won't cause link-time or run-time problems. */ |
|---|
| 257 | #if !defined(ARM4_API_CALL) |
|---|
| 258 | #define ARM4_API_CALL |
|---|
| 259 | #define ARM4_API_VACALL |
|---|
| 260 | #endif |
|---|
| 261 | |
|---|
| 262 | /* Set up the ARM4_API_DYNAMIC definition here so the ARM library can be */ |
|---|
| 263 | /* built correctly as a shared library or DLL. Note the return type of the */ |
|---|
| 264 | /* API call must be specified as an argument to this macro because MSVC */ |
|---|
| 265 | /* needs the __declspec() before and __stdcall keyword after the return type.*/ |
|---|
| 266 | /* */ |
|---|
| 267 | /* Note that dllexport and dllimport are needed only for _WIN32 or _WIN64. */ |
|---|
| 268 | /* It is recommended that ARM agent providers for Windows explicitly use an */ |
|---|
| 269 | /* libarm4.def to spell out the exact name of the exports, such that */ |
|---|
| 270 | /* applications can do a GetProcAddress() without problems. Note that in the */ |
|---|
| 271 | /* case of a compiler not supporting __declspec(), compile time errors are */ |
|---|
| 272 | /* to be expected. */ |
|---|
| 273 | |
|---|
| 274 | #if !(defined(_WIN32) || defined(_WIN64)) || defined(ARM4_NODLL) |
|---|
| 275 | #define ARM4_API_DYNAMIC(type) extern type ARM4_API_CALL |
|---|
| 276 | |
|---|
| 277 | #elif defined(__GNUC__) |
|---|
| 278 | #if defined(ARM4_BUILD_DLL) |
|---|
| 279 | #define ARM4_API_DYNAMIC(type) __attribute__((dllexport)) type ARM4_API_CALL |
|---|
| 280 | #else |
|---|
| 281 | #define ARM4_API_DYNAMIC(type) __attribute__((dllimport)) type ARM4_API_CALL |
|---|
| 282 | #endif |
|---|
| 283 | #else |
|---|
| 284 | #if defined(ARM4_BUILD_DLL) |
|---|
| 285 | #define ARM4_API_DYNAMIC(type) __declspec(dllexport) type ARM4_API_CALL |
|---|
| 286 | #else |
|---|
| 287 | #define ARM4_API_DYNAMIC(type) __declspec(dllimport) type ARM4_API_CALL |
|---|
| 288 | #endif /* __GNUC__ */ |
|---|
| 289 | |
|---|
| 290 | #endif /* !defined(_WIN32) || ... */ |
|---|
| 291 | |
|---|
| 292 | #define ARM4_API_STATIC(type) type ARM4_API_CALL |
|---|
| 293 | #define ARM4_API_VASTATIC(type) type ARM4_API_VACALL |
|---|
| 294 | |
|---|
| 295 | /* ------------------------------------------------------------------------- */ |
|---|
| 296 | /* ------------------------ Step 3: inlining support ----------------------- */ |
|---|
| 297 | /* ---------------------------- (compiler dependent) ----------------------- */ |
|---|
| 298 | /* ------------------------------------------------------------------------- */ |
|---|
| 299 | |
|---|
| 300 | /* determine correct inline keyword */ |
|---|
| 301 | #if (defined(__STDC_VERSION__) && __STDC_VERSION__ > 199900L) || \ |
|---|
| 302 | defined(__cplusplus) |
|---|
| 303 | /* C99 C compliant and C++ compilers use the inline keyword */ |
|---|
| 304 | #define ARM4_INLINE inline |
|---|
| 305 | |
|---|
| 306 | #elif defined(__GNUC__) |
|---|
| 307 | /* GNU C supports inlining */ |
|---|
| 308 | #if __GNUC__ > 2 |
|---|
| 309 | #define ARM4_INLINE static __attribute__((always_inline)) __inline__ |
|---|
| 310 | #else |
|---|
| 311 | #define ARM4_INLINE static __inline__ |
|---|
| 312 | #endif |
|---|
| 313 | |
|---|
| 314 | #elif defined(_MSC_VER) |
|---|
| 315 | /* MSVC supports inlining */ |
|---|
| 316 | #define ARM4_INLINE __inline |
|---|
| 317 | |
|---|
| 318 | #elif defined(__INTEL_COMPILER) |
|---|
| 319 | /* INTEL compiler can take both inline or __inline */ |
|---|
| 320 | #define ARM4_INLINE __inline |
|---|
| 321 | |
|---|
| 322 | #elif defined(__DECC) |
|---|
| 323 | /* Compaq C V6.1 cc compiler can take __inline */ |
|---|
| 324 | #define ARM4_INLINE __inline |
|---|
| 325 | |
|---|
| 326 | /* any other compiler specific inline support should be */ |
|---|
| 327 | /* placed here. */ |
|---|
| 328 | |
|---|
| 329 | #else |
|---|
| 330 | /* not sure if the current compiler supports inlining, so */ |
|---|
| 331 | /* use the default keyword. Compile time errors will result */ |
|---|
| 332 | /* if the compiler does not support the default keyword. */ |
|---|
| 333 | #define ARM4_INLINE inline |
|---|
| 334 | |
|---|
| 335 | #endif /* (defined(__STD_VERSION__) && ... */ |
|---|
| 336 | |
|---|
| 337 | /* ------------------------------------------------------------------------- */ |
|---|
| 338 | |
|---|
| 339 | #endif /* !ARM4OS_H_INCLUDED */ |
|---|