Index: gcc/c-family/c-pretty-print.c
===================================================================
--- gcc/c-family/c-pretty-print.c	(revision 189318)
+++ gcc/c-family/c-pretty-print.c	(working copy)
@@ -474,6 +474,10 @@
       pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
       break;
 
+    case MOD_TYPE:
+      pp_c_ws_string (pp, "bswapped");
+      break;
+
     case VECTOR_TYPE:
     case COMPLEX_TYPE:
       if (code == COMPLEX_TYPE)
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 189318)
+++ gcc/c-family/c.opt	(working copy)
@@ -772,6 +772,10 @@
 C++ ObjC++ Joined RejectNegative UInteger Var(max_constexpr_depth) Init(512)
 -fconstexpr-depth=<number>	Specify maximum constexpr recursion depth
 
+fbig-endian
+C Var(flag_big_endian)
+Compile code outside system headers as big-endian
+
 fdebug-cpp
 C ObjC C++ ObjC++
 Emit debug annotations during preprocessing
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 189318)
+++ gcc/c-family/c-common.c	(working copy)
@@ -417,6 +417,9 @@
   { "_Fract",           RID_FRACT,     D_CONLY | D_EXT },
   { "_Accum",           RID_ACCUM,     D_CONLY | D_EXT },
   { "_Sat",             RID_SAT,       D_CONLY | D_EXT },
+  { "_NativeEndian",    RID_SAT,       D_CONLY | D_EXT },
+  { "_LittleEndian",    RID_SAT,       D_CONLY | D_EXT },
+  { "_BigEndian",       RID_SAT,       D_CONLY | D_EXT },
   { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
   { "_Noreturn",        RID_NORETURN,  D_CONLY },
   { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
@@ -10850,6 +10853,9 @@
     case RID_DFLOAT128:
     case RID_FRACT:
     case RID_ACCUM:
+    case RID_NATIVE:
+    case RID_LE:
+    case RID_BE:
     case RID_BOOL:
     case RID_WCHAR:
     case RID_CHAR16:
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 189318)
+++ gcc/c-family/c-common.h	(working copy)
@@ -105,6 +105,7 @@
   RID_TYPES_COMPATIBLE_P,      RID_BUILTIN_COMPLEX,	     RID_BUILTIN_SHUFFLE,
   RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
   RID_FRACT, RID_ACCUM,
+  RID_NATIVE, RID_BE, RID_LE,
 
   /* C11 */
   RID_ALIGNAS,
Index: gcc/c/c-convert.c
===================================================================
--- gcc/c/c-convert.c	(revision 189318)
+++ gcc/c/c-convert.c	(working copy)
@@ -92,6 +92,31 @@
 
   STRIP_TYPE_NOPS (e);
 
+  if (TREE_CODE (TREE_TYPE (expr)) == MOD_TYPE)
+    {
+      switch (TYPE_PRECISION (TREE_TYPE (expr)))
+	{
+	case 8:
+	  e = fold_build1 (NOP_EXPR, TREE_TYPE (expr), e);
+	  break;
+	case 16:
+	  e = fold_build_call_array_loc (loc, TREE_TYPE (expr),
+					 build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAP16M)),
+					 1, &e);
+	  break;
+	case 32:
+	  e = fold_build_call_array_loc (loc, TREE_TYPE (expr),
+					 build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAP32M)),
+					 1, &e);
+	  break;
+	case 64:
+	  e = fold_build_call_array_loc (loc, TREE_TYPE (expr),
+					 build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAP64M)),
+					 1, &e);
+	  break;
+	}
+    }
+
   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
     return fold_convert_loc (loc, type, expr);
   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
@@ -107,6 +132,31 @@
     case VOID_TYPE:
       return fold_convert_loc (loc, type, e);
 
