summaryrefslogtreecommitdiff
path: root/src/vm/amd64/AsmMacros.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/amd64/AsmMacros.inc')
-rw-r--r--src/vm/amd64/AsmMacros.inc442
1 files changed, 442 insertions, 0 deletions
diff --git a/src/vm/amd64/AsmMacros.inc b/src/vm/amd64/AsmMacros.inc
new file mode 100644
index 0000000000..f95a291929
--- /dev/null
+++ b/src/vm/amd64/AsmMacros.inc
@@ -0,0 +1,442 @@
+; 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.
+
+;
+; Define macros to build unwind data for prologues.
+;
+
+push_nonvol_reg macro Reg
+
+ .errnz ___STACK_ADJUSTMENT_FORBIDDEN, <push_nonvol_reg cannot be used after save_reg_postrsp>
+
+ push Reg
+ .pushreg Reg
+
+ endm
+
+push_vol_reg macro Reg
+
+ .errnz ___STACK_ADJUSTMENT_FORBIDDEN, push_vol_reg cannot be used after save_reg_postrsp
+
+ push Reg
+ .allocstack 8
+
+ endm
+
+push_eflags macro
+
+ .errnz ___STACK_ADJUSTMENT_FORBIDDEN, push_eflags cannot be used after save_reg_postrsp
+
+ pushfq
+ .allocstack 8
+
+ endm
+
+alloc_stack macro Size
+
+ .errnz ___STACK_ADJUSTMENT_FORBIDDEN, alloc_stack cannot be used after save_reg_postrsp
+
+ sub rsp, Size
+ .allocstack Size
+
+ endm
+
+save_reg_frame macro Reg, FrameReg, Offset
+
+ .erre ___FRAME_REG_SET, save_reg_frame cannot be used before set_frame
+
+ mov Offset[FrameReg], Reg
+ .savereg Reg, Offset
+
+ endm
+
+save_reg_postrsp macro Reg, Offset
+
+ .errnz ___FRAME_REG_SET, save_reg_postrsp cannot be used after set_frame
+
+ mov Offset[rsp], Reg
+ .savereg Reg, Offset
+
+ ___STACK_ADJUSTMENT_FORBIDDEN = 1
+
+ endm
+
+save_xmm128_frame macro Reg, FrameReg, Offset
+
+ .erre ___FRAME_REG_SET, save_xmm128_frame cannot be used before set_frame
+
+ movdqa Offset[FrameReg], Reg
+ .savexmm128 Reg, Offset
+
+ endm
+
+save_xmm128_postrsp macro Reg, Offset
+
+ .errnz ___FRAME_REG_SET, save_reg_postrsp cannot be used after set_frame
+
+ movdqa Offset[rsp], Reg
+ .savexmm128 Reg, Offset
+
+ ___STACK_ADJUSTMENT_FORBIDDEN = 1
+
+ endm
+
+set_frame macro Reg, Offset
+
+ .errnz ___FRAME_REG_SET, set_frame cannot be used more than once
+
+if Offset
+
+ lea Reg, Offset[rsp]
+
+else
+
+ mov reg, rsp
+
+endif
+
+ .setframe Reg, Offset
+ ___FRAME_REG_SET = 1
+
+ endm
+
+END_PROLOGUE macro
+
+ .endprolog
+
+ endm
+
+
+;
+; Define function entry/end macros.
+;
+
+LEAF_ENTRY macro Name, Section
+
+Section segment para 'CODE'
+
+ align 16
+
+ public Name
+Name proc
+
+ endm
+
+LEAF_END macro Name, section
+
+Name endp
+
+Section ends
+
+ endm
+
+LEAF_END_MARKED macro Name, section
+ public Name&_End
+Name&_End label qword
+ ; this nop is important to keep the label in
+ ; the right place in the face of BBT
+ nop
+
+Name endp
+
+Section ends
+
+ endm
+
+
+NESTED_ENTRY macro Name, Section, Handler
+
+Section segment para 'CODE'
+
+ align 16
+
+ public Name
+
+ifb <Handler>
+
+Name proc frame
+
+else
+
+Name proc frame:Handler
+
+endif
+
+ ___FRAME_REG_SET = 0
+ ___STACK_ADJUSTMENT_FORBIDDEN = 0
+
+ endm
+
+NESTED_END macro Name, section
+
+Name endp
+
+Section ends
+
+ endm
+
+NESTED_END_MARKED macro Name, section
+ public Name&_End
+Name&_End label qword
+
+Name endp
+
+Section ends
+
+ endm
+
+
+;
+; Macro to Call GetThread() correctly whether it is indirect or direct
+;
+CALL_GETTHREAD macro
+ifndef GetThread
+extern GetThread:proc
+endif
+ call GetThread
+ endm
+
+CALL_GETAPPDOMAIN macro
+ifndef GetAppDomain
+extern GetAppDomain:proc
+endif
+ call GetAppDomain
+ endm
+
+;
+; if you change this code there will be corresponding code in JITInterfaceGen.cpp which will need to be changed
+;
+
+; DEFAULT_TARGET needs to always be futher away than the fixed up target will be
+
+
+JIT_HELPER_MONITOR_THUNK macro THUNK_NAME, Section
+Section segment para 'CODE'
+ align 16
+ public THUNK_NAME
+THUNK_NAME proc
+ xor edx, edx
+THUNK_NAME endp
+Section ends
+ endm
+
+;
+; Useful for enabling C++ to know where to patch code at runtime.
+;
+PATCH_LABEL macro Name
+ public Name
+Name::
+ endm
+
+;
+; Define alternate entry macro.
+;
+ALTERNATE_ENTRY macro Name
+ public Name
+Name label proc
+ endm
+
+;
+; Appropriate instructions for certain specific scenarios:
+; - REPRET: should be used as the return instruction when the return is a branch
+; target or immediately follows a conditional branch
+; - TAILJMP_RAX: ("jmp rax") should be used for tailcalls, this emits an instruction
+; sequence which is recognized by the unwinder as a valid epilogue terminator
+;
+REPRET TEXTEQU <DB 0F3h, 0C3h>
+TAILJMP_RAX TEXTEQU <DB 048h, 0FFh, 0E0h>
+
+NOP_2_BYTE macro
+
+ xchg ax,ax
+
+ endm
+
+NOP_3_BYTE macro
+
+ nop dword ptr [rax]
+
+ endm
+
+PUSH_CALLEE_SAVED_REGISTERS macro
+
+ push_nonvol_reg r15
+ push_nonvol_reg r14
+ push_nonvol_reg r13
+ push_nonvol_reg r12
+ push_nonvol_reg rbp
+ push_nonvol_reg rbx
+ push_nonvol_reg rsi
+ push_nonvol_reg rdi
+
+ endm
+
+SAVE_CALLEE_SAVED_REGISTERS macro ofs
+
+ save_reg_postrsp rdi, ofs + 0h
+ save_reg_postrsp rsi, ofs + 8h
+ save_reg_postrsp rbx, ofs + 10h
+ save_reg_postrsp rbp, ofs + 18h
+ save_reg_postrsp r12, ofs + 20h
+ save_reg_postrsp r13, ofs + 28h
+ save_reg_postrsp r14, ofs + 30h
+ save_reg_postrsp r15, ofs + 38h
+
+ endm
+
+POP_CALLEE_SAVED_REGISTERS macro
+
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rbp
+ pop r12
+ pop r13
+ pop r14
+ pop r15
+
+ endm
+
+SAVE_ARGUMENT_REGISTERS macro ofs
+
+ save_reg_postrsp rcx, ofs + 0h
+ save_reg_postrsp rdx, ofs + 8h
+ save_reg_postrsp r8, ofs + 10h
+ save_reg_postrsp r9, ofs + 18h
+
+ endm
+
+RESTORE_ARGUMENT_REGISTERS macro ofs
+
+ mov rcx, [rsp + ofs + 0h]
+ mov rdx, [rsp + ofs + 8h]
+ mov r8, [rsp + ofs + 10h]
+ mov r9, [rsp + ofs + 18h]
+
+ endm
+
+SAVE_FLOAT_ARGUMENT_REGISTERS macro ofs
+
+ save_xmm128_postrsp xmm0, ofs
+ save_xmm128_postrsp xmm1, ofs + 10h
+ save_xmm128_postrsp xmm2, ofs + 20h
+ save_xmm128_postrsp xmm3, ofs + 30h
+
+ endm
+
+RESTORE_FLOAT_ARGUMENT_REGISTERS macro ofs
+
+ movdqa xmm0, [rsp + ofs]
+ movdqa xmm1, [rsp + ofs + 10h]
+ movdqa xmm2, [rsp + ofs + 20h]
+ movdqa xmm3, [rsp + ofs + 30h]
+
+ endm
+
+
+; Stack layout:
+;
+; (stack parameters)
+; ...
+; r9
+; r8
+; rdx
+; rcx <- __PWTB_ArgumentRegisters
+; return address
+; CalleeSavedRegisters::r15
+; CalleeSavedRegisters::r14
+; CalleeSavedRegisters::r13
+; CalleeSavedRegisters::r12
+; CalleeSavedRegisters::rbp
+; CalleeSavedRegisters::rbx
+; CalleeSavedRegisters::rsi
+; CalleeSavedRegisters::rdi <- __PWTB_StackAlloc
+; padding to align xmm save area
+; xmm3
+; xmm2
+; xmm1
+; xmm0 <- __PWTB_FloatArgumentRegisters
+; extra locals + padding to qword align
+; callee's r9
+; callee's r8
+; callee's rdx
+; callee's rcx
+
+PROLOG_WITH_TRANSITION_BLOCK macro extraLocals := <0>, stackAllocOnEntry := <0>, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
+
+ __PWTB_FloatArgumentRegisters = SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES + extraLocals
+
+ if (__PWTB_FloatArgumentRegisters mod 16) ne 0
+ __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
+ endif
+
+ __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 4 * 16 + 8
+ __PWTB_TransitionBlock = __PWTB_StackAlloc
+ __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 9 * 8
+
+ .errnz stackAllocOnEntry ge 4*8, Max supported stackAllocOnEntry is 3*8
+
+ if stackAllocOnEntry gt 0
+ .allocstack stackAllocOnEntry
+ endif
+
+ ; PUSH_CALLEE_SAVED_REGISTERS expanded here
+
+ if stackAllocOnEntry lt 8
+ push_nonvol_reg r15
+ endif
+
+ if stackAllocOnEntry lt 2*8
+ push_nonvol_reg r14
+ endif
+
+ if stackAllocOnEntry lt 3*8
+ push_nonvol_reg r13
+ endif
+
+ push_nonvol_reg r12
+ push_nonvol_reg rbp
+ push_nonvol_reg rbx
+ push_nonvol_reg rsi
+ push_nonvol_reg rdi
+
+ alloc_stack __PWTB_StackAlloc
+ SAVE_ARGUMENT_REGISTERS __PWTB_ArgumentRegisters
+ SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
+
+ if stackAllocOnEntry ge 3*8
+ mov stackAllocSpill3, [rsp + __PWTB_StackAlloc + 28h]
+ save_reg_postrsp r13, __PWTB_StackAlloc + 28h
+ endif
+
+ if stackAllocOnEntry ge 2*8
+ mov stackAllocSpill2, [rsp + __PWTB_StackAlloc + 30h]
+ save_reg_postrsp r14, __PWTB_StackAlloc + 30h
+ endif
+
+ if stackAllocOnEntry ge 8
+ mov stackAllocSpill1, [rsp + __PWTB_StackAlloc + 38h]
+ save_reg_postrsp r15, __PWTB_StackAlloc + 38h
+ endif
+
+ END_PROLOGUE
+
+ endm
+
+EPILOG_WITH_TRANSITION_BLOCK_RETURN macro
+
+ add rsp, __PWTB_StackAlloc
+ POP_CALLEE_SAVED_REGISTERS
+ ret
+
+ endm
+
+EPILOG_WITH_TRANSITION_BLOCK_TAILCALL macro
+
+ RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
+ RESTORE_ARGUMENT_REGISTERS __PWTB_ArgumentRegisters
+ add rsp, __PWTB_StackAlloc
+ POP_CALLEE_SAVED_REGISTERS
+
+ endm