[cfe-commits] r129534 - in /cfe/trunk: include/clang/AST/Type.h include/clang/Basic/Attr.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/AttributeList.h lib/AST/DumpXML.cpp lib/AST/MicrosoftMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/TargetInfo.cpp lib/Sema/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaType.cpp test/CodeGen/arm-pcs.c

Anton Korobeynikov asl at math.spbu.ru
Thu Apr 14 13:06:49 PDT 2011


Author: asl
Date: Thu Apr 14 15:06:49 2011
New Revision: 129534

URL: http://llvm.org/viewvc/llvm-project?rev=129534&view=rev
Log:
Implement ARM pcs attribute. Basically it's another way of calling convention selection (AAPCS or
AAPCS+VFP), similar to fastcall / stdcall / whatevercall seen on x86.

In particular, all library functions should always be AAPCS regardless of floating point ABI used.

Added:
    cfe/trunk/test/CodeGen/arm-pcs.c
Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/lib/Sema/AttributeList.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Apr 14 15:06:49 2011
@@ -360,7 +360,9 @@
   CC_X86StdCall,  // __attribute__((stdcall))
   CC_X86FastCall, // __attribute__((fastcall))
   CC_X86ThisCall, // __attribute__((thiscall))
-  CC_X86Pascal    // __attribute__((pascal))
+  CC_X86Pascal,   // __attribute__((pascal))
+  CC_AAPCS,       // __attribute__((pcs("aapcs")))
+  CC_AAPCS_VFP    // __attribute__((pcs("aapcs-vfp")))
 };
 
 typedef std::pair<const Type*, Qualifiers> SplitQualType;
@@ -2864,9 +2866,10 @@
 
     // Enumerated operand (string or keyword).
     attr_objc_gc,
+    attr_pcs,
 
     FirstEnumOperandKind = attr_objc_gc,
-    LastEnumOperandKind = attr_objc_gc,
+    LastEnumOperandKind = attr_pcs,
 
     // No operand.
     attr_noreturn,

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Apr 14 15:06:49 2011
@@ -416,6 +416,13 @@
   let Spellings = ["packed"];
 }
 
+def Pcs : InheritableAttr {
+  let Spellings = ["pcs"];
+  let Args = [EnumArgument<"PCS", "PCSType",
+                           ["aapcs", "aapcs-vfp"],
+                           ["AAPCS", "AAPCS_VFP"]>];
+}
+
 def Pure : InheritableAttr {
   let Spellings = ["pure"];
 }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 14 15:06:49 2011
@@ -1151,6 +1151,7 @@
 def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
   "attribute was previously declared "
   "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
+def err_invalid_pcs : Error<"Invalid PCS type">;
 
 // Availability attribute
 def warn_availability_unknown_platform : Warning<

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Thu Apr 14 15:06:49 2011
@@ -213,6 +213,7 @@
     AT_ownership_takes,    // Clang-specific.
     AT_packed,
     AT_pascal,
+    AT_pcs,  // ARM specific
     AT_pure,
     AT_regparm,
     AT_section,

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Thu Apr 14 15:06:49 2011
@@ -911,6 +911,8 @@
     case CC_X86StdCall: return set("cc", "x86_stdcall");
     case CC_X86ThisCall: return set("cc", "x86_thiscall");
     case CC_X86Pascal: return set("cc", "x86_pascal");
+    case CC_AAPCS: return set("cc", "aapcs");
+    case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
     }
   }
 

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Apr 14 15:06:49 2011
@@ -874,6 +874,8 @@
   if (CC == CC_Default)
     CC = IsInstMethod ? getASTContext().getDefaultMethodCallConv() : CC_C;
   switch (CC) {
+    default:
+      assert(0 && "Unsupported CC for mangling");
     case CC_Default:
     case CC_C: Out << 'A'; break;
     case CC_X86Pascal: Out << 'C'; break;

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Apr 14 15:06:49 2011
@@ -1169,6 +1169,8 @@
   case CC_X86FastCall: return "fastcall";
   case CC_X86ThisCall: return "thiscall";
   case CC_X86Pascal: return "pascal";
+  case CC_AAPCS: return "aapcs";
+  case CC_AAPCS_VFP: return "aapcs-vfp";
   }
 
   llvm_unreachable("Invalid calling convention.");

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Apr 14 15:06:49 2011
@@ -400,6 +400,12 @@
   case CC_X86Pascal:
     S += " __attribute__((pascal))";
     break;