+    case MOD_TYPE:
+      e = convert (TREE_TYPE (type), e);
+      switch (TYPE_PRECISION (TREE_TYPE (e)))
+	{
+	case 8:
+	  ret = fold_build1 (NOP_EXPR, TREE_TYPE (e), e);
+	  break;
+	case 16:
+	  ret = fold_build_call_array_loc (loc, type,
+					   build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAPM16)),
+					   1, &e);
+	  break;
+	case 32:
+	  ret = fold_build_call_array_loc (loc, type,
+					   build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAPM32)),
+					   1, &e);
+	  break;
+	case 64:
+	  ret = fold_build_call_array_loc (loc, type,
+					   build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_BSWAPM64)),
+					   1, &e);
+	  break;
+	}
+      goto maybe_fold;
+
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
       ret = convert_to_integer (type, e);
Index: gcc/c/c-parser.c
===================================================================
--- gcc/c/c-parser.c	(revision 189318)
+++ gcc/c/c-parser.c	(working copy)
@@ -2185,6 +2185,10 @@
 	  align = c_parser_alignas_specifier (parser);
 	  declspecs_add_alignas (loc, specs, align);
 	  break;
+	case RID_BE:
+	case RID_LE:
+	case RID_NATIVE:
+	  declspecs_add_endian (loc, specs, c_parser_peek_token (parser)->keyword);
 	default:
 	  goto out;
 	}
@@ -6229,7 +6233,7 @@
   switch (c_parser_peek_token (parser)->type)
     {
     case CPP_NUMBER:
-      expr.value = c_parser_peek_token (parser)->value;
+      expr.value = maybe_byteswap (cte_none, c_parser_peek_token (parser)->value);
       loc = c_parser_peek_token (parser)->location;
       c_parser_consume_token (parser);
       if (TREE_CODE (expr.value) == FIXED_CST
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 189318)
+++ gcc/c/c-typeck.c	(working copy)
@@ -1996,6 +1996,9 @@
   if (exp == error_mark_node)
     return error_mark_node;
 
+  if (TREE_CODE (type) == MOD_TYPE)
+    exp = convert (TREE_TYPE (type), exp);
+
   promoted_type = targetm.promoted_type (type);
   if (promoted_type)
     return convert (promoted_type, exp);
@@ -2309,6 +2312,9 @@
       || TREE_TYPE (index) == error_mark_node)
     return error_mark_node;
 
+  if (TREE_CODE (TREE_TYPE (index)) == MOD_TYPE)
+    index = convert (TREE_TYPE (TREE_TYPE (index)), index);
+
   if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
       /* Allow vector[index] but not index[vector].  */
@@ -3171,8 +3177,14 @@
 	  return -1;
 	}
       else
-	/* Convert `short' and `char' to full-size `int'.  */
-	parmval = default_conversion (val);
+	{
+	  /* Convert `short' and `char' to full-size `int'.  */
+	  parmval = default_conversion (val);
+	  if (C_TYPE_FUNCTION_SWAP_ARGS (TREE_TYPE (function)))
+	    parmval = convert (build_bswap_type (TREE_TYPE (parmval)),
+			       parmval);
+	      
+	}
 
       VEC_replace (tree, values, parmnum, parmval);
       if (parmval == error_mark_node)
@@ -5087,6 +5099,8 @@
 			tree function, int parmnum)
 {
   enum tree_code codel = TREE_CODE (type);
+  bool bswappedl = false;
+  bool bswappedr = false;
   tree orig_rhs = rhs;
   tree rhstype;
   enum tree_code coder;
@@ -5240,6 +5254,16 @@
   rhs = require_complete_type (rhs);
   if (rhs == error_mark_node)
     return error_mark_node;
+  if (codel == MOD_TYPE)
+    {
+      bswappedl = true;
+      codel = TREE_CODE (TREE_TYPE (type));
+    }
+  if (coder == MOD_TYPE)
+    {
+      bswappedr = true;
+      coder = TREE_CODE (TREE_TYPE (rhstype));
+    }
   /* A type converts to a reference to it.
      This code doesn't fully support references, it's just for the
      special case of va_start and va_copy.  */
@@ -5273,6 +5297,7 @@
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
+	   && !bswappedl && !bswappedr
 	   && vector_types_convertible_p (type, TREE_TYPE (rhs), true))
     return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
