Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 1 | /* toolchain/gcc.h - GCC toolchain abstraction */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2010-2014 Wind River Systems, Inc. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are met: |
| 8 | * |
| 9 | * 1) Redistributions of source code must retain the above copyright notice, |
| 10 | * this list of conditions and the following disclaimer. |
| 11 | * |
| 12 | * 2) Redistributions in binary form must reproduce the above copyright notice, |
| 13 | * this list of conditions and the following disclaimer in the documentation |
| 14 | * and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * 3) Neither the name of Wind River Systems nor the names of its contributors |
| 17 | * may be used to endorse or promote products derived from this software without |
| 18 | * specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 30 | * POSSIBILITY OF SUCH DAMAGE. |
| 31 | */ |
| 32 | |
| 33 | /* |
| 34 | DESCRIPTION |
Peter Mitsis | 1c313b6 | 2015-05-20 10:33:48 -0400 | [diff] [blame] | 35 | Macros to abstract compiler capabilities for GCC toolchain. |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 36 | |
| 37 | \NOMANUAL |
| 38 | */ |
| 39 | |
| 40 | #include <toolchain/common.h> |
| 41 | |
| 42 | #define FUNC_ALIAS(func, aliasToFunc, retType) \ |
Yonattan Louise | d133f96 | 2015-05-12 10:43:08 -0500 | [diff] [blame] | 43 | retType aliasToFunc() __attribute__((alias(#func))) |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 44 | |
| 45 | #define _ALIAS_OF(of) __attribute__((alias(#of))) |
| 46 | |
Peter Mitsis | 18fa789 | 2015-05-21 16:16:54 -0400 | [diff] [blame] | 47 | #define __prekernel_init_level(level) __attribute__((section(".ctors." \ |
| 48 | _STRINGIFY(level)))) |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 49 | |
Yonattan Louise | a8571c4 | 2015-05-12 10:12:36 -0500 | [diff] [blame] | 50 | #define CODE_UNREACHABLE __builtin_unreachable() |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 51 | #define FUNC_NORETURN __attribute__((__noreturn__)) |
| 52 | |
| 53 | /* The GNU assembler for Cortex-M3 uses # for immediate values, not |
| 54 | * comments, so the @nobits# trick does not work. |
| 55 | */ |
| 56 | #if defined(VXMICRO_ARCH_arm) |
| 57 | #define _NODATA_SECTION(segment) __attribute__((section(#segment))) |
| 58 | #else |
| 59 | #define _NODATA_SECTION(segment) \ |
| 60 | __attribute__((section(#segment ",\"wa\",@nobits#"))) |
| 61 | #endif |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 62 | |
| 63 | /* |
| 64 | * Unaligned reads and writes |
| 65 | * |
| 66 | * To prevent GCC from generating a "breaking strict-aliasing rule" warning, |
| 67 | * use the __may_alias__ attribute to inform it that the pointer may alias |
| 68 | * another type. |
| 69 | */ |
| 70 | |
| 71 | #ifdef CONFIG_UNALIGNED_WRITE_UNSUPPORTED |
| 72 | #define UNALIGNED_READ(p) _Unaligned32Read((p)) |
| 73 | |
| 74 | #define UNALIGNED_WRITE(p, v) \ |
| 75 | do { \ |
Yonattan Louise | 29bd1c7 | 2015-04-07 11:59:24 -0500 | [diff] [blame] | 76 | unsigned int __attribute__((__may_alias__)) *pp = (unsigned int *)(p); \ |
Yonattan Louise | d133f96 | 2015-05-12 10:43:08 -0500 | [diff] [blame] | 77 | _Unaligned32Write(pp, (v)); \ |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 78 | } \ |
| 79 | while (0) |
| 80 | #else /* !CONFIG_UNALIGNED_WRITE_UNSUPPORTED */ |
| 81 | #define UNALIGNED_READ(p) (*(p)) |
| 82 | |
| 83 | #define UNALIGNED_WRITE(p, v) \ |
| 84 | do { \ |
Yonattan Louise | 29bd1c7 | 2015-04-07 11:59:24 -0500 | [diff] [blame] | 85 | unsigned int __attribute__((__may_alias__)) *pp = (unsigned int *)(p); \ |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 86 | *pp = (v); \ |
| 87 | } \ |
| 88 | while (0) |
| 89 | #endif /* !CONFIG_UNALIGNED_WRITE_UNSUPPORTED */ |
| 90 | |
Luiz Augusto von Dentz | 9ef64a3 | 2015-05-13 14:42:08 +0300 | [diff] [blame] | 91 | /* Unaligned access */ |
| 92 | #define UNALIGNED_GET(p) \ |
| 93 | __extension__ ({ \ |
| 94 | struct __attribute__((__packed__)) { \ |
| 95 | __typeof__(*(p)) __v; \ |
| 96 | } *__p = (__typeof__(__p)) (p); \ |
| 97 | __p->__v; \ |
| 98 | }) |
| 99 | |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 100 | #define _GENERIC_SECTION(segment) __attribute__((section(#segment))) |
| 101 | |
| 102 | #define PACK_STRUCT __attribute__((__packed__)) |
| 103 | #define ALIGN_STRUCT(x) __attribute__((aligned(x))) |
| 104 | |
| 105 | #define ARG_UNUSED(x) (void)(x) |
| 106 | |
| 107 | #define likely(x) __builtin_expect((long)!!(x), 1L) |
| 108 | #define unlikely(x) __builtin_expect((long)!!(x), 0L) |
| 109 | |
| 110 | /* These macros allow having ARM asm functions callable from thumb */ |
| 111 | |
| 112 | #if defined(_ASMLANGUAGE) && !defined(_LINKER) |
| 113 | |
| 114 | #ifdef VXMICRO_ARCH_arm |
| 115 | |
| 116 | #if defined(CONFIG_ISA_THUMB) |
| 117 | |
| 118 | #define FUNC_CODE() \ |
| 119 | .code 16; \ |
| 120 | .thumb_func; |
| 121 | |
| 122 | #define FUNC_INSTR(a) \ |
| 123 | BX pc; \ |
| 124 | NOP; \ |
| 125 | .code 32; \ |
| 126 | A##a: |
| 127 | |
| 128 | #elif defined(CONFIG_ISA_THUMB2) |
| 129 | |
| 130 | #define FUNC_CODE() .thumb; |
| 131 | #define FUNC_INSTR(a) |
| 132 | |
| 133 | #elif defined(CONFIG_ISA_ARM) |
| 134 | |
| 135 | #define FUNC_CODE() .code 32; |
| 136 | #define FUNC_INSTR(a) |
| 137 | |
| 138 | #else |
| 139 | |
| 140 | #error unknown instruction set |
| 141 | |
| 142 | #endif /* ISA */ |
| 143 | |
| 144 | #else |
| 145 | |
| 146 | #define FUNC_CODE() |
| 147 | #define FUNC_INSTR(a) |
| 148 | |
| 149 | #endif /* !VXMICRO_ARCH_arm */ |
| 150 | |
| 151 | #endif /* _ASMLANGUAGE && !_LINKER */ |
| 152 | |
| 153 | /* |
| 154 | * These macros are used to declare assembly language symbols that need |
| 155 | * to be typed properly(func or data) to be visible to the OMF tool. |
| 156 | * So that the build tool could mark them as an entry point to be linked |
| 157 | * correctly. This is an elfism. Use #if 0 for a.out. |
| 158 | */ |
| 159 | |
| 160 | #if defined(_ASMLANGUAGE) && !defined(_LINKER) |
| 161 | |
| 162 | #ifdef VXMICRO_ARCH_arm |
| 163 | #define GTEXT(sym) .global FUNC(sym); .type FUNC(sym),%function |
| 164 | #define GDATA(sym) .global FUNC(sym); .type FUNC(sym),%object |
| 165 | #define WTEXT(sym) .weak FUNC(sym); .type FUNC(sym),%function |
| 166 | #define WDATA(sym) .weak FUNC(sym); .type FUNC(sym),%object |
| 167 | #elif defined(VXMICRO_ARCH_arc) |
| 168 | /* |
| 169 | * Need to use assembly macros because ';' is interpreted as the start of |
| 170 | * a single line comment in the ARC assembler. |
| 171 | */ |
| 172 | |
| 173 | .macro glbl_text symbol |
| 174 | .globl FUNC(\symbol) |
| 175 | .type FUNC(\symbol), %function |
| 176 | .endm |
| 177 | |
| 178 | .macro glbl_data symbol |
| 179 | .globl FUNC(\symbol) |
| 180 | .type FUNC(\symbol), %object |
| 181 | .endm |
| 182 | |
| 183 | #define GTEXT(sym) glbl_text sym |
| 184 | #define GDATA(sym) glbl_data sym |
| 185 | #else /* !VXMICRO_ARCH_arm && !VXMICRO_ARCH_arc */ |
| 186 | #define GTEXT(sym) .globl FUNC(sym); .type FUNC(sym),@function |
| 187 | #define GDATA(sym) .globl FUNC(sym); .type FUNC(sym),@object |
| 188 | #endif |
| 189 | |
| 190 | /* |
| 191 | * These macros specify the section in which a given function or variable |
| 192 | * resides. |
| 193 | * |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 194 | * - SECTION_FUNC allows only one function to reside in a sub-section |
| 195 | * - SECTION_SUBSEC_FUNC allows multiple functions to reside in a sub-section |
| 196 | * This ensures that garbage collection only discards the section |
| 197 | * if all functions in the sub-section are not referenced. |
| 198 | */ |
| 199 | |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 200 | #if defined(VXMICRO_ARCH_arc) |
| 201 | /* |
| 202 | * Need to use assembly macros because ';' is interpreted as the start of |
| 203 | * a single line comment in the ARC assembler. |
| 204 | * |
| 205 | * Also, '\()' is needed in the .section directive of these macros for |
| 206 | * correct substitution of the 'section' variable. |
| 207 | */ |
| 208 | |
| 209 | .macro section_var section, symbol |
| 210 | .section .\section\().FUNC(\symbol) |
| 211 | FUNC(\symbol): |
| 212 | .endm |
| 213 | |
| 214 | .macro section_func section, symbol |
| 215 | .section .\section\().FUNC(\symbol), "ax" |
| 216 | FUNC_CODE() |
| 217 | PERFOPT_ALIGN |
| 218 | FUNC(\symbol): |
| 219 | FUNC_INSTR(\symbol) |
| 220 | .endm |
| 221 | |
| 222 | .macro section_subsec_func section, subsection, symbol |
| 223 | .section .\section\().\subsection, "ax" |
| 224 | PERFOPT_ALIGN |
| 225 | FUNC(\symbol): |
| 226 | .endm |
| 227 | |
| 228 | #define SECTION_VAR(sect, sym) section_var sect, sym |
| 229 | #define SECTION_FUNC(sect, sym) section_func sect, sym |
| 230 | #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \ |
| 231 | section_subsec_func sect, subsec, sym |
| 232 | #else /* !VXMICRO_ARCH_arc */ |
| 233 | |
| 234 | #define SECTION_VAR(sect, sym) .section .sect.FUNC(sym); FUNC(sym): |
| 235 | #define SECTION_FUNC(sect, sym) \ |
| 236 | .section .sect.FUNC(sym), "ax"; \ |
| 237 | FUNC_CODE() \ |
| 238 | PERFOPT_ALIGN; FUNC(sym): \ |
| 239 | FUNC_INSTR(sym) |
| 240 | #define SECTION_SUBSEC_FUNC(sect, subsec, sym) \ |
| 241 | .section .sect.subsec, "ax"; PERFOPT_ALIGN; FUNC(sym): |
| 242 | |
| 243 | #endif /* VXMICRO_ARCH_arc */ |
| 244 | |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 245 | #endif /* _ASMLANGUAGE && !_LINKER */ |
| 246 | |
| 247 | #if defined(CONFIG_ARM) && defined(_ASMLANGUAGE) |
| 248 | #if defined(CONFIG_ISA_THUMB2) |
| 249 | /* '.syntax unified' is a gcc-ism used in thumb-2 asm files */ |
| 250 | #define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb |
| 251 | #elif defined(CONFIG_ISA_THUMB) |
| 252 | #define _ASM_FILE_PROLOGUE .text; .code 16 |
| 253 | #else |
| 254 | #define _ASM_FILE_PROLOGUE .text; .code 32 |
| 255 | #endif |
Allan Stephens | e54a6c4 | 2015-05-25 15:00:04 -0400 | [diff] [blame] | 256 | #endif |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 257 | |
Allan Stephens | e54a6c4 | 2015-05-25 15:00:04 -0400 | [diff] [blame] | 258 | /* |
| 259 | * These macros generate absolute symbols for GCC |
| 260 | */ |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 261 | |
Allan Stephens | e54a6c4 | 2015-05-25 15:00:04 -0400 | [diff] [blame] | 262 | /* create an extern reference to the absolute symbol */ |
| 263 | |
| 264 | #define GEN_OFFSET_EXTERN(name) extern const char name[] |
| 265 | |
| 266 | #define GEN_ABS_SYM_BEGIN(name) \ |
| 267 | extern void name(void); \ |
| 268 | void name(void) \ |
| 269 | { |
| 270 | |
| 271 | #define GEN_ABS_SYM_END } |
| 272 | |
| 273 | #if defined(VXMICRO_ARCH_arm) |
| 274 | |
| 275 | /* |
| 276 | * GNU/ARM backend does not have a proper operand modifier which does not |
| 277 | * produces prefix # followed by value, such as %0 for PowerPC, Intel, and |
| 278 | * MIPS. The workaround performed here is using %B0 which converts |
| 279 | * the value to ~(value). Thus "n"(~(value)) is set in operand constraint |
| 280 | * to output (value) in the ARM specific GEN_OFFSET macro. |
| 281 | */ |
| 282 | |
| 283 | #define GEN_ABSOLUTE_SYM(name, value) \ |
| 284 | __asm__(".globl\t" #name "\n\t.equ\t" #name \ |
| 285 | ",%B0" \ |
| 286 | "\n\t.type\t" #name ",%%object" : : "n"(~(value))) |
| 287 | |
| 288 | #elif defined(VXMICRO_ARCH_x86) || defined(VXMICRO_ARCH_arc) |
| 289 | |
| 290 | #define GEN_ABSOLUTE_SYM(name, value) \ |
| 291 | __asm__(".globl\t" #name "\n\t.equ\t" #name \ |
| 292 | ",%c0" \ |
| 293 | "\n\t.type\t" #name ",@object" : : "n"(value)) |
| 294 | |
| 295 | #else |
| 296 | #error processor architecture not supported |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 297 | #endif |