+  case CC_AAPCS:
+    S += " __attribute__((pcs(\"aapcs\")))";
+    break;
+  case CC_AAPCS_VFP:
+    S += " __attribute__((pcs(\"aapcs-vfp\")))";
+    break;
   }
   if (Info.getNoReturn())
     S += " __attribute__((noreturn))";
@@ -851,6 +857,16 @@
   case AttributedType::attr_stdcall: S += "stdcall"; break;
   case AttributedType::attr_thiscall: S += "thiscall"; break;
   case AttributedType::attr_pascal: S += "pascal"; break;
+  case AttributedType::attr_pcs: {
+   S += "pcs(";
+   QualType t = T->getEquivalentType();
+   while (!t->isFunctionType())
+     t = t->getPointeeType();
+   S += (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
+         "\"aapcs\"" : "\"aapcs-vfp\"");
+   S += ")";
+   break;
+  }
   }
   S += "))";
 }

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Apr 14 15:06:49 2011
@@ -36,6 +36,8 @@
   case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
   case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
   case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
+  case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;
+  case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;
   // TODO: add support for CC_X86Pascal to llvm
   }
 }
@@ -104,6 +106,9 @@
   if (D->hasAttr<PascalAttr>())
     return CC_X86Pascal;
 
+  if (PcsAttr *PCS = D->getAttr<PcsAttr>())
+    return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP);
+
   return CC_C;
 }
 

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Apr 14 15:06:49 2011
@@ -2271,27 +2271,33 @@
        it != ie; ++it)
     it->info = classifyArgumentType(it->type);
 
-  const llvm::Triple &Triple(getContext().Target.getTriple());
+  // Always honor user-specified calling convention.
+  if (FI.getCallingConvention() != llvm::CallingConv::C)
+    return;
+
+  // Calling convention as default by an ABI.
   llvm::CallingConv::ID DefaultCC;
-  if (Triple.getEnvironmentName() == "gnueabi" ||
-      Triple.getEnvironmentName() == "eabi")
+  llvm::StringRef Env = getContext().Target.getTriple().getEnvironmentName();
+  if (Env == "gnueabi" || Env == "eabi")
     DefaultCC = llvm::CallingConv::ARM_AAPCS;
   else
     DefaultCC = llvm::CallingConv::ARM_APCS;
 
+  // If user did not ask for specific calling convention explicitly (e.g. via
+  // pcs attribute), set effective calling convention if it's different than ABI
+  // default.
   switch (getABIKind()) {
   case APCS:
     if (DefaultCC != llvm::CallingConv::ARM_APCS)
       FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS);
     break;
-
   case AAPCS:
     if (DefaultCC != llvm::CallingConv::ARM_AAPCS)
       FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS);
     break;
-
   case AAPCS_VFP:
-    FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS_VFP);
+    if (DefaultCC != llvm::CallingConv::ARM_AAPCS_VFP)
+      FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS_VFP);
     break;
   }
 }

Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Thu Apr 14 15:06:49 2011
@@ -201,5 +201,6 @@
     .Case("nocommon", AT_nocommon)
     .Case("opencl_kernel_function", AT_opencl_kernel_function)
     .Case("uuid", AT_uuid)
+    .Case("pcs", AT_pcs)
     .Default(UnknownAttribute);
 }

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Apr 14 15:06:49 2011
@@ -2427,6 +2427,30 @@
   case AttributeList::AT_pascal:
     d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
     return;
