diff --git a/configure b/configure
index f14009b465433..ea9320c901b6d 100755
--- a/configure
+++ b/configure
@@ -444,6 +444,10 @@ case $CFG_CPUTYPE in
         CFG_OSTYPE="${CFG_OSTYPE}eabihf"
         ;;
 
+    aarch64)
+        CFG_CPUTYPE=aarch64
+        ;;
+
     x86_64 | x86-64 | x64 | amd64)
         CFG_CPUTYPE=x86_64
         ;;
@@ -988,7 +992,7 @@ do
     make_dir $t/rt/jemalloc
     for i in                                          \
       isaac sync test \
-      arch/i386 arch/x86_64 arch/arm arch/mips
+      arch/i386 arch/x86_64 arch/arm arch/aarch64 arch/mips
     do
       make_dir $t/rt/stage$s/$i
     done
@@ -1165,7 +1169,7 @@ do
 
         msg "configuring LLVM for $gnu_t"
 
-        LLVM_TARGETS="--enable-targets=x86,x86_64,arm,mips"
+        LLVM_TARGETS="--enable-targets=x86,x86_64,arm,aarch64,mips"
         LLVM_BUILD="--build=$gnu_t"
         LLVM_HOST="--host=$gnu_t"
         LLVM_TARGET="--target=$gnu_t"
diff --git a/mk/cfg/aarch64-unknown-linux-gnu.mk b/mk/cfg/aarch64-unknown-linux-gnu.mk
new file mode 100644
index 0000000000000..fade026654960
--- /dev/null
+++ b/mk/cfg/aarch64-unknown-linux-gnu.mk
@@ -0,0 +1,30 @@
+# aarch64-unknown-linux-gnu configuration
+CROSS_PREFIX_aarch64-unknown-linux-gnu=aarch64-linux-gnu-
+CC_aarch64-unknown-linux-gnu=gcc
+CXX_aarch64-unknown-linux-gnu=g++
+CPP_aarch64-unknown-linux-gnu=gcc -E
+AR_aarch64-unknown-linux-gnu=ar
+CFG_LIB_NAME_aarch64-unknown-linux-gnu=lib$(1).so
+CFG_STATIC_LIB_NAME_aarch64-unknown-linux-gnu=lib$(1).a
+CFG_LIB_GLOB_aarch64-unknown-linux-gnu=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_aarch64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
+CFG_JEMALLOC_CFLAGS_aarch64-unknown-linux-gnu := -D__aarch64__ $(CFLAGS)
+CFG_GCCISH_CFLAGS_aarch64-unknown-linux-gnu := -Wall -g -fPIC -D__aarch64__ $(CFLAGS)
+CFG_GCCISH_CXXFLAGS_aarch64-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
+CFG_GCCISH_LINK_FLAGS_aarch64-unknown-linux-gnu := -shared -fPIC -g
+CFG_GCCISH_DEF_FLAG_aarch64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_aarch64-unknown-linux-gnu := .linux.def
+CFG_LLC_FLAGS_aarch64-unknown-linux-gnu :=
+CFG_INSTALL_NAME_aarch64-unknown-linux-gnu =
+CFG_EXE_SUFFIX_aarch64-unknown-linux-gnu :=
+CFG_WINDOWSY_aarch64-unknown-linux-gnu :=
+CFG_UNIXY_aarch64-unknown-linux-gnu := 1
+CFG_PATH_MUNGE_aarch64-unknown-linux-gnu := true
+CFG_LDPATH_aarch64-unknown-linux-gnu :=
+CFG_RUN_aarch64-unknown-linux-gnu=$(2)
+CFG_RUN_TARG_aarch64-unknown-linux-gnu=$(call CFG_RUN_aarch64-unknown-linux-gnu,,$(2))
+RUSTC_FLAGS_aarch64-unknown-linux-gnu :=
+RUSTC_CROSS_FLAGS_aarch64-unknown-linux-gnu :=
+CFG_GNU_TRIPLE_aarch64-unknown-linux-gnu := aarch64-unknown-linux-gnu
diff --git a/mk/main.mk b/mk/main.mk
index e67bee3cab54d..0d9419cccfa83 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -1,4 +1,4 @@
-# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 # file at the top-level directory of this distribution and at
 # http://rust-lang.org/COPYRIGHT.
 #
@@ -261,7 +261,7 @@ endif
 ######################################################################
 
 # FIXME: x86-ism
-LLVM_COMPONENTS=x86 arm mips ipo bitreader bitwriter linker asmparser mcjit \
+LLVM_COMPONENTS=x86 arm aarch64 mips ipo bitreader bitwriter linker asmparser mcjit \
                 interpreter instrumentation
 
 # Only build these LLVM tools
diff --git a/mk/platform.mk b/mk/platform.mk
index 7ca24736cb859..50bf51b20de18 100644
--- a/mk/platform.mk
+++ b/mk/platform.mk
@@ -1,4 +1,4 @@
-# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+# Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 # file at the top-level directory of this distribution and at
 # http://rust-lang.org/COPYRIGHT.
 #
@@ -177,7 +177,7 @@ define CFG_MAKE_TOOLCHAIN
         $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
         $$(call CFG_INSTALL_NAME_$(1),$$(4))
 
-  ifeq ($$(findstring $(HOST_$(1)),arm mips mipsel),)
+  ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel),)
 
   # We're using llvm-mc as our assembler because it supports
   # .cfi pseudo-ops on mac
@@ -189,7 +189,7 @@ define CFG_MAKE_TOOLCHAIN
                     -o=$$(1)
   else
 
