Index: gcc/genconditions.c
===================================================================
--- gcc/genconditions.c	2017-02-23 19:54:12.000000000 +0000
+++ gcc/genconditions.c	2017-07-13 09:18:20.866501621 +0100
@@ -67,6 +67,7 @@ #define CHECKING_P 0\n\
 #undef ENABLE_RTL_FLAG_CHECKING\n\
 #undef ENABLE_GC_CHECKING\n\
 #undef ENABLE_GC_ALWAYS_COLLECT\n\
+#define USE_ENUM_MODES\n\
 \n\
 #include \"coretypes.h\"\n\
 #include \"tm.h\"\n\
Index: gcc/genmodes.c
===================================================================
--- gcc/genmodes.c	2017-07-13 09:18:17.576867543 +0100
+++ gcc/genmodes.c	2017-07-13 09:18:20.866501621 +0100
@@ -1155,8 +1155,12 @@ enum machine_mode\n{");
 	printf ("%*s/* %s:%d */\n", 27 - count_, "",
 		 trim_filename (m->file), m->line);
 	printf ("#define HAVE_%smode\n", m->name);
-	printf ("#define %smode E_%smode\n",
+	printf ("#ifdef USE_ENUM_MODES\n");
+	printf ("#define %smode E_%smode\n", m->name, m->name);
+	printf ("#else\n");
+	printf ("#define %smode ((void) 0, E_%smode)\n",
 		m->name, m->name);
+	printf ("#endif\n");
       }
 
   puts ("  MAX_MACHINE_MODE,\n");
Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h	2017-07-02 10:05:20.996539436 +0100
+++ gcc/machmode.h	2017-07-13 09:18:20.866501621 +0100
@@ -20,6 +20,15 @@ Software Foundation; either version 3, o
 #ifndef HAVE_MACHINE_MODES
 #define HAVE_MACHINE_MODES
 
+extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES];
+extern const unsigned short mode_precision[NUM_MACHINE_MODES];
+extern const unsigned char mode_inner[NUM_MACHINE_MODES];
+extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
+extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
+extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
+extern const unsigned char mode_wider[NUM_MACHINE_MODES];
+extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
+
 /* Get the name of mode MODE as a string.  */
 
 extern const char * const mode_name[NUM_MACHINE_MODES];
@@ -174,22 +183,98 @@ #define CLASS_HAS_WIDER_MODES_P(CLASS)
 #define POINTER_BOUNDS_MODE_P(MODE)      \
   (GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS)
 
-/* Get the size in bytes and bits of an object of mode MODE.  */
+/* Return the base GET_MODE_SIZE value for MODE.  */
 
-extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES];
+ALWAYS_INLINE unsigned short
+mode_to_bytes (machine_mode mode)
+{
+#if GCC_VERSION >= 4001
+  return (__builtin_constant_p (mode)
+	  ? mode_size_inline (mode) : mode_size[mode]);
+#else
+  return mode_size[mode];
+#endif
+}
+
+/* Return the base GET_MODE_BITSIZE value for MODE.  */
+
+ALWAYS_INLINE unsigned short
+mode_to_bits (machine_mode mode)
+{
+  return mode_to_bytes (mode) * BITS_PER_UNIT;
+}
+
+/* Return the base GET_MODE_PRECISION value for MODE.  */
+
+ALWAYS_INLINE unsigned short
+mode_to_precision (machine_mode mode)
+{
+  return mode_precision[mode];
+}
+
+/* Return the base GET_MODE_INNER value for MODE.  */
+
+ALWAYS_INLINE machine_mode
+mode_to_inner (machine_mode mode)
+{
+#if GCC_VERSION >= 4001
+  return (machine_mode) (__builtin_constant_p (mode)
+			 ? mode_inner_inline (mode) : mode_inner[mode]);
+#else
+  return (machine_mode) mode_inner[mode];
+#endif
+}
+
+/* Return the base GET_MODE_UNIT_SIZE value for MODE.  */
+
+ALWAYS_INLINE unsigned char
+mode_to_unit_size (machine_mode mode)
+{
 #if GCC_VERSION >= 4001
-#define GET_MODE_SIZE(MODE) \
-  ((unsigned short) (__builtin_constant_p (MODE) \
-		     ? mode_size_inline (MODE) : mode_size[MODE]))
+  return (__builtin_constant_p (mode)
+	  ? mode_unit_size_inline (mode) : mode_unit_size[mode]);
 #else
-#define GET_MODE_SIZE(MODE)    ((unsigned short) mode_size[MODE])
+  return mode_unit_size[mode];
 #endif
-#define GET_MODE_BITSIZE(MODE) \
-  ((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT))
+}
+
+/* Return the base GET_MODE_UNIT_PRECISION value for MODE.  */
+
+ALWAYS_INLINE unsigned short
+mode_to_unit_precision (machine_mode mode)
+{
+#if GCC_VERSION >= 4001
+  return (__builtin_constant_p (mode)
+	  ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]);
+#else
+  return mode_unit_precision[mode];
+#endif
+}
+
+/* Return the base GET_MODE_NUNITS value for MODE.  */
+
+ALWAYS_INLINE unsigned short
+mode_to_nunits (machine_mode mode)
+{
+#if GCC_VERSION >= 4001
+  return (__builtin_constant_p (mode)
+	  ? mode_nunits_inline (mode) : mode_nunits[mode]);
+#else
+  return mode_nunits[mode];
+#endif
+}
+
+/* Get the size in bytes of an object of mode MODE.  */
+
+#define GET_MODE_SIZE(MODE) (mode_to_bytes (MODE))
+
+/* Get the size in bits of an object of mode MODE.  */
+
+#define GET_MODE_BITSIZE(MODE) (mode_to_bits (MODE))
 
 /* Get the number of value bits of an object of mode MODE.  */
-extern const unsigned short mode_precision[NUM_MACHINE_MODES];
-#define GET_MODE_PRECISION(MODE)  mode_precision[MODE]
+
+#define GET_MODE_PRECISION(MODE) (mode_to_precision (MODE))
 
 /* Get the number of integral bits of an object of mode MODE.  */
 extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES];
@@ -210,51 +295,22 @@ #define GET_MODE_MASK(MODE) mode_mask_ar
    mode of the vector elements.  For complex modes it is the mode of the real
    and imaginary parts.  For other modes it is MODE itself.  */
 
-extern const unsigned char mode_inner[NUM_MACHINE_MODES];
-#if GCC_VERSION >= 4001
-#define GET_MODE_INNER(MODE) \
-  ((machine_mode) (__builtin_constant_p (MODE) \
-			? mode_inner_inline (MODE) : mode_inner[MODE]))
-#else
-#define GET_MODE_INNER(MODE) ((machine_mode) mode_inner[MODE])
-#endif
+#define GET_MODE_INNER(MODE) (mode_to_inner (MODE))
 
 /* Get the size in bytes or bits of the basic parts of an
    object of mode MODE.  */
 
-extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
-#if GCC_VERSION >= 4001
-#define GET_MODE_UNIT_SIZE(MODE) \
-  ((unsigned char) (__builtin_constant_p (MODE) \
-		   ? mode_unit_size_inline (MODE) : mode_unit_size[MODE]))
-#else
-#define GET_MODE_UNIT_SIZE(MODE) mode_unit_size[MODE]
-#endif
+#define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE)
 
 #define GET_MODE_UNIT_BITSIZE(MODE) \
   ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
 
-extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
-#if GCC_VERSION >= 4001
-#define GET_MODE_UNIT_PRECISION(MODE) \
-  ((unsigned short) (__builtin_constant_p (MODE) \
-		    ? mode_unit_precision_inline (MODE)\
-		    : mode_unit_precision[MODE]))
-#else
-#define GET_MODE_UNIT_PRECISION(MODE) mode_unit_precision[MODE]
-#endif
-
+#define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE))
 
-/* Get the number of units in the object.  */
+/* Get the number of units in an object of mode MODE.  This is 2 for
+   complex modes and the number of elements for vector modes.  */
 
-extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
-#if GCC_VERSION >= 4001
-#define GET_MODE_NUNITS(MODE) \
-  ((unsigned char) (__builtin_constant_p (MODE) \
-		    ? mode_nunits_inline (MODE) : mode_nunits[MODE]))
-#else
-#define GET_MODE_NUNITS(MODE)  mode_nunits[MODE]
-#endif
+#define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE))
 
 /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI).  */
 
Index: gcc/system.h
===================================================================
--- gcc/system.h	2017-06-12 17:05:23.281759459 +0100
+++ gcc/system.h	2017-07-13 09:18:20.866501621 +0100
@@ -745,6 +745,12 @@ #define gcc_checking_assert(EXPR) gcc_as
 #define gcc_checking_assert(EXPR) ((void)(0 && (EXPR)))
 #endif
 
+#if GCC_VERSION >= 4000
+#define ALWAYS_INLINE inline __attribute__ ((always_inline))
+#else
+#define ALWAYS_INLINE inline
+#endif
+
 /* Use gcc_unreachable() to mark unreachable locations (like an
    unreachable default case of a switch.  Do not use gcc_assert(0).  */
 #if (GCC_VERSION >= 4005) && !ENABLE_ASSERT_CHECKING
Index: gcc/config/powerpcspe/powerpcspe-c.c
===================================================================
--- gcc/config/powerpcspe/powerpcspe-c.c	2017-07-13 09:18:19.088697749 +0100
+++ gcc/config/powerpcspe/powerpcspe-c.c	2017-07-13 09:18:20.865501731 +0100
@@ -6504,8 +6504,8 @@ altivec_resolve_overloaded_builtin (loca
     if (fcode == P6_OV_BUILTIN_CMPB)
       {
 	int overloaded_code;
-	int arg1_mode = TYPE_MODE (types[0]);
-	int arg2_mode = TYPE_MODE (types[1]);
+	machine_mode arg1_mode = TYPE_MODE (types[0]);
+	machine_mode arg2_mode = TYPE_MODE (types[1]);
 
 	if (nargs != 2)
 	  {
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	2017-05-03 08:46:30.890861653 +0100
+++ gcc/fortran/trans-types.c	2017-07-13 09:18:20.865501731 +0100
@@ -362,22 +362,23 @@ #define NAMED_SUBROUTINE(a,b,c,d) \
 void
 gfc_init_kinds (void)
 {
-  unsigned int mode;
+  machine_mode mode;
   int i_index, r_index, kind;
   bool saw_i4 = false, saw_i8 = false;
   bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
 
-  for (i_index = 0, mode = MIN_MODE_INT; mode <= MAX_MODE_INT; mode++)
+  for (i_index = 0, mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
+       mode = (machine_mode) ((int) mode + 1))
     {
       int kind, bitsize;
 
-      if (!targetm.scalar_mode_supported_p ((machine_mode) mode))
+      if (!targetm.scalar_mode_supported_p (mode))
 	continue;
 
       /* The middle end doesn't support constants larger than 2*HWI.
 	 Perhaps the target hook shouldn't have accepted these either,
 	 but just to be safe...  */
-      bitsize = GET_MODE_BITSIZE ((machine_mode) mode);
+      bitsize = GET_MODE_BITSIZE (mode);
       if (bitsize > 2*HOST_BITS_PER_WIDE_INT)
 	continue;
 
@@ -417,15 +418,16 @@ gfc_init_kinds (void)
   /* Set the maximum integer kind.  Used with at least BOZ constants.  */
   gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
 
-  for (r_index = 0, mode = MIN_MODE_FLOAT; mode <= MAX_MODE_FLOAT; mode++)
+  for (r_index = 0, mode = MIN_MODE_FLOAT; mode <= MAX_MODE_FLOAT;
+       mode = (machine_mode) ((int) mode + 1))
     {
       const struct real_format *fmt =
-	REAL_MODE_FORMAT ((machine_mode) mode);
+	REAL_MODE_FORMAT (mode);
       int kind;
 
       if (fmt == NULL)
 	continue;
-      if (!targetm.scalar_mode_supported_p ((machine_mode) mode))
+      if (!targetm.scalar_mode_supported_p (mode))
 	continue;
 
       /* Only let float, double, long double and __float128 go through.