@@ -6011,6 +6036,7 @@
   tree inside_init = init;
   tree semantic_type = NULL_TREE;
   bool maybe_const = true;
+  bool type_bswapped = false;
 
   if (type == error_mark_node
       || !init
@@ -6018,6 +6044,12 @@
       || TREE_TYPE (init) == error_mark_node)
     return error_mark_node;
 
+  if (code == MOD_TYPE)
+    {
+      type_bswapped = true;
+      code = TREE_CODE (TREE_TYPE (type));
+    }
+
   STRIP_TYPE_NOPS (inside_init);
 
   if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR)
Index: gcc/c/c-tree.h
===================================================================
--- gcc/c/c-tree.h	(revision 189318)
+++ gcc/c/c-tree.h	(working copy)
@@ -40,6 +40,10 @@
    nonzero if the definition of the type has already started.  */
 #define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
 
+/* In a FUNCTION_TYPE, nonzero if variadic arguments should be passed
+   byte-swapped.  */
+#define C_TYPE_FUNCTION_ARG_SWAP(TYPE) TYPE_LANG_FLAG_3 (TYPE)
+
 /* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
    declarations whose type would be completed by completing that type.  */
 #define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
@@ -256,6 +260,13 @@
 			    enumerator.  */
 };
 
+enum c_typespec_endian {
+  cte_none,
+  cte_big,
+  cte_little,
+  cte_native
+};
+
 /* A sequence of declaration specifiers in C.  When a new declaration
    specifier is added, please update the enum c_declspec_word above
    accordingly.  */
@@ -287,6 +298,7 @@
   /* The kind of type specifier if one has been seen, ctsk_none
      otherwise.  */
   ENUM_BITFIELD (c_typespec_kind) typespec_kind : 3;
+  ENUM_BITFIELD (c_typespec_endian) endian_kind : 2;
   /* Whether any expressions in typeof specifiers may appear in
      constant expressions.  */
   BOOL_BITFIELD expr_const_operands : 1;
@@ -547,6 +559,8 @@
 extern struct c_declspecs *build_null_declspecs (void);
 extern struct c_declspecs *declspecs_add_qual (source_location,
 					       struct c_declspecs *, tree);
+extern struct c_declspecs *declspecs_add_endian (source_location,
+						 struct c_declspecs *, enum rid);
 extern struct c_declspecs *declspecs_add_type (location_t,
 					       struct c_declspecs *,
 					       struct c_typespec);
@@ -575,6 +589,8 @@
 
 extern struct c_switch *c_switch_stack;
 
+extern bool in_byteswap_context (void);
+extern tree maybe_byteswap (enum c_typespec_endian, tree);
 extern tree c_objc_common_truthvalue_conversion (location_t, tree);
 extern tree require_complete_type (tree);
 extern int same_translation_unit_p (const_tree, const_tree);
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 189318)
+++ gcc/c/c-decl.c	(working copy)
@@ -5637,6 +5637,8 @@
 	    type_quals = TYPE_UNQUALIFIED;
 
 	    type = build_function_type (type, arg_types);