-  # For the ARM and MIPS crosses, use the toolchain assembler
+  # For the ARM, AARCH64 and MIPS crosses, use the toolchain assembler
   # FIXME: We should be able to use the LLVM assembler
   CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
 		    $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
diff --git a/src/doc/reference.md b/src/doc/reference.md
index a8abb595034b5..8c2c5ab7b8580 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2141,7 +2141,7 @@ arbitrarily complex configurations through nesting.
 The following configurations must be defined by the implementation:
 
 * `target_arch = "..."`. Target CPU architecture, such as `"x86"`, `"x86_64"`
-  `"mips"`, or `"arm"`.
+  `"mips"`, `"arm"`, or `"aarch64"`.
 * `target_endian = "..."`. Endianness of the target CPU, either `"little"` or
   `"big"`.
 * `target_family = "..."`. Operating system family of the target, e. g.
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index cdc30efd2d9a2..c57435cdc8c0c 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -120,7 +120,8 @@ unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) {
           target_arch = "mipsel"))]
 const MIN_ALIGN: uint = 8;
 #[cfg(any(target_arch = "x86",
-          target_arch = "x86_64"))]
+          target_arch = "x86_64",
+          target_arch = "aarch64"))]
 const MIN_ALIGN: uint = 16;
 
 #[cfg(external_funcs)]
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 70feb3e80cc0e..020f0f6de9bab 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -419,6 +419,12 @@ mod tests {
         }
     }
 
+    #[test] #[cfg(target_arch = "aarch64")]
+    fn test_hash_uint() {
+        let val = 0xdeadbeef_deadbeef_u64;
+        assert_eq!(hash(&(val as u64)), hash(&(val as uint)));
+        assert!(hash(&(val as u32)) != hash(&(val as uint)));
+    }
     #[test] #[cfg(target_arch = "arm")]
     fn test_hash_uint() {
         let val = 0xdeadbeef_deadbeef_u64;
diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs
index 75ddfd5413b31..96b50e8bccbad 100644
--- a/src/libcoretest/mem.rs
+++ b/src/libcoretest/mem.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -29,7 +29,8 @@ fn size_of_32() {
 }
 
 #[test]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64",
+          target_arch = "aarch64"))]
 fn size_of_64() {
     assert_eq!(size_of::<uint>(), 8u);
     assert_eq!(size_of::<*const uint>(), 8u);
@@ -61,7 +62,8 @@ fn align_of_32() {
 }
 
 #[test]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64",
+          target_arch = "aarch64"))]
 fn align_of_64() {
     assert_eq!(align_of::<uint>(), 8u);
     assert_eq!(align_of::<*const uint>(), 8u);
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index 9faaedc45f3b1..ac0bab67b406f 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -720,10 +720,14 @@ pub mod types {
 
         }
 
-        #[cfg(target_arch = "x86_64")]
+        #[cfg(any(target_arch = "x86_64",
+                  target_arch = "aarch64"))]
         pub mod arch {
             pub mod c95 {
+                #[cfg(not(target_arch = "aarch64"))]
                 pub type c_char = i8;
+                #[cfg(target_arch = "aarch64")]
+                pub type c_char = u8;
                 pub type c_schar = i8;
                 pub type c_uchar = u8;
                 pub type c_short = i16;
@@ -739,7 +743,10 @@ pub mod types {
                 pub type clock_t = i64;
                 pub type time_t = i64;
                 pub type suseconds_t = i64;
+                #[cfg(not(target_arch = "aarch64"))]
                 pub type wchar_t = i32;
+                #[cfg(target_arch = "aarch64")]
+                pub type wchar_t = u32;
             }
             pub mod c99 {
                 pub type c_longlong = i64;
@@ -760,6 +767,7 @@ pub mod types {
                 pub type mode_t = u32;
                 pub type ssize_t = i64;
             }
+            #[cfg(not(target_arch = "aarch64"))]
             pub mod posix01 {
                 use types::os::arch::c95::{c_int, c_long, time_t};
                 use types::os::arch::posix88::{dev_t, gid_t, ino_t};
@@ -769,6 +777,7 @@ pub mod types {
                 pub type nlink_t = u64;
                 pub type blksize_t = i64;
                 pub type blkcnt_t = i64;
+
                 #[repr(C)]
                 #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
@@ -802,6 +811,51 @@ pub mod types {
                     pub __size: [u64; 7]
                 }
             }
+            #[cfg(target_arch = "aarch64")]
+            pub mod posix01 {
+                use types::os::arch::c95::{c_int, c_long, time_t};
+                use types::os::arch::posix88::{dev_t, gid_t, ino_t};
+                use types::os::arch::posix88::{mode_t, off_t};
+                use types::os::arch::posix88::{uid_t};
+
+                pub type nlink_t = u32;
+                pub type blksize_t = i32;
+                pub type blkcnt_t = i64;
+
+                #[repr(C)]
+                #[deriving(Copy)] pub struct stat {
+                    pub st_dev: dev_t,
+                    pub st_ino: ino_t,
+                    pub st_mode: mode_t,
+                    pub st_nlink: nlink_t,
+                    pub st_uid: uid_t,
+                    pub st_gid: gid_t,
+                    pub st_rdev: dev_t,
+                    pub __pad1: dev_t,
+                    pub st_size: off_t,
+                    pub st_blksize: blksize_t,
+                    pub __pad2: c_int,
+                    pub st_blocks: blkcnt_t,
+                    pub st_atime: time_t,
+                    pub st_atime_nsec: c_long,
+                    pub st_mtime: time_t,
+                    pub st_mtime_nsec: c_long,
+                    pub st_ctime: time_t,
+                    pub st_ctime_nsec: c_long,
+                    pub __unused: [c_int; 2],
+                }
+
+                #[repr(C)]
+                #[deriving(Copy)] pub struct utimbuf {
+                    pub actime: time_t,
+                    pub modtime: time_t,
+                }
+
+                #[repr(C)]
+                #[deriving(Copy)] pub struct pthread_attr_t {
+                    pub __size: [u64; 8]
+                }
+            }
             pub mod posix08 {
             }
             pub mod bsd44 {
@@ -2444,7 +2498,8 @@ pub mod consts {
         }
         #[cfg(any(target_arch = "x86",
                   target_arch = "x86_64",
-                  target_arch = "arm"))]
+                  target_arch = "arm",
+                  target_arch = "aarch64"))]
         pub mod posix88 {
             use types::os::arch::c95::c_int;
             use types::common::c95::c_void;
@@ -2939,7 +2994,9 @@ pub mod consts {
             pub const PTHREAD_STACK_MIN: size_t = 16384;
 
             #[cfg(all(target_os = "linux",
-                      any(target_arch = "mips", target_arch = "mipsel")))]
+                      any(target_arch = "mips",
+                          target_arch = "mipsel",
+                          target_arch = "aarch64")))]
             pub const PTHREAD_STACK_MIN: size_t = 131072;
 
             pub const CLOCK_REALTIME: c_int = 0;
