diff --git a/gcc/config/aarch64/aarch64-elf-raw.h b/gcc/config/aarch64/aarch64-elf-raw.h
index 66ac75d..d9ec53f 100644
--- a/gcc/config/aarch64/aarch64-elf-raw.h
+++ b/gcc/config/aarch64/aarch64-elf-raw.h
@@ -22,8 +22,6 @@
 #ifndef GCC_AARCH64_ELF_RAW_H
 #define GCC_AARCH64_ELF_RAW_H
 
-#define AARCH64_DEFAULT_MEM_MODEL   AARCH64_MEM_MODEL_SMALL
-
 #define STARTFILE_SPEC " crti%O%s crtbegin%O%s crt0%O%s"
 #define ENDFILE_SPEC " crtend%O%s crtn%O%s"
 
diff --git a/gcc/config/aarch64/aarch64-linux.h b/gcc/config/aarch64/aarch64-linux.h
index 7b44982..7649eba 100644
--- a/gcc/config/aarch64/aarch64-linux.h
+++ b/gcc/config/aarch64/aarch64-linux.h
@@ -50,6 +50,4 @@
     }						\
   while (0)
 
-#define AARCH64_DEFAULT_MEM_MODEL   AARCH64_MEM_MODEL_SMALL
-
 #endif  /* GCC_AARCH64_LINUX_H */
diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
index 98d4519..8878829 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -35,4 +35,24 @@ enum aarch64_processor
   aarch64_none
 };
 
+/* The code model defines the address generation strategy.
+   Most have a PIC and non-PIC variant.  */
+enum aarch64_code_model {
+  /* Static code and data fit within a 1MB region.
+     Not fully implemented, mostly treated as SMALL.  */
+  AARCH64_CMODEL_TINY,
+  /* Static code, data and GOT/PLT fit within a 1MB region.
+     Not fully implemented, mostly treated as SMALL_PIC.  */
+  AARCH64_CMODEL_TINY_PIC,
+  /* Static code and data fit within a 4GB region.
+     The default non-PIC code model.  */
+  AARCH64_CMODEL_SMALL,
+  /* Static code, data and GOT/PLT fit within a 4GB region.
+     The default PIC code model.  */
+  AARCH64_CMODEL_SMALL_PIC,
+  /* No assumptions about addresses of code and data.
+     The PIC variant is not yet implemented.  */
+  AARCH64_CMODEL_LARGE,
+};
+
 #endif
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index e6f02b9..130b0dd 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -76,7 +76,7 @@ enum aarch64_symbol_context
    or
    str x1, [x0, :lo12:foo]
 
-   This corresponds to the small memory model of the compiler.
+   This corresponds to the small code model of the compiler.
 
    SYMBOL_SMALL_GOT: Similar to the one above but this
    gives us the GOT entry of the symbol being referred to :
@@ -100,7 +100,7 @@ enum aarch64_symbol_context
    SYMBOL_FORCE_TO_MEM : Global variables are addressed using
    constant pool. All variable addresses are spilled into constant
    pools. The constant pools themselves are addressed using PC
-   relative accesses. This only works for the large memory model.
+   relative accesses.  This only works for the large code model.
  */
 enum aarch64_symbol_type
 {
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 34d0475..a2dd224 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -86,9 +86,8 @@ struct aarch64_address_info {
   enum aarch64_symbol_type symbol_type;
 };
 
-/* Set up default memory model.  */
-enum aarch64_memory_model
-aarch64_default_mem_model = AARCH64_DEFAULT_MEM_MODEL;
+/* The current code model.  */
+enum aarch64_code_model aarch64_cmodel;
 
 #ifdef HAVE_AS_TLS
 #undef TARGET_HAVE_TLS
@@ -633,7 +632,6 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
 	  return;
 
 	default:
-	  error ("Unimplemented memory model in generating symbolic references.  */");
 	  gcc_unreachable ();
 	}
     }
@@ -3879,14 +3877,11 @@ aarch64_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
 			    rtx x ATTRIBUTE_UNUSED,
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
-  /* Force all constant pool entries into the current function
-     section.  XXX Will need fixing for Large PIC not to push relocatable
-     constants into text section.  */
-  gcc_assert (!flag_pic || (flag_pic && (aarch64_default_mem_model != AARCH64_MEM_MODEL_LARGE)));
+  /* Force all constant pool entries into the current function section.  */
   return function_section (current_function_decl);
 }
 