+	    if (in_byteswap_context ())
+	      C_TYPE_FUNCTION_ARG_SWAP (type) = true;
 	    declarator = declarator->declarator;
 
 	    /* Set the TYPE_CONTEXTs for each tagged type which is local to
@@ -8800,6 +8802,7 @@
   ret->expr_const_operands = true;
   ret->declspecs_seen_p = false;
   ret->typespec_kind = ctsk_none;
+  ret->endian_kind = cte_none;
   ret->non_sc_seen_p = false;
   ret->typedef_p = false;
   ret->explicit_signed_p = false;
@@ -9691,6 +9694,50 @@
   return specs;
 }
 
+struct c_declspecs *
+declspecs_add_endian (source_location loc,
+		      struct c_declspecs *specs, enum rid id)
+{
+  if (specs->endian_kind != cte_none)
+    {
+      error ("incompatible endian specificier");
+      return specs;
+    }
+  specs->endian_kind = (id == RID_NATIVE ? cte_native
+			: id == RID_LE ? cte_little
+			: cte_big);
+}
+
+bool
+in_byteswap_context (void)
+{
+  if (in_system_header)
+    return false;
+  if (flag_big_endian && !BYTES_BIG_ENDIAN)
+    return true;
+  return false;
+}
+
+tree
+maybe_byteswap (enum c_typespec_endian kind, tree x)
+{
+  tree type;
+  if (kind == cte_native
+      || (kind == cte_big && BYTES_BIG_ENDIAN)
+      || (kind == cte_little && !BYTES_BIG_ENDIAN)
+      || (kind == cte_none && !in_byteswap_context ()))
+    return x;
+
+  if (TYPE_P (x))
+    type = x;
+  else
+    type = TREE_TYPE (x);
+  type = build_bswap_type (type);
+  if (TYPE_P (x))
+    return type;
+  return convert (type, x);
+}
+
 /* Combine "long", "short", "signed", "unsigned" and "_Complex" type
    specifiers with any other type specifier to determine the resulting
    type.  This is where ISO C checks on complex types are made, since
@@ -9791,9 +9838,10 @@
     case cts_int128:
       gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
       gcc_assert (!(specs->signed_p && specs->unsigned_p));
-      specs->type = (specs->unsigned_p
-		     ? int128_unsigned_type_node
-		     : int128_integer_type_node);
+      specs->type = maybe_byteswap (specs->endian_kind,
+				    specs->unsigned_p
+				    ? int128_unsigned_type_node
+				    : int128_integer_type_node);
       if (specs->complex_p)
 	{
 	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
@@ -9805,21 +9853,25 @@
       gcc_assert (!(specs->long_p && specs->short_p));
       gcc_assert (!(specs->signed_p && specs->unsigned_p));
       if (specs->long_long_p)
-	specs->type = (specs->unsigned_p
-		       ? long_long_unsigned_type_node
-		       : long_long_integer_type_node);
+	specs->type = maybe_byteswap (specs->endian_kind,
+				      specs->unsigned_p
+				      ? long_long_unsigned_type_node
+				      : long_long_integer_type_node);
       else if (specs->long_p)
-	specs->type = (specs->unsigned_p
-		       ? long_unsigned_type_node
-		       : long_integer_type_node);
+	specs->type = maybe_byteswap (specs->endian_kind,
+				      specs->unsigned_p
+				      ? long_unsigned_type_node
+				      : long_integer_type_node);
       else if (specs->short_p)
-	specs->type = (specs->unsigned_p
-		       ? short_unsigned_type_node
-		       : short_integer_type_node);
+	specs->type = maybe_byteswap (specs->endian_kind,
+				      specs->unsigned_p
+				      ? short_unsigned_type_node
+				      : short_integer_type_node);
       else
-	specs->type = (specs->unsigned_p
-		       ? unsigned_type_node
-		       : integer_type_node);
+	specs->type = maybe_byteswap (specs->endian_kind,
+				      specs->unsigned_p
+				      ? unsigned_type_node
+				      : integer_type_node);
       if (specs->complex_p)
 	{
 	  pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 189318)
+++ gcc/tree.c	(working copy)
@@ -1163,13 +1163,16 @@
 tree
 build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
 {
+  enum tree_code code = TREE_CODE (type);
   tree t;
   int ix = -1;
   int limit = 0;
 
   gcc_assert (type);
 
-  switch (TREE_CODE (type))
+  if (code == MOD_TYPE)
+    code = TREE_CODE (TREE_TYPE (type)); 
+  switch (code)
     {
     case NULLPTR_TYPE:
       gcc_assert (hi == 0 && low == 0);
@@ -7123,6 +7126,16 @@
   return val;
 }
 
+/* Construct a modified type that is the byte-swapped version of TYPE.  */
+tree
+build_bswap_type (tree type)
+{
+  tree t = make_node (MOD_TYPE);
+  TREE_TYPE (t) = type;
+  layout_type (t);
+  return t;
+}
+
 /* Constructors for pointer, array and function types.
    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
    constructed by language-dependent code, not here.)  */
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 189318)
+++ gcc/tree.h	(working copy)
@@ -4378,6 +4378,7 @@
 extern tree build_pointer_type (tree);
 extern tree build_reference_type_for_mode (tree, enum machine_mode, bool);
 extern tree build_reference_type (tree);