@@ -2948,6 +3005,7 @@ pub mod consts {
         pub mod posix08 {
         }
         #[cfg(any(target_arch = "arm",
+                  target_arch = "aarch64",
                   target_arch = "x86",
                   target_arch = "x86_64"))]
         pub mod bsd44 {
@@ -3043,7 +3101,8 @@ pub mod consts {
         }
         #[cfg(any(target_arch = "x86",
                   target_arch = "x86_64",
-                  target_arch = "arm"))]
+                  target_arch = "arm",
+                  target_arch = "aarch64"))]
         pub mod extra {
             use types::os::arch::c95::c_int;
 
diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
new file mode 100644
index 0000000000000..296552a6abd90
--- /dev/null
+++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target::Target;
+
+pub fn target() -> Target {
+    let base = super::linux_base::opts();
+    Target {
+        data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                      f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\
+                      n32:64-S128".to_string(),
+        llvm_target: "aarch64-unknown-linux-gnu".to_string(),
+        target_endian: "little".to_string(),
+        target_word_size: "64".to_string(),
+        arch: "aarch64".to_string(),
+        target_os: "linux".to_string(),
+        options: base,
+    }
+}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index fdc9b72f1e9df..b7b74fe2314f2 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -60,6 +60,7 @@ mod arm_apple_ios;
 mod arm_linux_androideabi;
 mod arm_unknown_linux_gnueabi;
 mod arm_unknown_linux_gnueabihf;
+mod aarch64_unknown_linux_gnu;
 mod i686_apple_darwin;
 mod i386_apple_ios;
 mod i686_pc_windows_gnu;
@@ -88,8 +89,8 @@ pub struct Target {
     pub target_word_size: String,
     /// OS name to use for conditional compilation.
     pub target_os: String,
-    /// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm", and
-    /// "mips". "mips" includes "mipsel".
+    /// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm",
+    /// "aarch64", and "mips". "mips" includes "mipsel".
     pub arch: String,
     /// Optional settings with defaults.
     pub options: TargetOptions,
@@ -335,6 +336,7 @@ impl Target {
             arm_linux_androideabi,
             arm_unknown_linux_gnueabi,
             arm_unknown_linux_gnueabihf,
+            aarch64_unknown_linux_gnu,
 
             x86_64_unknown_freebsd,
 
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 296ebcf9cfd8f..e16c27a145093 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1962,6 +1962,11 @@ extern {
     pub fn LLVMInitializeARMTargetMC();
     pub fn LLVMInitializeARMAsmPrinter();
     pub fn LLVMInitializeARMAsmParser();
+    pub fn LLVMInitializeAArch64TargetInfo();
+    pub fn LLVMInitializeAArch64Target();
+    pub fn LLVMInitializeAArch64TargetMC();
+    pub fn LLVMInitializeAArch64AsmPrinter();
+    pub fn LLVMInitializeAArch64AsmParser();
     pub fn LLVMInitializeMipsTargetInfo();
     pub fn LLVMInitializeMipsTarget();
     pub fn LLVMInitializeMipsTargetMC();
@@ -2231,6 +2236,12 @@ pub unsafe fn static_link_hack_this_sucks() {
     LLVMInitializeARMAsmPrinter();
     LLVMInitializeARMAsmParser();
 
+    LLVMInitializeAArch64TargetInfo();
+    LLVMInitializeAArch64Target();
+    LLVMInitializeAArch64TargetMC();
+    LLVMInitializeAArch64AsmPrinter();
+    LLVMInitializeAArch64AsmParser();
+
     LLVMInitializeMipsTargetInfo();
     LLVMInitializeMipsTarget();
     LLVMInitializeMipsTargetMC();
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 5cd62675c1dc3..c1e470aa4e8b7 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -1,4 +1,4 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1029,6 +1029,12 @@ unsafe fn configure_llvm(sess: &Session) {
         llvm::LLVMInitializeARMAsmPrinter();
         llvm::LLVMInitializeARMAsmParser();
 
+        llvm::LLVMInitializeAArch64TargetInfo();
+        llvm::LLVMInitializeAArch64Target();
+        llvm::LLVMInitializeAArch64TargetMC();
+        llvm::LLVMInitializeAArch64AsmPrinter();
+        llvm::LLVMInitializeAArch64AsmParser();
+
         llvm::LLVMInitializeMipsTargetInfo();
         llvm::LLVMInitializeMipsTarget();
         llvm::LLVMInitializeMipsTargetMC();
diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs
index b8bee1000824d..5597e112f76d1 100644
--- a/src/librustc_trans/trans/asm.rs
+++ b/src/librustc_trans/trans/asm.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -165,6 +165,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
 // Basically what clang does
 
 #[cfg(any(target_arch = "arm",
+          target_arch = "aarch64",
           target_arch = "mips",
           target_arch = "mipsel"))]
 fn get_clobbers() -> String {
diff --git a/src/librustc_trans/trans/cabi.rs b/src/librustc_trans/trans/cabi.rs
index 9ea158fbe2101..abe5af44c3f56 100644
--- a/src/librustc_trans/trans/cabi.rs
+++ b/src/librustc_trans/trans/cabi.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -17,6 +17,7 @@ use trans::cabi_x86;
 use trans::cabi_x86_64;
 use trans::cabi_x86_win64;
 use trans::cabi_arm;
+use trans::cabi_aarch64;
 use trans::cabi_mips;
 use trans::type_::Type;
 
@@ -115,6 +116,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
             cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
         },
         "arm" => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
+        "aarch64" => cabi_aarch64::compute_abi_info(ccx, atys, rty, ret_def),
         "mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
         a => ccx.sess().fatal((format!("unrecognized arch \"{}\" in target specification", a))
                               []),
diff --git a/src/librustc_trans/trans/cabi_aarch64.rs b/src/librustc_trans/trans/cabi_aarch64.rs
new file mode 100644
index 0000000000000..66308503b818d
--- /dev/null
+++ b/src/librustc_trans/trans/cabi_aarch64.rs
@@ -0,0 +1,165 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_upper_case_globals)]
+
+use llvm;
+use llvm::{Integer, Pointer, Float, Double, Struct, Array};
+use llvm::{StructRetAttribute, ZExtAttribute};
+use trans::cabi::{FnType, ArgType};
+use trans::context::CrateContext;
+use trans::type_::Type;
+
+use std::cmp;
+
+fn align_up_to(off: uint, a: uint) -> uint {
+    return (off + a - 1u) / a * a;
+}
+
+fn align(off: uint, ty: Type) -> uint {
+    let a = ty_align(ty);
+    return align_up_to(off, a);
+}
+
+fn ty_align(ty: Type) -> uint {
+    match ty.kind() {
+        Integer => {
+            unsafe {
+                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
+            }
+        }
+        Pointer => 8,
+        Float => 4,
+        Double => 8,
+        Struct => {
+            if ty.is_packed() {
+                1
+            } else {
+                let str_tys = ty.field_types();
+                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
+            }
+        }
+        Array => {
+            let elt = ty.element_type();
+            ty_align(elt)
+        }
+        _ => panic!("ty_align: unhandled type")
+    }
+}
+
+fn ty_size(ty: Type) -> uint {
+    match ty.kind() {
+        Integer => {
+            unsafe {
+                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
+            }
+        }
+        Pointer => 8,
+        Float => 4,
+        Double => 8,
+        Struct => {
+            if ty.is_packed() {
+                let str_tys = ty.field_types();
+                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
+            } else {
+                let str_tys = ty.field_types();
+                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
+                align(size, ty)
+            }
+        }
+        Array => {
+            let len = ty.array_length();
+            let elt = ty.element_type();
+            let eltsz = ty_size(elt);
+            len * eltsz
+        }
+        _ => panic!("ty_size: unhandled type")
+    }
+}
+
+fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
+    if is_reg_ty(ty) {
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        return ArgType::direct(ty, None, None, attr);
+    }
+    let size = ty_size(ty);
+    if size <= 16 {
+        let llty = if size <= 1 {
+            Type::i8(ccx)
+        } else if size <= 2 {
+            Type::i16(ccx)
+        } else if size <= 4 {
+            Type::i32(ccx)
+        } else if size <= 8 {
+            Type::i64(ccx)
+        } else {
+            Type::array(&Type::i64(ccx), ((size + 7 ) / 8 ) as u64)
+        };
+        return ArgType::direct(ty, Some(llty), None, None);
+    }
+    ArgType::indirect(ty, Some(StructRetAttribute))
+}
+
+fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
+    if is_reg_ty(ty) {
+        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        return ArgType::direct(ty, None, None, attr);
+    }
+    let size = ty_size(ty);
+    if size <= 16 {
+        let llty = if size == 0 {
+            Type::array(&Type::i64(ccx), 0u64)
+        } else if size == 1 {
+            Type::i8(ccx)
+        } else if size == 2 {
+            Type::i16(ccx)
+        } else if size <= 4 {
+            Type::i32(ccx)
+        } else if size <= 8 {
+            Type::i64(ccx)
+        } else {
+            Type::array(&Type::i64(ccx), ((size + 7 ) / 8 ) as u64)
+        };
+        return ArgType::direct(ty, Some(llty), None, None);
+    }
+    ArgType::indirect(ty, None)
+}
+
+fn is_reg_ty(ty: Type) -> bool {
+    match ty.kind() {
+        Integer
+        | Pointer
+        | Float
+        | Double => true,
+        _ => false
+    }
+}
+
+pub fn compute_abi_info(ccx: &CrateContext,
+                        atys: &[Type],
+                        rty: Type,
+                        ret_def: bool) -> FnType {
+    let mut arg_tys = Vec::new();
+    for &aty in atys.iter() {
+        let ty = classify_arg_ty(ccx, aty);
+        arg_tys.push(ty);
+    }
+
+    let ret_ty = if ret_def {
+        classify_ret_ty(ccx, rty)
+    } else {
+        ArgType::direct(Type::void(ccx), None, None, None)
+    };
+
+    return FnType {
+        arg_tys: arg_tys,
+        ret_ty: ret_ty,
+    };
+}
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index c53e164fb0703..3030714f4e989 100644
--- a/src/librustc_trans/trans/mod.rs
+++ b/src/librustc_trans/trans/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -41,6 +41,7 @@ mod cabi_x86;
 mod cabi_x86_64;
 mod cabi_x86_win64;
 mod cabi_arm;
