[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