summaryrefslogtreecommitdiff
path: root/src/pal/inc/unixasmmacrosamd64.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/inc/unixasmmacrosamd64.inc')
-rw-r--r--src/pal/inc/unixasmmacrosamd64.inc355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/pal/inc/unixasmmacrosamd64.inc b/src/pal/inc/unixasmmacrosamd64.inc
new file mode 100644
index 0000000000..f221b4406b
--- /dev/null
+++ b/src/pal/inc/unixasmmacrosamd64.inc
@@ -0,0 +1,355 @@
+// 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 NESTED_ENTRY Name, Section, Handler
+ LEAF_ENTRY \Name, \Section
+ .ifnc \Handler, NoHandler
+#if defined(__APPLE__)
+ .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
+#else
+ .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
+#endif
+ .endif
+.endm
+
+.macro NESTED_END Name, Section
+ LEAF_END \Name, \Section
+#if defined(__APPLE__)
+ .set LOCAL_LABEL(\Name\()_Size), . - C_FUNC(\Name)
+ .section __LD,__compact_unwind,regular,debug
+ .quad C_FUNC(\Name)
+ .long LOCAL_LABEL(\Name\()_Size)
+ .long 0x04000000 # DWARF
+ .quad 0
+ .quad 0
+#endif
+.endm
+
+.macro PATCH_LABEL Name
+ .global C_FUNC(\Name)
+C_FUNC(\Name):
+.endm
+
+.macro LEAF_ENTRY Name, Section
+ .global C_FUNC(\Name)
+#if defined(__APPLE__)
+ .text
+#else
+ .type \Name, %function
+#endif
+C_FUNC(\Name):
+ .cfi_startproc
+.endm
+
+.macro LEAF_END Name, Section
+#if !defined(__APPLE__)
+ .size \Name, .-\Name
+#endif
+ .cfi_endproc
+.endm
+
+.macro LEAF_END_MARKED Name, Section
+C_FUNC(\Name\()_End):
+ .global C_FUNC(\Name\()_End)
+ LEAF_END \Name, \Section
+.endm
+
+.macro NOP_3_BYTE
+ nop dword ptr [rax]
+.endm
+
+.macro NOP_2_BYTE
+ xchg ax, ax
+.endm
+
+.macro REPRET
+ .byte 0xf3
+ .byte 0xc3
+.endm
+
+.macro TAILJMP_RAX
+ .byte 0x48
+ .byte 0xFF
+ .byte 0xE0
+.endm
+
+.macro PREPARE_EXTERNAL_VAR Name, HelperReg
+ mov \HelperReg, [rip + C_FUNC(\Name)@GOTPCREL]
+.endm
+
+.macro push_nonvol_reg Register
+ push \Register
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset \Register, 0
+.endm
+
+.macro pop_nonvol_reg Register
+ pop \Register
+ .cfi_adjust_cfa_offset -8
+ .cfi_restore \Register
+.endm
+
+.macro alloc_stack Size
+.att_syntax
+ lea -(\Size)(%rsp), %rsp
+.intel_syntax noprefix
+ .cfi_adjust_cfa_offset \Size
+.endm
+
+.macro free_stack Size
+.att_syntax
+ lea \Size(%rsp), %rsp
+.intel_syntax noprefix
+ .cfi_adjust_cfa_offset -\Size
+.endm
+
+.macro set_cfa_register Reg, Offset
+ .cfi_def_cfa_register \Reg
+ .cfi_def_cfa_offset \Offset
+.endm
+
+.macro save_reg_postrsp Reg, Offset
+ __Offset = \Offset
+ mov qword ptr [rsp + __Offset], \Reg
+ .cfi_rel_offset \Reg, __Offset
+.endm
+
+.macro restore_reg Reg, Offset
+ __Offset = \Offset
+ mov \Reg, [rsp + __Offset]
+ .cfi_restore \Reg
+.endm
+
+.macro save_xmm128_postrsp Reg, Offset
+ __Offset = \Offset
+ movdqa xmmword ptr [rsp + __Offset], \Reg
+ // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here,
+ // the xmm registers are not supported by the libunwind
+.endm
+
+.macro restore_xmm128 Reg, ofs
+ __Offset = \ofs
+ movdqa \Reg, xmmword ptr [rsp + __Offset]
+ // NOTE: We cannot use ".cfi_restore \Reg" here,
+ // the xmm registers are not supported by the libunwind
+
+.endm
+
+.macro PUSH_CALLEE_SAVED_REGISTERS
+
+ push_register rbp
+ push_register rbx
+ push_register r15
+ push_register r14
+ push_register r13
+ push_register r12
+
+.endm
+
+.macro POP_CALLEE_SAVED_REGISTERS
+
+ pop_nonvol_reg r12
+ pop_nonvol_reg r13
+ pop_nonvol_reg r14
+ pop_nonvol_reg r15
+ pop_nonvol_reg rbx
+ pop_nonvol_reg rbp
+
+.endm
+
+.macro push_register Reg
+ push \Reg
+ .cfi_adjust_cfa_offset 8
+.endm
+
+.macro push_eflags
+ pushfq
+ .cfi_adjust_cfa_offset 8
+.endm
+
+.macro push_argument_register Reg
+ push_register \Reg
+.endm
+
+.macro PUSH_ARGUMENT_REGISTERS
+
+ push_argument_register r9
+ push_argument_register r8
+ push_argument_register rcx
+ push_argument_register rdx
+ push_argument_register rsi
+ push_argument_register rdi
+
+.endm
+
+.macro pop_register Reg
+ pop \Reg
+ .cfi_adjust_cfa_offset -8
+.endm
+
+.macro pop_eflags
+ popfq
+ .cfi_adjust_cfa_offset -8
+.endm
+
+.macro pop_argument_register Reg
+ pop_register \Reg
+.endm
+
+.macro POP_ARGUMENT_REGISTERS
+
+ pop_argument_register rdi
+ pop_argument_register rsi
+ pop_argument_register rdx
+ pop_argument_register rcx
+ pop_argument_register r8
+ pop_argument_register r9
+
+.endm
+
+.macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
+
+ save_xmm128_postrsp xmm0, \ofs
+ save_xmm128_postrsp xmm1, \ofs + 0x10
+ save_xmm128_postrsp xmm2, \ofs + 0x20
+ save_xmm128_postrsp xmm3, \ofs + 0x30
+ save_xmm128_postrsp xmm4, \ofs + 0x40
+ save_xmm128_postrsp xmm5, \ofs + 0x50
+ save_xmm128_postrsp xmm6, \ofs + 0x60
+ save_xmm128_postrsp xmm7, \ofs + 0x70
+
+.endm
+
+.macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
+
+ restore_xmm128 xmm0, \ofs
+ restore_xmm128 xmm1, \ofs + 0x10
+ restore_xmm128 xmm2, \ofs + 0x20
+ restore_xmm128 xmm3, \ofs + 0x30
+ restore_xmm128 xmm4, \ofs + 0x40
+ restore_xmm128 xmm5, \ofs + 0x50
+ restore_xmm128 xmm6, \ofs + 0x60
+ restore_xmm128 xmm7, \ofs + 0x70
+
+.endm
+
+// Stack layout:
+//
+// (stack parameters)
+// ...
+// return address
+// CalleeSavedRegisters::rbp
+// CalleeSavedRegisters::rbx
+// CalleeSavedRegisters::r15
+// CalleeSavedRegisters::r14
+// CalleeSavedRegisters::r13
+// CalleeSavedRegisters::r12
+// ArgumentRegisters::r9
+// ArgumentRegisters::r8
+// ArgumentRegisters::rcx
+// ArgumentRegisters::rdx
+// ArgumentRegisters::rsi
+// ArgumentRegisters::rdi <- __PWTB_StackAlloc, __PWTB_TransitionBlock
+// padding to align xmm save area
+// xmm7
+// xmm6
+// xmm5
+// xmm4
+// xmm3
+// xmm2
+// xmm1
+// xmm0 <- __PWTB_FloatArgumentRegisters
+// extra locals + padding to qword align
+.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
+
+ set_cfa_register rsp, 8
+
+ __PWTB_FloatArgumentRegisters = \extraLocals
+
+ .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
+ __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
+ .endif
+
+ __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
+ __PWTB_TransitionBlock = __PWTB_StackAlloc
+
+ .if \stackAllocOnEntry >= 4*8
+ .error "Max supported stackAllocOnEntry is 3*8"
+ .endif
+
+ .if \stackAllocOnEntry > 0
+ .cfi_adjust_cfa_offset \stackAllocOnEntry
+ .endif
+
+ // PUSH_CALLEE_SAVED_REGISTERS expanded here
+
+ .if \stackAllocOnEntry < 8
+ push_nonvol_reg rbp
+ mov rbp, rsp
+ .endif
+
+ .if \stackAllocOnEntry < 2*8
+ push_nonvol_reg rbx
+ .endif
+
+ .if \stackAllocOnEntry < 3*8
+ push_nonvol_reg r15
+ .endif
+
+ push_nonvol_reg r14
+ push_nonvol_reg r13
+ push_nonvol_reg r12
+
+ // ArgumentRegisters
+ PUSH_ARGUMENT_REGISTERS
+
+ .if \stackAllocOnEntry >= 3*8
+ mov \stackAllocSpill3, [rsp + 0x48]
+ save_reg_postrsp r15, 0x48
+ .endif
+
+ .if \stackAllocOnEntry >= 2*8
+ mov \stackAllocSpill2, [rsp + 0x50]
+ save_reg_postrsp rbx, 0x50
+ .endif
+
+ .if \stackAllocOnEntry >= 8
+ mov \stackAllocSpill1, [rsp + 0x58]
+ save_reg_postrsp rbp, 0x58
+ lea rbp, [rsp + 0x58]
+ .endif
+
+ alloc_stack __PWTB_StackAlloc
+ SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
+
+ END_PROLOGUE
+
+.endm
+
+.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
+
+ free_stack __PWTB_StackAlloc
+ POP_ARGUMENT_REGISTERS
+ POP_CALLEE_SAVED_REGISTERS
+ ret
+
+.endm
+
+.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
+ free_stack __PWTB_StackAlloc
+ POP_ARGUMENT_REGISTERS
+ POP_CALLEE_SAVED_REGISTERS
+
+.endm
+
+.macro RESET_FRAME_WITH_RBP
+
+ mov rsp, rbp
+ set_cfa_register rsp, 16
+ pop_nonvol_reg rbp
+ .cfi_same_value rbp
+
+.endm