+mod cabi_aarch64;
 mod cabi_mips;
 mod foreign;
 mod intrinsic;
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 615a20baf893c..2ca6bccabc018 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1414,6 +1414,11 @@ mod arch_consts {
     pub const ARCH: &'static str = "arm";
 }
 
+#[cfg(target_arch = "aarch64")]
+mod arch_consts {
+    pub const ARCH: &'static str = "aarch64";
+}
+
 #[cfg(target_arch = "mips")]
 mod arch_consts {
     pub const ARCH: &'static str = "mips";
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 9f3ac84afff51..5caa71b43475e 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -1,4 +1,4 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -29,7 +29,10 @@ mod imp {
     use os::errno;
 
     #[cfg(all(target_os = "linux",
-              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
+              any(target_arch = "x86_64",
+                  target_arch = "x86",
+                  target_arch = "arm",
+                  target_arch = "aarch64")))]
     fn getrandom(buf: &mut [u8]) -> libc::c_long {
         extern "C" {
             fn syscall(number: libc::c_long, ...) -> libc::c_long;
@@ -39,7 +42,7 @@ mod imp {
         const NR_GETRANDOM: libc::c_long = 318;
         #[cfg(target_arch = "x86")]
         const NR_GETRANDOM: libc::c_long = 355;
-        #[cfg(target_arch = "arm")]
+        #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
         const NR_GETRANDOM: libc::c_long = 384;
 
         unsafe {
@@ -48,7 +51,10 @@ mod imp {
     }
 
     #[cfg(not(all(target_os = "linux",
-                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
+                  any(target_arch = "x86_64",
+                      target_arch = "x86",
+                      target_arch = "arm",
+                      target_arch = "aarch64"))))]
     fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
 
     fn getrandom_fill_bytes(v: &mut [u8]) {
@@ -82,7 +88,10 @@ mod imp {
     }
 
     #[cfg(all(target_os = "linux",
-              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
+              any(target_arch = "x86_64",
+                  target_arch = "x86",
+                  target_arch = "arm",
+                  target_arch = "aarch64")))]
     fn is_getrandom_available() -> bool {
         use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Relaxed};
 
