+// Stack management and unwinding.
+.macro setfp fp, offset = 0
+ .if \offset == 0
+ mov \fp, R_sp(r)
+#if __ELF__
+ .cfi_def_cfa_register \fp
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_setframe \fp, 0
+#endif
+ .else
+ lea \fp, [R_sp(r) + \offset]
+#if __ELF__
+ .cfi_def_cfa_register \fp
+ .cfi_adjust_cfa_offset -\offset
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_setframe \fp, \offset
+#endif
+ .endif
+ .L$_frameptr_p = -1
+ .macro dropfp; _dropfp \fp, \offset; .endm
+.endm
+
+.macro _dropfp fp, offset = 0
+ .if \offset == 0
+ mov R_sp(r), \fp
+#if __ELF__
+ .cfi_def_cfa_register R_sp(r)
+#endif
+ .else
+ lea R_sp(r), [\fp - \offset]
+#if __ELF__
+ .cfi_def_cfa_register R_sp(r)
+ .cfi_adjust_cfa_offset +\offset
+#endif
+ .endif
+ .L$_frameptr_p = 0
+ .purgem dropfp
+.endm
+
+.macro stalloc n
+ sub R_sp(r), \n
+#if __ELF__
+ .cfi_adjust_cfa_offset +\n
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_stackalloc \n
+#endif
+.endm
+
+.macro stfree n
+ add R_sp(r), \n
+#if __ELF__
+ .cfi_adjust_cfa_offset -\n
+#endif
+.endm
+
+.macro pushreg r
+ push \r
+#if __ELF__
+ .cfi_adjust_cfa_offset +WORDSZ
+ .cfi_rel_offset \r, 0
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_pushreg \r
+#endif
+.endm
+
+.macro popreg r
+ pop \r
+#if __ELF__
+ .cfi_adjust_cfa_offset -WORDSZ
+ .cfi_restore \r
+#endif
+.endm
+
+.macro savexmm r, offset
+ movdqa [R_sp(r) + \offset], \r
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_savexmm \r, \offset
+#endif
+.endm
+
+.macro rstrxmm r, offset
+ movdqa \r, [R_sp(r) + \offset]
+.endm
+
+.macro endprologue
+#if ABI_WIN && CPUFAM_AMD64
+ .seh_endprologue
+#endif
+ .L$_prologue_p = -1
+.endm
+