aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2012-10-16 22:30:41 +0000
committerDerek Schuff <dschuff@google.com>2012-10-16 22:30:41 +0000
commit263366f9241366f29ba65b703120f302490c39ff (patch)
treeb1c97ab1bb9b4de9c131c472eceb0fbaec961cc3 /lib/CodeGen
parent3f784bf89a4af448c91329e08314030b1bac7e5d (diff)
Add pnaclcall convention to Native Client targets.
Because PNaCl bitcode must be target-independent, it uses some different bitcode representations from other targets (e.g. byval and sret for structures). This means that without additional type information, it cannot meet some native ABI requirements for some targets (e.g. passing structures containing unions by value on x86-64). To allow generation of code which uses the correct native ABIs, we also support triples such as x86_64-nacl, which uses target-dependent IR (as opposed to le32-nacl, which uses byval and sret). To allow interoperation between the two types of code, this patch adds a calling convention attribute to be used in code compiled with the target-dependent triple, which will generate code using the le32-style bitcode. This calling convention does not need to be explicitly supported in the backend because it determines bitcode representation rather than native conventions (the backend just needs to undersand how to handle byval and sret for the Native Client OS). This patch implements __attribute__((pnaclcall)) to generate calls in bitcode according to the le32 bitcode conventions, an attribute which is accepted by any Native Client target, but issues a warning otherwise. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166065 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGCall.cpp3
-rw-r--r--lib/CodeGen/TargetInfo.cpp76
2 files changed, 78 insertions, 1 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index a8483d70b2..2ef5bd27a0 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -148,6 +148,9 @@ static CallingConv getCallingConventionForDecl(const Decl *D) {
if (PcsAttr *PCS = D->getAttr<PcsAttr>())
return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP);
+ if (D->hasAttr<PnaclCallAttr>())
+ return CC_PnaclCall;
+
return CC_C;
}
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 4ee9b97843..ad59fd2c90 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -2536,6 +2536,39 @@ llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
return AddrTyped;
}
+class NaClX86_64ABIInfo : public ABIInfo {
+ public:
+ NaClX86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX)
+ : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, HasAVX) {}
+ virtual void computeInfo(CGFunctionInfo &FI) const;
+ virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const;
+ private:
+ PNaClABIInfo PInfo; // Used for generating calls with pnaclcall callingconv.
+ X86_64ABIInfo NInfo; // Used for everything else.
+};
+
+class NaClX86_64TargetCodeGenInfo : public TargetCodeGenInfo {
+ public:
+ NaClX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX)
+ : TargetCodeGenInfo(new NaClX86_64ABIInfo(CGT, HasAVX)) {}
+};
+
+void NaClX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
+ if (FI.getASTCallingConvention() == CC_PnaclCall)
+ PInfo.computeInfo(FI);
+ else
+ NInfo.computeInfo(FI);
+}
+
+llvm::Value *NaClX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const {
+ // Always use the native convention; calling pnacl-style varargs functions
+ // is unuspported.
+ return NInfo.EmitVAArg(VAListAddr, Ty, CGF);
+}
+
+
// PowerPC-32
namespace {
@@ -3268,6 +3301,38 @@ llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
return AddrTyped;
}
+class NaClARMABIInfo : public ABIInfo {
+ public:
+ NaClARMABIInfo(CodeGen::CodeGenTypes &CGT, ARMABIInfo::ABIKind Kind)
+ : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, Kind) {}
+ virtual void computeInfo(CGFunctionInfo &FI) const;
+ virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const;
+ private:
+ PNaClABIInfo PInfo; // Used for generating calls with pnaclcall callingconv.
+ ARMABIInfo NInfo; // Used for everything else.
+};
+
+class NaClARMTargetCodeGenInfo : public TargetCodeGenInfo {
+ public:
+ NaClARMTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, ARMABIInfo::ABIKind Kind)
+ : TargetCodeGenInfo(new NaClARMABIInfo(CGT, Kind)) {}
+};
+
+void NaClARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
+ if (FI.getASTCallingConvention() == CC_PnaclCall)
+ PInfo.computeInfo(FI);
+ else
+ static_cast<const ABIInfo&>(NInfo).computeInfo(FI);
+}
+
+llvm::Value *NaClARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+ CodeGenFunction &CGF) const {
+ // Always use the native convention; calling pnacl-style varargs functions
+ // is unsupported.
+ return static_cast<const ABIInfo&>(NInfo).EmitVAArg(VAListAddr, Ty, CGF);
+}
+
//===----------------------------------------------------------------------===//
// NVPTX ABI Implementation
//===----------------------------------------------------------------------===//
@@ -4077,7 +4142,14 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
else if (CodeGenOpts.FloatABI == "hard")
Kind = ARMABIInfo::AAPCS_VFP;
- return *(TheTargetCodeGenInfo = new ARMTargetCodeGenInfo(Types, Kind));
+ switch (Triple.getOS()) {
+ case llvm::Triple::NativeClient:
+ return *(TheTargetCodeGenInfo =
+ new NaClARMTargetCodeGenInfo(Types, Kind));
+ default:
+ return *(TheTargetCodeGenInfo =
+ new ARMTargetCodeGenInfo(Types, Kind));
+ }
}
case llvm::Triple::ppc:
@@ -4143,6 +4215,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::MinGW32:
case llvm::Triple::Cygwin:
return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types));
+ case llvm::Triple::NativeClient:
+ return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types, HasAVX));
default:
return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types,
HasAVX));