summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorSteve MacLean <sdmaclea@qti.qualcomm.com>2017-02-17 13:25:37 -0500
committerJan Vorlicek <janvorli@microsoft.com>2017-02-17 19:25:37 +0100
commit9baa44aa334cf6f032e4abeae10dc1b960aaeb57 (patch)
tree9db49209ed0728eab25458e22f7416a0d31e0690 /src/pal
parent9f4aae6ac42f846473e6f70f2ac19e8910c97ccc (diff)
downloadcoreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.tar.gz
coreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.tar.bz2
coreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.zip
[ARM64/Unix] (#9500)
* [Arm64/Unix] Update arm64 *.S files to match *.asm * [Arm64/Unix] Fix CONTEXTToNativeContext() * [Arm64/Unix] ThrowExceptionFromContextInternal * [Arm64/Unix] Preserve x8 argument register * [ARM64/Unix] Add CFI directives Add native unwind info * [Arm64/Unix] Fix RtlRestoreContext * [Arm64/Unix] Restore FP from CurrentContextPointers * [Arm64/Unix] fix pointer math * [Arm64/Unix] Fix CallDescrWorkerInternal personality * [Arm64/Unix] More Fp fixups * [Arm64/Unix] CallEHFunclet machine state Restore non-volatile machine state in CallEHFunclet * [Arm64/Unix] CallDescrWorkerInternal Use empty stack slot to save argument * [Arm64/Unix] RtlVirtualUnwind update pointers * [Arm64] LazyMachState fixes * [Arm64/Unix] disable USE_REDIRECT_FOR_GCSTRESS When FEATURE_PAL is enableds USE_REDIRECT_FOR_GCSTRESS is not supported * [Arm64] ClearRegDisplayArgumentAndScratchRegisters() * [Arm64] Remove unnecesary copy in TransitionFrame * [Arm64/Unix] Fix comment per review * [Arm64/Unix] move constants per review * [Arm64/Unix] Use ldp per review Also fix indentation * [Arm64/Unix] Fix indentation per review * [Arm64/Unix] Remove m_Unwound per review comments * [Arm64/Unix] Use PREPARE_EXTERNAL_VAR to access globals * [Arm64/Unix] Fix more whitespace per earlier review comments
Diffstat (limited to 'src/pal')
-rw-r--r--src/pal/inc/unixasmmacrosarm64.inc151
-rw-r--r--src/pal/src/arch/arm64/asmconstants.h95
-rw-r--r--src/pal/src/arch/arm64/context2.S114
-rw-r--r--src/pal/src/arch/arm64/exceptionhelper.S25
-rw-r--r--src/pal/src/exception/seh-unwind.cpp1
-rw-r--r--src/pal/src/include/pal/context.h3
-rw-r--r--src/pal/src/thread/context.cpp2
7 files changed, 235 insertions, 156 deletions
diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc
index 359f27f878..ed73748e41 100644
--- a/src/pal/inc/unixasmmacrosarm64.inc
+++ b/src/pal/inc/unixasmmacrosarm64.inc
@@ -31,8 +31,8 @@ C_FUNC(\Name):
.endm
.macro LEAF_END_MARKED Name, Section
- .global C_FUNC(\Name\()_End)
C_FUNC(\Name\()_End):
+ .global C_FUNC(\Name\()_End)
LEAF_END \Name, \Section
.endm
@@ -48,18 +48,23 @@ C_FUNC(\Name\()_End):
.macro EPILOG_STACK_FREE Size
add sp, sp, \Size
+ .cfi_adjust_cfa_offset -\Size
.endm
.macro EPILOG_STACK_RESTORE
mov sp, fp
+ .cfi_restore sp
.endm
.macro PROLOG_SAVE_REG reg, ofs
str \reg, [sp, \ofs]
+ .cfi_rel_offset \reg, \ofs
.endm
.macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]
+ .cfi_rel_offset \reg1, \ofs
+ .cfi_rel_offset \reg2, \ofs + 8
.ifc \reg1, fp
mov fp, sp
.endif
@@ -67,6 +72,9 @@ C_FUNC(\Name\()_End):
.macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]!
+ .cfi_adjust_cfa_offset -\ofs
+ .cfi_rel_offset \reg1, 0
+ .cfi_rel_offset \reg2, 8
.ifc \reg1, fp
mov fp, sp
.endif
@@ -74,14 +82,20 @@ C_FUNC(\Name\()_End):
.macro EPILOG_RESTORE_REG reg, ofs
ldr \reg, [sp, \ofs]
+ .cfi_restore \reg1
.endm
.macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs
ldp \reg1, \reg2, [sp, \ofs]
+ .cfi_restore \reg1
+ .cfi_restore \reg2
.endm
.macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ofs
ldp \reg1, \reg2, [sp], \ofs
+ .cfi_restore \reg1
+ .cfi_restore \reg2
+ .cfi_adjust_cfa_offset -\ofs
.endm
.macro EPILOG_RETURN
@@ -94,14 +108,14 @@ C_FUNC(\Name\()_End):
//-----------------------------------------------------------------------------
// Define the prolog for a TransitionFrame-based method. This macro should be called first in the method and
-// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
+// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
//
// Stack layout:
//
// (stack parameters)
// ...
// fp
-// lr
+// lr
// CalleeSavedRegisters::x28
// CalleeSavedRegisters::x27
// CalleeSavedRegisters::x26
@@ -133,6 +147,7 @@ C_FUNC(\Name\()_End):
.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, SaveFPArgs = 1
__PWTB_FloatArgumentRegisters = \extraLocals
+ __PWTB_SaveFPArgs = \SaveFPArgs
.if ((__PWTB_FloatArgumentRegisters % 16) != 0)
__PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
@@ -140,74 +155,114 @@ C_FUNC(\Name\()_End):
__PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
- .if \SaveFPArgs > 0
+ .if (__PWTB_SaveFPArgs == 1)
__PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
.endif
__PWTB_StackAlloc = __PWTB_TransitionBlock
- __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
-
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-160
- // Spill callee saved registers
- PROLOG_SAVE_REG_PAIR x19, x20, #16
- PROLOG_SAVE_REG_PAIR x21, x22, #32
- PROLOG_SAVE_REG_PAIR x23, x24, #48
- PROLOG_SAVE_REG_PAIR x25, x26, #64
- PROLOG_SAVE_REG_PAIR x27, x28, #80
-
+ __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
+
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176
+ // Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
+
// Allocate space for the rest of the frame
PROLOG_STACK_ALLOC __PWTB_StackAlloc
-
+
// Spill argument registers.
SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
- .if \SaveFPArgs > 0
+ .if (__PWTB_SaveFPArgs == 1)
SAVE_FLOAT_ARGUMENT_REGISTERS sp, \extraLocals
.endif
.endm
//-----------------------------------------------------------------------------
-// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
+// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
// base address to be passed in $reg
//
// Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS
-.macro SAVE_ARGUMENT_REGISTERS reg, ofs
+.macro SAVE_ARGUMENT_REGISTERS reg, ofs
stp x0, x1, [\reg, #(\ofs)]
+ .cfi_rel_offset x0, \ofs
+ .cfi_rel_offset x1, \ofs + 8
stp x2, x3, [\reg, #(\ofs + 16)]
+ .cfi_rel_offset x2, \ofs + 16
+ .cfi_rel_offset x3, \ofs + 24
stp x4, x5, [\reg, #(\ofs + 32)]
+ .cfi_rel_offset x4, \ofs + 32
+ .cfi_rel_offset x5, \ofs + 40
stp x6, x7, [\reg, #(\ofs + 48)]
+ .cfi_rel_offset x6, \ofs + 48
+ .cfi_rel_offset x7, \ofs + 56
+ str x8, [\reg, #(\ofs + 64)]
+ .cfi_rel_offset x8, \ofs + 64
.endm
// Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS
-.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
+.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
stp d0, d1, [\reg, #(\ofs)]
+ .cfi_rel_offset d0, \ofs + 0
+ .cfi_rel_offset d1, \ofs + 8
stp d2, d3, [\reg, #(\ofs + 16)]
+ .cfi_rel_offset d2, \ofs + 16
+ .cfi_rel_offset d3, \ofs + 24
stp d4, d5, [\reg, #(\ofs + 32)]
+ .cfi_rel_offset d4, \ofs + 32
+ .cfi_rel_offset d5, \ofs + 40
stp d6, d7, [\reg, #(\ofs + 48)]
+ .cfi_rel_offset d6, \ofs + 48
+ .cfi_rel_offset d7, \ofs + 56
.endm
-.macro RESTORE_ARGUMENT_REGISTERS reg, ofs
+.macro RESTORE_ARGUMENT_REGISTERS reg, ofs
ldp x0, x1, [\reg, #(\ofs)]
+ .cfi_restore x0
+ .cfi_restore x1
ldp x2, x3, [\reg, #(\ofs + 16)]
+ .cfi_restore x2
+ .cfi_restore x3
ldp x4, x5, [\reg, #(\ofs + 32)]
+ .cfi_restore x4
+ .cfi_restore x5
ldp x6, x7, [\reg, #(\ofs + 48)]
+ .cfi_restore x6
+ .cfi_restore x7
+ ldr x8, [\reg, #(\ofs + 64)]
+ .cfi_restore x8
.endm
-.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
+.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
ldp d0, d1, [\reg, #(\ofs)]
+ .cfi_restore d0
+ .cfi_restore d1
ldp d2, d3, [\reg, #(\ofs + 16)]
+ .cfi_restore d2
+ .cfi_restore d3
ldp d4, d5, [\reg, #(\ofs + 32)]
+ .cfi_restore d4
+ .cfi_restore d5
ldp d6, d7, [\reg, #(\ofs + 48)]
+ .cfi_restore d6
+ .cfi_restore d7
+
+.endm
+.macro EPILOG_BRANCH Target
+ b \Target
.endm
.macro EPILOG_BRANCH_REG reg
@@ -216,40 +271,42 @@ C_FUNC(\Name\()_End):
.endm
-//-----------------------------------------------------------------------------
-// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
-// Since this is a tail call argument registers are restored.
-//
-.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL extraLocals = 0, SaveFPArgs =1
- __PWTB_FloatArgumentRegisters = \extraLocals
+.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
- .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
- __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
- .endif
+ EPILOG_STACK_FREE __PWTB_StackAlloc
- __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
+ ret
- .if \SaveFPArgs > 0
- __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
- .endif
+.endm
- __PWTB_StackAlloc = __PWTB_TransitionBlock
- __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
- .if \SaveFPArgs > 0
- RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
+//-----------------------------------------------------------------------------
+// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
+// Since this is a tail call argument registers are restored.
+//
+.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ .if (__PWTB_SaveFPArgs == 1)
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
.endif
RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
+
EPILOG_STACK_FREE __PWTB_StackAlloc
-
- EPILOG_RESTORE_REG_PAIR x19, x20, #16
- EPILOG_RESTORE_REG_PAIR x21, x22, #32
- EPILOG_RESTORE_REG_PAIR x23, x24, #48
- EPILOG_RESTORE_REG_PAIR x25, x26, #64
- EPILOG_RESTORE_REG_PAIR x27, x28, #80
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #160
+
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
.endm
@@ -273,8 +330,8 @@ __RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thr
IMPORT $__RedirectionFuncName
NESTED_ENTRY $__RedirectionStubFuncName
- PROLOG_SAVE_REG_PAIR fp, lr, #-16
- sub sp, sp, #16 // stack slot for CONTEXT * and padding
+ PROLOG_SAVE_REG_PAIR fp, lr, -16
+ sub sp, sp, #16 // stack slot for CONTEXT * and padding
//REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h and is used in GetCONTEXTFromRedirectedStubStackFrame
//If CONTEXT is not saved at 0 offset from SP it must be changed as well.
diff --git a/src/pal/src/arch/arm64/asmconstants.h b/src/pal/src/arch/arm64/asmconstants.h
new file mode 100644
index 0000000000..b2bf74461f
--- /dev/null
+++ b/src/pal/src/arch/arm64/asmconstants.h
@@ -0,0 +1,95 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef __PAL_ARM64_ASMCONSTANTS_H__
+#define __PAL_ARM64_ASMCONSTANTS_H__
+
+#define CONTEXT_ARM64 0x00400000L
+
+#define CONTEXT_CONTROL_BIT (0)
+#define CONTEXT_INTEGER_BIT (1)
+#define CONTEXT_FLOATING_POINT_BIT (2)
+#define CONTEXT_DEBUG_REGISTERS_BIT (3)
+
+#define CONTEXT_CONTROL (CONTEXT_ARM64 | (1L << CONTEXT_CONTROL_BIT))
+#define CONTEXT_INTEGER (CONTEXT_ARM64 | (1 << CONTEXT_INTEGER_BIT))
+#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | (1 << CONTEXT_FLOATING_POINT_BIT))
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | (1 << CONTEXT_DEBUG_REGISTERS_BIT))
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+
+
+#define CONTEXT_ContextFlags 0
+#define CONTEXT_Cpsr CONTEXT_ContextFlags+4
+#define CONTEXT_X0 CONTEXT_Cpsr+4
+#define CONTEXT_X1 CONTEXT_X0+8
+#define CONTEXT_X2 CONTEXT_X1+8
+#define CONTEXT_X3 CONTEXT_X2+8
+#define CONTEXT_X4 CONTEXT_X3+8
+#define CONTEXT_X5 CONTEXT_X4+8
+#define CONTEXT_X6 CONTEXT_X5+8
+#define CONTEXT_X7 CONTEXT_X6+8
+#define CONTEXT_X8 CONTEXT_X7+8
+#define CONTEXT_X9 CONTEXT_X8+8
+#define CONTEXT_X10 CONTEXT_X9+8
+#define CONTEXT_X11 CONTEXT_X10+8
+#define CONTEXT_X12 CONTEXT_X11+8
+#define CONTEXT_X13 CONTEXT_X12+8
+#define CONTEXT_X14 CONTEXT_X13+8
+#define CONTEXT_X15 CONTEXT_X14+8
+#define CONTEXT_X16 CONTEXT_X15+8
+#define CONTEXT_X17 CONTEXT_X16+8
+#define CONTEXT_X18 CONTEXT_X17+8
+#define CONTEXT_X19 CONTEXT_X18+8
+#define CONTEXT_X20 CONTEXT_X19+8
+#define CONTEXT_X21 CONTEXT_X20+8
+#define CONTEXT_X22 CONTEXT_X21+8
+#define CONTEXT_X23 CONTEXT_X22+8
+#define CONTEXT_X24 CONTEXT_X23+8
+#define CONTEXT_X25 CONTEXT_X24+8
+#define CONTEXT_X26 CONTEXT_X25+8
+#define CONTEXT_X27 CONTEXT_X26+8
+#define CONTEXT_X28 CONTEXT_X27+8
+#define CONTEXT_Fp CONTEXT_X28+8
+#define CONTEXT_Lr CONTEXT_Fp+8
+#define CONTEXT_Sp CONTEXT_Lr+8
+#define CONTEXT_Pc CONTEXT_Sp+8
+#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8
+#define CONTEXT_V0 0
+#define CONTEXT_V1 CONTEXT_V0+16
+#define CONTEXT_V2 CONTEXT_V1+16
+#define CONTEXT_V3 CONTEXT_V2+16
+#define CONTEXT_V4 CONTEXT_V3+16
+#define CONTEXT_V5 CONTEXT_V4+16
+#define CONTEXT_V6 CONTEXT_V5+16
+#define CONTEXT_V7 CONTEXT_V6+16
+#define CONTEXT_V8 CONTEXT_V7+16
+#define CONTEXT_V9 CONTEXT_V8+16
+#define CONTEXT_V10 CONTEXT_V9+16
+#define CONTEXT_V11 CONTEXT_V10+16
+#define CONTEXT_V12 CONTEXT_V11+16
+#define CONTEXT_V13 CONTEXT_V12+16
+#define CONTEXT_V14 CONTEXT_V13+16
+#define CONTEXT_V15 CONTEXT_V14+16
+#define CONTEXT_V16 CONTEXT_V15+16
+#define CONTEXT_V17 CONTEXT_V16+16
+#define CONTEXT_V18 CONTEXT_V17+16
+#define CONTEXT_V19 CONTEXT_V18+16
+#define CONTEXT_V20 CONTEXT_V19+16
+#define CONTEXT_V21 CONTEXT_V20+16
+#define CONTEXT_V22 CONTEXT_V21+16
+#define CONTEXT_V23 CONTEXT_V22+16
+#define CONTEXT_V24 CONTEXT_V23+16
+#define CONTEXT_V25 CONTEXT_V24+16
+#define CONTEXT_V26 CONTEXT_V25+16
+#define CONTEXT_V27 CONTEXT_V26+16
+#define CONTEXT_V28 CONTEXT_V27+16
+#define CONTEXT_V29 CONTEXT_V28+16
+#define CONTEXT_V30 CONTEXT_V29+16
+#define CONTEXT_V31 CONTEXT_V30+16
+#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31
+#define CONTEXT_Fpcr 0
+#define CONTEXT_Fpsr CONTEXT_Fpcr+4
+
+#endif
diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S
index a64e62c94d..e62a9ac4d9 100644
--- a/src/pal/src/arch/arm64/context2.S
+++ b/src/pal/src/arch/arm64/context2.S
@@ -8,87 +8,7 @@
//
#include "unixasmmacros.inc"
-
-#define CONTEXT_ARM64 0x00400000L
-
-#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
-#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
-#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L)
-#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L)
-
-#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
-
-#define CONTEXT_ContextFlags 0
-#define CONTEXT_Cpsr CONTEXT_ContextFlags+4
-#define CONTEXT_X0 CONTEXT_Cpsr+4
-#define CONTEXT_X1 CONTEXT_X0+8
-#define CONTEXT_X2 CONTEXT_X1+8
-#define CONTEXT_X3 CONTEXT_X2+8
-#define CONTEXT_X4 CONTEXT_X3+8
-#define CONTEXT_X5 CONTEXT_X4+8
-#define CONTEXT_X6 CONTEXT_X5+8
-#define CONTEXT_X7 CONTEXT_X6+8
-#define CONTEXT_X8 CONTEXT_X7+8
-#define CONTEXT_X9 CONTEXT_X8+8
-#define CONTEXT_X10 CONTEXT_X9+8
-#define CONTEXT_X11 CONTEXT_X10+8
-#define CONTEXT_X12 CONTEXT_X11+8
-#define CONTEXT_X13 CONTEXT_X12+8
-#define CONTEXT_X14 CONTEXT_X13+8
-#define CONTEXT_X15 CONTEXT_X14+8
-#define CONTEXT_X16 CONTEXT_X15+8
-#define CONTEXT_X17 CONTEXT_X16+8
-#define CONTEXT_X18 CONTEXT_X17+8
-#define CONTEXT_X19 CONTEXT_X18+8
-#define CONTEXT_X20 CONTEXT_X19+8
-#define CONTEXT_X21 CONTEXT_X20+8
-#define CONTEXT_X22 CONTEXT_X21+8
-#define CONTEXT_X23 CONTEXT_X22+8
-#define CONTEXT_X24 CONTEXT_X23+8
-#define CONTEXT_X25 CONTEXT_X24+8
-#define CONTEXT_X26 CONTEXT_X25+8
-#define CONTEXT_X27 CONTEXT_X26+8
-#define CONTEXT_X28 CONTEXT_X27+8
-#define CONTEXT_Fp CONTEXT_X28+8
-#define CONTEXT_Lr CONTEXT_Fp+8
-#define CONTEXT_Sp CONTEXT_Lr+8
-#define CONTEXT_Pc CONTEXT_Sp+8
-#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8
-#define CONTEXT_V0 0
-#define CONTEXT_V1 CONTEXT_V0+16
-#define CONTEXT_V2 CONTEXT_V1+16
-#define CONTEXT_V3 CONTEXT_V2+16
-#define CONTEXT_V4 CONTEXT_V3+16
-#define CONTEXT_V5 CONTEXT_V4+16
-#define CONTEXT_V6 CONTEXT_V5+16
-#define CONTEXT_V7 CONTEXT_V6+16
-#define CONTEXT_V8 CONTEXT_V7+16
-#define CONTEXT_V9 CONTEXT_V8+16
-#define CONTEXT_V10 CONTEXT_V9+16
-#define CONTEXT_V11 CONTEXT_V10+16
-#define CONTEXT_V12 CONTEXT_V11+16
-#define CONTEXT_V13 CONTEXT_V12+16
-#define CONTEXT_V14 CONTEXT_V13+16
-#define CONTEXT_V15 CONTEXT_V14+16
-#define CONTEXT_V16 CONTEXT_V15+16
-#define CONTEXT_V17 CONTEXT_V16+16
-#define CONTEXT_V18 CONTEXT_V17+16
-#define CONTEXT_V19 CONTEXT_V18+16
-#define CONTEXT_V20 CONTEXT_V19+16
-#define CONTEXT_V21 CONTEXT_V20+16
-#define CONTEXT_V22 CONTEXT_V21+16
-#define CONTEXT_V23 CONTEXT_V22+16
-#define CONTEXT_V24 CONTEXT_V23+16
-#define CONTEXT_V25 CONTEXT_V24+16
-#define CONTEXT_V26 CONTEXT_V25+16
-#define CONTEXT_V27 CONTEXT_V26+16
-#define CONTEXT_V28 CONTEXT_V27+16
-#define CONTEXT_V29 CONTEXT_V28+16
-#define CONTEXT_V30 CONTEXT_V29+16
-#define CONTEXT_V31 CONTEXT_V30+16
-#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31
-#define CONTEXT_Fpcr 0
-#define CONTEXT_Fpsr CONTEXT_Fpcr+4
+#include "asmconstants.h"
// Incoming:
// x0: Context*
@@ -115,10 +35,8 @@ LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
ldr x2, [sp, 24]
str w2, [x0, CONTEXT_Cpsr]
stp fp, lr, [x0, CONTEXT_Fp]
- add sp, sp, #32
- mov x2, sp
+ add x2, sp, #32
stp x2, lr, [x0, CONTEXT_Sp]
- sub sp, sp, #32
LOCAL_LABEL(Done_CONTEXT_CONTROL):
// we dont clobber x1 in the CONTEXT_CONTROL case
@@ -224,14 +142,8 @@ LEAF_ENTRY RtlRestoreContext, _TEXT
// since we potentially clobber x0 below, we'll bank it in x16
mov x16, x0
- ldr w2, [x16, CONTEXT_ContextFlags]
- // clangs assembler doesn't seem to support the mov Wx, imm32 yet
- movz w3, #0x40, lsl #16
- movk w3, #0x4
- mov w4, w3
- and w3, w2, w3
- cmp w3, w4
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT)
+ ldr w17, [x16, CONTEXT_ContextFlags]
+ tbz w17, #CONTEXT_FLOATING_POINT_BIT, LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT)
add x16, x16, CONTEXT_NEON_OFFSET
ldp q0, q1, [x16, CONTEXT_V0]
@@ -256,12 +168,7 @@ LEAF_ENTRY RtlRestoreContext, _TEXT
sub x16, x16, CONTEXT_NEON_OFFSET
LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT):
- movz w2, #0x40, lsl #16
- movk w2, #0x2
- mov w3, w2
- and w2, w1, w2
- cmp w2, w3
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_INTEGER)
+ tbz w17, #CONTEXT_INTEGER_BIT, LOCAL_LABEL(No_Restore_CONTEXT_INTEGER)
ldp x0, x1, [x16, CONTEXT_X0]
ldp x2, x3, [x16, CONTEXT_X2]
@@ -279,12 +186,7 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT):
ldr x28, [x16, CONTEXT_X28]
LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
- movz w2, #0x40, lsl #16
- movk w2, #0x2
- mov w3, w2
- and w2, w1, w2
- cmp w2, w3
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
+ tbz w17, #CONTEXT_CONTROL_BIT, LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
ldr w17, [x16, CONTEXT_Cpsr]
msr nzcv, x17
@@ -293,8 +195,8 @@ LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
mov sp, x17
ldr x17, [x16, CONTEXT_Pc]
br x17
-
+
LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
- ret
+ ret
LEAF_END RtlRestoreContext, _TEXT
diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S
index 4fdcfc5eb1..480846eb61 100644
--- a/src/pal/src/arch/arm64/exceptionhelper.S
+++ b/src/pal/src/arch/arm64/exceptionhelper.S
@@ -3,7 +3,30 @@
// See the LICENSE file in the project root for more information.
#include "unixasmmacros.inc"
+#include "asmconstants.h"
+//////////////////////////////////////////////////////////////////////////
+//
+// This function creates a stack frame right below the target frame, restores all callee
+// saved registers, SP, and LR from the passed in context.
+// Then it uses the ThrowExceptionHelper to throw the passed in exception from that context.
+// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
- EMIT_BREAKPOINT
+ // Save the FP & LR to the stack so that the unwind can work at the instruction after
+ // loading the FP from the context, but before loading the SP from the context.
+ stp fp, lr, [sp, -16]!
+
+ ldp x19,x20, [x0, #(CONTEXT_X19)]
+ ldp x21,x22, [x0, #(CONTEXT_X21)]
+ ldp x23,x24, [x0, #(CONTEXT_X23)]
+ ldp x24,x25, [x0, #(CONTEXT_X24)]
+ ldp x26,x27, [x0, #(CONTEXT_X26)]
+ ldp x28,fp, [x0, #(CONTEXT_X28)]
+ ldr lr, [x0, #(CONTEXT_Pc)]
+ ldr x2, [x0, #(CONTEXT_Sp)]
+ mov sp, x2
+
+ // The PAL_SEHException pointer
+ mov x0, x1
+ b EXTERNAL_C_FUNC(ThrowExceptionHelper)
LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index aeb6fa4b6a..1f20ee0cad 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -244,6 +244,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext,
GetContextPointer(cursor, unwContext, UNW_AARCH64_X26, &contextPointers->X26);
GetContextPointer(cursor, unwContext, UNW_AARCH64_X27, &contextPointers->X27);
GetContextPointer(cursor, unwContext, UNW_AARCH64_X28, &contextPointers->X28);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X29, &contextPointers->Fp);
#else
#error unsupported architecture
#endif
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index 6857c130ee..08fa05da7d 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -248,8 +248,7 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc)
#define MCREG_Sp(mc) ((mc).sp)
#define MCREG_Pc(mc) ((mc).pc)
-#define MCREG_PState(mc) ((mc).pstate)
-#define MCREG_Cpsr(mc) ((mc).cpsr)
+#define MCREG_Cpsr(mc) ((mc).pstate)
#else
// For FreeBSD, as found in x86/ucontext.h
#define MCREG_Rbp(mc) ((mc).mc_rbp)
diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp
index bee6ddd449..98867c9554 100644
--- a/src/pal/src/thread/context.cpp
+++ b/src/pal/src/thread/context.cpp
@@ -127,6 +127,8 @@ typedef int __ptrace_request;
ASSIGN_REG(R12)
#elif defined(_ARM64_)
#define ASSIGN_CONTROL_REGS \
+ ASSIGN_REG(Cpsr) \
+ ASSIGN_REG(Fp) \
ASSIGN_REG(Sp) \
ASSIGN_REG(Lr) \
ASSIGN_REG(Pc)