Index: include/llvm/Bitcode/LLVMBitCodes.h
===================================================================
--- include/llvm/Bitcode/LLVMBitCodes.h
+++ include/llvm/Bitcode/LLVMBitCodes.h
@@ -397,7 +397,8 @@
     ATTR_KIND_IN_ALLOCA = 38,
     ATTR_KIND_NON_NULL = 39,
     ATTR_KIND_JUMP_TABLE = 40,
-    ATTR_KIND_DEREFERENCEABLE = 41
+    ATTR_KIND_DEREFERENCEABLE = 41,
+    ATTR_KIND_HWREG = 42
   };
 
   enum ComdatSelectionKindCodes {
Index: include/llvm/IR/Argument.h
===================================================================
--- include/llvm/IR/Argument.h
+++ include/llvm/IR/Argument.h
@@ -65,6 +65,10 @@
   /// dereferenceable. Otherwise, zero is returned.
   uint64_t getDereferenceableBytes() const;
 
+  /// \brief If this argument has the hwreg attribute on it in its containing
+  /// function, return the physical register id. Otherwise, zero is returned.
+  uint64_t getHWReg() const;
+
   /// \brief Return true if this argument has the byval attribute on it in its
   /// containing function.
   bool hasByValAttr() const;
Index: include/llvm/IR/Attributes.h
===================================================================
--- include/llvm/IR/Attributes.h
+++ include/llvm/IR/Attributes.h
@@ -89,6 +89,7 @@
                            ///< often, so lazy binding isn't worthwhile
     NonNull,               ///< Pointer is known to be not null
     Dereferenceable,       ///< Pointer is known to be dereferenceable
+    HWReg,                 ///< Parameter is in a physical register
     NoRedZone,             ///< Disable redzone
     NoReturn,              ///< Mark the function as not returning
     NoUnwind,              ///< Function doesn't unwind stack
@@ -136,6 +137,7 @@
   static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
   static Attribute getWithDereferenceableBytes(LLVMContext &Context,
                                               uint64_t Bytes);
+  static Attribute getWithHWReg(LLVMContext &Context, uint64_t Reg);
 
   //===--------------------------------------------------------------------===//
   // Attribute Accessors
@@ -185,6 +187,9 @@
   /// dereferenceable attribute (or zero if unknown).
   uint64_t getDereferenceableBytes() const;
 
+  /// \brief Extract the register id of hwreg parameter (or zero if unknown).
+  uint64_t getHWReg() const;
+
   /// \brief The Attribute is converted to a string of equivalent mnemonic. This
   /// is, presumably, for writing out the mnemonics for the assembly writer.
   std::string getAsString(bool InAttrGrp = false) const;
@@ -331,6 +336,9 @@
   /// \brief Get the number of dereferenceable bytes (or zero if unknown).
   uint64_t getDereferenceableBytes(unsigned Index) const;
 
+  /// \brief Extract the register id of hwreg parameter. (or zero if unknown).
+  uint64_t getHWReg(unsigned Index) const;
+
   /// \brief Return the attributes at the index as a string.
   std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
 
@@ -411,14 +419,15 @@
   uint64_t Alignment;
   uint64_t StackAlignment;
   uint64_t DerefBytes;
+  uint64_t HWReg;
 public:
   AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {}
   explicit AttrBuilder(uint64_t Val)
-    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0), HWReg(0) {
     addRawValue(Val);
   }
   AttrBuilder(const Attribute &A)
-    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0), HWReg(0) {
     addAttribute(A);
   }
   AttrBuilder(AttributeSet AS, unsigned Idx);
@@ -476,6 +485,9 @@
   /// attribute exists (zero is returned otherwise).
   uint64_t getDereferenceableBytes() const { return DerefBytes; }
 
+  /// \brief Extract the register id of hwreg parameter (0=unknown).
+  uint64_t getHWReg() const { return HWReg; }
+
   /// \brief This turns an int alignment (which must be a power of 2) into the
   /// form used internally in Attribute.
   AttrBuilder &addAlignmentAttr(unsigned Align);