+  case AttributeList::AT_pcs: {
+    Expr *Arg = attr.getArg(0);
+    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+    if (Str == 0 || Str->isWide()) {
+      S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
+        << "pcs" << 1;
+      attr.setInvalid();
+      return;
+    }
+
+    llvm::StringRef StrRef = Str->getString();
+    PcsAttr::PCSType PCS;
+    if (StrRef == "aapcs")
+      PCS = PcsAttr::AAPCS;
+    else if (StrRef == "aapcs-vfp")
+      PCS = PcsAttr::AAPCS_VFP;
+    else {
+      S.Diag(attr.getLoc(), diag::err_invalid_pcs);
+      attr.setInvalid();
+      return;
+    }
+
+    d->addAttr(::new (S.Context) PcsAttr(attr.getLoc(), S.Context, PCS));
+  }
   default:
     llvm_unreachable("unexpected attribute kind");
     return;
@@ -2442,19 +2466,41 @@
   if (attr.isInvalid())
     return true;
 
-  if (attr.getNumArgs() != 0) {
+  if (attr.getNumArgs() != 0 &&
+      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) {
     Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     attr.setInvalid();
     return true;
   }
 
-  // TODO: diagnose uses of these conventions on the wrong target.
+  // TODO: diagnose uses of these conventions on the wrong target. Or, better
+  // move to TargetAttributesSema one day.
   switch (attr.getKind()) {
   case AttributeList::AT_cdecl: CC = CC_C; break;
   case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
   case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
   case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
   case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
+  case AttributeList::AT_pcs: {
+    Expr *Arg = attr.getArg(0);
+    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+    if (Str == 0 || Str->isWide()) {
+      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
+        << "pcs" << 1;
+      attr.setInvalid();
+      return true;
+    }
+
+    llvm::StringRef StrRef = Str->getString();
+    if (StrRef == "aapcs") {
+      CC = CC_AAPCS;
+      break;
+    } else if (StrRef == "aapcs-vfp") {
+      CC = CC_AAPCS_VFP;
+      break;
+    }
+    // FALLS THROUGH
+  }
   default: llvm_unreachable("unexpected attribute kind"); return true;
   }
 
@@ -2882,6 +2928,7 @@
   case AttributeList::AT_fastcall:
   case AttributeList::AT_thiscall:
   case AttributeList::AT_pascal:
+  case AttributeList::AT_pcs:
     HandleCallConvAttr(D, Attr, S);
     break;
   case AttributeList::AT_opencl_kernel_function:

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=129534&r1=129533&r2=129534&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Apr 14 15:06:49 2011
@@ -119,7 +119,8 @@
     case AttributeList::AT_stdcall: \
     case AttributeList::AT_thiscall: \
     case AttributeList::AT_pascal: \
-    case AttributeList::AT_regparm
+    case AttributeList::AT_regparm: \
+    case AttributeList::AT_pcs \
 
 namespace {
   /// An object which stores processing state for the entire
@@ -2244,6 +2245,8 @@
     return AttributeList::AT_thiscall;
   case AttributedType::attr_pascal:
     return AttributeList::AT_pascal;
+  case AttributedType::attr_pcs:
+    return AttributeList::AT_pcs;
   }
   llvm_unreachable("unexpected attribute kind!");
   return AttributeList::Kind();

Added: cfe/trunk/test/CodeGen/arm-pcs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-pcs.c?rev=129534&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/arm-pcs.c (added)
+++ cfe/trunk/test/CodeGen/arm-pcs.c Thu Apr 14 15:06:49 2011
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -emit-llvm -w -o - < %s | FileCheck %s
+typedef int __attribute__((pcs("aapcs"))) (*aapcs_fn)(void);
+typedef int __attribute__((pcs("aapcs-vfp"))) (*aapcs_vfp_fn)(void);
+
+aapcs_fn bar;
+
+int foo(aapcs_vfp_fn baz) {
+// CHECK: define i32 @foo
+// CHECK: call arm_aapcscc
+// CHECK: call arm_aapcs_vfpcc
+  return bar() + baz();
+}





More information about the cfe-commits mailing list