+extern tree build_bswap_type (tree);
 extern tree build_vector_type_for_mode (tree, enum machine_mode);
 extern tree build_vector_type (tree innertype, int nunits);
 extern tree build_opaque_vector_type (tree innertype, int nunits);
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 189318)
+++ gcc/builtins.c	(working copy)
@@ -6058,6 +6058,12 @@
     case BUILT_IN_BSWAP16:
     case BUILT_IN_BSWAP32:
     case BUILT_IN_BSWAP64:
+    case BUILT_IN_BSWAP16M:
+    case BUILT_IN_BSWAP32M:
+    case BUILT_IN_BSWAP64M:
+    case BUILT_IN_BSWAPM16:
+    case BUILT_IN_BSWAPM32:
+    case BUILT_IN_BSWAPM64:
       target = expand_builtin_bswap (target_mode, exp, target, subtarget);
       if (target)
 	return target;
@@ -8152,7 +8158,15 @@
 static tree
 fold_builtin_bswap (tree fndecl, tree arg)
 {
-  if (! validate_arg (arg, INTEGER_TYPE))
+  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+  if (fcode == BUILT_IN_BSWAP16M || fcode == BUILT_IN_BSWAP32M
+      || fcode == BUILT_IN_BSWAP64M)
+    {
+      if (!validate_arg (arg, MOD_TYPE)
+	  || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
+	return NULL_TREE;
+    }
+  else if (!validate_arg (arg, INTEGER_TYPE))
     return NULL_TREE;
 
   /* Optimize constant value.  */
@@ -8168,9 +8182,15 @@
 
       switch (DECL_FUNCTION_CODE (fndecl))
 	{
-	  case BUILT_IN_BSWAP16:
-	  case BUILT_IN_BSWAP32:
-	  case BUILT_IN_BSWAP64:
+	case BUILT_IN_BSWAP16:
+	case BUILT_IN_BSWAP32:
+	case BUILT_IN_BSWAP64:
+	case BUILT_IN_BSWAP16M:
+	case BUILT_IN_BSWAP32M:
+	case BUILT_IN_BSWAP64M:
+	case BUILT_IN_BSWAPM16:
+	case BUILT_IN_BSWAPM32:
+	case BUILT_IN_BSWAPM64:
 	    {
 	      int s;
 
@@ -10556,6 +10576,12 @@
     case BUILT_IN_BSWAP16:
     case BUILT_IN_BSWAP32:
     case BUILT_IN_BSWAP64:
+    case BUILT_IN_BSWAP16M:
+    case BUILT_IN_BSWAP32M:
+    case BUILT_IN_BSWAP64M:
+    case BUILT_IN_BSWAPM16:
+    case BUILT_IN_BSWAPM32:
+    case BUILT_IN_BSWAPM64:
       return fold_builtin_bswap (fndecl, arg0);
 
     CASE_INT_FN (BUILT_IN_FFS):
@@ -14336,6 +14362,12 @@
       case BUILT_IN_BSWAP16:
       case BUILT_IN_BSWAP32:
       case BUILT_IN_BSWAP64:
+      case BUILT_IN_BSWAP16M:
+      case BUILT_IN_BSWAP32M:
+      case BUILT_IN_BSWAP64M:
+      case BUILT_IN_BSWAPM16:
+      case BUILT_IN_BSWAPM32:
+      case BUILT_IN_BSWAPM64:
       case BUILT_IN_CLZ:
       case BUILT_IN_CLZIMAX:
       case BUILT_IN_CLZL:
Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 189318)
+++ gcc/builtin-types.def	(working copy)
@@ -79,6 +79,9 @@
 DEF_PRIMITIVE_TYPE (BT_UINT16, uint16_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT32, uint32_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT64, uint64_type_node)
+DEF_PRIMITIVE_TYPE (BT_UINT16_M, build_bswap_type (uint16_type_node))
+DEF_PRIMITIVE_TYPE (BT_UINT32_M, build_bswap_type (uint32_type_node))
+DEF_PRIMITIVE_TYPE (BT_UINT64_M, build_bswap_type (uint64_type_node))
 DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1))
 DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, (*lang_hooks.types.type_for_mode)
 				    (targetm.unwind_word_mode (), 1))
