[LLVMdev] arm64 / iOS support

Carlo Kok ck at remobjects.com
Thu Sep 26 05:26:20 PDT 2013


Carlo Kok schreef op 9/25/2013 8:32 PM:
> Attached is a working patch set for llvm to be able to emit arm64
> (currently as triple aarch64-apple-ios) mach-o object files, in case
> someone is interested. I'm not sure if the llvm maintainers want the
> patch given the previous message that there's going to be an official
> patch set from apple to support this, but here is mine.
>
> What works (tested on an iPhone 5S):
> * objc strings, selectors, class refs
> * defining classes
> * regular strings, int64 constants
> * exception handling
> * emitting debug info: I couldn't test this yet due to no support for it
> in lldb.
>
> What doesn't work yet:
> * varargs, need to figure out how to do that

Varargs are fixed in the attached patch. If anyone knows a better way to 
determine from the td if an argument is part of the vararg signature let 
me know.


-- 
Carlo Kok
RemObjects Software
-------------- next part --------------
 include/llvm/Target/TargetCallingConv.h          |  5 +++++
 include/llvm/Target/TargetCallingConv.td         |  4 ++++
 lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp |  2 ++
 lib/Target/AArch64/AArch64CallingConv.td         | 18 ++++++++++++++++++
 lib/Target/AArch64/AArch64ISelLowering.cpp       |  3 +++
 5 files changed, 32 insertions(+)

diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 1fd0bd9..28d8f3a 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -42,6 +42,8 @@ namespace ISD {
     static const uint64_t ByValAlignOffs = 7;
     static const uint64_t Split          = 1ULL<<11;
     static const uint64_t SplitOffs      = 11;
+    static const uint64_t VarArg         = 1ULL<<12;
+    static const uint64_t VarArgOffs     = 12;
     static const uint64_t OrigAlign      = 0x1FULL<<27;
     static const uint64_t OrigAlignOffs  = 27;
     static const uint64_t ByValSize      = 0xffffffffULL<<32; ///< Struct size
@@ -86,6 +88,9 @@ namespace ISD {
     bool isSplit()   const { return Flags & Split; }
     void setSplit()  { Flags |= One << SplitOffs; }
 
+    bool isVarArg()   const { return Flags & VarArg; }
+    void setVarArg()  { Flags |= One << VarArgOffs; }
+
     unsigned getOrigAlign() const {
       return (unsigned)
         ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index c1bef28..29f3de1 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -65,6 +65,10 @@ class CCIfSRet<CCAction A> : CCIf<"ArgFlags.isSRet()", A> {}
 /// CCIfNotVarArg - If the current function is not vararg - apply the action
 class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
 
+/// CCIfVarArg - If this argument is part of the vararg parameters, apply the
+/// action
+class CCIfVarArg<CCAction A> : CCIf<"ArgFlags.isVarArg()", A> {}
+
 /// CCAssignToReg - This action matches if there is a register in the specified
 /// list that is still available.  If so, it assigns the value to the first
 /// available register and succeeds.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 0971e8a..8f730a1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6768,6 +6768,8 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
       unsigned OriginalAlignment =
         getDataLayout()->getABITypeAlignment(ArgTy);
 
+      if (i >= CLI.NumFixedArgs)
+        Flags.setVarArg();
       if (Args[i].isZExt)
         Flags.setZExt();
       if (Args[i].isSExt)
diff --git a/lib/Target/AArch64/AArch64CallingConv.td b/lib/Target/AArch64/AArch64CallingConv.td
index a2a9f3f..fffe906 100644
--- a/lib/Target/AArch64/AArch64CallingConv.td
+++ b/lib/Target/AArch64/AArch64CallingConv.td
@@ -180,6 +180,24 @@ def CC_A64_APCS : CallingConv<[
 
 ]>;
 
+def CC_A64_APCS_VarArg : CallingConv<[
+  CCIfType<[f16, f32], CCPromoteToType<f64>>,
+  CCIfType<[f64], CCAssignToStack<8, 8>>,
+  CCIfType<[f128], CCAssignToStack<16, 16>>,
+  CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,    
+  CCIfType<[i64], CCIfSplit<CCAssignToStack<8, 16>>>,
+  CCIfType<[i64], CCAssignToStack<8, 8>>,
+  CCDelegateTo<CC_A64_APCS>
+]>;
+
+def CC_A64_APCS_MachO : CallingConv<[
+
+  CCIfVarArg<CCDelegateTo<CC_A64_APCS_VarArg>>,
+
+  CCDelegateTo<CC_A64_APCS>
+]>;
+
+
 // According to the PCS, X19-X30 are callee-saved, however only the low 64-bits
 // of vector registers (8-15) are callee-saved. The order here is is picked up
 // by PrologEpilogInserter.cpp to allocate stack slots, starting from top of
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp
index 0feaa0d..5491aa5 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -892,7 +892,10 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
   switch(CC) {
   default: llvm_unreachable("Unsupported calling convention");
   case CallingConv::Fast:
+    return CC_A64_APCS;
   case CallingConv::C:
+    if (Subtarget->isTargetDarwin())
+      return CC_A64_APCS_MachO; 
     return CC_A64_APCS;
   }
 }


More information about the llvm-dev mailing list