@@ -488,6 +500,10 @@
   /// internally in Attribute.
   AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
 
+  /// \brief This turns the register id into the form used internally in
+  /// Attribute.
+  AttrBuilder &addHWRegAttr(uint64_t Reg);
+
   /// \brief Return true if the builder contains no target-independent
   /// attributes.
   bool empty() const { return Attrs.none(); }
Index: include/llvm/IR/CallSite.h
===================================================================
--- include/llvm/IR/CallSite.h
+++ include/llvm/IR/CallSite.h
@@ -223,6 +223,11 @@
     CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
   }
 
+  /// @brief Extract the hwreg register for a parameter (0=unknown).
+  uint64_t getHWReg(uint16_t i) const {
+    CALLSITE_DELEGATE_GETTER(getHWReg(i));
+  }
+
   /// \brief Return true if the call should not be treated as a call to a
   /// builtin.
   bool isNoBuiltin() const {
Index: include/llvm/IR/Function.h
===================================================================
--- include/llvm/IR/Function.h
+++ include/llvm/IR/Function.h
@@ -234,6 +234,11 @@
     return AttributeSets.getDereferenceableBytes(i);
   }
 
+  /// @brief Extract the register id of hwreg parameter (0=unknown).
+  uint64_t getHWReg(unsigned i) const {
+    return AttributeSets.getHWReg(i);
+  }
+
   /// @brief Determine if the function does not access memory.
   bool doesNotAccessMemory() const {
     return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Index: include/llvm/IR/Instructions.h
===================================================================
--- include/llvm/IR/Instructions.h
+++ include/llvm/IR/Instructions.h
@@ -1433,6 +1433,11 @@
     return AttributeList.getDereferenceableBytes(i);
   }
 
+  /// \brief Extract the register id of a hwreg attribute (0=unknown).
+  uint64_t getHWReg(unsigned i) const {
+    return AttributeList.getHWReg(i);
+  }
+
   /// \brief Return true if the call should not be treated as a call to a
   /// builtin.
   bool isNoBuiltin() const {
@@ -3125,6 +3130,11 @@
     return AttributeList.getDereferenceableBytes(i);
   }
 
+  /// \brief Extract the register id for a hwreg parameter (0=unknown).
+  uint64_t getHWReg(unsigned i) const {
+    return AttributeList.getHWReg(i);
+  }
+
   /// \brief Return true if the call should not be treated as a call to a
   /// builtin.
   bool isNoBuiltin() const {
Index: include/llvm/Target/TargetCallingConv.h
===================================================================
--- include/llvm/Target/TargetCallingConv.h
+++ include/llvm/Target/TargetCallingConv.h
@@ -54,11 +54,15 @@
     static const uint64_t InConsecutiveRegs      = 0x1ULL<<63; ///< Struct size
     static const uint64_t InConsecutiveRegsOffs  = 63;
 
+    static const uint64_t ExtHWReg       = 0xFFFFULL<<0;
+    static const uint64_t ExtHWRegOffs   = 0;
+
     static const uint64_t One            = 1ULL; ///< 1 of this type, for shifts
 
     uint64_t Flags;
+    uint64_t Extension;
   public:
-    ArgFlagsTy() : Flags(0) { }
+    ArgFlagsTy() : Flags(0), Extension(0) { }
 
     bool isZExt()      const { return Flags & ZExt; }
     void setZExt()     { Flags |= One << ZExtOffs; }
@@ -120,6 +124,14 @@
 
     /// getRawBits - Represent the flags as a bunch of bits.
     uint64_t getRawBits() const { return Flags; }
+
+    bool isHWReg() const { return Extension & ExtHWReg; }
+    void setHWReg(unsigned Reg) {
+      Extension = (Extension & ~ExtHWReg) | (uint64_t)Reg<<ExtHWRegOffs;
+    }
+    unsigned getHWReg() {
+      return (unsigned)((Extension & ExtHWReg) >> ExtHWRegOffs);
+    }
   };
 
   /// InputArg - This struct carries flags and type information about a
