Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2018-05-18 00:04:30 +0300
committerdotnet-bot <dotnet-bot@microsoft.com>2018-05-18 00:04:30 +0300
commitedafa6b8f6100ef941c570363117907714730692 (patch)
tree340b0361f8c24ec75d76995304aa8d9f78df8fbf /src/Native
parentcecadf1808d028de68cddc54529feb526ca7854b (diff)
[tfs-changeset: 1700475]
Diffstat (limited to 'src/Native')
-rw-r--r--src/Native/Runtime/arm64/GcProbe.asm112
1 files changed, 61 insertions, 51 deletions
diff --git a/src/Native/Runtime/arm64/GcProbe.asm b/src/Native/Runtime/arm64/GcProbe.asm
index 3554c8eb3..f83141684 100644
--- a/src/Native/Runtime/arm64/GcProbe.asm
+++ b/src/Native/Runtime/arm64/GcProbe.asm
@@ -48,7 +48,7 @@ PROBE_FRAME_SIZE field 0
;; Perform the parts of setting up a probe frame that can occur during the prolog (and indeed this macro
;; can only be called from within the prolog).
MACRO
- ALLOC_PROBE_FRAME $extraStackSpace
+ ALLOC_PROBE_FRAME $extraStackSpace, $saveFPRegisters
;; First create PInvokeTransitionFrame
PROLOG_SAVE_REG_PAIR fp, lr, #-(PROBE_FRAME_SIZE + $extraStackSpace)! ;; Push down stack pointer and store FP and LR
@@ -80,16 +80,18 @@ PROBE_FRAME_SIZE field 0
;; Slot at [sp, #0x118] is reserved for NZCV
- ; Save the floating return registers
- PROLOG_NOP stp d0, d1, [sp, #0x120]
- PROLOG_NOP stp d2, d3, [sp, #0x130]
+ ;; Save the floating return registers
+ IF $saveFPRegisters
+ PROLOG_NOP stp d0, d1, [sp, #0x120]
+ PROLOG_NOP stp d2, d3, [sp, #0x130]
+ ENDIF
MEND
;; Undo the effects of an ALLOC_PROBE_FRAME. This may only be called within an epilog. Note that all
;; registers are restored (apart for sp and pc), even volatiles.
MACRO
- FREE_PROBE_FRAME $extraStackSpace
+ FREE_PROBE_FRAME $extraStackSpace, $restoreFPRegisters
;; Restore the scratch registers
PROLOG_NOP ldr x0, [sp, #0x78]
@@ -105,8 +107,10 @@ PROBE_FRAME_SIZE field 0
PROLOG_NOP ldr lr, [sp, #0x110]
; Restore the floating return registers
- EPILOG_NOP ldp d0, d1, [sp, #0x120]
- EPILOG_NOP ldp d2, d3, [sp, #0x130]
+ IF $restoreFPRegisters
+ EPILOG_NOP ldp d0, d1, [sp, #0x120]
+ EPILOG_NOP ldp d2, d3, [sp, #0x130]
+ ENDIF
;; Restore callee saved registers
EPILOG_RESTORE_REG_PAIR x19, x20, #0x20
@@ -167,7 +171,7 @@ __PPF_ThreadReg SETS "$threadReg"
; Define the method prolog, allocating enough stack space for the PInvokeTransitionFrame and saving
; incoming register values into it.
- ALLOC_PROBE_FRAME 0
+ ALLOC_PROBE_FRAME 0, {true}
; If the caller didn't provide a value for $threadReg then generate code to fetch the Thread* into x2.
; Record that x2 holds the Thread* in our local variable.
@@ -188,58 +192,64 @@ __PPF_ThreadReg SETS "x2"
MACRO
EPILOG_PROBE_FRAME
- FREE_PROBE_FRAME 0
+ FREE_PROBE_FRAME 0, {true}
EPILOG_RETURN
MEND
-;; ALLOC_PROBE_FRAME will save the first 4 vfp registers, in order to avoid trashing VFP registers across the loop
-;; hijack, we must save the rest -- d4-d31 (28).
-EXTRA_SAVE_SIZE equ (28*8)
+;; In order to avoid trashing VFP registers across the loop hijack we must save all user registers, so that
+;; registers used by the loop being hijacked will not be affected. Unlike ARM32 where neon registers (NQ0, ..., NQ15)
+;; are fully covered by the floating point registers D0 ... D31, we have 32 neon registers Q0, ... Q31 on ARM64
+;; which are not fully covered by the register D0 ... D31. Therefore we must explicitly save all Q registers.
+EXTRA_SAVE_SIZE equ (32*16)
MACRO
ALLOC_LOOP_HIJACK_FRAME
PROLOG_STACK_ALLOC EXTRA_SAVE_SIZE
-;; save VFP registers that were not saved by the ALLOC_PROBE_FRAME
- PROLOG_NOP stp d4, d5, [sp]
- PROLOG_NOP stp d6, d7, [sp, #0x10]
- PROLOG_NOP stp d8, d9, [sp, #0x20]
- PROLOG_NOP stp d10, d11, [sp, #0x30]
- PROLOG_NOP stp d12, d13, [sp, #0x40]
- PROLOG_NOP stp d14, d15, [sp, #0x50]
- PROLOG_NOP stp d16, d17, [sp, #0x60]
- PROLOG_NOP stp d18, d19, [sp, #0x70]
- PROLOG_NOP stp d20, d21, [sp, #0x80]
- PROLOG_NOP stp d22, d23, [sp, #0x90]
- PROLOG_NOP stp d24, d25, [sp, #0xA0]
- PROLOG_NOP stp d26, d27, [sp, #0xB0]
- PROLOG_NOP stp d28, d29, [sp, #0xC0]
- PROLOG_NOP stp d30, d31, [sp, #0xD0]
-
- ALLOC_PROBE_FRAME 0
+ ;; Save all neon registers
+ PROLOG_NOP stp q0, q1, [sp]
+ PROLOG_NOP stp q2, q3, [sp, #0x20]
+ PROLOG_NOP stp q4, q5, [sp, #0x40]
+ PROLOG_NOP stp q6, q7, [sp, #0x60]
+ PROLOG_NOP stp q8, q9, [sp, #0x80]
+ PROLOG_NOP stp q10, q11, [sp, #0xA0]
+ PROLOG_NOP stp q12, q13, [sp, #0xC0]
+ PROLOG_NOP stp q14, q15, [sp, #0xE0]
+ PROLOG_NOP stp q16, q17, [sp, #0x100]
+ PROLOG_NOP stp q18, q19, [sp, #0x120]
+ PROLOG_NOP stp q20, q21, [sp, #0x140]
+ PROLOG_NOP stp q22, q23, [sp, #0x160]
+ PROLOG_NOP stp q24, q25, [sp, #0x180]
+ PROLOG_NOP stp q26, q27, [sp, #0x1A0]
+ PROLOG_NOP stp q28, q29, [sp, #0x1C0]
+ PROLOG_NOP stp q30, q31, [sp, #0x1E0]
+
+ ALLOC_PROBE_FRAME 0, {false}
MEND
MACRO
FREE_LOOP_HIJACK_FRAME
- FREE_PROBE_FRAME 0
-
-;; restore VFP registers that will not be restored by the FREE_PROBE_FRAME
- PROLOG_NOP ldp d4, d5, [sp]
- PROLOG_NOP ldp d6, d7, [sp, #0x10]
- PROLOG_NOP ldp d8, d9, [sp, #0x20]
- PROLOG_NOP ldp d10, d11, [sp, #0x30]
- PROLOG_NOP ldp d12, d13, [sp, #0x40]
- PROLOG_NOP ldp d14, d15, [sp, #0x50]
- PROLOG_NOP ldp d16, d17, [sp, #0x60]
- PROLOG_NOP ldp d18, d19, [sp, #0x70]
- PROLOG_NOP ldp d20, d21, [sp, #0x80]
- PROLOG_NOP ldp d22, d23, [sp, #0x90]
- PROLOG_NOP ldp d24, d25, [sp, #0xA0]
- PROLOG_NOP ldp d26, d27, [sp, #0xB0]
- PROLOG_NOP ldp d28, d29, [sp, #0xC0]
- PROLOG_NOP ldp d30, d31, [sp, #0xD0]
+ FREE_PROBE_FRAME 0, {false}
+
+ ;; restore all neon registers
+ PROLOG_NOP ldp q0, q1, [sp]
+ PROLOG_NOP ldp q2, q3, [sp, #0x20]
+ PROLOG_NOP ldp q4, q5, [sp, #0x40]
+ PROLOG_NOP ldp q6, q7, [sp, #0x60]
+ PROLOG_NOP ldp q8, q9, [sp, #0x80]
+ PROLOG_NOP ldp q10, q11, [sp, #0xA0]
+ PROLOG_NOP ldp q12, q13, [sp, #0xC0]
+ PROLOG_NOP ldp q14, q15, [sp, #0xE0]
+ PROLOG_NOP ldp q16, q17, [sp, #0x100]
+ PROLOG_NOP ldp q18, q19, [sp, #0x120]
+ PROLOG_NOP ldp q20, q21, [sp, #0x140]
+ PROLOG_NOP ldp q22, q23, [sp, #0x160]
+ PROLOG_NOP ldp q24, q25, [sp, #0x180]
+ PROLOG_NOP ldp q26, q27, [sp, #0x1A0]
+ PROLOG_NOP ldp q28, q29, [sp, #0x1C0]
+ PROLOG_NOP ldp q30, q31, [sp, #0x1E0]
EPILOG_STACK_FREE EXTRA_SAVE_SIZE
MEND
@@ -405,7 +415,7 @@ EXTRA_SAVE_SIZE equ (28*8)
EPILOG_PROBE_FRAME
1
- FREE_PROBE_FRAME 0
+ FREE_PROBE_FRAME 0, {true}
EPILOG_NOP mov w0, #STATUS_REDHAWK_THREAD_ABORT
EPILOG_NOP mov x1, lr ;; return address as exception PC
EPILOG_NOP b RhpThrowHwEx
@@ -630,7 +640,7 @@ EXTRA_SAVE_SIZE equ (28*8)
EHJumpProbeProlog
PROLOG_NOP mov x0, x1 ; move the ex object reference into x0 so we can report it
- ALLOC_PROBE_FRAME 0x10
+ ALLOC_PROBE_FRAME 0x10, {true}
str x2, [sp, #PROBE_FRAME_SIZE]
;; x2 <- GetThread(), TRASHES x1
@@ -665,7 +675,7 @@ EXTRA_SAVE_SIZE equ (28*8)
EHJumpProbeEpilog
ldr x2, [sp, #PROBE_FRAME_SIZE]
- FREE_PROBE_FRAME 0x10 ; This restores exception object back into x0
+ FREE_PROBE_FRAME 0x10, {true} ; This restores exception object back into x0
EPILOG_NOP mov x1, x0 ; Move the Exception object back into x1 where the catch handler expects it
EPILOG_NOP ret x2
MEND
@@ -898,8 +908,8 @@ Abort
;;
;; [sp + 118] -> NZCV
;;
- ;; [sp + 120] -> d0, d1, d2, d3
- ;; [sp + 140] -> d4 ... d31
+ ;; [sp + 120] -> not used
+ ;; [sp + 140] -> q0 ... q31
;;
ALLOC_LOOP_HIJACK_FRAME