xref: /kernel/liteos_m/utils/los_compiler.h (revision 3d8536b4)
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 *    conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 *    of conditions and the following disclaimer in the documentation and/or other materials
13 *    provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 *    to endorse or promote products derived from this software without specific prior written
17 *    permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _LOS_COMPILER_H
33#define _LOS_COMPILER_H
34
35/* for IAR Compiler */
36#ifdef __ICCARM__
37#include "iccarm_builtin.h"
38#endif
39
40#ifdef __cplusplus
41#if __cplusplus
42extern "C" {
43#endif /* __cplusplus */
44#endif /* __cplusplus */
45
46/* for IAR Compiler */
47#ifdef __ICCARM__
48
49#ifndef ASM
50#define ASM           __asm
51#endif
52
53#ifndef INLINE
54#define INLINE        inline
55#endif
56
57#ifndef STATIC_INLINE
58#define STATIC_INLINE static inline
59#endif
60
61#ifndef USED
62#define USED          __root
63#endif
64
65#ifndef WEAK
66#define WEAK          __weak
67#endif
68
69#ifndef CLZ
70#define CLZ           __iar_builtin_CLZ
71#endif
72
73#ifndef NORETURN
74#define NORETURN      __attribute__ ((__noreturn__))
75#endif
76
77#ifndef UNREACHABLE
78#define UNREACHABLE   while (1)
79#endif
80
81/* for ARM Compiler */
82#elif defined(__CC_ARM)
83
84#ifndef ASM
85#define ASM           __asm
86#endif
87
88#ifndef INLINE
89#define INLINE        __inline
90#endif
91
92#ifndef STATIC_INLINE
93#define STATIC_INLINE static __inline
94#endif
95
96#ifndef USED
97#define USED          __attribute__((used))
98#endif
99
100#ifndef WEAK
101#define WEAK          __attribute__((weak))
102#endif
103
104#ifndef CLZ
105#define CLZ           __clz
106#endif
107
108#ifndef NORETURN
109#define NORETURN      __declspec(noreturn)
110#endif
111
112#ifndef UNREACHABLE
113#define UNREACHABLE   while (1)
114#endif
115
116#pragma anon_unions
117
118/* for GNU Compiler */
119#elif defined(__GNUC__)
120
121#ifndef ASM
122#define ASM           __asm
123#endif
124
125#ifndef INLINE
126#define INLINE        inline
127#endif
128
129#ifndef STATIC_INLINE
130#define STATIC_INLINE static inline
131#endif
132
133#ifndef USED
134#define USED          __attribute__((used))
135#endif
136
137#ifndef WEAK
138#define WEAK          __attribute__((weak))
139#endif
140
141#ifndef CLZ
142#define CLZ           __builtin_clz
143#endif
144
145#ifndef NORETURN
146#define NORETURN      __attribute__ ((__noreturn__))
147#endif
148
149#ifndef UNREACHABLE
150#define UNREACHABLE   __builtin_unreachable()
151#endif
152
153#else
154#error Unknown compiler.
155#endif
156
157#ifndef STATIC
158#define STATIC       static
159#endif
160
161/**
162 * @ingroup los_builddef
163 * Define inline keyword
164 */
165#ifndef INLINE
166#define INLINE                                              static inline
167#endif
168
169/**
170 * @ingroup los_builddef
171 * Little endian
172 */
173#define OS_LITTLE_ENDIAN                                    0x1234
174
175/**
176 * @ingroup los_builddef
177 * Big endian
178 */
179#define OS_BIG_ENDIAN                                       0x4321
180
181/**
182 * @ingroup los_builddef
183 * Byte order
184 */
185#ifndef OS_BYTE_ORDER
186#define OS_BYTE_ORDER                                       OS_LITTLE_ENDIAN
187#endif
188
189/* Define OS code data sections */
190/* The indicator function is inline */
191
192/**
193 * @ingroup los_builddef
194 * Allow inline sections
195 */
196#ifndef LITE_OS_SEC_ALW_INLINE
197#define LITE_OS_SEC_ALW_INLINE      // __attribute__((always_inline))
198#endif
199
200/**
201 * @ingroup los_builddef
202 * Vector table section
203 */
204#ifndef LITE_OS_SEC_VEC
205#define LITE_OS_SEC_VEC          __attribute__ ((section(".vector")))
206#endif
207
208/**
209 * @ingroup los_builddef
210 * .Text section (Code section)
211 */
212#ifndef LITE_OS_SEC_TEXT
213#define LITE_OS_SEC_TEXT            // __attribute__((section(".sram.text")))
214#endif
215
216/**
217 * @ingroup los_builddef
218 * .Text.ddr section
219 */
220#ifndef LITE_OS_SEC_TEXT_MINOR
221#define LITE_OS_SEC_TEXT_MINOR      // __attribute__((section(".dyn.text")))
222#endif
223
224/**
225 * @ingroup los_builddef
226 * .Text.init section
227 */
228#ifndef LITE_OS_SEC_TEXT_INIT
229#define LITE_OS_SEC_TEXT_INIT       // __attribute__((section(".dyn.text")))
230#endif
231
232/**
233 * @ingroup los_builddef
234 * .Data section
235 */
236#ifndef LITE_OS_SEC_DATA
237#define LITE_OS_SEC_DATA            // __attribute__((section(".dyn.data")))
238#endif
239
240/**
241 * @ingroup los_builddef
242 * .Data.init section
243 */
244#ifndef LITE_OS_SEC_DATA_INIT
245#define LITE_OS_SEC_DATA_INIT       // __attribute__((section(".dyn.data")))
246#endif
247
248/**
249 * @ingroup los_builddef
250 * Not initialized variable section
251 */
252#ifndef LITE_OS_SEC_BSS
253#define LITE_OS_SEC_BSS             // __attribute__((section(".sym.bss")))
254#endif
255
256/**
257 * @ingroup los_builddef
258 * .bss.ddr section
259 */
260#ifndef LITE_OS_SEC_BSS_MINOR
261#define LITE_OS_SEC_BSS_MINOR
262#endif
263
264/**
265 * @ingroup los_builddef
266 * .bss.init sections
267 */
268#ifndef LITE_OS_SEC_BSS_INIT
269#define LITE_OS_SEC_BSS_INIT
270#endif
271
272#ifndef LITE_OS_SEC_TEXT_DATA
273#define LITE_OS_SEC_TEXT_DATA       // __attribute__((section(".dyn.data")))
274#define LITE_OS_SEC_TEXT_BSS        // __attribute__((section(".dyn.bss")))
275#define LITE_OS_SEC_TEXT_RODATA     // __attribute__((section(".dyn.rodata")))
276#endif
277
278#ifndef LITE_OS_SEC_SYMDATA
279#define LITE_OS_SEC_SYMDATA         // __attribute__((section(".sym.data")))
280#endif
281
282#ifndef LITE_OS_SEC_SYMBSS
283#define LITE_OS_SEC_SYMBSS          // __attribute__((section(".sym.bss")))
284#endif
285
286
287#ifndef LITE_OS_SEC_KEEP_DATA_DDR
288#define LITE_OS_SEC_KEEP_DATA_DDR   // __attribute__((section(".keep.data.ddr")))
289#endif
290
291#ifndef LITE_OS_SEC_KEEP_TEXT_DDR
292#define LITE_OS_SEC_KEEP_TEXT_DDR   // __attribute__((section(".keep.text.ddr")))
293#endif
294
295#ifndef LITE_OS_SEC_KEEP_DATA_SRAM
296#define LITE_OS_SEC_KEEP_DATA_SRAM  // __attribute__((section(".keep.data.sram")))
297#endif
298
299#ifndef LITE_OS_SEC_KEEP_TEXT_SRAM
300#define LITE_OS_SEC_KEEP_TEXT_SRAM  // __attribute__((section(".keep.text.sram")))
301#endif
302
303#ifndef LITE_OS_SEC_BSS_MINOR
304#define LITE_OS_SEC_BSS_MINOR
305#endif
306
307/* type definitions */
308typedef unsigned char          UINT8;
309typedef unsigned short         UINT16;
310typedef unsigned int           UINT32;
311typedef signed char            INT8;
312typedef signed short           INT16;
313typedef signed int             INT32;
314typedef float                  FLOAT;
315typedef double                 DOUBLE;
316typedef char                   CHAR;
317
318typedef unsigned long long     UINT64;
319typedef signed long long       INT64;
320typedef unsigned int           UINTPTR;
321typedef signed int             INTPTR;
322
323typedef volatile INT32 Atomic;
324typedef volatile INT64 Atomic64;
325
326#ifndef DEFINED_BOOL
327typedef unsigned int           BOOL;
328#define DEFINED_BOOL
329#endif
330
331#ifndef VOID
332#define VOID          void
333#endif
334
335#ifndef FALSE
336#define FALSE         ((BOOL)0)
337#endif
338
339#ifndef TRUE
340#define TRUE          ((BOOL)1)
341#endif
342
343#ifndef NULL
344#ifdef __cplusplus
345#define NULL          0L
346#else
347#define NULL          ((void*)0)
348#endif
349#endif
350
351#define OS_NULL_BYTE  ((UINT8)0xFF)
352#define OS_NULL_SHORT ((UINT16)0xFFFF)
353#define OS_NULL_INT   ((UINT32)0xFFFFFFFF)
354
355#ifndef LOS_OK
356#define LOS_OK        0U
357#endif
358
359#ifndef LOS_NOK
360#define LOS_NOK       (UINT32)(-1)
361#endif
362
363#define OS_FAIL       1
364#define OS_ERROR      (UINT32)(-1)
365#define OS_INVALID    (UINT32)(-1)
366#define OS_64BIT_MAX  (0xFFFFFFFFFFFFFFFFULL)
367
368#define asm           __asm
369#ifdef typeof
370#undef typeof
371#endif
372#define typeof        __typeof__
373
374#define SIZE(a) (a)
375
376#define LOS_ASSERT_COND(expression)
377
378/**
379 * @ingroup los_base
380 * Align the beginning of the object with the base address addr,
381 * with boundary bytes being the smallest unit of alignment.
382 */
383#ifndef ALIGN
384#define ALIGN(addr, boundary)        LOS_Align(addr, boundary)
385#endif
386/**
387 * @ingroup los_base
388 * Align the tail of the object with the base address addr, with size bytes being the smallest unit of alignment.
389 */
390#define TRUNCATE(addr, size)         ((addr) & ~((size) - 1))
391
392
393/**
394 * @ingroup los_base
395 * @brief Align the value (addr) by some bytes (boundary) you specify.
396 *
397 * @par Description:
398 * This API is used to align the value (addr) by some bytes (boundary) you specify.
399 *
400 * @attention
401 * <ul>
402 * <li>the value of boundary usually is 4,8,16,32.</li>
403 * </ul>
404 *
405 * @param addr     [IN]  The variable what you want to align.
406 * @param boundary [IN]  The align size what you want to align.
407 *
408 * @retval #UINT32 The variable what have been aligned.
409 * @par Dependency:
410 * <ul><li>los_base.h: the header file that contains the API declaration.</li></ul>
411 * @see
412 */
413static inline UINT32 LOS_Align(UINT32 addr, UINT32 boundary)
414{
415    return (addr + (((addr + (boundary - 1)) > addr) ? (boundary - 1) : 0)) & ~(boundary - 1);
416}
417
418#define OS_GOTO_ERREND() \
419        do {                 \
420            goto LOS_ERREND; \
421        } while (0)
422
423#ifndef UNUSED
424#define UNUSED(X) (void)X
425#endif
426
427#if defined(__GNUC__)
428#ifndef __XTENSA_LX6__
429static inline void maybe_release_fence(int model)
430{
431    switch (model) {
432        case __ATOMIC_RELEASE:
433            __atomic_thread_fence (__ATOMIC_RELEASE);
434            break;
435        case __ATOMIC_ACQ_REL:
436            __atomic_thread_fence (__ATOMIC_ACQ_REL);
437            break;
438        case __ATOMIC_SEQ_CST:
439            __atomic_thread_fence (__ATOMIC_SEQ_CST);
440            break;
441        default:
442            break;
443    }
444}
445
446static inline void maybe_acquire_fence(int model)
447{
448    switch (model) {
449        case __ATOMIC_ACQUIRE:
450            __atomic_thread_fence (__ATOMIC_ACQUIRE);
451            break;
452        case __ATOMIC_ACQ_REL:
453            __atomic_thread_fence (__ATOMIC_ACQ_REL);
454            break;
455        case __ATOMIC_SEQ_CST:
456            __atomic_thread_fence (__ATOMIC_SEQ_CST);
457            break;
458        default:
459            break;
460    }
461}
462
463#define __LIBATOMIC_N_LOCKS	(1 << 4) /* 4, 1<<4 locks num */
464static inline BOOL *__libatomic_flag_for_address(void *addr)
465{
466    static BOOL flag_table[__LIBATOMIC_N_LOCKS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
467    UINTPTR p = (UINTPTR)(UINTPTR *)addr;
468    p += (p >> 2) + (p << 4); /* 2, 4, hash data */
469    p += (p >> 7) + (p << 5); /* 7, 5, hash data */
470    p += (p >> 17) + (p << 13); /* 17, 13, hash data */
471
472    if (sizeof(void *) > 4) { /* 4, sizeof int in 32bit system */
473        p += (p >> 31); /* 31, for hash high bits data */
474    }
475
476    p &= (__LIBATOMIC_N_LOCKS - 1);
477    return flag_table + p;
478}
479
480static inline void get_lock(void *addr, int model)
481{
482    BOOL *lock_ptr = __libatomic_flag_for_address (addr);
483
484    maybe_release_fence (model);
485    while (__atomic_test_and_set (lock_ptr, __ATOMIC_ACQUIRE) == 1) {
486        ;
487    }
488}
489
490static inline void free_lock(void *addr, int model)
491{
492    BOOL *lock_ptr = __libatomic_flag_for_address (addr);
493
494    __atomic_clear (lock_ptr, __ATOMIC_RELEASE);
495    maybe_acquire_fence (model);
496}
497
498static inline UINT64  __atomic_load_8(const volatile void *mem, int model)
499{
500    UINT64 ret;
501
502    void *memP = (void *)mem;
503    get_lock (memP, model);
504    ret = *(UINT64 *)mem;
505    free_lock (memP, model);
506    return ret;
507}
508
509static inline void __atomic_store_8(volatile void *mem, UINT64 val, int model)
510{
511    void *memP = (void *)mem;
512    get_lock (memP, model);
513    *(UINT64 *)mem = val;
514    free_lock (memP, model);
515}
516
517static inline UINT64 __atomic_exchange_8(volatile void *mem, UINT64 val, int model)
518{
519    UINT64 ret;
520
521    void *memP = (void *)mem;
522    get_lock (memP, model);
523    ret = *(UINT64 *)mem;
524    *(UINT64 *)mem = val;
525    free_lock (memP, model);
526    return ret;
527}
528#endif /* __XTENSA_LX6__ */
529
530#define ALIAS_OF(of) __attribute__((alias(#of)))
531#define FUNC_ALIAS(real_func, new_alias, args_list, return_type) \
532    return_type new_alias args_list ALIAS_OF(real_func)
533
534#else
535
536#define FUNC_ALIAS(real_func, new_alias, args_list, return_type)
537
538#endif /* __GNUC__ */
539
540#ifdef __cplusplus
541#if __cplusplus
542}
543#endif /* __cplusplus */
544#endif /* __cplusplus */
545
546#endif /* _LOS_COMPILER_H */
547