@@ -107,7 +116,10 @@ mod imp {
     }
 
     #[cfg(not(all(target_os = "linux",
-                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
+                  any(target_arch = "x86_64",
+                      target_arch = "x86",
+                      target_arch = "arm",
+                      target_arch = "aarch64"))))]
     fn is_getrandom_available() -> bool { false }
 
     /// A random number generator that retrieves randomness straight from
diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs
index 4dbe878277da3..3fdfb5327ee1f 100644
--- a/src/libstd/rt/libunwind.rs
+++ b/src/libstd/rt/libunwind.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -75,6 +75,9 @@ pub const unwinder_private_data_size: uint = 20;
 #[cfg(all(target_arch = "arm", target_os = "ios"))]
 pub const unwinder_private_data_size: uint = 5;
 
+#[cfg(target_arch = "aarch64")]
+pub const unwinder_private_data_size: uint = 2;
+
 #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
 pub const unwinder_private_data_size: uint = 2;
 
diff --git a/src/libstd/sys/common/stack.rs b/src/libstd/sys/common/stack.rs
index 2a88e20c8fa1f..ce5ab67ae613c 100644
--- a/src/libstd/sys/common/stack.rs
+++ b/src/libstd/sys/common/stack.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -226,6 +226,11 @@ pub unsafe fn record_sp_limit(limit: uint) {
         }
     }
 
+    // aarch64 - FIXME(AARCH64): missing...
+    #[cfg(target_arch = "aarch64")]
+    unsafe fn target_record_sp_limit(_: uint) {
+    }
+
     // iOS segmented stack is disabled for now, see related notes
     #[cfg(all(target_arch = "arm", target_os = "ios"))] #[inline(always)]
     unsafe fn target_record_sp_limit(_: uint) {
@@ -315,6 +320,12 @@ pub unsafe fn get_sp_limit() -> uint {
         }
     }
 
+    // aarch64 - FIXME(AARCH64): missing...
+    #[cfg(target_arch = "aarch64")]
+    unsafe fn target_get_sp_limit() -> uint {
+        1024
+    }
+
     // iOS doesn't support segmented stacks yet. This function might
     // be called by runtime though so it is unsafe to mark it as
     // unreachable, let's return a fixed constant.
diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs
index 1bb8ed78177dc..ca419d1c7f436 100644
--- a/src/libstd/sys/unix/c.rs
+++ b/src/libstd/sys/unix/c.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -28,7 +28,8 @@ pub const FIONBIO: libc::c_ulong = 0x8004667e;
 #[cfg(any(all(target_os = "linux",
               any(target_arch = "x86",
                   target_arch = "x86_64",
-                  target_arch = "arm")),
+                  target_arch = "arm",
+                  target_arch = "aarch64")),
           target_os = "android"))]
 pub const FIONBIO: libc::c_ulong = 0x5421;
 #[cfg(all(target_os = "linux",
