diff options
Diffstat (limited to 'src/vm/arm/asmmacros.h')
-rw-r--r-- | src/vm/arm/asmmacros.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/vm/arm/asmmacros.h b/src/vm/arm/asmmacros.h new file mode 100644 index 0000000000..cff79c259b --- /dev/null +++ b/src/vm/arm/asmmacros.h @@ -0,0 +1,161 @@ +// 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. + +;; ==++== +;; + +;; +;; ==--== + +;----------------------------------------------------------------------------- +; 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 + + +;----------------------------------------------------------------------------- +; Macro used to end a function with explicit _End label + MACRO + LEAF_END_MARKED $FuncName + + LCLS __EndLabelName +__EndLabelName SETS "$FuncName":CC:"_End" + EXPORT $__EndLabelName +$__EndLabelName + + LEAF_END $FuncName + + MEND + +;----------------------------------------------------------------------------- +; Macro use for enabling C++ to know where to patch code at runtime. + MACRO + PATCH_LABEL $FuncName +$FuncName + EXPORT $FuncName + + 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 + +;----------------------------------------------------------------------------- +; The following group of macros assist in implementing prologs and epilogs for methods that set up some +; subclass of TransitionFrame. They ensure that the SP is 64-bit aligned at the conclusion of the prolog and +; provide a helper macro to locate the start of the NegInfo (if there is one) for the frame. + +;----------------------------------------------------------------------------- +; 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). Takes the size of the frame's NegInfo +; (which may be zero) and the frame itself. No initialization of the frame is done beyond callee saved +; registers and (non-floating point) argument registers. +; + MACRO + PROLOG_WITH_TRANSITION_BLOCK $extraLocals, $SaveFPArgs, $PushArgRegs + + GBLA __PWTB_FloatArgumentRegisters + GBLA __PWTB_StackAlloc + GBLA __PWTB_TransitionBlock + GBLL __PWTB_SaveFPArgs + + IF "$SaveFPArgs" != "" +__PWTB_SaveFPArgs SETL $SaveFPArgs + ELSE +__PWTB_SaveFPArgs SETL {true} + ENDIF + + IF "$extraLocals" != "" +__PWTB_FloatArgumentRegisters SETA $extraLocals + ELSE +__PWTB_FloatArgumentRegisters SETA 0 + ENDIF + + IF __PWTB_SaveFPArgs + + IF __PWTB_FloatArgumentRegisters:MOD:8 != 0 +__PWTB_FloatArgumentRegisters SETA __PWTB_FloatArgumentRegisters + 4 + ENDIF +__PWTB_TransitionBlock SETA __PWTB_FloatArgumentRegisters + (SIZEOF__FloatArgumentRegisters + 4) ; padding + + ELSE + + IF __PWTB_FloatArgumentRegisters:MOD:8 == 0 +__PWTB_FloatArgumentRegisters SETA __PWTB_FloatArgumentRegisters + 4; padding + ENDIF +__PWTB_TransitionBlock SETA __PWTB_FloatArgumentRegisters + + ENDIF + +__PWTB_StackAlloc SETA __PWTB_TransitionBlock + + IF "$PushArgRegs" != "DoNotPushArgRegs" + ; Spill argument registers. + PROLOG_PUSH {r0-r3} + ENDIF + + ; Spill callee saved registers and return address. + PROLOG_PUSH {r4-r11,lr} + + ; Allocate space for the rest of the frame + PROLOG_STACK_ALLOC __PWTB_StackAlloc + + IF __PWTB_SaveFPArgs + add r6, sp, #(__PWTB_FloatArgumentRegisters) + vstm r6, {s0-s15} + ENDIF + + CHECK_STACK_ALIGNMENT + MEND + +;----------------------------------------------------------------------------- +; 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 + add r6, sp, #(__PWTB_FloatArgumentRegisters) + vldm r6, {s0-s15} + ENDIF + + EPILOG_STACK_FREE __PWTB_StackAlloc + EPILOG_POP {r4-r11,lr} + EPILOG_POP {r0-r3} + MEND + +;----------------------------------------------------------------------------- +; Provides a matching epilog to PROLOG_WITH_TRANSITION_FRAME and ends by returning to the original caller. +; Since this is not a tail call argument registers are not restored. +; + MACRO + EPILOG_WITH_TRANSITION_BLOCK_RETURN + + EPILOG_STACK_FREE __PWTB_StackAlloc + EPILOG_POP {r4-r11,lr} + EPILOG_STACK_FREE 16 + EPILOG_RETURN + MEND + |