AArch64: add stubs to support long function calls on MCJIT

As with global accesses, external functions could exist anywhere in
memory. Therefore the stub must create a complete 64-bit address. This
patch implements the fragment as (roughly):
    movz x16, #:abs_g3:somefunc
    movk x16, #:abs_g2_nc:somefunc
    movk x16, #:abs_g1_nc:somefunc
    movk x16, #:abs_g0_nc:somefunc
    br x16

In principle we could save 4 bytes by using a literal-load instead,
but it is unclear that would be more efficient and can only be tested
when real hardware is readily available.

This allows (for example) the MCJIT test 2003-05-07-ArgumentTest to
pass on AArch64.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181133 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 14c0cd8..714eaf4 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -336,7 +336,25 @@
 }
 
 uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
-  if (Arch == Triple::arm) {
+  if (Arch == Triple::aarch64) {
+    // This stub has to be able to access the full address space,
+    // since symbol lookup won't necessarily find a handy, in-range,
+    // PLT stub for functions which could be anywhere.
+    uint32_t *StubAddr = (uint32_t*)Addr;
+
+    // Stub can use ip0 (== x16) to calculate address
+    *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr>
+    StubAddr++;
+    *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:<addr>
+    StubAddr++;
+    *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:<addr>
+    StubAddr++;
+    *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:<addr>
+    StubAddr++;
+    *StubAddr = 0xd61f0200; // br ip0
+
+    return Addr;
+  } else if (Arch == Triple::arm) {
     // TODO: There is only ARM far stub now. We should add the Thumb stub,
     // and stubs for branches Thumb - ARM and ARM - Thumb.
     uint32_t *StubAddr = (uint32_t*)Addr;