@@ -43,7 +44,8 @@ pub const FIOCLEX: libc::c_ulong = 0x20006601;
 #[cfg(any(all(target_os = "linux",
               any(target_arch = "x86",
                   target_arch = "x86_64",
-                  target_arch = "arm")),
+                  target_arch = "arm",
+                  target_arch = "aarch64")),
           target_os = "android"))]
 pub const FIOCLEX: libc::c_ulong = 0x5451;
 #[cfg(all(target_os = "linux",
@@ -127,7 +129,8 @@ mod select {
 #[cfg(any(all(target_os = "linux",
               any(target_arch = "x86",
                   target_arch = "x86_64",
-                  target_arch = "arm")),
+                  target_arch = "arm",
+                  target_arch = "aarch64")),
           target_os = "android"))]
 mod signal {
     use libc;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 95ab9b459d671..1fd619a28db84 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -147,6 +147,7 @@ mod imp {
     #[cfg(any(all(target_os = "linux", target_arch = "x86"), // may not match
               all(target_os = "linux", target_arch = "x86_64"),
               all(target_os = "linux", target_arch = "arm"), // may not match
+              all(target_os = "linux", target_arch = "aarch64"),
               all(target_os = "linux", target_arch = "mips"), // may not match
               all(target_os = "linux", target_arch = "mipsel"), // may not match
               target_os = "android"))] // may not match
diff --git a/src/libstd/sys/unix/sync.rs b/src/libstd/sys/unix/sync.rs
index 77c5582d8a4ee..1d8a59dbbb3db 100644
--- a/src/libstd/sys/unix/sync.rs
+++ b/src/libstd/sys/unix/sync.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -125,15 +125,19 @@ mod os {
               target_arch = "mips",
               target_arch = "mipsel"))]
     const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
+    #[cfg(target_arch = "aarch64")]
+    const __SIZEOF_PTHREAD_MUTEX_T: uint = 48 - 8;
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "x86",
               target_arch = "arm",
+              target_arch = "aarch64",
               target_arch = "mips",
               target_arch = "mipsel"))]
     const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
 
-    #[cfg(target_arch = "x86_64")]
+    #[cfg(any(target_arch = "x86_64",
+              target_arch = "aarch64"))]
     const __SIZEOF_PTHREAD_RWLOCK_T: uint = 56 - 8;
 
     #[cfg(any(target_arch = "x86",
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 75e5ac59685b5..91d8aec01cf34 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -175,17 +175,21 @@ macro_rules! thread_local {
 #[doc(hidden)]
 macro_rules! __thread_local_inner {
     (static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(any(target_os = "macos", target_os = "linux"), thread_local)]
+        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                       not(target_arch = "aarch64")),
+                   thread_local)]
         static $name: ::std::thread_local::__impl::KeyInner<$t> =
             __thread_local_inner!($init, $t);
     );
     (pub static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(any(target_os = "macos", target_os = "linux"), thread_local)]
+        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                       not(target_arch = "aarch64")),
+                   thread_local)]
         pub static $name: ::std::thread_local::__impl::KeyInner<$t> =
             __thread_local_inner!($init, $t);
     );
     ($init:expr, $t:ty) => ({
-        #[cfg(any(target_os = "macos", target_os = "linux"))]
+        #[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
         const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
             ::std::thread_local::__impl::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: $init },
@@ -194,7 +198,7 @@ macro_rules! __thread_local_inner {
             }
         };
 
-        #[cfg(all(not(any(target_os = "macos", target_os = "linux"))))]
+        #[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
         const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
             unsafe extern fn __destroy(ptr: *mut u8) {
                 ::std::thread_local::__impl::destroy_value::<$t>(ptr);
@@ -317,7 +321,7 @@ impl<T: 'static> Key<T> {
     pub fn destroyed(&'static self) -> bool { self.state() == State::Destroyed }
 }
 
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
 mod imp {
     use prelude::v1::*;
 
@@ -449,7 +453,7 @@ mod imp {
     }
 }
 
-#[cfg(not(any(target_os = "macos", target_os = "linux")))]
+#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
 mod imp {
     use prelude::v1::*;
 
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index c53d393f1eb70..dc36fda3a020e 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -78,13 +78,19 @@ macro_rules! scoped_thread_local {
 #[doc(hidden)]
 macro_rules! __scoped_thread_local_inner {
     (static $name:ident: $t:ty) => (
-        #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios")),
+        #[cfg_attr(not(any(windows,
+                           target_os = "android",
+                           target_os = "ios",
+                           target_arch = "aarch64")),
                    thread_local)]
         static $name: ::std::thread_local::scoped::Key<$t> =
             __scoped_thread_local_inner!($t);
     );
     (pub static $name:ident: $t:ty) => (
-        #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios")),
+        #[cfg_attr(not(any(windows,
+                           target_os = "android",
+                           target_os = "ios",
+                           target_arch = "aarch64")),
                    thread_local)]
         pub static $name: ::std::thread_local::scoped::Key<$t> =
             __scoped_thread_local_inner!($t);