Index: lib/AsmParser/LLLexer.cpp
===================================================================
--- lib/AsmParser/LLLexer.cpp
+++ lib/AsmParser/LLLexer.cpp
@@ -599,6 +599,7 @@
   KEYWORD(inalloca);
   KEYWORD(cold);
   KEYWORD(dereferenceable);
+  KEYWORD(hwreg);
   KEYWORD(inlinehint);
   KEYWORD(inreg);
   KEYWORD(jumptable);
Index: lib/AsmParser/LLParser.h
===================================================================
--- lib/AsmParser/LLParser.h
+++ lib/AsmParser/LLParser.h
@@ -224,6 +224,7 @@
     bool ParseOptionalCallingConv(unsigned &CC);
     bool ParseOptionalAlignment(unsigned &Alignment);
     bool ParseOptionalDereferenceableBytes(uint64_t &Bytes);
+    bool ParseOptionalHWReg(uint64_t &Reg);
     bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope,
                                AtomicOrdering &Ordering);
     bool ParseOrdering(AtomicOrdering &Ordering);
Index: lib/AsmParser/LLParser.cpp
===================================================================
--- lib/AsmParser/LLParser.cpp
+++ lib/AsmParser/LLParser.cpp
@@ -976,6 +976,7 @@
       break;
     case lltok::kw_byval:
     case lltok::kw_dereferenceable:
+    case lltok::kw_hwreg:
     case lltok::kw_inalloca:
     case lltok::kw_nest:
     case lltok::kw_noalias:
@@ -1225,6 +1226,13 @@
       B.addDereferenceableAttr(Bytes);
       continue;
     }
+    case lltok::kw_hwreg: {
+      uint64_t Reg;
+      if (ParseOptionalHWReg(Reg))
+        return true;
+      B.addHWRegAttr(Reg);
+      continue;
+    }
     case lltok::kw_inalloca:        B.addAttribute(Attribute::InAlloca); break;
     case lltok::kw_inreg:           B.addAttribute(Attribute::InReg); break;
     case lltok::kw_nest:            B.addAttribute(Attribute::Nest); break;
@@ -1303,6 +1311,7 @@
     case lltok::kw_nocapture:
     case lltok::kw_returned:
     case lltok::kw_sret:
+    case lltok::kw_hwreg:
       HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
       break;
 
@@ -1538,6 +1547,23 @@
   return false;
 }
 
+/// ParseOptionalHWReg
+///   ::= 'hwreg' '(' 4 ')'
+bool LLParser::ParseOptionalHWReg(uint64_t &Reg) {
+  Reg = 0;
+  if (!EatIfPresent(lltok::kw_hwreg))
+    return false;
+  LocTy ParenLoc = Lex.getLoc();
+  if (!EatIfPresent(lltok::lparen))
+    return Error(ParenLoc, "expected '('");
+  LocTy DerefLoc = Lex.getLoc();
+  if (ParseUInt64(Reg)) return true;
+  ParenLoc = Lex.getLoc();
+  if (!EatIfPresent(lltok::rparen))
+    return Error(DerefLoc, "expected ')'");
+  return false;
+}
+
 /// ParseOptionalCommaAlign
 ///   ::=
 ///   ::= ',' align 4
Index: lib/AsmParser/LLToken.h
===================================================================
--- lib/AsmParser/LLToken.h
+++ lib/AsmParser/LLToken.h
@@ -106,6 +106,7 @@
     kw_inalloca,
     kw_cold,
     kw_dereferenceable,
+    kw_hwreg,
     kw_inlinehint,
     kw_inreg,
     kw_jumptable,
Index: lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- lib/Bitcode/Reader/BitcodeReader.cpp
+++ lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1098,6 +1098,8 @@
     return Attribute::NonNull;
   case bitc::ATTR_KIND_DEREFERENCEABLE:
     return Attribute::Dereferenceable;
+  case bitc::ATTR_KIND_HWREG:
+    return Attribute::HWReg;
   case bitc::ATTR_KIND_NO_RED_ZONE:
     return Attribute::NoRedZone;
   case bitc::ATTR_KIND_NO_RETURN:
