1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
4 .macro NESTED_ENTRY Name, Section, Handler
5 LEAF_ENTRY \Name, \Section
6 .ifnc \Handler, NoHandler
7 .cfi_personality 0x1B, C_FUNC(\Handler) // 0x1B == DW_EH_PE_pcrel | DW_EH_PE_sdata4
11 .macro NESTED_END Name, Section
12 LEAF_END \Name, \Section
15 .macro PATCH_LABEL Name
20 .macro LEAF_ENTRY Name, Section
22 .type \Name, %function
27 .macro LEAF_END Name, Section
32 .macro LEAF_END_MARKED Name, Section
34 .global C_FUNC(\Name\()_End)
35 LEAF_END \Name, \Section
36 // make sure this symbol gets its own address
40 .macro PREPARE_EXTERNAL_VAR Name, HelperReg
44 .macro PROLOG_STACK_ALLOC Size
46 .cfi_adjust_cfa_offset \Size
49 .macro EPILOG_STACK_FREE Size
51 .cfi_adjust_cfa_offset -\Size
54 .macro EPILOG_STACK_RESTORE
59 .macro PROLOG_SAVE_REG reg, ofs
61 .cfi_rel_offset \reg, \ofs
64 .macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs, __def_cfa_save=0
66 sd \reg2, (\ofs+8)(sp)
67 .cfi_rel_offset \reg1, \ofs
68 .cfi_rel_offset \reg2, \ofs + 8
69 .if (\__def_cfa_save == 1)
71 .cfi_def_cfa_register fp
75 .macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ssize, __def_cfa_save=1
77 .cfi_adjust_cfa_offset \ssize
82 .cfi_rel_offset \reg1, 0
83 .cfi_rel_offset \reg2, 8
84 .if (\__def_cfa_save == 1)
86 .cfi_def_cfa_register fp
90 .macro EPILOG_RESTORE_REG reg, ofs
95 .macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs
96 ld \reg2, (\ofs+8)(sp)
102 .macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ssize
109 .cfi_adjust_cfa_offset -\ssize
116 .macro EMIT_BREAKPOINT
120 .macro EPILOG_BRANCH Target
124 .macro EPILOG_BRANCH_REG reg
128 //-----------------------------------------------------------------------------
129 // The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
130 // base address to be passed in $reg
133 // Reserve 64 bytes of memory before calling SAVE_CALLEESAVED_REGISTERS
134 .macro SAVE_CALLEESAVED_REGISTERS reg, ofs
135 PROLOG_SAVE_REG_PAIR s1, s2, \ofs + 16
136 PROLOG_SAVE_REG_PAIR s3, s4, \ofs + 32
137 PROLOG_SAVE_REG_PAIR s5, s6, \ofs + 48
138 PROLOG_SAVE_REG_PAIR s7, s8, \ofs + 64
139 PROLOG_SAVE_REG_PAIR s9, s10, \ofs + 80
140 PROLOG_SAVE_REG_PAIR s11, tp \ofs + 96
141 PROLOG_SAVE_REG gp, \ofs + 112
144 // Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS
145 .macro SAVE_ARGUMENT_REGISTERS reg, ofs
147 sd a1, (\ofs + 8)(\reg)
148 sd a2, (\ofs + 16)(\reg)
149 sd a3, (\ofs + 24)(\reg)
150 sd a4, (\ofs + 32)(\reg)
151 sd a5, (\ofs + 40)(\reg)
152 sd a6, (\ofs + 48)(\reg)
153 sd a7, (\ofs + 56)(\reg)
156 // Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS
157 .macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
158 fsd fa0, (\ofs)(\reg)
159 fsd fa1, (\ofs + 8)(\reg)
160 fsd fa2, (\ofs + 16)(\reg)
161 fsd fa3, (\ofs + 24)(\reg)
162 fsd fa4, (\ofs + 32)(\reg)
163 fsd fa5, (\ofs + 40)(\reg)
164 fsd fa6, (\ofs + 48)(\reg)
165 fsd fa7, (\ofs + 56)(\reg)
168 // Reserve 64 bytes of memory before calling SAVE_FLOAT_CALLEESAVED_REGISTERS
169 .macro SAVE_FLOAT_CALLEESAVED_REGISTERS reg, ofs
174 .macro RESTORE_CALLEESAVED_REGISTERS reg, ofs
175 EPILOG_RESTORE_REG gp \ofs + 112
176 EPILOG_RESTORE_REG_PAIR s11, tp \ofs + 96
177 EPILOG_RESTORE_REG_PAIR s9, s10, \ofs + 80
178 EPILOG_RESTORE_REG_PAIR s7, s8, \ofs + 64
179 EPILOG_RESTORE_REG_PAIR s5, s6, \ofs + 48
180 EPILOG_RESTORE_REG_PAIR s3, s4, \ofs + 32
181 EPILOG_RESTORE_REG_PAIR s1, s2, \ofs + 16
184 .macro RESTORE_ARGUMENT_REGISTERS reg, ofs
186 ld a1, (\ofs + 8)(\reg)
187 ld a2, (\ofs + 16)(\reg)
188 ld a3, (\ofs + 24)(\reg)
189 ld a4, (\ofs + 32)(\reg)
190 ld a5, (\ofs + 40)(\reg)
191 ld a6, (\ofs + 48)(\reg)
192 ld a7, (\ofs + 56)(\reg)
195 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
196 fld fa0, (\ofs)(\reg)
197 fld fa1, (\ofs + 8)(\reg)
198 fld fa2, (\ofs + 16)(\reg)
199 fld fa3, (\ofs + 24)(\reg)
200 fld fa4, (\ofs + 32)(\reg)
201 fld fa5, (\ofs + 40)(\reg)
202 fld fa6, (\ofs + 48)(\reg)
203 fld fa7, (\ofs + 56)(\reg)
206 .macro RESTORE_FLOAT_CALLEESAVED_REGISTERS reg, ofs
211 //-----------------------------------------------------------------------------
212 // Define the prolog for a TransitionBlock-based method. This macro should be called first in the method and
213 // comprises the entire prolog.The locals must be 8 byte aligned
215 // Save_argument_registers:
225 // General Registers:
254 .macro PROLOG_WITH_TRANSITION_BLOCK extraParameters = 0, extraLocals = 0, SaveFPRegs = 1
255 __PWTB_SaveFPArgs = \SaveFPRegs
257 __PWTB_FloatArgumentRegisters = \extraLocals
259 // Note, stack (see __PWTB_StackAlloc variable) must be 16 byte aligned,
260 // SIZEOF__FloatArgumentRegisters (0x40) is 16 byte aligned, that mean initial
261 // __PWTB_FloatArgumentRegisters value must be not 16 byte aligned and
262 // after add (120 + 64) provide 16 byte aligned result.
263 .if ((__PWTB_FloatArgumentRegisters % 16) == 0)
264 __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
267 __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
269 .if (__PWTB_SaveFPArgs == 1)
270 __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
274 __PWTB_CalleeSavedRegisters = __PWTB_TransitionBlock
275 __PWTB_ArgumentRegisters = __PWTB_TransitionBlock + 120
277 // Including fp, ra, s1-s11, tp, gp, and (a0-a7)arguments. (1+1+11+1+1)*8 + 8*8.
278 __PWTB_StackAlloc = __PWTB_TransitionBlock + 120 + 64
279 PROLOG_STACK_ALLOC __PWTB_StackAlloc
280 PROLOG_SAVE_REG_PAIR fp, ra, __PWTB_CalleeSavedRegisters, 1
282 // First, Spill argument registers.
283 SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
285 // Then, Spill callee saved registers. sp=r2.
286 SAVE_CALLEESAVED_REGISTERS sp, __PWTB_CalleeSavedRegisters
289 .if (__PWTB_SaveFPArgs == 1)
290 SAVE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
295 .macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
297 RESTORE_CALLEESAVED_REGISTERS sp, __PWTB_CalleeSavedRegisters
299 EPILOG_RESTORE_REG_PAIR fp, ra, __PWTB_CalleeSavedRegisters
301 EPILOG_STACK_FREE __PWTB_StackAlloc
307 //-----------------------------------------------------------------------------
308 // Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
309 // Since this is a tail call argument registers are restored.
311 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
312 .if (__PWTB_SaveFPArgs == 1)
313 RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
316 RESTORE_CALLEESAVED_REGISTERS sp, __PWTB_CalleeSavedRegisters
318 RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
320 EPILOG_RESTORE_REG_PAIR fp, ra, __PWTB_CalleeSavedRegisters
322 EPILOG_STACK_FREE __PWTB_StackAlloc
325 // ------------------------------------------------------------------
326 // Macro to generate Redirection Stubs
328 // $reason : reason for redirection
329 // Eg. GCThreadControl
330 // NOTE: If you edit this macro, make sure you update GetCONTEXTFromRedirectedStubStackFrame.
331 // This function is used by both the personality routine and the debugger to retrieve the original CONTEXT.
332 .macro GenerateRedirectedHandledJITCaseStub reason
337 //-----------------------------------------------------------------------------
338 // Macro used to check (in debug builds only) whether the stack is 16-bytes aligned (a requirement before calling
339 // out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
340 // before a call (if you have a frame pointer and a dynamic stack). A breakpoint will be invoked if the stack
343 .macro CHECK_STACK_ALIGNMENT