openMSX
unreachable.hh
Go to the documentation of this file.
1 #ifndef UNREACHABLE_HH
2 #define UNREACHABLE_HH
3 
4 // GCC targeting MIPS will generate bad code when marking certain code as
5 // unreachable. This is very noticeable in SDLVideoSystem::getWindowSize(),
6 // which does not seem to write the output arguments, making openMSX fail the
7 // creation of an SDL video mode since the requested size is rubbish.
8 //
9 // This compiler bug has been reported as:
10 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51861
11 //
12 // It turns out this was not a specific issue for MIPS, but it could affect all
13 // architectures which use branch delay slots (e.g. also AVR and SPARC).
14 //
15 // At this moment the bug in gcc has been fixed, but the most recent gcc-4.5.x
16 // and gcc-4.6.x releases still contain the bug.
17 //
18 // For openMSX, this UNREACHABLE-optimization is not very important (it does
19 // improve speed/code-size, but not in very critical locations). So we decided
20 // to only enable this optimization starting from gcc-4.7 or from gcc-4.5 for a
21 // few white-listed architectures that we know don't use delay slots.
22 
23 #if defined(NDEBUG)
24  // __builtin_unreachable() was introduced in gcc-4.5
25  #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
26  // gcc-4.7 or above
27  #define UNREACHABLE __builtin_unreachable()
28 
29  #elif ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) && (defined(__i386__) || defined(__x86_64__) || defined(__arm__)))
30  // gcc-4.5 or gcc-4.6 on x86, x86_64 or arm (all without delay slots)
31  #define UNREACHABLE __builtin_unreachable()
32 
33  #elif defined(_MSC_VER)
34  // visual studio
35  #define UNREACHABLE __assume(0)
36 
37  #else
38  // fall-back
39  #define UNREACHABLE /*nothing*/
40 
41  #endif
42 
43 #else
44  // asserts enabled
45  #include <cassert>
46  #define UNREACHABLE assert(false)
47 
48 #endif
49 
50 #endif // UNREACHABLE_HH