@@ -92,14 +98,14 @@ macro_rules! __scoped_thread_local_inner {
     ($t:ty) => ({
         use std::thread_local::scoped::Key as __Key;
 
-        #[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
+        #[cfg(not(any(windows, target_os = "android", target_os = "ios", target_arch = "aarch64")))]
         const _INIT: __Key<$t> = __Key {
             inner: ::std::thread_local::scoped::__impl::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: 0 as *mut _ },
             }
         };
 
-        #[cfg(any(windows, target_os = "android", target_os = "ios"))]
+        #[cfg(any(windows, target_os = "android", target_os = "ios", target_arch = "aarch64"))]
         const _INIT: __Key<$t> = __Key {
             inner: ::std::thread_local::scoped::__impl::KeyInner {
                 inner: ::std::thread_local::scoped::__impl::OS_INIT,
@@ -199,7 +205,7 @@ impl<T> Key<T> {
     }
 }
 
-#[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
+#[cfg(not(any(windows, target_os = "android", target_os = "ios", target_arch = "aarch64")))]
 mod imp {
     use std::cell::UnsafeCell;
 
@@ -217,7 +223,7 @@ mod imp {
     }
 }
 
-#[cfg(any(windows, target_os = "android", target_os = "ios"))]
+#[cfg(any(windows, target_os = "android", target_os = "ios", target_arch = "aarch64"))]
 mod imp {
     use kinds::marker;
     use sys_common::thread_local::StaticKey as OsStaticKey;
diff --git a/src/rt/arch/aarch64/macros.S b/src/rt/arch/aarch64/macros.S
new file mode 100644
index 0000000000000..ae42a5d22433c
--- /dev/null
+++ b/src/rt/arch/aarch64/macros.S
@@ -0,0 +1,11 @@
+.macro	func _name
+	.text
+	.align	2
+	.globl	\_name
+	.type	\_name, %function
+\_name:
+.endm
+
+.macro	endfunc _name
+	.size	\_name, .-\_name
+.endm
diff --git a/src/rt/arch/aarch64/morestack.S b/src/rt/arch/aarch64/morestack.S
new file mode 100644
index 0000000000000..12827cea0feda
--- /dev/null
+++ b/src/rt/arch/aarch64/morestack.S
@@ -0,0 +1,19 @@
+#include "macros.S"
+
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
+
+/* See i386/morestack.S for the lengthy, general explanation. */
+
+.global rust_stack_exhausted
+
+// FIXME(AARCH64): this might not be perfectly right but works for now
+func	__morestack
+	.cfi_startproc
+	bl rust_stack_exhausted
+	// the above function ensures that it never returns
+	.cfi_endproc
+endfunc	__morestack
+	.hidden __morestack
diff --git a/src/rt/arch/aarch64/record_sp.S b/src/rt/arch/aarch64/record_sp.S
new file mode 100644
index 0000000000000..115e286866e6e
--- /dev/null
+++ b/src/rt/arch/aarch64/record_sp.S
@@ -0,0 +1,6 @@
+#include "macros.S"
+
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 40beb564f7c72..c1ad6754ca1c3 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2014-10-04
+2015-01-03
diff --git a/src/test/auxiliary/extern_calling_convention.rs b/src/test/auxiliary/extern_calling_convention.rs
index 1a579dd1b0e2d..d7e84a474e849 100644
--- a/src/test/auxiliary/extern_calling_convention.rs
+++ b/src/test/auxiliary/extern_calling_convention.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -24,7 +24,7 @@ pub extern "win64" fn foo(a: int, b: int, c: int, d: int) {
 }
 
 #[inline(never)]
-#[cfg(any(target_arch = "x86", target_arch = "arm"))]
+#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))]
 pub extern fn foo(a: int, b: int, c: int, d: int) {
     assert!(a == 1);
     assert!(b == 2);
diff --git a/src/test/compile-fail/asm-in-bad-modifier.rs b/src/test/compile-fail/asm-in-bad-modifier.rs
index d2216d95867be..bc240df9b3b1c 100644
--- a/src/test/compile-fail/asm-in-bad-modifier.rs
+++ b/src/test/compile-fail/asm-in-bad-modifier.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,7 +14,8 @@ fn foo(x: int) { println!("{}", x); }
 
 #[cfg(any(target_arch = "x86",
           target_arch = "x86_64",
-          target_arch = "arm"))]
+          target_arch = "arm",
+          target_arch = "aarch64"))]
 pub fn main() {
     let x: int;
     let y: int;
@@ -26,5 +27,8 @@ pub fn main() {
     foo(y);
 }
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")))]
+#[cfg(not(any(target_arch = "x86",
+              target_arch = "x86_64",
+              target_arch = "arm",
+              target_arch = "aarch64")))]
 pub fn main() {}
diff --git a/src/test/compile-fail/asm-out-assign-imm.rs b/src/test/compile-fail/asm-out-assign-imm.rs
index a35f72ab4dc7b..387b4bec47eaa 100644
--- a/src/test/compile-fail/asm-out-assign-imm.rs
+++ b/src/test/compile-fail/asm-out-assign-imm.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,7 +14,8 @@ fn foo(x: int) { println!("{}", x); }
 
 #[cfg(any(target_arch = "x86",
           target_arch = "x86_64",
-          target_arch = "arm"))]
+          target_arch = "arm",
+          target_arch = "aarch64"))]
 pub fn main() {
     let x: int;
     x = 1; //~ NOTE prior assignment occurs here
@@ -25,5 +26,8 @@ pub fn main() {
     foo(x);
 }
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")))]
+#[cfg(not(any(target_arch = "x86",
+              target_arch = "x86_64",
+              target_arch = "arm",
+              target_arch = "aarch64")))]
 pub fn main() {}
diff --git a/src/test/compile-fail/asm-out-no-modifier.rs b/src/test/compile-fail/asm-out-no-modifier.rs
index 76d4c516c4e82..4690bdc40cbc0 100644
--- a/src/test/compile-fail/asm-out-no-modifier.rs
+++ b/src/test/compile-fail/asm-out-no-modifier.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,7 +14,8 @@ fn foo(x: int) { println!("{}", x); }
 
 #[cfg(any(target_arch = "x86",
           target_arch = "x86_64",
-          target_arch = "arm"))]
+          target_arch = "arm",
+          target_arch = "aarch64"))]
 pub fn main() {
     let x: int;
     unsafe {
@@ -23,5 +24,8 @@ pub fn main() {
     foo(x);
 }
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")))]
+#[cfg(not(any(target_arch = "x86",
+              target_arch = "x86_64",
+              target_arch = "arm",
+              target_arch = "aarch64")))]
 pub fn main() {}
