41a4ce2f90c3281f95ed5342962b0b58b157c9cd
[picodrive.git] / pico / pico_port.h
1 #ifndef PICO_PORT_INCLUDED
2 #define PICO_PORT_INCLUDED
3
4 // provide size_t, uintptr_t
5 #include <stdlib.h>
6 #if !(defined(_MSC_VER) && _MSC_VER < 1800)
7 #include <stdint.h>
8 #endif
9 #include "pico_types.h"
10
11 #ifdef USE_LIBRETRO_VFS
12 #include "file_stream_transforms.h"
13 #endif
14
15 #if defined(__GNUC__) && defined(__i386__)
16 #define REGPARM(x) __attribute__((regparm(x)))
17 #else
18 #define REGPARM(x)
19 #endif
20
21 #ifdef __GNUC__
22 #define NOINLINE    __attribute__((noinline))
23 #define ALIGNED(n)  __attribute__((aligned(n)))
24 #define unlikely(x) __builtin_expect((x), 0)
25 #define likely(x)   __builtin_expect(!!(x), 1)
26 #else
27 #define NOINLINE
28 #define ALIGNED(n)
29 #define unlikely(x) (x)
30 #define likely(x) (x)
31 #endif
32
33 #ifdef _MSC_VER
34 #define snprintf _snprintf
35 #define strcasecmp _stricmp
36 #define strncasecmp _strnicmp
37 #define strdup _strdup
38 #endif
39
40
41 // There's no standard way to determine endianess at compile time. Try using
42 // some well known non-standard macros for detection.
43 #if defined __BYTE_ORDER__
44 #define CPU_IS_LE       __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
45 #elif defined __BYTE_ORDER
46 #define CPU_IS_LE       __BYTE_ORDER == __LITTLE_ENDIAN
47 #elif defined __BIG_ENDIAN__ || defined _M_PPC // Windows on PPC was big endian
48 #define CPU_IS_LE       0
49 #elif defined __LITTLE_ENDIAN__ || defined _WIN32 // all other Windows is LE
50 #define CPU_IS_LE       1
51 #else
52 #warning "can't detect byte order, assume little endian"
53 #define CPU_IS_LE       1
54 #endif
55 // NB mixed endian integer platforms are not supported.
56
57 #if CPU_IS_LE
58 // address/offset operations
59 #define MEM_BE2(a)      ((a)^1)         // addr/offs of u8 in u16, or u16 in u32
60 #define MEM_BE4(a)      ((a)^3)         // addr/offs of u8 in u32
61 #define MEM_LE2(a)      (a)
62 #define MEM_LE4(a)      (a)
63 // swapping
64 #define CPU_BE2(v)      ((u32)((u64)(v)<<16)|((u32)(v)>>16))
65 #define CPU_BE4(v)      (((u32)(v)>>24)|(((v)>>8)&0x00ff00)| \
66                         (((v)<<8)&0xff0000)|(u32)((v)<<24))
67 #define CPU_LE2(v)      (v)             // swap of 2*u16 in u32
68 #define CPU_LE4(v)      (v)             // swap of 4*u8  in u32
69 #else
70 // address/offset operations
71 #define MEM_BE2(a)      (a)
72 #define MEM_BE4(a)      (a)
73 #define MEM_LE2(a)      ((a)^1)
74 #define MEM_LE4(a)      ((a)^3)
75 // swapping
76 #define CPU_BE2(v)      (v)
77 #define CPU_BE4(v)      (v)
78 #define CPU_LE2(v)      ((u32)((u64)(v)<<16)|((u32)(v)>>16))
79 #define CPU_LE4(v)      (((u32)(v)>>24)|(((v)>>8)&0x00ff00)| \
80                         (((v)<<8)&0xff0000)|(u32)((v)<<24))
81 #endif
82
83 #endif // PICO_PORT_INCLUDED