summaryrefslogtreecommitdiff
path: root/src/vm/arm/asmmacros.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/arm/asmmacros.h')
-rw-r--r--src/vm/arm/asmmacros.h161
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
+