Merge da SC: macros.h, pool.h, BIT_CHANGE, nome dei processi, etc.
[bertos.git] / compiler.h
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 2001, 2002, 2003 Bernardo Innocenti <bernie@codewiz.org>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \version $Id$
10  *
11  * \author Bernardo Innocenti <bernie@develer.com>
12  *
13  * \brief Additional support macros for compiler independance
14  */
15
16 /*
17  * $Log$
18  * Revision 1.16  2004/08/14 19:37:57  rasky
19  * Merge da SC: macros.h, pool.h, BIT_CHANGE, nome dei processi, etc.
20  *
21  * Revision 1.15  2004/08/13 03:23:26  bernie
22  * Adjust a few MSVC tweaks from older projects.
23  *
24  * Revision 1.14  2004/08/10 06:56:29  bernie
25  * RESTRICT: New C99-like macro; STATIC_ASSERT: Fix warning for multiple invocation in one file.
26  *
27  * Revision 1.13  2004/08/02 20:20:29  aleph
28  * Merge from project_ks
29  *
30  * Revision 1.12  2004/08/01 01:21:17  bernie
31  * LIKELY(), UNLIKELY(): New compiler-specific macros.
32  *
33  * Revision 1.11  2004/07/30 14:34:10  rasky
34  * Vari fix per documentazione e commenti
35  * Aggiunte PP_CATn e STATIC_ASSERT
36  *
37  * Revision 1.10  2004/07/30 14:15:53  rasky
38  * Nuovo supporto unificato per detect della CPU
39  *
40  * Revision 1.9  2004/07/29 22:57:09  bernie
41  * vsprintf(): Remove prototype for backwards compatibility with GCC 3.4; ssize_t: Add definition for inferior compilers.
42  *
43  * Revision 1.8  2004/07/20 23:43:39  bernie
44  * Use attribute((always_inline)) to force inlining.  This fixes the much
45  * hated need of redundant prototypes for inline functions.
46  *
47  * Revision 1.7  2004/07/20 23:26:48  bernie
48  * Fix two errors introduced by previous commit.
49  *
50  * Revision 1.6  2004/07/20 23:12:43  bernie
51  * *** empty log message ***
52  *
53  * Revision 1.5  2004/07/20 17:08:03  bernie
54  * Cleanup documentation
55  *
56  * Revision 1.4  2004/06/27 15:20:26  aleph
57  * Change UNUSED() macro to accept two arguments: type and name;
58  * Add macro GNUC_PREREQ to detect GCC version during build;
59  * Some spacing cleanups and typo fix
60  *
61  * Revision 1.3  2004/06/06 18:00:39  bernie
62  * PP_CAT(): New macro.
63  *
64  * Revision 1.2  2004/06/03 11:27:09  bernie
65  * Add dual-license information.
66  *
67  * Revision 1.1  2004/05/23 17:48:35  bernie
68  * Add top-level files.
69  *
70  */
71 #ifndef COMPILER_H
72 #define COMPILER_H
73
74 #include "arch_config.h"
75 #include "cpu_detect.h"
76
77
78 #if defined __GNUC__ && defined __GNUC_MINOR__
79         #define GNUC_PREREQ(maj, min) \
80                 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
81 #else
82         #define GNUC_PREREQ(maj, min) 0
83 #endif
84
85 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
86         #define COMPILER_C99      1
87 #else
88         #define COMPILER_C99      0
89 #endif
90
91 #if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
92         #pragma language=extended
93         #define INTERRUPT(x)  interrupt [x]
94         #define REGISTER      shortad
95         #define INLINE        /* unsupported */
96
97         /* Imported from <longjmp.h>. Unfortunately, we can't just include
98          * this header because it typedefs jmp_buf to be an array of chars.
99          * This would allow the compiler to place the buffer on an odd address.
100          * The CPU _should_ be able to perform word accesses to
101          * unaligned data, but there are *BUGS* in the 80196KC with
102          * some combinations of opcodes and addressing modes. One of
103          * these, "ST SP,[?GR]+" is used in the longjmp() implementation
104          * provided by the IAR compiler ANSI C library. When ?GR contains
105          * an odd address, surprisingly the CPU will copy the high order
106          * byte of the source operand (SP) in the low order byte of the
107          * destination operand (the memory location pointed to by ?GR).
108          *
109          * We also need to replace the library setjmp()/longjmp() with
110          * our own versions because the IAR implementation "forgets" to
111          * save the contents of local registers (?LR).
112          */
113         struct _JMP_BUF
114         {
115                 void *  sp;                             /* Stack pointer */
116                 void *  return_addr;    /* Return address */
117                 int             lr[6];                  /* 6 local registers */
118         };
119
120         typedef struct _JMP_BUF jmp_buf[1];
121
122         int setjmp(jmp_buf env);
123         void longjmp(jmp_buf env, int val);
124
125         /* Fake bool support */
126         #define true (1==1)
127         #define false (1!=1)
128         typedef unsigned char bool;
129
130 #elif defined(_MSC_VER) /* Win32 emulation support */
131
132         #include <setjmp.h>
133         #include <time.h> /* for time_t */
134
135         /* FIXME: I can't remember why exactly this was needed (NdBernie) */
136         #define float double
137
138         /* Fake bool support */
139         #ifndef __cplusplus
140                 #define true 1
141                 #define false 0
142                 typedef int bool;
143         #endif /* !__cplusplus */
144
145         /* These C99 functions are oddly named in MSVCRT32.lib */
146         #define snprintf _snprintf
147         #define vsnprintf _vsnprintf
148
149 #elif defined(__GNUC__)
150
151         /* GCC attributes */
152         #define FORMAT(type,fmt,first)  __attribute__((__format__(type, fmt, first)))
153         #define NORETURN                __attribute__((__noreturn__))
154         #define UNUSED(type,arg)        __attribute__((__unused__)) type arg
155         #define INLINE                  static inline __attribute__((__always_inline__))
156         #define LIKELY(x)               __builtin_expect((x), 1)
157         #define UNLIKELY(x)             __builtin_expect((x), 0)
158         #define RESTRICT                __restrict__
159         #if GNUC_PREREQ(3,1)
160                 #define DEPRECATED      __attribute__((__deprecated__))
161         #endif
162
163         #if CPU_X86
164
165                 /* hack to avoid conflicts with system type */
166                 #define sigset_t system_sigset_t
167                 #include <stddef.h>
168                 #include <setjmp.h>
169                 #include <stdbool.h>
170                 #undef system_sigset_t
171
172         #elif CPU_AVR
173
174                 #include <stddef.h>
175                 #include <stdbool.h>
176
177                 /* Missing printf-family functions in avr-libc/stdio.h */
178                 #include <stdarg.h>
179                 #include <avr/pgmspace.h>
180                 int vsprintf_P(char *buf, const char * PROGMEM fmt, va_list ap);
181
182                 /* Support for harvard architectures */
183                 #ifdef _PROGMEM
184                         #define PGM_READ_CHAR(s) pgm_read_byte(s)
185                         #define PGM_FUNC(x) x ## _P
186                         #define PGM_ATTR        PROGMEM
187                 #endif
188
189         #endif
190
191 #elif defined(__MWERKS__) && CPU_DSP56K
192
193         #include <stdint.h>
194         #include <stddef.h>
195         #include <stdbool.h>
196         #include <setjmp.h>
197
198         // CodeWarrior has size_t as built-in type, but does not define this symbol.
199         #define _SIZE_T_DEFINED
200
201 #else
202         #error unknown compiler
203 #endif
204
205
206 /* A few defaults for missing compiler features. */
207 #ifndef INLINE
208 #define INLINE                 static inline
209 #endif
210 #ifndef NORETURN
211 #define NORETURN               /* nothing */
212 #endif
213 #ifndef FORMAT
214 #define FORMAT(type,fmt,first) /* nothing */
215 #endif
216 #ifndef DEPRECATED
217 #define DEPRECATED             /* nothing */
218 #endif
219 #ifndef UNUSED
220 #define UNUSED(type,arg)       type arg
221 #endif
222 #ifndef REGISTER
223 #define REGISTER               /* nothing */
224 #endif
225 #ifndef INTERRUPT
226 #define INTERRUPT(x)           ERROR_NOT_IMPLEMENTED
227 #endif
228 #ifndef LIKELY
229 #define LIKELY(x)              x
230 #endif
231 #ifndef UNLIKELY
232 #define UNLIKELY(x)            x
233 #endif
234 #ifndef RESTRICT
235 #define RESTRICT
236 #endif
237
238 /* Support for harvard architectures */
239 #ifndef PSTR
240 #define PSTR            /* nothing */
241 #endif
242 #ifndef PGM_READ_CHAR
243 #define PGM_READ_CHAR(s) (*(s))
244 #endif
245 #ifndef PGM_FUNC
246 #define PGM_FUNC(x) x
247 #endif
248 #ifndef PGM_ATTR
249 #define PGM_ATTR        /* nothing */
250 #endif
251
252
253 /* Misc definitions */
254 #ifndef NULL
255 #define NULL  0
256 #endif
257 #ifndef EOF
258 #define EOF   (-1)
259 #endif
260
261
262 /* Support for hybrid C/C++ applications. */
263 #ifdef __cplusplus
264         #define EXTERN_C_BEGIN  extern "C" {
265         #define EXTERN_C_END    }
266 #else
267         #define EXTERN_C_BEGIN  /* nothing */
268         #define EXTERN_C_END    /* nothing */
269 #endif
270
271
272 /*
273  * Standard type definitions
274  * These should be in <sys/types.h>, but many compilers lack them.
275  */
276 #if !(defined(size_t) || defined(_SIZE_T_DEFINED))
277         typedef unsigned int size_t;
278         typedef int ssize_t;
279 #endif
280 #if !(defined(_TIME_T_DEFINED) || defined(__time_t_defined))
281         typedef long time_t;
282 #endif /* _TIME_T_DEFINED || __time_t_defined */
283
284 /*! Storage for pointers and integers */
285 #define IPTR void *
286
287 typedef long utime_t;
288 typedef unsigned char sig_t;
289 typedef unsigned char sigset_t;
290 typedef unsigned char page_t;
291
292 #if (defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__))
293         /*
294          * ISO C99 fixed-size types
295          * These should be in <stdint.h>, but many compilers lack them.
296          */
297         typedef signed char         int8_t;
298         typedef short int           int16_t;
299         typedef long int            int32_t;
300         typedef unsigned char       uint8_t;
301         typedef unsigned short int  uint16_t;
302         typedef unsigned long int   uint32_t;
303 #elif defined(__AVR__)
304         /* TODO: should this detect GCC+AVR combo, or just CPU_AVR? */
305         /* avr-libc is weird... */
306         #include <inttypes.h>
307 #else
308         /* This is the correct location. */
309         #include <stdint.h>
310 #endif
311
312 /*!
313  * \name Types for hardware registers.
314  *
315  * Only use these types for registers whose contents can
316  * be changed asynchronously by external hardware.
317  *
318  * \{
319  */
320 #if CPU_DSP56K
321         /* Registers can be accessed only through 16-bit pointers */
322         typedef volatile uint16_t  reg16_t;
323 #else
324         typedef volatile uint8_t   reg8_t;
325         typedef volatile uint16_t  reg16_t;
326         typedef volatile uint32_t  reg32_t;
327 #endif
328 /*\}*/
329
330 #endif /* COMPILER_H */