@@ -1214,6 +1216,8 @@
             B.addStackAlignmentAttr(Record[++i]);
           else if (Kind == Attribute::Dereferenceable)
             B.addDereferenceableAttr(Record[++i]);
+          else if (Kind == Attribute::HWReg)
+            B.addHWRegAttr(Record[++i]);
         } else {                     // String attribute
           assert((Record[i] == 3 || Record[i] == 4) &&
                  "Invalid attribute group entry");
Index: lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- lib/Bitcode/Writer/BitcodeWriter.cpp
+++ lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -200,6 +200,8 @@
     return bitc::ATTR_KIND_NON_NULL;
   case Attribute::Dereferenceable:
     return bitc::ATTR_KIND_DEREFERENCEABLE;
+  case Attribute::HWReg:
+    return bitc::ATTR_KIND_HWREG;
   case Attribute::NoRedZone:
     return bitc::ATTR_KIND_NO_RED_ZONE;
   case Attribute::NoReturn:
Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7507,6 +7507,8 @@
         Flags.setSRet();
       if (F.getAttributes().hasAttribute(Idx, Attribute::ByVal))
         Flags.setByVal();
+      if (F.getAttributes().hasAttribute(Idx, Attribute::HWReg))
+        Flags.setHWReg(F.getAttributes().getHWReg(Idx));
       if (F.getAttributes().hasAttribute(Idx, Attribute::InAlloca)) {
         Flags.setInAlloca();
         // Set the byval flag for CCAssignFn callbacks that don't know about
Index: lib/IR/AttributeImpl.h
===================================================================
--- lib/IR/AttributeImpl.h
+++ lib/IR/AttributeImpl.h
@@ -117,7 +117,7 @@
       : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
     assert(
         (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment ||
-         Kind == Attribute::Dereferenceable) &&
+         Kind == Attribute::Dereferenceable || Kind == Attribute::HWReg) &&
         "Wrong kind for int attribute!");
   }
 
@@ -166,6 +166,7 @@
   unsigned getAlignment() const;
   unsigned getStackAlignment() const;
   uint64_t getDereferenceableBytes() const;
+  uint64_t getHWReg() const;
   std::string getAsString(bool InAttrGrp) const;
 
   typedef const Attribute *iterator;
Index: lib/IR/Attributes.cpp
===================================================================
--- lib/IR/Attributes.cpp
+++ lib/IR/Attributes.cpp
@@ -94,6 +94,12 @@
   return get(Context, Dereferenceable, Bytes);
 }
 
+Attribute Attribute::getWithHWReg(LLVMContext &Context,
+                                      uint64_t Reg) {
+  assert(Reg && "Reg must be non-zero.");
+  return get(Context, HWReg, Reg);
+}
+
 //===----------------------------------------------------------------------===//
 // Attribute Accessor Methods
 //===----------------------------------------------------------------------===//
@@ -170,6 +176,13 @@
   return pImpl->getValueAsInt();
 }
 
+/// This returns the hwreg attribute or zero of not used.
+uint64_t Attribute::getHWReg() const {
+  assert(hasAttribute(Attribute::HWReg) &&
+         "Trying to get hwreg register from non-hwreg attribute!");
+  return pImpl->getValueAsInt();
+}
+
 std::string Attribute::getAsString(bool InAttrGrp) const {
   if (!pImpl) return "";
 
@@ -291,6 +304,20 @@
     return Result;
   }
 
+  if (hasAttribute(Attribute::HWReg)) {
+    std::string Result;
+    Result += "hwreg";
+    if (InAttrGrp) {
+      Result += "=";
+      Result += utostr(getValueAsInt());
+    } else {
+      Result += "(";
+      Result += utostr(getValueAsInt());
+      Result += ")";
+    }
+    return Result;
+  }
+
   // Convert target-dependent attributes to strings of the form:
   //
   //   "kind"
@@ -426,6 +453,7 @@
   case Attribute::InAlloca:        return 1ULL << 43;
   case Attribute::NonNull:         return 1ULL << 44;
   case Attribute::JumpTable:       return 1ULL << 45;
