Arm-2D  
2D Image Processing Library for Cortex-M Processors
arm_2d_utils.h
1/*
2 * Copyright (C) 2010-2022 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: arm_2d_utils.h
22 * Description: Public header file for Arm-2D Library
23 *
24 * $Date: 29. Aug 2024
25 * $Revision: V.1.4.5
26 *
27 * -------------------------------------------------------------------- */
28
29#ifndef __ARM_2D_UTILS_H__
30#define __ARM_2D_UTILS_H__
31
32/*============================ INCLUDES ======================================*/
33
34#if defined(__clang__)
35# pragma clang diagnostic push
36# pragma clang diagnostic ignored "-Wunknown-warning-option"
37# pragma clang diagnostic ignored "-Wreserved-identifier"
38# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
39# pragma clang diagnostic ignored "-Wpadded"
40# pragma clang diagnostic ignored "-Wsign-conversion"
41# pragma clang diagnostic ignored "-Wimplicit-int-conversion"
42# pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
43# pragma clang diagnostic ignored "-Wundef"
44#elif defined(__IS_COMPILER_GCC__)
45# pragma GCC diagnostic push
46# pragma GCC diagnostic ignored "-Wpedantic"
47# pragma GCC diagnostic ignored "-Wstrict-aliasing"
48# pragma GCC diagnostic ignored "-Wnonnull-compare"
49#endif
50
51#ifdef __ARM_2D_HAS_USER_HEADER__
52# include __ARM_2D_HAS_USER_HEADER__
53#endif
54
55
56
57#undef __IS_SUPPORTED_ARM_ARCH__
58#if ( (defined(__ARM_ARCH) && __ARM_ARCH) \
59 || defined(__TARGET_ARCH_ARM)) && !defined(__APPLE__)
60# define __IS_SUPPORTED_ARM_ARCH__ 1
61#else
62# define __IS_SUPPORTED_ARM_ARCH__ 0
63#endif
64
65/*! \note arm-2d relies on CMSIS 5.8.0 and above.
66 */
67#if __IS_SUPPORTED_ARM_ARCH__
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73# include "cmsis_compiler.h"
74
75#ifdef __cplusplus
76}
77#endif
78
79#else
80# include "arm_2d_user_arch_port.h"
81#endif
82
83
84#ifdef __cplusplus
85extern "C" {
86#endif
87
88/*!
89 * \addtogroup gKernel 1 Kernel
90 * @{
91 */
92
93/*============================ MACROS ========================================*/
94
95
96/*----------------------------------------------------------------------------*
97 * Environment Detection *
98 *----------------------------------------------------------------------------*/
99
100
101/* The macros to identify compilers */
102
103/* detect IAR */
104#undef __IS_COMPILER_IAR__
105#if defined(__IAR_SYSTEMS_ICC__)
106# define __IS_COMPILER_IAR__ 1
107#endif
108
109/* detect arm compiler 5 */
110#undef __IS_COMPILER_ARM_COMPILER_5__
111#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
112# define __IS_COMPILER_ARM_COMPILER_5__ 1
113#endif
114
115
116/* detect arm compiler 6 */
117#undef __IS_COMPILER_ARM_COMPILER_6__
118#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
119# define __IS_COMPILER_ARM_COMPILER_6__ 1
120#endif
121
122/* detect arm compilers */
123#undef __IS_COMPILER_ARM_COMPILER__
124#if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__ \
125|| defined(__IS_COMPILER_ARM_COMPILER_6__) && __IS_COMPILER_ARM_COMPILER_6__
126# define __IS_COMPILER_ARM_COMPILER__ 1
127#endif
128
129/* detect clang (llvm) */
130#undef __IS_COMPILER_LLVM__
131#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
132# define __IS_COMPILER_LLVM__ 1
133#else
134
135/* detect gcc */
136# undef __IS_COMPILER_GCC__
137# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER__) \
138 || defined(__IS_COMPILER_LLVM__) \
139 || defined(__IS_COMPILER_IAR__))
140# define __IS_COMPILER_GCC__ 1
141# endif
142
143#endif
144
145/*----------------------------------------------------------------------------*
146 * OOC and Private Protection *
147 *----------------------------------------------------------------------------*/
148/* minimal support for OOPC */
149#undef __implement_ex
150#undef __implement
151#undef implement
152#undef implement_ex
153#undef inherit
154#undef inherit_ex
155
156/*!
157 * \note do NOT use this macro directly
158 */
159#ifdef __cplusplus
160# define __implement_ex(__type, __name) __type __name
161#else
162# define __implement_ex(__type, __name) \
163 union { \
164 __type __name; \
165 __type; \
166 }
167#endif
168/*!
169 * \note do NOT use this macro
170 */
171#define __inherit_ex(__type, __name) __type __name
172
173
174/*!
175 * \note do NOT use this macro directly
176 */
177#define __implement(__type) __implement_ex( __type, \
178 use_as__##__type)
179
180
181/*!
182 * \note do NOT use this macro directly
183 */
184#define __inherit(__type) __inherit_ex(__type,use_as__##__type)
185
186
187/*!
188 * \brief inherit a given class
189 * \param __type the base class, you can use .use_as_xxxxx for referencing
190 * the base.
191 * \note this macro supports microsoft extensions (-fms-extensions)
192 */
193#define implement(__type) __implement(__type)
194
195/*!
196 * \brief inherit a given class and give it an alias name
197 * \param __type the base class
198 * \param __name an alias name for referencing the base class
199 * \note this macro supports microsoft extensions (-fms-extensions)
200 */
201#define implement_ex(__type, __name) __implement_ex(__type, __name)
202
203
204/*!
205 * \brief inherit a given class
206 * \param __type the base class, you can use .use_as_xxxxx for referencing
207 * the base.
208 * \note this macro does NOT support microsoft extensions (-fms-extensions)
209 */
210#define inherit(__type) __inherit(__type)
211
212/*!
213 * \brief inherit a given class and give it an alias name
214 * \param __type the base class
215 * \param __name an alias name for referencing the base class
216 * \note this macro does NOT support microsoft extensions (-fms-extensions)
217 */
218#define inherit_ex(__type, __name) __inherit_ex(__type, __name)
219
220
221/*----------------------------------------------------------------------------*
222 * Misc *
223 *----------------------------------------------------------------------------*/
224
225/*!
226 * \brief a macro to mark unused variables and let the compiler happy
227 */
228#ifndef ARM_2D_UNUSED
229# define ARM_2D_UNUSED(__VAR) (void)(__VAR)
230#endif
231
232#undef ARM_TYPE_CONVERT
233/*!
234 * \brief convert a given variable to a specified type, the converted result
235 * can be used as lvalue.
236 * \param __VAR the target variable
237 * \param __TYPE the target type
238 */
239#define ARM_TYPE_CONVERT(__VAR, __TYPE) (*((__TYPE *)&(__VAR)))
240
241/*!
242 * \brief a macro to test the boolean result for a given value using a given
243 * bitmask
244 * \param[in] __VALUE the target value
245 * \param[in] __BITS a bitmask
246 * \retval true all bits in the bitmask is 1
247 * \retval false not all bits in the bitmask is 1
248 */
249#ifndef ARM_TEST_BITS
250# define ARM_TEST_BITS(__VALUE, __BITS) ((__BITS) == ((__VALUE) & (__BITS)))
251#endif
252
253/*!
254 * \brief get the number of items in an given array
255 */
256#ifndef dimof
257# define dimof(__array) (sizeof(__array)/sizeof(__array[0]))
258#endif
259
260/*!
261 * \brief get the offset of a given member in a specified structure/union
262 * \param __type the host type
263 * \param __member the name of the target member
264 * \return size_t the offset (in bytes)
265 */
266#ifndef offsetof
267# define offsetof(__type, __member) \
268 ((uintptr_t)&(((__type *)NULL)->__member))
269#endif
270
271/*!
272 * \note do NOT use this macro directly
273 */
274#define __ARM_TO_STRING(__STR) #__STR
275
276/*!
277 * \brief convert a string to C string
278 */
279#define ARM_TO_STRING(__STR) __ARM_TO_STRING(__STR)
280
281/*!
282 * \note do NOT use this macro directly
283 */
284#define __ARM_VA_NUM_ARGS_IMPL( _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, \
285 _13,_14,_15,_16,__N,...) __N
286
287/*!
288 * \brief A macro to count the number of parameters
289 *
290 * \note if GNU extension is not supported or enabled, the following express will
291 * be false: (__ARM_VA_NUM_ARGS() != 0)
292 * This might cause problems when in this library.
293 */
294#define __ARM_VA_NUM_ARGS(...) \
295 __ARM_VA_NUM_ARGS_IMPL( 0,##__VA_ARGS__,16,15,14,13,12,11,10,9, \
296 8,7,6,5,4,3,2,1,0)
297
298/*!
299 * \brief detect whether GNU extension is enabled in compilation or not
300 */
301#if __ARM_VA_NUM_ARGS() != 0
302# warning Please enable GNU extensions, it is required by the Arm-2D.
303#endif
304
305
306#undef ARM_2D_PARAM
307
308/*!
309 * \brief a macro helper to be used with ARM_2D_INVODE to improve the
310 * readability of the code
311 */
312#define ARM_2D_PARAM(...) __VA_ARGS__
313
314#ifndef ARM_2D_INVOKE
315/*!
316 * \brief A macro to safely invode a function pointer
317 *
318 * \param[in] __FUNC_PTR the target function pointer
319 * \param[in] ... an optional parameter list
320 */
321# define ARM_2D_INVOKE(__FUNC_PTR, ...) \
322 ((NULL == (__FUNC_PTR)) ? 0 : ((*(__FUNC_PTR))(__VA_ARGS__)))
323
324#endif
325
326#ifndef ARM_2D_INVOKE_RT_VOID
327/*!
328 * \brief A macro to safely call a function pointer that has no return value
329 *
330 * \param[in] __FUNC_PTR the target function pointer
331 * \param[in] ... an optional parameter list
332 */
333# define ARM_2D_INVOKE_RT_VOID(__FUNC_PTR, ...) \
334 if (NULL != (__FUNC_PTR)) (*(__FUNC_PTR))(__VA_ARGS__)
335
336#endif
337
338/*!
339 * \note do NOT use this macro directly
340 */
341#define __ARM_CONNECT2(__A, __B) __A##__B
342
343/*!
344 * \note do NOT use this macro directly
345 */
346#define __ARM_CONNECT2_ALT(__A, __B) __A##__B
347
348/*!
349 * \note do NOT use this macro directly
350 */
351#define __ARM_CONNECT3(__A, __B, __C) __A##__B##__C
352
353/*!
354 * \note do NOT use this macro directly
355 */
356#define __ARM_CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
357
358/*!
359 * \note do NOT use this macro directly
360 */
361#define __ARM_CONNECT5(__A, __B, __C, __D, __E) __A##__B##__C##__D##__E
362
363/*!
364 * \note do NOT use this macro directly
365 */
366#define __ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
367 __A##__B##__C##__D##__E##__F
368
369/*!
370 * \note do NOT use this macro directly
371 */
372#define __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
373 __A##__B##__C##__D##__E##__F##__G
374
375/*!
376 * \note do NOT use this macro directly
377 */
378#define __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
379 __A##__B##__C##__D##__E##__F##__G##__H
380
381/*!
382 * \note do NOT use this macro directly
383 */
384#define __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
385 __A##__B##__C##__D##__E##__F##__G##__H##__I
386
387/*!
388 * \brief connect two symbol names as one
389 */
390#define ARM_CONNECT2(__A, __B) __ARM_CONNECT2(__A, __B)
391
392/*!
393 * \brief connect two symbol names as one
394 */
395#define ARM_CONNECT2_ALT(__A, __B) __ARM_CONNECT2_ALT(__A, __B)
396
397/*!
398 * \brief connect three symbol names as one
399 */
400#define ARM_CONNECT3(__A, __B, __C) __ARM_CONNECT3(__A, __B, __C)
401
402/*!
403 * \brief connect four symbol names as one
404 */
405#define ARM_CONNECT4(__A, __B, __C, __D) __ARM_CONNECT4(__A, __B, __C, __D)
406
407/*!
408 * \brief connect five symbol names as one
409 */
410#define ARM_CONNECT5(__A, __B, __C, __D, __E) \
411 __ARM_CONNECT5(__A, __B, __C, __D, __E)
412
413/*!
414 * \brief connect six symbol names as one
415 */
416#define ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
417 __ARM_CONNECT6(__A, __B, __C, __D, __E, __F)
418
419/*!
420 * \brief connect seven symbol names as one
421 */
422#define ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
423 __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G)
424
425/*!
426 * \brief connect eight symbol names as one
427 */
428#define ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
429 __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H)
430
431/*!
432 * \brief connect nine symbol names as one
433 */
434#define ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
435 __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I)
436
437/*!
438 * \brief connect up to 9 symbol names as one
439 */
440#define arm_connect(...) \
441 ARM_CONNECT2_ALT(ARM_CONNECT, __ARM_VA_NUM_ARGS(__VA_ARGS__)) \
442 (__VA_ARGS__)
443
444/*!
445 * \brief connect up to 9 symbol names as one
446 */
447#define ARM_CONNECT(...) arm_connect(__VA_ARGS__)
448
449/*!
450 * \note do NOT use this macro directly
451 */
452#define __ARM_USING1(__declare) \
453 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
454 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
455 )
456
457/*!
458 * \note do NOT use this macro directly
459 */
460#define __ARM_USING2(__declare, __on_leave_expr) \
461 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
462 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
463 (__on_leave_expr) \
464 )
465
466/*!
467 * \note do NOT use this macro directly
468 */
469#define __ARM_USING3(__declare, __on_enter_expr, __on_leave_expr) \
470 for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
471 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
472 ((__on_enter_expr),1) : 0; \
473 (__on_leave_expr) \
474 )
475
476/*!
477 * \note do NOT use this macro directly
478 */
479#define __ARM_USING4(__dcl1, __dcl2, __on_enter_expr, __on_leave_expr) \
480 for (__dcl1,__dcl2,*ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)= NULL;\
481 ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
482 ((__on_enter_expr),1) : 0; \
483 (__on_leave_expr) \
484 )
485
486/*!
487 * \brief create a code segment with up to two local variables and
488 * entering/leaving operations
489 * \note prototype 1
490 * arm_using(local variable declaration) {
491 * code body
492 * }
493 *
494 * \note prototype 2
495 * arm_using(local variable declaration, {code segment before leaving the body}) {
496 * code body
497 * }
498 *
499 * \note prototype 3
500 * arm_using( local variable declaration,
501 * {code segment before entering the body},
502 * {code segment before leaving the body}
503 * ) {
504 * code body
505 * }
506 *
507 * \note prototype 4
508 * arm_using( local variable1 declaration,
509 local variable2 with the same type as the local variable 1,
510 * {code segment before entering the body},
511 * {code segment before leaving the body}
512 * ) {
513 * code body
514 * }
515 */
516#define arm_using(...) \
517 ARM_CONNECT2(__ARM_USING, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
518
519
520/*!
521 * \note do NOT use this macro directly
522 */
523#define __ARM_WITH2(__type, __addr) \
524 arm_using(__type *_=(__addr))
525
526/*!
527 * \note do NOT use this macro directly
528 */
529#define __ARM_WITH3(__type, __addr, __item) \
530 arm_using(__type *_=(__addr), *__item = _, (void)_, (void)0)
531
532/*!
533 * \brief a with block to access members of a given object
534 *
535 * \note prototype 1
536 * arm_with(object type, address of the object) {
537 * you can use _.xxxx to access the members of the object
538 * }
539 *
540 * \note prototype 2
541 * arm_with(object type, address of the object, name of the iterator) {
542 * you can use your own iterator to access the members of the object
543 * }
544 */
545#define arm_with(...) \
546 ARM_CONNECT2(__ARM_WITH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
547
548/*!
549 * \brief access each items in a given array
550 * \param __type the type of the array
551 * \param __array the target array
552 * \note you can use "_" as the current object (iterator)
553 */
554#define ARM_FOREACH2(__type, __array) \
555 arm_using(__type *_ = __array) \
556 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
557 ARM_CONNECT2(count,__LINE__) > 0; \
558 _++, ARM_CONNECT2(count,__LINE__)-- \
559 )
560
561/*!
562 * \brief access each items in a given array
563 * \param __type the type of the array
564 * \param __array the target array
565 * \param __item a name for the current item (iterator)
566 */
567#define ARM_FOREACH3(__type, __array, __item) \
568 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0 ) \
569 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
570 ARM_CONNECT2(count,__LINE__) > 0; \
571 _++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
572 )
573
574/*!
575 * \brief access each items in a given array
576 * \param __type the type of the array
577 * \param __array the target array or the pointer of an memory block
578 * \param __count number of items in the array/memory block
579 * \param __item a name for the current item (iterator)
580 */
581#define ARM_FOREACH4(__type, __array, __count, __item) \
582 arm_using(__type *_ = __array, *__item = _, (void)_, (void)0) \
583 for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = (__count); \
584 ARM_CONNECT2(count,__LINE__) > 0; \
585 _++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
586 )
587
588/*!
589 * \brief access each items in a given array
590 * \note there are 3 prototypes, please refer to ARM_FOREACH1/2/3 for details
591 */
592#define arm_foreach(...) \
593 ARM_CONNECT2(ARM_FOREACH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
594
595
596/*!
597 * \brief a wrapper for __attribute__((nonnull))
598 */
599#ifndef ARM_NONNULL
600# if defined(__IS_COMPILER_ARM_COMPILER_5__) ||\
601 defined(__IS_COMPILER_ARM_COMPILER_6__) ||\
602 defined(__IS_COMPILER_GCC__) ||\
603 defined(__IS_COMPILER_LLVM__)
604# define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
605# else
606# define ARM_NONNULL(...)
607# endif
608#endif
609
610/*!
611 * \note do NOT use this macro directly
612 */
613#define __ARM_SECTION(__X) __attribute__((section(__X)))
614
615/*!
616 * \brief an attribute to specify the section
617 * \note it works for both functions and static/global variables
618 */
619#ifndef ARM_SECTION
620# define ARM_SECTION(__X) __ARM_SECTION(__X)
621#endif
622
623/*!
624 * \brief an attribute for static variables that no initialisation is required
625 * in the C startup process.
626 */
627#ifndef ARM_NOINIT
628# if defined(__IS_COMPILER_ARM_COMPILER_5__)
629# define ARM_NOINIT __attribute__(( section( ".bss.noinit"),zero_init))
630# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
631# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
632# elif defined(__IS_COMPILER_IAR__)
633# define ARM_NOINIT __no_init
634# elif (defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)) && !defined(__APPLE__)
635# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
636# else
637# define ARM_NOINIT
638# endif
639#endif
640
641#undef __ARM_ALIGN
642
643/*!
644 * \note do NOT use this macro directly
645 */
646#define __ARM_ALIGN(__N) __attribute__((aligned(__N)))
647
648/*!
649 * \brief an attribute to specify aligment requirement
650 * \note it works for both functions and static/global variables
651 */
652#ifndef ARM_ALIGN
653# define ARM_ALIGN(__N) __ARM_ALIGN(__N)
654#endif
655
656
657
658/*!
659 * \brief local variable decoration for pointers: restrict
660 */
661#ifndef __RESTRICT
662# define __RESTRICT __restrict
663#endif
664
665/*!
666 * \brief an decoration for claiming that the immediate following symbol
667 * (variable / function) is not WEAK. If there is an __WEAK symbol, the
668 * __OVERRIDE_WEAK one can override it.
669 *
670 */
671#ifndef __OVERRIDE_WEAK
672# define __OVERRIDE_WEAK
673#endif
674
675/*!
676 * \brief A macro to generate a safe name, usually used in macro template as the
677 * name of local variables
678 *
679 */
680#define ARM_2D_SAFE_NAME(...) ARM_CONNECT(__,__LINE__,##__VA_ARGS__)
681
682/*!
683 * \brief A macro to generate a safe name, usually used in macro template as the
684 * name of local variables
685 *
686 */
687#define arm_2d_safe_name(...) ARM_2D_SAFE_NAME(__VA_ARGS__)
688
689/*!
690 * \brief a decoration to make the immediate following code irq-safe
691 *
692 * \code
693 arm_irq_safe {
694 // code inside the brackets are IRQ safe
695 ...
696 }
697
698 // the printf is IRQ safe
699 arm_irq_safe printf("IRQ safe printf\n");
700
701 \endcode
702 */
703#if __IS_SUPPORTED_ARM_ARCH__
704# undef arm_irq_safe
705# undef arm_exit_irq_safe
706# define arm_irq_safe \
707 arm_using( uint32_t ARM_2D_SAFE_NAME(temp) = \
708 ({uint32_t temp=__get_PRIMASK();__disable_irq();temp;}),\
709 __set_PRIMASK(ARM_2D_SAFE_NAME(temp)))
710# define arm_exit_irq_safe continue
711#endif
712
713
714#undef ARM_2D_WRAP_FUNC
715#undef __ARM_2D_WRAP_FUNC
716#undef ARM_2D_ORIG_FUNC
717#undef __ARM_2D_ORIG_FUNC
718
719#if defined(__IS_COMPILER_ARM_COMPILER_6__)
720
721/*!
722 * \note do NOT use this macro directly
723 */
724# define __ARM_2D_WRAP_FUNC(__FUNC) $Sub$$##__FUNC
725
726/*!
727 * \note do NOT use this macro directly
728 */
729# define __ARM_2D_ORIG_FUNC(__FUNC) $Super$$## __FUNC
730#else
731
732/*!
733 * \note do NOT use this macro directly
734 */
735# define __ARM_2D_WRAP_FUNC(x) __wrap_ ## x
736
737/*!
738 * \note do NOT use this macro directly
739 */
740# define __ARM_2D_ORIG_FUNC(x) __real_ ## x
741#endif
742
743/*!
744 * \brief a symbol wrapper to override a specified function
745 */
746#define ARM_2D_WRAP_FUNC(__FUNC) __ARM_2D_WRAP_FUNC(__FUNC)
747
748/*!
749 * \brief a symbol wrapper to refer the original function with a given name
750 */
751#define ARM_2D_ORIG_FUNC(__FUNC) __ARM_2D_ORIG_FUNC(__FUNC)
752
753/*----------------------------------------------------------------------------*
754 * List Operations *
755 *----------------------------------------------------------------------------*/
756
757/* ALL the parameters passed to following macros must be pointer variables. */
758
759/*!
760 * \note do NOT use this macro directly
761 */
762#define __ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
763 do { \
764 ((__arm_slist_node_t *)(__P_NODE))->ptNext = \
765 (__arm_slist_node_t *)(__P_TOP); \
766 (*(__arm_slist_node_t **)&(__P_TOP)) = \
767 (__arm_slist_node_t *)(__P_NODE); \
768 } while(0)
769
770/*!
771 * \brief push a item to a list
772 * \param[in] __P_TOP a pointer points to the first item of a list
773 * \param[in] __P_NODE a pointer points to the new item
774 */
775#define ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
776 __ARM_LIST_STACK_PUSH((__P_TOP), (__P_NODE))
777
778/*!
779 * \brief insert a item after a specified node
780 * \param[in] __P_TARGET a pointer points to the target node
781 * \param[in] __P_NODE a pointer points to the new item
782 */
783#define ARM_LIST_INSERT_AFTER(__P_TARGET, __P_NODE) \
784 __ARM_LIST_STACK_PUSH((__P_TARGET), (__P_NODE))
785
786/*!
787 * \note do NOT use this macro directly
788 */
789#define __ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
790 do { \
791 (*(__arm_slist_node_t **)&(__P_NODE)) = \
792 (__arm_slist_node_t *)(__P_TOP); \
793 if (NULL != (__P_TOP)) { \
794 (*(__arm_slist_node_t **)&(__P_TOP)) = \
795 ((__arm_slist_node_t *)(__P_NODE))->ptNext; \
796 ((__arm_slist_node_t *)(__P_NODE))->ptNext = NULL; \
797 } \
798 } while(0)
799
800/*!
801 * \brief pop a item from a list
802 * \param[in] __P_TOP a pointer points to the first item of a list
803 * \param[out] __P_NODE a pointer variable for the node
804 */
805#define ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
806 __ARM_LIST_STACK_POP((__P_TOP), (__P_NODE))
807
808/*!
809 * \brief remove a item after a specified node
810 * \param[in] __P_TARGET a pointer points to the target node
811 * \param[out] __P_NODE a pointer variable for the node
812 */
813#define ARM_LIST_REMOVE_AFTER(__P_TARGET, __P_NODE) \
814 ARM_LIST_STACK_POP((__P_TARGET), (__P_NODE))
815
816/*!
817 * \note do NOT use this macro directly
818 */
819#define __ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
820 do { \
821 if (NULL == (__TAIL)) { \
822 (*((__arm_slist_node_t **)&(__TAIL))) = \
823 (__arm_slist_node_t *)(__ITEM); \
824 (*((__arm_slist_node_t **)&(__HEAD))) = \
825 (__arm_slist_node_t *)(__ITEM); \
826 } else { \
827 ((__arm_slist_node_t *)(__TAIL))->ptNext = \
828 (__arm_slist_node_t *)(__ITEM); \
829 (*(__arm_slist_node_t **)&(__TAIL)) = \
830 (__arm_slist_node_t *)(__ITEM); \
831 } \
832 ((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
833 } while(0)
834
835/*!
836 * \brief enter a node to a queue
837 * \param[in] __HEAD a pointer points to the queue head
838 * \param[in] __TAIL a pointer points to the queue tail
839 * \param[in] __ITEM a pointer variable for the new node
840 */
841#define ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
842 __ARM_LIST_QUEUE_ENQUEUE((__HEAD), (__TAIL), (__ITEM))
843
844/*!
845 * \note do NOT use this macro directly
846 */
847#define __ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
848 do { \
849 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
850 if (NULL != (__HEAD)) { \
851 (*(__arm_slist_node_t **)&(__HEAD)) = \
852 ((__arm_slist_node_t *)(__HEAD))->ptNext; \
853 if (NULL == (__HEAD)) { \
854 (__TAIL) = NULL; \
855 } \
856 } \
857 } while(0)
858
859/*!
860 * \brief fetch a node from a queue
861 * \param[in] __HEAD a pointer points to the queue head
862 * \param[in] __TAIL a pointer points to the queue tail
863 * \param[out] __ITEM a pointer variable for the node
864 */
865#define ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
866 __ARM_LIST_QUEUE_DEQUEUE((__HEAD), (__TAIL), (__ITEM))
867
868/*!
869 * \note do NOT use this macro directly
870 */
871#define __ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
872 do { \
873 (*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
874 } while(0)
875
876/*!
877 * \brief peek a node from a queue
878 * \param[in] __HEAD a pointer points to the queue head
879 * \param[in] __TAIL a pointer points to the queue tail
880 * \param[out] __ITEM a pointer variable for the node
881 */
882#define ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
883 __ARM_LIST_QUEUE_PEEK((__HEAD), (__TAIL), (__ITEM)) \
884
885/*----------------------------------------------------------------------------*
886 * PT Operations *
887 *----------------------------------------------------------------------------*/
888/*
889Protothreads open source BSD-style license
890The protothreads library is released under an open source license that allows
891both commercial and non-commercial use without restrictions. The only
892requirement is that credits is given in the source code and in the documentation
893for your product.
894
895The full license text follows.
896
897Copyright (c) 2004-2005, Swedish Institute of Computer Science.
898All rights reserved.
899
900Redistribution and use in source and binary forms, with or without
901modification, are permitted provided that the following conditions
902are met:
9031. Redistributions of source code must retain the above copyright
904notice, this list of conditions and the following disclaimer.
9052. Redistributions in binary form must reproduce the above copyright
906notice, this list of conditions and the following disclaimer in the
907documentation and/or other materials provided with the distribution.
9083. Neither the name of the Institute nor the names of its contributors
909may be used to endorse or promote products derived from this software
910without specific prior written permission.
911
912THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `AS IS' AND
913ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
914IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
915ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
916FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
917DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
918OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
919HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
920LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
921OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
922SUCH DAMAGE.
923
924Author: Adam Dunkels
925*/
926
927#define ARM_PT_BEGIN(__STATE) \
928 enum { \
929 count_offset = __COUNTER__ + 1, \
930 }; \
931 uint8_t *ptPTState = &(__STATE); \
932 switch (__STATE) { \
933 case __COUNTER__ - count_offset:
934
935#define ARM_PT_ENTRY(...) \
936 (*ptPTState) = (__COUNTER__ - count_offset + 1) >> 1; \
937 __VA_ARGS__ \
938 case (__COUNTER__ - count_offset) >> 1: (void)(*ptPTState);
939
940#define ARM_PT_YIELD(...) \
941 ARM_PT_ENTRY(return __VA_ARGS__;)
942
943#define ARM_PT_END() \
944 (*ptPTState) = 0; \
945 break;}
946
947#define ARM_PT_GOTO_PREV_ENTRY(...) return __VA_ARGS__;
948
949
950#define ARM_PT_REPORT_STATUS(...) \
951 ARM_PT_ENTRY( \
952 return __VA_ARGS__; \
953 )
954
955#define ARM_PT_RETURN(...) \
956 (*ptPTState) = 0; \
957 return __VA_ARGS__;
958
959/*----------------------------------------------------------------------------*
960 * Definition Template *
961 *----------------------------------------------------------------------------*/
962
963/*!
964 * \note do NOT use this macro directly
965 */
966#define __def_low_lv_io(__NAME, __SW, ...) \
967const __arm_2d_low_level_io_t LOW_LEVEL_IO##__NAME = { \
968 .SW = (__arm_2d_io_func_t *)&(__SW), \
969 .HW = (NULL, ##__VA_ARGS__) \
970}
971
972
973/*!
974 * \brief a template to implement a specified low-level io interface
975 * \param __NAME the IO name
976 * \param __SW the default c implementation
977 * \param ... you can specify an optional implementation using some acceleration.
978 */
979#define def_low_lv_io(__NAME, __SW, ...) \
980 __def_low_lv_io(__NAME, __SW, ##__VA_ARGS__)
981
982/*!
983 * \note do NOT use this macro directly
984 */
985#define __ref_low_lv_io(__NAME) &LOW_LEVEL_IO##__NAME
986
987/*!
988 * \brief a symbol wrapper for referencing a specified low-level IO
989 */
990#define ref_low_lv_io(__NAME) __ref_low_lv_io(__NAME)
991
992/*----------------------------------------------------------------------------*
993 * LOG *
994 *----------------------------------------------------------------------------*/
995
996/*!
997 * \brief the bit-mask for log channels
998 */
999#define ARM_2D_LOG_CHN_TYPE_USER _BV(28) //!< the channel for user messages
1000#define ARM_2D_LOG_CHN_TYPE_INFO _BV(29) //!< the channel for generic information
1001#define ARM_2D_LOG_CHN_TYPE_WARNING _BV(30) //!< the channel for warnings messages
1002#define ARM_2D_LOG_CHN_TYPE_ERROR _BV(31) //!< the channel for error messages
1003
1004#define ARM_2D_LOG_CHN_PIPELINE _BV(0) //!< the channel dedicated to the pixel-pipeline
1005#define ARM_2D_LOG_CHN_OPCODE _BV(1) //!< the channel dedicated to OPCODEs and related algorithms
1006#define ARM_2D_LOG_CHN_HELPER _BV(2) //!< the channel dedicated to Helper services
1007#define ARM_2D_LOG_CHN_HELPER_PFB _BV(3) //!< the channel dedicated to the PFB helper service
1008#define ARM_2D_LOG_CHN_SCENE_PLAYER _BV(4) //!< the channel dedicated to the scene player service
1009#define ARM_2D_LOG_CHN_DIRTY_REGION_OPTIMISATION _BV(5) //!< the channel dedicated to the dirty region optimization services
1010#define ARM_2D_LOG_CHN_STATISTICS _BV(6) //!< the channel dedicated to show statistics
1011#define ARM_2D_LOG_CHN_CONTROLS _BV(7) //!< the channel dedicated to example controls
1012#define ARM_2D_LOG_CHN_APP _BV(24) //!< the channel dedicated to applications and examples
1013
1014
1015#if defined(__ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__) && __ARM_2D_CFG_LOG_OUTPUT_SUPPORT_COLOUR__
1016# define ARM_2D_TERMINAL_COLOUR_DEFAULT "\x1b[0m"
1017# define ARM_2D_TERMINAL_COLOUR_GREEN "\x1b[32m"
1018# define ARM_2D_TERMINAL_COLOUR_RED "\x1b[31m"
1019# define ARM_2D_TERMINAL_COLOUR_YELLOW "\x1b[33m"
1020# define ARM_2D_TERMINAL_COLOUR_WHITE "\x1b[97m"
1021# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK "\x1b[90m"
1022#else
1023# define ARM_2D_TERMINAL_COLOUR_DEFAULT
1024# define ARM_2D_TERMINAL_COLOUR_GREEN
1025# define ARM_2D_TERMINAL_COLOUR_RED
1026# define ARM_2D_TERMINAL_COLOUR_YELLOW
1027# define ARM_2D_TERMINAL_COLOUR_WHITE
1028# define ARM_2D_TERMINAL_COLOUR_BRIGHT_BLACK
1029#endif
1030
1031/*!
1032 * \brief the filter to enable log channels
1033 */
1034#ifndef __ARM_2D_LOG_CHANNEL_MASK_FILTER__
1035# define __ARM_2D_LOG_CHANNEL_MASK_FILTER__ 0xFFFFFFFF
1036#endif
1037
1038#ifndef __ARM_2D_LOG_PRINTF_PIPELINE
1039
1040/*!
1041 * \brief the log printf entry dedicated to pixel pipeline
1042 */
1043# define __ARM_2D_LOG_PRINTF_PIPELINE __arm_2d_log_printf
1044#endif
1045
1046#ifndef __ARM_2D_LOG_PRINTF_OPCODE
1047/*!
1048 * \brief the log printf entry dedicated to OPCODEs and related algorithms
1049 */
1050# define __ARM_2D_LOG_PRINTF_OPCODE __arm_2d_log_printf
1051#endif
1052
1053#ifndef __ARM_2D_LOG_PRINTF_HELPER
1054/*!
1055 * \brief the log printf entry dedicated to Helper services
1056 */
1057# define __ARM_2D_LOG_PRINTF_HELPER __arm_2d_log_printf
1058#endif
1059
1060#ifndef __ARM_2D_LOG_PRINTF_HELPER_PFB
1061/*!
1062 * \brief the log printf entry dedicated to the PFB helper service
1063 */
1064# define __ARM_2D_LOG_PRINTF_HELPER_PFB __arm_2d_log_printf
1065#endif
1066
1067#ifndef __ARM_2D_LOG_PRINTF_SCENE_PLAYER
1068/*!
1069 * \brief the log printf entry dedicated to the scene player service
1070 */
1071# define __ARM_2D_LOG_PRINTF_SCENE_PLAYER __arm_2d_log_printf
1072#endif
1073
1074#ifndef __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION
1075/*!
1076 * \brief the log printf entry dedicated to the dirty region optimization service
1077 */
1078# define __ARM_2D_LOG_PRINTF_DIRTY_REGION_OPTIMISATION \
1079 __arm_2d_log_printf
1080#endif
1081
1082#ifndef __ARM_2D_LOG_PRINTF_STATISTICS
1083/*!
1084 * \brief the log printf entry dedicated to show statistics
1085 */
1086# define __ARM_2D_LOG_PRINTF_STATISTICS __arm_2d_log_printf
1087#endif
1088
1089#ifndef __ARM_2D_LOG_PRINTF_CONTROLS
1090/*!
1091 * \brief the log printf entry dedicated to example controls
1092 */
1093# define __ARM_2D_LOG_PRINTF_CONTROLS __arm_2d_log_printf
1094#endif
1095
1096#ifndef __ARM_2D_LOG_PRINTF_APP
1097/*!
1098 * \brief the log printf entry dedicated to applications and examples
1099 */
1100# define __ARM_2D_LOG_PRINTF_APP __arm_2d_log_printf
1101#endif
1102
1103#if defined(__ARM_2D_CFG_ENABLE_LOG__) && __ARM_2D_CFG_ENABLE_LOG__
1104/*!
1105 * \brief the log entry for generic information
1106 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1107 * \param[in] __INDENT number of indents before print actual content
1108 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1109 * like function name, service name etc.
1110 * \param[in] __FORMAT_STR the format string used in printf
1111 * \param[in] ... the optional parameters
1112 */
1113# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1114 __ARM_2D_LOG_PRINTF_##__CHN( \
1115 (__INDENT), \
1116 (ARM_2D_LOG_CHN_TYPE_INFO | ARM_2D_LOG_CHN_##__CHN), \
1117 (__PREFIX), \
1118 (__FORMAT_STR),##__VA_ARGS__)
1119
1120/*!
1121 * \brief the log entry for warning messages
1122 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1123 * \param[in] __INDENT number of indents before print actual content
1124 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1125 * like function name, service name etc.
1126 * \param[in] __FORMAT_STR the format string used in printf
1127 * \param[in] ... the optional parameters
1128 */
1129# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1130 __ARM_2D_LOG_PRINTF_##__CHN( \
1131 (__INDENT), \
1132 (ARM_2D_LOG_CHN_TYPE_WARNING | ARM_2D_LOG_CHN_##__CHN), \
1133 (__PREFIX), \
1134 (__FORMAT_STR),##__VA_ARGS__)
1135
1136/*!
1137 * \brief the log entry for error messages
1138 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1139 * \param[in] __INDENT number of indents before print actual content
1140 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1141 * like function name, service name etc.
1142 * \param[in] __FORMAT_STR the format string used in printf
1143 * \param[in] ... the optional parameters
1144 */
1145# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1146 __ARM_2D_LOG_PRINTF_##__CHN( \
1147 (__INDENT), \
1148 (ARM_2D_LOG_CHN_TYPE_ERROR | ARM_2D_LOG_CHN_##__CHN), \
1149 (__PREFIX), \
1150 (__FORMAT_STR),##__VA_ARGS__)
1151
1152/*!
1153 * \brief the log entry for user messages
1154 * \param[in] __CHN the channel name, e.g. PIPELINE, OPCODE, HELPER, HELPER_PFB etc.
1155 * \param[in] __INDENT number of indents before print actual content
1156 * \param[in] __PREFIX a string used as prefix, we can use it to print content
1157 * like function name, service name etc.
1158 * \param[in] __FORMAT_STR the format string used in printf
1159 * \param[in] ... the optional parameters
1160 */
1161# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...) \
1162 __ARM_2D_LOG_PRINTF_##__CHN( \
1163 (__INDENT), \
1164 (ARM_2D_LOG_CHN_TYPE_USER | ARM_2D_LOG_CHN_##__CHN), \
1165 (__PREFIX), \
1166 (__FORMAT_STR),##__VA_ARGS__)
1167
1168#else
1169# define ARM_2D_LOG_INFO(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1170# define ARM_2D_LOG_WARNING(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1171# define ARM_2D_LOG_ERROR(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1172# define ARM_2D_LOG_USER(__CHN, __INDENT, __PREFIX, __FORMAT_STR, ...)
1173#endif
1174
1175
1176#ifndef __ARM_2D_PORT_PRINTF__
1177/*!
1178 * \brief the low level entry for printf
1179 * \note you can define this macro for retargeting
1180 */
1181# define __ARM_2D_PORT_PRINTF__(__format, ...) printf((__format), ##__VA_ARGS__)
1182#endif
1183
1184#ifndef __ARM_2D_LOG_MAX_STRING_LEN__
1185/*!
1186 * \brief the maximum allowed string length. The log service requests the specified
1187 * number of bytes for storing string. default value is 256
1188 * \note please make sure there are sufficient memory in HEAP.
1189 */
1190# define __ARM_2D_LOG_MAX_STRING_LEN__ 256
1191#endif
1192
1193/*============================ TYPES =========================================*/
1194
1195/*!
1196 * \brief a type for generic list
1197 *
1198 * \note to avoid using container_of() operand, please put __arm_slist_node_t
1199 * at the beginning of a class/structure
1200 */
1203 __arm_slist_node_t *ptNext; //!< the next node
1204};
1205
1206
1207/*============================ GLOBAL VARIABLES ==============================*/
1208/*============================ PROTOTYPES ====================================*/
1209
1210/*!
1211 * \brief an entry for log printf
1212 * \param[in] nIndentLevel number of indents before print actual content
1213 * \param[in] wChannelMask a bit-mask to indicate the log channel
1214 * \param[in] pchPrefix a string used as prefix, we can use it to print content
1215 * like function name, service name etc.
1216 * \param[in] pchFormatString the format string used in printf
1217 * \param[in] ... the optional parameters
1218 */
1219extern
1220void __arm_2d_log_printf(int32_t nIndentLevel,
1221 uint32_t wChannelMask,
1222 const char *pchPrefix,
1223 const char *pchFormatString,
1224 ...);
1225
1226
1227#if defined(__clang__)
1228# pragma clang diagnostic pop
1229#elif __IS_COMPILER_ARM_COMPILER_5__
1230#elif __IS_COMPILER_GCC__
1231# pragma GCC diagnostic pop
1232#endif
1233
1234#ifdef __cplusplus
1235}
1236#endif
1237
1238
1239#endif /* end of __ARM_2D_UTILS_H__ */
1240
1241
1242/*! @} */
1243
1244/*============================ MACROS ========================================*/
1245/*----------------------------------------------------------------------------*
1246 * Reentrant Macros *
1247 *----------------------------------------------------------------------------*/
1248
1249/* un-define macros */
1250#undef ARM_PRIVATE
1251#undef ARM_PROTECTED
1252#undef ARM_PUBLIC
1253
1254#define ARM_PUBLIC(...) struct {__VA_ARGS__};
1255
1256/* redefine macros */
1257#if defined(__cplusplus)
1258# define ARM_PRIVATE(...) \
1259 struct { \
1260 __VA_ARGS__ \
1261 };
1262
1263# define ARM_PROTECTED(...) \
1264 struct { \
1265 __VA_ARGS__ \
1266 };
1267
1268#elif defined(__ARM_2D_IMPL__) || defined(__IS_COMPILER_IAR__)
1269
1270# define ARM_PRIVATE(...) \
1271 struct { \
1272 __VA_ARGS__ \
1273 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1274
1275# define ARM_PROTECTED(...) \
1276 struct { \
1277 __VA_ARGS__ \
1278 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1279
1280#elif defined(__ARM_2D_INHERIT__)
1281
1282# define ARM_PRIVATE(...) \
1283 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1284 [sizeof(struct {__VA_ARGS__})] \
1285 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1286
1287# define ARM_PROTECTED(...) \
1288 struct { \
1289 __VA_ARGS__ \
1290 } __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1291
1292#else
1293# define ARM_PRIVATE(...) \
1294 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1295 [sizeof(struct {__VA_ARGS__})] \
1296 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1297
1298# define ARM_PROTECTED(...) \
1299 uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
1300 [sizeof(struct {__VA_ARGS__})] \
1301 __ALIGNED(__alignof__(struct {__VA_ARGS__}));
1302#endif
1303
1304
1305#undef ARM_PRIVATE_METHOD
1306#undef ARM_PROTECTED_METHOD
1307#undef ARM_PUBLIC_METHOD
1308
1309#if defined(__ARM_2D_IMPL__)
1310
1311# define ARM_PRIVATE_METHOD(...) __VA_ARGS__
1312# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1313# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1314
1315#elif defined(__ARM_2D_INHERIT__)
1316
1317# define ARM_PRIVATE_METHOD(...)
1318# define ARM_PROTECTED_METHOD(...) __VA_ARGS__
1319# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1320
1321#else
1322
1323# define ARM_PRIVATE_METHOD(...)
1324# define ARM_PROTECTED_METHOD(...)
1325# define ARM_PUBLIC_METHOD(...) __VA_ARGS__
1326
1327#endif
1328
1329
1330
1331/* post un-define macros */
1332
1333#undef __ARM_2D_IMPL__
1334#undef __ARM_2D_INHERIT__