diff --git a/src/test/compile-fail/asm-out-read-uninit.rs b/src/test/compile-fail/asm-out-read-uninit.rs
index aa83a89fec0a9..2577dcc3f9954 100644
--- a/src/test/compile-fail/asm-out-read-uninit.rs
+++ b/src/test/compile-fail/asm-out-read-uninit.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,7 +14,8 @@ fn foo(x: int) { println!("{}", x); }
 
 #[cfg(any(target_arch = "x86",
           target_arch = "x86_64",
-          target_arch = "arm"))]
+          target_arch = "arm",
+          target_arch = "aarch64"))]
 pub fn main() {
     let x: int;
     unsafe {
@@ -23,5 +24,8 @@ pub fn main() {
     foo(x);
 }
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")))]
+#[cfg(not(any(target_arch = "x86",
+              target_arch = "x86_64",
+              target_arch = "arm",
+              target_arch = "aarch64")))]
 pub fn main() {}
diff --git a/src/test/compile-fail/asm-src-loc.rs b/src/test/compile-fail/asm-src-loc.rs
index b4ebe07776a4d..e3cece7c8f0db 100644
--- a/src/test/compile-fail/asm-src-loc.rs
+++ b/src/test/compile-fail/asm-src-loc.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -12,6 +12,6 @@
 
 fn main() {
     unsafe {
-        asm!("nowayisthisavalidinstruction"); //~ ERROR invalid instruction
+        asm!("nowayisthisavalidinstruction"); //~ ERROR instruction
     }
 }
diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs b/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs
index 22a9fffb2fb23..0cb73bc98a45a 100644
--- a/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs
+++ b/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -32,7 +32,7 @@ fn main() {
     println!("ov3 0x%x",  x.as_slice()[idx]);
 }
 
-#[cfg(target_arch="x86_64")]
+#[cfg(any(target_arch="x86_64", target_arch = "aarch64"))]
 fn main() {
     // This version just panics anyways, for symmetry on 64-bit hosts.
     let x = vec!(1u,2u,3u);
diff --git a/src/test/run-pass/bitwise.rs b/src/test/run-pass/bitwise.rs
index c2d5f17054d58..251804e214b60 100644
--- a/src/test/run-pass/bitwise.rs
+++ b/src/test/run-pass/bitwise.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,7 +14,7 @@ fn target() {
     assert_eq!(-1000 as uint >> 3u, 536870787u);
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
 fn target() {
     assert_eq!(-1000 as uint >> 3u, 2305843009213693827u);
 }
diff --git a/src/test/run-pass/conditional-compile-arch.rs b/src/test/run-pass/conditional-compile-arch.rs
index 106f59d7c7860..0e9447bd2497d 100644
--- a/src/test/run-pass/conditional-compile-arch.rs
+++ b/src/test/run-pass/conditional-compile-arch.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -16,3 +16,6 @@ pub fn main() { }
 
 #[cfg(target_arch = "arm")]
 pub fn main() { }
+
+#[cfg(target_arch = "aarch64")]
+pub fn main() { }
diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs
index 6ab753d526f5d..52fcaf5c3ae8d 100644
--- a/src/test/run-pass/intrinsic-alignment.rs
+++ b/src/test/run-pass/intrinsic-alignment.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -32,7 +32,7 @@ mod m {
     }
 
     #[main]
-    #[cfg(any(target_arch = "x86_64", target_arch = "arm"))]
+    #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
     pub fn main() {
         unsafe {
             assert_eq!(::rusti::pref_align_of::<u64>(), 8u);
diff --git a/src/test/run-pass/issue-2895.rs b/src/test/run-pass/issue-2895.rs
index b9f522f1f8590..5f7a4d87b9ae2 100644
--- a/src/test/run-pass/issue-2895.rs
+++ b/src/test/run-pass/issue-2895.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -22,7 +22,7 @@ impl Drop for Kitty {
     fn drop(&mut self) {}
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64", target_arch="aarch64"))]
 pub fn main() {
     assert_eq!(mem::size_of::<Cat>(), 8 as uint);
     assert_eq!(mem::size_of::<Kitty>(), 16 as uint);
diff --git a/src/test/run-pass/rec-align-u32.rs b/src/test/run-pass/rec-align-u32.rs
index b7e362a57aaeb..e165b34f680ba 100644
--- a/src/test/run-pass/rec-align-u32.rs
+++ b/src/test/run-pass/rec-align-u32.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -36,7 +36,7 @@ struct Outer {
 }
 
 
-#[cfg(any(target_arch = "x86", target_arch = "arm"))]
+#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))]
 mod m {
     pub fn align() -> uint { 4u }
     pub fn size() -> uint { 8u }
diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs
index 26ec5976f9b48..c3cec77a64658 100644
--- a/src/test/run-pass/rec-align-u64.rs
+++ b/src/test/run-pass/rec-align-u64.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -47,7 +47,7 @@ mod m {
         pub fn size() -> uint { 12u }
     }
 
-    #[cfg(any(target_arch = "x86_64", target_arch = "arm"))]
+    #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
     pub mod m {
         pub fn align() -> uint { 8u }
         pub fn size() -> uint { 16u }
diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs
index bb06aec23f6bc..bd945327d107c 100644
--- a/src/test/run-pass/struct-return.rs
+++ b/src/test/run-pass/struct-return.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -46,7 +46,7 @@ fn test1() {
     }
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
 fn test2() {
     unsafe {
         let f = Floats { a: 1.234567890e-15_f64,