+  case Attribute::HWReg:
   case Attribute::Dereferenceable:
     llvm_unreachable("dereferenceable attribute not supported in raw format");
   }
@@ -519,6 +547,13 @@
   return 0;
 }
 
+uint64_t AttributeSetNode::getHWReg() const {
+  for (iterator I = begin(), E = end(); I != E; ++I)
+    if (I->hasAttribute(Attribute::HWReg))
+      return I->getHWReg();
+  return 0;
+}
+
 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
   std::string Str;
   for (iterator I = begin(), E = end(); I != E; ++I) {
@@ -554,6 +589,8 @@
         Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26;
       else if (Kind == Attribute::Dereferenceable)
         llvm_unreachable("dereferenceable not supported in bit mask");
+      else if (Kind == Attribute::HWReg)
+        llvm_unreachable("hwreg not supported in bit mask");
       else
         Mask |= AttributeImpl::getAttrMask(Kind);
     }
@@ -663,6 +700,9 @@
       Attrs.push_back(std::make_pair(Index,
                                      Attribute::getWithDereferenceableBytes(C,
                                        B.getDereferenceableBytes())));
+    else if (Kind == Attribute::HWReg)
+      Attrs.push_back(std::make_pair(Index,
+                                     Attribute::getWithHWReg(C, B.getHWReg())));
     else
       Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind)));
   }
@@ -932,6 +972,11 @@
   return ASN ? ASN->getDereferenceableBytes() : 0;
 }
 
+uint64_t AttributeSet::getHWReg(unsigned Index) const {
+  AttributeSetNode *ASN = getAttributes(Index);
+  return ASN ? ASN->getHWReg() : 0;
+}
+
 std::string AttributeSet::getAsString(unsigned Index,
                                       bool InAttrGrp) const {
   AttributeSetNode *ASN = getAttributes(Index);
@@ -1034,8 +1079,8 @@
 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
-         Val != Attribute::Dereferenceable &&
-         "Adding integer attribute without adding a value!");
+         Val != Attribute::Dereferenceable && Val != Attribute::HWReg
+         && "Adding integer attribute without adding a value!");
   Attrs[Val] = true;
   return *this;
 }
@@ -1055,6 +1100,8 @@
     StackAlignment = Attr.getStackAlignment();
   else if (Kind == Attribute::Dereferenceable)
     DerefBytes = Attr.getDereferenceableBytes();
+  else if (Kind == Attribute::HWReg)
+    HWReg = Attr.getHWReg();
   return *this;
 }
 
@@ -1099,6 +1146,8 @@
         StackAlignment = 0;
       else if (Kind == Attribute::Dereferenceable)
         DerefBytes = 0;
+      else if (Kind == Attribute::HWReg)
+        HWReg = 0;
     } else {
       assert(Attr.isStringAttribute() && "Invalid attribute type!");
       std::map<std::string, std::string>::iterator
@@ -1149,6 +1198,14 @@
   return *this;
 }
 
+AttrBuilder &AttrBuilder::addHWRegAttr(uint64_t Reg) {
+  if (Reg == 0) return *this;
+
+  Attrs[Attribute::HWReg] = true;
+  HWReg = Reg;
+  return *this;
+}
+
 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
   // FIXME: What if both have alignments, but they don't match?!
   if (!Alignment)
@@ -1227,6 +1284,8 @@
        I = Attribute::AttrKind(I + 1)) {
     if (I == Attribute::Dereferenceable)
       continue;
+    if (I == Attribute::HWReg)
+      continue;
     if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
       Attrs[I] = true;
  
Index: lib/IR/Function.cpp
===================================================================
--- lib/IR/Function.cpp
+++ lib/IR/Function.cpp
@@ -117,6 +117,10 @@
   return getParent()->getDereferenceableBytes(getArgNo()+1);
 }
 
+uint64_t Argument::getHWReg() const {
+  return getParent()->getHWReg(getArgNo()+1);
+}
+
 /// hasNestAttr - Return true if this argument has the nest attribute on
 /// it in its containing function.
 bool Argument::hasNestAttr() const {