18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2004, 2007 Maciej W. Rozycki 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 58c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 68c2ecf20Sopenharmony_ci * for more details. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#ifndef _ASM_COMPILER_H 98c2ecf20Sopenharmony_ci#define _ASM_COMPILER_H 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* 128c2ecf20Sopenharmony_ci * With GCC 4.5 onwards we can use __builtin_unreachable to indicate to the 138c2ecf20Sopenharmony_ci * compiler that a particular code path will never be hit. This allows it to be 148c2ecf20Sopenharmony_ci * optimised out of the generated binary. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Unfortunately at least GCC 4.6.3 through 7.3.0 inclusive suffer from a bug 178c2ecf20Sopenharmony_ci * that can lead to instructions from beyond an unreachable statement being 188c2ecf20Sopenharmony_ci * incorrectly reordered into earlier delay slots if the unreachable statement 198c2ecf20Sopenharmony_ci * is the only content of a case in a switch statement. This can lead to 208c2ecf20Sopenharmony_ci * seemingly random behaviour, such as invalid memory accesses from incorrectly 218c2ecf20Sopenharmony_ci * reordered loads or stores. See this potential GCC fix for details: 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00360.html 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * It is unclear whether GCC 8 onwards suffer from the same issue - nothing 268c2ecf20Sopenharmony_ci * relevant is mentioned in GCC 8 release notes and nothing obviously relevant 278c2ecf20Sopenharmony_ci * stands out in GCC commit logs, but these newer GCC versions generate very 288c2ecf20Sopenharmony_ci * different code for the testcase which doesn't exhibit the bug. 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * GCC also handles stack allocation suboptimally when calling noreturn 318c2ecf20Sopenharmony_ci * functions or calling __builtin_unreachable(): 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * We work around both of these issues by placing a volatile asm statement, 368c2ecf20Sopenharmony_ci * which GCC is prevented from reordering past, prior to __builtin_unreachable 378c2ecf20Sopenharmony_ci * calls. 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * The .insn statement is required to ensure that any branches to the 408c2ecf20Sopenharmony_ci * statement, which sadly must be kept due to the asm statement, are known to 418c2ecf20Sopenharmony_ci * be branches to code and satisfy linker requirements for microMIPS kernels. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_ci#undef barrier_before_unreachable 448c2ecf20Sopenharmony_ci#define barrier_before_unreachable() asm volatile(".insn") 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#if !defined(CONFIG_CC_IS_GCC) || \ 478c2ecf20Sopenharmony_ci (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) 488c2ecf20Sopenharmony_ci# define GCC_OFF_SMALL_ASM() "ZC" 498c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_MICROMIPS) 508c2ecf20Sopenharmony_ci# error "microMIPS compilation unsupported with GCC older than 4.9" 518c2ecf20Sopenharmony_ci#else 528c2ecf20Sopenharmony_ci# define GCC_OFF_SMALL_ASM() "R" 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_MIPSR6 568c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL "mips64r6" 578c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL MIPS_ISA_LEVEL 588c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL_RAW mips64r6 598c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW 608c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_MIPSR5) 618c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL "mips64r5" 628c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL MIPS_ISA_LEVEL 638c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL_RAW mips64r5 648c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW 658c2ecf20Sopenharmony_ci#else 668c2ecf20Sopenharmony_ci/* MIPS64 is a superset of MIPS32 */ 678c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL "mips64r2" 688c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL "arch=r4000" 698c2ecf20Sopenharmony_ci#define MIPS_ISA_LEVEL_RAW mips64r2 708c2ecf20Sopenharmony_ci#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW 718c2ecf20Sopenharmony_ci#endif /* CONFIG_CPU_MIPSR6 */ 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#endif /* _ASM_COMPILER_H */ 74