@@ -230,6 +233,12 @@
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16_M, BT_UINT16, BT_UINT16_M)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32_M, BT_UINT32, BT_UINT32_M)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64_M, BT_UINT64, BT_UINT64_M)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_M_UINT16, BT_UINT16_M, BT_UINT16)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_M_UINT32, BT_UINT32_M, BT_UINT32)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_M_UINT64, BT_UINT64_M, BT_UINT64)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
 
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def	(revision 189318)
+++ gcc/builtins.def	(working copy)
@@ -631,6 +631,12 @@
 DEF_GCC_BUILTIN        (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAP16M, "bswap16m", BT_FN_UINT16_UINT16_M, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAP32M, "bswap32m", BT_FN_UINT32_UINT32_M, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAP64M, "bswap64m", BT_FN_UINT64_UINT64_M, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAPM16, "bswapm16", BT_FN_UINT16_M_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAPM32, "bswapm32", BT_FN_UINT32_M_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAPM64, "bswapm64", BT_FN_UINT64_M_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
 /* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed.  */
 DEF_LIB_BUILTIN        (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c	(revision 189318)
+++ gcc/stor-layout.c	(working copy)
@@ -2069,6 +2069,14 @@
 	 of the language-specific code.  */
       gcc_unreachable ();
 
+    case MOD_TYPE:
+      SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type)));
+      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
+      TYPE_SIZE (type) = TYPE_SIZE (TREE_TYPE (type));
+      TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (TREE_TYPE (type));
+      TYPE_PRECISION (type) = TYPE_PRECISION (TREE_TYPE (type));
+      break;
+
     case BOOLEAN_TYPE:  /* Used for Java, Pascal, and Chill.  */
       if (TYPE_PRECISION (type) == 0)
 	TYPE_PRECISION (type) = 1; /* default to one byte/boolean.  */
Index: gcc/tree.def
===================================================================
--- gcc/tree.def	(revision 189318)
+++ gcc/tree.def	(working copy)
@@ -166,6 +166,10 @@
    automatically to the value it points to.  Used in C++.  */
 DEFTREECODE (REFERENCE_TYPE, "reference_type", tcc_type, 0)
 
+/* A modification of another type.  Used to describe byte-swapped
+   types.  */
+DEFTREECODE (MOD_TYPE, "mod_type", tcc_type, 0)
+
 /* The C++ decltype(nullptr) type.  */
 DEFTREECODE (NULLPTR_TYPE, "nullptr_type", tcc_type, 0)
 
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 189318)
+++ gcc/varasm.c	(working copy)
@@ -4508,6 +4508,8 @@
     }
 
   code = TREE_CODE (TREE_TYPE (exp));
+  if (code == MOD_TYPE)
+    code = TREE_CODE (TREE_TYPE (TREE_TYPE (exp)));
   thissize = int_size_in_bytes (TREE_TYPE (exp));
 
   /* Allow a constructor with no elements for any data type.
