Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2004, 2007  Maciej W. Rozycki
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  */
0008 #ifndef _ASM_COMPILER_H
0009 #define _ASM_COMPILER_H
0010 
0011 /*
0012  * With GCC 4.5 onwards we can use __builtin_unreachable to indicate to the
0013  * compiler that a particular code path will never be hit. This allows it to be
0014  * optimised out of the generated binary.
0015  *
0016  * Unfortunately at least GCC 4.6.3 through 7.3.0 inclusive suffer from a bug
0017  * that can lead to instructions from beyond an unreachable statement being
0018  * incorrectly reordered into earlier delay slots if the unreachable statement
0019  * is the only content of a case in a switch statement. This can lead to
0020  * seemingly random behaviour, such as invalid memory accesses from incorrectly
0021  * reordered loads or stores. See this potential GCC fix for details:
0022  *
0023  *   https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00360.html
0024  *
0025  * It is unclear whether GCC 8 onwards suffer from the same issue - nothing
0026  * relevant is mentioned in GCC 8 release notes and nothing obviously relevant
0027  * stands out in GCC commit logs, but these newer GCC versions generate very
0028  * different code for the testcase which doesn't exhibit the bug.
0029  *
0030  * GCC also handles stack allocation suboptimally when calling noreturn
0031  * functions or calling __builtin_unreachable():
0032  *
0033  *   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
0034  *
0035  * We work around both of these issues by placing a volatile asm statement,
0036  * which GCC is prevented from reordering past, prior to __builtin_unreachable
0037  * calls.
0038  *
0039  * The .insn statement is required to ensure that any branches to the
0040  * statement, which sadly must be kept due to the asm statement, are known to
0041  * be branches to code and satisfy linker requirements for microMIPS kernels.
0042  */
0043 #undef barrier_before_unreachable
0044 #define barrier_before_unreachable() asm volatile(".insn")
0045 
0046 #define GCC_OFF_SMALL_ASM() "ZC"
0047 
0048 #ifdef CONFIG_CPU_MIPSR6
0049 #define MIPS_ISA_LEVEL "mips64r6"
0050 #define MIPS_ISA_ARCH_LEVEL MIPS_ISA_LEVEL
0051 #define MIPS_ISA_LEVEL_RAW mips64r6
0052 #define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW
0053 #elif defined(CONFIG_CPU_MIPSR5)
0054 #define MIPS_ISA_LEVEL "mips64r5"
0055 #define MIPS_ISA_ARCH_LEVEL MIPS_ISA_LEVEL
0056 #define MIPS_ISA_LEVEL_RAW mips64r5
0057 #define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW
0058 #else
0059 /* MIPS64 is a superset of MIPS32 */
0060 #define MIPS_ISA_LEVEL "mips64r2"
0061 #define MIPS_ISA_ARCH_LEVEL "arch=r4000"
0062 #define MIPS_ISA_LEVEL_RAW mips64r2
0063 #define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW
0064 #endif /* CONFIG_CPU_MIPSR6 */
0065 
0066 #endif /* _ASM_COMPILER_H */