bf96ecb57d014ee6068de798094643ba5d2cefa6
[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  * All Rights Reserved.
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.1  2004/05/23 17:48:35  bernie
19  * Add top-level files.
20  *
21  */
22 #ifndef COMPILER_H
23 #define COMPILER_H
24
25 #include "arch_config.h"
26
27 #if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
28         #pragma language=extended
29         #define INTERRUPT(x)    interrupt [x]
30         #define REGISTER                shortad
31         #define ATOMIC                  monitor
32
33         /* GCC attributes */
34         #define FORMAT(type,fmt,first) /* nothing */
35         #define NORETURN               /* nothing */
36         #define UNUSED(arg)            arg
37
38         /* Imported from <longjmp.h>. Unfortunately, we can't just include
39          * this header because it typedefs jmp_buf to be an array of chars.
40          * This would allow the compiler to place the buffer on an odd address.
41          * The CPU _should_ be able to perform word accesses to
42          * unaligned data, but there are *BUGS* in the 80196KC with
43          * some combinations of opcodes and addressing modes. One of
44          * these, "ST SP,[?GR]+" is used in the longjmp() implementation
45          * provided by the IAR compiler ANSI C library. When ?GR contains
46          * an odd address, surprisingly the CPU will copy the high order
47          * byte of the source operand (SP) in the low order byte of the
48          * destination operand (the memory location pointed to by ?GR).
49          *
50          * We also need to replace the library setjmp()/longjmp() with
51          * our own versions because the IAR implementation "forgets" to
52          * save the contents of local registers (?LR).
53          */
54         struct _JMP_BUF
55         {
56                 void *  sp;                             /* Stack pointer */
57                 void *  return_addr;    /* Return address */
58                 int             lr[6];                  /* 6 local registers */
59         };
60
61         typedef struct _JMP_BUF jmp_buf[1];
62
63         int setjmp(jmp_buf env);
64         void longjmp(jmp_buf env, int val);
65
66         #ifndef __cplusplus
67                 #define true 1
68                 #define false 0
69                 typedef unsigned char bool;
70         #endif /* !__cplusplus */
71
72 #elif defined(_MSC_VER) /* Win32 emulation support */
73
74         #include <setjmp.h>
75         #include <time.h> /* for time_t */
76         #define float double
77
78         #define REGISTER                /* nothing */
79         #define INTERRUPT(x)    /* nothing */
80
81         /* GCC attributes */
82         #define FORMAT(type,fmt,first) /* nothing */
83         #define NORETURN               /* nothing */
84         #define UNUSED(arg)            arg
85         #define INLINE static inline
86
87         #ifdef __cplusplus
88                 extern "C" {
89         #endif
90                         void SchedulerIdle(void);
91         #ifdef __cplusplus
92                 }
93         #endif
94
95         /* Ouch, ReleaseSemaphore() conflicts with a WIN32 call ;-( */
96         #define ReleaseSemaphore KReleaseSemaphore
97
98         #ifndef __cplusplus
99                 #define true 1
100                 #define false 0
101                 typedef int bool;
102         #endif /* !__cplusplus */
103
104 #elif defined(__GNUC__)
105
106         /* GCC attributes */
107         #define FORMAT(type,fmt,first)  __attribute__((__format__(type, fmt, first)))
108         #define NORETURN                __attribute__((__noreturn__))
109         #define UNUSED(arg)             __attribute__((__unused__)) arg
110         //FIXME #define INLINE static inline
111         #define INLINE extern inline
112
113         #if defined(__i386__)
114
115                 /* hack to avoid conflicts with system type */
116                 #define sigset_t system_sigset_t
117                 #include <stddef.h>
118                 #include <setjmp.h>
119                 #include <stdbool.h>
120                 #undef system_sigset_t
121
122                 #define REGISTER                /* nothing */
123                 #define INTERRUPT(x)    /* nothing */
124
125                 #ifdef __cplusplus
126                         extern "C" {
127                 #endif
128                                 void SchedulerIdle(void);
129                 #ifdef __cplusplus
130                         }
131                 #endif
132
133         #elif defined(__AVR__)
134
135                 #include <stddef.h>
136                 #include <stdbool.h>
137                 #define FLASH           __attribute__((progmem))
138                 #define REGISTER                /* nothing */
139
140                 /* Missing printf-family functions in avr-libc/stdio.h */
141                 #include <stdarg.h>
142                 #include <avr/pgmspace.h>
143                 int vsprintf(char *buf, const char *fmt, va_list ap);
144                 int vsprintf_P(char *buf, const char * PROGMEM fmt, va_list ap);
145
146                 /* Support for hardvard architectures */
147                 #ifdef _PROGMEM
148                         #define PGM_READ_CHAR(s) pgm_read_byte(s)
149                         #define PGM_FUNC(x) x ## _P
150                         #define PGM_ATTR        PROGMEM
151                 #else
152                         #define PGM_READ_CHAR(s) (*(s))
153                         #define PGM_FUNC(x) x
154                         #define PGM_ATTR        /*nop*/
155                 #endif
156
157         #endif /* CPU */
158
159 #elif defined(__MWERKS__) && (defined(__m56800E__) || defined(__m56800__))
160
161         #include <stdint.h>
162         #include <stddef.h>
163         #include <stdbool.h>
164         #include <setjmp.h>
165
166         #define FLASH           /* nothing */
167         #define REGISTER                /* nothing */
168         #define INTERRUPT(x)    ERROR_NOT_IMPLEMENTED
169         #define SCHEDULER_IDLE  /* nothing */
170         
171         #define INLINE          static inline
172
173         /* GCC attributes */
174         #define FORMAT(type,fmt,first)  /* nothing */
175         #define NORETURN                /* nothing */
176         #define UNUSED(arg)             arg
177
178         /* Support for hardvard architectures */
179         #define PGM_READ_CHAR(s) (*(s))
180         #define PGM_FUNC                /* nothing */
181         #define PGM_ATTR                /* nothing */
182         #define PSTR            /* nothing */
183
184 #else
185         #error unknown compiler
186 #endif
187
188 /* Misc definitions */
189 #ifndef NULL
190 #define NULL    0
191 #endif
192 #ifndef EOF
193 #define EOF             (-1)
194 #endif
195
196
197 /* Quasi-ANSI macros
198  *
199  * offsetof(s,m) - Give the byte offset of the member <m> in struct <s>
200  * countof(a) - Count the number of elements in the static array <a>
201  */
202 #ifndef offsetof
203 #define offsetof(s,m)   (size_t)&(((s *)0)->m)
204 #endif
205
206 #ifndef countof
207 #define countof(a) (sizeof(a) / sizeof(*(a)))
208 #endif
209
210 /* Simple macros */
211 #define ABS(a)          (((a) < 0) ? -(a) : (a))
212 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
213 #define MAX(a,b)        (((a) > (b)) ? (a) : (b))
214
215 /*! Convert a bit value to a binary flag */
216 #ifndef BV
217 #define BV(x)   (1<<(x))
218 #endif
219
220 /*! Round up \a x to an even multiple of the 2's power \a pad */
221 #define ROUND2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
222
223 /*! Calculate a compile-time log2 for a uint8_t */
224 #define UINT8_LOG2(x) \
225         ((x) < 2 ? 0 : \
226          ((x) < 4 ? 1 : \
227           ((x) < 8 ? 2 : \
228            ((x) < 16 ? 3 : \
229             ((x) < 32 ? 4 : \
230              ((x) < 64 ? 5 : \
231               ((x) < 128 ? 6 : 7)))))))
232
233 /*! Calculate a compile-time log2 for a uint16_t */
234 #define UINT16_LOG2(x) \
235         ((x < 256) ? UINT8_LOG2(x) : UINT8_LOG2((x) >> 8) + 8)
236
237 /*! Calculate a compile-time log2 for a uint32_t */
238 #define UINT32_LOG2(x) \
239         ((x < 65536UL) ? UINT16_LOG2(x) : UINT16_LOG2((x) >> 16) + 16)
240
241 /* Type definitions - should go in <sys/types.h> */
242 #if !(defined(size_t) || defined(_SIZE_T_DEFINED))
243         #define size_t unsigned int
244 #endif
245 #if !(defined(_TIME_T_DEFINED) || defined(__time_t_defined))
246         typedef long time_t;
247 #endif /* _TIME_T_DEFINED || __time_t_defined */
248
249 /*! Storage for pointers and integers */
250 #define IPTR void *
251
252 typedef long utime_t;
253 typedef unsigned char sig_t;
254 typedef unsigned char sigset_t;
255 typedef unsigned char page_t;
256
257 /* ISO C99 fixed-size types */
258 #if (defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__))
259         typedef signed char         int8_t;
260         typedef short int           int16_t;
261         typedef long int            int32_t;
262         typedef unsigned char       uint8_t;
263         typedef unsigned short int  uint16_t;
264         typedef unsigned long int   uint32_t;
265 #elif defined(__AVR__)
266 #       include <inttypes.h>
267 #else
268 #       include <stdint.h>
269 #endif
270
271 #if (defined(__m56800E__) || defined(__m56800__))
272         /* Registers can be accessed only through 16-bit pointers */
273         typedef volatile uint16_t  reg16_t;
274 #else
275         typedef volatile uint8_t   reg8_t;
276         typedef volatile uint16_t  reg16_t;
277         typedef volatile uint32_t  reg32_t;
278 #endif
279
280 #endif /* COMPILER_H */