Index: Unwind/CMakeLists.txt
===================================================================
--- Unwind/CMakeLists.txt
+++ Unwind/CMakeLists.txt
@@ -7,11 +7,22 @@
   Unwind-sjlj.c
 )
 
-append_if(LIBUNWIND_SOURCES APPLE Unwind_AppleExtras.cpp)
+#append_if(LIBUNWIND_SOURCES APPLE Unwind_AppleExtras.cpp)
 
 set(LIBUNWIND_ASM_SOURCES
-  UnwindRegistersRestore.S
-  UnwindRegistersSave.S
+  UnwindRegistersRestore_jumpto.S
+  UnwindRegistersRestore_restoreCoreAndJumpTo.S
+  UnwindRegistersRestore_restoreVFPWithFLDMD.S
+  UnwindRegistersRestore_restoreVFPWithFLDMX.S
+  UnwindRegistersRestore_restoreVFPv3.S
+  UnwindRegistersRestore_restoreiWMMX.S
+  UnwindRegistersRestore_restoreiWMMXControl.S
+  UnwindRegistersSave_saveVFPWithFSTMD.S
+  UnwindRegistersSave_saveVFPWithFSTMX.S
+  UnwindRegistersSave_saveVFPv3.S
+  UnwindRegistersSave_saveiWMMXControl.S
+  UnwindRegistersSave_saveiWMMX.S
+  UnwindRegistersSave_unw_getcontext.S
 )
 
 set_source_files_properties(${LIBUNWIND_ASM_SOURCES} PROPERTIES LANGUAGE C)
@@ -32,7 +43,7 @@
   ../../include/unwind.h
 )
 
-append_if(LIBCXXABI_HEADERS APPLE ../../include/mach-o/compact_unwind_encoding.h)
+#append_if(LIBCXXABI_HEADERS APPLE ../../include/mach-o/compact_unwind_encoding.h)
 
 if (MSVC_IDE)
   # Force them all into the headers dir on MSVC, otherwise they end up at
