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

AsmMacros.h « arm « Runtime « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1e64ddc76bfb55f905fe75092a8e09eed86d7864 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
;; 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.

;; OS provided macros
#include <ksarm.h>
;; generated by the build from AsmOffsets.cpp
#include "AsmOffsets.inc"

;;
;; CONSTANTS -- INTEGER
;;
TSF_Attached                    equ 0x01
TSF_SuppressGcStress            equ 0x08
TSF_DoNotTriggerGc              equ 0x10
TSF_SuppressGcStress__OR__TSF_DoNotTriggerGC equ 0x18

;; GC type flags
GC_ALLOC_FINALIZE               equ 1
GC_ALLOC_ALIGN8_BIAS            equ 4
GC_ALLOC_ALIGN8                 equ 8

;; GC minimal sized object. We use this to switch between 4 and 8 byte alignment in the GC heap (see AllocFast.asm).
SIZEOF__MinObject               equ 12
    ASSERT (SIZEOF__MinObject :MOD: 8) == 4

;; Note: these must match the defs in PInvokeTransitionFrameFlags
PTFF_SAVE_R4            equ 0x00000001
PTFF_SAVE_R5            equ 0x00000002
PTFF_SAVE_R6            equ 0x00000004
PTFF_SAVE_R7            equ 0x00000008
PTFF_SAVE_R8            equ 0x00000010
PTFF_SAVE_R9            equ 0x00000020
PTFF_SAVE_R10           equ 0x00000040
PTFF_SAVE_ALL_PRESERVED equ 0x00000077  ;; NOTE: FP is not included in this set!
PTFF_SAVE_SP            equ 0x00000100
PTFF_SAVE_R0            equ 0x00000200  ;; R0 is saved if it contains a GC ref and we're in hijack handler
PTFF_SAVE_ALL_SCRATCH   equ 0x00003e00  ;; R0-R3,LR (R12 is trashed by the helpers anyway, but LR is relevant for loop hijacking
PTFF_R0_IS_GCREF        equ 0x00004000  ;; iff PTFF_SAVE_R0: set -> r0 is Object, clear -> r0 is scalar
PTFF_R0_IS_BYREF        equ 0x00008000  ;; iff PTFF_SAVE_R0: set -> r0 is ByRef, clear -> r0 is Object or scalar
PTFF_THREAD_ABORT       equ 0x00010000  ;; indicates that ThreadAbortException should be thrown when returning from the transition

;; These must match the TrapThreadsFlags enum
TrapThreadsFlags_None            equ 0
TrapThreadsFlags_AbortInProgress equ 1
TrapThreadsFlags_TrapThreads     equ 2

;; This must match HwExceptionCode.STATUS_REDHAWK_THREAD_ABORT
STATUS_REDHAWK_THREAD_ABORT      equ 0x43

;;
;; Rename fields of nested structs
;;
OFFSETOF__Thread__m_alloc_context__alloc_ptr        equ OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_ptr
OFFSETOF__Thread__m_alloc_context__alloc_limit      equ OFFSETOF__Thread__m_rgbAllocContextBuffer + OFFSETOF__gc_alloc_context__alloc_limit


__tls_array     equ 0x2C    ;; offsetof(TEB, ThreadLocalStoragePointer)

;;
;; MACROS
;;

        GBLS __SECTIONREL_tls_CurrentThread
__SECTIONREL_tls_CurrentThread SETS "SECTIONREL_tls_CurrentThread"

    MACRO
        INLINE_GETTHREAD $destReg, $trashReg
        EXTERN _tls_index

        ldr         $destReg, =_tls_index
        ldr         $destReg, [$destReg]
        mrc         p15, 0, $trashReg, c13, c0, 2
        ldr         $trashReg, [$trashReg, #__tls_array]
        ldr         $destReg, [$trashReg, $destReg, lsl #2]
        ldr         $trashReg, $__SECTIONREL_tls_CurrentThread
        add         $destReg, $trashReg
    MEND

        ;; INLINE_GETTHREAD_CONSTANT_POOL macro has to be used after the last function in the .asm file that used
        ;; INLINE_GETTHREAD. Optionally, it can be also used after any function that used INLINE_GETTHREAD
        ;; to improve density, or to reduce distance betweeen the constant pool and its use.
    MACRO
        INLINE_GETTHREAD_CONSTANT_POOL
        EXTERN tls_CurrentThread

$__SECTIONREL_tls_CurrentThread
        DCD tls_CurrentThread
        RELOC 15 ;; SECREL

__SECTIONREL_tls_CurrentThread SETS "$__SECTIONREL_tls_CurrentThread":CC:"_"

    MEND

    MACRO
        INLINE_THREAD_UNHIJACK $threadReg, $trashReg1, $trashReg2
        ;;
        ;; Thread::Unhijack()
        ;;
        ldr         $trashReg1, [$threadReg, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
        cbz         $trashReg1, %ft0

        ldr         $trashReg2, [$threadReg, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
        str         $trashReg1, [$trashReg2]
        mov         $trashReg1, #0
        str         $trashReg1, [$threadReg, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
        str         $trashReg1, [$threadReg, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
0
    MEND

DEFAULT_FRAME_SAVE_FLAGS equ PTFF_SAVE_ALL_PRESERVED + PTFF_SAVE_SP

;;
;; Macro used from unmanaged helpers called from managed code where the helper does not transition immediately
;; into pre-emptive mode but may cause a GC and thus requires the stack is crawlable. This is typically the
;; case for helpers that meddle in GC state (e.g. allocation helpers) where the code must remain in
;; cooperative mode since it handles object references and internal GC state directly but a garbage collection
;; may be inevitable. In these cases we need to be able to transition to pre-meptive mode deep within the
;; unmanaged code but still be able to initialize the stack iterator at the first stack frame which may hold
;; interesting GC references. In all our helper cases this corresponds to the most recent managed frame (e.g.
;; the helper's caller).
;;
;; This macro builds a frame describing the current state of managed code.
;;
;; INVARIANTS
;; - The macro assumes it defines the method prolog, it should typically be the first code in a method and
;;   certainly appear before any attempt to alter the stack pointer.
;; - This macro uses trashReg (after its initial value has been saved in the frame) and upon exit trashReg
;;   will contain the address of transition frame.
;;
    MACRO
        PUSH_COOP_PINVOKE_FRAME $trashReg

        PROLOG_STACK_ALLOC 4        ; Save space for caller's SP
        PROLOG_PUSH {r4-r6,r8-r10}  ; Save preserved registers
        PROLOG_STACK_ALLOC 8        ; Save space for flags and Thread*
        PROLOG_PUSH {r7}            ; Save caller's FP
        PROLOG_PUSH {r11,lr}        ; Save caller's frame-chain pointer and PC

        ; Compute SP value at entry to this method and save it in the last slot of the frame (slot #11).
        add         $trashReg, sp, #(12 * 4)
        str         $trashReg, [sp, #(11 * 4)]

        ; Record the bitmask of saved registers in the frame (slot #4).
        mov         $trashReg, #DEFAULT_FRAME_SAVE_FLAGS
        str         $trashReg, [sp, #(4 * 4)]

        mov         $trashReg, sp
    MEND

;; Pop the frame and restore register state preserved by PUSH_COOP_PINVOKE_FRAME
    MACRO
        POP_COOP_PINVOKE_FRAME
        EPILOG_POP  {r11,lr}        ; Restore caller's frame-chain pointer and PC (return address)
        EPILOG_POP  {r7}            ; Restore caller's FP
        EPILOG_STACK_FREE 8         ; Discard flags and Thread*
        EPILOG_POP  {r4-r6,r8-r10}  ; Restore preserved registers
        EPILOG_STACK_FREE 4         ; Discard caller's SP
    MEND


; Macro used to assign an alternate name to a symbol containing characters normally disallowed in a symbol
; name (e.g. C++ decorated names).
    MACRO
      SETALIAS   $name, $symbol
        GBLS    $name
$name   SETS    "|$symbol|"
    MEND


        ;
        ; Helper macro: create a global label for the given name,
        ; decorate it, and export it for external consumption.
        ;

        MACRO
        __ExportLabelName $FuncName

        LCLS    Name
Name    SETS    "|$FuncName|"
        EXPORT  $Name
$Name
        MEND

        ;
        ; Macro for indicating an alternate entry point into a function.
        ;

        MACRO
        LABELED_RETURN_ADDRESS $ReturnAddressName

        ; export the return address name, but do not perturb the code by forcing alignment
        __ExportLabelName $ReturnAddressName

        ; flush any pending literal pool stuff
        ROUT

        MEND

        MACRO
        EXPORT_POINTER_TO_ADDRESS $Name

1

        AREA        |.rdata|, ALIGN=4, DATA, READONLY

$Name

        DCD         %BT1

        EXPORT      $Name

        TEXTAREA

        ROUT

        MEND

;-----------------------------------------------------------------------------
; Macro used to check (in debug builds only) whether the stack is 64-bit aligned (a requirement before calling
; out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
; before a call (if you have a frame pointer and a dynamic stack). A breakpoint will be invoked if the stack
; is misaligned.
;
    MACRO
        CHECK_STACK_ALIGNMENT

#ifdef _DEBUG
        push    {r0}
        add     r0, sp, #4
        tst     r0, #7
        pop     {r0}
        beq     %F0
        EMIT_BREAKPOINT
0
#endif
    MEND

;; Loads a 32bit constant into destination register
    MACRO
        MOV32   $destReg, $constant

        movw    $destReg, #(($constant) & 0xFFFF)
        movt    $destReg, #(($constant) >> 16)
    MEND

;;
;; CONSTANTS -- SYMBOLS
;;

        SETALIAS G_LOWEST_ADDRESS, g_lowest_address
        SETALIAS G_HIGHEST_ADDRESS, g_highest_address
        SETALIAS G_EPHEMERAL_LOW, g_ephemeral_low
        SETALIAS G_EPHEMERAL_HIGH, g_ephemeral_high
        SETALIAS G_CARD_TABLE, g_card_table
        SETALIAS G_FREE_OBJECT_EETYPE, ?g_pFreeObjectMethodTable@@3PAVMethodTable@@A
#ifdef FEATURE_GC_STRESS
        SETALIAS THREAD__HIJACKFORGCSTRESS, ?HijackForGcStress@Thread@@SAXPAUPAL_LIMITED_CONTEXT@@@Z
        SETALIAS REDHAWKGCINTERFACE__STRESSGC, ?StressGc@RedhawkGCInterface@@SAXXZ
#endif ;; FEATURE_GC_STRESS
;;
;; IMPORTS
;;
        EXTERN RhpGcAlloc
        EXTERN RhDebugBreak
        EXTERN RhpWaitForSuspend2
        EXTERN RhpWaitForGC2
        EXTERN RhpReversePInvokeAttachOrTrapThread2
        EXTERN RhExceptionHandling_FailedAllocation
        EXTERN RhpPublishObject
        EXTERN RhpCalculateStackTraceWorker


        EXTERN $G_LOWEST_ADDRESS
        EXTERN $G_HIGHEST_ADDRESS
        EXTERN $G_EPHEMERAL_LOW
        EXTERN $G_EPHEMERAL_HIGH
        EXTERN $G_CARD_TABLE
        EXTERN RhpTrapThreads
        EXTERN $G_FREE_OBJECT_EETYPE

        EXTERN RhThrowHwEx
        EXTERN RhThrowEx
        EXTERN RhRethrow

#ifdef FEATURE_GC_STRESS
        EXTERN $REDHAWKGCINTERFACE__STRESSGC
        EXTERN $THREAD__HIJACKFORGCSTRESS
#endif ;; FEATURE_GC_STRESS