-
+
 /* Costs.  */
 
 /* Helper function for rtx cost calculation.  Strip a shift expression
@@ -4334,7 +4329,7 @@ aarch64_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
   return aarch64_tune_params->memmov_cost;
 }
 
-static void initialize_aarch64_memory_model (void);
+static void initialize_aarch64_code_model (void);
 
 /* Tuning parameters.  */
 
@@ -4615,13 +4610,7 @@ aarch64_override_options (void)
       aarch64_parse_tune ();
     }
 
-  if (flag_pic > 0)
-    {
-      aarch64_default_mem_model = AARCH64_MEM_MODEL_SMALL_PIC;
-    }
-
-  if (aarch64_mem_model_string != NULL)
-    initialize_aarch64_memory_model ();
+  initialize_aarch64_code_model ();
 
   aarch64_build_bitmask_table ();
 
@@ -4693,46 +4682,29 @@ aarch64_init_expanders (void)
   init_machine_status = aarch64_init_machine_status;
 }
 
-/* A checking mechanism for the implementation of the various
-    memory models.  */
-struct aarch64_mem_model
-{
-  const char * mem_model;
-  enum aarch64_memory_model model;
-  enum aarch64_memory_model model_pic;
-};
-
-
-static const struct aarch64_mem_model aarch64_memory_models[] =
-{
-  {"small", AARCH64_MEM_MODEL_SMALL, AARCH64_MEM_MODEL_SMALL_PIC},
-  {"large", AARCH64_MEM_MODEL_LARGE, AARCH64_MEM_MODEL_UNIMPLEMENTED}
-};
-
-void
-initialize_aarch64_memory_model (void)
+/* A checking mechanism for the implementation of the various code models.  */
+static void
+initialize_aarch64_code_model (void)
 {
-  unsigned i;
-  aarch64_default_mem_model = AARCH64_MEM_MODEL_UNIMPLEMENTED;
-  for (i = 0;
-       i < sizeof (aarch64_memory_models) / sizeof (struct aarch64_mem_model);
-       i++)
-    {
-      if (strcmp (aarch64_mem_model_string,
-		  aarch64_memory_models[i].mem_model) == 0)
-	{
-	  if (flag_pic == 0)
-	    aarch64_default_mem_model = aarch64_memory_models[i].model;
-	  else
-	    aarch64_default_mem_model = aarch64_memory_models[i].model_pic;
-	  break;
-	}
-    }
-
-  if (aarch64_default_mem_model == AARCH64_MEM_MODEL_UNIMPLEMENTED)
-    error ("Unimplemented / Illegal memory model `%s'%s",
-	   aarch64_mem_model_string,
-	   flag_pic ? " with -fPIC" : "");
+   if (flag_pic)
+     {
+       switch (aarch64_cmodel_var)
+	 {
+	 case AARCH64_CMODEL_TINY:
+	   aarch64_cmodel = AARCH64_CMODEL_TINY_PIC;
+	   break;
+	 case AARCH64_CMODEL_SMALL:
+	   aarch64_cmodel == AARCH64_CMODEL_SMALL_PIC;
+	   break;
+	 case AARCH64_CMODEL_LARGE:
+	   sorry ("code model %qs with -f%s", "large",
+		  flag_pic > 1 ? "PIC" : "pic");
+	 default:
+	   gcc_unreachable ();
+	 }
+     }
+   else
+     aarch64_cmodel = aarch64_cmodel_var;
 }
 
 /* Return true if SYMBOL_REF X binds locally.  */
