Index: llvm/trunk/docs/LangRef.rst
===================================================================
--- llvm/trunk/docs/LangRef.rst
+++ llvm/trunk/docs/LangRef.rst
@@ -1905,8 +1905,15 @@
     must be a multiple of 8-bits. If omitted, the natural stack
     alignment defaults to "unspecified", which does not prevent any
     alignment promotions.
+``P<address space>``
+    Specifies the address space that corresponds to program memory.
+    Harvard architectures can use this to specify what space LLVM
+    should place things such as functions into. If omitted, the
+    program memory space defaults to the default address space of 0,
+    which corresponds to a Von Neumann architecture that has code
+    and data in the same space.
 ``A<address space>``
-    Specifies the address space of  objects created by '``alloca``'.
+    Specifies the address space of objects created by '``alloca``'.
     Defaults to the default address space of 0.
 ``p[n]:<size>:<abi>:<pref>:<idx>``
     This specifies the *size* of a pointer and its ``<abi>`` and
Index: llvm/trunk/include/llvm/IR/DataLayout.h
===================================================================
--- llvm/trunk/include/llvm/IR/DataLayout.h
+++ llvm/trunk/include/llvm/IR/DataLayout.h
@@ -115,6 +115,7 @@
 
   unsigned AllocaAddrSpace;
   unsigned StackNaturalAlign;
+  unsigned ProgramAddrSpace;
 
   enum ManglingModeT {
     MM_None,
@@ -199,6 +200,7 @@
     BigEndian = DL.isBigEndian();
     AllocaAddrSpace = DL.AllocaAddrSpace;
     StackNaturalAlign = DL.StackNaturalAlign;
+    ProgramAddrSpace = DL.ProgramAddrSpace;
     ManglingMode = DL.ManglingMode;
     LegalIntWidths = DL.LegalIntWidths;
     Alignments = DL.Alignments;
@@ -255,6 +257,8 @@
   unsigned getStackAlignment() const { return StackNaturalAlign; }
   unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
 
+  unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }
+
   bool hasMicrosoftFastStdCallMangling() const {
     return ManglingMode == MM_WinCOFFX86;
   }
Index: llvm/trunk/lib/IR/DataLayout.cpp
===================================================================
--- llvm/trunk/lib/IR/DataLayout.cpp
+++ llvm/trunk/lib/IR/DataLayout.cpp
@@ -184,6 +184,7 @@
   BigEndian = false;
   AllocaAddrSpace = 0;
   StackNaturalAlign = 0;
+  ProgramAddrSpace = 0;
   ManglingMode = MM_None;
   NonIntegralAddressSpaces.clear();
 
@@ -224,6 +225,13 @@
   return Bits / 8;
 }
 
+static unsigned getAddrSpace(StringRef R) {
+  unsigned AddrSpace = getInt(R);
+  if (!isUInt<24>(AddrSpace))
+    report_fatal_error("Invalid address space, must be a 24-bit integer");
+  return AddrSpace;
+}
+
 void DataLayout::parseSpecifier(StringRef Desc) {
   StringRepresentation = Desc;
   while (!Desc.empty()) {
@@ -372,10 +380,12 @@
       StackNaturalAlign = inBytes(getInt(Tok));
       break;
     }
+    case 'P': { // Function address space.
+      ProgramAddrSpace = getAddrSpace(Tok);
+      break;
+    }
     case 'A': { // Default stack/alloca address space.
-      AllocaAddrSpace = getInt(Tok);
-      if (!isUInt<24>(AllocaAddrSpace))
-        report_fatal_error("Invalid address space, must be a 24bit integer");
+      AllocaAddrSpace = getAddrSpace(Tok);
       break;
     }
     case 'm':
@@ -422,6 +432,7 @@
   bool Ret = BigEndian == Other.BigEndian &&
              AllocaAddrSpace == Other.AllocaAddrSpace &&
              StackNaturalAlign == Other.StackNaturalAlign &&
+             ProgramAddrSpace == Other.ProgramAddrSpace &&
              ManglingMode == Other.ManglingMode &&
              LegalIntWidths == Other.LegalIntWidths &&
              Alignments == Other.Alignments && Pointers == Other.Pointers;
Index: llvm/trunk/test/Assembler/datalayout-program-addrspace.ll
===================================================================
--- llvm/trunk/test/Assembler/datalayout-program-addrspace.ll
+++ llvm/trunk/test/Assembler/datalayout-program-addrspace.ll
@@ -0,0 +1,5 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+; CHECK: target datalayout = "P1"
+target datalayout = "P1"
+
Index: llvm/trunk/test/Assembler/invalid-datalayout-alloca-addrspace.ll
===================================================================
--- llvm/trunk/test/Assembler/invalid-datalayout-alloca-addrspace.ll
+++ llvm/trunk/test/Assembler/invalid-datalayout-alloca-addrspace.ll
@@ -1,4 +1,4 @@
 ; RUN: not llvm-as < %s 2>&1 | FileCheck %s
 
 target datalayout = "A16777216"
-; CHECK: Invalid address space, must be a 24bit integer
+; CHECK: Invalid address space, must be a 24-bit integer
Index: llvm/trunk/test/Assembler/invalid-datalayout-program-addrspace.ll
===================================================================
--- llvm/trunk/test/Assembler/invalid-datalayout-program-addrspace.ll
+++ llvm/trunk/test/Assembler/invalid-datalayout-program-addrspace.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+; CHECK: Invalid address space, must be a 24-bit integer
+target datalayout = "P16777216"