Index: Unwind/UnwindRegistersRestore.S
===================================================================
--- Unwind/UnwindRegistersRestore.S
+++ Unwind/UnwindRegistersRestore.S
@@ -1,445 +0,0 @@
-//===-------------------- UnwindRegistersRestore.S ------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "assembly.h"
-
-  .text
-
-#if __i386__
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
-#
-# void libunwind::Registers_x86::jumpto()
-#
-# On entry:
-#  +                       +
-#  +-----------------------+
-#  + thread_state pointer  +
-#  +-----------------------+
-#  + return address        +
-#  +-----------------------+   <-- SP
-#  +                       +
-  movl   4(%esp), %eax
-  # set up eax and ret on new stack location
-  movl  28(%eax), %edx # edx holds new stack pointer
-  subl  $8,%edx
-  movl  %edx, 28(%eax)
-  movl  0(%eax), %ebx
-  movl  %ebx, 0(%edx)
-  movl  40(%eax), %ebx
-  movl  %ebx, 4(%edx)
-  # we now have ret and eax pushed onto where new stack will be
-  # restore all registers
-  movl   4(%eax), %ebx
-  movl   8(%eax), %ecx
-  movl  12(%eax), %edx
-  movl  16(%eax), %edi
-  movl  20(%eax), %esi
-  movl  24(%eax), %ebp
-  movl  28(%eax), %esp
-  # skip ss
-  # skip eflags
-  pop    %eax  # eax was already pushed on new stack
-  ret        # eip was already pushed on new stack
-  # skip cs
-  # skip ds
-  # skip es
-  # skip fs
-  # skip gs
-
-#elif __x86_64__
-
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
-#
-# void libunwind::Registers_x86_64::jumpto()
-#
-# On entry, thread_state pointer is in rdi
-
-  movq  56(%rdi), %rax # rax holds new stack pointer
-  subq  $16, %rax
-  movq  %rax, 56(%rdi)
-  movq  32(%rdi), %rbx  # store new rdi on new stack
-  movq  %rbx, 0(%rax)
-  movq  128(%rdi), %rbx # store new rip on new stack
-  movq  %rbx, 8(%rax)
-  # restore all registers
-  movq    0(%rdi), %rax
-  movq    8(%rdi), %rbx
-  movq   16(%rdi), %rcx
-  movq   24(%rdi), %rdx
-  # restore rdi later
-  movq   40(%rdi), %rsi
-  movq   48(%rdi), %rbp
-  # restore rsp later
-  movq   64(%rdi), %r8
-  movq   72(%rdi), %r9
-  movq   80(%rdi), %r10
-  movq   88(%rdi), %r11
-  movq   96(%rdi), %r12
-  movq  104(%rdi), %r13
-  movq  112(%rdi), %r14
-  movq  120(%rdi), %r15
-  # skip rflags
-  # skip cs
-  # skip fs
-  # skip gs
-  movq  56(%rdi), %rsp  # cut back rsp to new location
-  pop    %rdi      # rdi was saved here earlier
-  ret            # rip was saved here
-
-
-#elif __ppc__
-
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
-;
-; void libunwind::Registers_ppc::jumpto()
-;
-; On entry:
-;  thread_state pointer is in r3
-;
-
-  ; restore integral registerrs
-  ; skip r0 for now
-  ; skip r1 for now
-  lwz     r2, 16(r3)
-  ; skip r3 for now
-  ; skip r4 for now
-  ; skip r5 for now
-  lwz     r6, 32(r3)
-  lwz     r7, 36(r3)
-  lwz     r8, 40(r3)
-  lwz     r9, 44(r3)
-  lwz    r10, 48(r3)
-  lwz    r11, 52(r3)
-  lwz    r12, 56(r3)
-  lwz    r13, 60(r3)
-  lwz    r14, 64(r3)
-  lwz    r15, 68(r3)
-  lwz    r16, 72(r3)
-  lwz    r17, 76(r3)
-  lwz    r18, 80(r3)
-  lwz    r19, 84(r3)
-  lwz    r20, 88(r3)
-  lwz    r21, 92(r3)
-  lwz    r22, 96(r3)
-  lwz    r23,100(r3)
-  lwz    r24,104(r3)
-  lwz    r25,108(r3)
-  lwz    r26,112(r3)
-  lwz    r27,116(r3)
-  lwz    r28,120(r3)
-  lwz    r29,124(r3)
-  lwz    r30,128(r3)
-  lwz    r31,132(r3)
-
-  ; restore float registers
-  lfd    f0, 160(r3)
-  lfd    f1, 168(r3)
-  lfd    f2, 176(r3)
-  lfd    f3, 184(r3)
-  lfd    f4, 192(r3)
-  lfd    f5, 200(r3)
-  lfd    f6, 208(r3)
-  lfd    f7, 216(r3)
-  lfd    f8, 224(r3)
-  lfd    f9, 232(r3)
-  lfd    f10,240(r3)
-  lfd    f11,248(r3)
-  lfd    f12,256(r3)
-  lfd    f13,264(r3)
-  lfd    f14,272(r3)
-  lfd    f15,280(r3)
-  lfd    f16,288(r3)
-  lfd    f17,296(r3)
-  lfd    f18,304(r3)
-  lfd    f19,312(r3)
-  lfd    f20,320(r3)
-  lfd    f21,328(r3)
-  lfd    f22,336(r3)
-  lfd    f23,344(r3)
-  lfd    f24,352(r3)
-  lfd    f25,360(r3)
-  lfd    f26,368(r3)
-  lfd    f27,376(r3)
-  lfd    f28,384(r3)
-  lfd    f29,392(r3)
-  lfd    f30,400(r3)
-  lfd    f31,408(r3)
-
-  ; restore vector registers if any are in use
-  lwz    r5,156(r3)  ; test VRsave
-  cmpwi  r5,0
-  beq    Lnovec
-
-  subi  r4,r1,16
-  rlwinm  r4,r4,0,0,27  ; mask low 4-bits
-  ; r4 is now a 16-byte aligned pointer into the red zone
-  ; the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
-
-
-#define LOAD_VECTOR_UNALIGNEDl(_index) \
-  andis.  r0,r5,(1<<(15-_index))  @\
-  beq    Ldone  ## _index     @\
-  lwz    r0, 424+_index*16(r3)  @\
-  stw    r0, 0(r4)        @\
-  lwz    r0, 424+_index*16+4(r3)  @\
-  stw    r0, 4(r4)        @\
-  lwz    r0, 424+_index*16+8(r3)  @\
-  stw    r0, 8(r4)        @\
-  lwz    r0, 424+_index*16+12(r3)@\
-  stw    r0, 12(r4)        @\
-  lvx    v ## _index,0,r4    @\
-Ldone  ## _index:
-
-#define LOAD_VECTOR_UNALIGNEDh(_index) \
-  andi.  r0,r5,(1<<(31-_index))  @\
-  beq    Ldone  ## _index    @\
-  lwz    r0, 424+_index*16(r3)  @\
-  stw    r0, 0(r4)        @\
-  lwz    r0, 424+_index*16+4(r3)  @\
-  stw    r0, 4(r4)        @\
-  lwz    r0, 424+_index*16+8(r3)  @\
-  stw    r0, 8(r4)        @\
-  lwz    r0, 424+_index*16+12(r3)@\
-  stw    r0, 12(r4)        @\
-  lvx    v ## _index,0,r4    @\
-  Ldone  ## _index:
-
-
-  LOAD_VECTOR_UNALIGNEDl(0)
-  LOAD_VECTOR_UNALIGNEDl(1)
-  LOAD_VECTOR_UNALIGNEDl(2)
-  LOAD_VECTOR_UNALIGNEDl(3)
-  LOAD_VECTOR_UNALIGNEDl(4)
-  LOAD_VECTOR_UNALIGNEDl(5)
-  LOAD_VECTOR_UNALIGNEDl(6)
-  LOAD_VECTOR_UNALIGNEDl(7)
-  LOAD_VECTOR_UNALIGNEDl(8)
-  LOAD_VECTOR_UNALIGNEDl(9)
-  LOAD_VECTOR_UNALIGNEDl(10)
-  LOAD_VECTOR_UNALIGNEDl(11)
-  LOAD_VECTOR_UNALIGNEDl(12)
-  LOAD_VECTOR_UNALIGNEDl(13)
-  LOAD_VECTOR_UNALIGNEDl(14)
-  LOAD_VECTOR_UNALIGNEDl(15)
-  LOAD_VECTOR_UNALIGNEDh(16)
-  LOAD_VECTOR_UNALIGNEDh(17)
-  LOAD_VECTOR_UNALIGNEDh(18)
-  LOAD_VECTOR_UNALIGNEDh(19)
-  LOAD_VECTOR_UNALIGNEDh(20)
-  LOAD_VECTOR_UNALIGNEDh(21)
-  LOAD_VECTOR_UNALIGNEDh(22)
-  LOAD_VECTOR_UNALIGNEDh(23)
-  LOAD_VECTOR_UNALIGNEDh(24)
-  LOAD_VECTOR_UNALIGNEDh(25)
-  LOAD_VECTOR_UNALIGNEDh(26)
-  LOAD_VECTOR_UNALIGNEDh(27)
-  LOAD_VECTOR_UNALIGNEDh(28)
-  LOAD_VECTOR_UNALIGNEDh(29)
-  LOAD_VECTOR_UNALIGNEDh(30)
-  LOAD_VECTOR_UNALIGNEDh(31)
-
-Lnovec:
-  lwz    r0, 136(r3) ; __cr
-  mtocrf  255,r0
-  lwz    r0, 148(r3) ; __ctr
-  mtctr  r0
-  lwz    r0, 0(r3)  ; __ssr0
-  mtctr  r0
-  lwz    r0, 8(r3)  ; do r0 now
-  lwz    r5,28(r3)  ; do r5 now
-  lwz    r4,24(r3)  ; do r4 now
-  lwz    r1,12(r3)  ; do sp now
-  lwz    r3,20(r3)  ; do r3 last
-  bctr
-
-#elif __arm64__
-
-;
-; void libunwind::Registers_arm64::jumpto()
-;
-; On entry:
-;  thread_state pointer is in x0
-;
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
-  ; skip restore of x0,x1 for now
-  ldp    x2, x3,  [x0, #0x010]
-  ldp    x4, x5,  [x0, #0x020]
-  ldp    x6, x7,  [x0, #0x030]
-  ldp    x8, x9,  [x0, #0x040]
-  ldp    x10,x11, [x0, #0x050]
-  ldp    x12,x13, [x0, #0x060]
-  ldp    x14,x15, [x0, #0x070]
-  ldp    x16,x17, [x0, #0x080]
-  ldp    x18,x19, [x0, #0x090]
-  ldp    x20,x21, [x0, #0x0A0]
-  ldp    x22,x23, [x0, #0x0B0]
-  ldp    x24,x25, [x0, #0x0C0]
-  ldp    x26,x27, [x0, #0x0D0]
-  ldp    x28,fp,  [x0, #0x0E0]
-  ldr    lr,      [x0, #0x100]  ; restore pc into lr
-  ldr    x1,      [x0, #0x0F8]
-  mov    sp,x1          ; restore sp
-
-  ldp    d0, d1,  [x0, #0x110]
-  ldp    d2, d3,  [x0, #0x120]
-  ldp    d4, d5,  [x0, #0x130]
-  ldp    d6, d7,  [x0, #0x140]
-  ldp    d8, d9,  [x0, #0x150]
-  ldp    d10,d11, [x0, #0x160]
-  ldp    d12,d13, [x0, #0x170]
-  ldp    d14,d15, [x0, #0x180]
-  ldp    d16,d17, [x0, #0x190]
-  ldp    d18,d19, [x0, #0x1A0]
-  ldp    d20,d21, [x0, #0x1B0]
-  ldp    d22,d23, [x0, #0x1C0]
-  ldp    d24,d25, [x0, #0x1D0]
-  ldp    d26,d27, [x0, #0x1E0]
-  ldp    d28,d29, [x0, #0x1F0]
-  ldr    d30,     [x0, #0x200]
-  ldr    d31,     [x0, #0x208]
-
-  ldp    x0, x1,  [x0, #0x000]  ; restore x0,x1
-  ret    lr            ; jump to pc
-
-#elif __arm__ && !__APPLE__
-
-#if !defined(__ARM_ARCH_ISA_ARM)
-  .thumb
-#endif
-
-@
-@ void libunwind::Registers_arm::restoreCoreAndJumpTo()
-@
-@ On entry:
-@  thread_state pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv)
-#if !defined(__ARM_ARCH_ISA_ARM)
-  ldr r2, [r0, #52]
-  ldr r3, [r0, #60]
-  mov sp, r2
-  mov lr, r3         @ restore pc into lr
-  ldm r0, {r0-r7}
-#else
-  @ Use lr as base so that r0 can be restored.
-  mov lr, r0
-  @ 32bit thumb-2 restrictions for ldm:
-  @ . the sp (r13) cannot be in the list
-  @ . the pc (r15) and lr (r14) cannot both be in the list in an LDM instruction
-  ldm lr, {r0-r12}
-  ldr sp, [lr, #52]
-  ldr lr, [lr, #60]  @ restore pc into lr
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy)
-#if defined(__ARM_FP)
-  @ VFP and iwMMX instructions are only available when compiling with the flags
-  @ that enable them. We do not want to do that in the library (because we do not
-  @ want the compiler to generate instructions that access those) but this is
-  @ only accessed if the personality routine needs these registers. Use of
-  @ these registers implies they are, actually, available on the target, so
-  @ it's ok to execute.
-  @ So, generate the instruction using the corresponding coprocessor mnemonic.
-#if __ARM_ARCH < 7
-  ldc p11, cr0, [r0], {0x20}  @ fldmiad r0, {d0-d15}
-#else
-  vldmia r0, {d0-d15}
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
-  ldc p11, cr0, [r0], {0x21}  @ fldmiax r0, {d0-d15}
-#else
-  vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
-#if defined(__ARM_FP)
-#ifndef __ARM_NEON
-  ldcl p11, cr0, [r0], {0x20}  @ vldm r0, {d16-d31}
-#else
-  vldmia r0, {d16-d31}
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
-  ldcl p1, cr0, [r0], #8  @ wldrd wR0, [r0], #8
-  ldcl p1, cr1, [r0], #8  @ wldrd wR1, [r0], #8
-  ldcl p1, cr2, [r0], #8  @ wldrd wR2, [r0], #8
-  ldcl p1, cr3, [r0], #8  @ wldrd wR3, [r0], #8
-  ldcl p1, cr4, [r0], #8  @ wldrd wR4, [r0], #8
-  ldcl p1, cr5, [r0], #8  @ wldrd wR5, [r0], #8
-  ldcl p1, cr6, [r0], #8  @ wldrd wR6, [r0], #8
-  ldcl p1, cr7, [r0], #8  @ wldrd wR7, [r0], #8
-  ldcl p1, cr8, [r0], #8  @ wldrd wR8, [r0], #8
-  ldcl p1, cr9, [r0], #8  @ wldrd wR9, [r0], #8
-  ldcl p1, cr10, [r0], #8  @ wldrd wR10, [r0], #8
-  ldcl p1, cr11, [r0], #8  @ wldrd wR11, [r0], #8
-  ldcl p1, cr12, [r0], #8  @ wldrd wR12, [r0], #8
-  ldcl p1, cr13, [r0], #8  @ wldrd wR13, [r0], #8
-  ldcl p1, cr14, [r0], #8  @ wldrd wR14, [r0], #8
-  ldcl p1, cr15, [r0], #8  @ wldrd wR15, [r0], #8
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
-  ldc2 p1, cr8, [r0], #4  @ wldrw wCGR0, [r0], #4
-  ldc2 p1, cr9, [r0], #4  @ wldrw wCGR1, [r0], #4
-  ldc2 p1, cr10, [r0], #4  @ wldrw wCGR2, [r0], #4
-  ldc2 p1, cr11, [r0], #4  @ wldrw wCGR3, [r0], #4
-#endif
-  JMP(lr)
-
-#endif
Index: Unwind/UnwindRegistersRestore_jumpto.S
===================================================================
--- Unwind/UnwindRegistersRestore_jumpto.S
+++ Unwind/UnwindRegistersRestore_jumpto.S
@@ -0,0 +1,311 @@
+//===-------------------- UnwindRegistersRestore.S ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __i386__
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
+#
+# void libunwind::Registers_x86::jumpto()
+#
+# On entry:
+#  +                       +
+#  +-----------------------+
+#  + thread_state pointer  +
+#  +-----------------------+
+#  + return address        +
+#  +-----------------------+   <-- SP
+#  +                       +
+  movl   4(%esp), %eax
+  # set up eax and ret on new stack location
+  movl  28(%eax), %edx # edx holds new stack pointer
+  subl  $8,%edx
+  movl  %edx, 28(%eax)
+  movl  0(%eax), %ebx
+  movl  %ebx, 0(%edx)
+  movl  40(%eax), %ebx
+  movl  %ebx, 4(%edx)
+  # we now have ret and eax pushed onto where new stack will be
+  # restore all registers
+  movl   4(%eax), %ebx
+  movl   8(%eax), %ecx
+  movl  12(%eax), %edx
+  movl  16(%eax), %edi
+  movl  20(%eax), %esi
+  movl  24(%eax), %ebp
+  movl  28(%eax), %esp
+  # skip ss
+  # skip eflags
+  pop    %eax  # eax was already pushed on new stack
+  ret        # eip was already pushed on new stack
+  # skip cs
+  # skip ds
+  # skip es
+  # skip fs
+  # skip gs
+
+#elif __x86_64__
+
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
+#
+# void libunwind::Registers_x86_64::jumpto()
+#
+# On entry, thread_state pointer is in rdi
+
+  movq  56(%rdi), %rax # rax holds new stack pointer
+  subq  $16, %rax
+  movq  %rax, 56(%rdi)
+  movq  32(%rdi), %rbx  # store new rdi on new stack
+  movq  %rbx, 0(%rax)
+  movq  128(%rdi), %rbx # store new rip on new stack
+  movq  %rbx, 8(%rax)
+  # restore all registers
+  movq    0(%rdi), %rax
+  movq    8(%rdi), %rbx
+  movq   16(%rdi), %rcx
+  movq   24(%rdi), %rdx
+  # restore rdi later
+  movq   40(%rdi), %rsi
+  movq   48(%rdi), %rbp
+  # restore rsp later
+  movq   64(%rdi), %r8
+  movq   72(%rdi), %r9
+  movq   80(%rdi), %r10
+  movq   88(%rdi), %r11
+  movq   96(%rdi), %r12
+  movq  104(%rdi), %r13
+  movq  112(%rdi), %r14
+  movq  120(%rdi), %r15
+  # skip rflags
+  # skip cs
+  # skip fs
+  # skip gs
+  movq  56(%rdi), %rsp  # cut back rsp to new location
+  pop    %rdi      # rdi was saved here earlier
+  ret            # rip was saved here
+
+
+#elif __ppc__
+
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
+;
+; void libunwind::Registers_ppc::jumpto()
+;
+; On entry:
+;  thread_state pointer is in r3
+;
+
+  ; restore integral registerrs
+  ; skip r0 for now
+  ; skip r1 for now
+  lwz     r2, 16(r3)
+  ; skip r3 for now
+  ; skip r4 for now
+  ; skip r5 for now
+  lwz     r6, 32(r3)
+  lwz     r7, 36(r3)
+  lwz     r8, 40(r3)
+  lwz     r9, 44(r3)
+  lwz    r10, 48(r3)
+  lwz    r11, 52(r3)
+  lwz    r12, 56(r3)
+  lwz    r13, 60(r3)
+  lwz    r14, 64(r3)
+  lwz    r15, 68(r3)
+  lwz    r16, 72(r3)
+  lwz    r17, 76(r3)
+  lwz    r18, 80(r3)
+  lwz    r19, 84(r3)
+  lwz    r20, 88(r3)
+  lwz    r21, 92(r3)
+  lwz    r22, 96(r3)
+  lwz    r23,100(r3)
+  lwz    r24,104(r3)
+  lwz    r25,108(r3)
+  lwz    r26,112(r3)
+  lwz    r27,116(r3)
+  lwz    r28,120(r3)
+  lwz    r29,124(r3)
+  lwz    r30,128(r3)
+  lwz    r31,132(r3)
+
+  ; restore float registers
+  lfd    f0, 160(r3)
+  lfd    f1, 168(r3)
+  lfd    f2, 176(r3)
+  lfd    f3, 184(r3)
+  lfd    f4, 192(r3)
+  lfd    f5, 200(r3)
+  lfd    f6, 208(r3)
+  lfd    f7, 216(r3)
+  lfd    f8, 224(r3)
+  lfd    f9, 232(r3)
+  lfd    f10,240(r3)
+  lfd    f11,248(r3)
+  lfd    f12,256(r3)
+  lfd    f13,264(r3)
+  lfd    f14,272(r3)
+  lfd    f15,280(r3)
+  lfd    f16,288(r3)
+  lfd    f17,296(r3)
+  lfd    f18,304(r3)
+  lfd    f19,312(r3)
+  lfd    f20,320(r3)
+  lfd    f21,328(r3)
+  lfd    f22,336(r3)
+  lfd    f23,344(r3)
+  lfd    f24,352(r3)
+  lfd    f25,360(r3)
+  lfd    f26,368(r3)
+  lfd    f27,376(r3)
+  lfd    f28,384(r3)
+  lfd    f29,392(r3)
+  lfd    f30,400(r3)
+  lfd    f31,408(r3)
+
+  ; restore vector registers if any are in use
+  lwz    r5,156(r3)  ; test VRsave
+  cmpwi  r5,0
+  beq    Lnovec
+
+  subi  r4,r1,16
+  rlwinm  r4,r4,0,0,27  ; mask low 4-bits
+  ; r4 is now a 16-byte aligned pointer into the red zone
+  ; the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
+
+
+#define LOAD_VECTOR_UNALIGNEDl(_index) \
+  andis.  r0,r5,(1<<(15-_index))  @\
+  beq    Ldone  ## _index     @\
+  lwz    r0, 424+_index*16(r3)  @\
+  stw    r0, 0(r4)        @\
+  lwz    r0, 424+_index*16+4(r3)  @\
+  stw    r0, 4(r4)        @\
+  lwz    r0, 424+_index*16+8(r3)  @\
+  stw    r0, 8(r4)        @\
+  lwz    r0, 424+_index*16+12(r3)@\
+  stw    r0, 12(r4)        @\
+  lvx    v ## _index,0,r4    @\
+Ldone  ## _index:
+
+#define LOAD_VECTOR_UNALIGNEDh(_index) \
+  andi.  r0,r5,(1<<(31-_index))  @\
+  beq    Ldone  ## _index    @\
+  lwz    r0, 424+_index*16(r3)  @\
+  stw    r0, 0(r4)        @\
+  lwz    r0, 424+_index*16+4(r3)  @\
+  stw    r0, 4(r4)        @\
+  lwz    r0, 424+_index*16+8(r3)  @\
+  stw    r0, 8(r4)        @\
+  lwz    r0, 424+_index*16+12(r3)@\
+  stw    r0, 12(r4)        @\
+  lvx    v ## _index,0,r4    @\
+  Ldone  ## _index:
+
+
+  LOAD_VECTOR_UNALIGNEDl(0)
+  LOAD_VECTOR_UNALIGNEDl(1)
+  LOAD_VECTOR_UNALIGNEDl(2)
+  LOAD_VECTOR_UNALIGNEDl(3)
+  LOAD_VECTOR_UNALIGNEDl(4)
+  LOAD_VECTOR_UNALIGNEDl(5)
+  LOAD_VECTOR_UNALIGNEDl(6)
+  LOAD_VECTOR_UNALIGNEDl(7)
+  LOAD_VECTOR_UNALIGNEDl(8)
+  LOAD_VECTOR_UNALIGNEDl(9)
+  LOAD_VECTOR_UNALIGNEDl(10)
+  LOAD_VECTOR_UNALIGNEDl(11)
+  LOAD_VECTOR_UNALIGNEDl(12)
+  LOAD_VECTOR_UNALIGNEDl(13)
+  LOAD_VECTOR_UNALIGNEDl(14)
+  LOAD_VECTOR_UNALIGNEDl(15)
+  LOAD_VECTOR_UNALIGNEDh(16)
+  LOAD_VECTOR_UNALIGNEDh(17)
+  LOAD_VECTOR_UNALIGNEDh(18)
+  LOAD_VECTOR_UNALIGNEDh(19)
+  LOAD_VECTOR_UNALIGNEDh(20)
+  LOAD_VECTOR_UNALIGNEDh(21)
+  LOAD_VECTOR_UNALIGNEDh(22)
+  LOAD_VECTOR_UNALIGNEDh(23)
+  LOAD_VECTOR_UNALIGNEDh(24)
+  LOAD_VECTOR_UNALIGNEDh(25)
+  LOAD_VECTOR_UNALIGNEDh(26)
+  LOAD_VECTOR_UNALIGNEDh(27)
+  LOAD_VECTOR_UNALIGNEDh(28)
+  LOAD_VECTOR_UNALIGNEDh(29)
+  LOAD_VECTOR_UNALIGNEDh(30)
+  LOAD_VECTOR_UNALIGNEDh(31)
+
+Lnovec:
+  lwz    r0, 136(r3) ; __cr
+  mtocrf  255,r0
+  lwz    r0, 148(r3) ; __ctr
+  mtctr  r0
+  lwz    r0, 0(r3)  ; __ssr0
+  mtctr  r0
+  lwz    r0, 8(r3)  ; do r0 now
+  lwz    r5,28(r3)  ; do r5 now
+  lwz    r4,24(r3)  ; do r4 now
+  lwz    r1,12(r3)  ; do sp now
+  lwz    r3,20(r3)  ; do r3 last
+  bctr
+
+#elif __arm64__
+
+;
+; void libunwind::Registers_arm64::jumpto()
+;
+; On entry:
+;  thread_state pointer is in x0
+;
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
+  ; skip restore of x0,x1 for now
+  ldp    x2, x3,  [x0, #0x010]
+  ldp    x4, x5,  [x0, #0x020]
+  ldp    x6, x7,  [x0, #0x030]
+  ldp    x8, x9,  [x0, #0x040]
+  ldp    x10,x11, [x0, #0x050]
+  ldp    x12,x13, [x0, #0x060]
+  ldp    x14,x15, [x0, #0x070]
+  ldp    x16,x17, [x0, #0x080]
+  ldp    x18,x19, [x0, #0x090]
+  ldp    x20,x21, [x0, #0x0A0]
+  ldp    x22,x23, [x0, #0x0B0]
+  ldp    x24,x25, [x0, #0x0C0]
+  ldp    x26,x27, [x0, #0x0D0]
+  ldp    x28,fp,  [x0, #0x0E0]
+  ldr    lr,      [x0, #0x100]  ; restore pc into lr
+  ldr    x1,      [x0, #0x0F8]
+  mov    sp,x1          ; restore sp
+
+  ldp    d0, d1,  [x0, #0x110]
+  ldp    d2, d3,  [x0, #0x120]
+  ldp    d4, d5,  [x0, #0x130]
+  ldp    d6, d7,  [x0, #0x140]
+  ldp    d8, d9,  [x0, #0x150]
+  ldp    d10,d11, [x0, #0x160]
+  ldp    d12,d13, [x0, #0x170]
+  ldp    d14,d15, [x0, #0x180]
+  ldp    d16,d17, [x0, #0x190]
+  ldp    d18,d19, [x0, #0x1A0]
+  ldp    d20,d21, [x0, #0x1B0]
+  ldp    d22,d23, [x0, #0x1C0]
+  ldp    d24,d25, [x0, #0x1D0]
+  ldp    d26,d27, [x0, #0x1E0]
+  ldp    d28,d29, [x0, #0x1F0]
+  ldr    d30,     [x0, #0x200]
+  ldr    d31,     [x0, #0x208]
+
+  ldp    x0, x1,  [x0, #0x000]  ; restore x0,x1
+  ret    lr            ; jump to pc
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreCoreAndJumpTo.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreCoreAndJumpTo.S
+++ Unwind/UnwindRegistersRestore_restoreCoreAndJumpTo.S
@@ -0,0 +1,46 @@
+//===----------- UnwindRegistersRestore_restoreCoreAndJumpTo.S ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ void libunwind::Registers_arm::restoreCoreAndJumpTo()
+@
+@ On entry:
+@  thread_state pointer is in r0
+@
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv)
+#if !defined(__ARM_ARCH_ISA_ARM)
+  ldr r2, [r0, #52]
+  ldr r3, [r0, #60]
+  mov sp, r2
+  mov lr, r3         @ restore pc into lr
+  ldm r0, {r0-r7}
+#else
+  @ Use lr as base so that r0 can be restored.
+  mov lr, r0
+  @ 32bit thumb-2 restrictions for ldm:
+  @ . the sp (r13) cannot be in the list
+  @ . the pc (r15) and lr (r14) cannot both be in the list in an LDM instruction
+  ldm lr, {r0-r12}
+  ldr sp, [lr, #52]
+  ldr lr, [lr, #60]  @ restore pc into lr
+#endif
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreVFPWithFLDMD.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreVFPWithFLDMD.S
+++ Unwind/UnwindRegistersRestore_restoreVFPWithFLDMD.S
@@ -0,0 +1,39 @@
+//===-------------------- UnwindRegistersRestore.S ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy)
+  @ VFP and iwMMX instructions are only available when compiling with the flags
+  @ that enable them. We do not want to do that in the library (because we do not
+  @ want the compiler to generate instructions that access those) but this is
+  @ only accessed if the personality routine needs these registers. Use of
+  @ these registers implies they are, actually, available on the target, so
+  @ it's ok to execute.
+  @ So, generate the instruction using the corresponding coprocessor mnemonic.
+  vldmia r0, {d0-d15}
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreVFPWithFLDMX.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreVFPWithFLDMX.S
+++ Unwind/UnwindRegistersRestore_restoreVFPWithFLDMX.S
@@ -0,0 +1,32 @@
+//===-------------------- UnwindRegistersRestore.S ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy)
+  vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreVFPv3.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreVFPv3.S
+++ Unwind/UnwindRegistersRestore_restoreVFPv3.S
@@ -0,0 +1,32 @@
+//===--------------- UnwindRegistersRestore_restoreVFPv3.S ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv3
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
+  vldmia r0, {d16-d31}
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreiWMMX.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreiWMMX.S
+++ Unwind/UnwindRegistersRestore_restoreiWMMX.S
@@ -0,0 +1,49 @@
+//===--------------- UnwindRegistersRestore_restoreiWMMX.S ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@ Lie to the assembler to force it to let us use coprocessor mnemonics
+.arch armv5t
+
+@
+@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
+  ldcl p1, cr0, [r0], #8  @ wldrd wR0, [r0], #8
+  ldcl p1, cr1, [r0], #8  @ wldrd wR1, [r0], #8
+  ldcl p1, cr2, [r0], #8  @ wldrd wR2, [r0], #8
+  ldcl p1, cr3, [r0], #8  @ wldrd wR3, [r0], #8
+  ldcl p1, cr4, [r0], #8  @ wldrd wR4, [r0], #8
+  ldcl p1, cr5, [r0], #8  @ wldrd wR5, [r0], #8
+  ldcl p1, cr6, [r0], #8  @ wldrd wR6, [r0], #8
+  ldcl p1, cr7, [r0], #8  @ wldrd wR7, [r0], #8
+  ldcl p1, cr8, [r0], #8  @ wldrd wR8, [r0], #8
+  ldcl p1, cr9, [r0], #8  @ wldrd wR9, [r0], #8
+  ldcl p1, cr10, [r0], #8  @ wldrd wR10, [r0], #8
+  ldcl p1, cr11, [r0], #8  @ wldrd wR11, [r0], #8
+  ldcl p1, cr12, [r0], #8  @ wldrd wR12, [r0], #8
+  ldcl p1, cr13, [r0], #8  @ wldrd wR13, [r0], #8
+  ldcl p1, cr14, [r0], #8  @ wldrd wR14, [r0], #8
+  ldcl p1, cr15, [r0], #8  @ wldrd wR15, [r0], #8
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersRestore_restoreiWMMXControl.S
===================================================================
--- Unwind/UnwindRegistersRestore_restoreiWMMXControl.S
+++ Unwind/UnwindRegistersRestore_restoreiWMMXControl.S
@@ -0,0 +1,37 @@
+//===------------ UnwindRegistersRestore_restoreiWMMXControl.S ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+  .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@ Lie to the assembler to force it to let us use coprocessor mnemonics
+.arch armv5t
+
+@
+@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
+  ldc2 p1, cr8, [r0], #4  @ wldrw wCGR0, [r0], #4
+  ldc2 p1, cr9, [r0], #4  @ wldrw wCGR1, [r0], #4
+  ldc2 p1, cr10, [r0], #4  @ wldrw wCGR2, [r0], #4
+  ldc2 p1, cr11, [r0], #4  @ wldrw wCGR3, [r0], #4
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave.S
===================================================================
--- Unwind/UnwindRegistersSave.S
+++ Unwind/UnwindRegistersSave.S
@@ -1,424 +0,0 @@
-//===------------------------ UnwindRegistersSave.S -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "assembly.h"
-
-    .text
-
-#if __i386__
-
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-#
-# On entry:
-#   +                       +
-#   +-----------------------+
-#   + thread_state pointer  +
-#   +-----------------------+
-#   + return address        +
-#   +-----------------------+   <-- SP
-#   +                       +
-#
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-  push  %eax
-  movl  8(%esp), %eax
-  movl  %ebx,  4(%eax)
-  movl  %ecx,  8(%eax)
-  movl  %edx, 12(%eax)
-  movl  %edi, 16(%eax)
-  movl  %esi, 20(%eax)
-  movl  %ebp, 24(%eax)
-  movl  %esp, %edx
-  addl  $8, %edx
-  movl  %edx, 28(%eax)  # store what sp was at call site as esp
-  # skip ss
-  # skip eflags
-  movl  4(%esp), %edx
-  movl  %edx, 40(%eax)  # store return address as eip
-  # skip cs
-  # skip ds
-  # skip es
-  # skip fs
-  # skip gs
-  movl  (%esp), %edx
-  movl  %edx, (%eax)  # store original eax
-  popl  %eax
-  xorl  %eax, %eax    # return UNW_ESUCCESS
-  ret
-
-#elif __x86_64__
-
-#
-# extern int unw_getcontext(unw_context_t* thread_state)
-#
-# On entry:
-#  thread_state pointer is in rdi
-#
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-  movq  %rax,   (%rdi)
-  movq  %rbx,  8(%rdi)
-  movq  %rcx, 16(%rdi)
-  movq  %rdx, 24(%rdi)
-  movq  %rdi, 32(%rdi)
-  movq  %rsi, 40(%rdi)
-  movq  %rbp, 48(%rdi)
-  movq  %rsp, 56(%rdi)
-  addq  $8,   56(%rdi)
-  movq  %r8,  64(%rdi)
-  movq  %r9,  72(%rdi)
-  movq  %r10, 80(%rdi)
-  movq  %r11, 88(%rdi)
-  movq  %r12, 96(%rdi)
-  movq  %r13,104(%rdi)
-  movq  %r14,112(%rdi)
-  movq  %r15,120(%rdi)
-  movq  (%rsp),%rsi
-  movq  %rsi,128(%rdi) # store return address as rip
-  # skip rflags
-  # skip cs
-  # skip fs
-  # skip gs
-  xorl  %eax, %eax    # return UNW_ESUCCESS
-  ret
-
-#elif __ppc__
-
-;
-; extern int unw_getcontext(unw_context_t* thread_state)
-;
-; On entry:
-;  thread_state pointer is in r3
-;
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-  stw    r0,  8(r3)
-  mflr  r0
-  stw    r0,  0(r3)  ; store lr as ssr0
-  stw    r1, 12(r3)
-  stw    r2, 16(r3)
-  stw    r3, 20(r3)
-  stw    r4, 24(r3)
-  stw    r5, 28(r3)
-  stw    r6, 32(r3)
-  stw    r7, 36(r3)
-  stw    r8, 40(r3)
-  stw    r9, 44(r3)
-  stw     r10, 48(r3)
-  stw     r11, 52(r3)
-  stw     r12, 56(r3)
-  stw     r13, 60(r3)
-  stw     r14, 64(r3)
-  stw     r15, 68(r3)
-  stw     r16, 72(r3)
-  stw     r17, 76(r3)
-  stw     r18, 80(r3)
-  stw     r19, 84(r3)
-  stw     r20, 88(r3)
-  stw     r21, 92(r3)
-  stw     r22, 96(r3)
-  stw     r23,100(r3)
-  stw     r24,104(r3)
-  stw     r25,108(r3)
-  stw     r26,112(r3)
-  stw     r27,116(r3)
-  stw     r28,120(r3)
-  stw     r29,124(r3)
-  stw     r30,128(r3)
-  stw     r31,132(r3)
-
-  ; save VRSave register
-  mfspr  r0,256
-  stw    r0,156(r3)
-  ; save CR registers
-  mfcr  r0
-  stw    r0,136(r3)
-  ; save CTR register
-  mfctr  r0
-  stw    r0,148(r3)
-
-  ; save float registers
-  stfd    f0, 160(r3)
-  stfd    f1, 168(r3)
-  stfd    f2, 176(r3)
-  stfd    f3, 184(r3)
-  stfd    f4, 192(r3)
-  stfd    f5, 200(r3)
-  stfd    f6, 208(r3)
-  stfd    f7, 216(r3)
-  stfd    f8, 224(r3)
-  stfd    f9, 232(r3)
-  stfd    f10,240(r3)
-  stfd    f11,248(r3)
-  stfd    f12,256(r3)
-  stfd    f13,264(r3)
-  stfd    f14,272(r3)
-  stfd    f15,280(r3)
-  stfd    f16,288(r3)
-  stfd    f17,296(r3)
-  stfd    f18,304(r3)
-  stfd    f19,312(r3)
-  stfd    f20,320(r3)
-  stfd    f21,328(r3)
-  stfd    f22,336(r3)
-  stfd    f23,344(r3)
-  stfd    f24,352(r3)
-  stfd    f25,360(r3)
-  stfd    f26,368(r3)
-  stfd    f27,376(r3)
-  stfd    f28,384(r3)
-  stfd    f29,392(r3)
-  stfd    f30,400(r3)
-  stfd    f31,408(r3)
-
-
-  ; save vector registers
-
-  subi  r4,r1,16
-  rlwinm  r4,r4,0,0,27  ; mask low 4-bits
-  ; r4 is now a 16-byte aligned pointer into the red zone
-
-#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
-  stvx  _vec,0,r4           @\
-  lwz    r5, 0(r4)          @\
-  stw    r5, _offset(r3)    @\
-  lwz    r5, 4(r4)          @\
-  stw    r5, _offset+4(r3)  @\
-  lwz    r5, 8(r4)          @\
-  stw    r5, _offset+8(r3)  @\
-  lwz    r5, 12(r4)         @\
-  stw    r5, _offset+12(r3)
-
-  SAVE_VECTOR_UNALIGNED( v0, 424+0x000)
-  SAVE_VECTOR_UNALIGNED( v1, 424+0x010)
-  SAVE_VECTOR_UNALIGNED( v2, 424+0x020)
-  SAVE_VECTOR_UNALIGNED( v3, 424+0x030)
-  SAVE_VECTOR_UNALIGNED( v4, 424+0x040)
-  SAVE_VECTOR_UNALIGNED( v5, 424+0x050)
-  SAVE_VECTOR_UNALIGNED( v6, 424+0x060)
-  SAVE_VECTOR_UNALIGNED( v7, 424+0x070)
-  SAVE_VECTOR_UNALIGNED( v8, 424+0x080)
-  SAVE_VECTOR_UNALIGNED( v9, 424+0x090)
-  SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0)
-  SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0)
-  SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0)
-  SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0)
-  SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0)
-  SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0)
-  SAVE_VECTOR_UNALIGNED(v16, 424+0x100)
-  SAVE_VECTOR_UNALIGNED(v17, 424+0x110)
-  SAVE_VECTOR_UNALIGNED(v18, 424+0x120)
-  SAVE_VECTOR_UNALIGNED(v19, 424+0x130)
-  SAVE_VECTOR_UNALIGNED(v20, 424+0x140)
-  SAVE_VECTOR_UNALIGNED(v21, 424+0x150)
-  SAVE_VECTOR_UNALIGNED(v22, 424+0x160)
-  SAVE_VECTOR_UNALIGNED(v23, 424+0x170)
-  SAVE_VECTOR_UNALIGNED(v24, 424+0x180)
-  SAVE_VECTOR_UNALIGNED(v25, 424+0x190)
-  SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0)
-  SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0)
-  SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0)
-  SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0)
-  SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0)
-  SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0)
-
-  li  r3, 0    ; return UNW_ESUCCESS
-  blr
-
-
-#elif __arm64__
-
-;
-; extern int unw_getcontext(unw_context_t* thread_state)
-;
-; On entry:
-;  thread_state pointer is in x0
-;
-  .p2align 2
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-  stp    x0, x1,  [x0, #0x000]
-  stp    x2, x3,  [x0, #0x010]
-  stp    x4, x5,  [x0, #0x020]
-  stp    x6, x7,  [x0, #0x030]
-  stp    x8, x9,  [x0, #0x040]
-  stp    x10,x11, [x0, #0x050]
-  stp    x12,x13, [x0, #0x060]
-  stp    x14,x15, [x0, #0x070]
-  stp    x16,x17, [x0, #0x080]
-  stp    x18,x19, [x0, #0x090]
-  stp    x20,x21, [x0, #0x0A0]
-  stp    x22,x23, [x0, #0x0B0]
-  stp    x24,x25, [x0, #0x0C0]
-  stp    x26,x27, [x0, #0x0D0]
-  stp    x28,fp,  [x0, #0x0E0]
-  str    lr,      [x0, #0x0F0]
-  mov    x1,sp
-  str    x1,      [x0, #0x0F8]
-  str    lr,      [x0, #0x100]    ; store return address as pc
-  ; skip cpsr
-  stp    d0, d1,  [x0, #0x110]
-  stp    d2, d3,  [x0, #0x120]
-  stp    d4, d5,  [x0, #0x130]
-  stp    d6, d7,  [x0, #0x140]
-  stp    d8, d9,  [x0, #0x150]
-  stp    d10,d11, [x0, #0x160]
-  stp    d12,d13, [x0, #0x170]
-  stp    d14,d15, [x0, #0x180]
-  stp    d16,d17, [x0, #0x190]
-  stp    d18,d19, [x0, #0x1A0]
-  stp    d20,d21, [x0, #0x1B0]
-  stp    d22,d23, [x0, #0x1C0]
-  stp    d24,d25, [x0, #0x1D0]
-  stp    d26,d27, [x0, #0x1E0]
-  stp    d28,d29, [x0, #0x1F0]
-  str    d30,     [x0, #0x200]
-  str    d31,     [x0, #0x208]
-  ldr    x0, #0      ; return UNW_ESUCCESS
-  ret
-
-#elif __arm__ && !__APPLE__
-
-#if !defined(__ARM_ARCH_ISA_ARM)
-  .thumb
-#endif
-
-@
-@ extern int unw_getcontext(unw_context_t* thread_state)
-@
-@ On entry:
-@  thread_state pointer is in r0
-@ 
-@ Per EHABI #4.7 this only saves the core integer registers.
-@ EHABI #7.4.5 notes that in general all VRS registers should be restored
-@ however this is very hard to do for VFP registers because it is unknown
-@ to the library how many registers are implemented by the architecture.
-@ Instead, VFP registers are demand saved by logic external to unw_getcontext.
-@
-  .p2align 2
-DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-#if !defined(__ARM_ARCH_ISA_ARM)
-  stm r0!, {r0-r7}
-  mov r2, sp
-  mov r3, lr
-  str r2, [r0, #52]
-  str r3, [r0, #56]
-  str r3, [r0, #60]  @ store return address as pc
-#else
-  @ 32bit thumb-2 restrictions for stm:
-  @ . the sp (r13) cannot be in the list
-  @ . the pc (r15) cannot be in the list in an STM instruction
-  stm r0, {r0-r12}
-  str sp, [r0, #52]
-  str lr, [r0, #56]
-  str lr, [r0, #60]  @ store return address as pc
-#endif
-  mov r0, #0         @ return UNW_ESUCCESS
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
-  stc p11, cr0, [r0], {0x20}  @ fstmiad r0, {d0-d15}
-#else
-  vstmia r0, {d0-d15}
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
-  stc p11, cr0, [r0], {0x21}  @ fstmiax r0, {d0-d15}
-#else
-  vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
-#if defined(__ARM_FP)
-  @ VFP and iwMMX instructions are only available when compiling with the flags
-  @ that enable them. We do not want to do that in the library (because we do not
-  @ want the compiler to generate instructions that access those) but this is
-  @ only accessed if the personality routine needs these registers. Use of
-  @ these registers implies they are, actually, available on the target, so
-  @ it's ok to execute.
-  @ So, generate the instructions using the corresponding coprocessor mnemonic.
-#ifndef __ARM_NEON
-  stcl p11, cr0, [r0], {0x20}  @ vstm r0, {d16-d31}
-#else
-  vstmia r0, {d16-d31}
-#endif
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
-  stcl p1, cr0, [r0], #8  @ wstrd wR0, [r0], #8
-  stcl p1, cr1, [r0], #8  @ wstrd wR1, [r0], #8
-  stcl p1, cr2, [r0], #8  @ wstrd wR2, [r0], #8
-  stcl p1, cr3, [r0], #8  @ wstrd wR3, [r0], #8
-  stcl p1, cr4, [r0], #8  @ wstrd wR4, [r0], #8
-  stcl p1, cr5, [r0], #8  @ wstrd wR5, [r0], #8
-  stcl p1, cr6, [r0], #8  @ wstrd wR6, [r0], #8
-  stcl p1, cr7, [r0], #8  @ wstrd wR7, [r0], #8
-  stcl p1, cr8, [r0], #8  @ wstrd wR8, [r0], #8
-  stcl p1, cr9, [r0], #8  @ wstrd wR9, [r0], #8
-  stcl p1, cr10, [r0], #8  @ wstrd wR10, [r0], #8
-  stcl p1, cr11, [r0], #8  @ wstrd wR11, [r0], #8
-  stcl p1, cr12, [r0], #8  @ wstrd wR12, [r0], #8
-  stcl p1, cr13, [r0], #8  @ wstrd wR13, [r0], #8
-  stcl p1, cr14, [r0], #8  @ wstrd wR14, [r0], #8
-  stcl p1, cr15, [r0], #8  @ wstrd wR15, [r0], #8
-#endif
-  JMP(lr)
-
-@
-@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
-@
-@ On entry:
-@  values pointer is in r0
-@
-  .p2align 2
-DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
-  stc2 p1, cr8, [r0], #4  @ wstrw wCGR0, [r0], #4
-  stc2 p1, cr9, [r0], #4  @ wstrw wCGR1, [r0], #4
-  stc2 p1, cr10, [r0], #4  @ wstrw wCGR2, [r0], #4
-  stc2 p1, cr11, [r0], #4  @ wstrw wCGR3, [r0], #4
-#endif
-  JMP(lr)
-
-#endif
Index: Unwind/UnwindRegistersSave_saveVFPWithFSTMD.S
===================================================================
--- Unwind/UnwindRegistersSave_saveVFPWithFSTMD.S
+++ Unwind/UnwindRegistersSave_saveVFPWithFSTMD.S
@@ -0,0 +1,32 @@
+//===--------------- UnwindRegistersSave_saveVFPwithFSTMD.S ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
+  vstmia r0, {d0-d15}
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave_saveVFPWithFSTMX.S
===================================================================
--- Unwind/UnwindRegistersSave_saveVFPWithFSTMX.S
+++ Unwind/UnwindRegistersSave_saveVFPWithFSTMX.S
@@ -0,0 +1,32 @@
+//===------------------------ UnwindRegistersSave.S -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
+  vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave_saveVFPv3.S
===================================================================
--- Unwind/UnwindRegistersSave_saveVFPv3.S
+++ Unwind/UnwindRegistersSave_saveVFPv3.S
@@ -0,0 +1,39 @@
+//===------------------ UnwindRegistersSave_saveVFPv3.S -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+  .fpu vfpv3
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
+  @ VFP and iwMMX instructions are only available when compiling with the flags
+  @ that enable them. We do not want to do that in the library (because we do not
+  @ want the compiler to generate instructions that access those) but this is
+  @ only accessed if the personality routine needs these registers. Use of
+  @ these registers implies they are, actually, available on the target, so
+  @ it's ok to execute.
+  @ So, generate the instructions using the corresponding coprocessor mnemonic.
+  vstmia r0, {d16-d31}
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave_saveiWMMX.S
===================================================================
--- Unwind/UnwindRegistersSave_saveiWMMX.S
+++ Unwind/UnwindRegistersSave_saveiWMMX.S
@@ -0,0 +1,49 @@
+//===------------------ UnwindRegistersSave_saveiWMMX.S -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@ Lie to the assembler to force it to let us use coprocessor mnemonics
+.arch armv5t
+
+@
+@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
+  stcl p1, cr0, [r0], #8  @ wstrd wR0, [r0], #8
+  stcl p1, cr1, [r0], #8  @ wstrd wR1, [r0], #8
+  stcl p1, cr2, [r0], #8  @ wstrd wR2, [r0], #8
+  stcl p1, cr3, [r0], #8  @ wstrd wR3, [r0], #8
+  stcl p1, cr4, [r0], #8  @ wstrd wR4, [r0], #8
+  stcl p1, cr5, [r0], #8  @ wstrd wR5, [r0], #8
+  stcl p1, cr6, [r0], #8  @ wstrd wR6, [r0], #8
+  stcl p1, cr7, [r0], #8  @ wstrd wR7, [r0], #8
+  stcl p1, cr8, [r0], #8  @ wstrd wR8, [r0], #8
+  stcl p1, cr9, [r0], #8  @ wstrd wR9, [r0], #8
+  stcl p1, cr10, [r0], #8  @ wstrd wR10, [r0], #8
+  stcl p1, cr11, [r0], #8  @ wstrd wR11, [r0], #8
+  stcl p1, cr12, [r0], #8  @ wstrd wR12, [r0], #8
+  stcl p1, cr13, [r0], #8  @ wstrd wR13, [r0], #8
+  stcl p1, cr14, [r0], #8  @ wstrd wR14, [r0], #8
+  stcl p1, cr15, [r0], #8  @ wstrd wR15, [r0], #8
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave_saveiWMMXControl.S
===================================================================
--- Unwind/UnwindRegistersSave_saveiWMMXControl.S
+++ Unwind/UnwindRegistersSave_saveiWMMXControl.S
@@ -0,0 +1,37 @@
+//===--------------- UnwindRegistersSave_saveiWMMXControl.S ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@ Lie to the assembler to force it to let us use coprocessor mnemonics
+.arch armv5t
+
+@
+@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
+@
+@ On entry:
+@  values pointer is in r0
+@
+  .p2align 2
+DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
+  stc2 p1, cr8, [r0], #4  @ wstrw wCGR0, [r0], #4
+  stc2 p1, cr9, [r0], #4  @ wstrw wCGR1, [r0], #4
+  stc2 p1, cr10, [r0], #4  @ wstrw wCGR2, [r0], #4
+  stc2 p1, cr11, [r0], #4  @ wstrw wCGR3, [r0], #4
+  JMP(lr)
+
+#endif
Index: Unwind/UnwindRegistersSave_unw_getcontext.S
===================================================================
--- Unwind/UnwindRegistersSave_unw_getcontext.S
+++ Unwind/UnwindRegistersSave_unw_getcontext.S
@@ -0,0 +1,322 @@
+//===------------------------ UnwindRegistersSave.S -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assembly.h"
+
+    .text
+
+#if __i386__
+
+#
+# extern int unw_getcontext(unw_context_t* thread_state)
+#
+# On entry:
+#   +                       +
+#   +-----------------------+
+#   + thread_state pointer  +
+#   +-----------------------+
+#   + return address        +
+#   +-----------------------+   <-- SP
+#   +                       +
+#
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  push  %eax
+  movl  8(%esp), %eax
+  movl  %ebx,  4(%eax)
+  movl  %ecx,  8(%eax)
+  movl  %edx, 12(%eax)
+  movl  %edi, 16(%eax)
+  movl  %esi, 20(%eax)
+  movl  %ebp, 24(%eax)
+  movl  %esp, %edx
+  addl  $8, %edx
+  movl  %edx, 28(%eax)  # store what sp was at call site as esp
+  # skip ss
+  # skip eflags
+  movl  4(%esp), %edx
+  movl  %edx, 40(%eax)  # store return address as eip
+  # skip cs
+  # skip ds
+  # skip es
+  # skip fs
+  # skip gs
+  movl  (%esp), %edx
+  movl  %edx, (%eax)  # store original eax
+  popl  %eax
+  xorl  %eax, %eax    # return UNW_ESUCCESS
+  ret
+
+#elif __x86_64__
+
+#
+# extern int unw_getcontext(unw_context_t* thread_state)
+#
+# On entry:
+#  thread_state pointer is in rdi
+#
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  movq  %rax,   (%rdi)
+  movq  %rbx,  8(%rdi)
+  movq  %rcx, 16(%rdi)
+  movq  %rdx, 24(%rdi)
+  movq  %rdi, 32(%rdi)
+  movq  %rsi, 40(%rdi)
+  movq  %rbp, 48(%rdi)
+  movq  %rsp, 56(%rdi)
+  addq  $8,   56(%rdi)
+  movq  %r8,  64(%rdi)
+  movq  %r9,  72(%rdi)
+  movq  %r10, 80(%rdi)
+  movq  %r11, 88(%rdi)
+  movq  %r12, 96(%rdi)
+  movq  %r13,104(%rdi)
+  movq  %r14,112(%rdi)
+  movq  %r15,120(%rdi)
+  movq  (%rsp),%rsi
+  movq  %rsi,128(%rdi) # store return address as rip
+  # skip rflags
+  # skip cs
+  # skip fs
+  # skip gs
+  xorl  %eax, %eax    # return UNW_ESUCCESS
+  ret
+
+#elif __ppc__
+
+;
+; extern int unw_getcontext(unw_context_t* thread_state)
+;
+; On entry:
+;  thread_state pointer is in r3
+;
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  stw    r0,  8(r3)
+  mflr  r0
+  stw    r0,  0(r3)  ; store lr as ssr0
+  stw    r1, 12(r3)
+  stw    r2, 16(r3)
+  stw    r3, 20(r3)
+  stw    r4, 24(r3)
+  stw    r5, 28(r3)
+  stw    r6, 32(r3)
+  stw    r7, 36(r3)
+  stw    r8, 40(r3)
+  stw    r9, 44(r3)
+  stw     r10, 48(r3)
+  stw     r11, 52(r3)
+  stw     r12, 56(r3)
+  stw     r13, 60(r3)
+  stw     r14, 64(r3)
+  stw     r15, 68(r3)
+  stw     r16, 72(r3)
+  stw     r17, 76(r3)
+  stw     r18, 80(r3)
+  stw     r19, 84(r3)
+  stw     r20, 88(r3)
+  stw     r21, 92(r3)
+  stw     r22, 96(r3)
+  stw     r23,100(r3)
+  stw     r24,104(r3)
+  stw     r25,108(r3)
+  stw     r26,112(r3)
+  stw     r27,116(r3)
+  stw     r28,120(r3)
+  stw     r29,124(r3)
+  stw     r30,128(r3)
+  stw     r31,132(r3)
+
+  ; save VRSave register
+  mfspr  r0,256
+  stw    r0,156(r3)
+  ; save CR registers
+  mfcr  r0
+  stw    r0,136(r3)
+  ; save CTR register
+  mfctr  r0
+  stw    r0,148(r3)
+
+  ; save float registers
+  stfd    f0, 160(r3)
+  stfd    f1, 168(r3)
+  stfd    f2, 176(r3)
+  stfd    f3, 184(r3)
+  stfd    f4, 192(r3)
+  stfd    f5, 200(r3)
+  stfd    f6, 208(r3)
+  stfd    f7, 216(r3)
+  stfd    f8, 224(r3)
+  stfd    f9, 232(r3)
+  stfd    f10,240(r3)
+  stfd    f11,248(r3)
+  stfd    f12,256(r3)
+  stfd    f13,264(r3)
+  stfd    f14,272(r3)
+  stfd    f15,280(r3)
+  stfd    f16,288(r3)
+  stfd    f17,296(r3)
+  stfd    f18,304(r3)
+  stfd    f19,312(r3)
+  stfd    f20,320(r3)
+  stfd    f21,328(r3)
+  stfd    f22,336(r3)
+  stfd    f23,344(r3)
+  stfd    f24,352(r3)
+  stfd    f25,360(r3)
+  stfd    f26,368(r3)
+  stfd    f27,376(r3)
+  stfd    f28,384(r3)
+  stfd    f29,392(r3)
+  stfd    f30,400(r3)
+  stfd    f31,408(r3)
+
+
+  ; save vector registers
+
+  subi  r4,r1,16
+  rlwinm  r4,r4,0,0,27  ; mask low 4-bits
+  ; r4 is now a 16-byte aligned pointer into the red zone
+
+#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
+  stvx  _vec,0,r4           @\
+  lwz    r5, 0(r4)          @\
+  stw    r5, _offset(r3)    @\
+  lwz    r5, 4(r4)          @\
+  stw    r5, _offset+4(r3)  @\
+  lwz    r5, 8(r4)          @\
+  stw    r5, _offset+8(r3)  @\
+  lwz    r5, 12(r4)         @\
+  stw    r5, _offset+12(r3)
+
+  SAVE_VECTOR_UNALIGNED( v0, 424+0x000)
+  SAVE_VECTOR_UNALIGNED( v1, 424+0x010)
+  SAVE_VECTOR_UNALIGNED( v2, 424+0x020)
+  SAVE_VECTOR_UNALIGNED( v3, 424+0x030)
+  SAVE_VECTOR_UNALIGNED( v4, 424+0x040)
+  SAVE_VECTOR_UNALIGNED( v5, 424+0x050)
+  SAVE_VECTOR_UNALIGNED( v6, 424+0x060)
+  SAVE_VECTOR_UNALIGNED( v7, 424+0x070)
+  SAVE_VECTOR_UNALIGNED( v8, 424+0x080)
+  SAVE_VECTOR_UNALIGNED( v9, 424+0x090)
+  SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0)
+  SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0)
+  SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0)
+  SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0)
+  SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0)
+  SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0)
+  SAVE_VECTOR_UNALIGNED(v16, 424+0x100)
+  SAVE_VECTOR_UNALIGNED(v17, 424+0x110)
+  SAVE_VECTOR_UNALIGNED(v18, 424+0x120)
+  SAVE_VECTOR_UNALIGNED(v19, 424+0x130)
+  SAVE_VECTOR_UNALIGNED(v20, 424+0x140)
+  SAVE_VECTOR_UNALIGNED(v21, 424+0x150)
+  SAVE_VECTOR_UNALIGNED(v22, 424+0x160)
+  SAVE_VECTOR_UNALIGNED(v23, 424+0x170)
+  SAVE_VECTOR_UNALIGNED(v24, 424+0x180)
+  SAVE_VECTOR_UNALIGNED(v25, 424+0x190)
+  SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0)
+  SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0)
+  SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0)
+  SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0)
+  SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0)
+  SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0)
+
+  li  r3, 0    ; return UNW_ESUCCESS
+  blr
+
+
+#elif __arm64__
+
+;
+; extern int unw_getcontext(unw_context_t* thread_state)
+;
+; On entry:
+;  thread_state pointer is in x0
+;
+  .p2align 2
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+  stp    x0, x1,  [x0, #0x000]
+  stp    x2, x3,  [x0, #0x010]
+  stp    x4, x5,  [x0, #0x020]
+  stp    x6, x7,  [x0, #0x030]
+  stp    x8, x9,  [x0, #0x040]
+  stp    x10,x11, [x0, #0x050]
+  stp    x12,x13, [x0, #0x060]
+  stp    x14,x15, [x0, #0x070]
+  stp    x16,x17, [x0, #0x080]
+  stp    x18,x19, [x0, #0x090]
+  stp    x20,x21, [x0, #0x0A0]
+  stp    x22,x23, [x0, #0x0B0]
+  stp    x24,x25, [x0, #0x0C0]
+  stp    x26,x27, [x0, #0x0D0]
+  stp    x28,fp,  [x0, #0x0E0]
+  str    lr,      [x0, #0x0F0]
+  mov    x1,sp
+  str    x1,      [x0, #0x0F8]
+  str    lr,      [x0, #0x100]    ; store return address as pc
+  ; skip cpsr
+  stp    d0, d1,  [x0, #0x110]
+  stp    d2, d3,  [x0, #0x120]
+  stp    d4, d5,  [x0, #0x130]
+  stp    d6, d7,  [x0, #0x140]
+  stp    d8, d9,  [x0, #0x150]
+  stp    d10,d11, [x0, #0x160]
+  stp    d12,d13, [x0, #0x170]
+  stp    d14,d15, [x0, #0x180]
+  stp    d16,d17, [x0, #0x190]
+  stp    d18,d19, [x0, #0x1A0]
+  stp    d20,d21, [x0, #0x1B0]
+  stp    d22,d23, [x0, #0x1C0]
+  stp    d24,d25, [x0, #0x1D0]
+  stp    d26,d27, [x0, #0x1E0]
+  stp    d28,d29, [x0, #0x1F0]
+  str    d30,     [x0, #0x200]
+  str    d31,     [x0, #0x208]
+  ldr    x0, #0      ; return UNW_ESUCCESS
+  ret
+
+#elif __arm__ && !__APPLE__
+
+#if !defined(__ARM_ARCH_ISA_ARM)
+  .thumb
+#endif
+
+@
+@ extern int unw_getcontext(unw_context_t* thread_state)
+@
+@ On entry:
+@  thread_state pointer is in r0
+@ 
+@ Per EHABI #4.7 this only saves the core integer registers.
+@ EHABI #7.4.5 notes that in general all VRS registers should be restored
+@ however this is very hard to do for VFP registers because it is unknown
+@ to the library how many registers are implemented by the architecture.
+@ Instead, VFP registers are demand saved by logic external to unw_getcontext.
+@
+  .p2align 2
+DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+#if !defined(__ARM_ARCH_ISA_ARM)
+  stm r0!, {r0-r7}
+  mov r2, sp
+  mov r3, lr
+  str r2, [r0, #52]
+  str r3, [r0, #56]
+  str r3, [r0, #60]  @ store return address as pc
+#else
+  @ 32bit thumb-2 restrictions for stm:
+  @ . the sp (r13) cannot be in the list
+  @ . the pc (r15) cannot be in the list in an STM instruction
+  stm r0, {r0-r12}
+  str sp, [r0, #52]
+  str lr, [r0, #56]
+  str lr, [r0, #60]  @ store return address as pc
+#endif
+  mov r0, #0         @ return UNW_ESUCCESS
+  JMP(lr)
+
+#endif