@@ -4791,13 +4763,15 @@ aarch64_classify_symbol (rtx x,
 {
   if (GET_CODE (x) == LABEL_REF)
     {
-      switch (aarch64_default_mem_model)
+      switch (aarch64_cmodel)
 	{
-	case AARCH64_MEM_MODEL_LARGE:
+	case AARCH64_CMODEL_LARGE:
 	  return SYMBOL_FORCE_TO_MEM;
 
-	case AARCH64_MEM_MODEL_SMALL_PIC:
-	case AARCH64_MEM_MODEL_SMALL:
+	case AARCH64_CMODEL_TINY_PIC:
+	case AARCH64_CMODEL_TINY:
+	case AARCH64_CMODEL_SMALL_PIC:
+	case AARCH64_CMODEL_SMALL:
 	  return SYMBOL_SMALL_ABSOLUTE;
 
 	default:
@@ -4807,12 +4781,13 @@ aarch64_classify_symbol (rtx x,
 
   gcc_assert (GET_CODE (x) == SYMBOL_REF);
 
-  switch (aarch64_default_mem_model)
+  switch (aarch64_cmodel)
     {
-    case AARCH64_MEM_MODEL_LARGE:
+    case AARCH64_CMODEL_LARGE:
       return SYMBOL_FORCE_TO_MEM;
 
-    case AARCH64_MEM_MODEL_SMALL:
+    case AARCH64_CMODEL_TINY:
+    case AARCH64_CMODEL_SMALL:
 
       /* This is needed to get DFmode, TImode constants
 	 to be loaded off the constant pool. Is
@@ -4832,7 +4807,8 @@ aarch64_classify_symbol (rtx x,
 
       return SYMBOL_SMALL_ABSOLUTE;
 
-    case AARCH64_MEM_MODEL_SMALL_PIC:
+    case AARCH64_CMODEL_TINY_PIC:
+    case AARCH64_CMODEL_SMALL_PIC:
 
       if (CONSTANT_POOL_ADDRESS_P (x))
 	return SYMBOL_FORCE_TO_MEM;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 4a39d0b..fc1f36d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -801,48 +801,18 @@ enum tls_dialect
   TLS_DIALECT_DESC
 };
 
-/* Used for the code generation strategy dependent on the
-   memory model being used.
-
-   There are multiple memory models available.
-   Each one has a PIC and a non-PIC variant.
-
-   Tiny.
-   AARCH64_MEM_MODEL_TINY.
-   Unimplemented as of now.
-
-   Small.
-   AARCH64_MEM_MODEL_SMALL
-   Generate in sequences of adrh , ldrb and or
-   strb.
-
-   Large.
-   AARCH64_MEM_MODEL_LARGE
-   Default model as of now.
-*/
-enum aarch64_memory_model
-{
-  AARCH64_MEM_MODEL_UNIMPLEMENTED,
-  AARCH64_MEM_MODEL_TINY,
-  AARCH64_MEM_MODEL_SMALL,
-  AARCH64_MEM_MODEL_LARGE,
-  AARCH64_MEM_MODEL_TINY_PIC,
-  AARCH64_MEM_MODEL_SMALL_PIC,
-  AARCH64_MEM_MODEL_LARGE_PIC
-};
-
 extern enum tls_dialect aarch64_tls_dialect;
 
-extern enum aarch64_memory_model aarch64_default_mem_model;
+extern enum aarch64_code_model aarch64_cmodel;
 
 /* When using the tiny addressing model conditional and unconditional branches
    can span the whole of the available address space (1MB).  */
-#define HAS_LONG_COND_BRANCH					\
-  (aarch64_default_mem_model == AARCH64_MEM_MODEL_TINY		\
-   || aarch64_default_mem_model == AARCH64_MEM_MODEL_TINY_PIC)
+#define HAS_LONG_COND_BRANCH				\
+  (aarch64_cmodel == AARCH64_CMODEL_TINY		\
+   || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC)
 
-#define HAS_LONG_UNCOND_BRANCH					\
-  (aarch64_default_mem_model == AARCH64_MEM_MODEL_TINY		\
-   || aarch64_default_mem_model == AARCH64_MEM_MODEL_TINY_PIC)
+#define HAS_LONG_UNCOND_BRANCH				\
+  (aarch64_cmodel == AARCH64_CMODEL_TINY		\
+   || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC)
 
 #endif /* GCC_AARCH64_H */
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 3cdd335..0879507 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -21,6 +21,21 @@
 HeaderInclude
 config/aarch64/aarch64-opts.h
 
+; The code model option names for -mcmodel.
+
+Enum
+Name(cmodel) Type(enum aarch64_code_model)
+The code model option names for -mcmodel:
+
+EnumValue
+Enum(cmodel) String(tiny) Value(AARCH64_CMODEL_TINY)
+
+EnumValue
+Enum(cmodel) String(small) Value(AARCH64_CMODEL_SMALL)
+
+EnumValue
+Enum(cmodel) String(large) Value(AARCH64_CMODEL_LARGE)
+
 ; The cpu/arch option names to use in cpu/arch selection.
 
 Variable
@@ -45,8 +60,8 @@ Target Report RejectNegative InverseMask(BIG_END)
 Assume target CPU is configured as little endian
 
 mcmodel=
-Target RejectNegative Joined Var(aarch64_mem_model_string)
-Specify the PIC memory model - tiny, small, compact, medium, large
+Target RejectNegative Joined Enum(cmodel) Var(aarch64_cmodel_var) Init(AARCH64_CMODEL_SMALL)
+Specify the code model
 
 mstrict-align
 Target Report RejectNegative Mask(STRICT_ALIGN)
